From a855b64947a649500284406f7d4e6472f3368f12 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Mon, 8 Sep 2025 18:23:58 -0700 Subject: [PATCH 001/204] init --- src/transformers/__init__.py | 2 + .../generation/configuration_utils.py | 9 ++ src/transformers/generation/logits_process.py | 127 ++++++++++++++++++ src/transformers/generation/utils.py | 5 + tests/generation/test_logits_process.py | 71 ++++++++++ 5 files changed, 214 insertions(+) diff --git a/src/transformers/__init__.py b/src/transformers/__init__.py index 904d5e9c3f4a..f8d91bb15f0f 100755 --- a/src/transformers/__init__.py +++ b/src/transformers/__init__.py @@ -434,6 +434,7 @@ "MinLengthLogitsProcessor", "MinNewTokensLengthLogitsProcessor", "MinPLogitsWarper", + "TopHLogitsWarper", "NoBadWordsLogitsProcessor", "NoRepeatNGramLogitsProcessor", "PhrasalConstraint", @@ -692,6 +693,7 @@ from .generation import MinLengthLogitsProcessor as MinLengthLogitsProcessor from .generation import MinNewTokensLengthLogitsProcessor as MinNewTokensLengthLogitsProcessor from .generation import MinPLogitsWarper as MinPLogitsWarper + from .generation import TopHLogitsWarper as TopHLogitsWarper from .generation import NoBadWordsLogitsProcessor as NoBadWordsLogitsProcessor from .generation import NoRepeatNGramLogitsProcessor as NoRepeatNGramLogitsProcessor from .generation import PhrasalConstraint as PhrasalConstraint diff --git a/src/transformers/generation/configuration_utils.py b/src/transformers/generation/configuration_utils.py index bd7f02e64cee..c64e926f79c9 100644 --- a/src/transformers/generation/configuration_utils.py +++ b/src/transformers/generation/configuration_utils.py @@ -167,6 +167,12 @@ class GenerationConfig(PushToHubMixin): Minimum token probability, which will be scaled by the probability of the most likely token. It must be a value between 0 and 1. Typical values are in the 0.01-0.2 range, comparably selective as setting `top_p` in the 0.99-0.8 range (use the opposite of normal `top_p` values). + top_h (`float`, *optional*): + Entropy budget scaling factor, which controls how much of the distribution’s entropy is preserved when sampling. + Must be a value between 0 and 1. At each step, tokens are sorted by probability, and the smallest prefix of tokens + is kept whose *renormalized* entropy is less than or equal to `top_h` times the entropy of the full distribution. + Smaller values (e.g., 0.2–0.5) lead to more focused, deterministic outputs, while values closer to 1.0 allow more + randomness and diversity. Typical values are in the 0.3–0.6 range. typical_p (`float`, *optional*, defaults to 1.0): Local typicality measures how similar the conditional probability of predicting a target token next is to the expected conditional probability of predicting a random token next, given the partial text already @@ -357,6 +363,7 @@ def __init__(self, **kwargs): self.top_k = kwargs.pop("top_k", 50) self.top_p = kwargs.pop("top_p", 1.0) self.min_p = kwargs.pop("min_p", None) + self.top_h = kwargs.pop("top_h", None) self.typical_p = kwargs.pop("typical_p", 1.0) self.epsilon_cutoff = kwargs.pop("epsilon_cutoff", 0.0) self.eta_cutoff = kwargs.pop("eta_cutoff", 0.0) @@ -587,6 +594,8 @@ def validate(self, strict=False): minor_issues["top_p"] = greedy_wrong_parameter_msg.format(flag_name="top_p", flag_value=self.top_p) if self.min_p is not None: minor_issues["min_p"] = greedy_wrong_parameter_msg.format(flag_name="min_p", flag_value=self.min_p) + if self.top_h is not None: + minor_issues["top_h"] = greedy_wrong_parameter_msg.format(flag_name="top_h", flag_value=self.top_h) if self.typical_p is not None and self.typical_p != 1.0: minor_issues["typical_p"] = greedy_wrong_parameter_msg.format( flag_name="typical_p", flag_value=self.typical_p diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index f63d2246c6a9..01fe3021c388 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -581,6 +581,133 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to scores_processed = scores.masked_fill(indices_to_remove, self.filter_value) return scores_processed +class TopHLogitsWarper(LogitsProcessor): + + """ + [`LogitsProcessor`] that implements Top-H sampling, a decoding method which adaptively selects a subset of + high-probability tokens based on entropy and cumulative probability constraints. + + This method dynamically determines how many tokens to keep by analyzing the entropy difference of the selected + distribution, thereby balancing exploration and exploitation. It ensures that generated text maintains both + diversity and coherence. + + Args: + top_n (`int`, *optional*, defaults to 100): + The maximum number of tokens to consider for filtering. + Only the top `top_n` tokens (by probability) are evaluated. + temperature (`float`, *optional*, defaults to 1.0): + Softmax temperature. Higher values increase randomness, while lower values make predictions sharper. + alpha (`float`, *optional*, defaults to 0.4): + Scaling coefficient for the entropy-based threshold (`tau`). Must be in the range `(0, 1]`. + filter_value (`float`, *optional*, defaults to -inf): + All filtered values will be set to this float value. + + Example: + + ```python + >>> from transformers import AutoTokenizer, AutoModelForCausalLM + + >>> model = AutoModelForCausalLM.from_pretrained("distilgpt2") + >>> tokenizer = AutoTokenizer.from_pretrained("distilgpt2") + + >>> inputs = tokenizer("A sequence: 1, 2", return_tensors="pt") + + >>> outputs = model.generate(**inputs, do_sample=True, top_h=0.1) + >>> print(tokenizer.batch_decode(outputs, skip_special_tokens=True)[0]) + A sequence: 1, 2, 3, 4, 5, 6, 7, 8, 9 + ``` + """ + + + def __init__(self, top_h: float, temperature: float = 1.0, filter_value: float = -float("Inf")): + super().__init__() + + # input checks + if temperature == 0: + raise ValueError("Temperature must be non-zero to perform Top-H decoding.") + if not (0 < top_h <= 1): + raise ValueError("alpha must be in the range (0, 1].") + + self.top_n = 100 + self.temperature = temperature + self.coef = top_h + self.filter_value = filter_value + + @staticmethod + def calculate_entropy(probs): + + """ + Computes Shannon entropy of a probability distribution. + + Args: + probs (`torch.FloatTensor`): + Probability distribution over tokens. + + Return: + `torch.FloatTensor`: Scalar entropy value. + """ + + probs = probs/torch.sum(probs) + return -torch.sum(probs * torch.log2(probs)) + + def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor: + + """ + Filters logits using Top-H sampling. + + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Input token IDs. + scores (`torch.FloatTensor` of shape `(batch_size, vocab_size)`): + Raw logits from the model. + + Return: + `torch.FloatTensor` of shape `(batch_size, vocab_size)`: + Processed logits where invalid tokens are masked with `-inf`. + """ + + batch_size, vocab_size = scores.shape + device = scores.device + + # compute probabilities + scaled_logits = scores / self.temperature + probs = torch.softmax(scaled_logits, dim=-1) + + keep_mask = torch.zeros((batch_size, vocab_size), dtype=torch.bool, device=device) + + top_n = min(self.top_n, vocab_size) + + for b in range(batch_size): + # top-k for this example + top_probs, top_idx = torch.topk(probs[b], top_n, largest=True, sorted=True) + + # entropy-based threshold tau (computed on the top-k distribution) + alpha_sum = top_probs.sum() + tau = (self.calculate_entropy(top_probs) - torch.log2(alpha_sum)) * alpha_sum * self.coef + + # grow the kept set until the stopping rule triggers + sigma = top_probs[0] + H = - top_probs[0] * torch.log2(top_probs[0]) + chosen = [] + ind = 0 + for idx, p in zip(top_idx, top_probs): + chosen.append(idx) + ind += 1 + # update running sums for current prefix + sigma = sigma + top_probs[ind] + H = H + (-top_probs[ind] * torch.log2(top_probs[ind])) + # entropy difference term + entropy_diff = (H / sigma) + torch.log2(sigma) + if entropy_diff > (tau / sigma + torch.log2(sigma)): + break + + keep_mask[b, torch.stack(chosen)] = True + + # apply filtering + scores_processed = scores.clone() + scores_processed[~keep_mask] = self.filter_value + + return scores_processed class MinPLogitsWarper(LogitsProcessor): """ diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index 1fa0570ee81f..88a3797946ad 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -85,6 +85,7 @@ MinLengthLogitsProcessor, MinNewTokensLengthLogitsProcessor, MinPLogitsWarper, + TopHLogitsWarper, NoBadWordsLogitsProcessor, NoRepeatNGramLogitsProcessor, PrefixConstrainedLogitsProcessor, @@ -1278,6 +1279,10 @@ def _get_logits_processor( processors.append( MinPLogitsWarper(min_p=generation_config.min_p, min_tokens_to_keep=min_tokens_to_keep) ) + if generation_config.top_h is not None: + processors.append( + TopHLogitsWarper(top_h=generation_config.top_h) + ) if generation_config.typical_p is not None and generation_config.typical_p < 1.0: processors.append( TypicalLogitsWarper(mass=generation_config.typical_p, min_tokens_to_keep=min_tokens_to_keep) diff --git a/tests/generation/test_logits_process.py b/tests/generation/test_logits_process.py index 768e216ef534..483cfa8a99e7 100644 --- a/tests/generation/test_logits_process.py +++ b/tests/generation/test_logits_process.py @@ -42,6 +42,7 @@ MinLengthLogitsProcessor, MinNewTokensLengthLogitsProcessor, MinPLogitsWarper, + TopHLogitsWarper, NoBadWordsLogitsProcessor, NoRepeatNGramLogitsProcessor, PrefixConstrainedLogitsProcessor, @@ -393,6 +394,76 @@ def test_top_p_dist_warper(self): # first batch should keep three tokens, second batch would keep only 1, but due to `min_tokens_to_keep=2` keeps 2. self.assertListEqual((filtered_dist != 0.0).to(torch.long).sum(dim=-1).tolist(), [3, 2]) + def test_top_h_dist_warper(): + """ + We construct small distributions where the expected kept set is obvious for a given alpha. + We pass *log-probabilities* as "scores" so that softmax(scores) == original probabilities, + matching the style in other warper tests (e.g., MinP). + """ + + input_ids = None + + # --- Case 1: Highly peaked distribution -> small alpha keeps only the top-1 + dist1 = torch.log( + torch.tensor( + [[0.97, 0.01, 0.01, 0.01]], + device=torch_device, + dtype=torch.float, + ) + ) + top_h_warp = TopHLogitsWarper(alpha=0.3, min_tokens_to_keep=1) + filtered_logits = top_h_warp(input_ids, dist1.clone()) + filtered_dist = torch.exp(filtered_logits) # exp(-inf) -> 0 + + EXPECTED1 = torch.tensor( + [[0.97, 0.0, 0.0, 0.0]], + device=torch_device, + dtype=torch.float, + ) + torch.testing.assert_close(filtered_dist, EXPECTED1, rtol=1e-3, atol=1e-3) + + # --- Case 2: Moderately skewed distribution -> alpha large enough to keep exactly top-2 + dist2 = torch.log( + torch.tensor( + [[0.4, 0.3, 0.2, 0.1]], # entropy budget with alpha=0.7 yields 2-token prefix + device=torch_device, + dtype=torch.float, + ) + ) + top_h_warp = TopHLogitsWarper(alpha=0.7, min_tokens_to_keep=1) + filtered_logits = top_h_warp(input_ids, dist2.clone()) + filtered_dist = torch.exp(filtered_logits) + + EXPECTED2 = torch.tensor( + [[0.4, 0.3, 0.0, 0.0]], + device=torch_device, + dtype=torch.float, + ) + torch.testing.assert_close(filtered_dist, EXPECTED2, rtol=1e-3, atol=1e-3) + + # --- Case 3: Uniform distribution -> alpha=1.0 keeps all tokens + dist3 = torch.log( + torch.tensor( + [[0.25, 0.25, 0.25, 0.25]], + device=torch_device, + dtype=torch.float, + ) + ) + top_h_warp = TopHLogitsWarper(alpha=1.0, min_tokens_to_keep=1) + filtered_logits = top_h_warp(input_ids, dist3.clone()) + filtered_dist = torch.exp(filtered_logits) + + EXPECTED3 = torch.tensor( + [[0.25, 0.25, 0.25, 0.25]], + device=torch_device, + dtype=torch.float, + ) + torch.testing.assert_close(filtered_dist, EXPECTED3, rtol=1e-3, atol=1e-3) + + # Processor should not change logits in-place + top_h_warp = TopHLogitsWarper(alpha=0.5, min_tokens_to_keep=1) + out_again = top_h_warp(input_ids, dist3) + assert not torch.all(out_again == dist3) def test_min_p_dist_warper(self): input_ids = None From 2109ccf621d37c50ac52964a9df1b94001c177e5 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Mon, 8 Sep 2025 19:59:56 -0700 Subject: [PATCH 002/204] added TopH --- src/transformers/generation/__init__.py | 2 ++ src/transformers/generation/logits_process.py | 11 ++++------- tests/generation/test_logits_process.py | 10 +++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/transformers/generation/__init__.py b/src/transformers/generation/__init__.py index 4fb3d32213f8..ab0227548c96 100644 --- a/src/transformers/generation/__init__.py +++ b/src/transformers/generation/__init__.py @@ -69,6 +69,7 @@ "MinLengthLogitsProcessor", "MinNewTokensLengthLogitsProcessor", "MinPLogitsWarper", + "TopHLogitsWarper", "NoBadWordsLogitsProcessor", "NoRepeatNGramLogitsProcessor", "PrefixConstrainedLogitsProcessor", @@ -232,6 +233,7 @@ MinLengthLogitsProcessor, MinNewTokensLengthLogitsProcessor, MinPLogitsWarper, + TopHLogitsWarper, NoBadWordsLogitsProcessor, NoRepeatNGramLogitsProcessor, PrefixConstrainedLogitsProcessor, diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 01fe3021c388..03d48bb24c4a 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -595,8 +595,6 @@ class TopHLogitsWarper(LogitsProcessor): top_n (`int`, *optional*, defaults to 100): The maximum number of tokens to consider for filtering. Only the top `top_n` tokens (by probability) are evaluated. - temperature (`float`, *optional*, defaults to 1.0): - Softmax temperature. Higher values increase randomness, while lower values make predictions sharper. alpha (`float`, *optional*, defaults to 0.4): Scaling coefficient for the entropy-based threshold (`tau`). Must be in the range `(0, 1]`. filter_value (`float`, *optional*, defaults to -inf): @@ -619,17 +617,14 @@ class TopHLogitsWarper(LogitsProcessor): """ - def __init__(self, top_h: float, temperature: float = 1.0, filter_value: float = -float("Inf")): + def __init__(self, top_h: float, filter_value: float = -float("Inf")): super().__init__() # input checks - if temperature == 0: - raise ValueError("Temperature must be non-zero to perform Top-H decoding.") if not (0 < top_h <= 1): raise ValueError("alpha must be in the range (0, 1].") self.top_n = 100 - self.temperature = temperature self.coef = top_h self.filter_value = filter_value @@ -670,7 +665,7 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to device = scores.device # compute probabilities - scaled_logits = scores / self.temperature + scaled_logits = scores probs = torch.softmax(scaled_logits, dim=-1) keep_mask = torch.zeros((batch_size, vocab_size), dtype=torch.bool, device=device) @@ -693,6 +688,8 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to for idx, p in zip(top_idx, top_probs): chosen.append(idx) ind += 1 + if ind == len(top_probs): + break # update running sums for current prefix sigma = sigma + top_probs[ind] H = H + (-top_probs[ind] * torch.log2(top_probs[ind])) diff --git a/tests/generation/test_logits_process.py b/tests/generation/test_logits_process.py index 483cfa8a99e7..763879003775 100644 --- a/tests/generation/test_logits_process.py +++ b/tests/generation/test_logits_process.py @@ -394,7 +394,7 @@ def test_top_p_dist_warper(self): # first batch should keep three tokens, second batch would keep only 1, but due to `min_tokens_to_keep=2` keeps 2. self.assertListEqual((filtered_dist != 0.0).to(torch.long).sum(dim=-1).tolist(), [3, 2]) - def test_top_h_dist_warper(): + def test_top_h_dist_warper(self): """ We construct small distributions where the expected kept set is obvious for a given alpha. We pass *log-probabilities* as "scores" so that softmax(scores) == original probabilities, @@ -411,7 +411,7 @@ def test_top_h_dist_warper(): dtype=torch.float, ) ) - top_h_warp = TopHLogitsWarper(alpha=0.3, min_tokens_to_keep=1) + top_h_warp = TopHLogitsWarper(top_h=0.3) filtered_logits = top_h_warp(input_ids, dist1.clone()) filtered_dist = torch.exp(filtered_logits) # exp(-inf) -> 0 @@ -430,7 +430,7 @@ def test_top_h_dist_warper(): dtype=torch.float, ) ) - top_h_warp = TopHLogitsWarper(alpha=0.7, min_tokens_to_keep=1) + top_h_warp = TopHLogitsWarper(top_h=0.7) filtered_logits = top_h_warp(input_ids, dist2.clone()) filtered_dist = torch.exp(filtered_logits) @@ -449,7 +449,7 @@ def test_top_h_dist_warper(): dtype=torch.float, ) ) - top_h_warp = TopHLogitsWarper(alpha=1.0, min_tokens_to_keep=1) + top_h_warp = TopHLogitsWarper(top_h=1.0) filtered_logits = top_h_warp(input_ids, dist3.clone()) filtered_dist = torch.exp(filtered_logits) @@ -461,7 +461,7 @@ def test_top_h_dist_warper(): torch.testing.assert_close(filtered_dist, EXPECTED3, rtol=1e-3, atol=1e-3) # Processor should not change logits in-place - top_h_warp = TopHLogitsWarper(alpha=0.5, min_tokens_to_keep=1) + top_h_warp = TopHLogitsWarper(top_h=0.5) out_again = top_h_warp(input_ids, dist3) assert not torch.all(out_again == dist3) From 9902115ea0e7f0913a510d491ce6e243512f1f18 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 14:21:34 -0700 Subject: [PATCH 003/204] Update TopH logits_process.py --- src/transformers/generation/logits_process.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 03d48bb24c4a..67d3a6580641 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -605,12 +605,12 @@ class TopHLogitsWarper(LogitsProcessor): ```python >>> from transformers import AutoTokenizer, AutoModelForCausalLM - >>> model = AutoModelForCausalLM.from_pretrained("distilgpt2") - >>> tokenizer = AutoTokenizer.from_pretrained("distilgpt2") + >>> model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B") + >>> tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B") >>> inputs = tokenizer("A sequence: 1, 2", return_tensors="pt") - >>> outputs = model.generate(**inputs, do_sample=True, top_h=0.1) + >>> outputs = model.generate(**inputs, do_sample=True, top_h=0.4) >>> print(tokenizer.batch_decode(outputs, skip_special_tokens=True)[0]) A sequence: 1, 2, 3, 4, 5, 6, 7, 8, 9 ``` From 519d675e901ea3cc8577998a9af0d10a29a2f238 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 15:28:11 -0700 Subject: [PATCH 004/204] Update logits_process.py --- src/transformers/generation/logits_process.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 67d3a6580641..b38030146c3f 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -641,7 +641,7 @@ def calculate_entropy(probs): Return: `torch.FloatTensor`: Scalar entropy value. """ - + probs = probs [probs > 0] probs = probs/torch.sum(probs) return -torch.sum(probs * torch.log2(probs)) From d56a2617a35fc3c9df5d774c0835a8dacb5ad5d5 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 15:38:26 -0700 Subject: [PATCH 005/204] Update test_logits_process.py --- tests/generation/test_logits_process.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/generation/test_logits_process.py b/tests/generation/test_logits_process.py index 763879003775..dafacbc735a4 100644 --- a/tests/generation/test_logits_process.py +++ b/tests/generation/test_logits_process.py @@ -460,6 +460,25 @@ def test_top_h_dist_warper(self): ) torch.testing.assert_close(filtered_dist, EXPECTED3, rtol=1e-3, atol=1e-3) + # --- Case 4: Probabilities including 0 value + dist4 = torch.log( + torch.tensor( + [[0.75, 0.25, 0.0, 0.0]], + device=torch_device, + dtype=torch.float, + ) + ) + top_h_warp = TopHLogitsWarper(top_h=0.4) + filtered_logits = top_h_warp(input_ids, dist3.clone()) + filtered_dist = torch.exp(filtered_logits) + + EXPECTED4 = torch.tensor( + [[1.0, 0.0, 0.0, 0.0]], + device=torch_device, + dtype=torch.float, + ) + torch.testing.assert_close(filtered_dist, EXPECTED4, rtol=1e-3, atol=1e-3) + # Processor should not change logits in-place top_h_warp = TopHLogitsWarper(top_h=0.5) out_again = top_h_warp(input_ids, dist3) From cd3086988740b3f2eb5fee344bad34593706247b Mon Sep 17 00:00:00 2001 From: ArminAzizi98 <147081650+ArminAzizi98@users.noreply.github.com> Date: Thu, 11 Sep 2025 16:24:30 -0700 Subject: [PATCH 006/204] Update test_logits_process.py --- tests/generation/test_logits_process.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/generation/test_logits_process.py b/tests/generation/test_logits_process.py index dafacbc735a4..fb125320a3a7 100644 --- a/tests/generation/test_logits_process.py +++ b/tests/generation/test_logits_process.py @@ -473,7 +473,7 @@ def test_top_h_dist_warper(self): filtered_dist = torch.exp(filtered_logits) EXPECTED4 = torch.tensor( - [[1.0, 0.0, 0.0, 0.0]], + [[0.75, 0.0, 0.0, 0.0]], device=torch_device, dtype=torch.float, ) From c7c147223e805bc73112e1388af1f032d35242b7 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 18:18:58 -0700 Subject: [PATCH 007/204] added test No. 4 --- tests/generation/test_logits_process.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/generation/test_logits_process.py b/tests/generation/test_logits_process.py index fb125320a3a7..5c73db1dc14b 100644 --- a/tests/generation/test_logits_process.py +++ b/tests/generation/test_logits_process.py @@ -469,7 +469,7 @@ def test_top_h_dist_warper(self): ) ) top_h_warp = TopHLogitsWarper(top_h=0.4) - filtered_logits = top_h_warp(input_ids, dist3.clone()) + filtered_logits = top_h_warp(input_ids, dist4.clone()) filtered_dist = torch.exp(filtered_logits) EXPECTED4 = torch.tensor( From 91bc1b7e3a80dca32152992122c941e99030dd7d Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 20:27:52 -0700 Subject: [PATCH 008/204] Resolving __init__.py issues --- src/transformers/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformers/__init__.py b/src/transformers/__init__.py index 3fe187ab9c5e..98c3801bee79 100755 --- a/src/transformers/__init__.py +++ b/src/transformers/__init__.py @@ -436,7 +436,6 @@ "MinLengthLogitsProcessor", "MinNewTokensLengthLogitsProcessor", "MinPLogitsWarper", - "TopHLogitsWarper", "NoBadWordsLogitsProcessor", "NoRepeatNGramLogitsProcessor", "PhrasalConstraint", @@ -452,6 +451,7 @@ "SynthIDTextWatermarkingConfig", "SynthIDTextWatermarkLogitsProcessor", "TemperatureLogitsWarper", + "TopHLogitsWarper", "TopKLogitsWarper", "TopPLogitsWarper", "TypicalLogitsWarper", @@ -698,7 +698,6 @@ from .generation import MinLengthLogitsProcessor as MinLengthLogitsProcessor from .generation import MinNewTokensLengthLogitsProcessor as MinNewTokensLengthLogitsProcessor from .generation import MinPLogitsWarper as MinPLogitsWarper - from .generation import TopHLogitsWarper as TopHLogitsWarper from .generation import NoBadWordsLogitsProcessor as NoBadWordsLogitsProcessor from .generation import NoRepeatNGramLogitsProcessor as NoRepeatNGramLogitsProcessor from .generation import PhrasalConstraint as PhrasalConstraint @@ -732,6 +731,7 @@ from .generation import TFTemperatureLogitsWarper as TFTemperatureLogitsWarper from .generation import TFTopKLogitsWarper as TFTopKLogitsWarper from .generation import TFTopPLogitsWarper as TFTopPLogitsWarper + from .generation import TopHLogitsWarper as TopHLogitsWarper from .generation import TopKLogitsWarper as TopKLogitsWarper from .generation import TopPLogitsWarper as TopPLogitsWarper from .generation import TypicalLogitsWarper as TypicalLogitsWarper From 009aa73170c2f94ec58dfe62bc7aa37ea4352394 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 20:35:55 -0700 Subject: [PATCH 009/204] Resolving configuration_utils.py Issues --- src/transformers/generation/configuration_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformers/generation/configuration_utils.py b/src/transformers/generation/configuration_utils.py index 1c499f61a821..30b1c328ce49 100644 --- a/src/transformers/generation/configuration_utils.py +++ b/src/transformers/generation/configuration_utils.py @@ -172,7 +172,7 @@ class GenerationConfig(PushToHubMixin): Must be a value between 0 and 1. At each step, tokens are sorted by probability, and the smallest prefix of tokens is kept whose *renormalized* entropy is less than or equal to `top_h` times the entropy of the full distribution. Smaller values (e.g., 0.2–0.5) lead to more focused, deterministic outputs, while values closer to 1.0 allow more - randomness and diversity. Typical values are in the 0.3–0.6 range. + randomness and diversity. Typical values are in the 0.3–0.6 range. typical_p (`float`, *optional*, defaults to 1.0): Local typicality measures how similar the conditional probability of predicting a target token next is to the expected conditional probability of predicting a random token next, given the partial text already @@ -589,7 +589,7 @@ def validate(self, strict=False): if self.min_p is not None: minor_issues["min_p"] = greedy_wrong_parameter_msg.format(flag_name="min_p", flag_value=self.min_p) if self.top_h is not None: - minor_issues["top_h"] = greedy_wrong_parameter_msg.format(flag_name="top_h", flag_value=self.top_h) + minor_issues["top_h"] = greedy_wrong_parameter_msg.format(flag_name="top_h", flag_value=self.top_h) if self.typical_p is not None and self.typical_p != 1.0: minor_issues["typical_p"] = greedy_wrong_parameter_msg.format( flag_name="typical_p", flag_value=self.typical_p From 872bd47497e5b1890162da26df153d9f4ceabe10 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 20:39:00 -0700 Subject: [PATCH 010/204] Resolving logits_process.py Issues --- src/transformers/generation/logits_process.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index b38030146c3f..5ec24efae32a 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -593,7 +593,7 @@ class TopHLogitsWarper(LogitsProcessor): Args: top_n (`int`, *optional*, defaults to 100): - The maximum number of tokens to consider for filtering. + The maximum number of tokens to consider for filtering. Only the top `top_n` tokens (by probability) are evaluated. alpha (`float`, *optional*, defaults to 0.4): Scaling coefficient for the entropy-based threshold (`tau`). Must be in the range `(0, 1]`. @@ -623,7 +623,6 @@ def __init__(self, top_h: float, filter_value: float = -float("Inf")): # input checks if not (0 < top_h <= 1): raise ValueError("alpha must be in the range (0, 1].") - self.top_n = 100 self.coef = top_h self.filter_value = filter_value @@ -642,11 +641,10 @@ def calculate_entropy(probs): `torch.FloatTensor`: Scalar entropy value. """ probs = probs [probs > 0] - probs = probs/torch.sum(probs) + probs = probs/torch.sum(probs) return -torch.sum(probs * torch.log2(probs)) - def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor: - + def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor: """ Filters logits using Top-H sampling. @@ -660,13 +658,12 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to `torch.FloatTensor` of shape `(batch_size, vocab_size)`: Processed logits where invalid tokens are masked with `-inf`. """ - batch_size, vocab_size = scores.shape device = scores.device # compute probabilities scaled_logits = scores - probs = torch.softmax(scaled_logits, dim=-1) + probs = torch.softmax(scaled_logits, dim=-1) keep_mask = torch.zeros((batch_size, vocab_size), dtype=torch.bool, device=device) @@ -703,7 +700,6 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to # apply filtering scores_processed = scores.clone() scores_processed[~keep_mask] = self.filter_value - return scores_processed class MinPLogitsWarper(LogitsProcessor): From 2054fb6e48385aa4ff914a519d9e9388db25d021 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 20:41:09 -0700 Subject: [PATCH 011/204] Resolving utils.py Issues --- src/transformers/generation/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index dd7d21896f91..ab4bad636e17 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -85,7 +85,6 @@ MinLengthLogitsProcessor, MinNewTokensLengthLogitsProcessor, MinPLogitsWarper, - TopHLogitsWarper, NoBadWordsLogitsProcessor, NoRepeatNGramLogitsProcessor, PrefixConstrainedLogitsProcessor, @@ -94,6 +93,7 @@ SuppressTokensAtBeginLogitsProcessor, SuppressTokensLogitsProcessor, TemperatureLogitsWarper, + TopHLogitsWarper, TopKLogitsWarper, TopPLogitsWarper, TypicalLogitsWarper, From 5bc900df77ab4785692068206c7610da078a485b Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 20:43:14 -0700 Subject: [PATCH 012/204] Resolving test_logits_process.py Issues --- tests/generation/test_logits_process.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/generation/test_logits_process.py b/tests/generation/test_logits_process.py index 5c73db1dc14b..2863e8a1ad6d 100644 --- a/tests/generation/test_logits_process.py +++ b/tests/generation/test_logits_process.py @@ -42,7 +42,6 @@ MinLengthLogitsProcessor, MinNewTokensLengthLogitsProcessor, MinPLogitsWarper, - TopHLogitsWarper, NoBadWordsLogitsProcessor, NoRepeatNGramLogitsProcessor, PrefixConstrainedLogitsProcessor, @@ -50,6 +49,7 @@ SequenceBiasLogitsProcessor, SynthIDTextWatermarkLogitsProcessor, TemperatureLogitsWarper, + TopHLogitsWarper, TopKLogitsWarper, TopPLogitsWarper, TypicalLogitsWarper, @@ -478,7 +478,6 @@ def test_top_h_dist_warper(self): dtype=torch.float, ) torch.testing.assert_close(filtered_dist, EXPECTED4, rtol=1e-3, atol=1e-3) - # Processor should not change logits in-place top_h_warp = TopHLogitsWarper(top_h=0.5) out_again = top_h_warp(input_ids, dist3) From 768bda624865ced63a1ee45beee786c2e4b68de4 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 20:47:36 -0700 Subject: [PATCH 013/204] Resolving __init__.py issues --- src/transformers/generation/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/generation/__init__.py b/src/transformers/generation/__init__.py index ab0227548c96..a75cf1379466 100644 --- a/src/transformers/generation/__init__.py +++ b/src/transformers/generation/__init__.py @@ -69,7 +69,6 @@ "MinLengthLogitsProcessor", "MinNewTokensLengthLogitsProcessor", "MinPLogitsWarper", - "TopHLogitsWarper", "NoBadWordsLogitsProcessor", "NoRepeatNGramLogitsProcessor", "PrefixConstrainedLogitsProcessor", @@ -79,6 +78,7 @@ "SuppressTokensAtBeginLogitsProcessor", "SynthIDTextWatermarkLogitsProcessor", "TemperatureLogitsWarper", + "TopHLogitsWarper", "TopKLogitsWarper", "TopPLogitsWarper", "TypicalLogitsWarper", From d843f1c15264da1079589b7d8662104b336d708f Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 20:48:31 -0700 Subject: [PATCH 014/204] Resolving logits_process.py Issues --- src/transformers/generation/logits_process.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 5ec24efae32a..c16e98e769ed 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -644,7 +644,7 @@ def calculate_entropy(probs): probs = probs/torch.sum(probs) return -torch.sum(probs * torch.log2(probs)) - def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor: + def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor: """ Filters logits using Top-H sampling. From 290f97dc796dda6c1513880a506a9ca99275e714 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 20:50:47 -0700 Subject: [PATCH 015/204] Resolving __init__.py issues --- src/transformers/generation/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/generation/__init__.py b/src/transformers/generation/__init__.py index a75cf1379466..8500dc6ea80e 100644 --- a/src/transformers/generation/__init__.py +++ b/src/transformers/generation/__init__.py @@ -233,7 +233,6 @@ MinLengthLogitsProcessor, MinNewTokensLengthLogitsProcessor, MinPLogitsWarper, - TopHLogitsWarper, NoBadWordsLogitsProcessor, NoRepeatNGramLogitsProcessor, PrefixConstrainedLogitsProcessor, @@ -243,6 +242,7 @@ SuppressTokensLogitsProcessor, SynthIDTextWatermarkLogitsProcessor, TemperatureLogitsWarper, + TopHLogitsWarper, TopKLogitsWarper, TopPLogitsWarper, TypicalLogitsWarper, From 2b785ade3e699ef13b02b134f50b4370e41acb7f Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 21:13:02 -0700 Subject: [PATCH 016/204] Updated Docs --- docs/source/en/internal/generation_utils.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/source/en/internal/generation_utils.md b/docs/source/en/internal/generation_utils.md index 9deb926b905f..d267741a2c33 100644 --- a/docs/source/en/internal/generation_utils.md +++ b/docs/source/en/internal/generation_utils.md @@ -156,6 +156,9 @@ generation. [[autodoc]] TemperatureLogitsWarper - __call__ +[[autodoc]] TopHLogitsWarper + - __call__ + [[autodoc]] TopKLogitsWarper - __call__ From f35b6ce7a5fbf4d4edecc03e60fdacc630a9a6e8 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 21:56:06 -0700 Subject: [PATCH 017/204] Updated Docstring --- src/transformers/generation/logits_process.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index c16e98e769ed..a8163901e086 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -592,10 +592,7 @@ class TopHLogitsWarper(LogitsProcessor): diversity and coherence. Args: - top_n (`int`, *optional*, defaults to 100): - The maximum number of tokens to consider for filtering. - Only the top `top_n` tokens (by probability) are evaluated. - alpha (`float`, *optional*, defaults to 0.4): + top_h (`float`, *optional*, defaults to 0.4): Scaling coefficient for the entropy-based threshold (`tau`). Must be in the range `(0, 1]`. filter_value (`float`, *optional*, defaults to -inf): All filtered values will be set to this float value. From a566561ea4844dd7e105cf5162c28ac5700e4664 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 22:03:08 -0700 Subject: [PATCH 018/204] style: autoformat with make fixup --- src/transformers/generation/logits_process.py | 11 +++++------ src/transformers/generation/utils.py | 4 +--- tests/generation/test_logits_process.py | 1 + 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index a8163901e086..ec1ec110c6e3 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -581,8 +581,8 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to scores_processed = scores.masked_fill(indices_to_remove, self.filter_value) return scores_processed -class TopHLogitsWarper(LogitsProcessor): +class TopHLogitsWarper(LogitsProcessor): """ [`LogitsProcessor`] that implements Top-H sampling, a decoding method which adaptively selects a subset of high-probability tokens based on entropy and cumulative probability constraints. @@ -613,7 +613,6 @@ class TopHLogitsWarper(LogitsProcessor): ``` """ - def __init__(self, top_h: float, filter_value: float = -float("Inf")): super().__init__() @@ -626,7 +625,6 @@ def __init__(self, top_h: float, filter_value: float = -float("Inf")): @staticmethod def calculate_entropy(probs): - """ Computes Shannon entropy of a probability distribution. @@ -637,8 +635,8 @@ def calculate_entropy(probs): Return: `torch.FloatTensor`: Scalar entropy value. """ - probs = probs [probs > 0] - probs = probs/torch.sum(probs) + probs = probs[probs > 0] + probs = probs / torch.sum(probs) return -torch.sum(probs * torch.log2(probs)) def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor: @@ -676,7 +674,7 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to # grow the kept set until the stopping rule triggers sigma = top_probs[0] - H = - top_probs[0] * torch.log2(top_probs[0]) + H = -top_probs[0] * torch.log2(top_probs[0]) chosen = [] ind = 0 for idx, p in zip(top_idx, top_probs): @@ -699,6 +697,7 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to scores_processed[~keep_mask] = self.filter_value return scores_processed + class MinPLogitsWarper(LogitsProcessor): """ [`LogitsProcessor`] that performs min-p, i.e. keeps all tokens that are above a minimum probability, scaled by the diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index ab4bad636e17..cff4a6a4ed73 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -1282,9 +1282,7 @@ def _get_logits_processor( MinPLogitsWarper(min_p=generation_config.min_p, min_tokens_to_keep=min_tokens_to_keep) ) if generation_config.top_h is not None: - processors.append( - TopHLogitsWarper(top_h=generation_config.top_h) - ) + processors.append(TopHLogitsWarper(top_h=generation_config.top_h)) if generation_config.typical_p is not None and generation_config.typical_p < 1.0: processors.append( TypicalLogitsWarper(mass=generation_config.typical_p, min_tokens_to_keep=min_tokens_to_keep) diff --git a/tests/generation/test_logits_process.py b/tests/generation/test_logits_process.py index 2863e8a1ad6d..06531b52f5a5 100644 --- a/tests/generation/test_logits_process.py +++ b/tests/generation/test_logits_process.py @@ -394,6 +394,7 @@ def test_top_p_dist_warper(self): # first batch should keep three tokens, second batch would keep only 1, but due to `min_tokens_to_keep=2` keeps 2. self.assertListEqual((filtered_dist != 0.0).to(torch.long).sum(dim=-1).tolist(), [3, 2]) + def test_top_h_dist_warper(self): """ We construct small distributions where the expected kept set is obvious for a given alpha. From 49a611d2ebea2d20173f4cfcc8688c8036dc267c Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 22:32:45 -0700 Subject: [PATCH 019/204] Fixing Docstring --- src/transformers/generation/logits_process.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index ec1ec110c6e3..6de20c61e8c8 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -613,7 +613,7 @@ class TopHLogitsWarper(LogitsProcessor): ``` """ - def __init__(self, top_h: float, filter_value: float = -float("Inf")): + def __init__(self, top_h: float = 0.4, filter_value: float = -float("Inf")): super().__init__() # input checks From 3fb3a87b889c8a367c9a96306e49d894814d491a Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Mon, 15 Sep 2025 19:27:38 -0700 Subject: [PATCH 020/204] Update logits_process.py removed defaults --- src/transformers/generation/logits_process.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 6de20c61e8c8..e109f13ffee3 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -592,7 +592,7 @@ class TopHLogitsWarper(LogitsProcessor): diversity and coherence. Args: - top_h (`float`, *optional*, defaults to 0.4): + top_h (`float`): Scaling coefficient for the entropy-based threshold (`tau`). Must be in the range `(0, 1]`. filter_value (`float`, *optional*, defaults to -inf): All filtered values will be set to this float value. @@ -613,14 +613,14 @@ class TopHLogitsWarper(LogitsProcessor): ``` """ - def __init__(self, top_h: float = 0.4, filter_value: float = -float("Inf")): + def __init__(self, top_h: float, filter_value: float = -float("Inf")): super().__init__() # input checks if not (0 < top_h <= 1): - raise ValueError("alpha must be in the range (0, 1].") + raise ValueError("`top_h` must be in the range (0, 1].") self.top_n = 100 - self.coef = top_h + self.top_h = top_h self.filter_value = filter_value @staticmethod @@ -670,7 +670,7 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to # entropy-based threshold tau (computed on the top-k distribution) alpha_sum = top_probs.sum() - tau = (self.calculate_entropy(top_probs) - torch.log2(alpha_sum)) * alpha_sum * self.coef + tau = (self.calculate_entropy(top_probs) - torch.log2(alpha_sum)) * alpha_sum * self.top_h # grow the kept set until the stopping rule triggers sigma = top_probs[0] From 49175726b0bff55b35f82bd06aa35bfe5f3aa525 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Sun, 21 Sep 2025 18:45:44 -0700 Subject: [PATCH 021/204] Variable H name -> cumulative_entropy --- src/transformers/generation/logits_process.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index e109f13ffee3..29c09e4da51d 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -593,7 +593,7 @@ class TopHLogitsWarper(LogitsProcessor): Args: top_h (`float`): - Scaling coefficient for the entropy-based threshold (`tau`). Must be in the range `(0, 1]`. + Scaling coefficient for the entropy-based threshold. Must be in the range `(0, 1]`. filter_value (`float`, *optional*, defaults to -inf): All filtered values will be set to this float value. @@ -674,7 +674,7 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to # grow the kept set until the stopping rule triggers sigma = top_probs[0] - H = -top_probs[0] * torch.log2(top_probs[0]) + cumulative_entropy = -top_probs[0] * torch.log2(top_probs[0]) chosen = [] ind = 0 for idx, p in zip(top_idx, top_probs): @@ -684,9 +684,9 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to break # update running sums for current prefix sigma = sigma + top_probs[ind] - H = H + (-top_probs[ind] * torch.log2(top_probs[ind])) + cumulative_entropy = cumulative_entropy + (-top_probs[ind] * torch.log2(top_probs[ind])) # entropy difference term - entropy_diff = (H / sigma) + torch.log2(sigma) + entropy_diff = (cumulative_entropy / sigma) + torch.log2(sigma) if entropy_diff > (tau / sigma + torch.log2(sigma)): break From 11ef0a2dcb5303cb7015d912e7602b3e2eef07ba Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Wed, 24 Sep 2025 22:55:52 -0700 Subject: [PATCH 022/204] Using torch.distributions.Categorical --- src/transformers/generation/logits_process.py | 37 ++++--------------- src/transformers/generation/utils.py | 5 ++- 2 files changed, 10 insertions(+), 32 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 29c09e4da51d..29087cb0d6f2 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -623,22 +623,6 @@ def __init__(self, top_h: float, filter_value: float = -float("Inf")): self.top_h = top_h self.filter_value = filter_value - @staticmethod - def calculate_entropy(probs): - """ - Computes Shannon entropy of a probability distribution. - - Args: - probs (`torch.FloatTensor`): - Probability distribution over tokens. - - Return: - `torch.FloatTensor`: Scalar entropy value. - """ - probs = probs[probs > 0] - probs = probs / torch.sum(probs) - return -torch.sum(probs * torch.log2(probs)) - def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor: """ Filters logits using Top-H sampling. @@ -656,25 +640,20 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to batch_size, vocab_size = scores.shape device = scores.device - # compute probabilities - scaled_logits = scores - probs = torch.softmax(scaled_logits, dim=-1) - keep_mask = torch.zeros((batch_size, vocab_size), dtype=torch.bool, device=device) top_n = min(self.top_n, vocab_size) for b in range(batch_size): # top-k for this example - top_probs, top_idx = torch.topk(probs[b], top_n, largest=True, sorted=True) + top_probs, top_idx = torch.topk(scores[b], top_n, largest=True, sorted=True) + distribution = torch.distributions.Categorical(logits=top_probs) # entropy-based threshold tau (computed on the top-k distribution) - alpha_sum = top_probs.sum() - tau = (self.calculate_entropy(top_probs) - torch.log2(alpha_sum)) * alpha_sum * self.top_h + tau = distribution.entropy() * self.top_h # grow the kept set until the stopping rule triggers - sigma = top_probs[0] - cumulative_entropy = -top_probs[0] * torch.log2(top_probs[0]) + cumulative_entropy = - distribution.probs[torch.tensor([0], device=top_probs.device)] * distribution.log_prob(torch.tensor([0], device=top_probs.device)) # -top_probs[0] * torch.log2(top_probs[0]) chosen = [] ind = 0 for idx, p in zip(top_idx, top_probs): @@ -683,13 +662,11 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to if ind == len(top_probs): break # update running sums for current prefix - sigma = sigma + top_probs[ind] - cumulative_entropy = cumulative_entropy + (-top_probs[ind] * torch.log2(top_probs[ind])) + cumulative_entropy = cumulative_entropy - distribution.probs[torch.tensor([ind], device=top_probs.device)] * distribution.log_prob(torch.tensor([ind], device=top_probs.device)) + # entropy difference term - entropy_diff = (cumulative_entropy / sigma) + torch.log2(sigma) - if entropy_diff > (tau / sigma + torch.log2(sigma)): + if cumulative_entropy > tau: break - keep_mask[b, torch.stack(chosen)] = True # apply filtering diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index cff4a6a4ed73..20be80822fdb 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -1268,6 +1268,8 @@ def _get_logits_processor( # all samplers can be found in `generation_utils_samplers.py` if generation_config.temperature is not None and generation_config.temperature != 1.0: processors.append(TemperatureLogitsWarper(generation_config.temperature)) + if generation_config.top_h is not None: + processors.append(TopHLogitsWarper(top_h=generation_config.top_h)) if generation_config.top_k is not None and generation_config.top_k != 0: processors.append( TopKLogitsWarper(top_k=generation_config.top_k, min_tokens_to_keep=min_tokens_to_keep) @@ -1281,8 +1283,7 @@ def _get_logits_processor( processors.append( MinPLogitsWarper(min_p=generation_config.min_p, min_tokens_to_keep=min_tokens_to_keep) ) - if generation_config.top_h is not None: - processors.append(TopHLogitsWarper(top_h=generation_config.top_h)) + if generation_config.typical_p is not None and generation_config.typical_p < 1.0: processors.append( TypicalLogitsWarper(mass=generation_config.typical_p, min_tokens_to_keep=min_tokens_to_keep) From 90a3d940b999050b0e0a08b2670fa5ec485df98e Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Fri, 12 Sep 2025 17:57:59 +0800 Subject: [PATCH 023/204] Improve torch_dtype checks (#40808) * Improve torch_dtype checks Signed-off-by: Yuanyuan Chen * Apply suggestions from code review --------- Signed-off-by: Yuanyuan Chen Co-authored-by: Joao Gante --- src/transformers/commands/chat.py | 10 ++++++++-- src/transformers/commands/serving.py | 10 ++++++++-- src/transformers/pipelines/keypoint_matching.py | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/transformers/commands/chat.py b/src/transformers/commands/chat.py index 7d73fa80c138..70ee41c0c514 100644 --- a/src/transformers/commands/chat.py +++ b/src/transformers/commands/chat.py @@ -289,8 +289,14 @@ class ChatArguments: def __post_init__(self): """Only used for BC `torch_dtype` argument.""" # In this case only the BC torch_dtype was given - if self.torch_dtype is not None and self.dtype == "auto": - self.dtype = self.torch_dtype + if self.torch_dtype is not None: + if self.dtype is None: + self.dtype = self.torch_dtype + elif self.torch_dtype != self.dtype: + raise ValueError( + f"`torch_dtype` {self.torch_dtype} and `dtype` {self.dtype} have different values. `torch_dtype` is deprecated and " + "will be removed in 4.59.0, please set `dtype` instead." + ) def chat_command_factory(args: Namespace): diff --git a/src/transformers/commands/serving.py b/src/transformers/commands/serving.py index 6c5bbed3cfa4..33a48aed7e64 100644 --- a/src/transformers/commands/serving.py +++ b/src/transformers/commands/serving.py @@ -457,8 +457,14 @@ class ServeArguments: def __post_init__(self): """Only used for BC `torch_dtype` argument.""" # In this case only the BC torch_dtype was given - if self.torch_dtype is not None and self.dtype == "auto": - self.dtype = self.torch_dtype + if self.torch_dtype is not None: + if self.dtype is None: + self.dtype = self.torch_dtype + elif self.torch_dtype != self.dtype: + raise ValueError( + f"`torch_dtype` {self.torch_dtype} and `dtype` {self.dtype} have different values. `torch_dtype` is deprecated and " + "will be removed in 4.59.0, please set `dtype` instead." + ) class ServeCommand(BaseTransformersCLICommand): diff --git a/src/transformers/pipelines/keypoint_matching.py b/src/transformers/pipelines/keypoint_matching.py index 11afd3d4326c..6878f40ad985 100644 --- a/src/transformers/pipelines/keypoint_matching.py +++ b/src/transformers/pipelines/keypoint_matching.py @@ -147,7 +147,7 @@ def __call__( def preprocess(self, images, timeout=None): images = [load_image(image, timeout=timeout) for image in images] model_inputs = self.image_processor(images=images, return_tensors=self.framework) - model_inputs = model_inputs.to(self.torch_dtype) + model_inputs = model_inputs.to(self.dtype) target_sizes = [image.size for image in images] preprocess_outputs = {"model_inputs": model_inputs, "target_sizes": target_sizes} return preprocess_outputs From 2db9152e97a76ad96289c3efbf9cdb12a2b8051b Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Fri, 12 Sep 2025 12:21:12 +0200 Subject: [PATCH 024/204] Add VideoProcessors to auto-backend requirements (#40843) * add it * fix existing ones * add perception to auto_mapping... --- .../models/auto/video_processing_auto.py | 1 + .../models/glm4v/video_processing_glm4v.py | 31 +++----------- .../video_processing_instructblipvideo.py | 34 ++++----------- .../internvl/video_processing_internvl.py | 34 ++++----------- .../video_processing_llava_next_video.py | 16 +------ .../video_processing_llava_onevision.py | 16 +------ .../video_processing_perception_lm.py | 16 +------ .../qwen2_vl/video_processing_qwen2_vl.py | 41 +++++------------- .../sam2_video/video_processing_sam2_video.py | 25 ++--------- .../smolvlm/video_processing_smolvlm.py | 42 ++++--------------- .../video_processing_video_llava.py | 16 +------ .../models/vjepa2/video_processing_vjepa2.py | 12 +----- src/transformers/utils/import_utils.py | 1 + 13 files changed, 57 insertions(+), 228 deletions(-) diff --git a/src/transformers/models/auto/video_processing_auto.py b/src/transformers/models/auto/video_processing_auto.py index 5d9b58b51a91..b9a5c2204fd1 100644 --- a/src/transformers/models/auto/video_processing_auto.py +++ b/src/transformers/models/auto/video_processing_auto.py @@ -52,6 +52,7 @@ ("internvl", "InternVLVideoProcessor"), ("llava_next_video", "LlavaNextVideoVideoProcessor"), ("llava_onevision", "LlavaOnevisionVideoProcessor"), + ("perception_lm", "PerceptionLMVideoProcessor"), ("qwen2_5_omni", "Qwen2VLVideoProcessor"), ("qwen2_5_vl", "Qwen2VLVideoProcessor"), ("qwen2_vl", "Qwen2VLVideoProcessor"), diff --git a/src/transformers/models/glm4v/video_processing_glm4v.py b/src/transformers/models/glm4v/video_processing_glm4v.py index a327ac200507..0986c414f1d3 100644 --- a/src/transformers/models/glm4v/video_processing_glm4v.py +++ b/src/transformers/models/glm4v/video_processing_glm4v.py @@ -18,40 +18,22 @@ from typing import Optional, Union import numpy as np +import torch -from ...image_processing_utils import ( - BatchFeature, -) +from ...image_processing_utils import BatchFeature from ...image_utils import ( OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, ChannelDimension, + PILImageResampling, SizeDict, get_image_size, ) from ...processing_utils import Unpack, VideosKwargs -from ...utils import ( - TensorType, - add_start_docstrings, - is_torch_available, - is_vision_available, -) -from .image_processing_glm4v import smart_resize - - -if is_torch_available(): - import torch - -from ...utils.import_utils import requires -from ...video_processing_utils import ( - BASE_VIDEO_PROCESSOR_DOCSTRING, - BaseVideoProcessor, -) +from ...utils import TensorType, add_start_docstrings +from ...video_processing_utils import BASE_VIDEO_PROCESSOR_DOCSTRING, BaseVideoProcessor from ...video_utils import VideoMetadata, group_videos_by_shape, reorder_videos - - -if is_vision_available(): - from ...image_utils import PILImageResampling +from .image_processing_glm4v import smart_resize class Glm4vVideoProcessorInitKwargs(VideosKwargs): @@ -75,7 +57,6 @@ class Glm4vVideoProcessorInitKwargs(VideosKwargs): The merge size of the vision encoder to llm encoder. """, ) -@requires(backends=("torchvision",)) class Glm4vVideoProcessor(BaseVideoProcessor): resample = PILImageResampling.BICUBIC size = {"shortest_edge": 112 * 112, "longest_edge": 28 * 28 * 2 * 30000} diff --git a/src/transformers/models/instructblipvideo/video_processing_instructblipvideo.py b/src/transformers/models/instructblipvideo/video_processing_instructblipvideo.py index 805ecda06497..f4f482c56313 100644 --- a/src/transformers/models/instructblipvideo/video_processing_instructblipvideo.py +++ b/src/transformers/models/instructblipvideo/video_processing_instructblipvideo.py @@ -19,43 +19,25 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature -from ...image_utils import ( - OPENAI_CLIP_MEAN, - OPENAI_CLIP_STD, - SizeDict, -) +from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling, SizeDict from ...processing_utils import Unpack, VideosKwargs -from ...utils import ( - TensorType, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - is_vision_available, -) -from ...utils.import_utils import requires +from ...utils import TensorType, is_torchvision_v2_available from ...video_processing_utils import BaseVideoProcessor from ...video_utils import group_videos_by_shape, reorder_videos -if is_vision_available(): - from ...image_utils import PILImageResampling - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F - - -if is_torch_available(): - import torch +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class InstructBlipVideoVideoProcessorInitKwargs(VideosKwargs): ... -@requires(backends=("torchvision",)) class InstructBlipVideoVideoProcessor(BaseVideoProcessor): resample = PILImageResampling.BICUBIC image_mean = OPENAI_CLIP_MEAN diff --git a/src/transformers/models/internvl/video_processing_internvl.py b/src/transformers/models/internvl/video_processing_internvl.py index 2fc5729119e9..3c0ee8de1bef 100644 --- a/src/transformers/models/internvl/video_processing_internvl.py +++ b/src/transformers/models/internvl/video_processing_internvl.py @@ -16,44 +16,26 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature -from ...image_utils import ( - OPENAI_CLIP_MEAN, - OPENAI_CLIP_STD, - SizeDict, -) +from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling, SizeDict from ...processing_utils import Unpack, VideosKwargs -from ...utils import ( - TensorType, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - is_vision_available, -) -from ...utils.import_utils import requires +from ...utils import TensorType, is_torchvision_v2_available from ...video_processing_utils import BaseVideoProcessor from ...video_utils import VideoMetadata, group_videos_by_shape, reorder_videos -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F - - -if is_torch_available(): - import torch - -if is_vision_available(): - from ...image_utils import PILImageResampling +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class InternVLVideoProcessorInitKwargs(VideosKwargs): initial_shift: Union[bool, float, int] -@requires(backends=("torchvision",)) class InternVLVideoProcessor(BaseVideoProcessor): resample = PILImageResampling.BICUBIC image_mean = OPENAI_CLIP_MEAN diff --git a/src/transformers/models/llava_next_video/video_processing_llava_next_video.py b/src/transformers/models/llava_next_video/video_processing_llava_next_video.py index 95cd79da6551..80ed1e5b81b9 100644 --- a/src/transformers/models/llava_next_video/video_processing_llava_next_video.py +++ b/src/transformers/models/llava_next_video/video_processing_llava_next_video.py @@ -14,26 +14,14 @@ # limitations under the License. """Video processor class for LLaVa-NeXT-Video.""" -from ...image_utils import ( - OPENAI_CLIP_MEAN, - OPENAI_CLIP_STD, -) +from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling from ...processing_utils import Unpack, VideosKwargs -from ...utils import is_vision_available -from ...utils.import_utils import requires -from ...video_processing_utils import ( - BaseVideoProcessor, -) - - -if is_vision_available(): - from ...image_utils import PILImageResampling +from ...video_processing_utils import BaseVideoProcessor class LlavaNextVideoFastVideoProcessorInitKwargs(VideosKwargs): ... -@requires(backends=("torchvision",)) class LlavaNextVideoVideoProcessor(BaseVideoProcessor): resample = PILImageResampling.BICUBIC image_mean = OPENAI_CLIP_MEAN diff --git a/src/transformers/models/llava_onevision/video_processing_llava_onevision.py b/src/transformers/models/llava_onevision/video_processing_llava_onevision.py index 3972f424a94f..ddae0fcd3b6f 100644 --- a/src/transformers/models/llava_onevision/video_processing_llava_onevision.py +++ b/src/transformers/models/llava_onevision/video_processing_llava_onevision.py @@ -14,26 +14,14 @@ # limitations under the License. """Video processor class for LLaVa-Onevision.""" -from ...image_utils import ( - OPENAI_CLIP_MEAN, - OPENAI_CLIP_STD, -) +from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling from ...processing_utils import Unpack, VideosKwargs -from ...utils import is_vision_available -from ...utils.import_utils import requires -from ...video_processing_utils import ( - BaseVideoProcessor, -) - - -if is_vision_available(): - from ...image_utils import PILImageResampling +from ...video_processing_utils import BaseVideoProcessor class LlavaOnevisionFastVideoProcessorInitKwargs(VideosKwargs): ... -@requires(backends=("torchvision",)) class LlavaOnevisionVideoProcessor(BaseVideoProcessor): resample = PILImageResampling.BICUBIC image_mean = OPENAI_CLIP_MEAN diff --git a/src/transformers/models/perception_lm/video_processing_perception_lm.py b/src/transformers/models/perception_lm/video_processing_perception_lm.py index 7381045c1d7c..1023aa7c589d 100644 --- a/src/transformers/models/perception_lm/video_processing_perception_lm.py +++ b/src/transformers/models/perception_lm/video_processing_perception_lm.py @@ -13,26 +13,14 @@ # limitations under the License. """Video processor class for PerceptionLM.""" -from ...image_utils import ( - IMAGENET_STANDARD_MEAN, - IMAGENET_STANDARD_STD, -) +from ...image_utils import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD, PILImageResampling from ...processing_utils import Unpack, VideosKwargs -from ...utils import is_vision_available -from ...utils.import_utils import requires -from ...video_processing_utils import ( - BaseVideoProcessor, -) - - -if is_vision_available(): - from ...image_utils import PILImageResampling +from ...video_processing_utils import BaseVideoProcessor class PerceptionLMFastVideoProcessorInitKwargs(VideosKwargs): ... -@requires(backends=("torchvision",)) class PerceptionLMVideoProcessor(BaseVideoProcessor): resample = PILImageResampling.BICUBIC image_mean = IMAGENET_STANDARD_MEAN diff --git a/src/transformers/models/qwen2_vl/video_processing_qwen2_vl.py b/src/transformers/models/qwen2_vl/video_processing_qwen2_vl.py index f73a65484219..ba87909740a8 100644 --- a/src/transformers/models/qwen2_vl/video_processing_qwen2_vl.py +++ b/src/transformers/models/qwen2_vl/video_processing_qwen2_vl.py @@ -22,46 +22,28 @@ import math from typing import Optional, Union -from ...image_processing_utils import ( - BatchFeature, -) +import torch + +from ...image_processing_utils import BatchFeature from ...image_utils import ( OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, ChannelDimension, + PILImageResampling, SizeDict, get_image_size, ) from ...processing_utils import Unpack, VideosKwargs -from ...utils import ( - TensorType, - add_start_docstrings, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - is_vision_available, -) -from ...utils.import_utils import requires -from ...video_processing_utils import ( - BASE_VIDEO_PROCESSOR_DOCSTRING, - BaseVideoProcessor, -) +from ...utils import TensorType, add_start_docstrings, is_torchvision_v2_available +from ...video_processing_utils import BASE_VIDEO_PROCESSOR_DOCSTRING, BaseVideoProcessor from ...video_utils import VideoMetadata, group_videos_by_shape, reorder_videos +from .image_processing_qwen2_vl import smart_resize -if is_vision_available(): - from ...image_utils import PILImageResampling - from .image_processing_qwen2_vl import smart_resize - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F - - -if is_torch_available(): - import torch +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class Qwen2VLVideoProcessorInitKwargs(VideosKwargs): @@ -94,7 +76,6 @@ class Qwen2VLVideoProcessorInitKwargs(VideosKwargs): The maximum number of frames that can be sampled. """, ) -@requires(backends=("torchvision",)) class Qwen2VLVideoProcessor(BaseVideoProcessor): resample = PILImageResampling.BICUBIC size = {"shortest_edge": 128 * 28 * 28, "longest_edge": 28 * 28 * 768} diff --git a/src/transformers/models/sam2_video/video_processing_sam2_video.py b/src/transformers/models/sam2_video/video_processing_sam2_video.py index e30424305110..b0280828cb66 100644 --- a/src/transformers/models/sam2_video/video_processing_sam2_video.py +++ b/src/transformers/models/sam2_video/video_processing_sam2_video.py @@ -17,32 +17,15 @@ from typing import Optional, Union import numpy as np +import torch +from torch.nn import functional as F_t from ...image_processing_utils import BatchFeature -from ...image_utils import ( - IMAGENET_DEFAULT_MEAN, - IMAGENET_DEFAULT_STD, - SizeDict, -) -from ...utils import ( - TensorType, - is_torch_available, - is_vision_available, -) -from ...utils.import_utils import requires +from ...image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD, PILImageResampling, SizeDict +from ...utils import TensorType from ...video_processing_utils import BaseVideoProcessor -if is_torch_available(): - import torch - from torch.nn import functional as F_t - - -if is_vision_available(): - from ...image_utils import PILImageResampling - - -@requires(backends=("torchvision",)) class Sam2VideoVideoProcessor(BaseVideoProcessor): resample = PILImageResampling.BILINEAR image_mean = IMAGENET_DEFAULT_MEAN diff --git a/src/transformers/models/smolvlm/video_processing_smolvlm.py b/src/transformers/models/smolvlm/video_processing_smolvlm.py index 5ad70d870c63..44d7ab9cef37 100644 --- a/src/transformers/models/smolvlm/video_processing_smolvlm.py +++ b/src/transformers/models/smolvlm/video_processing_smolvlm.py @@ -16,43 +16,20 @@ from typing import Optional, Union import numpy as np +import torch -from ...image_processing_utils import ( - BatchFeature, - get_size_dict, -) -from ...image_utils import ( - IMAGENET_STANDARD_MEAN, - IMAGENET_STANDARD_STD, - SizeDict, -) +from ...image_processing_utils import BatchFeature, get_size_dict +from ...image_utils import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD, PILImageResampling, SizeDict from ...processing_utils import Unpack, VideosKwargs -from ...utils import ( - TensorType, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - is_vision_available, -) -from ...utils.import_utils import requires -from ...video_processing_utils import ( - BaseVideoProcessor, -) +from ...utils import TensorType, is_torchvision_v2_available +from ...video_processing_utils import BaseVideoProcessor from ...video_utils import VideoMetadata, group_videos_by_shape, reorder_videos -if is_vision_available(): - from ...image_utils import PILImageResampling - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F - - -if is_torch_available(): - import torch +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F from ...utils import logging @@ -124,7 +101,6 @@ class SmolVLMVideoProcessorInitKwargs(VideosKwargs): max_image_size: dict[str, int] = None -@requires(backends=("torchvision",)) class SmolVLMVideoProcessor(BaseVideoProcessor): resample = PILImageResampling.LANCZOS size = {"longest_edge": 4 * 364} diff --git a/src/transformers/models/video_llava/video_processing_video_llava.py b/src/transformers/models/video_llava/video_processing_video_llava.py index a05ce9303fe6..1e5deb543654 100644 --- a/src/transformers/models/video_llava/video_processing_video_llava.py +++ b/src/transformers/models/video_llava/video_processing_video_llava.py @@ -14,26 +14,14 @@ # limitations under the License. """Video processor class for Video-LLaVA.""" -from ...image_utils import ( - OPENAI_CLIP_MEAN, - OPENAI_CLIP_STD, -) +from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling from ...processing_utils import Unpack, VideosKwargs -from ...utils import is_vision_available -from ...utils.import_utils import requires -from ...video_processing_utils import ( - BaseVideoProcessor, -) - - -if is_vision_available(): - from ...image_utils import PILImageResampling +from ...video_processing_utils import BaseVideoProcessor class VideoLlavaFastVideoProcessorInitKwargs(VideosKwargs): ... -@requires(backends=("torchvision",)) class VideoLlavaVideoProcessor(BaseVideoProcessor): resample = PILImageResampling.BICUBIC image_mean = OPENAI_CLIP_MEAN diff --git a/src/transformers/models/vjepa2/video_processing_vjepa2.py b/src/transformers/models/vjepa2/video_processing_vjepa2.py index 2df100f7eb78..3a5f5509ba6b 100644 --- a/src/transformers/models/vjepa2/video_processing_vjepa2.py +++ b/src/transformers/models/vjepa2/video_processing_vjepa2.py @@ -14,24 +14,14 @@ # limitations under the License. """Fast Video processor class for VJEPA2.""" -from ...image_utils import ( - IMAGENET_DEFAULT_MEAN, - IMAGENET_DEFAULT_STD, -) +from ...image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD, PILImageResampling from ...processing_utils import Unpack, VideosKwargs -from ...utils import is_vision_available -from ...utils.import_utils import requires from ...video_processing_utils import BaseVideoProcessor -if is_vision_available(): - from ...image_utils import PILImageResampling - - class VJEPA2VideoProcessorInitKwargs(VideosKwargs): ... -@requires(backends=("torchvision",)) class VJEPA2VideoProcessor(BaseVideoProcessor): resample = PILImageResampling.BILINEAR image_mean = IMAGENET_DEFAULT_MEAN diff --git a/src/transformers/utils/import_utils.py b/src/transformers/utils/import_utils.py index d3c08eea5971..2f6dc0b8e714 100644 --- a/src/transformers/utils/import_utils.py +++ b/src/transformers/utils/import_utils.py @@ -2470,6 +2470,7 @@ def inner_fn(fun): lambda e: e.startswith("tokenization_") and e.endswith("_fast"): ("tokenizers",), lambda e: e.startswith("image_processing_") and e.endswith("_fast"): ("vision", "torch", "torchvision"), lambda e: e.startswith("image_processing_"): ("vision",), + lambda e: e.startswith("video_processing_"): ("vision", "torch", "torchvision"), } From e71afc5da12e3ac09aaef115337609e8e13fb92d Mon Sep 17 00:00:00 2001 From: Mohamed Mekkouri <93391238+MekkCyber@users.noreply.github.com> Date: Fri, 12 Sep 2025 12:22:25 +0200 Subject: [PATCH 025/204] Adds Causal Conv 1D kernel for mamba models (#40765) * add kernel * make style * keep causal-conv1d * small fix * small fix * fix modular converter * modular fix + lazy loading * revert changes modular * nit * hub kernels update * update * small nit --- .../falcon_mamba/modeling_falcon_mamba.py | 39 +++++++++++++---- .../falcon_mamba/modular_falcon_mamba.py | 22 ++++++---- .../models/mamba/modeling_mamba.py | 42 +++++++++++++++---- 3 files changed, 76 insertions(+), 27 deletions(-) diff --git a/src/transformers/models/falcon_mamba/modeling_falcon_mamba.py b/src/transformers/models/falcon_mamba/modeling_falcon_mamba.py index 90958725b6c4..dc593c979dc7 100644 --- a/src/transformers/models/falcon_mamba/modeling_falcon_mamba.py +++ b/src/transformers/models/falcon_mamba/modeling_falcon_mamba.py @@ -35,6 +35,7 @@ from ...utils import ModelOutput, auto_docstring, logging from ...utils.import_utils import ( is_causal_conv1d_available, + is_kernels_available, is_mamba_ssm_available, is_mambapy_available, ) @@ -54,11 +55,6 @@ else: selective_state_update, selective_scan_fn, mamba_inner_fn = None, None, None -if is_causal_conv1d_available(): - from causal_conv1d import causal_conv1d_fn, causal_conv1d_update -else: - causal_conv1d_update, causal_conv1d_fn = None, None - logger = logging.get_logger(__name__) @@ -166,6 +162,28 @@ def reset(self): self.ssm_states[layer_idx].zero_() +def _lazy_load_causal_conv1d(): + global _causal_conv1d_cache + if _causal_conv1d_cache is not None: + return _causal_conv1d_cache + + if is_kernels_available(): + from kernels import get_kernel + + _causal_conv1d_kernel = get_kernel("kernels-community/causal-conv1d") + _causal_conv1d_cache = (_causal_conv1d_kernel.causal_conv1d_update, _causal_conv1d_kernel.causal_conv1d_fn) + elif is_causal_conv1d_available(): + from causal_conv1d import causal_conv1d_fn, causal_conv1d_update + + _causal_conv1d_cache = (causal_conv1d_update, causal_conv1d_fn) + else: + _causal_conv1d_cache = (None, None) + return _causal_conv1d_cache + + +_causal_conv1d_cache = None + + def rms_forward(hidden_states, variance_epsilon=1e-6): """ Calculates simple RMSNorm with no learnable weights. `MambaRMSNorm` will @@ -245,6 +263,7 @@ def __init__(self, config: FalconMambaConfig, layer_idx: int): self.rms_eps = config.mixer_rms_eps def warn_slow_implementation(self): + causal_conv1d_update, causal_conv1d_fn = _lazy_load_causal_conv1d() is_fast_path_available = all( (selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn) ) @@ -253,8 +272,8 @@ def warn_slow_implementation(self): if is_mambapy_available(): logger.warning_once( "The fast path is not available because one of `(selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn)`" - " is None. Falling back to the mamba.py backend. To install follow https://github.com/state-spaces/mamba/#installation and" - " https://github.com/Dao-AILab/causal-conv1d" + " is None. Falling back to the mamba.py backend. To install follow https://github.com/state-spaces/mamba/#installation for mamba-ssm and" + " https://github.com/Dao-AILab/causal-conv1d or `pip install kernels` for causal-conv1d" ) else: raise ImportError( @@ -263,8 +282,8 @@ def warn_slow_implementation(self): else: logger.warning_once( "The fast path is not available because one of `(selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn)`" - " is None. Falling back to the sequential implementation of Mamba, as use_mambapy is set to False. To install follow https://github.com/state-spaces/mamba/#installation and" - " https://github.com/Dao-AILab/causal-conv1d. For the mamba.py backend, follow https://github.com/alxndrTL/mamba.py." + " is None. Falling back to the sequential implementation of Mamba, as use_mambapy is set to False. To install follow https://github.com/state-spaces/mamba/#installation for mamba-ssm and" + " https://github.com/Dao-AILab/causal-conv1d or `pip install kernels` for causal-conv1d. For the mamba.py backend, follow https://github.com/alxndrTL/mamba.py." ) def cuda_kernels_forward( @@ -299,6 +318,7 @@ def cuda_kernels_forward( ) else: + causal_conv1d_update, causal_conv1d_fn = _lazy_load_causal_conv1d() hidden_states, gate = projected_states.chunk(2, dim=1) if attention_mask is not None: @@ -493,6 +513,7 @@ def forward( cache_position: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.LongTensor] = None, ): + causal_conv1d_update, causal_conv1d_fn = _lazy_load_causal_conv1d() is_fast_path_available = all( (selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn) ) diff --git a/src/transformers/models/falcon_mamba/modular_falcon_mamba.py b/src/transformers/models/falcon_mamba/modular_falcon_mamba.py index f000f3f8271c..cfe2ec49a992 100644 --- a/src/transformers/models/falcon_mamba/modular_falcon_mamba.py +++ b/src/transformers/models/falcon_mamba/modular_falcon_mamba.py @@ -21,7 +21,10 @@ from torch import nn from ...utils import auto_docstring, logging -from ...utils.import_utils import is_causal_conv1d_available, is_mamba_ssm_available, is_mambapy_available +from ...utils.import_utils import ( + is_mamba_ssm_available, + is_mambapy_available, +) from ..mamba.configuration_mamba import MambaConfig from ..mamba.modeling_mamba import ( MambaBlock, @@ -33,6 +36,7 @@ MambaOutput, MambaPreTrainedModel, MambaRMSNorm, + _lazy_load_causal_conv1d, ) @@ -51,10 +55,7 @@ else: selective_state_update, selective_scan_fn, mamba_inner_fn = None, None, None -if is_causal_conv1d_available(): - from causal_conv1d import causal_conv1d_fn, causal_conv1d_update -else: - causal_conv1d_update, causal_conv1d_fn = None, None +_causal_conv1d_cache = None class FalconMambaConfig(MambaConfig): @@ -258,6 +259,7 @@ def rms_forward(hidden_states, variance_epsilon=1e-6): class FalconMambaMixer(MambaMixer): def warn_slow_implementation(self): + causal_conv1d_update, causal_conv1d_fn = _lazy_load_causal_conv1d() is_fast_path_available = all( (selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn) ) @@ -266,8 +268,8 @@ def warn_slow_implementation(self): if is_mambapy_available(): logger.warning_once( "The fast path is not available because one of `(selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn)`" - " is None. Falling back to the mamba.py backend. To install follow https://github.com/state-spaces/mamba/#installation and" - " https://github.com/Dao-AILab/causal-conv1d" + " is None. Falling back to the mamba.py backend. To install follow https://github.com/state-spaces/mamba/#installation for mamba-ssm and" + " https://github.com/Dao-AILab/causal-conv1d or `pip install kernels` for causal-conv1d" ) else: raise ImportError( @@ -276,8 +278,8 @@ def warn_slow_implementation(self): else: logger.warning_once( "The fast path is not available because one of `(selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn)`" - " is None. Falling back to the sequential implementation of Mamba, as use_mambapy is set to False. To install follow https://github.com/state-spaces/mamba/#installation and" - " https://github.com/Dao-AILab/causal-conv1d. For the mamba.py backend, follow https://github.com/alxndrTL/mamba.py." + " is None. Falling back to the sequential implementation of Mamba, as use_mambapy is set to False. To install follow https://github.com/state-spaces/mamba/#installation for mamba-ssm and" + " https://github.com/Dao-AILab/causal-conv1d or `pip install kernels` for causal-conv1d. For the mamba.py backend, follow https://github.com/alxndrTL/mamba.py." ) def __init__(self, config: FalconMambaConfig, layer_idx: int): @@ -323,6 +325,7 @@ def cuda_kernels_forward( ) else: + causal_conv1d_update, causal_conv1d_fn = _lazy_load_causal_conv1d() hidden_states, gate = projected_states.chunk(2, dim=1) if attention_mask is not None: @@ -516,6 +519,7 @@ def forward( cache_position: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.LongTensor] = None, ): + causal_conv1d_update, causal_conv1d_fn = _lazy_load_causal_conv1d() is_fast_path_available = all( (selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn) ) diff --git a/src/transformers/models/mamba/modeling_mamba.py b/src/transformers/models/mamba/modeling_mamba.py index 45a02bdd9505..10616323e13f 100644 --- a/src/transformers/models/mamba/modeling_mamba.py +++ b/src/transformers/models/mamba/modeling_mamba.py @@ -33,7 +33,12 @@ auto_docstring, logging, ) -from ...utils.import_utils import is_causal_conv1d_available, is_mamba_ssm_available, is_mambapy_available +from ...utils.import_utils import ( + is_causal_conv1d_available, + is_kernels_available, + is_mamba_ssm_available, + is_mambapy_available, +) from .configuration_mamba import MambaConfig @@ -50,10 +55,26 @@ else: selective_state_update, selective_scan_fn, mamba_inner_fn = None, None, None -if is_causal_conv1d_available(): - from causal_conv1d import causal_conv1d_fn, causal_conv1d_update -else: - causal_conv1d_update, causal_conv1d_fn = None, None +_causal_conv1d_cache = None + + +def _lazy_load_causal_conv1d(): + global _causal_conv1d_cache + if _causal_conv1d_cache is not None: + return _causal_conv1d_cache + + if is_kernels_available(): + from kernels import get_kernel + + _causal_conv1d_kernel = get_kernel("kernels-community/causal-conv1d") + _causal_conv1d_cache = (_causal_conv1d_kernel.causal_conv1d_update, _causal_conv1d_kernel.causal_conv1d_fn) + elif is_causal_conv1d_available(): + from causal_conv1d import causal_conv1d_fn, causal_conv1d_update + + _causal_conv1d_cache = (causal_conv1d_update, causal_conv1d_fn) + else: + _causal_conv1d_cache = (None, None) + return _causal_conv1d_cache class MambaCache: @@ -211,6 +232,7 @@ def __init__(self, config: MambaConfig, layer_idx: int): self.warn_slow_implementation() def warn_slow_implementation(self): + causal_conv1d_update, causal_conv1d_fn = _lazy_load_causal_conv1d() is_fast_path_available = all( (selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn) ) @@ -219,8 +241,8 @@ def warn_slow_implementation(self): if is_mambapy_available(): logger.warning_once( "The fast path is not available because one of `(selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn)`" - " is None. Falling back to the mamba.py backend. To install follow https://github.com/state-spaces/mamba/#installation and" - " https://github.com/Dao-AILab/causal-conv1d" + " is None. Falling back to the mamba.py backend. To install follow https://github.com/state-spaces/mamba/#installation for mamba-ssm and" + " install the kernels library using `pip install kernels` or https://github.com/Dao-AILab/causal-conv1d for causal-conv1d" ) else: raise ImportError( @@ -229,8 +251,8 @@ def warn_slow_implementation(self): else: logger.warning_once( "The fast path is not available because one of `(selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn)`" - " is None. Falling back to the sequential implementation of Mamba, as use_mambapy is set to False. To install follow https://github.com/state-spaces/mamba/#installation and" - " https://github.com/Dao-AILab/causal-conv1d. For the mamba.py backend, follow https://github.com/alxndrTL/mamba.py." + " is None. Falling back to the sequential implementation of Mamba, as use_mambapy is set to False. To install follow https://github.com/state-spaces/mamba/#installation for mamba-ssm and" + " install the kernels library using `pip install kernels` or https://github.com/Dao-AILab/causal-conv1d for causal-conv1d. For the mamba.py backend, follow https://github.com/alxndrTL/mamba.py." ) def cuda_kernels_forward( @@ -261,6 +283,7 @@ def cuda_kernels_forward( ) else: + causal_conv1d_update, causal_conv1d_fn = _lazy_load_causal_conv1d() hidden_states, gate = projected_states.chunk(2, dim=1) if attention_mask is not None: @@ -424,6 +447,7 @@ def forward( cache_position: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.LongTensor] = None, ): + causal_conv1d_update, causal_conv1d_fn = _lazy_load_causal_conv1d() is_fast_path_available = all( (selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn) ) From c19ca3e0c2918e8edde328a815e5053fb2bd23e3 Mon Sep 17 00:00:00 2001 From: Yuchao Zhang <418121364@qq.com> Date: Fri, 12 Sep 2025 18:44:57 +0800 Subject: [PATCH 026/204] Update no split modules in T5Gemma model (#40810) * Update no split modules in T5Gemma model * Update no_split_modules also for T5Gemma modular * Remove model_split_percents from test cases --------- Co-authored-by: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> --- src/transformers/models/t5gemma/modeling_t5gemma.py | 2 +- src/transformers/models/t5gemma/modular_t5gemma.py | 2 +- tests/models/t5gemma/test_modeling_t5gemma.py | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/transformers/models/t5gemma/modeling_t5gemma.py b/src/transformers/models/t5gemma/modeling_t5gemma.py index 4628614ba363..ba023447c2bc 100644 --- a/src/transformers/models/t5gemma/modeling_t5gemma.py +++ b/src/transformers/models/t5gemma/modeling_t5gemma.py @@ -585,7 +585,7 @@ class T5GemmaPreTrainedModel(PreTrainedModel): config: T5GemmaConfig base_model_prefix = "model" supports_gradient_checkpointing = True - _no_split_modules = ["T5GemmaBlock"] + _no_split_modules = ["T5GemmaEncoderLayer", "T5GemmaDecoderLayer"] _skip_keys_device_placement = ["past_key_values"] _supports_flash_attn = True _supports_sdpa = True diff --git a/src/transformers/models/t5gemma/modular_t5gemma.py b/src/transformers/models/t5gemma/modular_t5gemma.py index 924ddaa6871d..4ac42d99239c 100644 --- a/src/transformers/models/t5gemma/modular_t5gemma.py +++ b/src/transformers/models/t5gemma/modular_t5gemma.py @@ -476,7 +476,7 @@ class T5GemmaPreTrainedModel(Gemma2PreTrainedModel): config: T5GemmaConfig base_model_prefix = "model" supports_gradient_checkpointing = True - _no_split_modules = ["T5GemmaBlock"] + _no_split_modules = ["T5GemmaEncoderLayer", "T5GemmaDecoderLayer"] def _init_weights(self, module): # TODO: support initialization for encoders and decoders separately(?) diff --git a/tests/models/t5gemma/test_modeling_t5gemma.py b/tests/models/t5gemma/test_modeling_t5gemma.py index b44cc9f79054..6a94ff93ea23 100644 --- a/tests/models/t5gemma/test_modeling_t5gemma.py +++ b/tests/models/t5gemma/test_modeling_t5gemma.py @@ -597,7 +597,6 @@ class T5GemmaModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMi test_pruning = False _is_stateful = True is_encoder_decoder = True - model_split_percents = [0.5, 0.6] # used in `test_torch_compile_for_training` _torch_compile_train_cls = T5GemmaForConditionalGeneration if is_torch_available() else None @@ -1460,7 +1459,6 @@ class T5GemmaEncoderOnlyModelTest(ModelTesterMixin, unittest.TestCase): test_headmasking = False _is_stateful = True is_encoder_decoder = False - model_split_percents = [0.4, 0.5] # won't fix test_torchscript = False From 1817410a1afd9497b905d8d22ffa8f4603970d2f Mon Sep 17 00:00:00 2001 From: Pavel Iakubovskii Date: Fri, 12 Sep 2025 12:59:37 +0100 Subject: [PATCH 027/204] Replace image classification loss functions to `self.loss_function` (#40764) --- src/transformers/models/beit/modeling_beit.py | 24 +------ src/transformers/models/bit/modeling_bit.py | 21 +------ src/transformers/models/clip/modeling_clip.py | 24 +------ .../data2vec/modeling_data2vec_vision.py | 24 +------ .../modeling_efficientformer.py | 22 +------ .../models/deprecated/nat/modeling_nat.py | 22 +------ .../models/deprecated/van/modeling_van.py | 22 +------ .../vit_hybrid/modeling_vit_hybrid.py | 24 +------ .../models/dinat/modeling_dinat.py | 22 +------ .../models/donut/modeling_donut_swin.py | 2 +- .../efficientnet/modeling_efficientnet.py | 22 +------ .../models/focalnet/modeling_focalnet.py | 22 +------ .../models/hgnet_v2/modeling_hgnet_v2.py | 21 +------ .../models/hgnet_v2/modular_hgnet_v2.py | 21 +------ .../models/hiera/modeling_hiera.py | 24 +------ .../models/imagegpt/modeling_imagegpt.py | 22 +------ .../models/levit/modeling_levit.py | 23 +------ .../models/metaclip_2/modeling_metaclip_2.py | 24 +------ .../mobilenet_v1/modeling_mobilenet_v1.py | 22 +------ .../mobilenet_v2/modeling_mobilenet_v2.py | 23 +------ .../models/mobilevit/modeling_mobilevit.py | 23 +------ .../mobilevitv2/modeling_mobilevitv2.py | 23 +------ .../models/perceiver/modeling_perceiver.py | 63 +------------------ .../models/poolformer/modeling_poolformer.py | 22 +------ src/transformers/models/pvt/modeling_pvt.py | 22 +------ .../models/pvt_v2/modeling_pvt_v2.py | 22 +------ .../models/regnet/modeling_regnet.py | 21 +------ .../models/resnet/modeling_resnet.py | 21 +------ .../models/segformer/modeling_segformer.py | 24 +------ .../models/siglip/modeling_siglip.py | 24 +------ .../models/siglip2/modeling_siglip2.py | 24 +------ .../models/siglip2/modular_siglip2.py | 24 +------ .../swiftformer/modeling_swiftformer.py | 22 +------ src/transformers/models/swin/modeling_swin.py | 2 +- .../models/swinv2/modeling_swinv2.py | 2 +- .../models/textnet/modeling_textnet.py | 21 +------ .../timm_wrapper/modeling_timm_wrapper.py | 21 +------ 37 files changed, 50 insertions(+), 762 deletions(-) diff --git a/src/transformers/models/beit/modeling_beit.py b/src/transformers/models/beit/modeling_beit.py index 92c629f80cc5..09c887bcd2b4 100755 --- a/src/transformers/models/beit/modeling_beit.py +++ b/src/transformers/models/beit/modeling_beit.py @@ -23,7 +23,7 @@ import torch import torch.utils.checkpoint from torch import Tensor, nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss +from torch.nn import CrossEntropyLoss from ...activations import ACT2FN from ...modeling_layers import GradientCheckpointingLayer @@ -1020,26 +1020,8 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) + if not return_dict: output = (logits,) + outputs[2:] return ((loss,) + output) if loss is not None else output diff --git a/src/transformers/models/bit/modeling_bit.py b/src/transformers/models/bit/modeling_bit.py index 56e76dcb5632..ec778380b6ba 100644 --- a/src/transformers/models/bit/modeling_bit.py +++ b/src/transformers/models/bit/modeling_bit.py @@ -22,7 +22,6 @@ import torch import torch.utils.checkpoint from torch import Tensor, nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_outputs import ( @@ -744,25 +743,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/clip/modeling_clip.py b/src/transformers/models/clip/modeling_clip.py index 5a1a38913fc7..196381f33bbd 100644 --- a/src/transformers/models/clip/modeling_clip.py +++ b/src/transformers/models/clip/modeling_clip.py @@ -19,7 +19,6 @@ import torch from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_attn_mask_utils import _create_4d_causal_attention_mask, _prepare_4d_attention_mask @@ -1220,28 +1219,7 @@ def forward( loss = None if labels is not None: - # move labels to correct device to enable model parallelism - labels = labels.to(logits.device) - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) return ImageClassifierOutput( loss=loss, diff --git a/src/transformers/models/data2vec/modeling_data2vec_vision.py b/src/transformers/models/data2vec/modeling_data2vec_vision.py index 48c103cf648e..6d76852122ac 100644 --- a/src/transformers/models/data2vec/modeling_data2vec_vision.py +++ b/src/transformers/models/data2vec/modeling_data2vec_vision.py @@ -23,7 +23,7 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss +from torch.nn import CrossEntropyLoss from ...activations import ACT2FN from ...modeling_layers import GradientCheckpointingLayer @@ -935,26 +935,8 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) + if not return_dict: output = (logits,) + outputs[2:] return ((loss,) + output) if loss is not None else output diff --git a/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py b/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py index 7d75e45dbc85..3d918e7f5720 100644 --- a/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py +++ b/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py @@ -21,7 +21,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ....activations import ACT2FN from ....modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, ImageClassifierOutput @@ -660,26 +659,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[1:] diff --git a/src/transformers/models/deprecated/nat/modeling_nat.py b/src/transformers/models/deprecated/nat/modeling_nat.py index 0a951623bc7c..d463e2bc89cc 100644 --- a/src/transformers/models/deprecated/nat/modeling_nat.py +++ b/src/transformers/models/deprecated/nat/modeling_nat.py @@ -21,7 +21,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ....activations import ACT2FN from ....modeling_outputs import BackboneOutput @@ -810,26 +809,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/deprecated/van/modeling_van.py b/src/transformers/models/deprecated/van/modeling_van.py index a221bf6d6497..025234e4e71f 100644 --- a/src/transformers/models/deprecated/van/modeling_van.py +++ b/src/transformers/models/deprecated/van/modeling_van.py @@ -21,7 +21,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ....activations import ACT2FN from ....modeling_outputs import ( @@ -510,26 +509,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.config.num_labels == 1: - self.config.problem_type = "regression" - elif self.config.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.config.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.config.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/deprecated/vit_hybrid/modeling_vit_hybrid.py b/src/transformers/models/deprecated/vit_hybrid/modeling_vit_hybrid.py index 7d1c22301def..2d92655cc3e4 100644 --- a/src/transformers/models/deprecated/vit_hybrid/modeling_vit_hybrid.py +++ b/src/transformers/models/deprecated/vit_hybrid/modeling_vit_hybrid.py @@ -21,7 +21,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ....activations import ACT2FN from ....modeling_layers import GradientCheckpointingLayer @@ -725,28 +724,7 @@ def forward( loss = None if labels is not None: - # move labels to correct device to enable model parallelism - labels = labels.to(logits.device) - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[1:] diff --git a/src/transformers/models/dinat/modeling_dinat.py b/src/transformers/models/dinat/modeling_dinat.py index 916fc94a7958..384bdee49d35 100644 --- a/src/transformers/models/dinat/modeling_dinat.py +++ b/src/transformers/models/dinat/modeling_dinat.py @@ -21,7 +21,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_outputs import BackboneOutput @@ -736,26 +735,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/donut/modeling_donut_swin.py b/src/transformers/models/donut/modeling_donut_swin.py index 3126e88f251a..882fd72c508e 100644 --- a/src/transformers/models/donut/modeling_donut_swin.py +++ b/src/transformers/models/donut/modeling_donut_swin.py @@ -1014,7 +1014,7 @@ def forward( loss = None if labels is not None: - loss = self.loss_function(logits=logits, labels=labels, pooled_logits=logits, config=self.config) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/efficientnet/modeling_efficientnet.py b/src/transformers/models/efficientnet/modeling_efficientnet.py index 4de89316b759..70ec3914f7de 100644 --- a/src/transformers/models/efficientnet/modeling_efficientnet.py +++ b/src/transformers/models/efficientnet/modeling_efficientnet.py @@ -20,7 +20,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_outputs import ( @@ -547,26 +546,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/focalnet/modeling_focalnet.py b/src/transformers/models/focalnet/modeling_focalnet.py index 99cba945cfe0..e56ada740e22 100644 --- a/src/transformers/models/focalnet/modeling_focalnet.py +++ b/src/transformers/models/focalnet/modeling_focalnet.py @@ -22,7 +22,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_layers import GradientCheckpointingLayer @@ -846,26 +845,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/hgnet_v2/modeling_hgnet_v2.py b/src/transformers/models/hgnet_v2/modeling_hgnet_v2.py index c042dadf176d..1cd0e857afcd 100644 --- a/src/transformers/models/hgnet_v2/modeling_hgnet_v2.py +++ b/src/transformers/models/hgnet_v2/modeling_hgnet_v2.py @@ -25,7 +25,6 @@ import torch import torch.nn.functional as F from torch import Tensor, nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_outputs import BackboneOutput, BaseModelOutputWithNoAttention, ImageClassifierOutputWithNoAttention @@ -465,25 +464,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/hgnet_v2/modular_hgnet_v2.py b/src/transformers/models/hgnet_v2/modular_hgnet_v2.py index 3bfd23134701..b0c46d688053 100644 --- a/src/transformers/models/hgnet_v2/modular_hgnet_v2.py +++ b/src/transformers/models/hgnet_v2/modular_hgnet_v2.py @@ -19,7 +19,6 @@ import torch import torch.nn.functional as F from torch import Tensor, nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...configuration_utils import PretrainedConfig from ...modeling_outputs import ( @@ -588,25 +587,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/hiera/modeling_hiera.py b/src/transformers/models/hiera/modeling_hiera.py index 69aa24b9f8f0..bfef87618156 100644 --- a/src/transformers/models/hiera/modeling_hiera.py +++ b/src/transformers/models/hiera/modeling_hiera.py @@ -21,7 +21,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_layers import GradientCheckpointingLayer @@ -1320,28 +1319,7 @@ def forward( loss = None if labels is not None: - # move labels to correct device to enable model parallelism - labels = labels.to(logits.device) - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/imagegpt/modeling_imagegpt.py b/src/transformers/models/imagegpt/modeling_imagegpt.py index 23fe9b1e194d..c916a82aad03 100755 --- a/src/transformers/models/imagegpt/modeling_imagegpt.py +++ b/src/transformers/models/imagegpt/modeling_imagegpt.py @@ -21,7 +21,7 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss +from torch.nn import CrossEntropyLoss from ...activations import ACT2FN from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache @@ -1001,26 +1001,8 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" + loss = self.loss_function(labels, logits, self.config) - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) if not return_dict: output = (logits,) + transformer_outputs[1:] return ((loss,) + output) if loss is not None else output diff --git a/src/transformers/models/levit/modeling_levit.py b/src/transformers/models/levit/modeling_levit.py index fc275a1c4c40..a72f5604825f 100644 --- a/src/transformers/models/levit/modeling_levit.py +++ b/src/transformers/models/levit/modeling_levit.py @@ -21,7 +21,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...modeling_outputs import ( BaseModelOutputWithNoAttention, @@ -580,26 +579,8 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) + if not return_dict: output = (logits,) + outputs[2:] return ((loss,) + output) if loss is not None else output diff --git a/src/transformers/models/metaclip_2/modeling_metaclip_2.py b/src/transformers/models/metaclip_2/modeling_metaclip_2.py index cf1c66beb065..58c8ea956551 100644 --- a/src/transformers/models/metaclip_2/modeling_metaclip_2.py +++ b/src/transformers/models/metaclip_2/modeling_metaclip_2.py @@ -9,7 +9,6 @@ import torch from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_attn_mask_utils import _create_4d_causal_attention_mask, _prepare_4d_attention_mask @@ -1356,28 +1355,7 @@ def forward( loss = None if labels is not None: - # move labels to correct device to enable model parallelism - labels = labels.to(logits.device) - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) return ImageClassifierOutput( loss=loss, diff --git a/src/transformers/models/mobilenet_v1/modeling_mobilenet_v1.py b/src/transformers/models/mobilenet_v1/modeling_mobilenet_v1.py index d60738a29778..25997a46790c 100755 --- a/src/transformers/models/mobilenet_v1/modeling_mobilenet_v1.py +++ b/src/transformers/models/mobilenet_v1/modeling_mobilenet_v1.py @@ -18,7 +18,6 @@ import torch from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_outputs import BaseModelOutputWithPoolingAndNoAttention, ImageClassifierOutputWithNoAttention @@ -394,26 +393,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/mobilenet_v2/modeling_mobilenet_v2.py b/src/transformers/models/mobilenet_v2/modeling_mobilenet_v2.py index fa213ab9d98d..8f178f0480dd 100755 --- a/src/transformers/models/mobilenet_v2/modeling_mobilenet_v2.py +++ b/src/transformers/models/mobilenet_v2/modeling_mobilenet_v2.py @@ -18,7 +18,7 @@ import torch from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss +from torch.nn import CrossEntropyLoss from ...activations import ACT2FN from ...modeling_outputs import ( @@ -597,26 +597,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/mobilevit/modeling_mobilevit.py b/src/transformers/models/mobilevit/modeling_mobilevit.py index adfa133c510e..10fe620f7c0d 100755 --- a/src/transformers/models/mobilevit/modeling_mobilevit.py +++ b/src/transformers/models/mobilevit/modeling_mobilevit.py @@ -22,7 +22,7 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss +from torch.nn import CrossEntropyLoss from ...activations import ACT2FN from ...modeling_layers import GradientCheckpointingLayer @@ -774,26 +774,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py b/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py index 450c871ca9f0..291ce6136a54 100644 --- a/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py +++ b/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py @@ -21,7 +21,7 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss +from torch.nn import CrossEntropyLoss from ...activations import ACT2FN from ...modeling_layers import GradientCheckpointingLayer @@ -720,26 +720,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/perceiver/modeling_perceiver.py b/src/transformers/models/perceiver/modeling_perceiver.py index d07fa49ddc5f..1f6b84343d00 100755 --- a/src/transformers/models/perceiver/modeling_perceiver.py +++ b/src/transformers/models/perceiver/modeling_perceiver.py @@ -1214,26 +1214,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] @@ -1355,26 +1336,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] @@ -1497,26 +1459,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/poolformer/modeling_poolformer.py b/src/transformers/models/poolformer/modeling_poolformer.py index 0c72944000a1..3753eb464b04 100755 --- a/src/transformers/models/poolformer/modeling_poolformer.py +++ b/src/transformers/models/poolformer/modeling_poolformer.py @@ -20,7 +20,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_outputs import BaseModelOutputWithNoAttention, ImageClassifierOutputWithNoAttention @@ -370,26 +369,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/pvt/modeling_pvt.py b/src/transformers/models/pvt/modeling_pvt.py index 9e2c5a69d8de..446a85944801 100755 --- a/src/transformers/models/pvt/modeling_pvt.py +++ b/src/transformers/models/pvt/modeling_pvt.py @@ -25,7 +25,6 @@ import torch.nn.functional as F import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_outputs import BaseModelOutput, ImageClassifierOutput @@ -576,26 +575,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[1:] diff --git a/src/transformers/models/pvt_v2/modeling_pvt_v2.py b/src/transformers/models/pvt_v2/modeling_pvt_v2.py index 0e077f41d8f2..e434223a94a2 100644 --- a/src/transformers/models/pvt_v2/modeling_pvt_v2.py +++ b/src/transformers/models/pvt_v2/modeling_pvt_v2.py @@ -22,7 +22,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_layers import GradientCheckpointingLayer @@ -524,26 +523,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[1:] diff --git a/src/transformers/models/regnet/modeling_regnet.py b/src/transformers/models/regnet/modeling_regnet.py index c9cdda640b60..5eb65d92b8be 100644 --- a/src/transformers/models/regnet/modeling_regnet.py +++ b/src/transformers/models/regnet/modeling_regnet.py @@ -20,7 +20,6 @@ import torch import torch.utils.checkpoint from torch import Tensor, nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_outputs import ( @@ -366,25 +365,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/resnet/modeling_resnet.py b/src/transformers/models/resnet/modeling_resnet.py index 6529aab6ebe3..c766a91cd277 100644 --- a/src/transformers/models/resnet/modeling_resnet.py +++ b/src/transformers/models/resnet/modeling_resnet.py @@ -20,7 +20,6 @@ import torch import torch.utils.checkpoint from torch import Tensor, nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN from ...modeling_outputs import ( @@ -349,25 +348,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/segformer/modeling_segformer.py b/src/transformers/models/segformer/modeling_segformer.py index 559c8592bad2..4aa49d86466b 100755 --- a/src/transformers/models/segformer/modeling_segformer.py +++ b/src/transformers/models/segformer/modeling_segformer.py @@ -20,7 +20,7 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss from ...activations import ACT2FN from ...modeling_outputs import BaseModelOutput, ImageClassifierOutput, SemanticSegmenterOutput @@ -567,26 +567,8 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) + if not return_dict: output = (logits,) + outputs[1:] return ((loss,) + output) if loss is not None else output diff --git a/src/transformers/models/siglip/modeling_siglip.py b/src/transformers/models/siglip/modeling_siglip.py index 0720560a87a9..11cab1bf2187 100644 --- a/src/transformers/models/siglip/modeling_siglip.py +++ b/src/transformers/models/siglip/modeling_siglip.py @@ -22,7 +22,6 @@ import numpy as np import torch from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from torch.nn.init import _calculate_fan_in_and_fan_out from ...activations import ACT2FN @@ -1080,28 +1079,7 @@ def forward( loss = None if labels is not None: - # move labels to correct device to enable model parallelism - labels = labels.to(logits.device) - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) return ImageClassifierOutput( loss=loss, diff --git a/src/transformers/models/siglip2/modeling_siglip2.py b/src/transformers/models/siglip2/modeling_siglip2.py index 9cac8a35f6f6..cf2553bd6fe2 100644 --- a/src/transformers/models/siglip2/modeling_siglip2.py +++ b/src/transformers/models/siglip2/modeling_siglip2.py @@ -27,7 +27,6 @@ import torch import torch.nn as nn import torch.nn.functional as F -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from torch.nn.init import _calculate_fan_in_and_fan_out from ...activations import ACT2FN @@ -1178,28 +1177,7 @@ def forward( loss = None if labels is not None: - # move labels to correct device to enable model parallelism - labels = labels.to(logits.device) - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) return ImageClassifierOutput( loss=loss, diff --git a/src/transformers/models/siglip2/modular_siglip2.py b/src/transformers/models/siglip2/modular_siglip2.py index 5a13b8f69efc..260a82e5143e 100644 --- a/src/transformers/models/siglip2/modular_siglip2.py +++ b/src/transformers/models/siglip2/modular_siglip2.py @@ -17,7 +17,6 @@ import torch import torch.nn as nn import torch.nn.functional as F -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from transformers.models.siglip.configuration_siglip import SiglipConfig, SiglipTextConfig, SiglipVisionConfig from transformers.models.siglip.modeling_siglip import ( @@ -584,28 +583,7 @@ def forward( loss = None if labels is not None: - # move labels to correct device to enable model parallelism - labels = labels.to(logits.device) - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) return ImageClassifierOutput( loss=loss, diff --git a/src/transformers/models/swiftformer/modeling_swiftformer.py b/src/transformers/models/swiftformer/modeling_swiftformer.py index 4b6fac00a024..9e0c4c3147b7 100644 --- a/src/transformers/models/swiftformer/modeling_swiftformer.py +++ b/src/transformers/models/swiftformer/modeling_swiftformer.py @@ -20,7 +20,6 @@ import torch import torch.utils.checkpoint from torch import nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2CLS from ...modeling_outputs import BaseModelOutputWithNoAttention, ImageClassifierOutputWithNoAttention @@ -509,26 +508,7 @@ def forward( # calculate loss loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[1:] diff --git a/src/transformers/models/swin/modeling_swin.py b/src/transformers/models/swin/modeling_swin.py index 3287fe7933c7..37d3413fae5d 100644 --- a/src/transformers/models/swin/modeling_swin.py +++ b/src/transformers/models/swin/modeling_swin.py @@ -1152,7 +1152,7 @@ def forward( loss = None if labels is not None: - loss = self.loss_function(logits=logits, labels=labels, pooled_logits=logits, config=self.config) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/swinv2/modeling_swinv2.py b/src/transformers/models/swinv2/modeling_swinv2.py index 57731192d769..4d030178ed49 100644 --- a/src/transformers/models/swinv2/modeling_swinv2.py +++ b/src/transformers/models/swinv2/modeling_swinv2.py @@ -1227,7 +1227,7 @@ def forward( loss = None if labels is not None: - loss = self.loss_function(logits=logits, labels=labels, pooled_logits=logits, config=self.config) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/textnet/modeling_textnet.py b/src/transformers/models/textnet/modeling_textnet.py index aa66587ea2dc..ca39fdc0f2aa 100644 --- a/src/transformers/models/textnet/modeling_textnet.py +++ b/src/transformers/models/textnet/modeling_textnet.py @@ -19,7 +19,6 @@ import torch import torch.nn as nn from torch import Tensor -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from transformers import PreTrainedModel from transformers.activations import ACT2CLS @@ -335,25 +334,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: output = (logits,) + outputs[2:] diff --git a/src/transformers/models/timm_wrapper/modeling_timm_wrapper.py b/src/transformers/models/timm_wrapper/modeling_timm_wrapper.py index d6d844af4794..7839bf7813f2 100644 --- a/src/transformers/models/timm_wrapper/modeling_timm_wrapper.py +++ b/src/transformers/models/timm_wrapper/modeling_timm_wrapper.py @@ -18,7 +18,6 @@ import torch from torch import Tensor, nn -from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...modeling_outputs import ImageClassifierOutput, ModelOutput from ...modeling_utils import PreTrainedModel @@ -344,25 +343,7 @@ def forward( loss = None if labels is not None: - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - if self.config.problem_type == "regression": - loss_fct = MSELoss() - if self.num_labels == 1: - loss = loss_fct(logits.squeeze(), labels.squeeze()) - else: - loss = loss_fct(logits, labels) - elif self.config.problem_type == "single_label_classification": - loss_fct = CrossEntropyLoss() - loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - elif self.config.problem_type == "multi_label_classification": - loss_fct = BCEWithLogitsLoss() - loss = loss_fct(logits, labels) + loss = self.loss_function(labels, logits, self.config) if not return_dict: outputs = (loss, logits, hidden_states) From fb2795e2b11bce6bc7ea8845fe872d0454cf8125 Mon Sep 17 00:00:00 2001 From: Bo Zheng <368586905@qq.com> Date: Fri, 12 Sep 2025 20:08:01 +0800 Subject: [PATCH 028/204] Fix the misalignment between the l2norm in GDN of Qwen3-Next and the implementation in the FLA library. (#40842) * align torch implementation of gdn with fla. * fix fla import. * fix * remove unused attr * fixes * strictly align l2norm in Qwen3-Next with FLA implementation. --------- Co-authored-by: bozheng-hit Co-authored-by: Cyril Vallez --- .../models/qwen3_next/modeling_qwen3_next.py | 18 ++++++++++-------- .../models/qwen3_next/modular_qwen3_next.py | 18 ++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/transformers/models/qwen3_next/modeling_qwen3_next.py b/src/transformers/models/qwen3_next/modeling_qwen3_next.py index 990b776f0d57..ae2d3664e10e 100644 --- a/src/transformers/models/qwen3_next/modeling_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modeling_qwen3_next.py @@ -433,6 +433,12 @@ def torch_causal_conv1d_update( return out +def l2norm(x: torch.FloatTensor, dim: int = -1, eps: float = 1e-6): + """This function is intended to align with the l2norm implementation in the FLA library.""" + inv_norm = 1 / torch.sqrt((x * x).sum(dim=dim, keepdim=True) + eps) + return x * inv_norm + + def torch_chunk_gated_delta_rule( query, key, @@ -446,10 +452,8 @@ def torch_chunk_gated_delta_rule( ): initial_dtype = query.dtype if use_qk_l2norm_in_kernel: - head_dim = query.size(-1) - inv_scale = head_dim**-0.5 - query = F.rms_norm(query, (head_dim,), eps=1e-6) * inv_scale - key = F.rms_norm(key, (head_dim,), eps=1e-6) * inv_scale + query = l2norm(query, dim=-1, eps=1e-6) + key = l2norm(key, dim=-1, eps=1e-6) query, key, value, beta, g = [ x.transpose(1, 2).contiguous().to(torch.float32) for x in (query, key, value, beta, g) ] @@ -520,10 +524,8 @@ def torch_recurrent_gated_delta_rule( ): initial_dtype = query.dtype if use_qk_l2norm_in_kernel: - head_dim = query.size(-1) - inv_scale = head_dim**-0.5 - query = F.rms_norm(query, (head_dim,), eps=1e-6) * inv_scale - key = F.rms_norm(key, (head_dim,), eps=1e-6) * inv_scale + query = l2norm(query, dim=-1, eps=1e-6) + key = l2norm(key, dim=-1, eps=1e-6) query, key, value, beta, g = [ x.transpose(1, 2).contiguous().to(torch.float32) for x in (query, key, value, beta, g) ] diff --git a/src/transformers/models/qwen3_next/modular_qwen3_next.py b/src/transformers/models/qwen3_next/modular_qwen3_next.py index 7512f4a3060a..1854a391cfb6 100644 --- a/src/transformers/models/qwen3_next/modular_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modular_qwen3_next.py @@ -269,6 +269,12 @@ def torch_causal_conv1d_update( return out +def l2norm(x: torch.FloatTensor, dim: int = -1, eps: float = 1e-6): + """This function is intended to align with the l2norm implementation in the FLA library.""" + inv_norm = 1 / torch.sqrt((x * x).sum(dim=dim, keepdim=True) + eps) + return x * inv_norm + + def torch_chunk_gated_delta_rule( query, key, @@ -282,10 +288,8 @@ def torch_chunk_gated_delta_rule( ): initial_dtype = query.dtype if use_qk_l2norm_in_kernel: - head_dim = query.size(-1) - inv_scale = head_dim**-0.5 - query = F.rms_norm(query, (head_dim,), eps=1e-6) * inv_scale - key = F.rms_norm(key, (head_dim,), eps=1e-6) * inv_scale + query = l2norm(query, dim=-1, eps=1e-6) + key = l2norm(key, dim=-1, eps=1e-6) query, key, value, beta, g = [ x.transpose(1, 2).contiguous().to(torch.float32) for x in (query, key, value, beta, g) ] @@ -356,10 +360,8 @@ def torch_recurrent_gated_delta_rule( ): initial_dtype = query.dtype if use_qk_l2norm_in_kernel: - head_dim = query.size(-1) - inv_scale = head_dim**-0.5 - query = F.rms_norm(query, (head_dim,), eps=1e-6) * inv_scale - key = F.rms_norm(key, (head_dim,), eps=1e-6) * inv_scale + query = l2norm(query, dim=-1, eps=1e-6) + key = l2norm(key, dim=-1, eps=1e-6) query, key, value, beta, g = [ x.transpose(1, 2).contiguous().to(torch.float32) for x in (query, key, value, beta, g) ] From a300d04f159b4a8c148702657f319313cb7db7ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Ouazan?= <83456801+remi-or@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:35:31 +0200 Subject: [PATCH 029/204] Fixes for continuous batching (#40828) * Fix for CB attn mask and refactor * Tests for CB (not all passing) * Passing tests and a logger fix * Fixed the KV metrics that were broken when we moved to hybrid alloc * Fix circular import and style * Added tests for FA * Unfolded test to have device expectations * Fixes for H100 * more fixes for h100 * H100 are good * Style * Adding some comments from #40831 * Rename test * Avoid 1 letter variables * Dictonnary is only removed during kwargs * Test for supported sample * Fix a unvoluntary slice * Fixes for non-sliced inputs and small example improvments * Slice inputs is more understandabe * Style --- examples/pytorch/continuous_batching.py | 12 +- .../generation/continuous_batching/cache.py | 26 +- .../continuous_batching/cache_manager.py | 15 + .../continuous_batching/continuous_api.py | 317 ++++++++++-------- .../continuous_batching/requests.py | 2 +- src/transformers/integrations/eager_paged.py | 16 +- src/transformers/integrations/flash_paged.py | 13 +- src/transformers/integrations/sdpa_paged.py | 2 +- src/transformers/testing_utils.py | 6 +- src/transformers/utils/metrics.py | 56 ++-- tests/generation/test_continuous_batching.py | 208 +++++++++++- 11 files changed, 474 insertions(+), 199 deletions(-) diff --git a/examples/pytorch/continuous_batching.py b/examples/pytorch/continuous_batching.py index 9108339468a9..2b0d506eb895 100644 --- a/examples/pytorch/continuous_batching.py +++ b/examples/pytorch/continuous_batching.py @@ -187,18 +187,20 @@ def batch_generate( "--attn", type=str, default="paged_attention|kernels-community/flash-attn", help="Attention implementation" ) parser.add_argument("--matmul-precision", "-mp", type=str, default="high") # set to "none" to disable - parser.add_argument("--slice-inputs", action="store_true", default=False) - parser.add_argument("--use-cuda-graph", action="store_true", default=False) - parser.add_argument("--compile", action="store_true", default=False) + parser.add_argument("--no-slice-inputs", action="store_true") # slicing is enabled by default because much faster + parser.add_argument("--use-cuda-graph", "-cg", action="store_true") + parser.add_argument("--compile", action="store_true") parser.add_argument("--samples", type=int, default=500) parser.add_argument("--displayed", type=int, default=0, help="Number of samples to display") parser.add_argument("--output-file", type=str, default=None) - parser.add_argument("--compare", action="store_true", default=False) - parser.add_argument("--metrics", action="store_true", default=False) + parser.add_argument("--compare", action="store_true") + parser.add_argument("--metrics", action="store_true") parser.add_argument("--profile", type=str, default=None) args = parser.parse_args() + args.slice_inputs = not args.no_slice_inputs + # If turned on, we setup metrics if args.metrics: setup_metrics() diff --git a/src/transformers/generation/continuous_batching/cache.py b/src/transformers/generation/continuous_batching/cache.py index 82d2a0d47aac..05de093f661f 100644 --- a/src/transformers/generation/continuous_batching/cache.py +++ b/src/transformers/generation/continuous_batching/cache.py @@ -198,7 +198,7 @@ def __init__( # Add the inferred attributes to the class self.num_blocks = num_blocks self.max_batch_tokens = max_batch_tokens - logger.warning( + logger.info( f"PagedAttentionCache initialized with {self.num_blocks = }, {self.block_size = }, {page_size = }, " f"{self.max_batch_tokens = } {num_attention_masks = }" ) @@ -253,7 +253,7 @@ def get_num_free_blocks(self) -> int: return len(self._free_blocks) @traced - def get_read_indices( + def extend_read_indices( self, request_id: str, past_length: int, query_length: int, read_index: list[list[int]] ) -> None: """Retrieve physical cache indices for reading KV states in the cache across all layer groups. This method @@ -264,7 +264,7 @@ def get_read_indices( read_indices.extend(indices) @traced - def get_write_indices( + def extend_write_indices( self, request_id: str, past_length: int, query_length: int, write_index: list[list[int]] ) -> None: """Retrieve physical cache indices for writing new KV states to the cache across all layer groups. This method @@ -274,6 +274,16 @@ def get_write_indices( indices = cm.get_write_indices(request_id, past_length, query_length) write_indices.extend(indices) + @traced + def get_seqlens_k(self, request_id: str, past_length: int, query_length: int) -> dict[str, int]: + """Retrieve the key sequence length for the given request_id across all layer types. Returns a dictionary of + layer types to their corresponding key sequence lengths.""" + seqlens_k = {} + for cm in self.group_cache_managers: + attn_type, seqlen_k = cm.get_seqlens_k(request_id, past_length, query_length) + seqlens_k[attn_type] = seqlen_k + return seqlens_k + @traced def update( self, @@ -471,7 +481,7 @@ def compute_num_blocks_and_max_batch_tokens( b = 2 * (self.group_size * self.page_size * cache_dtype.itemsize + 2 * self.num_groups) b += m * (self.peak_activation_per_token * self._activation_dtype.itemsize + 28 + 4 * self.num_groups) c = -cache_memory - logger.info(f"Coefficients of 2nd degree polynomial: {a = }, {b = }, {c = }") + logger.debug(f"Coefficients of 2nd degree polynomial: {a = }, {b = }, {c = }") # Compute discriminant and greatest solution discriminant = b**2 - 4 * a * c @@ -485,11 +495,11 @@ def compute_num_blocks_and_max_batch_tokens( num_pages = floor(greatest_solution) num_blocks = num_pages // self.block_size if num_blocks > self._upper_bound_num_blocks: - logger.warning(f"{num_blocks = } is too large, setting to {self._upper_bound_num_blocks = }") + logger.info(f"{num_blocks = } is too large, setting to {self._upper_bound_num_blocks = }") num_blocks = self._upper_bound_num_blocks max_batch_tokens = int(greatest_solution * m) if max_batch_tokens > self._upper_bound_max_batch_tokens: - logger.warning(f"{max_batch_tokens = } is too large, setting to {self._upper_bound_max_batch_tokens = }") + logger.info(f"{max_batch_tokens = } is too large, setting to {self._upper_bound_max_batch_tokens = }") max_batch_tokens = self._upper_bound_max_batch_tokens return num_blocks, max_batch_tokens @@ -517,7 +527,7 @@ def compute_max_batch_tokens( # Compute max batch tokens and return max_batch_tokens = floor(num / denum) if max_batch_tokens > self._upper_bound_max_batch_tokens: - logger.warning(f"{max_batch_tokens = } is too large, setting to {self._upper_bound_max_batch_tokens = }") + logger.info(f"{max_batch_tokens = } is too large, setting to {self._upper_bound_max_batch_tokens = }") max_batch_tokens = self._upper_bound_max_batch_tokens return max_batch_tokens @@ -545,7 +555,7 @@ def compute_num_blocks( num_pages = floor(num / denum) num_blocks = num_pages // self.block_size if num_blocks > self._upper_bound_num_blocks: - logger.warning(f"{num_blocks = } is too large, setting to {self._upper_bound_num_blocks = }") + logger.info(f"{num_blocks = } is too large, setting to {self._upper_bound_num_blocks = }") num_blocks = self._upper_bound_num_blocks return num_blocks diff --git a/src/transformers/generation/continuous_batching/cache_manager.py b/src/transformers/generation/continuous_batching/cache_manager.py index 74fbcd7c1084..7e2d4f2b5532 100644 --- a/src/transformers/generation/continuous_batching/cache_manager.py +++ b/src/transformers/generation/continuous_batching/cache_manager.py @@ -53,6 +53,11 @@ def get_write_indices(self, request_id: str, past_length: int, query_length: int """Returns the physical indices of where to write request_id's cache in the cache tensor.""" pass + @abstractmethod + def get_seqlens_k(self, request_id: str, past_length: int, query_length: int) -> tuple[str, int]: + """Returns the attention type of the cache allocator and the key sequence length for the given request_id.""" + pass + class FullAttentionCacheAllocator(CacheAllocator): """Cache manager for a group of full attention layers.""" @@ -108,6 +113,11 @@ def get_write_indices(self, request_id: str, past_length: int, query_length: int physical_indices.append(physical_index) return physical_indices + def get_seqlens_k(self, request_id: str, past_length: int, query_length: int) -> tuple[str, int]: + """Returns the attention type of the cache allocator and the key sequence length for the given request_id.""" + seqlens_k = past_length + query_length + return "full_attention", seqlens_k + class SlidingAttentionCacheAllocator(CacheAllocator): """Cache manager for sliding window attention layers.""" @@ -191,6 +201,11 @@ def get_write_indices(self, request_id: str, past_length: int, query_length: int physical_indices = [-1] * padding_length + physical_indices return physical_indices + def get_seqlens_k(self, request_id: str, past_length: int, query_length: int) -> tuple[str, int]: + """Returns the attention type of the cache allocator and the key sequence length for the given request_id.""" + seqlens_k = query_length + min(past_length, self.sliding_window - 1) + return "sliding_attention", seqlens_k + # TODO: test the impact of this # def get_read_indices(self, request_id: str, past_length: int) -> list[int]: diff --git a/src/transformers/generation/continuous_batching/continuous_api.py b/src/transformers/generation/continuous_batching/continuous_api.py index e1dfd638cb34..b00c0a4825c3 100644 --- a/src/transformers/generation/continuous_batching/continuous_api.py +++ b/src/transformers/generation/continuous_batching/continuous_api.py @@ -19,7 +19,7 @@ from functools import partial from itertools import count from time import perf_counter -from typing import Optional +from typing import Optional, Union import torch from torch import nn @@ -102,11 +102,11 @@ def __init__( streaming: bool = False, manual_eviction: bool = False, slice_inputs: bool = True, # TODO: There should be an heuristic to decide on slicing, compile, cuda graphs... - ): + ) -> None: """Initialize the continuous batch processor. Args: - cache: The paged attention cache to use + cache: A [`PagedAttentionCache`] object config: The model configuration generation_config: The generation configuration input_queue: Queue for incoming requests @@ -147,97 +147,129 @@ def __init__( self.total_batch_size = 0 self.setup_static_tensors(cache.num_groups) - def return_attention_mask(self) -> bool: - return self.config._attn_implementation != "paged_attention" # we set `is_causal` to True in paged call - @traced(standalone=True) - def setup_static_tensors(self, num_groups: int): + def setup_static_tensors(self, num_groups: int) -> None: T = self.max_batch_tokens num_pages = self.cache.num_blocks * self.cache.block_size - tensor_metadata = {"dtype": torch.int32, "device": self.model_device} - self.tensor_metadata = tensor_metadata - self.input_ids = torch.empty((1, T), **tensor_metadata) - self.position_ids = torch.empty((1, T), **tensor_metadata) - self.cumulative_seqlens_q = torch.empty((T + 1,), **tensor_metadata) + self.tensor_metadata = {"dtype": torch.int32, "device": self.model_device} + + # Some tensors always have the same shape regardless of the model + self.input_ids = torch.empty((1, T), **self.tensor_metadata) + self.position_ids = torch.empty((1, T), **self.tensor_metadata) + self.cumulative_seqlens_q = torch.empty((T + 1,), **self.tensor_metadata) + self.max_seqlen_q = 0 + self.logits_indices = torch.empty((T,), **self.tensor_metadata) + self.output_ids = torch.empty((1, T), **self.tensor_metadata) + + # For some kwargs, we have a dict of tensors with as many items as there are attention types + layer_types = getattr(self.config, "layer_types", None) + if layer_types is None: + sliding_window = getattr(self.config, "sliding_window", 1) + layer_types = ["full_attention"] if sliding_window in [1, None] else ["sliding_attention"] + layer_types = list(set(layer_types)) + self.cumulative_seqlens_k = { - "full_attention": torch.empty((T + 1), **tensor_metadata), - "sliding_attention": torch.empty((T + 1), **tensor_metadata), - # TODO: can be generalized using layer types, for block-attn for instance + layer_type: torch.empty((T + 1), **self.tensor_metadata) for layer_type in layer_types } + self.max_seqlen_k = dict.fromkeys(layer_types, 0) - # There is one read and write index tensor per group - self.write_index_tensors = [torch.empty((T,), **tensor_metadata) for _ in range(num_groups)] - self.read_index_tensors = [torch.empty((num_pages + T), **tensor_metadata) for _ in range(num_groups)] - # +T is because there are -1 for seqlen_q when model uses a sliding window - - self.logits_indices = torch.empty((T,), **tensor_metadata) - self.max_seqlen_q = 0 - self.max_seqlen_k = {"full_attention": 0, "sliding_attention": 0} - self.output_ids = torch.empty((1, T), **tensor_metadata) - # Since attenention_mask is not always needed, we only allocate it if it is if self.return_attention_mask(): - # TODO: this could be 2 iff model is hybrid, and then we can also change memory handler to account for it - size_0 = 1 if self.sliding_window == 1 else 2 - self.attention_mask = torch.empty( - (size_0, 1, T, num_pages), dtype=self.model_dtype, device=self.model_device - ) + attn_mask_kwargs = { + "size": (1, 1, T, num_pages + T), + "dtype": self.model_dtype, + "device": self.model_device, + } + self.attention_mask = {layer_type: torch.empty(**attn_mask_kwargs) for layer_type in layer_types} else: - logger.warning(f"Attention mask is not needed for {self.config._attn_implementation}") self.attention_mask = None + + # For other kwargs, we need a list of tensors with as many tensors as there are groups + self.write_index_storage = [torch.empty((T,), **self.tensor_metadata) for _ in range(num_groups)] + self.read_index_storage = [torch.empty((num_pages + T), **self.tensor_metadata) for _ in range(num_groups)] + # For read index, the +T is because there are -1 for seqlen_q when model uses a sliding window + + # After allocating empty tensors, we reset them to the right value self.reset_static_tensors(full_reset=True) + def return_attention_mask(self) -> bool: + return self.config._attn_implementation != "paged_attention" # we set `is_causal` to True in paged call + @traced @torch.no_grad() def reset_static_tensors(self, full_reset: bool = False): """Reset static tensors for the next batch. In between batches, reset only the parts that were used in the last batch, but for initialisation, we can reset everything using the (full_reset) flag.""" # Compute the slice to reset - t = self.total_query_length if self.slice_inputs and not full_reset else self.write_index_tensors[0].size(-1) - c = self.total_key_length if self.slice_inputs and not full_reset else self.read_index_tensors[0].size(-1) - b = self.total_batch_size if self.slice_inputs and not full_reset else self.write_index_tensors[0].size(0) - # Reset the tensors - self.input_ids[:, :t].zero_() - self.position_ids[:, :t].zero_() - self.cumulative_seqlens_q[: b + 1].zero_() + if full_reset or not self.slice_inputs: + q_len = self.write_index_storage[0].size(-1) + k_len = self.read_index_storage[0].size(-1) + b_size = self.write_index_storage[0].size(0) + else: + q_len = self.total_query_length + k_len = self.total_key_length + b_size = self.total_batch_size + + # Reset the attributes that always have the same shape + self.input_ids[:, :q_len].zero_() + self.position_ids[:, :q_len].zero_() + self.cumulative_seqlens_q[: b_size + 1].zero_() + self.max_seqlen_q = 0 + self.logits_indices[:q_len].fill_(-1) + self.output_ids[:, :q_len].fill_(-1) + + # Reset the attributes that are either tensors or dict of tensors for layer_type in self.cumulative_seqlens_k: - self.cumulative_seqlens_k[layer_type][: b + 1].zero_() + self.cumulative_seqlens_k[layer_type][: b_size + 1].zero_() self.max_seqlen_k[layer_type] = 0 + if self.attention_mask is not None: + self.attention_mask[layer_type][:, :, :q_len, :k_len].fill_(torch.finfo(self.model_dtype).min) + + # Reset the attributes that are lists of tensors for i in range(self.cache.num_groups): - self.write_index_tensors[i][:t].fill_(-1) - self.read_index_tensors[i][: t + c].fill_(-1) - self.logits_indices[:t].fill_(-1) - self.max_seqlen_q = 0 - self.output_ids[:, :t].fill_(-1) - if self.attention_mask is not None: - self.attention_mask[:, :, :t, :c].fill_(torch.finfo(self.model_dtype).min) + self.write_index_storage[i][:q_len].fill_(-1) + self.read_index_storage[i][: q_len + k_len].fill_(-1) def get_model_kwargs(self) -> PagedAttentionArgs: """Get model keyword arguments for the current batch.""" # Compute the slice to return - t = self.total_query_length if self.slice_inputs else self.write_index.size(-1) - b = self.total_batch_size - # Prepare the kwargs + q_len = self.total_query_length if self.slice_inputs else self.write_index_storage[0].size(-1) + b_size = self.total_batch_size if self.slice_inputs else self.cumulative_seqlens_q.size(-1) - 1 + + # Prepare the kwargs, the attributes that are either tensors or dict of tensors are initialized to empty dicts kwargs = { - "input_ids": self.input_ids[:, :t], - "position_ids": self.position_ids[:, :t], - "cu_seq_lens_q": self.cumulative_seqlens_q[: b + 1], + "input_ids": self.input_ids[:, :q_len], + "position_ids": self.position_ids[:, :q_len], + "cu_seq_lens_q": self.cumulative_seqlens_q[: b_size + 1], + "max_seqlen_q": self.max_seqlen_q, + "logits_indices": self.logits_indices[:q_len], "cu_seq_lens_k": {}, + "max_seqlen_k": {}, + "attention_mask": {}, "read_index": self.read_index, # slicing is done during building "write_index": self.write_index, # slicing is done during building - "logits_indices": self.logits_indices[:t], - "max_seqlen_q": self.max_seqlen_q, - "max_seqlen_k": self.max_seqlen_k, "cache": self.cache, "use_cache": False, } - for layer_type in self.cumulative_seqlens_k: - kwargs["cu_seq_lens_k"][layer_type] = self.cumulative_seqlens_k[layer_type][: b + 1] - # If the attention mask is not None, we slice it as the others - if self.attention_mask is not None: - kwargs["attention_mask"] = {} - for layer_type, seqlens_k in kwargs["cu_seq_lens_k"].items(): - kwargs["attention_mask"][layer_type] = self.attention_mask[:1, :, :t, : seqlens_k[-1]] + + # For the attributes that are dict of tensors, we replace the dict with a tensor if there is only one entry + layer_types = list(self.cumulative_seqlens_k.keys()) + if len(layer_types) > 1: + for layer_type, seqlens_k in self.cumulative_seqlens_k.items(): + kwargs["cu_seq_lens_k"][layer_type] = seqlens_k[: b_size + 1] + kwargs["max_seqlen_k"][layer_type] = self.max_seqlen_k[layer_type] + if self.attention_mask is not None: + k_len = seqlens_k[b_size] if self.slice_inputs else self.attention_mask[layer_type].size(-1) + kwargs["attention_mask"][layer_type] = self.attention_mask[layer_type][..., :q_len, :k_len] else: + layer_type = layer_types[0] + kwargs["cu_seq_lens_k"] = self.cumulative_seqlens_k[layer_type][: b_size + 1] + kwargs["max_seqlen_k"] = self.max_seqlen_k[layer_type] + if self.attention_mask is not None: + k_len = self.cumulative_seqlens_k[layer_type][b_size] + k_len = k_len if self.slice_inputs else self.attention_mask[layer_type].size(-1) + kwargs["attention_mask"] = self.attention_mask[layer_type][..., :q_len, :k_len] + + if self.attention_mask is None: kwargs["attention_mask"] = None return kwargs @@ -283,75 +315,75 @@ def _handle_request_error(self, error, state: RequestState): @traced def prepare_next_batch(self) -> bool: - """Prepare tensors and metadata for the next model forward pass.""" - # Get new requests from the queue + """Prepare tensors and metadata for the next model forward pass. Returns True if there are requests to process, + False otherwise.""" + + # Get new requests from the queue, stop if there are no pending requests self._get_new_requests() self.scheduler.clear_cancelled_requests() if not self.scheduler.has_pending_requests(): return False - self.metrics.record_queue_metrics(len(self.scheduler.active_requests), len(self.scheduler.waiting_requests)) + # Schedule the next batch of requests, stop if there are no requests in the batch self.requests_in_batch = self.scheduler.schedule_batch(self.max_batch_tokens) if not self.requests_in_batch: return False - - # Get the request objects for this batch - self.reset_static_tensors() # TOOD: with slice_inputs, this might be unnecessary - position_ids = [] - input_ids = [] - read_index = [[] for _ in range(self.cache.num_groups)] - write_index = [[] for _ in range(self.cache.num_groups)] - cumulative_seqlens_q = [0] - cumulative_seqlens_k = {"full_attention": [0], "sliding_attention": [0]} - logits_indices = [] self.metrics.record_batch_metrics(self.requests_in_batch) + # Reset the static tensors used for storage + self.reset_static_tensors() # TODO: with slice_inputs, this might be unnecessary + + # Prepare accumulators self.total_query_length = 0 self.total_key_length = 0 self.total_batch_size = 0 + input_ids = [] + position_ids = [] + cumulative_seqlens_q = [0] + logits_indices = [] + + if isinstance(self.cumulative_seqlens_k, dict): + cumulative_seqlens_k = {layer_type: [0] for layer_type in self.cumulative_seqlens_k} + else: + cumulative_seqlens_k = [0] + + read_index = [[] for _ in range(self.cache.num_groups)] + write_index = [[] for _ in range(self.cache.num_groups)] + + # Go through all the requests in the batch for state in self.requests_in_batch: - next_input_ids = state.prompt_ids - input_ids.extend(next_input_ids) + # First we retrieve the lengths related to the request past_length = state.position_offset - query_length = len(next_input_ids) - key_length = query_length + past_length + query_length = len(state.prompt_ids) + seqlens_k = self.cache.get_seqlens_k(state.request_id, past_length, query_length) + # Then we update the total lengths that are used for slicing self.total_query_length += query_length - self.total_key_length += key_length + # total_key_length is used to slice the keys so we need to take the max of all the key lengths + self.total_key_length += max(seqlens_k.values()) self.total_batch_size += 1 + # And the attribute tracking the position in the request object + state.position_offset += query_length - positions_to_add = list(range(past_length, key_length)) - self.cache.get_read_indices(state.request_id, past_length, query_length, read_index) - self.cache.get_write_indices(state.request_id, past_length, query_length, write_index) - - position_ids.extend(positions_to_add) + # Then we accumulate for the object used in the kwargs + input_ids.extend(state.prompt_ids) + position_ids.extend(range(past_length, past_length + query_length)) cumulative_seqlens_q.append(cumulative_seqlens_q[-1] + query_length) + self.max_seqlen_q = max(self.max_seqlen_q, query_length) - cumulative_seqlens_k["full_attention"].append( - cumulative_seqlens_k["full_attention"][-1] + query_length + past_length - ) - cumulative_seqlens_k["sliding_attention"].append( - cumulative_seqlens_k["sliding_attention"][-1] - + query_length - + min(past_length, self.sliding_window - 1) - ) - - if len(state.remaining_prompt_ids) == 0: + if not state.remaining_prompt_ids: logits_indices.append(cumulative_seqlens_q[-1] - 1) - self.max_seqlen_q = max(self.max_seqlen_q, query_length) - self.max_seqlen_k["full_attention"] = max(self.max_seqlen_k["full_attention"], query_length + past_length) - self.max_seqlen_k["sliding_attention"] = max( - self.max_seqlen_k["sliding_attention"], query_length + min(past_length, self.sliding_window - 1) - ) - state.position_offset += query_length - logger.debug( - f"Scheduled: {len(self.requests_in_batch)}, Waiting: {len(self.scheduler.waiting_requests)}, " - f"Active: {len(self.scheduler.active_requests)}. cum Q: {cumulative_seqlens_q[-1]}. " - f"cum KV: {max(ck[-1] for ck in cumulative_seqlens_k)}, free blocks: {self.cache.get_num_free_blocks()}" - ) + for layer_type, layer_type_seqlen_k in seqlens_k.items(): + cumulative_seqlens_k[layer_type].append(cumulative_seqlens_k[layer_type][-1] + layer_type_seqlen_k) + self.max_seqlen_k[layer_type] = max(self.max_seqlen_k[layer_type], layer_type_seqlen_k) + + self.cache.extend_read_indices(state.request_id, past_length, query_length, read_index) + self.cache.extend_write_indices(state.request_id, past_length, query_length, write_index) + + # When looping over request is done, we can build the actual tensors self._build_tensors( input_ids, position_ids, @@ -361,54 +393,64 @@ def prepare_next_batch(self) -> bool: cumulative_seqlens_k, logits_indices, ) - self.metrics.record_kv_cache_memory_metrics(self.cache) + if logger.isEnabledFor(logging.DEBUG): + if isinstance(self.cumulative_seqlens_k, dict): + ck = max(cumulative_seqlens_k[layer_type][-1] for layer_type in self.cumulative_seqlens_k) + else: + ck = cumulative_seqlens_k[-1] + logger.debug( + f"Scheduled: {len(self.requests_in_batch)}, Waiting: {len(self.scheduler.waiting_requests)}, " + f"Active: {len(self.scheduler.active_requests)}. cum Q: {cumulative_seqlens_q[-1]}. " + f"cum KV: {ck}, free blocks: {self.cache.get_num_free_blocks()}" + ) return True @traced def _build_tensors( self, - input_ids, - position_ids, + input_ids: list[int], + position_ids: list[int], read_index: list[list[int]], write_index: list[list[int]], - cumulative_seqlens_q, - cumulative_seqlens_k, - logits_indices, - ): + cumulative_seqlens_q: list[int], + cumulative_seqlens_k: Union[list[int], dict[str, list[int]]], + logits_indices: list[int], + ) -> None: + """Builds the actual tensors for the current batch, by modifying the already allocated tensors in place.""" to_tensor = partial(torch.tensor, **self.tensor_metadata) + + # Those kwargs always have the same type regardless of the model self.input_ids[:, : len(input_ids)] = to_tensor(input_ids) self.position_ids[:, : len(position_ids)] = to_tensor(position_ids) + self.cumulative_seqlens_q[: len(cumulative_seqlens_q)] = to_tensor(cumulative_seqlens_q) + self.logits_indices[: len(logits_indices)] = to_tensor(logits_indices) + # Those kwargs are either dict of tensors or tensors, so we need to handle both cases + for layer_type, layer_type_seqlens_k in cumulative_seqlens_k.items(): + self.cumulative_seqlens_k[layer_type][: len(layer_type_seqlens_k)] = to_tensor(layer_type_seqlens_k) + if self.attention_mask is not None: + build_attention_mask( + attention_mask=self.attention_mask[layer_type], + cumulative_seqlens_q=cumulative_seqlens_q, + cumulative_seqlens_k=layer_type_seqlens_k, + sliding_window=self.sliding_window if layer_type == "sliding_attention" else 1, + ) + + # The index only contain references to the storage tensors, so we update the storage and their references self.read_index = [] self.write_index = [] for i, group_read_indices, group_write_indices in zip(count(), read_index, write_index): # Write in the actual tensors - self.read_index_tensors[i][: len(group_read_indices)] = to_tensor(group_read_indices) - self.write_index_tensors[i][: len(group_write_indices)] = to_tensor(group_write_indices) + self.read_index_storage[i][: len(group_read_indices)] = to_tensor(group_read_indices) + self.write_index_storage[i][: len(group_write_indices)] = to_tensor(group_write_indices) # Slice to the right size - r = len(group_read_indices) if self.slice_inputs else self.read_index_tensors[i].size(-1) - w = len(group_write_indices) if self.slice_inputs else self.write_index_tensors[i].size(-1) + r = len(group_read_indices) if self.slice_inputs else self.read_index_storage[i].size(-1) + w = len(group_write_indices) if self.slice_inputs else self.write_index_storage[i].size(-1) # Add to the index - self.read_index.append(self.read_index_tensors[i][:r]) - self.write_index.append(self.write_index_tensors[i][:w]) - - self.cumulative_seqlens_q[: len(cumulative_seqlens_q)] = to_tensor(cumulative_seqlens_q) - for layer_type in self.cumulative_seqlens_k: - l = len(cumulative_seqlens_k[layer_type]) - self.cumulative_seqlens_k[layer_type][:l] = to_tensor(cumulative_seqlens_k[layer_type]) - self.logits_indices[: len(logits_indices)] = to_tensor(logits_indices) - - if self.attention_mask is not None: - build_attention_mask(self.attention_mask[0], cumulative_seqlens_q, cumulative_seqlens_k["full_attention"]) - if self.sliding_window != 1: - build_attention_mask( - self.attention_mask[1], - cumulative_seqlens_q, - cumulative_seqlens_k["sliding_attention"], - self.sliding_window, - ) + self.read_index.append(self.read_index_storage[i][:r]) + self.write_index.append(self.write_index_storage[i][:w]) @traced def _sync(self): @@ -526,12 +568,15 @@ def __init__( self.model.generation_config.top_p = None self.do_sample = getattr(generation_config, "do_sample", True) self.logit_processor = self.model._get_logits_processor(generation_config) - self.use_cuda_graph = getattr(generation_config, "use_cuda_graph", True) + self.use_cuda_graph = getattr(generation_config, "use_cuda_graph", False) # TODO: same as do_sample self.profile = getattr(generation_config, "profile", False) self.manual_eviction = manual_eviction self.batch_processor: Optional[ContinuousBatchProcessor] = None self.slice_inputs = slice_inputs + if self.use_cuda_graph: + raise NotImplementedError("Cuda graphs are not supported yet") + @traced def start(self): """Start the background generation thread.""" diff --git a/src/transformers/generation/continuous_batching/requests.py b/src/transformers/generation/continuous_batching/requests.py index a4e6da837e7a..a27cefd18fcf 100644 --- a/src/transformers/generation/continuous_batching/requests.py +++ b/src/transformers/generation/continuous_batching/requests.py @@ -25,7 +25,7 @@ # We centralize the logger here to coordinate between logging and progress bar logger = logging.getLogger("ContinuousBatchingLogger") -logger.setLevel(logging.INFO) +# logger.setLevel(logging.INFO) @staticmethod diff --git a/src/transformers/integrations/eager_paged.py b/src/transformers/integrations/eager_paged.py index 6c0b16852f78..8293bd049c80 100644 --- a/src/transformers/integrations/eager_paged.py +++ b/src/transformers/integrations/eager_paged.py @@ -42,7 +42,7 @@ def eager_paged_attention_forward( # Get the right causal mask for the current layer if isinstance(attention_mask, dict): sliding_window = getattr(module, "sliding_window", 1) - layer_type = "full_attention" if sliding_window == 1 else "sliding_attention" + layer_type = "full_attention" if sliding_window == 1 or sliding_window is None else "sliding_attention" causal_mask = attention_mask[layer_type] else: causal_mask = attention_mask @@ -51,7 +51,19 @@ def eager_paged_attention_forward( if causal_mask is not None: attn_weights = attn_weights + causal_mask - attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + # Handle attention sinks if the model has them + if hasattr(module, "sinks"): + # Retrieve the sink and add it to the attention weights + sinks = module.sinks.reshape(1, -1, 1, 1).expand(query.shape[0], -1, query.shape[-2], -1) + attn_weights = torch.cat([attn_weights, sinks], dim=-1) + # Normalize the attention weights for better numerical stability + attn_weights = attn_weights - attn_weights.max(dim=-1, keepdim=True).values + # Apply softmax and drop the sink. Not exactly the same code as eager w/ sink, but the same code does not produce the same results. + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + attn_weights = attn_weights[..., :-1] + else: + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + attn_output = torch.matmul(attn_weights, value) attn_output = attn_output.transpose(1, 2).contiguous() diff --git a/src/transformers/integrations/flash_paged.py b/src/transformers/integrations/flash_paged.py index d9f0b4a3b702..329fab4c9323 100644 --- a/src/transformers/integrations/flash_paged.py +++ b/src/transformers/integrations/flash_paged.py @@ -56,18 +56,19 @@ def paged_attention_forward( if cache is not None: k, v = cache.update(k, v, module.layer_idx, **kwargs) - # Check if we are in a sliding window context - cu_seq_lens_k = cu_seq_lens_k[layer_type].clone() - max_seqlen_k = max_seqlen_k[layer_type] - - # If there is no cache, we assume this is full attention, and we check if cu_seq_lens_k is a list of tensors - elif isinstance(cu_seq_lens_k, list): + # Retrieve the cumulative sequence lengths for the current layer + if isinstance(cu_seq_lens_k, dict): cu_seq_lens_k = cu_seq_lens_k[layer_type].clone() max_seqlen_k = max_seqlen_k[layer_type] + else: + cu_seq_lens_k = cu_seq_lens_k.clone() + max_seqlen_k = max_seqlen_k if implementation is not None and hasattr(implementation, "flash_attn_varlen_func"): flash_attn_varlen_func = implementation.flash_attn_varlen_func + custom_kwargs = {"s_aux": kwargs.get("s_aux")} if "s_aux" in kwargs else {} + attn_output = flash_attn_varlen_func( q.transpose(1, 2).squeeze(0).contiguous(), k.contiguous(), diff --git a/src/transformers/integrations/sdpa_paged.py b/src/transformers/integrations/sdpa_paged.py index b9ad60fa3ec1..e6cbac418156 100644 --- a/src/transformers/integrations/sdpa_paged.py +++ b/src/transformers/integrations/sdpa_paged.py @@ -42,7 +42,7 @@ def sdpa_attention_paged_forward( # Get the right causal mask for the current layer if isinstance(attention_mask, dict): sliding_window = getattr(module, "sliding_window", 1) - layer_type = "full_attention" if sliding_window == 1 else "sliding_attention" + layer_type = "full_attention" if sliding_window == 1 or sliding_window is None else "sliding_attention" causal_mask = attention_mask[layer_type] else: causal_mask = attention_mask diff --git a/src/transformers/testing_utils.py b/src/transformers/testing_utils.py index 3e71d925c571..afc0c3e6d794 100644 --- a/src/transformers/testing_utils.py +++ b/src/transformers/testing_utils.py @@ -596,12 +596,12 @@ def require_flash_attn(test_case): def require_kernels(test_case): """ - Decorator marking a test that requires Flash Attention. + Decorator marking a test that requires the kernels library. - These tests are skipped when Flash Attention isn't installed. + These tests are skipped when the kernels library isn't installed. """ - return unittest.skipUnless(is_kernels_available(), "test requires Flash Attention")(test_case) + return unittest.skipUnless(is_kernels_available(), "test requires the kernels library")(test_case) def require_flash_attn_3(test_case): diff --git a/src/transformers/utils/metrics.py b/src/transformers/utils/metrics.py index 114abd8400e0..62b41995a6d9 100644 --- a/src/transformers/utils/metrics.py +++ b/src/transformers/utils/metrics.py @@ -4,8 +4,6 @@ from enum import Enum from typing import Any, Callable, Optional, Union -import torch - class RequestStatus(Enum): """Status of a generation request through its lifecycle.""" @@ -337,42 +335,28 @@ def record_kv_cache_memory_metrics(self, cache) -> None: return try: - # Calculate memory usage based on cache configuration - num_used_blocks = cache.num_blocks - len(cache._free_blocks) - num_layers = len(cache.key_cache) - - # Each used block stores key and value states - # Each with shape: (num_kv_heads, block_size, head_dim) - bytes_per_parameter = 2 if cache.dtype in [torch.float16, torch.bfloat16] else 4 # Size in bytes - - # Total bytes = num_layers * num_used_blocks * block_size * - # num_kv_heads * head_dim * 2 (both K and V) * bytes_per_parameter - memory_bytes = ( - num_layers - * num_used_blocks - * cache.block_size - * cache.num_key_value_heads - * cache.head_dim - * 2 # For both key and value caches - * bytes_per_parameter - ) - - free_memory_bytes = ( - num_layers - * len(cache._free_blocks) - * cache.block_size - * cache.num_key_value_heads - * cache.head_dim - * 2 # For both key and value caches - * bytes_per_parameter - ) - - self.kv_cache_memory_gauge.set(memory_bytes) + # Retrieve the memory footprint of the cache + page_size = cache.head_dim * cache.num_key_value_heads + page_mem_in_bytes = page_size * cache.dtype.itemsize + # When a block is allocated, it is for both K and V, so we multiply by 2 + # It's also allocated accross all cache tensors, so we multiply by the nb of tensors: len(cache.key_cache) + block_mem_in_bytes = 2 * len(cache.key_cache) * cache.block_size * page_mem_in_bytes + + # Retrieve the number of used and free blocks + free_blocks = cache.get_num_free_blocks() + used_blocks = cache.num_blocks - free_blocks + + # Convert that into used and free memory in bytes + used_memory_bytes = used_blocks * block_mem_in_bytes + free_memory_bytes = free_blocks * block_mem_in_bytes + + # Update the telemetry gauges and add a message in the logs + self.kv_cache_memory_gauge.set(used_memory_bytes) self.kv_cache_free_memory_gauge.set(free_memory_bytes) logger.debug( - f"KV Cache memory: {memory_bytes / (1024 * 1024):.2f}MB, " - f"Used blocks: {num_used_blocks}/{cache.num_blocks} " - f"({num_used_blocks / cache.num_blocks * 100:.1f}%)" + f"KV Cache memory: {used_memory_bytes / (1024 * 1024):.2f}MB, " + f"Used blocks: {used_blocks}/{cache.num_blocks} " + f"({used_blocks / cache.num_blocks * 100:.1f}%)" ) except Exception as e: logger.warning(f"Failed to record KV cache memory metrics: {e}") diff --git a/tests/generation/test_continuous_batching.py b/tests/generation/test_continuous_batching.py index 44e2f3c22122..3179479bdb11 100644 --- a/tests/generation/test_continuous_batching.py +++ b/tests/generation/test_continuous_batching.py @@ -15,10 +15,15 @@ import unittest from typing import Optional +import torch from parameterized import parameterized -from transformers import AutoConfig +from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer from transformers.generation.continuous_batching.cache import group_layers_by_attn_type +from transformers.testing_utils import Expectations, require_kernels, require_torch_gpu, slow + + +ALLOW_EXPECTED_OUTPUTS = True # this is a debug flag when you want to measure deviation between CB and non-CB gen class ContinuousBatchingTest(unittest.TestCase): @@ -82,3 +87,204 @@ def test_group_layers( expected_group_type, f"Test failed for: {layer_types_str = }, {sliding_window = }, {group_types = }", ) + + def _continuous_batching_parity( + self, model_id: str, attn_implementation: str, expected_outputs: dict[str, str] + ) -> None: + # Prepare common elements + tokenizer = AutoTokenizer.from_pretrained(model_id, padding_side="left") + prompts = [ + "Janet's ducks lay 16 eggs per day. She eats three for breakfast every morning and bakes muffins for her " + "friends every day with four. She sells the remainder at the farmers' market daily for $2 per fresh " + "duck egg. How much in dollars does she make every day at the farmers' market? The answer is:", + "A robe takes 2 bolts of blue fiber and half that much white fiber. How many bolts in total does it take? " + "The answer is:", + "Josh decides to try flipping a house. He buys a house for $80,000 and then puts in $50,000 in repairs. " + "This increased the value of the house by 150%. How much profit did he make? The answer is:", + ] # fmt: skip + batched_inputs = [tokenizer.encode(prompt) for prompt in prompts] + + # Generation with continuous batching + model = AutoModelForCausalLM.from_pretrained(model_id, attn_implementation=attn_implementation, dtype="auto") + model = model.cuda().eval() + model.generation_config.max_new_tokens = 40 + model.generation_config.do_sample = False + model.generation_config.use_cuda_graph = False + + cb_outputs = model.generate_batch(inputs=batched_inputs, generation_config=model.generation_config) + + # Generation without continuous batching + if attn_implementation == "sdpa_paged": + non_cb_attn_implementation = "sdpa" + elif attn_implementation == "eager_paged": + non_cb_attn_implementation = "eager" + elif attn_implementation == "paged_attention|kernels-community/flash-attn": + non_cb_attn_implementation = "eager" + else: + raise ValueError(f"Invalid attention implementation: {attn_implementation}") + + # We regenerate the model because just changing the attn_implementation does not work + model = AutoModelForCausalLM.from_pretrained( + model_id, attn_implementation=non_cb_attn_implementation, dtype="auto" + ) + model = model.cuda().eval() + model.generation_config.max_new_tokens = 40 + model.generation_config.do_sample = False + model.generation_config.use_cuda_graph = False + + for request_id, request in cb_outputs.items(): + # Generate without continuous batching + input_ids = torch.tensor([request.prompt_ids]).cuda() + attention_mask = torch.ones_like(input_ids) + outputs = model.generate( + input_ids, attention_mask=attention_mask, generation_config=model.generation_config + ) + generated_tokens = outputs[0][input_ids.shape[1] :] + non_cb_decoded_output = tokenizer.decode(generated_tokens, skip_special_tokens=True) + input_ids = input_ids.tolist()[0] + + # Check that the generated output with and without CB match + cb_decoded_output = tokenizer.decode(request.generated_tokens, skip_special_tokens=True) + outputs_match = non_cb_decoded_output == cb_decoded_output + + # If they dont, that might be expected: the outputs can differ slightly due to numerical differences + # If that's the case, there is an expected output ready + if not outputs_match: + expected_output = expected_outputs.get(request_id) if ALLOW_EXPECTED_OUTPUTS else None + + if expected_output is None: + self.fail( + f"Test {request_id = } failed, no expected output was provided.\nRef:" + f"{repr(non_cb_decoded_output)}\nOut:{repr(cb_decoded_output)}" + ) + else: + self.assertEqual( + expected_output, + cb_decoded_output, + msg=f"Test {request_id = } failed, expected output did not match.\n" + f"Exp:{repr(expected_output)}\nOut:{repr(cb_decoded_output)}", + ) + + # Eager tests + @require_torch_gpu + @slow + def test_continuous_batching_parity_llama_eager(self) -> None: + expected_outputs = Expectations({ + ("rocm", (9, 4)): { + "req_0": " $16. How did I get that answer? I used the following equation: 16 - 3 - 4 = 9. 9 x $2 = $18. $18 -" + }, + ("cuda", (9, 0)): { + "req_1": " 3 bolts of blue fiber and 1.5 bolts of white fiber. The total number of bolts is 4.5. The total number of bolts is 4.5. The total", + "req_2": " $50,000. This is because the value of the house increased by 150%, which means that the value of the house increased by $50,000. This is because the value of the" + } + }).get_expectation() # fmt: skip + self._continuous_batching_parity("meta-llama/Llama-3.1-8B", "eager_paged", expected_outputs) + + @require_torch_gpu + @slow + def test_continuous_batching_parity_gemma_eager(self) -> None: + expected_outputs = Expectations({ + ("rocm", (9, 4)): { + "req_1": " \n\n**Answer:** 3 bolts\n\n**Solution:**\n\n* **White fiber:** The robe needs half as much white fiber as blue fiber, so it needs 2 bolts / 2 =" + }, + ("cuda", (9, 0)): { + "req_0": "\n\n**$12**\n\n**Here's how to solve it:**\n\n* **Eggs eaten:** 3\n* **Eggs left:** 16 - 3 = 13", + "req_1": " \n \n 2 + 1 = 3 bolts \n \n \n \n \n \n \n \n \n \n \n \n \n " + } + }).get_expectation() # fmt: skip + self._continuous_batching_parity("google/gemma-2-2b-it", "eager_paged", expected_outputs) + + @require_torch_gpu + @slow + def test_continuous_batching_parity_qwen_eager(self) -> None: + expected_outputs = {} + self._continuous_batching_parity("Qwen/Qwen3-4B-Instruct-2507", "eager_paged", expected_outputs) + + @require_torch_gpu + @slow + def test_continuous_batching_parity_gpt_oss_eager(self) -> None: + expected_outputs = Expectations({ + ("cuda", (9, 0)): { + "req_1": " 2.5 bolts. The question: \"What is the name of the puzzle that involves a robe taking 2 bolts of blue fiber and half that much white fiber?\" The answer: \"The", + "req_2": " 50%.\"\n\nWe need to parse: He buys a house for $80,000. He puts in $50,000 in repairs. This increased the value of the house by 150%." + } + }).get_expectation() # fmt: skip + self._continuous_batching_parity("openai/gpt-oss-20b", "eager_paged", expected_outputs) + + # SDPA tests + @require_torch_gpu + @slow + def test_continuous_batching_parity_llama_sdpa(self) -> None: + expected_outputs = Expectations({ + ("rocm", (9, 4)): { + "req_2": " $50,000. This is because the value of the house increased by 150%, which means that the value of the house increased by $50,000. This is because the value of the" + } + }).get_expectation() # fmt: skip + self._continuous_batching_parity("meta-llama/Llama-3.1-8B", "sdpa_paged", expected_outputs) + + @require_torch_gpu + @slow + def test_continuous_batching_parity_gemma_sdpa(self) -> None: + expected_outputs = Expectations({ + ("cuda", (9, 0)): { + "req_1": " \n\n**Answer:** 3 bolts\n\n**Solution:**\n\n* **White fiber:** The robe needs half as much white fiber as blue fiber, so it needs 2 bolts / 2 =", + } + }).get_expectation() # fmt: skip + self._continuous_batching_parity("google/gemma-2-2b-it", "sdpa_paged", expected_outputs) + + @require_torch_gpu + @slow + def test_continuous_batching_parity_qwen_sdpa(self) -> None: + expected_outputs = {} + self._continuous_batching_parity("Qwen/Qwen3-4B-Instruct-2507", "sdpa_paged", expected_outputs) + + # GPT-OSS is not compatible with SDPA because it has an attention sink. TODO: is this fixable? + + # Flash attention test + @require_torch_gpu + @require_kernels + @slow + def test_continuous_batching_parity_llama_flash(self) -> None: + expected_outputs = Expectations({ + ("cuda", (9, 0)): { + "req_1": " 3 bolts of blue fiber and 1.5 bolts of white fiber. The total number of bolts is 4.5 bolts. The total number of bolts is 4.5 bolts.", + } + }).get_expectation() # fmt: skip + self._continuous_batching_parity( + "meta-llama/Llama-3.1-8B", "paged_attention|kernels-community/flash-attn", expected_outputs + ) + + @require_torch_gpu + @require_kernels + @slow + def test_continuous_batching_parity_gemma_flash(self) -> None: + expected_outputs = Expectations({ + ("cuda", (9, 0)): { + "req_1": " \n \n 2 + 1 = 3 bolts \n \n \n \n \n \n \n \n \n \n \n \n \n ", + } + }).get_expectation() # fmt: skip + self._continuous_batching_parity( + "google/gemma-2-2b-it", "paged_attention|kernels-community/flash-attn", expected_outputs + ) + + @require_torch_gpu + @require_kernels + @slow + def test_continuous_batching_parity_qwen_flash(self) -> None: + expected_outputs = {} + self._continuous_batching_parity( + "Qwen/Qwen3-4B-Instruct-2507", "paged_attention|kernels-community/flash-attn", expected_outputs + ) + + @require_torch_gpu + @require_kernels + @slow + def test_continuous_batching_parity_gpt_oss_flash(self) -> None: + expected_outputs = {} + self._continuous_batching_parity( + "openai/gpt-oss-20b", "paged_attention|kernels-community/flash-attn", expected_outputs + ) + + +# FIXME: the gemma test seem broken, there is a message about cuda graphs and the sdpa and flash expecteations are +# inverted on CUDA. On AMD they do fine. From d5ab59f67b118065646ff10c99c6d9fc1dc6e749 Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Fri, 12 Sep 2025 15:14:54 +0100 Subject: [PATCH 030/204] [tests] re-enable aria fast tests (#40846) * rise from the dead * test --- .../models/idefics3/modeling_idefics3.py | 1 + .../models/smolvlm/modeling_smolvlm.py | 1 + src/transformers/utils/generic.py | 22 ++++- tests/generation/test_utils.py | 6 +- tests/models/aria/test_modeling_aria.py | 87 +++++-------------- 5 files changed, 44 insertions(+), 73 deletions(-) diff --git a/src/transformers/models/idefics3/modeling_idefics3.py b/src/transformers/models/idefics3/modeling_idefics3.py index 24429672da28..ea79003fbd74 100644 --- a/src/transformers/models/idefics3/modeling_idefics3.py +++ b/src/transformers/models/idefics3/modeling_idefics3.py @@ -481,6 +481,7 @@ def forward( self, pixel_values, patch_attention_mask: Optional[torch.BoolTensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, BaseModelOutput]: batch_size = pixel_values.size(0) if patch_attention_mask is None: diff --git a/src/transformers/models/smolvlm/modeling_smolvlm.py b/src/transformers/models/smolvlm/modeling_smolvlm.py index f0928c2cccdc..5d302015a7c9 100644 --- a/src/transformers/models/smolvlm/modeling_smolvlm.py +++ b/src/transformers/models/smolvlm/modeling_smolvlm.py @@ -368,6 +368,7 @@ def forward( self, pixel_values, patch_attention_mask: Optional[torch.BoolTensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, BaseModelOutput]: batch_size = pixel_values.size(0) if patch_attention_mask is None: diff --git a/src/transformers/utils/generic.py b/src/transformers/utils/generic.py index 65d221fbc4af..94d842eee826 100644 --- a/src/transformers/utils/generic.py +++ b/src/transformers/utils/generic.py @@ -813,12 +813,11 @@ def wrapper(*args, **kwargs): class TransformersKwargs(TypedDict, total=False): """ - Keyword arguments to be passed to the loss function + Keyword arguments to be passed to the forward pass of a `PreTrainedModel`. Attributes: num_items_in_batch (`Optional[torch.Tensor]`, *optional*): - Number of items in the batch. It is recommended to pass it when - you are doing gradient accumulation. + Number of items in the batch. It is recommended to pass it when you are doing gradient accumulation. output_hidden_states (`Optional[bool]`, *optional*): Most of the models support outputting all hidden states computed during the forward pass. output_attentions (`Optional[bool]`, *optional*): @@ -1059,7 +1058,22 @@ def wrapped_forward(*args, **kwargs): module.forward = make_capture_wrapper(module, original_forward, key, specs.index) monkey_patched_layers.append((module, original_forward)) - outputs = func(self, *args, **kwargs) + try: + outputs = func(self, *args, **kwargs) + except TypeError as original_exception: + # If we get a TypeError, it's possible that the model is not receiving the recordable kwargs correctly. + # Get a TypeError even after removing the recordable kwargs -> re-raise the original exception + # Otherwise -> we're probably missing `**kwargs` in the decorated function + kwargs_without_recordable = {k: v for k, v in kwargs.items() if k not in recordable_keys} + try: + outputs = func(self, *args, **kwargs_without_recordable) + except TypeError: + raise original_exception + raise TypeError( + "Missing `**kwargs` in the signature of the `@check_model_inputs`-decorated function " + f"({func.__qualname__})" + ) + # Restore original forward methods for module, original_forward in monkey_patched_layers: module.forward = original_forward diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index 6d5613dd2aed..e55c37eca800 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -2131,12 +2131,12 @@ def _check_encoder_hidden_states_for_generate(self, hidden_states, batch_size, c def _check_past_key_values_for_generate(self, batch_size, decoder_past_key_values, cache_length, config): self.assertIsInstance(decoder_past_key_values, (tuple, Cache)) - # (batch, head, seq_length, head_features) + # (batch, # kv heads, seq_length, head_features) expected_shape = ( batch_size, - config.num_key_value_heads if hasattr(config, "num_key_value_heads") else config.num_attention_heads, + getattr(config, "num_key_value_heads", None) or config.num_attention_heads, cache_length, - config.hidden_size // config.num_attention_heads, + getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads, ) if isinstance(decoder_past_key_values, Cache): diff --git a/tests/models/aria/test_modeling_aria.py b/tests/models/aria/test_modeling_aria.py index a392b3949d8c..17259a5effa8 100644 --- a/tests/models/aria/test_modeling_aria.py +++ b/tests/models/aria/test_modeling_aria.py @@ -15,7 +15,6 @@ import unittest -import pytest import requests from transformers import ( @@ -61,6 +60,10 @@ class AriaVisionText2TextModelTester: def __init__( self, parent, + batch_size=13, + num_channels=3, + image_size=16, + num_image_tokens=4, ignore_index=-100, image_token_index=9, projector_hidden_act="gelu", @@ -83,16 +86,16 @@ def __init__( num_choices=4, pad_token_id=1, hidden_size=32, - intermediate_size=64, + intermediate_size=16, max_position_embeddings=60, model_type="aria_moe_lm", moe_intermediate_size=4, - moe_num_experts=4, + moe_num_experts=3, moe_topk=2, - num_attention_heads=8, + num_attention_heads=2, num_experts_per_tok=3, num_hidden_layers=2, - num_key_value_heads=8, + num_key_value_heads=2, rope_theta=5000000, vocab_size=99, eos_token_id=2, @@ -100,15 +103,15 @@ def __init__( ), is_training=True, vision_config=Idefics3VisionConfig( - image_size=358, - patch_size=10, + image_size=16, + patch_size=8, num_channels=3, is_training=True, hidden_size=32, - projection_dim=20, + projection_dim=4, num_hidden_layers=2, - num_attention_heads=16, - intermediate_size=10, + num_attention_heads=2, + intermediate_size=4, dropout=0.1, attention_dropout=0.1, initializer_range=0.02, @@ -130,11 +133,14 @@ def __init__( self.num_attention_heads = text_config.num_attention_heads self.is_training = is_training - self.batch_size = 10 - self.num_channels = 3 - self.image_size = 358 - self.num_image_tokens = 128 + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.num_image_tokens = num_image_tokens self.seq_length = seq_length + self.num_image_tokens + self.projector_patch_to_query_dict = { + vision_config.image_size**2 // vision_config.patch_size**2: vision_config.projection_dim + } def get_config(self): return AriaConfig( @@ -146,6 +152,7 @@ def get_config(self): vision_feature_select_strategy=self.vision_feature_select_strategy, vision_feature_layer=self.vision_feature_layer, eos_token_id=self.eos_token_id, + projector_patch_to_query_dict=self.projector_patch_to_query_dict, ) def prepare_config_and_inputs(self): @@ -176,7 +183,6 @@ def prepare_config_and_inputs_for_common(self): return config, inputs_dict -@slow @require_torch class AriaForConditionalGenerationModelTest(ModelTesterMixin, GenerationTesterMixin, unittest.TestCase): """ @@ -193,61 +199,10 @@ def setUp(self): self.model_tester = AriaVisionText2TextModelTester(self) self.config_tester = ConfigTester(self, config_class=AriaConfig, has_text_modality=False) - @unittest.skip( - reason="This architecture seems to not compute gradients properly when using GC, check: https://github.com/huggingface/transformers/pull/27124" - ) - def test_training_gradient_checkpointing(self): - pass - - @unittest.skip( - reason="This architecture seems to not compute gradients properly when using GC, check: https://github.com/huggingface/transformers/pull/27124" - ) - def test_training_gradient_checkpointing_use_reentrant(self): - pass - - @unittest.skip( - reason="This architecture seems to not compute gradients properly when using GC, check: https://github.com/huggingface/transformers/pull/27124" - ) - def test_training_gradient_checkpointing_use_reentrant_false(self): - pass - - @unittest.skip(reason="Compile not yet supported because in LLava models") - @pytest.mark.torch_compile_test - def test_sdpa_can_compile_dynamic(self): - pass - - @unittest.skip(reason="Compile not yet supported because in LLava models") - def test_sdpa_can_dispatch_on_flash(self): - pass - - @unittest.skip(reason="Feedforward chunking is not yet supported") - def test_feed_forward_chunking(self): - pass - @unittest.skip(reason="Unstable test") def test_initialization(self): pass - @unittest.skip(reason="Dynamic control flow due to MoE") - def test_generate_with_static_cache(self): - pass - - @unittest.skip(reason="Dynamic control flow due to MoE") - def test_generate_from_inputs_embeds_with_static_cache(self): - pass - - @unittest.skip(reason="Aria uses nn.MHA which is not compatible with offloading") - def test_cpu_offload(self): - pass - - @unittest.skip(reason="Aria uses nn.MHA which is not compatible with offloading") - def test_disk_offload_bin(self): - pass - - @unittest.skip(reason="Aria uses nn.MHA which is not compatible with offloading") - def test_disk_offload_safetensors(self): - pass - SKIP = False torch_accelerator_module = getattr(torch, torch_device) From e25fcbf8effbdea111011c09ecdfdaf9d0ca3d34 Mon Sep 17 00:00:00 2001 From: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com> Date: Fri, 12 Sep 2025 10:21:22 -0400 Subject: [PATCH 031/204] [SAM2] Fix inconsistent results with original implementation with input boxes (#40800) * Fix inconsistencies with box input inference with original repo * remove print * always pad * fix modular --- .../models/metaclip_2/modeling_metaclip_2.py | 5 ++--- .../models/metaclip_2/modular_metaclip_2.py | 5 ++--- src/transformers/models/sam2/modeling_sam2.py | 11 ++++++----- src/transformers/models/sam2/modular_sam2.py | 11 ++++++----- .../models/sam2_video/modeling_sam2_video.py | 11 ++++++----- tests/models/sam2/test_modeling_sam2.py | 18 +++++++++--------- 6 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/transformers/models/metaclip_2/modeling_metaclip_2.py b/src/transformers/models/metaclip_2/modeling_metaclip_2.py index 58c8ea956551..c05a3019c279 100644 --- a/src/transformers/models/metaclip_2/modeling_metaclip_2.py +++ b/src/transformers/models/metaclip_2/modeling_metaclip_2.py @@ -960,9 +960,8 @@ def forward( interpolate_pos_encoding: bool = False, ) -> MetaClip2Output: r""" - Args: - return_loss (`bool`, *optional*): - Whether or not to return the contrastive loss. + return_loss (`bool`, *optional*): + Whether or not to return the contrastive loss. Examples: diff --git a/src/transformers/models/metaclip_2/modular_metaclip_2.py b/src/transformers/models/metaclip_2/modular_metaclip_2.py index 2f6085519119..4d5a536ab93f 100644 --- a/src/transformers/models/metaclip_2/modular_metaclip_2.py +++ b/src/transformers/models/metaclip_2/modular_metaclip_2.py @@ -551,9 +551,8 @@ def forward( interpolate_pos_encoding: bool = False, ): r""" - Args: - return_loss (`bool`, *optional*): - Whether or not to return the contrastive loss. + return_loss (`bool`, *optional*): + Whether or not to return the contrastive loss. Examples: diff --git a/src/transformers/models/sam2/modeling_sam2.py b/src/transformers/models/sam2/modeling_sam2.py index 20ea1d5e6230..ef16466d344c 100644 --- a/src/transformers/models/sam2/modeling_sam2.py +++ b/src/transformers/models/sam2/modeling_sam2.py @@ -793,13 +793,14 @@ def _embed_points(self, points: torch.Tensor, labels: torch.Tensor, pad: bool) - def _embed_boxes(self, boxes: torch.Tensor) -> torch.Tensor: """Embeds box prompts.""" - boxes = boxes + 0.5 # Shift to center of pixel - batch_size, nb_boxes = boxes.shape[:2] - coords = boxes.reshape(batch_size, nb_boxes, 2, 2) - input_shape = (self.input_image_size, self.input_image_size) - corner_embedding = self.shared_embedding(coords, input_shape) + boxes += 0.5 # Shift to center of pixel + coords = boxes.view(*boxes.shape[:2], 2, 2) + # add padding point for consistency with the original implementation + coords = torch.nn.functional.pad(coords, (0, 0, 0, 1), mode="constant", value=0) + corner_embedding = self.shared_embedding(coords, (self.input_image_size, self.input_image_size)) corner_embedding[:, :, 0, :] += self.point_embed.weight[2] corner_embedding[:, :, 1, :] += self.point_embed.weight[3] + corner_embedding[:, :, 2, :] = self.not_a_point_embed.weight.expand_as(corner_embedding[:, :, 2, :]) return corner_embedding def forward( diff --git a/src/transformers/models/sam2/modular_sam2.py b/src/transformers/models/sam2/modular_sam2.py index 647acde0dee9..5fff232a839c 100644 --- a/src/transformers/models/sam2/modular_sam2.py +++ b/src/transformers/models/sam2/modular_sam2.py @@ -882,13 +882,14 @@ def _embed_points(self, points: torch.Tensor, labels: torch.Tensor, pad: bool) - def _embed_boxes(self, boxes: torch.Tensor) -> torch.Tensor: """Embeds box prompts.""" - boxes = boxes + 0.5 # Shift to center of pixel - batch_size, nb_boxes = boxes.shape[:2] - coords = boxes.reshape(batch_size, nb_boxes, 2, 2) - input_shape = (self.input_image_size, self.input_image_size) - corner_embedding = self.shared_embedding(coords, input_shape) + boxes += 0.5 # Shift to center of pixel + coords = boxes.view(*boxes.shape[:2], 2, 2) + # add padding point for consistency with the original implementation + coords = torch.nn.functional.pad(coords, (0, 0, 0, 1), mode="constant", value=0) + corner_embedding = self.shared_embedding(coords, (self.input_image_size, self.input_image_size)) corner_embedding[:, :, 0, :] += self.point_embed.weight[2] corner_embedding[:, :, 1, :] += self.point_embed.weight[3] + corner_embedding[:, :, 2, :] = self.not_a_point_embed.weight.expand_as(corner_embedding[:, :, 2, :]) return corner_embedding diff --git a/src/transformers/models/sam2_video/modeling_sam2_video.py b/src/transformers/models/sam2_video/modeling_sam2_video.py index 6982921fbef5..f4c1261d6779 100644 --- a/src/transformers/models/sam2_video/modeling_sam2_video.py +++ b/src/transformers/models/sam2_video/modeling_sam2_video.py @@ -1224,13 +1224,14 @@ def _embed_points(self, points: torch.Tensor, labels: torch.Tensor, pad: bool) - def _embed_boxes(self, boxes: torch.Tensor) -> torch.Tensor: """Embeds box prompts.""" - boxes = boxes + 0.5 # Shift to center of pixel - batch_size, nb_boxes = boxes.shape[:2] - coords = boxes.reshape(batch_size, nb_boxes, 2, 2) - input_shape = (self.input_image_size, self.input_image_size) - corner_embedding = self.shared_embedding(coords, input_shape) + boxes += 0.5 # Shift to center of pixel + coords = boxes.view(*boxes.shape[:2], 2, 2) + # add padding point for consistency with the original implementation + coords = torch.nn.functional.pad(coords, (0, 0, 0, 1), mode="constant", value=0) + corner_embedding = self.shared_embedding(coords, (self.input_image_size, self.input_image_size)) corner_embedding[:, :, 0, :] += self.point_embed.weight[2] corner_embedding[:, :, 1, :] += self.point_embed.weight[3] + corner_embedding[:, :, 2, :] = self.not_a_point_embed.weight.expand_as(corner_embedding[:, :, 2, :]) return corner_embedding def forward( diff --git a/tests/models/sam2/test_modeling_sam2.py b/tests/models/sam2/test_modeling_sam2.py index b1456a3eb273..a6584f034064 100644 --- a/tests/models/sam2/test_modeling_sam2.py +++ b/tests/models/sam2/test_modeling_sam2.py @@ -901,7 +901,7 @@ def test_inference_batched_images_batched_boxes(self): self.assertEqual(outputs.pred_masks.shape, (2, 4, 1, 256, 256)) torch.testing.assert_close( outputs.iou_scores, - torch.tensor([[[0.9873], [0.9264], [0.9496], [0.9208]], [[0.9445], [0.9496], [0.9497], [0.9481]]]).to( + torch.tensor([[[0.9904], [0.9689], [0.9770], [0.9079]], [[0.9739], [0.9816], [0.9838], [0.9781]]]).to( torch_device ), atol=1e-4, @@ -912,16 +912,16 @@ def test_inference_batched_images_batched_boxes(self): torch.tensor( [ [ - [[[-7.6204, -11.9286], [-8.7747, -10.5662]]], - [[[-17.1070, -23.4025], [-20.9608, -19.5600]]], - [[[-20.5766, -29.4410], [-26.0739, -24.3225]]], - [[[-19.7201, -29.0836], [-24.4915, -23.6377]]], + [[[-11.1540, -18.3994], [-12.4230, -17.4403]]], + [[[-19.3144, -29.3947], [-24.6341, -24.1144]]], + [[[-24.2983, -37.6470], [-31.6659, -31.0893]]], + [[[-25.4313, -44.0231], [-34.0903, -34.7447]]], ], [ - [[[-18.5259, -23.5202], [-25.1906, -17.2518]]], - [[[-20.1214, -25.4215], [-25.7877, -19.1169]]], - [[[-21.0878, -24.7938], [-27.5625, -19.2650]]], - [[[-20.5210, -22.5343], [-26.0968, -17.7544]]], + [[[-22.5539, -30.4633], [-32.8940, -21.6813]]], + [[[-23.6637, -31.3489], [-32.5095, -22.4442]]], + [[[-25.2987, -30.9999], [-34.6243, -24.1717]]], + [[[-26.3150, -30.5313], [-35.0152, -24.0271]]], ], ] ).to(torch_device), From 1e83816ca0ad38799d7bfb8c5763a9e038d9e955 Mon Sep 17 00:00:00 2001 From: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com> Date: Fri, 12 Sep 2025 10:33:28 -0400 Subject: [PATCH 032/204] [Sam2Video] Fix video inference with batched boxes and add test (#40797) fix video inference with batched boxes and add test --- .../models/sam2_video/modular_sam2_video.py | 3 +- .../sam2_video/processing_sam2_video.py | 3 +- .../sam2_video/test_modeling_sam2_video.py | 41 +++++++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/transformers/models/sam2_video/modular_sam2_video.py b/src/transformers/models/sam2_video/modular_sam2_video.py index bc569aec2811..83483e9d724e 100644 --- a/src/transformers/models/sam2_video/modular_sam2_video.py +++ b/src/transformers/models/sam2_video/modular_sam2_video.py @@ -836,8 +836,7 @@ def process_new_points_or_boxes_for_video_frame( "(please use clear_old_points=True instead)" ) box_coords = input_boxes.reshape(1, -1, 2, 2) - box_labels = torch.tensor([2, 3], dtype=torch.int32) - box_labels = box_labels.reshape(1, -1, 2) + box_labels = torch.tensor([2, 3], dtype=torch.int32).repeat(1, box_coords.shape[1], 1) input_points = torch.cat([box_coords, input_points], dim=2) input_labels = torch.cat([box_labels, input_labels], dim=2) diff --git a/src/transformers/models/sam2_video/processing_sam2_video.py b/src/transformers/models/sam2_video/processing_sam2_video.py index 7588cf256788..d5a3c94d7f87 100644 --- a/src/transformers/models/sam2_video/processing_sam2_video.py +++ b/src/transformers/models/sam2_video/processing_sam2_video.py @@ -721,8 +721,7 @@ def process_new_points_or_boxes_for_video_frame( "(please use clear_old_points=True instead)" ) box_coords = input_boxes.reshape(1, -1, 2, 2) - box_labels = torch.tensor([2, 3], dtype=torch.int32) - box_labels = box_labels.reshape(1, -1, 2) + box_labels = torch.tensor([2, 3], dtype=torch.int32).repeat(1, box_coords.shape[1], 1) input_points = torch.cat([box_coords, input_points], dim=2) input_labels = torch.cat([box_labels, input_labels], dim=2) diff --git a/tests/models/sam2_video/test_modeling_sam2_video.py b/tests/models/sam2_video/test_modeling_sam2_video.py index 0c23e22b89df..d4e41b365d8b 100644 --- a/tests/models/sam2_video/test_modeling_sam2_video.py +++ b/tests/models/sam2_video/test_modeling_sam2_video.py @@ -393,6 +393,47 @@ def test_inference_mask_generation_video_multi_objects_multi_points(self): rtol=1e-4, ) + def test_inference_mask_generation_video_batched_bb(self): + raw_video = prepare_video() + inference_session = self.processor.init_video_session(video=raw_video, inference_device=torch_device) + ann_frame_idx = 0 # the frame index we interact with + ann_obj_ids = [2, 3] # give a unique id to each object we interact with (it can be any integers) + + self.processor.add_inputs_to_inference_session( + inference_session=inference_session, + frame_idx=ann_frame_idx, + obj_ids=ann_obj_ids, + input_boxes=[[[300, 0, 500, 400], [400, 0, 600, 400]]], + ) + + frames = [] + for sam2_video_output in self.video_model.propagate_in_video_iterator( + inference_session=inference_session, + start_frame_idx=ann_frame_idx, + max_frame_num_to_track=2, + ): + video_res_masks = self.processor.post_process_masks( + [sam2_video_output.pred_masks], [raw_video.shape[-3:-1]], binarize=False + )[0] + print(video_res_masks.shape) + frames.append(video_res_masks) + frames = torch.stack(frames, dim=0) + self.assertEqual(frames.shape, (3, 2, 1, raw_video.shape[-3], raw_video.shape[-2])) + print(frames.shape) + print(frames[:3, :, :, :2, :2]) + torch.testing.assert_close( + frames[:3, :, :, :2, :2], + torch.tensor( + [ + [[[[-13.1427, -13.1427], [-13.7753, -13.7753]]], [[[-8.4576, -8.4576], [-8.7329, -8.7329]]]], + [[[[-14.9998, -14.9998], [-15.7086, -15.7086]]], [[[-9.2998, -9.2998], [-9.8947, -9.8947]]]], + [[[[-15.4558, -15.4558], [-16.1649, -16.1649]]], [[[-10.4880, -10.4880], [-11.2098, -11.2098]]]], + ] + ).to(torch_device), + atol=1e-4, + rtol=1e-4, + ) + def test_inference_propagate_video_from_mask_input(self): raw_video = prepare_video() inference_session = self.processor.init_video_session(video=raw_video, inference_device=torch_device) From 55d3458a099b6b9f602f57303efa3b8d2755d8b2 Mon Sep 17 00:00:00 2001 From: Ryan Mullins Date: Fri, 12 Sep 2025 11:36:03 -0400 Subject: [PATCH 033/204] add: differential privacy research model (#40851) * VaultGemma * Removing Sequence and Token classification models. Removing integration tests for now * Remove pass-only modular code. style fixes * Update vaultgemma.md * Update docs/source/en/model_doc/vaultgemma.md Co-authored-by: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> * Update docs/source/en/model_doc/vaultgemma.md Co-authored-by: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> * Add links to model doc * Correct model doc usage examples * Updating model doc to describe differences from Gemma 2 * Update model_doc links * Adding integration tests * style fixes * repo consistency * attribute exception --------- Co-authored-by: Amer Co-authored-by: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> --- docs/source/en/_toctree.yml | 2 + docs/source/en/model_doc/vaultgemma.md | 103 ++++ src/transformers/models/__init__.py | 1 + .../models/auto/configuration_auto.py | 2 + src/transformers/models/auto/modeling_auto.py | 2 + .../models/vaultgemma/__init__.py | 29 + .../vaultgemma/configuration_vaultgemma.py | 182 ++++++ .../models/vaultgemma/modeling_vaultgemma.py | 566 ++++++++++++++++++ .../models/vaultgemma/modular_vaultgemma.py | 84 +++ tests/models/vaultgemma/__init__.py | 0 .../vaultgemma/test_modeling_vaultgemma.py | 322 ++++++++++ utils/check_config_attributes.py | 1 + 12 files changed, 1294 insertions(+) create mode 100644 docs/source/en/model_doc/vaultgemma.md create mode 100644 src/transformers/models/vaultgemma/__init__.py create mode 100644 src/transformers/models/vaultgemma/configuration_vaultgemma.py create mode 100644 src/transformers/models/vaultgemma/modeling_vaultgemma.py create mode 100644 src/transformers/models/vaultgemma/modular_vaultgemma.py create mode 100644 tests/models/vaultgemma/__init__.py create mode 100644 tests/models/vaultgemma/test_modeling_vaultgemma.py diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index 240d912f10b6..b56d16ff69e2 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -709,6 +709,8 @@ title: UL2 - local: model_doc/umt5 title: UMT5 + - local: model_doc/vaultgemma + title: VaultGemma - local: model_doc/xmod title: X-MOD - local: model_doc/xglm diff --git a/docs/source/en/model_doc/vaultgemma.md b/docs/source/en/model_doc/vaultgemma.md new file mode 100644 index 000000000000..c9eb36124fca --- /dev/null +++ b/docs/source/en/model_doc/vaultgemma.md @@ -0,0 +1,103 @@ + + +# VaultGemma + +## Overview + +[VaultGemma](https://services.google.com/fh/files/blogs/vaultgemma_tech_report.pdf) is a text-only decoder model +derived from [Gemma 2](https://huggingface.co/docs/transformers/en/model_doc/gemma2), notably it drops the norms after +the Attention and MLP blocks, and uses full attention for all layers instead of alternating between full attention and +local sliding attention. VaultGemma is available as a pretrained model with 1B parameters that uses a 1024 token +sequence length. + +VaultGemma was trained from scratch with sequence-level differential privacy (DP). Its training data includes the same +mixture as the [Gemma 2 models](https://huggingface.co/collections/google/gemma-2-release-667d6600fd5220e7b967f315), +consisting of a number of documents of varying lengths. Additionally, it is trained using +[DP stochastic gradient descent (DP-SGD)](https://arxiv.org/abs/1607.00133) and provides a +(ε ≤ 2.0, δ ≤ 1.1e-10)-sequence-level DP guarantee, where a sequence consists of 1024 consecutive tokens extracted from +heterogeneous data sources. Specifically, the privacy unit of the guarantee is for the sequences after sampling and +packing of the mixture. + +> [!TIP] +> Click on the VaultGemma models in the right sidebar for more examples of how to apply VaultGemma to different language tasks. + +The example below demonstrates how to chat with the model with [`Pipeline`], the [`AutoModel`] class, or from the +command line. + + + + + +```python +from transformers import pipeline + +pipe = pipeline( + task="text-generation", + model="google/vaultgemma-1b", + dtype="auto", + device_map="auto", +) + +text = "Tell me an unknown interesting biology fact about the brain." +outputs = pipe(text, max_new_tokens=32) +response = outputs[0]["generated_text"] +print(response) +``` + + + + +```python +# pip install accelerate +from transformers import AutoTokenizer, AutoModelForCausalLM + +model_id = "google/vaultgemma-1b" +tokenizer = AutoTokenizer.from_pretrained(model_id) +model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto", dtype="auto") + +text = "Tell me an unknown interesting biology fact about the brain." +input_ids = tokenizer(text, return_tensors="pt").to(model.device) + +outputs = model.generate(**input_ids, max_new_tokens=32) +print(tokenizer.decode(outputs[0])) +``` + + + + +``` +echo -e "Write me a poem about Machine Learning. Answer:" | transformers run --task text2text-generation --model google/vaultgemma-1b-pt --device 0 +``` + + + + +## VaultGemmaConfig + +[[autodoc]] VaultGemmaConfig + +## VaultGemmaModel + +[[autodoc]] VaultGemmaModel + - forward + +## VaultGemmaForCausalLM + +[[autodoc]] VaultGemmaForCausalLM diff --git a/src/transformers/models/__init__.py b/src/transformers/models/__init__.py index 1e70e0e7b4d7..50484a5ca40e 100644 --- a/src/transformers/models/__init__.py +++ b/src/transformers/models/__init__.py @@ -338,6 +338,7 @@ from .unispeech_sat import * from .univnet import * from .upernet import * + from .vaultgemma import * from .video_llava import * from .videomae import * from .vilt import * diff --git a/src/transformers/models/auto/configuration_auto.py b/src/transformers/models/auto/configuration_auto.py index 0d6981d685ed..6a71f49f1783 100644 --- a/src/transformers/models/auto/configuration_auto.py +++ b/src/transformers/models/auto/configuration_auto.py @@ -400,6 +400,7 @@ ("univnet", "UnivNetConfig"), ("upernet", "UperNetConfig"), ("van", "VanConfig"), + ("vaultgemma", "VaultGemmaConfig"), ("video_llava", "VideoLlavaConfig"), ("videomae", "VideoMAEConfig"), ("vilt", "ViltConfig"), @@ -842,6 +843,7 @@ ("univnet", "UnivNet"), ("upernet", "UPerNet"), ("van", "VAN"), + ("vaultgemma", "VaultGemma"), ("video_llava", "VideoLlava"), ("videomae", "VideoMAE"), ("vilt", "ViLT"), diff --git a/src/transformers/models/auto/modeling_auto.py b/src/transformers/models/auto/modeling_auto.py index a4b9434f24b9..9243289b62ef 100644 --- a/src/transformers/models/auto/modeling_auto.py +++ b/src/transformers/models/auto/modeling_auto.py @@ -384,6 +384,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("unispeech-sat", "UniSpeechSatModel"), ("univnet", "UnivNetModel"), ("van", "VanModel"), + ("vaultgemma", "VaultGemmaModel"), ("video_llava", "VideoLlavaModel"), ("videomae", "VideoMAEModel"), ("vilt", "ViltModel"), @@ -732,6 +733,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("starcoder2", "Starcoder2ForCausalLM"), ("transfo-xl", "TransfoXLLMHeadModel"), ("trocr", "TrOCRForCausalLM"), + ("vaultgemma", "VaultGemmaForCausalLM"), ("whisper", "WhisperForCausalLM"), ("xglm", "XGLMForCausalLM"), ("xlm", "XLMWithLMHeadModel"), diff --git a/src/transformers/models/vaultgemma/__init__.py b/src/transformers/models/vaultgemma/__init__.py new file mode 100644 index 000000000000..e252b5b81dc1 --- /dev/null +++ b/src/transformers/models/vaultgemma/__init__.py @@ -0,0 +1,29 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from typing import TYPE_CHECKING + +from ...utils import _LazyModule +from ...utils.import_utils import define_import_structure + + +if TYPE_CHECKING: + from .configuration_vaultgemma import * + from .modeling_vaultgemma import * +else: + import sys + + _file = globals()["__file__"] + sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__) diff --git a/src/transformers/models/vaultgemma/configuration_vaultgemma.py b/src/transformers/models/vaultgemma/configuration_vaultgemma.py new file mode 100644 index 000000000000..3e9d419a5854 --- /dev/null +++ b/src/transformers/models/vaultgemma/configuration_vaultgemma.py @@ -0,0 +1,182 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/vaultgemma/modular_vaultgemma.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_vaultgemma.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from ...configuration_utils import PretrainedConfig, layer_type_validation + + +class VaultGemmaConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`VaultGemmaModel`]. It is used to instantiate an VaultGemma + 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 VaultGemma-7B. + e.g. [google/vaultgemma-7b](https://huggingface.co/google/vaultgemma-7b) + 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 256000): + Vocabulary size of the VaultGemma model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`VaultGemmaModel`] + hidden_size (`int`, *optional*, defaults to 2304): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 9216): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 26): + Number of hidden layers in the Transformer decoder. + num_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Transformer decoder. + num_key_value_heads (`int`, *optional*, defaults to 4): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to + `num_attention_heads`. + head_dim (`int`, *optional*, defaults to 256): + The attention head dimension. + hidden_activation (`str` or `function`, *optional*, defaults to `"gelu_pytorch_tanh"`): + The non-linear activation function (function or string) in the decoder. Will default to `"gelu_pytorch_tanh"` + if not specified. `"gelu_pytorch_tanh"` uses an approximation of the `"gelu"` activation function. + max_position_embeddings (`int`, *optional*, defaults to 8192): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + pad_token_id (`int`, *optional*, defaults to 0): + Padding token id. + eos_token_id (`int`, *optional*, defaults to 1): + End of stream token id. + bos_token_id (`int`, *optional*, defaults to 2): + Beginning of stream token id. + tie_word_embeddings (`bool`, *optional*, defaults to `True`): + Whether to tie weight embeddings + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period of the RoPE embeddings. + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + query_pre_attn_scalar (`float`, *optional*, defaults to 256): + scaling factor used on the attention scores + sliding_window (`int`, *optional*, defaults to 4096): + in VaultGemma, every other layer uses sliding window attention. This is the size of the sliding window. + layer_types (`list`, *optional*): + Attention pattern for each layer. + final_logit_softcapping (`float`, *optional*, defaults to 30.0): + scaling factor when applying tanh softcapping on the logits. + attn_logit_softcapping (`float`, *optional*, defaults to 50.0): + scaling factor when applying tanh softcapping on the attention scores. + + ```python + >>> from transformers import VaultGemmaModel, VaultGemmaConfig + >>> # Initializing a VaultGemma vaultgemma-7b style configuration + >>> configuration = VaultGemmaConfig() + >>> # Initializing a model from the vaultgemma-7b style configuration + >>> model = VaultGemmaModel(configuration) + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "vaultgemma" + keys_to_ignore_at_inference = ["past_key_values"] + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise", + "layers.*.self_attn.k_proj": "colwise", + "layers.*.self_attn.v_proj": "colwise", + "layers.*.self_attn.o_proj": "rowwise", + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=256000, + hidden_size=2304, + intermediate_size=9216, + num_hidden_layers=26, + num_attention_heads=8, + num_key_value_heads=4, + head_dim=256, + hidden_activation="gelu_pytorch_tanh", + max_position_embeddings=8192, + initializer_range=0.02, + rms_norm_eps=1e-6, + use_cache=True, + pad_token_id=0, + eos_token_id=1, + bos_token_id=2, + tie_word_embeddings=True, + rope_theta=10000.0, + attention_bias=False, + attention_dropout=0.0, + query_pre_attn_scalar=256, + sliding_window=4096, + layer_types=None, + final_logit_softcapping=30.0, + attn_logit_softcapping=50.0, + **kwargs, + ): + super().__init__( + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + tie_word_embeddings=tie_word_embeddings, + **kwargs, + ) + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.head_dim = head_dim + self.num_key_value_heads = num_key_value_heads + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.rope_theta = rope_theta + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + self.hidden_activation = hidden_activation + self.query_pre_attn_scalar = query_pre_attn_scalar + self.sliding_window = sliding_window + self.final_logit_softcapping = final_logit_softcapping + self.attn_logit_softcapping = attn_logit_softcapping + self.layer_types = layer_types + + if self.layer_types is None: + self.layer_types = [ + "sliding_attention" if bool((i + 1) % 2) else "full_attention" for i in range(self.num_hidden_layers) + ] + layer_type_validation(self.layer_types) + + +__all__ = ["VaultGemmaConfig"] diff --git a/src/transformers/models/vaultgemma/modeling_vaultgemma.py b/src/transformers/models/vaultgemma/modeling_vaultgemma.py new file mode 100644 index 000000000000..c70a7a83fa9c --- /dev/null +++ b/src/transformers/models/vaultgemma/modeling_vaultgemma.py @@ -0,0 +1,566 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/vaultgemma/modular_vaultgemma.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_vaultgemma.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from typing import Callable, Optional, Union + +import torch +import torch.nn as nn + +from ...activations import ACT2FN +from ...cache_utils import Cache, DynamicCache +from ...generation import GenerationMixin +from ...masking_utils import create_causal_mask, create_sliding_window_causal_mask +from ...modeling_flash_attention_utils import FlashAttentionKwargs +from ...modeling_layers import GradientCheckpointingLayer +from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging +from ...utils.deprecation import deprecate_kwarg +from ...utils.generic import check_model_inputs +from .configuration_vaultgemma import VaultGemmaConfig + + +logger = logging.get_logger(__name__) + + +class VaultGemmaRMSNorm(nn.Module): + def __init__(self, dim: int, eps: float = 1e-6): + super().__init__() + self.eps = eps + self.weight = nn.Parameter(torch.zeros(dim)) + + def _norm(self, x): + return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) + + def forward(self, x): + output = self._norm(x.float()) + # Llama does x.to(float16) * w whilst VaultGemma is (x * w).to(float16) + # See https://github.com/huggingface/transformers/pull/29402 + output = output * (1.0 + self.weight.float()) + return output.type_as(x) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.eps}" + + +class VaultGemmaMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + self.act_fn = ACT2FN[config.hidden_activation] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +def rotate_half(x): + """Rotates half the hidden dims of the input.""" + x1 = x[..., : x.shape[-1] // 2] + x2 = x[..., x.shape[-1] // 2 :] + return torch.cat((-x2, x1), dim=-1) + + +def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1): + """Applies Rotary Position Embedding to the query and key tensors. + + Args: + q (`torch.Tensor`): The query tensor. + k (`torch.Tensor`): The key tensor. + cos (`torch.Tensor`): The cosine part of the rotary embedding. + sin (`torch.Tensor`): The sine part of the rotary embedding. + position_ids (`torch.Tensor`, *optional*): + Deprecated and unused. + unsqueeze_dim (`int`, *optional*, defaults to 1): + The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and + sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note + that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and + k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes + cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have + the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. + Returns: + `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. + """ + cos = cos.unsqueeze(unsqueeze_dim) + sin = sin.unsqueeze(unsqueeze_dim) + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + return q_embed, k_embed + + +def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor: + """ + This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, + num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim) + """ + batch, num_key_value_heads, slen, head_dim = hidden_states.shape + if n_rep == 1: + return hidden_states + hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim) + return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim) + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + dropout: float = 0.0, + scaling: Optional[float] = None, + softcap: Optional[float] = None, + **kwargs, +) -> tuple[torch.Tensor, torch.Tensor]: + if scaling is None: + scaling = module.head_dim**-0.5 + + key_states = repeat_kv(key, module.num_key_value_groups) + value_states = repeat_kv(value, module.num_key_value_groups) + + attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling + + if softcap is not None: + attn_weights = attn_weights / softcap + attn_weights = torch.tanh(attn_weights) + attn_weights = attn_weights * softcap + if attention_mask is not None: # no matter the length, we just slice it + causal_mask = attention_mask[:, :, :, : key_states.shape[-2]] + attn_weights = attn_weights + causal_mask + + # upcast attention to fp32 + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + attn_output = torch.matmul(attn_weights, value_states) + attn_output = attn_output.transpose(1, 2).contiguous() + return attn_output, attn_weights + + +class VaultGemmaAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: VaultGemmaConfig, layer_idx: int): + super().__init__() + self.config = config + self.layer_idx = layer_idx + self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) + self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads + self.scaling = config.query_pre_attn_scalar**-0.5 + self.attention_dropout = self.config.attention_dropout + self.is_causal = True + + self.q_proj = nn.Linear( + config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias + ) + self.k_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.v_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.o_proj = nn.Linear( + config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias + ) + self.attn_logit_softcapping = self.config.attn_logit_softcapping + self.sliding_window = config.sliding_window if config.layer_types[layer_idx] == "sliding_attention" else None + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) + key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=self.attention_dropout if self.training else 0.0, + scaling=self.scaling, + sliding_window=self.sliding_window, + softcap=self.attn_logit_softcapping, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class VaultGemmaDecoderLayer(GradientCheckpointingLayer): + def __init__(self, config: VaultGemmaConfig, layer_idx: int): + super().__init__() + self.hidden_size = config.hidden_size + self.config = config + self.attention_type = config.layer_types[layer_idx] + self.self_attn = VaultGemmaAttention(config=config, layer_idx=layer_idx) + self.mlp = VaultGemmaMLP(config) + self.input_layernorm = VaultGemmaRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + self.pre_feedforward_layernorm = VaultGemmaRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + output_attentions: Optional[bool] = False, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + **kwargs, + ) -> tuple[torch.FloatTensor, Optional[tuple[torch.FloatTensor, torch.FloatTensor]]]: + residual = hidden_states + hidden_states = self.input_layernorm(hidden_states) + # Self Attention + hidden_states, self_attn_weights = self.self_attn( + hidden_states=hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + output_attentions=output_attentions, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.pre_feedforward_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + if output_attentions: + outputs += (self_attn_weights,) + + return outputs + + +class VaultGemmaRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: VaultGemmaConfig, device=None): + super().__init__() + # BC: "rope_type" was originally "type" + if hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): + self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type")) + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device) + position_ids_expanded = position_ids[:, None, :].float() + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + +@auto_docstring +class VaultGemmaPreTrainedModel(PreTrainedModel): + config: VaultGemmaConfig + base_model_prefix = "model" + supports_gradient_checkpointing = True + _no_split_modules = ["VaultGemmaDecoderLayer"] + _skip_keys_device_placement = ["past_key_values"] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + + _can_compile_fullgraph = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": VaultGemmaDecoderLayer, + "attentions": VaultGemmaAttention, + } + + +@auto_docstring +class VaultGemmaModel(VaultGemmaPreTrainedModel): + def __init__(self, config: VaultGemmaConfig): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + + self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx) + self.layers = nn.ModuleList( + [VaultGemmaDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = VaultGemmaRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = VaultGemmaRotaryEmbedding(config=config) + self.gradient_checkpointing = False + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> BaseModelOutputWithPast: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + use_cache = use_cache if use_cache is not None else self.config.use_cache + + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if self.gradient_checkpointing and self.training and use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`." + ) + use_cache = False + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if use_cache and past_key_values is None and not self.training: + past_key_values = DynamicCache(config=self.config) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + # It may already have been prepared by e.g. `generate` + if not isinstance(causal_mask_mapping := attention_mask, dict): + # Prepare mask arguments + mask_kwargs = { + "config": self.config, + "input_embeds": inputs_embeds, + "attention_mask": attention_mask, + "cache_position": cache_position, + "past_key_values": past_key_values, + "position_ids": position_ids, + } + # Create the masks + causal_mask_mapping = { + "full_attention": create_causal_mask(**mask_kwargs), + "sliding_attention": create_sliding_window_causal_mask(**mask_kwargs), + } + + # embed positions + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + # normalized + # VaultGemma downcasts the below to float16, causing sqrt(3072)=55.4256 to become 55.5 + # See https://github.com/huggingface/transformers/pull/29402 + normalizer = torch.tensor(self.config.hidden_size**0.5, dtype=hidden_states.dtype) + hidden_states = hidden_states * normalizer + + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + + for decoder_layer in self.layers[: self.config.num_hidden_layers]: + if output_hidden_states: + all_hidden_states += (hidden_states,) + + layer_outputs = decoder_layer( + hidden_states, + position_embeddings=position_embeddings, + attention_mask=causal_mask_mapping[decoder_layer.attention_type], + position_ids=position_ids, + past_key_values=past_key_values, + output_attentions=output_attentions, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attns += (layer_outputs[1],) + + hidden_states = self.norm(hidden_states) + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + hidden_states=all_hidden_states, + attentions=all_self_attns, + ) + + +@auto_docstring +class VaultGemmaForCausalLM(VaultGemmaPreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.weight"] + _tp_plan = {"lm_head": "colwise_rep"} + _pp_plan = {"lm_head": (["hidden_states"], ["logits"])} + + def __init__(self, config): + super().__init__(config) + self.model = VaultGemmaModel(config) + self.vocab_size = config.vocab_size + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs, + ) -> CausalLMOutputWithPast: + r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, VaultGemmaForCausalLM + + >>> model = VaultGemmaForCausalLM.from_pretrained("google/gemma-2-9b") + >>> tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-9b") + + >>> prompt = "What is your favorite condiment?" + >>> inputs = tokenizer(prompt, return_tensors="pt") + + >>> # Generate + >>> generate_ids = model.generate(inputs.input_ids, max_length=30) + >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] + "What is your favorite condiment?" + ```""" + + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn) + outputs: BaseModelOutputWithPast = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs.last_hidden_state + # Only compute necessary logits, and do not upcast them to float if we are not computing the loss + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]) + if self.config.final_logit_softcapping is not None: + logits = logits / self.config.final_logit_softcapping + logits = torch.tanh(logits) + logits = logits * self.config.final_logit_softcapping + + loss = None + if labels is not None: + loss = self.loss_function(logits, labels, self.vocab_size, **kwargs) + + return CausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +__all__ = ["VaultGemmaForCausalLM", "VaultGemmaModel", "VaultGemmaPreTrainedModel"] diff --git a/src/transformers/models/vaultgemma/modular_vaultgemma.py b/src/transformers/models/vaultgemma/modular_vaultgemma.py new file mode 100644 index 000000000000..133fc50ded3b --- /dev/null +++ b/src/transformers/models/vaultgemma/modular_vaultgemma.py @@ -0,0 +1,84 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from typing import Optional + +import torch + +from ...cache_utils import Cache +from ..gemma2.configuration_gemma2 import Gemma2Config +from ..gemma2.modeling_gemma2 import Gemma2DecoderLayer, Gemma2ForCausalLM + + +class VaultGemmaConfig(Gemma2Config): + pass + + +class VaultGemmaDecoderLayer(Gemma2DecoderLayer): + def __init__(self, **super_kwargs): + super().__init__(**super_kwargs) + del self.post_attention_layernorm + del self.post_feedforward_layernorm + + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + output_attentions: Optional[bool] = False, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + **kwargs, + ) -> tuple[torch.FloatTensor, Optional[tuple[torch.FloatTensor, torch.FloatTensor]]]: + residual = hidden_states + hidden_states = self.input_layernorm(hidden_states) + # Self Attention + hidden_states, self_attn_weights = self.self_attn( + hidden_states=hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + output_attentions=output_attentions, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.pre_feedforward_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + if output_attentions: + outputs += (self_attn_weights,) + + return outputs + + +class VaultGemmaForCausalLM(Gemma2ForCausalLM): + pass + + +__all__ = [ + "VaultGemmaConfig", + "VaultGemmaForCausalLM", + "VaultGemmaModel", # noqa: F822 + "VaultGemmaPreTrainedModel", # noqa: F822 +] diff --git a/tests/models/vaultgemma/__init__.py b/tests/models/vaultgemma/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/models/vaultgemma/test_modeling_vaultgemma.py b/tests/models/vaultgemma/test_modeling_vaultgemma.py new file mode 100644 index 000000000000..548cfd3f57f0 --- /dev/null +++ b/tests/models/vaultgemma/test_modeling_vaultgemma.py @@ -0,0 +1,322 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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 VaultGemma model.""" + +import unittest + +import pytest +from packaging import version +from parameterized import parameterized + +from transformers import ( + AutoModelForCausalLM, + AutoTokenizer, + DynamicCache, + VaultGemmaConfig, + is_torch_available, + pipeline, +) +from transformers.cache_utils import DynamicLayer, DynamicSlidingWindowLayer +from transformers.generation.configuration_utils import GenerationConfig +from transformers.testing_utils import ( + Expectations, + cleanup, + is_flash_attn_2_available, + require_read_token, + require_torch, + require_torch_accelerator, + slow, + torch_device, +) + +from ...causal_lm_tester import CausalLMModelTest, CausalLMModelTester +from ...test_configuration_common import ConfigTester + + +if is_torch_available(): + import torch + + from transformers import ( + VaultGemmaForCausalLM, + VaultGemmaModel, + ) + + +class VaultGemmaModelTester(CausalLMModelTester): + if is_torch_available(): + config_class = VaultGemmaConfig + base_model_class = VaultGemmaModel + causal_lm_class = VaultGemmaForCausalLM + pipeline_model_mapping = ( + { + "feature-extraction": VaultGemmaModel, + "text-generation": VaultGemmaForCausalLM, + } + if is_torch_available() + else {} + ) + + +@require_torch +class VaultGemmaModelTest(CausalLMModelTest, unittest.TestCase): + all_model_classes = (VaultGemmaModel, VaultGemmaForCausalLM) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": VaultGemmaModel, + "text-generation": VaultGemmaForCausalLM, + } + if is_torch_available() + else {} + ) + + test_headmasking = False + test_pruning = False + _is_stateful = True + model_split_percents = [0.5, 0.6] + model_tester_class = VaultGemmaModelTester + + def setUp(self): + self.model_tester = VaultGemmaModelTester(self) + self.config_tester = ConfigTester(self, config_class=VaultGemmaConfig, hidden_size=37) + + +@slow +@require_torch_accelerator +class VaultGemmaIntegrationTest(unittest.TestCase): + input_text = ["Hello I am doing", "Hi today"] + + def setUp(self): + cleanup(torch_device, gc_collect=True) + + def tearDown(self): + cleanup(torch_device, gc_collect=True) + + @require_read_token + def test_model_bf16(self): + model_id = "google/vaultgemma-1b" + EXPECTED_TEXTS = [ + "Hello I am doing a project on the 1918 flu pandemic and I am trying to find out how many", + "Hi today I'm going to be talking about the history of the United States. The United States of America", + ] + + model = AutoModelForCausalLM.from_pretrained(model_id, dtype=torch.bfloat16, attn_implementation="eager").to( + torch_device + ) + + tokenizer = AutoTokenizer.from_pretrained(model_id) + inputs = tokenizer(self.input_text, return_tensors="pt", padding=True).to(torch_device) + + output = model.generate(**inputs, max_new_tokens=20, do_sample=False) + output_text = tokenizer.batch_decode(output, skip_special_tokens=False) + + self.assertEqual(output_text, EXPECTED_TEXTS) + + @require_read_token + def test_model_pipeline_bf16(self): + model_id = "google/vaultgemma-1b" + # EXPECTED_TEXTS should match the same non-pipeline test, minus the special tokens + EXPECTED_TEXTS = [ + "Hello I am doing a project on the 1918 flu pandemic and I am trying to find out how many", + "Hi today I'm going to be talking about the history of the United States. The United States of America", + ] + + model = AutoModelForCausalLM.from_pretrained( + model_id, dtype=torch.bfloat16, attn_implementation="flex_attention" + ).to(torch_device) + tokenizer = AutoTokenizer.from_pretrained(model_id) + pipe = pipeline("text-generation", model=model, tokenizer=tokenizer) + + output = pipe(self.input_text, max_new_tokens=20, do_sample=False, padding=True) + + self.assertEqual(output[0][0]["generated_text"], EXPECTED_TEXTS[0]) + self.assertEqual(output[1][0]["generated_text"], EXPECTED_TEXTS[1]) + + @pytest.mark.torch_export_test + @slow + @require_read_token + def test_export_static_cache(self): + if version.parse(torch.__version__) < version.parse("2.5.0"): + self.skipTest(reason="This test requires torch >= 2.5 to run.") + + from transformers.integrations.executorch import ( + TorchExportableModuleWithStaticCache, + ) + + model_id = "google/vaultgemma-1b" + tokenizer = AutoTokenizer.from_pretrained(model_id, pad_token="", padding_side="right") + EXPECTED_TEXT_COMPLETIONS = Expectations( + { + ("xpu", 3): [ + "Hello I am doing a project for my school and I need to know how to make a program that will take a number" + ], + ("cuda", 7): [ + "Hello I am doing a project for my school and I need to know how to make a program that will take a number" + ], + ("cuda", 8): [ + "Hello I am doing a project for my class and I am having trouble with the code. I am trying to make a" + ], + ("rocm", (9, 5)): [ + "Hello I am doing a project for my school and I need to know how to make a program that will take a number" + ], + } + ) + EXPECTED_TEXT_COMPLETION = EXPECTED_TEXT_COMPLETIONS.get_expectation() + max_generation_length = tokenizer(EXPECTED_TEXT_COMPLETION, return_tensors="pt", padding=True)[ + "input_ids" + ].shape[-1] + + # Load model + device = "cpu" # TODO (joao / export experts): should be on `torch_device`, but causes GPU OOM + dtype = torch.bfloat16 + cache_implementation = "static" + attn_implementation = "sdpa" + batch_size = 1 + model = AutoModelForCausalLM.from_pretrained( + model_id, + device_map=device, + dtype=dtype, + attn_implementation=attn_implementation, + generation_config=GenerationConfig( + use_cache=True, + cache_implementation=cache_implementation, + max_length=max_generation_length, + cache_config={ + "batch_size": batch_size, + "max_cache_len": max_generation_length, + }, + ), + ) + + prompts = ["Hello I am doing"] + prompt_tokens = tokenizer(prompts, return_tensors="pt", padding=True).to(model.device) + prompt_token_ids = prompt_tokens["input_ids"] + max_new_tokens = max_generation_length - prompt_token_ids.shape[-1] + + # Static Cache + export + from transformers.integrations.executorch import TorchExportableModuleForDecoderOnlyLM + + exportable_module = TorchExportableModuleForDecoderOnlyLM(model) + exported_program = exportable_module.export( + input_ids=torch.tensor([[1]], dtype=torch.long, device=model.device), + cache_position=torch.tensor([0], dtype=torch.long, device=model.device), + ) + ep_generated_ids = TorchExportableModuleWithStaticCache.generate( + exported_program=exported_program, prompt_token_ids=prompt_token_ids, max_new_tokens=max_new_tokens + ) + ep_generated_text = tokenizer.batch_decode(ep_generated_ids, skip_special_tokens=True) + self.assertEqual(EXPECTED_TEXT_COMPLETION, ep_generated_text) + + @parameterized.expand([("flash_attention_2",), ("sdpa",), ("flex_attention",), ("eager",)]) + @require_read_token + def test_generation_beyond_sliding_window(self, attn_implementation: str): + """Test that we can correctly generate beyond the sliding window. This is non trivial as + we need to correctly slice the attention mask in all cases (because we use a hybrid cache). + Outputs for every attention functions should be coherent and identical. + """ + # Impossible to test it with this model (even with < 100 tokens), probably due to the compilation of a large model. + if attn_implementation == "flex_attention": + self.skipTest( + reason="`flex_attention` gives `torch._inductor.exc.InductorError: RuntimeError: No valid triton configs. OutOfMemoryError: out of resource: triton_tem_fused_0 Required: 147456 Hardware limit:101376 Reducing block sizes or `num_stages` may help.`" + ) + + if attn_implementation == "flash_attention_2" and not is_flash_attn_2_available(): + self.skipTest("FlashAttention2 is required for this test.") + + if torch_device == "xpu" and attn_implementation == "flash_attention_2": + self.skipTest(reason="Intel XPU doesn't support flash_attention_2 as of now.") + + model_id = "google/vaultgemma-1b" + EXPECTED_COMPLETIONS = [ + " the people, the food, the culture, the history, the music, the art, the architecture", + ", green, yellow, orange, purple, pink, brown, black, white, gray, silver", + ] + + input_text = [ + "This is a nice place. " * 800 + "I really enjoy the scenery,", # This is larger than 4096 tokens + "A list of colors: red, blue", # This will almost all be padding tokens + ] + tokenizer = AutoTokenizer.from_pretrained(model_id, padding="left") + inputs = tokenizer(input_text, padding=True, return_tensors="pt").to(torch_device) + + model = AutoModelForCausalLM.from_pretrained( + model_id, attn_implementation=attn_implementation, dtype=torch.float16 + ).to(torch_device) + + # Make sure prefill is larger than sliding window + input_size = inputs.input_ids.shape[-1] + self.assertTrue(input_size > model.config.sliding_window) + + # It should by Hybrid by default from hub config, but let's make sure! + out = model.generate(**inputs, max_new_tokens=20, cache_implementation="hybrid")[:, input_size:] + output_text = tokenizer.batch_decode(out) + + self.assertEqual(output_text, EXPECTED_COMPLETIONS) + + @parameterized.expand([("flash_attention_2",), ("sdpa",), ("flex_attention",), ("eager",)]) + @require_read_token + def test_generation_beyond_sliding_window_dynamic(self, attn_implementation: str): + """ + Same as above, but explicitly setting the cache to Dynamic, as it's otherwise static by default for + the model on the hub + """ + # Impossible to test it with this model (even with < 100 tokens), probably due to the compilation of a large model. + if attn_implementation == "flex_attention": + self.skipTest( + reason="`flex_attention` gives `torch._inductor.exc.InductorError: RuntimeError: No valid triton configs. OutOfMemoryError: out of resource: triton_tem_fused_0 Required: 147456 Hardware limit:101376 Reducing block sizes or `num_stages` may help.`" + ) + + if attn_implementation == "flash_attention_2" and not is_flash_attn_2_available(): + self.skipTest("FlashAttention2 is required for this test.") + + if torch_device == "xpu" and attn_implementation == "flash_attention_2": + self.skipTest(reason="Intel XPU doesn't support flash_attention_2 as of now.") + + model_id = "google/vaultgemma-1b" + EXPECTED_COMPLETIONS = [ + " the people, the food, the culture, the history, the music, the art, the architecture", + ", green, yellow, orange, purple, pink, brown, black, white, gray, silver", + ] + + input_text = [ + "This is a nice place. " * 800 + "I really enjoy the scenery,", # This is larger than 4096 tokens + "A list of colors: red, blue", # This will almost all be padding tokens + ] + tokenizer = AutoTokenizer.from_pretrained(model_id, padding="left") + inputs = tokenizer(input_text, padding=True, return_tensors="pt").to(torch_device) + + model = AutoModelForCausalLM.from_pretrained( + model_id, attn_implementation=attn_implementation, dtype=torch.float16 + ).to(torch_device) + + # Make sure prefill is larger than sliding window + input_size = inputs.input_ids.shape[-1] + self.assertTrue(input_size > model.config.sliding_window) + + out = model.generate(**inputs, max_new_tokens=20, cache_implementation="dynamic", return_dict_in_generate=True) + output_text = tokenizer.batch_decode(out.sequences[:, input_size:]) + + self.assertEqual(output_text, EXPECTED_COMPLETIONS) + + # Let's check that the dynamic cache has hybrid layers! + dynamic_cache = out.past_key_values + self.assertTrue(isinstance(dynamic_cache, DynamicCache)) + for layer, layer_type in zip(dynamic_cache.layers, model.config.layer_types): + if layer_type == "sliding_attention": + self.assertTrue(isinstance(layer, DynamicSlidingWindowLayer)) + self.assertEqual(layer.keys.shape[-2], model.config.sliding_window - 1) + else: + self.assertTrue(isinstance(layer, DynamicLayer)) + # max_new_tokens - 1 because last token generated is not cached + self.assertEqual(layer.keys.shape[-2], input_size + 20 - 1) diff --git a/utils/check_config_attributes.py b/utils/check_config_attributes.py index 22c7f67972ee..d3ca53a56076 100644 --- a/utils/check_config_attributes.py +++ b/utils/check_config_attributes.py @@ -305,6 +305,7 @@ ], "SmolLM3Config": ["no_rope_layer_interval"], "Gemma3nVisionConfig": ["architecture", "do_pooling", "model_args"], # this is for use in `timm` + "VaultGemmaConfig": ["tie_word_embeddings"], } From 1814fa6b7d5fb4214256366cf6a9db5f8d67ea1d Mon Sep 17 00:00:00 2001 From: eustlb <94853470+eustlb@users.noreply.github.com> Date: Fri, 12 Sep 2025 18:07:48 +0200 Subject: [PATCH 034/204] [test] Fix test_eager_matches_sdpa incorrectly skipped (#40852) * ouput_attentions in typed kwargs * correct typing in GenericForTokenClassification * improve --- src/transformers/modeling_layers.py | 2 +- tests/test_modeling_common.py | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/transformers/modeling_layers.py b/src/transformers/modeling_layers.py index 4f4a599693dd..dd2a3c76c254 100644 --- a/src/transformers/modeling_layers.py +++ b/src/transformers/modeling_layers.py @@ -262,7 +262,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, - **kwargs, + **kwargs: Unpack[TransformersKwargs], ) -> TokenClassifierOutput: outputs: BaseModelOutputWithPast = getattr(self, self.base_model_prefix)( input_ids, diff --git a/tests/test_modeling_common.py b/tests/test_modeling_common.py index 8330c19a5e6b..fac305d59ee0 100755 --- a/tests/test_modeling_common.py +++ b/tests/test_modeling_common.py @@ -230,6 +230,20 @@ def _test_eager_matches_sdpa_inference( set_model_tester_for_less_flaky_test(self) + def _can_output_attn(model): + parameters = inspect.signature(model.forward).parameters + if "output_attentions" in parameters: + return True + + kwargs_param = parameters.get("kwargs") + if kwargs_param is not None: + try: + annotation = kwargs_param.annotation.__args__ + return "output_attentions" in annotation[0].__annotations__ + except AttributeError: + return False + return False + for model_class in self.all_model_classes: config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() set_config_for_less_flaky_test(config) @@ -263,7 +277,7 @@ def _test_eager_matches_sdpa_inference( set_model_for_less_flaky_test(model_eager) set_model_for_less_flaky_test(model_sdpa) - can_output_attn = "output_attentions" in inspect.signature(model_sdpa.forward).parameters + can_output_attn = _can_output_attn(model_sdpa) if not (self.has_attentions and can_output_attn) and output_attentions: self.skipTest(reason="Model does not support output_attentions") @@ -370,7 +384,7 @@ def _test_eager_matches_sdpa_inference( if "attention_mask" in inspect.signature(model_eager.forward).parameters: processed_inputs["attention_mask"] = dummy_attention_mask - if self.has_attentions and "output_attentions" in inspect.signature(model_sdpa.forward).parameters: + if self.has_attentions and _can_output_attn(model_sdpa): processed_inputs["output_attentions"] = output_attentions if "bool_masked_pos" in inspect.signature(model_eager.forward).parameters: dummy_mask = torch.ones((self.model_tester.num_masks,)) From d78b3a97979573fff596e5b9016311e2a9a631e9 Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Fri, 12 Sep 2025 17:12:27 +0100 Subject: [PATCH 035/204] [tests] move generative tests away from `test_modeling_common.py` (#40854) move tests --- tests/causal_lm_tester.py | 18 +- tests/generation/test_utils.py | 338 ++++++++++++++++++++++ tests/test_modeling_common.py | 503 +-------------------------------- 3 files changed, 363 insertions(+), 496 deletions(-) diff --git a/tests/causal_lm_tester.py b/tests/causal_lm_tester.py index 6677b46f8ab2..8600f1dc265e 100644 --- a/tests/causal_lm_tester.py +++ b/tests/causal_lm_tester.py @@ -18,7 +18,7 @@ import pytest from parameterized import parameterized -from transformers import PretrainedConfig, set_seed +from transformers import AutoModelForCausalLM, PretrainedConfig, set_seed from transformers.testing_utils import ( is_flaky, require_flash_attn, @@ -474,6 +474,22 @@ def test_flash_attn_2_equivalence(self): logits_fa = outputs_fa.hidden_states[-1] torch.testing.assert_close(logits_fa, logits, atol=3e-2, rtol=3e-2) + def test_causal_lm_can_accept_training_kwargs(self): + if not getattr(self.model_tester, "is_training", False): + self.skipTest(reason="ModelTester is not configured to run training tests") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + with tempfile.TemporaryDirectory() as tmpdir: + with torch.device(torch_device): + model_eager = AutoModelForCausalLM.from_config(config, dtype=torch.float32) + + model_eager.save_pretrained(tmpdir) + model = AutoModelForCausalLM.from_pretrained(tmpdir, dtype=torch.float32, device_map=torch_device) + inputs_dict["num_items_in_batch"] = torch.tensor(inputs_dict["input_ids"].shape[0]) + inputs_dict["labels"] = inputs_dict["input_ids"] + _ = model(**inputs_dict, return_dict=False) + def _config_supports_rope_scaling(config: PretrainedConfig) -> bool: """Returns whether a certain model config supports RoPE scaling parameterization.""" diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index e55c37eca800..dbeade214410 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -61,6 +61,7 @@ if is_torch_available(): import torch + import torch.nn.functional as F from transformers import ( AutoModelForCausalLM, @@ -70,6 +71,7 @@ AutoModelForVision2Seq, BartForConditionalGeneration, BartTokenizer, + DataCollatorWithFlattening, GPT2LMHeadModel, GPT2Tokenizer, ImageGPTForCausalImageModeling, @@ -1912,6 +1914,342 @@ def test_eager_matches_fa3_generate(self): """Tests that generate has equivalent outputs with FA3 and eager attention implementations.""" self._test_attention_implementation("flash_attention_3") + @require_flash_attn + @require_torch_gpu + @pytest.mark.flash_attn_test + def test_flash_attention_2_continue_generate_with_position_ids(self): + """ + Tests whether flash attention can continue its generation from given position ids. + + NOTE: This serves as regression check as we had instances where flash attention entered the varlen + path here. It should now always enter the base `flash_fn`. + """ + + max_new_tokens = 2 + for model_class in self.all_generative_model_classes: + if not model_class._supports_flash_attn: + self.skipTest(f"{model_class.__name__} does not support Flash Attention.") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if not hasattr(config.get_text_config(), "use_cache"): + self.skipTest(f"{model_class.__name__} doesn't support caching") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation="flash_attention_2", + ) + .to(torch_device) + .eval() + ) + + # Drop all keys except for `input_ids`. Hard to manipulate with multimodals/head_mask/etc + dummy_input_ids = inputs_dict["input_ids"] + dummy_position_ids = torch.arange(dummy_input_ids.shape[1], device=torch_device) + dummy_position_ids = dummy_position_ids.unsqueeze(0).repeat(dummy_input_ids.shape[0], 1) + + # Store cache for the input prompt + output = model(dummy_input_ids, position_ids=dummy_position_ids, use_cache=True) + if "past_key_values" not in output: + self.skipTest("This model doesn't return `past_key_values`") + + # create new input_ids and position_ids to continue generation re-using the cache + new_input_ids = output.logits[:, -1, :].float().argmax(-1)[:, None] + past_length = dummy_input_ids.shape[1] + position_ids = torch.arange(past_length, past_length + new_input_ids.shape[1], device=torch_device) + position_ids = position_ids.unsqueeze(0).repeat(new_input_ids.shape[0], 1) + + output = model( + input_ids=new_input_ids, + past_key_values=output.past_key_values, + position_ids=position_ids, + use_cache=True, + ) + next_token_logits = output.logits[:, -1, :].float() + + generate_kwargs = { + "pad_token_id": -1, + "eos_token_id": -1, + "forced_eos_token_id": None, + "use_cache": True, + "do_sample": False, + "return_dict_in_generate": True, + "output_logits": True, + "max_new_tokens": max_new_tokens, + } + generation_out = model.generate(dummy_input_ids, **generate_kwargs) + next_token_logits_from_generate = generation_out.logits[-1] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(next_token_logits_from_generate, next_token_logits, rtol=tol, atol=tol) + + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Tests that the given attention implementation can work with packed sequences and infers the mask + from position ids. This test requires the model to use new attention mask API which handles packing. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + + def test_eager_padding_matches_padding_free_with_position_ids(self): + self.attention_mask_padding_matches_padding_free_with_position_ids(attn_implementation="eager") + + def test_sdpa_padding_matches_padding_free_with_position_ids(self): + self.attention_mask_padding_matches_padding_free_with_position_ids(attn_implementation="sdpa") + + @require_flash_attn + @require_torch_gpu + @pytest.mark.flash_attn_test + @slow + def test_flash_attention_2_padding_matches_padding_free_with_position_ids(self): + self.attention_mask_padding_matches_padding_free_with_position_ids(attn_implementation="flash_attention_2") + + @require_flash_attn + @require_torch_gpu + @pytest.mark.flash_attn_test + @slow + def test_flash_attention_2_padding_matches_padding_free_with_position_ids_and_fa_kwargs(self): + self.attention_mask_padding_matches_padding_free_with_position_ids( + attn_implementation="flash_attention_2", fa_kwargs=True + ) + + @require_flash_attn_3 + @require_torch_gpu + @pytest.mark.flash_attn_3_test + @slow + def test_flash_attention_3_padding_matches_padding_free_with_position_ids(self): + self.attention_mask_padding_matches_padding_free_with_position_ids(attn_implementation="flash_attention_3") + + @require_flash_attn_3 + @require_torch_gpu + @pytest.mark.flash_attn_3_test + @slow + def test_flash_attention_3_padding_matches_padding_free_with_position_ids_and_fa_kwargs(self): + self.attention_mask_padding_matches_padding_free_with_position_ids( + attn_implementation="flash_attention_3", fa_kwargs=True + ) + + def _get_custom_4d_mask_test_data(self): + # Sequence in which all but the last token is the same + input_ids = torch.tensor( + [[10, 11, 12, 13], [10, 11, 12, 14], [10, 11, 12, 15]], device=torch_device, dtype=torch.int64 + ) + position_ids = torch.tensor([[0, 1, 2, 3]] * 3, device=torch_device, dtype=torch.int64) + + # Combining common prefix with the unique ending tokens: + input_ids_shared_prefix = torch.cat([input_ids[0][:-1], input_ids[:, -1]]).unsqueeze(0) + + # Creating a 4D mask where each of the last 3 tokens do not attend to each other. + mask_shared_prefix = torch.tensor( + [ + [ + [ + [1, 0, 0, 0, 0, 0], + [1, 1, 0, 0, 0, 0], + [1, 1, 1, 0, 0, 0], + [1, 1, 1, 1, 0, 0], + [1, 1, 1, 0, 1, 0], + [1, 1, 1, 0, 0, 1], + ] + ] + ], + ) + # inverting the attention mask + mask_dtype = torch.float32 + min_dtype = torch.finfo(mask_dtype).min + mask_shared_prefix = (mask_shared_prefix.eq(0.0)).to(dtype=mask_dtype, device=torch_device) * min_dtype + + # Creating a position_ids tensor. note the repeating figures in the end. + position_ids_shared_prefix = torch.tensor([[0, 1, 2, 3, 3, 3]], device=torch_device, dtype=torch.int64) + + return input_ids, position_ids, input_ids_shared_prefix, mask_shared_prefix, position_ids_shared_prefix + + def test_custom_4d_attention_mask(self): + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + set_model_tester_for_less_flaky_test(self) + + for model_class in self.all_generative_model_classes: + if not model_class._can_compile_fullgraph: + self.skipTest(f"{model_class.__name__} is not guaranteed to work with custom 4D attention masks") + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + set_config_for_less_flaky_test(config) + if getattr(config, "sliding_window", 0) is not None and getattr(config, "sliding_window", 0) > 0: + self.skipTest(f"{model_class.__name__} with sliding window attention is not supported by this test") + model = model_class(config).to(device=torch_device, dtype=torch.float32).eval() + set_model_for_less_flaky_test(model) + if "position_ids" not in inspect.signature(model.forward).parameters: + continue # model doesn't accept position ids and probably has special way to model positions + + ( + input_ids, + position_ids, + input_ids_shared_prefix, + mask_shared_prefix, + position_ids_shared_prefix, + ) = self._get_custom_4d_mask_test_data() + + logits = model.forward(input_ids, position_ids=position_ids).logits + # logits.shape == torch.Size([3, 4, ...]) + + logits_shared_prefix = model( + input_ids_shared_prefix, + attention_mask=mask_shared_prefix, + position_ids=position_ids_shared_prefix, + )[0] + # logits_shared_prefix.shape == torch.Size([1, 6, ...]) + + out_last_tokens = logits[:, -1, :] # last tokens in each batch line + out_shared_prefix_last_tokens = logits_shared_prefix[0, -3:, :] # last three tokens + + # comparing softmax-normalized logits: + normalized_0 = F.softmax(out_last_tokens, dim=-1) + normalized_1 = F.softmax(out_shared_prefix_last_tokens, dim=-1) + torch.testing.assert_close(normalized_0, normalized_1, rtol=1e-3, atol=1e-3) + + def test_forward_with_logits_to_keep(self): + for model_class in self.all_generative_model_classes: + if "logits_to_keep" not in set(inspect.signature(model_class.forward).parameters.keys()): + self.skipTest(reason="This model does not support `logits_to_keep` argument.") + + config, inputs = self.model_tester.prepare_config_and_inputs_for_common() + batch_size, sequence_length = inputs["input_ids"].shape[:2] + vocab_size = config.get_text_config().vocab_size + model = model_class(config).to(device=torch_device).eval() + # some models have labels but `logits_to_keep` should not be used in train mode + _ = inputs.pop("labels", None) + + # logits_to_keep=0 is a special case meaning "keep all logits" + all_logits = model(**inputs, logits_to_keep=0).logits + last_token_logits = model(**inputs, logits_to_keep=1).logits + + # Assert all shapes are correct + self.assertEqual(tuple(all_logits.shape), (batch_size, sequence_length, vocab_size)) + self.assertEqual(tuple(last_token_logits.shape), (batch_size, 1, vocab_size)) + + # Assert the last tokens are actually the same (except for the natural fluctuation due to order of FP ops) + torch.testing.assert_close(all_logits[:, -1:, :], last_token_logits, rtol=1e-5, atol=1e-5) + def _check_generate_outputs(self, output, config, use_cache=False, num_return_sequences=1, num_beams=1): input_batch_size = int(output.sequences.shape[0] / num_return_sequences) internal_batch_size = ( diff --git a/tests/test_modeling_common.py b/tests/test_modeling_common.py index fac305d59ee0..f4c890e3ce15 100755 --- a/tests/test_modeling_common.py +++ b/tests/test_modeling_common.py @@ -34,9 +34,7 @@ from transformers import ( AutoModel, - AutoModelForCausalLM, AutoModelForSequenceClassification, - DataCollatorWithFlattening, PretrainedConfig, PreTrainedModel, is_torch_available, @@ -125,7 +123,6 @@ if is_torch_available(): import torch - import torch.nn.functional as F from safetensors.torch import load_file as safe_load_file from safetensors.torch import save_file as safe_save_file from torch import nn @@ -247,6 +244,11 @@ def _can_output_attn(model): for model_class in self.all_model_classes: config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() set_config_for_less_flaky_test(config) + + # If it's a model with sliding window attention, let's test it with sliding window + if hasattr(config, "sliding_window"): + config.sliding_window = 2 + model = model_class(config) # TODO: standardize the interfaces for musicgen models, see other todo in this test if model.__class__.__name__ == "MusicgenMelodyForConditionalGeneration": @@ -1197,41 +1199,6 @@ def test_training(self): loss = model(**inputs).loss loss.backward() - def test_causal_lm_can_accept_kwargs(self): - if not getattr(self.model_tester, "is_training", False): - self.skipTest(reason="ModelTester is not configured to run training tests") - - valid_model_class = False - incompatible_models = ( - "MusicgenForCausalLM", - "MusicgenMelodyForCausalLM", - "MllamaForCausalLM", - "CpmAntForCausalLM", - "GotOcr2ForConditionalGeneration", - ) - for model_class in self.all_model_classes: - if ( - model_class.__name__ in get_values(MODEL_FOR_CAUSAL_LM_MAPPING_NAMES) - and model_class.__name__ not in incompatible_models - ): - valid_model_class = True - if not valid_model_class: - self.skipTest(reason="No causal lm model classes found") - for model_class in self.all_model_classes: - model_name = model_class.__name__ - if model_name in get_values(MODEL_FOR_CAUSAL_LM_MAPPING_NAMES) and model_name not in incompatible_models: - config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() - - with tempfile.TemporaryDirectory() as tmpdir: - with torch.device(torch_device): - model_eager = AutoModelForCausalLM.from_config(config, dtype=torch.float32) - - model_eager.save_pretrained(tmpdir) - model = AutoModelForCausalLM.from_pretrained(tmpdir, dtype=torch.float32, device_map=torch_device) - inputs_dict["num_items_in_batch"] = torch.tensor(inputs_dict["input_ids"].shape[0]) - inputs_dict["labels"] = inputs_dict["input_ids"] - _ = model(**inputs_dict, return_dict=False) - def test_training_gradient_checkpointing(self): # Scenario - 1 default behaviour self.check_training_gradient_checkpointing() @@ -2758,65 +2725,6 @@ def recursive_check(tuple_object, dict_object): model, tuple_inputs, dict_inputs, {"output_hidden_states": True, "output_attentions": True} ) - # Don't copy this method to model specific test file! - # TODO: remove this method once the issues are all fixed! - def _make_attention_mask_non_null(self, inputs_dict): - """Make sure no sequence has all zeros as attention mask""" - - for k in ["attention_mask", "encoder_attention_mask", "decoder_attention_mask"]: - if k in inputs_dict: - attention_mask = inputs_dict[k] - - # Make sure no all 0s attention masks - to avoid failure at this moment. - # Put `1` at the beginning of sequences to make it still work when combining causal attention masks. - # TODO: remove this line once a fix regarding large negative values for attention mask is done. - attention_mask = torch.cat( - [torch.ones_like(attention_mask[:, :1], dtype=attention_mask.dtype), attention_mask[:, 1:]], dim=-1 - ) - - # Here we make the first sequence with all 0s as attention mask. - # Currently, this will fail for `TFWav2Vec2Model`. This is caused by the different large negative - # values, like `1e-4`, `1e-9`, `1e-30` and `-inf` for attention mask across models/frameworks. - # TODO: enable this block once the large negative values thing is cleaned up. - # (see https://github.com/huggingface/transformers/issues/14859) - # attention_mask = torch.cat( - # [torch.zeros_like(attention_mask[:1], dtype=attention_mask.dtype), attention_mask[1:]], - # dim=0 - # ) - - inputs_dict[k] = attention_mask - - # Don't copy this method to model specific test file! - # TODO: remove this method once the issues are all fixed! - def _postprocessing_to_ignore_test_cases(self, tf_outputs, pt_outputs, model_class): - """For temporarily ignoring some failed test cases (issues to be fixed)""" - - tf_keys = {k for k, v in tf_outputs.items() if v is not None} - pt_keys = {k for k, v in pt_outputs.items() if v is not None} - - key_differences = tf_keys.symmetric_difference(pt_keys) - - if model_class.__name__ in [ - "FlaubertWithLMHeadModel", - "FunnelForPreTraining", - "ElectraForPreTraining", - "XLMWithLMHeadModel", - ]: - for k in key_differences: - if k in ["loss", "losses"]: - tf_keys.discard(k) - pt_keys.discard(k) - elif model_class.__name__.startswith("GPT2"): - # `TFGPT2` has `past_key_values` as a tensor while `GPT2` has it as a tuple. - tf_keys.discard("past_key_values") - pt_keys.discard("past_key_values") - - # create new outputs from the remaining fields - new_tf_outputs = type(tf_outputs)(**{k: tf_outputs[k] for k in tf_keys}) - new_pt_outputs = type(pt_outputs)(**{k: pt_outputs[k] for k in pt_keys}) - - return new_tf_outputs, new_pt_outputs - def test_inputs_embeds(self): config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() @@ -3485,7 +3393,7 @@ def _init_weights(self, module): ) def test_model_is_small(self): - # Just a consistency check to make sure we are not running tests on 80M parameter models. + # Just a consistency check to make sure we are not running tests on 1M parameter models. config, _ = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: @@ -3989,57 +3897,6 @@ def test_sdpa_can_compile_dynamic(self): with torch.no_grad(): _ = model(**inputs_dict) - def test_sdpa_matches_eager_sliding_window(self): - if not self.has_attentions: - self.skipTest(reason="Model architecture does not support attentions") - - WINDOW_ATTENTION_MODELS = ["mistral", "mixtral", "minimax", "qwen2", "qwen_moe", "starcoder2"] - - if len(self.all_generative_model_classes) == 0: - self.skipTest(f"No generative model classes for {self.__class__.__name__}") - - for model_class in self.all_generative_model_classes: - if model_class._supports_sdpa: - self.skipTest(reason="Model architecture does not support attentions") - config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() - - if config.model_type not in WINDOW_ATTENTION_MODELS: - self.skipTest(f"{config.model_type} does not use window attention") - - config.sliding_window = 2 - - dummy_input = inputs_dict[model_class.main_input_name] - attention_mask = inputs_dict["attention_mask"] - - self.assertTrue(dummy_input.ndim == 2) - self.assertTrue(dummy_input.shape[1] > 6) - - with tempfile.TemporaryDirectory() as tmpdir: - with torch.device(torch_device): - model_eager = AutoModelForCausalLM.from_config( - config, attn_implementation="eager", dtype=torch.float32 - ) - - model_eager.save_pretrained(tmpdir) - - with torch.device(torch_device): - model_sdpa = AutoModelForCausalLM.from_pretrained( - tmpdir, attn_implementation="sdpa", dtype=torch.float32 - ) - - model_eager = model_eager.eval() - model_sdpa = model_sdpa.eval() - - with torch.no_grad(): - with sdpa_kernel(enable_flash=False, enable_math=True, enable_mem_efficient=False): - res_eager = model_eager(**inputs_dict, return_dict=False)[0] - res_sdpa = model_sdpa(**inputs_dict, return_dict=False)[0] - - # Only non-padding tokens are expected to match. - self.assertTrue( - torch.allclose(res_eager[attention_mask == 1], res_sdpa[attention_mask == 1], rtol=1e-4, atol=1e-4) - ) - def flash_attn_can_dispatch_composite_models(self, attn_implementation: str): """ Tests if composite models can dispatch on flash attention if the sub-models support it. @@ -4123,7 +3980,7 @@ def test_flash_attn_2_fp32_ln(self): if not self.has_attentions: self.skipTest(reason="Model architecture does not support attentions") - for model_class in self.all_generative_model_classes: + for model_class in self.all_generative_model_classes: # TODO: this test should run on all classes instead if not model_class._supports_flash_attn: self.skipTest(f"{model_class.__name__} does not support Flash Attention 2") config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() @@ -4209,240 +4066,6 @@ def test_flash_attn_2_can_compile_with_attention_mask_None_without_graph_break(s assert not loss.isnan().any() - def attention_mask_padding_matches_padding_free_with_position_ids( - self, attn_implementation: str, fa_kwargs: bool = False - ): - """ - Tests that the given attention implementation can work with packed sequences and infers the mask - from position ids. This test requires the model to use new attention mask API which handles packing. - """ - if not self.has_attentions: - self.skipTest(reason="Model architecture does not support attentions") - - max_new_tokens = 30 - support_flag = { - "sdpa": "_supports_sdpa", - "flash_attention_2": "_supports_flash_attn", - "flash_attention_3": "_supports_flash_attn", - } - - for model_class in self.all_generative_model_classes: - if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): - self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") - - # can't infer if new attn mask API is supported by assume that only model with attention backend support it - if not model_class._supports_attention_backend: - self.skipTest(f"{model_class.__name__} does not support new attention mask API") - - if model_class._is_stateful: # non-transformer models most probably have no packing support - self.skipTest(f"{model_class.__name__} doesn't support packing!") - - config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() - if config.is_encoder_decoder: - self.skipTest("Model is an encoder-decoder") - - if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: - self.skipTest("Model dummy inputs should contain padding in their attention mask") - - if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: - self.skipTest("Model dummy inputs should contain text input ids") - - # make sure that all models have enough positions for generation - dummy_input_ids = inputs_dict["input_ids"] - if hasattr(config, "max_position_embeddings"): - config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 - - model = model_class(config) - if "position_ids" not in inspect.signature(model.forward).parameters: - self.skipTest("Model does not support position_ids") - - if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: - continue # this model doesn't accept position ids as input - - with tempfile.TemporaryDirectory() as tmpdirname: - model.save_pretrained(tmpdirname) - - # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc - inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} - - # Ensure left padding, to adapt for some models - if 0 in inputs_dict["attention_mask"][:, -1]: - inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) - dummy_attention_mask = inputs_dict["attention_mask"] - dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id - - model = ( - model_class.from_pretrained( - tmpdirname, - dtype=torch.bfloat16, - attn_implementation=attn_implementation, - ) - .to(torch_device) - .eval() - ) - - if fa_kwargs: - # flatten - features = [ - {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) - ] - - # add position_ids + fa_kwargs - data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) - batch = data_collator(features) - padfree_inputs_dict = { - k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() - } - else: - # create packed position_ids - position_ids = ( - torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) - .long() - .unsqueeze(0) - .to(torch_device) - ) - padfree_inputs_dict = { - "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), - "position_ids": position_ids, - } - - # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path - res_padded = model(**inputs_dict, use_cache=False) - res_padfree = model(**padfree_inputs_dict, use_cache=False) - - logits_padded = res_padded.logits[dummy_attention_mask.bool()] - logits_padfree = res_padfree.logits[0] - - # acceptable numerical instability - tol = torch.finfo(torch.bfloat16).eps - torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) - - def test_eager_padding_matches_padding_free_with_position_ids(self): - self.attention_mask_padding_matches_padding_free_with_position_ids(attn_implementation="eager") - - def test_sdpa_padding_matches_padding_free_with_position_ids(self): - self.attention_mask_padding_matches_padding_free_with_position_ids(attn_implementation="sdpa") - - @require_flash_attn - @require_torch_gpu - @mark.flash_attn_test - @slow - def test_flash_attention_2_padding_matches_padding_free_with_position_ids(self): - self.attention_mask_padding_matches_padding_free_with_position_ids(attn_implementation="flash_attention_2") - - @require_flash_attn - @require_torch_gpu - @mark.flash_attn_test - @slow - def test_flash_attention_2_padding_matches_padding_free_with_position_ids_and_fa_kwargs(self): - self.attention_mask_padding_matches_padding_free_with_position_ids( - attn_implementation="flash_attention_2", fa_kwargs=True - ) - - @require_flash_attn_3 - @require_torch_gpu - @mark.flash_attn_3_test - @slow - def test_flash_attention_3_padding_matches_padding_free_with_position_ids(self): - self.attention_mask_padding_matches_padding_free_with_position_ids(attn_implementation="flash_attention_3") - - @require_flash_attn_3 - @require_torch_gpu - @mark.flash_attn_3_test - @slow - def test_flash_attention_3_padding_matches_padding_free_with_position_ids_and_fa_kwargs(self): - self.attention_mask_padding_matches_padding_free_with_position_ids( - attn_implementation="flash_attention_3", fa_kwargs=True - ) - - @require_flash_attn - @require_torch_gpu - @mark.flash_attn_test - def test_flash_attention_2_continue_generate_with_position_ids(self): - """ - Tests whether flash attention can continue its generation from given position ids. - - NOTE: This serves as regression check as we had instances where flash attention entered the varlen - path here. It should now always enter the base `flash_fn`. - """ - - max_new_tokens = 2 - for model_class in self.all_generative_model_classes: - if not model_class._supports_flash_attn: - self.skipTest(f"{model_class.__name__} does not support Flash Attention.") - - config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() - if config.is_encoder_decoder: - self.skipTest("Model is an encoder-decoder") - - if not hasattr(config.get_text_config(), "use_cache"): - self.skipTest(f"{model_class.__name__} doesn't support caching") - - if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: - self.skipTest("Model dummy inputs should contain text input ids") - - # make sure that all models have enough positions for generation - dummy_input_ids = inputs_dict["input_ids"] - if hasattr(config, "max_position_embeddings"): - config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 - - model = model_class(config) - if "position_ids" not in inspect.signature(model.forward).parameters: - self.skipTest("Model does not support position_ids") - - with tempfile.TemporaryDirectory() as tmpdirname: - model.save_pretrained(tmpdirname) - model = ( - model_class.from_pretrained( - tmpdirname, - dtype=torch.bfloat16, - attn_implementation="flash_attention_2", - ) - .to(torch_device) - .eval() - ) - - # Drop all keys except for `input_ids`. Hard to manipulate with multimodals/head_mask/etc - dummy_input_ids = inputs_dict["input_ids"] - dummy_position_ids = torch.arange(dummy_input_ids.shape[1], device=torch_device) - dummy_position_ids = dummy_position_ids.unsqueeze(0).repeat(dummy_input_ids.shape[0], 1) - - # Store cache for the input prompt - output = model(dummy_input_ids, position_ids=dummy_position_ids, use_cache=True) - if "past_key_values" not in output: - self.skipTest("This model doesn't return `past_key_values`") - - # create new input_ids and position_ids to continue generation re-using the cache - new_input_ids = output.logits[:, -1, :].float().argmax(-1)[:, None] - past_length = dummy_input_ids.shape[1] - position_ids = torch.arange(past_length, past_length + new_input_ids.shape[1], device=torch_device) - position_ids = position_ids.unsqueeze(0).repeat(new_input_ids.shape[0], 1) - - output = model( - input_ids=new_input_ids, - past_key_values=output.past_key_values, - position_ids=position_ids, - use_cache=True, - ) - next_token_logits = output.logits[:, -1, :].float() - - generate_kwargs = { - "pad_token_id": -1, - "eos_token_id": -1, - "forced_eos_token_id": None, - "use_cache": True, - "do_sample": False, - "return_dict_in_generate": True, - "output_logits": True, - "max_new_tokens": max_new_tokens, - } - generation_out = model.generate(dummy_input_ids, **generate_kwargs) - next_token_logits_from_generate = generation_out.logits[-1] - - # acceptable numerical instability - tol = torch.finfo(torch.bfloat16).eps - torch.testing.assert_close(next_token_logits_from_generate, next_token_logits, rtol=tol, atol=tol) - def flash_attn_from_config(self, attn_implementation: str): r""" Tests if the model can be loaded with `attn_implementation` from the config and if the @@ -4451,7 +4074,7 @@ def flash_attn_from_config(self, attn_implementation: str): if not self.has_attentions: self.skipTest(reason="Model architecture does not support attentions") - for model_class in self.all_generative_model_classes: + for model_class in self.all_generative_model_classes: # TODO: this test should run on all classes instead if not model_class._supports_flash_attn: self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") @@ -4497,41 +4120,6 @@ def test_flash_attn_2_from_config(self): def test_flash_attn_3_from_config(self): self.flash_attn_from_config(attn_implementation="flash_attention_3") - def _get_custom_4d_mask_test_data(self): - # Sequence in which all but the last token is the same - input_ids = torch.tensor( - [[10, 11, 12, 13], [10, 11, 12, 14], [10, 11, 12, 15]], device=torch_device, dtype=torch.int64 - ) - position_ids = torch.tensor([[0, 1, 2, 3]] * 3, device=torch_device, dtype=torch.int64) - - # Combining common prefix with the unique ending tokens: - input_ids_shared_prefix = torch.cat([input_ids[0][:-1], input_ids[:, -1]]).unsqueeze(0) - - # Creating a 4D mask where each of the last 3 tokens do not attend to each other. - mask_shared_prefix = torch.tensor( - [ - [ - [ - [1, 0, 0, 0, 0, 0], - [1, 1, 0, 0, 0, 0], - [1, 1, 1, 0, 0, 0], - [1, 1, 1, 1, 0, 0], - [1, 1, 1, 0, 1, 0], - [1, 1, 1, 0, 0, 1], - ] - ] - ], - ) - # inverting the attention mask - mask_dtype = torch.float32 - min_dtype = torch.finfo(mask_dtype).min - mask_shared_prefix = (mask_shared_prefix.eq(0.0)).to(dtype=mask_dtype, device=torch_device) * min_dtype - - # Creating a position_ids tensor. note the repeating figures in the end. - position_ids_shared_prefix = torch.tensor([[0, 1, 2, 3, 3, 3]], device=torch_device, dtype=torch.int64) - - return input_ids, position_ids, input_ids_shared_prefix, mask_shared_prefix, position_ids_shared_prefix - def test_sliding_window_mask(self): """Tests that we can control the sliding window attention behavior of a model.""" config, inputs = self.model_tester.prepare_config_and_inputs_for_common() @@ -4586,58 +4174,6 @@ def test_sliding_window_mask(self): for layer_attention in attentions_not_sliding: self.assertFalse((layer_attention[:, :, ~sliding_mask] == 0).all().item()) - def test_custom_4d_attention_mask(self): - if not self.has_attentions: - self.skipTest(reason="Model architecture does not support attentions") - - if len(self.all_generative_model_classes) == 0: - self.skipTest( - reason="Model architecture has no generative classes, and thus not necessarily supporting 4D masks" - ) - - set_model_tester_for_less_flaky_test(self) - - for model_class in self.all_generative_model_classes: - if not model_class._can_compile_fullgraph: - self.skipTest(f"{model_class.__name__} is not guaranteed to work with custom 4D attention masks") - config, _ = self.model_tester.prepare_config_and_inputs_for_common() - set_config_for_less_flaky_test(config) - if getattr(config, "sliding_window", 0) is not None and getattr(config, "sliding_window", 0) > 0: - self.skipTest(f"{model_class.__name__} with sliding window attention is not supported by this test") - model = model_class(config).to(device=torch_device, dtype=torch.float32).eval() - set_model_for_less_flaky_test(model) - if "position_ids" not in inspect.signature(model.forward).parameters: - continue # model doesn't accept position ids and probably has special way to model positions - - if "position_ids" not in inspect.signature(model.forward).parameters: - continue # this model doesn't accept position ids as input - - ( - input_ids, - position_ids, - input_ids_shared_prefix, - mask_shared_prefix, - position_ids_shared_prefix, - ) = self._get_custom_4d_mask_test_data() - - logits = model.forward(input_ids, position_ids=position_ids).logits - # logits.shape == torch.Size([3, 4, ...]) - - logits_shared_prefix = model( - input_ids_shared_prefix, - attention_mask=mask_shared_prefix, - position_ids=position_ids_shared_prefix, - )[0] - # logits_shared_prefix.shape == torch.Size([1, 6, ...]) - - out_last_tokens = logits[:, -1, :] # last tokens in each batch line - out_shared_prefix_last_tokens = logits_shared_prefix[0, -3:, :] # last three tokens - - # comparing softmax-normalized logits: - normalized_0 = F.softmax(out_last_tokens, dim=-1) - normalized_1 = F.softmax(out_shared_prefix_last_tokens, dim=-1) - torch.testing.assert_close(normalized_0, normalized_1, rtol=1e-3, atol=1e-3) - @slow @require_torch_accelerator @pytest.mark.torch_compile_test @@ -4688,29 +4224,6 @@ def test_torch_compile_for_training(self): for name, param in model._orig_mod.named_parameters(): torch.testing.assert_close(param.grad.detach().cpu(), params[name], rtol=1e-4, atol=1e-4) - def test_forward_with_logits_to_keep(self): - for model_class in self.all_generative_model_classes: - if "logits_to_keep" not in set(inspect.signature(model_class.forward).parameters.keys()): - self.skipTest(reason="This model does not support `logits_to_keep` argument.") - - config, inputs = self.model_tester.prepare_config_and_inputs_for_common() - batch_size, sequence_length = inputs["input_ids"].shape[:2] - vocab_size = config.get_text_config().vocab_size - model = model_class(config).to(device=torch_device).eval() - # some models have labels but `logits_to_keep` should not be used in train mode - _ = inputs.pop("labels", None) - - # logits_to_keep=0 is a special case meaning "keep all logits" - all_logits = model(**inputs, logits_to_keep=0).logits - last_token_logits = model(**inputs, logits_to_keep=1).logits - - # Assert all shapes are correct - self.assertEqual(tuple(all_logits.shape), (batch_size, sequence_length, vocab_size)) - self.assertEqual(tuple(last_token_logits.shape), (batch_size, 1, vocab_size)) - - # Assert the last tokens are actually the same (except for the natural fluctuation due to order of FP ops) - torch.testing.assert_close(all_logits[:, -1:, :], last_token_logits, rtol=1e-5, atol=1e-5) - @slow @require_torch_greater_or_equal("2.5") @pytest.mark.torch_export_test From a7900053d825274f88c911419d85bf6f11592e7c Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Fri, 12 Sep 2025 17:24:22 +0100 Subject: [PATCH 036/204] [generate] Always use decoder config to init cache (#40772) * mega derp * fix * always use the decoder --- src/transformers/cache_utils.py | 4 ++-- src/transformers/generation/utils.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/transformers/cache_utils.py b/src/transformers/cache_utils.py index 9591503d975b..d7b0fe6e1f83 100644 --- a/src/transformers/cache_utils.py +++ b/src/transformers/cache_utils.py @@ -1010,7 +1010,7 @@ def __init__( layers = [] # If a config is passed, use it to infer the layer types and initialize accordingly if config is not None: - config = config.get_text_config() + config = config.get_text_config(decoder=True) sliding_window = getattr(config, "sliding_window", None) or getattr(config, "attention_chunk_size", None) layer_types = getattr(config, "layer_types", None) if layer_types is None: @@ -1122,7 +1122,7 @@ def __init__( offload_only_non_sliding: bool = True, **kwargs, ): - config = config.get_text_config() + config = config.get_text_config(decoder=True) layer_types = getattr(config, "layer_types", None) # If `layer_types` is not explicitly provided, infer if the model is fully sliding if layer_types is None: diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index 20be80822fdb..85a238c81b32 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -1871,7 +1871,7 @@ def _get_cache(self, cache_implementation: str, batch_size: int, max_cache_len: self._cache = StaticCache(**self_attention_cache_kwargs) if requires_cross_attention_cache: cross_attention_cache_kwargs = { - "config": self.config.get_text_config(encoder=True), + "config": self.config.get_text_config(decoder=True), "max_cache_len": model_kwargs["encoder_outputs"][0].shape[1], "offloading": offload_cache, } @@ -1976,7 +1976,7 @@ def _prepare_cache_for_generation( ): dynamic_cache_kwargs = {} else: - dynamic_cache_kwargs = {"config": self.config} + dynamic_cache_kwargs = {"config": self.config.get_text_config(decoder=True)} if generation_config.cache_implementation is not None: if generation_config.cache_implementation in ALL_STATIC_CACHE_IMPLEMENTATIONS: if generation_config.cache_implementation in DEPRECATED_STATIC_CACHE_IMPLEMENTATIONS: From e1356608f4c6ecbfc07f162375ab7f721c85e99f Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Sat, 13 Sep 2025 08:49:19 +0800 Subject: [PATCH 037/204] Use checkpoint in auto_class_docstring (#40844) Signed-off-by: Yuanyuan Chen --- src/transformers/utils/auto_docstring.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/transformers/utils/auto_docstring.py b/src/transformers/utils/auto_docstring.py index c259d2035573..a9d9a8cba788 100644 --- a/src/transformers/utils/auto_docstring.py +++ b/src/transformers/utils/auto_docstring.py @@ -1098,7 +1098,7 @@ def contains_type(type_hint, target_type) -> tuple[bool, Optional[object]]: if args == (): try: return issubclass(type_hint, target_type), type_hint - except Exception as _: + except Exception: return issubclass(type(type_hint), target_type), type_hint found_type_tuple = [contains_type(arg, target_type)[0] for arg in args] found_type = any(found_type_tuple) @@ -1112,6 +1112,8 @@ def get_model_name(obj): Get the model name from the file path of the object. """ path = inspect.getsourcefile(obj) + if path is None: + return None if path.split(os.path.sep)[-3] != "models": return None file_name = path.split(os.path.sep)[-1] @@ -1783,9 +1785,10 @@ def auto_class_docstring(cls, custom_intro=None, custom_args=None, checkpoint=No is_dataclass = False docstring_init = "" + docstring_args = "" if "PreTrainedModel" in (x.__name__ for x in cls.__mro__): docstring_init = auto_method_docstring( - cls.__init__, parent_class=cls, custom_args=custom_args + cls.__init__, parent_class=cls, custom_args=custom_args, checkpoint=checkpoint ).__doc__.replace("Args:", "Parameters:") elif "ModelOutput" in (x.__name__ for x in cls.__mro__): # We have a data class @@ -1797,6 +1800,7 @@ def auto_class_docstring(cls, custom_intro=None, custom_args=None, checkpoint=No cls.__init__, parent_class=cls, custom_args=custom_args, + checkpoint=checkpoint, source_args_dict=get_args_doc_from_source(ModelOutputArgs), ).__doc__ indent_level = get_indent_level(cls) @@ -1836,7 +1840,7 @@ def auto_class_docstring(cls, custom_intro=None, custom_args=None, checkpoint=No docstring += docstring_args if docstring_args else "\nArgs:\n" source_args_dict = get_args_doc_from_source(ModelOutputArgs) doc_class = cls.__doc__ if cls.__doc__ else "" - documented_kwargs, _ = parse_docstring(doc_class) + documented_kwargs = parse_docstring(doc_class)[0] for param_name, param_type_annotation in cls.__annotations__.items(): param_type = str(param_type_annotation) optional = False From c27433080ed9f44dff24ce20a016a0275ee5beec Mon Sep 17 00:00:00 2001 From: Albert Villanova del Moral <8515462+albertvillanova@users.noreply.github.com> Date: Sun, 14 Sep 2025 17:35:42 +0200 Subject: [PATCH 038/204] Fix TrainingArguments.parallelism_config NameError with accelerate<1.10.1 (#40818) Fix ParallelismConfig type for accelerate < 1.10.1 Co-authored-by: Marc Sun <57196510+SunMarc@users.noreply.github.com> --- src/transformers/training_args.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/transformers/training_args.py b/src/transformers/training_args.py index 19cfadb992f1..5219feb22023 100644 --- a/src/transformers/training_args.py +++ b/src/transformers/training_args.py @@ -77,8 +77,10 @@ from .trainer_pt_utils import AcceleratorConfig - if is_accelerate_available("1.10.1"): - from accelerate.parallelism_config import ParallelismConfig +if is_accelerate_available("1.10.1"): + from accelerate.parallelism_config import ParallelismConfig +else: + ParallelismConfig = Any if is_torch_xla_available(): import torch_xla.core.xla_model as xm @@ -1264,7 +1266,7 @@ class TrainingArguments: ) }, ) - parallelism_config: Optional["ParallelismConfig"] = field( + parallelism_config: Optional[ParallelismConfig] = field( default=None, metadata={"help": ("Parallelism configuration for the training run. Requires Accelerate `1.10.1`")}, ) From 33c51a8bfc09ffa36fd05fb22e3b68106501cdcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Hadnagy?= Date: Sun, 14 Sep 2025 18:42:49 +0200 Subject: [PATCH 039/204] Redirect MI355 CI results to dummy dataset (#40862) --- .github/workflows/self-scheduled-amd-mi355-caller.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/self-scheduled-amd-mi355-caller.yml b/.github/workflows/self-scheduled-amd-mi355-caller.yml index bd2fde3b0529..d7061f433569 100644 --- a/.github/workflows/self-scheduled-amd-mi355-caller.yml +++ b/.github/workflows/self-scheduled-amd-mi355-caller.yml @@ -23,7 +23,7 @@ jobs: runner_scale_set: amd-mi355-ci docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: optimum-amd/transformers_daily_ci + report_repo_id: hf-transformers-bot/transformers-ci-dummy secrets: inherit torch-pipeline: @@ -35,7 +35,7 @@ jobs: runner_scale_set: amd-mi355-ci docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: optimum-amd/transformers_daily_ci + report_repo_id: hf-transformers-bot/transformers-ci-dummy secrets: inherit example-ci: @@ -47,7 +47,7 @@ jobs: runner_scale_set: amd-mi355-ci docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: optimum-amd/transformers_daily_ci + report_repo_id: hf-transformers-bot/transformers-ci-dummy secrets: inherit deepspeed-ci: @@ -59,5 +59,5 @@ jobs: runner_scale_set: amd-mi355-ci docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: optimum-amd/transformers_daily_ci + report_repo_id: hf-transformers-bot/transformers-ci-dummy secrets: inherit From c8416c8191bdf2dce16d34de4a05b2c08a1e476e Mon Sep 17 00:00:00 2001 From: Grzegorz Kwasniewski <213329731+greg-kwasniewski1@users.noreply.github.com> Date: Mon, 15 Sep 2025 10:46:32 +0200 Subject: [PATCH 040/204] [Bug fix #40813] Fix base_model_tp_plan of Starcoder2 model. (#40814) Signed-off-by: greg-kwasniewski1 <213329731+greg-kwasniewski1@users.noreply.github.com> --- src/transformers/models/starcoder2/configuration_starcoder2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/models/starcoder2/configuration_starcoder2.py b/src/transformers/models/starcoder2/configuration_starcoder2.py index 795fcb4696b8..a700b4f42548 100644 --- a/src/transformers/models/starcoder2/configuration_starcoder2.py +++ b/src/transformers/models/starcoder2/configuration_starcoder2.py @@ -141,7 +141,7 @@ class Starcoder2Config(PretrainedConfig): "layers.*.self_attn.v_proj": "colwise", "layers.*.self_attn.o_proj": "rowwise", "layers.*.mlp.c_fc": "colwise", - "layers.*.mlp.c_proj": "colwise", + "layers.*.mlp.c_proj": "rowwise", } base_model_pp_plan = { "embed_tokens": (["input_ids"], ["inputs_embeds"]), From 6cf9c59cc2cff09ded4f57fb9f67c373db965eba Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Mon, 15 Sep 2025 09:52:32 +0100 Subject: [PATCH 041/204] [docstrings / type hints] Update outdated annotations for `past_key_values` (#40803) * some fixes * nits * indentation * indentation * a bunch of type hints * bulk changes --- src/transformers/generation/utils.py | 16 ++++---- src/transformers/models/aria/modeling_aria.py | 8 ++-- .../models/autoformer/modeling_autoformer.py | 31 ++++++-------- .../models/aya_vision/modeling_aya_vision.py | 8 ++-- src/transformers/models/bark/modeling_bark.py | 4 +- src/transformers/models/bart/modeling_bart.py | 6 +-- src/transformers/models/bert/modeling_bert.py | 6 +-- .../modeling_bert_generation.py | 6 +-- .../models/big_bird/modeling_big_bird.py | 4 +- .../modeling_bigbird_pegasus.py | 8 ++-- .../models/biogpt/modeling_biogpt.py | 10 ++--- .../models/biogpt/modular_biogpt.py | 10 ++--- .../models/blenderbot/modeling_blenderbot.py | 6 +-- .../modeling_blenderbot_small.py | 6 +-- .../models/blip/modeling_blip_text.py | 10 ++--- .../bridgetower/modeling_bridgetower.py | 4 +- .../models/camembert/modeling_camembert.py | 6 +-- .../models/chameleon/modeling_chameleon.py | 4 +- .../chinese_clip/modeling_chinese_clip.py | 3 +- src/transformers/models/clvp/modeling_clvp.py | 6 +-- .../models/cohere/modeling_cohere.py | 2 +- .../models/cohere/modular_cohere.py | 2 +- .../models/cohere2/modeling_cohere2.py | 2 +- .../cohere2_vision/modeling_cohere2_vision.py | 8 ++-- .../models/colpali/modeling_colpali.py | 7 ++-- .../models/colqwen2/modeling_colqwen2.py | 7 ++-- .../models/colqwen2/modular_colqwen2.py | 5 +-- .../models/cpmant/modeling_cpmant.py | 12 +++--- src/transformers/models/csm/generation_csm.py | 2 +- src/transformers/models/csm/modeling_csm.py | 12 +++--- src/transformers/models/csm/modular_csm.py | 12 +++--- src/transformers/models/ctrl/modeling_ctrl.py | 8 ++-- .../models/data2vec/modeling_data2vec_text.py | 6 +-- src/transformers/models/dbrx/modeling_dbrx.py | 2 +- .../modeling_decision_transformer.py | 2 +- .../deepseek_vl/modeling_deepseek_vl.py | 12 ++---- .../modeling_deepseek_vl_hybrid.py | 12 ++---- .../deprecated/ernie_m/modeling_ernie_m.py | 13 +++--- .../modeling_gptsan_japanese.py | 13 +++--- .../models/deprecated/mega/modeling_mega.py | 11 ++--- .../models/deprecated/nezha/modeling_nezha.py | 11 ++--- .../open_llama/modeling_open_llama.py | 11 ++--- .../deprecated/qdqbert/modeling_qdqbert.py | 3 +- .../models/deprecated/realm/modeling_realm.py | 9 +++-- .../modeling_speech_to_text_2.py | 7 ++-- .../modeling_trajectory_transformer.py | 5 ++- .../xlm_prophetnet/modeling_xlm_prophetnet.py | 21 +++++----- src/transformers/models/doge/modeling_doge.py | 4 +- src/transformers/models/doge/modular_doge.py | 4 +- .../models/electra/modeling_electra.py | 6 +-- .../modeling_encoder_decoder.py | 3 +- .../models/ernie/modeling_ernie.py | 6 +-- .../ernie4_5_moe/modeling_ernie4_5_moe.py | 4 +- .../models/falcon/modeling_falcon.py | 4 +- src/transformers/models/fsmt/modeling_fsmt.py | 6 +-- .../models/gemma3/modeling_gemma3.py | 15 ++----- .../models/gemma3/modular_gemma3.py | 4 +- .../models/gemma3n/modeling_gemma3n.py | 16 ++++---- .../models/gemma3n/modular_gemma3n.py | 14 +++---- .../models/glm4v/modeling_glm4v.py | 18 ++++----- .../models/glm4v/modular_glm4v.py | 8 ++-- .../models/glm4v_moe/modeling_glm4v_moe.py | 16 ++++---- .../models/got_ocr2/modeling_got_ocr2.py | 8 ++-- src/transformers/models/gpt2/modeling_gpt2.py | 17 ++++---- .../gpt_bigcode/modeling_gpt_bigcode.py | 8 ++-- .../models/gpt_oss/modeling_gpt_oss.py | 2 +- .../models/gpt_oss/modular_gpt_oss.py | 2 +- src/transformers/models/gptj/modeling_gptj.py | 2 +- .../models/granite/modeling_granite.py | 2 +- .../models/granite/modular_granite.py | 2 +- .../granite_speech/modeling_granite_speech.py | 5 +-- .../models/granitemoe/modeling_granitemoe.py | 2 +- .../modeling_granitemoehybrid.py | 2 +- .../modular_granitemoehybrid.py | 2 +- .../modeling_granitemoeshared.py | 2 +- .../modular_granitemoeshared.py | 2 +- .../models/idefics/modeling_idefics.py | 18 ++++----- .../models/idefics2/modeling_idefics2.py | 19 +++++---- .../models/idefics3/modeling_idefics3.py | 14 +++---- .../models/imagegpt/modeling_imagegpt.py | 6 +-- .../models/informer/modeling_informer.py | 16 ++++---- .../models/informer/modular_informer.py | 4 +- .../models/internvl/modeling_internvl.py | 8 ++-- .../models/janus/modeling_janus.py | 12 ++---- .../models/jetmoe/modeling_jetmoe.py | 2 +- .../models/kosmos2/modeling_kosmos2.py | 28 +++++-------- .../models/kosmos2_5/modeling_kosmos2_5.py | 20 ++++------ .../modeling_kyutai_speech_to_text.py | 2 +- src/transformers/models/led/modeling_led.py | 40 ++++++++----------- src/transformers/models/lfm2/modeling_lfm2.py | 2 +- src/transformers/models/lfm2/modular_lfm2.py | 2 +- .../models/llama4/modeling_llama4.py | 7 ++-- .../models/llava/modeling_llava.py | 8 ++-- .../models/llava_next/modeling_llava_next.py | 8 ++-- .../modeling_llava_next_video.py | 8 ++-- .../modular_llava_next_video.py | 6 +-- .../modeling_llava_onevision.py | 8 ++-- .../models/m2m_100/modeling_m2m_100.py | 6 +-- .../models/marian/modeling_marian.py | 6 +-- .../models/mbart/modeling_mbart.py | 6 +-- .../megatron_bert/modeling_megatron_bert.py | 6 +-- src/transformers/models/mimi/modeling_mimi.py | 17 ++------ .../models/minimax/modeling_minimax.py | 4 +- .../models/minimax/modular_minimax.py | 4 +- .../models/mistral3/modeling_mistral3.py | 8 ++-- .../models/mixtral/modeling_mixtral.py | 2 +- .../models/mixtral/modular_mixtral.py | 2 +- .../models/mllama/modeling_mllama.py | 2 +- .../models/moshi/modeling_moshi.py | 35 +++++----------- src/transformers/models/mpt/modeling_mpt.py | 8 ++-- .../models/musicgen/modeling_musicgen.py | 10 ++--- .../modeling_musicgen_melody.py | 17 ++++---- src/transformers/models/mvp/modeling_mvp.py | 16 ++++---- .../models/nemotron/modeling_nemotron.py | 2 +- .../models/nllb_moe/modeling_nllb_moe.py | 14 +++---- .../models/olmoe/modeling_olmoe.py | 2 +- src/transformers/models/opt/modeling_opt.py | 17 ++++---- .../models/ovis2/modeling_ovis2.py | 13 +++--- .../models/ovis2/modular_ovis2.py | 5 ++- .../models/paligemma/modeling_paligemma.py | 15 ++----- .../models/pegasus/modeling_pegasus.py | 10 ++--- .../models/pegasus_x/modeling_pegasus_x.py | 10 ++--- .../perception_lm/modeling_perception_lm.py | 13 +++--- .../perception_lm/modular_perception_lm.py | 11 +++-- .../models/persimmon/modeling_persimmon.py | 4 +- src/transformers/models/phi/modeling_phi.py | 2 +- src/transformers/models/phi/modular_phi.py | 2 +- .../models/phimoe/modeling_phimoe.py | 4 +- .../models/plbart/modeling_plbart.py | 6 +-- .../models/prophetnet/modeling_prophetnet.py | 38 ++++++++---------- .../qwen2_5_omni/modeling_qwen2_5_omni.py | 14 +++---- .../qwen2_5_omni/modular_qwen2_5_omni.py | 10 ++--- .../models/qwen2_5_vl/modeling_qwen2_5_vl.py | 14 +++---- .../models/qwen2_moe/modeling_qwen2_moe.py | 4 +- .../models/qwen2_vl/modeling_qwen2_vl.py | 14 +++---- .../models/qwen3_moe/modeling_qwen3_moe.py | 4 +- .../models/qwen3_moe/modular_qwen3_moe.py | 2 +- .../models/qwen3_next/modeling_qwen3_next.py | 4 +- .../models/qwen3_next/modular_qwen3_next.py | 2 +- src/transformers/models/rag/modeling_rag.py | 6 +-- .../models/rembert/modeling_rembert.py | 6 +-- .../models/roberta/modeling_roberta.py | 6 +-- .../modeling_roberta_prelayernorm.py | 6 +-- .../models/roc_bert/modeling_roc_bert.py | 6 +-- .../models/roformer/modeling_roformer.py | 4 +- .../seamless_m4t/modeling_seamless_m4t.py | 18 ++++----- .../modeling_seamless_m4t_v2.py | 14 +++---- .../shieldgemma2/modeling_shieldgemma2.py | 2 +- .../models/smolvlm/modeling_smolvlm.py | 14 +++---- .../modeling_speech_encoder_decoder.py | 3 +- .../speech_to_text/modeling_speech_to_text.py | 12 +++--- .../models/speecht5/modeling_speecht5.py | 24 +++++------ .../models/stablelm/modeling_stablelm.py | 4 +- .../modeling_time_series_transformer.py | 14 +++---- .../models/trocr/modeling_trocr.py | 10 ++--- src/transformers/models/udop/modeling_udop.py | 7 ++-- src/transformers/models/umt5/modeling_umt5.py | 2 +- .../video_llava/modeling_video_llava.py | 10 ++--- .../models/vipllava/modeling_vipllava.py | 8 ++-- .../modeling_vision_encoder_decoder.py | 3 +- .../models/whisper/modeling_whisper.py | 13 +----- src/transformers/models/xglm/modeling_xglm.py | 6 +-- .../xlm_roberta/modeling_xlm_roberta.py | 6 +-- .../xlm_roberta_xl/modeling_xlm_roberta_xl.py | 4 +- src/transformers/models/xmod/modeling_xmod.py | 6 +-- 165 files changed, 613 insertions(+), 789 deletions(-) diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index 85a238c81b32..a885a4c716e6 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -167,7 +167,7 @@ class GenerateDecoderOnlyOutput(ModelOutput): hidden_states (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `output_hidden_states=True`): Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of `torch.FloatTensor` of shape `(batch_size, generated_length, hidden_size)`. - past_key_values (`tuple(tuple(torch.FloatTensor)))`, *optional*, returned when `use_cache=True`): + past_key_values (`Cache`, *optional*, returned when `use_cache=True`): Returns the model cache, used to speed up decoding. Different models have a different cache format, check the model's documentation. Usually, a [`~cache_utils.Cache`] instance. """ @@ -177,7 +177,7 @@ class GenerateDecoderOnlyOutput(ModelOutput): logits: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[tuple[torch.FloatTensor]]] = None hidden_states: Optional[tuple[tuple[torch.FloatTensor]]] = None - past_key_values: Optional[tuple[tuple[tuple[torch.FloatTensor]]]] = None + past_key_values: Optional[Cache] = None @dataclass @@ -212,7 +212,7 @@ class GenerateEncoderDecoderOutput(ModelOutput): decoder_hidden_states (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `output_hidden_states=True`): Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of `torch.FloatTensor` of shape `(batch_size, generated_length, hidden_size)`. - past_key_values (`tuple(tuple(torch.FloatTensor)))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + past_key_values (`Cache`, *optional*, returned when `use_cache=True`): Returns the model cache, used to speed up decoding. Different models have a different cache format, check the model's documentation. Usually, a [`~cache_utils.Cache`] instance. """ @@ -225,7 +225,7 @@ class GenerateEncoderDecoderOutput(ModelOutput): decoder_attentions: Optional[tuple[tuple[torch.FloatTensor]]] = None cross_attentions: Optional[tuple[tuple[torch.FloatTensor]]] = None decoder_hidden_states: Optional[tuple[tuple[torch.FloatTensor]]] = None - past_key_values: Optional[tuple[tuple[tuple[torch.FloatTensor]]]] = None + past_key_values: Optional[Cache] = None @dataclass @@ -257,7 +257,7 @@ class GenerateBeamDecoderOnlyOutput(ModelOutput): hidden_states (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `output_hidden_states=True`): Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of `torch.FloatTensor` of shape `(batch_size*num_beams*num_return_sequences, generated_length, hidden_size)`. - past_key_values (`tuple(tuple(torch.FloatTensor)))`, *optional*, returned when `use_cache=True`): + past_key_values (`Cache`, *optional*, returned when `use_cache=True`): Returns the model cache, used to speed up decoding. Different models have a different cache format, check the model's documentation. Usually, a [`~cache_utils.Cache`] instance. """ @@ -269,7 +269,7 @@ class GenerateBeamDecoderOnlyOutput(ModelOutput): beam_indices: Optional[torch.LongTensor] = None attentions: Optional[tuple[tuple[torch.FloatTensor]]] = None hidden_states: Optional[tuple[tuple[torch.FloatTensor]]] = None - past_key_values: Optional[tuple[tuple[tuple[torch.FloatTensor]]]] = None + past_key_values: Optional[Cache] = None @dataclass @@ -311,7 +311,7 @@ class GenerateBeamEncoderDecoderOutput(ModelOutput): decoder_hidden_states (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `output_hidden_states=True`): Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of `torch.FloatTensor` of shape `(batch_size*num_beams*num_return_sequences, generated_length, hidden_size)`. - past_key_values (`tuple(tuple(torch.FloatTensor)))`, *optional*, returned when `use_cache=True`): + past_key_values (`Cache`, *optional*, returned when `use_cache=True`): Returns the model cache, used to speed up decoding. Different models have a different cache format, check the model's documentation. Usually, a [`~cache_utils.Cache`] instance. """ @@ -326,7 +326,7 @@ class GenerateBeamEncoderDecoderOutput(ModelOutput): decoder_attentions: Optional[tuple[tuple[torch.FloatTensor]]] = None cross_attentions: Optional[tuple[tuple[torch.FloatTensor]]] = None decoder_hidden_states: Optional[tuple[tuple[torch.FloatTensor]]] = None - past_key_values: Optional[tuple[tuple[tuple[torch.FloatTensor]]]] = None + past_key_values: Optional[Cache] = None # TODO (joao): remove the equivalent classes and typing shortcuts below in v5 diff --git a/src/transformers/models/aria/modeling_aria.py b/src/transformers/models/aria/modeling_aria.py index bccb7dff9e92..f3261909dd03 100644 --- a/src/transformers/models/aria/modeling_aria.py +++ b/src/transformers/models/aria/modeling_aria.py @@ -873,8 +873,7 @@ class AriaCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -885,7 +884,7 @@ class AriaCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None @@ -900,8 +899,7 @@ class AriaCausalLMOutputWithPast(ModelOutput): class AriaModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/autoformer/modeling_autoformer.py b/src/transformers/models/autoformer/modeling_autoformer.py index f3a62be4b1d0..efa952a5a28b 100644 --- a/src/transformers/models/autoformer/modeling_autoformer.py +++ b/src/transformers/models/autoformer/modeling_autoformer.py @@ -62,11 +62,8 @@ class AutoFormerDecoderOutput(ModelOutput): hidden_size)` is output. trend (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): Trend tensor for each time series. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` @@ -81,7 +78,7 @@ class AutoFormerDecoderOutput(ModelOutput): last_hidden_state: Optional[torch.FloatTensor] = None trend: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None cross_attentions: Optional[tuple[torch.FloatTensor]] = None @@ -102,10 +99,8 @@ class AutoformerModelOutput(ModelOutput): hidden_size)` is output. trend (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): Trend tensor for each time series. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape - `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -121,7 +116,7 @@ class AutoformerModelOutput(ModelOutput): last_hidden_state: Optional[torch.FloatTensor] = None trend: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None decoder_hidden_states: Optional[tuple[torch.FloatTensor]] = None decoder_attentions: Optional[tuple[torch.FloatTensor]] = None cross_attentions: Optional[tuple[torch.FloatTensor]] = None @@ -781,7 +776,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -1064,7 +1059,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -1107,10 +1102,8 @@ def forward( - 1 indicates the head is **not masked**, - 0 indicates the head is **masked**. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1440,7 +1433,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[list[torch.FloatTensor]] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, output_hidden_states: Optional[bool] = None, output_attentions: Optional[bool] = None, use_cache: Optional[bool] = None, @@ -1708,7 +1701,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[list[torch.FloatTensor]] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, output_hidden_states: Optional[bool] = None, output_attentions: Optional[bool] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/aya_vision/modeling_aya_vision.py b/src/transformers/models/aya_vision/modeling_aya_vision.py index 5ccb074399f5..fe9c2f72b05b 100644 --- a/src/transformers/models/aya_vision/modeling_aya_vision.py +++ b/src/transformers/models/aya_vision/modeling_aya_vision.py @@ -118,8 +118,7 @@ class AyaVisionCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -130,7 +129,7 @@ class AyaVisionCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None @@ -145,8 +144,7 @@ class AyaVisionCausalLMOutputWithPast(ModelOutput): class AyaVisionModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/bark/modeling_bark.py b/src/transformers/models/bark/modeling_bark.py index fd31ff7a3c40..8770e3e0691b 100644 --- a/src/transformers/models/bark/modeling_bark.py +++ b/src/transformers/models/bark/modeling_bark.py @@ -23,7 +23,7 @@ from torch import nn from torch.nn import functional as F -from ...cache_utils import DynamicCache +from ...cache_utils import Cache, DynamicCache from ...generation import GenerationMixin from ...generation.logits_process import ( AlternatingCodebooksLogitsProcessor, @@ -437,7 +437,7 @@ def prepare_inputs_for_generation( def forward( self, input_ids: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/bart/modeling_bart.py b/src/transformers/models/bart/modeling_bart.py index ee04f019ba29..55c7654fe2e5 100755 --- a/src/transformers/models/bart/modeling_bart.py +++ b/src/transformers/models/bart/modeling_bart.py @@ -405,7 +405,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -988,9 +988,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/bert/modeling_bert.py b/src/transformers/models/bert/modeling_bert.py index f32fa309073f..20edbf6383c5 100755 --- a/src/transformers/models/bert/modeling_bert.py +++ b/src/transformers/models/bert/modeling_bert.py @@ -613,7 +613,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -887,7 +887,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1171,7 +1171,7 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/bert_generation/modeling_bert_generation.py b/src/transformers/models/bert_generation/modeling_bert_generation.py index fbfd43a1a16f..f29d22d06f83 100755 --- a/src/transformers/models/bert_generation/modeling_bert_generation.py +++ b/src/transformers/models/bert_generation/modeling_bert_generation.py @@ -363,7 +363,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -641,7 +641,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -796,7 +796,7 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/big_bird/modeling_big_bird.py b/src/transformers/models/big_bird/modeling_big_bird.py index 70d166a9c008..20a5a08c246a 100755 --- a/src/transformers/models/big_bird/modeling_big_bird.py +++ b/src/transformers/models/big_bird/modeling_big_bird.py @@ -1852,7 +1852,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -2386,7 +2386,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, diff --git a/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py b/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py index 959202e866ed..90f3c886ad93 100755 --- a/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py +++ b/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py @@ -1480,7 +1480,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -2148,9 +2148,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -2945,7 +2943,7 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/biogpt/modeling_biogpt.py b/src/transformers/models/biogpt/modeling_biogpt.py index 542d7c0a0e1e..8690082625a7 100755 --- a/src/transformers/models/biogpt/modeling_biogpt.py +++ b/src/transformers/models/biogpt/modeling_biogpt.py @@ -295,7 +295,7 @@ def forward( `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. layer_head_mask (`torch.FloatTensor`): mask for attention heads in a given layer of size `(encoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -517,7 +517,7 @@ def forward( attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, position_ids: Optional[torch.LongTensor] = None, output_attentions: Optional[bool] = None, @@ -688,7 +688,7 @@ def forward( attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, position_ids: Optional[torch.LongTensor] = None, @@ -770,7 +770,7 @@ def forward( token_type_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, @@ -862,7 +862,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/biogpt/modular_biogpt.py b/src/transformers/models/biogpt/modular_biogpt.py index e37fbce26a76..5753e066913f 100644 --- a/src/transformers/models/biogpt/modular_biogpt.py +++ b/src/transformers/models/biogpt/modular_biogpt.py @@ -118,7 +118,7 @@ def forward( `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. layer_head_mask (`torch.FloatTensor`): mask for attention heads in a given layer of size `(encoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -340,7 +340,7 @@ def forward( attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, position_ids: Optional[torch.LongTensor] = None, output_attentions: Optional[bool] = None, @@ -511,7 +511,7 @@ def forward( attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, position_ids: Optional[torch.LongTensor] = None, @@ -593,7 +593,7 @@ def forward( token_type_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, @@ -685,7 +685,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/blenderbot/modeling_blenderbot.py b/src/transformers/models/blenderbot/modeling_blenderbot.py index 044ce18460c1..56561612bac2 100755 --- a/src/transformers/models/blenderbot/modeling_blenderbot.py +++ b/src/transformers/models/blenderbot/modeling_blenderbot.py @@ -396,7 +396,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -942,9 +942,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py b/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py index 496613ab3255..556fbeb4d0cb 100755 --- a/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py +++ b/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py @@ -388,7 +388,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -928,9 +928,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/blip/modeling_blip_text.py b/src/transformers/models/blip/modeling_blip_text.py index acde2b26912f..0eb140685fda 100644 --- a/src/transformers/models/blip/modeling_blip_text.py +++ b/src/transformers/models/blip/modeling_blip_text.py @@ -416,7 +416,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -699,7 +699,7 @@ def forward( encoder_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -716,7 +716,7 @@ def forward( the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - 1 for tokens that are **not masked**, - 0 for tokens that are **masked**. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*): + past_key_values (`Cache`, *optional*): Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all @@ -870,7 +870,7 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -893,7 +893,7 @@ def forward( Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]` - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*): + past_key_values (`Cache`, *optional*): Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all diff --git a/src/transformers/models/bridgetower/modeling_bridgetower.py b/src/transformers/models/bridgetower/modeling_bridgetower.py index 35853d7f1c8a..2c798fcf4772 100644 --- a/src/transformers/models/bridgetower/modeling_bridgetower.py +++ b/src/transformers/models/bridgetower/modeling_bridgetower.py @@ -750,7 +750,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -1041,7 +1041,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/camembert/modeling_camembert.py b/src/transformers/models/camembert/modeling_camembert.py index f91ea45d622e..f566bab0b8ed 100644 --- a/src/transformers/models/camembert/modeling_camembert.py +++ b/src/transformers/models/camembert/modeling_camembert.py @@ -570,7 +570,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -809,7 +809,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1462,7 +1462,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/chameleon/modeling_chameleon.py b/src/transformers/models/chameleon/modeling_chameleon.py index c0c6b560ef16..6b2ab15bbb9e 100644 --- a/src/transformers/models/chameleon/modeling_chameleon.py +++ b/src/transformers/models/chameleon/modeling_chameleon.py @@ -405,7 +405,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence kwargs (`dict`, *optional*): @@ -475,7 +475,7 @@ def forward( query_sequence_length, key_sequence_length)` if default attention is used. position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Indices of positions of each input sequence tokens in the position embeddings - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. diff --git a/src/transformers/models/chinese_clip/modeling_chinese_clip.py b/src/transformers/models/chinese_clip/modeling_chinese_clip.py index 3af6e01a34d5..c10d0c855ce1 100644 --- a/src/transformers/models/chinese_clip/modeling_chinese_clip.py +++ b/src/transformers/models/chinese_clip/modeling_chinese_clip.py @@ -22,6 +22,7 @@ from torch import nn from ...activations import ACT2FN +from ...cache_utils import Cache from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutput, @@ -874,7 +875,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/clvp/modeling_clvp.py b/src/transformers/models/clvp/modeling_clvp.py index e847c3e4208e..acef62d5da21 100644 --- a/src/transformers/models/clvp/modeling_clvp.py +++ b/src/transformers/models/clvp/modeling_clvp.py @@ -1029,7 +1029,7 @@ def forward( token_type_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -1195,7 +1195,7 @@ def forward( token_type_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -1361,7 +1361,7 @@ def prepare_inputs_for_generation( def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/cohere/modeling_cohere.py b/src/transformers/models/cohere/modeling_cohere.py index c342b95994b1..1dfa0ce0be33 100644 --- a/src/transformers/models/cohere/modeling_cohere.py +++ b/src/transformers/models/cohere/modeling_cohere.py @@ -307,7 +307,7 @@ def forward( attention_mask (`torch.FloatTensor`, *optional*): attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1, query_sequence_length, key_sequence_length)` if default attention is used. - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. diff --git a/src/transformers/models/cohere/modular_cohere.py b/src/transformers/models/cohere/modular_cohere.py index 4f05fedc986e..62b6b1988daa 100644 --- a/src/transformers/models/cohere/modular_cohere.py +++ b/src/transformers/models/cohere/modular_cohere.py @@ -225,7 +225,7 @@ def forward( attention_mask (`torch.FloatTensor`, *optional*): attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1, query_sequence_length, key_sequence_length)` if default attention is used. - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. diff --git a/src/transformers/models/cohere2/modeling_cohere2.py b/src/transformers/models/cohere2/modeling_cohere2.py index 384e1c22088e..bab804aab67e 100644 --- a/src/transformers/models/cohere2/modeling_cohere2.py +++ b/src/transformers/models/cohere2/modeling_cohere2.py @@ -284,7 +284,7 @@ def forward( attention_mask (`torch.FloatTensor`, *optional*): attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1, query_sequence_length, key_sequence_length)` if default attention is used. - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. diff --git a/src/transformers/models/cohere2_vision/modeling_cohere2_vision.py b/src/transformers/models/cohere2_vision/modeling_cohere2_vision.py index ddb0f360c6d6..1dc993967b5c 100644 --- a/src/transformers/models/cohere2_vision/modeling_cohere2_vision.py +++ b/src/transformers/models/cohere2_vision/modeling_cohere2_vision.py @@ -84,8 +84,7 @@ def forward(self, image_features): class Cohere2VisionModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -110,8 +109,7 @@ class Cohere2VisionCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -122,7 +120,7 @@ class Cohere2VisionCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/colpali/modeling_colpali.py b/src/transformers/models/colpali/modeling_colpali.py index ad53d6a98538..a59224e20456 100644 --- a/src/transformers/models/colpali/modeling_colpali.py +++ b/src/transformers/models/colpali/modeling_colpali.py @@ -15,7 +15,7 @@ """PyTorch ColPali model""" from dataclasses import dataclass -from typing import Optional, Union +from typing import Optional import torch from torch import nn @@ -67,8 +67,7 @@ class ColPaliForRetrievalOutput(ModelOutput): embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): The embeddings of the model. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -79,7 +78,7 @@ class ColPaliForRetrievalOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None embeddings: Optional[torch.Tensor] = None - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/colqwen2/modeling_colqwen2.py b/src/transformers/models/colqwen2/modeling_colqwen2.py index 684804ee377a..d448962f4e97 100644 --- a/src/transformers/models/colqwen2/modeling_colqwen2.py +++ b/src/transformers/models/colqwen2/modeling_colqwen2.py @@ -20,7 +20,7 @@ # limitations under the License. from dataclasses import dataclass -from typing import Optional, Union +from typing import Optional from torch import nn @@ -75,8 +75,7 @@ class ColQwen2ForRetrievalOutput(ModelOutput): embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): The embeddings of the model. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -84,7 +83,7 @@ class ColQwen2ForRetrievalOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None embeddings: Optional[torch.Tensor] = None - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None diff --git a/src/transformers/models/colqwen2/modular_colqwen2.py b/src/transformers/models/colqwen2/modular_colqwen2.py index 2c268248856b..72469fef7a21 100644 --- a/src/transformers/models/colqwen2/modular_colqwen2.py +++ b/src/transformers/models/colqwen2/modular_colqwen2.py @@ -279,8 +279,7 @@ class ColQwen2ForRetrievalOutput(ModelOutput): embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): The embeddings of the model. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -288,7 +287,7 @@ class ColQwen2ForRetrievalOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None embeddings: Optional[torch.Tensor] = None - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None diff --git a/src/transformers/models/cpmant/modeling_cpmant.py b/src/transformers/models/cpmant/modeling_cpmant.py index 9fe0afeb72a3..8eb5bc4d1968 100755 --- a/src/transformers/models/cpmant/modeling_cpmant.py +++ b/src/transformers/models/cpmant/modeling_cpmant.py @@ -104,7 +104,7 @@ def forward( Provide positional information to self-attention block. output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. - past_key_values (`tuple[torch.Tensor, torch.Tensor]`, *optional*): + past_key_values (`Cache`, *optional*): Cached past key and value projection states. use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding @@ -191,7 +191,7 @@ def forward( Provide positional information to self-attention block. output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): + past_key_values (`Cache`, *optional*): Cached past key and value projection states. use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding @@ -315,7 +315,7 @@ def forward( Provides position information to attention mechanism of shape `(num_heads, seq_len, seq_len)` output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. - past_key_values (`tuple[torch.Tensor, torch.Tensor])`, *optional*): + past_key_values (`Cache`, *optional*): Cached past key and value projection states use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding @@ -366,7 +366,7 @@ def forward( Whether or not to return the attentions tensors of all attention layers. output_hidden_states (`bool`, *optional*): Whether or not to return the hidden states of all layers. - past_key_values (`tuple[torch.Tensor, torch.Tensor])`, *optional*): + past_key_values (`Cache`, *optional*): Cached past key and value projection states use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding @@ -590,7 +590,7 @@ def forward( input_ids: Optional[torch.Tensor] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, @@ -722,7 +722,7 @@ def __init__(self, config: CpmAntConfig): def forward( self, input_ids: Optional[torch.Tensor] = None, - past_key_values: Optional[list[tuple[torch.Tensor, torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/csm/generation_csm.py b/src/transformers/models/csm/generation_csm.py index b14f353685c2..400c023e0284 100644 --- a/src/transformers/models/csm/generation_csm.py +++ b/src/transformers/models/csm/generation_csm.py @@ -62,7 +62,7 @@ class CsmGenerateOutput(GenerateDecoderOnlyOutput): hidden_states (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `output_hidden_states=True`): Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of `torch.FloatTensor` of shape `(batch_size, generated_length, hidden_size)`. - past_key_values (`tuple(tuple(torch.FloatTensor)))`, *optional*, returned when `use_cache=True`): + past_key_values (`Cache`, *optional*, returned when `use_cache=True`): Returns the model cache, used to speed up decoding. Different models have a different cache format, check audio (`list(torch.FloatTensor)` of length `batch_size`): The generated audio. diff --git a/src/transformers/models/csm/modeling_csm.py b/src/transformers/models/csm/modeling_csm.py index 7cfa90397010..80157e2aa93a 100644 --- a/src/transformers/models/csm/modeling_csm.py +++ b/src/transformers/models/csm/modeling_csm.py @@ -60,8 +60,7 @@ class CsmOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -69,9 +68,8 @@ class CsmOutputWithPast(ModelOutput): Language modeling loss (for next-token prediction) of the depth decoder model. depth_decoder_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the depth decoder (scores for each vocabulary token before SoftMax). - depth_decoder_past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + depth_decoder_past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). depth_decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, + one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. @@ -86,12 +84,12 @@ class CsmOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None attentions: Optional[tuple[torch.FloatTensor, ...]] = None depth_decoder_loss: Optional[torch.FloatTensor] = None depth_decoder_logits: Optional[torch.FloatTensor] = None - depth_decoder_past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + depth_decoder_past_key_values: Optional[Cache] = None depth_decoder_hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None depth_decoder_attentions: Optional[tuple[torch.FloatTensor, ...]] = None backbone_loss: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/csm/modular_csm.py b/src/transformers/models/csm/modular_csm.py index f83a1abd5ae8..cb7d4a6c209c 100644 --- a/src/transformers/models/csm/modular_csm.py +++ b/src/transformers/models/csm/modular_csm.py @@ -59,8 +59,7 @@ class CsmOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -68,9 +67,8 @@ class CsmOutputWithPast(ModelOutput): Language modeling loss (for next-token prediction) of the depth decoder model. depth_decoder_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the depth decoder (scores for each vocabulary token before SoftMax). - depth_decoder_past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + depth_decoder_past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). depth_decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, + one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. @@ -85,12 +83,12 @@ class CsmOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None attentions: Optional[tuple[torch.FloatTensor, ...]] = None depth_decoder_loss: Optional[torch.FloatTensor] = None depth_decoder_logits: Optional[torch.FloatTensor] = None - depth_decoder_past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + depth_decoder_past_key_values: Optional[Cache] = None depth_decoder_hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None depth_decoder_attentions: Optional[tuple[torch.FloatTensor, ...]] = None backbone_loss: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/ctrl/modeling_ctrl.py b/src/transformers/models/ctrl/modeling_ctrl.py index ece001f9ce1f..e20fffede948 100644 --- a/src/transformers/models/ctrl/modeling_ctrl.py +++ b/src/transformers/models/ctrl/modeling_ctrl.py @@ -22,7 +22,7 @@ from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss -from ...cache_utils import DynamicCache +from ...cache_utils import Cache, DynamicCache from ...generation import GenerationMixin from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast, SequenceClassifierOutput from ...modeling_utils import PreTrainedModel @@ -271,7 +271,7 @@ def _prune_heads(self, heads_to_prune): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, @@ -456,7 +456,7 @@ def __init__(self, config): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, @@ -598,7 +598,7 @@ def __init__(self, config): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/data2vec/modeling_data2vec_text.py b/src/transformers/models/data2vec/modeling_data2vec_text.py index 844d329c7e19..9d52c9953307 100644 --- a/src/transformers/models/data2vec/modeling_data2vec_text.py +++ b/src/transformers/models/data2vec/modeling_data2vec_text.py @@ -467,7 +467,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -643,7 +643,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -789,7 +789,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/dbrx/modeling_dbrx.py b/src/transformers/models/dbrx/modeling_dbrx.py index 1f80a48455fe..ab3ddce51310 100644 --- a/src/transformers/models/dbrx/modeling_dbrx.py +++ b/src/transformers/models/dbrx/modeling_dbrx.py @@ -771,7 +771,7 @@ def forward( attention_mask (`torch.Tensor`, *optional*): attention mask of size (batch_size, sequence_length) if flash attention is used or (batch_size, 1, query_sequence_length, key_sequence_length) if default attention is used. - past_key_values (`Tuple(torch.Tensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. output_router_logits (`bool`, *optional*): Whether or not to return the router logits. diff --git a/src/transformers/models/decision_transformer/modeling_decision_transformer.py b/src/transformers/models/decision_transformer/modeling_decision_transformer.py index 78db13c42d68..3ac0ab038219 100755 --- a/src/transformers/models/decision_transformer/modeling_decision_transformer.py +++ b/src/transformers/models/decision_transformer/modeling_decision_transformer.py @@ -527,7 +527,7 @@ def set_input_embeddings(self, new_embeddings): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/deepseek_vl/modeling_deepseek_vl.py b/src/transformers/models/deepseek_vl/modeling_deepseek_vl.py index 2a34ce84a93e..039602a159f2 100644 --- a/src/transformers/models/deepseek_vl/modeling_deepseek_vl.py +++ b/src/transformers/models/deepseek_vl/modeling_deepseek_vl.py @@ -55,10 +55,7 @@ class DeepseekVLBaseModelOutputWithPast(ModelOutput): If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, hidden_size)` is output. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` @@ -71,7 +68,7 @@ class DeepseekVLBaseModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None @@ -90,8 +87,7 @@ class DeepseekVLCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -104,7 +100,7 @@ class DeepseekVLCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None diff --git a/src/transformers/models/deepseek_vl_hybrid/modeling_deepseek_vl_hybrid.py b/src/transformers/models/deepseek_vl_hybrid/modeling_deepseek_vl_hybrid.py index 65c5c8024e09..cae509e14d64 100644 --- a/src/transformers/models/deepseek_vl_hybrid/modeling_deepseek_vl_hybrid.py +++ b/src/transformers/models/deepseek_vl_hybrid/modeling_deepseek_vl_hybrid.py @@ -52,10 +52,7 @@ class DeepseekVLHybridBaseModelOutputWithPast(ModelOutput): If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, hidden_size)` is output. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` @@ -68,7 +65,7 @@ class DeepseekVLHybridBaseModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None @@ -87,8 +84,7 @@ class DeepseekVLHybridCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -101,7 +97,7 @@ class DeepseekVLHybridCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None diff --git a/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py b/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py index e2c939b255b5..90f215157b7e 100755 --- a/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py +++ b/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py @@ -23,6 +23,7 @@ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ....activations import ACT2FN +from ....cache_utils import Cache from ....modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, BaseModelOutputWithPoolingAndCrossAttentions, @@ -127,7 +128,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, ) -> tuple[torch.Tensor]: mixed_query_layer = self.q_proj(hidden_states) @@ -255,7 +256,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, ) -> tuple[torch.Tensor]: self_outputs = self.self_attn( @@ -298,7 +299,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = True, ): residual = hidden_states @@ -347,7 +348,7 @@ def forward( input_embeds: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, return_dict: Optional[bool] = True, @@ -629,7 +630,7 @@ def forward( position_ids: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_hidden_states: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -818,7 +819,7 @@ def forward( position_ids: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_hidden_states: Optional[bool] = None, output_attentions: Optional[bool] = None, return_dict: Optional[bool] = True, diff --git a/src/transformers/models/deprecated/gptsan_japanese/modeling_gptsan_japanese.py b/src/transformers/models/deprecated/gptsan_japanese/modeling_gptsan_japanese.py index 9300245ca7f6..0e2d27f03bac 100644 --- a/src/transformers/models/deprecated/gptsan_japanese/modeling_gptsan_japanese.py +++ b/src/transformers/models/deprecated/gptsan_japanese/modeling_gptsan_japanese.py @@ -20,6 +20,7 @@ import torch.nn as nn from ....activations import ACT2FN +from ....cache_utils import Cache from ....modeling_outputs import MoECausalLMOutputWithPast, MoEModelOutputWithPastAndCrossAttentions from ....modeling_utils import PreTrainedModel from ....utils import ( @@ -383,7 +384,7 @@ def forward( self, hidden_states: torch.Tensor, key_value_states: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, layer_head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False, @@ -519,7 +520,7 @@ def __init__(self, config, has_relative_attention_bias=False): def forward( self, hidden_states: Optional[tuple[torch.FloatTensor]], - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = False, @@ -601,7 +602,7 @@ def __init__(self, config, ext_layer=False): def forward( self, hidden_states: Optional[tuple[torch.FloatTensor]], - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = False, @@ -885,7 +886,7 @@ def forward( attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.FloatTensor] = None, spout: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, head_mask: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = False, inputs_embeds: Optional[torch.FloatTensor] = None, @@ -1111,7 +1112,7 @@ def forward( attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.FloatTensor] = None, spout: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, head_mask: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = False, inputs_embeds: Optional[torch.FloatTensor] = None, @@ -1268,7 +1269,7 @@ def prepare_inputs_for_generation( attention_mask: torch.FloatTensor, token_type_ids: Optional[torch.FloatTensor] = None, spout: Optional[Union[list, torch.FloatTensor]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, **kwargs, ): if isinstance(spout, list): diff --git a/src/transformers/models/deprecated/mega/modeling_mega.py b/src/transformers/models/deprecated/mega/modeling_mega.py index cc77cb2874e6..c6edc57f8cf6 100644 --- a/src/transformers/models/deprecated/mega/modeling_mega.py +++ b/src/transformers/models/deprecated/mega/modeling_mega.py @@ -24,6 +24,7 @@ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ....activations import ACT2FN +from ....cache_utils import Cache from ....modeling_outputs import ( BaseModelOutputWithPoolingAndCrossAttentions, CausalLMOutputWithCrossAttentions, @@ -625,7 +626,7 @@ def forward( key: Optional[torch.Tensor], value: Optional[torch.Tensor], key_padding_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: bool = False, use_cache: bool = False, ) -> tuple[torch.Tensor, Optional[torch.Tensor]]: @@ -910,7 +911,7 @@ def forward( input, padding_mask: Optional[torch.Tensor] = None, causal_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions=False, use_cache=False, ): @@ -1182,7 +1183,7 @@ def forward( causal_mask: Optional[torch.LongTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: bool = False, ) -> tuple[torch.Tensor]: @@ -1490,7 +1491,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1675,7 +1676,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/deprecated/nezha/modeling_nezha.py b/src/transformers/models/deprecated/nezha/modeling_nezha.py index 635a078c6a13..3dd67c22d72e 100644 --- a/src/transformers/models/deprecated/nezha/modeling_nezha.py +++ b/src/transformers/models/deprecated/nezha/modeling_nezha.py @@ -26,6 +26,7 @@ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ....activations import ACT2FN +from ....cache_utils import Cache from ....modeling_layers import GradientCheckpointingLayer from ....modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -251,7 +252,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, ) -> tuple[torch.Tensor]: mixed_query_layer = self.query(hidden_states) @@ -396,7 +397,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, ) -> tuple[torch.Tensor]: self_outputs = self.self( @@ -465,7 +466,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, ) -> tuple[torch.Tensor]: # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 @@ -543,7 +544,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -877,7 +878,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/deprecated/open_llama/modeling_open_llama.py b/src/transformers/models/deprecated/open_llama/modeling_open_llama.py index a6c6ab449685..4ce63feceb74 100644 --- a/src/transformers/models/deprecated/open_llama/modeling_open_llama.py +++ b/src/transformers/models/deprecated/open_llama/modeling_open_llama.py @@ -28,6 +28,7 @@ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ....activations import ACT2FN +from ....cache_utils import Cache from ....modeling_attn_mask_utils import _prepare_4d_causal_attention_mask from ....modeling_layers import GradientCheckpointingLayer from ....modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast, SequenceClassifierOutputWithPast @@ -274,7 +275,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: bool = False, use_cache: bool = False, ) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]: @@ -366,7 +367,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, ) -> tuple[torch.FloatTensor, Optional[tuple[torch.FloatTensor, torch.FloatTensor]]]: @@ -557,7 +558,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -684,7 +685,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, @@ -851,7 +852,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py b/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py index cfa66aaf0250..74bad366e8d5 100755 --- a/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py +++ b/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py @@ -26,6 +26,7 @@ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ....activations import ACT2FN +from ....cache_utils import Cache from ....modeling_layers import GradientCheckpointingLayer from ....modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -859,7 +860,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/deprecated/realm/modeling_realm.py b/src/transformers/models/deprecated/realm/modeling_realm.py index 284a99b559f4..9e2de5c9c1c4 100644 --- a/src/transformers/models/deprecated/realm/modeling_realm.py +++ b/src/transformers/models/deprecated/realm/modeling_realm.py @@ -24,6 +24,7 @@ from torch.nn import CrossEntropyLoss from ....activations import ACT2FN +from ....cache_utils import Cache from ....modeling_layers import GradientCheckpointingLayer from ....modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -256,7 +257,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, ) -> tuple[torch.Tensor]: mixed_query_layer = self.query(hidden_states) @@ -405,7 +406,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, ) -> tuple[torch.Tensor]: self_outputs = self.self( @@ -474,7 +475,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, ) -> tuple[torch.Tensor]: # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 @@ -552,7 +553,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, diff --git a/src/transformers/models/deprecated/speech_to_text_2/modeling_speech_to_text_2.py b/src/transformers/models/deprecated/speech_to_text_2/modeling_speech_to_text_2.py index 2117526b04f8..854f21c06550 100755 --- a/src/transformers/models/deprecated/speech_to_text_2/modeling_speech_to_text_2.py +++ b/src/transformers/models/deprecated/speech_to_text_2/modeling_speech_to_text_2.py @@ -22,6 +22,7 @@ from torch.nn import CrossEntropyLoss from ....activations import ACT2FN +from ....cache_utils import Cache from ....modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_causal_attention_mask from ....modeling_layers import GradientCheckpointingLayer from ....modeling_outputs import BaseModelOutputWithPastAndCrossAttentions, CausalLMOutputWithCrossAttentions @@ -148,7 +149,7 @@ def forward( self, hidden_states: torch.Tensor, key_value_states: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, layer_head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False, @@ -304,7 +305,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, layer_head_mask: Optional[torch.Tensor] = None, cross_attn_layer_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = True, ): @@ -707,7 +708,7 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py b/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py index cf49223b8b5d..dcacffabc8b9 100644 --- a/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py +++ b/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py @@ -25,6 +25,7 @@ from torch import nn from torch.nn import functional as F +from ....cache_utils import Cache from ....modeling_layers import GradientCheckpointingLayer from ....modeling_utils import PreTrainedModel from ....utils import ( @@ -142,7 +143,7 @@ class TrajectoryTransformerOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None @@ -464,7 +465,7 @@ def pad_to_full_observation(self, hidden_states): def forward( self, trajectories: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, targets: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/deprecated/xlm_prophetnet/modeling_xlm_prophetnet.py b/src/transformers/models/deprecated/xlm_prophetnet/modeling_xlm_prophetnet.py index d526b7d65048..e85660223b58 100644 --- a/src/transformers/models/deprecated/xlm_prophetnet/modeling_xlm_prophetnet.py +++ b/src/transformers/models/deprecated/xlm_prophetnet/modeling_xlm_prophetnet.py @@ -26,6 +26,7 @@ from torch.nn import LayerNorm from ....activations import ACT2FN +from ....cache_utils import Cache from ....modeling_layers import GradientCheckpointingLayer from ....modeling_outputs import BaseModelOutput from ....modeling_utils import PreTrainedModel @@ -312,7 +313,7 @@ class XLMProphetNetSeq2SeqLMOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None logits_ngram: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None decoder_hidden_states: Optional[tuple[torch.FloatTensor]] = None decoder_ngram_hidden_states: Optional[tuple[torch.FloatTensor]] = None decoder_attentions: Optional[tuple[torch.FloatTensor]] = None @@ -398,7 +399,7 @@ class XLMProphetNetSeq2SeqModelOutput(ModelOutput): last_hidden_state: torch.FloatTensor last_hidden_state_ngram: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None decoder_hidden_states: Optional[tuple[torch.FloatTensor]] = None decoder_ngram_hidden_states: Optional[tuple[torch.FloatTensor]] = None decoder_attentions: Optional[tuple[torch.FloatTensor]] = None @@ -470,7 +471,7 @@ class XLMProphetNetDecoderModelOutput(ModelOutput): last_hidden_state: torch.FloatTensor last_hidden_state_ngram: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None hidden_states_ngram: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None @@ -532,7 +533,7 @@ class XLMProphetNetDecoderLMOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None logits_ngram: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None hidden_states_ngram: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None @@ -658,7 +659,7 @@ def forward( key_value_states: Optional[Tensor] = None, attention_mask: Optional[Tensor] = None, layer_head_mask: Optional[Tensor] = None, - past_key_values: Optional[tuple[Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: bool = False, ) -> tuple[Tensor, Optional[Tensor]]: batch_size, tgt_len, hidden_size = hidden_states.size() @@ -814,7 +815,7 @@ def prepare_for_onnx_export_(self): def forward( self, hidden_states, - past_key_values: Optional[tuple[Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask=None, layer_head_mask=None, extended_predict_attention_mask=None, @@ -1398,7 +1399,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -1745,7 +1746,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, decoder_inputs_embeds: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, @@ -1861,7 +1862,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, decoder_inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, @@ -2087,7 +2088,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/doge/modeling_doge.py b/src/transformers/models/doge/modeling_doge.py index b94667398507..5822cad62017 100644 --- a/src/transformers/models/doge/modeling_doge.py +++ b/src/transformers/models/doge/modeling_doge.py @@ -450,7 +450,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[TransformersKwargs], @@ -726,7 +726,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/doge/modular_doge.py b/src/transformers/models/doge/modular_doge.py index fdee6e09c465..c4c95e627376 100644 --- a/src/transformers/models/doge/modular_doge.py +++ b/src/transformers/models/doge/modular_doge.py @@ -534,7 +534,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[TransformersKwargs], @@ -708,7 +708,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/electra/modeling_electra.py b/src/transformers/models/electra/modeling_electra.py index c5366f1e50e5..9327bc0fdf26 100644 --- a/src/transformers/models/electra/modeling_electra.py +++ b/src/transformers/models/electra/modeling_electra.py @@ -522,7 +522,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -718,7 +718,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1498,7 +1498,7 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py b/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py index b5ce450a9c7f..30e2370b2240 100644 --- a/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py +++ b/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py @@ -25,6 +25,7 @@ from torch import nn from torch.nn import CrossEntropyLoss +from ...cache_utils import Cache from ...configuration_utils import PretrainedConfig from ...generation import GenerationMixin from ...modeling_outputs import BaseModelOutput, Seq2SeqLMOutput @@ -450,7 +451,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.BoolTensor] = None, encoder_outputs: Optional[tuple[torch.FloatTensor]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/ernie/modeling_ernie.py b/src/transformers/models/ernie/modeling_ernie.py index 9bbc84b0a048..a5ed4a3f5328 100644 --- a/src/transformers/models/ernie/modeling_ernie.py +++ b/src/transformers/models/ernie/modeling_ernie.py @@ -451,7 +451,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -727,7 +727,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -999,7 +999,7 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/ernie4_5_moe/modeling_ernie4_5_moe.py b/src/transformers/models/ernie4_5_moe/modeling_ernie4_5_moe.py index 36f1f25c32be..2976beba1033 100644 --- a/src/transformers/models/ernie4_5_moe/modeling_ernie4_5_moe.py +++ b/src/transformers/models/ernie4_5_moe/modeling_ernie4_5_moe.py @@ -409,7 +409,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[FlashAttentionKwargs], ) -> torch.FloatTensor: @@ -427,7 +427,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence. position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): diff --git a/src/transformers/models/falcon/modeling_falcon.py b/src/transformers/models/falcon/modeling_falcon.py index c6e248a30fcf..5ec1792e4581 100644 --- a/src/transformers/models/falcon/modeling_falcon.py +++ b/src/transformers/models/falcon/modeling_falcon.py @@ -1110,7 +1110,7 @@ def __init__(self, config: FalconConfig): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor, torch.Tensor], ...]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, @@ -1236,7 +1236,7 @@ def __init__(self, config: FalconConfig): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor, torch.Tensor], ...]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/fsmt/modeling_fsmt.py b/src/transformers/models/fsmt/modeling_fsmt.py index 71d0dc66ced5..85618847dbf7 100644 --- a/src/transformers/models/fsmt/modeling_fsmt.py +++ b/src/transformers/models/fsmt/modeling_fsmt.py @@ -586,7 +586,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = False, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -922,7 +922,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[torch.FloatTensor]] = None, - past_key_values: Optional[tuple[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1068,7 +1068,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[torch.FloatTensor]] = None, - past_key_values: Optional[tuple[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, decoder_inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/gemma3/modeling_gemma3.py b/src/transformers/models/gemma3/modeling_gemma3.py index f8cbfcf1de77..889a374b5493 100644 --- a/src/transformers/models/gemma3/modeling_gemma3.py +++ b/src/transformers/models/gemma3/modeling_gemma3.py @@ -56,12 +56,6 @@ ) class Gemma3ModelOutputWithPast(BaseModelOutputWithPast): r""" - past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) - - Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. image_hidden_states (`torch.FloatTensor`, *optional*): A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`. image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state. @@ -83,8 +77,7 @@ class Gemma3CausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.text_config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -95,7 +88,7 @@ class Gemma3CausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None @@ -843,7 +836,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, @@ -1028,7 +1021,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, diff --git a/src/transformers/models/gemma3/modular_gemma3.py b/src/transformers/models/gemma3/modular_gemma3.py index 4d2ca5423b2b..b0cb272dd04a 100644 --- a/src/transformers/models/gemma3/modular_gemma3.py +++ b/src/transformers/models/gemma3/modular_gemma3.py @@ -781,7 +781,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, @@ -893,7 +893,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, diff --git a/src/transformers/models/gemma3n/modeling_gemma3n.py b/src/transformers/models/gemma3n/modeling_gemma3n.py index 198ed7c0fcce..68595ead4371 100644 --- a/src/transformers/models/gemma3n/modeling_gemma3n.py +++ b/src/transformers/models/gemma3n/modeling_gemma3n.py @@ -56,9 +56,8 @@ ) class Gemma3nModelOutputWithPast(BaseModelOutputWithPast): r""" - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -87,9 +86,8 @@ class Gemma3nCausalLMOutputWithPast(ModelOutput): Language modeling loss (for next-token prediction). logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.text_config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -103,7 +101,7 @@ class Gemma3nCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None @@ -2012,7 +2010,7 @@ def forward( attention_mask: Optional[torch.Tensor] = None, input_features_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, @@ -2217,7 +2215,7 @@ def forward( attention_mask: Optional[torch.Tensor] = None, input_features_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, diff --git a/src/transformers/models/gemma3n/modular_gemma3n.py b/src/transformers/models/gemma3n/modular_gemma3n.py index 619c295250fb..d46471dfdab8 100644 --- a/src/transformers/models/gemma3n/modular_gemma3n.py +++ b/src/transformers/models/gemma3n/modular_gemma3n.py @@ -647,9 +647,8 @@ def __init__( class Gemma3nModelOutputWithPast(PaligemmaModelOutputWithPast): r""" - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -670,9 +669,8 @@ class Gemma3nCausalLMOutputWithPast(PaliGemmaCausalLMOutputWithPast): Language modeling loss (for next-token prediction). logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.text_config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -2324,7 +2322,7 @@ def forward( attention_mask: Optional[torch.Tensor] = None, input_features_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, @@ -2505,7 +2503,7 @@ def forward( attention_mask: Optional[torch.Tensor] = None, input_features_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, diff --git a/src/transformers/models/glm4v/modeling_glm4v.py b/src/transformers/models/glm4v/modeling_glm4v.py index b6e7751414f7..fbfeae9130e1 100644 --- a/src/transformers/models/glm4v/modeling_glm4v.py +++ b/src/transformers/models/glm4v/modeling_glm4v.py @@ -597,7 +597,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, @@ -642,8 +642,7 @@ def forward( class Glm4vModelOutputWithPast(ModelOutput): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -652,7 +651,7 @@ class Glm4vModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -813,7 +812,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, cache_position: Optional[torch.LongTensor] = None, @@ -1183,7 +1182,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, pixel_values: Optional[torch.Tensor] = None, pixel_values_videos: Optional[torch.FloatTensor] = None, @@ -1297,8 +1296,7 @@ class Glm4vCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1308,7 +1306,7 @@ class Glm4vCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -1363,7 +1361,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, pixel_values: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/glm4v/modular_glm4v.py b/src/transformers/models/glm4v/modular_glm4v.py index ccc8dc9c7e3a..7c400edc51c3 100644 --- a/src/transformers/models/glm4v/modular_glm4v.py +++ b/src/transformers/models/glm4v/modular_glm4v.py @@ -686,7 +686,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, @@ -862,7 +862,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, cache_position: Optional[torch.LongTensor] = None, @@ -1194,7 +1194,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, pixel_values: Optional[torch.Tensor] = None, pixel_values_videos: Optional[torch.FloatTensor] = None, @@ -1307,7 +1307,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, pixel_values: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/glm4v_moe/modeling_glm4v_moe.py b/src/transformers/models/glm4v_moe/modeling_glm4v_moe.py index 770d611707bb..045e78df5233 100644 --- a/src/transformers/models/glm4v_moe/modeling_glm4v_moe.py +++ b/src/transformers/models/glm4v_moe/modeling_glm4v_moe.py @@ -776,8 +776,7 @@ def forward(self, x, position_ids): class Glm4vMoeModelOutputWithPast(ModelOutput): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -786,7 +785,7 @@ class Glm4vMoeModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -929,7 +928,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, cache_position: Optional[torch.LongTensor] = None, @@ -1299,7 +1298,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, pixel_values: Optional[torch.Tensor] = None, pixel_values_videos: Optional[torch.FloatTensor] = None, @@ -1413,8 +1412,7 @@ class Glm4vMoeCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1424,7 +1422,7 @@ class Glm4vMoeCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -1479,7 +1477,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, pixel_values: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/got_ocr2/modeling_got_ocr2.py b/src/transformers/models/got_ocr2/modeling_got_ocr2.py index 788ac69d931a..35b74335c21f 100644 --- a/src/transformers/models/got_ocr2/modeling_got_ocr2.py +++ b/src/transformers/models/got_ocr2/modeling_got_ocr2.py @@ -485,8 +485,7 @@ class GotOcr2CausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -497,7 +496,7 @@ class GotOcr2CausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None @@ -512,8 +511,7 @@ class GotOcr2CausalLMOutputWithPast(ModelOutput): class GotOcr2ModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/gpt2/modeling_gpt2.py b/src/transformers/models/gpt2/modeling_gpt2.py index 375479f19780..c34755b8b440 100644 --- a/src/transformers/models/gpt2/modeling_gpt2.py +++ b/src/transformers/models/gpt2/modeling_gpt2.py @@ -622,9 +622,8 @@ class GPT2DoubleHeadsModelOutput(ModelOutput): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). mc_logits (`torch.FloatTensor` of shape `(batch_size, num_choices)`): Prediction scores of the multiple choice classification head (scores for each choice before SoftMax). - past_key_values (`tuple[tuple[torch.Tensor]]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of length `config.n_layers`, containing tuples of tensors of shape `(batch_size, num_heads, - sequence_length, embed_size_per_head)`). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -634,7 +633,7 @@ class GPT2DoubleHeadsModelOutput(ModelOutput): mc_loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None mc_logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None @@ -777,7 +776,7 @@ def _prune_heads(self, heads_to_prune): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[tuple[tuple[torch.Tensor]], Cache]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, @@ -1030,7 +1029,7 @@ def deparallelize(self): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, @@ -1179,7 +1178,7 @@ def deparallelize(self): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, @@ -1332,7 +1331,7 @@ def __init__(self, config): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, @@ -1465,7 +1464,7 @@ def __init__(self, config): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py b/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py index eea96798e4cd..96fb40b1d69f 100644 --- a/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py +++ b/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py @@ -433,7 +433,7 @@ def set_input_embeddings(self, new_embeddings): def forward( self, input_ids: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, token_type_ids: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, @@ -616,7 +616,7 @@ def __init__(self, config): def forward( self, input_ids: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, token_type_ids: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, @@ -723,7 +723,7 @@ def __init__(self, config): def forward( self, input_ids: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, token_type_ids: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, @@ -856,7 +856,7 @@ def __init__(self, config): def forward( self, input_ids: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, token_type_ids: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/gpt_oss/modeling_gpt_oss.py b/src/transformers/models/gpt_oss/modeling_gpt_oss.py index ffb420b067e2..0d5c936e8adc 100644 --- a/src/transformers/models/gpt_oss/modeling_gpt_oss.py +++ b/src/transformers/models/gpt_oss/modeling_gpt_oss.py @@ -463,7 +463,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, cache_position: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/gpt_oss/modular_gpt_oss.py b/src/transformers/models/gpt_oss/modular_gpt_oss.py index 193792bf0a01..aba879af9336 100644 --- a/src/transformers/models/gpt_oss/modular_gpt_oss.py +++ b/src/transformers/models/gpt_oss/modular_gpt_oss.py @@ -393,7 +393,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, cache_position: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/gptj/modeling_gptj.py b/src/transformers/models/gptj/modeling_gptj.py index 5681398972fc..56256df7d582 100644 --- a/src/transformers/models/gptj/modeling_gptj.py +++ b/src/transformers/models/gptj/modeling_gptj.py @@ -1037,7 +1037,7 @@ def __init__(self, config): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.FloatTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/granite/modeling_granite.py b/src/transformers/models/granite/modeling_granite.py index dc458b619def..846865c55508 100644 --- a/src/transformers/models/granite/modeling_granite.py +++ b/src/transformers/models/granite/modeling_granite.py @@ -259,7 +259,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): diff --git a/src/transformers/models/granite/modular_granite.py b/src/transformers/models/granite/modular_granite.py index a0141bd91245..1b90609e5460 100644 --- a/src/transformers/models/granite/modular_granite.py +++ b/src/transformers/models/granite/modular_granite.py @@ -77,7 +77,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): diff --git a/src/transformers/models/granite_speech/modeling_granite_speech.py b/src/transformers/models/granite_speech/modeling_granite_speech.py index e4a6ad1c41f4..1e44c9781dec 100644 --- a/src/transformers/models/granite_speech/modeling_granite_speech.py +++ b/src/transformers/models/granite_speech/modeling_granite_speech.py @@ -46,8 +46,7 @@ class GraniteSpeechCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -55,7 +54,7 @@ class GraniteSpeechCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None diff --git a/src/transformers/models/granitemoe/modeling_granitemoe.py b/src/transformers/models/granitemoe/modeling_granitemoe.py index cb4258c1a1ac..29c23a356509 100644 --- a/src/transformers/models/granitemoe/modeling_granitemoe.py +++ b/src/transformers/models/granitemoe/modeling_granitemoe.py @@ -541,7 +541,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence output_router_logits (`bool`, *optional*): diff --git a/src/transformers/models/granitemoehybrid/modeling_granitemoehybrid.py b/src/transformers/models/granitemoehybrid/modeling_granitemoehybrid.py index e3a1e69fc861..f35211558bf7 100644 --- a/src/transformers/models/granitemoehybrid/modeling_granitemoehybrid.py +++ b/src/transformers/models/granitemoehybrid/modeling_granitemoehybrid.py @@ -1150,7 +1150,7 @@ def forward( attention_mask (`torch.FloatTensor`, *optional*): attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1, query_sequence_length, key_sequence_length)` if default attention is used. - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. diff --git a/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py b/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py index 4de1ff253914..2ebddb88e316 100644 --- a/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py +++ b/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py @@ -96,7 +96,7 @@ def forward( attention_mask (`torch.FloatTensor`, *optional*): attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1, query_sequence_length, key_sequence_length)` if default attention is used. - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. diff --git a/src/transformers/models/granitemoeshared/modeling_granitemoeshared.py b/src/transformers/models/granitemoeshared/modeling_granitemoeshared.py index 1ef28d710e2d..d9ff21d3ebba 100644 --- a/src/transformers/models/granitemoeshared/modeling_granitemoeshared.py +++ b/src/transformers/models/granitemoeshared/modeling_granitemoeshared.py @@ -474,7 +474,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence output_router_logits (`bool`, *optional*): diff --git a/src/transformers/models/granitemoeshared/modular_granitemoeshared.py b/src/transformers/models/granitemoeshared/modular_granitemoeshared.py index 4170deca2e1d..529a07f0317a 100644 --- a/src/transformers/models/granitemoeshared/modular_granitemoeshared.py +++ b/src/transformers/models/granitemoeshared/modular_granitemoeshared.py @@ -117,7 +117,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence output_router_logits (`bool`, *optional*): diff --git a/src/transformers/models/idefics/modeling_idefics.py b/src/transformers/models/idefics/modeling_idefics.py index c86262b95b7a..c80cb2e88bdc 100644 --- a/src/transformers/models/idefics/modeling_idefics.py +++ b/src/transformers/models/idefics/modeling_idefics.py @@ -60,10 +60,7 @@ class IdeficsBaseModelOutputWithPast(ModelOutput): If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, hidden_size)` is output. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` @@ -76,7 +73,7 @@ class IdeficsBaseModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None @@ -95,8 +92,7 @@ class IdeficsCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -109,7 +105,7 @@ class IdeficsCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None @@ -575,7 +571,7 @@ def forward( key_value_states: Optional[torch.Tensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor, torch.Tensor]: @@ -663,7 +659,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[TransformersKwargs], ) -> torch.FloatTensor: @@ -769,7 +765,7 @@ def forward( image_hidden_states: Optional[torch.Tensor] = None, image_attention_mask: Optional[torch.Tensor] = None, cross_attention_gate: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, **kwargs: Unpack[TransformersKwargs], ) -> torch.FloatTensor: r""" diff --git a/src/transformers/models/idefics2/modeling_idefics2.py b/src/transformers/models/idefics2/modeling_idefics2.py index 1ed120350813..264d3fc831ab 100644 --- a/src/transformers/models/idefics2/modeling_idefics2.py +++ b/src/transformers/models/idefics2/modeling_idefics2.py @@ -53,10 +53,8 @@ class Idefics2BaseModelOutputWithPast(ModelOutput): If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, hidden_size)` is output. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). + Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -67,7 +65,7 @@ class Idefics2BaseModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None @@ -87,19 +85,20 @@ class Idefics2CausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). + Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. image_hidden_states (`tuple(torch.FloatTensor)`, *optional*): Tuple of `torch.FloatTensor` (one for the output of the image embeddings, `(batch_size, num_images, sequence_length, hidden_size)`. + image_hidden_states of the model produced by the vision encoder, and optionally by the perceiver """ loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None @@ -584,7 +583,7 @@ def forward( context (`torch.Tensor`): Tensor of shape [bsz, seq, embed_dim] representing long-form context to resample. attention_mask (`torch.Tensor`, *optional*): Tensor of shape [bsz, 1, seq, n_latents] representing attention mask. position_ids (`torch.LongTensor`, *optional*): Tensor of shape [bsz, seq] representing position indices of each input token. - past_key_values (`tuple[torch.Tensor]`, *optional*): Tuple of tensors containing cached key and value states. + past_key_values (`Cache`, *optional*): Tuple of tensors containing cached key and value states. output_attentions (`bool`, *optional*, defaults to `False`): Whether to return attention weights. use_cache (`bool`, *optional*, defaults to `False`): Whether to use past_key_values for caching. """ @@ -669,7 +668,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states """ residual = latents diff --git a/src/transformers/models/idefics3/modeling_idefics3.py b/src/transformers/models/idefics3/modeling_idefics3.py index ea79003fbd74..9d726f814465 100644 --- a/src/transformers/models/idefics3/modeling_idefics3.py +++ b/src/transformers/models/idefics3/modeling_idefics3.py @@ -52,10 +52,8 @@ class Idefics3BaseModelOutputWithPast(ModelOutput): If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, hidden_size)` is output. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). + Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -66,7 +64,7 @@ class Idefics3BaseModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None @@ -85,8 +83,8 @@ class Idefics3CausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). + Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. image_hidden_states (`tuple(torch.FloatTensor)`, *optional*): @@ -97,7 +95,7 @@ class Idefics3CausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None diff --git a/src/transformers/models/imagegpt/modeling_imagegpt.py b/src/transformers/models/imagegpt/modeling_imagegpt.py index c916a82aad03..6a424727d8e5 100755 --- a/src/transformers/models/imagegpt/modeling_imagegpt.py +++ b/src/transformers/models/imagegpt/modeling_imagegpt.py @@ -573,7 +573,7 @@ def _prune_heads(self, heads_to_prune): def forward( self, input_ids: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, token_type_ids: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, @@ -800,7 +800,7 @@ def __init__(self, config: ImageGPTConfig): def forward( self, input_ids: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, token_type_ids: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, @@ -932,7 +932,7 @@ def __init__(self, config: ImageGPTConfig): def forward( self, input_ids: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, token_type_ids: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/informer/modeling_informer.py b/src/transformers/models/informer/modeling_informer.py index 79e2ca8e0bd4..b0fc4964a9ae 100644 --- a/src/transformers/models/informer/modeling_informer.py +++ b/src/transformers/models/informer/modeling_informer.py @@ -564,7 +564,7 @@ def forward( self, hidden_states: torch.Tensor, key_value_states: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, layer_head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False, @@ -911,7 +911,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -1141,7 +1141,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -1182,10 +1182,8 @@ def forward( - 1 indicates the head is **not masked**, - 0 indicates the head is **masked**. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1478,7 +1476,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[list[torch.FloatTensor]] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, output_hidden_states: Optional[bool] = None, output_attentions: Optional[bool] = None, use_cache: Optional[bool] = None, @@ -1772,7 +1770,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[list[torch.FloatTensor]] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, output_hidden_states: Optional[bool] = None, output_attentions: Optional[bool] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/informer/modular_informer.py b/src/transformers/models/informer/modular_informer.py index d69623b56473..aa6e2ad30a9f 100644 --- a/src/transformers/models/informer/modular_informer.py +++ b/src/transformers/models/informer/modular_informer.py @@ -20,7 +20,7 @@ import torch from torch import nn -from ...cache_utils import EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...modeling_attn_mask_utils import ( _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa, @@ -251,7 +251,7 @@ def forward( self, hidden_states: torch.Tensor, key_value_states: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, layer_head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False, diff --git a/src/transformers/models/internvl/modeling_internvl.py b/src/transformers/models/internvl/modeling_internvl.py index 3168546635ff..2b43dd299864 100644 --- a/src/transformers/models/internvl/modeling_internvl.py +++ b/src/transformers/models/internvl/modeling_internvl.py @@ -509,8 +509,7 @@ def forward(self, image_features): class InternVLModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -736,8 +735,7 @@ class InternVLCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -748,7 +746,7 @@ class InternVLCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/janus/modeling_janus.py b/src/transformers/models/janus/modeling_janus.py index 9fa2ba354dd0..eee387664832 100644 --- a/src/transformers/models/janus/modeling_janus.py +++ b/src/transformers/models/janus/modeling_janus.py @@ -100,10 +100,7 @@ class JanusBaseModelOutputWithPast(ModelOutput): If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, hidden_size)` is output. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` @@ -116,7 +113,7 @@ class JanusBaseModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None @@ -135,8 +132,7 @@ class JanusCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -149,7 +145,7 @@ class JanusCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None diff --git a/src/transformers/models/jetmoe/modeling_jetmoe.py b/src/transformers/models/jetmoe/modeling_jetmoe.py index 3171612eb492..896426a5e320 100644 --- a/src/transformers/models/jetmoe/modeling_jetmoe.py +++ b/src/transformers/models/jetmoe/modeling_jetmoe.py @@ -798,7 +798,7 @@ def forward( self, hidden_states: Optional[torch.FloatTensor], position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.FloatTensor] = None, output_attentions: Optional[bool] = False, output_router_logits: Optional[bool] = False, diff --git a/src/transformers/models/kosmos2/modeling_kosmos2.py b/src/transformers/models/kosmos2/modeling_kosmos2.py index ee77fd701c16..0372ec92a6ee 100644 --- a/src/transformers/models/kosmos2/modeling_kosmos2.py +++ b/src/transformers/models/kosmos2/modeling_kosmos2.py @@ -99,11 +99,8 @@ def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_l ) class Kosmos2ModelOutput(ModelOutput): r""" - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` @@ -121,7 +118,7 @@ class Kosmos2ModelOutput(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_embeds: Optional[torch.FloatTensor] = None @@ -147,11 +144,8 @@ class Kosmos2ForConditionalGenerationModelOutput(ModelOutput): Language modeling loss (for next-token prediction). logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` @@ -170,7 +164,7 @@ class Kosmos2ForConditionalGenerationModelOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_embeds: Optional[torch.FloatTensor] = None @@ -1006,7 +1000,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, @@ -1259,7 +1253,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, @@ -1342,7 +1336,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, labels: Optional[torch.LongTensor] = None, @@ -1561,7 +1555,7 @@ def forward( image_embeds_position_mask: Optional[torch.Tensor] = None, attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, image_embeds: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, @@ -1697,7 +1691,7 @@ def forward( image_embeds_position_mask: Optional[torch.Tensor] = None, attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, image_embeds: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py b/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py index c51d9109b48b..51357a57726c 100644 --- a/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py +++ b/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py @@ -150,7 +150,7 @@ def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_l - 1 for places where to put the image features, - 0 for places that are not for image features (i.e. for text tokens). - past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + past_key_values (`Cache` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that @@ -210,7 +210,7 @@ def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_l [What are attention masks?](../glossary#attention-mask) - past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + past_key_values (`Cache` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that @@ -272,11 +272,8 @@ class Kosmos2_5ModelOutput(ModelOutput): the weighted average in the self-attention heads. vision_model_output(`BaseModelOutputWithPooling`, *optional*): The output of the [`Kosmos2VisionModel`]. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` @@ -284,7 +281,7 @@ class Kosmos2_5ModelOutput(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None width: Optional[torch.FloatTensor] = None @@ -334,11 +331,8 @@ class Kosmos2_5ForConditionalGenerationModelOutput(ModelOutput): the weighted average in the self-attention heads. vision_model_output(`BaseModelOutputWithPooling`, *optional*): The output of the [`Kosmos2VisionModel`]. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` diff --git a/src/transformers/models/kyutai_speech_to_text/modeling_kyutai_speech_to_text.py b/src/transformers/models/kyutai_speech_to_text/modeling_kyutai_speech_to_text.py index 10dc2b629fbf..9eba7e163670 100644 --- a/src/transformers/models/kyutai_speech_to_text/modeling_kyutai_speech_to_text.py +++ b/src/transformers/models/kyutai_speech_to_text/modeling_kyutai_speech_to_text.py @@ -761,7 +761,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence kwargs (`dict`, *optional*): diff --git a/src/transformers/models/led/modeling_led.py b/src/transformers/models/led/modeling_led.py index 9354a7a7c5c0..e34a261df552 100755 --- a/src/transformers/models/led/modeling_led.py +++ b/src/transformers/models/led/modeling_led.py @@ -1027,7 +1027,7 @@ def forward( *(decoder_attention_heads,)*. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for encoder attention heads in a given layer of size *(decoder_attention_heads,)*. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`): Whether the base model outputs attentions. This requires the attentions tensor to be reshaped in this function. """ @@ -1190,9 +1190,8 @@ class LEDSeq2SeqModelOutput(ModelOutput): If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, hidden_size)` is output. - past_key_values (`list[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, - num_heads, sequence_length, embed_size_per_head)`). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1206,7 +1205,7 @@ class LEDSeq2SeqModelOutput(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None decoder_hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None decoder_attentions: Optional[tuple[torch.FloatTensor, ...]] = None cross_attentions: Optional[tuple[torch.FloatTensor, ...]] = None @@ -1228,9 +1227,8 @@ class LEDSeq2SeqLMOutput(ModelOutput): Language modeling loss. logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`list[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, - num_heads, sequence_length, embed_size_per_head)`). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1245,7 +1243,7 @@ class LEDSeq2SeqLMOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None decoder_hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None decoder_attentions: Optional[tuple[torch.FloatTensor, ...]] = None cross_attentions: Optional[tuple[torch.FloatTensor, ...]] = None @@ -1267,9 +1265,8 @@ class LEDSeq2SeqSequenceClassifierOutput(ModelOutput): Classification (or regression if config.num_labels==1) loss. logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`): Classification (or regression if config.num_labels==1) scores (before SoftMax). - past_key_values (`list[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, - num_heads, sequence_length, embed_size_per_head)`). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1284,7 +1281,7 @@ class LEDSeq2SeqSequenceClassifierOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None decoder_hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None decoder_attentions: Optional[tuple[torch.FloatTensor, ...]] = None cross_attentions: Optional[tuple[torch.FloatTensor, ...]] = None @@ -1304,9 +1301,8 @@ class LEDSeq2SeqQuestionAnsweringModelOutput(ModelOutput): r""" loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided): Total span extraction loss is the sum of a Cross-Entropy for the start and end positions. - past_key_values (`list[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, - num_heads, sequence_length, embed_size_per_head)`). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1322,7 +1318,7 @@ class LEDSeq2SeqQuestionAnsweringModelOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None start_logits: Optional[torch.FloatTensor] = None end_logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None decoder_hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None decoder_attentions: Optional[tuple[torch.FloatTensor, ...]] = None cross_attentions: Optional[tuple[torch.FloatTensor, ...]] = None @@ -1709,10 +1705,8 @@ def forward( - 1 indicates the head is **not masked**, - 0 indicates the head is **masked**. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1899,7 +1893,7 @@ def forward( cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, global_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, @@ -2064,7 +2058,7 @@ def forward( cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, global_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/lfm2/modeling_lfm2.py b/src/transformers/models/lfm2/modeling_lfm2.py index d802bd8e81a9..5ea4314968e2 100644 --- a/src/transformers/models/lfm2/modeling_lfm2.py +++ b/src/transformers/models/lfm2/modeling_lfm2.py @@ -544,7 +544,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Lfm2HybridConvCache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs, ) -> torch.Tensor: diff --git a/src/transformers/models/lfm2/modular_lfm2.py b/src/transformers/models/lfm2/modular_lfm2.py index 5d3791cbe3b1..5832a4d457a0 100644 --- a/src/transformers/models/lfm2/modular_lfm2.py +++ b/src/transformers/models/lfm2/modular_lfm2.py @@ -409,7 +409,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Lfm2HybridConvCache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs, ) -> torch.Tensor: diff --git a/src/transformers/models/llama4/modeling_llama4.py b/src/transformers/models/llama4/modeling_llama4.py index 223d4a107806..a53443004d49 100644 --- a/src/transformers/models/llama4/modeling_llama4.py +++ b/src/transformers/models/llama4/modeling_llama4.py @@ -392,7 +392,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, # necessary, but kept here for BC @@ -657,8 +657,7 @@ class Llama4CausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -669,7 +668,7 @@ class Llama4CausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/llava/modeling_llava.py b/src/transformers/models/llava/modeling_llava.py index ae8956d4df70..9a116dac4d23 100644 --- a/src/transformers/models/llava/modeling_llava.py +++ b/src/transformers/models/llava/modeling_llava.py @@ -44,8 +44,7 @@ class LlavaModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -70,8 +69,7 @@ class LlavaCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -82,7 +80,7 @@ class LlavaCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/llava_next/modeling_llava_next.py b/src/transformers/models/llava_next/modeling_llava_next.py index a319afec0337..8cca63f4a66c 100644 --- a/src/transformers/models/llava_next/modeling_llava_next.py +++ b/src/transformers/models/llava_next/modeling_llava_next.py @@ -154,8 +154,7 @@ def unpad_image(tensor, original_size): class LlavaNextModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -180,8 +179,7 @@ class LlavaNextCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -192,7 +190,7 @@ class LlavaNextCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/llava_next_video/modeling_llava_next_video.py b/src/transformers/models/llava_next_video/modeling_llava_next_video.py index 3845c301cc8f..3ef172962c2c 100644 --- a/src/transformers/models/llava_next_video/modeling_llava_next_video.py +++ b/src/transformers/models/llava_next_video/modeling_llava_next_video.py @@ -52,8 +52,7 @@ class LlavaNextVideoModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -83,8 +82,7 @@ class LlavaNextVideoCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -98,7 +96,7 @@ class LlavaNextVideoCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/llava_next_video/modular_llava_next_video.py b/src/transformers/models/llava_next_video/modular_llava_next_video.py index f4802930f784..73745f435b7d 100644 --- a/src/transformers/models/llava_next_video/modular_llava_next_video.py +++ b/src/transformers/models/llava_next_video/modular_llava_next_video.py @@ -183,8 +183,7 @@ def __init__( class LlavaNextVideoModelOutputWithPast(LlavaNextModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -206,8 +205,7 @@ class LlavaNextVideoCausalLMOutputWithPast(LlavaNextCausalLMOutputWithPast): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/llava_onevision/modeling_llava_onevision.py b/src/transformers/models/llava_onevision/modeling_llava_onevision.py index 204cd157c3fd..e4cb0c9aeafd 100644 --- a/src/transformers/models/llava_onevision/modeling_llava_onevision.py +++ b/src/transformers/models/llava_onevision/modeling_llava_onevision.py @@ -53,8 +53,7 @@ class LlavaOnevisionModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -84,8 +83,7 @@ class LlavaOnevisionCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -99,7 +97,7 @@ class LlavaOnevisionCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/m2m_100/modeling_m2m_100.py b/src/transformers/models/m2m_100/modeling_m2m_100.py index e87893691c8b..6015aa54d76b 100755 --- a/src/transformers/models/m2m_100/modeling_m2m_100.py +++ b/src/transformers/models/m2m_100/modeling_m2m_100.py @@ -462,7 +462,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -1001,9 +1001,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/marian/modeling_marian.py b/src/transformers/models/marian/modeling_marian.py index 1b2f0b9e85bf..342e622321a8 100755 --- a/src/transformers/models/marian/modeling_marian.py +++ b/src/transformers/models/marian/modeling_marian.py @@ -405,7 +405,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -938,9 +938,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/mbart/modeling_mbart.py b/src/transformers/models/mbart/modeling_mbart.py index d1846c2531f6..21c54b6de60e 100755 --- a/src/transformers/models/mbart/modeling_mbart.py +++ b/src/transformers/models/mbart/modeling_mbart.py @@ -406,7 +406,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -984,9 +984,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/megatron_bert/modeling_megatron_bert.py b/src/transformers/models/megatron_bert/modeling_megatron_bert.py index 0c4cb0f93f8e..4987bd15dffd 100755 --- a/src/transformers/models/megatron_bert/modeling_megatron_bert.py +++ b/src/transformers/models/megatron_bert/modeling_megatron_bert.py @@ -497,7 +497,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -773,7 +773,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1022,7 +1022,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/mimi/modeling_mimi.py b/src/transformers/models/mimi/modeling_mimi.py index 119f4a4d1afb..64537d5fcd94 100644 --- a/src/transformers/models/mimi/modeling_mimi.py +++ b/src/transformers/models/mimi/modeling_mimi.py @@ -957,7 +957,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence kwargs (`dict`, *optional*): @@ -1055,19 +1055,8 @@ def forward( config.n_positions - 1]`. [What are position IDs?](../glossary#position-ids) - past_key_values (`Cache` or `tuple(tuple(torch.FloatTensor))`, *optional*): - Pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention - blocks) that can be used to speed up sequential decoding. This typically consists in the `past_key_values` - returned by the model at a previous stage of decoding, when `use_cache=True` or `config.use_cache=True`. - - Two formats are allowed: - - a [`~cache_utils.Cache`] instance; - - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`). This is also known as the legacy - cache format. - - The model will output the same cache format that is fed as input. If no `past_key_values` are passed, the - legacy cache format will be returned. + past_key_values (`Cache`, *optional*): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). If `past_key_values` are used, the user can optionally input only the last `input_ids` (those that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all `input_ids` diff --git a/src/transformers/models/minimax/modeling_minimax.py b/src/transformers/models/minimax/modeling_minimax.py index ac5e0fe2a24c..633e053e2d54 100644 --- a/src/transformers/models/minimax/modeling_minimax.py +++ b/src/transformers/models/minimax/modeling_minimax.py @@ -517,7 +517,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, output_router_logits: Optional[bool] = False, use_cache: Optional[bool] = False, @@ -532,7 +532,7 @@ def forward( with `head_dim` being the embedding dimension of each attention head. attention_mask (`torch.Tensor`, *optional*): attention mask of size `(batch, sequence_length)` where padding elements are indicated by 0. - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. diff --git a/src/transformers/models/minimax/modular_minimax.py b/src/transformers/models/minimax/modular_minimax.py index 9026457e35cb..76f9df0d5304 100644 --- a/src/transformers/models/minimax/modular_minimax.py +++ b/src/transformers/models/minimax/modular_minimax.py @@ -412,7 +412,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, output_router_logits: Optional[bool] = False, use_cache: Optional[bool] = False, @@ -427,7 +427,7 @@ def forward( with `head_dim` being the embedding dimension of each attention head. attention_mask (`torch.Tensor`, *optional*): attention mask of size `(batch, sequence_length)` where padding elements are indicated by 0. - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. diff --git a/src/transformers/models/mistral3/modeling_mistral3.py b/src/transformers/models/mistral3/modeling_mistral3.py index ecfb3080ee96..2c2a53a54352 100644 --- a/src/transformers/models/mistral3/modeling_mistral3.py +++ b/src/transformers/models/mistral3/modeling_mistral3.py @@ -135,8 +135,7 @@ class Mistral3CausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -147,7 +146,7 @@ class Mistral3CausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None @@ -162,8 +161,7 @@ class Mistral3CausalLMOutputWithPast(ModelOutput): class Mistral3ModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/mixtral/modeling_mixtral.py b/src/transformers/models/mixtral/modeling_mixtral.py index b5786e910d31..2412092aeb86 100644 --- a/src/transformers/models/mixtral/modeling_mixtral.py +++ b/src/transformers/models/mixtral/modeling_mixtral.py @@ -313,7 +313,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[TransformersKwargs], ) -> torch.FloatTensor: diff --git a/src/transformers/models/mixtral/modular_mixtral.py b/src/transformers/models/mixtral/modular_mixtral.py index ffcf8224353f..d897824c4cff 100644 --- a/src/transformers/models/mixtral/modular_mixtral.py +++ b/src/transformers/models/mixtral/modular_mixtral.py @@ -245,7 +245,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[TransformersKwargs], ) -> torch.FloatTensor: diff --git a/src/transformers/models/mllama/modeling_mllama.py b/src/transformers/models/mllama/modeling_mllama.py index 2125af6c12d2..e30ac5a8fa64 100644 --- a/src/transformers/models/mllama/modeling_mllama.py +++ b/src/transformers/models/mllama/modeling_mllama.py @@ -635,7 +635,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): diff --git a/src/transformers/models/moshi/modeling_moshi.py b/src/transformers/models/moshi/modeling_moshi.py index 27c08626115d..868d050db5c9 100644 --- a/src/transformers/models/moshi/modeling_moshi.py +++ b/src/transformers/models/moshi/modeling_moshi.py @@ -83,7 +83,7 @@ class MoshiConditionalGenerationGenerateOutput(ModelOutput): hidden_states (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `output_hidden_states=True`): Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of `torch.FloatTensor` of shape `(batch_size*num_beams*num_return_sequences, generated_length, hidden_size)`. - past_key_values (`tuple(tuple(torch.FloatTensor)))`, *optional*, returned when `use_cache=True`): + past_key_values (`Cache`, *optional*, returned when `use_cache=True`): Contains the model cache, used to speed up decoding. Different models have a different cache format, check the model's documentation. Usually, a [`~cache_utils.Cache`] instance. audio_codes (`torch.LongTensor` of shape `(batch_size*num_return_sequences, num_codeooks, sequence_length)`, *optional*): @@ -98,7 +98,7 @@ class MoshiConditionalGenerationGenerateOutput(ModelOutput): beam_indices: Optional[torch.LongTensor] = None attentions: Optional[tuple[tuple[torch.FloatTensor]]] = None hidden_states: Optional[tuple[tuple[torch.FloatTensor]]] = None - past_key_values: Optional[tuple[tuple[tuple[torch.FloatTensor]]]] = None + past_key_values: Optional[Cache] = None audio_codes: Optional[torch.LongTensor] = None @@ -115,8 +115,7 @@ class MoshiCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -125,7 +124,7 @@ class MoshiCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None attentions: Optional[tuple[torch.FloatTensor, ...]] = None @@ -143,8 +142,7 @@ class MoshiConditionalGenerationOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the text language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -152,7 +150,7 @@ class MoshiConditionalGenerationOutputWithPast(ModelOutput): Audio language modeling loss (for next-token prediction). audio_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the audio language modeling heads. - depth_past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + depth_past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): Past key-values of the depth decoder. depth_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): Hidden states of the depth decoder @@ -164,12 +162,12 @@ class MoshiConditionalGenerationOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None attentions: Optional[tuple[torch.FloatTensor, ...]] = None depth_loss: Optional[torch.FloatTensor] = None audio_logits: Optional[torch.FloatTensor] = None - depth_past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + depth_past_key_values: Optional[Cache] = None depth_hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None depth_attentions: Optional[tuple[torch.FloatTensor, ...]] = None @@ -764,7 +762,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence kwargs (`dict`, *optional*): @@ -908,19 +906,8 @@ def forward( - 1 indicates the head is **not masked**, - 0 indicates the head is **masked**. - past_key_values (`Cache` or `tuple(tuple(torch.FloatTensor))`, *optional*): - Pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention - blocks) that can be used to speed up sequential decoding. This typically consists in the `past_key_values` - returned by the model at a previous stage of decoding, when `use_cache=True` or `config.use_cache=True`. - - Two formats are allowed: - - a [`~cache_utils.Cache`] instance; - - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`). This is also known as the legacy - cache format. - - The model will output the same cache format that is fed as input. If no `past_key_values` are passed, the - legacy cache format will be returned. + past_key_values (`Cache`, *optional*): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). If `past_key_values` are used, the user can optionally input only the last `input_ids` (those that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all `input_ids` diff --git a/src/transformers/models/mpt/modeling_mpt.py b/src/transformers/models/mpt/modeling_mpt.py index 8a9dafa564fc..57b875432758 100644 --- a/src/transformers/models/mpt/modeling_mpt.py +++ b/src/transformers/models/mpt/modeling_mpt.py @@ -305,7 +305,7 @@ def set_input_embeddings(self, new_embeddings: torch.Tensor): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[tuple[tuple[torch.Tensor, torch.Tensor], ...], Cache]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, @@ -445,7 +445,7 @@ def set_output_embeddings(self, new_embeddings: torch.Tensor): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor, torch.Tensor], ...]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, @@ -543,7 +543,7 @@ def __init__(self, config: MptConfig): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor, torch.Tensor], ...]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, @@ -666,7 +666,7 @@ def __init__(self, config: MptConfig): def forward( self, input_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor, torch.Tensor], ...]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/musicgen/modeling_musicgen.py b/src/transformers/models/musicgen/modeling_musicgen.py index 3860632d7306..fec5fabc5470 100644 --- a/src/transformers/models/musicgen/modeling_musicgen.py +++ b/src/transformers/models/musicgen/modeling_musicgen.py @@ -365,7 +365,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -487,7 +487,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -751,7 +751,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -878,7 +878,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, @@ -1699,7 +1699,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.BoolTensor] = None, encoder_outputs: Optional[tuple[torch.FloatTensor]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/musicgen_melody/modeling_musicgen_melody.py b/src/transformers/models/musicgen_melody/modeling_musicgen_melody.py index 2c5e53fd8910..e7237157e156 100644 --- a/src/transformers/models/musicgen_melody/modeling_musicgen_melody.py +++ b/src/transformers/models/musicgen_melody/modeling_musicgen_melody.py @@ -75,9 +75,8 @@ class MusicgenMelodyOutputWithPast(ModelOutput): Language modeling loss (for next-token prediction). logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -88,7 +87,7 @@ class MusicgenMelodyOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None encoder_hidden_states: Optional[torch.FloatTensor] = None @@ -354,7 +353,7 @@ def forward( attention_mask (`torch.FloatTensor`): attention mask of size `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. layer_head_mask (`torch.FloatTensor`): mask for attention heads in a given layer of size `(attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -455,7 +454,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -689,7 +688,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -809,7 +808,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -1585,7 +1584,7 @@ def forward( input_features: Optional[torch.FloatTensor] = None, decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.BoolTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, diff --git a/src/transformers/models/mvp/modeling_mvp.py b/src/transformers/models/mvp/modeling_mvp.py index d5a5b2188cf5..22af2b5a74de 100644 --- a/src/transformers/models/mvp/modeling_mvp.py +++ b/src/transformers/models/mvp/modeling_mvp.py @@ -383,7 +383,7 @@ def forward( `(2, decoder_attention_heads, pro_len, head_dim)`. cross_attn_prompt (`torch.FloatTensor`): prompt of cross attention of shape `(2, decoder_attention_heads, pro_len, head_dim)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -755,7 +755,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -804,10 +804,8 @@ def forward( - 1 indicates the head is **not masked**, - 0 indicates the head is **masked**. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1009,7 +1007,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[list[torch.FloatTensor]] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, @@ -1172,7 +1170,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[list[torch.FloatTensor]] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, @@ -1700,7 +1698,7 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/nemotron/modeling_nemotron.py b/src/transformers/models/nemotron/modeling_nemotron.py index 55a33f9ffba5..35b1aedb71f8 100644 --- a/src/transformers/models/nemotron/modeling_nemotron.py +++ b/src/transformers/models/nemotron/modeling_nemotron.py @@ -542,7 +542,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): diff --git a/src/transformers/models/nllb_moe/modeling_nllb_moe.py b/src/transformers/models/nllb_moe/modeling_nllb_moe.py index 5969229adc4a..f0131b6b999b 100644 --- a/src/transformers/models/nllb_moe/modeling_nllb_moe.py +++ b/src/transformers/models/nllb_moe/modeling_nllb_moe.py @@ -773,7 +773,7 @@ def forward( mask for attention heads in a given layer of size `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under @@ -1128,7 +1128,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -1178,10 +1178,8 @@ def forward( - 1 indicates the head is **not masked**, - 0 indicates the head is **masked**. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1470,7 +1468,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, @@ -1614,7 +1612,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/olmoe/modeling_olmoe.py b/src/transformers/models/olmoe/modeling_olmoe.py index 277d601df04b..9d7d0727da9b 100644 --- a/src/transformers/models/olmoe/modeling_olmoe.py +++ b/src/transformers/models/olmoe/modeling_olmoe.py @@ -662,7 +662,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): diff --git a/src/transformers/models/opt/modeling_opt.py b/src/transformers/models/opt/modeling_opt.py index 6f06a2214768..a2c4bb500a65 100644 --- a/src/transformers/models/opt/modeling_opt.py +++ b/src/transformers/models/opt/modeling_opt.py @@ -143,7 +143,7 @@ def __init__( def forward( self, hidden_states: torch.Tensor, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, layer_head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False, @@ -221,7 +221,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, layer_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, position_ids: Optional[torch.LongTensor] = None, @@ -241,7 +241,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence.. """ @@ -537,8 +537,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -703,7 +702,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -776,7 +775,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, @@ -884,7 +883,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, @@ -996,7 +995,7 @@ def forward( input_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, start_positions: Optional[torch.LongTensor] = None, end_positions: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/ovis2/modeling_ovis2.py b/src/transformers/models/ovis2/modeling_ovis2.py index 6f6e95891609..75ff19ab9d14 100644 --- a/src/transformers/models/ovis2/modeling_ovis2.py +++ b/src/transformers/models/ovis2/modeling_ovis2.py @@ -27,6 +27,7 @@ from torch import nn from ...activations import ACT2FN +from ...cache_utils import Cache from ...generation import GenerationMixin from ...integrations import use_kernel_forward_from_hub from ...modeling_layers import GradientCheckpointingLayer @@ -47,8 +48,7 @@ class Ovis2ModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -73,8 +73,7 @@ class Ovis2CausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -85,7 +84,7 @@ class Ovis2CausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None @@ -596,7 +595,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, @@ -717,7 +716,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/ovis2/modular_ovis2.py b/src/transformers/models/ovis2/modular_ovis2.py index 6856be8feb4f..09ce53703a15 100644 --- a/src/transformers/models/ovis2/modular_ovis2.py +++ b/src/transformers/models/ovis2/modular_ovis2.py @@ -19,6 +19,7 @@ import torch from torch import nn +from ...cache_utils import Cache from ...generation import GenerationMixin from ...modeling_outputs import BaseModelOutput from ...modeling_utils import PreTrainedModel @@ -257,7 +258,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, @@ -351,7 +352,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/paligemma/modeling_paligemma.py b/src/transformers/models/paligemma/modeling_paligemma.py index 1ae480913ca1..5600af24344f 100644 --- a/src/transformers/models/paligemma/modeling_paligemma.py +++ b/src/transformers/models/paligemma/modeling_paligemma.py @@ -49,12 +49,6 @@ ) class PaligemmaModelOutputWithPast(BaseModelOutputWithPast): r""" - past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) - - Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. image_hidden_states (`torch.FloatTensor`, *optional*): A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`. image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state. @@ -76,8 +70,7 @@ class PaliGemmaCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.text_config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -88,7 +81,7 @@ class PaliGemmaCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None @@ -280,7 +273,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, @@ -440,7 +433,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, diff --git a/src/transformers/models/pegasus/modeling_pegasus.py b/src/transformers/models/pegasus/modeling_pegasus.py index c32dc54f44c0..58eedc77bc3c 100755 --- a/src/transformers/models/pegasus/modeling_pegasus.py +++ b/src/transformers/models/pegasus/modeling_pegasus.py @@ -396,7 +396,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -988,9 +988,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1222,7 +1220,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[torch.FloatTensor]] = None, - past_key_values: Optional[tuple[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, decoder_inputs_embeds: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, @@ -1402,7 +1400,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[torch.FloatTensor]] = None, - past_key_values: Optional[tuple[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, decoder_inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/pegasus_x/modeling_pegasus_x.py b/src/transformers/models/pegasus_x/modeling_pegasus_x.py index 8f7472bb4052..0279688c00e8 100755 --- a/src/transformers/models/pegasus_x/modeling_pegasus_x.py +++ b/src/transformers/models/pegasus_x/modeling_pegasus_x.py @@ -696,7 +696,7 @@ def forward( cross attention input to the layer of shape *(seq_len, batch, embed_dim)* encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -1248,9 +1248,7 @@ def forward( [What are attention masks?](../glossary#attention-mask) past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1469,7 +1467,7 @@ def forward( decoder_input_ids: Optional[torch.Tensor] = None, decoder_attention_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[torch.FloatTensor]] = None, - past_key_values: Optional[tuple[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, decoder_inputs_embeds: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, @@ -1619,7 +1617,7 @@ def forward( decoder_input_ids: Optional[torch.Tensor] = None, decoder_attention_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[torch.FloatTensor]] = None, - past_key_values: Optional[tuple[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, decoder_inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/perception_lm/modeling_perception_lm.py b/src/transformers/models/perception_lm/modeling_perception_lm.py index d310d44a0136..074e91e14e88 100644 --- a/src/transformers/models/perception_lm/modeling_perception_lm.py +++ b/src/transformers/models/perception_lm/modeling_perception_lm.py @@ -26,6 +26,7 @@ import torch.nn.functional as F from torch import nn +from ...cache_utils import Cache from ...generation import GenerationMixin from ...modeling_outputs import BaseModelOutputWithPast, ModelOutput from ...modeling_utils import PreTrainedModel @@ -109,8 +110,7 @@ class PerceptionLMPreTrainedModel(PreTrainedModel): class PerceptionLMModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -140,8 +140,7 @@ class PerceptionLMCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -155,7 +154,7 @@ class PerceptionLMCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None @@ -256,7 +255,7 @@ def forward( pixel_values_videos: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -355,7 +354,7 @@ def forward( pixel_values_videos: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/perception_lm/modular_perception_lm.py b/src/transformers/models/perception_lm/modular_perception_lm.py index b2d6e4090c3a..2e748c82a7bc 100644 --- a/src/transformers/models/perception_lm/modular_perception_lm.py +++ b/src/transformers/models/perception_lm/modular_perception_lm.py @@ -21,6 +21,7 @@ import torch.utils.checkpoint from torch import nn +from ...cache_utils import Cache from ...utils import ( auto_docstring, can_return_tuple, @@ -98,8 +99,7 @@ class PerceptionLMPreTrainedModel(LlavaPreTrainedModel): class PerceptionLMModelOutputWithPast(LlavaModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -121,8 +121,7 @@ class PerceptionLMCausalLMOutputWithPast(LlavaCausalLMOutputWithPast): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -217,7 +216,7 @@ def forward( pixel_values_videos: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -325,7 +324,7 @@ def forward( pixel_values_videos: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/persimmon/modeling_persimmon.py b/src/transformers/models/persimmon/modeling_persimmon.py index 4c7cfd236ac5..02ec819315b7 100644 --- a/src/transformers/models/persimmon/modeling_persimmon.py +++ b/src/transformers/models/persimmon/modeling_persimmon.py @@ -322,7 +322,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, @@ -338,7 +338,7 @@ def forward( Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, config.n_positions - 1]`. [What are position IDs?](../glossary#position-ids) - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under diff --git a/src/transformers/models/phi/modeling_phi.py b/src/transformers/models/phi/modeling_phi.py index b9b719425229..165a2b887423 100644 --- a/src/transformers/models/phi/modeling_phi.py +++ b/src/transformers/models/phi/modeling_phi.py @@ -221,7 +221,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/phi/modular_phi.py b/src/transformers/models/phi/modular_phi.py index d17501ed24dd..b7c9b9c926ed 100644 --- a/src/transformers/models/phi/modular_phi.py +++ b/src/transformers/models/phi/modular_phi.py @@ -132,7 +132,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/phimoe/modeling_phimoe.py b/src/transformers/models/phimoe/modeling_phimoe.py index 295af2a6c736..d3d79847b073 100644 --- a/src/transformers/models/phimoe/modeling_phimoe.py +++ b/src/transformers/models/phimoe/modeling_phimoe.py @@ -822,7 +822,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, output_router_logits: Optional[bool] = False, use_cache: Optional[bool] = False, @@ -835,7 +835,7 @@ def forward( hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` attention_mask (`torch.FloatTensor`, *optional*): attention mask of size `(batch, sequence_length)` where padding elements are indicated by 0. - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. diff --git a/src/transformers/models/plbart/modeling_plbart.py b/src/transformers/models/plbart/modeling_plbart.py index 38085a72264c..60239bf9ac54 100644 --- a/src/transformers/models/plbart/modeling_plbart.py +++ b/src/transformers/models/plbart/modeling_plbart.py @@ -752,7 +752,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -904,9 +904,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/prophetnet/modeling_prophetnet.py b/src/transformers/models/prophetnet/modeling_prophetnet.py index a79c803e77b9..d69bb7d9c802 100644 --- a/src/transformers/models/prophetnet/modeling_prophetnet.py +++ b/src/transformers/models/prophetnet/modeling_prophetnet.py @@ -129,9 +129,8 @@ class ProphetNetSeq2SeqLMOutput(ModelOutput): logits_ngram (`torch.FloatTensor` of shape `(batch_size, ngram * decoder_sequence_length, config.vocab_size)`): Prediction scores of the predict stream language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`list[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, - num_attn_heads, decoder_sequence_length, embed_size_per_head)`). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -154,7 +153,7 @@ class ProphetNetSeq2SeqLMOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None logits_ngram: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None decoder_hidden_states: Optional[tuple[torch.FloatTensor]] = None decoder_ngram_hidden_states: Optional[tuple[torch.FloatTensor]] = None decoder_attentions: Optional[tuple[torch.FloatTensor]] = None @@ -190,9 +189,8 @@ class ProphetNetSeq2SeqModelOutput(ModelOutput): hidden_size)` is output. last_hidden_state_ngram (`torch.FloatTensor` of shape `(batch_size,ngram * decoder_sequence_length, config.vocab_size)`, *optional*): Sequence of predict stream hidden-states at the output of the last layer of the decoder of the model. - past_key_values (`list[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, - num_attn_heads, decoder_sequence_length, embed_size_per_head)`). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -214,7 +212,7 @@ class ProphetNetSeq2SeqModelOutput(ModelOutput): last_hidden_state: torch.FloatTensor last_hidden_state_ngram: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None decoder_hidden_states: Optional[tuple[torch.FloatTensor]] = None decoder_ngram_hidden_states: Optional[tuple[torch.FloatTensor]] = None decoder_attentions: Optional[tuple[torch.FloatTensor]] = None @@ -249,9 +247,8 @@ class ProphetNetDecoderModelOutput(ModelOutput): hidden_size)` is output. last_hidden_state_ngram (`torch.FloatTensor` of shape `(batch_size, ngram * decoder_sequence_length, config.vocab_size)`): Sequence of predict stream hidden-states at the output of the last layer of the decoder of the model. - past_key_values (`list[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, - num_attn_heads, decoder_sequence_length, embed_size_per_head)`). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -271,7 +268,7 @@ class ProphetNetDecoderModelOutput(ModelOutput): last_hidden_state: torch.FloatTensor last_hidden_state_ngram: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None hidden_states_ngram: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None @@ -301,9 +298,8 @@ class ProphetNetDecoderLMOutput(ModelOutput): logits_ngram (`torch.FloatTensor` of shape `(batch_size, ngram * decoder_sequence_length, config.vocab_size)`): Prediction scores of the predict stream language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`list[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, - num_attn_heads, decoder_sequence_length, embed_size_per_head)`). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -324,7 +320,7 @@ class ProphetNetDecoderLMOutput(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None logits_ngram: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None hidden_states_ngram: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None @@ -613,7 +609,7 @@ def prepare_for_onnx_export_(self): def forward( self, hidden_states, - past_key_values: Optional[tuple[Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask=None, layer_head_mask=None, extended_predict_attention_mask=None, @@ -1188,7 +1184,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -1522,7 +1518,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, decoder_inputs_embeds: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, @@ -1658,7 +1654,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, decoder_inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, @@ -1862,7 +1858,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.Tensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/qwen2_5_omni/modeling_qwen2_5_omni.py b/src/transformers/models/qwen2_5_omni/modeling_qwen2_5_omni.py index 51f9440001d6..6b69ced26591 100644 --- a/src/transformers/models/qwen2_5_omni/modeling_qwen2_5_omni.py +++ b/src/transformers/models/qwen2_5_omni/modeling_qwen2_5_omni.py @@ -494,8 +494,7 @@ class Qwen2_5OmniThinkerCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`, *optional*): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -505,7 +504,7 @@ class Qwen2_5OmniThinkerCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -1439,7 +1438,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, @@ -1457,7 +1456,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence. position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): @@ -2056,8 +2055,7 @@ class Qwen2_5OmniTalkerCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -2070,7 +2068,7 @@ class Qwen2_5OmniTalkerCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None diff --git a/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py b/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py index 260ead04b76c..007f98345988 100644 --- a/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py +++ b/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py @@ -1549,8 +1549,7 @@ class Qwen2_5OmniThinkerCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`, *optional*): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1560,7 +1559,7 @@ class Qwen2_5OmniThinkerCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -2504,8 +2503,7 @@ class Qwen2_5OmniTalkerCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -2518,7 +2516,7 @@ class Qwen2_5OmniTalkerCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None diff --git a/src/transformers/models/qwen2_5_vl/modeling_qwen2_5_vl.py b/src/transformers/models/qwen2_5_vl/modeling_qwen2_5_vl.py index b3303b363dae..6d05cc32f4a8 100644 --- a/src/transformers/models/qwen2_5_vl/modeling_qwen2_5_vl.py +++ b/src/transformers/models/qwen2_5_vl/modeling_qwen2_5_vl.py @@ -473,8 +473,7 @@ def forward(self, hidden_states: torch.Tensor, grid_thw: torch.Tensor, **kwargs) class Qwen2_5_VLModelOutputWithPast(ModelOutput): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -483,7 +482,7 @@ class Qwen2_5_VLModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -705,7 +704,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, @@ -723,7 +722,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence. position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): @@ -1340,8 +1339,7 @@ class Qwen2_5_VLCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1351,7 +1349,7 @@ class Qwen2_5_VLCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None diff --git a/src/transformers/models/qwen2_moe/modeling_qwen2_moe.py b/src/transformers/models/qwen2_moe/modeling_qwen2_moe.py index f9540485e656..070eb6e89fd5 100644 --- a/src/transformers/models/qwen2_moe/modeling_qwen2_moe.py +++ b/src/transformers/models/qwen2_moe/modeling_qwen2_moe.py @@ -673,7 +673,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, output_router_logits: Optional[bool] = False, use_cache: Optional[bool] = False, @@ -695,7 +695,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence. position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): diff --git a/src/transformers/models/qwen2_vl/modeling_qwen2_vl.py b/src/transformers/models/qwen2_vl/modeling_qwen2_vl.py index bb9fda02df18..0509ef9e085e 100644 --- a/src/transformers/models/qwen2_vl/modeling_qwen2_vl.py +++ b/src/transformers/models/qwen2_vl/modeling_qwen2_vl.py @@ -64,8 +64,7 @@ class Qwen2VLModelOutputWithPast(ModelOutput): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -74,7 +73,7 @@ class Qwen2VLModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -93,8 +92,7 @@ class Qwen2VLCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -104,7 +102,7 @@ class Qwen2VLCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -567,7 +565,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, @@ -585,7 +583,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence. position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): diff --git a/src/transformers/models/qwen3_moe/modeling_qwen3_moe.py b/src/transformers/models/qwen3_moe/modeling_qwen3_moe.py index 62790435f17b..2056e7c76a3a 100644 --- a/src/transformers/models/qwen3_moe/modeling_qwen3_moe.py +++ b/src/transformers/models/qwen3_moe/modeling_qwen3_moe.py @@ -309,7 +309,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[FlashAttentionKwargs], ) -> torch.FloatTensor: @@ -327,7 +327,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence. position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): diff --git a/src/transformers/models/qwen3_moe/modular_qwen3_moe.py b/src/transformers/models/qwen3_moe/modular_qwen3_moe.py index 3ccaf4475fb7..b9213a5e5bbb 100644 --- a/src/transformers/models/qwen3_moe/modular_qwen3_moe.py +++ b/src/transformers/models/qwen3_moe/modular_qwen3_moe.py @@ -147,7 +147,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[FlashAttentionKwargs], ) -> torch.FloatTensor: diff --git a/src/transformers/models/qwen3_next/modeling_qwen3_next.py b/src/transformers/models/qwen3_next/modeling_qwen3_next.py index ae2d3664e10e..a05857a247b7 100644 --- a/src/transformers/models/qwen3_next/modeling_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modeling_qwen3_next.py @@ -883,7 +883,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[FlashAttentionKwargs], ) -> torch.FloatTensor: @@ -901,7 +901,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence. position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): diff --git a/src/transformers/models/qwen3_next/modular_qwen3_next.py b/src/transformers/models/qwen3_next/modular_qwen3_next.py index 1854a391cfb6..bc902b8e1b5f 100644 --- a/src/transformers/models/qwen3_next/modular_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modular_qwen3_next.py @@ -647,7 +647,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[FlashAttentionKwargs], ) -> torch.FloatTensor: diff --git a/src/transformers/models/rag/modeling_rag.py b/src/transformers/models/rag/modeling_rag.py index f3932137a082..13389107a2cb 100644 --- a/src/transformers/models/rag/modeling_rag.py +++ b/src/transformers/models/rag/modeling_rag.py @@ -51,8 +51,7 @@ class RetrievAugLMMarginOutput(ModelOutput): Score between each retrieved document embeddings (see `retrieved_doc_embeds`) and `question_encoder_last_hidden_state`. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, - num_heads, sequence_length, embed_size_per_head)`). + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains precomputed hidden-states (key and values in the attention blocks) of the decoder that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -142,8 +141,7 @@ class RetrievAugLMOutput(ModelOutput): Score between each retrieved document embeddings (see `retrieved_doc_embeds`) and `question_encoder_last_hidden_state`. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, - num_heads, sequence_length, embed_size_per_head)`). + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains precomputed hidden-states (key and values in the attention blocks) of the decoder that can be used (see `past_key_values` input) to speed up sequential decoding. diff --git a/src/transformers/models/rembert/modeling_rembert.py b/src/transformers/models/rembert/modeling_rembert.py index 5c27186096de..a9ee455116c4 100755 --- a/src/transformers/models/rembert/modeling_rembert.py +++ b/src/transformers/models/rembert/modeling_rembert.py @@ -492,7 +492,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: bool = False, output_hidden_states: bool = False, @@ -690,7 +690,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -934,7 +934,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, diff --git a/src/transformers/models/roberta/modeling_roberta.py b/src/transformers/models/roberta/modeling_roberta.py index 105152a8f8dc..6999dddf1b1a 100644 --- a/src/transformers/models/roberta/modeling_roberta.py +++ b/src/transformers/models/roberta/modeling_roberta.py @@ -569,7 +569,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -749,7 +749,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -927,7 +927,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py b/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py index 3faebd368bb4..072466bd8b04 100644 --- a/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py +++ b/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py @@ -459,7 +459,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -636,7 +636,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -795,7 +795,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/roc_bert/modeling_roc_bert.py b/src/transformers/models/roc_bert/modeling_roc_bert.py index 76c198ed0b82..e0b8b4b434ba 100644 --- a/src/transformers/models/roc_bert/modeling_roc_bert.py +++ b/src/transformers/models/roc_bert/modeling_roc_bert.py @@ -578,7 +578,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -822,7 +822,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1352,7 +1352,7 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, labels: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, diff --git a/src/transformers/models/roformer/modeling_roformer.py b/src/transformers/models/roformer/modeling_roformer.py index aa10b27d0f05..56dce4cb753b 100644 --- a/src/transformers/models/roformer/modeling_roformer.py +++ b/src/transformers/models/roformer/modeling_roformer.py @@ -838,7 +838,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1071,7 +1071,7 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, diff --git a/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py b/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py index fe7341354a6d..15f368281775 100755 --- a/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py +++ b/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py @@ -1285,7 +1285,7 @@ def forward( encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - past_key_values (`Tuple(torch.FloatTensor)`): + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under @@ -1762,7 +1762,7 @@ def forward( attention_mask: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -1912,7 +1912,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, @@ -2032,7 +2032,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, @@ -2507,7 +2507,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, @@ -2759,7 +2759,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, @@ -3028,7 +3028,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, @@ -3346,7 +3346,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, @@ -3700,7 +3700,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py b/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py index 095917fae3f1..ccad4450451d 100644 --- a/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py +++ b/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py @@ -1119,7 +1119,7 @@ def forward( encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - past_key_values (`Tuple(torch.FloatTensor)`): + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under @@ -1805,7 +1805,7 @@ def forward( attention_mask: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -2715,7 +2715,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, @@ -2974,7 +2974,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, @@ -3251,7 +3251,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, @@ -3607,7 +3607,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, @@ -3998,7 +3998,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.LongTensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, diff --git a/src/transformers/models/shieldgemma2/modeling_shieldgemma2.py b/src/transformers/models/shieldgemma2/modeling_shieldgemma2.py index e27c01cb599e..49261f039a56 100644 --- a/src/transformers/models/shieldgemma2/modeling_shieldgemma2.py +++ b/src/transformers/models/shieldgemma2/modeling_shieldgemma2.py @@ -86,7 +86,7 @@ def forward( pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + past_key_values: Optional[Cache] = None, token_type_ids: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, diff --git a/src/transformers/models/smolvlm/modeling_smolvlm.py b/src/transformers/models/smolvlm/modeling_smolvlm.py index 5d302015a7c9..d536c52e12cf 100644 --- a/src/transformers/models/smolvlm/modeling_smolvlm.py +++ b/src/transformers/models/smolvlm/modeling_smolvlm.py @@ -419,10 +419,8 @@ class SmolVLMBaseModelOutputWithPast(ModelOutput): If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, hidden_size)` is output. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). + Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -433,7 +431,7 @@ class SmolVLMBaseModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None @@ -741,8 +739,8 @@ class SmolVLMCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). + Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. image_hidden_states (`tuple(torch.FloatTensor)`, *optional*): @@ -753,7 +751,7 @@ class SmolVLMCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[tuple[torch.FloatTensor]] = None diff --git a/src/transformers/models/speech_encoder_decoder/modeling_speech_encoder_decoder.py b/src/transformers/models/speech_encoder_decoder/modeling_speech_encoder_decoder.py index 9a519cd9a5dc..272ebdc741bc 100644 --- a/src/transformers/models/speech_encoder_decoder/modeling_speech_encoder_decoder.py +++ b/src/transformers/models/speech_encoder_decoder/modeling_speech_encoder_decoder.py @@ -20,6 +20,7 @@ from torch import nn from torch.nn import CrossEntropyLoss +from ...cache_utils import Cache from ...configuration_utils import PretrainedConfig from ...generation import GenerationMixin from ...modeling_outputs import BaseModelOutput, Seq2SeqLMOutput @@ -322,7 +323,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.BoolTensor] = None, encoder_outputs: Optional[tuple[torch.FloatTensor]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/speech_to_text/modeling_speech_to_text.py b/src/transformers/models/speech_to_text/modeling_speech_to_text.py index b1a380bc99b6..8cfc99266041 100755 --- a/src/transformers/models/speech_to_text/modeling_speech_to_text.py +++ b/src/transformers/models/speech_to_text/modeling_speech_to_text.py @@ -454,7 +454,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -822,10 +822,8 @@ def forward( - 1 indicates the head is **not masked**, - 0 indicates the head is **masked**. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1072,7 +1070,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -1223,7 +1221,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/speecht5/modeling_speecht5.py b/src/transformers/models/speecht5/modeling_speecht5.py index 6292358575fd..026585cdd77b 100644 --- a/src/transformers/models/speecht5/modeling_speecht5.py +++ b/src/transformers/models/speecht5/modeling_speecht5.py @@ -1145,7 +1145,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -1501,7 +1501,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1543,10 +1543,8 @@ def forward( - 1 indicates the head is **not masked**, - 0 indicates the head is **masked**. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1695,7 +1693,7 @@ def forward( speaker_embeddings: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1749,7 +1747,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -1797,7 +1795,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -2002,7 +2000,7 @@ def forward( decoder_head_mask: Optional[torch.FloatTensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, speaker_embeddings: Optional[torch.FloatTensor] = None, output_attentions: Optional[bool] = None, @@ -2160,7 +2158,7 @@ def forward( decoder_head_mask: Optional[torch.FloatTensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -2484,7 +2482,7 @@ def forward( decoder_head_mask: Optional[torch.FloatTensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -2839,7 +2837,7 @@ def forward( decoder_head_mask: Optional[torch.FloatTensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[tuple[tuple[torch.FloatTensor]]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/stablelm/modeling_stablelm.py b/src/transformers/models/stablelm/modeling_stablelm.py index 5413f54ee584..9daefe0a39df 100755 --- a/src/transformers/models/stablelm/modeling_stablelm.py +++ b/src/transformers/models/stablelm/modeling_stablelm.py @@ -546,7 +546,7 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, @@ -562,7 +562,7 @@ def forward( `[0, config.n_positions - 1]`. [What are position IDs?](../glossary#position-ids) - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): + past_key_values (`Cache`, *optional*): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under diff --git a/src/transformers/models/time_series_transformer/modeling_time_series_transformer.py b/src/transformers/models/time_series_transformer/modeling_time_series_transformer.py index 25abedadfe76..9810eae30d5e 100644 --- a/src/transformers/models/time_series_transformer/modeling_time_series_transformer.py +++ b/src/transformers/models/time_series_transformer/modeling_time_series_transformer.py @@ -570,7 +570,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -917,7 +917,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -958,10 +958,8 @@ def forward( - 1 indicates the head is **not masked**, - 0 indicates the head is **masked**. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1254,7 +1252,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[list[torch.FloatTensor]] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, output_hidden_states: Optional[bool] = None, output_attentions: Optional[bool] = None, use_cache: Optional[bool] = None, @@ -1516,7 +1514,7 @@ def forward( decoder_head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, encoder_outputs: Optional[list[torch.FloatTensor]] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, output_hidden_states: Optional[bool] = None, output_attentions: Optional[bool] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/trocr/modeling_trocr.py b/src/transformers/models/trocr/modeling_trocr.py index 83eb51b43444..70cded0a5147 100644 --- a/src/transformers/models/trocr/modeling_trocr.py +++ b/src/transformers/models/trocr/modeling_trocr.py @@ -362,7 +362,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size *(decoder_attention_heads,)*. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -535,10 +535,8 @@ def forward( - 1 indicates the head is **not masked**, - 0 indicates the head is **masked**. - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -752,7 +750,7 @@ def forward( encoder_attention_mask: Optional[torch.LongTensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/udop/modeling_udop.py b/src/transformers/models/udop/modeling_udop.py index 3debe9c62cb4..668ec6bfec3b 100644 --- a/src/transformers/models/udop/modeling_udop.py +++ b/src/transformers/models/udop/modeling_udop.py @@ -77,10 +77,9 @@ class BaseModelOutputWithAttentionMask(ModelOutput): - 1 for tokens that are **not masked**, - 0 for tokens that are **masked**. past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. Contains pre-computed hidden-states (key and values in the + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). + + Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): diff --git a/src/transformers/models/umt5/modeling_umt5.py b/src/transformers/models/umt5/modeling_umt5.py index bcf877e1da4c..a8c592b727c6 100644 --- a/src/transformers/models/umt5/modeling_umt5.py +++ b/src/transformers/models/umt5/modeling_umt5.py @@ -263,7 +263,7 @@ def forward( self, hidden_states: torch.Tensor, encoder_hidden_states: Optional[torch.Tensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, attention_mask: Optional[torch.Tensor] = None, layer_head_mask: Optional[torch.Tensor] = None, cache_position: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/video_llava/modeling_video_llava.py b/src/transformers/models/video_llava/modeling_video_llava.py index 896c357e3cd2..41a4d0abed17 100644 --- a/src/transformers/models/video_llava/modeling_video_llava.py +++ b/src/transformers/models/video_llava/modeling_video_llava.py @@ -45,8 +45,7 @@ class VideoLlavaModelOutputWithPast(ModelOutput): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -59,7 +58,7 @@ class VideoLlavaModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None @@ -79,8 +78,7 @@ class VideoLlavaCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -94,7 +92,7 @@ class VideoLlavaCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/vipllava/modeling_vipllava.py b/src/transformers/models/vipllava/modeling_vipllava.py index 6a8c6944bcb8..f9a376120d63 100644 --- a/src/transformers/models/vipllava/modeling_vipllava.py +++ b/src/transformers/models/vipllava/modeling_vipllava.py @@ -44,8 +44,7 @@ class VipLlavaModelOutputWithPast(BaseModelOutputWithPast): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -70,8 +69,7 @@ class VipLlavaCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -82,7 +80,7 @@ class VipLlavaCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None image_hidden_states: Optional[torch.FloatTensor] = None diff --git a/src/transformers/models/vision_encoder_decoder/modeling_vision_encoder_decoder.py b/src/transformers/models/vision_encoder_decoder/modeling_vision_encoder_decoder.py index d9f2c593a026..d6bc2dcc0f8e 100644 --- a/src/transformers/models/vision_encoder_decoder/modeling_vision_encoder_decoder.py +++ b/src/transformers/models/vision_encoder_decoder/modeling_vision_encoder_decoder.py @@ -22,6 +22,7 @@ import torch from torch import nn +from ...cache_utils import Cache from ...configuration_utils import PretrainedConfig from ...generation import GenerationMixin from ...modeling_outputs import BaseModelOutput, Seq2SeqLMOutput @@ -440,7 +441,7 @@ def forward( decoder_input_ids: Optional[torch.LongTensor] = None, decoder_attention_mask: Optional[torch.BoolTensor] = None, encoder_outputs: Optional[tuple[torch.FloatTensor]] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/whisper/modeling_whisper.py b/src/transformers/models/whisper/modeling_whisper.py index f636586ac8ba..da30a332d749 100644 --- a/src/transformers/models/whisper/modeling_whisper.py +++ b/src/transformers/models/whisper/modeling_whisper.py @@ -492,7 +492,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -813,16 +813,7 @@ def forward( - 0 indicates the head is **masked**. past_key_values (`EncoderDecoderCache` or `tuple(tuple(torch.FloatTensor))`, *optional*): - Pre-computed hidden-states that can be used to speed up auto-regressive (sequential) decoding. There are - four sets of pre-computed hidden-states: key and values states in the self-attention blocks (2) and - in the cross-attention blocks (2). The `past_key_values` are returned when `use_cache=True` is passed or - when `config.use_cache=True` - - Two formats are allowed: - - An [`~cache_utils.EncoderDecoderCache`] instance; - - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape - `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of diff --git a/src/transformers/models/xglm/modeling_xglm.py b/src/transformers/models/xglm/modeling_xglm.py index b900c08316d8..cfa42502399b 100755 --- a/src/transformers/models/xglm/modeling_xglm.py +++ b/src/transformers/models/xglm/modeling_xglm.py @@ -322,7 +322,7 @@ def forward( `(encoder_attention_heads,)`. cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of size `(decoder_attention_heads,)`. - past_key_values (`Tuple(torch.FloatTensor)`): cached past key and value projection states + past_key_values (`Cache`): cached past key and value projection states output_attentions (`bool`, *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned tensors for more detail. @@ -439,7 +439,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, @@ -626,7 +626,7 @@ def forward( encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, cross_attn_head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, diff --git a/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py b/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py index 40def52d645e..a398ff0b916c 100644 --- a/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py +++ b/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py @@ -570,7 +570,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -740,7 +740,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -919,7 +919,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py b/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py index c625ce7b53ea..067f58ab93c6 100644 --- a/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py +++ b/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py @@ -732,7 +732,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -910,7 +910,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, diff --git a/src/transformers/models/xmod/modeling_xmod.py b/src/transformers/models/xmod/modeling_xmod.py index 06cb898f09c3..bb1ba68d4624 100644 --- a/src/transformers/models/xmod/modeling_xmod.py +++ b/src/transformers/models/xmod/modeling_xmod.py @@ -521,7 +521,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, @@ -732,7 +732,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, @@ -895,7 +895,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, From 23e87bb82933d59f4126f20cf872050722832323 Mon Sep 17 00:00:00 2001 From: Marc Sun <57196510+SunMarc@users.noreply.github.com> Date: Mon, 15 Sep 2025 11:05:47 +0200 Subject: [PATCH 042/204] fix florence kwargs (#40826) --- src/transformers/models/florence2/modeling_florence2.py | 5 +---- src/transformers/models/florence2/modular_florence2.py | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/transformers/models/florence2/modeling_florence2.py b/src/transformers/models/florence2/modeling_florence2.py index 57a00843e32e..afa05e8e3c91 100644 --- a/src/transformers/models/florence2/modeling_florence2.py +++ b/src/transformers/models/florence2/modeling_florence2.py @@ -25,7 +25,6 @@ from ...activations import ACT2FN from ...cache_utils import Cache from ...generation import GenerationMixin -from ...modeling_flash_attention_utils import FlashAttentionKwargs from ...modeling_outputs import Seq2SeqLMOutput, Seq2SeqModelOutput from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import Unpack @@ -726,7 +725,6 @@ def forward( output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, cache_position: Optional[torch.LongTensor] = None, - **kwargs: Unpack[FlashAttentionKwargs], ) -> Union[tuple, Florence2Seq2SeqModelOutput]: output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions output_hidden_states = ( @@ -777,7 +775,6 @@ def forward( output_hidden_states=output_hidden_states, cache_position=cache_position, return_dict=True, - **kwargs, ) return Florence2Seq2SeqModelOutput( @@ -922,7 +919,7 @@ def forward( output_hidden_states=output_hidden_states, return_dict=True, cache_position=cache_position, - **kwargs, + # **kwargs, ## TODO: add back when Bart attention is refactored and takes kwargs ) hidden_states = outputs[0] diff --git a/src/transformers/models/florence2/modular_florence2.py b/src/transformers/models/florence2/modular_florence2.py index 03e0fd0535cf..12bf00ca253d 100644 --- a/src/transformers/models/florence2/modular_florence2.py +++ b/src/transformers/models/florence2/modular_florence2.py @@ -24,7 +24,6 @@ from ...configuration_utils import PretrainedConfig from ...feature_extraction_utils import BatchFeature from ...image_utils import ImageInput -from ...modeling_flash_attention_utils import FlashAttentionKwargs from ...modeling_outputs import Seq2SeqLMOutput, Seq2SeqModelOutput from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import MultiModalData, ProcessorMixin, Unpack @@ -1569,7 +1568,6 @@ def forward( output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, cache_position: Optional[torch.LongTensor] = None, - **kwargs: Unpack[FlashAttentionKwargs], ) -> Union[tuple, Florence2Seq2SeqModelOutput]: output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions output_hidden_states = ( @@ -1620,7 +1618,6 @@ def forward( output_hidden_states=output_hidden_states, cache_position=cache_position, return_dict=True, - **kwargs, ) return Florence2Seq2SeqModelOutput( @@ -1731,7 +1728,7 @@ def forward( output_hidden_states=output_hidden_states, return_dict=True, cache_position=cache_position, - **kwargs, + # **kwargs, ## TODO: add back when Bart attention is refactored and takes kwargs ) hidden_states = outputs[0] From 7e29410b950b47d8ac54b415c65cbb0acb8c7419 Mon Sep 17 00:00:00 2001 From: NanoCode012 Date: Mon, 15 Sep 2025 16:05:55 +0700 Subject: [PATCH 043/204] fix: XIELU act parameters not being casted to correct dtype (#40812) --- src/transformers/activations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformers/activations.py b/src/transformers/activations.py index 813cd2c3c811..60fd2adb8ef5 100644 --- a/src/transformers/activations.py +++ b/src/transformers/activations.py @@ -262,8 +262,8 @@ def _xielu_cuda(self, x: Tensor) -> Tensor: ) result = self._xielu_cuda_obj.forward( x, - self.alpha_p, - self.alpha_n, + self.alpha_p.to(x.dtype), + self.alpha_n.to(x.dtype), # Temporary until xIELU CUDA fully implemented -> self.{beta,eps}.item() self._beta_scalar, self._eps_scalar, From bb5b7689c1e568172bd7cd84718d62272b7b8efa Mon Sep 17 00:00:00 2001 From: Arthur <48595927+ArthurZucker@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:08:29 +0200 Subject: [PATCH 044/204] Update model tags and integration references in bug report (#40881) --- .github/ISSUE_TEMPLATE/bug-report.yml | 28 ++++++++++----------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 6c3a71de04a1..78e96e9b3386 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -36,19 +36,23 @@ body: Models: - - text models: @ArthurZucker - - vision models: @amyeroberts, @qubvel - - speech models: @eustlb + - text models: @ArthurZucker @Cyrilvallez + - vision models: @yonigozlan @molbap + - audio models: @eustlb @ebezzam @vasqu + - multimodal models: @zucchini-nlp - graph models: @clefourrier Library: - - flax: @gante and @Rocketknight1 - generate: @zucchini-nlp (visual-language models) or @gante (all others) + - continuous batching: @remi-or @ArthurZucker @McPatate - pipelines: @Rocketknight1 - - tensorflow: @gante and @Rocketknight1 - tokenizers: @ArthurZucker and @itazap - trainer: @zach-huggingface @SunMarc + - attention: @vasqu @ArthurZucker @CyrilVallez + - model loading (from pretrained, etc): @CyrilVallez + - distributed: @3outeille @ArthurZucker @S1ro1 + - CIs: @ydshieh Integrations: @@ -56,6 +60,7 @@ body: - ray/raytune: @richardliaw, @amogkam - Big Model Inference: @SunMarc - quantization (bitsandbytes, autogpt): @SunMarc @MekkCyber + - kernels: @MekkCyber @drbh Devices/Backends: @@ -69,19 +74,6 @@ body: - for issues with a model, report at https://discuss.huggingface.co/ and tag the model's creator. - HF projects: - - - accelerate: [different repo](https://github.com/huggingface/accelerate) - - datasets: [different repo](https://github.com/huggingface/datasets) - - diffusers: [different repo](https://github.com/huggingface/diffusers) - - rust tokenizers: [different repo](https://github.com/huggingface/tokenizers) - - Maintained examples (not research project or legacy): - - - Flax: @Rocketknight1 - - PyTorch: See Models above and tag the person corresponding to the modality of the example. - - TensorFlow: @Rocketknight1 - Research projects are not maintained and should be taken as is. placeholder: "@Username ..." From d69d754bbdd4b6119194d9cad758fe51d66eda87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=89=BE=E5=8A=9B=E5=8F=AF?= <178652170+thalahors@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:45:13 +0200 Subject: [PATCH 045/204] [Qwen3 Next] Use numerically stable `rsqrt` (#40848) use numerically stable inverse --- src/transformers/models/qwen3_next/modeling_qwen3_next.py | 2 +- src/transformers/models/qwen3_next/modular_qwen3_next.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformers/models/qwen3_next/modeling_qwen3_next.py b/src/transformers/models/qwen3_next/modeling_qwen3_next.py index a05857a247b7..7d2b60d943e2 100644 --- a/src/transformers/models/qwen3_next/modeling_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modeling_qwen3_next.py @@ -435,7 +435,7 @@ def torch_causal_conv1d_update( def l2norm(x: torch.FloatTensor, dim: int = -1, eps: float = 1e-6): """This function is intended to align with the l2norm implementation in the FLA library.""" - inv_norm = 1 / torch.sqrt((x * x).sum(dim=dim, keepdim=True) + eps) + inv_norm = torch.rsqrt((x * x).sum(dim=dim, keepdim=True) + eps) return x * inv_norm diff --git a/src/transformers/models/qwen3_next/modular_qwen3_next.py b/src/transformers/models/qwen3_next/modular_qwen3_next.py index bc902b8e1b5f..f76a242877b9 100644 --- a/src/transformers/models/qwen3_next/modular_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modular_qwen3_next.py @@ -271,7 +271,7 @@ def torch_causal_conv1d_update( def l2norm(x: torch.FloatTensor, dim: int = -1, eps: float = 1e-6): """This function is intended to align with the l2norm implementation in the FLA library.""" - inv_norm = 1 / torch.sqrt((x * x).sum(dim=dim, keepdim=True) + eps) + inv_norm = torch.rsqrt((x * x).sum(dim=dim, keepdim=True) + eps) return x * inv_norm From 4d3d07f5a90a57a38c3177602eb15f12537ac59a Mon Sep 17 00:00:00 2001 From: JJJYmmm <92386084+JJJYmmm@users.noreply.github.com> Date: Mon, 15 Sep 2025 18:46:18 +0800 Subject: [PATCH 046/204] Adding Support for Qwen3-VL Series (#40795) * add qwen3vl series * make fixup * fix import * re-protect import * fix it finally (need to merge main into the branch) * skip processor test (need the checkpoint) * oups typo * simplify modular * remove unecesary attr * fix layer * remove unused rope_deltas args * reuse image def * remove unnesesary imports --------- Co-authored-by: Cyril Vallez Co-authored-by: Cyril Vallez --- docs/source/en/_toctree.yml | 4 + docs/source/en/model_doc/qwen3_vl.md | 117 ++ docs/source/en/model_doc/qwen3_vl_moe.md | 109 ++ src/transformers/models/__init__.py | 2 + .../models/auto/configuration_auto.py | 10 + .../models/auto/image_processing_auto.py | 1 + src/transformers/models/auto/modeling_auto.py | 8 + .../models/auto/processing_auto.py | 2 + .../models/auto/tokenization_auto.py | 2 + .../models/auto/video_processing_auto.py | 2 + src/transformers/models/qwen3_vl/__init__.py | 29 + .../models/qwen3_vl/configuration_qwen3_vl.py | 287 +++ .../models/qwen3_vl/modeling_qwen3_vl.py | 1568 +++++++++++++++ .../models/qwen3_vl/modular_qwen3_vl.py | 1472 ++++++++++++++ .../models/qwen3_vl/processing_qwen3_vl.py | 328 ++++ .../qwen3_vl/video_processing_qwen3_vl.py | 276 +++ .../models/qwen3_vl_moe/__init__.py | 27 + .../configuration_qwen3_vl_moe.py | 331 ++++ .../qwen3_vl_moe/modeling_qwen3_vl_moe.py | 1711 +++++++++++++++++ .../qwen3_vl_moe/modular_qwen3_vl_moe.py | 434 +++++ tests/models/qwen3_vl/__init__.py | 0 .../models/qwen3_vl/test_modeling_qwen3_vl.py | 299 +++ .../qwen3_vl/test_processing_qwen3_vl.py | 379 ++++ .../test_video_processing_qwen3_vl.py | 330 ++++ tests/models/qwen3_vl_moe/__init__.py | 0 .../test_modeling_qwen3_vl_moe.py | 298 +++ utils/check_repo.py | 20 +- 27 files changed, 8039 insertions(+), 7 deletions(-) create mode 100644 docs/source/en/model_doc/qwen3_vl.md create mode 100644 docs/source/en/model_doc/qwen3_vl_moe.md create mode 100644 src/transformers/models/qwen3_vl/__init__.py create mode 100644 src/transformers/models/qwen3_vl/configuration_qwen3_vl.py create mode 100644 src/transformers/models/qwen3_vl/modeling_qwen3_vl.py create mode 100644 src/transformers/models/qwen3_vl/modular_qwen3_vl.py create mode 100644 src/transformers/models/qwen3_vl/processing_qwen3_vl.py create mode 100644 src/transformers/models/qwen3_vl/video_processing_qwen3_vl.py create mode 100644 src/transformers/models/qwen3_vl_moe/__init__.py create mode 100644 src/transformers/models/qwen3_vl_moe/configuration_qwen3_vl_moe.py create mode 100644 src/transformers/models/qwen3_vl_moe/modeling_qwen3_vl_moe.py create mode 100644 src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py create mode 100644 tests/models/qwen3_vl/__init__.py create mode 100644 tests/models/qwen3_vl/test_modeling_qwen3_vl.py create mode 100644 tests/models/qwen3_vl/test_processing_qwen3_vl.py create mode 100644 tests/models/qwen3_vl/test_video_processing_qwen3_vl.py create mode 100644 tests/models/qwen3_vl_moe/__init__.py create mode 100644 tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index b56d16ff69e2..aa5b35aeb198 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -1127,6 +1127,10 @@ title: Qwen2Audio - local: model_doc/qwen2_vl title: Qwen2VL + - local: model_doc/qwen3_vl + title: Qwen3VL + - local: model_doc/qwen3_vl_moe + title: Qwen3VLMoe - local: model_doc/sam2 title: SAM2 - local: model_doc/sam2_video diff --git a/docs/source/en/model_doc/qwen3_vl.md b/docs/source/en/model_doc/qwen3_vl.md new file mode 100644 index 000000000000..9e90363a1eba --- /dev/null +++ b/docs/source/en/model_doc/qwen3_vl.md @@ -0,0 +1,117 @@ + +*This model was released on None and added to Hugging Face Transformers on 2025-08-16.* + +
+
+PyTorch +FlashAttention +SDPA
+
+ +# Qwen3-VL + +[Qwen3-VL](https://huggingface.co/papers/2502.13923) is a multimodal vision-language model series, encompassing both dense and MoE variants, as well as Instruct and Thinking versions. Building upon its predecessors, Qwen3-VL delivers significant improvements in visual understanding while maintaining strong pure text capabilities. Key architectural advancements include: enhanced MRope with interleaved layout for better spatial-temporal modeling, DeepStack integration to effectively leverage multi-level features from the Vision Transformer (ViT), and improved video understanding through text-based time alignment—evolving from T-RoPE to text timestamp alignment for more precise temporal grounding. These innovations collectively enable Qwen3-VL to achieve superior performance in complex multimodal tasks. + +Model usage + + + + +```py +import torch +from transformers import Qwen3VLForConditionalGeneration, AutoProcessor + +model = Qwen3VLForConditionalGeneration.from_pretrained( + "Qwen/Qwen3-VL", + dtype=torch.float16, + device_map="auto", + attn_implementation="sdpa" +) +processor = AutoProcessor.from_pretrained("Qwen/Qwen3-VL") +messages = [ + { + "role":"user", + "content":[ + { + "type":"image", + "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg" + }, + { + "type":"text", + "text":"Describe this image." + } + ] + } + +] + +inputs = processor.apply_chat_template( + messages, + tokenize=True, + add_generation_prompt=True, + return_dict=True, + return_tensors="pt", +) +inputs.pop("token_type_ids", None) + +generated_ids = model.generate(**inputs, max_new_tokens=128) +generated_ids_trimmed = [ + out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids) +] +output_text = processor.batch_decode( + generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False +) +print(output_text) +``` + + + +## Qwen3VLConfig + +[[autodoc]] Qwen3VLConfig + +## Qwen3VLTextConfig + +[[autodoc]] Qwen3VLTextConfig + +## Qwen3VLProcessor + +[[autodoc]] Qwen3VLProcessor + +## Qwen3VLVideoProcessor + +[[autodoc]] Qwen3VLVideoProcessor + +## Qwen3VLVisionModel + +[[autodoc]] Qwen3VLVisionModel + - forward + +## Qwen3VLTextModel + +[[autodoc]] Qwen3VLTextModel + - forward + +## Qwen3VLModel + +[[autodoc]] Qwen3VLModel + - forward + +## Qwen3VLForConditionalGeneration + +[[autodoc]] Qwen3VLForConditionalGeneration + - forward diff --git a/docs/source/en/model_doc/qwen3_vl_moe.md b/docs/source/en/model_doc/qwen3_vl_moe.md new file mode 100644 index 000000000000..76d046efff2d --- /dev/null +++ b/docs/source/en/model_doc/qwen3_vl_moe.md @@ -0,0 +1,109 @@ + +*This model was released on None and added to Hugging Face Transformers on 2025-08-17.* + +
+
+PyTorch +FlashAttention +SDPA
+
+ +# Qwen3-VL-Moe + +[Qwen3-VL](https://huggingface.co/papers/2502.13923) is a multimodal vision-language model series, encompassing both dense and MoE variants, as well as Instruct and Thinking versions. Building upon its predecessors, Qwen3-VL delivers significant improvements in visual understanding while maintaining strong pure text capabilities. Key architectural advancements include: enhanced MRope with interleaved layout for better spatial-temporal modeling, DeepStack integration to effectively leverage multi-level features from the Vision Transformer (ViT), and improved video understanding through text-based time alignment—evolving from T-RoPE to text timestamp alignment for more precise temporal grounding. These innovations collectively enable Qwen3-VL to achieve superior performance in complex multimodal tasks. + +Model usage + + + + +```py +import torch +from transformers import Qwen3VLMoeForConditionalGeneration, AutoProcessor + +model = Qwen3VLMoeForConditionalGeneration.from_pretrained( + "Qwen/Qwen3-VL-Moe", + dtype=torch.float16, + device_map="auto", + attn_implementation="sdpa" +) +processor = AutoProcessor.from_pretrained("Qwen/Qwen3-VL-Moe") +messages = [ + { + "role":"user", + "content":[ + { + "type":"image", + "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg" + }, + { + "type":"text", + "text":"Describe this image." + } + ] + } + +] + +inputs = processor.apply_chat_template( + messages, + tokenize=True, + add_generation_prompt=True, + return_dict=True, + return_tensors="pt", +) +inputs.pop("token_type_ids", None) + +generated_ids = model.generate(**inputs, max_new_tokens=128) +generated_ids_trimmed = [ + out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids) +] +output_text = processor.batch_decode( + generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False +) +print(output_text) +``` + + + +## Qwen3VLMoeConfig + +[[autodoc]] Qwen3VLMoeConfig + +## Qwen3VLMoeTextConfig + +[[autodoc]] Qwen3VLMoeTextConfig + +## Qwen3VLMoeVisionModel + +[[autodoc]] Qwen3VLMoeVisionModel + - forward + +## Qwen3VLMoeTextModel + +[[autodoc]] Qwen3VLMoeTextModel + - forward + +## Qwen3VLMoeModel + +[[autodoc]] Qwen3VLMoeModel + - forward + +## Qwen3VLMoeForConditionalGeneration + +[[autodoc]] Qwen3VLMoeForConditionalGeneration + - forward diff --git a/src/transformers/models/__init__.py b/src/transformers/models/__init__.py index 50484a5ca40e..c18cbd44f7ea 100644 --- a/src/transformers/models/__init__.py +++ b/src/transformers/models/__init__.py @@ -278,6 +278,8 @@ from .qwen3 import * from .qwen3_moe import * from .qwen3_next import * + from .qwen3_vl import * + from .qwen3_vl_moe import * from .rag import * from .recurrent_gemma import * from .reformer import * diff --git a/src/transformers/models/auto/configuration_auto.py b/src/transformers/models/auto/configuration_auto.py index 6a71f49f1783..a977c727c9e8 100644 --- a/src/transformers/models/auto/configuration_auto.py +++ b/src/transformers/models/auto/configuration_auto.py @@ -325,6 +325,10 @@ ("qwen3", "Qwen3Config"), ("qwen3_moe", "Qwen3MoeConfig"), ("qwen3_next", "Qwen3NextConfig"), + ("qwen3_vl", "Qwen3VLConfig"), + ("qwen3_vl_moe", "Qwen3VLMoeConfig"), + ("qwen3_vl_moe_text", "Qwen3VLMoeTextConfig"), + ("qwen3_vl_text", "Qwen3VLTextConfig"), ("rag", "RagConfig"), ("realm", "RealmConfig"), ("recurrent_gemma", "RecurrentGemmaConfig"), @@ -764,6 +768,10 @@ ("qwen3", "Qwen3"), ("qwen3_moe", "Qwen3MoE"), ("qwen3_next", "Qwen3Next"), + ("qwen3_vl", "Qwen3VL"), + ("qwen3_vl_moe", "Qwen3VLMoe"), + ("qwen3_vl_moe_text", "Qwen3VLMoe"), + ("qwen3_vl_text", "Qwen3VL"), ("rag", "RAG"), ("realm", "REALM"), ("recurrent_gemma", "RecurrentGemma"), @@ -952,6 +960,8 @@ ("internvl_vision", "internvl"), ("qwen2_5_vl_text", "qwen2_5_vl"), ("qwen2_vl_text", "qwen2_vl"), + ("qwen3_vl_text", "qwen3_vl"), + ("qwen3_vl_moe_text", "qwen3_vl_moe"), ("sam_vision_model", "sam"), ("sam2_vision_model", "sam2"), ("sam2_hiera_det_model", "sam2"), diff --git a/src/transformers/models/auto/image_processing_auto.py b/src/transformers/models/auto/image_processing_auto.py index 7d07ca6dc7d6..193e8f8fd940 100644 --- a/src/transformers/models/auto/image_processing_auto.py +++ b/src/transformers/models/auto/image_processing_auto.py @@ -156,6 +156,7 @@ ("pvt_v2", ("PvtImageProcessor", "PvtImageProcessorFast")), ("qwen2_5_vl", ("Qwen2VLImageProcessor", "Qwen2VLImageProcessorFast")), ("qwen2_vl", ("Qwen2VLImageProcessor", "Qwen2VLImageProcessorFast")), + ("qwen3_vl", ("Qwen2VLImageProcessor", "Qwen2VLImageProcessorFast")), ("regnet", ("ConvNextImageProcessor", "ConvNextImageProcessorFast")), ("resnet", ("ConvNextImageProcessor", "ConvNextImageProcessorFast")), ("rt_detr", ("RTDetrImageProcessor", "RTDetrImageProcessorFast")), diff --git a/src/transformers/models/auto/modeling_auto.py b/src/transformers/models/auto/modeling_auto.py index 9243289b62ef..1e0388de23cb 100644 --- a/src/transformers/models/auto/modeling_auto.py +++ b/src/transformers/models/auto/modeling_auto.py @@ -319,6 +319,10 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("qwen3", "Qwen3Model"), ("qwen3_moe", "Qwen3MoeModel"), ("qwen3_next", "Qwen3NextModel"), + ("qwen3_vl", "Qwen3VLModel"), + ("qwen3_vl_moe", "Qwen3VLMoeModel"), + ("qwen3_vl_moe_text", "Qwen3VLMoeTextModel"), + ("qwen3_vl_text", "Qwen3VLTextModel"), ("recurrent_gemma", "RecurrentGemmaModel"), ("reformer", "ReformerModel"), ("regnet", "RegNetModel"), @@ -974,6 +978,8 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("pix2struct", "Pix2StructForConditionalGeneration"), ("qwen2_5_vl", "Qwen2_5_VLForConditionalGeneration"), ("qwen2_vl", "Qwen2VLForConditionalGeneration"), + ("qwen3_vl", "Qwen3VLForConditionalGeneration"), + ("qwen3_vl_moe", "Qwen3VLMoeForConditionalGeneration"), ("video_llava", "VideoLlavaForConditionalGeneration"), ("vipllava", "VipLlavaForConditionalGeneration"), ("vision-encoder-decoder", "VisionEncoderDecoderModel"), @@ -1028,6 +1034,8 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("pixtral", "LlavaForConditionalGeneration"), ("qwen2_5_vl", "Qwen2_5_VLForConditionalGeneration"), ("qwen2_vl", "Qwen2VLForConditionalGeneration"), + ("qwen3_vl", "Qwen3VLForConditionalGeneration"), + ("qwen3_vl_moe", "Qwen3VLMoeForConditionalGeneration"), ("shieldgemma2", "Gemma3ForConditionalGeneration"), ("smolvlm", "SmolVLMForConditionalGeneration"), ("udop", "UdopForConditionalGeneration"), diff --git a/src/transformers/models/auto/processing_auto.py b/src/transformers/models/auto/processing_auto.py index d8db58cb7b1f..13583c55002f 100644 --- a/src/transformers/models/auto/processing_auto.py +++ b/src/transformers/models/auto/processing_auto.py @@ -120,6 +120,8 @@ ("qwen2_5_vl", "Qwen2_5_VLProcessor"), ("qwen2_audio", "Qwen2AudioProcessor"), ("qwen2_vl", "Qwen2VLProcessor"), + ("qwen3_vl", "Qwen3VLProcessor"), + ("qwen3_vl_moe", "Qwen3VLProcessor"), ("sam", "SamProcessor"), ("sam2", "Sam2Processor"), ("sam_hq", "SamHQProcessor"), diff --git a/src/transformers/models/auto/tokenization_auto.py b/src/transformers/models/auto/tokenization_auto.py index 688faf00c4ea..0ef450f45cb9 100644 --- a/src/transformers/models/auto/tokenization_auto.py +++ b/src/transformers/models/auto/tokenization_auto.py @@ -583,6 +583,8 @@ "Qwen2TokenizerFast" if is_tokenizers_available() else None, ), ), + ("qwen3_vl", ("Qwen2Tokenizer", "Qwen2TokenizerFast" if is_tokenizers_available() else None)), + ("qwen3_vl_moe", ("Qwen2Tokenizer", "Qwen2TokenizerFast" if is_tokenizers_available() else None)), ("rag", ("RagTokenizer", None)), ("realm", ("RealmTokenizer", "RealmTokenizerFast" if is_tokenizers_available() else None)), ( diff --git a/src/transformers/models/auto/video_processing_auto.py b/src/transformers/models/auto/video_processing_auto.py index b9a5c2204fd1..551de914626e 100644 --- a/src/transformers/models/auto/video_processing_auto.py +++ b/src/transformers/models/auto/video_processing_auto.py @@ -56,6 +56,8 @@ ("qwen2_5_omni", "Qwen2VLVideoProcessor"), ("qwen2_5_vl", "Qwen2VLVideoProcessor"), ("qwen2_vl", "Qwen2VLVideoProcessor"), + ("qwen3_vl", "Qwen3VLVideoProcessor"), + ("qwen3_vl_moe", "Qwen3VLVideoProcessor"), ("sam2_video", "Sam2VideoVideoProcessor"), ("smolvlm", "SmolVLMVideoProcessor"), ("video_llava", "VideoLlavaVideoProcessor"), diff --git a/src/transformers/models/qwen3_vl/__init__.py b/src/transformers/models/qwen3_vl/__init__.py new file mode 100644 index 000000000000..e37161a2e415 --- /dev/null +++ b/src/transformers/models/qwen3_vl/__init__.py @@ -0,0 +1,29 @@ +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. +from typing import TYPE_CHECKING + +from ...utils import _LazyModule +from ...utils.import_utils import define_import_structure + + +if TYPE_CHECKING: + from .configuration_qwen3_vl import * + from .modeling_qwen3_vl import * + from .processing_qwen3_vl import * + from .video_processing_qwen3_vl import * +else: + import sys + + _file = globals()["__file__"] + sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__) diff --git a/src/transformers/models/qwen3_vl/configuration_qwen3_vl.py b/src/transformers/models/qwen3_vl/configuration_qwen3_vl.py new file mode 100644 index 000000000000..132ffa8be150 --- /dev/null +++ b/src/transformers/models/qwen3_vl/configuration_qwen3_vl.py @@ -0,0 +1,287 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/qwen3_vl/modular_qwen3_vl.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_qwen3_vl.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. +from ...configuration_utils import PretrainedConfig +from ...modeling_rope_utils import rope_config_validation + + +class Qwen3VLVisionConfig(PretrainedConfig): + model_type = "qwen3_vl" + base_config_key = "vision_config" + + def __init__( + self, + depth=27, + hidden_size=1152, + hidden_act="gelu_pytorch_tanh", + intermediate_size=4304, + num_heads=16, + in_channels=3, + patch_size=16, + spatial_merge_size=2, + temporal_patch_size=2, + out_hidden_size=3584, + num_position_embeddings=2304, + deepstack_visual_indexes=[8, 16, 24], + initializer_range=0.02, + **kwargs, + ): + super().__init__(**kwargs) + + self.depth = depth + self.hidden_size = hidden_size + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.num_heads = num_heads + self.in_channels = in_channels + self.patch_size = patch_size + self.spatial_merge_size = spatial_merge_size + self.temporal_patch_size = temporal_patch_size + self.out_hidden_size = out_hidden_size + self.num_position_embeddings = num_position_embeddings + self.initializer_range = initializer_range + self.deepstack_visual_indexes = deepstack_visual_indexes + + +class Qwen3VLTextConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3VLTextModel`]. It is used to instantiate a + Qwen3-VL model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of + Qwen3-VL-4B-Instruct [Qwen/Qwen3-VL-4B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-4B-Instruct). + + 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 151936): + Vocabulary size of the Qwen3VL model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`Qwen3VLModel`] + hidden_size (`int`, *optional*, defaults to 4096): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 22016): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 32): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 32): + Number of attention heads for each attention layer in the Transformer encoder. + num_key_value_heads (`int`, *optional*, defaults to 32): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to `32`. + head_dim (`int`, *optional*, defaults to 128): + The dimension of the head. If not specified, will default to `hidden_size // num_attention_heads`. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 128000): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether the model's input and output word embeddings should be tied. + rope_theta (`float`, *optional*, defaults to 5000000.0): + The base period of the RoPE embeddings. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type + and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value + accordingly. + Expected contents: + `rope_type` (`str`): + The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope', + 'llama3'], with 'default' being the original RoPE implementation. + `factor` (`float`, *optional*): + Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In + most scaling types, a `factor` of x will enable the model to handle sequences of length x * + original maximum pre-trained length. + `original_max_position_embeddings` (`int`, *optional*): + Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during + pretraining. + `attention_factor` (`float`, *optional*): + Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention + computation. If unspecified, it defaults to value recommended by the implementation, using the + `factor` field to infer the suggested value. + `beta_fast` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear + ramp function. If unspecified, it defaults to 32. + `beta_slow` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear + ramp function. If unspecified, it defaults to 1. + `short_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to short contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `long_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to long contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `low_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE + `high_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + + ```python + >>> from transformers import Qwen3VLTextModel, Qwen3VLTextConfig + + >>> # Initializing a Qwen3VL style configuration + >>> configuration = Qwen3VLTextConfig() + + >>> # Initializing a model from the Qwen3-VL-7B style configuration + >>> model = Qwen3VLTextModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_vl_text" + base_config_key = "text_config" + + def __init__( + self, + vocab_size=151936, + hidden_size=4096, + intermediate_size=22016, + num_hidden_layers=32, + num_attention_heads=32, + num_key_value_heads=32, + head_dim=128, + hidden_act="silu", + max_position_embeddings=128000, + initializer_range=0.02, + rms_norm_eps=1e-6, + use_cache=True, + tie_word_embeddings=False, + rope_theta=5000000.0, + rope_scaling=None, + attention_bias=False, + attention_dropout=0.0, + **kwargs, + ): + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + + # for backward compatibility + if num_key_value_heads is None: + num_key_value_heads = num_attention_heads + + self.num_key_value_heads = num_key_value_heads + self.head_dim = head_dim + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + + rope_config_validation(self, ignore_keys={"mrope_section", "mrope_interleaved"}) + + super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs) + + +class Qwen3VLConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3VLModel`]. It is used to instantiate a + Qwen3-VL model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of + Qwen3-VL-4B-Instruct [Qwen/Qwen3-VL-4B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-4B-Instruct). + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + text_config (`Union[PreTrainedConfig, dict]`, *optional*, defaults to `Qwen3VLTextConfig`): + The config object or dictionary of the text backbone. + vision_config (`Union[PreTrainedConfig, dict]`, *optional*, defaults to `Qwen3VLVisionConfig`): + The config object or dictionary of the vision backbone. + image_token_id (`int`, *optional*, defaults to 151655): + The image token index to encode the image prompt. + video_token_id (`int`, *optional*, defaults to 151656): + The video token index to encode the image prompt. + vision_start_token_id (`int`, *optional*, defaults to 151652): + The start token index to encode the image prompt. + vision_end_token_id (`int`, *optional*, defaults to 151653): + The end token index to encode the image prompt. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether to tie the word embeddings. + + ```python + >>> from transformers import Qwen3VLForConditionalGeneration, Qwen3VLConfig + + >>> # Initializing a Qwen3-VL style configuration + >>> configuration = Qwen3VLConfig() + + >>> # Initializing a model from the Qwen3-VL-4B style configuration + >>> model = Qwen3VLForConditionalGeneration(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_vl" + sub_configs = {"vision_config": Qwen3VLVisionConfig, "text_config": Qwen3VLTextConfig} + keys_to_ignore_at_inference = ["past_key_values"] + + def __init__( + self, + text_config=None, + vision_config=None, + image_token_id=151655, + video_token_id=151656, + vision_start_token_id=151652, + vision_end_token_id=151653, + tie_word_embeddings=False, + **kwargs, + ): + if isinstance(vision_config, dict): + self.vision_config = self.sub_configs["vision_config"](**vision_config) + elif vision_config is None: + self.vision_config = self.sub_configs["vision_config"]() + + if isinstance(text_config, dict): + self.text_config = self.sub_configs["text_config"](**text_config) + elif text_config is None: + self.text_config = self.sub_configs["text_config"]() + + self.image_token_id = image_token_id + self.video_token_id = video_token_id + self.vision_start_token_id = vision_start_token_id + self.vision_end_token_id = vision_end_token_id + super().__init__(**kwargs, tie_word_embeddings=tie_word_embeddings) + + +__all__ = ["Qwen3VLConfig", "Qwen3VLTextConfig"] diff --git a/src/transformers/models/qwen3_vl/modeling_qwen3_vl.py b/src/transformers/models/qwen3_vl/modeling_qwen3_vl.py new file mode 100644 index 000000000000..a18366a2a534 --- /dev/null +++ b/src/transformers/models/qwen3_vl/modeling_qwen3_vl.py @@ -0,0 +1,1568 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/qwen3_vl/modular_qwen3_vl.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_qwen3_vl.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. + +from dataclasses import dataclass +from typing import Any, Callable, Optional, Union + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from ...activations import ACT2FN +from ...cache_utils import Cache, DynamicCache +from ...generation import GenerationMixin +from ...integrations import use_kernel_forward_from_hub +from ...masking_utils import create_causal_mask +from ...modeling_flash_attention_utils import FlashAttentionKwargs +from ...modeling_layers import GradientCheckpointingLayer +from ...modeling_outputs import BaseModelOutputWithPast, ModelOutput +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, is_torchdynamo_compiling +from ...utils.deprecation import deprecate_kwarg +from ...utils.generic import check_model_inputs +from .configuration_qwen3_vl import Qwen3VLConfig, Qwen3VLTextConfig, Qwen3VLVisionConfig + + +class Qwen3VLVisionMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.linear_fc1 = nn.Linear(self.hidden_size, self.intermediate_size, bias=True) + self.linear_fc2 = nn.Linear(self.intermediate_size, self.hidden_size, bias=True) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, hidden_state): + return self.linear_fc2(self.act_fn(self.linear_fc1(hidden_state))) + + +class Qwen3VLVisionPatchEmbed(nn.Module): + def __init__(self, config) -> None: + super().__init__() + self.patch_size = config.patch_size + self.temporal_patch_size = config.temporal_patch_size + self.in_channels = config.in_channels + self.embed_dim = config.hidden_size + + kernel_size = [self.temporal_patch_size, self.patch_size, self.patch_size] + self.proj = nn.Conv3d(self.in_channels, self.embed_dim, kernel_size=kernel_size, stride=kernel_size, bias=True) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + target_dtype = self.proj.weight.dtype + hidden_states = hidden_states.view( + -1, self.in_channels, self.temporal_patch_size, self.patch_size, self.patch_size + ) + hidden_states = self.proj(hidden_states.to(dtype=target_dtype)).view(-1, self.embed_dim) + return hidden_states + + +class Qwen3VLVisionRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, dim: int, theta: float = 10000.0) -> None: + super().__init__() + inv_freq = 1.0 / (theta ** (torch.arange(0, dim, 2, dtype=torch.float) / dim)) + self.register_buffer("inv_freq", inv_freq, persistent=False) + + def forward(self, seqlen: int) -> torch.Tensor: + seq = torch.arange(seqlen, device=self.inv_freq.device, dtype=self.inv_freq.dtype) + freqs = torch.outer(seq, self.inv_freq) + return freqs + + +class Qwen3VLVisionPatchMerger(nn.Module): + def __init__(self, config: Qwen3VLVisionConfig, use_postshuffle_norm=False) -> None: + super().__init__() + self.hidden_size = config.hidden_size * (config.spatial_merge_size**2) + self.use_postshuffle_norm = use_postshuffle_norm + self.norm = nn.LayerNorm(self.hidden_size if use_postshuffle_norm else config.hidden_size, eps=1e-6) + self.linear_fc1 = nn.Linear(self.hidden_size, self.hidden_size) + self.act_fn = nn.GELU() + self.linear_fc2 = nn.Linear(self.hidden_size, config.out_hidden_size) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + x = self.norm(x.view(-1, self.hidden_size) if self.use_postshuffle_norm else x).view(-1, self.hidden_size) + x = self.linear_fc2(self.act_fn(self.linear_fc1(x))) + return x + + +def rotate_half(x): + """Rotates half the hidden dims of the input.""" + x1 = x[..., : x.shape[-1] // 2] + x2 = x[..., x.shape[-1] // 2 :] + return torch.cat((-x2, x1), dim=-1) + + +def apply_rotary_pos_emb_vision( + q: torch.Tensor, k: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor +) -> tuple[torch.Tensor, torch.Tensor]: + orig_q_dtype = q.dtype + orig_k_dtype = k.dtype + q, k = q.float(), k.float() + cos, sin = cos.unsqueeze(-2).float(), sin.unsqueeze(-2).float() + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + q_embed = q_embed.to(orig_q_dtype) + k_embed = k_embed.to(orig_k_dtype) + return q_embed, k_embed + + +def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor: + """ + This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, + num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim) + """ + batch, num_key_value_heads, slen, head_dim = hidden_states.shape + if n_rep == 1: + return hidden_states + hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim) + return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim) + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: float, + dropout: float = 0.0, + **kwargs: Unpack[TransformersKwargs], +): + key_states = repeat_kv(key, module.num_key_value_groups) + value_states = repeat_kv(value, module.num_key_value_groups) + + attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling + if attention_mask is not None: + causal_mask = attention_mask[:, :, :, : key_states.shape[-2]] + attn_weights = attn_weights + causal_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + attn_output = torch.matmul(attn_weights, value_states) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + +class Qwen3VLVisionAttention(nn.Module): + def __init__(self, config: Qwen3VLVisionConfig) -> None: + super().__init__() + self.dim = config.hidden_size + self.num_heads = config.num_heads + self.head_dim = self.dim // self.num_heads + self.num_key_value_groups = 1 # needed for eager attention + self.qkv = nn.Linear(self.dim, self.dim * 3, bias=True) + self.proj = nn.Linear(self.dim, self.dim) + self.scaling = self.head_dim**-0.5 + self.config = config + self.attention_dropout = 0.0 + self.is_causal = False + + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: torch.Tensor, + rotary_pos_emb: Optional[torch.Tensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + **kwargs, + ) -> torch.Tensor: + seq_length = hidden_states.shape[0] + query_states, key_states, value_states = ( + self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0) + ) + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb_vision(query_states, key_states, cos, sin) + + query_states = query_states.transpose(0, 1).unsqueeze(0) + key_states = key_states.transpose(0, 1).unsqueeze(0) + value_states = value_states.transpose(0, 1).unsqueeze(0) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + if self.config._attn_implementation == "flash_attention_2": + # Flash Attention 2: Use cu_seqlens for variable length attention + max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max() + attn_output, _ = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + cu_seq_lens_q=cu_seqlens, + cu_seq_lens_k=cu_seqlens, + max_length_q=max_seqlen, + max_length_k=max_seqlen, + is_causal=False, + **kwargs, + ) + else: + # Other implementations: Process each chunk separately + lengths = cu_seqlens[1:] - cu_seqlens[:-1] + splits = [ + torch.split(tensor, lengths.tolist(), dim=2) for tensor in (query_states, key_states, value_states) + ] + + attn_outputs = [ + attention_interface( + self, + q, + k, + v, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + is_causal=False, + **kwargs, + )[0] + for q, k, v in zip(*splits) + ] + attn_output = torch.cat(attn_outputs, dim=1) + + attn_output = attn_output.reshape(seq_length, -1).contiguous() + attn_output = self.proj(attn_output) + return attn_output + + +class Qwen3VLVisionBlock(GradientCheckpointingLayer): + def __init__(self, config, attn_implementation: str = "sdpa") -> None: + super().__init__() + self.norm1 = nn.LayerNorm(config.hidden_size, eps=1e-6) + self.norm2 = nn.LayerNorm(config.hidden_size, eps=1e-6) + self.attn = Qwen3VLVisionAttention(config=config) + self.mlp = Qwen3VLVisionMLP(config=config) + + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: torch.Tensor, + rotary_pos_emb: Optional[torch.Tensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + **kwargs, + ) -> torch.Tensor: + hidden_states = hidden_states + self.attn( + self.norm1(hidden_states), + cu_seqlens=cu_seqlens, + rotary_pos_emb=rotary_pos_emb, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = hidden_states + self.mlp(self.norm2(hidden_states)) + return hidden_states + + +class Qwen3VLTextRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: Qwen3VLTextConfig, device=None): + super().__init__() + if hasattr(config, "rope_scaling") and config.rope_scaling is not None: + self.rope_type = config.rope_scaling.get("rope_type", "default") + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + self.mrope_section = config.rope_scaling.get("mrope_section", [24, 20, 20]) + + def apply_interleaved_mrope(self, freqs, mrope_section): + """Apply interleaved MRoPE to 3D rotary embeddings. + Reorganizes frequency layout from chunked [TTT...HHH...WWW] to + interleaved [THTHWHTHW...TT], preserving frequency continuity. + args: + x: (3, bs, seq_len, head_dim // 2) + mrope_section: (3,) + returns: + x_t: (bs, seq_len, head_dim // 2) + """ + freqs_t = freqs[0] # just overwrite the first dimension T + for dim, offset in enumerate((1, 2), start=1): # H, W + length = mrope_section[dim] * 3 + idx = slice(offset, length, 3) + freqs_t[..., idx] = freqs[dim, ..., idx] + return freqs_t + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + # In contrast to other models, Qwen3VL has different position ids for the grids + # So we expand the inv_freq to shape (3, ...) + if position_ids.ndim == 2: + position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1) + inv_freq_expanded = self.inv_freq[None, None, :, None].float().expand(3, position_ids.shape[1], -1, 1) + position_ids_expanded = position_ids[:, :, None, :].float() # shape (3, bs, 1, positions) + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(2, 3) + freqs = self.apply_interleaved_mrope(freqs, self.mrope_section) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + +@use_kernel_forward_from_hub("RMSNorm") +class Qwen3VLTextRMSNorm(nn.Module): + def __init__(self, hidden_size, eps: float = 1e-6) -> None: + """ + Qwen3VLTextRMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return self.weight * hidden_states.to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1): + """Applies Rotary Position Embedding to the query and key tensors. + + Args: + q (`torch.Tensor`): The query tensor. + k (`torch.Tensor`): The key tensor. + cos (`torch.Tensor`): The cosine part of the rotary embedding. + sin (`torch.Tensor`): The sine part of the rotary embedding. + position_ids (`torch.Tensor`, *optional*): + Deprecated and unused. + unsqueeze_dim (`int`, *optional*, defaults to 1): + The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and + sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note + that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and + k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes + cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have + the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. + Returns: + `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. + """ + cos = cos.unsqueeze(unsqueeze_dim) + sin = sin.unsqueeze(unsqueeze_dim) + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + return q_embed, k_embed + + +class Qwen3VLTextAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: Qwen3VLTextConfig, layer_idx: int): + super().__init__() + self.config = config + self.layer_idx = layer_idx + self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) + self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads + self.scaling = self.head_dim**-0.5 + self.attention_dropout = config.attention_dropout + self.is_causal = True + + self.q_proj = nn.Linear( + config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias + ) + self.k_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.v_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.o_proj = nn.Linear( + config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias + ) + self.q_norm = Qwen3VLTextRMSNorm(self.head_dim, eps=config.rms_norm_eps) # unlike olmo, only on the head dim! + self.k_norm = Qwen3VLTextRMSNorm( + self.head_dim, eps=config.rms_norm_eps + ) # thus post q_norm does not need reshape + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor]]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class Qwen3VLTextMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +class Qwen3VLTextDecoderLayer(GradientCheckpointingLayer): + def __init__(self, config: Qwen3VLTextConfig, layer_idx: int): + super().__init__() + self.hidden_size = config.hidden_size + + self.self_attn = Qwen3VLTextAttention(config=config, layer_idx=layer_idx) + + self.mlp = Qwen3VLTextMLP(config) + self.input_layernorm = Qwen3VLTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = Qwen3VLTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> torch.Tensor: + residual = hidden_states + hidden_states = self.input_layernorm(hidden_states) + # Self Attention + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + hidden_states + return hidden_states + + +@dataclass +@auto_docstring( + custom_intro=""" + Base class for Llava outputs, with hidden states and attentions. + """ +) +class Qwen3VLModelOutputWithPast(ModelOutput): + r""" + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape + `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + + Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see + `past_key_values` input) to speed up sequential decoding. + rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*): + The rope index difference between sequence length and multimodal rope. + """ + + last_hidden_state: Optional[torch.FloatTensor] = None + past_key_values: Optional[list[torch.FloatTensor]] = None + hidden_states: Optional[tuple[torch.FloatTensor]] = None + attentions: Optional[tuple[torch.FloatTensor]] = None + rope_deltas: Optional[torch.LongTensor] = None + + +@auto_docstring +class Qwen3VLPreTrainedModel(PreTrainedModel): + config: Qwen3VLConfig + base_model_prefix = "model" + supports_gradient_checkpointing = True + _no_split_modules = ["Qwen3VLTextDecoderLayer", "Qwen3VLVisionBlock"] + _skip_keys_device_placement = "past_key_values" + _supports_flash_attn = True + _supports_sdpa = True + + _can_compile_fullgraph = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": Qwen3VLTextDecoderLayer, + "attentions": Qwen3VLTextAttention, + } + + +class Qwen3VLVisionModel(Qwen3VLPreTrainedModel): + config: Qwen3VLVisionConfig + _no_split_modules = ["Qwen3VLVisionBlock"] + + def __init__(self, config, *inputs, **kwargs) -> None: + super().__init__(config, *inputs, **kwargs) + self.spatial_merge_size = config.spatial_merge_size + self.patch_size = config.patch_size + self.spatial_merge_unit = self.spatial_merge_size * self.spatial_merge_size + + self.patch_embed = Qwen3VLVisionPatchEmbed( + config=config, + ) + + self.pos_embed = nn.Embedding(config.num_position_embeddings, config.hidden_size) + self.num_grid_per_side = int(config.num_position_embeddings**0.5) + + head_dim = config.hidden_size // config.num_heads + self.rotary_pos_emb = Qwen3VLVisionRotaryEmbedding(head_dim // 2) + + self.blocks = nn.ModuleList([Qwen3VLVisionBlock(config) for _ in range(config.depth)]) + self.merger = Qwen3VLVisionPatchMerger( + config=config, + use_postshuffle_norm=False, + ) + + self.deepstack_visual_indexes = config.deepstack_visual_indexes + self.deepstack_merger_list = nn.ModuleList( + [ + Qwen3VLVisionPatchMerger( + config=config, + use_postshuffle_norm=True, + ) + for _ in range(len(config.deepstack_visual_indexes)) + ] + ) + + self.gradient_checkpointing = False + + def rot_pos_emb(self, grid_thw: torch.Tensor) -> torch.Tensor: + merge_size = self.spatial_merge_size + + max_hw = int(grid_thw[:, 1:].max().item()) + freq_table = self.rotary_pos_emb(max_hw) # (max_hw, dim // 2) + device = freq_table.device + + total_tokens = int(torch.prod(grid_thw, dim=1).sum().item()) + pos_ids = torch.empty((total_tokens, 2), dtype=torch.long, device=device) + + offset = 0 + for num_frames, height, width in grid_thw: + merged_h, merged_w = height // merge_size, width // merge_size + + block_rows = torch.arange(merged_h, device=device) # block row indices + block_cols = torch.arange(merged_w, device=device) # block col indices + intra_row = torch.arange(merge_size, device=device) # intra-block row offsets + intra_col = torch.arange(merge_size, device=device) # intra-block col offsets + + # Compute full-resolution positions + row_idx = block_rows[:, None, None, None] * merge_size + intra_row[None, None, :, None] + col_idx = block_cols[None, :, None, None] * merge_size + intra_col[None, None, None, :] + + row_idx = row_idx.expand(merged_h, merged_w, merge_size, merge_size).reshape(-1) + col_idx = col_idx.expand(merged_h, merged_w, merge_size, merge_size).reshape(-1) + + coords = torch.stack((row_idx, col_idx), dim=-1) + + if num_frames > 1: + coords = coords.repeat(num_frames, 1) + + num_tokens = coords.shape[0] + pos_ids[offset : offset + num_tokens] = coords + offset += num_tokens + + embeddings = freq_table[pos_ids] # lookup rotary embeddings + embeddings = embeddings.flatten(1) + return embeddings + + def fast_pos_embed_interpolate(self, grid_thw): + grid_ts, grid_hs, grid_ws = grid_thw[:, 0], grid_thw[:, 1], grid_thw[:, 2] + + idx_list = [[] for _ in range(4)] + weight_list = [[] for _ in range(4)] + + for t, h, w in zip(grid_ts, grid_hs, grid_ws): + h_idxs = torch.linspace(0, self.num_grid_per_side - 1, h) + w_idxs = torch.linspace(0, self.num_grid_per_side - 1, w) + + h_idxs_floor = h_idxs.int() + w_idxs_floor = w_idxs.int() + h_idxs_ceil = (h_idxs.int() + 1).clip(max=self.num_grid_per_side - 1) + w_idxs_ceil = (w_idxs.int() + 1).clip(max=self.num_grid_per_side - 1) + + dh = h_idxs - h_idxs_floor + dw = w_idxs - w_idxs_floor + + base_h = h_idxs_floor * self.num_grid_per_side + base_h_ceil = h_idxs_ceil * self.num_grid_per_side + + indices = [ + (base_h[None].T + w_idxs_floor[None]).flatten(), + (base_h[None].T + w_idxs_ceil[None]).flatten(), + (base_h_ceil[None].T + w_idxs_floor[None]).flatten(), + (base_h_ceil[None].T + w_idxs_ceil[None]).flatten(), + ] + + weights = [ + ((1 - dh)[None].T * (1 - dw)[None]).flatten(), + ((1 - dh)[None].T * dw[None]).flatten(), + (dh[None].T * (1 - dw)[None]).flatten(), + (dh[None].T * dw[None]).flatten(), + ] + + for i in range(4): + idx_list[i].extend(indices[i].tolist()) + weight_list[i].extend(weights[i].tolist()) + + idx_tensor = torch.tensor(idx_list, dtype=torch.long, device=self.pos_embed.weight.device) + weight_tensor = torch.tensor( + weight_list, dtype=self.pos_embed.weight.dtype, device=self.pos_embed.weight.device + ) + pos_embeds = self.pos_embed(idx_tensor) * weight_tensor[:, :, None] + patch_pos_embeds = pos_embeds[0] + pos_embeds[1] + pos_embeds[2] + pos_embeds[3] + + patch_pos_embeds = patch_pos_embeds.split([h * w for h, w in zip(grid_hs, grid_ws)]) + + patch_pos_embeds_permute = [] + merge_size = self.config.spatial_merge_size + for pos_embed, t, h, w in zip(patch_pos_embeds, grid_ts, grid_hs, grid_ws): + pos_embed = pos_embed.repeat(t, 1) + pos_embed = ( + pos_embed.view(t, h // merge_size, merge_size, w // merge_size, merge_size, -1) + .permute(0, 1, 3, 2, 4, 5) + .flatten(0, 4) + ) + patch_pos_embeds_permute.append(pos_embed) + patch_pos_embeds = torch.cat(patch_pos_embeds_permute) + return patch_pos_embeds + + def forward(self, hidden_states: torch.Tensor, grid_thw: torch.Tensor, **kwargs) -> torch.Tensor: + """ + Args: + hidden_states (`torch.Tensor` of shape `(seq_len, hidden_size)`): + The final hidden states of the model. + grid_thw (`torch.Tensor` of shape `(num_images_or_videos, 3)`): + The temporal, height and width of feature shape of each image in LLM. + + Returns: + `torch.Tensor`: hidden_states. + """ + hidden_states = self.patch_embed(hidden_states) + + pos_embeds = self.fast_pos_embed_interpolate(grid_thw) + hidden_states = hidden_states + pos_embeds + + rotary_pos_emb = self.rot_pos_emb(grid_thw) + + seq_len, _ = hidden_states.size() + hidden_states = hidden_states.reshape(seq_len, -1) + rotary_pos_emb = rotary_pos_emb.reshape(seq_len, -1) + emb = torch.cat((rotary_pos_emb, rotary_pos_emb), dim=-1) + position_embeddings = (emb.cos(), emb.sin()) + + cu_seqlens = torch.repeat_interleave(grid_thw[:, 1] * grid_thw[:, 2], grid_thw[:, 0]).cumsum( + dim=0, + # Select dtype based on the following factors: + # - FA2 requires that cu_seqlens_q must have dtype int32 + # - torch.onnx.export requires that cu_seqlens_q must have same dtype as grid_thw + # See https://github.com/huggingface/transformers/pull/34852 for more information + dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32, + ) + cu_seqlens = F.pad(cu_seqlens, (1, 0), value=0) + + deepstack_feature_lists = [] + for layer_num, blk in enumerate(self.blocks): + hidden_states = blk( + hidden_states, + cu_seqlens=cu_seqlens, + position_embeddings=position_embeddings, + **kwargs, + ) + if layer_num in self.deepstack_visual_indexes: + deepstack_feature = self.deepstack_merger_list[self.deepstack_visual_indexes.index(layer_num)]( + hidden_states + ) + deepstack_feature_lists.append(deepstack_feature) + + hidden_states = self.merger(hidden_states) + + return hidden_states, deepstack_feature_lists + + +@auto_docstring( + custom_intro=( + "Text part of Qwen3VL, " + "not a pure text-only model, as DeepStack integrates visual features into the early hidden states." + ) +) +class Qwen3VLTextModel(Qwen3VLPreTrainedModel): + config: Qwen3VLTextConfig + _no_split_modules = ["Qwen3VLTextDecoderLayer"] + + def __init__(self, config: Qwen3VLTextConfig): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + + self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx) + self.layers = nn.ModuleList( + [Qwen3VLTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = Qwen3VLTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = Qwen3VLTextRotaryEmbedding(config=config) + self.gradient_checkpointing = False + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + # args for deepstack + visual_pos_masks: Optional[torch.Tensor] = None, + deepstack_visual_embeds: Optional[list[torch.Tensor]] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> Union[tuple, BaseModelOutputWithPast]: + r""" + visual_pos_masks (`torch.Tensor` of shape `(batch_size, seqlen)`, *optional*): + The mask of the visual positions. + deepstack_visual_embeds (`list[torch.Tensor]`, *optional*): + The deepstack visual embeddings. The shape is (num_layers, visual_seqlen, embed_dim). + The feature is extracted from the different visual encoder layers, and fed to the decoder + hidden states. It's from the paper DeepStack(https://arxiv.org/abs/2406.04334). + """ + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + # torch.jit.trace() doesn't support cache objects in the output + if use_cache and past_key_values is None and not torch.jit.is_tracing(): + past_key_values = DynamicCache(config=self.config) + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + # the hard coded `3` is for temporal, height and width. + if position_ids is None: + position_ids = cache_position.view(1, 1, -1).expand(3, inputs_embeds.shape[0], -1) + elif position_ids.ndim == 2: + position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1) + + if position_ids.ndim == 3 and position_ids.shape[0] == 4: + text_position_ids = position_ids[0] + position_ids = position_ids[1:] + else: + text_position_ids = position_ids[0] + + attention_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=text_position_ids, + ) + + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + # decoder layers + for layer_idx, decoder_layer in enumerate(self.layers): + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + position_ids=text_position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = layer_outputs + + # add visual features to the hidden states of first several layers + if deepstack_visual_embeds is not None and layer_idx in range(len(deepstack_visual_embeds)): + hidden_states = self._deepstack_process( + hidden_states, + visual_pos_masks, + deepstack_visual_embeds[layer_idx], + ) + + hidden_states = self.norm(hidden_states) + + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) + + def _deepstack_process( + self, hidden_states: torch.Tensor, visual_pos_masks: torch.Tensor, visual_embeds: torch.Tensor + ): + visual_pos_masks = visual_pos_masks.to(hidden_states.device) + visual_embeds = visual_embeds.to(hidden_states.device, hidden_states.dtype) + local_this = hidden_states[visual_pos_masks, :].clone() + visual_embeds + hidden_states[visual_pos_masks, :] = local_this + return hidden_states + + +@auto_docstring +class Qwen3VLModel(Qwen3VLPreTrainedModel): + base_model_prefix = "" + _checkpoint_conversion_mapping = {} + # Reference: fix gemma3 grad acc #37208 + accepts_loss_kwargs = False + config: Qwen3VLConfig + _no_split_modules = ["Qwen3VLTextDecoderLayer", "Qwen3VLVisionBlock"] + + def __init__(self, config): + super().__init__(config) + self.visual = Qwen3VLVisionModel._from_config(config.vision_config) + self.language_model = Qwen3VLTextModel._from_config(config.text_config) + self.rope_deltas = None # cache rope_deltas here + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.language_model.get_input_embeddings() + + def set_input_embeddings(self, value): + self.language_model.set_input_embeddings(value) + + def set_decoder(self, decoder): + self.language_model = decoder + + def get_decoder(self): + return self.language_model + + def get_rope_index( + self, + input_ids: Optional[torch.LongTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + """Different from the original implementation, Qwen3VL use timestamps rather than absolute time position ids.""" + + # Since we use timestamps to seperate videos, like , the video_grid_thw should also be split + if video_grid_thw is not None: + video_grid_thw = torch.repeat_interleave(video_grid_thw, video_grid_thw[:, 0], dim=0) + video_grid_thw[:, 0] = 1 + + spatial_merge_size = self.config.vision_config.spatial_merge_size + image_token_id = self.config.image_token_id + video_token_id = self.config.video_token_id + vision_start_token_id = self.config.vision_start_token_id + mrope_position_deltas = [] + if input_ids is not None and (image_grid_thw is not None or video_grid_thw is not None): + total_input_ids = input_ids + if attention_mask is None: + attention_mask = torch.ones_like(total_input_ids) + position_ids = torch.ones( + 3, + input_ids.shape[0], + input_ids.shape[1], + dtype=input_ids.dtype, + device=input_ids.device, + ) + image_index, video_index = 0, 0 + attention_mask = attention_mask.to(total_input_ids.device) + for i, input_ids in enumerate(total_input_ids): + input_ids = input_ids[attention_mask[i] == 1] + image_nums, video_nums = 0, 0 + vision_start_indices = torch.argwhere(input_ids == vision_start_token_id).squeeze(1) + vision_tokens = input_ids[vision_start_indices + 1] + image_nums = (vision_tokens == image_token_id).sum() + video_nums = (vision_tokens == video_token_id).sum() + input_tokens = input_ids.tolist() + llm_pos_ids_list: list = [] + st = 0 + remain_images, remain_videos = image_nums, video_nums + for _ in range(image_nums + video_nums): + if image_token_id in input_tokens and remain_images > 0: + ed_image = input_tokens.index(image_token_id, st) + else: + ed_image = len(input_tokens) + 1 + if video_token_id in input_tokens and remain_videos > 0: + ed_video = input_tokens.index(video_token_id, st) + else: + ed_video = len(input_tokens) + 1 + if ed_image < ed_video: + t, h, w = ( + image_grid_thw[image_index][0], + image_grid_thw[image_index][1], + image_grid_thw[image_index][2], + ) + image_index += 1 + remain_images -= 1 + ed = ed_image + + else: + t, h, w = ( + video_grid_thw[video_index][0], + video_grid_thw[video_index][1], + video_grid_thw[video_index][2], + ) + video_index += 1 + remain_videos -= 1 + ed = ed_video + llm_grid_t, llm_grid_h, llm_grid_w = ( + t.item(), + h.item() // spatial_merge_size, + w.item() // spatial_merge_size, + ) + text_len = ed - st + + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx) + + # t_index is always 0 because llm_grid_t is always 1 (we use timestamps to encode the temporal information for videos) + t_index = torch.arange(llm_grid_t).view(-1, 1).expand(-1, llm_grid_h * llm_grid_w).flatten() + h_index = torch.arange(llm_grid_h).view(1, -1, 1).expand(llm_grid_t, -1, llm_grid_w).flatten() + w_index = torch.arange(llm_grid_w).view(1, 1, -1).expand(llm_grid_t, llm_grid_h, -1).flatten() + llm_pos_ids_list.append(torch.stack([t_index, h_index, w_index]) + text_len + st_idx) + st = ed + llm_grid_t * llm_grid_h * llm_grid_w + + if st < len(input_tokens): + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + text_len = len(input_tokens) - st + llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx) + + llm_positions = torch.cat(llm_pos_ids_list, dim=1).reshape(3, -1) + position_ids[..., i, attention_mask[i] == 1] = llm_positions.to(position_ids.device) + mrope_position_deltas.append(llm_positions.max() + 1 - len(total_input_ids[i])) + mrope_position_deltas = torch.tensor(mrope_position_deltas, device=input_ids.device).unsqueeze(1) + return position_ids, mrope_position_deltas + else: + if attention_mask is not None: + position_ids = attention_mask.long().cumsum(-1) - 1 + position_ids.masked_fill_(attention_mask == 0, 1) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1).to(attention_mask.device) + max_position_ids = position_ids.max(0, keepdim=False)[0].max(-1, keepdim=True)[0] + mrope_position_deltas = max_position_ids + 1 - attention_mask.shape[-1] + else: + position_ids = ( + torch.arange(input_ids.shape[1], device=input_ids.device) + .view(1, 1, -1) + .expand(3, input_ids.shape[0], -1) + ) + mrope_position_deltas = torch.zeros( + [input_ids.shape[0], 1], + device=input_ids.device, + dtype=input_ids.dtype, + ) + + return position_ids, mrope_position_deltas + + def get_video_features( + self, pixel_values_videos: torch.FloatTensor, video_grid_thw: Optional[torch.LongTensor] = None + ): + """ + Encodes videos into continuous embeddings that can be forwarded to the language model. The deepstack visual features are also returned. + + Args: + pixel_values_videos (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`): + The tensors corresponding to the input videos. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + """ + # Same implementation as for images + return self.get_image_features(pixel_values_videos, video_grid_thw) + + def get_image_features(self, pixel_values: torch.FloatTensor, image_grid_thw: Optional[torch.LongTensor] = None): + """ + Encodes images into continuous embeddings that can be forwarded to the language model. The deepstack visual features are also returned. + + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`): + The tensors corresponding to the input images. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + """ + pixel_values = pixel_values.type(self.visual.dtype) + image_embeds, deepstack_image_embeds = self.visual(pixel_values, grid_thw=image_grid_thw) + split_sizes = (image_grid_thw.prod(-1) // self.visual.spatial_merge_size**2).tolist() + image_embeds = torch.split(image_embeds, split_sizes) + return image_embeds, deepstack_image_embeds + + def get_placeholder_mask( + self, + input_ids: torch.LongTensor, + inputs_embeds: torch.FloatTensor, + image_features: Optional[torch.FloatTensor] = None, + video_features: Optional[torch.FloatTensor] = None, + ): + """ + Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is + equal to the length of multimodal features. If the lengths are different, an error is raised. + """ + if input_ids is None: + special_image_mask = inputs_embeds == self.get_input_embeddings()( + torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + special_image_mask = special_image_mask.all(-1) + special_video_mask = inputs_embeds == self.get_input_embeddings()( + torch.tensor(self.config.video_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + special_video_mask = special_video_mask.all(-1) + else: + special_image_mask = input_ids == self.config.image_token_id + special_video_mask = input_ids == self.config.video_token_id + + n_image_tokens = special_image_mask.sum() + special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device) + if image_features is not None and inputs_embeds[special_image_mask].numel() != image_features.numel(): + raise ValueError( + f"Image features and image tokens do not match: tokens: {n_image_tokens}, features {image_features.shape[0]}" + ) + + n_video_tokens = special_video_mask.sum() + special_video_mask = special_video_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device) + if video_features is not None and inputs_embeds[special_video_mask].numel() != video_features.numel(): + raise ValueError( + f"Videos features and video tokens do not match: tokens: {n_video_tokens}, features {video_features.shape[0]}" + ) + + return special_image_mask, special_video_mask + + @auto_docstring + @can_return_tuple + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + pixel_values: Optional[torch.Tensor] = None, + pixel_values_videos: Optional[torch.FloatTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, Qwen3VLModelOutputWithPast]: + r""" + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + """ + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds = self.get_input_embeddings()(input_ids) + + image_mask = None + video_mask = None + + if pixel_values is not None: + image_embeds, deepstack_image_embeds = self.get_image_features(pixel_values, image_grid_thw) + image_embeds = torch.cat(image_embeds, dim=0).to(inputs_embeds.device, inputs_embeds.dtype) + image_mask, _ = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, image_features=image_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds) + + if pixel_values_videos is not None: + video_embeds, deepstack_video_embeds = self.get_video_features(pixel_values_videos, video_grid_thw) + video_embeds = torch.cat(video_embeds, dim=0).to(inputs_embeds.device, inputs_embeds.dtype) + _, video_mask = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, video_features=video_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter(video_mask, video_embeds) + + visual_pos_masks = None + deepstack_visual_embeds = None + if image_mask is not None and video_mask is not None: + # aggregate visual_pos_masks and deepstack_visual_embeds + image_mask = image_mask[..., 0] + video_mask = video_mask[..., 0] + visual_pos_masks = image_mask | video_mask + deepstack_visual_embeds = [] + image_mask_joint = image_mask[visual_pos_masks] + video_mask_joint = video_mask[visual_pos_masks] + for img_embed, vid_embed in zip(deepstack_image_embeds, deepstack_video_embeds): + embed_joint = img_embed.new_zeros(visual_pos_masks.sum(), img_embed.shape[-1]).to(img_embed.device) + embed_joint[image_mask_joint, :] = img_embed + embed_joint[video_mask_joint, :] = vid_embed + deepstack_visual_embeds.append(embed_joint) + elif image_mask is not None: + image_mask = image_mask[..., 0] + visual_pos_masks = image_mask + deepstack_visual_embeds = deepstack_image_embeds + elif video_mask is not None: + video_mask = video_mask[..., 0] + visual_pos_masks = video_mask + deepstack_visual_embeds = deepstack_video_embeds + + if position_ids is None: + attention_mask_tensor = ( + attention_mask if not isinstance(attention_mask, dict) else attention_mask["full_attention"] + ) + if attention_mask_tensor is not None and attention_mask_tensor.ndim == 4: + attention_mask_tensor = torch.diagonal(attention_mask_tensor[:, 0], dim1=1, dim2=2) + # Only apply conversion for floating point tensors (inverted masks) + if attention_mask_tensor.dtype.is_floating_point: + attention_mask_tensor = attention_mask_tensor / torch.finfo(attention_mask_tensor.dtype).min + attention_mask_tensor = (1.0 - attention_mask_tensor).int() + + # Calculate RoPE index once per generation in the pre-fill stage only. + # When compiling, we can't check tensor values thus we check only input length + # It is safe to assume that `length!=1` means we're in pre-fill because compiled + # models currently cannot do asssisted decoding + prefill_compiled_stage = is_torchdynamo_compiling() and ( + (input_ids is not None and input_ids.shape[1] != 1) + or (inputs_embeds is not None and inputs_embeds.shape[1] != 1) + ) + prefill_noncompiled_stage = not is_torchdynamo_compiling() and ( + (cache_position is not None and cache_position[0] == 0) + or (past_key_values is None or past_key_values.get_seq_length() == 0) + ) + if (prefill_compiled_stage or prefill_noncompiled_stage) or self.rope_deltas is None: + position_ids, rope_deltas = self.get_rope_index( + input_ids, + image_grid_thw, + video_grid_thw, + attention_mask=attention_mask_tensor, + ) + self.rope_deltas = rope_deltas + # then use the prev pre-calculated rope-deltas to get the correct position ids + else: + batch_size, seq_length, _ = inputs_embeds.shape + delta = ( + (cache_position[0] + self.rope_deltas).to(inputs_embeds.device) + if cache_position is not None + else 0 + ) + position_ids = torch.arange(seq_length, device=inputs_embeds.device) + position_ids = position_ids.view(1, -1).expand(batch_size, -1) + if cache_position is not None: # otherwise `deltas` is an int `0` + delta = delta.repeat_interleave(batch_size // delta.shape[0], dim=0) + position_ids = position_ids.add(delta) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1) + + outputs = self.language_model( + input_ids=None, + position_ids=position_ids, + attention_mask=attention_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + visual_pos_masks=visual_pos_masks, + deepstack_visual_embeds=deepstack_visual_embeds, + **kwargs, + ) + + return Qwen3VLModelOutputWithPast( + last_hidden_state=outputs.last_hidden_state, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + rope_deltas=self.rope_deltas, + ) + + +@dataclass +@auto_docstring( + custom_intro=""" + Base class for Qwen3VL causal language model (or autoregressive) outputs. + """ +) +class Qwen3VLCausalLMOutputWithPast(ModelOutput): + r""" + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided): + Language modeling loss (for next-token prediction). + logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape + `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + + Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see + `past_key_values` input) to speed up sequential decoding. + rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*): + The rope index difference between sequence length and multimodal rope. + """ + + loss: Optional[torch.FloatTensor] = None + logits: Optional[torch.FloatTensor] = None + past_key_values: Optional[list[torch.FloatTensor]] = None + hidden_states: Optional[tuple[torch.FloatTensor]] = None + attentions: Optional[tuple[torch.FloatTensor]] = None + rope_deltas: Optional[torch.LongTensor] = None + + +class Qwen3VLForConditionalGeneration(Qwen3VLPreTrainedModel, GenerationMixin): + _checkpoint_conversion_mapping = {} + _tied_weights_keys = ["lm_head.weight"] + # Reference: fix gemma3 grad acc #37208 + accepts_loss_kwargs = False + config: Qwen3VLConfig + + def __init__(self, config): + super().__init__(config) + self.model = Qwen3VLModel(config) + self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False) + + self.post_init() + + def get_input_embeddings(self): + return self.model.get_input_embeddings() + + def set_input_embeddings(self, value): + self.model.set_input_embeddings(value) + + def set_decoder(self, decoder): + self.model.set_decoder(decoder) + + def get_decoder(self): + return self.model.get_decoder() + + def get_video_features( + self, pixel_values_videos: torch.FloatTensor, video_grid_thw: Optional[torch.LongTensor] = None + ): + return self.model.get_video_features(pixel_values_videos, video_grid_thw) + + def get_image_features(self, pixel_values: torch.FloatTensor, image_grid_thw: Optional[torch.LongTensor] = None): + return self.model.get_image_features(pixel_values, image_grid_thw) + + # Make modules available through conditional class for BC + @property + def language_model(self): + return self.model.language_model + + @property + def visual(self): + return self.model.visual + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[list[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.Tensor] = None, + pixel_values_videos: Optional[torch.FloatTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, Qwen3VLCausalLMOutputWithPast]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + + Example: + TODO: Add example + """ + outputs = self.model( + input_ids=input_ids, + pixel_values=pixel_values, + pixel_values_videos=pixel_values_videos, + image_grid_thw=image_grid_thw, + video_grid_thw=video_grid_thw, + position_ids=position_ids, + attention_mask=attention_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs[0] + + # Only compute necessary logits, and do not upcast them to float if we are not computing the loss + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]) + + loss = None + if labels is not None: + loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.text_config.vocab_size) + + return Qwen3VLCausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + rope_deltas=outputs.rope_deltas, + ) + + def prepare_inputs_for_generation( + self, + input_ids, + past_key_values=None, + attention_mask=None, + inputs_embeds=None, + cache_position=None, + position_ids=None, + use_cache=True, + pixel_values=None, + pixel_values_videos=None, + image_grid_thw=None, + video_grid_thw=None, + **kwargs, + ): + # Overwritten -- in specific circumstances we don't want to forward image inputs to the model + + model_inputs = super().prepare_inputs_for_generation( + input_ids, + past_key_values=past_key_values, + attention_mask=attention_mask, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + position_ids=position_ids, + pixel_values=pixel_values, + pixel_values_videos=pixel_values_videos, + image_grid_thw=image_grid_thw, + video_grid_thw=video_grid_thw, + use_cache=use_cache, + **kwargs, + ) + + # Qwen3VL position_ids are prepareed with rope_deltas in forward + model_inputs["position_ids"] = None + + if cache_position[0] != 0: + model_inputs["pixel_values"] = None + model_inputs["pixel_values_videos"] = None + + return model_inputs + + def _get_image_nums_and_video_nums( + self, + input_ids: Optional[torch.LongTensor], + inputs_embeds: Optional[torch.Tensor] = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + """ + Get the number of images and videos for each sample to calculate the separation length of the sample tensor. + These parameters are not passed through the processor to avoid unpredictable impacts from interface modifications. + + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. + + Returns: + image_nums (`torch.LongTensor` of shape `(batch_size, num_images_sample)`) + video_nums (`torch.LongTensor` of shape `(batch_size, num_videos_sample)`) + """ + image_token_id = self.config.image_token_id + video_token_id = self.config.video_token_id + vision_start_token_id = self.config.vision_start_token_id + + if inputs_embeds is not None: + vision_start_mask = ( + inputs_embeds + == self.get_input_embeddings()( + torch.tensor(vision_start_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + )[..., 0] + image_mask = ( + inputs_embeds + == self.get_input_embeddings()( + torch.tensor(image_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + )[..., 0] + video_mask = ( + inputs_embeds + == self.get_input_embeddings()( + torch.tensor(video_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + )[..., 0] + else: + vision_start_mask = input_ids == vision_start_token_id + image_mask = input_ids == image_token_id + video_mask = input_ids == video_token_id + + vision_first_mask = torch.roll(vision_start_mask, shifts=1, dims=1) + image_nums = torch.sum(vision_first_mask & image_mask, dim=1) + video_nums = torch.sum(vision_first_mask & video_mask, dim=1) + + return image_nums, video_nums + + def _expand_inputs_for_generation( + self, + expand_size: int = 1, + is_encoder_decoder: bool = False, + input_ids: Optional[torch.LongTensor] = None, + **model_kwargs, + ) -> tuple[torch.LongTensor, dict[str, Any]]: + # Overwritten -- Support for expanding tensors without a batch size dimension + # e.g., pixel_values, image_grid_thw, pixel_values_videos, video_grid_thw, second_per_grid_t + # pixel_values.shape[0] is sum(seqlen_images for samples) + # image_grid_thw.shape[0] is sum(num_images for samples) + + if expand_size == 1: + return input_ids, model_kwargs + + visual_keys = ["pixel_values", "image_grid_thw", "pixel_values_videos", "video_grid_thw", "second_per_grid_ts"] + + def _expand_dict_for_generation_visual(dict_to_expand): + image_grid_thw = model_kwargs.get("image_grid_thw", None) + video_grid_thw = model_kwargs.get("video_grid_thw", None) + image_nums, video_nums = self._get_image_nums_and_video_nums( + input_ids, inputs_embeds=model_kwargs.get("inputs_embeds", None) + ) + + def _repeat_interleave_samples(x, lengths, repeat_times): + samples = torch.split(x, lengths) + repeat_args = [repeat_times] + [1] * (x.dim() - 1) + result = torch.cat([sample.repeat(*repeat_args) for sample in samples], dim=0) + return result + + for key in dict_to_expand: + if key == "pixel_values": + # split images into samples + samples = torch.split(image_grid_thw, list(image_nums)) + # compute the sequence length of images for each sample + lengths = [torch.prod(sample, dim=1).sum() for sample in samples] + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "image_grid_thw": + # get the num of images for each sample + lengths = list(image_nums) + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "pixel_values_videos": + samples = torch.split(video_grid_thw, list(video_nums)) + lengths = [torch.prod(sample, dim=1).sum() for sample in samples] + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "video_grid_thw": + lengths = list(video_nums) + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "second_per_grid_ts": + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=list(video_nums), repeat_times=expand_size + ) + return dict_to_expand + + def _expand_dict_for_generation(dict_to_expand): + for key in dict_to_expand: + if ( + key != "cache_position" + and dict_to_expand[key] is not None + and isinstance(dict_to_expand[key], torch.Tensor) + and key not in visual_keys + ): + dict_to_expand[key] = dict_to_expand[key].repeat_interleave(expand_size, dim=0) + return dict_to_expand + + model_kwargs = _expand_dict_for_generation_visual(model_kwargs) + + if input_ids is not None: + input_ids = input_ids.repeat_interleave(expand_size, dim=0) + + model_kwargs = _expand_dict_for_generation(model_kwargs) + + if is_encoder_decoder: + if model_kwargs.get("encoder_outputs") is None: + raise ValueError("If `is_encoder_decoder` is True, make sure that `encoder_outputs` is defined.") + model_kwargs["encoder_outputs"] = _expand_dict_for_generation(model_kwargs["encoder_outputs"]) + + return input_ids, model_kwargs + + +__all__ = [ + "Qwen3VLVisionModel", + "Qwen3VLForConditionalGeneration", + "Qwen3VLModel", + "Qwen3VLPreTrainedModel", + "Qwen3VLTextModel", +] diff --git a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py new file mode 100644 index 000000000000..ae608e81a05d --- /dev/null +++ b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py @@ -0,0 +1,1472 @@ +# coding=utf-8 +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. +"""PyTorch Qwen3-VL model.""" + +from typing import Callable, Optional, Union + +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + +from ...activations import ACT2FN +from ...cache_utils import Cache, DynamicCache +from ...configuration_utils import PretrainedConfig +from ...feature_extraction_utils import BatchFeature +from ...image_utils import ImageInput +from ...masking_utils import create_causal_mask +from ...modeling_flash_attention_utils import FlashAttentionKwargs +from ...modeling_outputs import BaseModelOutputWithPast +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update, rope_config_validation +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS +from ...processing_utils import ProcessingKwargs, Unpack, VideosKwargs +from ...tokenization_utils_base import PreTokenizedInput, TextInput +from ...utils import auto_docstring, can_return_tuple, is_torchdynamo_compiling, logging +from ...utils.generic import check_model_inputs +from ...video_utils import VideoInput +from ..qwen2_5_vl.modeling_qwen2_5_vl import ( + Qwen2_5_VLCausalLMOutputWithPast, + Qwen2_5_VLForConditionalGeneration, + Qwen2_5_VLModel, + Qwen2_5_VLVisionBlock, +) +from ..qwen2_vl.modeling_qwen2_vl import ( + PatchEmbed, + Qwen2VLModelOutputWithPast, + Qwen2VLPreTrainedModel, + TransformersKwargs, + VisionAttention, + VisionRotaryEmbedding, +) +from ..qwen2_vl.processing_qwen2_vl import Qwen2VLImagesKwargs, Qwen2VLProcessor +from ..qwen3.modeling_qwen3 import ( + Qwen3Attention, + Qwen3DecoderLayer, + Qwen3Model, + apply_rotary_pos_emb, + eager_attention_forward, +) + + +logger = logging.get_logger(__name__) + + +class Qwen3VLVisionConfig(PretrainedConfig): + model_type = "qwen3_vl" + base_config_key = "vision_config" + + def __init__( + self, + depth=27, + hidden_size=1152, + hidden_act="gelu_pytorch_tanh", + intermediate_size=4304, + num_heads=16, + in_channels=3, + patch_size=16, + spatial_merge_size=2, + temporal_patch_size=2, + out_hidden_size=3584, + num_position_embeddings=2304, + deepstack_visual_indexes=[8, 16, 24], + initializer_range=0.02, + **kwargs, + ): + super().__init__(**kwargs) + + self.depth = depth + self.hidden_size = hidden_size + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.num_heads = num_heads + self.in_channels = in_channels + self.patch_size = patch_size + self.spatial_merge_size = spatial_merge_size + self.temporal_patch_size = temporal_patch_size + self.out_hidden_size = out_hidden_size + self.num_position_embeddings = num_position_embeddings + self.initializer_range = initializer_range + self.deepstack_visual_indexes = deepstack_visual_indexes + + +class Qwen3VLTextConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3VLTextModel`]. It is used to instantiate a + Qwen3-VL model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of + Qwen3-VL-4B-Instruct [Qwen/Qwen3-VL-4B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-4B-Instruct). + + 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 151936): + Vocabulary size of the Qwen3VL model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`Qwen3VLModel`] + hidden_size (`int`, *optional*, defaults to 4096): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 22016): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 32): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 32): + Number of attention heads for each attention layer in the Transformer encoder. + num_key_value_heads (`int`, *optional*, defaults to 32): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to `32`. + head_dim (`int`, *optional*, defaults to 128): + The dimension of the head. If not specified, will default to `hidden_size // num_attention_heads`. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 128000): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether the model's input and output word embeddings should be tied. + rope_theta (`float`, *optional*, defaults to 5000000.0): + The base period of the RoPE embeddings. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type + and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value + accordingly. + Expected contents: + `rope_type` (`str`): + The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope', + 'llama3'], with 'default' being the original RoPE implementation. + `factor` (`float`, *optional*): + Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In + most scaling types, a `factor` of x will enable the model to handle sequences of length x * + original maximum pre-trained length. + `original_max_position_embeddings` (`int`, *optional*): + Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during + pretraining. + `attention_factor` (`float`, *optional*): + Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention + computation. If unspecified, it defaults to value recommended by the implementation, using the + `factor` field to infer the suggested value. + `beta_fast` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear + ramp function. If unspecified, it defaults to 32. + `beta_slow` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear + ramp function. If unspecified, it defaults to 1. + `short_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to short contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `long_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to long contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `low_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE + `high_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + + ```python + >>> from transformers import Qwen3VLTextModel, Qwen3VLTextConfig + + >>> # Initializing a Qwen3VL style configuration + >>> configuration = Qwen3VLTextConfig() + + >>> # Initializing a model from the Qwen3-VL-7B style configuration + >>> model = Qwen3VLTextModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_vl_text" + base_config_key = "text_config" + + def __init__( + self, + vocab_size=151936, + hidden_size=4096, + intermediate_size=22016, + num_hidden_layers=32, + num_attention_heads=32, + num_key_value_heads=32, + head_dim=128, + hidden_act="silu", + max_position_embeddings=128000, + initializer_range=0.02, + rms_norm_eps=1e-6, + use_cache=True, + tie_word_embeddings=False, + rope_theta=5000000.0, + rope_scaling=None, + attention_bias=False, + attention_dropout=0.0, + **kwargs, + ): + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + + # for backward compatibility + if num_key_value_heads is None: + num_key_value_heads = num_attention_heads + + self.num_key_value_heads = num_key_value_heads + self.head_dim = head_dim + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + + rope_config_validation(self, ignore_keys={"mrope_section", "mrope_interleaved"}) + + super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs) + + +class Qwen3VLConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3VLModel`]. It is used to instantiate a + Qwen3-VL model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of + Qwen3-VL-4B-Instruct [Qwen/Qwen3-VL-4B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-4B-Instruct). + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + text_config (`Union[PreTrainedConfig, dict]`, *optional*, defaults to `Qwen3VLTextConfig`): + The config object or dictionary of the text backbone. + vision_config (`Union[PreTrainedConfig, dict]`, *optional*, defaults to `Qwen3VLVisionConfig`): + The config object or dictionary of the vision backbone. + image_token_id (`int`, *optional*, defaults to 151655): + The image token index to encode the image prompt. + video_token_id (`int`, *optional*, defaults to 151656): + The video token index to encode the image prompt. + vision_start_token_id (`int`, *optional*, defaults to 151652): + The start token index to encode the image prompt. + vision_end_token_id (`int`, *optional*, defaults to 151653): + The end token index to encode the image prompt. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether to tie the word embeddings. + + ```python + >>> from transformers import Qwen3VLForConditionalGeneration, Qwen3VLConfig + + >>> # Initializing a Qwen3-VL style configuration + >>> configuration = Qwen3VLConfig() + + >>> # Initializing a model from the Qwen3-VL-4B style configuration + >>> model = Qwen3VLForConditionalGeneration(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_vl" + sub_configs = {"vision_config": Qwen3VLVisionConfig, "text_config": Qwen3VLTextConfig} + keys_to_ignore_at_inference = ["past_key_values"] + + def __init__( + self, + text_config=None, + vision_config=None, + image_token_id=151655, + video_token_id=151656, + vision_start_token_id=151652, + vision_end_token_id=151653, + tie_word_embeddings=False, + **kwargs, + ): + if isinstance(vision_config, dict): + self.vision_config = self.sub_configs["vision_config"](**vision_config) + elif vision_config is None: + self.vision_config = self.sub_configs["vision_config"]() + + if isinstance(text_config, dict): + self.text_config = self.sub_configs["text_config"](**text_config) + elif text_config is None: + self.text_config = self.sub_configs["text_config"]() + + self.image_token_id = image_token_id + self.video_token_id = video_token_id + self.vision_start_token_id = vision_start_token_id + self.vision_end_token_id = vision_end_token_id + super().__init__(**kwargs, tie_word_embeddings=tie_word_embeddings) + + +class Qwen3VLVisionMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.linear_fc1 = nn.Linear(self.hidden_size, self.intermediate_size, bias=True) + self.linear_fc2 = nn.Linear(self.intermediate_size, self.hidden_size, bias=True) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, hidden_state): + return self.linear_fc2(self.act_fn(self.linear_fc1(hidden_state))) + + +class Qwen3VLVisionPatchEmbed(PatchEmbed): + def __init__(self, config) -> None: + super().__init__() + self.patch_size = config.patch_size + self.temporal_patch_size = config.temporal_patch_size + self.in_channels = config.in_channels + self.embed_dim = config.hidden_size + + kernel_size = [self.temporal_patch_size, self.patch_size, self.patch_size] + self.proj = nn.Conv3d(self.in_channels, self.embed_dim, kernel_size=kernel_size, stride=kernel_size, bias=True) + + +class Qwen3VLVisionRotaryEmbedding(VisionRotaryEmbedding): + pass + + +class Qwen3VLVisionPatchMerger(nn.Module): + def __init__(self, config: Qwen3VLVisionConfig, use_postshuffle_norm=False) -> None: + super().__init__() + self.hidden_size = config.hidden_size * (config.spatial_merge_size**2) + self.use_postshuffle_norm = use_postshuffle_norm + self.norm = nn.LayerNorm(self.hidden_size if use_postshuffle_norm else config.hidden_size, eps=1e-6) + self.linear_fc1 = nn.Linear(self.hidden_size, self.hidden_size) + self.act_fn = nn.GELU() + self.linear_fc2 = nn.Linear(self.hidden_size, config.out_hidden_size) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + x = self.norm(x.view(-1, self.hidden_size) if self.use_postshuffle_norm else x).view(-1, self.hidden_size) + x = self.linear_fc2(self.act_fn(self.linear_fc1(x))) + return x + + +class Qwen3VLVisionAttention(VisionAttention): + def __init__(self, config: Qwen3VLVisionConfig) -> None: + super().__init__() + self.dim = config.hidden_size + + +class Qwen3VLVisionBlock(Qwen2_5_VLVisionBlock): + def __init__(self, config, attn_implementation: str = "sdpa") -> None: + super().__init__() + self.norm1 = nn.LayerNorm(config.hidden_size, eps=1e-6) + self.norm2 = nn.LayerNorm(config.hidden_size, eps=1e-6) + self.attn = Qwen3VLVisionAttention(config=config) + self.mlp = Qwen3VLVisionMLP(config=config) + + +class Qwen3VLTextRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: Qwen3VLTextConfig, device=None): + super().__init__() + if hasattr(config, "rope_scaling") and config.rope_scaling is not None: + self.rope_type = config.rope_scaling.get("rope_type", "default") + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + self.mrope_section = config.rope_scaling.get("mrope_section", [24, 20, 20]) + + def apply_interleaved_mrope(self, freqs, mrope_section): + """Apply interleaved MRoPE to 3D rotary embeddings. + Reorganizes frequency layout from chunked [TTT...HHH...WWW] to + interleaved [THTHWHTHW...TT], preserving frequency continuity. + args: + x: (3, bs, seq_len, head_dim // 2) + mrope_section: (3,) + returns: + x_t: (bs, seq_len, head_dim // 2) + """ + freqs_t = freqs[0] # just overwrite the first dimension T + for dim, offset in enumerate((1, 2), start=1): # H, W + length = mrope_section[dim] * 3 + idx = slice(offset, length, 3) + freqs_t[..., idx] = freqs[dim, ..., idx] + return freqs_t + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + # In contrast to other models, Qwen3VL has different position ids for the grids + # So we expand the inv_freq to shape (3, ...) + if position_ids.ndim == 2: + position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1) + inv_freq_expanded = self.inv_freq[None, None, :, None].float().expand(3, position_ids.shape[1], -1, 1) + position_ids_expanded = position_ids[:, :, None, :].float() # shape (3, bs, 1, positions) + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(2, 3) + freqs = self.apply_interleaved_mrope(freqs, self.mrope_section) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + +class Qwen3VLTextAttention(Qwen3Attention): + def __init__(self, config: Qwen3VLTextConfig, layer_idx: int): + super().__init__(config, layer_idx) + del self.sliding_window + + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor]]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class Qwen3VLTextDecoderLayer(Qwen3DecoderLayer): + def __init__(self, config: Qwen3VLTextConfig, layer_idx: int): + super().__init__(config, layer_idx) + del self.attention_type + + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> torch.Tensor: + return super().forward( + hidden_states=hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + +class Qwen3VLModelOutputWithPast(Qwen2VLModelOutputWithPast): + pass + + +class Qwen3VLPreTrainedModel(Qwen2VLPreTrainedModel): + config: Qwen3VLConfig + _no_split_modules = ["Qwen3VLTextDecoderLayer", "Qwen3VLVisionBlock"] + _can_record_outputs = { + "hidden_states": Qwen3VLTextDecoderLayer, + "attentions": Qwen3VLTextAttention, + } + + +class Qwen3VLVisionModel(Qwen3VLPreTrainedModel): + config: Qwen3VLVisionConfig + _no_split_modules = ["Qwen3VLVisionBlock"] + + def __init__(self, config, *inputs, **kwargs) -> None: + super().__init__(config, *inputs, **kwargs) + self.spatial_merge_size = config.spatial_merge_size + self.patch_size = config.patch_size + self.spatial_merge_unit = self.spatial_merge_size * self.spatial_merge_size + + self.patch_embed = Qwen3VLVisionPatchEmbed( + config=config, + ) + + self.pos_embed = nn.Embedding(config.num_position_embeddings, config.hidden_size) + self.num_grid_per_side = int(config.num_position_embeddings**0.5) + + head_dim = config.hidden_size // config.num_heads + self.rotary_pos_emb = Qwen3VLVisionRotaryEmbedding(head_dim // 2) + + self.blocks = nn.ModuleList([Qwen3VLVisionBlock(config) for _ in range(config.depth)]) + self.merger = Qwen3VLVisionPatchMerger( + config=config, + use_postshuffle_norm=False, + ) + + self.deepstack_visual_indexes = config.deepstack_visual_indexes + self.deepstack_merger_list = nn.ModuleList( + [ + Qwen3VLVisionPatchMerger( + config=config, + use_postshuffle_norm=True, + ) + for _ in range(len(config.deepstack_visual_indexes)) + ] + ) + + self.gradient_checkpointing = False + + def rot_pos_emb(self, grid_thw: torch.Tensor) -> torch.Tensor: + merge_size = self.spatial_merge_size + + max_hw = int(grid_thw[:, 1:].max().item()) + freq_table = self.rotary_pos_emb(max_hw) # (max_hw, dim // 2) + device = freq_table.device + + total_tokens = int(torch.prod(grid_thw, dim=1).sum().item()) + pos_ids = torch.empty((total_tokens, 2), dtype=torch.long, device=device) + + offset = 0 + for num_frames, height, width in grid_thw: + merged_h, merged_w = height // merge_size, width // merge_size + + block_rows = torch.arange(merged_h, device=device) # block row indices + block_cols = torch.arange(merged_w, device=device) # block col indices + intra_row = torch.arange(merge_size, device=device) # intra-block row offsets + intra_col = torch.arange(merge_size, device=device) # intra-block col offsets + + # Compute full-resolution positions + row_idx = block_rows[:, None, None, None] * merge_size + intra_row[None, None, :, None] + col_idx = block_cols[None, :, None, None] * merge_size + intra_col[None, None, None, :] + + row_idx = row_idx.expand(merged_h, merged_w, merge_size, merge_size).reshape(-1) + col_idx = col_idx.expand(merged_h, merged_w, merge_size, merge_size).reshape(-1) + + coords = torch.stack((row_idx, col_idx), dim=-1) + + if num_frames > 1: + coords = coords.repeat(num_frames, 1) + + num_tokens = coords.shape[0] + pos_ids[offset : offset + num_tokens] = coords + offset += num_tokens + + embeddings = freq_table[pos_ids] # lookup rotary embeddings + embeddings = embeddings.flatten(1) + return embeddings + + def fast_pos_embed_interpolate(self, grid_thw): + grid_ts, grid_hs, grid_ws = grid_thw[:, 0], grid_thw[:, 1], grid_thw[:, 2] + + idx_list = [[] for _ in range(4)] + weight_list = [[] for _ in range(4)] + + for t, h, w in zip(grid_ts, grid_hs, grid_ws): + h_idxs = torch.linspace(0, self.num_grid_per_side - 1, h) + w_idxs = torch.linspace(0, self.num_grid_per_side - 1, w) + + h_idxs_floor = h_idxs.int() + w_idxs_floor = w_idxs.int() + h_idxs_ceil = (h_idxs.int() + 1).clip(max=self.num_grid_per_side - 1) + w_idxs_ceil = (w_idxs.int() + 1).clip(max=self.num_grid_per_side - 1) + + dh = h_idxs - h_idxs_floor + dw = w_idxs - w_idxs_floor + + base_h = h_idxs_floor * self.num_grid_per_side + base_h_ceil = h_idxs_ceil * self.num_grid_per_side + + indices = [ + (base_h[None].T + w_idxs_floor[None]).flatten(), + (base_h[None].T + w_idxs_ceil[None]).flatten(), + (base_h_ceil[None].T + w_idxs_floor[None]).flatten(), + (base_h_ceil[None].T + w_idxs_ceil[None]).flatten(), + ] + + weights = [ + ((1 - dh)[None].T * (1 - dw)[None]).flatten(), + ((1 - dh)[None].T * dw[None]).flatten(), + (dh[None].T * (1 - dw)[None]).flatten(), + (dh[None].T * dw[None]).flatten(), + ] + + for i in range(4): + idx_list[i].extend(indices[i].tolist()) + weight_list[i].extend(weights[i].tolist()) + + idx_tensor = torch.tensor(idx_list, dtype=torch.long, device=self.pos_embed.weight.device) + weight_tensor = torch.tensor( + weight_list, dtype=self.pos_embed.weight.dtype, device=self.pos_embed.weight.device + ) + pos_embeds = self.pos_embed(idx_tensor) * weight_tensor[:, :, None] + patch_pos_embeds = pos_embeds[0] + pos_embeds[1] + pos_embeds[2] + pos_embeds[3] + + patch_pos_embeds = patch_pos_embeds.split([h * w for h, w in zip(grid_hs, grid_ws)]) + + patch_pos_embeds_permute = [] + merge_size = self.config.spatial_merge_size + for pos_embed, t, h, w in zip(patch_pos_embeds, grid_ts, grid_hs, grid_ws): + pos_embed = pos_embed.repeat(t, 1) + pos_embed = ( + pos_embed.view(t, h // merge_size, merge_size, w // merge_size, merge_size, -1) + .permute(0, 1, 3, 2, 4, 5) + .flatten(0, 4) + ) + patch_pos_embeds_permute.append(pos_embed) + patch_pos_embeds = torch.cat(patch_pos_embeds_permute) + return patch_pos_embeds + + def forward(self, hidden_states: torch.Tensor, grid_thw: torch.Tensor, **kwargs) -> torch.Tensor: + """ + Args: + hidden_states (`torch.Tensor` of shape `(seq_len, hidden_size)`): + The final hidden states of the model. + grid_thw (`torch.Tensor` of shape `(num_images_or_videos, 3)`): + The temporal, height and width of feature shape of each image in LLM. + + Returns: + `torch.Tensor`: hidden_states. + """ + hidden_states = self.patch_embed(hidden_states) + + pos_embeds = self.fast_pos_embed_interpolate(grid_thw) + hidden_states = hidden_states + pos_embeds + + rotary_pos_emb = self.rot_pos_emb(grid_thw) + + seq_len, _ = hidden_states.size() + hidden_states = hidden_states.reshape(seq_len, -1) + rotary_pos_emb = rotary_pos_emb.reshape(seq_len, -1) + emb = torch.cat((rotary_pos_emb, rotary_pos_emb), dim=-1) + position_embeddings = (emb.cos(), emb.sin()) + + cu_seqlens = torch.repeat_interleave(grid_thw[:, 1] * grid_thw[:, 2], grid_thw[:, 0]).cumsum( + dim=0, + # Select dtype based on the following factors: + # - FA2 requires that cu_seqlens_q must have dtype int32 + # - torch.onnx.export requires that cu_seqlens_q must have same dtype as grid_thw + # See https://github.com/huggingface/transformers/pull/34852 for more information + dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32, + ) + cu_seqlens = F.pad(cu_seqlens, (1, 0), value=0) + + deepstack_feature_lists = [] + for layer_num, blk in enumerate(self.blocks): + hidden_states = blk( + hidden_states, + cu_seqlens=cu_seqlens, + position_embeddings=position_embeddings, + **kwargs, + ) + if layer_num in self.deepstack_visual_indexes: + deepstack_feature = self.deepstack_merger_list[self.deepstack_visual_indexes.index(layer_num)]( + hidden_states + ) + deepstack_feature_lists.append(deepstack_feature) + + hidden_states = self.merger(hidden_states) + + return hidden_states, deepstack_feature_lists + + +@auto_docstring( + custom_intro=( + "Text part of Qwen3VL, " + "not a pure text-only model, as DeepStack integrates visual features into the early hidden states." + ) +) +class Qwen3VLTextModel(Qwen3VLPreTrainedModel, Qwen3Model): + config: Qwen3VLTextConfig + _no_split_modules = ["Qwen3VLTextDecoderLayer"] + + def __init__(self, config: Qwen3VLTextConfig): + super().__init__(config) + del self.has_sliding_layers + + def _deepstack_process( + self, hidden_states: torch.Tensor, visual_pos_masks: torch.Tensor, visual_embeds: torch.Tensor + ): + visual_pos_masks = visual_pos_masks.to(hidden_states.device) + visual_embeds = visual_embeds.to(hidden_states.device, hidden_states.dtype) + local_this = hidden_states[visual_pos_masks, :].clone() + visual_embeds + hidden_states[visual_pos_masks, :] = local_this + return hidden_states + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + # args for deepstack + visual_pos_masks: Optional[torch.Tensor] = None, + deepstack_visual_embeds: Optional[list[torch.Tensor]] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> Union[tuple, BaseModelOutputWithPast]: + r""" + visual_pos_masks (`torch.Tensor` of shape `(batch_size, seqlen)`, *optional*): + The mask of the visual positions. + deepstack_visual_embeds (`list[torch.Tensor]`, *optional*): + The deepstack visual embeddings. The shape is (num_layers, visual_seqlen, embed_dim). + The feature is extracted from the different visual encoder layers, and fed to the decoder + hidden states. It's from the paper DeepStack(https://arxiv.org/abs/2406.04334). + """ + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + # torch.jit.trace() doesn't support cache objects in the output + if use_cache and past_key_values is None and not torch.jit.is_tracing(): + past_key_values = DynamicCache(config=self.config) + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + # the hard coded `3` is for temporal, height and width. + if position_ids is None: + position_ids = cache_position.view(1, 1, -1).expand(3, inputs_embeds.shape[0], -1) + elif position_ids.ndim == 2: + position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1) + + if position_ids.ndim == 3 and position_ids.shape[0] == 4: + text_position_ids = position_ids[0] + position_ids = position_ids[1:] + else: + text_position_ids = position_ids[0] + + attention_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=text_position_ids, + ) + + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + # decoder layers + for layer_idx, decoder_layer in enumerate(self.layers): + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + position_ids=text_position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = layer_outputs + + # add visual features to the hidden states of first several layers + if deepstack_visual_embeds is not None and layer_idx in range(len(deepstack_visual_embeds)): + hidden_states = self._deepstack_process( + hidden_states, + visual_pos_masks, + deepstack_visual_embeds[layer_idx], + ) + + hidden_states = self.norm(hidden_states) + + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) + + +@auto_docstring +class Qwen3VLModel(Qwen2_5_VLModel): + config: Qwen3VLConfig + _checkpoint_conversion_mapping = {} + _no_split_modules = ["Qwen3VLTextDecoderLayer", "Qwen3VLVisionBlock"] + + def __init__(self, config): + super().__init__(config) + self.visual = Qwen3VLVisionModel._from_config(config.vision_config) + self.language_model = Qwen3VLTextModel._from_config(config.text_config) + + def get_rope_index( + self, + input_ids: Optional[torch.LongTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + """Different from the original implementation, Qwen3VL use timestamps rather than absolute time position ids.""" + + # Since we use timestamps to seperate videos, like , the video_grid_thw should also be split + if video_grid_thw is not None: + video_grid_thw = torch.repeat_interleave(video_grid_thw, video_grid_thw[:, 0], dim=0) + video_grid_thw[:, 0] = 1 + + spatial_merge_size = self.config.vision_config.spatial_merge_size + image_token_id = self.config.image_token_id + video_token_id = self.config.video_token_id + vision_start_token_id = self.config.vision_start_token_id + mrope_position_deltas = [] + if input_ids is not None and (image_grid_thw is not None or video_grid_thw is not None): + total_input_ids = input_ids + if attention_mask is None: + attention_mask = torch.ones_like(total_input_ids) + position_ids = torch.ones( + 3, + input_ids.shape[0], + input_ids.shape[1], + dtype=input_ids.dtype, + device=input_ids.device, + ) + image_index, video_index = 0, 0 + attention_mask = attention_mask.to(total_input_ids.device) + for i, input_ids in enumerate(total_input_ids): + input_ids = input_ids[attention_mask[i] == 1] + image_nums, video_nums = 0, 0 + vision_start_indices = torch.argwhere(input_ids == vision_start_token_id).squeeze(1) + vision_tokens = input_ids[vision_start_indices + 1] + image_nums = (vision_tokens == image_token_id).sum() + video_nums = (vision_tokens == video_token_id).sum() + input_tokens = input_ids.tolist() + llm_pos_ids_list: list = [] + st = 0 + remain_images, remain_videos = image_nums, video_nums + for _ in range(image_nums + video_nums): + if image_token_id in input_tokens and remain_images > 0: + ed_image = input_tokens.index(image_token_id, st) + else: + ed_image = len(input_tokens) + 1 + if video_token_id in input_tokens and remain_videos > 0: + ed_video = input_tokens.index(video_token_id, st) + else: + ed_video = len(input_tokens) + 1 + if ed_image < ed_video: + t, h, w = ( + image_grid_thw[image_index][0], + image_grid_thw[image_index][1], + image_grid_thw[image_index][2], + ) + image_index += 1 + remain_images -= 1 + ed = ed_image + + else: + t, h, w = ( + video_grid_thw[video_index][0], + video_grid_thw[video_index][1], + video_grid_thw[video_index][2], + ) + video_index += 1 + remain_videos -= 1 + ed = ed_video + llm_grid_t, llm_grid_h, llm_grid_w = ( + t.item(), + h.item() // spatial_merge_size, + w.item() // spatial_merge_size, + ) + text_len = ed - st + + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx) + + # t_index is always 0 because llm_grid_t is always 1 (we use timestamps to encode the temporal information for videos) + t_index = torch.arange(llm_grid_t).view(-1, 1).expand(-1, llm_grid_h * llm_grid_w).flatten() + h_index = torch.arange(llm_grid_h).view(1, -1, 1).expand(llm_grid_t, -1, llm_grid_w).flatten() + w_index = torch.arange(llm_grid_w).view(1, 1, -1).expand(llm_grid_t, llm_grid_h, -1).flatten() + llm_pos_ids_list.append(torch.stack([t_index, h_index, w_index]) + text_len + st_idx) + st = ed + llm_grid_t * llm_grid_h * llm_grid_w + + if st < len(input_tokens): + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + text_len = len(input_tokens) - st + llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx) + + llm_positions = torch.cat(llm_pos_ids_list, dim=1).reshape(3, -1) + position_ids[..., i, attention_mask[i] == 1] = llm_positions.to(position_ids.device) + mrope_position_deltas.append(llm_positions.max() + 1 - len(total_input_ids[i])) + mrope_position_deltas = torch.tensor(mrope_position_deltas, device=input_ids.device).unsqueeze(1) + return position_ids, mrope_position_deltas + else: + if attention_mask is not None: + position_ids = attention_mask.long().cumsum(-1) - 1 + position_ids.masked_fill_(attention_mask == 0, 1) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1).to(attention_mask.device) + max_position_ids = position_ids.max(0, keepdim=False)[0].max(-1, keepdim=True)[0] + mrope_position_deltas = max_position_ids + 1 - attention_mask.shape[-1] + else: + position_ids = ( + torch.arange(input_ids.shape[1], device=input_ids.device) + .view(1, 1, -1) + .expand(3, input_ids.shape[0], -1) + ) + mrope_position_deltas = torch.zeros( + [input_ids.shape[0], 1], + device=input_ids.device, + dtype=input_ids.dtype, + ) + + return position_ids, mrope_position_deltas + + def get_image_features(self, pixel_values: torch.FloatTensor, image_grid_thw: Optional[torch.LongTensor] = None): + """ + Encodes images into continuous embeddings that can be forwarded to the language model. The deepstack visual features are also returned. + + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`): + The tensors corresponding to the input images. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + """ + pixel_values = pixel_values.type(self.visual.dtype) + image_embeds, deepstack_image_embeds = self.visual(pixel_values, grid_thw=image_grid_thw) + split_sizes = (image_grid_thw.prod(-1) // self.visual.spatial_merge_size**2).tolist() + image_embeds = torch.split(image_embeds, split_sizes) + return image_embeds, deepstack_image_embeds + + def get_video_features( + self, pixel_values_videos: torch.FloatTensor, video_grid_thw: Optional[torch.LongTensor] = None + ): + """ + Encodes videos into continuous embeddings that can be forwarded to the language model. The deepstack visual features are also returned. + + Args: + pixel_values_videos (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`): + The tensors corresponding to the input videos. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + """ + # Same implementation as for images + return self.get_image_features(pixel_values_videos, video_grid_thw) + + @auto_docstring + @can_return_tuple + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + pixel_values: Optional[torch.Tensor] = None, + pixel_values_videos: Optional[torch.FloatTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, Qwen3VLModelOutputWithPast]: + r""" + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + """ + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds = self.get_input_embeddings()(input_ids) + + image_mask = None + video_mask = None + + if pixel_values is not None: + image_embeds, deepstack_image_embeds = self.get_image_features(pixel_values, image_grid_thw) + image_embeds = torch.cat(image_embeds, dim=0).to(inputs_embeds.device, inputs_embeds.dtype) + image_mask, _ = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, image_features=image_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds) + + if pixel_values_videos is not None: + video_embeds, deepstack_video_embeds = self.get_video_features(pixel_values_videos, video_grid_thw) + video_embeds = torch.cat(video_embeds, dim=0).to(inputs_embeds.device, inputs_embeds.dtype) + _, video_mask = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, video_features=video_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter(video_mask, video_embeds) + + visual_pos_masks = None + deepstack_visual_embeds = None + if image_mask is not None and video_mask is not None: + # aggregate visual_pos_masks and deepstack_visual_embeds + image_mask = image_mask[..., 0] + video_mask = video_mask[..., 0] + visual_pos_masks = image_mask | video_mask + deepstack_visual_embeds = [] + image_mask_joint = image_mask[visual_pos_masks] + video_mask_joint = video_mask[visual_pos_masks] + for img_embed, vid_embed in zip(deepstack_image_embeds, deepstack_video_embeds): + embed_joint = img_embed.new_zeros(visual_pos_masks.sum(), img_embed.shape[-1]).to(img_embed.device) + embed_joint[image_mask_joint, :] = img_embed + embed_joint[video_mask_joint, :] = vid_embed + deepstack_visual_embeds.append(embed_joint) + elif image_mask is not None: + image_mask = image_mask[..., 0] + visual_pos_masks = image_mask + deepstack_visual_embeds = deepstack_image_embeds + elif video_mask is not None: + video_mask = video_mask[..., 0] + visual_pos_masks = video_mask + deepstack_visual_embeds = deepstack_video_embeds + + if position_ids is None: + attention_mask_tensor = ( + attention_mask if not isinstance(attention_mask, dict) else attention_mask["full_attention"] + ) + if attention_mask_tensor is not None and attention_mask_tensor.ndim == 4: + attention_mask_tensor = torch.diagonal(attention_mask_tensor[:, 0], dim1=1, dim2=2) + # Only apply conversion for floating point tensors (inverted masks) + if attention_mask_tensor.dtype.is_floating_point: + attention_mask_tensor = attention_mask_tensor / torch.finfo(attention_mask_tensor.dtype).min + attention_mask_tensor = (1.0 - attention_mask_tensor).int() + + # Calculate RoPE index once per generation in the pre-fill stage only. + # When compiling, we can't check tensor values thus we check only input length + # It is safe to assume that `length!=1` means we're in pre-fill because compiled + # models currently cannot do asssisted decoding + prefill_compiled_stage = is_torchdynamo_compiling() and ( + (input_ids is not None and input_ids.shape[1] != 1) + or (inputs_embeds is not None and inputs_embeds.shape[1] != 1) + ) + prefill_noncompiled_stage = not is_torchdynamo_compiling() and ( + (cache_position is not None and cache_position[0] == 0) + or (past_key_values is None or past_key_values.get_seq_length() == 0) + ) + if (prefill_compiled_stage or prefill_noncompiled_stage) or self.rope_deltas is None: + position_ids, rope_deltas = self.get_rope_index( + input_ids, + image_grid_thw, + video_grid_thw, + attention_mask=attention_mask_tensor, + ) + self.rope_deltas = rope_deltas + # then use the prev pre-calculated rope-deltas to get the correct position ids + else: + batch_size, seq_length, _ = inputs_embeds.shape + delta = ( + (cache_position[0] + self.rope_deltas).to(inputs_embeds.device) + if cache_position is not None + else 0 + ) + position_ids = torch.arange(seq_length, device=inputs_embeds.device) + position_ids = position_ids.view(1, -1).expand(batch_size, -1) + if cache_position is not None: # otherwise `deltas` is an int `0` + delta = delta.repeat_interleave(batch_size // delta.shape[0], dim=0) + position_ids = position_ids.add(delta) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1) + + outputs = self.language_model( + input_ids=None, + position_ids=position_ids, + attention_mask=attention_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + visual_pos_masks=visual_pos_masks, + deepstack_visual_embeds=deepstack_visual_embeds, + **kwargs, + ) + + return Qwen3VLModelOutputWithPast( + last_hidden_state=outputs.last_hidden_state, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + rope_deltas=self.rope_deltas, + ) + + +class Qwen3VLCausalLMOutputWithPast(Qwen2_5_VLCausalLMOutputWithPast): + pass + + +class Qwen3VLForConditionalGeneration(Qwen2_5_VLForConditionalGeneration): + config: Qwen3VLConfig + _checkpoint_conversion_mapping = {} + + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[list[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.Tensor] = None, + pixel_values_videos: Optional[torch.FloatTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, Qwen3VLCausalLMOutputWithPast]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + + Example: + TODO: Add example + """ + outputs = self.model( + input_ids=input_ids, + pixel_values=pixel_values, + pixel_values_videos=pixel_values_videos, + image_grid_thw=image_grid_thw, + video_grid_thw=video_grid_thw, + position_ids=position_ids, + attention_mask=attention_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs[0] + + # Only compute necessary logits, and do not upcast them to float if we are not computing the loss + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]) + + loss = None + if labels is not None: + loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.text_config.vocab_size) + + return Qwen3VLCausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + rope_deltas=outputs.rope_deltas, + ) + + def prepare_inputs_for_generation( + self, + input_ids, + past_key_values=None, + attention_mask=None, + inputs_embeds=None, + cache_position=None, + position_ids=None, + use_cache=True, + pixel_values=None, + pixel_values_videos=None, + image_grid_thw=None, + video_grid_thw=None, + **kwargs, + ): + # Overwritten -- in specific circumstances we don't want to forward image inputs to the model + + model_inputs = super().prepare_inputs_for_generation( + input_ids, + past_key_values=past_key_values, + attention_mask=attention_mask, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + position_ids=position_ids, + pixel_values=pixel_values, + pixel_values_videos=pixel_values_videos, + image_grid_thw=image_grid_thw, + video_grid_thw=video_grid_thw, + use_cache=use_cache, + **kwargs, + ) + + # Qwen3VL position_ids are prepareed with rope_deltas in forward + model_inputs["position_ids"] = None + + if cache_position[0] != 0: + model_inputs["pixel_values"] = None + model_inputs["pixel_values_videos"] = None + + return model_inputs + + +class Qwen3VLVideosProcessorKwargs(VideosKwargs, total=False): + pass + + +class Qwen3VLImagesKwargs(Qwen2VLImagesKwargs): + pass + + +class Qwen3VLProcessorKwargs(ProcessingKwargs, total=False): + images_kwargs: Qwen3VLImagesKwargs + videos_kwargs: Qwen3VLVideosProcessorKwargs + _defaults = { + "text_kwargs": { + "padding": False, + "return_token_type_ids": False, + "return_mm_token_type_ids": False, + }, + "videos_kwargs": {"return_metadata": True}, + } + + +class Qwen3VLProcessor(Qwen2VLProcessor): + r""" + Constructs a Qwen3VL processor which wraps a Qwen3VL image processor and a Qwen2 tokenizer into a single processor. + [`Qwen3VLProcessor`] offers all the functionalities of [`Qwen2VLImageProcessor`] and [`Qwen2TokenizerFast`]. See the + [`~Qwen3VLProcessor.__call__`] and [`~Qwen3VLProcessor.decode`] for more information. + Args: + image_processor ([`Qwen2VLImageProcessor`], *optional*): + The image processor is a required input. + tokenizer ([`Qwen2TokenizerFast`], *optional*): + The tokenizer is a required input. + video_processor ([`Qwen3VLVideoProcessor`], *optional*): + The video processor is a required input. + chat_template (`str`, *optional*): A Jinja template which will be used to convert lists of messages + in a chat into a tokenizable string. + """ + + def __init__(self, image_processor=None, tokenizer=None, video_processor=None, chat_template=None, **kwargs): + super().__init__(image_processor, tokenizer, video_processor, chat_template, **kwargs) + self.vision_start_token = ( + "<|vision_start|>" if not hasattr(tokenizer, "vision_start_token") else tokenizer.vision_start_token + ) + self.vision_end_token = ( + "<|vision_end|>" if not hasattr(tokenizer, "vision_end_token") else tokenizer.vision_end_token + ) + self.vision_start_token_id = ( + tokenizer.vision_start_token_id + if getattr(tokenizer, "vision_start_token_id", None) + else tokenizer.convert_tokens_to_ids(self.vision_start_token) + ) + self.vision_end_token_id = ( + tokenizer.vision_end_token_id + if getattr(tokenizer, "vision_end_token_id", None) + else tokenizer.convert_tokens_to_ids(self.vision_end_token) + ) + + def __call__( + self, + images: ImageInput = None, + text: Union[TextInput, PreTokenizedInput, list[TextInput], list[PreTokenizedInput]] = None, + videos: VideoInput = None, + **kwargs: Unpack[Qwen3VLProcessorKwargs], + ) -> BatchFeature: + """ + Main method to prepare for the model one or several sequences(s) and image(s). This method forwards the `text` + and `kwargs` arguments to Qwen2TokenizerFast's [`~Qwen2TokenizerFast.__call__`] if `text` is not `None` to encode + the text. To prepare the vision inputs, this method forwards the `vision_infos` and `kwrags` arguments to + Qwen2VLImageProcessor's [`~Qwen2VLImageProcessor.__call__`] if `vision_infos` is not `None`. + + Args: + images (`PIL.Image.Image`, `np.ndarray`, `torch.Tensor`, `list[PIL.Image.Image]`, `list[np.ndarray]`, `list[torch.Tensor]`): + The image or batch of images to be prepared. Each image can be a PIL image, NumPy array or PyTorch + tensor. Both channels-first and channels-last formats are supported. + text (`str`, `list[str]`, `list[list[str]]`): + The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings + (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set + `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + videos (`np.ndarray`, `torch.Tensor`, `list[np.ndarray]`, `list[torch.Tensor]`): + The image or batch of videos to be prepared. Each video can be a 4D NumPy array or PyTorch + tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors of a particular framework. Acceptable values are: + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return NumPy `np.ndarray` objects. + - `'jax'`: Return JAX `jnp.ndarray` objects. + + Returns: + [`BatchFeature`]: A [`BatchFeature`] with the following fields: + + - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`. + - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when + `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not + `None`). + - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`. + - **pixel_values_videos** -- Pixel values of videos to be fed to a model. Returned when `videos` is not `None`. + - **image_grid_thw** -- List of image 3D grid in LLM. Returned when `images` is not `None`. + - **video_grid_thw** -- List of video 3D grid in LLM. Returned when `videos` is not `None`. + """ + output_kwargs = self._merge_kwargs( + Qwen3VLProcessorKwargs, + tokenizer_init_kwargs=self.tokenizer.init_kwargs, + **kwargs, + ) + if images is not None: + image_inputs = self.image_processor(images=images, **output_kwargs["images_kwargs"]) + image_grid_thw = image_inputs["image_grid_thw"] + else: + image_inputs = {} + image_grid_thw = None + + if videos is not None: + videos_inputs = self.video_processor(videos=videos, **output_kwargs["videos_kwargs"]) + video_grid_thw = videos_inputs["video_grid_thw"] + # If user has not requested video metadata, pop it + if "return_metadata" not in kwargs: + video_metadata = videos_inputs.pop("video_metadata") + else: + video_metadata = videos_inputs["video_metadata"] + video_grid_thw = videos_inputs["video_grid_thw"] + else: + videos_inputs = {} + video_grid_thw = None + + if not isinstance(text, list): + text = [text] + + text = text.copy() # below lines change text in-place + if image_grid_thw is not None: + merge_length = self.image_processor.merge_size**2 + index = 0 + for i in range(len(text)): + while self.image_token in text[i]: + num_image_tokens = image_grid_thw[index].prod() // merge_length + text[i] = text[i].replace(self.image_token, "<|placeholder|>" * num_image_tokens, 1) + index += 1 + text[i] = text[i].replace("<|placeholder|>", self.image_token) + + if video_grid_thw is not None: + merge_length = self.video_processor.merge_size**2 + index = 0 + for i in range(len(text)): + while self.video_token in text[i]: + metadata = video_metadata[i] + if metadata.fps is None: + logger.warning_once( + "Qwen3VL requires frame timestamps to construct prompts, but the `fps` of the input video could not be inferred. " + "Probably `video_metadata` was missing from inputs and you passed pre-sampled frames. " + "Defaulting to `fps=24`. Please provide `video_metadata` for more accurate results." + ) + metadata.fps = 24 if metadata.fps is None else metadata.fps + + # if timestamps are not provided, calculate them + curr_timestamp = self._calculate_timestamps( + metadata.frames_indices, + metadata.fps, + self.video_processor.merge_size, + ) + + video_placeholder = "" + frame_seqlen = video_grid_thw[index][1:].prod() // merge_length + for frame_idx in range(video_grid_thw[index][0]): + curr_time = curr_timestamp[frame_idx] + video_placeholder += f"<{curr_time:.1f} seconds>" + video_placeholder += ( + self.vision_start_token + "<|placeholder|>" * frame_seqlen + self.vision_end_token + ) + if f"{self.vision_start_token}{self.video_token}{self.vision_end_token}" in text[i]: + text[i] = text[i].replace( + f"{self.vision_start_token}{self.video_token}{self.vision_end_token}", video_placeholder, 1 + ) + else: + # vllm may input video token directly + text[i] = text[i].replace(self.video_token, video_placeholder, 1) + index += 1 + + text[i] = text[i].replace("<|placeholder|>", self.video_token) + + return_tensors = output_kwargs["text_kwargs"].pop("return_tensors", None) + return_mm_token_type_ids = output_kwargs["text_kwargs"].pop("return_mm_token_type_ids", None) + text_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"]) + self._check_special_mm_tokens(text, text_inputs, modalities=["image", "video"]) + + if return_mm_token_type_ids: + array_ids = np.array(text_inputs["input_ids"]) + mm_token_type_ids = np.zeros_like(text_inputs["input_ids"]) + mm_token_type_ids[array_ids == self.image_token_id] = 1 + text_inputs["mm_token_type_ids"] = mm_token_type_ids.tolist() + + return BatchFeature(data={**text_inputs, **image_inputs, **videos_inputs}, tensor_type=return_tensors) + + def _calculate_timestamps(self, indices: Union[list[int], np.ndarray], video_fps: float, merge_size: int = 2): + if not isinstance(indices, list): + indices = indices.tolist() + if len(indices) % merge_size != 0: + indices.extend(indices[-1] for _ in range(merge_size - len(indices) % merge_size)) + timestamps = [idx / video_fps for idx in indices] + # @JJJYmmm frames are merged by self.merge_size, \ + # so we need to average the timestamps between the first/last frame within the temporal patch + timestamps = [ + (timestamps[i] + timestamps[i + merge_size - 1]) / 2 for i in range(0, len(timestamps), merge_size) + ] + return timestamps + + +__all__ = [ + "Qwen3VLConfig", + "Qwen3VLTextConfig", + "Qwen3VLVisionModel", + "Qwen3VLForConditionalGeneration", + "Qwen3VLModel", + "Qwen3VLPreTrainedModel", + "Qwen3VLProcessor", + "Qwen3VLTextModel", +] diff --git a/src/transformers/models/qwen3_vl/processing_qwen3_vl.py b/src/transformers/models/qwen3_vl/processing_qwen3_vl.py new file mode 100644 index 000000000000..cac82e738f39 --- /dev/null +++ b/src/transformers/models/qwen3_vl/processing_qwen3_vl.py @@ -0,0 +1,328 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/qwen3_vl/modular_qwen3_vl.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_qwen3_vl.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. + +from typing import Optional, Union + +import numpy as np + +from ...feature_extraction_utils import BatchFeature +from ...image_utils import ImageInput +from ...processing_utils import ImagesKwargs, MultiModalData, ProcessingKwargs, ProcessorMixin, Unpack, VideosKwargs +from ...tokenization_utils_base import PreTokenizedInput, TextInput +from ...utils import logging +from ...video_utils import VideoInput + + +logger = logging.get_logger(__name__) + + +class Qwen3VLVideosProcessorKwargs(VideosKwargs, total=False): + pass + + +class Qwen3VLImagesKwargs(ImagesKwargs): + min_pixels: Optional[int] + max_pixels: Optional[int] + patch_size: Optional[int] + temporal_patch_size: Optional[int] + merge_size: Optional[int] + + +class Qwen3VLProcessorKwargs(ProcessingKwargs, total=False): + images_kwargs: Qwen3VLImagesKwargs + videos_kwargs: Qwen3VLVideosProcessorKwargs + _defaults = { + "text_kwargs": { + "padding": False, + "return_token_type_ids": False, + "return_mm_token_type_ids": False, + }, + "videos_kwargs": {"return_metadata": True}, + } + + +class Qwen3VLProcessor(ProcessorMixin): + r""" + Constructs a Qwen3VL processor which wraps a Qwen3VL image processor and a Qwen2 tokenizer into a single processor. + [`Qwen3VLProcessor`] offers all the functionalities of [`Qwen2VLImageProcessor`] and [`Qwen2TokenizerFast`]. See the + [`~Qwen3VLProcessor.__call__`] and [`~Qwen3VLProcessor.decode`] for more information. + Args: + image_processor ([`Qwen2VLImageProcessor`], *optional*): + The image processor is a required input. + tokenizer ([`Qwen2TokenizerFast`], *optional*): + The tokenizer is a required input. + video_processor ([`Qwen3VLVideoProcessor`], *optional*): + The video processor is a required input. + chat_template (`str`, *optional*): A Jinja template which will be used to convert lists of messages + in a chat into a tokenizable string. + """ + + attributes = ["image_processor", "tokenizer", "video_processor"] + image_processor_class = "AutoImageProcessor" + video_processor_class = "AutoVideoProcessor" + tokenizer_class = ("Qwen2Tokenizer", "Qwen2TokenizerFast") + + def __init__(self, image_processor=None, tokenizer=None, video_processor=None, chat_template=None, **kwargs): + super().__init__(image_processor, tokenizer, video_processor, chat_template=chat_template) + self.image_token = "<|image_pad|>" if not hasattr(tokenizer, "image_token") else tokenizer.image_token + self.video_token = "<|video_pad|>" if not hasattr(tokenizer, "video_token") else tokenizer.video_token + self.image_token_id = ( + tokenizer.image_token_id + if getattr(tokenizer, "image_token_id", None) + else tokenizer.convert_tokens_to_ids(self.image_token) + ) + self.video_token_id = ( + tokenizer.video_token_id + if getattr(tokenizer, "video_token_id", None) + else tokenizer.convert_tokens_to_ids(self.video_token) + ) + self.vision_start_token = ( + "<|vision_start|>" if not hasattr(tokenizer, "vision_start_token") else tokenizer.vision_start_token + ) + self.vision_end_token = ( + "<|vision_end|>" if not hasattr(tokenizer, "vision_end_token") else tokenizer.vision_end_token + ) + self.vision_start_token_id = ( + tokenizer.vision_start_token_id + if getattr(tokenizer, "vision_start_token_id", None) + else tokenizer.convert_tokens_to_ids(self.vision_start_token) + ) + self.vision_end_token_id = ( + tokenizer.vision_end_token_id + if getattr(tokenizer, "vision_end_token_id", None) + else tokenizer.convert_tokens_to_ids(self.vision_end_token) + ) + + def __call__( + self, + images: ImageInput = None, + text: Union[TextInput, PreTokenizedInput, list[TextInput], list[PreTokenizedInput]] = None, + videos: VideoInput = None, + **kwargs: Unpack[Qwen3VLProcessorKwargs], + ) -> BatchFeature: + """ + Main method to prepare for the model one or several sequences(s) and image(s). This method forwards the `text` + and `kwargs` arguments to Qwen2TokenizerFast's [`~Qwen2TokenizerFast.__call__`] if `text` is not `None` to encode + the text. To prepare the vision inputs, this method forwards the `vision_infos` and `kwrags` arguments to + Qwen2VLImageProcessor's [`~Qwen2VLImageProcessor.__call__`] if `vision_infos` is not `None`. + + Args: + images (`PIL.Image.Image`, `np.ndarray`, `torch.Tensor`, `list[PIL.Image.Image]`, `list[np.ndarray]`, `list[torch.Tensor]`): + The image or batch of images to be prepared. Each image can be a PIL image, NumPy array or PyTorch + tensor. Both channels-first and channels-last formats are supported. + text (`str`, `list[str]`, `list[list[str]]`): + The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings + (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set + `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + videos (`np.ndarray`, `torch.Tensor`, `list[np.ndarray]`, `list[torch.Tensor]`): + The image or batch of videos to be prepared. Each video can be a 4D NumPy array or PyTorch + tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors of a particular framework. Acceptable values are: + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return NumPy `np.ndarray` objects. + - `'jax'`: Return JAX `jnp.ndarray` objects. + + Returns: + [`BatchFeature`]: A [`BatchFeature`] with the following fields: + + - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`. + - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when + `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not + `None`). + - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`. + - **pixel_values_videos** -- Pixel values of videos to be fed to a model. Returned when `videos` is not `None`. + - **image_grid_thw** -- List of image 3D grid in LLM. Returned when `images` is not `None`. + - **video_grid_thw** -- List of video 3D grid in LLM. Returned when `videos` is not `None`. + """ + output_kwargs = self._merge_kwargs( + Qwen3VLProcessorKwargs, + tokenizer_init_kwargs=self.tokenizer.init_kwargs, + **kwargs, + ) + if images is not None: + image_inputs = self.image_processor(images=images, **output_kwargs["images_kwargs"]) + image_grid_thw = image_inputs["image_grid_thw"] + else: + image_inputs = {} + image_grid_thw = None + + if videos is not None: + videos_inputs = self.video_processor(videos=videos, **output_kwargs["videos_kwargs"]) + video_grid_thw = videos_inputs["video_grid_thw"] + # If user has not requested video metadata, pop it + if "return_metadata" not in kwargs: + video_metadata = videos_inputs.pop("video_metadata") + else: + video_metadata = videos_inputs["video_metadata"] + video_grid_thw = videos_inputs["video_grid_thw"] + else: + videos_inputs = {} + video_grid_thw = None + + if not isinstance(text, list): + text = [text] + + text = text.copy() # below lines change text in-place + if image_grid_thw is not None: + merge_length = self.image_processor.merge_size**2 + index = 0 + for i in range(len(text)): + while self.image_token in text[i]: + num_image_tokens = image_grid_thw[index].prod() // merge_length + text[i] = text[i].replace(self.image_token, "<|placeholder|>" * num_image_tokens, 1) + index += 1 + text[i] = text[i].replace("<|placeholder|>", self.image_token) + + if video_grid_thw is not None: + merge_length = self.video_processor.merge_size**2 + index = 0 + for i in range(len(text)): + while self.video_token in text[i]: + metadata = video_metadata[i] + if metadata.fps is None: + logger.warning_once( + "Qwen3VL requires frame timestamps to construct prompts, but the `fps` of the input video could not be inferred. " + "Probably `video_metadata` was missing from inputs and you passed pre-sampled frames. " + "Defaulting to `fps=24`. Please provide `video_metadata` for more accurate results." + ) + metadata.fps = 24 if metadata.fps is None else metadata.fps + + # if timestamps are not provided, calculate them + curr_timestamp = self._calculate_timestamps( + metadata.frames_indices, + metadata.fps, + self.video_processor.merge_size, + ) + + video_placeholder = "" + frame_seqlen = video_grid_thw[index][1:].prod() // merge_length + for frame_idx in range(video_grid_thw[index][0]): + curr_time = curr_timestamp[frame_idx] + video_placeholder += f"<{curr_time:.1f} seconds>" + video_placeholder += ( + self.vision_start_token + "<|placeholder|>" * frame_seqlen + self.vision_end_token + ) + if f"{self.vision_start_token}{self.video_token}{self.vision_end_token}" in text[i]: + text[i] = text[i].replace( + f"{self.vision_start_token}{self.video_token}{self.vision_end_token}", video_placeholder, 1 + ) + else: + # vllm may input video token directly + text[i] = text[i].replace(self.video_token, video_placeholder, 1) + index += 1 + + text[i] = text[i].replace("<|placeholder|>", self.video_token) + + return_tensors = output_kwargs["text_kwargs"].pop("return_tensors", None) + return_mm_token_type_ids = output_kwargs["text_kwargs"].pop("return_mm_token_type_ids", None) + text_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"]) + self._check_special_mm_tokens(text, text_inputs, modalities=["image", "video"]) + + if return_mm_token_type_ids: + array_ids = np.array(text_inputs["input_ids"]) + mm_token_type_ids = np.zeros_like(text_inputs["input_ids"]) + mm_token_type_ids[array_ids == self.image_token_id] = 1 + text_inputs["mm_token_type_ids"] = mm_token_type_ids.tolist() + + return BatchFeature(data={**text_inputs, **image_inputs, **videos_inputs}, tensor_type=return_tensors) + + def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): + """ + Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. + Args: + image_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (height, width) per each image. + video_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (num_frames, height, width) per each video. + Returns: + `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided + input modalities, along with other useful data. + """ + + vision_data = {} + if image_sizes is not None: + images_kwargs = Qwen3VLProcessorKwargs._defaults.get("images_kwargs", {}) + images_kwargs.update(kwargs) + merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size + + num_image_patches = [ + self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) + for image_size in image_sizes + ] + num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] + vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) + + if video_sizes is not None: + videos_kwargs = Qwen3VLProcessorKwargs._defaults.get("videos_kwargs", {}) + videos_kwargs.update(kwargs) + num_video_patches = [ + self.video_processor.get_number_of_video_patches(*video_size, videos_kwargs) + for video_size in video_sizes + ] + num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] + vision_data["num_video_tokens"] = num_video_tokens + + return MultiModalData(**vision_data) + + def post_process_image_text_to_text( + self, generated_outputs, skip_special_tokens=True, clean_up_tokenization_spaces=False, **kwargs + ): + """ + Post-process the output of the model to decode the text. + + Args: + generated_outputs (`torch.Tensor` or `np.ndarray`): + The output of the model `generate` function. The output is expected to be a tensor of shape `(batch_size, sequence_length)` + or `(sequence_length,)`. + skip_special_tokens (`bool`, *optional*, defaults to `True`): + Whether or not to remove special tokens in the output. Argument passed to the tokenizer's `batch_decode` method. + clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`): + Whether or not to clean up the tokenization spaces. Argument passed to the tokenizer's `batch_decode` method. + **kwargs: + Additional arguments to be passed to the tokenizer's `batch_decode method`. + + Returns: + `list[str]`: The decoded text. + """ + return self.tokenizer.batch_decode( + generated_outputs, + skip_special_tokens=skip_special_tokens, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + **kwargs, + ) + + def _calculate_timestamps(self, indices: Union[list[int], np.ndarray], video_fps: float, merge_size: int = 2): + if not isinstance(indices, list): + indices = indices.tolist() + if len(indices) % merge_size != 0: + indices.extend(indices[-1] for _ in range(merge_size - len(indices) % merge_size)) + timestamps = [idx / video_fps for idx in indices] + # @JJJYmmm frames are merged by self.merge_size, \ + # so we need to average the timestamps between the first/last frame within the temporal patch + timestamps = [ + (timestamps[i] + timestamps[i + merge_size - 1]) / 2 for i in range(0, len(timestamps), merge_size) + ] + return timestamps + + +__all__ = ["Qwen3VLProcessor"] diff --git a/src/transformers/models/qwen3_vl/video_processing_qwen3_vl.py b/src/transformers/models/qwen3_vl/video_processing_qwen3_vl.py new file mode 100644 index 000000000000..c4648788c9dc --- /dev/null +++ b/src/transformers/models/qwen3_vl/video_processing_qwen3_vl.py @@ -0,0 +1,276 @@ +# coding=utf-8 +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. +"""video processor class for Qwen3-VL.""" + +import math +from typing import Optional, Union + +import numpy as np +import torch + +from ...feature_extraction_utils import BatchFeature +from ...image_utils import ChannelDimension, PILImageResampling, SizeDict, get_image_size +from ...processing_utils import Unpack, VideosKwargs +from ...utils import TensorType, add_start_docstrings, logging +from ...video_processing_utils import BASE_VIDEO_PROCESSOR_DOCSTRING, BaseVideoProcessor +from ...video_utils import VideoMetadata, group_videos_by_shape, reorder_videos + + +logger = logging.get_logger(__name__) + + +def smart_resize( + num_frames: int, + height: int, + width: int, + temporal_factor: int = 2, + factor: int = 32, + min_pixels: int = 128 * 128, + max_pixels: int = 16 * 16 * 2 * 2 * 2 * 6144, +): + if num_frames < temporal_factor: + raise ValueError(f"t:{num_frames} must be larger than temporal_factor:{temporal_factor}") + if height < factor or width < factor: + raise ValueError(f"height:{height} or width:{width} must be larger than factor:{factor}") + elif max(height, width) / min(height, width) > 200: + raise ValueError( + f"absolute aspect ratio must be smaller than 200, got {max(height, width) / min(height, width)}" + ) + h_bar = round(height / factor) * factor + w_bar = round(width / factor) * factor + t_bar = round(num_frames / temporal_factor) * temporal_factor + + if t_bar * h_bar * w_bar > max_pixels: + beta = math.sqrt((num_frames * height * width) / max_pixels) + h_bar = max(factor, math.floor(height / beta / factor) * factor) + w_bar = max(factor, math.floor(width / beta / factor) * factor) + elif t_bar * h_bar * w_bar < min_pixels: + beta = math.sqrt(min_pixels / (num_frames * height * width)) + h_bar = math.ceil(height * beta / factor) * factor + w_bar = math.ceil(width * beta / factor) * factor + + return h_bar, w_bar + + +class Qwen3VLVideoProcessorInitKwargs(VideosKwargs): + patch_size: Optional[int] + temporal_patch_size: Optional[int] + merge_size: Optional[int] + min_frames: Optional[int] + max_frames: Optional[int] + + +@add_start_docstrings( + "Constructs a fast Qwen3-VL image processor that dynamically resizes videos based on the original videos.", + BASE_VIDEO_PROCESSOR_DOCSTRING, + """ + patch_size (`int`, *optional*, defaults to 16): + The spacial patch size of the vision encoder. + temporal_patch_size (`int`, *optional*, defaults to 2): + The temporal patch size of the vision encoder. + merge_size (`int`, *optional*, defaults to 2): + The merge size of the vision encoder to llm encoder. + """, +) +class Qwen3VLVideoProcessor(BaseVideoProcessor): + resample = PILImageResampling.BICUBIC + size = {"shortest_edge": 128 * 32 * 32, "longest_edge": 32 * 32 * 768} + image_mean = [0.5, 0.5, 0.5] + image_std = [0.5, 0.5, 0.5] + do_resize = True + do_rescale = True + do_normalize = True + do_convert_rgb = True + patch_size = 16 + temporal_patch_size = 2 + merge_size = 2 + fps = 2 + min_frames = 4 + max_frames = 768 + do_sample_frames = True + valid_kwargs = Qwen3VLVideoProcessorInitKwargs + model_input_names = ["pixel_values_videos", "video_grid_thw"] + + def __init__(self, **kwargs: Unpack[Qwen3VLVideoProcessorInitKwargs]): + super().__init__(**kwargs) + if self.size is not None and ( + self.size.get("shortest_edge", None) is None or self.size.get("longest_edge", None) is None + ): + raise ValueError("size must contain 'shortest_edge' and 'longest_edge' keys.") + + def _further_process_kwargs( + self, + size: Optional[SizeDict] = None, + **kwargs, + ) -> dict: + """ + Update kwargs that need further processing before being validated + Can be overridden by subclasses to customize the processing of kwargs. + """ + if size is not None and ("shortest_edge" not in size or "longest_edge" not in size): + raise ValueError("size must contain 'shortest_edge' and 'longest_edge' keys.") + + return super()._further_process_kwargs(size=size, **kwargs) + + def sample_frames( + self, + metadata: VideoMetadata, + num_frames: Optional[int] = None, + fps: Optional[Union[int, float]] = None, + **kwargs, + ): + """ + Default sampling function which uniformly samples the desired number of frames between 0 and total number of frames. + If `fps` is passed along with metadata, `fps` frames per second are sampled uniformty. Arguments `num_frames` + and `fps` are mutually exclusive. + + Args: + video (`torch.Tensor`): + Video that need to be sampled. + metadata (`VideoMetadata`): + Metadata of the video containing information about total duration, fps and total number of frames. + num_frames (`int`, *optional*): + Maximum number of frames to sample. Defaults to `self.num_frames`. + fps (`int` or `float`, *optional*): + Target frames to sample per second. Defaults to `self.fps`. + Returns: + torch.Tensor: + Sampled video frames. + """ + if fps is not None and num_frames is not None: + raise ValueError("`num_frames` and `fps` are mutually exclusive arguments, please use only one!") + + total_num_frames = metadata.total_num_frames + fps = fps if fps is not None else self.fps + + # If num_frames is not given but fps is, calculate num_frames from fps + if num_frames is None and fps is not None: + if metadata.fps is None: + metadata.fps = 24 + logger.warning_once( + "Asked to sample `fps` frames per second but no video metadata was provided which is required when sampling with `fps`. " + "Defaulting to `fps=24`. Please provide `video_metadata` for more accurate results." + ) + num_frames = int(total_num_frames / metadata.fps * fps) + num_frames = min(min(max(num_frames, self.min_frames), self.max_frames), total_num_frames) + + if num_frames is None: + num_frames = min(max(total_num_frames, self.min_frames), self.max_frames) + + indices = np.linspace(0, total_num_frames - 1, num_frames).round().astype(int) + + return indices + + def _preprocess( + self, + videos: list[torch.Tensor], + do_convert_rgb: bool = True, + do_resize: bool = True, + size: Optional[SizeDict] = None, + interpolation: PILImageResampling = PILImageResampling.BICUBIC, + do_rescale: bool = True, + rescale_factor: float = 1 / 255.0, + do_normalize: bool = True, + image_mean: Optional[Union[float, list[float]]] = None, + image_std: Optional[Union[float, list[float]]] = None, + patch_size: Optional[int] = None, + temporal_patch_size: Optional[int] = None, + merge_size: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + **kwargs, + ): + grouped_videos, grouped_videos_index = group_videos_by_shape(videos) + resized_videos_grouped = {} + + for shape, stacked_videos in grouped_videos.items(): + B, T, C, H, W = stacked_videos.shape + num_frames, height, width = T, H, W + if do_resize: + resized_height, resized_width = smart_resize( + num_frames=num_frames, + height=height, + width=width, + temporal_factor=temporal_patch_size, + factor=patch_size * merge_size, + min_pixels=size.shortest_edge, + max_pixels=size.longest_edge, + ) + stacked_videos = stacked_videos.view(B * T, C, H, W) + stacked_videos = self.resize( + stacked_videos, + size=SizeDict(height=resized_height, width=resized_width), + interpolation=interpolation, + ) + stacked_videos = stacked_videos.view(B, T, C, resized_height, resized_width) + resized_videos_grouped[shape] = stacked_videos + resized_videos = reorder_videos(resized_videos_grouped, grouped_videos_index) + + # Group videos by size for further processing + # Needed in case do_resize is False, or resize returns videos with different sizes + grouped_videos, grouped_videos_index = group_videos_by_shape(resized_videos) + processed_videos_grouped = {} + processed_grids = {} + for shape, stacked_videos in grouped_videos.items(): + resized_height, resized_width = get_image_size(stacked_videos[0], channel_dim=ChannelDimension.FIRST) + + # Fused rescale and normalize + stacked_videos = self.rescale_and_normalize( + stacked_videos, do_rescale, rescale_factor, do_normalize, image_mean, image_std + ) + patches = stacked_videos + + # Check that videos have `num_frames` divisible by `temporal_patch_size` + if patches.shape[1] % temporal_patch_size != 0: + repeats = patches[:, -1:].repeat(1, temporal_patch_size - 1, 1, 1, 1) + patches = torch.cat([patches, repeats], dim=1) + batch_size, grid_t, channel = patches.shape[:3] + grid_t = grid_t // temporal_patch_size + grid_h, grid_w = resized_height // patch_size, resized_width // patch_size + + patches = patches.view( + batch_size, + grid_t, + temporal_patch_size, + channel, + grid_h // merge_size, + merge_size, + patch_size, + grid_w // merge_size, + merge_size, + patch_size, + ) + patches = patches.permute(0, 1, 4, 7, 5, 8, 3, 2, 6, 9) + flatten_patches = patches.reshape( + batch_size, + grid_t * grid_h * grid_w, + channel * temporal_patch_size * patch_size * patch_size, + ) + + processed_videos_grouped[shape] = flatten_patches + processed_grids[shape] = [[grid_t, grid_h, grid_w]] * batch_size + + processed_videos = reorder_videos(processed_videos_grouped, grouped_videos_index) + processed_grids = reorder_videos(processed_grids, grouped_videos_index) + pixel_values_videos = torch.cat(processed_videos, dim=0) + video_grid_thw = torch.tensor(processed_grids) + data = { + "pixel_values_videos": pixel_values_videos, + "video_grid_thw": video_grid_thw, + } + + return BatchFeature(data=data, tensor_type=return_tensors) + + +__all__ = ["Qwen3VLVideoProcessor"] diff --git a/src/transformers/models/qwen3_vl_moe/__init__.py b/src/transformers/models/qwen3_vl_moe/__init__.py new file mode 100644 index 000000000000..a4000cb27272 --- /dev/null +++ b/src/transformers/models/qwen3_vl_moe/__init__.py @@ -0,0 +1,27 @@ +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. +from typing import TYPE_CHECKING + +from ...utils import _LazyModule +from ...utils.import_utils import define_import_structure + + +if TYPE_CHECKING: + from .configuration_qwen3_vl_moe import * + from .modeling_qwen3_vl_moe import * +else: + import sys + + _file = globals()["__file__"] + sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__) diff --git a/src/transformers/models/qwen3_vl_moe/configuration_qwen3_vl_moe.py b/src/transformers/models/qwen3_vl_moe/configuration_qwen3_vl_moe.py new file mode 100644 index 000000000000..c4a31e8f9f92 --- /dev/null +++ b/src/transformers/models/qwen3_vl_moe/configuration_qwen3_vl_moe.py @@ -0,0 +1,331 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_qwen3_vl_moe.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. +from ...configuration_utils import PretrainedConfig +from ...modeling_rope_utils import rope_config_validation + + +class Qwen3VLMoeTextConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3VLMoeTextModel`]. It is used to instantiate a + Qwen3-VL-MOE model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of + Qwen3-VL-30B-A3B-Instruct [Qwen/Qwen3-VL-30B-A3B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-30B-A3B-Instruct). + + 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 151936): + Vocabulary size of the Qwen2MoE model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`Qwen2MoeModel`] + hidden_size (`int`, *optional*, defaults to 2048): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 5632): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 24): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer encoder. + num_key_value_heads (`int`, *optional*, defaults to 16): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details checkout [this + paper](https://arxiv.org/pdf/2305.13245.pdf). If it is not specified, will default to `32`. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 128000): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether the model's input and output word embeddings should be tied. + rope_theta (`float`, *optional*, defaults to 5000000.0): + The base period of the RoPE embeddings. + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + decoder_sparse_step (`int`, *optional*, defaults to 1): + The frequency of the MoE layer. + moe_intermediate_size (`int`, *optional*, defaults to 1408): + Intermediate size of the routed expert. + num_experts_per_tok (`int`, *optional*, defaults to 4): + Number of selected experts. + num_experts (`int`, *optional*, defaults to 60): + Number of routed experts. + norm_topk_prob (`bool`, *optional*, defaults to `True`): + Whether to normalize the topk probabilities. + mlp_only_layers (`List[int]`, *optional*, defaults to `[]`): + Indicate which layers use Qwen3VLMoeMLP rather than Qwen3VLMoeSparseMoeBlock + The list contains layer index, from 0 to num_layers-1 if we have num_layers layers + If `mlp_only_layers` is empty, `decoder_sparse_step` is used to determine the sparsity. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type + and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value + accordingly. + Expected contents: + `rope_type` (`str`): + The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope', + 'llama3'], with 'default' being the original RoPE implementation. + `factor` (`float`, *optional*): + Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In + most scaling types, a `factor` of x will enable the model to handle sequences of length x * + original maximum pre-trained length. + `original_max_position_embeddings` (`int`, *optional*): + Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during + pretraining. + `attention_factor` (`float`, *optional*): + Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention + computation. If unspecified, it defaults to value recommended by the implementation, using the + `factor` field to infer the suggested value. + `beta_fast` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear + ramp function. If unspecified, it defaults to 32. + `beta_slow` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear + ramp function. If unspecified, it defaults to 1. + `short_factor` (`List[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to short contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `long_factor` (`List[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to long contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `low_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE + `high_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE + head_dim (`int`, *optional*): + The dimension of the head. If not specified, will default to `hidden_size // num_attention_heads`. + + ```python + >>> from transformers import Qwen3VLMoeForConditionalGeneration, Qwen3VLMoeConfig + + >>> # Initializing a Qwen3VLMoe style configuration + >>> configuration = Qwen3VLMoeConfig() + + >>> # Initializing a model from the Qwen3-VL-30B-A3B style configuration + >>> model = Qwen3VLMoeForConditionalGeneration(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_vl_moe_text" + base_config_key = "text_config" + keys_to_ignore_at_inference = ["past_key_values"] + # Default tensor parallel plan for base model `Qwen3VLMoe` + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise", + "layers.*.self_attn.k_proj": "colwise", + "layers.*.self_attn.v_proj": "colwise", + "layers.*.self_attn.o_proj": "rowwise", + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=151936, + hidden_size=2048, + intermediate_size=5632, + num_hidden_layers=24, + num_attention_heads=16, + num_key_value_heads=16, + hidden_act="silu", + max_position_embeddings=128000, + initializer_range=0.02, + rms_norm_eps=1e-6, + use_cache=True, + tie_word_embeddings=False, + rope_theta=5000000.0, + attention_bias=False, + attention_dropout=0.0, + decoder_sparse_step=1, + moe_intermediate_size=1408, + num_experts_per_tok=4, + num_experts=60, + norm_topk_prob=True, + mlp_only_layers=None, + rope_scaling=None, + head_dim=None, + **kwargs, + ): + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + + # for backward compatibility + if num_key_value_heads is None: + num_key_value_heads = num_attention_heads + + self.num_key_value_heads = num_key_value_heads + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.rope_theta = rope_theta + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + self.rope_scaling = rope_scaling + self.head_dim = head_dim or hidden_size // num_attention_heads + + rope_config_validation(self, ignore_keys={"mrope_section", "mrope_interleaved"}) + + # MoE arguments + self.decoder_sparse_step = decoder_sparse_step + self.moe_intermediate_size = moe_intermediate_size + self.num_experts_per_tok = num_experts_per_tok + self.num_experts = num_experts + self.norm_topk_prob = norm_topk_prob + self.mlp_only_layers = [] if mlp_only_layers is None else mlp_only_layers + + super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs) + + +class Qwen3VLMoeVisionConfig(PretrainedConfig): + model_type = "qwen3_vl_moe" + base_config_key = "vision_config" + + def __init__( + self, + depth=27, + hidden_size=1152, + hidden_act="gelu_pytorch_tanh", + intermediate_size=4304, + num_heads=16, + in_channels=3, + patch_size=16, + spatial_merge_size=2, + temporal_patch_size=2, + out_hidden_size=3584, + num_position_embeddings=2304, + deepstack_visual_indexes=[8, 16, 24], + initializer_range=0.02, + **kwargs, + ): + super().__init__(**kwargs) + + self.depth = depth + self.hidden_size = hidden_size + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.num_heads = num_heads + self.in_channels = in_channels + self.patch_size = patch_size + self.spatial_merge_size = spatial_merge_size + self.temporal_patch_size = temporal_patch_size + self.out_hidden_size = out_hidden_size + self.num_position_embeddings = num_position_embeddings + self.initializer_range = initializer_range + self.deepstack_visual_indexes = deepstack_visual_indexes + + +class Qwen3VLMoeConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3VLMoeModel`]. It is used to instantiate a + Qwen3-VL-MOE model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of + Qwen3-VL-30B-A3B-Instruct [Qwen/Qwen3-VL-30B-A3B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-30B-A3B-Instruct). + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + text_config (`Union[PreTrainedConfig, dict]`, *optional*, defaults to `Qwen3VLMoeTextConfig`): + The config object or dictionary of the text backbone. + vision_config (`Union[PreTrainedConfig, dict]`, *optional*, defaults to `Qwen3VLMoeVisionConfig`): + The config object or dictionary of the vision backbone. + image_token_id (`int`, *optional*, defaults to 151655): + The image token index to encode the image prompt. + video_token_id (`int`, *optional*, defaults to 151656): + The video token index to encode the image prompt. + vision_start_token_id (`int`, *optional*, defaults to 151652): + The start token index to encode the image prompt. + vision_end_token_id (`int`, *optional*, defaults to 151653): + The end token index to encode the image prompt. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether to tie the word embeddings. + + ```python + >>> from transformers import Qwen3VLMoeForConditionalGeneration, Qwen3VLMoeConfig + + >>> # Initializing a Qwen3-VL-MOE style configuration + >>> configuration = Qwen3VLMoeConfig() + + >>> # Initializing a model from the Qwen3-VL-30B-A3B style configuration + >>> model = Qwen3VLMoeForConditionalGeneration(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_vl_moe" + sub_configs = {"vision_config": Qwen3VLMoeVisionConfig, "text_config": Qwen3VLMoeTextConfig} + keys_to_ignore_at_inference = ["past_key_values"] + + def __init__( + self, + text_config=None, + vision_config=None, + image_token_id=151655, + video_token_id=151656, + vision_start_token_id=151652, + vision_end_token_id=151653, + tie_word_embeddings=False, + **kwargs, + ): + if isinstance(vision_config, dict): + self.vision_config = self.sub_configs["vision_config"](**vision_config) + elif vision_config is None: + self.vision_config = self.sub_configs["vision_config"]() + + if isinstance(text_config, dict): + self.text_config = self.sub_configs["text_config"](**text_config) + elif text_config is None: + self.text_config = self.sub_configs["text_config"]() + + self.image_token_id = image_token_id + self.video_token_id = video_token_id + self.vision_start_token_id = vision_start_token_id + self.vision_end_token_id = vision_end_token_id + super().__init__(**kwargs, tie_word_embeddings=tie_word_embeddings) + + +__all__ = ["Qwen3VLMoeConfig", "Qwen3VLMoeTextConfig"] diff --git a/src/transformers/models/qwen3_vl_moe/modeling_qwen3_vl_moe.py b/src/transformers/models/qwen3_vl_moe/modeling_qwen3_vl_moe.py new file mode 100644 index 000000000000..74b793f096f3 --- /dev/null +++ b/src/transformers/models/qwen3_vl_moe/modeling_qwen3_vl_moe.py @@ -0,0 +1,1711 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_qwen3_vl_moe.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. + +from dataclasses import dataclass +from typing import Any, Callable, Optional, Union + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from ...activations import ACT2FN +from ...cache_utils import Cache, DynamicCache +from ...generation import GenerationMixin +from ...integrations import use_kernel_forward_from_hub +from ...masking_utils import create_causal_mask +from ...modeling_flash_attention_utils import FlashAttentionKwargs +from ...modeling_layers import GradientCheckpointingLayer +from ...modeling_outputs import BaseModelOutputWithPast, ModelOutput +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, is_torchdynamo_compiling +from ...utils.deprecation import deprecate_kwarg +from ...utils.generic import OutputRecorder, check_model_inputs +from .configuration_qwen3_vl_moe import Qwen3VLMoeConfig, Qwen3VLMoeTextConfig, Qwen3VLMoeVisionConfig + + +@use_kernel_forward_from_hub("RMSNorm") +class Qwen3VLMoeTextRMSNorm(nn.Module): + def __init__(self, hidden_size, eps=1e-6): + """ + Qwen3VLMoeTextRMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states): + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return self.weight * hidden_states.to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +class Qwen3VLMoeTextRouter(nn.Linear): + def __init__(self, config): + super().__init__(config.hidden_size, config.num_experts, bias=False) + self.hidden_size = config.hidden_size + self.top_k = config.num_experts_per_tok + # since all the models use norm_topk_prob, we don't need to have a extra check for it + # self.norm_topk_prob = config.norm_topk_prob + + def forward(self, hidden_states): + hidden_states = hidden_states.reshape(-1, self.hidden_size) + router_logits = super().forward(hidden_states) + routing_weights = torch.nn.functional.softmax(router_logits, dim=-1, dtype=torch.float) + routing_weights, router_indices = torch.topk(routing_weights, self.top_k, dim=-1) + routing_weights = routing_weights / routing_weights.sum(dim=-1, keepdim=True) + routing_weights = routing_weights.to(hidden_states.dtype) + router_weights = torch.zeros_like(router_logits).scatter_(1, router_indices, routing_weights) + return router_weights, router_logits, router_indices + + +class Qwen3VLMoeTextExperts(nn.Module): + def __init__(self, config): + super().__init__() + self.num_experts = config.num_experts + self.intermediate_size = config.moe_intermediate_size + self.hidden_size = config.hidden_size + self.expert_dim = self.intermediate_size + self.gate_up_proj = nn.Parameter(torch.empty(self.num_experts, self.hidden_size, 2 * self.expert_dim)) + self.down_proj = nn.Parameter(torch.empty((self.num_experts, self.expert_dim, self.hidden_size))) + self.act_fn = ACT2FN[config.hidden_act] + + def forward( + self, hidden_states: torch.Tensor, routing_weights: torch.Tensor, router_indices: torch.Tensor + ) -> torch.Tensor: + """ + When training it is more efficient to just loop over the experts and compute the output for each expert + as otherwise the memory would explode. + + For inference we can sacrifice some memory and compute the output for all experts at once. By repeating the inputs. + + Args: + hidden_states (torch.Tensor): (batch_size * token_num, hidden_size) + routing_weights (torch.Tensor): (batch_size * token_num, num_experts) + router_indices (torch.Tensor): (batch_size * token_num, top_k) + Returns: + torch.Tensor + """ + batch_size = hidden_states.shape[0] + hidden_states = hidden_states.reshape(-1, self.hidden_size) # (num_tokens, hidden_size) + if self.training: + next_states = torch.zeros_like(hidden_states, dtype=hidden_states.dtype, device=hidden_states.device) + with torch.no_grad(): + expert_mask = torch.nn.functional.one_hot(router_indices, num_classes=self.num_experts) + expert_mask = expert_mask.permute(2, 1, 0) + # we sum on the top_k and on the sequence length to get which experts + # are hit this time around + expert_hit = torch.greater(expert_mask.sum(dim=(-1, -2)), 0).nonzero() + for expert_idx in expert_hit[:]: + with torch.no_grad(): + _, token_idx = torch.where(expert_mask[expert_idx[0]]) + current_state = hidden_states[token_idx] + gate_up = current_state @ self.gate_up_proj[expert_idx] + gate, up = gate_up.chunk(2, dim=-1) + gated_output = up * self.act_fn(gate) + out = gated_output @ self.down_proj[expert_idx] + weighted_output = out[0] * routing_weights[token_idx, expert_idx, None] + next_states.index_add_(0, token_idx, weighted_output.to(hidden_states.dtype)) + next_states = next_states.view(batch_size, -1, self.hidden_size) + else: + hidden_states = hidden_states.repeat(self.num_experts, 1) + hidden_states = hidden_states.view(self.num_experts, -1, self.hidden_size) + gate_up = torch.bmm(hidden_states, self.gate_up_proj) + gate, up = gate_up.chunk(2, dim=-1) # not supported for DTensors + next_states = torch.bmm((up * self.act_fn(gate)), self.down_proj) + next_states = next_states.reshape(self.num_experts, batch_size, -1, self.hidden_size) + next_states = ( + next_states * routing_weights.transpose(0, 1).view(self.num_experts, batch_size, -1)[..., None] + ) + next_states = next_states.sum(dim=0) + return next_states + + +class Qwen3VLMoeTextSparseMoeBlock(nn.Module): + def __init__(self, config): + super().__init__() + self.hidden_size = config.hidden_size + self.num_experts = config.num_experts + self.gate = Qwen3VLMoeTextRouter(config) + self.experts = Qwen3VLMoeTextExperts(config) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + router_weights, router_logits, router_indices = self.gate(hidden_states) + routed_out = self.experts(hidden_states, router_weights, router_indices) + return routed_out, router_logits + + +def rotate_half(x): + """Rotates half the hidden dims of the input.""" + x1 = x[..., : x.shape[-1] // 2] + x2 = x[..., x.shape[-1] // 2 :] + return torch.cat((-x2, x1), dim=-1) + + +def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor: + """ + This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, + num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim) + """ + batch, num_key_value_heads, slen, head_dim = hidden_states.shape + if n_rep == 1: + return hidden_states + hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim) + return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim) + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: float, + dropout: float = 0.0, + **kwargs: Unpack[TransformersKwargs], +): + key_states = repeat_kv(key, module.num_key_value_groups) + value_states = repeat_kv(value, module.num_key_value_groups) + + attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling + if attention_mask is not None: + causal_mask = attention_mask[:, :, :, : key_states.shape[-2]] + attn_weights = attn_weights + causal_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + attn_output = torch.matmul(attn_weights, value_states) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + +def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1): + """Applies Rotary Position Embedding to the query and key tensors. + + Args: + q (`torch.Tensor`): The query tensor. + k (`torch.Tensor`): The key tensor. + cos (`torch.Tensor`): The cosine part of the rotary embedding. + sin (`torch.Tensor`): The sine part of the rotary embedding. + position_ids (`torch.Tensor`, *optional*): + Deprecated and unused. + unsqueeze_dim (`int`, *optional*, defaults to 1): + The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and + sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note + that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and + k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes + cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have + the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. + Returns: + `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. + """ + cos = cos.unsqueeze(unsqueeze_dim) + sin = sin.unsqueeze(unsqueeze_dim) + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + return q_embed, k_embed + + +class Qwen3VLMoeTextAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: Qwen3VLMoeTextConfig, layer_idx: int): + super().__init__() + self.config = config + self.layer_idx = layer_idx + self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) + self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads + self.scaling = self.head_dim**-0.5 + self.attention_dropout = config.attention_dropout + self.is_causal = True + + self.q_proj = nn.Linear( + config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias + ) + self.k_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.v_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.o_proj = nn.Linear( + config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias + ) + self.q_norm = Qwen3VLMoeTextRMSNorm( + self.head_dim, eps=config.rms_norm_eps + ) # unlike olmo, only on the head dim! + self.k_norm = Qwen3VLMoeTextRMSNorm( + self.head_dim, eps=config.rms_norm_eps + ) # thus post q_norm does not need reshape + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor]]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class Qwen3VLMoeTextMLP(nn.Module): + def __init__(self, config, intermediate_size=None): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = intermediate_size if intermediate_size is not None else config.intermediate_size + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +class Qwen3VLMoeTextDecoderLayer(GradientCheckpointingLayer): + def __init__(self, config: Qwen3VLMoeTextConfig, layer_idx: int): + super().__init__() + self.hidden_size = config.hidden_size + + self.self_attn = Qwen3VLMoeTextAttention(config, layer_idx) + + if (layer_idx not in config.mlp_only_layers) and ( + config.num_experts > 0 and (layer_idx + 1) % config.decoder_sparse_step == 0 + ): + self.mlp = Qwen3VLMoeTextSparseMoeBlock(config) + else: + self.mlp = Qwen3VLMoeTextMLP(config, intermediate_size=config.intermediate_size) + + self.input_layernorm = Qwen3VLMoeTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = Qwen3VLMoeTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[tuple[torch.Tensor]] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> torch.FloatTensor: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`, *optional*): attention mask of size + `(batch, sequence_length)` where padding elements are indicated by 0. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_router_logits (`bool`, *optional*): + Whether or not to return the logits of all the routers. They are useful for computing the router loss, + and should not be returned during inference. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): + Indices depicting the position of the input sequence tokens in the sequence. + position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): + Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`, + with `head_dim` being the embedding dimension of each attention head. + kwargs (`dict`, *optional*): + Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code + into the model + """ + residual = hidden_states + + hidden_states = self.input_layernorm(hidden_states) + + # Self Attention + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + **kwargs, + ) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + # For the MoE layers, we need to unpack + if isinstance(hidden_states, tuple): + hidden_states, _ = hidden_states + hidden_states = residual + hidden_states + + return hidden_states + + +@auto_docstring +class Qwen3VLMoePreTrainedModel(PreTrainedModel): + config: Qwen3VLMoeConfig + base_model_prefix = "model" + supports_gradient_checkpointing = True + _no_split_modules = ["Qwen3VLMoeTextDecoderLayer", "Qwen3VLMoeVisionBlock"] + _skip_keys_device_placement = ["past_key_values"] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _can_compile_fullgraph = False # MoE models don't work with torch.compile (`torch.where(condition)` not supported) + _supports_attention_backend = True + _can_record_outputs = { + "router_logits": OutputRecorder(Qwen3VLMoeTextSparseMoeBlock, index=1), + "hidden_states": Qwen3VLMoeTextDecoderLayer, + "attentions": Qwen3VLMoeTextAttention, + } + + def _init_weights(self, module): + """Initialize the weights.""" + super()._init_weights(module) + if hasattr(self.config, "initializer_range"): + std = self.config.initializer_range + else: + std = getattr(self.config.get_text_config(), "initializer_range", 0.02) + if isinstance(module, Qwen3VLMoeTextExperts): + module.gate_up_proj.data.normal_(mean=0.0, std=std) + module.down_proj.data.normal_(mean=0.0, std=std) + + +class Qwen3VLMoeVisionMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.linear_fc1 = nn.Linear(self.hidden_size, self.intermediate_size, bias=True) + self.linear_fc2 = nn.Linear(self.intermediate_size, self.hidden_size, bias=True) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, hidden_state): + return self.linear_fc2(self.act_fn(self.linear_fc1(hidden_state))) + + +class Qwen3VLMoeVisionPatchEmbed(nn.Module): + def __init__(self, config) -> None: + super().__init__() + self.patch_size = config.patch_size + self.temporal_patch_size = config.temporal_patch_size + self.in_channels = config.in_channels + self.embed_dim = config.hidden_size + + kernel_size = [self.temporal_patch_size, self.patch_size, self.patch_size] + self.proj = nn.Conv3d(self.in_channels, self.embed_dim, kernel_size=kernel_size, stride=kernel_size, bias=True) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + target_dtype = self.proj.weight.dtype + hidden_states = hidden_states.view( + -1, self.in_channels, self.temporal_patch_size, self.patch_size, self.patch_size + ) + hidden_states = self.proj(hidden_states.to(dtype=target_dtype)).view(-1, self.embed_dim) + return hidden_states + + +class Qwen3VLMoeVisionRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, dim: int, theta: float = 10000.0) -> None: + super().__init__() + inv_freq = 1.0 / (theta ** (torch.arange(0, dim, 2, dtype=torch.float) / dim)) + self.register_buffer("inv_freq", inv_freq, persistent=False) + + def forward(self, seqlen: int) -> torch.Tensor: + seq = torch.arange(seqlen, device=self.inv_freq.device, dtype=self.inv_freq.dtype) + freqs = torch.outer(seq, self.inv_freq) + return freqs + + +class Qwen3VLMoeVisionPatchMerger(nn.Module): + def __init__(self, config: Qwen3VLMoeVisionConfig, use_postshuffle_norm=False) -> None: + super().__init__() + self.hidden_size = config.hidden_size * (config.spatial_merge_size**2) + self.use_postshuffle_norm = use_postshuffle_norm + self.norm = nn.LayerNorm(self.hidden_size if use_postshuffle_norm else config.hidden_size, eps=1e-6) + self.linear_fc1 = nn.Linear(self.hidden_size, self.hidden_size) + self.act_fn = nn.GELU() + self.linear_fc2 = nn.Linear(self.hidden_size, config.out_hidden_size) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + x = self.norm(x.view(-1, self.hidden_size) if self.use_postshuffle_norm else x).view(-1, self.hidden_size) + x = self.linear_fc2(self.act_fn(self.linear_fc1(x))) + return x + + +def apply_rotary_pos_emb_vision( + q: torch.Tensor, k: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor +) -> tuple[torch.Tensor, torch.Tensor]: + orig_q_dtype = q.dtype + orig_k_dtype = k.dtype + q, k = q.float(), k.float() + cos, sin = cos.unsqueeze(-2).float(), sin.unsqueeze(-2).float() + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + q_embed = q_embed.to(orig_q_dtype) + k_embed = k_embed.to(orig_k_dtype) + return q_embed, k_embed + + +class Qwen3VLMoeVisionAttention(nn.Module): + def __init__(self, config: Qwen3VLMoeVisionConfig) -> None: + super().__init__() + self.dim = config.hidden_size + self.num_heads = config.num_heads + self.head_dim = self.dim // self.num_heads + self.num_key_value_groups = 1 # needed for eager attention + self.qkv = nn.Linear(self.dim, self.dim * 3, bias=True) + self.proj = nn.Linear(self.dim, self.dim) + self.scaling = self.head_dim**-0.5 + self.config = config + self.attention_dropout = 0.0 + self.is_causal = False + + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: torch.Tensor, + rotary_pos_emb: Optional[torch.Tensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + **kwargs, + ) -> torch.Tensor: + seq_length = hidden_states.shape[0] + query_states, key_states, value_states = ( + self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0) + ) + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb_vision(query_states, key_states, cos, sin) + + query_states = query_states.transpose(0, 1).unsqueeze(0) + key_states = key_states.transpose(0, 1).unsqueeze(0) + value_states = value_states.transpose(0, 1).unsqueeze(0) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + if self.config._attn_implementation == "flash_attention_2": + # Flash Attention 2: Use cu_seqlens for variable length attention + max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max() + attn_output, _ = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + cu_seq_lens_q=cu_seqlens, + cu_seq_lens_k=cu_seqlens, + max_length_q=max_seqlen, + max_length_k=max_seqlen, + is_causal=False, + **kwargs, + ) + else: + # Other implementations: Process each chunk separately + lengths = cu_seqlens[1:] - cu_seqlens[:-1] + splits = [ + torch.split(tensor, lengths.tolist(), dim=2) for tensor in (query_states, key_states, value_states) + ] + + attn_outputs = [ + attention_interface( + self, + q, + k, + v, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + is_causal=False, + **kwargs, + )[0] + for q, k, v in zip(*splits) + ] + attn_output = torch.cat(attn_outputs, dim=1) + + attn_output = attn_output.reshape(seq_length, -1).contiguous() + attn_output = self.proj(attn_output) + return attn_output + + +class Qwen3VLMoeVisionBlock(GradientCheckpointingLayer): + def __init__(self, config, attn_implementation: str = "sdpa") -> None: + super().__init__() + self.norm1 = nn.LayerNorm(config.hidden_size, eps=1e-6) + self.norm2 = nn.LayerNorm(config.hidden_size, eps=1e-6) + self.attn = Qwen3VLMoeVisionAttention(config=config) + self.mlp = Qwen3VLMoeVisionMLP(config=config) + + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: torch.Tensor, + rotary_pos_emb: Optional[torch.Tensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + **kwargs, + ) -> torch.Tensor: + hidden_states = hidden_states + self.attn( + self.norm1(hidden_states), + cu_seqlens=cu_seqlens, + rotary_pos_emb=rotary_pos_emb, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = hidden_states + self.mlp(self.norm2(hidden_states)) + return hidden_states + + +class Qwen3VLMoeVisionModel(Qwen3VLMoePreTrainedModel): + config: Qwen3VLMoeVisionConfig + _no_split_modules = ["Qwen3VLMoeVisionBlock"] + + def __init__(self, config, *inputs, **kwargs) -> None: + super().__init__(config, *inputs, **kwargs) + self.spatial_merge_size = config.spatial_merge_size + self.patch_size = config.patch_size + self.spatial_merge_unit = self.spatial_merge_size * self.spatial_merge_size + + self.patch_embed = Qwen3VLMoeVisionPatchEmbed( + config=config, + ) + + self.pos_embed = nn.Embedding(config.num_position_embeddings, config.hidden_size) + self.num_grid_per_side = int(config.num_position_embeddings**0.5) + + head_dim = config.hidden_size // config.num_heads + self.rotary_pos_emb = Qwen3VLMoeVisionRotaryEmbedding(head_dim // 2) + + self.blocks = nn.ModuleList([Qwen3VLMoeVisionBlock(config) for _ in range(config.depth)]) + self.merger = Qwen3VLMoeVisionPatchMerger( + config=config, + use_postshuffle_norm=False, + ) + + self.deepstack_visual_indexes = config.deepstack_visual_indexes + self.deepstack_merger_list = nn.ModuleList( + [ + Qwen3VLMoeVisionPatchMerger( + config=config, + use_postshuffle_norm=True, + ) + for _ in range(len(config.deepstack_visual_indexes)) + ] + ) + + self.gradient_checkpointing = False + + def rot_pos_emb(self, grid_thw: torch.Tensor) -> torch.Tensor: + merge_size = self.spatial_merge_size + + max_hw = int(grid_thw[:, 1:].max().item()) + freq_table = self.rotary_pos_emb(max_hw) # (max_hw, dim // 2) + device = freq_table.device + + total_tokens = int(torch.prod(grid_thw, dim=1).sum().item()) + pos_ids = torch.empty((total_tokens, 2), dtype=torch.long, device=device) + + offset = 0 + for num_frames, height, width in grid_thw: + merged_h, merged_w = height // merge_size, width // merge_size + + block_rows = torch.arange(merged_h, device=device) # block row indices + block_cols = torch.arange(merged_w, device=device) # block col indices + intra_row = torch.arange(merge_size, device=device) # intra-block row offsets + intra_col = torch.arange(merge_size, device=device) # intra-block col offsets + + # Compute full-resolution positions + row_idx = block_rows[:, None, None, None] * merge_size + intra_row[None, None, :, None] + col_idx = block_cols[None, :, None, None] * merge_size + intra_col[None, None, None, :] + + row_idx = row_idx.expand(merged_h, merged_w, merge_size, merge_size).reshape(-1) + col_idx = col_idx.expand(merged_h, merged_w, merge_size, merge_size).reshape(-1) + + coords = torch.stack((row_idx, col_idx), dim=-1) + + if num_frames > 1: + coords = coords.repeat(num_frames, 1) + + num_tokens = coords.shape[0] + pos_ids[offset : offset + num_tokens] = coords + offset += num_tokens + + embeddings = freq_table[pos_ids] # lookup rotary embeddings + embeddings = embeddings.flatten(1) + return embeddings + + def fast_pos_embed_interpolate(self, grid_thw): + grid_ts, grid_hs, grid_ws = grid_thw[:, 0], grid_thw[:, 1], grid_thw[:, 2] + + idx_list = [[] for _ in range(4)] + weight_list = [[] for _ in range(4)] + + for t, h, w in zip(grid_ts, grid_hs, grid_ws): + h_idxs = torch.linspace(0, self.num_grid_per_side - 1, h) + w_idxs = torch.linspace(0, self.num_grid_per_side - 1, w) + + h_idxs_floor = h_idxs.int() + w_idxs_floor = w_idxs.int() + h_idxs_ceil = (h_idxs.int() + 1).clip(max=self.num_grid_per_side - 1) + w_idxs_ceil = (w_idxs.int() + 1).clip(max=self.num_grid_per_side - 1) + + dh = h_idxs - h_idxs_floor + dw = w_idxs - w_idxs_floor + + base_h = h_idxs_floor * self.num_grid_per_side + base_h_ceil = h_idxs_ceil * self.num_grid_per_side + + indices = [ + (base_h[None].T + w_idxs_floor[None]).flatten(), + (base_h[None].T + w_idxs_ceil[None]).flatten(), + (base_h_ceil[None].T + w_idxs_floor[None]).flatten(), + (base_h_ceil[None].T + w_idxs_ceil[None]).flatten(), + ] + + weights = [ + ((1 - dh)[None].T * (1 - dw)[None]).flatten(), + ((1 - dh)[None].T * dw[None]).flatten(), + (dh[None].T * (1 - dw)[None]).flatten(), + (dh[None].T * dw[None]).flatten(), + ] + + for i in range(4): + idx_list[i].extend(indices[i].tolist()) + weight_list[i].extend(weights[i].tolist()) + + idx_tensor = torch.tensor(idx_list, dtype=torch.long, device=self.pos_embed.weight.device) + weight_tensor = torch.tensor( + weight_list, dtype=self.pos_embed.weight.dtype, device=self.pos_embed.weight.device + ) + pos_embeds = self.pos_embed(idx_tensor) * weight_tensor[:, :, None] + patch_pos_embeds = pos_embeds[0] + pos_embeds[1] + pos_embeds[2] + pos_embeds[3] + + patch_pos_embeds = patch_pos_embeds.split([h * w for h, w in zip(grid_hs, grid_ws)]) + + patch_pos_embeds_permute = [] + merge_size = self.config.spatial_merge_size + for pos_embed, t, h, w in zip(patch_pos_embeds, grid_ts, grid_hs, grid_ws): + pos_embed = pos_embed.repeat(t, 1) + pos_embed = ( + pos_embed.view(t, h // merge_size, merge_size, w // merge_size, merge_size, -1) + .permute(0, 1, 3, 2, 4, 5) + .flatten(0, 4) + ) + patch_pos_embeds_permute.append(pos_embed) + patch_pos_embeds = torch.cat(patch_pos_embeds_permute) + return patch_pos_embeds + + def forward(self, hidden_states: torch.Tensor, grid_thw: torch.Tensor, **kwargs) -> torch.Tensor: + """ + Args: + hidden_states (`torch.Tensor` of shape `(seq_len, hidden_size)`): + The final hidden states of the model. + grid_thw (`torch.Tensor` of shape `(num_images_or_videos, 3)`): + The temporal, height and width of feature shape of each image in LLM. + + Returns: + `torch.Tensor`: hidden_states. + """ + hidden_states = self.patch_embed(hidden_states) + + pos_embeds = self.fast_pos_embed_interpolate(grid_thw) + hidden_states = hidden_states + pos_embeds + + rotary_pos_emb = self.rot_pos_emb(grid_thw) + + seq_len, _ = hidden_states.size() + hidden_states = hidden_states.reshape(seq_len, -1) + rotary_pos_emb = rotary_pos_emb.reshape(seq_len, -1) + emb = torch.cat((rotary_pos_emb, rotary_pos_emb), dim=-1) + position_embeddings = (emb.cos(), emb.sin()) + + cu_seqlens = torch.repeat_interleave(grid_thw[:, 1] * grid_thw[:, 2], grid_thw[:, 0]).cumsum( + dim=0, + # Select dtype based on the following factors: + # - FA2 requires that cu_seqlens_q must have dtype int32 + # - torch.onnx.export requires that cu_seqlens_q must have same dtype as grid_thw + # See https://github.com/huggingface/transformers/pull/34852 for more information + dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32, + ) + cu_seqlens = F.pad(cu_seqlens, (1, 0), value=0) + + deepstack_feature_lists = [] + for layer_num, blk in enumerate(self.blocks): + hidden_states = blk( + hidden_states, + cu_seqlens=cu_seqlens, + position_embeddings=position_embeddings, + **kwargs, + ) + if layer_num in self.deepstack_visual_indexes: + deepstack_feature = self.deepstack_merger_list[self.deepstack_visual_indexes.index(layer_num)]( + hidden_states + ) + deepstack_feature_lists.append(deepstack_feature) + + hidden_states = self.merger(hidden_states) + + return hidden_states, deepstack_feature_lists + + +class Qwen3VLMoeTextRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: Qwen3VLMoeTextConfig, device=None): + super().__init__() + if hasattr(config, "rope_scaling") and config.rope_scaling is not None: + self.rope_type = config.rope_scaling.get("rope_type", "default") + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + self.mrope_section = config.rope_scaling.get("mrope_section", [24, 20, 20]) + + def apply_interleaved_mrope(self, freqs, mrope_section): + """Apply interleaved MRoPE to 3D rotary embeddings. + Reorganizes frequency layout from chunked [TTT...HHH...WWW] to + interleaved [THTHWHTHW...TT], preserving frequency continuity. + args: + x: (3, bs, seq_len, head_dim // 2) + mrope_section: (3,) + returns: + x_t: (bs, seq_len, head_dim // 2) + """ + freqs_t = freqs[0] # just overwrite the first dimension T + for dim, offset in enumerate((1, 2), start=1): # H, W + length = mrope_section[dim] * 3 + idx = slice(offset, length, 3) + freqs_t[..., idx] = freqs[dim, ..., idx] + return freqs_t + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + # In contrast to other models, Qwen3VLMoe has different position ids for the grids + # So we expand the inv_freq to shape (3, ...) + if position_ids.ndim == 2: + position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1) + inv_freq_expanded = self.inv_freq[None, None, :, None].float().expand(3, position_ids.shape[1], -1, 1) + position_ids_expanded = position_ids[:, :, None, :].float() # shape (3, bs, 1, positions) + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(2, 3) + freqs = self.apply_interleaved_mrope(freqs, self.mrope_section) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + +@auto_docstring( + custom_intro=( + "Text part of Qwen3VLMoe, " + "not a pure text-only model, as DeepStack integrates visual features into the early hidden states." + ) +) +class Qwen3VLMoeTextModel(Qwen3VLMoePreTrainedModel): + config: Qwen3VLMoeTextConfig + _no_split_modules = ["Qwen3VLMoeTextDecoderLayer"] + + def __init__(self, config: Qwen3VLMoeTextConfig): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + + self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx) + self.layers = nn.ModuleList( + [Qwen3VLMoeTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = Qwen3VLMoeTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = Qwen3VLMoeTextRotaryEmbedding(config=config) + self.gradient_checkpointing = False + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + # args for deepstack + visual_pos_masks: Optional[torch.Tensor] = None, + deepstack_visual_embeds: Optional[list[torch.Tensor]] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> Union[tuple, BaseModelOutputWithPast]: + r""" + visual_pos_masks (`torch.Tensor` of shape `(batch_size, seqlen)`, *optional*): + The mask of the visual positions. + deepstack_visual_embeds (`list[torch.Tensor]`, *optional*): + The deepstack visual embeddings. The shape is (num_layers, visual_seqlen, embed_dim). + The feature is extracted from the different visual encoder layers, and fed to the decoder + hidden states. It's from the paper DeepStack(https://arxiv.org/abs/2406.04334). + """ + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + # torch.jit.trace() doesn't support cache objects in the output + if use_cache and past_key_values is None and not torch.jit.is_tracing(): + past_key_values = DynamicCache(config=self.config) + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + # the hard coded `3` is for temporal, height and width. + if position_ids is None: + position_ids = cache_position.view(1, 1, -1).expand(3, inputs_embeds.shape[0], -1) + elif position_ids.ndim == 2: + position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1) + + if position_ids.ndim == 3 and position_ids.shape[0] == 4: + text_position_ids = position_ids[0] + position_ids = position_ids[1:] + else: + text_position_ids = position_ids[0] + + attention_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=text_position_ids, + ) + + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + # decoder layers + for layer_idx, decoder_layer in enumerate(self.layers): + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + position_ids=text_position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = layer_outputs + + # add visual features to the hidden states of first several layers + if deepstack_visual_embeds is not None and layer_idx in range(len(deepstack_visual_embeds)): + hidden_states = self._deepstack_process( + hidden_states, + visual_pos_masks, + deepstack_visual_embeds[layer_idx], + ) + + hidden_states = self.norm(hidden_states) + + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) + + def _deepstack_process( + self, hidden_states: torch.Tensor, visual_pos_masks: torch.Tensor, visual_embeds: torch.Tensor + ): + visual_pos_masks = visual_pos_masks.to(hidden_states.device) + visual_embeds = visual_embeds.to(hidden_states.device, hidden_states.dtype) + local_this = hidden_states[visual_pos_masks, :].clone() + visual_embeds + hidden_states[visual_pos_masks, :] = local_this + return hidden_states + + +@dataclass +@auto_docstring( + custom_intro=""" + Base class for Llava outputs, with hidden states and attentions. + """ +) +class Qwen3VLMoeModelOutputWithPast(ModelOutput): + r""" + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape + `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + + Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see + `past_key_values` input) to speed up sequential decoding. + rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*): + The rope index difference between sequence length and multimodal rope. + """ + + last_hidden_state: Optional[torch.FloatTensor] = None + past_key_values: Optional[list[torch.FloatTensor]] = None + hidden_states: Optional[tuple[torch.FloatTensor]] = None + attentions: Optional[tuple[torch.FloatTensor]] = None + rope_deltas: Optional[torch.LongTensor] = None + + +@auto_docstring +class Qwen3VLMoeModel(Qwen3VLMoePreTrainedModel): + base_model_prefix = "" + _checkpoint_conversion_mapping = {} + # Reference: fix gemma3 grad acc #37208 + accepts_loss_kwargs = False + config: Qwen3VLMoeConfig + _no_split_modules = ["Qwen3VLMoeTextDecoderLayer", "Qwen3VLMoeVisionBlock"] + + def __init__(self, config): + super().__init__(config) + self.visual = Qwen3VLMoeVisionModel._from_config(config.vision_config) + self.language_model = Qwen3VLMoeTextModel._from_config(config.text_config) + self.rope_deltas = None # cache rope_deltas here + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.language_model.get_input_embeddings() + + def set_input_embeddings(self, value): + self.language_model.set_input_embeddings(value) + + def set_decoder(self, decoder): + self.language_model = decoder + + def get_decoder(self): + return self.language_model + + def get_rope_index( + self, + input_ids: Optional[torch.LongTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + """Different from the original implementation, Qwen3VLMoe use timestamps rather than absolute time position ids.""" + + # Since we use timestamps to seperate videos, like , the video_grid_thw should also be split + if video_grid_thw is not None: + video_grid_thw = torch.repeat_interleave(video_grid_thw, video_grid_thw[:, 0], dim=0) + video_grid_thw[:, 0] = 1 + + spatial_merge_size = self.config.vision_config.spatial_merge_size + image_token_id = self.config.image_token_id + video_token_id = self.config.video_token_id + vision_start_token_id = self.config.vision_start_token_id + mrope_position_deltas = [] + if input_ids is not None and (image_grid_thw is not None or video_grid_thw is not None): + total_input_ids = input_ids + if attention_mask is None: + attention_mask = torch.ones_like(total_input_ids) + position_ids = torch.ones( + 3, + input_ids.shape[0], + input_ids.shape[1], + dtype=input_ids.dtype, + device=input_ids.device, + ) + image_index, video_index = 0, 0 + attention_mask = attention_mask.to(total_input_ids.device) + for i, input_ids in enumerate(total_input_ids): + input_ids = input_ids[attention_mask[i] == 1] + image_nums, video_nums = 0, 0 + vision_start_indices = torch.argwhere(input_ids == vision_start_token_id).squeeze(1) + vision_tokens = input_ids[vision_start_indices + 1] + image_nums = (vision_tokens == image_token_id).sum() + video_nums = (vision_tokens == video_token_id).sum() + input_tokens = input_ids.tolist() + llm_pos_ids_list: list = [] + st = 0 + remain_images, remain_videos = image_nums, video_nums + for _ in range(image_nums + video_nums): + if image_token_id in input_tokens and remain_images > 0: + ed_image = input_tokens.index(image_token_id, st) + else: + ed_image = len(input_tokens) + 1 + if video_token_id in input_tokens and remain_videos > 0: + ed_video = input_tokens.index(video_token_id, st) + else: + ed_video = len(input_tokens) + 1 + if ed_image < ed_video: + t, h, w = ( + image_grid_thw[image_index][0], + image_grid_thw[image_index][1], + image_grid_thw[image_index][2], + ) + image_index += 1 + remain_images -= 1 + ed = ed_image + + else: + t, h, w = ( + video_grid_thw[video_index][0], + video_grid_thw[video_index][1], + video_grid_thw[video_index][2], + ) + video_index += 1 + remain_videos -= 1 + ed = ed_video + llm_grid_t, llm_grid_h, llm_grid_w = ( + t.item(), + h.item() // spatial_merge_size, + w.item() // spatial_merge_size, + ) + text_len = ed - st + + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx) + + # t_index is always 0 because llm_grid_t is always 1 (we use timestamps to encode the temporal information for videos) + t_index = torch.arange(llm_grid_t).view(-1, 1).expand(-1, llm_grid_h * llm_grid_w).flatten() + h_index = torch.arange(llm_grid_h).view(1, -1, 1).expand(llm_grid_t, -1, llm_grid_w).flatten() + w_index = torch.arange(llm_grid_w).view(1, 1, -1).expand(llm_grid_t, llm_grid_h, -1).flatten() + llm_pos_ids_list.append(torch.stack([t_index, h_index, w_index]) + text_len + st_idx) + st = ed + llm_grid_t * llm_grid_h * llm_grid_w + + if st < len(input_tokens): + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + text_len = len(input_tokens) - st + llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx) + + llm_positions = torch.cat(llm_pos_ids_list, dim=1).reshape(3, -1) + position_ids[..., i, attention_mask[i] == 1] = llm_positions.to(position_ids.device) + mrope_position_deltas.append(llm_positions.max() + 1 - len(total_input_ids[i])) + mrope_position_deltas = torch.tensor(mrope_position_deltas, device=input_ids.device).unsqueeze(1) + return position_ids, mrope_position_deltas + else: + if attention_mask is not None: + position_ids = attention_mask.long().cumsum(-1) - 1 + position_ids.masked_fill_(attention_mask == 0, 1) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1).to(attention_mask.device) + max_position_ids = position_ids.max(0, keepdim=False)[0].max(-1, keepdim=True)[0] + mrope_position_deltas = max_position_ids + 1 - attention_mask.shape[-1] + else: + position_ids = ( + torch.arange(input_ids.shape[1], device=input_ids.device) + .view(1, 1, -1) + .expand(3, input_ids.shape[0], -1) + ) + mrope_position_deltas = torch.zeros( + [input_ids.shape[0], 1], + device=input_ids.device, + dtype=input_ids.dtype, + ) + + return position_ids, mrope_position_deltas + + def get_video_features( + self, pixel_values_videos: torch.FloatTensor, video_grid_thw: Optional[torch.LongTensor] = None + ): + """ + Encodes videos into continuous embeddings that can be forwarded to the language model. The deepstack visual features are also returned. + + Args: + pixel_values_videos (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`): + The tensors corresponding to the input videos. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + """ + # Same implementation as for images + return self.get_image_features(pixel_values_videos, video_grid_thw) + + def get_image_features(self, pixel_values: torch.FloatTensor, image_grid_thw: Optional[torch.LongTensor] = None): + """ + Encodes images into continuous embeddings that can be forwarded to the language model. The deepstack visual features are also returned. + + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`): + The tensors corresponding to the input images. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + """ + pixel_values = pixel_values.type(self.visual.dtype) + image_embeds, deepstack_image_embeds = self.visual(pixel_values, grid_thw=image_grid_thw) + split_sizes = (image_grid_thw.prod(-1) // self.visual.spatial_merge_size**2).tolist() + image_embeds = torch.split(image_embeds, split_sizes) + return image_embeds, deepstack_image_embeds + + def get_placeholder_mask( + self, + input_ids: torch.LongTensor, + inputs_embeds: torch.FloatTensor, + image_features: Optional[torch.FloatTensor] = None, + video_features: Optional[torch.FloatTensor] = None, + ): + """ + Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is + equal to the length of multimodal features. If the lengths are different, an error is raised. + """ + if input_ids is None: + special_image_mask = inputs_embeds == self.get_input_embeddings()( + torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + special_image_mask = special_image_mask.all(-1) + special_video_mask = inputs_embeds == self.get_input_embeddings()( + torch.tensor(self.config.video_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + special_video_mask = special_video_mask.all(-1) + else: + special_image_mask = input_ids == self.config.image_token_id + special_video_mask = input_ids == self.config.video_token_id + + n_image_tokens = special_image_mask.sum() + special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device) + if image_features is not None and inputs_embeds[special_image_mask].numel() != image_features.numel(): + raise ValueError( + f"Image features and image tokens do not match: tokens: {n_image_tokens}, features {image_features.shape[0]}" + ) + + n_video_tokens = special_video_mask.sum() + special_video_mask = special_video_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device) + if video_features is not None and inputs_embeds[special_video_mask].numel() != video_features.numel(): + raise ValueError( + f"Videos features and video tokens do not match: tokens: {n_video_tokens}, features {video_features.shape[0]}" + ) + + return special_image_mask, special_video_mask + + @auto_docstring + @can_return_tuple + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + pixel_values: Optional[torch.Tensor] = None, + pixel_values_videos: Optional[torch.FloatTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, Qwen3VLMoeModelOutputWithPast]: + r""" + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + """ + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds = self.get_input_embeddings()(input_ids) + + image_mask = None + video_mask = None + + if pixel_values is not None: + image_embeds, deepstack_image_embeds = self.get_image_features(pixel_values, image_grid_thw) + image_embeds = torch.cat(image_embeds, dim=0).to(inputs_embeds.device, inputs_embeds.dtype) + image_mask, _ = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, image_features=image_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds) + + if pixel_values_videos is not None: + video_embeds, deepstack_video_embeds = self.get_video_features(pixel_values_videos, video_grid_thw) + video_embeds = torch.cat(video_embeds, dim=0).to(inputs_embeds.device, inputs_embeds.dtype) + _, video_mask = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, video_features=video_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter(video_mask, video_embeds) + + visual_pos_masks = None + deepstack_visual_embeds = None + if image_mask is not None and video_mask is not None: + # aggregate visual_pos_masks and deepstack_visual_embeds + image_mask = image_mask[..., 0] + video_mask = video_mask[..., 0] + visual_pos_masks = image_mask | video_mask + deepstack_visual_embeds = [] + image_mask_joint = image_mask[visual_pos_masks] + video_mask_joint = video_mask[visual_pos_masks] + for img_embed, vid_embed in zip(deepstack_image_embeds, deepstack_video_embeds): + embed_joint = img_embed.new_zeros(visual_pos_masks.sum(), img_embed.shape[-1]).to(img_embed.device) + embed_joint[image_mask_joint, :] = img_embed + embed_joint[video_mask_joint, :] = vid_embed + deepstack_visual_embeds.append(embed_joint) + elif image_mask is not None: + image_mask = image_mask[..., 0] + visual_pos_masks = image_mask + deepstack_visual_embeds = deepstack_image_embeds + elif video_mask is not None: + video_mask = video_mask[..., 0] + visual_pos_masks = video_mask + deepstack_visual_embeds = deepstack_video_embeds + + if position_ids is None: + attention_mask_tensor = ( + attention_mask if not isinstance(attention_mask, dict) else attention_mask["full_attention"] + ) + if attention_mask_tensor is not None and attention_mask_tensor.ndim == 4: + attention_mask_tensor = torch.diagonal(attention_mask_tensor[:, 0], dim1=1, dim2=2) + # Only apply conversion for floating point tensors (inverted masks) + if attention_mask_tensor.dtype.is_floating_point: + attention_mask_tensor = attention_mask_tensor / torch.finfo(attention_mask_tensor.dtype).min + attention_mask_tensor = (1.0 - attention_mask_tensor).int() + + # Calculate RoPE index once per generation in the pre-fill stage only. + # When compiling, we can't check tensor values thus we check only input length + # It is safe to assume that `length!=1` means we're in pre-fill because compiled + # models currently cannot do asssisted decoding + prefill_compiled_stage = is_torchdynamo_compiling() and ( + (input_ids is not None and input_ids.shape[1] != 1) + or (inputs_embeds is not None and inputs_embeds.shape[1] != 1) + ) + prefill_noncompiled_stage = not is_torchdynamo_compiling() and ( + (cache_position is not None and cache_position[0] == 0) + or (past_key_values is None or past_key_values.get_seq_length() == 0) + ) + if (prefill_compiled_stage or prefill_noncompiled_stage) or self.rope_deltas is None: + position_ids, rope_deltas = self.get_rope_index( + input_ids, + image_grid_thw, + video_grid_thw, + attention_mask=attention_mask_tensor, + ) + self.rope_deltas = rope_deltas + # then use the prev pre-calculated rope-deltas to get the correct position ids + else: + batch_size, seq_length, _ = inputs_embeds.shape + delta = ( + (cache_position[0] + self.rope_deltas).to(inputs_embeds.device) + if cache_position is not None + else 0 + ) + position_ids = torch.arange(seq_length, device=inputs_embeds.device) + position_ids = position_ids.view(1, -1).expand(batch_size, -1) + if cache_position is not None: # otherwise `deltas` is an int `0` + delta = delta.repeat_interleave(batch_size // delta.shape[0], dim=0) + position_ids = position_ids.add(delta) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1) + + outputs = self.language_model( + input_ids=None, + position_ids=position_ids, + attention_mask=attention_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + visual_pos_masks=visual_pos_masks, + deepstack_visual_embeds=deepstack_visual_embeds, + **kwargs, + ) + + return Qwen3VLMoeModelOutputWithPast( + last_hidden_state=outputs.last_hidden_state, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + rope_deltas=self.rope_deltas, + ) + + +@dataclass +@auto_docstring( + custom_intro=""" + Base class for Qwen3VLMoe causal language model (or autoregressive) outputs. + """ +) +class Qwen3VLMoeCausalLMOutputWithPast(ModelOutput): + r""" + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided): + Language modeling loss (for next-token prediction). + logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape + `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + + Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see + `past_key_values` input) to speed up sequential decoding. + rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*): + The rope index difference between sequence length and multimodal rope. + """ + + loss: Optional[torch.FloatTensor] = None + logits: Optional[torch.FloatTensor] = None + past_key_values: Optional[list[torch.FloatTensor]] = None + hidden_states: Optional[tuple[torch.FloatTensor]] = None + attentions: Optional[tuple[torch.FloatTensor]] = None + rope_deltas: Optional[torch.LongTensor] = None + + +class Qwen3VLMoeForConditionalGeneration(Qwen3VLMoePreTrainedModel, GenerationMixin): + _checkpoint_conversion_mapping = {} + _tied_weights_keys = ["lm_head.weight"] + # Reference: fix gemma3 grad acc #37208 + accepts_loss_kwargs = False + config: Qwen3VLMoeConfig + + def __init__(self, config): + super().__init__(config) + self.model = Qwen3VLMoeModel(config) + self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False) + + self.post_init() + + def get_input_embeddings(self): + return self.model.get_input_embeddings() + + def set_input_embeddings(self, value): + self.model.set_input_embeddings(value) + + def set_decoder(self, decoder): + self.model.set_decoder(decoder) + + def get_decoder(self): + return self.model.get_decoder() + + def get_video_features( + self, pixel_values_videos: torch.FloatTensor, video_grid_thw: Optional[torch.LongTensor] = None + ): + return self.model.get_video_features(pixel_values_videos, video_grid_thw) + + def get_image_features(self, pixel_values: torch.FloatTensor, image_grid_thw: Optional[torch.LongTensor] = None): + return self.model.get_image_features(pixel_values, image_grid_thw) + + # Make modules available through conditional class for BC + @property + def language_model(self): + return self.model.language_model + + @property + def visual(self): + return self.model.visual + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[list[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.Tensor] = None, + pixel_values_videos: Optional[torch.FloatTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, Qwen3VLMoeCausalLMOutputWithPast]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + + Example: + TODO: Add example + """ + outputs = self.model( + input_ids=input_ids, + pixel_values=pixel_values, + pixel_values_videos=pixel_values_videos, + image_grid_thw=image_grid_thw, + video_grid_thw=video_grid_thw, + position_ids=position_ids, + attention_mask=attention_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs[0] + + # Only compute necessary logits, and do not upcast them to float if we are not computing the loss + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]) + + loss = None + if labels is not None: + loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.text_config.vocab_size) + + return Qwen3VLMoeCausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + rope_deltas=outputs.rope_deltas, + ) + + def prepare_inputs_for_generation( + self, + input_ids, + past_key_values=None, + attention_mask=None, + inputs_embeds=None, + cache_position=None, + position_ids=None, + use_cache=True, + pixel_values=None, + pixel_values_videos=None, + image_grid_thw=None, + video_grid_thw=None, + **kwargs, + ): + # Overwritten -- in specific circumstances we don't want to forward image inputs to the model + + model_inputs = super().prepare_inputs_for_generation( + input_ids, + past_key_values=past_key_values, + attention_mask=attention_mask, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + position_ids=position_ids, + pixel_values=pixel_values, + pixel_values_videos=pixel_values_videos, + image_grid_thw=image_grid_thw, + video_grid_thw=video_grid_thw, + use_cache=use_cache, + **kwargs, + ) + + # Qwen3VLMoe position_ids are prepareed with rope_deltas in forward + model_inputs["position_ids"] = None + + if cache_position[0] != 0: + model_inputs["pixel_values"] = None + model_inputs["pixel_values_videos"] = None + + return model_inputs + + def _get_image_nums_and_video_nums( + self, + input_ids: Optional[torch.LongTensor], + inputs_embeds: Optional[torch.Tensor] = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + """ + Get the number of images and videos for each sample to calculate the separation length of the sample tensor. + These parameters are not passed through the processor to avoid unpredictable impacts from interface modifications. + + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. + + Returns: + image_nums (`torch.LongTensor` of shape `(batch_size, num_images_sample)`) + video_nums (`torch.LongTensor` of shape `(batch_size, num_videos_sample)`) + """ + image_token_id = self.config.image_token_id + video_token_id = self.config.video_token_id + vision_start_token_id = self.config.vision_start_token_id + + if inputs_embeds is not None: + vision_start_mask = ( + inputs_embeds + == self.get_input_embeddings()( + torch.tensor(vision_start_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + )[..., 0] + image_mask = ( + inputs_embeds + == self.get_input_embeddings()( + torch.tensor(image_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + )[..., 0] + video_mask = ( + inputs_embeds + == self.get_input_embeddings()( + torch.tensor(video_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + )[..., 0] + else: + vision_start_mask = input_ids == vision_start_token_id + image_mask = input_ids == image_token_id + video_mask = input_ids == video_token_id + + vision_first_mask = torch.roll(vision_start_mask, shifts=1, dims=1) + image_nums = torch.sum(vision_first_mask & image_mask, dim=1) + video_nums = torch.sum(vision_first_mask & video_mask, dim=1) + + return image_nums, video_nums + + def _expand_inputs_for_generation( + self, + expand_size: int = 1, + is_encoder_decoder: bool = False, + input_ids: Optional[torch.LongTensor] = None, + **model_kwargs, + ) -> tuple[torch.LongTensor, dict[str, Any]]: + # Overwritten -- Support for expanding tensors without a batch size dimension + # e.g., pixel_values, image_grid_thw, pixel_values_videos, video_grid_thw, second_per_grid_t + # pixel_values.shape[0] is sum(seqlen_images for samples) + # image_grid_thw.shape[0] is sum(num_images for samples) + + if expand_size == 1: + return input_ids, model_kwargs + + visual_keys = ["pixel_values", "image_grid_thw", "pixel_values_videos", "video_grid_thw", "second_per_grid_ts"] + + def _expand_dict_for_generation_visual(dict_to_expand): + image_grid_thw = model_kwargs.get("image_grid_thw", None) + video_grid_thw = model_kwargs.get("video_grid_thw", None) + image_nums, video_nums = self._get_image_nums_and_video_nums( + input_ids, inputs_embeds=model_kwargs.get("inputs_embeds", None) + ) + + def _repeat_interleave_samples(x, lengths, repeat_times): + samples = torch.split(x, lengths) + repeat_args = [repeat_times] + [1] * (x.dim() - 1) + result = torch.cat([sample.repeat(*repeat_args) for sample in samples], dim=0) + return result + + for key in dict_to_expand: + if key == "pixel_values": + # split images into samples + samples = torch.split(image_grid_thw, list(image_nums)) + # compute the sequence length of images for each sample + lengths = [torch.prod(sample, dim=1).sum() for sample in samples] + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "image_grid_thw": + # get the num of images for each sample + lengths = list(image_nums) + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "pixel_values_videos": + samples = torch.split(video_grid_thw, list(video_nums)) + lengths = [torch.prod(sample, dim=1).sum() for sample in samples] + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "video_grid_thw": + lengths = list(video_nums) + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "second_per_grid_ts": + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=list(video_nums), repeat_times=expand_size + ) + return dict_to_expand + + def _expand_dict_for_generation(dict_to_expand): + for key in dict_to_expand: + if ( + key != "cache_position" + and dict_to_expand[key] is not None + and isinstance(dict_to_expand[key], torch.Tensor) + and key not in visual_keys + ): + dict_to_expand[key] = dict_to_expand[key].repeat_interleave(expand_size, dim=0) + return dict_to_expand + + model_kwargs = _expand_dict_for_generation_visual(model_kwargs) + + if input_ids is not None: + input_ids = input_ids.repeat_interleave(expand_size, dim=0) + + model_kwargs = _expand_dict_for_generation(model_kwargs) + + if is_encoder_decoder: + if model_kwargs.get("encoder_outputs") is None: + raise ValueError("If `is_encoder_decoder` is True, make sure that `encoder_outputs` is defined.") + model_kwargs["encoder_outputs"] = _expand_dict_for_generation(model_kwargs["encoder_outputs"]) + + return input_ids, model_kwargs + + +__all__ = [ + "Qwen3VLMoeVisionModel", + "Qwen3VLMoeForConditionalGeneration", + "Qwen3VLMoeModel", + "Qwen3VLMoePreTrainedModel", + "Qwen3VLMoeTextModel", +] diff --git a/src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py b/src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py new file mode 100644 index 000000000000..456d7c60aa89 --- /dev/null +++ b/src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py @@ -0,0 +1,434 @@ +# coding=utf-8 +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. +"""PyTorch Qwen3-VL-MOE model.""" + +import torch +import torch.nn as nn + +from ...activations import ACT2FN +from ...configuration_utils import PretrainedConfig +from ...modeling_rope_utils import rope_config_validation +from ...modeling_utils import PreTrainedModel +from ...utils import logging +from ..qwen3_moe.modeling_qwen3_moe import ( + Qwen3MoeDecoderLayer, + Qwen3MoePreTrainedModel, + Qwen3MoeRMSNorm, +) +from ..qwen3_vl.configuration_qwen3_vl import Qwen3VLConfig, Qwen3VLVisionConfig +from ..qwen3_vl.modeling_qwen3_vl import ( + Qwen3VLForConditionalGeneration, + Qwen3VLModel, + Qwen3VLTextAttention, + Qwen3VLTextModel, + Qwen3VLVisionModel, +) + + +logger = logging.get_logger(__name__) + + +class Qwen3VLMoeTextConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3VLMoeTextModel`]. It is used to instantiate a + Qwen3-VL-MOE model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of + Qwen3-VL-30B-A3B-Instruct [Qwen/Qwen3-VL-30B-A3B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-30B-A3B-Instruct). + + 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 151936): + Vocabulary size of the Qwen2MoE model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`Qwen2MoeModel`] + hidden_size (`int`, *optional*, defaults to 2048): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 5632): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 24): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer encoder. + num_key_value_heads (`int`, *optional*, defaults to 16): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details checkout [this + paper](https://arxiv.org/pdf/2305.13245.pdf). If it is not specified, will default to `32`. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 128000): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether the model's input and output word embeddings should be tied. + rope_theta (`float`, *optional*, defaults to 5000000.0): + The base period of the RoPE embeddings. + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + decoder_sparse_step (`int`, *optional*, defaults to 1): + The frequency of the MoE layer. + moe_intermediate_size (`int`, *optional*, defaults to 1408): + Intermediate size of the routed expert. + num_experts_per_tok (`int`, *optional*, defaults to 4): + Number of selected experts. + num_experts (`int`, *optional*, defaults to 60): + Number of routed experts. + norm_topk_prob (`bool`, *optional*, defaults to `True`): + Whether to normalize the topk probabilities. + mlp_only_layers (`List[int]`, *optional*, defaults to `[]`): + Indicate which layers use Qwen3VLMoeMLP rather than Qwen3VLMoeSparseMoeBlock + The list contains layer index, from 0 to num_layers-1 if we have num_layers layers + If `mlp_only_layers` is empty, `decoder_sparse_step` is used to determine the sparsity. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type + and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value + accordingly. + Expected contents: + `rope_type` (`str`): + The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope', + 'llama3'], with 'default' being the original RoPE implementation. + `factor` (`float`, *optional*): + Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In + most scaling types, a `factor` of x will enable the model to handle sequences of length x * + original maximum pre-trained length. + `original_max_position_embeddings` (`int`, *optional*): + Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during + pretraining. + `attention_factor` (`float`, *optional*): + Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention + computation. If unspecified, it defaults to value recommended by the implementation, using the + `factor` field to infer the suggested value. + `beta_fast` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear + ramp function. If unspecified, it defaults to 32. + `beta_slow` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear + ramp function. If unspecified, it defaults to 1. + `short_factor` (`List[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to short contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `long_factor` (`List[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to long contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `low_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE + `high_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE + head_dim (`int`, *optional*): + The dimension of the head. If not specified, will default to `hidden_size // num_attention_heads`. + + ```python + >>> from transformers import Qwen3VLMoeForConditionalGeneration, Qwen3VLMoeConfig + + >>> # Initializing a Qwen3VLMoe style configuration + >>> configuration = Qwen3VLMoeConfig() + + >>> # Initializing a model from the Qwen3-VL-30B-A3B style configuration + >>> model = Qwen3VLMoeForConditionalGeneration(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_vl_moe_text" + base_config_key = "text_config" + keys_to_ignore_at_inference = ["past_key_values"] + # Default tensor parallel plan for base model `Qwen3VLMoe` + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise", + "layers.*.self_attn.k_proj": "colwise", + "layers.*.self_attn.v_proj": "colwise", + "layers.*.self_attn.o_proj": "rowwise", + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=151936, + hidden_size=2048, + intermediate_size=5632, + num_hidden_layers=24, + num_attention_heads=16, + num_key_value_heads=16, + hidden_act="silu", + max_position_embeddings=128000, + initializer_range=0.02, + rms_norm_eps=1e-6, + use_cache=True, + tie_word_embeddings=False, + rope_theta=5000000.0, + attention_bias=False, + attention_dropout=0.0, + decoder_sparse_step=1, + moe_intermediate_size=1408, + num_experts_per_tok=4, + num_experts=60, + norm_topk_prob=True, + mlp_only_layers=None, + rope_scaling=None, + head_dim=None, + **kwargs, + ): + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + + # for backward compatibility + if num_key_value_heads is None: + num_key_value_heads = num_attention_heads + + self.num_key_value_heads = num_key_value_heads + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.rope_theta = rope_theta + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + self.rope_scaling = rope_scaling + self.head_dim = head_dim or hidden_size // num_attention_heads + + rope_config_validation(self, ignore_keys={"mrope_section", "mrope_interleaved"}) + + # MoE arguments + self.decoder_sparse_step = decoder_sparse_step + self.moe_intermediate_size = moe_intermediate_size + self.num_experts_per_tok = num_experts_per_tok + self.num_experts = num_experts + self.norm_topk_prob = norm_topk_prob + self.mlp_only_layers = [] if mlp_only_layers is None else mlp_only_layers + + super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs) + + +class Qwen3VLMoeVisionConfig(Qwen3VLVisionConfig): + pass + + +class Qwen3VLMoeConfig(Qwen3VLConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3VLMoeModel`]. It is used to instantiate a + Qwen3-VL-MOE model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of + Qwen3-VL-30B-A3B-Instruct [Qwen/Qwen3-VL-30B-A3B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-30B-A3B-Instruct). + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + text_config (`Union[PreTrainedConfig, dict]`, *optional*, defaults to `Qwen3VLMoeTextConfig`): + The config object or dictionary of the text backbone. + vision_config (`Union[PreTrainedConfig, dict]`, *optional*, defaults to `Qwen3VLMoeVisionConfig`): + The config object or dictionary of the vision backbone. + image_token_id (`int`, *optional*, defaults to 151655): + The image token index to encode the image prompt. + video_token_id (`int`, *optional*, defaults to 151656): + The video token index to encode the image prompt. + vision_start_token_id (`int`, *optional*, defaults to 151652): + The start token index to encode the image prompt. + vision_end_token_id (`int`, *optional*, defaults to 151653): + The end token index to encode the image prompt. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether to tie the word embeddings. + + ```python + >>> from transformers import Qwen3VLMoeForConditionalGeneration, Qwen3VLMoeConfig + + >>> # Initializing a Qwen3-VL-MOE style configuration + >>> configuration = Qwen3VLMoeConfig() + + >>> # Initializing a model from the Qwen3-VL-30B-A3B style configuration + >>> model = Qwen3VLMoeForConditionalGeneration(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_vl_moe" + sub_configs = {"vision_config": Qwen3VLMoeVisionConfig, "text_config": Qwen3VLMoeTextConfig} + + +class Qwen3VLMoeTextRMSNorm(Qwen3MoeRMSNorm): + pass + + +class Qwen3VLMoeTextRouter(nn.Linear): + def __init__(self, config): + super().__init__(config.hidden_size, config.num_experts, bias=False) + self.hidden_size = config.hidden_size + self.top_k = config.num_experts_per_tok + # since all the models use norm_topk_prob, we don't need to have a extra check for it + # self.norm_topk_prob = config.norm_topk_prob + + def forward(self, hidden_states): + hidden_states = hidden_states.reshape(-1, self.hidden_size) + router_logits = super().forward(hidden_states) + routing_weights = torch.nn.functional.softmax(router_logits, dim=-1, dtype=torch.float) + routing_weights, router_indices = torch.topk(routing_weights, self.top_k, dim=-1) + routing_weights = routing_weights / routing_weights.sum(dim=-1, keepdim=True) + routing_weights = routing_weights.to(hidden_states.dtype) + router_weights = torch.zeros_like(router_logits).scatter_(1, router_indices, routing_weights) + return router_weights, router_logits, router_indices + + +class Qwen3VLMoeTextExperts(nn.Module): + def __init__(self, config): + super().__init__() + self.num_experts = config.num_experts + self.intermediate_size = config.moe_intermediate_size + self.hidden_size = config.hidden_size + self.expert_dim = self.intermediate_size + self.gate_up_proj = nn.Parameter(torch.empty(self.num_experts, self.hidden_size, 2 * self.expert_dim)) + self.down_proj = nn.Parameter(torch.empty((self.num_experts, self.expert_dim, self.hidden_size))) + self.act_fn = ACT2FN[config.hidden_act] + + def forward( + self, hidden_states: torch.Tensor, routing_weights: torch.Tensor, router_indices: torch.Tensor + ) -> torch.Tensor: + """ + When training it is more efficient to just loop over the experts and compute the output for each expert + as otherwise the memory would explode. + + For inference we can sacrifice some memory and compute the output for all experts at once. By repeating the inputs. + + Args: + hidden_states (torch.Tensor): (batch_size * token_num, hidden_size) + routing_weights (torch.Tensor): (batch_size * token_num, num_experts) + router_indices (torch.Tensor): (batch_size * token_num, top_k) + Returns: + torch.Tensor + """ + batch_size = hidden_states.shape[0] + hidden_states = hidden_states.reshape(-1, self.hidden_size) # (num_tokens, hidden_size) + if self.training: + next_states = torch.zeros_like(hidden_states, dtype=hidden_states.dtype, device=hidden_states.device) + with torch.no_grad(): + expert_mask = torch.nn.functional.one_hot(router_indices, num_classes=self.num_experts) + expert_mask = expert_mask.permute(2, 1, 0) + # we sum on the top_k and on the sequence length to get which experts + # are hit this time around + expert_hit = torch.greater(expert_mask.sum(dim=(-1, -2)), 0).nonzero() + for expert_idx in expert_hit[:]: + with torch.no_grad(): + _, token_idx = torch.where(expert_mask[expert_idx[0]]) + current_state = hidden_states[token_idx] + gate_up = current_state @ self.gate_up_proj[expert_idx] + gate, up = gate_up.chunk(2, dim=-1) + gated_output = up * self.act_fn(gate) + out = gated_output @ self.down_proj[expert_idx] + weighted_output = out[0] * routing_weights[token_idx, expert_idx, None] + next_states.index_add_(0, token_idx, weighted_output.to(hidden_states.dtype)) + next_states = next_states.view(batch_size, -1, self.hidden_size) + else: + hidden_states = hidden_states.repeat(self.num_experts, 1) + hidden_states = hidden_states.view(self.num_experts, -1, self.hidden_size) + gate_up = torch.bmm(hidden_states, self.gate_up_proj) + gate, up = gate_up.chunk(2, dim=-1) # not supported for DTensors + next_states = torch.bmm((up * self.act_fn(gate)), self.down_proj) + next_states = next_states.reshape(self.num_experts, batch_size, -1, self.hidden_size) + next_states = ( + next_states * routing_weights.transpose(0, 1).view(self.num_experts, batch_size, -1)[..., None] + ) + next_states = next_states.sum(dim=0) + return next_states + + +class Qwen3VLMoeTextSparseMoeBlock(nn.Module): + def __init__(self, config): + super().__init__() + self.hidden_size = config.hidden_size + self.num_experts = config.num_experts + self.gate = Qwen3VLMoeTextRouter(config) + self.experts = Qwen3VLMoeTextExperts(config) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + router_weights, router_logits, router_indices = self.gate(hidden_states) + routed_out = self.experts(hidden_states, router_weights, router_indices) + return routed_out, router_logits + + +class Qwen3VLMoeTextAttention(Qwen3VLTextAttention): + pass + + +class Qwen3VLMoeTextDecoderLayer(Qwen3MoeDecoderLayer): + pass + + +class Qwen3VLMoePreTrainedModel(Qwen3MoePreTrainedModel): + config: Qwen3VLMoeConfig + _no_split_modules = ["Qwen3VLMoeTextDecoderLayer", "Qwen3VLMoeVisionBlock"] + + def _init_weights(self, module): + """Initialize the weights.""" + PreTrainedModel._init_weights(self, module) + if hasattr(self.config, "initializer_range"): + std = self.config.initializer_range + else: + std = getattr(self.config.get_text_config(), "initializer_range", 0.02) + if isinstance(module, Qwen3VLMoeTextExperts): + module.gate_up_proj.data.normal_(mean=0.0, std=std) + module.down_proj.data.normal_(mean=0.0, std=std) + + +class Qwen3VLMoeVisionModel(Qwen3VLVisionModel): + pass + + +class Qwen3VLMoeTextModel(Qwen3VLTextModel): + pass + + +class Qwen3VLMoeModel(Qwen3VLModel): + pass + + +class Qwen3VLMoeForConditionalGeneration(Qwen3VLForConditionalGeneration): + pass + + +__all__ = [ + "Qwen3VLMoeConfig", + "Qwen3VLMoeTextConfig", + "Qwen3VLMoeVisionModel", + "Qwen3VLMoeForConditionalGeneration", + "Qwen3VLMoeModel", + "Qwen3VLMoePreTrainedModel", + "Qwen3VLMoeTextModel", +] diff --git a/tests/models/qwen3_vl/__init__.py b/tests/models/qwen3_vl/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/models/qwen3_vl/test_modeling_qwen3_vl.py b/tests/models/qwen3_vl/test_modeling_qwen3_vl.py new file mode 100644 index 000000000000..35031bf542aa --- /dev/null +++ b/tests/models/qwen3_vl/test_modeling_qwen3_vl.py @@ -0,0 +1,299 @@ +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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 Qwen3-VL model.""" + +import copy +import unittest + +from transformers import ( + Qwen3VLConfig, + Qwen3VLForConditionalGeneration, + Qwen3VLModel, + is_torch_available, +) +from transformers.testing_utils import ( + require_torch, + torch_device, +) + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + floats_tensor, + ids_tensor, +) + + +if is_torch_available(): + import torch + + +class Qwen3VLVisionText2TextModelTester: + def __init__( + self, + parent, + batch_size=3, + seq_length=7, + num_channels=3, + ignore_index=-100, + image_size=16, + text_config={ + "bos_token_id": 0, + "eos_token_id": 1, + "pad_token_id": 2, + "hidden_act": "silu", + "head_dim": 8, + "hidden_size": 32, + "vocab_size": 99, + "intermediate_size": 37, + "max_position_embeddings": 512, + "model_type": "qwen3_vl", + "num_attention_heads": 4, + "num_hidden_layers": 4, + "num_key_value_heads": 2, + "rope_theta": 10000, + "tie_word_embeddings": True, + "rope_scaling": {"rope_type": "default", "mrope_section": [16, 8, 8], "mrope_interleaved": True}, + }, + vision_config={ + "depth": 2, + "in_chans": 3, + "hidden_act": "gelu_pytorch_tanh", + "intermediate_size": 32, + "out_hidden_size": 32, + "hidden_size": 32, + "num_heads": 4, + "patch_size": 16, + "spatial_merge_size": 1, + "temporal_patch_size": 2, + "num_position_embeddings": 16, + "deepstack_visual_indexes": [0, 1], + }, + image_token_id=3, + video_token_id=4, + vision_start_token_id=5, + vision_end_token_id=6, + tie_word_embeddings=True, + is_training=True, + ): + self.parent = parent + self.ignore_index = ignore_index + self.is_training = is_training + + self.vision_config = vision_config + self.text_config = text_config + + self.vocab_size = text_config["vocab_size"] + self.bos_token_id = text_config["bos_token_id"] + self.eos_token_id = text_config["eos_token_id"] + self.pad_token_id = text_config["pad_token_id"] + self.head_dim = text_config["head_dim"] + self.hidden_size = text_config["hidden_size"] + self.intermediate_size = text_config["intermediate_size"] + self.num_hidden_layers = text_config["num_hidden_layers"] + self.num_attention_heads = text_config["num_attention_heads"] + self.num_key_value_heads = text_config["num_key_value_heads"] + self.rope_theta = text_config["rope_theta"] + self.rope_scaling = text_config["rope_scaling"] + self.hidden_act = text_config["hidden_act"] + self.max_position_embeddings = text_config["max_position_embeddings"] + self.model_type = text_config["model_type"] + + self.vision_start_token_id = vision_start_token_id + self.vision_end_token_id = vision_end_token_id + self.image_token_id = image_token_id + self.video_token_id = video_token_id + self.tie_word_embeddings = tie_word_embeddings + + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.num_image_tokens = 32 + self.seq_length = seq_length + self.num_image_tokens + + def get_config(self): + return Qwen3VLConfig( + text_config=self.text_config, + vision_config=self.vision_config, + image_token_id=self.image_token_id, + video_token_id=self.video_token_id, + vision_start_token_id=self.vision_start_token_id, + vision_end_token_id=self.vision_end_token_id, + tie_word_embeddings=self.tie_word_embeddings, + ) + + def prepare_config_and_inputs(self): + config = self.get_config() + patch_size = config.vision_config.patch_size + temporal_patch_size = config.vision_config.temporal_patch_size + pixel_values = floats_tensor( + [ + self.batch_size * (self.image_size**2) // (patch_size**2), + self.num_channels * (patch_size**2) * temporal_patch_size, + ] + ) + + return config, pixel_values + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values = config_and_inputs + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + attention_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + + input_ids[:, -1] = self.pad_token_id + input_ids[input_ids == self.video_token_id] = self.pad_token_id + input_ids[input_ids == self.image_token_id] = self.pad_token_id + input_ids[input_ids == self.vision_start_token_id] = self.pad_token_id + input_ids[:, self.num_image_tokens] = self.image_token_id + input_ids[:, self.num_image_tokens - 1] = self.vision_start_token_id + inputs_dict = { + "pixel_values": pixel_values, + "image_grid_thw": torch.tensor([[1, 1, 1]] * self.batch_size, device=torch_device), + "input_ids": input_ids, + "attention_mask": attention_mask, + } + return config, inputs_dict + + +@require_torch +class Qwen3VLModelTest(ModelTesterMixin, GenerationTesterMixin, unittest.TestCase): + """ + Model tester for `Qwen3VLForConditionalGeneration`. + """ + + all_model_classes = ( + ( + Qwen3VLModel, + Qwen3VLForConditionalGeneration, + ) + if is_torch_available() + else () + ) + test_pruning = False + test_head_masking = False + + def setUp(self): + self.model_tester = Qwen3VLVisionText2TextModelTester(self) + self.config_tester = ConfigTester(self, config_class=Qwen3VLConfig, has_text_modality=False) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_mismatching_num_image_tokens(self): + """ + Tests that VLMs through an error with explicit message saying what is wrong + when number of images don't match number of image tokens in the text. + Also we need to test multi-image cases when one prompr has multiple image tokens. + """ + config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + model = model_class(config).to(torch_device) + _ = model(**input_dict) # successful forward with no modifications + curr_input_dict = copy.deepcopy(input_dict) + + # remove one image but leave the image token in text + patch_size = config.vision_config.patch_size + one_img_length = (self.model_tester.image_size**2) // (patch_size**2) + curr_input_dict["pixel_values"] = curr_input_dict["pixel_values"][-one_img_length:, ...] + curr_input_dict["image_grid_thw"] = curr_input_dict["image_grid_thw"][-1:, ...] + with self.assertRaises(ValueError): + _ = model(**curr_input_dict) + + # simulate multi-image case by concatenating inputs where each has exactly one image/image-token + input_ids = curr_input_dict["input_ids"][:1] + pixel_values = curr_input_dict["pixel_values"][:one_img_length] + image_grid_thw = curr_input_dict["image_grid_thw"][:1] + input_ids = torch.cat([input_ids, input_ids], dim=0) + + # one image and two image tokens raise an error + with self.assertRaises(ValueError): + _ = model( + input_ids=input_ids, + pixel_values=pixel_values, + image_grid_thw=image_grid_thw, + ) + + # two images and two image tokens don't raise an error + pixel_values = torch.cat([pixel_values, pixel_values], dim=0) + image_grid_thw = torch.cat([image_grid_thw, image_grid_thw], dim=0) + _ = model( + input_ids=input_ids, + pixel_values=pixel_values, + image_grid_thw=image_grid_thw, + ) + + def test_video_forward(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + B = self.model_tester.batch_size + C = config.vision_config.in_chans + T = config.vision_config.temporal_patch_size + P = config.vision_config.patch_size + + input_ids = ids_tensor([B, self.model_tester.seq_length], self.model_tester.vocab_size) + + F = 4 + patch_H = self.model_tester.image_size // P + patch_W = self.model_tester.image_size // P + patch_T = F // T + patches_per_video = patch_T * patch_H * patch_W + pathed_per_frame = patch_H * patch_W + pixel_values_videos = floats_tensor( + [ + # first dim: batch_size * num_patches + B * patches_per_video, + # second dim: in_channels * temporal_patch_size * patch_size^2 + C * T * (P**2), + ] + ) + + # qwen3vl use timestamps for video, so split it into patch_T sub-videos + video_grid_thw = torch.tensor([[1, patch_H, patch_W] for _ in range(patch_T)] * B) + + # sanity check + self.assertEqual(pixel_values_videos.shape[0], video_grid_thw.prod(dim=1).sum().item()) + + # Insert video token sequence + input_ids[:, -1] = self.model_tester.pad_token_id + input_ids[input_ids == self.model_tester.video_token_id] = self.model_tester.pad_token_id + input_ids[input_ids == self.model_tester.image_token_id] = self.model_tester.pad_token_id + input_ids[input_ids == self.model_tester.vision_start_token_id] = self.model_tester.pad_token_id + input_ids[:, self.model_tester.num_image_tokens] = self.model_tester.video_token_id + + insertion_point = self.model_tester.num_image_tokens + + self.assertLessEqual((B * patches_per_video) + insertion_point, self.model_tester.seq_length) + for b in range(B): + # each frame is separated by a vision_start_token_id + for frame_idx in range(patch_T): + input_ids[b, insertion_point + frame_idx * (pathed_per_frame + 1)] = ( + self.model_tester.vision_start_token_id + ) + input_ids[ + b, + insertion_point + frame_idx * (pathed_per_frame + 1) + 1 : insertion_point + + (frame_idx + 1) * (pathed_per_frame + 1), + ] = self.model_tester.video_token_id + + for model_class in self.all_model_classes: + # TODO:we should remove this because we use timestamps for video + model = model_class(config).to(torch_device) + outputs = model( + input_ids=input_ids, + pixel_values_videos=pixel_values_videos, + video_grid_thw=video_grid_thw, + ) + self.assertIsNotNone(outputs) diff --git a/tests/models/qwen3_vl/test_processing_qwen3_vl.py b/tests/models/qwen3_vl/test_processing_qwen3_vl.py new file mode 100644 index 000000000000..87636dcf607d --- /dev/null +++ b/tests/models/qwen3_vl/test_processing_qwen3_vl.py @@ -0,0 +1,379 @@ +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. + +import inspect +import shutil +import tempfile +import unittest + +import numpy as np +import pytest + +from transformers import AutoProcessor, Qwen2TokenizerFast +from transformers.testing_utils import require_av, require_torch, require_torchvision, require_vision +from transformers.utils import is_torch_available, is_vision_available + +from ...test_processing_common import ProcessorTesterMixin + + +if is_vision_available(): + from transformers import Qwen2VLImageProcessorFast, Qwen3VLProcessor + +if is_torch_available(): + import torch + + +@require_vision +@require_torch +@require_torchvision +@unittest.skip("The checkpoint is not yet released") +class Qwen3VLProcessorTest(ProcessorTesterMixin, unittest.TestCase): + processor_class = Qwen3VLProcessor + + @classmethod + def setUpClass(cls): + cls.tmpdirname = tempfile.mkdtemp() + processor = Qwen3VLProcessor.from_pretrained( + "Qwen/Qwen3-VL-4B-Instruct", patch_size=4, max_pixels=56 * 56, min_pixels=28 * 28 + ) + processor.save_pretrained(cls.tmpdirname) + cls.image_token = processor.image_token + + def get_tokenizer(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs).tokenizer + + def get_image_processor(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs).image_processor + + def get_video_processor(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs).video_processor + + def get_processor(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs) + + @classmethod + def tearDownClass(cls): + shutil.rmtree(cls.tmpdirname, ignore_errors=True) + + # Copied from tests.models.llava.test_processing_llava.LlavaProcessorTest.test_get_num_vision_tokens + def test_get_num_vision_tokens(self): + "Tests general functionality of the helper used internally in vLLM" + + processor = self.get_processor() + + output = processor._get_num_multimodal_tokens(image_sizes=[(100, 100), (300, 100), (500, 30)]) + self.assertTrue("num_image_tokens" in output) + self.assertEqual(len(output["num_image_tokens"]), 3) + + self.assertTrue("num_image_patches" in output) + self.assertEqual(len(output["num_image_patches"]), 3) + + def test_save_load_pretrained_default(self): + tokenizer = self.get_tokenizer() + image_processor = self.get_image_processor() + video_processor = self.get_video_processor() + + processor = Qwen3VLProcessor( + tokenizer=tokenizer, image_processor=image_processor, video_processor=video_processor + ) + processor.save_pretrained(self.tmpdirname) + processor = Qwen3VLProcessor.from_pretrained(self.tmpdirname, use_fast=True) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer.get_vocab()) + self.assertEqual(processor.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertIsInstance(processor.tokenizer, Qwen2TokenizerFast) + self.assertIsInstance(processor.image_processor, Qwen2VLImageProcessorFast) + + def test_image_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + video_processor = self.get_video_processor() + + processor = Qwen3VLProcessor( + tokenizer=tokenizer, image_processor=image_processor, video_processor=video_processor + ) + + image_input = self.prepare_image_inputs() + + input_image_proc = image_processor(image_input, return_tensors="pt") + input_processor = processor(images=image_input, text="dummy", return_tensors="pt") + + for key in input_image_proc: + self.assertAlmostEqual(input_image_proc[key].sum(), input_processor[key].sum(), delta=1e-2) + + def test_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + video_processor = self.get_video_processor() + + processor = Qwen3VLProcessor( + tokenizer=tokenizer, image_processor=image_processor, video_processor=video_processor + ) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + inputs = processor(text=input_str, images=image_input) + + self.assertListEqual( + list(inputs.keys()), + ["input_ids", "attention_mask", "pixel_values", "image_grid_thw"], + ) + + # test if it raises when no input is passed + with pytest.raises(ValueError): + processor() + + # test if it raises when no text is passed + with pytest.raises(TypeError): + processor(images=image_input) + + def test_model_input_names(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + video_processor = self.get_video_processor() + + processor = Qwen3VLProcessor( + tokenizer=tokenizer, image_processor=image_processor, video_processor=video_processor + ) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + video_inputs = self.prepare_video_inputs() + + inputs = processor(text=input_str, images=image_input, videos=video_inputs, do_sample_frames=False) + + self.assertListEqual(list(inputs.keys()), processor.model_input_names) + + @require_torch + @require_av + def _test_apply_chat_template( + self, + modality: str, + batch_size: int, + return_tensors: str, + input_name: str, + processor_name: str, + input_data: list[str], + ): + processor = self.get_processor() + if processor.chat_template is None: + self.skipTest("Processor has no chat template") + + if processor_name not in self.processor_class.attributes: + self.skipTest(f"{processor_name} attribute not present in {self.processor_class}") + + batch_messages = [ + [ + { + "role": "user", + "content": [{"type": "text", "text": "Describe this."}], + }, + ] + ] * batch_size + + # Test that jinja can be applied + formatted_prompt = processor.apply_chat_template(batch_messages, add_generation_prompt=True, tokenize=False) + self.assertEqual(len(formatted_prompt), batch_size) + + # Test that tokenizing with template and directly with `self.tokenizer` gives same output + formatted_prompt_tokenized = processor.apply_chat_template( + batch_messages, add_generation_prompt=True, tokenize=True, return_tensors=return_tensors + ) + add_special_tokens = True + if processor.tokenizer.bos_token is not None and formatted_prompt[0].startswith(processor.tokenizer.bos_token): + add_special_tokens = False + tok_output = processor.tokenizer( + formatted_prompt, return_tensors=return_tensors, add_special_tokens=add_special_tokens + ) + expected_output = tok_output.input_ids + self.assertListEqual(expected_output.tolist(), formatted_prompt_tokenized.tolist()) + + # Test that kwargs passed to processor's `__call__` are actually used + tokenized_prompt_100 = processor.apply_chat_template( + batch_messages, + add_generation_prompt=True, + tokenize=True, + padding="max_length", + truncation=True, + return_tensors=return_tensors, + max_length=100, + ) + self.assertEqual(len(tokenized_prompt_100[0]), 100) + + # Test that `return_dict=True` returns text related inputs in the dict + out_dict_text = processor.apply_chat_template( + batch_messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors=return_tensors, + ) + self.assertTrue(all(key in out_dict_text for key in ["input_ids", "attention_mask"])) + self.assertEqual(len(out_dict_text["input_ids"]), batch_size) + self.assertEqual(len(out_dict_text["attention_mask"]), batch_size) + + # Test that with modality URLs and `return_dict=True`, we get modality inputs in the dict + for idx, url in enumerate(input_data[:batch_size]): + batch_messages[idx][0]["content"] = [batch_messages[idx][0]["content"][0], {"type": modality, "url": url}] + + out_dict = processor.apply_chat_template( + batch_messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors=return_tensors, + max_frames=2, # by default no more than 2 frames, otherwise too slow + ) + input_name = getattr(self, input_name) + self.assertTrue(input_name in out_dict) + self.assertEqual(len(out_dict["input_ids"]), batch_size) + self.assertEqual(len(out_dict["attention_mask"]), batch_size) + + if modality == "video": + # qwen pixels don't scale with bs same way as other models, calculate expected video token count based on video_grid_thw + expected_video_token_count = 0 + for thw in out_dict["video_grid_thw"]: + expected_video_token_count += thw[0] * thw[1] * thw[2] + mm_len = expected_video_token_count + else: + mm_len = batch_size * 192 + self.assertEqual(len(out_dict[input_name]), mm_len) + + return_tensor_to_type = {"pt": torch.Tensor, "np": np.ndarray, None: list} + for k in out_dict: + self.assertIsInstance(out_dict[k], return_tensor_to_type[return_tensors]) + + @require_av + @unittest.skip("qwen3_vl can't sample frames from image frames directly, user can use `qwen-vl-utils`") + def test_apply_chat_template_video_1(self): + pass + + @require_av + @unittest.skip("qwen3_vl can't sample frames from image frames directly, user can use `qwen-vl-utils`") + def test_apply_chat_template_video_2(self): + pass + + @require_av + def test_apply_chat_template_video_frame_sampling(self): + processor = self.get_processor() + if processor.chat_template is None: + self.skipTest("Processor has no chat template") + + signature = inspect.signature(processor.__call__) + if "videos" not in {*signature.parameters.keys()} or ( + signature.parameters.get("videos") is not None + and signature.parameters["videos"].annotation == inspect._empty + ): + self.skipTest("Processor doesn't accept videos at input") + + messages = [ + [ + { + "role": "user", + "content": [ + {"type": "video"}, + {"type": "text", "text": "What is shown in this video?"}, + ], + }, + ] + ] + + formatted_prompt = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=False) + self.assertEqual(len(formatted_prompt), 1) + + formatted_prompt_tokenized = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=True) + expected_output = processor.tokenizer(formatted_prompt, return_tensors=None).input_ids + self.assertListEqual(expected_output, formatted_prompt_tokenized) + + out_dict = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=True, return_dict=True) + self.assertListEqual(list(out_dict.keys()), ["input_ids", "attention_mask"]) + + # Add video URL for return dict and load with `num_frames` arg + messages[0][0]["content"][0] = { + "type": "video", + "url": "https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_10MB.mp4", + } + num_frames = 3 + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + num_frames=num_frames, + ) + self.assertTrue(self.videos_input_name in out_dict_with_video) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 360) + + # Load with `fps` arg + fps = 1 + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + fps=fps, + ) + self.assertTrue(self.videos_input_name in out_dict_with_video) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 900) + + # Load with `fps` and `num_frames` args, should raise an error + with self.assertRaises(ValueError): + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + fps=fps, + num_frames=num_frames, + ) + + # Load without any arg should load the whole video + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + ) + self.assertTrue(self.videos_input_name in out_dict_with_video) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 27000) + + # Load video as a list of frames (i.e. images). NOTE: each frame should have same size + # because we assume they come from one video + messages[0][0]["content"][0] = { + "type": "video", + "url": [ + "https://www.ilankelman.org/stopsigns/australia.jpg", + "https://www.ilankelman.org/stopsigns/australia.jpg", + ], + } + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + do_sample_frames=False, + ) + self.assertTrue(self.videos_input_name in out_dict_with_video) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 160) + + def test_kwargs_overrides_custom_image_processor_kwargs(self): + processor = self.get_processor() + self.skip_processor_without_typed_kwargs(processor) + + input_str = self.prepare_text_inputs() + image_input = self.prepare_image_inputs() + inputs = processor(text=input_str, images=image_input, max_pixels=56 * 56 * 4, return_tensors="pt") + self.assertEqual(inputs[self.images_input_name].shape[0], 612) + inputs = processor(text=input_str, images=image_input, return_tensors="pt") + self.assertEqual(inputs[self.images_input_name].shape[0], 100) diff --git a/tests/models/qwen3_vl/test_video_processing_qwen3_vl.py b/tests/models/qwen3_vl/test_video_processing_qwen3_vl.py new file mode 100644 index 000000000000..9230f0f9502e --- /dev/null +++ b/tests/models/qwen3_vl/test_video_processing_qwen3_vl.py @@ -0,0 +1,330 @@ +# coding=utf-8 +# Copyright 2025 HuggingFace Inc. +# +# 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. + +import unittest + +import numpy as np + +from transformers.image_utils import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torch_available, is_torchvision_available, is_vision_available + +from ...test_video_processing_common import VideoProcessingTestMixin, prepare_video_inputs + + +if is_torch_available(): + from PIL import Image + +if is_vision_available() and is_torchvision_available(): + from transformers import Qwen3VLVideoProcessor + from transformers.models.qwen3_vl.video_processing_qwen3_vl import smart_resize + + +class Qwen3VLVideoProcessingTester: + def __init__( + self, + parent, + batch_size=5, + num_frames=8, + num_channels=3, + min_resolution=32, + max_resolution=80, + temporal_patch_size=2, + patch_size=16, + merge_size=2, + do_resize=True, + size=None, + do_normalize=True, + image_mean=IMAGENET_STANDARD_MEAN, + image_std=IMAGENET_STANDARD_STD, + do_convert_rgb=True, + ): + size = size if size is not None else {"longest_edge": 20, "shortest_edge": 10} + self.parent = parent + self.batch_size = batch_size + self.num_frames = num_frames + self.num_channels = num_channels + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + self.do_convert_rgb = do_convert_rgb + self.temporal_patch_size = temporal_patch_size + self.patch_size = patch_size + self.merge_size = merge_size + + def prepare_video_processor_dict(self): + return { + "do_resize": self.do_resize, + "size": self.size, + "do_normalize": self.do_normalize, + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_convert_rgb": self.do_convert_rgb, + "do_sample_frames": True, + } + + def prepare_video_metadata(self, videos): + video_metadata = [] + for video in videos: + if isinstance(video, list): + num_frames = len(video) + elif hasattr(video, "shape"): + if len(video.shape) == 4: # (T, H, W, C) + num_frames = video.shape[0] + else: + num_frames = 1 + else: + num_frames = self.num_frames + + metadata = { + "fps": 2, + "duration": num_frames / 2, + "total_num_frames": num_frames, + } + video_metadata.append(metadata) + return video_metadata + + def expected_output_video_shape(self, videos): + grid_t = self.num_frames // self.temporal_patch_size + hidden_dim = self.num_channels * self.temporal_patch_size * self.patch_size * self.patch_size + seq_len = 0 + for video in videos: + if isinstance(video, list) and isinstance(video[0], Image.Image): + video = np.stack([np.array(frame) for frame in video]) + elif hasattr(video, "shape"): + pass + else: + video = np.array(video) + + if hasattr(video, "shape") and len(video.shape) >= 3: + if len(video.shape) == 4: + t, height, width = video.shape[:3] + elif len(video.shape) == 3: + height, width = video.shape[:2] + t = 1 + else: + t, height, width = self.num_frames, self.min_resolution, self.min_resolution + else: + t, height, width = self.num_frames, self.min_resolution, self.min_resolution + + resized_height, resized_width = smart_resize( + t, + height, + width, + factor=self.patch_size * self.merge_size, + min_pixels=self.size["shortest_edge"], + max_pixels=self.size["longest_edge"], + ) + grid_h, grid_w = resized_height // self.patch_size, resized_width // self.patch_size + seq_len += grid_t * grid_h * grid_w + return [seq_len, hidden_dim] + + def prepare_video_inputs(self, equal_resolution=False, return_tensors="pil"): + videos = prepare_video_inputs( + batch_size=self.batch_size, + num_frames=self.num_frames, + num_channels=self.num_channels, + min_resolution=self.min_resolution, + max_resolution=self.max_resolution, + equal_resolution=equal_resolution, + return_tensors=return_tensors, + ) + return videos + + +@require_torch +@require_vision +class Qwen3VLVideoProcessingTest(VideoProcessingTestMixin, unittest.TestCase): + fast_video_processing_class = Qwen3VLVideoProcessor if is_torchvision_available() else None + input_name = "pixel_values_videos" + + def setUp(self): + super().setUp() + self.video_processor_tester = Qwen3VLVideoProcessingTester(self) + + @property + def video_processor_dict(self): + return self.video_processor_tester.prepare_video_processor_dict() + + def test_video_processor_from_dict_with_kwargs(self): + video_processor = self.fast_video_processing_class.from_dict(self.video_processor_dict) + self.assertEqual(video_processor.size, {"longest_edge": 20, "shortest_edge": 10}) + + video_processor = self.fast_video_processing_class.from_dict( + self.video_processor_dict, size={"longest_edge": 42, "shortest_edge": 42} + ) + self.assertEqual(video_processor.size, {"longest_edge": 42, "shortest_edge": 42}) + + def test_call_pil(self): + for video_processing_class in self.video_processor_list: + video_processing = video_processing_class(**self.video_processor_dict) + video_inputs = self.video_processor_tester.prepare_video_inputs( + equal_resolution=False, return_tensors="pil" + ) + + for video in video_inputs: + self.assertIsInstance(video[0], Image.Image) + + video_metadata = self.video_processor_tester.prepare_video_metadata(video_inputs) + encoded_videos = video_processing( + video_inputs[0], video_metadata=[video_metadata[0]], return_tensors="pt" + )[self.input_name] + expected_output_video_shape = self.video_processor_tester.expected_output_video_shape([video_inputs[0]]) + self.assertEqual(list(encoded_videos.shape), expected_output_video_shape) + encoded_videos = video_processing(video_inputs, video_metadata=video_metadata, return_tensors="pt")[ + self.input_name + ] + expected_output_video_shape = self.video_processor_tester.expected_output_video_shape(video_inputs) + self.assertEqual(list(encoded_videos.shape), expected_output_video_shape) + + def test_call_numpy(self): + for video_processing_class in self.video_processor_list: + video_processing = video_processing_class(**self.video_processor_dict) + video_inputs = self.video_processor_tester.prepare_video_inputs( + equal_resolution=False, return_tensors="np" + ) + + video_metadata = self.video_processor_tester.prepare_video_metadata(video_inputs) + encoded_videos = video_processing( + video_inputs[0], video_metadata=[video_metadata[0]], return_tensors="pt" + )[self.input_name] + expected_output_video_shape = self.video_processor_tester.expected_output_video_shape([video_inputs[0]]) + self.assertEqual(list(encoded_videos.shape), expected_output_video_shape) + + encoded_videos = video_processing(video_inputs, video_metadata=video_metadata, return_tensors="pt")[ + self.input_name + ] + expected_output_video_shape = self.video_processor_tester.expected_output_video_shape(video_inputs) + self.assertEqual(list(encoded_videos.shape), expected_output_video_shape) + + def test_call_pytorch(self): + for video_processing_class in self.video_processor_list: + video_processing = video_processing_class(**self.video_processor_dict) + video_inputs = self.video_processor_tester.prepare_video_inputs( + equal_resolution=False, return_tensors="pt" + ) + video_metadata = self.video_processor_tester.prepare_video_metadata(video_inputs) + encoded_videos = video_processing( + video_inputs[0], video_metadata=[video_metadata[0]], return_tensors="pt" + )[self.input_name] + expected_output_video_shape = self.video_processor_tester.expected_output_video_shape([video_inputs[0]]) + self.assertEqual(list(encoded_videos.shape), expected_output_video_shape) + encoded_videos = video_processing(video_inputs, video_metadata=video_metadata, return_tensors="pt")[ + self.input_name + ] + expected_output_video_shape = self.video_processor_tester.expected_output_video_shape(video_inputs) + self.assertEqual(list(encoded_videos.shape), expected_output_video_shape) + + @unittest.skip("Skip for now, the test needs adjustment for Qwen3VL") + def test_call_numpy_4_channels(self): + for video_processing_class in self.video_processor_list: + # Test that can process videos which have an arbitrary number of channels + # Initialize video_processing + video_processor = video_processing_class(**self.video_processor_dict) + + # create random numpy tensors + self.video_processor_tester.num_channels = 4 + video_inputs = self.video_processor_tester.prepare_video_inputs( + equal_resolution=False, return_tensors="np" + ) + + # Test not batched input + encoded_videos = video_processor( + video_inputs[0], + return_tensors="pt", + input_data_format="channels_last", + image_mean=0, + image_std=1, + )[self.input_name] + expected_output_video_shape = self.video_processor_tester.expected_output_video_shape([video_inputs[0]]) + self.assertEqual(list(encoded_videos.shape), expected_output_video_shape) + + # Test batched + encoded_videos = video_processor( + video_inputs, + return_tensors="pt", + input_data_format="channels_last", + image_mean=0, + image_std=1, + )[self.input_name] + expected_output_video_shape = self.video_processor_tester.expected_output_video_shape(video_inputs) + self.assertEqual(list(encoded_videos.shape), expected_output_video_shape) + + def test_nested_input(self): + """Tests that the processor can work with nested list where each video is a list of arrays""" + for video_processing_class in self.video_processor_list: + video_processing = video_processing_class(**self.video_processor_dict) + video_inputs = self.video_processor_tester.prepare_video_inputs( + equal_resolution=False, return_tensors="np" + ) + + video_inputs_nested = [list(video) for video in video_inputs] + video_metadata = self.video_processor_tester.prepare_video_metadata(video_inputs) + + # Test not batched input + encoded_videos = video_processing( + video_inputs_nested[0], video_metadata=[video_metadata[0]], return_tensors="pt" + )[self.input_name] + expected_output_video_shape = self.video_processor_tester.expected_output_video_shape([video_inputs[0]]) + self.assertEqual(list(encoded_videos.shape), expected_output_video_shape) + + # Test batched + encoded_videos = video_processing(video_inputs_nested, video_metadata=video_metadata, return_tensors="pt")[ + self.input_name + ] + expected_output_video_shape = self.video_processor_tester.expected_output_video_shape(video_inputs) + self.assertEqual(list(encoded_videos.shape), expected_output_video_shape) + + def test_call_sample_frames(self): + for video_processing_class in self.video_processor_list: + video_processor_dict = self.video_processor_dict.copy() + video_processing = video_processing_class(**video_processor_dict) + + prev_num_frames = self.video_processor_tester.num_frames + self.video_processor_tester.num_frames = 8 + prev_min_resolution = getattr(self.video_processor_tester, "min_resolution", None) + prev_max_resolution = getattr(self.video_processor_tester, "max_resolution", None) + self.video_processor_tester.min_resolution = 56 + self.video_processor_tester.max_resolution = 112 + + video_inputs = self.video_processor_tester.prepare_video_inputs( + equal_resolution=False, + return_tensors="torch", + ) + + metadata = [[{"total_num_frames": 8, "fps": 4}]] + batched_metadata = metadata * len(video_inputs) + + encoded_videos = video_processing(video_inputs[0], return_tensors="pt", video_metadata=metadata)[ + self.input_name + ] + encoded_videos_batched = video_processing( + video_inputs, return_tensors="pt", video_metadata=batched_metadata + )[self.input_name] + + self.assertIsNotNone(encoded_videos) + self.assertIsNotNone(encoded_videos_batched) + self.assertEqual(len(encoded_videos.shape), 2) + self.assertEqual(len(encoded_videos_batched.shape), 2) + + self.video_processor_tester.num_frames = prev_num_frames + if prev_min_resolution is not None: + self.video_processor_tester.min_resolution = prev_min_resolution + if prev_max_resolution is not None: + self.video_processor_tester.max_resolution = prev_max_resolution diff --git a/tests/models/qwen3_vl_moe/__init__.py b/tests/models/qwen3_vl_moe/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py b/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py new file mode 100644 index 000000000000..adae69a81fa8 --- /dev/null +++ b/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py @@ -0,0 +1,298 @@ +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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 Qwen3VLMoe model.""" + +import copy +import unittest + +from transformers import ( + Qwen3VLMoeConfig, + Qwen3VLMoeForConditionalGeneration, + Qwen3VLMoeModel, + is_torch_available, +) +from transformers.testing_utils import ( + require_torch, + torch_device, +) + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + floats_tensor, + ids_tensor, +) + + +if is_torch_available(): + import torch + + +class Qwen3VLMoeVisionText2TextModelTester: + def __init__( + self, + parent, + batch_size=3, + seq_length=7, + num_channels=3, + ignore_index=-100, + image_size=16, + text_config={ + "bos_token_id": 0, + "eos_token_id": 1, + "pad_token_id": 2, + "hidden_act": "silu", + "hidden_size": 32, + "vocab_size": 99, + "intermediate_size": 37, + "max_position_embeddings": 512, + "model_type": "qwen3_vl_moe", + "num_attention_heads": 4, + "num_key_value_heads": 2, + "num_hidden_layers": 4, + "moe_intermediate_size": 16, + "num_experts_per_tok": 4, + "num_experts": 8, + "rope_theta": 10000, + "tie_word_embeddings": True, + "rope_scaling": {"rope_type": "default", "mrope_section": [16, 8, 8], "mrope_interleaved": True}, + }, + vision_config={ + "depth": 2, + "in_chans": 3, + "hidden_act": "gelu_pytorch_tanh", + "intermediate_size": 32, + "out_hidden_size": 32, + "hidden_size": 32, + "num_heads": 4, + "patch_size": 16, + "spatial_merge_size": 1, + "temporal_patch_size": 2, + "num_position_embeddings": 16, + "deepstack_visual_indexes": [0, 1], + }, + image_token_id=3, + video_token_id=4, + vision_start_token_id=5, + vision_end_token_id=6, + tie_word_embeddings=True, + is_training=True, + ): + self.parent = parent + self.ignore_index = ignore_index + self.is_training = is_training + + self.vision_config = vision_config + self.text_config = text_config + + self.vocab_size = text_config["vocab_size"] + self.bos_token_id = text_config["bos_token_id"] + self.eos_token_id = text_config["eos_token_id"] + self.pad_token_id = text_config["pad_token_id"] + self.hidden_size = text_config["hidden_size"] + self.intermediate_size = text_config["intermediate_size"] + self.num_hidden_layers = text_config["num_hidden_layers"] + self.num_attention_heads = text_config["num_attention_heads"] + self.num_key_value_heads = text_config["num_key_value_heads"] + self.rope_theta = text_config["rope_theta"] + self.rope_scaling = text_config["rope_scaling"] + self.hidden_act = text_config["hidden_act"] + self.max_position_embeddings = text_config["max_position_embeddings"] + self.model_type = text_config["model_type"] + + self.vision_start_token_id = vision_start_token_id + self.vision_end_token_id = vision_end_token_id + self.image_token_id = image_token_id + self.video_token_id = video_token_id + self.tie_word_embeddings = tie_word_embeddings + + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.num_image_tokens = 32 + self.seq_length = seq_length + self.num_image_tokens + + def get_config(self): + return Qwen3VLMoeConfig( + text_config=self.text_config, + vision_config=self.vision_config, + image_token_id=self.image_token_id, + video_token_id=self.video_token_id, + vision_start_token_id=self.vision_start_token_id, + vision_end_token_id=self.vision_end_token_id, + tie_word_embeddings=self.tie_word_embeddings, + ) + + def prepare_config_and_inputs(self): + config = self.get_config() + patch_size = config.vision_config.patch_size + temporal_patch_size = config.vision_config.temporal_patch_size + pixel_values = floats_tensor( + [ + self.batch_size * (self.image_size**2) // (patch_size**2), + self.num_channels * (patch_size**2) * temporal_patch_size, + ] + ) + + return config, pixel_values + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values = config_and_inputs + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + attention_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + + input_ids[:, -1] = self.pad_token_id + input_ids[input_ids == self.video_token_id] = self.pad_token_id + input_ids[input_ids == self.image_token_id] = self.pad_token_id + input_ids[input_ids == self.vision_start_token_id] = self.pad_token_id + input_ids[:, self.num_image_tokens] = self.image_token_id + input_ids[:, self.num_image_tokens - 1] = self.vision_start_token_id + inputs_dict = { + "pixel_values": pixel_values, + "image_grid_thw": torch.tensor([[1, 1, 1]] * self.batch_size, device=torch_device), + "input_ids": input_ids, + "attention_mask": attention_mask, + } + return config, inputs_dict + + +@require_torch +class Qwen3VLMoeModelTest(ModelTesterMixin, GenerationTesterMixin, unittest.TestCase): + """ + Model tester for `Qwen3VLMoeForConditionalGeneration`. + """ + + all_model_classes = ( + ( + Qwen3VLMoeModel, + Qwen3VLMoeForConditionalGeneration, + ) + if is_torch_available() + else () + ) + test_pruning = False + test_head_masking = False + + def setUp(self): + self.model_tester = Qwen3VLMoeVisionText2TextModelTester(self) + self.config_tester = ConfigTester(self, config_class=Qwen3VLMoeConfig, has_text_modality=False) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_mismatching_num_image_tokens(self): + """ + Tests that VLMs through an error with explicit message saying what is wrong + when number of images don't match number of image tokens in the text. + Also we need to test multi-image cases when one prompr has multiple image tokens. + """ + config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + model = model_class(config).to(torch_device) + _ = model(**input_dict) # successful forward with no modifications + curr_input_dict = copy.deepcopy(input_dict) + + # remove one image but leave the image token in text + patch_size = config.vision_config.patch_size + one_img_length = (self.model_tester.image_size**2) // (patch_size**2) + curr_input_dict["pixel_values"] = curr_input_dict["pixel_values"][-one_img_length:, ...] + curr_input_dict["image_grid_thw"] = curr_input_dict["image_grid_thw"][-1:, ...] + with self.assertRaises(ValueError): + _ = model(**curr_input_dict) + + # simulate multi-image case by concatenating inputs where each has exactly one image/image-token + input_ids = curr_input_dict["input_ids"][:1] + pixel_values = curr_input_dict["pixel_values"][:one_img_length] + image_grid_thw = curr_input_dict["image_grid_thw"][:1] + input_ids = torch.cat([input_ids, input_ids], dim=0) + + # one image and two image tokens raise an error + with self.assertRaises(ValueError): + _ = model( + input_ids=input_ids, + pixel_values=pixel_values, + image_grid_thw=image_grid_thw, + ) + + # two images and two image tokens don't raise an error + pixel_values = torch.cat([pixel_values, pixel_values], dim=0) + image_grid_thw = torch.cat([image_grid_thw, image_grid_thw], dim=0) + _ = model( + input_ids=input_ids, + pixel_values=pixel_values, + image_grid_thw=image_grid_thw, + ) + + def test_video_forward(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + B = self.model_tester.batch_size + C = config.vision_config.in_chans + T = config.vision_config.temporal_patch_size + P = config.vision_config.patch_size + + input_ids = ids_tensor([B, self.model_tester.seq_length], self.model_tester.vocab_size) + + F = 4 + patch_H = self.model_tester.image_size // P + patch_W = self.model_tester.image_size // P + patch_T = F // T + patches_per_video = patch_T * patch_H * patch_W + pathed_per_frame = patch_H * patch_W + pixel_values_videos = floats_tensor( + [ + # first dim: batch_size * num_patches + B * patches_per_video, + # second dim: in_channels * temporal_patch_size * patch_size^2 + C * T * (P**2), + ] + ) + video_grid_thw = torch.tensor([[1, patch_H, patch_W] for _ in range(patch_T)] * B) + + # sanity check + self.assertEqual(pixel_values_videos.shape[0], video_grid_thw.prod(dim=1).sum().item()) + + # Insert video token sequence + input_ids[:, -1] = self.model_tester.pad_token_id + input_ids[input_ids == self.model_tester.video_token_id] = self.model_tester.pad_token_id + input_ids[input_ids == self.model_tester.image_token_id] = self.model_tester.pad_token_id + input_ids[input_ids == self.model_tester.vision_start_token_id] = self.model_tester.pad_token_id + input_ids[:, self.model_tester.num_image_tokens] = self.model_tester.video_token_id + + insertion_point = self.model_tester.num_image_tokens + + self.assertLessEqual((B * patches_per_video) + insertion_point, self.model_tester.seq_length) + for b in range(B): + # each frame is separated by a vision_start_token_id + for frame_idx in range(patch_T): + input_ids[b, insertion_point + frame_idx * (pathed_per_frame + 1)] = ( + self.model_tester.vision_start_token_id + ) + input_ids[ + b, + insertion_point + frame_idx * (pathed_per_frame + 1) + 1 : insertion_point + + (frame_idx + 1) * (pathed_per_frame + 1), + ] = self.model_tester.video_token_id + + for model_class in self.all_model_classes: + # TODO:we should remove this because we use timestamps for video + model = model_class(config).to(torch_device) + outputs = model( + input_ids=input_ids, + pixel_values_videos=pixel_values_videos, + video_grid_thw=video_grid_thw, + ) + self.assertIsNotNone(outputs) diff --git a/utils/check_repo.py b/utils/check_repo.py index 8a73468a1e49..e932e5bfc24c 100644 --- a/utils/check_repo.py +++ b/utils/check_repo.py @@ -71,6 +71,8 @@ "Qwen2AudioEncoder", "Qwen2VisionTransformerPretrainedModel", "Qwen2_5_VisionTransformerPretrainedModel", + "Qwen3VLVisionModel", + "Qwen3VLMoeVisionModel", "SwitchTransformersStack", "TFDPRSpanPredictor", "MaskFormerSwinModel", @@ -151,13 +153,17 @@ "ChameleonVQVAE", # VQVAE here is used only for encoding (discretizing) and is tested as part of bigger model "Qwen2VLModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2VLForConditionalGeneration. "Qwen2_5_VLModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5_VLForConditionalGeneration. - "Qwen2_5OmniForConditionalGeneration", # Not a regular model. Testted in Qwen2_5OmniModelIntegrationTest - "Qwen2_5OmniTalkerForConditionalGeneration", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntegrationTest. - "Qwen2_5OmniTalkerModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntegrationTest. - "Qwen2_5OmniThinkerTextModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntegrationTest. - "Qwen2_5OmniToken2WavModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntegrationTest. - "Qwen2_5OmniToken2WavDiTModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntegrationTest. - "Qwen2_5OmniToken2WavBigVGANModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntegrationTest. + "Qwen3VLModel", # Building part of bigger (tested) model. Tested implicitly through Qwen3VLForConditionalGeneration. + "Qwen3VLMoeModel", # Building part of bigger (tested) model. Tested implicitly through Qwen3VLMoeForConditionalGeneration. + "Qwen3VLTextModel", # Building part of bigger (tested) model. + "Qwen3VLMoeTextModel", # Building part of bigger (tested) model. + "Qwen2_5OmniForConditionalGeneration", # Not a regular model. Testted in Qwen2_5OmniModelIntergrationTest + "Qwen2_5OmniTalkerForConditionalGeneration", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntergrationTest. + "Qwen2_5OmniTalkerModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntergrationTest. + "Qwen2_5OmniThinkerTextModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntergrationTest. + "Qwen2_5OmniToken2WavModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntergrationTest. + "Qwen2_5OmniToken2WavDiTModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntergrationTest. + "Qwen2_5OmniToken2WavBigVGANModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntergrationTest. "MllamaTextModel", # Building part of bigger (tested) model. # TODO: add tests "MllamaVisionModel", # Building part of bigger (tested) model. # TODO: add tests "Llama4TextModel", # Building part of bigger (tested) model. # TODO: add tests From f8b33110193395389decbbc542c94f408d35933f Mon Sep 17 00:00:00 2001 From: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:46:30 +0200 Subject: [PATCH 047/204] [`VaultGemma`] Update expectations in integration tests (#40855) * fix tests * style --- .../vaultgemma/test_modeling_vaultgemma.py | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/tests/models/vaultgemma/test_modeling_vaultgemma.py b/tests/models/vaultgemma/test_modeling_vaultgemma.py index 548cfd3f57f0..3d40eed91ac9 100644 --- a/tests/models/vaultgemma/test_modeling_vaultgemma.py +++ b/tests/models/vaultgemma/test_modeling_vaultgemma.py @@ -107,8 +107,8 @@ def tearDown(self): def test_model_bf16(self): model_id = "google/vaultgemma-1b" EXPECTED_TEXTS = [ - "Hello I am doing a project on the 1918 flu pandemic and I am trying to find out how many", - "Hi today I'm going to be talking about the history of the United States. The United States of America", + "Hello I am doing a project on a 1990 240sx. I have a 1", + "Hi today I am going to show you how to make a simple 3D model of a 3D", ] model = AutoModelForCausalLM.from_pretrained(model_id, dtype=torch.bfloat16, attn_implementation="eager").to( @@ -128,13 +128,11 @@ def test_model_pipeline_bf16(self): model_id = "google/vaultgemma-1b" # EXPECTED_TEXTS should match the same non-pipeline test, minus the special tokens EXPECTED_TEXTS = [ - "Hello I am doing a project on the 1918 flu pandemic and I am trying to find out how many", - "Hi today I'm going to be talking about the history of the United States. The United States of America", + "Hello I am doing a project on a 1990 240sx. I have a 1", + "Hi today I am going to show you how to make a simple 3D model of a 3D", ] - model = AutoModelForCausalLM.from_pretrained( - model_id, dtype=torch.bfloat16, attn_implementation="flex_attention" - ).to(torch_device) + model = AutoModelForCausalLM.from_pretrained(model_id, dtype=torch.bfloat16).to(torch_device) tokenizer = AutoTokenizer.from_pretrained(model_id) pipe = pipeline("text-generation", model=model, tokenizer=tokenizer) @@ -158,18 +156,7 @@ def test_export_static_cache(self): tokenizer = AutoTokenizer.from_pretrained(model_id, pad_token="", padding_side="right") EXPECTED_TEXT_COMPLETIONS = Expectations( { - ("xpu", 3): [ - "Hello I am doing a project for my school and I need to know how to make a program that will take a number" - ], - ("cuda", 7): [ - "Hello I am doing a project for my school and I need to know how to make a program that will take a number" - ], - ("cuda", 8): [ - "Hello I am doing a project for my class and I am having trouble with the code. I am trying to make a" - ], - ("rocm", (9, 5)): [ - "Hello I am doing a project for my school and I need to know how to make a program that will take a number" - ], + ("cuda", 8): ["Hello I am doing a project on a 1990 240sx. I have a 1"], } ) EXPECTED_TEXT_COMPLETION = EXPECTED_TEXT_COMPLETIONS.get_expectation() @@ -239,8 +226,8 @@ def test_generation_beyond_sliding_window(self, attn_implementation: str): model_id = "google/vaultgemma-1b" EXPECTED_COMPLETIONS = [ - " the people, the food, the culture, the history, the music, the art, the architecture", - ", green, yellow, orange, purple, pink, brown, black, white, gray, silver", + " place pretty place pretty place. place pretty place pretty place. place pretty place pretty place. place pretty", + ", green, yellow, orange, purple, black, white, and gray.\n\nA list of", ] input_text = [ @@ -285,8 +272,8 @@ def test_generation_beyond_sliding_window_dynamic(self, attn_implementation: str model_id = "google/vaultgemma-1b" EXPECTED_COMPLETIONS = [ - " the people, the food, the culture, the history, the music, the art, the architecture", - ", green, yellow, orange, purple, pink, brown, black, white, gray, silver", + " place pretty place pretty place. place pretty place pretty place. place pretty place pretty place. place pretty", + ", green, yellow, orange, purple, black, white, and gray.\n\nA list of", ] input_text = [ From dd64685cf12902eb2ac1aa79cc4e1fe9b376e998 Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Mon, 15 Sep 2025 13:07:08 +0200 Subject: [PATCH 048/204] Fix modular consistency (#40883) * reapply modular * add missing one --- .../models/qwen3_vl/modeling_qwen3_vl.py | 12 +++++------- .../models/qwen3_vl/modular_qwen3_vl.py | 2 +- .../models/qwen3_vl_moe/modeling_qwen3_vl_moe.py | 16 +++++++--------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/transformers/models/qwen3_vl/modeling_qwen3_vl.py b/src/transformers/models/qwen3_vl/modeling_qwen3_vl.py index a18366a2a534..d3bc3b6b044f 100644 --- a/src/transformers/models/qwen3_vl/modeling_qwen3_vl.py +++ b/src/transformers/models/qwen3_vl/modeling_qwen3_vl.py @@ -528,8 +528,7 @@ def forward( class Qwen3VLModelOutputWithPast(ModelOutput): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -538,7 +537,7 @@ class Qwen3VLModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -1255,8 +1254,7 @@ class Qwen3VLCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1266,7 +1264,7 @@ class Qwen3VLCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -1322,7 +1320,7 @@ def forward( input_ids: torch.LongTensor = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, pixel_values: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py index ae608e81a05d..7a2fa852739e 100644 --- a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py +++ b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py @@ -1156,7 +1156,7 @@ def forward( input_ids: torch.LongTensor = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, pixel_values: Optional[torch.Tensor] = None, diff --git a/src/transformers/models/qwen3_vl_moe/modeling_qwen3_vl_moe.py b/src/transformers/models/qwen3_vl_moe/modeling_qwen3_vl_moe.py index 74b793f096f3..08c647ea50ac 100644 --- a/src/transformers/models/qwen3_vl_moe/modeling_qwen3_vl_moe.py +++ b/src/transformers/models/qwen3_vl_moe/modeling_qwen3_vl_moe.py @@ -348,7 +348,7 @@ def forward( position_embeddings: tuple[torch.Tensor, torch.Tensor], attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[tuple[torch.Tensor]] = None, + past_key_values: Optional[Cache] = None, cache_position: Optional[torch.LongTensor] = None, **kwargs: Unpack[FlashAttentionKwargs], ) -> torch.FloatTensor: @@ -366,7 +366,7 @@ def forward( use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). - past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + past_key_values (`Cache`, *optional*): cached past key and value projection states cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): Indices depicting the position of the input sequence tokens in the sequence. position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): @@ -1011,8 +1011,7 @@ def _deepstack_process( class Qwen3VLMoeModelOutputWithPast(ModelOutput): r""" past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1021,7 +1020,7 @@ class Qwen3VLMoeModelOutputWithPast(ModelOutput): """ last_hidden_state: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -1398,8 +1397,7 @@ class Qwen3VLMoeCausalLMOutputWithPast(ModelOutput): logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. @@ -1409,7 +1407,7 @@ class Qwen3VLMoeCausalLMOutputWithPast(ModelOutput): loss: Optional[torch.FloatTensor] = None logits: Optional[torch.FloatTensor] = None - past_key_values: Optional[list[torch.FloatTensor]] = None + past_key_values: Optional[Cache] = None hidden_states: Optional[tuple[torch.FloatTensor]] = None attentions: Optional[tuple[torch.FloatTensor]] = None rope_deltas: Optional[torch.LongTensor] = None @@ -1465,7 +1463,7 @@ def forward( input_ids: torch.LongTensor = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, - past_key_values: Optional[list[torch.FloatTensor]] = None, + past_key_values: Optional[Cache] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, pixel_values: Optional[torch.Tensor] = None, From d8a69ff72d4a611720cd11774edc43f2885b4fb6 Mon Sep 17 00:00:00 2001 From: Manuel de Prada Corral <6536835+manueldeprada@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:08:00 +0200 Subject: [PATCH 049/204] =?UTF-8?q?=F0=9F=94=B4=20Move=20variable=20output?= =?UTF-8?q?=20controls=20to=20`=5Fprepare=5Fgeneration=5Fconfig=20`=20(#40?= =?UTF-8?q?715)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * move checks to validate steps where possible * fix csm and other models that override _sample * ops dia you again * opsie * joao review * Move variable output controls to `prepare_inputs_for_generation` * fix a bunch of models * back to basics * final touches --- src/transformers/generation/utils.py | 25 ++++++------- .../models/bamba/modeling_bamba.py | 6 ++++ .../models/bamba/modular_bamba.py | 6 ++++ .../models/bloom/modeling_bloom.py | 6 ++++ src/transformers/models/ctrl/modeling_ctrl.py | 12 ++++++- .../models/falcon_h1/modeling_falcon_h1.py | 6 ++++ .../models/falcon_h1/modular_falcon_h1.py | 6 ++++ .../falcon_mamba/modeling_falcon_mamba.py | 6 ++++ src/transformers/models/git/modeling_git.py | 9 ++++- .../modeling_granitemoehybrid.py | 6 ++++ .../modular_granitemoehybrid.py | 6 ++++ .../models/jamba/modeling_jamba.py | 6 ++++ .../models/kosmos2_5/modeling_kosmos2_5.py | 9 ++++- .../models/mamba/modeling_mamba.py | 6 ++++ .../models/mamba2/modeling_mamba2.py | 6 ++++ .../models/moshi/modeling_moshi.py | 7 +++- .../models/openai/modeling_openai.py | 9 ++++- .../models/prophetnet/modeling_prophetnet.py | 12 ++++++- .../models/reformer/modeling_reformer.py | 12 +++++-- src/transformers/models/rwkv/modeling_rwkv.py | 6 ++++ src/transformers/models/xlm/modeling_xlm.py | 13 ++++++- .../xlm_roberta_xl/modeling_xlm_roberta_xl.py | 12 ++++++- .../models/xlnet/modeling_xlnet.py | 17 ++++++--- .../models/xlstm/modeling_xlstm.py | 6 ++++ .../models/zamba/modeling_zamba.py | 6 ++++ .../models/zamba2/modeling_zamba2.py | 6 ++++ tests/generation/test_utils.py | 35 +++++++++++++++++++ tests/models/dia/test_modeling_dia.py | 4 +++ tests/models/moshi/test_modeling_moshi.py | 8 +++++ 29 files changed, 246 insertions(+), 28 deletions(-) diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index a885a4c716e6..c800f7888c37 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -46,6 +46,7 @@ from ..tokenization_utils import ExtensionsTrie from ..utils import ( ModelOutput, + TransformersKwargs, is_accelerate_available, is_hqq_available, is_optimum_quanto_available, @@ -560,8 +561,9 @@ def prepare_inputs_for_generation( **kwargs, ): """ - Prepare the model inputs for generation. It includes operations like computing the 4D attention mask or - slicing inputs given the existing cache. + Prepare the model inputs for generation. Notable steps include selecting the correct input key and cloning when appropriate, + creating position_ids from the attention_mask when missing, slicing inputs and converting 2D attention masks to 4D for + compilable caches, and finally forwarding all additional keyword arguments unchanged to the model's forward pass. See the forward pass in the model documentation for expected arguments (different models might have different requirements for e.g. `past_key_values`). This function should work as is for most LLMs. @@ -1596,8 +1598,9 @@ def _validate_model_kwargs(self, model_kwargs: dict[str, Any]): decoder_model_args = set(inspect.signature(decoder.forward).parameters) model_args |= {f"decoder_{x}" for x in decoder_model_args} + # TransformersKwargs are model-agnostic attention and generation arguments such as 'output_attentions' for key, value in model_kwargs.items(): - if value is not None and key not in model_args: + if value is not None and key not in model_args and key not in TransformersKwargs.__optional_keys__: unused_model_args.append(key) if unused_model_args: @@ -1802,6 +1805,11 @@ def _prepare_generation_config( # Finally, apply any passed kwargs model_kwargs = generation_config.update(**kwargs) + # And keep in model_kwargs variable output controls + output_attentions = generation_config.output_attentions + output_hidden_states = generation_config.output_hidden_states + model_kwargs.update({"output_attentions": output_attentions} if output_attentions else {}) + model_kwargs.update({"output_hidden_states": output_hidden_states} if output_hidden_states else {}) return generation_config, model_kwargs @@ -2765,10 +2773,6 @@ def _sample( # prepare model inputs model_inputs = self.prepare_inputs_for_generation(input_ids, **model_kwargs) - # prepare variable output controls (note: some models won't accept all output controls) - model_inputs.update({"output_attentions": output_attentions} if output_attentions else {}) - model_inputs.update({"output_hidden_states": output_hidden_states} if output_hidden_states else {}) - if is_prefill: outputs = self(**model_inputs, return_dict=True) is_prefill = False @@ -3251,10 +3255,6 @@ def _beam_search( flat_running_sequences = self._flatten_beam_dim(running_sequences[:, :, :cur_len]) model_inputs = self.prepare_inputs_for_generation(flat_running_sequences, **model_kwargs) - # prepare variable output controls (note: some models won't accept all output controls) - model_inputs.update({"output_attentions": output_attentions} if output_attentions else {}) - model_inputs.update({"output_hidden_states": output_hidden_states} if output_hidden_states else {}) - model_outputs = self(**model_inputs, return_dict=True) # synced_gpus: don't waste resources running the code we don't need; kwargs must be updated before skipping @@ -3579,9 +3579,6 @@ def _assisted_decoding( model_inputs["logits_to_keep"] = candidate_length + 1 # 2.2. Run a forward pass on the candidate sequence - # prepare variable output controls (note: some models won't accept all output controls) - model_inputs.update({"output_attentions": output_attentions} if output_attentions else {}) - model_inputs.update({"output_hidden_states": output_hidden_states} if output_hidden_states else {}) outputs = self(**model_inputs) diff --git a/src/transformers/models/bamba/modeling_bamba.py b/src/transformers/models/bamba/modeling_bamba.py index f5e337e52ebd..09f00845524d 100644 --- a/src/transformers/models/bamba/modeling_bamba.py +++ b/src/transformers/models/bamba/modeling_bamba.py @@ -1492,6 +1492,12 @@ def prepare_inputs_for_generation( "cache_position": cache_position, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs diff --git a/src/transformers/models/bamba/modular_bamba.py b/src/transformers/models/bamba/modular_bamba.py index aec09861de81..52814930a172 100644 --- a/src/transformers/models/bamba/modular_bamba.py +++ b/src/transformers/models/bamba/modular_bamba.py @@ -1211,6 +1211,12 @@ def prepare_inputs_for_generation( "cache_position": cache_position, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs diff --git a/src/transformers/models/bloom/modeling_bloom.py b/src/transformers/models/bloom/modeling_bloom.py index 699a177fc6c1..605ae4f59b63 100644 --- a/src/transformers/models/bloom/modeling_bloom.py +++ b/src/transformers/models/bloom/modeling_bloom.py @@ -818,6 +818,12 @@ def prepare_inputs_for_generation( "attention_mask": attention_mask, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs @auto_docstring diff --git a/src/transformers/models/ctrl/modeling_ctrl.py b/src/transformers/models/ctrl/modeling_ctrl.py index e20fffede948..506bed039b17 100644 --- a/src/transformers/models/ctrl/modeling_ctrl.py +++ b/src/transformers/models/ctrl/modeling_ctrl.py @@ -570,7 +570,17 @@ def prepare_inputs_for_generation(self, input_ids, past_key_values=None, use_cac input_ids = input_ids[:, remove_prefix_length:] - return {"input_ids": input_ids, "past_key_values": past_key_values, "use_cache": use_cache} + model_inputs = {"input_ids": input_ids, "past_key_values": past_key_values, "use_cache": use_cache} + + # token_type_ids are computed on CTRLModel.forward() + kwargs.pop("token_type_ids", None) + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + print(f"Warning: {key} is not a recognized input.") + model_inputs[key] = value + + return model_inputs @auto_docstring( diff --git a/src/transformers/models/falcon_h1/modeling_falcon_h1.py b/src/transformers/models/falcon_h1/modeling_falcon_h1.py index 865daf384b49..5f08309b2085 100644 --- a/src/transformers/models/falcon_h1/modeling_falcon_h1.py +++ b/src/transformers/models/falcon_h1/modeling_falcon_h1.py @@ -1607,6 +1607,12 @@ def prepare_inputs_for_generation( "cache_position": cache_position, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs diff --git a/src/transformers/models/falcon_h1/modular_falcon_h1.py b/src/transformers/models/falcon_h1/modular_falcon_h1.py index 8b00de3ab97f..c81e8967bcf2 100644 --- a/src/transformers/models/falcon_h1/modular_falcon_h1.py +++ b/src/transformers/models/falcon_h1/modular_falcon_h1.py @@ -1372,6 +1372,12 @@ def prepare_inputs_for_generation( "cache_position": cache_position, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs diff --git a/src/transformers/models/falcon_mamba/modeling_falcon_mamba.py b/src/transformers/models/falcon_mamba/modeling_falcon_mamba.py index dc593c979dc7..3cdf6da7bda3 100644 --- a/src/transformers/models/falcon_mamba/modeling_falcon_mamba.py +++ b/src/transformers/models/falcon_mamba/modeling_falcon_mamba.py @@ -862,6 +862,12 @@ def prepare_inputs_for_generation( "attention_mask": attention_mask, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs @auto_docstring diff --git a/src/transformers/models/git/modeling_git.py b/src/transformers/models/git/modeling_git.py index cdd0f622bd86..0125132718a3 100644 --- a/src/transformers/models/git/modeling_git.py +++ b/src/transformers/models/git/modeling_git.py @@ -1442,7 +1442,7 @@ def prepare_inputs_for_generation( if attention_mask is None: attention_mask = input_ids.new_ones(input_shape) - return { + model_inputs = { "input_ids": input_ids, "attention_mask": attention_mask, "pixel_values": kwargs.get("pixel_values"), @@ -1450,5 +1450,12 @@ def prepare_inputs_for_generation( "use_cache": use_cache, } + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + + return model_inputs + __all__ = ["GitForCausalLM", "GitModel", "GitPreTrainedModel", "GitVisionModel"] diff --git a/src/transformers/models/granitemoehybrid/modeling_granitemoehybrid.py b/src/transformers/models/granitemoehybrid/modeling_granitemoehybrid.py index f35211558bf7..7f9883779c43 100644 --- a/src/transformers/models/granitemoehybrid/modeling_granitemoehybrid.py +++ b/src/transformers/models/granitemoehybrid/modeling_granitemoehybrid.py @@ -1829,6 +1829,12 @@ def prepare_inputs_for_generation( "cache_position": cache_position, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs diff --git a/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py b/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py index 2ebddb88e316..55ad2b43c1bb 100644 --- a/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py +++ b/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py @@ -383,6 +383,12 @@ def prepare_inputs_for_generation( "cache_position": cache_position, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs diff --git a/src/transformers/models/jamba/modeling_jamba.py b/src/transformers/models/jamba/modeling_jamba.py index f604ffd3b72e..17246d6f1b2e 100755 --- a/src/transformers/models/jamba/modeling_jamba.py +++ b/src/transformers/models/jamba/modeling_jamba.py @@ -1448,6 +1448,12 @@ def prepare_inputs_for_generation( "cache_position": cache_position, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs diff --git a/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py b/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py index 51357a57726c..1bb70fd5093d 100644 --- a/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py +++ b/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py @@ -1642,7 +1642,7 @@ def prepare_inputs_for_generation( dim=1, ) - return { + model_inputs = { "input_ids": input_ids, "image_embeds": image_embeds, "image_embeds_position_mask": image_embeds_position_mask, @@ -1652,6 +1652,13 @@ def prepare_inputs_for_generation( "use_cache": use_cache, } + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in model_kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + + return model_inputs + @add_start_docstrings( """ diff --git a/src/transformers/models/mamba/modeling_mamba.py b/src/transformers/models/mamba/modeling_mamba.py index 10616323e13f..4a53c47c8b4a 100644 --- a/src/transformers/models/mamba/modeling_mamba.py +++ b/src/transformers/models/mamba/modeling_mamba.py @@ -803,6 +803,12 @@ def prepare_inputs_for_generation( "attention_mask": attention_mask, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs @auto_docstring diff --git a/src/transformers/models/mamba2/modeling_mamba2.py b/src/transformers/models/mamba2/modeling_mamba2.py index 85cf026e49d0..738c5376c33e 100644 --- a/src/transformers/models/mamba2/modeling_mamba2.py +++ b/src/transformers/models/mamba2/modeling_mamba2.py @@ -989,6 +989,12 @@ def prepare_inputs_for_generation( "attention_mask": attention_mask, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs @auto_docstring diff --git a/src/transformers/models/moshi/modeling_moshi.py b/src/transformers/models/moshi/modeling_moshi.py index 868d050db5c9..503177f95b4a 100644 --- a/src/transformers/models/moshi/modeling_moshi.py +++ b/src/transformers/models/moshi/modeling_moshi.py @@ -2242,7 +2242,7 @@ def prepare_inputs_for_generation( # we want to do it after a first token has been generated if model_inputs["input_ids"] is not None: - last_hidden_state = kwargs.get("last_hidden_state") + last_hidden_state = kwargs.pop("last_hidden_state") # (batch_size, sequence_length, dim) -> (batch_size * sequence_length, 1, dim) last_hidden_state = last_hidden_state.view(-1, 1, last_hidden_state.shape[-1]) @@ -2274,6 +2274,11 @@ def prepare_inputs_for_generation( model_inputs["input_ids"] = None model_inputs["inputs_embeds"] = inputs_embeds + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs def _update_model_kwargs_for_generation( diff --git a/src/transformers/models/openai/modeling_openai.py b/src/transformers/models/openai/modeling_openai.py index 27c84910cb43..44fa05227ff8 100644 --- a/src/transformers/models/openai/modeling_openai.py +++ b/src/transformers/models/openai/modeling_openai.py @@ -602,7 +602,14 @@ def forward( def prepare_inputs_for_generation(self, input_ids: torch.LongTensor, **kwargs) -> dict[str, Any]: # Overwritten -- old model with reduced inputs - return {"input_ids": input_ids} + model_inputs = {"input_ids": input_ids} + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + + return model_inputs @auto_docstring( diff --git a/src/transformers/models/prophetnet/modeling_prophetnet.py b/src/transformers/models/prophetnet/modeling_prophetnet.py index d69bb7d9c802..5e80ee4f0faa 100644 --- a/src/transformers/models/prophetnet/modeling_prophetnet.py +++ b/src/transformers/models/prophetnet/modeling_prophetnet.py @@ -2006,7 +2006,7 @@ def prepare_inputs_for_generation( if past_key_values is not None and past_key_values.get_seq_length() > 0: input_ids = input_ids[:, -1:] # first step, decoder_cached_states are empty - return { + model_inputs = { "input_ids": input_ids, # encoder_outputs is defined. input_ids not needed "attention_mask": attention_mask, "head_mask": head_mask, @@ -2014,6 +2014,16 @@ def prepare_inputs_for_generation( "use_cache": use_cache, } + # Prophetnet does not support cache_position + kwargs.pop("cache_position", None) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + + return model_inputs + class ProphetNetDecoderWrapper(ProphetNetPreTrainedModel): """ diff --git a/src/transformers/models/reformer/modeling_reformer.py b/src/transformers/models/reformer/modeling_reformer.py index 367af6692357..990f21359bc0 100755 --- a/src/transformers/models/reformer/modeling_reformer.py +++ b/src/transformers/models/reformer/modeling_reformer.py @@ -2345,14 +2345,22 @@ def prepare_inputs_for_generation( if past_key_values is not None: input_ids = input_ids[:, -1:] - inputs_dict = { + model_inputs = { "input_ids": input_ids, "past_buckets_states": past_key_values, "use_cache": use_cache, "num_hashes": num_hashes, } - return inputs_dict + # Attention mask is computed on ReformerModel.forward() + kwargs.pop("attention_mask", None) + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + print(f"Warning: {key} is not a recognized input.") + model_inputs[key] = value + + return model_inputs def _reorder_cache(self, past_key_values, beam_idx): reord_past_buckets_states = [] diff --git a/src/transformers/models/rwkv/modeling_rwkv.py b/src/transformers/models/rwkv/modeling_rwkv.py index 0b16af278946..d86d4d0f8707 100644 --- a/src/transformers/models/rwkv/modeling_rwkv.py +++ b/src/transformers/models/rwkv/modeling_rwkv.py @@ -719,6 +719,12 @@ def prepare_inputs_for_generation(self, input_ids, state=None, inputs_embeds=Non model_inputs["state"] = state model_inputs["use_cache"] = use_cache + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs @auto_docstring diff --git a/src/transformers/models/xlm/modeling_xlm.py b/src/transformers/models/xlm/modeling_xlm.py index 4e7316fb781b..a73b4a51cea4 100755 --- a/src/transformers/models/xlm/modeling_xlm.py +++ b/src/transformers/models/xlm/modeling_xlm.py @@ -994,7 +994,18 @@ def prepare_inputs_for_generation(self, input_ids, **kwargs): langs = torch.full_like(input_ids, lang_id) else: langs = None - return {"input_ids": input_ids, "langs": langs} + model_inputs = {"input_ids": input_ids, "langs": langs} + + # They are calculated on the fly on XLMModel.forward() + kwargs.pop("token_type_ids", None) + kwargs.pop("attention_mask", None) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + + return model_inputs @auto_docstring def forward( diff --git a/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py b/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py index 067f58ab93c6..99b925015a71 100644 --- a/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py +++ b/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py @@ -1013,13 +1013,23 @@ def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attenti if position_ids is not None: position_ids = position_ids[:, remove_prefix_length:] - return { + model_inputs = { "input_ids": input_ids, "attention_mask": attention_mask, "position_ids": position_ids, "past_key_values": past_key_values, } + # They are calculated on the fly on XLMRobertaXLModel.forward() + model_kwargs.pop("token_type_ids", None) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in model_kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + + return model_inputs + @auto_docstring class XLMRobertaXLForMaskedLM(XLMRobertaXLPreTrainedModel): diff --git a/src/transformers/models/xlnet/modeling_xlnet.py b/src/transformers/models/xlnet/modeling_xlnet.py index 736521ee9561..0c6b9f76eade 100755 --- a/src/transformers/models/xlnet/modeling_xlnet.py +++ b/src/transformers/models/xlnet/modeling_xlnet.py @@ -1472,7 +1472,7 @@ def prepare_inputs_for_generation(self, input_ids, past_key_values=None, use_mem ) target_mapping[:, 0, -1] = 1.0 - inputs = { + model_inputs = { "input_ids": input_ids, "perm_mask": perm_mask, "target_mapping": target_mapping, @@ -1481,9 +1481,18 @@ def prepare_inputs_for_generation(self, input_ids, past_key_values=None, use_mem # if past is defined in model kwargs then use it for faster decoding if past_key_values: - inputs["mems"] = tuple(layer_past[:-offset, :, :] for layer_past in past_key_values) - - return inputs + model_inputs["mems"] = tuple(layer_past[:-offset, :, :] for layer_past in past_key_values) + + # Attention mask is computed on the fly on XLNetModel.forward() + kwargs.pop("attention_mask", None) + # TODO: Ignoring use_cache should not happen, fixme. + kwargs.pop("use_cache", None) + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + + return model_inputs @auto_docstring def forward( diff --git a/src/transformers/models/xlstm/modeling_xlstm.py b/src/transformers/models/xlstm/modeling_xlstm.py index b77ec26d2b31..7e2fce997683 100644 --- a/src/transformers/models/xlstm/modeling_xlstm.py +++ b/src/transformers/models/xlstm/modeling_xlstm.py @@ -1556,6 +1556,12 @@ def prepare_inputs_for_generation( model_inputs = {"input_ids": input_ids} model_inputs.update({"cache_params": cache_params, "use_cache": use_cache}) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs @can_return_tuple diff --git a/src/transformers/models/zamba/modeling_zamba.py b/src/transformers/models/zamba/modeling_zamba.py index 9c0f86ea4489..2f9edb1e113c 100644 --- a/src/transformers/models/zamba/modeling_zamba.py +++ b/src/transformers/models/zamba/modeling_zamba.py @@ -1185,6 +1185,12 @@ def prepare_inputs_for_generation( "cache_position": cache_position, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs diff --git a/src/transformers/models/zamba2/modeling_zamba2.py b/src/transformers/models/zamba2/modeling_zamba2.py index ddd4f6f69079..33e7e4b5a351 100644 --- a/src/transformers/models/zamba2/modeling_zamba2.py +++ b/src/transformers/models/zamba2/modeling_zamba2.py @@ -1606,6 +1606,12 @@ def prepare_inputs_for_generation( "cache_position": cache_position, } ) + + # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). + for key, value in kwargs.items(): + if key not in model_inputs: + model_inputs[key] = value + return model_inputs diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index dbeade214410..3b828cd8313a 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -1803,6 +1803,41 @@ def test_inherits_generation_mixin(self): for model_class in self.all_generative_model_classes: self.assertTrue("GenerationMixin" in str(model_class.__bases__)) + @pytest.mark.generate + def test_prepare_inputs_for_generation_kwargs_forwards(self, **extra_kwargs): + """Tests that prepare_inputs_for_generation forwards arbitrary kwargs.""" + for model_class in self.all_generative_model_classes: + config, _ = self.prepare_config_and_inputs_for_generate() + + model = model_class(config).to(torch_device).eval() + + input_ids = torch.tensor([[1, 2, 3], [4, 5, 6]]).to(torch_device) + + input_args = { + "input_ids": input_ids, + "cache_position": torch.tensor([9]).to(torch_device), + "position_ids": torch.tensor([[0, 1, 2], [0, 1, 2]]).to(torch_device), + } + arbitrary_kwargs = { + "output_attentions": True, + "output_hidden_states": True, + "custom_arg": "test_value", + "numeric_arg": 42, + } + + model_inputs = model.prepare_inputs_for_generation(**input_args, **arbitrary_kwargs, **extra_kwargs) + + # Verify that input_ids has proper name + if config.is_encoder_decoder: + self.assertTrue("decoder_input_ids" in model_inputs) + else: + self.assertTrue("input_ids" in model_inputs) + + # Verify that arbitrary kwargs are forwarded + for key, value in arbitrary_kwargs.items(): + self.assertTrue(key in model_inputs) + self.assertTrue(model_inputs[key] == value) + def _test_attention_implementation(self, attn_implementation): """ Compares the output of generate with the eager attention implementation against other implementations. diff --git a/tests/models/dia/test_modeling_dia.py b/tests/models/dia/test_modeling_dia.py index 989608d686ea..5ac321c5a753 100644 --- a/tests/models/dia/test_modeling_dia.py +++ b/tests/models/dia/test_modeling_dia.py @@ -517,6 +517,10 @@ def test_generate_continue_from_past_key_values(self): ) ) + @pytest.mark.generate + def test_prepare_inputs_for_generation_kwargs_forwards(self): + super().test_prepare_inputs_for_generation_kwargs_forwards(encoder_outputs=torch.randn(2, 2, 32)) + @unittest.skip(reason="Indirectly checked in Dia through the generate methods.") def test_hidden_states_output(self): pass diff --git a/tests/models/moshi/test_modeling_moshi.py b/tests/models/moshi/test_modeling_moshi.py index 6df9393f8041..21f56e1bc56d 100644 --- a/tests/models/moshi/test_modeling_moshi.py +++ b/tests/models/moshi/test_modeling_moshi.py @@ -868,6 +868,14 @@ def test_generate_continue_from_inputs_embeds(self): def test_save_load(self): super().test_save_load() + @pytest.mark.generate + @unittest.skip(reason="Moshi requires setting `model.generated_audio_codes` in generate() before preparing inputs") + def test_prepare_inputs_for_generation_kwargs_forwards(self): + # If in the future `model.generated_audio_codes` is not required, this test can be re-enabled + super().test_prepare_inputs_for_generation_kwargs_forwards( + last_hidden_state=torch.randn(2, 3, 32), kwargs_depth_decoder={} + ) + def place_dict_on_device(dict_to_place, device): for key in dict_to_place: From 777b559b805ed5bb6169bad0227a58dfac95b21e Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 15 Sep 2025 19:51:22 +0800 Subject: [PATCH 050/204] Clarify passing is_causal in sdpa_attention_paged_forward (#40838) * Correctly pass is_causal in sdpa_attention_paged_forward Signed-off-by: Yuanyuan Chen * Improve typing Signed-off-by: Yuanyuan Chen * Add comment Signed-off-by: Yuanyuan Chen * Improve comments Signed-off-by: Yuanyuan Chen * Revert typing Signed-off-by: Yuanyuan Chen --------- Signed-off-by: Yuanyuan Chen --- src/transformers/integrations/sdpa_paged.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/integrations/sdpa_paged.py b/src/transformers/integrations/sdpa_paged.py index e6cbac418156..befa88f1406e 100644 --- a/src/transformers/integrations/sdpa_paged.py +++ b/src/transformers/integrations/sdpa_paged.py @@ -23,7 +23,6 @@ def sdpa_attention_paged_forward( attention_mask: Optional[torch.Tensor], dropout: float = 0.0, scaling: Optional[float] = None, - is_causal: Optional[bool] = None, **kwargs, ) -> tuple[torch.Tensor, None]: # Add KV cache to the key and value tensors @@ -58,6 +57,7 @@ def sdpa_attention_paged_forward( attn_mask=causal_mask, dropout_p=dropout, scale=scaling, + # Packed sequence format is used for input, so that it can never be causal. is_causal=False, ) attn_output = attn_output.transpose(1, 2).contiguous() From b13c6d8464667fd7a89fddb95f05a4857b39cb58 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 15 Sep 2025 19:54:14 +0800 Subject: [PATCH 051/204] Use torch.expm1 and torch.log1p for better numerical results (#40860) Signed-off-by: Yuanyuan Chen --- src/transformers/activations.py | 4 ++-- src/transformers/models/llama4/modeling_llama4.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transformers/activations.py b/src/transformers/activations.py index 60fd2adb8ef5..e9054f609a77 100644 --- a/src/transformers/activations.py +++ b/src/transformers/activations.py @@ -204,9 +204,9 @@ def __init__( with_vector_loads=False, ): super().__init__() - self.alpha_p = nn.Parameter(torch.log(torch.exp(torch.tensor(alpha_p_init, dtype=dtype)) - 1).unsqueeze(0)) + self.alpha_p = nn.Parameter(torch.log(torch.expm1(torch.tensor(alpha_p_init, dtype=dtype))).unsqueeze(0)) self.alpha_n = nn.Parameter( - torch.log(torch.exp(torch.tensor(alpha_n_init - beta, dtype=dtype)) - 1).unsqueeze(0) + torch.log(torch.expm1(torch.tensor(alpha_n_init - beta, dtype=dtype))).unsqueeze(0) ) self.register_buffer("beta", torch.tensor(beta, dtype=dtype)) self.register_buffer("eps", torch.tensor(eps, dtype=dtype)) diff --git a/src/transformers/models/llama4/modeling_llama4.py b/src/transformers/models/llama4/modeling_llama4.py index a53443004d49..79e6d97ddbe7 100644 --- a/src/transformers/models/llama4/modeling_llama4.py +++ b/src/transformers/models/llama4/modeling_llama4.py @@ -338,7 +338,7 @@ def forward( # Use temperature tuning from https://huggingface.co/papers/2501.19399) to NoROPE layers if self.attn_temperature_tuning and not self.use_rope: attn_scales = ( - torch.log(torch.floor((cache_position.float() + 1.0) / self.floor_scale) + 1.0) * self.attn_scale + 1.0 + torch.log1p(torch.floor((cache_position.float() + 1.0) / self.floor_scale)) * self.attn_scale + 1.0 ) attn_scales = attn_scales.view((1, input_shape[-1], 1, 1)).expand((*input_shape, 1, 1)) # batch size > 1 query_states = (query_states * attn_scales).to(query_states.dtype) From 332286f54c059f21503d1278325dff5f309520f6 Mon Sep 17 00:00:00 2001 From: Samuel Barry <127697809+SamuelBarryCS@users.noreply.github.com> Date: Mon, 15 Sep 2025 08:03:43 -0700 Subject: [PATCH 052/204] Add Fast PromptDepthAnything Processor (#40602) * Test & import setup * First version passing tests * Ruff * Dummy post processing * Add numerical test * Adjust * Doc * Ruff * remove unused arg * Refine interpolation method and push test script * update bench * Comments * Update src/transformers/models/auto/image_processing_auto.py Co-authored-by: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com> * Remove benchmrk script * Update docstrings * Update src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything_fast.py Co-authored-by: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com> * Update src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything_fast.py Co-authored-by: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com> * doc * further process kwargs * remove it * remove * Remove to dict * remove crop middle * Remove param specific handling * Update testing logic * remove ensure multiple of as kwargs * fix formatting * Remove none default and get image size * Move stuff to _preprocess_image_like_inputs and refacto * Clean * ruff * End of file & comments * ruff again * Padding fixed * Remove comments to pass tests * Remove prompt depth from kwargs * Adjust output_size logic * Docstring for preprocess * auto_docstring for preprocess * pass as an arg * update test batched * stack images * remove prompt scale to meter * return tensors back in preprocess * remove copying of images * Update behavior to match old processoer * Fix batch size of tests * fix test and fast * Fix slow processor * Put tests back to pytorch * remove check and modify batched tests * test do_pad + slow processor fix --------- Co-authored-by: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com> Co-authored-by: yonigozlan --- .../en/model_doc/prompt_depth_anything.md | 6 + .../models/auto/image_processing_auto.py | 2 +- .../models/prompt_depth_anything/__init__.py | 1 + .../image_processing_prompt_depth_anything.py | 14 +- ...e_processing_prompt_depth_anything_fast.py | 379 ++++++++++++++++++ ..._image_processing_prompt_depth_anything.py | 120 ++++-- 6 files changed, 487 insertions(+), 35 deletions(-) create mode 100644 src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything_fast.py diff --git a/docs/source/en/model_doc/prompt_depth_anything.md b/docs/source/en/model_doc/prompt_depth_anything.md index 84960a33ccec..5af13c5d630e 100644 --- a/docs/source/en/model_doc/prompt_depth_anything.md +++ b/docs/source/en/model_doc/prompt_depth_anything.md @@ -93,5 +93,11 @@ If you are interested in submitting a resource to be included here, please feel ## PromptDepthAnythingImageProcessor [[autodoc]] PromptDepthAnythingImageProcessor + - preprocess + - post_process_depth_estimation + +## PromptDepthAnythingImageProcessorFast + +[[autodoc]] PromptDepthAnythingImageProcessorFast - preprocess - post_process_depth_estimation \ No newline at end of file diff --git a/src/transformers/models/auto/image_processing_auto.py b/src/transformers/models/auto/image_processing_auto.py index 193e8f8fd940..ebaa4a30849d 100644 --- a/src/transformers/models/auto/image_processing_auto.py +++ b/src/transformers/models/auto/image_processing_auto.py @@ -151,7 +151,7 @@ ("pix2struct", ("Pix2StructImageProcessor", None)), ("pixtral", ("PixtralImageProcessor", "PixtralImageProcessorFast")), ("poolformer", ("PoolFormerImageProcessor", "PoolFormerImageProcessorFast")), - ("prompt_depth_anything", ("PromptDepthAnythingImageProcessor", None)), + ("prompt_depth_anything", ("PromptDepthAnythingImageProcessor", "PromptDepthAnythingImageProcessorFast")), ("pvt", ("PvtImageProcessor", "PvtImageProcessorFast")), ("pvt_v2", ("PvtImageProcessor", "PvtImageProcessorFast")), ("qwen2_5_vl", ("Qwen2VLImageProcessor", "Qwen2VLImageProcessorFast")), diff --git a/src/transformers/models/prompt_depth_anything/__init__.py b/src/transformers/models/prompt_depth_anything/__init__.py index 3cb05f8e3788..0f2206150f0a 100644 --- a/src/transformers/models/prompt_depth_anything/__init__.py +++ b/src/transformers/models/prompt_depth_anything/__init__.py @@ -20,6 +20,7 @@ if TYPE_CHECKING: from .configuration_prompt_depth_anything import PromptDepthAnythingConfig from .image_processing_prompt_depth_anything import PromptDepthAnythingImageProcessor + from .image_processing_prompt_depth_anything_fast import PromptDepthAnythingImageProcessorFast from .modeling_prompt_depth_anything import ( PromptDepthAnythingForDepthEstimation, PromptDepthAnythingPreTrainedModel, diff --git a/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py b/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py index b5323c308ca4..a5fad19b1a1b 100644 --- a/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py +++ b/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py @@ -13,7 +13,6 @@ """Image processor class for PromptDepthAnything.""" import math -from collections.abc import Iterable from typing import TYPE_CHECKING, Optional, Union @@ -68,13 +67,11 @@ def _constrain_to_multiple_of(val, multiple, min_val=0, max_val=None): def _get_resize_output_image_size( input_image: np.ndarray, - output_size: Union[int, Iterable[int]], + output_size: tuple[int, int], keep_aspect_ratio: bool, multiple: int, input_data_format: Optional[Union[str, ChannelDimension]] = None, ) -> tuple[int, int]: - output_size = (output_size, output_size) if isinstance(output_size, int) else output_size - input_height, input_width = get_image_size(input_image, input_data_format) output_height, output_width = output_size @@ -266,11 +263,11 @@ def _get_pad(size, size_divisor): height, width = get_image_size(image, input_data_format) - pad_size_left, pad_size_right = _get_pad(height, size_divisor) - pad_size_top, pad_size_bottom = _get_pad(width, size_divisor) + pad_size_top, pad_size_bottom = _get_pad(height, size_divisor) + pad_size_left, pad_size_right = _get_pad(width, size_divisor) padded_image = pad( - image, ((pad_size_left, pad_size_right), (pad_size_top, pad_size_bottom)), data_format=data_format + image, ((pad_size_top, pad_size_bottom), (pad_size_left, pad_size_right)), data_format=data_format ) return padded_image @@ -452,7 +449,8 @@ def preprocess( # We can simply select one pixel and set it to a small value. depth[0, 0] = depth[0, 0] + 1e-6 depth = depth[..., None].astype(np.float32) - depth = to_channel_dimension_format(depth, data_format, input_channel_dim=input_data_format) + # Always use LAST as input format since we add channel dim with [..., None] + depth = to_channel_dimension_format(depth, data_format, input_channel_dim=ChannelDimension.LAST) processed_prompt_depths.append(depth) prompt_depths = processed_prompt_depths diff --git a/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything_fast.py b/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything_fast.py new file mode 100644 index 000000000000..4cb6c6732e90 --- /dev/null +++ b/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything_fast.py @@ -0,0 +1,379 @@ +# coding=utf-8 +# Copyright 2025 The HuggingFace Inc. team. All rights reserved. +# +# 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. +"""Fast Image processor class for PromptDepthAnything.""" + +import math +from typing import TYPE_CHECKING, Optional, Union + +from ...image_processing_utils import BatchFeature +from ...processing_utils import Unpack + + +if TYPE_CHECKING: + from ...modeling_outputs import DepthEstimatorOutput +from ...image_processing_utils_fast import ( + BaseImageProcessorFast, + DefaultFastImageProcessorKwargs, + group_images_by_shape, + reorder_images, +) +from ...image_utils import ( + IMAGENET_STANDARD_MEAN, + IMAGENET_STANDARD_STD, + ChannelDimension, + ImageInput, + PILImageResampling, + SizeDict, +) +from ...utils import ( + TensorType, + auto_docstring, + is_torch_available, + is_torchvision_available, + is_torchvision_v2_available, + requires_backends, +) + + +if is_torch_available(): + import torch + +if is_torchvision_available(): + if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F + else: + from torchvision.transforms import functional as F + + +def _constrain_to_multiple_of(val, multiple, min_val=0, max_val=None): + """Constrain a value to be a multiple of another value.""" + x = round(val / multiple) * multiple + + if max_val is not None and x > max_val: + x = math.floor(val / multiple) * multiple + + if x < min_val: + x = math.ceil(val / multiple) * multiple + + return x + + +def _get_resize_output_image_size( + input_image: "torch.Tensor", + output_size: tuple[int, int], + keep_aspect_ratio: bool, + multiple: int, +) -> tuple[int, int]: + """Get the output size for resizing an image.""" + input_height, input_width = input_image.shape[-2:] + output_height, output_width = output_size + + # determine new height and width + scale_height = output_height / input_height + scale_width = output_width / input_width + + if keep_aspect_ratio: + # scale as little as possible + if abs(1 - scale_width) < abs(1 - scale_height): + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + + new_height = _constrain_to_multiple_of(scale_height * input_height, multiple=multiple) + new_width = _constrain_to_multiple_of(scale_width * input_width, multiple=multiple) + + return (new_height, new_width) + + +class PromptDepthAnythingFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): + """ + keep_aspect_ratio (`bool`, *optional*): + If `True`, the image is resized to the largest possible size such that the aspect ratio is preserved. + ensure_multiple_of (`int`, *optional*): + If `do_resize` is `True`, the image is resized to a size that is a multiple of this value. + do_pad (`bool`, *optional*): + Whether to apply center padding. + size_divisor (`int`, *optional*): + If `do_pad` is `True`, pads the image dimensions to be divisible by this value. + prompt_scale_to_meter (`float`, *optional*): + Scale factor to convert the prompt depth to meters. + """ + + keep_aspect_ratio: Optional[bool] + ensure_multiple_of: Optional[int] + do_pad: Optional[bool] + size_divisor: Optional[int] + prompt_scale_to_meter: Optional[float] + + +@auto_docstring +class PromptDepthAnythingImageProcessorFast(BaseImageProcessorFast): + model_input_names = ["pixel_values", "prompt_depth"] + + resample = PILImageResampling.BICUBIC + image_mean = IMAGENET_STANDARD_MEAN + image_std = IMAGENET_STANDARD_STD + size = {"height": 384, "width": 384} + do_resize = True + do_rescale = True + do_normalize = True + keep_aspect_ratio = False + ensure_multiple_of = 1 + do_pad = False + size_divisor = None + prompt_scale_to_meter = 0.001 + valid_kwargs = PromptDepthAnythingFastImageProcessorKwargs + + def __init__(self, **kwargs: Unpack[PromptDepthAnythingFastImageProcessorKwargs]): + super().__init__(**kwargs) + + @auto_docstring + def preprocess( + self, + images: ImageInput, + prompt_depth: Optional[ImageInput] = None, + **kwargs: Unpack[PromptDepthAnythingFastImageProcessorKwargs], + ) -> BatchFeature: + r""" + prompt_depth (`ImageInput`, *optional*): + Prompt depth to preprocess. + """ + return super().preprocess(images, prompt_depth, **kwargs) + + def resize_with_aspect_ratio( + self, + image: "torch.Tensor", + size: SizeDict, + keep_aspect_ratio: bool = False, + ensure_multiple_of: int = 1, + interpolation: Optional["F.InterpolationMode"] = None, + ) -> "torch.Tensor": + """ + Resize an image to target size while optionally maintaining aspect ratio and ensuring dimensions are multiples. + """ + # Set default interpolation to BICUBIC to match the slow processor (causes slight numerical differences otherwise) + if interpolation is None: + interpolation = F.InterpolationMode.BICUBIC + + # Custom resize with aspect ratio preservation and ensure_multiple_of constraint + output_size = _get_resize_output_image_size( + image, + output_size=(size["height"], size["width"]), + keep_aspect_ratio=keep_aspect_ratio, + multiple=ensure_multiple_of, + ) + + # Standard resize method with calculated output size + return self.resize( + image=image, + size=SizeDict(height=output_size[0], width=output_size[1]), + interpolation=interpolation, + ) + + def pad_image( + self, + image: "torch.Tensor", + size_divisor: int, + ) -> "torch.Tensor": + """ + Center pad an image to be a multiple of size_divisor. + """ + + def _get_pad(size, size_divisor): + new_size = math.ceil(size / size_divisor) * size_divisor + pad_size = new_size - size + pad_size_left = pad_size // 2 + pad_size_right = pad_size - pad_size_left + return pad_size_left, pad_size_right + + height, width = image.shape[-2:] + + # Match slow processor and PyTorch convention: width->left/right, height->top/bottom + pad_size_left, pad_size_right = _get_pad(width, size_divisor) + pad_size_top, pad_size_bottom = _get_pad(height, size_divisor) + + # Use torchvision padding for fast processing + # /!\ NB: torchvision F.pad expects (left, top, right, bottom) for the last two dims (W then H) + # Source: https://docs.pytorch.org/vision/main/generated/torchvision.transforms.Pad.html + # So: (left=width_pad, top=height_pad, right=width_pad, bottom=height_pad) + padding = [pad_size_left, pad_size_top, pad_size_right, pad_size_bottom] + padded_image = F.pad(image, padding=padding) + + return padded_image + + def _preprocess_image_like_inputs( + self, + images: ImageInput, + prompt_depth: Optional[ImageInput], + input_data_format: ChannelDimension, + device: Optional[Union[str, "torch.device"]] = None, + prompt_scale_to_meter: Optional[float] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + **kwargs: Unpack[PromptDepthAnythingFastImageProcessorKwargs], + ) -> BatchFeature: + """ + Preprocess image-like inputs, including the main images and optional prompt depth. + """ + images = self._prepare_image_like_inputs( + images=images, do_convert_rgb=False, input_data_format=input_data_format, device=device + ) # always use do_convert_rgb=False rather than defining it as a param to match slow processor + + # Process images with the standard pipeline + pixel_values = self._preprocess(images, return_tensors=return_tensors, **kwargs) + + data = {"pixel_values": pixel_values} + + # Process prompt depth if provided + if prompt_depth is not None: + processed_prompt_depths = self._prepare_image_like_inputs( + images=prompt_depth, + do_convert_rgb=False, # Depth maps should not be converted + input_data_format=input_data_format, + device=images[0].device if images else device, + expected_ndims=2, + ) + + # Validate prompt_depths has same length as images as in slow processor + if len(processed_prompt_depths) != len(images): + raise ValueError( + f"Number of prompt depth images ({len(processed_prompt_depths)}) does not match number of input images ({len(images)})" + ) + + final_prompt_depths = [] + for depth in processed_prompt_depths: + depth = depth * prompt_scale_to_meter + + # Handle case where depth is constant (min == max) + if depth.min() == depth.max(): + depth[0, 0] = depth[0, 0] + 1e-6 # Add small variation to avoid numerical issues + + if depth.ndim == 2: # Add channel dimension if needed + depth = depth.unsqueeze(0) # [H, W] -> [1, H, W] (channels first) + + depth = depth.float() # Convert to float32 to match slow processor + final_prompt_depths.append(depth) + + if return_tensors: + # Stack while preserving the [H, W, C] format that the slow processor uses + final_prompt_depths = torch.stack(final_prompt_depths, dim=0) + + data["prompt_depth"] = final_prompt_depths + + return BatchFeature(data=data, tensor_type=return_tensors) + + def _preprocess( + self, + images: list["torch.Tensor"], + do_resize: bool, + size: SizeDict, + keep_aspect_ratio: Optional[bool], + interpolation: Optional["F.InterpolationMode"], + do_rescale: bool, + rescale_factor: float, + do_normalize: bool, + image_mean: Optional[Union[float, list[float]]], + image_std: Optional[Union[float, list[float]]], + do_pad: Optional[bool], + disable_grouping: Optional[bool], + ensure_multiple_of: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + size_divisor: Optional[int] = None, + **kwargs, + ) -> "torch.Tensor": + """ + Override the base _preprocess method to handle custom PromptDepthAnything parameters. + """ + grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) + resized_images_grouped = {} + + for shape, stacked_images in grouped_images.items(): + if do_resize: + stacked_images = self.resize_with_aspect_ratio( + image=stacked_images, + size=size, + keep_aspect_ratio=keep_aspect_ratio, + ensure_multiple_of=ensure_multiple_of, + interpolation=interpolation, + ) + resized_images_grouped[shape] = stacked_images + + resized_images = reorder_images(resized_images_grouped, grouped_images_index) + + grouped_images, grouped_images_index = group_images_by_shape(resized_images, disable_grouping=disable_grouping) + processed_images_grouped = {} + + for shape, stacked_images in grouped_images.items(): + stacked_images = self.rescale_and_normalize( + stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std + ) + + if do_pad and size_divisor is not None: + stacked_images = self.pad_image(stacked_images, size_divisor) + + processed_images_grouped[shape] = stacked_images + + processed_images = reorder_images(processed_images_grouped, grouped_images_index) + + # Only stack tensors if they all have the same shape and return_tensors is specified + if return_tensors == "pt": + processed_images = torch.stack(processed_images, dim=0) + + return processed_images + + def post_process_depth_estimation( + self, + outputs: "DepthEstimatorOutput", + target_sizes: Optional[Union[TensorType, list[tuple[int, int]], None]] = None, + ) -> list[dict[str, TensorType]]: + """ + Converts the raw output of [`DepthEstimatorOutput`] into final depth predictions and depth PIL images. + Only supports PyTorch. + + Args: + outputs ([`DepthEstimatorOutput`]): + Raw outputs of the model. + target_sizes (`TensorType` or `list[tuple[int, int]]`, *optional*): + Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size + (height, width) of each image in the batch. If left to None, predictions will not be resized. + + Returns: + `list[dict[str, TensorType]]`: A list of dictionaries of tensors representing the processed depth + predictions. + """ + requires_backends(self, "torch") + + predicted_depth = outputs.predicted_depth + + if (target_sizes is not None) and (len(predicted_depth) != len(target_sizes)): + raise ValueError( + "Make sure that you pass in as many target sizes as the batch dimension of the predicted depth" + ) + + results = [] + target_sizes = [None] * len(predicted_depth) if target_sizes is None else target_sizes + for depth, target_size in zip(predicted_depth, target_sizes): + if target_size is not None: + depth = torch.nn.functional.interpolate( + depth.unsqueeze(0).unsqueeze(1), size=target_size, mode="bicubic", align_corners=False + ).squeeze() + + results.append({"predicted_depth": depth}) + + return results + + +__all__ = ["PromptDepthAnythingImageProcessorFast"] diff --git a/tests/models/prompt_depth_anything/test_image_processing_prompt_depth_anything.py b/tests/models/prompt_depth_anything/test_image_processing_prompt_depth_anything.py index eb40058deefd..99bbcdb54d87 100644 --- a/tests/models/prompt_depth_anything/test_image_processing_prompt_depth_anything.py +++ b/tests/models/prompt_depth_anything/test_image_processing_prompt_depth_anything.py @@ -17,8 +17,8 @@ import numpy as np -from transformers.file_utils import is_vision_available from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torchvision_available, is_vision_available from ...test_image_processing_common import ImageProcessingTestMixin, prepare_image_inputs @@ -26,6 +26,9 @@ if is_vision_available(): from transformers import PromptDepthAnythingImageProcessor + if is_torchvision_available(): + from transformers import PromptDepthAnythingImageProcessorFast + class PromptDepthAnythingImageProcessingTester(unittest.TestCase): def __init__( @@ -84,6 +87,7 @@ def prepare_image_inputs(self, equal_resolution=False, numpify=False, torchify=F @require_vision class PromptDepthAnythingImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase): image_processing_class = PromptDepthAnythingImageProcessor if is_vision_available() else None + fast_image_processing_class = PromptDepthAnythingImageProcessorFast if is_torchvision_available() else None def setUp(self): super().setUp() @@ -94,45 +98,109 @@ def image_processor_dict(self): return self.image_processor_tester.prepare_image_processor_dict() def test_image_processor_properties(self): - image_processing = self.image_processing_class(**self.image_processor_dict) - self.assertTrue(hasattr(image_processing, "image_mean")) - self.assertTrue(hasattr(image_processing, "image_std")) - self.assertTrue(hasattr(image_processing, "do_normalize")) - self.assertTrue(hasattr(image_processing, "do_resize")) - self.assertTrue(hasattr(image_processing, "size")) - self.assertTrue(hasattr(image_processing, "do_rescale")) - self.assertTrue(hasattr(image_processing, "rescale_factor")) - self.assertTrue(hasattr(image_processing, "do_pad")) - self.assertTrue(hasattr(image_processing, "size_divisor")) - self.assertTrue(hasattr(image_processing, "prompt_scale_to_meter")) + for image_processing_class in self.image_processor_list: + image_processing = image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + self.assertTrue(hasattr(image_processing, "do_rescale")) + self.assertTrue(hasattr(image_processing, "rescale_factor")) + self.assertTrue(hasattr(image_processing, "do_pad")) + self.assertTrue(hasattr(image_processing, "size_divisor")) + self.assertTrue(hasattr(image_processing, "prompt_scale_to_meter")) def test_image_processor_from_dict_with_kwargs(self): - image_processor = self.image_processing_class.from_dict(self.image_processor_dict) - self.assertEqual(image_processor.size, {"height": 18, "width": 18}) + for image_processing_class in self.image_processor_list: + image_processor = image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"height": 18, "width": 18}) - image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42) - self.assertEqual(image_processor.size, {"height": 42, "width": 42}) + image_processor = image_processing_class.from_dict(self.image_processor_dict, size=42) + self.assertEqual(image_processor.size, {"height": 42, "width": 42}) def test_keep_aspect_ratio(self): size = {"height": 512, "width": 512} - image_processor = PromptDepthAnythingImageProcessor(size=size, keep_aspect_ratio=True, ensure_multiple_of=32) + for image_processing_class in self.image_processor_list: + image_processor = image_processing_class(size=size, keep_aspect_ratio=True, ensure_multiple_of=32) - image = np.zeros((489, 640, 3)) + image = np.zeros((489, 640, 3)) - pixel_values = image_processor(image, return_tensors="pt").pixel_values + pixel_values = image_processor(image, return_tensors="pt").pixel_values - self.assertEqual(list(pixel_values.shape), [1, 3, 512, 672]) + self.assertEqual(list(pixel_values.shape), [1, 3, 512, 672]) def test_prompt_depth_processing(self): size = {"height": 756, "width": 756} - image_processor = PromptDepthAnythingImageProcessor(size=size, keep_aspect_ratio=True, ensure_multiple_of=32) + for image_processing_class in self.image_processor_list: + image_processor = image_processing_class(size=size, keep_aspect_ratio=True, ensure_multiple_of=32) + + image = np.zeros((756, 1008, 3)) + prompt_depth = np.random.random((192, 256)) + + outputs = image_processor(image, prompt_depth=prompt_depth, return_tensors="pt") + pixel_values = outputs.pixel_values + prompt_depth_values = outputs.prompt_depth + + self.assertEqual(list(pixel_values.shape), [1, 3, 768, 1024]) + self.assertEqual(list(prompt_depth_values.shape), [1, 1, 192, 256]) + + @require_torch + @require_vision + def test_slow_fast_equivalence(self): + if not self.test_slow_image_processor or not self.test_fast_image_processor: + self.skipTest(reason="Skipping slow/fast equivalence test") + + if self.image_processing_class is None or self.fast_image_processing_class is None: + self.skipTest(reason="Skipping slow/fast equivalence test as one of the image processors is not defined") image = np.zeros((756, 1008, 3)) prompt_depth = np.random.random((192, 256)) - outputs = image_processor(image, prompt_depth=prompt_depth, return_tensors="pt") - pixel_values = outputs.pixel_values - prompt_depth_values = outputs.prompt_depth + size = {"height": 756, "width": 756} + image_processor_slow = self.image_processing_class( + size=size, keep_aspect_ratio=True, ensure_multiple_of=32, do_pad=True, size_divisor=51 + ) + image_processor_fast = self.fast_image_processing_class( + size=size, keep_aspect_ratio=True, ensure_multiple_of=32, do_pad=True, size_divisor=51 + ) + + encoding_slow = image_processor_slow(image, prompt_depth=prompt_depth, return_tensors="pt") + encoding_fast = image_processor_fast(image, prompt_depth=prompt_depth, return_tensors="pt") + + self._assert_slow_fast_tensors_equivalence(encoding_slow.pixel_values, encoding_fast.pixel_values) + self.assertEqual(encoding_slow.prompt_depth.dtype, encoding_fast.prompt_depth.dtype) + + self._assert_slow_fast_tensors_equivalence(encoding_slow.prompt_depth, encoding_fast.prompt_depth) + + @require_torch + @require_vision + def test_slow_fast_equivalence_batched(self): + if not self.test_slow_image_processor or not self.test_fast_image_processor: + self.skipTest(reason="Skipping slow/fast equivalence test") + + if self.image_processing_class is None or self.fast_image_processing_class is None: + self.skipTest(reason="Skipping slow/fast equivalence test as one of the image processors is not defined") + + if hasattr(self.image_processor_tester, "do_center_crop") and self.image_processor_tester.do_center_crop: + self.skipTest( + reason="Skipping as do_center_crop is True and center_crop functions are not equivalent for fast and slow processors" + ) + + batch_size = self.image_processor_tester.batch_size + images = self.image_processor_tester.prepare_image_inputs(equal_resolution=True, torchify=True) + prompt_depths = [np.random.random((192, 256)) for _ in range(batch_size)] + + size = {"height": 756, "width": 756} + image_processor_slow = self.image_processing_class(size=size, keep_aspect_ratio=False, ensure_multiple_of=32) + image_processor_fast = self.fast_image_processing_class( + size=size, keep_aspect_ratio=False, ensure_multiple_of=32 + ) + + encoding_slow = image_processor_slow(images, prompt_depth=prompt_depths, return_tensors="pt") + encoding_fast = image_processor_fast(images, prompt_depth=prompt_depths, return_tensors="pt") + + self._assert_slow_fast_tensors_equivalence(encoding_slow.pixel_values, encoding_fast.pixel_values) + self.assertEqual(encoding_slow.prompt_depth.dtype, encoding_fast.prompt_depth.dtype) - self.assertEqual(list(pixel_values.shape), [1, 3, 768, 1024]) - self.assertEqual(list(prompt_depth_values.shape), [1, 1, 192, 256]) + self._assert_slow_fast_tensors_equivalence(encoding_slow.prompt_depth, encoding_fast.prompt_depth) From a4d417c773af5c64a2377049d0c5a70a94bf1f66 Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Mon, 15 Sep 2025 17:23:13 +0200 Subject: [PATCH 053/204] Fix deta loading & dataclass (#40878) * fix * fix 2 --- src/transformers/models/deprecated/deta/modeling_deta.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformers/models/deprecated/deta/modeling_deta.py b/src/transformers/models/deprecated/deta/modeling_deta.py index a5066958b6c6..c4f6f5c65ded 100644 --- a/src/transformers/models/deprecated/deta/modeling_deta.py +++ b/src/transformers/models/deprecated/deta/modeling_deta.py @@ -326,7 +326,7 @@ class DetaObjectDetectionOutput(ModelOutput): encoder_last_hidden_state: Optional[torch.FloatTensor] = None encoder_hidden_states: Optional[tuple[torch.FloatTensor]] = None encoder_attentions: Optional[tuple[torch.FloatTensor]] = None - enc_outputs_class = None + enc_outputs_class: Optional[torch.FloatTensor] = None enc_outputs_coord_logits: Optional[torch.FloatTensor] = None output_proposals: Optional[torch.FloatTensor] = None @@ -1857,7 +1857,7 @@ def __init__(self, config: DetaConfig): prior_prob = 0.01 bias_value = -math.log((1 - prior_prob) / prior_prob) - self.class_embed.bias.data = torch.ones(config.num_labels) * bias_value + self.class_embed.bias.data.fill_(bias_value) nn.init.constant_(self.bbox_embed.layers[-1].weight.data, 0) nn.init.constant_(self.bbox_embed.layers[-1].bias.data, 0) From 493dd21dd2e414a7ec30bf53be19154169f708a6 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 15 Sep 2025 23:38:13 +0800 Subject: [PATCH 054/204] Remove dict branch of attention_mask in sdpa_attention_paged_forward (#40882) Remove dict branch of attention_mask Signed-off-by: Yuanyuan Chen --- src/transformers/integrations/sdpa_paged.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/transformers/integrations/sdpa_paged.py b/src/transformers/integrations/sdpa_paged.py index befa88f1406e..528eb6ca0773 100644 --- a/src/transformers/integrations/sdpa_paged.py +++ b/src/transformers/integrations/sdpa_paged.py @@ -39,12 +39,7 @@ def sdpa_attention_paged_forward( value = repeat_kv(value, module.num_key_value_groups) # Get the right causal mask for the current layer - if isinstance(attention_mask, dict): - sliding_window = getattr(module, "sliding_window", 1) - layer_type = "full_attention" if sliding_window == 1 or sliding_window is None else "sliding_attention" - causal_mask = attention_mask[layer_type] - else: - causal_mask = attention_mask + causal_mask = attention_mask # Run the actual attention query = query.contiguous() From aa8fea44e7d8f35f393bf68a49d8140eb055cc3b Mon Sep 17 00:00:00 2001 From: HyunZ118 <156191095+HyunZ118@users.noreply.github.com> Date: Tue, 16 Sep 2025 02:06:57 +0900 Subject: [PATCH 055/204] =?UTF-8?q?=F0=9F=8C=90=20[i18n-KO]=20Translated?= =?UTF-8?q?=20smolvlm.md=20to=20Korean=20(#40414)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: manual edits * Apply suggestions from code review * Update docs/source/ko/model_doc/smolvlm.md * Update docs/source/ko/model_doc/smolvlm.md * Update docs/source/ko/model_doc/smolvlm.md * Update docs/source/ko/model_doc/smolvlm.md * Update docs/source/ko/_toctree.yml Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --------- Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --- docs/source/ko/_toctree.yml | 4 +- docs/source/ko/model_doc/smolvlm.md | 210 ++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 docs/source/ko/model_doc/smolvlm.md diff --git a/docs/source/ko/_toctree.yml b/docs/source/ko/_toctree.yml index 74833464ccd1..98d2e1381069 100644 --- a/docs/source/ko/_toctree.yml +++ b/docs/source/ko/_toctree.yml @@ -1161,8 +1161,8 @@ title: SigLIP2 - local: in_translation title: SmolLM3 - - local: in_translation - title: SmolVLM + - local: model_doc/smolvlm + title: 소형 비전 언어 모델 - local: in_translation title: Speech Encoder Decoder Models - local: in_translation diff --git a/docs/source/ko/model_doc/smolvlm.md b/docs/source/ko/model_doc/smolvlm.md new file mode 100644 index 000000000000..1ebd50519c18 --- /dev/null +++ b/docs/source/ko/model_doc/smolvlm.md @@ -0,0 +1,210 @@ + +*이 모델은 2025년 2월 20일에 출시되었으며, 동시에 허깅페이스 `Transformer` 라이브러리에 추가되었습니다.* + +# 소형 비전 언어 모델(SmolVLM)[[smolvlm]] + +
+PyTorch +FlashAttention +SDPA +
+ +## 개요[[overview]] +[SmolVLM2](https://huggingface.co/papers/2504.05299) ([블로그 글](https://huggingface.co/blog/smolvlm2)) 은 Idefics3 모델을 개선한 버전으로, 두 가지 주요 차이점이 있습니다: + +- 텍스트 모델로 SmolLM2를 사용합니다. +- 한 장의 이미지뿐 아니라 여러 장의 이미지와 비디오 입력도 지원합니다. + +## 사용 팁[[usage-tips]] + +입력된 이미지는 설정에 따라 원본 해상도를 유지하거나 크기를 조절할 수 있습니다. 이때 이미지 크기 조절 여부와 방식은 `do_resize`와 `size` 파라미터로 결정됩니다. + +비디오의 경우에는 업샘플링을 하면 안 됩니다. + +만약 `do_resize`가 `True`일 경우, 모델은 기본적으로 이미지의 가장 긴 변을 4*512 픽셀이 되도록 크기를 조절합니다. +이 기본 동작은 `size` 파라미터에 딕셔너리를 전달하여 원하는 값으로 직접 설정할 수 있습니다. 예를 들어, 기본값은 `{"longest_edge": 4 * 512}` 이여도 사용자 필요에 따라 다른 값으로 변경할 수 있습니다. + +다음은 리사이징을 제어하고 사용자 정의 크기로 변경하는 방법입니다: +```python +image_processor = SmolVLMImageProcessor(do_resize=True, size={"longest_edge": 2 * 512}, max_image_size=512) +``` + +또한, `max_image_size` 매개변수는 이미지를 분할하는 정사각형 패치의 크기를 제어합니다. 이 값은 기본적으로 512로 설정되어 있으며 필요에 따라 조정 가능합니다. 이미지 처리기는 리사이징을 마친 후, `max_image_size` 값을 기준으로 이미지를 여러 개의 정사각형 패치로 분할합니다. + +이 모델의 기여자는 [orrzohar](https://huggingface.co/orrzohar) 입니다. + + + +## 사용 예시[[usage-example]] + +### 단일 미디어 추론[[single-media-inference]] + +이 모델은 이미지와 비디오를 모두 입력으로 받을 수 있지만, 한 번에 사용할 수 있는 미디어는 반드시 하나의 종류여야 합니다. 관련 예시 코드는 다음과 같습니다. + +```python +import torch +from transformers import AutoProcessor, AutoModelForImageTextToText + +processor = AutoProcessor.from_pretrained("HuggingFaceTB/SmolVLM2-256M-Video-Instruct") +model = AutoModelForImageTextToText.from_pretrained( + "HuggingFaceTB/SmolVLM2-256M-Video-Instruct", + dtype=torch.bfloat16, + device_map="auto" +) + +conversation = [ + { + "role": "user", + "content":[ + {"type": "image", "url": "http://images.cocodataset.org/val2017/000000039769.jpg"}, + {"type": "text", "text": "이 이미지에 대해 설명해주세요."} + ] + } +] + +inputs = processor.apply_chat_template( + conversation, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", +).to(model.device, dtype=torch.bfloat16) + +output_ids = model.generate(**inputs, max_new_tokens=128) +generated_texts = processor.batch_decode(output_ids, skip_special_tokens=True) +print(generated_texts) + + +# Video +conversation = [ + { + "role": "user", + "content": [ + {"type": "video", "path": "/path/to/video.mp4"}, + {"type": "text", "text": "이 비디오에 대해 자세히 설명해주세요."} + ] + }, +] + +inputs = processor.apply_chat_template( + conversation, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", +).to(model.device, dtype=torch.bfloat16) + +generated_ids = model.generate(**inputs, do_sample=False, max_new_tokens=100) +generated_texts = processor.batch_decode(generated_ids, skip_special_tokens=True) +print(generated_texts[0]) +``` + +### 배치 다중 미디어 추론[[batch-mixed-media-inference]] + +이 모델은 여러 이미지, 비디오, 텍스트로 구성된 입력을 한 번에 배치 형태로 처리할 수 있습니다. 관련 예시는 다음과 같습니다. + +```python +import torch +from transformers import AutoProcessor, AutoModelForImageTextToText + +processor = AutoProcessor.from_pretrained("HuggingFaceTB/SmolVLM2-256M-Video-Instruct") +model = AutoModelForImageTextToText.from_pretrained( + "HuggingFaceTB/SmolVLM2-256M-Video-Instruct", + dtype=torch.bfloat16, + device_map="auto" +) + +# 첫 번째 이미지에 대한 구성 +conversation1 = [ + { + "role": "user", + "content": [ + {"type": "image", "path": "/path/to/image.jpg"}, + {"type": "text", "text": "이 이미지에 대해 설명해주세요."} + ] + } +] + +# 두 장의 이미지를 포함한 구성 +conversation2 = [ + { + "role": "user", + "content": [ + {"type": "image", "path": "/path/to/image.jpg"}, + {"type": "image", "path": "/path/to/image.jpg"}, + {"type": "text", "text": "그림에 무엇이 적혀있나요?"} + ] + } +] + +# 텍스트만 포함하고 있는 구성 +conversation3 = [ + {"role": "user","content": "당신은 누구인가요?"} +] + + +conversations = [conversation1, conversation2, conversation3] +inputs = processor.apply_chat_template( + conversation, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", +).to(model.device, dtype=torch.bfloat16) + +generated_ids = model.generate(**inputs, do_sample=False, max_new_tokens=100) +generated_texts = processor.batch_decode(generated_ids, skip_special_tokens=True) +print(generated_texts[0]) +``` + +## SmolVLMConfig[[transformers.SmolVLMConfig]] + +[[autodoc]] SmolVLMConfig + +## SmolVLMVisionConfig[[transformers.SmolVLMVisionConfig]] + +[[autodoc]] SmolVLMVisionConfig + +## Idefics3VisionTransformer[[transformers.SmolVLMVisionTransformer]] + +[[autodoc]] SmolVLMVisionTransformer + +## SmolVLMModel[[transformers.SmolVLMModel]] + +[[autodoc]] SmolVLMModel + - forward + +## SmolVLMForConditionalGeneration[[transformers.SmolVLMForConditionalGeneration]] + +[[autodoc]] SmolVLMForConditionalGeneration + - forward + +## SmolVLMImageProcessor[[transformers.SmolVLMImageProcessor]] +[[autodoc]] SmolVLMImageProcessor + - preprocess + +## SmolVLMImageProcessorFast[[transformers.SmolVLMImageProcessorFast]] +[[autodoc]] SmolVLMImageProcessorFast + - preprocess + +## SmolVLMVideoProcessor[[transformers.SmolVLMVideoProcessor]] +[[autodoc]] SmolVLMVideoProcessor + - preprocess + +## SmolVLMProcessor[[transformers.SmolVLMProcessor]] +[[autodoc]] SmolVLMProcessor + - __call__ From cbe9f2e6595f6bbb5f77596f8f8a81b3c070f63d Mon Sep 17 00:00:00 2001 From: HyunZ118 <156191095+HyunZ118@users.noreply.github.com> Date: Tue, 16 Sep 2025 02:07:16 +0900 Subject: [PATCH 056/204] =?UTF-8?q?=F0=9F=8C=90=20[i18n-KO]=20Translated?= =?UTF-8?q?=20`imageprocessor.md`=20to=20Korean=20(#39557)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: manual translation * docs: fix ko/_toctree.yml * Apply suggestions from code review Co-authored-by: YONGSANG <71686691+4N3MONE@users.noreply.github.com> Co-authored-by: Yijun Lee <119404328+yijun-lee@users.noreply.github.com> * Update docs/source/ko/image_processors.md Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --------- Co-authored-by: YONGSANG <71686691+4N3MONE@users.noreply.github.com> Co-authored-by: Yijun Lee <119404328+yijun-lee@users.noreply.github.com> Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --- docs/source/ko/_toctree.yml | 4 +- docs/source/ko/image_processors.md | 223 +++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 docs/source/ko/image_processors.md diff --git a/docs/source/ko/_toctree.yml b/docs/source/ko/_toctree.yml index 98d2e1381069..df2d53c49a96 100644 --- a/docs/source/ko/_toctree.yml +++ b/docs/source/ko/_toctree.yml @@ -29,8 +29,8 @@ - sections: - local: fast_tokenizers title: 🤗 Tokenizers 라이브러리에서 토크나이저 사용하기 - - local: in_translation - title: (번역중) Image processors + - local: image_processors + title: 이미지 프로세서 - local: in_translation title: (번역중) Video processors - local: in_translation diff --git a/docs/source/ko/image_processors.md b/docs/source/ko/image_processors.md new file mode 100644 index 000000000000..eddccb799ecf --- /dev/null +++ b/docs/source/ko/image_processors.md @@ -0,0 +1,223 @@ + + +# 이미지 프로세서(Image processor) [[image-processors]] + +이미지 프로세서는 이미지를 픽셀 값, 즉 이미지의 색상과 크기를 나타내는 텐서로 변환합니다. 이 픽셀 값은 비전 모델의 입력으로 사용됩니다. 이때 사전 학습된 모델이 새로운 이미지를 올바르게 인식하려면 입력되는 이미지의 형식이 학습 당시 사용했던 데이터와 똑같아야 합니다. 이미지 프로세서는 다음과 같은 작업을 통해 이미지 형식을 통일시켜주는 역할을 합니다. + +- 이미지 크기를 조절하는 [`~BaseImageProcessor.center_crop`] +- 픽셀 값을 정규화하는 [`~BaseImageProcessor.normalize`] 또는 크기를 재조정하는 [`~BaseImageProcessor.rescale`] + +Hugging Face [Hub](https://hf.co)나 로컬 디렉토리에 있는 비전 모델에서 이미지 프로세서의 설정(이미지 크기, 정규화 및 리사이즈 여부 등)을 불러오려면 [`~ImageProcessingMixin.from_pretrained`]를 사용하세요. 각 사전 학습된 모델의 설정은 [preprocessor_config.json](https://huggingface.co/google/vit-base-patch16-224/blob/main/preprocessor_config.json) 파일에 저장되어 있습니다. + +```py +from transformers import AutoImageProcessor + +image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224") +``` + +이미지를 이미지 프로세서에 전달하여 픽셀 값으로 변환하고, `return_tensors="pt"` 를 설정하여 PyTorch 텐서를 반환받으세요. 이미지가 텐서로 어떻게 보이는지 궁금하다면 입력값을 한번 출력해보시는걸 추천합니다! + +```py +from PIL import Image +import requests + +url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/image_processor_example.png" +image = Image.open(requests.get(url, stream=True).raw).convert("RGB") +inputs = image_processor(image, return_tensors="pt") +``` + +이 가이드에서는 이미지 프로세서 클래스와 비전 모델을 위한 이미지 전처리 방법에 대해 다룰 예정입니다. + +## 이미지 프로세서 클래스(Image processor classes) [[image-processor-classes]] + +이미지 프로세서들은 [`~BaseImageProcessor.center_crop`], [`~BaseImageProcessor.normalize`], [`~BaseImageProcessor.rescale`] 함수를 제공하는 [`BaseImageProcessor`] 클래스를 상속받습니다. 이미지 프로세서에는 두 가지 종류가 있습니다. + +- [`BaseImageProcessor`]는 파이썬 기반 구현체입니다. +- [`BaseImageProcessorFast`]는 더 빠른 [torchvision-backed](https://pytorch.org/vision/stable/index.html) 버전입니다. [torch.Tensor](https://pytorch.org/docs/stable/tensors.html)입력의 배치 처리 시 최대 33배 더 빠를 수 있습니다. [`BaseImageProcessorFast`]는 현재 모든 비전 모델에서 사용할 수 있는 것은 아니기 때문에 모델의 API 문서를 참조하여 지원 여부를 확인해 주세요. + +각 이미지 프로세서는 이미지 프로세서를 불러오고 저장하기 위한 [`~ImageProcessingMixin.from_pretrained`]와 [`~ImageProcessingMixin.save_pretrained`] 메소드를 제공하는 [`ImageProcessingMixin`] 클래스를 상속받아 기능을 확장시킵니다. + +이미지 프로세서를 불러오는 방법은 [`AutoImageProcessor`]를 사용하거나 모델별 이미지 프로세서를 사용하는 방식 두 가지가 있습니다. + + + + +[AutoClass](./model_doc/auto) API는 이미지 프로세서가 어떤 모델과 연관되어 있는지 직접 지정하지 않고도 편리하게 불러올 수 있는 방법을 제공합니다. + +[`~AutoImageProcessor.from_pretrained`]를 사용해 이미지 프로세서를 불러옵니다. 만약 빠른 프로세서를 사용하고 싶다면 `use_fast=True`를 추가하세요. + +```py +from transformers import AutoImageProcessor + +image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224", use_fast=True) +``` + + + + +각 이미지 프로세서는 특정 비전 모델에 맞춰져 있습니다. 따라서 프로세서의 설정 파일에는 해당 모델이 필요로 하는 이미지 크기나 정규화, 리사이즈 적용 여부 같은 정보가 담겨있습니다. + +이러한 이미지 프로세서는 모델별 클래스에서 직접 불러올 수 있으며, 더 빠른 버전의 지원 여부는 해당 모델의 API 문서에서 확인 가능합니다. + +```py +from transformers import ViTImageProcessor + +image_processor = ViTImageProcessor.from_pretrained("google/vit-base-patch16-224") +``` + +빠른 이미지 프로세서를 불러오기 위해 fast 구현 클래스를 사용해보세요. + +```py +from transformers import ViTImageProcessorFast + +image_processor = ViTImageProcessorFast.from_pretrained("google/vit-base-patch16-224") +``` + + + + +## 빠른 이미지 프로세서(Fast image processors) [[fast-image-processors]] + +[`BaseImageProcessorFast`]는 [torchvision](https://pytorch.org/vision/stable/index.html)을 기반으로 하며, 특히 GPU에서 처리할 때 속도가 훨씬 빠릅니다. 이 클래스는 기존 [`BaseImageProcessor`]와 완전히 동일하게 설계되었기 때문에, 모델이 지원한다면 별도 수정 없이 바로 교체해서 사용할 수 있습니다. [torchvision](https://pytorch.org/get-started/locally/#mac-installation)을 설치한 뒤 `use_fast` 파라미터를 `True`로 지정해주시면 됩니다. + + +```py +from transformers import AutoImageProcessor + +processor = AutoImageProcessor.from_pretrained("facebook/detr-resnet-50", use_fast=True) +``` + +`device` 파라미터를 사용해 어느 장치에서 처리할지 지정할 수 있습니다. 만약 입력값이 텐서(tensor)라면 그 텐서와 동일한 장치에서, 그렇지 않은 경우에는 기본적으로 CPU에서 처리됩니다. 아래는 빠른 프로세서를 GPU에서 사용하도록 설정하는 예제입니다. + +```py +from torchvision.io import read_image +from transformers import DetrImageProcessorFast + +images = read_image("image.jpg") +processor = DetrImageProcessorFast.from_pretrained("facebook/detr-resnet-50") +images_processed = processor(images, return_tensors="pt", device="cuda") +``` + +
+Benchmarks + +이 벤치마크는 NVIDIA A10G Tensor Core GPU가 장착된 [AWS EC2 g5.2xlarge](https://aws.amazon.com/ec2/instance-types/g5/) 인스턴스에서 측정된 결과입니다. + +
+ +
+
+ +
+
+ +
+
+ +
+
+ +## 전처리(Preprocess) [[preprocess]] + +Transformers의 비전 모델은 입력값으로 PyTorch 텐서 형태의 픽셀 값을 받습니다. 이미지 프로세서는 이미지를 바로 이 픽셀 값 텐서(배치 크기, 채널 수, 높이, 너비)로 변환하는 역할을 합니다. 이 과정에서 모델이 요구하는 크기로 이미지를 조절하고, 픽셀 값 또한 모델 기준에 맞춰 정규화하거나 재조정합니다. + +이러한 이미지 전처리는 이미지 증강과는 다른 개념입니다. 이미지 증강은 학습 데이터를 늘리거나 과적합을 막기 위해 이미지에 의도적인 변화(밝기, 색상, 회전 등)를 주는 기술입니다. 반면, 이미지 전처리는 이미지를 사전 학습된 모델이 요구하는 입력 형식에 정확히 맞춰주는 작업에만 집중합니다. + +일반적으로 모델 성능을 높이기 위해, 이미지는 보통 증강 과정을 거친 뒤 전처리되어 모델에 입력됩니다. 이때 증강 작업은 [Albumentations](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/image_classification_albumentations.ipynb), [Kornia](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/image_classification_kornia.ipynb)) 와 같은 라이브러리를 사용할 수 있으며, 이후 전처리 단계에서 이미지 프로세서를 사용하면 됩니다. + +이번 가이드에서는 이미지 증강을 위해 torchvision의 [transforms](https://pytorch.org/vision/stable/transforms.html) 모듈을 사용하겠습니다. + +우선 [food101](https://hf.co/datasets/food101) 데이터셋의 일부만 샘플로 불러와서 시작하겠습니다. + +```py +from datasets import load_dataset + +dataset = load_dataset("food101", split="train[:100]") +``` + +[transforms](https://pytorch.org/vision/stable/transforms.html) 모듈의 [Compose](https://pytorch.org/vision/master/generated/torchvision.transforms.Compose.html)API는 여러 변환을 하나로 묶어주는 역할을 합니다. 여기서는 이미지를 무작위로 자르고 리사이즈하는 [RandomResizedCrop](https://pytorch.org/vision/main/generated/torchvision.transforms.RandomResizedCrop.html)과 색상을 무작위로 바꾸는 [ColorJitter](https://pytorch.org/vision/main/generated/torchvision.transforms.ColorJitter.html)를 함께 사용해보겠습니다. + +이때 잘라낼 이미지의 크기는 이미지 프로세서에서 가져올 수 있습니다. 모델에 따라 정확한 높이와 너비가 필요할 때도 있고, 가장 짧은 변 `shortest_edge` 값만 필요할 때도 있습니다. + +```py +from torchvision.transforms import RandomResizedCrop, ColorJitter, Compose + +size = ( + image_processor.size["shortest_edge"] + if "shortest_edge" in image_processor.size + else (image_processor.size["height"], image_processor.size["width"]) +) +_transforms = Compose([RandomResizedCrop(size), ColorJitter(brightness=0.5, hue=0.5)]) +``` + +준비된 변환값 들을 이미지에 적용하고, RGB 형식으로 바꿔줍니다. 그 다음, 이렇게 증강된 이미지를 이미지 프로세서에 넣어 픽셀 값을 반환합니다. + +여기서 `do_resize`파라미터를 `False`로 설정한 이유는, 앞선 증강 단계에서 [RandomResizedCrop](https://pytorch.org/vision/main/generated/torchvision.transforms.RandomResizedCrop.html)을 통해 이미 이미지 크기를 조절했기 때문입니다. 만약 증강 과정을 생략한다면, 이미지 프로세서는 `image_mean`과 `image_std`값(전처리기 설정 파일에 저장됨)을 사용해 자동으로 리사이즈와 정규화를 수행하게 됩니다. + +```py +def transforms(examples): + images = [_transforms(img.convert("RGB")) for img in examples["image"]] + examples["pixel_values"] = image_processor(images, do_resize=False, return_tensors="pt")["pixel_values"] + return examples +``` + +[`~datasets.Dataset.set_transform`]을 사용하면 결합된 증강 및 전처리 기능을 전체 데이터셋에 실시간으로 적용됩니다. + +```py +dataset.set_transform(transforms) +``` + +이제 처리된 픽셀 값을 다시 이미지로 변환하여 증강 및 전처리 결과가 어떻게 나왔는지 직접 확인해 봅시다. + +```py +import numpy as np +import matplotlib.pyplot as plt + +img = dataset[0]["pixel_values"] +plt.imshow(img.permute(1, 2, 0)) +``` + +
+
+ +
이전
+
+
+ +
이후
+
+
+ +이미지 프로세서는 전처리뿐만 아니라, 객체 탐지나 분할과 같은 비전 작업에서 모델의 결과값을 바운딩 박스나 분할 맵처럼 의미 있는 예측으로 바꿔주는 후처리 기능도 갖추고 있습니다. + +### 패딩(Padding) [[padding]] + +[DETR](./model_doc/detr)과 같은 일부 모델은 훈련 중에 [scale augmentation](https://paperswithcode.com/method/image-scale-augmentation)을 사용하기 때문에 한 배치 내에 포함된 이미지들의 크기가 제각각 일 수 있습니다. 아시다시피 크기가 서로 다른 이미지들은 하나의 배치로 묶을 수 없죠. + +이 문제를 해결하려면 이미지에 특수 패딩 토큰인 `0`을 채워 넣어 크기를 통일시켜주면 됩니다. [pad](https://github.com/huggingface/transformers/blob/9578c2597e2d88b6f0b304b5a05864fd613ddcc1/src/transformers/models/detr/image_processing_detr.py#L1151) 메소드로 패딩을 적용하고, 이렇게 크기가 통일된 이미지들을 배치로 묶기 위해 사용자 정의 `collate` 함수를 만들어 사용하세요. + +```py +def collate_fn(batch): + pixel_values = [item["pixel_values"] for item in batch] + encoding = image_processor.pad(pixel_values, return_tensors="pt") + labels = [item["labels"] for item in batch] + batch = {} + batch["pixel_values"] = encoding["pixel_values"] + batch["pixel_mask"] = encoding["pixel_mask"] + batch["labels"] = labels + return batch +``` From 23772dc6c938fc3eeb7c2817558bc79294bf201b Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Mon, 15 Sep 2025 19:22:31 +0100 Subject: [PATCH 057/204] [generate] remove docs of a feature that no longer exists (#40895) --- docs/source/en/llm_optims.md | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/docs/source/en/llm_optims.md b/docs/source/en/llm_optims.md index e1043327bc4a..ff9089cdaa32 100644 --- a/docs/source/en/llm_optims.md +++ b/docs/source/en/llm_optims.md @@ -183,36 +183,6 @@ text 'My favorite all time favorite condiment is ketchup. I love it on everything. I love it on my eggs, my fries, my chicken, my burgers, my hot dogs, my sandwiches, my salads, my p'] ``` - - - -Compiling the entire [`~GenerationMixin.generate`] function also compiles the input preparation logit processor operations, and more, in addition to the forward pass. With this approach, you don't need to initialize [`StaticCache`] or set the [cache_implementation](https://hf.co/docs/transformers/main_classes/text_generation#transformers.GenerationConfig.cache_implementation) parameter. - -```py -from transformers import AutoTokenizer, AutoModelForCausalLM -import torch -import os -os.environ["TOKENIZERS_PARALLELISM"] = "false" # To prevent long warnings :) - -tokenizer = AutoTokenizer.from_pretrained("google/gemma-2b") -model = AutoModelForCausalLM.from_pretrained("google/gemma-2b", dtype="auto", device_map="auto") - -model.generate = torch.compile(model.generate, mode="reduce-overhead", fullgraph=True) -input_text = "The theory of special relativity states " -input_ids = tokenizer(input_text, return_tensors="pt").to(model.device.type) - -outputs = model.generate(**input_ids) -print(tokenizer.batch_decode(outputs, skip_special_tokens=True)) -['The theory of special relativity states 1. The speed of light is constant in all inertial reference'] -``` - -This usage pattern is more appropriate for unique hardware or use cases, but there are several drawbacks to consider. - -1. Compilation is much slower. -2. Parameters must be configured through [`GenerationConfig`]. -3. Many warnings and exceptions are suppressed. We recommend testing the uncompiled model first. -4. Many features are unavailable at the moment. For example, generation does not stop if an `EOS` token is selected. - From b4d7f5fcad3f7e6efdc824d5e2e5470013546897 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Tue, 16 Sep 2025 10:21:48 +0200 Subject: [PATCH 058/204] =?UTF-8?q?Make=20debugging=20failing=20tests=20(c?= =?UTF-8?q?heck=20and=20update=20expect=20output=20values)=20easier=20?= =?UTF-8?q?=F0=9F=94=A5=20=20(#40727)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix * fix --------- Co-authored-by: ydshieh --- conftest.py | 7 + src/transformers/testing_utils.py | 690 ++++++++++++++++++++++++++++++ 2 files changed, 697 insertions(+) diff --git a/conftest.py b/conftest.py index 196d98716239..dd63a629d2c5 100644 --- a/conftest.py +++ b/conftest.py @@ -16,6 +16,7 @@ # by pytest before any tests are run import doctest +import os import sys import warnings from os.path import abspath, dirname, join @@ -27,6 +28,7 @@ HfDoctestModule, HfDocTestParser, is_torch_available, + patch_testing_methods_to_collect_info, patch_torch_compile_force_graph, ) @@ -145,3 +147,8 @@ def check_output(self, want, got, optionflags): # patch `torch.compile`: if `TORCH_COMPILE_FORCE_FULLGRAPH=1` (or values considered as true, e.g. yes, y, etc.), # the patched version will always run with `fullgraph=True`. patch_torch_compile_force_graph() + + + +if os.environ.get("PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS", "").lower() in ("yes", "true", "on", "y", "1"): + patch_testing_methods_to_collect_info() diff --git a/src/transformers/testing_utils.py b/src/transformers/testing_utils.py index afc0c3e6d794..15b32c5fe45c 100644 --- a/src/transformers/testing_utils.py +++ b/src/transformers/testing_utils.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import ast import collections import contextlib import copy @@ -31,6 +32,7 @@ import tempfile import threading import time +import traceback import types import unittest from collections import UserDict, defaultdict @@ -3433,6 +3435,384 @@ def patched(*args, **kwargs): torch.compile = patched +def _get_test_info(): + """ + Collect some information about the current test. + + For example, test full name, line number, stack, traceback, etc. + """ + + full_test_name = os.environ.get("PYTEST_CURRENT_TEST", "").split(" ")[0] + test_file, test_class, test_name = full_test_name.split("::") + + # from the most recent frame to the top frame + stack_from_inspect = inspect.stack() + # but visit from the top frame to the most recent frame + + test_frame, test_obj, test_method = None, None, None + for frame in reversed(stack_from_inspect): + if test_file in str(frame).replace(r"\\", "/"): + if test_name == frame.frame.f_locals["self"]._testMethodName: + test_frame = frame + # The test instance + test_obj = frame.frame.f_locals["self"] + test_method = getattr(test_obj, test_name) + break + + if test_frame is not None: + line_number = test_frame.lineno + + # most inner (recent) to most outer () frames + captured_frames = [] + to_capture = False + # up to the test method being called + for frame in reversed(stack_from_inspect): + if test_file in str(frame).replace(r"\\", "/"): + if "self" in frame.frame.f_locals and test_name == frame.frame.f_locals["self"]._testMethodName: + to_capture = True + elif "patched" in frame.frame.f_code.co_name: + to_capture = False + break + if to_capture: + captured_frames.append(frame) + + tb_next = None + for frame_info in reversed(captured_frames): + tb = types.TracebackType(tb_next, frame_info.frame, frame_info.frame.f_lasti, frame_info.frame.f_lineno) + tb_next = tb + test_traceback = tb + + stack = traceback.extract_stack() + + # The frame that calls this patched method (it may not be the test method) + # -1: `_get_test_info`; -2: `patched_xxx`; -3: the caller to `patched_xxx` + caller_frame = stack[-3] + caller_path = os.path.relpath(caller_frame.filename) + caller_lineno = caller_frame.lineno + + test_lineno = line_number + + # Get the code context in the test function/method. + from _pytest._code.source import Source + + with open(test_file) as fp: + s = fp.read() + source = Source(s) + test_code_context = "\n".join(source.getstatement(test_lineno - 1).lines) + + # Get the code context in the caller (to the patched function/method). + with open(caller_path) as fp: + s = fp.read() + source = Source(s) + caller_code_context = "\n".join(source.getstatement(caller_lineno - 1).lines) + + test_info = ( + f"test:\n\n{full_test_name}\n\n{'-' * 80}\n\ntest context: {test_file}:{test_lineno}\n\n{test_code_context}" + ) + test_info = f"{test_info}\n\n{'-' * 80}\n\ncaller context: {caller_path}:{caller_lineno}\n\n{caller_code_context}" + + return ( + full_test_name, + test_file, + test_lineno, + test_obj, + test_method, + test_frame, + test_traceback, + test_code_context, + caller_path, + caller_lineno, + caller_code_context, + test_info, + ) + + +def _get_call_arguments(code_context): + """ + Analyze the positional and keyword arguments in a call expression. + + This will extract the expressions of the positional and kwyword arguments, and associate them to the positions and + the keyword arugment names. + """ + + def get_argument_name(node): + """Extract the name/expression from an AST node""" + if isinstance(node, ast.Name): + return node.id + elif isinstance(node, ast.Attribute): + return ast.unparse(node) + elif isinstance(node, ast.Constant): + return repr(node.value) + else: + return ast.unparse(node) + + indent = len(code_context) - len(code_context.lstrip()) + code_context = code_context.replace(" " * indent, "") + + try: + # Parse the line + tree = ast.parse(code_context, mode="eval") + + assert isinstance(tree.body, ast.Call) + call_node = tree.body + + if call_node: + result = { + "positional_args": [], + "keyword_args": {}, + "starargs": None, # *args + "kwargs": None, # **kwargs + } + + # Extract positional arguments + for arg in call_node.args: + arg_name = get_argument_name(arg) + result["positional_args"].append(arg_name) + + # Extract keyword arguments + for keyword in call_node.keywords: + if keyword.arg is None: + # This is **kwargs + result["kwargs"] = get_argument_name(keyword.value) + else: + # Regular keyword argument + arg_name = get_argument_name(keyword.value) + result["keyword_args"][keyword.arg] = arg_name + + return result + + except (SyntaxError, AttributeError) as e: + print(f"Error parsing: {e}") + + return None + + +def _prepare_debugging_info(test_info, info): + """Combine the information about the test and the call information to a patched function/method within it.""" + + info = f"{test_info}\n\n{info}" + p = os.path.join(os.environ.get("_PATCHED_TESTING_METHODS_OUTPUT_DIR", ""), "captured_info.txt") + # TODO (ydshieh): This is not safe when we use pytest-xdist with more than 1 worker. + with open(p, "a") as fp: + fp.write(f"{info}\n\n{'=' * 120}\n\n") + + return info + + +def _patched_tearDown(self, *args, **kwargs): + """Used to report a test that has failures captured and handled by patched functions/methods (without re-raise). + + The patched functions/methods refer to the `patched` defined in `_patch_with_call_info`, which is applied to + `torch.testing.assert_close` and `unittest.case.TestCase.assertEqual`. + + The objective is to avoid a failure being silence after being processed. + + If there is any failure that is not handled by the patched functions/methods, we add custom error message for them + along with the usual pytest failure report. + """ + + # Check for regular failures before clearing: + # when `_patched_tearDown` is called, the current test fails due to an assertion error given by a method being + # patched by `_patch_with_call_info`. The patched method catches such an error and continue running the remaining + # statements within the test. If the test fails with another error not handled by the patched methods, we don't let + # pytest to fail and report it but the original failure (the first one that was processed) instead. + # We still record those failures not handled by the patched methods, and add custom messages along with the usual + # pytest failure report. + regular_failures_info = [] + if hasattr(self, "_outcome") and self._outcome.errors: + for error_entry in self._outcome.errors: + test_instance, (exc_type, exc_obj, exc_tb) = error_entry + # breakpoint() + regular_failures_info.append( + { + "message": f"{str(exc_obj)}\n\n", + "type": exc_type.__name__, + "file": "test_modeling_vit.py", + "line": 237, # get_deepest_frame_line(exc_tb) # Your helper function + } + ) + + # Clear the regular failure (i.e. that is not from any of our patched assertion methods) from pytest's records. + self._outcome.errors.clear() + + # reset back to the original tearDown method, so `_patched_tearDown` won't be run by the subsequent tests if they + # have only test failures that are not handle by the patched methods (or no test failure at all). + orig_tearDown = _patched_tearDown.orig_tearDown + type(self).tearDown = orig_tearDown + + # Call the original tearDown + orig_tearDown(self, *args, **kwargs) + + # Get the failure + test_method = getattr(self, self._testMethodName) + captured_failures = test_method.__func__.captured_failures[id(test_method)] + + # TODO: How could we show several exceptions in a sinigle test on the terminal? (Maybe not a good idea) + captured_exceptions = captured_failures[0]["exception"] + captured_traceback = captured_failures[0]["traceback"] + # Show the cpatured information on the terminal. + capturued_info = [x["info"] for x in captured_failures] + capturued_info_str = f"\n\n{'=' * 80}\n\n".join(capturued_info) + + # Enhance the exception message if there were suppressed failures + if regular_failures_info: + enhanced_message = f"""{str(captured_exceptions)} + +{"=" * 80} +Handled Failures: ({len(capturued_info)} handled): +{"-" * 80}\n +{capturued_info_str} + +{"=" * 80} +Unhandled Failures: ({len(regular_failures_info)} unhandled): +{"-" * 80}\n +{", ".join(f"{info['type']}: {info['message']}{info['file']}:{info['line']}" for info in regular_failures_info)} + +{"-" * 80} +Note: This failure occurred after other failures analyzed by the patched assertion methods. +To see the full details, temporarily disable assertion patching. +{"=" * 80}""" + + # Create new exception with enhanced message + enhanced_exception = type(captured_exceptions)(enhanced_message) + enhanced_exception.__cause__ = captured_exceptions.__cause__ + enhanced_exception.__context__ = captured_exceptions.__context__ + + # Raise with your existing traceback reconstruction + captured_exceptions = enhanced_exception + + # clean up the recorded status + del test_method.__func__.captured_failures + + raise captured_exceptions.with_traceback(captured_traceback) + + +def _patch_with_call_info(module_or_class, attr_name, _parse_call_info_func, target_args): + """ + Patch a callerable `attr_name` of a module or class `module_or_class`. + + This will allow us to collect the call information, e.g. the argument names and values, also the literal expressions + passed as the arguments. + """ + orig_method = getattr(module_or_class, attr_name) + if not callable(orig_method): + return + + def patched(*args, **kwargs): + # If the target callable is not called within a test, simply call it without modification. + if not os.environ.get("PYTEST_CURRENT_TEST", ""): + return orig_method(*args, **kwargs) + + try: + orig_method(*args, **kwargs) + except AssertionError as e: + captured_exception = e + # captured_traceback = e.__traceback__ + ( + full_test_name, + test_file, + test_lineno, + test_obj, + test_method, + test_frame, + test_traceback, + test_code_context, + caller_path, + caller_lineno, + caller_code_context, + test_info, + ) = _get_test_info() + test_info = f"{test_info}\n\n{'-' * 80}\n\npatched method: {orig_method.__module__}.{orig_method.__name__}" + call_argument_expressions = _get_call_arguments(caller_code_context) + + # This is specific + info = _parse_call_info_func(orig_method, args, kwargs, call_argument_expressions, target_args) + info = _prepare_debugging_info(test_info, info) + + # Save this, so we can raise at the end of the current test + captured_failure = { + "result": "failed", + "exception": captured_exception, + "traceback": test_traceback, + "info": info, + } + + # Record the failure status and its information, so we can raise it later. + # We are modifying the (unbound) function at class level: not its logic but only adding a new extra + # attribute. + if getattr(test_method.__func__, "captured_failures", None) is None: + test_method.__func__.captured_failures = {} + if id(test_method) not in test_method.__func__.captured_failures: + test_method.__func__.captured_failures[id(test_method)] = [] + test_method.__func__.captured_failures[id(test_method)].append(captured_failure) + + # This modifies the `tearDown` which will be called after every tests, but we reset it back inside + # `_patched_tearDown`. + if not hasattr(type(test_obj).tearDown, "orig_tearDown"): + orig_tearDown = type(test_obj).tearDown + _patched_tearDown.orig_tearDown = orig_tearDown + type(test_obj).tearDown = _patched_tearDown + + setattr(module_or_class, attr_name, patched) + + +def _parse_call_info(func, args, kwargs, call_argument_expressions, target_args): + """ + Prepare a string containing the call info to `func`, e.g. argument names/values/expressions. + """ + signature = inspect.signature(func) + signature_names = [param.name for param_name, param in signature.parameters.items()] + + # called as `self.method_name()` or `xxx.method_name()`. + if len(args) == len(call_argument_expressions["positional_args"]) + 1: + # We simply add "self" as the expression despite it might not be the actual argument name. + # (This part is very unlikely what a user would be interest to know) + call_argument_expressions["positional_args"] = ["self"] + call_argument_expressions["positional_args"] + + param_position_mapping = {param_name: idx for idx, param_name in enumerate(signature_names)} + + arg_info = {} + for arg_name in target_args: + if arg_name in kwargs: + arg_value = kwargs[arg_name] + arg_expr = call_argument_expressions["keyword_args"][arg_name] + else: + arg_pos = param_position_mapping[arg_name] + arg_value = args[arg_pos] + arg_expr = call_argument_expressions["positional_args"][arg_pos] + + arg_value_str = _format_py_obj(arg_value) + arg_info[arg_name] = {"arg_expr": arg_expr, "arg_value_str": arg_value_str} + + info = "" + for arg_name in arg_info: + arg_expr, arg_value_str = arg_info[arg_name]["arg_expr"], arg_info[arg_name]["arg_value_str"] + info += f"{'-' * 80}\n\nargument name: `{arg_name}`\nargument expression: `{arg_expr}`\n\nargument value:\n\n{arg_value_str}\n\n" + + # remove the trailing \n\n + info = info[:-2] + + return info + + +def patch_testing_methods_to_collect_info(): + """ + Patch some methods (`torch.testing.assert_close`, `unittest.case.TestCase.assertEqual`, etc). + + This will allow us to collect the call information, e.g. the argument names and values, also the literal expressions + passed as the arguments. + """ + p = os.path.join(os.environ.get("_PATCHED_TESTING_METHODS_OUTPUT_DIR", ""), "captured_info.txt") + Path(p).unlink(missing_ok=True) + + if is_torch_available(): + import torch + + _patch_with_call_info(torch.testing, "assert_close", _parse_call_info, target_args=("actual", "expected")) + + _patch_with_call_info(unittest.case.TestCase, "assertEqual", _parse_call_info, target_args=("first", "second")) + + def torchrun(script: str, nproc_per_node: int, is_torchrun: bool = True, env: Optional[dict] = None): """Run the `script` using `torchrun` command for multi-processing in a subprocess. Captures errors as necessary.""" with tempfile.NamedTemporaryFile(mode="w+", suffix=".py") as tmp: @@ -3451,3 +3831,313 @@ def torchrun(script: str, nproc_per_node: int, is_torchrun: bool = True, env: Op _ = subprocess.run(cmd, capture_output=True, env=env, text=True, check=True) except subprocess.CalledProcessError as e: raise Exception(f"The following error was captured: {e.stderr}") + + +def _format_tensor(t, indent_level=0, sci_mode=None): + """Format torch's tensor in a pretty way to be shown 👀 in the test report.""" + + # `torch.testing.assert_close` could accept python int/float numbers. + if not isinstance(t, torch.Tensor): + t = torch.tensor(t) + + # Simply make the processing below simpler (not to hande both case) + is_scalar = False + if t.ndim == 0: + t = torch.tensor([t]) + is_scalar = True + + # For scalar or one-dimensional tensor, keep it as one-line. If there is only one element along any dimension except + # the last one, we also keep it as one-line. + if t.ndim <= 1 or set(t.shape[0:-1]) == {1}: + # Use `detach` to remove `grad_fn=<...>`, and use `to("cpu")` to remove `device='...'` + t = t.detach().to("cpu") + + # We work directly with the string representation instead the tensor itself + t_str = str(t) + + # remove `tensor( ... )` so keep only the content + t_str = t_str.replace("tensor(", "").replace(")", "") + + # Sometimes there are extra spaces between `[` and the first digit of the first value (for alignment). + # For example `[[ 0.06, -0.51], [-0.76, -0.49]]`. It may have multiple consecutive spaces. + # Let's remove such extra spaces. + while "[ " in t_str: + t_str = t_str.replace("[ ", "[") + + # Put everything in a single line. We replace `\n` by a space ` ` so we still keep `,\n` as `, `. + t_str = t_str.replace("\n", " ") + + # Remove repeated spaces (introduced by the previous step) + while " " in t_str: + t_str = t_str.replace(" ", " ") + + # remove leading `[` and `]` for scalar tensor + if is_scalar: + t_str = t_str[1:-1] + + t_str = " " * 4 * indent_level + t_str + + return t_str + + # Otherwise, we separte the representations of every elements along an outer dimension by new lines (after a `,`). + # The representatioin each element is obtained by calling this function recursively with corrent `indent_level`. + else: + t_str = str(t) + + # (For the recursive calls should receive this value) + if sci_mode is None: + sci_mode = "e+" in t_str or "e-" in t_str + + # Use the original content to determine the scientific mode to use. This is required as the representation of + # t[index] (computed below) maybe have different format regarding scientific notation. + torch.set_printoptions(sci_mode=sci_mode) + + t_str = " " * 4 * indent_level + "[\n" + # Keep the ending `,` for all outer dimensions whose representations are not put in one-line, even if there is + # only one element along that dimension. + t_str += ",\n".join(_format_tensor(x, indent_level=indent_level + 1, sci_mode=sci_mode) for x in t) + t_str += ",\n" + " " * 4 * indent_level + "]" + + torch.set_printoptions(sci_mode=None) + + return t_str + + +def _quote_string(s): + """Given a string `s`, return a python literal expression that give `s` when it is used in a python source code. + + For example, if `s` is the string `abc`, the return value is `"abc"`. + + We choice double quotes over single quote despite `str(s)` would give `'abc'` instead of `"abc"`. + """ + has_single_quote = "'" in s + has_double_quote = '"' in s + + if has_single_quote and has_double_quote: + # replace any double quote by the raw string r'\"'. + s = s.replace('"', r"\"") + return f'"{s}"' + elif has_single_quote: + return f'"{s}"' + elif has_double_quote: + return f"'{s}'" + else: + return f'"{s}"' + + +def _format_py_obj(obj, indent=0, mode="", cache=None, prefix=""): + """Format python objects of basic built-in type in a pretty way so we could copy-past them to code editor easily. + + Currently, this support int, float, str, list, tuple, and dict. + + It also works with `torch.Tensor` via calling `format_tesnor`. + """ + + if cache is None: + cache = {} + else: + if (id(obj), indent, mode, prefix) in cache: + return cache[(id(obj), indent, mode, prefix)] + + # special format method for `torch.Tensor` + if str(obj.__class__) == "": + return _format_tensor(obj) + + elif obj.__class__.__name__ == "str": + quoted_string = _quote_string(obj) + # we don't want the newline being interpreted + quoted_string = quoted_string.replace("\n", r"\n") + output = quoted_string + + elif obj.__class__.__name__ in ["int", "float"]: + # for float like `1/3`, we will get `0.3333333333333333` + output = str(obj) + + elif obj.__class__.__name__ in ["list", "tuple", "dict"]: + parenthesis = { + "list": "[]", + "tuple": "()", + "dict": "{}", + } + p1, p2 = parenthesis[obj.__class__.__name__] + + elements_without_indent = [] + if isinstance(obj, dict): + for idx, (k, v) in enumerate(obj.items()): + last_element = idx == len(obj) - 1 + ok = _format_py_obj(k, indent=indent + 1, mode="one-line", cache=cache) + ov = _format_py_obj( + v, + indent=indent + 1, + mode=mode, + cache=cache, + prefix=ok.lstrip() + ": " + "," if not last_element else "", + ) + # Each element could be multiple-line, but the indent of its first line is removed + elements_without_indent.append(f"{ok.lstrip()}: {ov.lstrip()}") + + else: + for idx, x in enumerate(obj): + last_element = idx == len(obj) - 1 + o = _format_py_obj( + x, indent=indent + 1, mode=mode, cache=cache, prefix="," if not last_element else "" + ) + # Each element could be multiple-line, but the indent of its first line is removed + elements_without_indent.append(o.lstrip()) + + groups = [] + buf = [] + for idx, x in enumerate(elements_without_indent): + buf.append(x) + + x_expanded = "\n" in buf[-1] + not_last_element = idx != len(elements_without_indent) - 1 + # if `x` should be separated from subsequent elements + should_finalize_x = x_expanded or len(f"{' ' * (4 * (indent + 1))}") + len( + ", ".join(buf[-1:]) + ) > 120 - int(not_last_element) + + # if `buf[:-1]` (i.e. without `x`) should be combined together (into one line) + should_finalize_buf = x_expanded + + # the recursive call returns single line, so we can use it to determine if we can fit the width limit + if not should_finalize_buf: + buf_not_fit_into_one_line = len(f"{' ' * (4 * (indent + 1))}") + len(", ".join(buf)) > 120 - int( + not_last_element + ) + should_finalize_buf = buf_not_fit_into_one_line + + # any element of iterable type need to be on its own line + if (type(obj[idx]) if type(obj) is not dict else type(list(obj.values())[idx])) in [list, tuple, dict]: + should_finalize_x = True + should_finalize_buf = True + + # any type change --> need to be added after a new line + prev_type = None + current_type = type(obj[idx]) if type(obj) is not dict else type(list(obj.values())[idx]) + if len(buf) > 1: + prev_type = type(obj[idx - 1]) if type(obj) is not dict else type(list(obj.values())[idx - 1]) + type_changed = current_type != prev_type + if type_changed: + should_finalize_buf = True + + # all elements in the buf are string --> don't finalize the buf by width limit + if prev_type is None or (prev_type is str and current_type is str): + should_finalize_buf = False + + # collect as many elements of string type as possible (without width limit). + # These will be examined as a whole (if not fit into the width, each element would be in its own line) + if current_type is str: + should_finalize_x = False + # `len(buf) == 1` or `obj[idx-1]` is a string + if prev_type in [None, str]: + should_finalize_buf = False + + if should_finalize_buf: + orig_buf_len = len(buf) + + if orig_buf_len > 1: + not_fit_into_one_line = None + + # all elements in `obj` that give `buf[:-1]` are string. + if prev_type is str: + # `-1` at the end: because buf[-2] is not the last element + not_fit_into_one_line = len(f"{' ' * (4 * (indent + 1))}") + len(", ".join(buf[:-1])) > 120 - 1 + + if not_fit_into_one_line: + for x in buf[:-1]: + groups.append([x]) + else: + groups.append(buf[:-1]) + + buf = buf[-1:] + + if should_finalize_x: + groups.append(buf) + buf = [] + + # The last buf + if len(buf) > 0: + not_fit_into_one_line = None + if current_type is str: + # no `-1` at the end: because buf[-1] is the last element + not_fit_into_one_line = len(f"{' ' * (4 * (indent + 1))}") + len(", ".join(buf)) > 120 + + if not_fit_into_one_line: + for x in buf: + groups.append([x]) + else: + groups.append(buf) + + output = f"{' ' * 4 * indent}{p1}\n" + element_strings = [f"{' ' * (4 * (indent + 1))}" + ", ".join(buf) for buf in groups] + output += ",\n".join(element_strings) + output += f"\n{' ' * 4 * indent}{p2}" + + # if all elements are in one-line + no_new_line_in_elements = all("\n" not in x for x in element_strings) + # if yes, we can form a one-line representation of `obj` + could_use_one_line = no_new_line_in_elements + + # if mode == "one-line", this function always returns one-line representation, so `no_new_line_in_elements` + # will be `True`. + if could_use_one_line: + one_line_form = ", ".join([x.lstrip() for x in element_strings]) + one_line_form = f"{p1}{one_line_form}{p2}" + + if mode == "one-line": + return output + + # check with the width limit + could_use_one_line = len(f"{' ' * 4 * indent}") + len(prefix) + len(one_line_form) <= 120 + + # extra conditions for returning one-line representation + def use_one_line_repr(obj): + # interable types + if type(obj) in (list, tuple, dict): + # get all types + element_types = [] + if type(obj) is dict: + element_types.extend(type(x) for x in obj.values()) + elif type(obj) in [list, tuple]: + element_types.extend(type(x) for x in obj) + + # At least one element is of iterable type + if any(x in (list, tuple, dict) for x in element_types): + # If `obj` has more than one element and at least one of them is iterable --> no one line repr. + if len(obj) > 1: + return False + + # only one element that is iterable, but not the same type as `obj` --> no one line repr. + if type(obj) is not type(obj[0]): + return False + + # one-line repr. if possible, without width limit + return no_new_line_in_elements + + # all elements are of simple types, but more than one type --> no one line repr. + if len(set(element_types)) > 1: + return False + + # all elements are of the same simple type + if element_types[0] in [int, float]: + # one-line repr. without width limit + return no_new_line_in_elements + elif element_types[0] in [str]: + if len(obj) == 1: + # one single string element --> one-line repr. without width limit + return no_new_line_in_elements + else: + # multiple string elements --> one-line repr. if fit into width limit + return could_use_one_line + + # simple types (int, flat, string) + return True + + # width condition combined with specific mode conditions + if use_one_line_repr(obj): + output = f"{' ' * 4 * indent}{one_line_form}" + + cache[(id(obj), indent, mode, prefix)] = output + + return output From 60c95539f7dce43b203c505c2c2835b55062b027 Mon Sep 17 00:00:00 2001 From: Mohamed Mekkouri <93391238+MekkCyber@users.noreply.github.com> Date: Tue, 16 Sep 2025 10:50:54 +0200 Subject: [PATCH 059/204] Fixing the call to kernelize (#40628) * fix * style * overload train and eval * add getter and setter --- src/transformers/modeling_utils.py | 48 +++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index c46422784e13..4d2011b09a15 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -5203,14 +5203,7 @@ def _assign_original_dtype(module): # check if using kernels if use_kernels: - if not is_kernels_available(): - raise ValueError( - "Kernels are not available. To use kernels, please install kernels using `pip install kernels`" - ) - - from kernels import Device, kernelize - - kernelize(model, device=Device(type=model.device.type)) + model.use_kernels = True # If it is a model with generation capabilities, attempt to load generation files (generation config, # custom generate function) @@ -5971,6 +5964,36 @@ def loss_function(self): def loss_function(self, value): self._loss_function = value + def kernelize(self): + if not is_kernels_available(): + raise ValueError( + "Kernels are not available. To use kernels, please install kernels using `pip install kernels`" + ) + from kernels import Device, Mode, kernelize + + mode = Mode.INFERENCE if not self.training else Mode.TRAINING + kernelize(self, device=Device(type=self.device.type), mode=mode) + self._use_kernels = True + + @property + def use_kernels(self) -> bool: + return getattr(self, "_use_kernels", False) + + @use_kernels.setter + def use_kernels(self, value: bool) -> None: + # Avoid re-kernelizing if already enabled + if bool(value) and getattr(self, "_use_kernels", False): + return + + if value: + self.kernelize() + else: + if getattr(self, "_use_kernels", False): + logger.warning_once( + "Disabling kernels at runtime is a no-op as there is no 'unkernelize' routine; keeping current kernels active." + ) + self._use_kernels = False + def get_compiled_call(self, compile_config: Optional[CompileConfig]) -> Callable: """Return a `torch.compile`'d version of `self.__call__`. This is useful to dynamically choose between non-compiled/compiled `forward` during inference, especially to switch between prefill (where we don't @@ -6093,6 +6116,15 @@ def get_parameter_or_buffer(self, target: str): raise AttributeError(f"`{target}` is neither a parameter, buffer, nor extra state.") + def train(self, mode: bool = True): + out = super().train(mode) + if self.use_kernels: + self.kernelize() + return out + + def eval(self): + return self.train(False) + PreTrainedModel.push_to_hub = copy_func(PreTrainedModel.push_to_hub) if PreTrainedModel.push_to_hub.__doc__ is not None: From 294ec23146c8ae0b30337ea3d6019bc0b06407c2 Mon Sep 17 00:00:00 2001 From: Pablo Montalvo <39954772+molbap@users.noreply.github.com> Date: Tue, 16 Sep 2025 10:57:13 +0200 Subject: [PATCH 060/204] Fix getter regression (#40824) * test things * style * move tests to a sane place --- src/transformers/modeling_utils.py | 9 +- tests/utils/test_modeling_utils.py | 178 +++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 3 deletions(-) diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index 4d2011b09a15..a11f7743ed8e 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -3004,11 +3004,14 @@ def get_decoder(self): if hasattr(self, "model"): inner = self.model - if hasattr(inner, "get_decoder"): + # See: https://github.com/huggingface/transformers/issues/40815 + if hasattr(inner, "get_decoder") and type(inner) is not type(self): return inner.get_decoder() return inner - return None # raise AttributeError(f"{self.__class__.__name__} has no decoder; override `get_decoder()` if needed.") + # If this is a base transformer model (no decoder/model attributes), return self + # This handles cases like MistralModel which is itself the decoder + return self def set_decoder(self, decoder): """ @@ -3027,7 +3030,7 @@ def set_decoder(self, decoder): self.model = decoder return - return # raise AttributeError(f"{self.__class__.__name__} cannot accept a decoder; override `set_decoder()`.") + return def _init_weights(self, module): """ diff --git a/tests/utils/test_modeling_utils.py b/tests/utils/test_modeling_utils.py index 7f24c9882540..be55cc563300 100644 --- a/tests/utils/test_modeling_utils.py +++ b/tests/utils/test_modeling_utils.py @@ -39,16 +39,27 @@ AutoModel, AutoModelForImageClassification, AutoModelForSequenceClassification, + BartConfig, + BartForConditionalGeneration, CLIPTextModelWithProjection, DynamicCache, + GPT2Config, + GPT2LMHeadModel, + LlavaConfig, LlavaForConditionalGeneration, + MistralConfig, MistralForCausalLM, + OPTConfig, + OPTForCausalLM, OwlViTForObjectDetection, PretrainedConfig, + T5Config, + T5ForConditionalGeneration, is_torch_available, logging, ) from transformers.modeling_flash_attention_utils import is_flash_attn_available +from transformers.models.mistral.modeling_mistral import MistralModel from transformers.testing_utils import ( TOKEN, CaptureLogger, @@ -2871,3 +2882,170 @@ def forward(self, hidden_states, attention_mask): model.save_pretrained(tmpdirname) model = MyModel.from_pretrained(tmpdirname) self.assertEqual(model.my_layer.some_counter, 42) + + +class TestGetDecoder(unittest.TestCase): + def test_causal_lm_get_decoder_returns_underlying_model(self): + cfg = MistralConfig( + vocab_size=128, + hidden_size=32, + intermediate_size=64, + num_hidden_layers=2, + num_attention_heads=4, + ) + model = MistralForCausalLM(cfg) + dec = model.get_decoder() + + assert dec is model.model, f"Expected get_decoder() to return model.model, got {type(dec)}" + + def test_seq2seq_get_decoder_still_returns_decoder_module(self): + cfg = BartConfig( + vocab_size=128, + d_model=32, + encoder_layers=2, + decoder_layers=2, + encoder_attention_heads=4, + decoder_attention_heads=4, + encoder_ffn_dim=64, + decoder_ffn_dim=64, + ) + model = BartForConditionalGeneration(cfg) + dec = model.get_decoder() + + assert dec is model.model.decoder, "Seq2seq get_decoder() should return the decoder submodule" + + def test_base_model_returns_self(self): + """Test that base transformer models (no decoder/model attributes) return self.""" + cfg = MistralConfig( + vocab_size=128, + hidden_size=32, + intermediate_size=64, + num_hidden_layers=2, + num_attention_heads=4, + ) + base_model = MistralModel(cfg) + dec = base_model.get_decoder() + + assert dec is base_model, f"Base model get_decoder() should return self, got {type(dec)}" + + def test_explicit_decoder_attribute_opt(self): + """Test models with explicit decoder attribute (OPT style).""" + cfg = OPTConfig( + vocab_size=128, + hidden_size=32, + ffn_dim=64, + num_hidden_layers=2, + num_attention_heads=4, + max_position_embeddings=512, + ) + model = OPTForCausalLM(cfg) + dec = model.get_decoder() + + assert dec is model.model.decoder, f"OPT get_decoder() should return model.decoder, got {type(dec)}" + + def test_explicit_decoder_attribute_t5(self): + """Test encoder-decoder models with explicit decoder attribute.""" + cfg = T5Config( + vocab_size=128, + d_model=32, + d_ff=64, + num_layers=2, + num_heads=4, + ) + model = T5ForConditionalGeneration(cfg) + dec = model.get_decoder() + + assert dec is model.decoder, f"T5 get_decoder() should return decoder attribute, got {type(dec)}" + + def test_same_type_recursion_prevention(self): + """Test that same-type recursion is prevented (see issue #40815).""" + cfg = MistralConfig( + vocab_size=128, + hidden_size=32, + intermediate_size=64, + num_hidden_layers=2, + num_attention_heads=4, + ) + model = MistralForCausalLM(cfg) + + assert type(model) is not type(model.model), "Types should be different to prevent recursion" + + dec = model.get_decoder() + assert dec is model.model, f"Should return model.model without infinite recursion, got {type(dec)}" + + inner_dec = model.model.get_decoder() + assert inner_dec is model.model, f"Inner model should return itself, got {type(inner_dec)}" + + def test_nested_wrapper_recursion(self): + """Test models that don't have model/decoder attributes return self.""" + cfg = GPT2Config( + vocab_size=128, + n_embd=32, + n_layer=2, + n_head=4, + n_positions=512, + ) + model = GPT2LMHeadModel(cfg) + dec = model.get_decoder() + + assert dec is model, f"GPT2 get_decoder() should return self (fallback), got {type(dec)}" + + def test_model_without_get_decoder(self): + """Test edge case where model has model attribute but no get_decoder method.""" + + class MockInnerModel: + """Mock model without get_decoder method.""" + + pass + + class MockWrapperModel: + """Mock wrapper with model attribute but inner has no get_decoder.""" + + def __init__(self): + self.model = MockInnerModel() + + def get_decoder(self): + if hasattr(self, "decoder"): + return self.decoder + if hasattr(self, "model"): + inner = self.model + if hasattr(inner, "get_decoder") and type(inner) is not type(self): + return inner.get_decoder() + return inner + return self + + wrapper = MockWrapperModel() + dec = wrapper.get_decoder() + + assert dec is wrapper.model, f"Should return inner model when no get_decoder, got {type(dec)}" + + def test_vision_language_model(self): + """Test vision-language models like LLaVA that delegate to language_model.""" + text_config = MistralConfig( + vocab_size=128, + hidden_size=32, + intermediate_size=64, + num_hidden_layers=2, + num_attention_heads=4, + ) + + vision_config = { + "hidden_size": 32, + "intermediate_size": 64, + "num_hidden_layers": 2, + "num_attention_heads": 4, + "num_channels": 3, + "image_size": 224, + "patch_size": 16, + } + + cfg = LlavaConfig( + text_config=text_config.to_dict(), + vision_config=vision_config, + vocab_size=128, + ) + + model = LlavaForConditionalGeneration(cfg) + dec = model.get_decoder() + + assert dec is model.language_model, f"LLaVA get_decoder() should return language_model, got {type(dec)}" From dcb52bf5a16c59a728a517daaffbbe74461ad00e Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:00:07 +0200 Subject: [PATCH 061/204] Fix flaky `Gemma3nAudioFeatureExtractionTest::test_dither` (#40902) * fix * fix * fix --------- Co-authored-by: ydshieh --- tests/models/gemma3n/test_feature_extraction_gemma3n.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/models/gemma3n/test_feature_extraction_gemma3n.py b/tests/models/gemma3n/test_feature_extraction_gemma3n.py index 29dba741c3da..30d2e1bb9468 100644 --- a/tests/models/gemma3n/test_feature_extraction_gemma3n.py +++ b/tests/models/gemma3n/test_feature_extraction_gemma3n.py @@ -277,10 +277,12 @@ def test_dither(self): diff = input_features_dither - input_features_no_dither # features are not identical - self.assertTrue(np.abs(diff).mean() > 1e-6) + assert np.abs(diff).mean() > 1e-6 # features are not too different - self.assertTrue(np.abs(diff).mean() <= 1e-4) - self.assertTrue(np.abs(diff).max() <= 5e-3) + # the heuristic value `7e-4` is obtained by running 50000 times (maximal value is around 3e-4). + assert np.abs(diff).mean() < 7e-4 + # the heuristic value `8e-1` is obtained by running 50000 times (maximal value is around 5e-1). + assert np.abs(diff).max() < 8e-1 @require_torch def test_double_precision_pad(self): From b947b60c95c62599b496a8f64698aa52aeb23bb8 Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Tue, 16 Sep 2025 11:41:20 +0200 Subject: [PATCH 062/204] [cache] Merge static sliding and static chunked layer (#40893) * merge * get rid of tensors in get_mask_sizes!! * remove branch * add comment explanation * re-add the class with deprecation cycle --- src/transformers/cache_utils.py | 146 +++++++++++--------------------- 1 file changed, 49 insertions(+), 97 deletions(-) diff --git a/src/transformers/cache_utils.py b/src/transformers/cache_utils.py index d7b0fe6e1f83..e519db4d8f2d 100644 --- a/src/transformers/cache_utils.py +++ b/src/transformers/cache_utils.py @@ -372,85 +372,6 @@ def __init__(self, max_cache_len: int, sliding_window: int): super().__init__(max_cache_len=effective_max_cache_len) self.cumulative_length = 0 - def update( - self, - key_states: torch.Tensor, - value_states: torch.Tensor, - cache_kwargs: Optional[dict[str, Any]] = None, - ) -> tuple[torch.Tensor, torch.Tensor]: - """ - Update the key and value caches in-place, and return the necessary keys and value states. - - Args: - key_states (`torch.Tensor`): The new key states to cache. - value_states (`torch.Tensor`): The new value states to cache. - cache_kwargs (`dict[str, Any]`, *optional*): Additional arguments for the cache. - - Returns: - tuple[`torch.Tensor`, `torch.Tensor`]: The key and value states. - """ - # Lazy initialization - if self.keys is None: - self.lazy_initialization(key_states) - - cache_position = cache_kwargs.get("cache_position") - - is_full = self.cumulative_length >= self.max_cache_len - # Update it now that we saved the value above - self.cumulative_length += key_states.shape[-2] - - # Handle prefill phase when prompt length > sliding_window_size. - # Note that we store cropped key/value states in the cache but return the full key/value states. - if cache_position.shape[0] > self.max_cache_len: - self.keys.copy_(key_states[:, :, -self.max_cache_len :, :]) - self.values.copy_(value_states[:, :, -self.max_cache_len :, :]) - # Return the full states here - return key_states, value_states - - # Here we only assume decoding stage, i.e. 1 token at a time - if is_full: - # Roll all values to the left by 1 position - new_keys = self.keys.roll(-1, dims=-2) - new_values = self.values.roll(-1, dims=-2) - # Overwrite the last position with new states - # (note: very important to use a tensor to index here, see https://github.com/pytorch/pytorch/issues/159855) - index = torch.tensor([-1], dtype=int, device=self.device) - new_keys[:, :, index] = key_states - new_values[:, :, index] = value_states - - # Copy back into `self` (do not just assign again) in order to keep the static dynamo address - self.keys.copy_(new_keys) - self.values.copy_(new_values) - else: - try: - self.keys.index_copy_(2, cache_position, key_states) - self.values.index_copy_(2, cache_position, value_states) - except NotImplementedError: - self.keys[:, :, cache_position] = key_states - self.values[:, :, cache_position] = value_states - - return self.keys, self.values - - def get_mask_sizes(self, cache_position: torch.Tensor) -> tuple[int, int]: - """Return the length and offset of the cache, used to generate the attention mask""" - query_length = cache_position.shape[0] - first_cache_position = cache_position[0] - - kv_offset = torch.clamp(first_cache_position - self.max_cache_len + 1, min=0) - # This is not general (see HybridChunkedCache for the whole general case), but it's what the cache returns - kv_length = max(query_length, self.max_cache_len) - return kv_length, kv_offset - - def get_seq_length(self) -> int: - """Returns the sequence length of the cached states.""" - return self.cumulative_length - - -class ChunkedSlidingLayer(SlidingWindowLayer): - """ - An extended SlidingWindowLayer that supports prefill chunking, originally implemented for Llama 4. - """ - def update( self, key_states: torch.Tensor, @@ -480,16 +401,29 @@ def update( self.cumulative_length += key_states.shape[-2] if is_full: - full_key_states = torch.cat((self.keys[:, :, 1:, :], key_states), dim=-2) - full_value_states = torch.cat((self.values[:, :, 1:, :], value_states), dim=-2) - # Fast decoding path -> here as the effective size is still sliding window, it is extremely important - # to return `self.key_cache[layer_idx]` and `self.value_cache[layer_idx]`, as they have the fixed address - # in memory (the values are the same as the full states, but not the address!!) + # In general, we should use a much simpler `cat` here as well, independently of the states size. However, + # dynamo is currently bugged when doing it - see https://github.com/pytorch/pytorch/issues/159855 for more details if key_states.shape[-2] == 1: - self.keys.copy_(full_key_states) - self.values.copy_(full_value_states) + # Roll all values to the left by 1 position + new_keys = self.keys.roll(-1, dims=-2) + new_values = self.values.roll(-1, dims=-2) + # Overwrite the last position with new states + # (note: very important to use a tensor to index here, see https://github.com/pytorch/pytorch/issues/159855) + index = torch.tensor([-1], dtype=int, device=self.device) + new_keys[:, :, index] = key_states + new_values[:, :, index] = value_states + + # Copy back into `self` (do not just assign again) in order to keep the static dynamo address + self.keys.copy_(new_keys) + self.values.copy_(new_values) + # Very important to return the `self` tensors here, as they have the static dynamo address return self.keys, self.values - elif not is_full and cumulative_length + key_states.shape[2] > self.max_cache_len: + # Already full but using more than 1 new token (e.g. prefill caching, chat continuation, etc...) + else: + full_key_states = torch.cat((self.keys[:, :, 1:, :], key_states), dim=-2) + full_value_states = torch.cat((self.values[:, :, 1:, :], value_states), dim=-2) + # Not yet full, but becoming full on this update + elif cumulative_length + key_states.shape[2] > self.max_cache_len: # Fast prefill path, no need to cat() in this case, as the cache is currently empty if cumulative_length == 0: full_key_states = key_states @@ -504,33 +438,38 @@ def update( except NotImplementedError: self.keys[:, :, cache_position] = key_states self.values[:, :, cache_position] = value_states + + # Very important to return the `self` tensors here, as they have the static dynamo address return self.keys, self.values + # We only cache the last `sliding_window` tokens self.keys.copy_(full_key_states[:, :, -self.max_cache_len :, :]) self.values.copy_(full_value_states[:, :, -self.max_cache_len :, :]) # we should return the whole states instead of `self.keys/values` here, as otherwise we lose some context - # which is outside the window return full_key_states, full_value_states def get_mask_sizes(self, cache_position: torch.Tensor) -> tuple[int, int]: """Return the length and offset of the cache, used to generate the attention mask""" query_length = cache_position.shape[0] - first_cache_position = cache_position[0] sliding_window = self.max_cache_len + is_full = self.cumulative_length >= self.max_cache_len - kv_offset = torch.clamp(first_cache_position - sliding_window + 1, min=0) - # This is the true general case for any Cache using local attention (sliding or chunked) - if first_cache_position >= sliding_window: - # Here the Cache is already full + kv_offset = max(self.cumulative_length - sliding_window + 1, 0) + # The cache is already full + if is_full: kv_length = sliding_window + query_length - 1 - elif first_cache_position < sliding_window and first_cache_position + query_length > sliding_window: - # Here the Cache becomes full with the new input - kv_length = first_cache_position + query_length + # Not yet full, but becoming full on this update + elif self.cumulative_length + query_length > sliding_window: + kv_length = self.cumulative_length + query_length else: # Here the Cache is still smaller than the local size, but we return the local size as it's static kv_length = sliding_window return kv_length, kv_offset + def get_seq_length(self) -> int: + """Returns the sequence length of the cached states.""" + return self.cumulative_length + class QuantizedLayer(DynamicLayer): """ @@ -1023,6 +962,8 @@ def __init__( layer_types = layer_types[: -config.num_kv_shared_layers] for layer_type in layer_types: + # From a cache point of view, both sliding and chunked are the same in how they should behave and how many + # states they should return - only the mask changes to make them different at the end! if layer_type in ("sliding_attention", "chunked_attention"): layers.append(DynamicSlidingWindowLayer(sliding_window=sliding_window)) else: @@ -1141,7 +1082,9 @@ def __init__( if layer_type == "sliding_attention": layer = SlidingWindowLayer(max_cache_len=max_cache_len, sliding_window=config.sliding_window) elif layer_type == "chunked_attention": - layer = ChunkedSlidingLayer(max_cache_len=max_cache_len, sliding_window=config.attention_chunk_size) + # From a cache point of view, both sliding and chunked are the same in how they should behave and how many + # states they should return - only the mask changes to make them different at the end! + layer = SlidingWindowLayer(max_cache_len=max_cache_len, sliding_window=config.attention_chunk_size) else: layer = StaticLayer(max_cache_len=max_cache_len) layers.append(layer) @@ -1414,6 +1357,15 @@ def is_compileable(self) -> bool: ### Deprecated classes +class ChunkedSlidingLayer(SlidingWindowLayer): + def __init__(self, max_cache_len: int, sliding_window: int): + logger.warning_once( + "`ChunkedSlidingLayer` is deprecated and will be removed in version v4.59 " + "Use `SlidingWindowLayer` instead, which has the exact same functionalities." + ) + super().__init__(max_cache_len, sliding_window) + + class OffloadedCache(DynamicCache): def __init__(self) -> None: logger.warning_once( From f096c5bd6b212a56986b447b9b773da9d8f93ec3 Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Tue, 16 Sep 2025 12:14:12 +0200 Subject: [PATCH 063/204] Harmonize CacheLayer names (#40892) * unify naming * style * doc as well * post rebase fix * style * style * revert --- conftest.py | 1 - docs/source/en/cache_explanation.md | 4 ++-- docs/source/en/internal/generation_utils.md | 2 +- docs/source/ko/cache_explanation.md | 4 ++-- docs/source/ko/internal/generation_utils.md | 2 +- src/transformers/__init__.py | 2 ++ src/transformers/cache_utils.py | 21 ++++++++++++++++----- 7 files changed, 24 insertions(+), 12 deletions(-) diff --git a/conftest.py b/conftest.py index dd63a629d2c5..67064fbd5d3d 100644 --- a/conftest.py +++ b/conftest.py @@ -149,6 +149,5 @@ def check_output(self, want, got, optionflags): patch_torch_compile_force_graph() - if os.environ.get("PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS", "").lower() in ("yes", "true", "on", "y", "1"): patch_testing_methods_to_collect_info() diff --git a/docs/source/en/cache_explanation.md b/docs/source/en/cache_explanation.md index 04272b7ff895..0e192fd47f42 100644 --- a/docs/source/en/cache_explanation.md +++ b/docs/source/en/cache_explanation.md @@ -85,7 +85,7 @@ When you use Transformers' [`Cache`] class, the self-attention module performs s Caches are structured as a list of layers, where each layer contains a key and value cache. The key and value caches are tensors with the shape `[batch_size, num_heads, seq_len, head_dim]`. -Layers can be of different types (e.g. `DynamicLayer`, `StaticLayer`, `SlidingWindowLayer`), which mostly changes how sequence length is handled and how the cache is updated. +Layers can be of different types (e.g. `DynamicLayer`, `StaticLayer`, `StaticSlidingWindowLayer`), which mostly changes how sequence length is handled and how the cache is updated. The simplest is a `DynamicLayer` that grows as more tokens are processed. The sequence length dimension (`seq_len`) increases with each new token: @@ -94,7 +94,7 @@ cache.layers[idx].keys = torch.cat([cache.layers[idx].keys, key_states], dim=-2) cache.layers[idx].values = torch.cat([cache.layers[idx].values, value_states], dim=-2) ``` -Other layer types like `StaticLayer` and `SlidingWindowLayer` have a fixed sequence length that is set when the cache is created. This makes them compatible with `torch.compile`. In the case of `SlidingWindowLayer`, existing tokens are shifted out of the cache when a new token is added. +Other layer types like `StaticLayer` and `StaticSlidingWindowLayer` have a fixed sequence length that is set when the cache is created. This makes them compatible with `torch.compile`. In the case of `StaticSlidingWindowLayer`, existing tokens are shifted out of the cache when a new token is added. The example below demonstrates how to create a generation loop with [`DynamicCache`]. As discussed, the attention mask is a concatenation of past and current token values and `1` is added to the cache position for the next token. diff --git a/docs/source/en/internal/generation_utils.md b/docs/source/en/internal/generation_utils.md index d267741a2c33..a35ae4d5d066 100644 --- a/docs/source/en/internal/generation_utils.md +++ b/docs/source/en/internal/generation_utils.md @@ -253,7 +253,7 @@ A [`Constraint`] can be used to force the generation to include specific tokens - update - lazy_initialization -[[autodoc]] SlidingWindowLayer +[[autodoc]] StaticSlidingWindowLayer - update - lazy_initialization diff --git a/docs/source/ko/cache_explanation.md b/docs/source/ko/cache_explanation.md index a2390449738a..6f2a3242616c 100644 --- a/docs/source/ko/cache_explanation.md +++ b/docs/source/ko/cache_explanation.md @@ -84,7 +84,7 @@ Transformers의 [`Cache`] 클래스를 사용할 때, 셀프 어텐션 모듈은 캐시는 각 레이어가 key와 value 캐시를 포함하는 레이어 목록 형태로 구성되어 있습니다. key 및 value 캐시는 `[batch_size, num_heads, seq_len, head_dim]` 형태의 텐서입니다. -레이어는 서로 다른 타입일 수 있으며(예: `DynamicLayer`, `StaticLayer`, `SlidingWindowLayer`), 이는 주로 시퀀스 길이를 어떻게 처리하고 캐시를 어떻게 갱신하는지에 따라 달라집니다. +레이어는 서로 다른 타입일 수 있으며(예: `DynamicLayer`, `StaticLayer`, `StaticSlidingWindowLayer`), 이는 주로 시퀀스 길이를 어떻게 처리하고 캐시를 어떻게 갱신하는지에 따라 달라집니다. 가장 단순한 형태는 `DynamicLayer`로, 더 많은 토큰이 처리됨에 따라 점진적으로 확장됩니다. 시퀀스 길이 차원(`seq_len`)은 새로운 토큰이 추가될 때마다 증가합니다: @@ -93,7 +93,7 @@ cache.layers[idx].keys = torch.cat([cache.layers[idx].keys, key_states], dim=-2) cache.layers[idx].values = torch.cat([cache.layers[idx].values, value_states], dim=-2) ``` -`StaticLayer`나 `SlidingWindowLayer`와 같은 다른 레이어 타입은 캐시가 생성될 때 고정된 시퀀스 길이를 가지며, 이는 `torch.compile`과 호환되도록 만듭니다. `SlidingWindowLayer`의 경우, 새로운 토큰이 추가되면 기존 토큰은 캐시에서 제거됩니다. +`StaticLayer`나 `StaticSlidingWindowLayer`와 같은 다른 레이어 타입은 캐시가 생성될 때 고정된 시퀀스 길이를 가지며, 이는 `torch.compile`과 호환되도록 만듭니다. `StaticSlidingWindowLayer`의 경우, 새로운 토큰이 추가되면 기존 토큰은 캐시에서 제거됩니다. 아래 예제는 [`DynamicCache`]로 생성 루프를 만드는 방법을 보여줍니다. 논의된 바와 같이, 어텐션 마스크는 과거와 현재 토큰값의 연결이며 다음 토큰을 위해 캐시 위치에 `1`이 추가됩니다. diff --git a/docs/source/ko/internal/generation_utils.md b/docs/source/ko/internal/generation_utils.md index 8b8442609979..d97dfb2ae6f3 100644 --- a/docs/source/ko/internal/generation_utils.md +++ b/docs/source/ko/internal/generation_utils.md @@ -330,7 +330,7 @@ generation_output[:2] [[autodoc]] StaticLayer - update -[[autodoc]] SlidingWindowLayer +[[autodoc]] StaticSlidingWindowLayer - update [[autodoc]] QuantoQuantizedLayer diff --git a/src/transformers/__init__.py b/src/transformers/__init__.py index 98c3801bee79..d6399aa8d094 100755 --- a/src/transformers/__init__.py +++ b/src/transformers/__init__.py @@ -378,6 +378,7 @@ "CacheLayerMixin", "DynamicLayer", "StaticLayer", + "StaticSlidingWindowLayer", "SlidingWindowLayer", "ChunkedSlidingLayer", "QuantoQuantizedLayer", @@ -601,6 +602,7 @@ from .cache_utils import SlidingWindowLayer as SlidingWindowLayer from .cache_utils import StaticCache as StaticCache from .cache_utils import StaticLayer as StaticLayer + from .cache_utils import StaticSlidingWindowLayer as StaticSlidingWindowLayer from .configuration_utils import PretrainedConfig as PretrainedConfig from .convert_slow_tokenizer import SLOW_TO_FAST_CONVERTERS as SLOW_TO_FAST_CONVERTERS from .convert_slow_tokenizer import convert_slow_tokenizer as convert_slow_tokenizer diff --git a/src/transformers/cache_utils.py b/src/transformers/cache_utils.py index e519db4d8f2d..7c79f7dd4548 100644 --- a/src/transformers/cache_utils.py +++ b/src/transformers/cache_utils.py @@ -352,7 +352,7 @@ def get_max_cache_shape(self) -> int: return self.max_cache_len -class SlidingWindowLayer(StaticLayer): +class StaticSlidingWindowLayer(StaticLayer): """ A static cache layer that stores the key and value states as static tensors of shape `[batch_size, num_heads, min(max_cache_len, sliding_window), head_dim]`. It lazily allocates its full backing @@ -1080,11 +1080,13 @@ def __init__( layers = [] for layer_type in layer_types: if layer_type == "sliding_attention": - layer = SlidingWindowLayer(max_cache_len=max_cache_len, sliding_window=config.sliding_window) + layer = StaticSlidingWindowLayer(max_cache_len=max_cache_len, sliding_window=config.sliding_window) elif layer_type == "chunked_attention": # From a cache point of view, both sliding and chunked are the same in how they should behave and how many # states they should return - only the mask changes to make them different at the end! - layer = SlidingWindowLayer(max_cache_len=max_cache_len, sliding_window=config.attention_chunk_size) + layer = StaticSlidingWindowLayer( + max_cache_len=max_cache_len, sliding_window=config.attention_chunk_size + ) else: layer = StaticLayer(max_cache_len=max_cache_len) layers.append(layer) @@ -1357,11 +1359,20 @@ def is_compileable(self) -> bool: ### Deprecated classes -class ChunkedSlidingLayer(SlidingWindowLayer): +class SlidingWindowLayer(StaticSlidingWindowLayer): + def __init__(self, max_cache_len: int, sliding_window: int): + logger.warning_once( + "`SlidingWindowLayer` is deprecated and will be removed in version v4.59 " + "Use `StaticSlidingWindowLayer` instead, which is a better name for it." + ) + super().__init__(max_cache_len, sliding_window) + + +class ChunkedSlidingLayer(StaticSlidingWindowLayer): def __init__(self, max_cache_len: int, sliding_window: int): logger.warning_once( "`ChunkedSlidingLayer` is deprecated and will be removed in version v4.59 " - "Use `SlidingWindowLayer` instead, which has the exact same functionalities." + "Use `StaticSlidingWindowLayer` instead, which has the exact same functionalities." ) super().__init__(max_cache_len, sliding_window) From 15d5f49502ea9f831fb4f195d12715e0529b5332 Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Tue, 16 Sep 2025 12:48:58 +0200 Subject: [PATCH 064/204] [cache] Only use scalars in `get_mask_sizes` (#40907) * remove tensor ops * style * style --- src/transformers/cache_utils.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/transformers/cache_utils.py b/src/transformers/cache_utils.py index 7c79f7dd4548..1e08144c414d 100644 --- a/src/transformers/cache_utils.py +++ b/src/transformers/cache_utils.py @@ -122,8 +122,7 @@ def get_mask_sizes(self, cache_position: torch.Tensor) -> tuple[int, int]: """Return the length and offset of the cache, used to generate the mask""" kv_offset = 0 query_length = cache_position.shape[0] - past_seen_tokens = self.get_seq_length() - kv_length = query_length + past_seen_tokens + kv_length = self.get_seq_length() + query_length return kv_length, kv_offset def get_seq_length(self) -> int: @@ -212,14 +211,13 @@ def update( def get_mask_sizes(self, cache_position: torch.Tensor) -> tuple[int, int]: """Return the length and offset of the cache, used to generate the attention mask""" query_length = cache_position.shape[0] - first_cache_position = cache_position[0] + is_full = self.cumulative_length >= self.sliding_window - kv_offset = torch.clamp(first_cache_position - self.sliding_window + 1, min=0) - - if self.get_seq_length() >= self.sliding_window: + kv_offset = max(self.cumulative_length - self.sliding_window + 1, 0) + if is_full: kv_length = self.sliding_window - 1 + query_length else: - kv_length = self.get_seq_length() + query_length + kv_length = self.cumulative_length + query_length return kv_length, kv_offset @@ -461,9 +459,10 @@ def get_mask_sizes(self, cache_position: torch.Tensor) -> tuple[int, int]: # Not yet full, but becoming full on this update elif self.cumulative_length + query_length > sliding_window: kv_length = self.cumulative_length + query_length + # Here the Cache is still smaller than the local size, but we return the local size as it's static else: - # Here the Cache is still smaller than the local size, but we return the local size as it's static kv_length = sliding_window + return kv_length, kv_offset def get_seq_length(self) -> int: From 288352dfce8cc03210f8f6288e3db3697379d49a Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Tue, 16 Sep 2025 13:01:51 +0200 Subject: [PATCH 065/204] Set seed for `Glm4vIntegrationTest` (#40905) * fix * fix * fix --------- Co-authored-by: ydshieh --- tests/models/glm4v/test_modeling_glm4v.py | 54 +++++++++++++++++------ 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/tests/models/glm4v/test_modeling_glm4v.py b/tests/models/glm4v/test_modeling_glm4v.py index 5d5e129f7e5a..6c3845b10e88 100644 --- a/tests/models/glm4v/test_modeling_glm4v.py +++ b/tests/models/glm4v/test_modeling_glm4v.py @@ -282,6 +282,8 @@ def test_inputs_embeds_matches_input_ids(self): @require_torch class Glm4vIntegrationTest(unittest.TestCase): def setUp(self): + cleanup(torch_device, gc_collect=True) + self.processor = AutoProcessor.from_pretrained("THUDM/GLM-4.1V-9B-Thinking") self.message = [ { @@ -340,8 +342,11 @@ def test_small_model_integration_test(self): # verify generation inputs = inputs.to(torch_device) + # This model on the hub has `do_sample=True`. + torch.manual_seed(42) + output = model.generate(**inputs, max_new_tokens=30) - EXPECTED_DECODED_TEXT = "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks" + EXPECTED_DECODED_TEXT = "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture doesn't look like a dog; it's actually a cat. Specifically" self.assertEqual( self.processor.decode(output[0], skip_special_tokens=True), EXPECTED_DECODED_TEXT, @@ -357,12 +362,15 @@ def test_small_model_integration_test_batch(self): batch_messages, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt" ).to(torch_device) + # This model on the hub has `do_sample=True`. + torch.manual_seed(42) + # it should not matter whether two images are the same size or not output = model.generate(**inputs, max_new_tokens=30) EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks", - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks" + "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture doesn't look like a dog; it's actually a cat. Specifically", + "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture has a stocky body, thick fur, and a face that's" ] # fmt: skip self.assertEqual( self.processor.batch_decode(output, skip_special_tokens=True), @@ -395,10 +403,13 @@ def test_small_model_integration_test_with_video(self): inputs = processor.apply_chat_template( messages, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt", padding=True ).to(torch_device) + + # This model on the hub has `do_sample=True`. + torch.manual_seed(42) + output = model.generate(**inputs, max_new_tokens=30) - EXPECTED_DECODED_TEXT = [ - "\n012345Describe this video.\nGot it, let's analyze the video. First, the scene is an indoor tennis court. There are two players: one in the foreground wearing" - ] # fmt: skip + EXPECTED_DECODED_TEXT = ["\n012345Describe this video.\nGot it, let's analyze the video. First, the scene is an indoor tennis court. There are two players: one in a white shirt"] # fmt: skip + self.assertEqual( processor.batch_decode(output, skip_special_tokens=True), EXPECTED_DECODED_TEXT, @@ -413,6 +424,9 @@ def test_small_model_integration_test_expand(self): self.message, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt" ).to(torch_device) + # This model on the hub has `do_sample=True`. + torch.manual_seed(42) + output = model.generate(**inputs, max_new_tokens=30, do_sample=False, num_beams=2, num_return_sequences=2) EXPECTED_DECODED_TEXT = [ @@ -442,12 +456,15 @@ def test_small_model_integration_test_batch_wo_image(self): padding=True, ).to(torch_device) + # This model on the hub has `do_sample=True`. + torch.manual_seed(42) + # it should not matter whether two images are the same size or not output = model.generate(**inputs, max_new_tokens=30) EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks", - '\nWho are you?\nGot it, the user is asking "Who are you?" I need to respond appropriately. First, I should clarify that I\'m an AI assistant' + "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture doesn't look like a dog; it's actually a cat. Specifically", + "\nWho are you?\nGot it, let's look at the user's question: \"Who are you?\" This is a common question when someone is just starting a conversation" ] # fmt: skip self.assertEqual( self.processor.batch_decode(output, skip_special_tokens=True), @@ -469,12 +486,15 @@ def test_small_model_integration_test_batch_different_resolutions(self): padding=True, ).to(torch_device) + # This model on the hub has `do_sample=True`. + torch.manual_seed(42) + # it should not matter whether two images are the same size or not output = model.generate(**inputs, max_new_tokens=30) EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks", - "\nWhat kind of dog is this?\nGot it, let's look at the image. Wait, the animals here are cats, not dogs. The question is about a dog, but" + "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture doesn't look like a dog; it's actually a cat. Specifically", + "\nWhat kind of dog is this?\nGot it, let's look at the image. Wait, the animals here are cats, not dogs. The question is about a dog, but", ] # fmt: skip self.assertEqual( self.processor.batch_decode(output, skip_special_tokens=True), @@ -501,12 +521,15 @@ def test_small_model_integration_test_batch_flashatt2(self): padding=True, ).to(torch_device) + # This model on the hub has `do_sample=True`. + torch.manual_seed(42) + # it should not matter whether two images are the same size or not output = model.generate(**inputs, max_new_tokens=30) EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks", - "\nWhat kind of dog is this?\nGot it, let's look at the image. Wait, the animals here are cats, not dogs. The question is about a dog, but", + "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture doesn't look like a dog. Wait, it's a cat,", + "\nWhat kind of dog is this?\nGot it, let's look at the image. Wait, the animals here are cats, not dogs. The question is about a dog, but" ] # fmt: skip self.assertEqual( self.processor.batch_decode(output, skip_special_tokens=True), @@ -536,12 +559,15 @@ def test_small_model_integration_test_batch_wo_image_flashatt2(self): padding=True, ).to(torch_device) + # This model on the hub has `do_sample=True`. + torch.manual_seed(42) + # it should not matter whether two images are the same size or not output = model.generate(**inputs, max_new_tokens=30) EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks", - '\nWho are you?\nGot it, let\'s look at the question. The user is asking "Who are you?" which is a common question when someone meets an AI' + "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture doesn't look like a dog; it's actually a cat. Specifically", + "\nWho are you?\nGot it, let's look at the user's question: \"Who are you?\" This is a common question when someone is just starting a conversation" ] # fmt: skip self.assertEqual( From a418ac81954bc8ef2030d7f93fb827b88809fc45 Mon Sep 17 00:00:00 2001 From: Shane A Date: Tue, 16 Sep 2025 04:28:23 -0700 Subject: [PATCH 066/204] Add Olmo3 model (#40778) * transformers add-new-model-like for Olmo3 * Implement modular Olmo3 * Update Olmo3 tests * Copy Olmo2 weight converter to Olmo3 * Implement Olmo3 weight converter * Fix code quality errors * Remove unused import * Address rope-related PR comments * Update Olmo3 model doc with minimal details * Fix Olmo3 rope test failure * Fix 7B integration test --- docs/source/en/_toctree.yml | 2 + docs/source/en/model_doc/olmo3.md | 147 +++++ src/transformers/models/__init__.py | 1 + .../models/auto/configuration_auto.py | 2 + src/transformers/models/auto/modeling_auto.py | 2 + .../models/auto/tokenization_auto.py | 1 + src/transformers/models/olmo3/__init__.py | 29 + .../models/olmo3/configuration_olmo3.py | 225 ++++++++ .../olmo3/convert_olmo3_weights_to_hf.py | 459 ++++++++++++++++ .../models/olmo3/modeling_olmo3.py | 509 ++++++++++++++++++ .../models/olmo3/modular_olmo3.py | 427 +++++++++++++++ tests/models/olmo3/__init__.py | 0 tests/models/olmo3/test_modeling_olmo3.py | 299 ++++++++++ 13 files changed, 2103 insertions(+) create mode 100644 docs/source/en/model_doc/olmo3.md create mode 100644 src/transformers/models/olmo3/__init__.py create mode 100644 src/transformers/models/olmo3/configuration_olmo3.py create mode 100644 src/transformers/models/olmo3/convert_olmo3_weights_to_hf.py create mode 100644 src/transformers/models/olmo3/modeling_olmo3.py create mode 100644 src/transformers/models/olmo3/modular_olmo3.py create mode 100644 tests/models/olmo3/__init__.py create mode 100644 tests/models/olmo3/test_modeling_olmo3.py diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index aa5b35aeb198..b496fcb4e4b9 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -625,6 +625,8 @@ title: OLMo - local: model_doc/olmo2 title: OLMo2 + - local: model_doc/olmo3 + title: Olmo3 - local: model_doc/olmoe title: OLMoE - local: model_doc/open-llama diff --git a/docs/source/en/model_doc/olmo3.md b/docs/source/en/model_doc/olmo3.md new file mode 100644 index 000000000000..e320181925ca --- /dev/null +++ b/docs/source/en/model_doc/olmo3.md @@ -0,0 +1,147 @@ + +*This model was released on {release_date} and added to Hugging Face Transformers on 2025-09-08.* +
+
+ PyTorch + FlashAttention + SDPA +
+
+ +# OLMo3 +Olmo3 is an improvement on [OLMo2](./olmo2). More details will be released on *soon*. + +> [!TIP] +> Click on the OLMo3 models in the right sidebar for more examples of how to apply OLMo3 to different language tasks. + +The example below demonstrates how to generate text with [`Pipeline`], [`AutoModel`] and from the command line. + + + + +```py +import torch +from transformers import pipeline + +pipe = pipeline( + task="text-generation", + model="allenai/TBA", + dtype=torch.bfloat16, + device=0, +) + +result = pipe("Plants create energy through a process known as") +print(result) +``` + + + + +```py +import torch +from transformers import AutoModelForCausalLM, AutoTokenizer + +tokenizer = AutoTokenizer.from_pretrained( + "allenai/TBA" +) + +model = AutoModelForCausalLM.from_pretrained( + "allenai/TBA", + dtype=torch.bfloat16, + device_map="auto", + attn_implementation="sdpa" +) +input_ids = tokenizer("Plants create energy through a process known as", return_tensors="pt").to(model.device) + +output = model.generate(**input_ids, max_length=50, cache_implementation="static") +print(tokenizer.decode(output[0], skip_special_tokens=True)) +``` + + + + +```bash +echo -e "Plants create energy through a process known as" | transformers-cli run --task text-generation --model allenai/TBA --device 0 +``` + + + + +Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for more available quantization backends. + +The example below uses [torchao](../quantization/torchao) to only quantize the weights to 4-bits. +```py + +#pip install torchao +import torch +from transformers import AutoModelForCausalLM, AutoTokenizer, TorchAoConfig + +torchao_config = TorchAoConfig( + "int4_weight_only", + group_size=128 +) + +tokenizer = AutoTokenizer.from_pretrained( + "allenai/TBA" +) + +model = AutoModelForCausalLM.from_pretrained( + "allenai/TBA", + quantization_config=torchao_config, + dtype=torch.bfloat16, + device_map="auto", + attn_implementation="sdpa" +) +input_ids = tokenizer("Plants create energy through a process known as", return_tensors="pt").to(model.device) + +output = model.generate(**input_ids, max_length=50, cache_implementation="static") +print(tokenizer.decode(output[0], skip_special_tokens=True)) + +``` + + +## Notes + +- Load specific intermediate checkpoints by adding the `revision` parameter to [`~PreTrainedModel.from_pretrained`]. + + ```py + from transformers import AutoModelForCausalLM + + model = AutoModelForCausalLM.from_pretrained("allenai/TBA", revision="stage1-step140000-tokens294B") + ``` + + +## Olmo3Config + +[[autodoc]] Olmo3Config + +## Olmo3ForCausalLM + +[[autodoc]] Olmo3ForCausalLM + +## Olmo3Model + +[[autodoc]] Olmo3Model + - forward + +## Olmo3PreTrainedModel + +[[autodoc]] Olmo3PreTrainedModel + - forward \ No newline at end of file diff --git a/src/transformers/models/__init__.py b/src/transformers/models/__init__.py index c18cbd44f7ea..13e616ca51ca 100644 --- a/src/transformers/models/__init__.py +++ b/src/transformers/models/__init__.py @@ -239,6 +239,7 @@ from .nystromformer import * from .olmo import * from .olmo2 import * + from .olmo3 import * from .olmoe import * from .omdet_turbo import * from .oneformer import * diff --git a/src/transformers/models/auto/configuration_auto.py b/src/transformers/models/auto/configuration_auto.py index a977c727c9e8..7a69ab18215d 100644 --- a/src/transformers/models/auto/configuration_auto.py +++ b/src/transformers/models/auto/configuration_auto.py @@ -281,6 +281,7 @@ ("nystromformer", "NystromformerConfig"), ("olmo", "OlmoConfig"), ("olmo2", "Olmo2Config"), + ("olmo3", "Olmo3Config"), ("olmoe", "OlmoeConfig"), ("omdet-turbo", "OmDetTurboConfig"), ("oneformer", "OneFormerConfig"), @@ -723,6 +724,7 @@ ("nystromformer", "Nyströmformer"), ("olmo", "OLMo"), ("olmo2", "OLMo2"), + ("olmo3", "Olmo3"), ("olmoe", "OLMoE"), ("omdet-turbo", "OmDet-Turbo"), ("oneformer", "OneFormer"), diff --git a/src/transformers/models/auto/modeling_auto.py b/src/transformers/models/auto/modeling_auto.py index 1e0388de23cb..e871a4848c01 100644 --- a/src/transformers/models/auto/modeling_auto.py +++ b/src/transformers/models/auto/modeling_auto.py @@ -280,6 +280,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("nystromformer", "NystromformerModel"), ("olmo", "OlmoModel"), ("olmo2", "Olmo2Model"), + ("olmo3", "Olmo3Model"), ("olmoe", "OlmoeModel"), ("omdet-turbo", "OmDetTurboForObjectDetection"), ("oneformer", "OneFormerModel"), @@ -704,6 +705,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("nemotron", "NemotronForCausalLM"), ("olmo", "OlmoForCausalLM"), ("olmo2", "Olmo2ForCausalLM"), + ("olmo3", "Olmo3ForCausalLM"), ("olmoe", "OlmoeForCausalLM"), ("open-llama", "OpenLlamaForCausalLM"), ("openai-gpt", "OpenAIGPTLMHeadModel"), diff --git a/src/transformers/models/auto/tokenization_auto.py b/src/transformers/models/auto/tokenization_auto.py index 0ef450f45cb9..eae569f1dae4 100644 --- a/src/transformers/models/auto/tokenization_auto.py +++ b/src/transformers/models/auto/tokenization_auto.py @@ -485,6 +485,7 @@ ), ("olmo", (None, "GPTNeoXTokenizerFast" if is_tokenizers_available() else None)), ("olmo2", (None, "GPTNeoXTokenizerFast" if is_tokenizers_available() else None)), + ("olmo3", (None, "GPT2TokenizerFast" if is_tokenizers_available() else None)), ("olmoe", (None, "GPTNeoXTokenizerFast" if is_tokenizers_available() else None)), ( "omdet-turbo", diff --git a/src/transformers/models/olmo3/__init__.py b/src/transformers/models/olmo3/__init__.py new file mode 100644 index 000000000000..e743c2ee3dae --- /dev/null +++ b/src/transformers/models/olmo3/__init__.py @@ -0,0 +1,29 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from typing import TYPE_CHECKING + +from ...utils import _LazyModule +from ...utils.import_utils import define_import_structure + + +if TYPE_CHECKING: + from .configuration_olmo3 import * + from .modeling_olmo3 import * +else: + import sys + + _file = globals()["__file__"] + sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__) diff --git a/src/transformers/models/olmo3/configuration_olmo3.py b/src/transformers/models/olmo3/configuration_olmo3.py new file mode 100644 index 000000000000..a6ea71f3a97a --- /dev/null +++ b/src/transformers/models/olmo3/configuration_olmo3.py @@ -0,0 +1,225 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/olmo3/modular_olmo3.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_olmo3.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from ...configuration_utils import PretrainedConfig, layer_type_validation +from ...modeling_rope_utils import rope_config_validation + + +class Olmo3Config(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Olmo3Model`]. It is used to instantiate an OLMo3 + 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 [allenai/OLMo-3-0725-1B](https://huggingface.co/allenai/OLMo-3-0725-1B). + + 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 50304): + Vocabulary size of the Olmo3 model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`Olmo3Model`] + hidden_size (`int`, *optional*, defaults to 4096): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 11008): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 32): + Number of hidden layers in the Transformer decoder. + num_attention_heads (`int`, *optional*, defaults to 32): + Number of attention heads for each attention layer in the Transformer decoder. + num_key_value_heads (`int`, *optional*): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to + `num_attention_heads`. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 2048): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + pad_token_id (`int`, *optional*, defaults to 1): + Padding token id. + bos_token_id (`int`, *optional*): + Beginning of stream token id. + eos_token_id (`int`, *optional*, defaults to 50279): + End of stream token id. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether to tie weight embeddings + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period of the RoPE embeddings. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type + and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value + accordingly. + Expected contents: + `rope_type` (`str`): + The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope', + 'llama3'], with 'default' being the original RoPE implementation. + `factor` (`float`, *optional*): + Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In + most scaling types, a `factor` of x will enable the model to handle sequences of length x * + original maximum pre-trained length. + `original_max_position_embeddings` (`int`, *optional*): + Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during + pretraining. + `attention_factor` (`float`, *optional*): + Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention + computation. If unspecified, it defaults to value recommended by the implementation, using the + `factor` field to infer the suggested value. + `beta_fast` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear + ramp function. If unspecified, it defaults to 32. + `beta_slow` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear + ramp function. If unspecified, it defaults to 1. + `short_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to short contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `long_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to long contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `low_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE + `high_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + rms_norm_eps (`float`, *optional*, defaults to 1e-05): + The epsilon used by the rms normalization layers. + sliding_window (`int`, *optional*, defaults to 4096): + Size of the sliding window for sliding window attention. + layer_types (`list`, *optional*): + Attention pattern for each layer. Defaults to sliding window attention + for 3 out of 4 layers, and full attention for every 4th layer. + + ```python + >>> from transformers import Olmo3Model, Olmo3Config + + >>> # Initializing a Olmo3 7B style configuration + >>> configuration = Olmo3Config() + + >>> # Initializing a model from the Olmo3 7B style configuration + >>> model = Olmo3Model(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ``` + """ + + model_type = "olmo3" + keys_to_ignore_at_inference = ["past_key_values"] + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.k_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.v_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.o_proj": "rowwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=50304, + hidden_size=4096, + intermediate_size=11008, + num_hidden_layers=32, + num_attention_heads=32, + num_key_value_heads=None, + hidden_act="silu", + max_position_embeddings=2048, + initializer_range=0.02, + use_cache=True, + pad_token_id=1, + bos_token_id=None, + eos_token_id=50279, + tie_word_embeddings=False, + rope_theta=10000.0, + rope_scaling=None, + attention_bias=False, + attention_dropout=0.0, + rms_norm_eps=1e-5, + sliding_window=4096, + layer_types=None, + **kwargs, + ): + super().__init__( + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + tie_word_embeddings=tie_word_embeddings, + **kwargs, + ) + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + + # for backward compatibility + if num_key_value_heads is None: + num_key_value_heads = num_attention_heads + + self.num_key_value_heads = num_key_value_heads + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.use_cache = use_cache + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self._rope_scaling_validation() + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + + self.rms_norm_eps = rms_norm_eps + + self.sliding_window = sliding_window + self.layer_types = layer_types + if self.layer_types is None: + self.layer_types = [ + "sliding_attention" if (i + 1) % 4 != 0 else "full_attention" for i in range(self.num_hidden_layers) + ] + layer_type_validation(self.layer_types) + + def _rope_scaling_validation(self): + """ + Validate the `rope_scaling` configuration. + """ + rope_config_validation(self) + + +__all__ = ["Olmo3Config"] diff --git a/src/transformers/models/olmo3/convert_olmo3_weights_to_hf.py b/src/transformers/models/olmo3/convert_olmo3_weights_to_hf.py new file mode 100644 index 000000000000..ce6d85f65358 --- /dev/null +++ b/src/transformers/models/olmo3/convert_olmo3_weights_to_hf.py @@ -0,0 +1,459 @@ +# Copyright 2025 EleutherAI and The HuggingFace Inc. team. All rights reserved. +# +# 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. +from __future__ import annotations + +import argparse +import gc +import io +import json +import os +import pickle +import shutil +import traceback +import uuid +from collections.abc import Sequence +from concurrent.futures import ThreadPoolExecutor, as_completed +from dataclasses import dataclass +from pathlib import Path +from typing import Any, cast + +import torch +import torch.distributed.checkpoint as dist_cp +from torch.distributed.checkpoint.metadata import Metadata, MetadataIndex, StorageMeta +from torch.distributed.checkpoint.planner import ( + LoadItemType, + ReadItem, +) +from torch.futures import Future + +from transformers import AutoTokenizer, Olmo3Config, Olmo3ForCausalLM + + +""" +Sample usage: + +``` +python src/transformers/models/olmo3/convert_olmo3_weights_to_hf.py \ + --input_dir /path/to/downloaded/olmo3/weights --model_size 7B --output_dir /output/path +``` + +Thereafter, models can be loaded via: + +```py +from transformers import Olmo3ForCausalLM, AutoTokenizer + +model = Olmo3ForCausalLM.from_pretrained("/output/path") +tokenizer = AutoTokenizer.from_pretrained("/output/path") +``` + +Important note: you need to be able to host the whole model in RAM to execute this script (even if the biggest versions +come in several checkpoints they each contain a part of each weight of the model, so we need to load them all in RAM). +""" + + +def compute_intermediate_size(n, ffn_dim_multiplier=1, multiple_of=256): + return multiple_of * ((int(ffn_dim_multiplier * int(8 * n / 3)) + multiple_of - 1) // multiple_of) + + +def read_json(path): + with open(path, "r") as f: + return json.load(f) + + +def write_json(text, path): + with open(path, "w") as f: + json.dump(text, f) + + +def normalize_path(path: Path | str) -> str: + return str(path).rstrip("/").replace("file://", "") + + +def generate_uuid() -> str: + return str(uuid.uuid4()) + + +def get_bytes_range(path: Path | str, bytes_start: int, num_bytes: int) -> bytes: + with open(path, "rb") as f: + f.seek(bytes_start) + return f.read(num_bytes) + + +def _narrow_tensor_by_index(tensor: torch.Tensor, offsets: Sequence[int], sizes: Sequence[int]) -> torch.Tensor: + """ + Narrow the tensor according to ``offsets`` and ``sizes``. + """ + narrowed_tensor = tensor + for idx, (offset, size) in enumerate(zip(offsets, sizes)): + if size < tensor.size(idx): + # Reshape to get shard for this rank and we don't want autograd + # recording here for the narrow op and 'local_shard' should be a + # leaf variable in the autograd graph. + narrowed_tensor = narrowed_tensor.narrow(idx, offset, size) + return narrowed_tensor + + +@dataclass +class _StorageInfo: + """This is the per entry storage info.""" + + relative_path: str + offset: int + length: int + + +@dataclass +class _StoragePrefix: + prefix: str + + +class RemoteFileSystemReader(dist_cp.StorageReader): + """ + A :class:`~torch.distributed.checkpoint.StorageReader` based on :class:`~torch.distributed.checkpoint.FileSystemReader` + that can read data directly from cloud storage as well as a local directory. + """ + + def __init__( + self, + path: Path | str, + *, + thread_count: int | None = None, + pre_download: bool = False, + work_dir: Path | str | None = None, + ): + super().__init__() + if thread_count is not None and thread_count <= 0: + raise ValueError("thread count must be at least 1") + self.path = normalize_path(path) + self.thread_count = thread_count or 1 + self.pre_download = pre_download + self.work_dir = normalize_path(work_dir) if work_dir is not None else None + self.storage_data: dict[MetadataIndex, _StorageInfo] = {} + self.load_id = generate_uuid() + self._metadata: Metadata | None = None + + def _get_bytes(self, relative_path: str, offset: int, length: int) -> bytes: + full_path = f"{self.path}/{relative_path}" + return get_bytes_range(full_path, offset, length) + + def _get_content_for_read(self, read_item: ReadItem) -> tuple[ReadItem, bytes]: + sinfo = self.storage_data[read_item.storage_index] + content = self._get_bytes(sinfo.relative_path, sinfo.offset, sinfo.length) + return (read_item, content) + + def reset(self, checkpoint_id: Path | str | None = None) -> None: + self.storage_data = {} + if checkpoint_id: + self.path = normalize_path(checkpoint_id) + self.load_id = generate_uuid() + + def read_data(self, plan: dist_cp.LoadPlan, planner: dist_cp.LoadPlanner) -> Future[None]: + with ThreadPoolExecutor(max_workers=self.thread_count) as executor: + read_item_content_futures = [] + for read_item in plan.items: + read_item_content_futures.append(executor.submit(self._get_content_for_read, read_item)) + read_item_content_results = [] + for f in as_completed(read_item_content_futures): + try: + read_item_content_results.append(f.result()) + except BaseException: + # NOTE: we might get an error here that can't be pickled, which causes a different failure + # later when PyTorch tries to reduce that error across ranks. So here we just make + # sure we're raising a simple error type that can be pickled. + raise RuntimeError(f"Original error:\n{traceback.format_exc()}") + + # Modified from `FileSystemReader.read_data()` + for read_item, content in read_item_content_results: + bytes = io.BytesIO(content) + bytes.seek(0) + if read_item.type == LoadItemType.BYTE_IO: + planner.load_bytes(read_item, bytes) + else: + # NOTE: 'weights_only=False' needed to load torchao's float8 linear layer checkpoints + tensor = cast(torch.Tensor, torch.load(bytes, map_location="cpu", weights_only=False)) + tensor = _narrow_tensor_by_index(tensor, read_item.storage_offsets, read_item.lengths) + target_tensor = planner.resolve_tensor(read_item).detach() + + assert target_tensor.size() == tensor.size(), ( + f"req {read_item.storage_index} mismatch sizes {target_tensor.size()} vs {tensor.size()}" + ) + target_tensor.copy_(tensor) + planner.commit_tensor(read_item, target_tensor) + + fut: Future = Future() + fut.set_result(None) + return fut + + def read_metadata(self) -> Metadata: + if self._metadata is None: + try: + with (Path(self.path) / ".metadata").open("rb") as metadata_file: + metadata = pickle.load(metadata_file) + except FileNotFoundError as exc: + msg = f"'{self.path}' is not a distributed checkpoint folder." + suggested_dir = os.path.join(self.path, "model_and_optim") + if Path(os.path.join(suggested_dir, ".metadata")).exists(): + msg += f" Did you mean to use '{suggested_dir}'?" + raise FileNotFoundError(msg) from exc + + if getattr(metadata, "storage_meta", None) is None: + metadata.storage_meta = StorageMeta() + metadata.storage_meta.load_id = self.load_id + + self._metadata = metadata + + return self._metadata + + def set_up_storage_reader(self, metadata: Metadata, is_coordinator: bool) -> None: + del is_coordinator + self.storage_data = metadata.storage_data + assert self.storage_data is not None + + def prepare_local_plan(self, plan: dist_cp.LoadPlan) -> dist_cp.LoadPlan: + return plan + + def prepare_global_plan(self, global_plan: list[dist_cp.LoadPlan]) -> list[dist_cp.LoadPlan]: + return global_plan + + @property + def checkpoint_id(self) -> str: + return self.path + + @classmethod + def validate_checkpoint_id(cls, checkpoint_id: Path | str) -> bool: + del checkpoint_id + return True + + +def load_model(model_path: str): + def _load_unsharded_keys( + dir: Path | str, + keys: list[str], + *, + pre_download: bool = False, + work_dir: Path | str | None = None, + ) -> dict[str, Any]: + from torch.distributed.checkpoint.default_planner import _EmptyStateDictLoadPlanner + from torch.distributed.checkpoint.state_dict_loader import _load_state_dict + + state_dict: dict[str, Any] = {} + _load_state_dict( + state_dict, + storage_reader=RemoteFileSystemReader(dir, pre_download=pre_download, work_dir=work_dir), + planner=_EmptyStateDictLoadPlanner(keys=keys), + no_dist=True, + ) + return state_dict + + with (Path(model_path) / ".metadata").open("rb") as metadata_file: + metadata = pickle.load(metadata_file) + keys = [key for key in metadata.state_dict_metadata.keys() if key.startswith("model.")] + + # keys = ["model.blocks.0.attention.w_q.weight"] + + return _load_unsharded_keys( + model_path, + keys, + # model_path, ["model.blocks.0.attention.w_q.weight", "model.blocks.0.attention.w_k.weight"] + ) + + +def write_model( + model_path, + input_base_path, + include_tokenizer=True, + tokenizer_id=None, + safe_serialization=True, + tmp_cleanup=True, +): + os.makedirs(model_path, exist_ok=True) + tmp_model_path = os.path.join(model_path, "tmp") + os.makedirs(tmp_model_path, exist_ok=True) + + config_path = Path(input_base_path) / "config.json" + olmo3_config = json.loads(config_path.read_text()) + model_config = olmo3_config["model"] + block_config = model_config["block"] + attention_config = block_config["attention"] + tokenizer_config = olmo3_config["dataset"]["tokenizer"] + + n_layers = model_config["n_layers"] + n_heads = attention_config["n_heads"] + dim = model_config["d_model"] + dims_per_head = dim // n_heads + base = attention_config["rope"]["theta"] + inv_freq = 1.0 / (base ** (torch.arange(0, dims_per_head, 2).float() / dims_per_head)) + max_position_embeddings = olmo3_config["train_module"]["max_sequence_length"] + + if attention_config.get("n_kv_heads", None) is not None: + num_key_value_heads = model_config["n_kv_heads"] # for GQA / MQA + else: + num_key_value_heads = n_heads + + print(f"Fetching all parameters from the checkpoint at {input_base_path}.") + + # Not sharded + # (The sharded implementation would also work, but this is simpler.) + loaded = load_model(os.path.join(input_base_path, "model_and_optim"))["model"] + print(loaded.keys()) + # loaded = torch.load(os.path.join(input_base_path, "model.pt"), map_location="cpu", weights_only=True) + + param_count = 0 + index_dict: dict[str, Any] = {"weight_map": {}} + for layer_i in range(n_layers): + filename = f"pytorch_model-{layer_i + 1}-of-{n_layers + 1}.bin" + # Unsharded + state_dict = { + f"model.layers.{layer_i}.self_attn.q_proj.weight": loaded[f"blocks.{layer_i}.attention.w_q.weight"], + f"model.layers.{layer_i}.self_attn.k_proj.weight": loaded[f"blocks.{layer_i}.attention.w_k.weight"], + f"model.layers.{layer_i}.self_attn.v_proj.weight": loaded[f"blocks.{layer_i}.attention.w_v.weight"], + f"model.layers.{layer_i}.self_attn.o_proj.weight": loaded[f"blocks.{layer_i}.attention.w_out.weight"], + f"model.layers.{layer_i}.self_attn.q_norm.weight": loaded[f"blocks.{layer_i}.attention.q_norm.weight"], + f"model.layers.{layer_i}.self_attn.k_norm.weight": loaded[f"blocks.{layer_i}.attention.k_norm.weight"], + f"model.layers.{layer_i}.mlp.gate_proj.weight": loaded[f"blocks.{layer_i}.feed_forward.w1.weight"], + f"model.layers.{layer_i}.mlp.down_proj.weight": loaded[f"blocks.{layer_i}.feed_forward.w2.weight"], + f"model.layers.{layer_i}.mlp.up_proj.weight": loaded[f"blocks.{layer_i}.feed_forward.w3.weight"], + f"model.layers.{layer_i}.post_attention_layernorm.weight": loaded[ + f"blocks.{layer_i}.attention_norm.weight" + ], + f"model.layers.{layer_i}.post_feedforward_layernorm.weight": loaded[ + f"blocks.{layer_i}.feed_forward_norm.weight" + ], + } + + state_dict[f"model.layers.{layer_i}.self_attn.rotary_emb.inv_freq"] = inv_freq + + for k, v in state_dict.items(): + index_dict["weight_map"][k] = filename + param_count += v.numel() + torch.save(state_dict, os.path.join(tmp_model_path, filename)) + + filename = f"pytorch_model-{n_layers + 1}-of-{n_layers + 1}.bin" + + # Unsharded + # TODO: Deal with weight-tying + state_dict = { + "model.embed_tokens.weight": loaded["embeddings.weight"], + "model.norm.weight": loaded["lm_head.norm.weight"], + "lm_head.weight": loaded["lm_head.w_out.weight"], + } + + for k, v in state_dict.items(): + index_dict["weight_map"][k] = filename + param_count += v.numel() + torch.save(state_dict, os.path.join(tmp_model_path, filename)) + + # Write configs + index_dict["metadata"] = {"total_size": param_count * 2} + write_json(index_dict, os.path.join(tmp_model_path, "pytorch_model.bin.index.json")) + + config = Olmo3Config( + vocab_size=model_config["vocab_size"], + hidden_size=dim, + intermediate_size=block_config["feed_forward"]["hidden_size"], + num_hidden_layers=n_layers, + num_attention_heads=n_heads, + num_key_value_heads=num_key_value_heads, + max_position_embeddings=max_position_embeddings, + pad_token_id=tokenizer_config["pad_token_id"], + bos_token_id=None, + eos_token_id=tokenizer_config["eos_token_id"], + tie_word_embeddings=False, + rms_norm_eps=block_config["layer_norm"]["eps"], + rope_theta=base, + ) + config.save_pretrained(tmp_model_path) + + # Make space so we can load the model properly now. + del state_dict + del loaded + gc.collect() + + if include_tokenizer: + tokenizer_id = tokenizer_id or tokenizer_config["identifier"] + _write_tokenizer(model_path, tokenizer_id) + + print("Loading the checkpoint in a Olmo 3 model.") + model = Olmo3ForCausalLM.from_pretrained(tmp_model_path, dtype=torch.bfloat16) + print("Resizing token embeddings to match tokenizer config.") + model.resize_token_embeddings(tokenizer_config["vocab_size"]) + # Avoid saving this as part of the config. + del model.config._name_or_path + print("Saving in the Transformers format.") + model.save_pretrained(model_path, safe_serialization=safe_serialization) + if tmp_cleanup: + # Make cleanup optional; attempting to `rmtree` the `tmp_model_path` causes + # errors if using NFS. + shutil.rmtree(tmp_model_path) + + +def _write_tokenizer( + output_path: Path, + tokenizer_id: str, +) -> None: + print(f"Saving a tokenizer to {output_path}.") + + tokenizer = AutoTokenizer.from_pretrained(tokenizer_id) + tokenizer.save_pretrained(output_path) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + "--input_dir", + required=True, + help="Location of Olmo 3 weights, which contains config.yaml and model.pt.", + ) + parser.add_argument( + "--no_tokenizer", + action="store_false", + dest="include_tokenizer", + help="If set, do not convert OLMo tokenizer to HF tokenizer.", + ) + parser.add_argument( + "--tokenizer", + type=Path, + default=None, + help="Location of Olmo 3 tokenizer json file. Defaults to what is set in the config file.", + ) + parser.add_argument( + "--output_dir", + required=True, + help="Location to write HF model and tokenizer", + ) + parser.add_argument( + "--no_tmp_cleanup", + action="store_false", + dest="tmp_cleanup", + help="If passed, don't remove temp dir at end of HF conversion.", + ) + parser.add_argument( + "--no_safe_serialization", + action="store_false", + dest="safe_serialization", + help="Whether or not to save using `safetensors`.", + ) + args = parser.parse_args() + write_model( + model_path=args.output_dir, + input_base_path=args.input_dir, + safe_serialization=args.safe_serialization, + include_tokenizer=args.include_tokenizer, + tokenizer_id=args.tokenizer, + tmp_cleanup=args.tmp_cleanup, + ) + + +if __name__ == "__main__": + main() diff --git a/src/transformers/models/olmo3/modeling_olmo3.py b/src/transformers/models/olmo3/modeling_olmo3.py new file mode 100644 index 000000000000..3a7e2b5ff953 --- /dev/null +++ b/src/transformers/models/olmo3/modeling_olmo3.py @@ -0,0 +1,509 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/olmo3/modular_olmo3.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_olmo3.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from typing import Callable, Optional, Union + +import torch +import torch.nn as nn + +from transformers.utils.generic import TransformersKwargs + +from ...activations import ACT2FN +from ...cache_utils import Cache, DynamicCache +from ...generation import GenerationMixin +from ...integrations import use_kernel_forward_from_hub +from ...masking_utils import create_causal_mask, create_sliding_window_causal_mask +from ...modeling_layers import GradientCheckpointingLayer +from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack +from ...utils import auto_docstring, can_return_tuple +from ...utils.deprecation import deprecate_kwarg +from ...utils.generic import check_model_inputs +from .configuration_olmo3 import Olmo3Config + + +@use_kernel_forward_from_hub("RMSNorm") +class Olmo3RMSNorm(nn.Module): + def __init__(self, hidden_size, eps=1e-6): + """ + Olmo3RMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states): + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return (self.weight * hidden_states).to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor: + """ + This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, + num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim) + """ + batch, num_key_value_heads, slen, head_dim = hidden_states.shape + if n_rep == 1: + return hidden_states + hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim) + return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim) + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: float, + dropout: float = 0.0, + **kwargs: Unpack[TransformersKwargs], +): + key_states = repeat_kv(key, module.num_key_value_groups) + value_states = repeat_kv(value, module.num_key_value_groups) + + attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling + if attention_mask is not None: + causal_mask = attention_mask[:, :, :, : key_states.shape[-2]] + attn_weights = attn_weights + causal_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + attn_output = torch.matmul(attn_weights, value_states) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + +def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1): + """Applies Rotary Position Embedding to the query and key tensors. + + Args: + q (`torch.Tensor`): The query tensor. + k (`torch.Tensor`): The key tensor. + cos (`torch.Tensor`): The cosine part of the rotary embedding. + sin (`torch.Tensor`): The sine part of the rotary embedding. + position_ids (`torch.Tensor`, *optional*): + Deprecated and unused. + unsqueeze_dim (`int`, *optional*, defaults to 1): + The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and + sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note + that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and + k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes + cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have + the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. + Returns: + `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. + """ + q_type, k_type = q.dtype, k.dtype + cos = cos.unsqueeze(unsqueeze_dim) + sin = sin.unsqueeze(unsqueeze_dim) + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + return q_embed.to(q_type), k_embed.to(k_type) + + +def rotate_half(x): + """Rotates half the hidden dims of the input.""" + x1 = x[..., : x.shape[-1] // 2] + x2 = x[..., x.shape[-1] // 2 :] + return torch.cat((-x2, x1), dim=-1) + + +class Olmo3Attention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: Olmo3Config, layer_idx: int): + super().__init__() + self.config = config + self.layer_idx = layer_idx + self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) + self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads + self.scaling = self.head_dim**-0.5 + self.attention_dropout = config.attention_dropout + self.is_causal = True + + self.q_proj = nn.Linear( + config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias + ) + self.k_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.v_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.o_proj = nn.Linear( + config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias + ) + self.q_norm = Olmo3RMSNorm(config.num_attention_heads * self.head_dim, config.rms_norm_eps) + self.k_norm = Olmo3RMSNorm(config.num_key_value_heads * self.head_dim, config.rms_norm_eps) + assert config.layer_types is not None + self.attention_type = config.layer_types[layer_idx] + self.sliding_window = config.sliding_window if self.attention_type == "sliding_attention" else None + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor]]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_norm(self.q_proj(hidden_states)) + key_states = self.k_norm(self.k_proj(hidden_states)) + value_states = self.v_proj(hidden_states) + + query_states = query_states.view(hidden_shape).transpose(1, 2) + key_states = key_states.view(hidden_shape).transpose(1, 2) + value_states = value_states.view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + sliding_window=self.sliding_window, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class Olmo3MLP(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +class Olmo3DecoderLayer(GradientCheckpointingLayer): + def __init__(self, config: Olmo3Config, layer_idx: int): + super().__init__() + self.hidden_size = config.hidden_size + self.self_attn = Olmo3Attention(config=config, layer_idx=layer_idx) + + self.mlp = Olmo3MLP(config) + self.post_attention_layernorm = Olmo3RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_feedforward_layernorm = Olmo3RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, # necessary, but kept here for BC + **kwargs: Unpack[TransformersKwargs], + ) -> torch.Tensor: + residual = hidden_states + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states = self.mlp(hidden_states) + hidden_states = self.post_feedforward_layernorm(hidden_states) + hidden_states = residual + hidden_states + return hidden_states + + +class Olmo3RotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: Olmo3Config, device=None, rope_type: Optional[str] = None): + super().__init__() + if rope_type is not None: + self.rope_type = rope_type + elif hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): + # BC: "rope_type" was originally "type" + self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type")) + else: + self.rope_type = "default" + assert self.rope_type is not None + + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device) + position_ids_expanded = position_ids[:, None, :].float() + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + return cos, sin + + +@auto_docstring +class Olmo3PreTrainedModel(PreTrainedModel): + config: Olmo3Config + base_model_prefix = "model" + supports_gradient_checkpointing = True + _no_split_modules = ["Olmo3DecoderLayer"] + _skip_keys_device_placement = ["past_key_values"] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + + _can_compile_fullgraph = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": Olmo3DecoderLayer, + "attentions": Olmo3Attention, + } + + +@auto_docstring +class Olmo3Model(Olmo3PreTrainedModel): + def __init__(self, config: Olmo3Config): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + + self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx) + self.layers = nn.ModuleList( + [Olmo3DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = Olmo3RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.gradient_checkpointing = False + self.rotary_embs = nn.ModuleDict( + { + "sliding_attention": Olmo3RotaryEmbedding(config=config, rope_type="default"), + "full_attention": Olmo3RotaryEmbedding(config=config), + } + ) + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> BaseModelOutputWithPast: + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds: torch.Tensor = self.embed_tokens(input_ids) + + if use_cache and past_key_values is None: + past_key_values = DynamicCache(config=self.config) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position: torch.Tensor = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + # It may already have been prepared by e.g. `generate` + if not isinstance(causal_mask_mapping := attention_mask, dict): + # Prepare mask arguments + mask_kwargs = { + "config": self.config, + "input_embeds": inputs_embeds, + "attention_mask": attention_mask, + "cache_position": cache_position, + "past_key_values": past_key_values, + "position_ids": position_ids, + } + # Create the masks + causal_mask_mapping = { + "full_attention": create_causal_mask(**mask_kwargs), + "sliding_attention": create_sliding_window_causal_mask(**mask_kwargs), + } + + hidden_states = inputs_embeds + position_embeddings_mapping = { + "sliding_attention": self.rotary_embs["sliding_attention"](hidden_states, position_ids), + "full_attention": self.rotary_embs["full_attention"](hidden_states, position_ids), + } + + for decoder_layer in self.layers[: self.config.num_hidden_layers]: + hidden_states = decoder_layer( + hidden_states, + attention_mask=causal_mask_mapping[decoder_layer.self_attn.attention_type], + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings_mapping[decoder_layer.self_attn.attention_type], + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) + + +@auto_docstring +class Olmo3ForCausalLM(Olmo3PreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.weight"] + _tp_plan = {"lm_head": "colwise_rep"} + _pp_plan = {"lm_head": (["hidden_states"], ["logits"])} + + def __init__(self, config): + super().__init__(config) + self.model = Olmo3Model(config) + self.vocab_size = config.vocab_size + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs: Unpack[TransformersKwargs], + ) -> CausalLMOutputWithPast: + r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, Olmo3ForCausalLM + + >>> model = Olmo3ForCausalLM.from_pretrained("meta-olmo3/Olmo3-2-7b-hf") + >>> tokenizer = AutoTokenizer.from_pretrained("meta-olmo3/Olmo3-2-7b-hf") + + >>> prompt = "Hey, are you conscious? Can you talk to me?" + >>> inputs = tokenizer(prompt, return_tensors="pt") + + >>> # Generate + >>> generate_ids = model.generate(inputs.input_ids, max_length=30) + >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] + "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you." + ```""" + outputs: BaseModelOutputWithPast = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs.last_hidden_state + # Only compute necessary logits, and do not upcast them to float if we are not computing the loss + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]) + + loss = None + if labels is not None: + loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs) + + return CausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +__all__ = ["Olmo3ForCausalLM", "Olmo3Model", "Olmo3PreTrainedModel"] diff --git a/src/transformers/models/olmo3/modular_olmo3.py b/src/transformers/models/olmo3/modular_olmo3.py new file mode 100644 index 000000000000..8799c8dc07d7 --- /dev/null +++ b/src/transformers/models/olmo3/modular_olmo3.py @@ -0,0 +1,427 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from typing import Callable, Optional + +import torch +import torch.nn as nn + +from transformers.utils.generic import TransformersKwargs + +from ...cache_utils import Cache, DynamicCache +from ...configuration_utils import layer_type_validation +from ...masking_utils import create_causal_mask, create_sliding_window_causal_mask +from ...modeling_outputs import BaseModelOutputWithPast +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, rope_config_validation +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS +from ...processing_utils import Unpack +from ..olmo2.configuration_olmo2 import Olmo2Config +from ..olmo2.modeling_olmo2 import ( + Olmo2Attention, + Olmo2DecoderLayer, + Olmo2ForCausalLM, + Olmo2Model, + Olmo2PreTrainedModel, + Olmo2RMSNorm, + Olmo2RotaryEmbedding, + apply_rotary_pos_emb, + eager_attention_forward, +) + + +class Olmo3Config(Olmo2Config): + r""" + This is the configuration class to store the configuration of a [`Olmo3Model`]. It is used to instantiate an OLMo3 + 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 [allenai/OLMo-3-0725-1B](https://huggingface.co/allenai/OLMo-3-0725-1B). + + 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 50304): + Vocabulary size of the Olmo3 model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`Olmo3Model`] + hidden_size (`int`, *optional*, defaults to 4096): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 11008): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 32): + Number of hidden layers in the Transformer decoder. + num_attention_heads (`int`, *optional*, defaults to 32): + Number of attention heads for each attention layer in the Transformer decoder. + num_key_value_heads (`int`, *optional*): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to + `num_attention_heads`. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 2048): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + pad_token_id (`int`, *optional*, defaults to 1): + Padding token id. + bos_token_id (`int`, *optional*): + Beginning of stream token id. + eos_token_id (`int`, *optional*, defaults to 50279): + End of stream token id. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether to tie weight embeddings + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period of the RoPE embeddings. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type + and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value + accordingly. + Expected contents: + `rope_type` (`str`): + The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope', + 'llama3'], with 'default' being the original RoPE implementation. + `factor` (`float`, *optional*): + Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In + most scaling types, a `factor` of x will enable the model to handle sequences of length x * + original maximum pre-trained length. + `original_max_position_embeddings` (`int`, *optional*): + Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during + pretraining. + `attention_factor` (`float`, *optional*): + Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention + computation. If unspecified, it defaults to value recommended by the implementation, using the + `factor` field to infer the suggested value. + `beta_fast` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear + ramp function. If unspecified, it defaults to 32. + `beta_slow` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear + ramp function. If unspecified, it defaults to 1. + `short_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to short contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `long_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to long contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `low_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE + `high_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + rms_norm_eps (`float`, *optional*, defaults to 1e-05): + The epsilon used by the rms normalization layers. + sliding_window (`int`, *optional*, defaults to 4096): + Size of the sliding window for sliding window attention. + layer_types (`list`, *optional*): + Attention pattern for each layer. Defaults to sliding window attention + for 3 out of 4 layers, and full attention for every 4th layer. + + ```python + >>> from transformers import Olmo3Model, Olmo3Config + + >>> # Initializing a Olmo3 7B style configuration + >>> configuration = Olmo3Config() + + >>> # Initializing a model from the Olmo3 7B style configuration + >>> model = Olmo3Model(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ``` + """ + + model_type = "olmo3" + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.k_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.v_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.o_proj": "rowwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=50304, + hidden_size=4096, + intermediate_size=11008, + num_hidden_layers=32, + num_attention_heads=32, + num_key_value_heads=None, + hidden_act="silu", + max_position_embeddings=2048, + initializer_range=0.02, + use_cache=True, + pad_token_id=1, + bos_token_id=None, + eos_token_id=50279, + tie_word_embeddings=False, + rope_theta=10000.0, + rope_scaling=None, + attention_bias=False, + attention_dropout=0.0, + rms_norm_eps=1e-5, + sliding_window=4096, + layer_types=None, + **kwargs, + ): + super().__init__( + vocab_size=vocab_size, + hidden_size=hidden_size, + intermediate_size=intermediate_size, + num_hidden_layers=num_hidden_layers, + num_attention_heads=num_attention_heads, + num_key_value_heads=num_key_value_heads, + hidden_act=hidden_act, + max_position_embeddings=max_position_embeddings, + initializer_range=initializer_range, + use_cache=use_cache, + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + tie_word_embeddings=tie_word_embeddings, + rope_theta=rope_theta, + rope_scaling=rope_scaling, + attention_bias=attention_bias, + attention_dropout=attention_dropout, + rms_norm_eps=rms_norm_eps, + **kwargs, + ) + + self.sliding_window = sliding_window + self.layer_types = layer_types + if self.layer_types is None: + self.layer_types = [ + "sliding_attention" if (i + 1) % 4 != 0 else "full_attention" for i in range(self.num_hidden_layers) + ] + layer_type_validation(self.layer_types) + + def _rope_scaling_validation(self): + """ + Validate the `rope_scaling` configuration. + """ + rope_config_validation(self) + + +class Olmo3RMSNorm(Olmo2RMSNorm): + pass + + +# Olmo3 attention is identical to OLMo 2 attention except: +# - Sliding window attention is used for 3 out of 4 layers. +class Olmo3Attention(Olmo2Attention): + def __init__(self, config: Olmo3Config, layer_idx: int): + super().__init__(config, layer_idx=layer_idx) + assert config.layer_types is not None + self.attention_type = config.layer_types[layer_idx] + self.sliding_window = config.sliding_window if self.attention_type == "sliding_attention" else None + + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor]]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_norm(self.q_proj(hidden_states)) + key_states = self.k_norm(self.k_proj(hidden_states)) + value_states = self.v_proj(hidden_states) + + query_states = query_states.view(hidden_shape).transpose(1, 2) + key_states = key_states.view(hidden_shape).transpose(1, 2) + value_states = value_states.view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + sliding_window=self.sliding_window, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class Olmo3DecoderLayer(Olmo2DecoderLayer): + pass + + +# OLMo 3 RoPE is identical to OLMo 2 RoPE, except: +# - RoPE scaling is not applied to sliding window attention layers. +class Olmo3RotaryEmbedding(Olmo2RotaryEmbedding): + def __init__(self, config: Olmo3Config, device=None, rope_type: Optional[str] = None): + nn.Module.__init__(self) + if rope_type is not None: + self.rope_type = rope_type + elif hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): + # BC: "rope_type" was originally "type" + self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type")) + else: + self.rope_type = "default" + assert self.rope_type is not None + + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + +class Olmo3PreTrainedModel(Olmo2PreTrainedModel): + pass + + +# The OLMo 3 model is identical to the OLMo 2 model, except: +# - Sliding window attention is used for 3 out of 4 layers. +# - RoPE scaling is not applied to sliding window attention layers. +class Olmo3Model(Olmo2Model): + def __init__(self, config: Olmo3Config): + super().__init__(config) + self.norm = Olmo3RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.layers = nn.ModuleList( + [Olmo3DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_embs = nn.ModuleDict( + { + "sliding_attention": Olmo3RotaryEmbedding(config=config, rope_type="default"), + "full_attention": Olmo3RotaryEmbedding(config=config), + } + ) + del self.rotary_emb + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> BaseModelOutputWithPast: + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds: torch.Tensor = self.embed_tokens(input_ids) + + if use_cache and past_key_values is None: + past_key_values = DynamicCache(config=self.config) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position: torch.Tensor = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + # It may already have been prepared by e.g. `generate` + if not isinstance(causal_mask_mapping := attention_mask, dict): + # Prepare mask arguments + mask_kwargs = { + "config": self.config, + "input_embeds": inputs_embeds, + "attention_mask": attention_mask, + "cache_position": cache_position, + "past_key_values": past_key_values, + "position_ids": position_ids, + } + # Create the masks + causal_mask_mapping = { + "full_attention": create_causal_mask(**mask_kwargs), + "sliding_attention": create_sliding_window_causal_mask(**mask_kwargs), + } + + hidden_states = inputs_embeds + position_embeddings_mapping = { + "sliding_attention": self.rotary_embs["sliding_attention"](hidden_states, position_ids), + "full_attention": self.rotary_embs["full_attention"](hidden_states, position_ids), + } + + for decoder_layer in self.layers[: self.config.num_hidden_layers]: + hidden_states = decoder_layer( + hidden_states, + attention_mask=causal_mask_mapping[decoder_layer.self_attn.attention_type], + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings_mapping[decoder_layer.self_attn.attention_type], + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) + + +class Olmo3ForCausalLM(Olmo2ForCausalLM): + pass + + +__all__ = [ + "Olmo3Config", + "Olmo3ForCausalLM", + "Olmo3Model", + "Olmo3PreTrainedModel", # noqa: F822 +] diff --git a/tests/models/olmo3/__init__.py b/tests/models/olmo3/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/models/olmo3/test_modeling_olmo3.py b/tests/models/olmo3/test_modeling_olmo3.py new file mode 100644 index 000000000000..973bb7aeec19 --- /dev/null +++ b/tests/models/olmo3/test_modeling_olmo3.py @@ -0,0 +1,299 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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 Olmo3 model.""" + +import unittest + +import pytest +from packaging import version +from parameterized import parameterized + +from transformers import Olmo3Config, is_torch_available, set_seed +from transformers.generation.configuration_utils import GenerationConfig +from transformers.models.auto.tokenization_auto import AutoTokenizer +from transformers.testing_utils import ( + Expectations, + cleanup, + require_torch, + slow, + torch_device, +) + +from ...causal_lm_tester import CausalLMModelTest, CausalLMModelTester +from ...test_modeling_common import ids_tensor + + +if is_torch_available(): + import torch + + from transformers import ( + Olmo3ForCausalLM, + Olmo3Model, + ) + from transformers.models.olmo3.modeling_olmo3 import Olmo3RotaryEmbedding + + +class Olmo3ModelTester(CausalLMModelTester): + if is_torch_available(): + config_class = Olmo3Config + base_model_class = Olmo3Model + causal_lm_class = Olmo3ForCausalLM + + +@require_torch +class Olmo3ModelTest(CausalLMModelTest, unittest.TestCase): + all_model_classes = (Olmo3Model, Olmo3ForCausalLM) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": Olmo3Model, + "text-generation": Olmo3ForCausalLM, + } + if is_torch_available() + else {} + ) + test_headmasking = False + test_pruning = False + fx_compatible = False + test_torchscript = False + test_all_params_have_gradient = False + model_tester_class = Olmo3ModelTester + rotary_embedding_layer = Olmo3RotaryEmbedding + + # Need to use `0.8` instead of `0.9` for `test_cpu_offload` + # This is because we are hitting edge cases with the causal_mask buffer + model_split_percents = [0.5, 0.7, 0.8] + + # used in `test_torch_compile_for_training` + _torch_compile_train_cls = Olmo3ForCausalLM if is_torch_available() else None + + @parameterized.expand([("linear",), ("dynamic",), ("yarn",)]) + def test_model_rope_scaling_from_config(self, scaling_type): + if self.rotary_embedding_layer is None: + self.skipTest("Rotary embedding layer not set") + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + # Rope only gets applied to full attention layers in Olmo3, so make all layers full attention. + config.layer_types = ["full_attention"] * len(config.layer_types) + + short_input = ids_tensor([1, 10], config.vocab_size) + long_input = ids_tensor([1, int(config.max_position_embeddings * 1.5)], config.vocab_size) + + set_seed(42) # Fixed seed at init time so the two models get the same random weights + original_model = self.model_tester_class.base_model_class(config) + original_model.to(torch_device) + original_model.eval() + original_short_output = original_model(short_input).last_hidden_state + original_long_output = original_model(long_input).last_hidden_state + + set_seed(42) # Fixed seed at init time so the two models get the same random weights + config.rope_scaling = {"type": scaling_type, "factor": 10.0} + scaled_model = self.model_tester_class.base_model_class(config) + scaled_model.to(torch_device) + scaled_model.eval() + scaled_short_output = scaled_model(short_input).last_hidden_state + scaled_long_output = scaled_model(long_input).last_hidden_state + + # Dynamic scaling does not change the RoPE embeddings until it receives an input longer than the original + # maximum sequence length, so the outputs for the short input should match. + if scaling_type == "dynamic": + torch.testing.assert_close(original_short_output, scaled_short_output, rtol=1e-5, atol=1e-5) + else: + self.assertFalse(torch.allclose(original_short_output, scaled_short_output, atol=1e-5)) + + # The output should be different for long inputs + self.assertFalse(torch.allclose(original_long_output, scaled_long_output, atol=1e-5)) + + def test_model_rope_scaling_frequencies(self): + """Tests the frequency properties of the different RoPE scaling types on the model RoPE layer.""" + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + # Parent test class's attempt to find Olmo3 rope fails, so we pass here explicitly. + rope_class = Olmo3RotaryEmbedding + + scaling_factor = 10 + short_input_length = 10 + long_input_length = int(config.max_position_embeddings * 1.5) + + # Inputs + x = torch.randn( + 1, dtype=torch.float32, device=torch_device + ) # used exclusively to get the dtype and the device + position_ids_short = torch.arange(short_input_length, dtype=torch.long, device=torch_device) + position_ids_short = position_ids_short.unsqueeze(0) + position_ids_long = torch.arange(long_input_length, dtype=torch.long, device=torch_device) + position_ids_long = position_ids_long.unsqueeze(0) + + # Sanity check original RoPE + config.rope_scaling = {"rope_type": "default"} + original_rope = rope_class(config=config).to(torch_device) + original_cos_short, original_sin_short = original_rope(x, position_ids_short) + original_cos_long, original_sin_long = original_rope(x, position_ids_long) + torch.testing.assert_close(original_cos_short, original_cos_long[:, :short_input_length, :]) + torch.testing.assert_close(original_sin_short, original_sin_long[:, :short_input_length, :]) + + # Sanity check linear RoPE scaling + # New position "x" should match original position with index "x/scaling_factor" + config.rope_scaling = {"rope_type": "linear", "factor": scaling_factor} + linear_scaling_rope = rope_class(config=config).to(torch_device) + linear_cos_short, linear_sin_short = linear_scaling_rope(x, position_ids_short) + linear_cos_long, linear_sin_long = linear_scaling_rope(x, position_ids_long) + torch.testing.assert_close(linear_cos_short, linear_cos_long[:, :short_input_length, :]) + torch.testing.assert_close(linear_sin_short, linear_sin_long[:, :short_input_length, :]) + for new_position in range(0, long_input_length, scaling_factor): + original_position = int(new_position // scaling_factor) + torch.testing.assert_close(linear_cos_long[:, new_position, :], original_cos_long[:, original_position, :]) + torch.testing.assert_close(linear_sin_long[:, new_position, :], original_sin_long[:, original_position, :]) + + # Sanity check Dynamic NTK RoPE scaling + # Scaling should only be observed after a long input is fed. We can observe that the frequencies increase + # with scaling_factor (or that `inv_freq` decreases) + config.rope_scaling = {"rope_type": "dynamic", "factor": scaling_factor} + ntk_scaling_rope = rope_class(config=config).to(torch_device) + ntk_cos_short, ntk_sin_short = ntk_scaling_rope(x, position_ids_short) + ntk_cos_long, ntk_sin_long = ntk_scaling_rope(x, position_ids_long) + torch.testing.assert_close(ntk_cos_short, original_cos_short) + torch.testing.assert_close(ntk_sin_short, original_sin_short) + with self.assertRaises(AssertionError): + torch.testing.assert_close(ntk_cos_long, original_cos_long) + with self.assertRaises(AssertionError): + torch.testing.assert_close(ntk_sin_long, original_sin_long) + self.assertTrue((ntk_scaling_rope.inv_freq <= original_rope.inv_freq).all()) + + # Sanity check Yarn RoPE scaling + # Scaling should be over the entire input + config.rope_scaling = {"rope_type": "yarn", "factor": scaling_factor} + yarn_scaling_rope = rope_class(config=config).to(torch_device) + yarn_cos_short, yarn_sin_short = yarn_scaling_rope(x, position_ids_short) + yarn_cos_long, yarn_sin_long = yarn_scaling_rope(x, position_ids_long) + torch.testing.assert_close(yarn_cos_short, yarn_cos_long[:, :short_input_length, :]) + torch.testing.assert_close(yarn_sin_short, yarn_sin_long[:, :short_input_length, :]) + with self.assertRaises(AssertionError): + torch.testing.assert_close(yarn_cos_short, original_cos_short) + with self.assertRaises(AssertionError): + torch.testing.assert_close(yarn_sin_short, original_sin_short) + with self.assertRaises(AssertionError): + torch.testing.assert_close(yarn_cos_long, original_cos_long) + with self.assertRaises(AssertionError): + torch.testing.assert_close(yarn_sin_long, original_sin_long) + + +@require_torch +class Olmo3IntegrationTest(unittest.TestCase): + def setUp(self): + cleanup(torch_device, gc_collect=True) + + def tearDown(self): + cleanup(torch_device, gc_collect=True) + + @slow + def test_model_7b_logits(self): + input_ids = [[1, 306, 4658, 278, 6593, 310, 2834, 338]] + model = Olmo3ForCausalLM.from_pretrained("shanearora/2025-sep-a-base-model").to( + torch_device, dtype=torch.bfloat16 + ) + out = model(torch.tensor(input_ids, device=torch_device)).logits.float() + # Expected mean on dim = -1 + expectations = Expectations( + { + ("cuda", 8): [[1.9575, -2.4659, 0.5985, 1.3795, -0.5207, -0.9844, -2.7795, -1.0069]], + } + ) + EXPECTED_MEAN = torch.tensor(expectations.get_expectation(), device=torch_device) + torch.testing.assert_close(out.mean(-1), EXPECTED_MEAN, rtol=1e-2, atol=1e-2) + # slicing logits[0, 0, 0:30] + expectations = Expectations( + { + ("cuda", 8): [8.5625, 5.7812, 4.4688, 2.7031, 3.1094, 4.8125, 5.7188, 3.4219, 2.3906, 2.0938, 3.9844, 5.4688, 3.5312, 5.0938, 2.7656, 8.8125, 9.4375, 9.0625, 8.5000, 8.1875, 7.8750, 7.5312, 7.3125, 7.2812, 7.0000, 2.5625, 4.0312, 3.1719, 7.6562, 4.5625], + } + ) # fmt: skip + EXPECTED_SLICE = torch.tensor(expectations.get_expectation(), device=torch_device) + torch.testing.assert_close(out[0, 0, :30], EXPECTED_SLICE, rtol=1e-2, atol=1e-2) + + @slow + def test_model_7b_greedy_generation(self): + EXPECTED_TEXT_COMPLETION = """Simply put, the theory of relativity states that 1) the laws of physics are the same for all observers, and 2) the speed of light is the same for all observers. The first part of the theory is called the principle of relativity, and the second part is called the principle of the constancy of the speed of light. The theory of rel""" + prompt = "Simply put, the theory of relativity states that " + tokenizer = AutoTokenizer.from_pretrained("allenai/dolma2-tokenizer", device_map="auto") + model = Olmo3ForCausalLM.from_pretrained("shanearora/2025-sep-a-base-model", device_map="auto") + input_ids = tokenizer.encode(prompt, return_tensors="pt").to(model.device) + + # greedy generation outputs + generated_ids = model.generate(input_ids, max_new_tokens=64, top_p=None, temperature=1, do_sample=False) + text = tokenizer.decode(generated_ids[0], skip_special_tokens=True) + self.assertEqual(EXPECTED_TEXT_COMPLETION, text) + + @pytest.mark.torch_export_test + @slow + def test_export_static_cache(self): + if version.parse(torch.__version__) < version.parse("2.4.0"): + self.skipTest(reason="This test requires torch >= 2.4 to run.") + + from transformers.integrations.executorch import ( + TorchExportableModuleWithStaticCache, + convert_and_export_with_cache, + ) + + olmo3_model = "shanearora/2025-sep-a-base-model" + + tokenizer = AutoTokenizer.from_pretrained(olmo3_model, pad_token="", padding_side="right") + EXPECTED_TEXT_COMPLETION = [ + "Simply put, the theory of relativity states that 1) the laws of physics are the same for all observers, and 2", + ] + max_generation_length = tokenizer(EXPECTED_TEXT_COMPLETION, return_tensors="pt", padding=True)[ + "input_ids" + ].shape[-1] + + # Load model + device = "cpu" # TODO (joao / export experts): should be on `torch_device`, but causes GPU OOM + dtype = torch.bfloat16 + cache_implementation = "static" + attn_implementation = "sdpa" + batch_size = 1 + generation_config = GenerationConfig( + use_cache=True, + cache_implementation=cache_implementation, + max_length=max_generation_length, + cache_config={ + "batch_size": batch_size, + "max_cache_len": max_generation_length, + }, + ) + model = Olmo3ForCausalLM.from_pretrained( + olmo3_model, + device_map=device, + dtype=dtype, + attn_implementation=attn_implementation, + generation_config=generation_config, + ) + + prompts = ["Simply put, the theory of relativity states that "] + prompt_tokens = tokenizer(prompts, return_tensors="pt", padding=True).to(model.device) + prompt_token_ids = prompt_tokens["input_ids"] + max_new_tokens = max_generation_length - prompt_token_ids.shape[-1] + + # Static Cache + eager + eager_generated_ids = model.generate( + **prompt_tokens, max_new_tokens=max_new_tokens, do_sample=False, cache_implementation=cache_implementation + ) + eager_generated_text = tokenizer.batch_decode(eager_generated_ids, skip_special_tokens=True) + self.assertEqual(EXPECTED_TEXT_COMPLETION, eager_generated_text) + + # Static Cache + export + exported_program = convert_and_export_with_cache(model) + ep_generated_ids = TorchExportableModuleWithStaticCache.generate( + exported_program=exported_program, prompt_token_ids=prompt_token_ids, max_new_tokens=max_new_tokens + ) + ep_generated_text = tokenizer.batch_decode(ep_generated_ids, skip_special_tokens=True) + self.assertEqual(EXPECTED_TEXT_COMPLETION, ep_generated_text) From 8534f2d1e6e6999b32633e2991e1efaa4074da0f Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Tue, 16 Sep 2025 20:56:11 +0800 Subject: [PATCH 067/204] remove dummy EncodingFast (#40864) Signed-off-by: Yuanyuan Chen --- src/transformers/tokenization_utils_base.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/transformers/tokenization_utils_base.py b/src/transformers/tokenization_utils_base.py index 18f365dd2a94..e4df51c7f867 100644 --- a/src/transformers/tokenization_utils_base.py +++ b/src/transformers/tokenization_utils_base.py @@ -98,9 +98,11 @@ def flatten(arr: list): return res +if is_tokenizers_available() or TYPE_CHECKING: + from tokenizers import Encoding as EncodingFast + if is_tokenizers_available(): from tokenizers import AddedToken - from tokenizers import Encoding as EncodingFast else: @dataclass(frozen=False, eq=True) @@ -129,12 +131,6 @@ def __getstate__(self): def __str__(self): return self.content - @dataclass - class EncodingFast: - """This is dummy class because without the `tokenizers` library we don't have these objects anyway""" - - pass - logger = logging.get_logger(__name__) @@ -238,7 +234,8 @@ def __init__( ): super().__init__(data) - if isinstance(encoding, EncodingFast): + # If encoding is not None, the fast tokenization is used + if encoding is not None and isinstance(encoding, EncodingFast): encoding = [encoding] self._encodings = encoding From 1f0df5f702d833f9698e96601c9e6fda54ba8a0a Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 16 Sep 2025 21:11:48 +0800 Subject: [PATCH 068/204] Improve module name handling for local custom code (#40809) * Improve module name handling for local custom code * Use `%lazy` in logging messages * Revert "Use `%lazy` in logging messages" This reverts commit 5848755d5805e67177c5218f351c0ac852df9340. * Add notes for sanitization rule in docstring * Remove too many underscores * Update src/transformers/dynamic_module_utils.py * Update src/transformers/dynamic_module_utils.py --------- Co-authored-by: Matt --- src/transformers/dynamic_module_utils.py | 34 +++++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/transformers/dynamic_module_utils.py b/src/transformers/dynamic_module_utils.py index 61a230999ed0..5b541c076f63 100644 --- a/src/transformers/dynamic_module_utils.py +++ b/src/transformers/dynamic_module_utils.py @@ -19,6 +19,7 @@ import importlib import importlib.metadata import importlib.util +import keyword import os import re import shutil @@ -48,11 +49,36 @@ def _sanitize_module_name(name: str) -> str: + r""" + Tries to sanitize a module name so that it can be used as a Python module. + + The following transformations are applied: + + 1. Replace `.` in module names with `_dot_`. + 2. Replace `-` in module names with `_hyphen_`. + 3. If the module name starts with a digit, prepend it with `_`. + 4. Warn if the sanitized name is a Python reserved keyword or not a valid identifier. + + If the input name is already a valid identifier, it is returned unchanged. """ - Replace `.` in module names with `_dot_` so that it doesn't - look like an import path separator. - """ - return name.replace(".", "_dot_") + # We not replacing `\W` characters with `_` to avoid collisions. Because `_` is a very common + # separator used in module names, replacing `\W` with `_` would create too many collisions. + # Once a module is imported, it is cached in `sys.modules` and the second import would return + # the first module, which might not be the expected behavior if name collisions happen. + new_name = name.replace(".", "_dot_").replace("-", "_hyphen_") + if new_name and new_name[0].isdigit(): + new_name = f"_{new_name}" + if keyword.iskeyword(new_name): + logger.warning( + f"The module name {new_name} (originally {name}) is a reserved keyword in Python. " + "Please rename the original module to avoid import issues." + ) + elif not new_name.isidentifier(): + logger.warning( + f"The module name {new_name} (originally {name}) is not a valid Python identifier. " + "Please rename the original module to avoid import issues." + ) + return new_name _HF_REMOTE_CODE_LOCK = threading.Lock() From b0676502a8cff8d25033c13b0d76f8ae923ae2c3 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Tue, 16 Sep 2025 15:18:07 +0200 Subject: [PATCH 069/204] Remove `runner_map` (#40880) * fix * fix --------- Co-authored-by: ydshieh --- .github/workflows/model_jobs.yml | 11 ++-- .github/workflows/self-scheduled-caller.yml | 1 + .github/workflows/self-scheduled.yml | 8 +-- utils/get_runner_map.py | 65 --------------------- 4 files changed, 10 insertions(+), 75 deletions(-) delete mode 100644 utils/get_runner_map.py diff --git a/.github/workflows/model_jobs.yml b/.github/workflows/model_jobs.yml index 7e30cde735fa..5da145c2b006 100644 --- a/.github/workflows/model_jobs.yml +++ b/.github/workflows/model_jobs.yml @@ -12,9 +12,6 @@ on: slice_id: required: true type: number - runner_map: - required: false - type: string docker: required: true type: string @@ -54,10 +51,12 @@ jobs: matrix: folders: ${{ fromJson(inputs.folder_slices)[inputs.slice_id] }} runs-on: - group: ${{ fromJson(inputs.runner_map)[matrix.folders][inputs.machine_type] }} + group: '${{ inputs.machine_type }}' container: image: ${{ inputs.docker }} options: --gpus all --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache/ + outputs: + machine_type: ${{ steps.set_machine_type.outputs.machine_type }} steps: - name: Echo input and matrix info shell: bash @@ -111,6 +110,7 @@ jobs: run: pip freeze - name: Set `machine_type` for report and artifact names + id: set_machine_type working-directory: /transformers shell: bash run: | @@ -126,6 +126,7 @@ jobs: echo "$machine_type" echo "machine_type=$machine_type" >> $GITHUB_ENV + echo "machine_type=$machine_type" >> $GITHUB_OUTPUT - name: Run all tests on GPU working-directory: /transformers @@ -159,5 +160,5 @@ jobs: job: run_models_gpu report_repo_id: ${{ inputs.report_repo_id }} gpu_name: ${{ inputs.runner_type }} - machine_type: ${{ inputs.machine_type }} + machine_type: ${{ needs.run_models_gpu.outputs.machine_type }} secrets: inherit diff --git a/.github/workflows/self-scheduled-caller.yml b/.github/workflows/self-scheduled-caller.yml index 78c7f3c60f23..01f5a0a48bdd 100644 --- a/.github/workflows/self-scheduled-caller.yml +++ b/.github/workflows/self-scheduled-caller.yml @@ -88,6 +88,7 @@ jobs: job: run_trainer_and_fsdp_gpu slack_report_channel: "#transformers-ci-daily-training" docker: huggingface/transformers-all-latest-gpu + runner_type: "a10" ci_event: Daily CI report_repo_id: hf-internal-testing/transformers_daily_ci commit_sha: ${{ github.sha }} diff --git a/.github/workflows/self-scheduled.yml b/.github/workflows/self-scheduled.yml index a5dbc9d59a82..7129b1867fc4 100644 --- a/.github/workflows/self-scheduled.yml +++ b/.github/workflows/self-scheduled.yml @@ -68,7 +68,6 @@ jobs: outputs: folder_slices: ${{ steps.set-matrix.outputs.folder_slices }} slice_ids: ${{ steps.set-matrix.outputs.slice_ids }} - runner_map: ${{ steps.set-matrix.outputs.runner_map }} quantization_matrix: ${{ steps.set-matrix-quantization.outputs.quantization_matrix }} steps: - name: Update clone @@ -95,7 +94,6 @@ jobs: if [ "${{ inputs.job }}" = "run_models_gpu" ]; then echo "folder_slices=$(python3 ../utils/split_model_tests.py --models '${{ inputs.models }}' --num_splits ${{ env.NUM_SLICES }})" >> $GITHUB_OUTPUT echo "slice_ids=$(python3 -c 'd = list(range(${{ env.NUM_SLICES }})); print(d)')" >> $GITHUB_OUTPUT - echo "runner_map=$(python3 ../utils/get_runner_map.py)" >> $GITHUB_OUTPUT elif [ "${{ inputs.job }}" = "run_trainer_and_fsdp_gpu" ]; then echo "folder_slices=[['trainer'], ['fsdp']]" >> $GITHUB_OUTPUT echo "slice_ids=[0, 1]" >> $GITHUB_OUTPUT @@ -119,14 +117,13 @@ jobs: strategy: fail-fast: false matrix: - machine_type: [single-gpu, multi-gpu] + machine_type: [aws-g5-4xlarge-cache, aws-g5-12xlarge-cache] slice_id: ${{ fromJSON(needs.setup.outputs.slice_ids) }} uses: ./.github/workflows/model_jobs.yml with: folder_slices: ${{ needs.setup.outputs.folder_slices }} machine_type: ${{ matrix.machine_type }} slice_id: ${{ matrix.slice_id }} - runner_map: ${{ needs.setup.outputs.runner_map }} docker: ${{ inputs.docker }} commit_sha: ${{ inputs.commit_sha || github.sha }} runner_type: ${{ inputs.runner_type }} @@ -147,9 +144,10 @@ jobs: folder_slices: ${{ needs.setup.outputs.folder_slices }} machine_type: ${{ matrix.machine_type }} slice_id: ${{ matrix.slice_id }} - runner_map: ${{ needs.setup.outputs.runner_map }} docker: ${{ inputs.docker }} commit_sha: ${{ inputs.commit_sha || github.sha }} + runner_type: ${{ inputs.runner_type }} + report_repo_id: ${{ inputs.report_repo_id }} report_name_prefix: run_trainer_and_fsdp_gpu secrets: inherit diff --git a/utils/get_runner_map.py b/utils/get_runner_map.py deleted file mode 100644 index 7b36651165bc..000000000000 --- a/utils/get_runner_map.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2025 The HuggingFace Team. All rights reserved. -# -# 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. - -""" -This script is used to get a map containing the information of runners to use in GitHub Actions workflow files. -This is meant to be a temporary file that helps us to switch progressively from T4 to A10 runners. - -The data is stored in a Hub repository [hf-internal-testing/transformers_daily_ci](https://huggingface.co/datasets/hf-internal-testing/transformers_daily_ci/blob/main/runner_map.json). -Currently, in that file, we specify the models for which we want to run the tests with T4 runners to avoid many test failures showing on the CI reports. -We will work on the tests toward to use A10 for all CI jobs. -""" - -import os - -import requests - - -if __name__ == "__main__": - # T4 - t4_runners = { - "single-gpu": "aws-g4dn-4xlarge-cache", - "multi-gpu": "aws-g4dn-12xlarge-cache", - } - - # A10 - a10_runners = { - "single-gpu": "aws-g5-4xlarge-cache", - "multi-gpu": "aws-g5-12xlarge-cache", - } - - tests = os.getcwd() - model_tests = os.listdir(os.path.join(tests, "models")) - d1 = sorted(filter(os.path.isdir, os.listdir(tests))) - d2 = sorted(filter(os.path.isdir, [f"models/{x}" for x in model_tests])) - d1.remove("models") - d = d2 + d1 - - response = requests.get( - "https://huggingface.co/datasets/hf-internal-testing/transformers_daily_ci/resolve/main/runner_map.json" - ) - # The models that we want to run with T4 runners - jobs_using_t4 = response.json() - - runner_map = {} - for key in d: - modified_key = key - if modified_key.startswith("models/"): - modified_key = key[len("models/") :] - if modified_key in jobs_using_t4: - runner_map[key] = t4_runners - else: - runner_map[key] = a10_runners - - print(runner_map) From 5c7684e0da1a75f544703ed2db694aec3c8bcdde Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Tue, 16 Sep 2025 15:34:04 +0200 Subject: [PATCH 070/204] disable `test_fast_is_faster_than_slow` (#40909) fix Co-authored-by: ydshieh --- .../depth_pro/test_image_processing_depth_pro.py | 8 +------- .../test_image_processing_efficientloftr.py | 1 + .../kosmos2_5/test_image_processing_kosmos2_5.py | 12 ------------ .../layoutlmv2/test_image_processing_layoutlmv2.py | 4 ---- .../layoutlmv3/test_image_processing_layoutlmv3.py | 4 ---- tests/models/owlv2/test_image_processing_owlv2.py | 4 ---- .../models/rt_detr/test_image_processing_rt_detr.py | 7 ------- .../models/swin2sr/test_image_processing_swin2sr.py | 4 ---- .../vitmatte/test_image_processing_vitmatte.py | 2 +- tests/test_image_processing_common.py | 4 ++-- 10 files changed, 5 insertions(+), 45 deletions(-) diff --git a/tests/models/depth_pro/test_image_processing_depth_pro.py b/tests/models/depth_pro/test_image_processing_depth_pro.py index a14b60617150..8661d6a8da40 100644 --- a/tests/models/depth_pro/test_image_processing_depth_pro.py +++ b/tests/models/depth_pro/test_image_processing_depth_pro.py @@ -15,7 +15,7 @@ import unittest -from transformers.testing_utils import is_flaky, require_torch, require_vision +from transformers.testing_utils import require_torch, require_vision from transformers.utils import is_torchvision_available, is_vision_available from ...test_image_processing_common import ImageProcessingTestMixin, prepare_image_inputs @@ -115,9 +115,3 @@ def test_image_processor_from_dict_with_kwargs(self): image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42) self.assertEqual(image_processor.size, {"height": 42, "width": 42}) - - @is_flaky( - description="fast and slow, both processors use torch implementation, see: https://github.com/huggingface/transformers/issues/34920", - ) - def test_fast_is_faster_than_slow(self): - super().test_fast_is_faster_than_slow() diff --git a/tests/models/efficientloftr/test_image_processing_efficientloftr.py b/tests/models/efficientloftr/test_image_processing_efficientloftr.py index d4d978428ff0..ba142974b78d 100644 --- a/tests/models/efficientloftr/test_image_processing_efficientloftr.py +++ b/tests/models/efficientloftr/test_image_processing_efficientloftr.py @@ -143,6 +143,7 @@ def test_slow_fast_equivalence_batched(self): self._assert_slow_fast_tensors_equivalence(encoding_slow.pixel_values, encoding_fast.pixel_values) + @unittest.skip(reason="Many failing cases. This test needs a more deep investigation.") def test_fast_is_faster_than_slow(self): """Override the generic test since EfficientLoFTR requires image pairs.""" if not self.test_slow_image_processor or not self.test_fast_image_processor: diff --git a/tests/models/kosmos2_5/test_image_processing_kosmos2_5.py b/tests/models/kosmos2_5/test_image_processing_kosmos2_5.py index 38c7340632c3..05d2813f98ca 100644 --- a/tests/models/kosmos2_5/test_image_processing_kosmos2_5.py +++ b/tests/models/kosmos2_5/test_image_processing_kosmos2_5.py @@ -177,12 +177,6 @@ def test_can_compile_fast_image_processor(self): output_eager.pixel_values, output_compiled.pixel_values, atol=1e-4, rtol=1e-4, mean_atol=1e-5 ) - @unittest.skip( - reason="Kosmos2_5ImageProcessor already uses many torch operations. Fast image processor only works faster with sufficiently large batch size on GPU." - ) - def test_fast_is_faster_than_slow(self): - super().test_fast_is_faster_than_slow() - def test_image_processor_properties(self): image_processor = self.image_processing_class(**self.image_processor_dict) self.assertTrue(hasattr(image_processor, "do_normalize")) @@ -376,12 +370,6 @@ def test_slow_fast_equivalence_batched(self): def test_can_compile_fast_image_processor(self): return super().test_can_compile_fast_image_processor() - @unittest.skip( - reason="Kosmos2_5ImageProcessor already uses many torch operations. Fast image processor only works faster with sufficiently large batch size on GPU." - ) - def test_fast_is_faster_than_slow(self): - super().test_fast_is_faster_than_slow() - def test_image_processor_properties(self): image_processor = self.image_processing_class(**self.image_processor_dict) self.assertTrue(hasattr(image_processor, "do_normalize")) diff --git a/tests/models/layoutlmv2/test_image_processing_layoutlmv2.py b/tests/models/layoutlmv2/test_image_processing_layoutlmv2.py index 1007fd0881ac..9c2a3eee735d 100644 --- a/tests/models/layoutlmv2/test_image_processing_layoutlmv2.py +++ b/tests/models/layoutlmv2/test_image_processing_layoutlmv2.py @@ -105,10 +105,6 @@ def setUp(self): def image_processor_dict(self): return self.image_processor_tester.prepare_image_processor_dict() - @unittest.skip(reason="FIXME: @yoni.") - def test_fast_is_faster_than_slow(self): - pass - def test_image_processor_properties(self): for image_processing_class in self.image_processor_list: image_processing = image_processing_class(**self.image_processor_dict) diff --git a/tests/models/layoutlmv3/test_image_processing_layoutlmv3.py b/tests/models/layoutlmv3/test_image_processing_layoutlmv3.py index 52cae636d87e..8d3577e55371 100644 --- a/tests/models/layoutlmv3/test_image_processing_layoutlmv3.py +++ b/tests/models/layoutlmv3/test_image_processing_layoutlmv3.py @@ -86,10 +86,6 @@ def setUp(self): def image_processor_dict(self): return self.image_processor_tester.prepare_image_processor_dict() - @unittest.skip(reason="FIXME: @yoni.") - def test_fast_is_faster_than_slow(self): - pass - def test_image_processor_properties(self): for image_processing_class in self.image_processor_list: image_processing = image_processing_class(**self.image_processor_dict) diff --git a/tests/models/owlv2/test_image_processing_owlv2.py b/tests/models/owlv2/test_image_processing_owlv2.py index 8eadf4511c57..230665087746 100644 --- a/tests/models/owlv2/test_image_processing_owlv2.py +++ b/tests/models/owlv2/test_image_processing_owlv2.py @@ -99,10 +99,6 @@ def setUp(self): def image_processor_dict(self): return self.image_processor_tester.prepare_image_processor_dict() - @unittest.skip(reason="FIXME: @yoni. It always fails: `0.12 not less than or equal to 0.03`.") - def test_fast_is_faster_than_slow(self): - super().test_fast_is_faster_than_slow() - def test_image_processor_properties(self): for image_processing_class in self.image_processor_list: image_processing = image_processing_class(**self.image_processor_dict) diff --git a/tests/models/rt_detr/test_image_processing_rt_detr.py b/tests/models/rt_detr/test_image_processing_rt_detr.py index 58afe2cfc472..15e07d40e2cb 100644 --- a/tests/models/rt_detr/test_image_processing_rt_detr.py +++ b/tests/models/rt_detr/test_image_processing_rt_detr.py @@ -16,7 +16,6 @@ from transformers.image_utils import load_image from transformers.testing_utils import ( - is_flaky, require_torch, require_torch_accelerator, require_torchvision, @@ -435,9 +434,3 @@ def test_fast_processor_equivalence_cpu_accelerator_coco_detection_annotations(s ) # verify size torch.testing.assert_close(encoding_cpu["labels"][0]["size"], encoding_gpu["labels"][0]["size"].to("cpu")) - - @is_flaky( - description="Still flaky with a failing ratio of ~0.6% after #36240", - ) - def test_fast_is_faster_than_slow(self): - super().test_fast_is_faster_than_slow() diff --git a/tests/models/swin2sr/test_image_processing_swin2sr.py b/tests/models/swin2sr/test_image_processing_swin2sr.py index f8b0f545dd82..eecb023c29a0 100644 --- a/tests/models/swin2sr/test_image_processing_swin2sr.py +++ b/tests/models/swin2sr/test_image_processing_swin2sr.py @@ -187,10 +187,6 @@ def test_call_pytorch(self): expected_output_image_shape = self.image_processor_tester.expected_output_image_shape([image_inputs[0]]) self.assertEqual(tuple(encoded_images.shape), (1, *expected_output_image_shape)) - @unittest.skip(reason="No speed gain on CPU due to minimal processing.") - def test_fast_is_faster_than_slow(self): - pass - def test_slow_fast_equivalence_batched(self): image_inputs = self.image_processor_tester.prepare_image_inputs(equal_resolution=True, torchify=True) diff --git a/tests/models/vitmatte/test_image_processing_vitmatte.py b/tests/models/vitmatte/test_image_processing_vitmatte.py index 644a90d03d31..dc5597b1918b 100644 --- a/tests/models/vitmatte/test_image_processing_vitmatte.py +++ b/tests/models/vitmatte/test_image_processing_vitmatte.py @@ -266,7 +266,7 @@ def test_image_processor_preprocess_arguments(self): self.assertGreaterEqual(len(raised_warnings), 1) self.assertIn("extra_argument", messages) - @unittest.skip(reason="TODO: Yoni") + @unittest.skip(reason="Many failing cases. This test needs a more deep investigation.") def test_fast_is_faster_than_slow(self): if not self.test_slow_image_processor or not self.test_fast_image_processor: self.skipTest(reason="Skipping speed test") diff --git a/tests/test_image_processing_common.py b/tests/test_image_processing_common.py index 635d6a35dc85..b98c94093e2d 100644 --- a/tests/test_image_processing_common.py +++ b/tests/test_image_processing_common.py @@ -18,6 +18,7 @@ import pathlib import tempfile import time +import unittest import warnings from copy import deepcopy @@ -30,7 +31,6 @@ from transformers.image_utils import AnnotationFormat, AnnotionFormat from transformers.testing_utils import ( check_json_file_has_correct_format, - is_flaky, require_torch, require_torch_accelerator, require_vision, @@ -216,7 +216,7 @@ def test_slow_fast_equivalence_batched(self): @require_vision @require_torch - @is_flaky() + @unittest.skip(reason="Many failing cases. This test needs a more deep investigation.") def test_fast_is_faster_than_slow(self): if not self.test_slow_image_processor or not self.test_fast_image_processor: self.skipTest(reason="Skipping speed test") From f8fb8a553d9c11b54763da7b77b371aae8be2ea8 Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Tue, 16 Sep 2025 15:08:48 +0100 Subject: [PATCH 071/204] [gemma3] `Gemma3ForConditionalGeneration` compatible with assisted generation (#40791) * gemma3vision compatible with assisted generation * docstring * BC * docstring * failing checks * make fixup * apply changes to modular * misc fixes * is_initialized * fix poor rebase --- src/transformers/cache_utils.py | 31 +++++++++------ src/transformers/configuration_utils.py | 9 ++++- .../generation/candidate_generator.py | 6 ++- src/transformers/generation/utils.py | 39 ++++++++++++------- .../models/cohere2/configuration_cohere2.py | 2 +- .../models/cohere2/modular_cohere2.py | 2 +- .../models/dots1/configuration_dots1.py | 2 +- .../models/exaone4/configuration_exaone4.py | 2 +- .../models/exaone4/modular_exaone4.py | 2 +- .../models/gemma2/configuration_gemma2.py | 2 +- .../models/gemma2/modular_gemma2.py | 2 +- .../models/gemma3/configuration_gemma3.py | 2 +- .../models/gemma3/modeling_gemma3.py | 14 ++++++- .../models/gemma3/modular_gemma3.py | 16 ++++++-- .../models/gemma3n/configuration_gemma3n.py | 2 +- .../models/gemma3n/modular_gemma3n.py | 2 +- .../models/gpt_oss/configuration_gpt_oss.py | 2 +- .../models/llama4/configuration_llama4.py | 2 +- .../models/minimax/configuration_minimax.py | 2 +- .../models/minimax/modular_minimax.py | 2 +- .../models/qwen2/configuration_qwen2.py | 2 +- .../configuration_qwen2_5_omni.py | 4 +- .../qwen2_5_omni/modular_qwen2_5_omni.py | 4 +- .../qwen2_5_vl/configuration_qwen2_5_vl.py | 2 +- .../models/qwen2_vl/configuration_qwen2_vl.py | 2 +- .../models/qwen3/configuration_qwen3.py | 2 +- .../qwen3_next/configuration_qwen3_next.py | 2 +- .../models/smollm3/configuration_smollm3.py | 2 +- .../models/smollm3/modular_smollm3.py | 2 +- .../models/t5gemma/configuration_t5gemma.py | 2 +- .../vaultgemma/configuration_vaultgemma.py | 2 +- src/transformers/testing_utils.py | 4 ++ tests/generation/test_utils.py | 18 ++++----- tests/models/gemma3/test_modeling_gemma3.py | 11 ------ tests/models/gemma3n/test_modeling_gemma3n.py | 36 ++++++++++++++--- tests/test_modeling_common.py | 5 --- 36 files changed, 151 insertions(+), 92 deletions(-) diff --git a/src/transformers/cache_utils.py b/src/transformers/cache_utils.py index 1e08144c414d..e6f2645a766e 100644 --- a/src/transformers/cache_utils.py +++ b/src/transformers/cache_utils.py @@ -31,6 +31,7 @@ class CacheLayerMixin(ABC): def __init__(self): self.keys: Optional[torch.Tensor] = None self.values: Optional[torch.Tensor] = None + self.is_initialized = False def __repr__(self): return f"{self.__class__.__name__}" @@ -54,19 +55,19 @@ def get_max_cache_shape(self) -> int: ... def offload(self): """Offload this layer's data to CPU device.""" - if self.keys is not None: + if self.is_initialized: self.keys = self.keys.to("cpu", non_blocking=True) self.values = self.values.to("cpu", non_blocking=True) def prefetch(self): """In case of layer offloading, this allows to move the data back to the layer's device ahead of time.""" - if self.keys is not None and self.keys.device != self.device: + if self.is_initialized and self.keys.device != self.device: self.keys = self.keys.to(self.device, non_blocking=True) self.values = self.values.to(self.device, non_blocking=True) def reset(self) -> None: """Resets the cache values while preserving the objects""" - if self.keys is not None: + if self.is_initialized: self.keys.zero_() self.values.zero_() # This attribute is set on several Layers @@ -92,6 +93,7 @@ def lazy_initialization(self, key_states: torch.Tensor): self.dtype, self.device = key_states.dtype, key_states.device self.keys = torch.tensor([], dtype=self.dtype, device=self.device) self.values = torch.tensor([], dtype=self.dtype, device=self.device) + self.is_initialized = True def update( self, @@ -111,7 +113,7 @@ def update( tuple[`torch.Tensor`, `torch.Tensor`]: The key and value states. """ # Lazy initialization - if self.keys is None: + if not self.is_initialized: self.lazy_initialization(key_states) self.keys = torch.cat([self.keys, key_states], dim=-2) @@ -127,7 +129,7 @@ def get_mask_sizes(self, cache_position: torch.Tensor) -> tuple[int, int]: def get_seq_length(self) -> int: """Returns the sequence length of the cached states.""" - if self.keys is None or self.keys.numel() == 0: + if not self.is_initialized or self.keys.numel() == 0: return 0 return self.keys.shape[-2] @@ -193,7 +195,7 @@ def update( tuple[`torch.Tensor`, `torch.Tensor`]: The key and value states. """ # Lazy initialization - if self.keys is None: + if not self.is_initialized: self.lazy_initialization(key_states) self.cumulative_length += key_states.shape[-2] @@ -295,6 +297,8 @@ def lazy_initialization(self, key_states: torch.Tensor): torch._dynamo.mark_static_address(self.keys) torch._dynamo.mark_static_address(self.values) + self.is_initialized = True + def update( self, key_states: torch.Tensor, @@ -313,7 +317,7 @@ def update( tuple[`torch.Tensor`, `torch.Tensor`]: The key and value states. """ # Lazy initialization - if self.keys is None: + if not self.is_initialized: self.lazy_initialization(key_states) # Some old models give None for `cache_position` or even omit passing `cache_kwargs` when used as cross-attention, @@ -343,7 +347,7 @@ def get_seq_length(self) -> int: """Returns the sequence length of the cached states.""" # Occupied cache == any slot in the 3rd dim (sequence length) holds a non-zero value. To save on compute, let's # limit the check to the first batch member and head dimension. - return (self.keys[0, 0].any(dim=-1)).sum() if self.keys is not None else 0 + return (self.keys[0, 0].any(dim=-1)).sum() if self.is_initialized else 0 def get_max_cache_shape(self) -> int: """Return the maximum cache shape of the cache""" @@ -388,7 +392,7 @@ def update( tuple[`torch.Tensor`, `torch.Tensor`]: The key and value states. """ # Lazy initialization - if self.keys is None: + if not self.is_initialized: self.lazy_initialization(key_states) cache_position = cache_kwargs.get("cache_position") @@ -518,7 +522,7 @@ def update( self.cumulative_length += key_states.shape[-2] # Lazy initialization - if self.keys is None: + if not self.is_initialized: self.lazy_initialization(key_states) self._quantized_keys = self._quantize(key_states.contiguous(), axis=self.axis_key) self._quantized_values = self._quantize(value_states.contiguous(), axis=self.axis_value) @@ -859,6 +863,11 @@ def is_compileable(self) -> bool: return False return all(layer.is_compileable for layer in self.layers) + @property + def is_initialized(self) -> bool: + """Return whether the cache data is initialized""" + return len(self.layers) > 0 and all(layer.is_initialized for layer in self.layers) + @property def is_sliding(self) -> list[bool]: """Return whether the layers of the cache are sliding window""" @@ -871,8 +880,6 @@ def __getitem__(self, layer_idx: int) -> tuple[torch.Tensor, torch.Tensor]: """ if layer_idx < len(self.layers): return self.layers[layer_idx].keys, self.layers[layer_idx].values - # elif len(self.layers) == 0: - # return None, None else: raise KeyError( f"Cache only has {len(self.layers)} layers, attempted to access layer with index {layer_idx}" diff --git a/src/transformers/configuration_utils.py b/src/transformers/configuration_utils.py index 0ed8a0399f4d..126b683e672d 100755 --- a/src/transformers/configuration_utils.py +++ b/src/transformers/configuration_utils.py @@ -1369,7 +1369,12 @@ def recursive_diff_dict(dict_a, dict_b, config_obj=None): ) -def layer_type_validation(layer_types: list[str]): - """Check that each entry in `layer_types` are allowed.""" +def layer_type_validation(layer_types: list[str], num_hidden_layers: Optional[int] = None): + """Check that `layer_types` is correctly defined.""" if not all(layer_type in ALLOWED_LAYER_TYPES for layer_type in layer_types): raise ValueError(f"The `layer_types` entries must be in {ALLOWED_LAYER_TYPES}") + if num_hidden_layers is not None and num_hidden_layers != len(layer_types): + raise ValueError( + f"`num_hidden_layers` ({num_hidden_layers}) must be equal to the number of layer types " + f"({len(layer_types)})" + ) diff --git a/src/transformers/generation/candidate_generator.py b/src/transformers/generation/candidate_generator.py index 9f62e4dd0158..a455e69d03ff 100644 --- a/src/transformers/generation/candidate_generator.py +++ b/src/transformers/generation/candidate_generator.py @@ -185,7 +185,7 @@ def __init__( ) # We need to roll back the cache in assisted generation, only DynamicCache is supported - self.generation_config.cache_implementation = None + self.generation_config.cache_implementation = "dynamic_full" if ( is_sklearn_available() @@ -298,6 +298,10 @@ def _update_past_and_masks( ) self.assistant_kwargs = _prepare_token_type_ids(self.assistant_kwargs, input_ids.shape[-1]) + # This unsets `dynamic_full`, needed to initialize a new cache for the assistant. After the first forward + # pass on each generation, we reuse the cache instead. + self.generation_config.cache_implementation = None + return has_past_key_values def _prepare_generation_args(self, input_ids: torch.LongTensor, min_new_tokens: int, max_new_tokens: int) -> dict: diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index c800f7888c37..fa9933d1e5e2 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -1938,6 +1938,10 @@ def _prepare_cache_for_generation( "Cache object) is unsupported. Please use only one of the two." ) if isinstance(user_defined_cache, tuple) and self._supports_default_dynamic_cache(): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `Cache` instead." + ) model_kwargs[cache_name] = ( DynamicCache.from_legacy_cache(user_defined_cache) if not requires_cross_attention_cache @@ -1950,14 +1954,13 @@ def _prepare_cache_for_generation( if generation_config.use_cache is False: return - # Quick escape route 3: model that only supports legacy caches or models that supply it in `prepare_inputs_for_generation` (mamba, zamba, ...) + # Quick escape route 3: model that only supports legacy caches or models that supply it in + # `prepare_inputs_for_generation` (mamba, zamba, ...) if not self._supports_default_dynamic_cache(): if generation_config.cache_implementation is not None: - warnings.warn( - "This model does not support `Cache` instances, it only supports the legacy cache format (tuple " - f"of tuples). `cache_implementation` (set to {generation_config.cache_implementation}) will be " - "ignored.", - UserWarning, + logger.warning_once( + "This model does not support `Cache` instances. `cache_implementation` (set to " + f"{generation_config.cache_implementation}) will be ignored.", ) return @@ -1989,8 +1992,9 @@ def _prepare_cache_for_generation( if generation_config.cache_implementation in ALL_STATIC_CACHE_IMPLEMENTATIONS: if generation_config.cache_implementation in DEPRECATED_STATIC_CACHE_IMPLEMENTATIONS: logger.warning_once( - f"Using `cache_implementation='{generation_config.cache_implementation}' is deprecated. Please only " - f"use one of {STATIC_CACHE_IMPLEMENTATIONS}, and the layer structure will be inferred automatically." + f"Using `cache_implementation='{generation_config.cache_implementation}' is deprecated. " + f"Please only use one of {STATIC_CACHE_IMPLEMENTATIONS}, and the layer structure will be " + "inferred automatically." ) model_kwargs[cache_name] = self._get_cache( cache_implementation=generation_config.cache_implementation, @@ -2014,8 +2018,8 @@ def _prepare_cache_for_generation( if backend == "quanto" and not is_optimum_quanto_available(): raise ImportError( - "You need to install optimum-quanto in order to use KV cache quantization with optimum-quanto backend. " - "Please install it via with `pip install optimum-quanto`" + "You need to install optimum-quanto in order to use KV cache quantization with optimum-quanto " + "backend. Please install it via with `pip install optimum-quanto`" ) elif backend == "HQQ" and not is_hqq_available(): raise ImportError( @@ -2030,11 +2034,18 @@ def _prepare_cache_for_generation( # Use DynamicCache instance by default. This will avoid back and forth from legacy format that # keeps copying the cache thus using much more memory + # TODO (joao): remove this `else` when we remove the last traces of the legacy cache format (v4.58.0, search + # for `instance(past_key_values, Cache)` as well). In general, if `cache_implementation` is unset, cache + # initialization should happen inside the model at prefill time. else: - model_kwargs[cache_name] = ( - DynamicCache(**dynamic_cache_kwargs) - if not requires_cross_attention_cache - else EncoderDecoderCache(DynamicCache(**dynamic_cache_kwargs), DynamicCache(**dynamic_cache_kwargs)) + model_kwargs[cache_name] = DynamicCache(**dynamic_cache_kwargs) + + # TODO (joao): this logic is incomplete, e.g. `offloaded` should apply to both caches. Refactor this function + # to correctly pass parameterization to both caches. + if requires_cross_attention_cache and not isinstance(model_kwargs[cache_name], EncoderDecoderCache): + model_kwargs[cache_name] = EncoderDecoderCache( + model_kwargs[cache_name], # self-attention cache + DynamicCache(**dynamic_cache_kwargs), # cross-attention cache ) def _supports_logits_to_keep(self) -> bool: diff --git a/src/transformers/models/cohere2/configuration_cohere2.py b/src/transformers/models/cohere2/configuration_cohere2.py index 49ddd30ce755..c92f63cad312 100644 --- a/src/transformers/models/cohere2/configuration_cohere2.py +++ b/src/transformers/models/cohere2/configuration_cohere2.py @@ -226,7 +226,7 @@ def __init__( "sliding_attention" if bool((i + 1) % self._sliding_window_pattern) else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) __all__ = ["Cohere2Config"] diff --git a/src/transformers/models/cohere2/modular_cohere2.py b/src/transformers/models/cohere2/modular_cohere2.py index 85d18429f9ce..91ed748e0361 100644 --- a/src/transformers/models/cohere2/modular_cohere2.py +++ b/src/transformers/models/cohere2/modular_cohere2.py @@ -247,7 +247,7 @@ def __init__( "sliding_attention" if bool((i + 1) % self._sliding_window_pattern) else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) class Cohere2RotaryEmbedding(CohereRotaryEmbedding): diff --git a/src/transformers/models/dots1/configuration_dots1.py b/src/transformers/models/dots1/configuration_dots1.py index ca198e71d09e..c8596ddc3828 100644 --- a/src/transformers/models/dots1/configuration_dots1.py +++ b/src/transformers/models/dots1/configuration_dots1.py @@ -200,7 +200,7 @@ def __init__( else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) super().__init__( tie_word_embeddings=tie_word_embeddings, diff --git a/src/transformers/models/exaone4/configuration_exaone4.py b/src/transformers/models/exaone4/configuration_exaone4.py index d80d7d0ca381..0ced6651d41c 100644 --- a/src/transformers/models/exaone4/configuration_exaone4.py +++ b/src/transformers/models/exaone4/configuration_exaone4.py @@ -213,7 +213,7 @@ def __init__( ] if "sliding_window" in self.layer_types: self.cache_implementation = "hybrid" - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) super().__init__( bos_token_id=bos_token_id, eos_token_id=eos_token_id, tie_word_embeddings=tie_word_embeddings, **kwargs diff --git a/src/transformers/models/exaone4/modular_exaone4.py b/src/transformers/models/exaone4/modular_exaone4.py index 604dc9b8f9cb..d366354bda2f 100644 --- a/src/transformers/models/exaone4/modular_exaone4.py +++ b/src/transformers/models/exaone4/modular_exaone4.py @@ -248,7 +248,7 @@ def __init__( ] if "sliding_window" in self.layer_types: self.cache_implementation = "hybrid" - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) super().__init__( bos_token_id=bos_token_id, eos_token_id=eos_token_id, tie_word_embeddings=tie_word_embeddings, **kwargs diff --git a/src/transformers/models/gemma2/configuration_gemma2.py b/src/transformers/models/gemma2/configuration_gemma2.py index 95ca6df873c2..d43ec4c47371 100644 --- a/src/transformers/models/gemma2/configuration_gemma2.py +++ b/src/transformers/models/gemma2/configuration_gemma2.py @@ -176,7 +176,7 @@ def __init__( self.layer_types = [ "sliding_attention" if bool((i + 1) % 2) else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) __all__ = ["Gemma2Config"] diff --git a/src/transformers/models/gemma2/modular_gemma2.py b/src/transformers/models/gemma2/modular_gemma2.py index 2a3e05e4754e..47d612de5a4b 100644 --- a/src/transformers/models/gemma2/modular_gemma2.py +++ b/src/transformers/models/gemma2/modular_gemma2.py @@ -200,7 +200,7 @@ def __init__( self.layer_types = [ "sliding_attention" if bool((i + 1) % 2) else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) class Gemma2RMSNorm(GemmaRMSNorm): diff --git a/src/transformers/models/gemma3/configuration_gemma3.py b/src/transformers/models/gemma3/configuration_gemma3.py index c32c15b65ecd..15d055654b11 100644 --- a/src/transformers/models/gemma3/configuration_gemma3.py +++ b/src/transformers/models/gemma3/configuration_gemma3.py @@ -240,7 +240,7 @@ def __init__( "sliding_attention" if bool((i + 1) % self._sliding_window_pattern) else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) class Gemma3Config(PretrainedConfig): diff --git a/src/transformers/models/gemma3/modeling_gemma3.py b/src/transformers/models/gemma3/modeling_gemma3.py index 889a374b5493..7a91db1905f7 100644 --- a/src/transformers/models/gemma3/modeling_gemma3.py +++ b/src/transformers/models/gemma3/modeling_gemma3.py @@ -920,11 +920,21 @@ def forward( "past_key_values": past_key_values, "position_ids": position_ids, } - if token_type_ids is not None and inputs_embeds.shape[1] != 1: + # NOTE: this `is_prefill` logic is not flawless, it fails when we're using a cache eagerly initialized + # (e.g. compiled prefill) AND `pixel_values` are not provided. Determining prefill in that case requires + # checking data values, which is not compile-compatible. + is_prefill = ( + not use_cache + or past_key_values is None + or not past_key_values.is_initialized + or pixel_values is not None + ) + if token_type_ids is not None and is_prefill: # We need to pass an additional mask function to account for token type ids, and it needs to be an `or` # First find where a new image block starts: 1 if image and previous not image - # The images cannot attend to future images, but can attend to all prev images and to itself bidirectionally + # The images cannot attend to future images, but can attend to all prev images and to itself + # bidirectionally is_image = (token_type_ids == 1).to(cache_position.device) new_image_start = is_image & ~nn.functional.pad(is_image, (1, 0), value=0)[:, :-1] image_group_ids = torch.cumsum(new_image_start.int(), dim=1) - 1 diff --git a/src/transformers/models/gemma3/modular_gemma3.py b/src/transformers/models/gemma3/modular_gemma3.py index b0cb272dd04a..f0658f9825f8 100644 --- a/src/transformers/models/gemma3/modular_gemma3.py +++ b/src/transformers/models/gemma3/modular_gemma3.py @@ -251,7 +251,7 @@ def __init__( "sliding_attention" if bool((i + 1) % self._sliding_window_pattern) else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) class Gemma3Config(PretrainedConfig): @@ -838,11 +838,21 @@ def forward( "past_key_values": past_key_values, "position_ids": position_ids, } - if token_type_ids is not None and inputs_embeds.shape[1] != 1: + # NOTE: this `is_prefill` logic is not flawless, it fails when we're using a cache eagerly initialized + # (e.g. compiled prefill) AND `pixel_values` are not provided. Determining prefill in that case requires + # checking data values, which is not compile-compatible. + is_prefill = ( + not use_cache + or past_key_values is None + or not past_key_values.is_initialized + or pixel_values is not None + ) + if token_type_ids is not None and is_prefill: # We need to pass an additional mask function to account for token type ids, and it needs to be an `or` # First find where a new image block starts: 1 if image and previous not image - # The images cannot attend to future images, but can attend to all prev images and to itself bidirectionally + # The images cannot attend to future images, but can attend to all prev images and to itself + # bidirectionally is_image = (token_type_ids == 1).to(cache_position.device) new_image_start = is_image & ~nn.functional.pad(is_image, (1, 0), value=0)[:, :-1] image_group_ids = torch.cumsum(new_image_start.int(), dim=1) - 1 diff --git a/src/transformers/models/gemma3n/configuration_gemma3n.py b/src/transformers/models/gemma3n/configuration_gemma3n.py index efb9b2a648dd..3502d2a423c9 100644 --- a/src/transformers/models/gemma3n/configuration_gemma3n.py +++ b/src/transformers/models/gemma3n/configuration_gemma3n.py @@ -277,7 +277,7 @@ def __init__( else: self.layer_types = layer_types - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) self.hidden_size_per_layer_input = hidden_size_per_layer_input self.num_kv_shared_layers = num_kv_shared_layers diff --git a/src/transformers/models/gemma3n/modular_gemma3n.py b/src/transformers/models/gemma3n/modular_gemma3n.py index d46471dfdab8..0264d77c02d5 100644 --- a/src/transformers/models/gemma3n/modular_gemma3n.py +++ b/src/transformers/models/gemma3n/modular_gemma3n.py @@ -290,7 +290,7 @@ def __init__( else: self.layer_types = layer_types - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) self.hidden_size_per_layer_input = hidden_size_per_layer_input self.num_kv_shared_layers = num_kv_shared_layers diff --git a/src/transformers/models/gpt_oss/configuration_gpt_oss.py b/src/transformers/models/gpt_oss/configuration_gpt_oss.py index 003d38c900a7..6459e9a7fd4a 100644 --- a/src/transformers/models/gpt_oss/configuration_gpt_oss.py +++ b/src/transformers/models/gpt_oss/configuration_gpt_oss.py @@ -103,7 +103,7 @@ def __init__( self.layer_types = [ "sliding_attention" if bool((i + 1) % 2) else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) self.attention_bias = True self.max_position_embeddings = max_position_embeddings diff --git a/src/transformers/models/llama4/configuration_llama4.py b/src/transformers/models/llama4/configuration_llama4.py index d74107c2610a..7ced47cb9436 100644 --- a/src/transformers/models/llama4/configuration_llama4.py +++ b/src/transformers/models/llama4/configuration_llama4.py @@ -378,7 +378,7 @@ def __init__( self.layer_types = [ "chunked_attention" if no_rope else "full_attention" for no_rope in self.no_rope_layers ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) class Llama4Config(PretrainedConfig): diff --git a/src/transformers/models/minimax/configuration_minimax.py b/src/transformers/models/minimax/configuration_minimax.py index 7fa62ff8d180..2ab46efb2cf8 100644 --- a/src/transformers/models/minimax/configuration_minimax.py +++ b/src/transformers/models/minimax/configuration_minimax.py @@ -224,7 +224,7 @@ def __init__( self.layer_types = [ "full_attention" if bool((i + 1) % 2) else "linear_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) __all__ = ["MiniMaxConfig"] diff --git a/src/transformers/models/minimax/modular_minimax.py b/src/transformers/models/minimax/modular_minimax.py index 76f9df0d5304..d3af8beab87f 100644 --- a/src/transformers/models/minimax/modular_minimax.py +++ b/src/transformers/models/minimax/modular_minimax.py @@ -178,7 +178,7 @@ def __init__( self.layer_types = [ "full_attention" if bool((i + 1) % 2) else "linear_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) class MiniMaxRMSNorm(MixtralRMSNorm): diff --git a/src/transformers/models/qwen2/configuration_qwen2.py b/src/transformers/models/qwen2/configuration_qwen2.py index 3d5b7d4edcf8..4d75e25092f4 100644 --- a/src/transformers/models/qwen2/configuration_qwen2.py +++ b/src/transformers/models/qwen2/configuration_qwen2.py @@ -207,7 +207,7 @@ def __init__( else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) super().__init__( tie_word_embeddings=tie_word_embeddings, diff --git a/src/transformers/models/qwen2_5_omni/configuration_qwen2_5_omni.py b/src/transformers/models/qwen2_5_omni/configuration_qwen2_5_omni.py index 5df1b10a6528..7bd36b7a3c0d 100644 --- a/src/transformers/models/qwen2_5_omni/configuration_qwen2_5_omni.py +++ b/src/transformers/models/qwen2_5_omni/configuration_qwen2_5_omni.py @@ -407,7 +407,7 @@ def __init__( else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) class Qwen2_5OmniThinkerConfig(PretrainedConfig): @@ -787,7 +787,7 @@ def __init__( else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs) diff --git a/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py b/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py index 007f98345988..07cd851d4f88 100644 --- a/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py +++ b/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py @@ -442,7 +442,7 @@ def __init__( else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) class Qwen2_5OmniThinkerConfig(PretrainedConfig): @@ -822,7 +822,7 @@ def __init__( else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs) diff --git a/src/transformers/models/qwen2_5_vl/configuration_qwen2_5_vl.py b/src/transformers/models/qwen2_5_vl/configuration_qwen2_5_vl.py index 9312fdf2b44d..a7a489c3e867 100644 --- a/src/transformers/models/qwen2_5_vl/configuration_qwen2_5_vl.py +++ b/src/transformers/models/qwen2_5_vl/configuration_qwen2_5_vl.py @@ -252,7 +252,7 @@ def __init__( else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) # Validate the correctness of rotary position embeddings parameters # BC: if there is a 'type' field, move it to 'rope_type'. diff --git a/src/transformers/models/qwen2_vl/configuration_qwen2_vl.py b/src/transformers/models/qwen2_vl/configuration_qwen2_vl.py index d60c2eb62e32..1f9e0a3a5bc4 100644 --- a/src/transformers/models/qwen2_vl/configuration_qwen2_vl.py +++ b/src/transformers/models/qwen2_vl/configuration_qwen2_vl.py @@ -241,7 +241,7 @@ def __init__( else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) # Validate the correctness of rotary position embeddings parameters # BC: if there is a 'type' field, move it to 'rope_type'. diff --git a/src/transformers/models/qwen3/configuration_qwen3.py b/src/transformers/models/qwen3/configuration_qwen3.py index 2a52938cc115..0b642913dce5 100644 --- a/src/transformers/models/qwen3/configuration_qwen3.py +++ b/src/transformers/models/qwen3/configuration_qwen3.py @@ -215,7 +215,7 @@ def __init__( else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) super().__init__( tie_word_embeddings=tie_word_embeddings, diff --git a/src/transformers/models/qwen3_next/configuration_qwen3_next.py b/src/transformers/models/qwen3_next/configuration_qwen3_next.py index 9db251a06893..148166cbd16f 100644 --- a/src/transformers/models/qwen3_next/configuration_qwen3_next.py +++ b/src/transformers/models/qwen3_next/configuration_qwen3_next.py @@ -248,7 +248,7 @@ def __init__( "linear_attention" if bool((i + 1) % interval_pattern) else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) # linear attention part self.linear_conv_kernel_dim = linear_conv_kernel_dim diff --git a/src/transformers/models/smollm3/configuration_smollm3.py b/src/transformers/models/smollm3/configuration_smollm3.py index fd1861a589f9..325703f782c0 100644 --- a/src/transformers/models/smollm3/configuration_smollm3.py +++ b/src/transformers/models/smollm3/configuration_smollm3.py @@ -235,7 +235,7 @@ def __init__( layer_types.append("full_attention") self.layer_types = layer_types - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) # Validate the correctness of rotary position embeddings parameters # BC: if there is a 'type' field, move it to 'rope_type'. diff --git a/src/transformers/models/smollm3/modular_smollm3.py b/src/transformers/models/smollm3/modular_smollm3.py index 66d58f07a372..cd82fccbd7cc 100644 --- a/src/transformers/models/smollm3/modular_smollm3.py +++ b/src/transformers/models/smollm3/modular_smollm3.py @@ -254,7 +254,7 @@ def __init__( layer_types.append("full_attention") self.layer_types = layer_types - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) # Validate the correctness of rotary position embeddings parameters # BC: if there is a 'type' field, move it to 'rope_type'. diff --git a/src/transformers/models/t5gemma/configuration_t5gemma.py b/src/transformers/models/t5gemma/configuration_t5gemma.py index 86e367413ace..217a24df0417 100644 --- a/src/transformers/models/t5gemma/configuration_t5gemma.py +++ b/src/transformers/models/t5gemma/configuration_t5gemma.py @@ -178,7 +178,7 @@ def __init__( self.layer_types = [ "sliding_attention" if bool((i + 1) % 2) else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) class T5GemmaConfig(PretrainedConfig): diff --git a/src/transformers/models/vaultgemma/configuration_vaultgemma.py b/src/transformers/models/vaultgemma/configuration_vaultgemma.py index 3e9d419a5854..1b93ae6ccb04 100644 --- a/src/transformers/models/vaultgemma/configuration_vaultgemma.py +++ b/src/transformers/models/vaultgemma/configuration_vaultgemma.py @@ -176,7 +176,7 @@ def __init__( self.layer_types = [ "sliding_attention" if bool((i + 1) % 2) else "full_attention" for i in range(self.num_hidden_layers) ] - layer_type_validation(self.layer_types) + layer_type_validation(self.layer_types, self.num_hidden_layers) __all__ = ["VaultGemmaConfig"] diff --git a/src/transformers/testing_utils.py b/src/transformers/testing_utils.py index 15b32c5fe45c..51fa682c7be4 100644 --- a/src/transformers/testing_utils.py +++ b/src/transformers/testing_utils.py @@ -1639,6 +1639,10 @@ def assert_screenout(out, what): def set_model_tester_for_less_flaky_test(test_case): + # NOTE: this function edits the config object, which may lead to hard-to-debug side-effects. Use with caution. + # Do not use in tests/models where objects behave very differently based on the config's hidden layer settings + # (e.g. KV caches, sliding window attention, ...) + # TODO (if possible): Avoid exceptional cases exceptional_classes = [ "ZambaModelTester", diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index 3b828cd8313a..680002d4600b 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -52,7 +52,6 @@ require_torch_multi_accelerator, set_config_for_less_flaky_test, set_model_for_less_flaky_test, - set_model_tester_for_less_flaky_test, slow, torch_device, ) @@ -675,10 +674,6 @@ def test_assisted_decoding_matches_greedy_search(self, assistant_type): # - assisted_decoding does not support `use_cache = False` # - assisted_decoding does not support `batch_size > 1` - # No idea why this cause problem! - if type(self).__name__ not in ["Gemma3nTextModelTest"]: - set_model_tester_for_less_flaky_test(self) - for model_class in self.all_generative_model_classes: if model_class._is_stateful: self.skipTest(reason="Stateful models don't support assisted generation") @@ -720,6 +715,8 @@ def test_assisted_decoding_matches_greedy_search(self, assistant_type): # the assistant model is correct # c) there are at least two forward passes in the main model, to ensure the input preparation of # the main model is correct + # d) use a cache type compatible with rollbacks (only dynamic cache atm). Otherwise, there may be + # differences vs model-specific default cache generation_kwargs = { "eos_token_id": -1, # see a) "max_new_tokens": 4, # see c) @@ -731,6 +728,7 @@ def test_assisted_decoding_matches_greedy_search(self, assistant_type): "output_attentions": self.has_attentions, "return_dict_in_generate": True, "use_cache": True, + "cache_implementation": "dynamic_full", # see d) } logits_processor_kwargs = self._get_logits_processor_kwargs(config=model.config) @@ -804,6 +802,8 @@ def test_prompt_lookup_decoding_matches_greedy_search(self): # prompt lookup is correct # c) there are at least two forward passes in the main model, to ensure the input preparation of # the main model is correct + # d) use a cache type compatible with rollbacks (only dynamic cache atm). Otherwise, there may be + # differences vs model-specific default cache generation_kwargs = { "eos_token_id": -1, # see a) "max_new_tokens": 4, # see c) @@ -815,6 +815,7 @@ def test_prompt_lookup_decoding_matches_greedy_search(self): "output_attentions": self.has_attentions, "return_dict_in_generate": True, "use_cache": True, + "cache_implementation": "dynamic_full", # see d) } logits_processor_kwargs = self._get_logits_processor_kwargs(config=model.config) @@ -872,6 +873,8 @@ def test_assisted_decoding_sample(self): # the assistant model is correct # c) there are at least two forward passes in the main model, to ensure the input preparation of # the main model is correct + # d) use a cache type compatible with rollbacks (only dynamic cache atm). Otherwise, there may be + # differences vs model-specific default cache assistant_model = model assistant_model.generation_config.num_assistant_tokens = 2 # see b) assistant_model.generation_config.num_assistant_tokens_schedule = "constant" # see b) @@ -887,6 +890,7 @@ def test_assisted_decoding_sample(self): "output_attentions": self.has_attentions, "return_dict_in_generate": True, "use_cache": True, + "cache_implementation": "dynamic_full", # see d) } logits_processor_kwargs = self._get_logits_processor_kwargs(config=model.config) output_assisted = model.generate(**generation_kwargs, **inputs_dict, **logits_processor_kwargs) @@ -1183,7 +1187,6 @@ def test_generate_from_inputs_embeds(self, _, num_beams): """Tests that we can generate from `inputs_embeds` instead of `input_ids` in LLMs, VLMs, etc""" # When supported, tests that the decoder model can generate from `inputs_embeds` instead of `input_ids` # if fails, you should probably update the `prepare_inputs_for_generation` function - set_model_tester_for_less_flaky_test(self) for model_class in self.all_generative_model_classes: config, inputs_dict = self.prepare_config_and_inputs_for_generate() @@ -1851,7 +1854,6 @@ def _test_attention_implementation(self, attn_implementation): "flash_attention_3": "_supports_flash_attn", } - set_model_tester_for_less_flaky_test(self) for model_class in self.all_generative_model_classes: if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): self.skipTest(f"{model_class.__name__} does not support `attn_implementation={attn_implementation}`") @@ -2222,8 +2224,6 @@ def test_custom_4d_attention_mask(self): if not self.has_attentions: self.skipTest(reason="Model architecture does not support attentions") - set_model_tester_for_less_flaky_test(self) - for model_class in self.all_generative_model_classes: if not model_class._can_compile_fullgraph: self.skipTest(f"{model_class.__name__} is not guaranteed to work with custom 4D attention masks") diff --git a/tests/models/gemma3/test_modeling_gemma3.py b/tests/models/gemma3/test_modeling_gemma3.py index 122b3f033b11..ddef6e0d6bc1 100644 --- a/tests/models/gemma3/test_modeling_gemma3.py +++ b/tests/models/gemma3/test_modeling_gemma3.py @@ -345,17 +345,6 @@ def test_training_gradient_checkpointing_use_reentrant(self): def test_training_gradient_checkpointing_use_reentrant_false(self): pass - @parameterized.expand([("random",), ("same",)]) - @pytest.mark.generate - @unittest.skip("Gemma3 does not seem to be compatible with assisted decoding") - def test_assisted_decoding_matches_greedy_search(self, assistant_type): - pass - - @pytest.mark.generate - @unittest.skip("Gemma3 does not seem to be compatible with assisted decoding") - def test_assisted_decoding_sample(self): - pass - @unittest.skip( reason="Siglip (vision backbone) uses the same initialization scheme as the Flax original implementation" ) diff --git a/tests/models/gemma3n/test_modeling_gemma3n.py b/tests/models/gemma3n/test_modeling_gemma3n.py index ccfe8ec6a365..5e4b774a8bd0 100644 --- a/tests/models/gemma3n/test_modeling_gemma3n.py +++ b/tests/models/gemma3n/test_modeling_gemma3n.py @@ -385,23 +385,47 @@ def test_eager_matches_sdpa_inference( output_attentions, enable_kernels, ): - "We need to relax a bit the `atols` for fp32 here due to the altup projections" + "We need to relax a bit the `atols` and `rtols` for fp32 here due to the altup projections" atols = { - ("cpu", False, torch.float32): 1e-3, # this was relaxed + ("cpu", False, torch.float32): 5e-2, # this was relaxed ("cpu", False, torch.float16): 5e-3, ("cpu", False, torch.bfloat16): 1e-2, - ("cpu", True, torch.float32): 1e-3, # this was relaxed + ("cpu", True, torch.float32): 5e-2, # this was relaxed ("cpu", True, torch.float16): 5e-3, ("cpu", True, torch.bfloat16): 1e-2, - ("cuda", False, torch.float32): 1e-3, # this was relaxed + ("cuda", False, torch.float32): 5e-2, # this was relaxed ("cuda", False, torch.bfloat16): 1e-2, ("cuda", False, torch.float16): 5e-3, - ("cuda", True, torch.float32): 1e-3, # this was relaxed + ("cuda", True, torch.float32): 5e-2, # this was relaxed ("cuda", True, torch.bfloat16): 1e-2, ("cuda", True, torch.float16): 5e-3, } + + rtols = { + ("cpu", False, torch.float32): 1e-2, # this was relaxed + ("cpu", False, torch.float16): 5e-3, + ("cpu", False, torch.bfloat16): 1e-2, + ("cpu", True, torch.float32): 1e-2, # this was relaxed + ("cpu", True, torch.float16): 5e-3, + ("cpu", True, torch.bfloat16): 1e-2, + ("cuda", False, torch.float32): 1e-2, # this was relaxed + ("cuda", False, torch.bfloat16): 1e-2, + ("cuda", False, torch.float16): 5e-3, + ("cuda", True, torch.float32): 1e-2, # this was relaxed + ("cuda", True, torch.bfloat16): 3e-2, + ("cuda", True, torch.float16): 5e-3, + } + _test_eager_matches_sdpa_inference( - self, name, dtype, padding_side, use_attention_mask, output_attentions, enable_kernels, atols=atols + self, + name, + dtype, + padding_side, + use_attention_mask, + output_attentions, + enable_kernels, + atols=atols, + rtols=rtols, ) @pytest.mark.generate diff --git a/tests/test_modeling_common.py b/tests/test_modeling_common.py index f4c890e3ce15..4e95b1f255a5 100755 --- a/tests/test_modeling_common.py +++ b/tests/test_modeling_common.py @@ -100,7 +100,6 @@ run_test_using_subprocess, set_config_for_less_flaky_test, set_model_for_less_flaky_test, - set_model_tester_for_less_flaky_test, slow, torch_device, ) @@ -225,8 +224,6 @@ def _test_eager_matches_sdpa_inference( ("cuda", True, torch.float16): 5e-3, } - set_model_tester_for_less_flaky_test(self) - def _can_output_attn(model): parameters = inspect.signature(model.forward).parameters if "output_attentions" in parameters: @@ -1095,8 +1092,6 @@ def recursive_check(batched_object, single_row_object, model_name, key): msg += str(e) raise AssertionError(msg) - set_model_tester_for_less_flaky_test(self) - config, batched_input = self.model_tester.prepare_config_and_inputs_for_common() set_config_for_less_flaky_test(config) From 4248a67eb4183435e1c6eac86e2e38835e881d58 Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Tue, 16 Sep 2025 15:18:06 +0100 Subject: [PATCH 072/204] [generate] misc fixes (#40906) misc fixes --- src/transformers/generation/utils.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index fa9933d1e5e2..5affe68d1374 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -576,6 +576,9 @@ def prepare_inputs_for_generation( # 2. Generic cache-dependent input preparation if past_key_values is not None: model_inputs["past_key_values"] = past_key_values + # TODO (joao): handle the case where cache length == input_ids length. The function below results in an + # exception because we get empty input_ids after slicing. In essence, we need to roll back the cache 1 + # token to recompute the logits for the first token to be generated (but not all caches support roll backs) inputs_embeds, input_ids = self._cache_dependant_input_preparation( input_ids, inputs_embeds, cache_position ) @@ -2635,19 +2638,19 @@ def heal_tokens( # replace bos with pad to not condition healing on it input_ids = torch.where(input_ids == bos_token_id, pad_token_id, input_ids) - """ - the latter code assumes the input_ids is not empty, - input_id has to be checked if contains elements - """ + # the latter code assumes the input_ids is not empty, input_id has to be checked if contains elements if input_ids.numel() == 0: return input_ids tail_ids = input_ids[:, -1].tolist() - space_tok = tokenizer.convert_ids_to_tokens(tokenizer.convert_tokens_to_ids(" "))[0] # tail tokens are used for a prefix search, thus, whitespaces are replaced with # their tokenization (e.g. 'Ġ') to enable search for tokens prefixed with a whitespace - tail_toks = (tokenizer.decode(t).replace(" ", space_tok) for t in tail_ids) + if tokenizer.convert_tokens_to_ids(" ") is not None: + space_tok = tokenizer.convert_ids_to_tokens(tokenizer.convert_tokens_to_ids(" "))[0] + tail_toks = (tokenizer.decode(t).replace(" ", space_tok) for t in tail_ids) + else: + tail_toks = (tokenizer.decode(t) for t in tail_ids) for batch_idx, (tail_id, tail_tok) in enumerate(zip(tail_ids, tail_toks)): batch_ids = input_ids[batch_idx] From cc4f3139f64c4ce67650c24ed1d938f7d33bf12e Mon Sep 17 00:00:00 2001 From: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com> Date: Tue, 16 Sep 2025 12:01:38 -0400 Subject: [PATCH 073/204] =?UTF-8?q?=F0=9F=94=B4Make=20`center=5Fcrop`=20fa?= =?UTF-8?q?st=20equivalent=20to=20slow=20(#40856)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit make center_crop fast equivalent to slow --- .../image_processing_utils_fast.py | 22 +++++++++++++++++-- .../image_processing_perceiver_fast.py | 2 +- .../test_image_processing_chinese_clip.py | 10 +-------- tests/test_image_processing_common.py | 5 ----- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/transformers/image_processing_utils_fast.py b/src/transformers/image_processing_utils_fast.py index 071348cb4330..5fb87c345ef0 100644 --- a/src/transformers/image_processing_utils_fast.py +++ b/src/transformers/image_processing_utils_fast.py @@ -405,10 +405,11 @@ def rescale_and_normalize( def center_crop( self, image: "torch.Tensor", - size: dict[str, int], + size: SizeDict, **kwargs, ) -> "torch.Tensor": """ + Note: override torchvision's center_crop to have the same behavior as the slow processor. Center crop an image to `(size["height"], size["width"])`. If the input size is smaller than `crop_size` along any edge, the image is padded with 0's and then center cropped. @@ -423,7 +424,24 @@ def center_crop( """ if size.height is None or size.width is None: raise ValueError(f"The size dictionary must have keys 'height' and 'width'. Got {size.keys()}") - return F.center_crop(image, (size["height"], size["width"])) + image_height, image_width = image.shape[-2:] + crop_height, crop_width = size.height, size.width + + if crop_width > image_width or crop_height > image_height: + padding_ltrb = [ + (crop_width - image_width) // 2 if crop_width > image_width else 0, + (crop_height - image_height) // 2 if crop_height > image_height else 0, + (crop_width - image_width + 1) // 2 if crop_width > image_width else 0, + (crop_height - image_height + 1) // 2 if crop_height > image_height else 0, + ] + image = F.pad(image, padding_ltrb, fill=0) # PIL uses fill value 0 + image_height, image_width = image.shape[-2:] + if crop_width == image_width and crop_height == image_height: + return image + + crop_top = int((image_height - crop_height) / 2.0) + crop_left = int((image_width - crop_width) / 2.0) + return F.crop(image, crop_top, crop_left, crop_height, crop_width) def convert_to_rgb( self, diff --git a/src/transformers/models/perceiver/image_processing_perceiver_fast.py b/src/transformers/models/perceiver/image_processing_perceiver_fast.py index 640083ba82dd..ecd7f938f569 100644 --- a/src/transformers/models/perceiver/image_processing_perceiver_fast.py +++ b/src/transformers/models/perceiver/image_processing_perceiver_fast.py @@ -81,7 +81,7 @@ def center_crop( min_dim = min(height, width) cropped_height = int((size.height / crop_size.height) * min_dim) cropped_width = int((size.width / crop_size.width) * min_dim) - return F.center_crop(image, (cropped_height, cropped_width)) + return super().center_crop(image, SizeDict(height=cropped_height, width=cropped_width)) def _preprocess( self, diff --git a/tests/models/chinese_clip/test_image_processing_chinese_clip.py b/tests/models/chinese_clip/test_image_processing_chinese_clip.py index 7acae860b08a..18670bcb4d64 100644 --- a/tests/models/chinese_clip/test_image_processing_chinese_clip.py +++ b/tests/models/chinese_clip/test_image_processing_chinese_clip.py @@ -141,7 +141,7 @@ class ChineseCLIPImageProcessingTestFourChannels(ImageProcessingTestMixin, unitt def setUp(self): super().setUp() - self.image_processor_tester = ChineseCLIPImageProcessingTester(self, num_channels=4, do_center_crop=True) + self.image_processor_tester = ChineseCLIPImageProcessingTester(self, num_channels=3, do_center_crop=True) self.expected_encoded_image_num_channels = 3 @property @@ -160,14 +160,6 @@ def test_image_processor_properties(self): self.assertTrue(hasattr(image_processing, "image_std")) self.assertTrue(hasattr(image_processing, "do_convert_rgb")) - @unittest.skip(reason="ChineseCLIPImageProcessor does not support 4 channels yet") # FIXME Amy - def test_call_numpy(self): - return super().test_call_numpy() - - @unittest.skip(reason="ChineseCLIPImageProcessor does not support 4 channels yet") # FIXME Amy - def test_call_pytorch(self): - return super().test_call_torch() - @unittest.skip( reason="ChineseCLIPImageProcessor doesn't treat 4 channel PIL and numpy consistently yet" ) # FIXME Amy diff --git a/tests/test_image_processing_common.py b/tests/test_image_processing_common.py index b98c94093e2d..ce0bd4181be5 100644 --- a/tests/test_image_processing_common.py +++ b/tests/test_image_processing_common.py @@ -200,11 +200,6 @@ def test_slow_fast_equivalence_batched(self): if self.image_processing_class is None or self.fast_image_processing_class is None: self.skipTest(reason="Skipping slow/fast equivalence test as one of the image processors is not defined") - if hasattr(self.image_processor_tester, "do_center_crop") and self.image_processor_tester.do_center_crop: - self.skipTest( - reason="Skipping as do_center_crop is True and center_crop functions are not equivalent for fast and slow processors" - ) - dummy_images = self.image_processor_tester.prepare_image_inputs(equal_resolution=False, torchify=True) image_processor_slow = self.image_processing_class(**self.image_processor_dict) image_processor_fast = self.fast_image_processing_class(**self.image_processor_dict) From c689f1643170421aed7f57fa90c88d4e993d884b Mon Sep 17 00:00:00 2001 From: Raushan Turganbay Date: Tue, 16 Sep 2025 18:07:56 +0200 Subject: [PATCH 074/204] Fix dtype in Paligemma (#40912) * fix dtypes * fix copies * delete unused attr --- src/transformers/models/colpali/modeling_colpali.py | 3 ++- src/transformers/models/colqwen2/modeling_colqwen2.py | 9 ++------- src/transformers/models/colqwen2/modular_colqwen2.py | 9 ++------- src/transformers/models/gemma3/modular_gemma3.py | 4 ++++ src/transformers/models/gemma3n/modular_gemma3n.py | 1 + src/transformers/models/paligemma/modeling_paligemma.py | 8 ++++++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/transformers/models/colpali/modeling_colpali.py b/src/transformers/models/colpali/modeling_colpali.py index a59224e20456..fe92252b9a80 100644 --- a/src/transformers/models/colpali/modeling_colpali.py +++ b/src/transformers/models/colpali/modeling_colpali.py @@ -156,7 +156,8 @@ def forward( vlm_image_hidden_states = vlm_output.image_hidden_states if pixel_values is not None else None last_hidden_states = vlm_output[0] # (batch_size, sequence_length, hidden_size) - embeddings = self.embedding_proj_layer(last_hidden_states) # (batch_size, sequence_length, dim) + proj_dtype = self.embedding_proj_layer.weight.dtype + embeddings = self.embedding_proj_layer(last_hidden_states.to(proj_dtype)) # (batch_size, sequence_length, dim) # L2 normalization embeddings = embeddings / embeddings.norm(dim=-1, keepdim=True) # (batch_size, sequence_length, dim) diff --git a/src/transformers/models/colqwen2/modeling_colqwen2.py b/src/transformers/models/colqwen2/modeling_colqwen2.py index d448962f4e97..fc0f585531ae 100644 --- a/src/transformers/models/colqwen2/modeling_colqwen2.py +++ b/src/transformers/models/colqwen2/modeling_colqwen2.py @@ -143,9 +143,6 @@ def forward( image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): The temporal, height and width of feature shape of each image in LLM. """ - if pixel_values is not None: - pixel_values = pixel_values.to(dtype=self.dtype) # (batch_size, max_num_patches, pixel_values) - # Handle the custom "pixel_values" input obtained with `ColQwen2Processor` through unpadding if pixel_values is not None and image_grid_thw is not None: # NOTE: image_grid_thw: (batch_size, 3) where image_grid_thw[i] = (num_patches_h, num_patches_w, temporal_patch_size) @@ -182,9 +179,6 @@ def forward( image_embeds = image_embeds.to(inputs_embeds.device, inputs_embeds.dtype) inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds) - if attention_mask is not None: - attention_mask = attention_mask.to(inputs_embeds.device) - vlm_output = self.vlm.model( input_ids=None, position_ids=position_ids, @@ -201,7 +195,8 @@ def forward( vlm_hidden_states = vlm_output.hidden_states if output_hidden_states else None last_hidden_states = vlm_output[0] # (batch_size, sequence_length, hidden_size) - embeddings = self.embedding_proj_layer(last_hidden_states) # (batch_size, sequence_length, dim) + proj_dtype = self.embedding_proj_layer.weight.dtype + embeddings = self.embedding_proj_layer(last_hidden_states.to(proj_dtype)) # (batch_size, sequence_length, dim) # L2 normalization embeddings = embeddings / embeddings.norm(dim=-1, keepdim=True) # (batch_size, sequence_length, dim) diff --git a/src/transformers/models/colqwen2/modular_colqwen2.py b/src/transformers/models/colqwen2/modular_colqwen2.py index 72469fef7a21..a4684d670d17 100644 --- a/src/transformers/models/colqwen2/modular_colqwen2.py +++ b/src/transformers/models/colqwen2/modular_colqwen2.py @@ -336,9 +336,6 @@ def forward( image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): The temporal, height and width of feature shape of each image in LLM. """ - if pixel_values is not None: - pixel_values = pixel_values.to(dtype=self.dtype) # (batch_size, max_num_patches, pixel_values) - # Handle the custom "pixel_values" input obtained with `ColQwen2Processor` through unpadding if pixel_values is not None and image_grid_thw is not None: # NOTE: image_grid_thw: (batch_size, 3) where image_grid_thw[i] = (num_patches_h, num_patches_w, temporal_patch_size) @@ -375,9 +372,6 @@ def forward( image_embeds = image_embeds.to(inputs_embeds.device, inputs_embeds.dtype) inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds) - if attention_mask is not None: - attention_mask = attention_mask.to(inputs_embeds.device) - vlm_output = self.vlm.model( input_ids=None, position_ids=position_ids, @@ -394,7 +388,8 @@ def forward( vlm_hidden_states = vlm_output.hidden_states if output_hidden_states else None last_hidden_states = vlm_output[0] # (batch_size, sequence_length, hidden_size) - embeddings = self.embedding_proj_layer(last_hidden_states) # (batch_size, sequence_length, dim) + proj_dtype = self.embedding_proj_layer.weight.dtype + embeddings = self.embedding_proj_layer(last_hidden_states.to(proj_dtype)) # (batch_size, sequence_length, dim) # L2 normalization embeddings = embeddings / embeddings.norm(dim=-1, keepdim=True) # (batch_size, sequence_length, dim) diff --git a/src/transformers/models/gemma3/modular_gemma3.py b/src/transformers/models/gemma3/modular_gemma3.py index f0658f9825f8..c7db46bf7574 100644 --- a/src/transformers/models/gemma3/modular_gemma3.py +++ b/src/transformers/models/gemma3/modular_gemma3.py @@ -756,6 +756,10 @@ class Gemma3Model(PaliGemmaModel): # we are filtering the logits/labels so we shouldn't divide the loss based on num_items_in_batch accepts_loss_kwargs = False + def __init__(self, config: Gemma3Config): + super().__init__(config) + del self.text_config_dtype + def get_image_features(self, pixel_values: torch.Tensor) -> torch.Tensor: """ Projects the last hidden state from the vision model into language model space. diff --git a/src/transformers/models/gemma3n/modular_gemma3n.py b/src/transformers/models/gemma3n/modular_gemma3n.py index 0264d77c02d5..48de2bb27f7f 100644 --- a/src/transformers/models/gemma3n/modular_gemma3n.py +++ b/src/transformers/models/gemma3n/modular_gemma3n.py @@ -2241,6 +2241,7 @@ class Gemma3nModel(PaliGemmaModel): def __init__(self, config: Gemma3nConfig): super().__init__(config) del self.multi_modal_projector # Replaced by Gemma3nVisionEmbedder + del self.text_config_dtype self.vocab_size_per_layer_input = config.text_config.vocab_size_per_layer_input self.audio_tower = AutoModel.from_config(config.audio_config) self.embed_vision = Gemma3nMultimodalEmbedder(config.vision_config, config.text_config) diff --git a/src/transformers/models/paligemma/modeling_paligemma.py b/src/transformers/models/paligemma/modeling_paligemma.py index 5600af24344f..a165bc22a0de 100644 --- a/src/transformers/models/paligemma/modeling_paligemma.py +++ b/src/transformers/models/paligemma/modeling_paligemma.py @@ -143,6 +143,7 @@ def __init__(self, config: PaliGemmaConfig): self.language_model = language_model self.pad_token_id = self.config.pad_token_id if self.config.pad_token_id is not None else -1 + self.text_config_dtype = self.config.get_text_config().dtype or self.dtype self.post_init() # Copied from transformers.models.llava.modeling_llava.LlavaModel.get_input_embeddings with Llava->PaliGemma @@ -174,7 +175,7 @@ def _update_causal_mask( return None is_training = is_training if is_training is not None else self.training using_static_cache = isinstance(past_key_values, StaticCache) - min_dtype = torch.finfo(self.dtype).min + min_dtype = torch.finfo(self.text_config_dtype).min if input_tensor is None: input_tensor = attention_mask @@ -193,7 +194,10 @@ def _update_causal_mask( return attention_mask causal_mask = torch.full( - (sequence_length, target_length), fill_value=min_dtype, dtype=self.dtype, device=cache_position.device + (sequence_length, target_length), + fill_value=min_dtype, + dtype=self.text_config_dtype, + device=cache_position.device, ) # Causal diagonal mask only if training, otherwise attend to the whole prefix. Training-specific attn for prefix is handled below if sequence_length != 1: From cf7356bc7f21d1f90bd7445af3b151f9461fb22a Mon Sep 17 00:00:00 2001 From: Aritra Roy Gosthipaty Date: Wed, 17 Sep 2025 00:01:28 +0530 Subject: [PATCH 075/204] [Docs] Adding documentation of MXFP4 Quantization (#40885) * adding mxfp4 quantization docs * review suggestions * Apply suggestions from code review Co-authored-by: vb Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --------- Co-authored-by: vb Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --- docs/source/en/_toctree.yml | 2 + docs/source/en/quantization/mxfp4.md | 80 ++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 docs/source/en/quantization/mxfp4.md diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index b496fcb4e4b9..4ddfa2ed167d 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -199,6 +199,8 @@ title: HIGGS - local: quantization/hqq title: HQQ + - local: quantization/mxfp4 + title: MXFP4 - local: quantization/optimum title: Optimum - local: quantization/quanto diff --git a/docs/source/en/quantization/mxfp4.md b/docs/source/en/quantization/mxfp4.md new file mode 100644 index 000000000000..a2b9f7634c8d --- /dev/null +++ b/docs/source/en/quantization/mxfp4.md @@ -0,0 +1,80 @@ + + +# MXFP4 + +Note: MXFP4 quantisation currently only works for OpenAI GPT-OSS 120b and 20b. + +MXFP4 is a 4-bit floating point format that dramatically reduces the memory requirements of large models. Large models (GPT-OSS-120B) can fit on a single 80GB GPU and smaller models (GPT-OSS-20B) only require 16GB of memory. It uses blockwise scaling to preserve it's range and accuracy, which typically becomes degraded at lower precisions. + +To use MXPF4, make sure your hardware meets the following requirements. + +- Install Accelerate, kernels, and Triton ≥ 3.4. Only manually install Triton ≥ 3.4 if you're using PyTorch 2.7 because it is already supported in PyTorch 2.8. +- NVIDIA GPU Compute Capability ≥ 7.5 which includes Tesla GPUs and newer. Use [get_device_capability](https://docs.pytorch.org/docs/stable/generated/torch.cuda.get_device_capability.html) to check Compute Capability. + + +```python +from torch import cuda +cuda.get_device_capability() + +# (7, 5) +``` + +Check a model's quantization config as shown below to see if it supports MXFP4. If `'quant_method': 'mxfp4'`, then the model automatically uses MXFP4. + +```py +from transformers import GptOssConfig + +model_id = "openai/gpt-oss-120b" +cfg = GptOssConfig.from_pretrained(model_id) +print(cfg.quantization_config) + +# Example output: +# { +# 'modules_to_not_convert': [ +# 'model.layers.*.self_attn', +# 'model.layers.*.mlp.router', +# 'model.embed_tokens', +# 'lm_head' +# ], +# 'quant_method': 'mxfp4' +# } +``` + + +## MXFP4 kernels + +Transformers automatically pulls the MXFP4-aware Triton kernels from the community repository when you load a model that needs them. The kernels are stored in your local cache and used during the forward pass. + +MXFP4 kernels are used by default, if available and supported, and does not require any code changes. + +You can use [hf cache scan](https://huggingface.co/docs/huggingface_hub/en/guides/manage-cache#scan-your-cache) to verify the kernels are downloaded. + +```shell +hf cache scan +``` + + +```shell +REPO ID REPO TYPE SIZE ON DISK +-------------------------------- --------- ------------ +kernels-community/triton_kernels model 536.2K +openai/gpt-oss-20b model 13.8G +``` + +## Resources + +Learn more about MXFP4 quantization and how blockwise scaling works in this [blog post](https://huggingface.co/blog/faster-transformers#mxfp4-quantization). From 053228af8c9237cdd626a14f1c77e78b548958c4 Mon Sep 17 00:00:00 2001 From: Raushan Turganbay Date: Wed, 17 Sep 2025 09:46:49 +0200 Subject: [PATCH 076/204] Processor load with multi-processing (#40786) push --- src/transformers/feature_extraction_utils.py | 37 ++++++++++++-------- src/transformers/image_processing_base.py | 37 ++++++++++++-------- src/transformers/video_processing_utils.py | 37 ++++++++++++-------- 3 files changed, 66 insertions(+), 45 deletions(-) diff --git a/src/transformers/feature_extraction_utils.py b/src/transformers/feature_extraction_utils.py index b5d9e8f72e0a..a9ff39b0cc19 100644 --- a/src/transformers/feature_extraction_utils.py +++ b/src/transformers/feature_extraction_utils.py @@ -44,7 +44,7 @@ logging, requires_backends, ) -from .utils.hub import cached_files +from .utils.hub import cached_file if TYPE_CHECKING: @@ -506,20 +506,27 @@ def get_feature_extractor_dict( feature_extractor_file = FEATURE_EXTRACTOR_NAME try: # Load from local folder or from cache or download from model Hub and cache - resolved_feature_extractor_files = cached_files( - pretrained_model_name_or_path, - filenames=[feature_extractor_file, PROCESSOR_NAME], - cache_dir=cache_dir, - force_download=force_download, - proxies=proxies, - resume_download=resume_download, - local_files_only=local_files_only, - subfolder=subfolder, - token=token, - user_agent=user_agent, - revision=revision, - _raise_exceptions_for_missing_entries=False, - ) + resolved_feature_extractor_files = [ + resolved_file + for filename in [feature_extractor_file, PROCESSOR_NAME] + if ( + resolved_file := cached_file( + pretrained_model_name_or_path, + filename=filename, + cache_dir=cache_dir, + force_download=force_download, + proxies=proxies, + resume_download=resume_download, + local_files_only=local_files_only, + subfolder=subfolder, + token=token, + user_agent=user_agent, + revision=revision, + _raise_exceptions_for_missing_entries=False, + ) + ) + is not None + ] resolved_feature_extractor_file = resolved_feature_extractor_files[0] except OSError: # Raise any environment error raise by `cached_file`. It will have a helpful error message adapted to diff --git a/src/transformers/image_processing_base.py b/src/transformers/image_processing_base.py index 4f84c29a9939..dfe94ffd0df7 100644 --- a/src/transformers/image_processing_base.py +++ b/src/transformers/image_processing_base.py @@ -34,7 +34,7 @@ is_remote_url, logging, ) -from .utils.hub import cached_files +from .utils.hub import cached_file ImageProcessorType = TypeVar("ImageProcessorType", bound="ImageProcessingMixin") @@ -330,20 +330,27 @@ def get_image_processor_dict( image_processor_file = image_processor_filename try: # Load from local folder or from cache or download from model Hub and cache - resolved_image_processor_files = cached_files( - pretrained_model_name_or_path, - filenames=[image_processor_file, PROCESSOR_NAME], - cache_dir=cache_dir, - force_download=force_download, - proxies=proxies, - resume_download=resume_download, - local_files_only=local_files_only, - token=token, - user_agent=user_agent, - revision=revision, - subfolder=subfolder, - _raise_exceptions_for_missing_entries=False, - ) + resolved_image_processor_files = [ + resolved_file + for filename in [image_processor_file, PROCESSOR_NAME] + if ( + resolved_file := cached_file( + pretrained_model_name_or_path, + filename=filename, + cache_dir=cache_dir, + force_download=force_download, + proxies=proxies, + resume_download=resume_download, + local_files_only=local_files_only, + token=token, + user_agent=user_agent, + revision=revision, + subfolder=subfolder, + _raise_exceptions_for_missing_entries=False, + ) + ) + is not None + ] resolved_image_processor_file = resolved_image_processor_files[0] except OSError: # Raise any environment error raise by `cached_file`. It will have a helpful error message adapted to diff --git a/src/transformers/video_processing_utils.py b/src/transformers/video_processing_utils.py index 562a5de65718..43d9e2bfd26e 100644 --- a/src/transformers/video_processing_utils.py +++ b/src/transformers/video_processing_utils.py @@ -50,7 +50,7 @@ is_torchvision_v2_available, logging, ) -from .utils.hub import cached_files +from .utils.hub import cached_file from .utils.import_utils import requires from .video_utils import ( VideoInput, @@ -683,20 +683,27 @@ def get_video_processor_dict( try: # Try to load with a new config name first and if not successful try with the old file name # NOTE: we will gradually change to saving all processor configs as nested dict in PROCESSOR_NAME - resolved_video_processor_files = cached_files( - pretrained_model_name_or_path, - filenames=[VIDEO_PROCESSOR_NAME, IMAGE_PROCESSOR_NAME, PROCESSOR_NAME], - cache_dir=cache_dir, - force_download=force_download, - proxies=proxies, - resume_download=resume_download, - local_files_only=local_files_only, - token=token, - user_agent=user_agent, - revision=revision, - subfolder=subfolder, - _raise_exceptions_for_missing_entries=False, - ) + resolved_video_processor_files = [ + resolved_file + for filename in [VIDEO_PROCESSOR_NAME, IMAGE_PROCESSOR_NAME, PROCESSOR_NAME] + if ( + resolved_file := cached_file( + pretrained_model_name_or_path, + filename=filename, + cache_dir=cache_dir, + force_download=force_download, + proxies=proxies, + resume_download=resume_download, + local_files_only=local_files_only, + token=token, + user_agent=user_agent, + revision=revision, + subfolder=subfolder, + _raise_exceptions_for_missing_entries=False, + ) + ) + is not None + ] resolved_video_processor_file = resolved_video_processor_files[0] except OSError: # Raise any OS error raise by `cached_file`. It will have a helpful error message adapted to From 030af754315bcf3466955e9e374ad8f5af6d5587 Mon Sep 17 00:00:00 2001 From: Yaswanth Gali <82788246+yaswanth19@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:44:13 +0530 Subject: [PATCH 077/204] [Llama4] Remove `image_sizes` arg and deprecate `vision_feature_layer` (#40832) * Remove unused arg * deprecate * revrt one change * get set go * version correction * fix * make style * comment --- .../models/llama4/configuration_llama4.py | 19 ++++++++++++++++--- .../models/llama4/modeling_llama4.py | 14 +------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/transformers/models/llama4/configuration_llama4.py b/src/transformers/models/llama4/configuration_llama4.py index 7ced47cb9436..932f4975dba7 100644 --- a/src/transformers/models/llama4/configuration_llama4.py +++ b/src/transformers/models/llama4/configuration_llama4.py @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import warnings from ...configuration_utils import PretrainedConfig, layer_type_validation from ...utils import logging @@ -56,7 +57,6 @@ class Llama4VisionConfig(PretrainedConfig): The size (resolution) of each patch. norm_eps (`float`, *optional*, defaults to 1e-05): The epsilon used by the layer normalization layers. - vision_feature_layer (``, *optional*, defaults to -1): TODO vision_feature_select_strategy (`int`, *optional*, defaults to `"default"`): TODO initializer_range (`float`, *optional*, defaults to 0.02): The standard deviation of the truncated_normal_initializer for initializing all weight matrices. @@ -93,7 +93,6 @@ def __init__( image_size: int = 448, patch_size: int = 14, norm_eps: float = 1e-5, - vision_feature_layer=-1, vision_feature_select_strategy="default", initializer_range: float = 0.02, pixel_shuffle_ratio=0.5, @@ -122,9 +121,23 @@ def __init__( self.multi_modal_projector_bias = multi_modal_projector_bias self.projector_dropout = projector_dropout self.attention_dropout = attention_dropout - self.vision_feature_layer = vision_feature_layer self.vision_feature_select_strategy = vision_feature_select_strategy self.rope_theta = rope_theta + + self._vision_feature_layer = kwargs.get("vision_feature_layer", -1) + + @property + def vision_feature_layer(self): + warnings.warn( + "The `vision_feature_layer` attribute is deprecated and will be removed in v4.58.0.", + FutureWarning, + ) + return self._vision_feature_layer + + @vision_feature_layer.setter + def vision_feature_layer(self, value): + self._vision_feature_layer = value + super().__init__(**kwargs) diff --git a/src/transformers/models/llama4/modeling_llama4.py b/src/transformers/models/llama4/modeling_llama4.py index 79e6d97ddbe7..17bd9d59372d 100644 --- a/src/transformers/models/llama4/modeling_llama4.py +++ b/src/transformers/models/llama4/modeling_llama4.py @@ -1173,7 +1173,6 @@ def get_decoder(self): def get_image_features( self, pixel_values: torch.FloatTensor, - vision_feature_layer: Union[int, list[int]], vision_feature_select_strategy: str, **kwargs, ): @@ -1183,10 +1182,6 @@ def get_image_features( Args: pixel_values (`torch.FloatTensor]` of shape `(batch_size, channels, height, width)`) The tensors corresponding to the input images. - vision_feature_layer (`Union[int, list[int]]`): - The index of the layer to select the vision feature. If multiple indices are provided, - the vision feature of the corresponding indices will be concatenated to form the - vision features. vision_feature_select_strategy (`str`): The feature selection strategy used to select the vision feature from the vision backbone. Can be one of `"default"` or `"full"` @@ -1224,6 +1219,7 @@ def get_placeholder_mask( return special_image_mask @auto_docstring + @deprecate_kwarg("vision_feature_layer", version="4.58") def forward( self, input_ids: Optional[torch.LongTensor] = None, @@ -1241,7 +1237,6 @@ def forward( return_dict: Optional[bool] = None, cache_position: Optional[torch.LongTensor] = None, logits_to_keep: Union[int, torch.Tensor] = 0, - image_sizes: Optional[torch.Tensor] = None, **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, Llama4CausalLMOutputWithPast]: r""" @@ -1277,11 +1272,6 @@ def forward( output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states ) return_dict = return_dict if return_dict is not None else self.config.use_return_dict - vision_feature_layer = ( - vision_feature_layer - if vision_feature_layer is not None - else self.config.vision_config.vision_feature_layer - ) vision_feature_select_strategy = ( vision_feature_select_strategy if vision_feature_select_strategy is not None @@ -1302,9 +1292,7 @@ def forward( if pixel_values is not None: image_features = self.get_image_features( pixel_values=pixel_values, - vision_feature_layer=vision_feature_layer, vision_feature_select_strategy=vision_feature_select_strategy, - image_sizes=image_sizes, ) vision_flat = image_features.view(-1, image_features.size(-1)) From 3e2e555c3e1856f7f7cf53e0e953ecf7664542c4 Mon Sep 17 00:00:00 2001 From: Akshay Babbar Date: Wed, 17 Sep 2025 14:45:55 +0530 Subject: [PATCH 078/204] Fix #40067: Add dedicated UMT5 support to GGUF loader (config, tokenizer, test) (#40218) * Fix #40067 : add UMT5 support in GGUF loader (config, tokenizer, test) * chore: fix code formatting and linting issues * refactor: move UMT5 GGUF test to quantization directory and clean up comments * chore: trigger CI pipeline * refactor(tests): Move UMT5 Encoder GGUF test to GgufModelTests. This consolidates the new test into the main class for consistency. * Add regression check to UMT5 encoder GGUF test Verify encoder output against reference tensor values with appropriate tolerances for stability. * Update tests/quantization/ggml/test_ggml.py Co-authored-by: Mohamed Mekkouri <93391238+MekkCyber@users.noreply.github.com> * Update tests/quantization/ggml/test_ggml.py remove comments Co-authored-by: Mohamed Mekkouri <93391238+MekkCyber@users.noreply.github.com> --------- Co-authored-by: Mohamed Mekkouri <93391238+MekkCyber@users.noreply.github.com> --- src/transformers/integrations/ggml.py | 14 ++++++ .../modeling_gguf_pytorch_utils.py | 13 ++++-- tests/quantization/ggml/test_ggml.py | 46 ++++++++++++++++++- 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/transformers/integrations/ggml.py b/src/transformers/integrations/ggml.py index a06cec1c8c60..703fd0156365 100644 --- a/src/transformers/integrations/ggml.py +++ b/src/transformers/integrations/ggml.py @@ -250,6 +250,19 @@ "attention.sliding_window": "sliding_window", "vocab_size": "vocab_size", }, + "umt5": { + "context_length": "n_positions", + "block_count": "num_layers", + "feed_forward_length": "d_ff", + "embedding_length": "d_model", + "attention.key_length": "d_kv", + "attention.head_count": "num_heads", + "attention.head_count_kv": "num_key_value_heads", + "attention.layer_norm_epsilon": "layer_norm_epsilon", + "attention.relative_buckets_count": "relative_attention_num_buckets", + "decoder_start_token_id": "decoder_start_token_id", + "vocab_size": "vocab_size", + }, "deci": { "context_length": "max_position_embeddings", "block_count": "num_hidden_layers", @@ -728,6 +741,7 @@ def converted(self) -> Tokenizer: "nemotron": GGUFGPTConverter, "gemma2": GGUFGemmaConverter, "gemma3_text": GGUFGemmaConverter, + "umt5": GGUFT5Converter, "deci": GGUFLlamaConverter, "decilm": GGUFLlamaConverter, } diff --git a/src/transformers/modeling_gguf_pytorch_utils.py b/src/transformers/modeling_gguf_pytorch_utils.py index 7ef2725c10b0..9b90fb82afa2 100644 --- a/src/transformers/modeling_gguf_pytorch_utils.py +++ b/src/transformers/modeling_gguf_pytorch_utils.py @@ -300,6 +300,8 @@ def get_gguf_hf_weights_map( model_type = "qwen3moe" elif model_type == "gemma3_text": model_type = "gemma3" + elif model_type == "umt5": + model_type = "t5" arch = None for key, value in MODEL_ARCH_NAMES.items(): if value == model_type: @@ -386,9 +388,14 @@ def load_gguf_checkpoint(gguf_checkpoint_path, return_tensors=False, model_to_lo # It needs to be developed for supporting legacy t5. elif "t5" in architecture or "t5encoder" in architecture: parsed_parameters["config"]["is_gated_act"] = True - if "t5encoder" in architecture: - parsed_parameters["config"]["architectures"] = ["T5EncoderModel"] - updated_architecture = "t5" + if model_name and "umt5" in model_name[0].lower(): + updated_architecture = "umt5" + if "t5encoder" in architecture: + parsed_parameters["config"]["architectures"] = ["UMT5EncoderModel"] + else: + if "t5encoder" in architecture: + parsed_parameters["config"]["architectures"] = ["T5EncoderModel"] + updated_architecture = "t5" else: updated_architecture = architecture diff --git a/tests/quantization/ggml/test_ggml.py b/tests/quantization/ggml/test_ggml.py index 8be00dfde814..ac6fb30fe606 100644 --- a/tests/quantization/ggml/test_ggml.py +++ b/tests/quantization/ggml/test_ggml.py @@ -16,7 +16,14 @@ from parameterized import parameterized -from transformers import AddedToken, AutoModelForCausalLM, AutoModelForSeq2SeqLM, AutoTokenizer +from transformers import ( + AddedToken, + AutoModelForCausalLM, + AutoModelForSeq2SeqLM, + AutoTokenizer, + UMT5Config, + UMT5EncoderModel, +) from transformers.testing_utils import ( require_gguf, require_read_token, @@ -303,6 +310,7 @@ class GgufModelTests(unittest.TestCase): gemma3_vision_model_id = "unsloth/gemma-3-4b-it-GGUF" qwen3_model_id = "Qwen/Qwen3-0.6B-GGUF" qwen3moe_model_id = "Qwen/Qwen3-30B-A3B-GGUF" + umt5_encoder_model_id = "city96/umt5-xxl-encoder-gguf" q4_0_phi3_model_id = "Phi-3-mini-4k-instruct-q4.gguf" q4_0_mistral_model_id = "mistral-7b-instruct-v0.2.Q4_0.gguf" @@ -341,6 +349,7 @@ class GgufModelTests(unittest.TestCase): fp16_deci_model_id = "decilm-7b-uniform-gqa-f16.gguf" q8_0_qwen3_model_id = "Qwen3-0.6B-Q8_0.gguf" q4_k_m_qwen3moe_model_id = "Qwen3-30B-A3B-Q4_K_M.gguf" + q8_0_umt5_encoder_model_id = "umt5-xxl-encoder-Q8_0.gguf" example_text = "Hello" @@ -1072,3 +1081,38 @@ def test_qwen3moe_q4_k_m(self): EXPECTED_TEXT = "Hello, I am a 20 year old male" self.assertEqual(tokenizer.decode(out[0], skip_special_tokens=True), EXPECTED_TEXT) + + def test_umt5_encoder_q8_0(self): + """ + Verifies that a UMT5 encoder loads directly from a GGUF file using + UMT5EncoderModel.from_pretrained(...), and the config is correctly UMT5. + """ + model = UMT5EncoderModel.from_pretrained( + self.umt5_encoder_model_id, + gguf_file=self.q8_0_umt5_encoder_model_id, + dtype=torch.float16, + device_map="auto", + ) + model.eval() + + self.assertIsInstance(model, UMT5EncoderModel) + self.assertIsInstance(model.config, UMT5Config) + self.assertEqual(model.config.model_type, "umt5") + self.assertIn("UMT5EncoderModel", getattr(model.config, "architectures", [])) + + input_ids = torch.tensor([[1, 2, 3, 4]], dtype=torch.long).to(torch_device) + with torch.no_grad(): + outputs = model(input_ids=input_ids) + + self.assertTrue(hasattr(outputs, "last_hidden_state")) + self.assertEqual(outputs.last_hidden_state.dim(), 3) # (batch, seq_len, hidden) + + EXPECTED_OUTPUT = torch.tensor( + [ + [-0.0010, -0.0145, 0.0133], + [-0.0006, 0.1814, 0.1132], + [0.0005, 0.0083, -0.0285], + ] + ).to(torch_device) + + torch.testing.assert_close(outputs.last_hidden_state[0, :3, :3], EXPECTED_OUTPUT, rtol=6e-3, atol=4e-4) From 1575c0328890c134360947edf0fb58fc54f507f4 Mon Sep 17 00:00:00 2001 From: liangel-02 Date: Wed, 17 Sep 2025 02:20:50 -0700 Subject: [PATCH 079/204] [torchao safetensors] renaming get_state_dict function (#40774) renaming get_state_dict function Co-authored-by: Mohamed Mekkouri <93391238+MekkCyber@users.noreply.github.com> --- src/transformers/modeling_utils.py | 7 +++++-- src/transformers/quantizers/base.py | 6 +++--- src/transformers/quantizers/quantizer_mxfp4.py | 5 +++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index a11f7743ed8e..33ecceacb17a 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -4015,8 +4015,11 @@ def save_pretrained( repo_id = self._create_repo(repo_id, **kwargs) files_timestamps = self._get_files_timestamps(save_directory) + metadata = {} if hf_quantizer is not None: - state_dict = hf_quantizer.get_state_dict(self) + state_dict, metadata = hf_quantizer.get_state_dict_and_metadata(self, safe_serialization) + metadata["format"] = "pt" + # Only save the model itself if we are using distributed training model_to_save = unwrap_model(self) # save the string version of dtype to the config, e.g. convert torch.float32 => "float32" @@ -4294,7 +4297,7 @@ def save_pretrained( if safe_serialization: # At some point we will need to deal better with save_function (used for TPU and other distributed # joyfulness), but for now this enough. - safe_save_file(shard, os.path.join(save_directory, shard_file), metadata={"format": "pt"}) + safe_save_file(shard, os.path.join(save_directory, shard_file), metadata=metadata) else: save_function(shard, os.path.join(save_directory, shard_file)) diff --git a/src/transformers/quantizers/base.py b/src/transformers/quantizers/base.py index 653953abec0a..323faa9c17e2 100644 --- a/src/transformers/quantizers/base.py +++ b/src/transformers/quantizers/base.py @@ -338,9 +338,9 @@ def is_compileable(self) -> bool: """Flag indicating whether the quantized model can be compiled""" return False - def get_state_dict(self, model): - """Get state dict. Useful when we need to modify a bit the state dict due to quantization""" - return None + def get_state_dict_and_metadata(self, model, safe_serialization=False): + """Get state dict and metadata. Useful when we need to modify a bit the state dict due to quantization""" + return None, {} @abstractmethod def _process_model_before_weight_loading(self, model, **kwargs): ... diff --git a/src/transformers/quantizers/quantizer_mxfp4.py b/src/transformers/quantizers/quantizer_mxfp4.py index b9076007d38d..d0d370a11df6 100644 --- a/src/transformers/quantizers/quantizer_mxfp4.py +++ b/src/transformers/quantizers/quantizer_mxfp4.py @@ -379,7 +379,7 @@ def update_param_name(self, param_name: str) -> str: return param_name.replace("down_proj", "down_proj_blocks") return param_name - def get_state_dict(self, model): + def get_state_dict_and_metadata(self, model): from ..integrations import Mxfp4GptOssExperts state_dict = model.state_dict() @@ -411,7 +411,8 @@ def get_state_dict(self, model): ).transpose(-1, -2) ) - return state_dict + metadata = {} + return state_dict, metadata def is_serializable(self, safe_serialization=None): return True From 901e5d77ff39a8f3cdfbada27131954e7deab84f Mon Sep 17 00:00:00 2001 From: Mohamed Mekkouri <93391238+MekkCyber@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:36:09 +0200 Subject: [PATCH 080/204] Adding activation kernels (#40890) * first commit * add mode * revert modeling * add compile * rm print --- src/transformers/activations.py | 4 +++ src/transformers/integrations/hub_kernels.py | 27 ++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/transformers/activations.py b/src/transformers/activations.py index e9054f609a77..8bfd517add9f 100644 --- a/src/transformers/activations.py +++ b/src/transformers/activations.py @@ -18,6 +18,7 @@ import torch from torch import Tensor, nn +from .integrations.hub_kernels import use_kernel_forward_from_hub from .utils import logging from .utils.import_utils import is_torchdynamo_compiling @@ -38,6 +39,7 @@ def forward(self, input: Tensor) -> Tensor: return nn.functional.gelu(input, approximate="tanh") +@use_kernel_forward_from_hub("NewGELU") class NewGELUActivation(nn.Module): """ Implementation of the GELU activation function currently in Google BERT repo (identical to OpenAI GPT). Also see @@ -70,6 +72,7 @@ def forward(self, input: Tensor) -> Tensor: return self.act(input) +@use_kernel_forward_from_hub("FastGELU") class FastGELUActivation(nn.Module): """ Applies GELU approximation that is slower than QuickGELU but more accurate. See: https://github.com/hendrycks/GELUs @@ -79,6 +82,7 @@ def forward(self, input: Tensor) -> Tensor: return 0.5 * input * (1.0 + torch.tanh(input * 0.7978845608 * (1.0 + 0.044715 * input * input))) +@use_kernel_forward_from_hub("QuickGELU") class QuickGELUActivation(nn.Module): """ Applies GELU approximation that is fast but somewhat inaccurate. See: https://github.com/hendrycks/GELUs diff --git a/src/transformers/integrations/hub_kernels.py b/src/transformers/integrations/hub_kernels.py index 248b6b1b0b9d..5be21e2f9a51 100644 --- a/src/transformers/integrations/hub_kernels.py +++ b/src/transformers/integrations/hub_kernels.py @@ -84,6 +84,33 @@ ) }, }, + "FastGELU": { + "cuda": { + Mode.INFERENCE | Mode.TORCH_COMPILE: LayerRepository( + repo_id="kernels-community/activation", + layer_name="FastGELU", + version=">=0.0.4,<0.1.0", + ) + } + }, + "QuickGELU": { + "cuda": { + Mode.INFERENCE | Mode.TORCH_COMPILE: LayerRepository( + repo_id="kernels-community/activation", + layer_name="QuickGELU", + version=">=0.0.4,<0.1.0", + ) + } + }, + "NewGELU": { + "cuda": { + Mode.INFERENCE | Mode.TORCH_COMPILE: LayerRepository( + repo_id="kernels-community/activation", + layer_name="NewGELU", + version=">=0.0.4,<0.1.0", + ) + } + }, } register_kernel_mapping(_KERNEL_MAPPING) From 8b942de6911fb94ea874b203b2ddf7d7e55cc16a Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:42:13 +0200 Subject: [PATCH 081/204] Minor fix for #40727 (#40929) * fix * fix --------- Co-authored-by: ydshieh --- src/transformers/testing_utils.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/transformers/testing_utils.py b/src/transformers/testing_utils.py index 51fa682c7be4..d8ec62124556 100644 --- a/src/transformers/testing_utils.py +++ b/src/transformers/testing_utils.py @@ -3466,15 +3466,21 @@ def _get_test_info(): if test_frame is not None: line_number = test_frame.lineno - # most inner (recent) to most outer () frames + # The frame of `patched` being called (the one and the only one calling `_get_test_info`) + # This is used to get the original method being patched in order to get the context. + frame_of_patched_obj = None + captured_frames = [] to_capture = False - # up to the test method being called + # From the most outer (i.e. python's `runpy.py`) frame to most inner frame (i.e. the frame of this method) + # Between `the test method being called` and `before entering `patched``. for frame in reversed(stack_from_inspect): if test_file in str(frame).replace(r"\\", "/"): if "self" in frame.frame.f_locals and test_name == frame.frame.f_locals["self"]._testMethodName: to_capture = True - elif "patched" in frame.frame.f_code.co_name: + # TODO: check simply with the name is not robust. + elif "patched" == frame.frame.f_code.co_name: + frame_of_patched_obj = frame to_capture = False break if to_capture: @@ -3486,11 +3492,17 @@ def _get_test_info(): tb_next = tb test_traceback = tb + origin_method_being_patched = frame_of_patched_obj.frame.f_locals["orig_method"] + + # An iterable of type `traceback.StackSummary` with each element of type `FrameSummary` stack = traceback.extract_stack() + # The frame which calls `the original method being patched` + caller_frame = None + # From the most inner (i.e. recent) frame to the most outer frame + for frame in reversed(stack): + if origin_method_being_patched.__name__ in frame.line: + caller_frame = frame - # The frame that calls this patched method (it may not be the test method) - # -1: `_get_test_info`; -2: `patched_xxx`; -3: the caller to `patched_xxx` - caller_frame = stack[-3] caller_path = os.path.relpath(caller_frame.filename) caller_lineno = caller_frame.lineno From 1935c2280dce57e6e53b117aa57c270fa0a14538 Mon Sep 17 00:00:00 2001 From: Duc-Viet Hoang Date: Wed, 17 Sep 2025 18:49:56 +0700 Subject: [PATCH 082/204] Add support for Florence-2 training (#40914) * Support training florence2 * update doc and testing model to florence-community * fix florence-2 test, use head dim 16 instead of 8 for fa2 * skip test_sdpa_can_dispatch_on_flash * Apply style fixes --------- Co-authored-by: github-actions[bot] --- docs/source/en/model_doc/florence2.md | 2 +- .../models/florence2/modeling_florence2.py | 29 ++++++++++++++++++ .../models/florence2/modular_florence2.py | 11 ++++++- .../florence2/test_modeling_florence2.py | 30 +++++++++++-------- .../florence2/test_processing_florence2.py | 4 +-- 5 files changed, 59 insertions(+), 17 deletions(-) diff --git a/docs/source/en/model_doc/florence2.md b/docs/source/en/model_doc/florence2.md index 94ff4ae6d732..148653202067 100644 --- a/docs/source/en/model_doc/florence2.md +++ b/docs/source/en/model_doc/florence2.md @@ -44,7 +44,7 @@ from transformers import pipeline pipeline = pipeline( "image-text-to-text", - model="ducviet00/Florence-2-base-hf", + model="florence-community/Florence-2-base", device=0, dtype=torch.bfloat16 ) diff --git a/src/transformers/models/florence2/modeling_florence2.py b/src/transformers/models/florence2/modeling_florence2.py index afa05e8e3c91..0c1cf26fa4bc 100644 --- a/src/transformers/models/florence2/modeling_florence2.py +++ b/src/transformers/models/florence2/modeling_florence2.py @@ -33,6 +33,7 @@ auto_docstring, can_return_tuple, is_torch_available, + logging, ) from ..auto import AutoModel from .configuration_florence2 import Florence2Config, Florence2VisionConfig @@ -44,6 +45,9 @@ import torch.nn.functional as F +logger = logging.get_logger(__name__) + + def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = False) -> torch.Tensor: """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). @@ -793,6 +797,22 @@ def get_encoder(self): return self.language_model.get_encoder() +def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start_token_id: int): + """ + Shift input ids one token to the right. + """ + shifted_input_ids = input_ids.new_zeros(input_ids.shape) + shifted_input_ids[:, 1:] = input_ids[:, :-1].clone() + shifted_input_ids[:, 0] = decoder_start_token_id + + if pad_token_id is None: + raise ValueError("self.model.config.pad_token_id has to be defined.") + # replace possible -100 values in labels by `pad_token_id` + shifted_input_ids.masked_fill_(shifted_input_ids == -100, pad_token_id) + + return shifted_input_ids + + @auto_docstring( custom_intro=""" Florence-2 is a vision model for captioning, detection, and segmentation. @@ -901,6 +921,15 @@ def forward( ) return_dict = return_dict if return_dict is not None else self.config.use_return_dict + if labels is not None: + if use_cache: + logger.warning("The `use_cache` argument is changed to `False` since `labels` is provided.") + use_cache = False + if decoder_input_ids is None and decoder_inputs_embeds is None: + decoder_input_ids = shift_tokens_right( + labels, self.config.text_config.pad_token_id, self.config.text_config.decoder_start_token_id + ) + outputs = self.model( input_ids=input_ids, pixel_values=pixel_values, diff --git a/src/transformers/models/florence2/modular_florence2.py b/src/transformers/models/florence2/modular_florence2.py index 12bf00ca253d..d82d9ac5255e 100644 --- a/src/transformers/models/florence2/modular_florence2.py +++ b/src/transformers/models/florence2/modular_florence2.py @@ -36,7 +36,7 @@ logging, ) from ..auto import CONFIG_MAPPING, AutoConfig -from ..bart.modeling_bart import eager_attention_forward +from ..bart.modeling_bart import eager_attention_forward, shift_tokens_right from ..beit.modeling_beit import BeitDropPath from ..llama4.modeling_llama4 import Llama4VisionMLP from ..llava.modeling_llava import LlavaForConditionalGeneration, LlavaModel, LlavaPreTrainedModel @@ -1710,6 +1710,15 @@ def forward( ) return_dict = return_dict if return_dict is not None else self.config.use_return_dict + if labels is not None: + if use_cache: + logger.warning("The `use_cache` argument is changed to `False` since `labels` is provided.") + use_cache = False + if decoder_input_ids is None and decoder_inputs_embeds is None: + decoder_input_ids = shift_tokens_right( + labels, self.config.text_config.pad_token_id, self.config.text_config.decoder_start_token_id + ) + outputs = self.model( input_ids=input_ids, pixel_values=pixel_values, diff --git a/tests/models/florence2/test_modeling_florence2.py b/tests/models/florence2/test_modeling_florence2.py index d53b527aedae..e191bf1032d6 100644 --- a/tests/models/florence2/test_modeling_florence2.py +++ b/tests/models/florence2/test_modeling_florence2.py @@ -58,11 +58,11 @@ def __init__( vocab_size=99, max_position_embeddings=64, encoder_layers=1, - encoder_ffn_dim=8, + encoder_ffn_dim=16, decoder_layers=1, - decoder_ffn_dim=8, + decoder_ffn_dim=16, num_attention_heads=1, - d_model=8, + d_model=16, activation_function="gelu", dropout=0.1, eos_token_id=2, @@ -74,12 +74,12 @@ def __init__( patch_stride=[4], patch_padding=[3], patch_prenorm=[False], - embed_dim=[8], + embed_dim=[16], num_heads=[1], num_groups=[1], window_size=12, drop_path_rate=0.1, - projection_dim=8, + projection_dim=16, ): self.parent = parent self.batch_size = batch_size @@ -215,6 +215,10 @@ def create_and_check_florence2_model_fp16_forward(self, config, input_ids, pixel def test_load_save_without_tied_weights(self): pass + @unittest.skip(reason="SDPA can't dispatch on flash due to unsupported qkv stride") + def test_sdpa_can_dispatch_on_flash(self): + pass + @require_torch class Florence2ForConditionalGenerationModelTest(ModelTesterMixin, GenerationTesterMixin, unittest.TestCase): @@ -271,7 +275,7 @@ def tearDown(self): cleanup(torch_device, gc_collect=True) def test_base_model_inference_eager(self): - model_name = "ducviet00/Florence-2-base-hf" + model_name = "florence-community/Florence-2-base" processor = AutoProcessor.from_pretrained(model_name) model = Florence2ForConditionalGeneration.from_pretrained(model_name, attn_implementation="eager").to( torch_device @@ -295,7 +299,7 @@ def test_base_model_inference_eager(self): self.assertEqual(generated_text, EXPECTED_GENERATED_TEXT) def test_base_model_batching_inference_eager(self): - model_name = "ducviet00/Florence-2-base-hf" + model_name = "florence-community/Florence-2-base" processor = AutoProcessor.from_pretrained(model_name) model = Florence2ForConditionalGeneration.from_pretrained(model_name, attn_implementation="eager").to( torch_device @@ -343,7 +347,7 @@ def test_base_model_batching_inference_eager(self): self.assertEqual(parsed_answer_1, EXPECTED_PARSED_ANSWER_1) def test_base_model_inference_sdpa(self): - model_name = "ducviet00/Florence-2-base-hf" + model_name = "florence-community/Florence-2-base" processor = AutoProcessor.from_pretrained(model_name) model = Florence2ForConditionalGeneration.from_pretrained(model_name, attn_implementation="sdpa").to( torch_device @@ -375,7 +379,7 @@ def test_base_model_inference_sdpa(self): self.assertEqual(parsed_answer, EXPECTED_PARSED_ANSWER) def test_base_model_batching_inference_sdpa(self): - model_name = "ducviet00/Florence-2-base-hf" + model_name = "florence-community/Florence-2-base" processor = AutoProcessor.from_pretrained(model_name) model = Florence2ForConditionalGeneration.from_pretrained(model_name, attn_implementation="sdpa").to( torch_device @@ -415,7 +419,7 @@ def test_base_model_batching_inference_sdpa(self): self.assertEqual(parsed_answer, EXPECTED_PARSED_ANSWER) def test_large_model_inference_eager(self): - model_name = "ducviet00/Florence-2-large-hf" + model_name = "florence-community/Florence-2-large" processor = AutoProcessor.from_pretrained(model_name) model = Florence2ForConditionalGeneration.from_pretrained(model_name, attn_implementation="eager").to( torch_device @@ -439,7 +443,7 @@ def test_large_model_inference_eager(self): self.assertEqual(generated_text, EXPECTED_GENERATED_TEXT) def test_large_model_batching_inference_eager(self): - model_name = "ducviet00/Florence-2-large-hf" + model_name = "florence-community/Florence-2-large" processor = AutoProcessor.from_pretrained(model_name) model = Florence2ForConditionalGeneration.from_pretrained(model_name, attn_implementation="eager").to( torch_device @@ -485,7 +489,7 @@ def test_large_model_batching_inference_eager(self): self.assertEqual(parsed_answer_1, EXPECTED_PARSED_ANSWER_1) def test_large_model_inference_sdpa(self): - model_name = "ducviet00/Florence-2-large-hf" + model_name = "florence-community/Florence-2-large" processor = AutoProcessor.from_pretrained(model_name) model = Florence2ForConditionalGeneration.from_pretrained(model_name, attn_implementation="sdpa").to( torch_device @@ -517,7 +521,7 @@ def test_large_model_inference_sdpa(self): self.assertEqual(parsed_answer, EXPECTED_PARSED_ANSWER) def test_large_model_batching_inference_sdpa(self): - model_name = "ducviet00/Florence-2-large-hf" + model_name = "florence-community/Florence-2-large" processor = AutoProcessor.from_pretrained(model_name) model = Florence2ForConditionalGeneration.from_pretrained(model_name, attn_implementation="sdpa").to( torch_device diff --git a/tests/models/florence2/test_processing_florence2.py b/tests/models/florence2/test_processing_florence2.py index 2f9a72c9c7e7..351e4768e53d 100644 --- a/tests/models/florence2/test_processing_florence2.py +++ b/tests/models/florence2/test_processing_florence2.py @@ -38,9 +38,9 @@ class Florence2ProcessorTest(ProcessorTesterMixin, unittest.TestCase): def setUpClass(cls): cls.tmpdirname = tempfile.mkdtemp() - image_processor = CLIPImageProcessor.from_pretrained("ducviet00/Florence-2-base-hf") + image_processor = CLIPImageProcessor.from_pretrained("florence-community/Florence-2-base") image_processor.image_seq_length = 0 - tokenizer = BartTokenizerFast.from_pretrained("ducviet00/Florence-2-base-hf") + tokenizer = BartTokenizerFast.from_pretrained("florence-community/Florence-2-base") tokenizer.image_token = "" tokenizer.image_token_id = tokenizer.encode(tokenizer.image_token, add_special_tokens=False)[0] tokenizer.extra_special_tokens = {"image_token": ""} From 2e287d17a29e1fbc359ea035ef44b0ee43605f77 Mon Sep 17 00:00:00 2001 From: Pablo Montalvo <39954772+molbap@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:48:10 +0200 Subject: [PATCH 083/204] Add LongCat-Flash (#40730) * working draft for LongCat * BC changes to deepseek_v3 for modular * format * various modularities * better tp plan * better init * minor changes * make modular better * clean up patterns * Revert a couple of modular commits, because we won't convert in the end * make things explicit. * draft test * toctree, tests and imports * drop * woops * make better things * update test * update * fixes * style and CI * convert stuff * up * ah, yes, that * enable gen tests * fix cache shape in test (sum of 2 things) * fix tests * comments * re-Identitise * minimize changes * better defaults * modular betterment * fix configuration, add documentation * fix init * add integration tests * add info * simplify * update slow tests * fix * style * some additional long tests * cpu-only long test * fix last tests? * urg * cleaner tests why not * fix * improve slow tests, no skip * style * don't upcast * one skip * finally fix parallelism --- docs/source/en/_toctree.yml | 2 + docs/source/en/model_doc/longcat_flash.md | 128 ++++ src/transformers/models/__init__.py | 1 + .../models/auto/configuration_auto.py | 2 + src/transformers/models/auto/modeling_auto.py | 2 + .../models/longcat_flash/__init__.py | 29 + .../configuration_longcat_flash.py | 235 ++++++ .../longcat_flash/modeling_longcat_flash.py | 684 ++++++++++++++++++ .../longcat_flash/modular_longcat_flash.py | 382 ++++++++++ tests/models/longcat_flash/__init__.py | 0 .../test_modeling_longcat_flash.py | 473 ++++++++++++ 11 files changed, 1938 insertions(+) create mode 100644 docs/source/en/model_doc/longcat_flash.md create mode 100644 src/transformers/models/longcat_flash/__init__.py create mode 100644 src/transformers/models/longcat_flash/configuration_longcat_flash.py create mode 100644 src/transformers/models/longcat_flash/modeling_longcat_flash.py create mode 100644 src/transformers/models/longcat_flash/modular_longcat_flash.py create mode 100644 tests/models/longcat_flash/__init__.py create mode 100644 tests/models/longcat_flash/test_modeling_longcat_flash.py diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index 4ddfa2ed167d..65411024d4a3 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -559,6 +559,8 @@ title: Llama2 - local: model_doc/llama3 title: Llama3 + - local: model_doc/longcat_flash + title: LongCatFlash - local: model_doc/longformer title: Longformer - local: model_doc/longt5 diff --git a/docs/source/en/model_doc/longcat_flash.md b/docs/source/en/model_doc/longcat_flash.md new file mode 100644 index 000000000000..b2c2d7a00646 --- /dev/null +++ b/docs/source/en/model_doc/longcat_flash.md @@ -0,0 +1,128 @@ + +*This model was released on 2025-09-01 and added to Hugging Face Transformers on 2025-09-15.* + + +# LongCatFlash + +## Overview + +The LongCatFlash model was proposed in [LongCat-Flash Technical Report](https://huggingface.co/papers/2509.01322) by the Meituan LongCat Team. +LongCat-Flash is a 560B parameter Mixture-of-Experts (MoE) model that activates 18.6B-31.3B parameters dynamically (average ~27B). The model features a shortcut-connected architecture enabling high inference speed (>100 tokens/second) and advanced reasoning capabilities. + +The abstract from the paper is the following: + +*We present LongCat-Flash, a 560 billion parameter Mixture-of-Experts (MoE) language model featuring a dynamic computation mechanism that activates 18.6B-31.3B parameters based on context (average ~27B). The model incorporates a shortcut-connected architecture enabling high inference speed (>100 tokens/second) and demonstrates strong performance across multiple benchmarks including 89.71% accuracy on MMLU and exceptional agentic tool use capabilities.* + +Tips: + +- LongCat-Flash uses a unique shortcut-connected MoE architecture that enables faster inference compared to traditional MoE models +- The model supports up to 128k context length for long-form tasks +- Dynamic parameter activation makes it computationally efficient while maintaining high performance +- Best suited for applications requiring strong reasoning, coding, and tool-calling capabilities +- The MoE architecture includes zero experts (nn.Identity modules) which act as skip connections, allowing tokens to bypass expert computation when appropriate + +This model was contributed by [Molbap](https://huggingface.co/Molbap). +The original code can be found [here](https://huggingface.co/meituan-longcat/LongCat-Flash-Chat). + +## Usage examples + +The model is large: you will need 2x8 H100 to run inference. +```python +# launch_longcat.py +from transformers import LongcatFlashForCausalLM, AutoTokenizer +import torch + +model_id = "meituan-longcat/LongCat-Flash-Chat" + +tokenizer = AutoTokenizer.from_pretrained(model_id) + +chat = [ + {"role": "user", "content": "Hello! What is the capital of France? What can you tell me about it?"}, +] + +model = LongcatFlashForCausalLM.from_pretrained( + model_id, + tp_plan="auto", + dtype=torch.bfloat16, + ) + +inputs = tokenizer.apply_chat_template( + chat, tokenize=True, add_generation_prompt=True, return_tensors="pt").to(model.device) + +outputs = model.generate(inputs, max_new_tokens=30) +print(tokenizer.batch_decode(outputs)) +``` + +To run with TP, you will need torchrun: + +```bash +torchrun --nproc_per_node=8 --nnodes=2 --node_rank=0 | 1 --rdzv-id --rdzv-backend c10d --rdzv-endpoint $NODE_ID:$NODE_PORT --log-dir ./logs_longcat launch_longcat.py +``` + +And you'll get a nice generation: +```json +[Round 0] USER:Hello! What is the capital of France? What can you tell me about it? ASSISTANT:Hello! 😊 The capital of France is Paris, one of the most famous and beloved cities in the world. Here’s a quick overview of what makes Paris special: +1. Iconic Landmarks + + Eiffel Tower – The global symbol of France, built in 1889 for the World's Fair. + Notre-Dame Cathedral – A masterpiece of Gothic architecture (currently under restoration after the 2019 fire). + Louvre Museum – The world’s largest art museum, home to the Mona Lisa and Venus de Milo. + Sacré-Cœur Basilica – A stunning white church atop Montmartre with panoramic views. + Arc de Triomphe – Honors French military victories, with the Tomb of the Unknown Soldier beneath it. + Champs-Élysées – A glamorous avenue leading to the Arc de Triomphe, lined with shops and cafés. + +2. Culture & Arts + + Paris is the "City of Light" (La Ville Lumière), a nickname from its early adoption of street lighting and its role as a center of enlightenment. + It’s a global hub for fashion (haute couture, Paris Fashion Week) and art (Impressionism, Picasso, Dali). + Famous literary figures like Hemingway, Fitzgerald, and Sartre lived and wrote here. + +3. Food & Cuisine + + Croissants, baguettes, macarons, and crème brûlée are just a few of its culinary delights. + Paris has over 100 Michelin-starred restaurants and countless cozy bistros. + The Marché d’Aligre and Rue Mouffetard are great for fresh produce and local flavors. + +4. History & Politics + + Founded in the 3rd century BC by the Parisii tribe, it became a major European city under the Romans. + The French Revolution (1789–1799) began here, leading to the fall of the monarchy. + Today, it’s the political and economic heart of France, housing the French President’s residence (Élysée Palace) and the National Assembly. + +** +``` + +## LongcatFlashConfig + +[[autodoc]] LongcatFlashConfig + +## LongcatFlashPreTrainedModel + +[[autodoc]] LongcatFlashPreTrainedModel + - forward + +## LongcatFlashModel + +[[autodoc]] LongcatFlashModel + - forward + +## LongcatFlashForCausalLM + +[[autodoc]] LongcatFlashForCausalLM diff --git a/src/transformers/models/__init__.py b/src/transformers/models/__init__.py index 13e616ca51ca..18d74ade4126 100644 --- a/src/transformers/models/__init__.py +++ b/src/transformers/models/__init__.py @@ -190,6 +190,7 @@ from .llava_next import * from .llava_next_video import * from .llava_onevision import * + from .longcat_flash import * from .longformer import * from .longt5 import * from .luke import * diff --git a/src/transformers/models/auto/configuration_auto.py b/src/transformers/models/auto/configuration_auto.py index 7a69ab18215d..a9303913e861 100644 --- a/src/transformers/models/auto/configuration_auto.py +++ b/src/transformers/models/auto/configuration_auto.py @@ -230,6 +230,7 @@ ("llava_next", "LlavaNextConfig"), ("llava_next_video", "LlavaNextVideoConfig"), ("llava_onevision", "LlavaOnevisionConfig"), + ("longcat_flash", "LongcatFlashConfig"), ("longformer", "LongformerConfig"), ("longt5", "LongT5Config"), ("luke", "LukeConfig"), @@ -665,6 +666,7 @@ ("llava_next", "LLaVA-NeXT"), ("llava_next_video", "LLaVa-NeXT-Video"), ("llava_onevision", "LLaVA-Onevision"), + ("longcat_flash", "LongCatFlash"), ("longformer", "Longformer"), ("longt5", "LongT5"), ("luke", "LUKE"), diff --git a/src/transformers/models/auto/modeling_auto.py b/src/transformers/models/auto/modeling_auto.py index e871a4848c01..571f654a9499 100644 --- a/src/transformers/models/auto/modeling_auto.py +++ b/src/transformers/models/auto/modeling_auto.py @@ -230,6 +230,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("llava_next", "LlavaNextModel"), ("llava_next_video", "LlavaNextVideoModel"), ("llava_onevision", "LlavaOnevisionModel"), + ("longcat_flash", "LongcatFlashModel"), ("longformer", "LongformerModel"), ("longt5", "LongT5Model"), ("luke", "LukeModel"), @@ -685,6 +686,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("llama", "LlamaForCausalLM"), ("llama4", "Llama4ForCausalLM"), ("llama4_text", "Llama4ForCausalLM"), + ("longcat_flash", "LongcatFlashForCausalLM"), ("mamba", "MambaForCausalLM"), ("mamba2", "Mamba2ForCausalLM"), ("marian", "MarianForCausalLM"), diff --git a/src/transformers/models/longcat_flash/__init__.py b/src/transformers/models/longcat_flash/__init__.py new file mode 100644 index 000000000000..a9a9429d9d05 --- /dev/null +++ b/src/transformers/models/longcat_flash/__init__.py @@ -0,0 +1,29 @@ +# coding=utf-8 +# Copyright 2025 Meituan and the HuggingFace Inc. team. All rights reserved. +# +# 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. + +from typing import TYPE_CHECKING + +from ...utils import _LazyModule +from ...utils.import_utils import define_import_structure + + +if TYPE_CHECKING: + from .configuration_longcat_flash import * + from .modeling_longcat_flash import * +else: + import sys + + _file = globals()["__file__"] + sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__) diff --git a/src/transformers/models/longcat_flash/configuration_longcat_flash.py b/src/transformers/models/longcat_flash/configuration_longcat_flash.py new file mode 100644 index 000000000000..4c5930db8f3a --- /dev/null +++ b/src/transformers/models/longcat_flash/configuration_longcat_flash.py @@ -0,0 +1,235 @@ +# coding=utf-8 +# Copyright 2025 Meituan and the HuggingFace Inc. team. All rights reserved. +# +# 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. + +"""LongCat Flash model configuration""" + +from ...configuration_utils import PretrainedConfig +from ...modeling_rope_utils import rope_config_validation + + +class LongcatFlashConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`LongcatFlashModel`]. It is used to instantiate + a LongCat Flash 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 LongCat Flash architecture. + e.g. [meituan-longcat/LongCat-Flash-Chat](https://huggingface.co/meituan-longcat/LongCat-Flash-Chat) + 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 131072): + Vocabulary size of the LongCat Flash model. Defines the number of different tokens that can be represented by the + `input_ids` passed when calling [`LongcatFlashModel`] + hidden_size (`int`, *optional*, defaults to 6144): + Dimension of the hidden representations. + num_hidden_layers (`int`, *optional*, defaults to 56): + Number of hidden layers in the Transformer decoder. + num_layers (`int`, *optional*, defaults to 28): + number of layers, each with 2 sublayers. + num_attention_heads (`int`, *optional*, defaults to 64): + Number of attention heads for each attention layer in the Transformer decoder. + num_key_value_heads (`int`, *optional*): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting from a multi-head checkpoint to a GQA checkpoint, each group key and value head should be + constructed by meanpooling all the original heads within that group. For more details checkout [this + paper](https://arxiv.org/pdf/2305.13245.pdf). If it is not specified, will default to + `num_attention_heads`. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 131072): + 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). + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-05): + The epsilon value used by the RMS normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + pad_token_id (`int`, *optional*): + Padding token id. + bos_token_id (`int`, *optional*, defaults to 1): + Beginning of stream token id. + eos_token_id (`int`, *optional*, defaults to 2): + End of stream token id. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether to tie input and output embeddings. + rope_theta (`float`, *optional*, defaults to 10000000.0): + The base period of the RoPE embeddings. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. Currently supports two scaling + strategies: linear and dynamic. Their scaling factor must be a float greater than 1. The expected format is + `{"type": strategy name, "factor": scaling factor}`. + attention_bias (`bool`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + ffn_hidden_size (`int`, *optional*, defaults to 12288): + Dimension of the MLP representations. + q_lora_rank (`int`, *optional*, defaults to 1536): + The rank of the query LoRA projection in MLA (Multi-head Latent Attention). + kv_lora_rank (`int`, *optional*, defaults to 512): + The rank of the key-value LoRA projection in MLA. + qk_nope_head_dim (`int`, *optional*, defaults to 128): + The dimension of the non-position encoding part of query/key heads. + qk_rope_head_dim (`int`, *optional*, defaults to 64): + The dimension of the RoPE part of query/key heads. + head_dim (`int`, *optional*, defaults to 64): + Standard dimension of qk heads, unused except for CI. + v_head_dim (`int`, *optional*, defaults to 128): + The dimension of value heads. + qk_head_dim (`int`, *optional*): + The total dimension of query/key heads. If not specified, set to `qk_nope_head_dim + qk_rope_head_dim`. + moe_topk (`int`, *optional*, defaults to 12): + Number of experts to route to for each token in the MoE layer. + n_routed_experts (`int`, *optional*, defaults to 512): + Number of routed experts in the MoE layer. + zero_expert_num (`int`, *optional*, defaults to 256): + Number of zero experts (identity function) to add to the expert pool. + expert_ffn_hidden_size (`int`, *optional*, defaults to 2048): + Hidden size of individual expert FFN layers. + routed_scaling_factor (`float`, *optional*, defaults to 6.0): + Scaling factor applied to the routing weights. + + ```python + >>> from transformers import LongcatFlashModel, LongcatFlashConfig + + >>> # Initializing a LongCat Flash style configuration + >>> configuration = LongcatFlashConfig() + + >>> # Initializing a model from the configuration + >>> model = LongcatFlashModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "longcat_flash" + keys_to_ignore_at_inference = ["past_key_values"] + base_model_tp_plan = { + "layers.*.self_attn.*.q_b_proj": "colwise", + "layers.*.self_attn.*.kv_b_proj": "colwise", + "layers.*.self_attn.*.o_proj": "rowwise", + "layers.*.mlps.*.gate_proj": "colwise", + "layers.*.mlps.*.up_proj": "colwise", + "layers.*.mlps.*.down_proj": "rowwise", + "layers.*.mlp.experts.*.gate_proj": "colwise", + "layers.*.mlp.experts.*.up_proj": "colwise", + "layers.*.mlp.experts.*.down_proj": "rowwise", + } + + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=131072, + hidden_size=6144, + num_hidden_layers=56, + num_layers=28, + num_attention_heads=64, + num_key_value_heads=None, + hidden_act="silu", + max_position_embeddings=131072, + initializer_range=0.02, + rms_norm_eps=1e-5, + use_cache=True, + pad_token_id=None, + bos_token_id=1, + eos_token_id=2, + tie_word_embeddings=False, + rope_theta=10000000.0, + rope_scaling=None, + attention_bias=False, + attention_dropout=0.0, + ffn_hidden_size=12288, + q_lora_rank=1536, + kv_lora_rank=512, + qk_nope_head_dim=128, + qk_rope_head_dim=64, + head_dim=64, + v_head_dim=128, + qk_head_dim=None, + moe_topk=12, + n_routed_experts=512, + zero_expert_num=256, + expert_ffn_hidden_size=2048, + routed_scaling_factor=6.0, + **kwargs, + ): + if num_key_value_heads is None: + num_key_value_heads = num_attention_heads + + if qk_head_dim is None: + qk_head_dim = qk_nope_head_dim + qk_rope_head_dim + + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.num_layers = num_layers + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.num_key_value_heads = num_key_value_heads + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + + self.ffn_hidden_size = ffn_hidden_size + + self.q_lora_rank = q_lora_rank + self.kv_lora_rank = kv_lora_rank + self.qk_nope_head_dim = qk_nope_head_dim + self.qk_rope_head_dim = qk_rope_head_dim + self.v_head_dim = v_head_dim + self.qk_head_dim = qk_head_dim + self.head_dim = head_dim + + self.moe_topk = moe_topk + self.n_routed_experts = n_routed_experts + self.zero_expert_num = zero_expert_num + self.expert_ffn_hidden_size = expert_ffn_hidden_size + self.routed_scaling_factor = routed_scaling_factor + + if self.rope_scaling is not None and "type" in self.rope_scaling: + self.rope_scaling["rope_type"] = self.rope_scaling["type"] + + if self.rope_scaling is not None: + for key in ["beta_fast", "beta_slow", "factor"]: + if key in self.rope_scaling: + self.rope_scaling[key] = float(self.rope_scaling[key]) + + rope_config_validation(self) + + super().__init__( + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + tie_word_embeddings=tie_word_embeddings, + **kwargs, + ) + + +__all__ = ["LongcatFlashConfig"] diff --git a/src/transformers/models/longcat_flash/modeling_longcat_flash.py b/src/transformers/models/longcat_flash/modeling_longcat_flash.py new file mode 100644 index 000000000000..87e812852b37 --- /dev/null +++ b/src/transformers/models/longcat_flash/modeling_longcat_flash.py @@ -0,0 +1,684 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/longcat_flash/modular_longcat_flash.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_longcat_flash.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 Meituan and the HuggingFace Inc. team. All rights reserved. +# +# 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. + +import math +from typing import Callable, Optional, Union + +import torch +import torch.nn.functional as F +from torch import nn + +from ...activations import ACT2FN +from ...cache_utils import Cache, DynamicCache +from ...generation import GenerationMixin +from ...integrations import use_kernel_forward_from_hub +from ...masking_utils import create_causal_mask +from ...modeling_flash_attention_utils import FlashAttentionKwargs +from ...modeling_layers import GradientCheckpointingLayer +from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple +from ...utils.deprecation import deprecate_kwarg +from ...utils.generic import check_model_inputs +from .configuration_longcat_flash import LongcatFlashConfig + + +@use_kernel_forward_from_hub("RMSNorm") +class LongcatFlashRMSNorm(nn.Module): + def __init__(self, hidden_size, eps=1e-6): + """ + LongcatFlashRMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states): + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return self.weight * hidden_states.to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +class LongcatFlashRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: LongcatFlashConfig, device=None): + super().__init__() + # BC: "rope_type" was originally "type" + if hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): + self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type")) + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device) + position_ids_expanded = position_ids[:, None, :].float() + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + +class LongcatFlashMLP(nn.Module): + def __init__(self, config, hidden_size=None, intermediate_size=None): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size if hidden_size is None else hidden_size + self.intermediate_size = config.ffn_hidden_size if intermediate_size is None else intermediate_size + + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +class LongcatFlashTopkRouter(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + + self.top_k = config.moe_topk + self.n_routed_experts = config.n_routed_experts + (config.zero_expert_num or 0) + self.routed_scaling_factor = config.routed_scaling_factor + self.register_buffer("e_score_correction_bias", torch.zeros(self.n_routed_experts)) + self.router_bias = getattr(config, "router_bias", False) + self.classifier = nn.Linear(config.hidden_size, self.n_routed_experts, bias=self.router_bias) + + @torch.no_grad() + def get_topk_indices(self, scores): + scores_for_choice = scores.view(-1, self.n_routed_experts) + self.e_score_correction_bias.unsqueeze(0) + topk_indices = torch.topk(scores_for_choice, k=self.top_k, dim=-1, sorted=False)[1] + return topk_indices + + def forward(self, hidden_states): + hidden_states = hidden_states.view(-1, self.config.hidden_size) + router_logits = F.linear(hidden_states.type(torch.float32), self.classifier.weight.type(torch.float32)) + scores = router_logits.softmax(dim=-1) + topk_indices = self.get_topk_indices(scores) + topk_weights = scores.gather(1, topk_indices) + topk_weights = topk_weights * self.routed_scaling_factor + return topk_indices, topk_weights + + +class LongcatFlashMoE(nn.Module): + """ + A mixed expert module containing zero compute (identity) experts. + """ + + def __init__(self, config): + super().__init__() + self.intermediate_size = config.expert_ffn_hidden_size + self.config = config + + self.experts = nn.ModuleList( + [LongcatFlashMLP(config, intermediate_size=self.intermediate_size) for _ in range(config.n_routed_experts)] + + [nn.Identity() for _ in range(config.zero_expert_num)] + ) + + self.router = LongcatFlashTopkRouter(config) + + def moe(self, hidden_states: torch.Tensor, topk_indices: torch.Tensor, topk_weights: torch.Tensor): + r""" + CALL FOR CONTRIBUTION! I don't have time to optimise this right now, but expert weights need to be fused + to not have to do a loop here (deepseek has 256 experts soooo yeah). + """ + final_hidden_states = torch.zeros_like(hidden_states, dtype=topk_weights.dtype) + expert_mask = torch.nn.functional.one_hot(topk_indices, num_classes=len(self.experts)) + expert_mask = expert_mask.permute(2, 0, 1) + + for expert_idx in range(len(self.experts)): + expert = self.experts[expert_idx] + mask = expert_mask[expert_idx] + token_indices, weight_indices = torch.where(mask) + + if token_indices.numel() > 0: + expert_weights = topk_weights[token_indices, weight_indices] + expert_input = hidden_states[token_indices] + expert_output = expert(expert_input) + weighted_output = expert_output * expert_weights.unsqueeze(-1) + final_hidden_states.index_add_(0, token_indices, weighted_output) + + # in original deepseek, the output of the experts are gathered once we leave this module + # thus the moe module is itelsf an IsolatedParallel module + # and all expert are "local" meaning we shard but we don't gather + return final_hidden_states.type(hidden_states.dtype) + + def forward(self, hidden_states): + orig_shape = hidden_states.shape + topk_indices, topk_weights = self.router(hidden_states) + hidden_states = hidden_states.view(-1, hidden_states.shape[-1]) + hidden_states = self.moe(hidden_states, topk_indices, topk_weights).view(*orig_shape) + return hidden_states + + +def rotate_half(x): + """Rotates half the hidden dims of the input.""" + x1 = x[..., : x.shape[-1] // 2] + x2 = x[..., x.shape[-1] // 2 :] + return torch.cat((-x2, x1), dim=-1) + + +def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor: + """ + This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, + num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim) + """ + batch, num_key_value_heads, slen, head_dim = hidden_states.shape + if n_rep == 1: + return hidden_states + hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim) + return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim) + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: float, + dropout: float = 0.0, + **kwargs: Unpack[TransformersKwargs], +): + key_states = repeat_kv(key, module.num_key_value_groups) + value_states = repeat_kv(value, module.num_key_value_groups) + + attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling + if attention_mask is not None: + causal_mask = attention_mask[:, :, :, : key_states.shape[-2]] + attn_weights = attn_weights + causal_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + attn_output = torch.matmul(attn_weights, value_states) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + +def apply_rotary_pos_emb_interleave(q, k, cos, sin, position_ids=None, unsqueeze_dim=1): + r""" + TODO let's just use the original freqcis computation to not have the view + transpose + reshape! This is not optimized! + Applies Rotary Position Embedding to the query and key tensors. + + Args: + q (`torch.Tensor`): The query tensor. + k (`torch.Tensor`): The key tensor. + cos (`torch.Tensor`): The cosine part of the rotary embedding. + sin (`torch.Tensor`): The sine part of the rotary embedding. + position_ids (`torch.Tensor`): + The position indices of the tokens corresponding to the query and key tensors. For example, this can be + used to pass offsetted position ids when working with a KV-cache. + unsqueeze_dim (`int`, *optional*, defaults to 1): + The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and + sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note + that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and + k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes + cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have + the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. + Returns: + `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. + """ + cos = cos.unsqueeze(unsqueeze_dim) + sin = sin.unsqueeze(unsqueeze_dim) + + b, h, s, d = q.shape + q = q.view(b, h, s, d // 2, 2).transpose(4, 3).reshape(b, h, s, d) + + b, h, s, d = k.shape + k = k.view(b, h, s, d // 2, 2).transpose(4, 3).reshape(b, h, s, d) + + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + return q_embed, k_embed + + +def yarn_get_mscale(scale=1, mscale=1): + if scale <= 1: + return 1.0 + return 0.1 * mscale * math.log(scale) + 1.0 + + +class LongcatFlashMLA(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config, layer_idx: int): + super().__init__() + self.config = config + self.layer_idx = layer_idx + self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads + self.attention_dropout = config.attention_dropout + self.num_heads = config.num_attention_heads + self.rope_theta = config.rope_theta + self.q_lora_rank = config.q_lora_rank + self.qk_rope_head_dim = config.qk_rope_head_dim + self.kv_lora_rank = config.kv_lora_rank + self.v_head_dim = config.v_head_dim + self.qk_nope_head_dim = config.qk_nope_head_dim + self.qk_head_dim = config.qk_head_dim + + self.is_causal = True + if self.q_lora_rank is None: + self.q_proj = nn.Linear(config.hidden_size, self.num_heads * self.qk_head_dim, bias=False) + else: + self.q_a_proj = nn.Linear(config.hidden_size, config.q_lora_rank, bias=config.attention_bias) + self.q_a_layernorm = LongcatFlashRMSNorm(config.q_lora_rank) + self.q_b_proj = nn.Linear(config.q_lora_rank, self.num_heads * self.qk_head_dim, bias=False) + + self.kv_a_proj_with_mqa = nn.Linear( + config.hidden_size, + self.kv_lora_rank + self.qk_rope_head_dim, + bias=config.attention_bias, + ) + self.kv_a_layernorm = LongcatFlashRMSNorm(self.kv_lora_rank) + self.kv_b_proj = nn.Linear( + self.kv_lora_rank, + self.num_heads * (self.qk_nope_head_dim + self.v_head_dim), + bias=False, + ) + + self.o_proj = nn.Linear( + self.num_heads * self.v_head_dim, + config.hidden_size, + bias=config.attention_bias, + ) + + self.scaling = self.qk_head_dim ** (-0.5) + if self.config.rope_scaling is not None: + mscale_all_dim = self.config.rope_scaling.get("mscale_all_dim", 0) + scaling_factor = self.config.rope_scaling["factor"] + if mscale_all_dim: + mscale = yarn_get_mscale(scaling_factor, mscale_all_dim) + self.scaling = self.scaling * mscale * mscale + + self.mla_scale_q_lora = (config.hidden_size / self.q_lora_rank) ** 0.5 + self.mla_scale_kv_lora = (config.hidden_size / self.kv_lora_rank) ** 0.5 + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]: + batch_size, seq_length = hidden_states.shape[:-1] + query_shape = (batch_size, seq_length, -1, self.qk_head_dim) + key_shape = (batch_size, seq_length, -1, self.qk_nope_head_dim + self.v_head_dim) + # we always do a lora for queries as well + q_states = self.q_b_proj(self.q_a_layernorm(self.q_a_proj(hidden_states))) + q_states = q_states.view(query_shape).transpose(1, 2) + q_pass, q_rot = torch.split(q_states, [self.qk_nope_head_dim, self.qk_rope_head_dim], dim=-1) + + compressed_kv = self.kv_a_proj_with_mqa(hidden_states) + k_pass, k_rot = torch.split(compressed_kv, [self.kv_lora_rank, self.qk_rope_head_dim], dim=-1) + k_pass = self.kv_a_layernorm(k_pass) + + # apply LoRA scaling + q_pass = q_pass * self.mla_scale_q_lora + q_rot = q_rot * self.mla_scale_q_lora + k_pass = k_pass * self.mla_scale_kv_lora + + k_pass = self.kv_b_proj(k_pass).view(key_shape).transpose(1, 2) + k_pass, value_states = torch.split(k_pass, [self.qk_nope_head_dim, self.v_head_dim], dim=-1) + + k_rot = k_rot.view(batch_size, 1, seq_length, self.qk_rope_head_dim) + + cos, sin = position_embeddings + q_rot, k_rot = apply_rotary_pos_emb_interleave(q_rot, k_rot, cos, sin) + k_rot = k_rot.expand(*k_pass.shape[:-1], -1) + + query_states = torch.cat((q_pass, q_rot), dim=-1) + key_states = torch.cat((k_pass, k_rot), dim=-1) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + if self.config._attn_implementation == "flash_attention_2" and self.qk_head_dim != self.v_head_dim: + value_states = F.pad(value_states, [0, self.qk_head_dim - self.v_head_dim]) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + if self.config._attn_implementation == "flash_attention_2" and self.qk_head_dim != self.v_head_dim: + attn_output = attn_output[:, :, :, : self.v_head_dim] + + attn_output = attn_output.reshape(batch_size, seq_length, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class LongcatFlashDecoderLayer(GradientCheckpointingLayer): + """ + LongCat decoder layer with dual-sublayer + shortcut MoE architecture. + + Each logical layer contains: + - 2 attention sublayers (with layer indices: layer_idx*2, layer_idx*2+1) + - 2 MLP sublayers + - 1 shortcut MoE connection + """ + + def __init__(self, config, layer_idx: int): + super().__init__() + self.layer_idx = layer_idx + self.hidden_size = config.hidden_size + + self.mlp = LongcatFlashMoE(config) + + self.self_attn = nn.ModuleList([LongcatFlashMLA(config=config, layer_idx=layer_idx * 2 + i) for i in [0, 1]]) + self.mlps = nn.ModuleList([LongcatFlashMLP(config) for _ in [0, 1]]) + self.input_layernorm = nn.ModuleList( + [LongcatFlashRMSNorm(config.hidden_size, eps=config.rms_norm_eps) for _ in [0, 1]] + ) + self.post_attention_layernorm = nn.ModuleList( + [LongcatFlashRMSNorm(config.hidden_size, eps=config.rms_norm_eps) for _ in [0, 1]] + ) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> torch.Tensor: + residual = hidden_states + hidden_states = self.input_layernorm[0](hidden_states) + + hidden_states, _ = self.self_attn[0]( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.post_attention_layernorm[0](hidden_states) + + shortcut_mlp_output = self.mlp(hidden_states) + hidden_states = self.mlps[0](hidden_states) + hidden_states = residual + hidden_states + + # shortcut connection after second sublayer + residual = hidden_states + hidden_states = self.input_layernorm[1](hidden_states) + + hidden_states, _ = self.self_attn[1]( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.post_attention_layernorm[1](hidden_states) + + hidden_states = self.mlps[1](hidden_states) + hidden_states = residual + hidden_states + shortcut_mlp_output + + return hidden_states + + +@auto_docstring +class LongcatFlashPreTrainedModel(PreTrainedModel): + config: LongcatFlashConfig + base_model_prefix = "model" + supports_gradient_checkpointing = True + _no_split_modules = ["LongcatFlashDecoderLayer"] + _skip_keys_device_placement = ["past_key_values"] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _can_compile_fullgraph = False + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": LongcatFlashDecoderLayer, + "attentions": LongcatFlashMLA, + } + + def _init_weights(self, module): + super()._init_weights(module) + if isinstance(module, LongcatFlashTopkRouter): + module.classifier.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + + +@auto_docstring +class LongcatFlashModel(LongcatFlashPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"model\.mtp.*"] + + def __init__(self, config): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + + self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx) + self.layers = nn.ModuleList( + [LongcatFlashDecoderLayer(config, layer_idx) for layer_idx in range(config.num_layers)] + ) + self.norm = LongcatFlashRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = LongcatFlashRotaryEmbedding(config=config) + self.gradient_checkpointing = False + # Each layer above has 2 sublayers, config hack to have a correct cache (to avoid a checkpoint change) + self.head_dim = config.head_dim # For CI happiness (we didn't convert so head_dim is not directly used) # noqa + + self.config.num_hidden_layers = 2 * config.num_layers + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> BaseModelOutputWithPast: + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds: torch.Tensor = self.embed_tokens(input_ids) + + if use_cache and past_key_values is None: + past_key_values = DynamicCache(config=self.config) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position: torch.Tensor = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + causal_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + hidden_states = inputs_embeds + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for decoder_layer in self.layers[: self.config.num_layers]: + hidden_states = decoder_layer( + hidden_states, + attention_mask=causal_mask, + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + hidden_states=None, + attentions=None, + ) + + +@auto_docstring +class LongcatFlashForCausalLM(LongcatFlashPreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.weight"] + _tp_plan = {"lm_head": "colwise_rep"} + _pp_plan = {"lm_head": (["hidden_states"], ["logits"])} + _keys_to_ignore_on_load_unexpected = [r"model\.mtp.*"] + + def __init__(self, config): + super().__init__(config) + self.model = LongcatFlashModel(config) + self.vocab_size = config.vocab_size + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs: Unpack[TransformersKwargs], + ) -> CausalLMOutputWithPast: + r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, LongcatFlashForCausalLM + + >>> model = LongcatFlashForCausalLM.from_pretrained("meta-longcat_flash/LongcatFlash-2-7b-hf") + >>> tokenizer = AutoTokenizer.from_pretrained("meta-longcat_flash/LongcatFlash-2-7b-hf") + + >>> prompt = "Hey, are you conscious? Can you talk to me?" + >>> inputs = tokenizer(prompt, return_tensors="pt") + + >>> # Generate + >>> generate_ids = model.generate(inputs.input_ids, max_length=30) + >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] + "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you." + ```""" + outputs: BaseModelOutputWithPast = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs.last_hidden_state + # Only compute necessary logits, and do not upcast them to float if we are not computing the loss + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]) + + loss = None + if labels is not None: + loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs) + + return CausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +__all__ = ["LongcatFlashPreTrainedModel", "LongcatFlashModel", "LongcatFlashForCausalLM"] diff --git a/src/transformers/models/longcat_flash/modular_longcat_flash.py b/src/transformers/models/longcat_flash/modular_longcat_flash.py new file mode 100644 index 000000000000..f58ca870aefc --- /dev/null +++ b/src/transformers/models/longcat_flash/modular_longcat_flash.py @@ -0,0 +1,382 @@ +# coding=utf-8 +# Copyright 2025 Meituan and the HuggingFace Inc. team. All rights reserved. +# +# 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. + +from typing import Callable, Optional + +import torch +import torch.nn.functional as F +from torch import nn + +from ...cache_utils import Cache, DynamicCache +from ...masking_utils import create_causal_mask +from ...modeling_flash_attention_utils import FlashAttentionKwargs +from ...modeling_layers import GradientCheckpointingLayer +from ...modeling_outputs import BaseModelOutputWithPast +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, logging +from ..deepseek_v3.modeling_deepseek_v3 import ( + DeepseekV3Attention, + DeepseekV3ForCausalLM, + DeepseekV3MLP, + DeepseekV3Model, + DeepseekV3MoE, + DeepseekV3PreTrainedModel, + DeepseekV3RMSNorm, + DeepseekV3RotaryEmbedding, + DeepseekV3TopkRouter, + apply_rotary_pos_emb_interleave, + eager_attention_forward, +) + + +logger = logging.get_logger(__name__) + + +class LongcatFlashRMSNorm(DeepseekV3RMSNorm): + pass + + +class LongcatFlashRotaryEmbedding(DeepseekV3RotaryEmbedding): + pass + + +# TODO remap config key ffn_hidden_size -> intermediate_size +class LongcatFlashMLP(DeepseekV3MLP): + def __init__(self, config, hidden_size=None, intermediate_size=None): + super().__init__() + self.intermediate_size = config.ffn_hidden_size if intermediate_size is None else intermediate_size + + +# TODO remap config key moe_topk -> num_experts_per_tok +class LongcatFlashTopkRouter(DeepseekV3TopkRouter): + def __init__(self, config): + super().__init__(config) + del self.n_group + del self.topk_group + del self.weight + del self.norm_topk_prob + + self.top_k = config.moe_topk + self.n_routed_experts = config.n_routed_experts + (config.zero_expert_num or 0) + self.routed_scaling_factor = config.routed_scaling_factor + self.register_buffer("e_score_correction_bias", torch.zeros(self.n_routed_experts)) + self.router_bias = getattr(config, "router_bias", False) + self.classifier = nn.Linear(config.hidden_size, self.n_routed_experts, bias=self.router_bias) + + @torch.no_grad() + def get_topk_indices(self, scores): + scores_for_choice = scores.view(-1, self.n_routed_experts) + self.e_score_correction_bias.unsqueeze(0) + topk_indices = torch.topk(scores_for_choice, k=self.top_k, dim=-1, sorted=False)[1] + return topk_indices + + def forward(self, hidden_states): + hidden_states = hidden_states.view(-1, self.config.hidden_size) + router_logits = F.linear(hidden_states.type(torch.float32), self.classifier.weight.type(torch.float32)) + scores = router_logits.softmax(dim=-1) + topk_indices = self.get_topk_indices(scores) + topk_weights = scores.gather(1, topk_indices) + topk_weights = topk_weights * self.routed_scaling_factor + return topk_indices, topk_weights + + +# remap config key expert_ffn_hidden_size -> moe_intermediate_size +class LongcatFlashMoE(DeepseekV3MoE): + """ + A mixed expert module containing zero compute (identity) experts. + """ + + def __init__(self, config): + self.intermediate_size = config.expert_ffn_hidden_size + super().__init__(config) + del self.gate + del self.shared_experts + + self.experts = nn.ModuleList( + [LongcatFlashMLP(config, intermediate_size=self.intermediate_size) for _ in range(config.n_routed_experts)] + + [nn.Identity() for _ in range(config.zero_expert_num)] + ) + + self.router = LongcatFlashTopkRouter(config) + + def forward(self, hidden_states): + orig_shape = hidden_states.shape + topk_indices, topk_weights = self.router(hidden_states) + hidden_states = hidden_states.view(-1, hidden_states.shape[-1]) + hidden_states = self.moe(hidden_states, topk_indices, topk_weights).view(*orig_shape) + return hidden_states + + +class LongcatFlashMLA(DeepseekV3Attention): + def __init__(self, config, layer_idx: int): + super().__init__(config, layer_idx) + + self.mla_scale_q_lora = (config.hidden_size / self.q_lora_rank) ** 0.5 + self.mla_scale_kv_lora = (config.hidden_size / self.kv_lora_rank) ** 0.5 + + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]: + batch_size, seq_length = hidden_states.shape[:-1] + query_shape = (batch_size, seq_length, -1, self.qk_head_dim) + key_shape = (batch_size, seq_length, -1, self.qk_nope_head_dim + self.v_head_dim) + # we always do a lora for queries as well + q_states = self.q_b_proj(self.q_a_layernorm(self.q_a_proj(hidden_states))) + q_states = q_states.view(query_shape).transpose(1, 2) + q_pass, q_rot = torch.split(q_states, [self.qk_nope_head_dim, self.qk_rope_head_dim], dim=-1) + + compressed_kv = self.kv_a_proj_with_mqa(hidden_states) + k_pass, k_rot = torch.split(compressed_kv, [self.kv_lora_rank, self.qk_rope_head_dim], dim=-1) + k_pass = self.kv_a_layernorm(k_pass) + + # apply LoRA scaling + q_pass = q_pass * self.mla_scale_q_lora + q_rot = q_rot * self.mla_scale_q_lora + k_pass = k_pass * self.mla_scale_kv_lora + + k_pass = self.kv_b_proj(k_pass).view(key_shape).transpose(1, 2) + k_pass, value_states = torch.split(k_pass, [self.qk_nope_head_dim, self.v_head_dim], dim=-1) + + k_rot = k_rot.view(batch_size, 1, seq_length, self.qk_rope_head_dim) + + cos, sin = position_embeddings + q_rot, k_rot = apply_rotary_pos_emb_interleave(q_rot, k_rot, cos, sin) + k_rot = k_rot.expand(*k_pass.shape[:-1], -1) + + query_states = torch.cat((q_pass, q_rot), dim=-1) + key_states = torch.cat((k_pass, k_rot), dim=-1) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + if self.config._attn_implementation == "flash_attention_2" and self.qk_head_dim != self.v_head_dim: + value_states = F.pad(value_states, [0, self.qk_head_dim - self.v_head_dim]) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + if self.config._attn_implementation == "flash_attention_2" and self.qk_head_dim != self.v_head_dim: + attn_output = attn_output[:, :, :, : self.v_head_dim] + + attn_output = attn_output.reshape(batch_size, seq_length, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class LongcatFlashDecoderLayer(GradientCheckpointingLayer): + """ + LongCat decoder layer with dual-sublayer + shortcut MoE architecture. + + Each logical layer contains: + - 2 attention sublayers (with layer indices: layer_idx*2, layer_idx*2+1) + - 2 MLP sublayers + - 1 shortcut MoE connection + """ + + def __init__(self, config, layer_idx: int): + super().__init__() + self.layer_idx = layer_idx + self.hidden_size = config.hidden_size + + self.mlp = LongcatFlashMoE(config) + + self.self_attn = nn.ModuleList([LongcatFlashMLA(config=config, layer_idx=layer_idx * 2 + i) for i in [0, 1]]) + self.mlps = nn.ModuleList([LongcatFlashMLP(config) for _ in [0, 1]]) + self.input_layernorm = nn.ModuleList( + [LongcatFlashRMSNorm(config.hidden_size, eps=config.rms_norm_eps) for _ in [0, 1]] + ) + self.post_attention_layernorm = nn.ModuleList( + [LongcatFlashRMSNorm(config.hidden_size, eps=config.rms_norm_eps) for _ in [0, 1]] + ) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> torch.Tensor: + residual = hidden_states + hidden_states = self.input_layernorm[0](hidden_states) + + hidden_states, _ = self.self_attn[0]( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.post_attention_layernorm[0](hidden_states) + + shortcut_mlp_output = self.mlp(hidden_states) + hidden_states = self.mlps[0](hidden_states) + hidden_states = residual + hidden_states + + # shortcut connection after second sublayer + residual = hidden_states + hidden_states = self.input_layernorm[1](hidden_states) + + hidden_states, _ = self.self_attn[1]( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.post_attention_layernorm[1](hidden_states) + + hidden_states = self.mlps[1](hidden_states) + hidden_states = residual + hidden_states + shortcut_mlp_output + + return hidden_states + + +class LongcatFlashPreTrainedModel(DeepseekV3PreTrainedModel): + _can_record_outputs = { + "hidden_states": LongcatFlashDecoderLayer, + "attentions": LongcatFlashMLA, + } + + def _init_weights(self, module): + PreTrainedModel._init_weights(self, module) + if isinstance(module, LongcatFlashTopkRouter): + module.classifier.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + + +class LongcatFlashModel(DeepseekV3Model): + _keys_to_ignore_on_load_unexpected = [r"model\.mtp.*"] + + def __init__(self, config): + super().__init__(config) + self.layers = nn.ModuleList( + [LongcatFlashDecoderLayer(config, layer_idx) for layer_idx in range(config.num_layers)] + ) + # Each layer above has 2 sublayers, config hack to have a correct cache (to avoid a checkpoint change) + self.head_dim = config.head_dim # For CI happiness (we didn't convert so head_dim is not directly used) # noqa + + self.config.num_hidden_layers = 2 * config.num_layers + self.norm = LongcatFlashRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = LongcatFlashRotaryEmbedding(config=config) + self.gradient_checkpointing = False + + # Initialize weights and apply final processing + self.post_init() + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], + ): + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds: torch.Tensor = self.embed_tokens(input_ids) + + if use_cache and past_key_values is None: + past_key_values = DynamicCache(config=self.config) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position: torch.Tensor = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + causal_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + hidden_states = inputs_embeds + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for decoder_layer in self.layers[: self.config.num_layers]: + hidden_states = decoder_layer( + hidden_states, + attention_mask=causal_mask, + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + hidden_states=None, + attentions=None, + ) + + +class LongcatFlashForCausalLM(DeepseekV3ForCausalLM): + _keys_to_ignore_on_load_unexpected = [r"model\.mtp.*"] + + def __init__(self, config): + super().__init__(config) + self.model = LongcatFlashModel(config) + + +__all__ = ["LongcatFlashPreTrainedModel", "LongcatFlashModel", "LongcatFlashForCausalLM"] diff --git a/tests/models/longcat_flash/__init__.py b/tests/models/longcat_flash/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/models/longcat_flash/test_modeling_longcat_flash.py b/tests/models/longcat_flash/test_modeling_longcat_flash.py new file mode 100644 index 000000000000..bc52e890ce0a --- /dev/null +++ b/tests/models/longcat_flash/test_modeling_longcat_flash.py @@ -0,0 +1,473 @@ +# Copyright 2025 Meituan and the HuggingFace Inc. team. All rights reserved. +# +# 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 LongcatFlash model.""" + +import copy +import tempfile +import unittest + +from parameterized import parameterized +from pytest import mark + +from transformers import LongcatFlashConfig, is_torch_available, set_seed +from transformers.testing_utils import ( + require_bitsandbytes, + require_flash_attn, + require_large_cpu_ram, + require_torch, + require_torch_gpu, + slow, + torch_device, +) + +from ...causal_lm_tester import CausalLMModelTest, CausalLMModelTester +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ids_tensor + + +if is_torch_available(): + import torch + + from transformers import AutoTokenizer, LongcatFlashForCausalLM, LongcatFlashModel + + +class LongcatFlashModelTester(CausalLMModelTester): + if is_torch_available(): + config_class = LongcatFlashConfig + base_model_class = LongcatFlashModel + causal_lm_class = LongcatFlashForCausalLM + + def __init__( + self, + parent, + batch_size=2, + seq_length=7, + is_training=True, + use_input_mask=True, + use_labels=True, + vocab_size=99, + hidden_size=144, + ffn_hidden_size=288, + expert_ffn_hidden_size=48, + num_layers=2, + num_attention_heads=8, + num_key_value_heads=8, + kv_lora_rank=16, + q_lora_rank=48, + qk_rope_head_dim=4, + v_head_dim=8, + qk_nope_head_dim=8, + head_dim=4, + n_routed_experts=4, + zero_expert_num=2, + moe_topk=2, + routed_scaling_factor=1.0, + hidden_act="silu", + max_position_embeddings=128, + initializer_range=0.02, + rms_norm_eps=1e-6, + bos_token_id=1, + eos_token_id=2, + pad_token_id=3, + type_sequence_label_size=2, + num_labels=3, + num_choices=4, + ): + 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_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.ffn_hidden_size = ffn_hidden_size + self.expert_ffn_hidden_size = expert_ffn_hidden_size + self.num_layers = num_layers + self.num_hidden_layers = 2 * num_layers # for compatibility + self.expected_num_hidden_layers = 3 # embedding + 2 layers + self.num_attention_heads = num_attention_heads + self.num_key_value_heads = num_key_value_heads + self.kv_lora_rank = kv_lora_rank + self.q_lora_rank = q_lora_rank + self.qk_rope_head_dim = qk_rope_head_dim + self.v_head_dim = v_head_dim + self.qk_nope_head_dim = qk_nope_head_dim + self.head_dim = head_dim + self.n_routed_experts = n_routed_experts + self.zero_expert_num = zero_expert_num + self.moe_topk = moe_topk + self.routed_scaling_factor = routed_scaling_factor + self.hidden_act = hidden_act + self.max_position_embeddings = max_position_embeddings + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.bos_token_id = bos_token_id + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.type_sequence_label_size = type_sequence_label_size + self.num_labels = num_labels + self.num_choices = num_choices + + def get_config(self): + return LongcatFlashConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + ffn_hidden_size=self.ffn_hidden_size, + expert_ffn_hidden_size=self.expert_ffn_hidden_size, + num_layers=self.num_layers, + num_attention_heads=self.num_attention_heads, + num_key_value_heads=self.num_key_value_heads, + kv_lora_rank=self.kv_lora_rank, + q_lora_rank=self.q_lora_rank, + qk_rope_head_dim=self.qk_rope_head_dim, + v_head_dim=self.v_head_dim, + qk_nope_head_dim=self.qk_nope_head_dim, + head_dim=self.head_dim, + n_routed_experts=self.n_routed_experts, + zero_expert_num=self.zero_expert_num, + moe_topk=self.moe_topk, + routed_scaling_factor=self.routed_scaling_factor, + hidden_act=self.hidden_act, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + rms_norm_eps=self.rms_norm_eps, + pad_token_id=self.pad_token_id, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = LongcatFlashModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask) + 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=None, + encoder_attention_mask=None, + ): + model = LongcatFlashForCausalLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + 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 = torch.tril(torch.ones(self.batch_size, self.seq_length)).to(torch_device) + + token_type_ids = None + + 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 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 LongcatFlashModelTest(CausalLMModelTest, unittest.TestCase): + all_model_classes = (LongcatFlashModel, LongcatFlashForCausalLM) if is_torch_available() else () + all_generative_model_classes = (LongcatFlashForCausalLM,) if is_torch_available() else () + + pipeline_model_mapping = ( + { + "feature-extraction": LongcatFlashModel, + "text-generation": LongcatFlashForCausalLM, + } + if is_torch_available() + else {} + ) + + model_split_percents = [0.5, 0.8] + + test_headmasking = False + test_pruning = False + + model_tester_class = LongcatFlashModelTester + + def setUp(self): + self.model_tester = LongcatFlashModelTester(self) + self.config_tester = ConfigTester(self, config_class=LongcatFlashConfig, hidden_size=37, num_attention_heads=3) + + 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_for_causal_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_causal_lm(*config_and_inputs) + + @unittest.skip("LongcatFlash buffers include complex numbers, which breaks this test") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip("LongcatFlash buffers include complex numbers, which breaks this test") + def test_save_load_fast_init_to_base(self): + pass + + def test_past_key_values_format(self): + config, inputs = self.model_tester.prepare_config_and_inputs_for_common() + batch_size, seq_length = inputs["input_ids"].shape + + k_embed_dim = config.qk_nope_head_dim + config.qk_rope_head_dim + v_embed_dim = config.v_head_dim + + self_attention_keys_shape = (batch_size, config.num_key_value_heads, seq_length, k_embed_dim) + self_attention_values_shape = (batch_size, config.num_key_value_heads, seq_length, v_embed_dim) + + num_hidden_layers = config.num_hidden_layers + all_cache_shapes = [[self_attention_keys_shape, self_attention_values_shape] for _ in range(num_hidden_layers)] + + super().test_past_key_values_format(custom_all_cache_shapes=all_cache_shapes) + + def _check_past_key_values_for_generate(self, batch_size, decoder_past_key_values, cache_length, config): + from transformers.cache_utils import Cache + + self.assertIsInstance(decoder_past_key_values, (tuple, Cache)) + + k_embed_dim = config.qk_nope_head_dim + config.qk_rope_head_dim + v_embed_dim = config.v_head_dim + + expected_key_shape = (batch_size, config.num_key_value_heads, cache_length, k_embed_dim) + expected_value_shape = (batch_size, config.num_key_value_heads, cache_length, v_embed_dim) + + if isinstance(decoder_past_key_values, Cache): + for layer_idx in range(config.num_hidden_layers): + self.assertEqual(decoder_past_key_values.layers[layer_idx].keys.shape, expected_key_shape) + self.assertEqual(decoder_past_key_values.layers[layer_idx].values.shape, expected_value_shape) + else: + for layer_past in decoder_past_key_values: + self.assertEqual(layer_past[0].shape, expected_key_shape) + self.assertEqual(layer_past[1].shape, expected_value_shape) + + @unittest.skip("MoE experts may not receive gradients with small test data") + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip("MoE experts may not receive gradients with small test data") + def test_training_gradient_checkpointing_use_reentrant(self): + pass + + @unittest.skip("MoE experts may not receive gradients with small test data") + def test_training_gradient_checkpointing_use_reentrant_false(self): + pass + + @unittest.skip("LongcatFlash router uses weight.type() directly in forward which prevents offloading") + def test_cpu_offload(self): + pass + + @unittest.skip("LongcatFlash router uses weight.type() directly in forward which prevents offloading") + def test_disk_offload_bin(self): + pass + + @unittest.skip("LongcatFlash router uses weight.type() directly in forward which prevents offloading") + def test_disk_offload_safetensors(self): + pass + + @unittest.skip("Most probably because of the MOE, the moe and router does not ignore padding tokens") + def test_eager_padding_matches_padding_free_with_position_ids(self): + pass + + @unittest.skip(reason="SDPA can't dispatch on flash due to unsupported head dims") + def test_sdpa_can_dispatch_on_flash(self): + pass + + @staticmethod + def _prepare_config_headdim(config, requested_dim): + # there's specific head dims due to lora compressions in longcat + config = copy.deepcopy(config) + config.attention_dropout = 0 + + if requested_dim > config.qk_rope_head_dim: + config.qk_rope_head_dim = requested_dim + config.qk_nope_head_dim = max(config.qk_nope_head_dim, requested_dim) + config.v_head_dim = max(config.v_head_dim, requested_dim) + config.qk_head_dim = config.qk_nope_head_dim + config.qk_rope_head_dim + config.head_dim = requested_dim + config.q_lora_rank = max(config.q_lora_rank, requested_dim * 4) + config.kv_lora_rank = max(config.kv_lora_rank, requested_dim * 2) + config.hidden_size = max(config.hidden_size, config.num_attention_heads * requested_dim) + + return config + + @parameterized.expand([("linear",), ("dynamic",), ("yarn",)]) + def test_model_rope_scaling_from_config(self, scaling_type): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + short_input = ids_tensor([1, 10], config.vocab_size) + long_input = ids_tensor([1, int(config.max_position_embeddings * 1.5)], config.vocab_size) + + set_seed(42) + original_model = self.model_tester_class.base_model_class(config) + original_model.to(torch_device) + original_model.eval() + original_short_output = original_model(short_input).last_hidden_state + original_long_output = original_model(long_input).last_hidden_state + + set_seed(42) + config.rope_scaling = {"type": scaling_type, "factor": 10.0} + scaled_model = self.model_tester_class.base_model_class(config) + scaled_model.to(torch_device) + scaled_model.eval() + scaled_short_output = scaled_model(short_input).last_hidden_state + scaled_long_output = scaled_model(long_input).last_hidden_state + + if scaling_type == "dynamic": + torch.testing.assert_close(original_short_output, scaled_short_output, rtol=1e-5, atol=1e-5) + else: + self.assertFalse(torch.allclose(original_short_output, scaled_short_output, atol=1e-5)) + + self.assertFalse(torch.allclose(original_long_output, scaled_long_output, atol=1e-5)) + + @require_flash_attn + @require_torch_gpu + @require_bitsandbytes + @mark.flash_attn_test + @slow + def test_flash_attn_2_fp32_ln(self): + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + for model_class in self.all_generative_model_classes: # TODO: this test should run on all classes instead + if not model_class._supports_flash_attn: + self.skipTest(f"{model_class.__name__} does not support Flash Attention 2") + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + model = model_class(config) + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + dummy_input = inputs_dict[model.main_input_name] + dummy_attention_mask = inputs_dict.get("attention_mask", torch.ones_like(dummy_input)) + batch_size = dummy_attention_mask.shape[0] + + is_padding_right = dummy_attention_mask[:, -1].sum().item() != batch_size + + # To avoid errors with padding_side=="right" + if is_padding_right: + dummy_attention_mask = torch.ones_like(dummy_input) + + model = model_class.from_pretrained( + tmpdirname, + dtype=torch.float16, + attn_implementation="flash_attention_2", + device_map="auto", # small change to ensure device placement + ) + + # no upcasting at all + + if model.config.is_encoder_decoder: + dummy_decoder_input_ids = inputs_dict["decoder_input_ids"] + dummy_decoder_attention_mask = inputs_dict["decoder_attention_mask"] + + _ = model(dummy_input, decoder_input_ids=dummy_decoder_input_ids) + # with attention mask + _ = model( + dummy_input, + attention_mask=dummy_attention_mask, + decoder_input_ids=dummy_decoder_input_ids, + decoder_attention_mask=dummy_decoder_attention_mask, + ) + else: + _ = model(dummy_input) + # with attention mask + _ = model(dummy_input, attention_mask=dummy_attention_mask) + + +@slow +class LongcatFlashIntegrationTest(unittest.TestCase): + short_model_id = "hf-internal-testing/LongCat-ShortCat" + # This is a cut-down model that matches part of the early logits of the larger one + # Only a couple experts + layers + # But if it fails, it means the larger model might have issues as well + model_id = "meituan-longcat/LongCat-Flash-Chat" + + @slow + def test_shortcat_generation(self): + self.model = LongcatFlashForCausalLM.from_pretrained( + self.short_model_id, + device_map="auto", + dtype=torch.bfloat16, + ) + self.model.generation_config.bos_token_id = 1 + self.model.generation_config.pad_token_id = 3 + self.model.generation_config.eos_token_id = 2 + self.tokenizer = AutoTokenizer.from_pretrained(self.model_id) + + chat = [{"role": "user", "content": "Paris is..."}] + inputs = self.tokenizer.apply_chat_template( + chat, tokenize=True, add_generation_prompt=True, return_tensors="pt" + ).to(self.model.device) + + with torch.no_grad(): + outputs = self.model.generate(inputs, max_new_tokens=10, do_sample=False) + + response = self.tokenizer.batch_decode(outputs, skip_special_tokens=False)[0] + expected_output = "[Round 0] USER:Paris is... ASSISTANT: dig年车龄juanaheast稍achaotingupebarebones" + + self.assertEqual(response, expected_output) + + @slow + @require_large_cpu_ram + def test_longcat_generation_cpu(self): + # takes absolutely forever and a lot RAM, but allows to test the output in the CI + model = LongcatFlashForCausalLM.from_pretrained(self.model_id, device_map="cpu", dtype=torch.bfloat16) + tokenizer = AutoTokenizer.from_pretrained(self.model_id) + + chat = [{"role": "user", "content": "Paris is..."}] + inputs = tokenizer.apply_chat_template(chat, tokenize=True, add_generation_prompt=True, return_tensors="pt") + + with torch.no_grad(): + outputs = model.generate(inputs, max_new_tokens=10, do_sample=False) + + response = tokenizer.batch_decode(outputs, skip_special_tokens=False)[0] + expected_output = "[Round 0] USER:Paris is... ASSISTANT:Paris is... a city of timeless charm, where" + + self.assertEqual(response, expected_output) From 9baa3d680e8471d5d23d1f2e771cb8c6b7d59cf8 Mon Sep 17 00:00:00 2001 From: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:17:06 -0400 Subject: [PATCH 084/204] [DOC] Add missing dates in model cards (#40922) add missing dates --- docs/source/en/model_doc/apertus.md | 5 ++++- docs/source/en/model_doc/florence2.md | 5 ++++- docs/source/en/model_doc/nllb.md | 18 +++++++++--------- docs/source/en/model_doc/sam2.md | 6 ++++-- docs/source/en/model_doc/sam2_video.md | 6 ++++-- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/docs/source/en/model_doc/apertus.md b/docs/source/en/model_doc/apertus.md index 670cf5c8a77b..ba0bdb230bf9 100644 --- a/docs/source/en/model_doc/apertus.md +++ b/docs/source/en/model_doc/apertus.md @@ -13,6 +13,9 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on 2025-09-02 and added to Hugging Face Transformers on 2025-08-28.* + +# Apertus
@@ -23,7 +26,7 @@ rendered properly in your Markdown viewer.
-# Apertus +## Overview [Apertus](https://www.swiss-ai.org) is a family of large language models from the Swiss AI Initiative. diff --git a/docs/source/en/model_doc/florence2.md b/docs/source/en/model_doc/florence2.md index 148653202067..77e8de10c31b 100644 --- a/docs/source/en/model_doc/florence2.md +++ b/docs/source/en/model_doc/florence2.md @@ -13,6 +13,9 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on 2024-06-16 and added to Hugging Face Transformers on 2025-08-20.* + +# Florence-2
@@ -21,7 +24,7 @@ rendered properly in your Markdown viewer.
-# Florence-2 +## Overview [Florence-2](https://huggingface.co/papers/2311.06242) is an advanced vision foundation model that uses a prompt-based approach to handle a wide range of vision and vision-language tasks. Florence-2 can interpret simple text prompts to perform tasks like captioning, object detection, and segmentation. It leverages the FLD-5B dataset, containing 5.4 billion annotations across 126 million images, to master multi-task learning. The model's sequence-to-sequence architecture enables it to excel in both zero-shot and fine-tuned settings, proving to be a competitive vision foundation model. diff --git a/docs/source/en/model_doc/nllb.md b/docs/source/en/model_doc/nllb.md index 95c3bf3c9d2d..6f12a3aa746b 100644 --- a/docs/source/en/model_doc/nllb.md +++ b/docs/source/en/model_doc/nllb.md @@ -13,6 +13,9 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on 2022-07-11 and added to Hugging Face Transformers on 2022-07-18.* + +# NLLB
@@ -22,10 +25,7 @@ rendered properly in your Markdown viewer.
-*This model was released on 2022-07-11 and added to Hugging Face Transformers on 2022-07-18.* - - -# NLLB +## Overview [NLLB: No Language Left Behind](https://huggingface.co/papers/2207.04672) is a multilingual translation model. It's trained on data using data mining techniques tailored for low-resource languages and supports over 200 languages. NLLB features a conditional compute architecture using a Sparsely Gated Mixture of Experts. @@ -33,7 +33,7 @@ rendered properly in your Markdown viewer. You can find all the original NLLB checkpoints under the [AI at Meta](https://huggingface.co/facebook/models?search=nllb) organization. > [!TIP] -> This model was contributed by [Lysandre](https://huggingface.co/lysandre). +> This model was contributed by [Lysandre](https://huggingface.co/lysandre). > Click on the NLLB models in the right sidebar for more examples of how to apply NLLB to different translation tasks. The example below demonstrates how to translate text with [`Pipeline`] or the [`AutoModel`] class. @@ -120,17 +120,17 @@ visualizer("UN Chief says there is no military solution in Syria") >>> tokenizer("How was your day?").input_ids [256047, 13374, 1398, 4260, 4039, 248130, 2] ``` - + To revert to the legacy behavior, use the code example below. - + ```python >>> from transformers import NllbTokenizer >>> tokenizer = NllbTokenizer.from_pretrained("facebook/nllb-200-distilled-600M", legacy_behaviour=True) ``` - + - For non-English languages, specify the language's [BCP-47](https://github.com/facebookresearch/flores/blob/main/flores200/README.md#languages-in-flores-200) code with the `src_lang` keyword as shown below. - + - See example below for a translation from Romanian to German. ```python >>> from transformers import AutoModelForSeq2SeqLM, AutoTokenizer diff --git a/docs/source/en/model_doc/sam2.md b/docs/source/en/model_doc/sam2.md index 546aa0a0ca88..c2a3fe5acebc 100644 --- a/docs/source/en/model_doc/sam2.md +++ b/docs/source/en/model_doc/sam2.md @@ -13,6 +13,10 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on 2024-07-29 and added to Hugging Face Transformers on 2025-08-14.* + +# SAM2 +
PyTorch @@ -21,8 +25,6 @@ rendered properly in your Markdown viewer.
-# SAM2 - ## Overview SAM2 (Segment Anything Model 2) was proposed in [Segment Anything in Images and Videos](https://ai.meta.com/research/publications/sam-2-segment-anything-in-images-and-videos/) by Nikhila Ravi, Valentin Gabeur, Yuan-Ting Hu, Ronghang Hu, Chaitanya Ryali, Tengyu Ma, Haitham Khedr, Roman Rädle, Chloe Rolland, Laura Gustafson, Eric Mintun, Junting Pan, Kalyan Vasudev Alwala, Nicolas Carion, Chao-Yuan Wu, Ross Girshick, Piotr Dollár, Christoph Feichtenhofer. diff --git a/docs/source/en/model_doc/sam2_video.md b/docs/source/en/model_doc/sam2_video.md index 1f773be30738..330955592650 100644 --- a/docs/source/en/model_doc/sam2_video.md +++ b/docs/source/en/model_doc/sam2_video.md @@ -13,6 +13,10 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on 2024-07-29 and added to Hugging Face Transformers on 2025-08-14.* + +# SAM2 Video +
PyTorch @@ -21,8 +25,6 @@ rendered properly in your Markdown viewer.
-# SAM2 Video - ## Overview SAM2 (Segment Anything Model 2) was proposed in [Segment Anything in Images and Videos](https://ai.meta.com/research/publications/sam-2-segment-anything-in-images-and-videos/) by Nikhila Ravi, Valentin Gabeur, Yuan-Ting Hu, Ronghang Hu, Chaitanya Ryali, Tengyu Ma, Haitham Khedr, Roman Rädle, Chloe Rolland, Laura Gustafson, Eric Mintun, Junting Pan, Kalyan Vasudev Alwala, Nicolas Carion, Chao-Yuan Wu, Ross Girshick, Piotr Dollár, Christoph Feichtenhofer. From dccd2df9e5e5cf3305ca8905551128a09ee1a8ac Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Wed, 17 Sep 2025 16:37:56 +0100 Subject: [PATCH 085/204] [models] remove unused `import torch.utils.checkpoint` (#40934) --- src/transformers/models/align/modeling_align.py | 1 - src/transformers/models/altclip/modeling_altclip.py | 1 - .../modeling_audio_spectrogram_transformer.py | 1 - src/transformers/models/autoformer/modeling_autoformer.py | 1 - src/transformers/models/bamba/modular_bamba.py | 1 - src/transformers/models/bart/modeling_bart.py | 1 - src/transformers/models/beit/modeling_beit.py | 1 - src/transformers/models/bert/modeling_bert.py | 1 - .../models/bert_generation/modeling_bert_generation.py | 1 - src/transformers/models/big_bird/modeling_big_bird.py | 1 - src/transformers/models/biogpt/modular_biogpt.py | 1 - src/transformers/models/bit/modeling_bit.py | 1 - src/transformers/models/blenderbot/modeling_blenderbot.py | 1 - .../models/blenderbot_small/modeling_blenderbot_small.py | 1 - src/transformers/models/blip/modeling_blip.py | 1 - src/transformers/models/blip/modeling_blip_text.py | 1 - src/transformers/models/blip_2/modeling_blip_2.py | 1 - src/transformers/models/bloom/modeling_bloom.py | 1 - src/transformers/models/bridgetower/modeling_bridgetower.py | 1 - src/transformers/models/bros/modeling_bros.py | 1 - src/transformers/models/camembert/modeling_camembert.py | 1 - src/transformers/models/canine/modeling_canine.py | 1 - src/transformers/models/chameleon/modeling_chameleon.py | 1 - src/transformers/models/chinese_clip/modeling_chinese_clip.py | 1 - src/transformers/models/clipseg/modeling_clipseg.py | 1 - src/transformers/models/clvp/modeling_clvp.py | 1 - src/transformers/models/codegen/modeling_codegen.py | 1 - src/transformers/models/cohere/modular_cohere.py | 1 - src/transformers/models/convbert/modeling_convbert.py | 1 - src/transformers/models/convnext/modeling_convnext.py | 1 - src/transformers/models/convnextv2/modeling_convnextv2.py | 1 - src/transformers/models/cpmant/modeling_cpmant.py | 1 - src/transformers/models/cvt/modeling_cvt.py | 1 - src/transformers/models/data2vec/modeling_data2vec_text.py | 1 - src/transformers/models/data2vec/modeling_data2vec_vision.py | 1 - src/transformers/models/dbrx/modeling_dbrx.py | 1 - src/transformers/models/deberta/modeling_deberta.py | 1 - src/transformers/models/deberta_v2/modeling_deberta_v2.py | 1 - .../decision_transformer/modeling_decision_transformer.py | 1 - src/transformers/models/deepseek_v3/modular_deepseek_v3.py | 1 - src/transformers/models/deit/modeling_deit.py | 1 - .../deprecated/efficientformer/modeling_efficientformer.py | 1 - src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py | 1 - src/transformers/models/deprecated/mctct/modeling_mctct.py | 1 - src/transformers/models/deprecated/mega/modeling_mega.py | 1 - src/transformers/models/deprecated/nat/modeling_nat.py | 1 - src/transformers/models/deprecated/nezha/modeling_nezha.py | 1 - .../models/deprecated/open_llama/modeling_open_llama.py | 1 - src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py | 1 - .../trajectory_transformer/modeling_trajectory_transformer.py | 1 - src/transformers/models/deprecated/tvlt/modeling_tvlt.py | 1 - src/transformers/models/deprecated/van/modeling_van.py | 1 - .../models/deprecated/vit_hybrid/modeling_vit_hybrid.py | 1 - .../models/deprecated/xlm_prophetnet/modeling_xlm_prophetnet.py | 1 - .../models/depth_anything/modeling_depth_anything.py | 1 - src/transformers/models/dinat/modeling_dinat.py | 1 - src/transformers/models/dinov2/modeling_dinov2.py | 1 - .../dinov2_with_registers/modular_dinov2_with_registers.py | 1 - .../models/dinov3_convnext/modeling_dinov3_convnext.py | 1 - src/transformers/models/dinov3_vit/modular_dinov3_vit.py | 1 - src/transformers/models/donut/modeling_donut_swin.py | 1 - src/transformers/models/dpt/modeling_dpt.py | 1 - src/transformers/models/efficientnet/modeling_efficientnet.py | 1 - src/transformers/models/electra/modeling_electra.py | 1 - src/transformers/models/emu3/modular_emu3.py | 1 - src/transformers/models/ernie/modeling_ernie.py | 1 - src/transformers/models/esm/modeling_esm.py | 1 - src/transformers/models/evolla/modular_evolla.py | 1 - src/transformers/models/falcon/modeling_falcon.py | 1 - src/transformers/models/falcon_h1/modular_falcon_h1.py | 1 - src/transformers/models/falcon_mamba/modular_falcon_mamba.py | 1 - src/transformers/models/flava/modeling_flava.py | 1 - src/transformers/models/fnet/modeling_fnet.py | 1 - src/transformers/models/focalnet/modeling_focalnet.py | 1 - src/transformers/models/fuyu/modeling_fuyu.py | 1 - src/transformers/models/gemma2/modular_gemma2.py | 1 - src/transformers/models/gemma3/modular_gemma3.py | 1 - src/transformers/models/git/modeling_git.py | 1 - src/transformers/models/glm/modular_glm.py | 1 - src/transformers/models/glm4_moe/modular_glm4_moe.py | 1 - src/transformers/models/glpn/modeling_glpn.py | 1 - src/transformers/models/gpt2/modeling_gpt2.py | 1 - src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py | 1 - src/transformers/models/gpt_neo/modeling_gpt_neo.py | 1 - src/transformers/models/gpt_neox/modular_gpt_neox.py | 1 - .../models/gpt_neox_japanese/modeling_gpt_neox_japanese.py | 1 - src/transformers/models/gptj/modeling_gptj.py | 1 - src/transformers/models/granite/modular_granite.py | 1 - src/transformers/models/groupvit/modeling_groupvit.py | 1 - src/transformers/models/helium/modular_helium.py | 1 - src/transformers/models/hiera/modeling_hiera.py | 1 - .../models/hunyuan_v1_dense/modular_hunyuan_v1_dense.py | 1 - .../models/hunyuan_v1_moe/modular_hunyuan_v1_moe.py | 1 - src/transformers/models/ibert/modeling_ibert.py | 1 - src/transformers/models/idefics/modeling_idefics.py | 1 - src/transformers/models/idefics/vision.py | 1 - src/transformers/models/idefics2/modeling_idefics2.py | 1 - src/transformers/models/idefics3/modeling_idefics3.py | 1 - src/transformers/models/imagegpt/modeling_imagegpt.py | 1 - src/transformers/models/instructblip/modeling_instructblip.py | 1 - .../models/instructblipvideo/modular_instructblipvideo.py | 1 - src/transformers/models/internvl/modular_internvl.py | 1 - src/transformers/models/jamba/modeling_jamba.py | 1 - src/transformers/models/janus/modular_janus.py | 2 +- src/transformers/models/jetmoe/modeling_jetmoe.py | 1 - src/transformers/models/kosmos2/modeling_kosmos2.py | 1 - src/transformers/models/kosmos2_5/modeling_kosmos2_5.py | 1 - src/transformers/models/layoutlm/modeling_layoutlm.py | 1 - src/transformers/models/layoutlmv2/modeling_layoutlmv2.py | 1 - src/transformers/models/layoutlmv3/modeling_layoutlmv3.py | 1 - src/transformers/models/led/modeling_led.py | 1 - src/transformers/models/levit/modeling_levit.py | 1 - src/transformers/models/lilt/modeling_lilt.py | 1 - src/transformers/models/llava/modeling_llava.py | 1 - src/transformers/models/longformer/modeling_longformer.py | 1 - src/transformers/models/luke/modeling_luke.py | 1 - src/transformers/models/mamba/modeling_mamba.py | 1 - src/transformers/models/mamba2/modeling_mamba2.py | 1 - src/transformers/models/marian/modeling_marian.py | 1 - src/transformers/models/markuplm/modeling_markuplm.py | 1 - src/transformers/models/mbart/modeling_mbart.py | 1 - src/transformers/models/megatron_bert/modeling_megatron_bert.py | 1 - src/transformers/models/mgp_str/modeling_mgp_str.py | 1 - src/transformers/models/mimi/modeling_mimi.py | 1 - src/transformers/models/mixtral/modular_mixtral.py | 1 - src/transformers/models/mllama/modeling_mllama.py | 1 - src/transformers/models/mobilevit/modeling_mobilevit.py | 1 - src/transformers/models/mobilevitv2/modeling_mobilevitv2.py | 1 - src/transformers/models/modernbert/modular_modernbert.py | 1 - src/transformers/models/moshi/modeling_moshi.py | 1 - src/transformers/models/mpt/modeling_mpt.py | 1 - src/transformers/models/mra/modeling_mra.py | 1 - src/transformers/models/mvp/modeling_mvp.py | 1 - src/transformers/models/nemotron/modeling_nemotron.py | 1 - src/transformers/models/nystromformer/modeling_nystromformer.py | 1 - src/transformers/models/olmo/modular_olmo.py | 1 - src/transformers/models/olmoe/modeling_olmoe.py | 1 - src/transformers/models/opt/modeling_opt.py | 1 - src/transformers/models/owlv2/modeling_owlv2.py | 1 - src/transformers/models/owlvit/modeling_owlvit.py | 1 - src/transformers/models/paligemma/modeling_paligemma.py | 1 - src/transformers/models/pegasus/modeling_pegasus.py | 1 - src/transformers/models/pegasus_x/modeling_pegasus_x.py | 1 - src/transformers/models/perceiver/modeling_perceiver.py | 1 - src/transformers/models/perception_lm/modular_perception_lm.py | 1 - src/transformers/models/persimmon/modeling_persimmon.py | 1 - src/transformers/models/phi3/modular_phi3.py | 1 - src/transformers/models/phimoe/modeling_phimoe.py | 1 - src/transformers/models/pix2struct/modeling_pix2struct.py | 1 - src/transformers/models/pixtral/modeling_pixtral.py | 1 - src/transformers/models/plbart/modular_plbart.py | 1 - src/transformers/models/poolformer/modeling_poolformer.py | 1 - src/transformers/models/prophetnet/modeling_prophetnet.py | 1 - src/transformers/models/pvt/modeling_pvt.py | 1 - src/transformers/models/pvt_v2/modeling_pvt_v2.py | 1 - src/transformers/models/qwen2/modular_qwen2.py | 1 - src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py | 1 - src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py | 1 - src/transformers/models/qwen2_moe/modeling_qwen2_moe.py | 1 - src/transformers/models/qwen2_vl/modeling_qwen2_vl.py | 1 - src/transformers/models/qwen3_moe/modular_qwen3_moe.py | 1 - src/transformers/models/qwen3_next/modular_qwen3_next.py | 1 - .../models/recurrent_gemma/modeling_recurrent_gemma.py | 1 - src/transformers/models/regnet/modeling_regnet.py | 1 - src/transformers/models/rembert/modeling_rembert.py | 1 - src/transformers/models/resnet/modeling_resnet.py | 1 - src/transformers/models/roberta/modeling_roberta.py | 1 - .../roberta_prelayernorm/modeling_roberta_prelayernorm.py | 1 - src/transformers/models/roc_bert/modeling_roc_bert.py | 1 - src/transformers/models/roformer/modeling_roformer.py | 1 - src/transformers/models/rwkv/modeling_rwkv.py | 1 - src/transformers/models/sam2/modular_sam2.py | 1 - src/transformers/models/sam2_video/modular_sam2_video.py | 1 - src/transformers/models/seamless_m4t/modeling_seamless_m4t.py | 1 - .../models/seamless_m4t_v2/modeling_seamless_m4t_v2.py | 1 - src/transformers/models/segformer/modeling_segformer.py | 1 - src/transformers/models/seggpt/modeling_seggpt.py | 1 - src/transformers/models/sew/modular_sew.py | 1 - src/transformers/models/sew_d/modeling_sew_d.py | 1 - src/transformers/models/shieldgemma2/modeling_shieldgemma2.py | 1 - src/transformers/models/smolvlm/modular_smolvlm.py | 1 - src/transformers/models/speecht5/modeling_speecht5.py | 1 - src/transformers/models/splinter/modeling_splinter.py | 1 - src/transformers/models/stablelm/modeling_stablelm.py | 1 - src/transformers/models/starcoder2/modular_starcoder2.py | 1 - src/transformers/models/swiftformer/modeling_swiftformer.py | 1 - src/transformers/models/swin/modeling_swin.py | 1 - src/transformers/models/swin2sr/modeling_swin2sr.py | 1 - src/transformers/models/swinv2/modeling_swinv2.py | 1 - src/transformers/models/tapas/modeling_tapas.py | 1 - src/transformers/models/timesformer/modeling_timesformer.py | 1 - src/transformers/models/tvp/modeling_tvp.py | 1 - src/transformers/models/univnet/modeling_univnet.py | 1 - src/transformers/models/video_llava/modeling_video_llava.py | 1 - src/transformers/models/videomae/modeling_videomae.py | 1 - src/transformers/models/vilt/modeling_vilt.py | 1 - src/transformers/models/visual_bert/modeling_visual_bert.py | 1 - src/transformers/models/vit/modeling_vit.py | 1 - src/transformers/models/vit_mae/modeling_vit_mae.py | 1 - src/transformers/models/vit_msn/modeling_vit_msn.py | 1 - src/transformers/models/vitdet/modeling_vitdet.py | 1 - src/transformers/models/vitpose/modeling_vitpose.py | 1 - .../models/vitpose_backbone/modeling_vitpose_backbone.py | 1 - src/transformers/models/vits/modeling_vits.py | 1 - src/transformers/models/vivit/modeling_vivit.py | 1 - src/transformers/models/wav2vec2/modeling_wav2vec2.py | 1 - src/transformers/models/whisper/modeling_whisper.py | 1 - src/transformers/models/x_clip/modeling_x_clip.py | 1 - src/transformers/models/xglm/modeling_xglm.py | 1 - src/transformers/models/xlm_roberta/modeling_xlm_roberta.py | 1 - .../models/xlm_roberta_xl/modeling_xlm_roberta_xl.py | 1 - src/transformers/models/xlstm/modeling_xlstm.py | 1 - src/transformers/models/xmod/modeling_xmod.py | 1 - src/transformers/models/yolos/modeling_yolos.py | 1 - src/transformers/models/yoso/modeling_yoso.py | 1 - src/transformers/models/zamba/modeling_zamba.py | 1 - src/transformers/models/zamba2/modular_zamba2.py | 1 - src/transformers/models/zoedepth/modeling_zoedepth.py | 1 - 218 files changed, 1 insertion(+), 218 deletions(-) diff --git a/src/transformers/models/align/modeling_align.py b/src/transformers/models/align/modeling_align.py index 063b3312ccc5..c226a3b36ac6 100644 --- a/src/transformers/models/align/modeling_align.py +++ b/src/transformers/models/align/modeling_align.py @@ -19,7 +19,6 @@ from typing import Any, Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/altclip/modeling_altclip.py b/src/transformers/models/altclip/modeling_altclip.py index 8b98548d0bfe..61468141c570 100755 --- a/src/transformers/models/altclip/modeling_altclip.py +++ b/src/transformers/models/altclip/modeling_altclip.py @@ -20,7 +20,6 @@ import torch import torch.nn as nn -import torch.utils.checkpoint from ...activations import ACT2FN from ...modeling_layers import GradientCheckpointingLayer diff --git a/src/transformers/models/audio_spectrogram_transformer/modeling_audio_spectrogram_transformer.py b/src/transformers/models/audio_spectrogram_transformer/modeling_audio_spectrogram_transformer.py index 516dc4187885..c445fbb0e36d 100644 --- a/src/transformers/models/audio_spectrogram_transformer/modeling_audio_spectrogram_transformer.py +++ b/src/transformers/models/audio_spectrogram_transformer/modeling_audio_spectrogram_transformer.py @@ -17,7 +17,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/autoformer/modeling_autoformer.py b/src/transformers/models/autoformer/modeling_autoformer.py index efa952a5a28b..fe11fc4c4860 100644 --- a/src/transformers/models/autoformer/modeling_autoformer.py +++ b/src/transformers/models/autoformer/modeling_autoformer.py @@ -22,7 +22,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/bamba/modular_bamba.py b/src/transformers/models/bamba/modular_bamba.py index 52814930a172..f2495b446aa5 100644 --- a/src/transformers/models/bamba/modular_bamba.py +++ b/src/transformers/models/bamba/modular_bamba.py @@ -22,7 +22,6 @@ from typing import Optional, TypedDict, Union import torch -import torch.utils.checkpoint from torch import nn from transformers.activations import ACT2FN diff --git a/src/transformers/models/bart/modeling_bart.py b/src/transformers/models/bart/modeling_bart.py index 55c7654fe2e5..0a1f2451cff1 100755 --- a/src/transformers/models/bart/modeling_bart.py +++ b/src/transformers/models/bart/modeling_bart.py @@ -19,7 +19,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/beit/modeling_beit.py b/src/transformers/models/beit/modeling_beit.py index 09c887bcd2b4..cb4e0d712651 100755 --- a/src/transformers/models/beit/modeling_beit.py +++ b/src/transformers/models/beit/modeling_beit.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/bert/modeling_bert.py b/src/transformers/models/bert/modeling_bert.py index 20edbf6383c5..b9238d8bb071 100755 --- a/src/transformers/models/bert/modeling_bert.py +++ b/src/transformers/models/bert/modeling_bert.py @@ -22,7 +22,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/bert_generation/modeling_bert_generation.py b/src/transformers/models/bert_generation/modeling_bert_generation.py index f29d22d06f83..4be87a0cd544 100755 --- a/src/transformers/models/bert_generation/modeling_bert_generation.py +++ b/src/transformers/models/bert_generation/modeling_bert_generation.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/big_bird/modeling_big_bird.py b/src/transformers/models/big_bird/modeling_big_bird.py index 20a5a08c246a..f42b1eeaeeb1 100755 --- a/src/transformers/models/big_bird/modeling_big_bird.py +++ b/src/transformers/models/big_bird/modeling_big_bird.py @@ -21,7 +21,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/biogpt/modular_biogpt.py b/src/transformers/models/biogpt/modular_biogpt.py index 5753e066913f..001c1de65756 100644 --- a/src/transformers/models/biogpt/modular_biogpt.py +++ b/src/transformers/models/biogpt/modular_biogpt.py @@ -19,7 +19,6 @@ import torch import torch.nn as nn -import torch.utils.checkpoint from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN diff --git a/src/transformers/models/bit/modeling_bit.py b/src/transformers/models/bit/modeling_bit.py index ec778380b6ba..1e491f06eae6 100644 --- a/src/transformers/models/bit/modeling_bit.py +++ b/src/transformers/models/bit/modeling_bit.py @@ -20,7 +20,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import Tensor, nn from ...activations import ACT2FN diff --git a/src/transformers/models/blenderbot/modeling_blenderbot.py b/src/transformers/models/blenderbot/modeling_blenderbot.py index 56561612bac2..3e25fad20d31 100755 --- a/src/transformers/models/blenderbot/modeling_blenderbot.py +++ b/src/transformers/models/blenderbot/modeling_blenderbot.py @@ -20,7 +20,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py b/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py index 556fbeb4d0cb..e0e404f27cf8 100755 --- a/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py +++ b/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py @@ -18,7 +18,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/blip/modeling_blip.py b/src/transformers/models/blip/modeling_blip.py index c3b5821601fb..f979518e9e11 100644 --- a/src/transformers/models/blip/modeling_blip.py +++ b/src/transformers/models/blip/modeling_blip.py @@ -19,7 +19,6 @@ from typing import Any, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn.functional import normalize diff --git a/src/transformers/models/blip/modeling_blip_text.py b/src/transformers/models/blip/modeling_blip_text.py index 0eb140685fda..6f1f58c75334 100644 --- a/src/transformers/models/blip/modeling_blip_text.py +++ b/src/transformers/models/blip/modeling_blip_text.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, device, nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/blip_2/modeling_blip_2.py b/src/transformers/models/blip_2/modeling_blip_2.py index 6a488fba8f5a..b552df47f2fc 100644 --- a/src/transformers/models/blip_2/modeling_blip_2.py +++ b/src/transformers/models/blip_2/modeling_blip_2.py @@ -20,7 +20,6 @@ from typing import Any, Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/bloom/modeling_bloom.py b/src/transformers/models/bloom/modeling_bloom.py index 605ae4f59b63..6fde63e03b4d 100644 --- a/src/transformers/models/bloom/modeling_bloom.py +++ b/src/transformers/models/bloom/modeling_bloom.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, LayerNorm, MSELoss from torch.nn import functional as F diff --git a/src/transformers/models/bridgetower/modeling_bridgetower.py b/src/transformers/models/bridgetower/modeling_bridgetower.py index 2c798fcf4772..59c5be00c316 100644 --- a/src/transformers/models/bridgetower/modeling_bridgetower.py +++ b/src/transformers/models/bridgetower/modeling_bridgetower.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/bros/modeling_bros.py b/src/transformers/models/bros/modeling_bros.py index f12b47081d6a..d01a4c5a1c6d 100755 --- a/src/transformers/models/bros/modeling_bros.py +++ b/src/transformers/models/bros/modeling_bros.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/camembert/modeling_camembert.py b/src/transformers/models/camembert/modeling_camembert.py index f566bab0b8ed..3a07402f739a 100644 --- a/src/transformers/models/camembert/modeling_camembert.py +++ b/src/transformers/models/camembert/modeling_camembert.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/canine/modeling_canine.py b/src/transformers/models/canine/modeling_canine.py index 1f83c15b4f96..585961180f9e 100644 --- a/src/transformers/models/canine/modeling_canine.py +++ b/src/transformers/models/canine/modeling_canine.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/chameleon/modeling_chameleon.py b/src/transformers/models/chameleon/modeling_chameleon.py index 6b2ab15bbb9e..033b8ecd7c63 100644 --- a/src/transformers/models/chameleon/modeling_chameleon.py +++ b/src/transformers/models/chameleon/modeling_chameleon.py @@ -19,7 +19,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/chinese_clip/modeling_chinese_clip.py b/src/transformers/models/chinese_clip/modeling_chinese_clip.py index c10d0c855ce1..a0b461ab3ed3 100644 --- a/src/transformers/models/chinese_clip/modeling_chinese_clip.py +++ b/src/transformers/models/chinese_clip/modeling_chinese_clip.py @@ -18,7 +18,6 @@ from typing import Any, Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/clipseg/modeling_clipseg.py b/src/transformers/models/clipseg/modeling_clipseg.py index 5938aebd1ff5..3db986aa040f 100644 --- a/src/transformers/models/clipseg/modeling_clipseg.py +++ b/src/transformers/models/clipseg/modeling_clipseg.py @@ -20,7 +20,6 @@ from typing import Any, Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/clvp/modeling_clvp.py b/src/transformers/models/clvp/modeling_clvp.py index acef62d5da21..552434b5bb22 100644 --- a/src/transformers/models/clvp/modeling_clvp.py +++ b/src/transformers/models/clvp/modeling_clvp.py @@ -21,7 +21,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/codegen/modeling_codegen.py b/src/transformers/models/codegen/modeling_codegen.py index 6ccb502766cb..887b400b4799 100644 --- a/src/transformers/models/codegen/modeling_codegen.py +++ b/src/transformers/models/codegen/modeling_codegen.py @@ -17,7 +17,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/cohere/modular_cohere.py b/src/transformers/models/cohere/modular_cohere.py index 62b6b1988daa..daa12a15ed26 100644 --- a/src/transformers/models/cohere/modular_cohere.py +++ b/src/transformers/models/cohere/modular_cohere.py @@ -25,7 +25,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...cache_utils import Cache diff --git a/src/transformers/models/convbert/modeling_convbert.py b/src/transformers/models/convbert/modeling_convbert.py index 130cf183849e..080b93fa92a6 100755 --- a/src/transformers/models/convbert/modeling_convbert.py +++ b/src/transformers/models/convbert/modeling_convbert.py @@ -20,7 +20,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/convnext/modeling_convnext.py b/src/transformers/models/convnext/modeling_convnext.py index b61d18ed7294..3120c140d2ed 100755 --- a/src/transformers/models/convnext/modeling_convnext.py +++ b/src/transformers/models/convnext/modeling_convnext.py @@ -17,7 +17,6 @@ from typing import Optional import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/convnextv2/modeling_convnextv2.py b/src/transformers/models/convnextv2/modeling_convnextv2.py index a5fe43f84c8b..bfa5338f5e86 100644 --- a/src/transformers/models/convnextv2/modeling_convnextv2.py +++ b/src/transformers/models/convnextv2/modeling_convnextv2.py @@ -17,7 +17,6 @@ from typing import Optional import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/cpmant/modeling_cpmant.py b/src/transformers/models/cpmant/modeling_cpmant.py index 8eb5bc4d1968..1930cc0e8793 100755 --- a/src/transformers/models/cpmant/modeling_cpmant.py +++ b/src/transformers/models/cpmant/modeling_cpmant.py @@ -19,7 +19,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/cvt/modeling_cvt.py b/src/transformers/models/cvt/modeling_cvt.py index 85e2bde325e2..9d935ee84893 100644 --- a/src/transformers/models/cvt/modeling_cvt.py +++ b/src/transformers/models/cvt/modeling_cvt.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/data2vec/modeling_data2vec_text.py b/src/transformers/models/data2vec/modeling_data2vec_text.py index 9d52c9953307..f866dd9144a6 100644 --- a/src/transformers/models/data2vec/modeling_data2vec_text.py +++ b/src/transformers/models/data2vec/modeling_data2vec_text.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/data2vec/modeling_data2vec_vision.py b/src/transformers/models/data2vec/modeling_data2vec_vision.py index 6d76852122ac..f214f8eb6a0b 100644 --- a/src/transformers/models/data2vec/modeling_data2vec_vision.py +++ b/src/transformers/models/data2vec/modeling_data2vec_vision.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/dbrx/modeling_dbrx.py b/src/transformers/models/dbrx/modeling_dbrx.py index ab3ddce51310..5f3a423213cb 100644 --- a/src/transformers/models/dbrx/modeling_dbrx.py +++ b/src/transformers/models/dbrx/modeling_dbrx.py @@ -18,7 +18,6 @@ from typing import Any, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/deberta/modeling_deberta.py b/src/transformers/models/deberta/modeling_deberta.py index 0e298f52297a..461572b47677 100644 --- a/src/transformers/models/deberta/modeling_deberta.py +++ b/src/transformers/models/deberta/modeling_deberta.py @@ -17,7 +17,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/deberta_v2/modeling_deberta_v2.py b/src/transformers/models/deberta_v2/modeling_deberta_v2.py index 047d4b3acd25..9d06f00c0ce6 100644 --- a/src/transformers/models/deberta_v2/modeling_deberta_v2.py +++ b/src/transformers/models/deberta_v2/modeling_deberta_v2.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, LayerNorm, MSELoss diff --git a/src/transformers/models/decision_transformer/modeling_decision_transformer.py b/src/transformers/models/decision_transformer/modeling_decision_transformer.py index 3ac0ab038219..f9c68fcbdeae 100755 --- a/src/transformers/models/decision_transformer/modeling_decision_transformer.py +++ b/src/transformers/models/decision_transformer/modeling_decision_transformer.py @@ -20,7 +20,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/deepseek_v3/modular_deepseek_v3.py b/src/transformers/models/deepseek_v3/modular_deepseek_v3.py index 38cc8dbb5ea1..fc3dc0c4ce3b 100644 --- a/src/transformers/models/deepseek_v3/modular_deepseek_v3.py +++ b/src/transformers/models/deepseek_v3/modular_deepseek_v3.py @@ -3,7 +3,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/deit/modeling_deit.py b/src/transformers/models/deit/modeling_deit.py index 6a6be311137d..4015dcbe0bc3 100644 --- a/src/transformers/models/deit/modeling_deit.py +++ b/src/transformers/models/deit/modeling_deit.py @@ -19,7 +19,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py b/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py index 3d918e7f5720..d35d3e82c007 100644 --- a/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py +++ b/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ....activations import ACT2FN diff --git a/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py b/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py index 90f215157b7e..f0e97c132d09 100755 --- a/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py +++ b/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn, tensor from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/deprecated/mctct/modeling_mctct.py b/src/transformers/models/deprecated/mctct/modeling_mctct.py index 3c9d259e8215..253b09c1c43c 100755 --- a/src/transformers/models/deprecated/mctct/modeling_mctct.py +++ b/src/transformers/models/deprecated/mctct/modeling_mctct.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ....activations import ACT2FN diff --git a/src/transformers/models/deprecated/mega/modeling_mega.py b/src/transformers/models/deprecated/mega/modeling_mega.py index c6edc57f8cf6..c237afee9a33 100644 --- a/src/transformers/models/deprecated/mega/modeling_mega.py +++ b/src/transformers/models/deprecated/mega/modeling_mega.py @@ -19,7 +19,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/deprecated/nat/modeling_nat.py b/src/transformers/models/deprecated/nat/modeling_nat.py index d463e2bc89cc..a619cdb11225 100644 --- a/src/transformers/models/deprecated/nat/modeling_nat.py +++ b/src/transformers/models/deprecated/nat/modeling_nat.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ....activations import ACT2FN diff --git a/src/transformers/models/deprecated/nezha/modeling_nezha.py b/src/transformers/models/deprecated/nezha/modeling_nezha.py index 3dd67c22d72e..ddfecac9f506 100644 --- a/src/transformers/models/deprecated/nezha/modeling_nezha.py +++ b/src/transformers/models/deprecated/nezha/modeling_nezha.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/deprecated/open_llama/modeling_open_llama.py b/src/transformers/models/deprecated/open_llama/modeling_open_llama.py index 4ce63feceb74..5e182e0f813f 100644 --- a/src/transformers/models/deprecated/open_llama/modeling_open_llama.py +++ b/src/transformers/models/deprecated/open_llama/modeling_open_llama.py @@ -23,7 +23,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py b/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py index 74bad366e8d5..f92bc07a8bfb 100755 --- a/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py +++ b/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py b/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py index dcacffabc8b9..b6ae410c1474 100644 --- a/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py +++ b/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py @@ -21,7 +21,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import functional as F diff --git a/src/transformers/models/deprecated/tvlt/modeling_tvlt.py b/src/transformers/models/deprecated/tvlt/modeling_tvlt.py index 5f34083ac2ff..2b21df928ff3 100644 --- a/src/transformers/models/deprecated/tvlt/modeling_tvlt.py +++ b/src/transformers/models/deprecated/tvlt/modeling_tvlt.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/deprecated/van/modeling_van.py b/src/transformers/models/deprecated/van/modeling_van.py index 025234e4e71f..c0fc0bc1a637 100644 --- a/src/transformers/models/deprecated/van/modeling_van.py +++ b/src/transformers/models/deprecated/van/modeling_van.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ....activations import ACT2FN diff --git a/src/transformers/models/deprecated/vit_hybrid/modeling_vit_hybrid.py b/src/transformers/models/deprecated/vit_hybrid/modeling_vit_hybrid.py index 2d92655cc3e4..86b1594a20c9 100644 --- a/src/transformers/models/deprecated/vit_hybrid/modeling_vit_hybrid.py +++ b/src/transformers/models/deprecated/vit_hybrid/modeling_vit_hybrid.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ....activations import ACT2FN diff --git a/src/transformers/models/deprecated/xlm_prophetnet/modeling_xlm_prophetnet.py b/src/transformers/models/deprecated/xlm_prophetnet/modeling_xlm_prophetnet.py index e85660223b58..3c4dc3de8393 100644 --- a/src/transformers/models/deprecated/xlm_prophetnet/modeling_xlm_prophetnet.py +++ b/src/transformers/models/deprecated/xlm_prophetnet/modeling_xlm_prophetnet.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, nn from torch.nn import LayerNorm diff --git a/src/transformers/models/depth_anything/modeling_depth_anything.py b/src/transformers/models/depth_anything/modeling_depth_anything.py index 06a3a8d300b8..bc7d74131204 100644 --- a/src/transformers/models/depth_anything/modeling_depth_anything.py +++ b/src/transformers/models/depth_anything/modeling_depth_anything.py @@ -17,7 +17,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...modeling_outputs import DepthEstimatorOutput diff --git a/src/transformers/models/dinat/modeling_dinat.py b/src/transformers/models/dinat/modeling_dinat.py index 384bdee49d35..4b7ec37b0ea8 100644 --- a/src/transformers/models/dinat/modeling_dinat.py +++ b/src/transformers/models/dinat/modeling_dinat.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/dinov2/modeling_dinov2.py b/src/transformers/models/dinov2/modeling_dinov2.py index 96a051327e01..0a9a2cba1da7 100644 --- a/src/transformers/models/dinov2/modeling_dinov2.py +++ b/src/transformers/models/dinov2/modeling_dinov2.py @@ -18,7 +18,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/dinov2_with_registers/modular_dinov2_with_registers.py b/src/transformers/models/dinov2_with_registers/modular_dinov2_with_registers.py index c23e523e3434..686528002b09 100644 --- a/src/transformers/models/dinov2_with_registers/modular_dinov2_with_registers.py +++ b/src/transformers/models/dinov2_with_registers/modular_dinov2_with_registers.py @@ -17,7 +17,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ....transformers.models.dinov2.modeling_dinov2 import ( diff --git a/src/transformers/models/dinov3_convnext/modeling_dinov3_convnext.py b/src/transformers/models/dinov3_convnext/modeling_dinov3_convnext.py index 2318faf14824..df2ef491192c 100644 --- a/src/transformers/models/dinov3_convnext/modeling_dinov3_convnext.py +++ b/src/transformers/models/dinov3_convnext/modeling_dinov3_convnext.py @@ -18,7 +18,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/dinov3_vit/modular_dinov3_vit.py b/src/transformers/models/dinov3_vit/modular_dinov3_vit.py index f4a1e69beaac..0515a1a1e0bf 100644 --- a/src/transformers/models/dinov3_vit/modular_dinov3_vit.py +++ b/src/transformers/models/dinov3_vit/modular_dinov3_vit.py @@ -19,7 +19,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from transformers.models.arcee.modeling_arcee import ArceeMLP diff --git a/src/transformers/models/donut/modeling_donut_swin.py b/src/transformers/models/donut/modeling_donut_swin.py index 882fd72c508e..c5736b16183b 100644 --- a/src/transformers/models/donut/modeling_donut_swin.py +++ b/src/transformers/models/donut/modeling_donut_swin.py @@ -23,7 +23,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/dpt/modeling_dpt.py b/src/transformers/models/dpt/modeling_dpt.py index f797f53aa4b6..363fce92f897 100755 --- a/src/transformers/models/dpt/modeling_dpt.py +++ b/src/transformers/models/dpt/modeling_dpt.py @@ -24,7 +24,6 @@ from typing import Callable, Optional import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/efficientnet/modeling_efficientnet.py b/src/transformers/models/efficientnet/modeling_efficientnet.py index 70ec3914f7de..a263ff20760c 100644 --- a/src/transformers/models/efficientnet/modeling_efficientnet.py +++ b/src/transformers/models/efficientnet/modeling_efficientnet.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/electra/modeling_electra.py b/src/transformers/models/electra/modeling_electra.py index 9327bc0fdf26..a10b0b658337 100644 --- a/src/transformers/models/electra/modeling_electra.py +++ b/src/transformers/models/electra/modeling_electra.py @@ -20,7 +20,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/emu3/modular_emu3.py b/src/transformers/models/emu3/modular_emu3.py index 5dd8d02f61aa..32599727b24c 100644 --- a/src/transformers/models/emu3/modular_emu3.py +++ b/src/transformers/models/emu3/modular_emu3.py @@ -21,7 +21,6 @@ import torch import torch.nn as nn import torch.nn.functional as F -import torch.utils.checkpoint from ...cache_utils import Cache from ...generation import GenerationMixin diff --git a/src/transformers/models/ernie/modeling_ernie.py b/src/transformers/models/ernie/modeling_ernie.py index a5ed4a3f5328..7cbce6b2d20b 100644 --- a/src/transformers/models/ernie/modeling_ernie.py +++ b/src/transformers/models/ernie/modeling_ernie.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/esm/modeling_esm.py b/src/transformers/models/esm/modeling_esm.py index 5db366aa6197..ddcf460f01ee 100755 --- a/src/transformers/models/esm/modeling_esm.py +++ b/src/transformers/models/esm/modeling_esm.py @@ -19,7 +19,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/evolla/modular_evolla.py b/src/transformers/models/evolla/modular_evolla.py index a58a3e7b7341..18a50e9abfae 100644 --- a/src/transformers/models/evolla/modular_evolla.py +++ b/src/transformers/models/evolla/modular_evolla.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, nn from ...cache_utils import Cache, DynamicCache diff --git a/src/transformers/models/falcon/modeling_falcon.py b/src/transformers/models/falcon/modeling_falcon.py index 5ec1792e4581..26dc56e41480 100644 --- a/src/transformers/models/falcon/modeling_falcon.py +++ b/src/transformers/models/falcon/modeling_falcon.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, LayerNorm, MSELoss from torch.nn import functional as F diff --git a/src/transformers/models/falcon_h1/modular_falcon_h1.py b/src/transformers/models/falcon_h1/modular_falcon_h1.py index c81e8967bcf2..24eb98ccd1ed 100644 --- a/src/transformers/models/falcon_h1/modular_falcon_h1.py +++ b/src/transformers/models/falcon_h1/modular_falcon_h1.py @@ -23,7 +23,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from transformers.activations import ACT2FN diff --git a/src/transformers/models/falcon_mamba/modular_falcon_mamba.py b/src/transformers/models/falcon_mamba/modular_falcon_mamba.py index cfe2ec49a992..6df2be3a2652 100644 --- a/src/transformers/models/falcon_mamba/modular_falcon_mamba.py +++ b/src/transformers/models/falcon_mamba/modular_falcon_mamba.py @@ -17,7 +17,6 @@ from typing import Optional import torch -import torch.utils.checkpoint from torch import nn from ...utils import auto_docstring, logging diff --git a/src/transformers/models/flava/modeling_flava.py b/src/transformers/models/flava/modeling_flava.py index cefaa6f95f68..266c3e96af5a 100644 --- a/src/transformers/models/flava/modeling_flava.py +++ b/src/transformers/models/flava/modeling_flava.py @@ -21,7 +21,6 @@ from typing import Any, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/fnet/modeling_fnet.py b/src/transformers/models/fnet/modeling_fnet.py index 1cb0e764b2a1..2ad09a3b268b 100755 --- a/src/transformers/models/fnet/modeling_fnet.py +++ b/src/transformers/models/fnet/modeling_fnet.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/focalnet/modeling_focalnet.py b/src/transformers/models/focalnet/modeling_focalnet.py index e56ada740e22..ed31b5deb527 100644 --- a/src/transformers/models/focalnet/modeling_focalnet.py +++ b/src/transformers/models/focalnet/modeling_focalnet.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/fuyu/modeling_fuyu.py b/src/transformers/models/fuyu/modeling_fuyu.py index d5edfadc3ffc..2095e9877c2c 100644 --- a/src/transformers/models/fuyu/modeling_fuyu.py +++ b/src/transformers/models/fuyu/modeling_fuyu.py @@ -17,7 +17,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...cache_utils import Cache diff --git a/src/transformers/models/gemma2/modular_gemma2.py b/src/transformers/models/gemma2/modular_gemma2.py index 47d612de5a4b..c7e34e4abed4 100644 --- a/src/transformers/models/gemma2/modular_gemma2.py +++ b/src/transformers/models/gemma2/modular_gemma2.py @@ -17,7 +17,6 @@ import torch import torch.nn as nn -import torch.utils.checkpoint from ...activations import ACT2FN from ...cache_utils import Cache, DynamicCache diff --git a/src/transformers/models/gemma3/modular_gemma3.py b/src/transformers/models/gemma3/modular_gemma3.py index c7db46bf7574..d10d01f55759 100644 --- a/src/transformers/models/gemma3/modular_gemma3.py +++ b/src/transformers/models/gemma3/modular_gemma3.py @@ -19,7 +19,6 @@ import torch import torch.nn as nn -import torch.utils.checkpoint from ...cache_utils import Cache, DynamicCache from ...configuration_utils import PretrainedConfig, layer_type_validation diff --git a/src/transformers/models/git/modeling_git.py b/src/transformers/models/git/modeling_git.py index 0125132718a3..4122b7a0df79 100644 --- a/src/transformers/models/git/modeling_git.py +++ b/src/transformers/models/git/modeling_git.py @@ -20,7 +20,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/glm/modular_glm.py b/src/transformers/models/glm/modular_glm.py index ec07be10fb6a..90730c0184a3 100644 --- a/src/transformers/models/glm/modular_glm.py +++ b/src/transformers/models/glm/modular_glm.py @@ -17,7 +17,6 @@ import torch import torch.nn as nn -import torch.utils.checkpoint from ...utils import logging from ..llama.modeling_llama import ( diff --git a/src/transformers/models/glm4_moe/modular_glm4_moe.py b/src/transformers/models/glm4_moe/modular_glm4_moe.py index bc07483c7f22..20144c8ffc40 100644 --- a/src/transformers/models/glm4_moe/modular_glm4_moe.py +++ b/src/transformers/models/glm4_moe/modular_glm4_moe.py @@ -17,7 +17,6 @@ from typing import Optional import torch -import torch.utils.checkpoint from torch import nn from ...configuration_utils import PretrainedConfig diff --git a/src/transformers/models/glpn/modeling_glpn.py b/src/transformers/models/glpn/modeling_glpn.py index 65e7b9b2654d..e326750743a1 100755 --- a/src/transformers/models/glpn/modeling_glpn.py +++ b/src/transformers/models/glpn/modeling_glpn.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/gpt2/modeling_gpt2.py b/src/transformers/models/gpt2/modeling_gpt2.py index c34755b8b440..ae0786179464 100644 --- a/src/transformers/models/gpt2/modeling_gpt2.py +++ b/src/transformers/models/gpt2/modeling_gpt2.py @@ -22,7 +22,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py b/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py index 96fb40b1d69f..6992dc642a4f 100644 --- a/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py +++ b/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py @@ -17,7 +17,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/gpt_neo/modeling_gpt_neo.py b/src/transformers/models/gpt_neo/modeling_gpt_neo.py index f7cf160cbb21..69d74565745a 100755 --- a/src/transformers/models/gpt_neo/modeling_gpt_neo.py +++ b/src/transformers/models/gpt_neo/modeling_gpt_neo.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/gpt_neox/modular_gpt_neox.py b/src/transformers/models/gpt_neox/modular_gpt_neox.py index 1d808304c306..532b7a607ae8 100644 --- a/src/transformers/models/gpt_neox/modular_gpt_neox.py +++ b/src/transformers/models/gpt_neox/modular_gpt_neox.py @@ -1,7 +1,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/gpt_neox_japanese/modeling_gpt_neox_japanese.py b/src/transformers/models/gpt_neox_japanese/modeling_gpt_neox_japanese.py index e25548d90f0c..70399f376c75 100755 --- a/src/transformers/models/gpt_neox_japanese/modeling_gpt_neox_japanese.py +++ b/src/transformers/models/gpt_neox_japanese/modeling_gpt_neox_japanese.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, nn from ...activations import ACT2FN diff --git a/src/transformers/models/gptj/modeling_gptj.py b/src/transformers/models/gptj/modeling_gptj.py index 56256df7d582..cb6a4f579c52 100644 --- a/src/transformers/models/gptj/modeling_gptj.py +++ b/src/transformers/models/gptj/modeling_gptj.py @@ -19,7 +19,6 @@ import torch import torch.fx -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/granite/modular_granite.py b/src/transformers/models/granite/modular_granite.py index 1b90609e5460..37e1955fcb09 100644 --- a/src/transformers/models/granite/modular_granite.py +++ b/src/transformers/models/granite/modular_granite.py @@ -16,7 +16,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...cache_utils import Cache, DynamicCache diff --git a/src/transformers/models/groupvit/modeling_groupvit.py b/src/transformers/models/groupvit/modeling_groupvit.py index 9ea10095eec8..775ebd286f0a 100644 --- a/src/transformers/models/groupvit/modeling_groupvit.py +++ b/src/transformers/models/groupvit/modeling_groupvit.py @@ -20,7 +20,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/helium/modular_helium.py b/src/transformers/models/helium/modular_helium.py index fe53f7820abb..6c2538d438f9 100644 --- a/src/transformers/models/helium/modular_helium.py +++ b/src/transformers/models/helium/modular_helium.py @@ -18,7 +18,6 @@ import torch import torch.nn as nn -import torch.utils.checkpoint from ...utils import logging from ..gemma.modeling_gemma import GemmaForCausalLM, GemmaForSequenceClassification, GemmaForTokenClassification diff --git a/src/transformers/models/hiera/modeling_hiera.py b/src/transformers/models/hiera/modeling_hiera.py index bfef87618156..0c084f0f836e 100644 --- a/src/transformers/models/hiera/modeling_hiera.py +++ b/src/transformers/models/hiera/modeling_hiera.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/hunyuan_v1_dense/modular_hunyuan_v1_dense.py b/src/transformers/models/hunyuan_v1_dense/modular_hunyuan_v1_dense.py index c79ccc6a616d..d527abc08f93 100644 --- a/src/transformers/models/hunyuan_v1_dense/modular_hunyuan_v1_dense.py +++ b/src/transformers/models/hunyuan_v1_dense/modular_hunyuan_v1_dense.py @@ -17,7 +17,6 @@ from typing import Callable, Optional import torch -import torch.utils.checkpoint from torch import nn from transformers.cache_utils import Cache diff --git a/src/transformers/models/hunyuan_v1_moe/modular_hunyuan_v1_moe.py b/src/transformers/models/hunyuan_v1_moe/modular_hunyuan_v1_moe.py index 645c54ae73af..a72d6268fe70 100644 --- a/src/transformers/models/hunyuan_v1_moe/modular_hunyuan_v1_moe.py +++ b/src/transformers/models/hunyuan_v1_moe/modular_hunyuan_v1_moe.py @@ -18,7 +18,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from transformers.cache_utils import Cache diff --git a/src/transformers/models/ibert/modeling_ibert.py b/src/transformers/models/ibert/modeling_ibert.py index 6b960148ca9b..57b3df2f570b 100644 --- a/src/transformers/models/ibert/modeling_ibert.py +++ b/src/transformers/models/ibert/modeling_ibert.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/idefics/modeling_idefics.py b/src/transformers/models/idefics/modeling_idefics.py index c80cb2e88bdc..f2fb135a4f4e 100644 --- a/src/transformers/models/idefics/modeling_idefics.py +++ b/src/transformers/models/idefics/modeling_idefics.py @@ -24,7 +24,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/idefics/vision.py b/src/transformers/models/idefics/vision.py index 72521761d9d1..f6143064835e 100644 --- a/src/transformers/models/idefics/vision.py +++ b/src/transformers/models/idefics/vision.py @@ -19,7 +19,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/idefics2/modeling_idefics2.py b/src/transformers/models/idefics2/modeling_idefics2.py index 264d3fc831ab..3aab4b01977f 100644 --- a/src/transformers/models/idefics2/modeling_idefics2.py +++ b/src/transformers/models/idefics2/modeling_idefics2.py @@ -18,7 +18,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/idefics3/modeling_idefics3.py b/src/transformers/models/idefics3/modeling_idefics3.py index 9d726f814465..32c75c1f3667 100644 --- a/src/transformers/models/idefics3/modeling_idefics3.py +++ b/src/transformers/models/idefics3/modeling_idefics3.py @@ -18,7 +18,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/imagegpt/modeling_imagegpt.py b/src/transformers/models/imagegpt/modeling_imagegpt.py index 6a424727d8e5..a962141e4479 100755 --- a/src/transformers/models/imagegpt/modeling_imagegpt.py +++ b/src/transformers/models/imagegpt/modeling_imagegpt.py @@ -19,7 +19,6 @@ from typing import Any, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/instructblip/modeling_instructblip.py b/src/transformers/models/instructblip/modeling_instructblip.py index af039a508c5d..20c0def10fd1 100644 --- a/src/transformers/models/instructblip/modeling_instructblip.py +++ b/src/transformers/models/instructblip/modeling_instructblip.py @@ -19,7 +19,6 @@ from typing import Any, Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/instructblipvideo/modular_instructblipvideo.py b/src/transformers/models/instructblipvideo/modular_instructblipvideo.py index ff30263700cf..5619c2e79b9a 100644 --- a/src/transformers/models/instructblipvideo/modular_instructblipvideo.py +++ b/src/transformers/models/instructblipvideo/modular_instructblipvideo.py @@ -16,7 +16,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from transformers.models.instructblip.configuration_instructblip import ( InstructBlipQFormerConfig, diff --git a/src/transformers/models/internvl/modular_internvl.py b/src/transformers/models/internvl/modular_internvl.py index bcef3a2ccbb0..ac7a4f516c06 100644 --- a/src/transformers/models/internvl/modular_internvl.py +++ b/src/transformers/models/internvl/modular_internvl.py @@ -20,7 +20,6 @@ import torch import torch.nn as nn -import torch.utils.checkpoint from ...activations import ACT2FN from ...cache_utils import Cache diff --git a/src/transformers/models/jamba/modeling_jamba.py b/src/transformers/models/jamba/modeling_jamba.py index 17246d6f1b2e..c8ddeb970e26 100755 --- a/src/transformers/models/jamba/modeling_jamba.py +++ b/src/transformers/models/jamba/modeling_jamba.py @@ -24,7 +24,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/janus/modular_janus.py b/src/transformers/models/janus/modular_janus.py index 261e994262aa..7f75147a5b1e 100644 --- a/src/transformers/models/janus/modular_janus.py +++ b/src/transformers/models/janus/modular_janus.py @@ -70,7 +70,7 @@ import torch import torch.nn as nn import torch.nn.functional as F - import torch.utils.checkpoint + if is_vision_available(): import PIL diff --git a/src/transformers/models/jetmoe/modeling_jetmoe.py b/src/transformers/models/jetmoe/modeling_jetmoe.py index 896426a5e320..0ca0a9a43669 100644 --- a/src/transformers/models/jetmoe/modeling_jetmoe.py +++ b/src/transformers/models/jetmoe/modeling_jetmoe.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import functional as F diff --git a/src/transformers/models/kosmos2/modeling_kosmos2.py b/src/transformers/models/kosmos2/modeling_kosmos2.py index 0372ec92a6ee..76acda9f0de9 100644 --- a/src/transformers/models/kosmos2/modeling_kosmos2.py +++ b/src/transformers/models/kosmos2/modeling_kosmos2.py @@ -19,7 +19,6 @@ from typing import Any, Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py b/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py index 1bb70fd5093d..8f9fbd706b32 100644 --- a/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py +++ b/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py @@ -19,7 +19,6 @@ from typing import Any, Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/layoutlm/modeling_layoutlm.py b/src/transformers/models/layoutlm/modeling_layoutlm.py index b3b79ef99d38..9e71eb7d8fb9 100644 --- a/src/transformers/models/layoutlm/modeling_layoutlm.py +++ b/src/transformers/models/layoutlm/modeling_layoutlm.py @@ -17,7 +17,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/layoutlmv2/modeling_layoutlmv2.py b/src/transformers/models/layoutlmv2/modeling_layoutlmv2.py index 11d8127ef6c2..3f444fbb6b28 100755 --- a/src/transformers/models/layoutlmv2/modeling_layoutlmv2.py +++ b/src/transformers/models/layoutlmv2/modeling_layoutlmv2.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/layoutlmv3/modeling_layoutlmv3.py b/src/transformers/models/layoutlmv3/modeling_layoutlmv3.py index bd8b525bb427..73bf26b0dfbe 100644 --- a/src/transformers/models/layoutlmv3/modeling_layoutlmv3.py +++ b/src/transformers/models/layoutlmv3/modeling_layoutlmv3.py @@ -21,7 +21,6 @@ import torch import torch.nn as nn import torch.nn.functional as F -import torch.utils.checkpoint from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN diff --git a/src/transformers/models/led/modeling_led.py b/src/transformers/models/led/modeling_led.py index e34a261df552..26d1321842e6 100755 --- a/src/transformers/models/led/modeling_led.py +++ b/src/transformers/models/led/modeling_led.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/levit/modeling_levit.py b/src/transformers/models/levit/modeling_levit.py index a72f5604825f..3deca07e2400 100644 --- a/src/transformers/models/levit/modeling_levit.py +++ b/src/transformers/models/levit/modeling_levit.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...modeling_outputs import ( diff --git a/src/transformers/models/lilt/modeling_lilt.py b/src/transformers/models/lilt/modeling_lilt.py index c3bcbf31f035..bb00d16c3965 100644 --- a/src/transformers/models/lilt/modeling_lilt.py +++ b/src/transformers/models/lilt/modeling_lilt.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/llava/modeling_llava.py b/src/transformers/models/llava/modeling_llava.py index 9a116dac4d23..bc0bb0df7c7b 100644 --- a/src/transformers/models/llava/modeling_llava.py +++ b/src/transformers/models/llava/modeling_llava.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/longformer/modeling_longformer.py b/src/transformers/models/longformer/modeling_longformer.py index f181217cd101..cdc708924967 100755 --- a/src/transformers/models/longformer/modeling_longformer.py +++ b/src/transformers/models/longformer/modeling_longformer.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/luke/modeling_luke.py b/src/transformers/models/luke/modeling_luke.py index ed1f2084c9e8..e78197beeb57 100644 --- a/src/transformers/models/luke/modeling_luke.py +++ b/src/transformers/models/luke/modeling_luke.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/mamba/modeling_mamba.py b/src/transformers/models/mamba/modeling_mamba.py index 4a53c47c8b4a..487cb3d19306 100644 --- a/src/transformers/models/mamba/modeling_mamba.py +++ b/src/transformers/models/mamba/modeling_mamba.py @@ -19,7 +19,6 @@ from typing import Any, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/mamba2/modeling_mamba2.py b/src/transformers/models/mamba2/modeling_mamba2.py index 738c5376c33e..a423c5b42fbd 100644 --- a/src/transformers/models/mamba2/modeling_mamba2.py +++ b/src/transformers/models/mamba2/modeling_mamba2.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/marian/modeling_marian.py b/src/transformers/models/marian/modeling_marian.py index 342e622321a8..f5f567346412 100755 --- a/src/transformers/models/marian/modeling_marian.py +++ b/src/transformers/models/marian/modeling_marian.py @@ -20,7 +20,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/markuplm/modeling_markuplm.py b/src/transformers/models/markuplm/modeling_markuplm.py index aeb817be7060..78fbf8f215aa 100755 --- a/src/transformers/models/markuplm/modeling_markuplm.py +++ b/src/transformers/models/markuplm/modeling_markuplm.py @@ -18,7 +18,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/mbart/modeling_mbart.py b/src/transformers/models/mbart/modeling_mbart.py index 21c54b6de60e..55fad55a87ae 100755 --- a/src/transformers/models/mbart/modeling_mbart.py +++ b/src/transformers/models/mbart/modeling_mbart.py @@ -18,7 +18,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/megatron_bert/modeling_megatron_bert.py b/src/transformers/models/megatron_bert/modeling_megatron_bert.py index 4987bd15dffd..a75c0f575aca 100755 --- a/src/transformers/models/megatron_bert/modeling_megatron_bert.py +++ b/src/transformers/models/megatron_bert/modeling_megatron_bert.py @@ -22,7 +22,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/mgp_str/modeling_mgp_str.py b/src/transformers/models/mgp_str/modeling_mgp_str.py index 8f65375a7895..be7cf08b14ab 100644 --- a/src/transformers/models/mgp_str/modeling_mgp_str.py +++ b/src/transformers/models/mgp_str/modeling_mgp_str.py @@ -20,7 +20,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...modeling_outputs import BaseModelOutput diff --git a/src/transformers/models/mimi/modeling_mimi.py b/src/transformers/models/mimi/modeling_mimi.py index 64537d5fcd94..f22cad968247 100644 --- a/src/transformers/models/mimi/modeling_mimi.py +++ b/src/transformers/models/mimi/modeling_mimi.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/mixtral/modular_mixtral.py b/src/transformers/models/mixtral/modular_mixtral.py index d897824c4cff..744f8c1321dc 100644 --- a/src/transformers/models/mixtral/modular_mixtral.py +++ b/src/transformers/models/mixtral/modular_mixtral.py @@ -23,7 +23,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/mllama/modeling_mllama.py b/src/transformers/models/mllama/modeling_mllama.py index e30ac5a8fa64..eb6cbee777d6 100644 --- a/src/transformers/models/mllama/modeling_mllama.py +++ b/src/transformers/models/mllama/modeling_mllama.py @@ -19,7 +19,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/mobilevit/modeling_mobilevit.py b/src/transformers/models/mobilevit/modeling_mobilevit.py index 10fe620f7c0d..415c33a7cb85 100755 --- a/src/transformers/models/mobilevit/modeling_mobilevit.py +++ b/src/transformers/models/mobilevit/modeling_mobilevit.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py b/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py index 291ce6136a54..4e0e972a648a 100644 --- a/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py +++ b/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/modernbert/modular_modernbert.py b/src/transformers/models/modernbert/modular_modernbert.py index 394fdce4fe80..276a754cc101 100644 --- a/src/transformers/models/modernbert/modular_modernbert.py +++ b/src/transformers/models/modernbert/modular_modernbert.py @@ -20,7 +20,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/moshi/modeling_moshi.py b/src/transformers/models/moshi/modeling_moshi.py index 503177f95b4a..7546fc90e542 100644 --- a/src/transformers/models/moshi/modeling_moshi.py +++ b/src/transformers/models/moshi/modeling_moshi.py @@ -20,7 +20,6 @@ import torch import torch.nn as nn -import torch.utils.checkpoint from torch.nn import CrossEntropyLoss from ...activations import ACT2FN diff --git a/src/transformers/models/mpt/modeling_mpt.py b/src/transformers/models/mpt/modeling_mpt.py index 57b875432758..c7bf0a795d42 100644 --- a/src/transformers/models/mpt/modeling_mpt.py +++ b/src/transformers/models/mpt/modeling_mpt.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, LayerNorm, MSELoss from torch.nn import functional as F diff --git a/src/transformers/models/mra/modeling_mra.py b/src/transformers/models/mra/modeling_mra.py index 3a37712e8580..86bee4d09b5a 100644 --- a/src/transformers/models/mra/modeling_mra.py +++ b/src/transformers/models/mra/modeling_mra.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from torch.utils.cpp_extension import load diff --git a/src/transformers/models/mvp/modeling_mvp.py b/src/transformers/models/mvp/modeling_mvp.py index 22af2b5a74de..6838f209cb4e 100644 --- a/src/transformers/models/mvp/modeling_mvp.py +++ b/src/transformers/models/mvp/modeling_mvp.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/nemotron/modeling_nemotron.py b/src/transformers/models/nemotron/modeling_nemotron.py index 35b1aedb71f8..b98f0a5ef2ac 100644 --- a/src/transformers/models/nemotron/modeling_nemotron.py +++ b/src/transformers/models/nemotron/modeling_nemotron.py @@ -20,7 +20,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import Size, Tensor, nn from ...activations import ACT2FN diff --git a/src/transformers/models/nystromformer/modeling_nystromformer.py b/src/transformers/models/nystromformer/modeling_nystromformer.py index 45e69b6b4693..3eb1fad24019 100755 --- a/src/transformers/models/nystromformer/modeling_nystromformer.py +++ b/src/transformers/models/nystromformer/modeling_nystromformer.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/olmo/modular_olmo.py b/src/transformers/models/olmo/modular_olmo.py index f54b9106345e..c89e927e4e08 100644 --- a/src/transformers/models/olmo/modular_olmo.py +++ b/src/transformers/models/olmo/modular_olmo.py @@ -3,7 +3,6 @@ import torch import torch.nn as nn import torch.nn.functional as F -import torch.utils.checkpoint from ...cache_utils import Cache from ...modeling_utils import ALL_ATTENTION_FUNCTIONS diff --git a/src/transformers/models/olmoe/modeling_olmoe.py b/src/transformers/models/olmoe/modeling_olmoe.py index 9d7d0727da9b..4070d3b2b480 100644 --- a/src/transformers/models/olmoe/modeling_olmoe.py +++ b/src/transformers/models/olmoe/modeling_olmoe.py @@ -16,7 +16,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/opt/modeling_opt.py b/src/transformers/models/opt/modeling_opt.py index a2c4bb500a65..68af2a02017b 100644 --- a/src/transformers/models/opt/modeling_opt.py +++ b/src/transformers/models/opt/modeling_opt.py @@ -17,7 +17,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/owlv2/modeling_owlv2.py b/src/transformers/models/owlv2/modeling_owlv2.py index 81c7a088df9f..715df44f01f0 100644 --- a/src/transformers/models/owlv2/modeling_owlv2.py +++ b/src/transformers/models/owlv2/modeling_owlv2.py @@ -19,7 +19,6 @@ from typing import Any, Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, nn from ...activations import ACT2FN diff --git a/src/transformers/models/owlvit/modeling_owlvit.py b/src/transformers/models/owlvit/modeling_owlvit.py index 107c8a9dab2f..3971b1376d9c 100644 --- a/src/transformers/models/owlvit/modeling_owlvit.py +++ b/src/transformers/models/owlvit/modeling_owlvit.py @@ -19,7 +19,6 @@ from typing import Any, Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, nn from ...activations import ACT2FN diff --git a/src/transformers/models/paligemma/modeling_paligemma.py b/src/transformers/models/paligemma/modeling_paligemma.py index a165bc22a0de..abd8595e24ab 100644 --- a/src/transformers/models/paligemma/modeling_paligemma.py +++ b/src/transformers/models/paligemma/modeling_paligemma.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...cache_utils import Cache, StaticCache diff --git a/src/transformers/models/pegasus/modeling_pegasus.py b/src/transformers/models/pegasus/modeling_pegasus.py index 58eedc77bc3c..dc3a8005acac 100755 --- a/src/transformers/models/pegasus/modeling_pegasus.py +++ b/src/transformers/models/pegasus/modeling_pegasus.py @@ -20,7 +20,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/pegasus_x/modeling_pegasus_x.py b/src/transformers/models/pegasus_x/modeling_pegasus_x.py index 0279688c00e8..0c1ae32cabe2 100755 --- a/src/transformers/models/pegasus_x/modeling_pegasus_x.py +++ b/src/transformers/models/pegasus_x/modeling_pegasus_x.py @@ -20,7 +20,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/perceiver/modeling_perceiver.py b/src/transformers/models/perceiver/modeling_perceiver.py index 1f6b84343d00..f0e4e3e5dbe0 100755 --- a/src/transformers/models/perceiver/modeling_perceiver.py +++ b/src/transformers/models/perceiver/modeling_perceiver.py @@ -24,7 +24,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/perception_lm/modular_perception_lm.py b/src/transformers/models/perception_lm/modular_perception_lm.py index 2e748c82a7bc..2b50b8242202 100644 --- a/src/transformers/models/perception_lm/modular_perception_lm.py +++ b/src/transformers/models/perception_lm/modular_perception_lm.py @@ -18,7 +18,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...cache_utils import Cache diff --git a/src/transformers/models/persimmon/modeling_persimmon.py b/src/transformers/models/persimmon/modeling_persimmon.py index 02ec819315b7..c963bb53852a 100644 --- a/src/transformers/models/persimmon/modeling_persimmon.py +++ b/src/transformers/models/persimmon/modeling_persimmon.py @@ -22,7 +22,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/phi3/modular_phi3.py b/src/transformers/models/phi3/modular_phi3.py index a945fb21b935..d355c3792a6b 100644 --- a/src/transformers/models/phi3/modular_phi3.py +++ b/src/transformers/models/phi3/modular_phi3.py @@ -18,7 +18,6 @@ from typing import Callable, Optional import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/phimoe/modeling_phimoe.py b/src/transformers/models/phimoe/modeling_phimoe.py index d3d79847b073..711aabd4b962 100644 --- a/src/transformers/models/phimoe/modeling_phimoe.py +++ b/src/transformers/models/phimoe/modeling_phimoe.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/pix2struct/modeling_pix2struct.py b/src/transformers/models/pix2struct/modeling_pix2struct.py index d780dc534879..463fec98256f 100644 --- a/src/transformers/models/pix2struct/modeling_pix2struct.py +++ b/src/transformers/models/pix2struct/modeling_pix2struct.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/pixtral/modeling_pixtral.py b/src/transformers/models/pixtral/modeling_pixtral.py index 564c118fccb9..79bf0ee6bbda 100644 --- a/src/transformers/models/pixtral/modeling_pixtral.py +++ b/src/transformers/models/pixtral/modeling_pixtral.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/plbart/modular_plbart.py b/src/transformers/models/plbart/modular_plbart.py index 8d7f0022cfb4..29c253144557 100644 --- a/src/transformers/models/plbart/modular_plbart.py +++ b/src/transformers/models/plbart/modular_plbart.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/poolformer/modeling_poolformer.py b/src/transformers/models/poolformer/modeling_poolformer.py index 3753eb464b04..8c6dc8191630 100755 --- a/src/transformers/models/poolformer/modeling_poolformer.py +++ b/src/transformers/models/poolformer/modeling_poolformer.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/prophetnet/modeling_prophetnet.py b/src/transformers/models/prophetnet/modeling_prophetnet.py index 5e80ee4f0faa..260b0c698407 100644 --- a/src/transformers/models/prophetnet/modeling_prophetnet.py +++ b/src/transformers/models/prophetnet/modeling_prophetnet.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, nn from torch.nn import LayerNorm diff --git a/src/transformers/models/pvt/modeling_pvt.py b/src/transformers/models/pvt/modeling_pvt.py index 446a85944801..21af67542d70 100755 --- a/src/transformers/models/pvt/modeling_pvt.py +++ b/src/transformers/models/pvt/modeling_pvt.py @@ -23,7 +23,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/pvt_v2/modeling_pvt_v2.py b/src/transformers/models/pvt_v2/modeling_pvt_v2.py index e434223a94a2..204198787e45 100644 --- a/src/transformers/models/pvt_v2/modeling_pvt_v2.py +++ b/src/transformers/models/pvt_v2/modeling_pvt_v2.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/qwen2/modular_qwen2.py b/src/transformers/models/qwen2/modular_qwen2.py index b4555ef927e3..d946e4b7e1f0 100644 --- a/src/transformers/models/qwen2/modular_qwen2.py +++ b/src/transformers/models/qwen2/modular_qwen2.py @@ -1,7 +1,6 @@ from typing import Callable, Optional import torch -import torch.utils.checkpoint from packaging import version from torch import nn diff --git a/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py b/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py index 07cd851d4f88..afb0cda5ccfe 100644 --- a/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py +++ b/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py @@ -22,7 +22,6 @@ import numpy as np import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from torch.nn import Parameter diff --git a/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py b/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py index d62f94f37678..b59644c37df9 100644 --- a/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py +++ b/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py @@ -25,7 +25,6 @@ import torch import torch.nn as nn import torch.nn.functional as F -import torch.utils.checkpoint from transformers.models.qwen2_vl.configuration_qwen2_vl import Qwen2VLConfig, Qwen2VLTextConfig from transformers.models.qwen2_vl.modeling_qwen2_vl import ( diff --git a/src/transformers/models/qwen2_moe/modeling_qwen2_moe.py b/src/transformers/models/qwen2_moe/modeling_qwen2_moe.py index 070eb6e89fd5..c4b37477d5af 100644 --- a/src/transformers/models/qwen2_moe/modeling_qwen2_moe.py +++ b/src/transformers/models/qwen2_moe/modeling_qwen2_moe.py @@ -24,7 +24,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/qwen2_vl/modeling_qwen2_vl.py b/src/transformers/models/qwen2_vl/modeling_qwen2_vl.py index 0509ef9e085e..269f37492ad6 100644 --- a/src/transformers/models/qwen2_vl/modeling_qwen2_vl.py +++ b/src/transformers/models/qwen2_vl/modeling_qwen2_vl.py @@ -25,7 +25,6 @@ import torch import torch.nn as nn import torch.nn.functional as F -import torch.utils.checkpoint from torch.nn import LayerNorm from ...activations import ACT2FN diff --git a/src/transformers/models/qwen3_moe/modular_qwen3_moe.py b/src/transformers/models/qwen3_moe/modular_qwen3_moe.py index b9213a5e5bbb..e7dd3dda00ac 100644 --- a/src/transformers/models/qwen3_moe/modular_qwen3_moe.py +++ b/src/transformers/models/qwen3_moe/modular_qwen3_moe.py @@ -18,7 +18,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/qwen3_next/modular_qwen3_next.py b/src/transformers/models/qwen3_next/modular_qwen3_next.py index f76a242877b9..e141e229eedf 100644 --- a/src/transformers/models/qwen3_next/modular_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modular_qwen3_next.py @@ -18,7 +18,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/recurrent_gemma/modeling_recurrent_gemma.py b/src/transformers/models/recurrent_gemma/modeling_recurrent_gemma.py index daef714ab883..d7d1ce33e8f0 100644 --- a/src/transformers/models/recurrent_gemma/modeling_recurrent_gemma.py +++ b/src/transformers/models/recurrent_gemma/modeling_recurrent_gemma.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/regnet/modeling_regnet.py b/src/transformers/models/regnet/modeling_regnet.py index 5eb65d92b8be..70611113885f 100644 --- a/src/transformers/models/regnet/modeling_regnet.py +++ b/src/transformers/models/regnet/modeling_regnet.py @@ -18,7 +18,6 @@ from typing import Optional import torch -import torch.utils.checkpoint from torch import Tensor, nn from ...activations import ACT2FN diff --git a/src/transformers/models/rembert/modeling_rembert.py b/src/transformers/models/rembert/modeling_rembert.py index a9ee455116c4..0fc9635cda88 100755 --- a/src/transformers/models/rembert/modeling_rembert.py +++ b/src/transformers/models/rembert/modeling_rembert.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/resnet/modeling_resnet.py b/src/transformers/models/resnet/modeling_resnet.py index c766a91cd277..59a509fe03cd 100644 --- a/src/transformers/models/resnet/modeling_resnet.py +++ b/src/transformers/models/resnet/modeling_resnet.py @@ -18,7 +18,6 @@ from typing import Optional import torch -import torch.utils.checkpoint from torch import Tensor, nn from ...activations import ACT2FN diff --git a/src/transformers/models/roberta/modeling_roberta.py b/src/transformers/models/roberta/modeling_roberta.py index 6999dddf1b1a..33fb44118a90 100644 --- a/src/transformers/models/roberta/modeling_roberta.py +++ b/src/transformers/models/roberta/modeling_roberta.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py b/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py index 072466bd8b04..81481574b01e 100644 --- a/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py +++ b/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/roc_bert/modeling_roc_bert.py b/src/transformers/models/roc_bert/modeling_roc_bert.py index e0b8b4b434ba..22a72f91bc38 100644 --- a/src/transformers/models/roc_bert/modeling_roc_bert.py +++ b/src/transformers/models/roc_bert/modeling_roc_bert.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/roformer/modeling_roformer.py b/src/transformers/models/roformer/modeling_roformer.py index 56dce4cb753b..3fc94cf87675 100644 --- a/src/transformers/models/roformer/modeling_roformer.py +++ b/src/transformers/models/roformer/modeling_roformer.py @@ -20,7 +20,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/rwkv/modeling_rwkv.py b/src/transformers/models/rwkv/modeling_rwkv.py index d86d4d0f8707..816b22f1b2dd 100644 --- a/src/transformers/models/rwkv/modeling_rwkv.py +++ b/src/transformers/models/rwkv/modeling_rwkv.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...generation import GenerationMixin diff --git a/src/transformers/models/sam2/modular_sam2.py b/src/transformers/models/sam2/modular_sam2.py index 5fff232a839c..be2a5eb1c6d2 100644 --- a/src/transformers/models/sam2/modular_sam2.py +++ b/src/transformers/models/sam2/modular_sam2.py @@ -21,7 +21,6 @@ import torch import torch.nn as nn import torch.nn.functional as F -import torch.utils.checkpoint from ...activations import ACT2FN from ...image_processing_utils import BatchFeature, get_size_dict diff --git a/src/transformers/models/sam2_video/modular_sam2_video.py b/src/transformers/models/sam2_video/modular_sam2_video.py index 83483e9d724e..9ba8e6526305 100644 --- a/src/transformers/models/sam2_video/modular_sam2_video.py +++ b/src/transformers/models/sam2_video/modular_sam2_video.py @@ -24,7 +24,6 @@ import torch import torch.nn as nn import torch.nn.functional as F -import torch.utils.checkpoint from torch import Tensor from tqdm import tqdm diff --git a/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py b/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py index 15f368281775..5078d437e978 100755 --- a/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py +++ b/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py b/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py index ccad4450451d..7aa15cb84ddd 100644 --- a/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py +++ b/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/segformer/modeling_segformer.py b/src/transformers/models/segformer/modeling_segformer.py index 4aa49d86466b..8a81f68beadd 100755 --- a/src/transformers/models/segformer/modeling_segformer.py +++ b/src/transformers/models/segformer/modeling_segformer.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss diff --git a/src/transformers/models/seggpt/modeling_seggpt.py b/src/transformers/models/seggpt/modeling_seggpt.py index 93ca95b91094..7e82d26c9e74 100644 --- a/src/transformers/models/seggpt/modeling_seggpt.py +++ b/src/transformers/models/seggpt/modeling_seggpt.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import functional as F diff --git a/src/transformers/models/sew/modular_sew.py b/src/transformers/models/sew/modular_sew.py index 5b4ee00c4a65..b15c2e5c23a3 100644 --- a/src/transformers/models/sew/modular_sew.py +++ b/src/transformers/models/sew/modular_sew.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/sew_d/modeling_sew_d.py b/src/transformers/models/sew_d/modeling_sew_d.py index 53eeda91f3da..f8b71241c79e 100644 --- a/src/transformers/models/sew_d/modeling_sew_d.py +++ b/src/transformers/models/sew_d/modeling_sew_d.py @@ -21,7 +21,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss, LayerNorm diff --git a/src/transformers/models/shieldgemma2/modeling_shieldgemma2.py b/src/transformers/models/shieldgemma2/modeling_shieldgemma2.py index 49261f039a56..5e12b0129ab6 100644 --- a/src/transformers/models/shieldgemma2/modeling_shieldgemma2.py +++ b/src/transformers/models/shieldgemma2/modeling_shieldgemma2.py @@ -17,7 +17,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from ...cache_utils import Cache from ...modeling_outputs import ImageClassifierOutputWithNoAttention diff --git a/src/transformers/models/smolvlm/modular_smolvlm.py b/src/transformers/models/smolvlm/modular_smolvlm.py index 25d55b1a974a..ffc7f06c97c9 100644 --- a/src/transformers/models/smolvlm/modular_smolvlm.py +++ b/src/transformers/models/smolvlm/modular_smolvlm.py @@ -16,7 +16,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...cache_utils import Cache, DynamicCache diff --git a/src/transformers/models/speecht5/modeling_speecht5.py b/src/transformers/models/speecht5/modeling_speecht5.py index 026585cdd77b..b3e79a46680c 100644 --- a/src/transformers/models/speecht5/modeling_speecht5.py +++ b/src/transformers/models/speecht5/modeling_speecht5.py @@ -19,7 +19,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, L1Loss diff --git a/src/transformers/models/splinter/modeling_splinter.py b/src/transformers/models/splinter/modeling_splinter.py index 905c7a27ad3d..116a17330923 100755 --- a/src/transformers/models/splinter/modeling_splinter.py +++ b/src/transformers/models/splinter/modeling_splinter.py @@ -18,7 +18,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/stablelm/modeling_stablelm.py b/src/transformers/models/stablelm/modeling_stablelm.py index 9daefe0a39df..6b31565a1b1d 100755 --- a/src/transformers/models/stablelm/modeling_stablelm.py +++ b/src/transformers/models/stablelm/modeling_stablelm.py @@ -23,7 +23,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/starcoder2/modular_starcoder2.py b/src/transformers/models/starcoder2/modular_starcoder2.py index a1baf7de8767..f37c75510abe 100644 --- a/src/transformers/models/starcoder2/modular_starcoder2.py +++ b/src/transformers/models/starcoder2/modular_starcoder2.py @@ -22,7 +22,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from transformers.utils.generic import check_model_inputs diff --git a/src/transformers/models/swiftformer/modeling_swiftformer.py b/src/transformers/models/swiftformer/modeling_swiftformer.py index 9e0c4c3147b7..95114e3d332c 100644 --- a/src/transformers/models/swiftformer/modeling_swiftformer.py +++ b/src/transformers/models/swiftformer/modeling_swiftformer.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2CLS diff --git a/src/transformers/models/swin/modeling_swin.py b/src/transformers/models/swin/modeling_swin.py index 37d3413fae5d..18b61abbd3a4 100644 --- a/src/transformers/models/swin/modeling_swin.py +++ b/src/transformers/models/swin/modeling_swin.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/swin2sr/modeling_swin2sr.py b/src/transformers/models/swin2sr/modeling_swin2sr.py index c2d12e8d78ae..e010a1d8a01e 100644 --- a/src/transformers/models/swin2sr/modeling_swin2sr.py +++ b/src/transformers/models/swin2sr/modeling_swin2sr.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/swinv2/modeling_swinv2.py b/src/transformers/models/swinv2/modeling_swinv2.py index 4d030178ed49..1463f0f82e7e 100644 --- a/src/transformers/models/swinv2/modeling_swinv2.py +++ b/src/transformers/models/swinv2/modeling_swinv2.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import Tensor, nn from ...activations import ACT2FN diff --git a/src/transformers/models/tapas/modeling_tapas.py b/src/transformers/models/tapas/modeling_tapas.py index 3f4bf53d1acc..075b834533b6 100644 --- a/src/transformers/models/tapas/modeling_tapas.py +++ b/src/transformers/models/tapas/modeling_tapas.py @@ -21,7 +21,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/timesformer/modeling_timesformer.py b/src/transformers/models/timesformer/modeling_timesformer.py index c0110b379aac..0aa06d5c33bb 100644 --- a/src/transformers/models/timesformer/modeling_timesformer.py +++ b/src/transformers/models/timesformer/modeling_timesformer.py @@ -19,7 +19,6 @@ import torch import torch.nn.functional -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/tvp/modeling_tvp.py b/src/transformers/models/tvp/modeling_tvp.py index 77d74bffe0ee..0b8b626d2dd2 100644 --- a/src/transformers/models/tvp/modeling_tvp.py +++ b/src/transformers/models/tvp/modeling_tvp.py @@ -19,7 +19,6 @@ from typing import Optional import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/univnet/modeling_univnet.py b/src/transformers/models/univnet/modeling_univnet.py index 1a9c2aa54e72..e7595ff38f8a 100644 --- a/src/transformers/models/univnet/modeling_univnet.py +++ b/src/transformers/models/univnet/modeling_univnet.py @@ -17,7 +17,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...modeling_outputs import ModelOutput diff --git a/src/transformers/models/video_llava/modeling_video_llava.py b/src/transformers/models/video_llava/modeling_video_llava.py index 41a4d0abed17..2db424455087 100644 --- a/src/transformers/models/video_llava/modeling_video_llava.py +++ b/src/transformers/models/video_llava/modeling_video_llava.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/videomae/modeling_videomae.py b/src/transformers/models/videomae/modeling_videomae.py index 335ae485289a..97c227f1d8bf 100755 --- a/src/transformers/models/videomae/modeling_videomae.py +++ b/src/transformers/models/videomae/modeling_videomae.py @@ -21,7 +21,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import MSELoss diff --git a/src/transformers/models/vilt/modeling_vilt.py b/src/transformers/models/vilt/modeling_vilt.py index ed749f85362a..75e58f9858fd 100755 --- a/src/transformers/models/vilt/modeling_vilt.py +++ b/src/transformers/models/vilt/modeling_vilt.py @@ -20,7 +20,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/visual_bert/modeling_visual_bert.py b/src/transformers/models/visual_bert/modeling_visual_bert.py index 3ea9b45537cb..cdc3e3adc69b 100755 --- a/src/transformers/models/visual_bert/modeling_visual_bert.py +++ b/src/transformers/models/visual_bert/modeling_visual_bert.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss, KLDivLoss, LogSoftmax diff --git a/src/transformers/models/vit/modeling_vit.py b/src/transformers/models/vit/modeling_vit.py index 3e84687d8ffa..d9c01927ffc4 100644 --- a/src/transformers/models/vit/modeling_vit.py +++ b/src/transformers/models/vit/modeling_vit.py @@ -19,7 +19,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/vit_mae/modeling_vit_mae.py b/src/transformers/models/vit_mae/modeling_vit_mae.py index 8b4b9efafeb5..a74d172805bd 100755 --- a/src/transformers/models/vit_mae/modeling_vit_mae.py +++ b/src/transformers/models/vit_mae/modeling_vit_mae.py @@ -21,7 +21,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/vit_msn/modeling_vit_msn.py b/src/transformers/models/vit_msn/modeling_vit_msn.py index fa99fa62a753..eee739b13864 100644 --- a/src/transformers/models/vit_msn/modeling_vit_msn.py +++ b/src/transformers/models/vit_msn/modeling_vit_msn.py @@ -18,7 +18,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/vitdet/modeling_vitdet.py b/src/transformers/models/vitdet/modeling_vitdet.py index 1498b72d856d..8debcaf11fa5 100644 --- a/src/transformers/models/vitdet/modeling_vitdet.py +++ b/src/transformers/models/vitdet/modeling_vitdet.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/vitpose/modeling_vitpose.py b/src/transformers/models/vitpose/modeling_vitpose.py index 900eb3aadf7b..250341797aab 100644 --- a/src/transformers/models/vitpose/modeling_vitpose.py +++ b/src/transformers/models/vitpose/modeling_vitpose.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...modeling_outputs import BackboneOutput diff --git a/src/transformers/models/vitpose_backbone/modeling_vitpose_backbone.py b/src/transformers/models/vitpose_backbone/modeling_vitpose_backbone.py index b5c596832fb4..1c61763d5e56 100644 --- a/src/transformers/models/vitpose_backbone/modeling_vitpose_backbone.py +++ b/src/transformers/models/vitpose_backbone/modeling_vitpose_backbone.py @@ -23,7 +23,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/vits/modeling_vits.py b/src/transformers/models/vits/modeling_vits.py index 45eca357ffb5..7300ea7f798e 100644 --- a/src/transformers/models/vits/modeling_vits.py +++ b/src/transformers/models/vits/modeling_vits.py @@ -20,7 +20,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/vivit/modeling_vivit.py b/src/transformers/models/vivit/modeling_vivit.py index aca26da16695..b27b56e640c6 100755 --- a/src/transformers/models/vivit/modeling_vivit.py +++ b/src/transformers/models/vivit/modeling_vivit.py @@ -17,7 +17,6 @@ from typing import Callable, Optional import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/wav2vec2/modeling_wav2vec2.py b/src/transformers/models/wav2vec2/modeling_wav2vec2.py index 90760d290e82..d8c58a333e07 100755 --- a/src/transformers/models/wav2vec2/modeling_wav2vec2.py +++ b/src/transformers/models/wav2vec2/modeling_wav2vec2.py @@ -21,7 +21,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/whisper/modeling_whisper.py b/src/transformers/models/whisper/modeling_whisper.py index da30a332d749..9ae3b33ebc6f 100644 --- a/src/transformers/models/whisper/modeling_whisper.py +++ b/src/transformers/models/whisper/modeling_whisper.py @@ -19,7 +19,6 @@ import numpy as np import torch -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/x_clip/modeling_x_clip.py b/src/transformers/models/x_clip/modeling_x_clip.py index 5a4b478ceef9..403b9a408162 100644 --- a/src/transformers/models/x_clip/modeling_x_clip.py +++ b/src/transformers/models/x_clip/modeling_x_clip.py @@ -19,7 +19,6 @@ from typing import Any, Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/xglm/modeling_xglm.py b/src/transformers/models/xglm/modeling_xglm.py index cfa42502399b..0f863f3f274f 100755 --- a/src/transformers/models/xglm/modeling_xglm.py +++ b/src/transformers/models/xglm/modeling_xglm.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py b/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py index a398ff0b916c..a3a252572ec9 100644 --- a/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py +++ b/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py b/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py index 99b925015a71..d0c71365d214 100644 --- a/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py +++ b/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/xlstm/modeling_xlstm.py b/src/transformers/models/xlstm/modeling_xlstm.py index 7e2fce997683..5bb438efce7e 100644 --- a/src/transformers/models/xlstm/modeling_xlstm.py +++ b/src/transformers/models/xlstm/modeling_xlstm.py @@ -18,7 +18,6 @@ import torch import torch.nn.functional as F -import torch.utils.checkpoint from torch import nn from torch.nn import CrossEntropyLoss diff --git a/src/transformers/models/xmod/modeling_xmod.py b/src/transformers/models/xmod/modeling_xmod.py index bb1ba68d4624..7c8328447cb0 100644 --- a/src/transformers/models/xmod/modeling_xmod.py +++ b/src/transformers/models/xmod/modeling_xmod.py @@ -18,7 +18,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/yolos/modeling_yolos.py b/src/transformers/models/yolos/modeling_yolos.py index 2571cf82733d..13fd9886ea96 100755 --- a/src/transformers/models/yolos/modeling_yolos.py +++ b/src/transformers/models/yolos/modeling_yolos.py @@ -19,7 +19,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/yoso/modeling_yoso.py b/src/transformers/models/yoso/modeling_yoso.py index 221ebaa637fe..0ad53b81f492 100644 --- a/src/transformers/models/yoso/modeling_yoso.py +++ b/src/transformers/models/yoso/modeling_yoso.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/zamba/modeling_zamba.py b/src/transformers/models/zamba/modeling_zamba.py index 2f9edb1e113c..a69b7a0a3f86 100644 --- a/src/transformers/models/zamba/modeling_zamba.py +++ b/src/transformers/models/zamba/modeling_zamba.py @@ -23,7 +23,6 @@ from typing import Any, Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss diff --git a/src/transformers/models/zamba2/modular_zamba2.py b/src/transformers/models/zamba2/modular_zamba2.py index ea305ba7a5b6..3cada0c0dd43 100644 --- a/src/transformers/models/zamba2/modular_zamba2.py +++ b/src/transformers/models/zamba2/modular_zamba2.py @@ -19,7 +19,6 @@ from typing import Callable, Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN diff --git a/src/transformers/models/zoedepth/modeling_zoedepth.py b/src/transformers/models/zoedepth/modeling_zoedepth.py index d79bb27d56c0..7bbad31c2ee0 100644 --- a/src/transformers/models/zoedepth/modeling_zoedepth.py +++ b/src/transformers/models/zoedepth/modeling_zoedepth.py @@ -19,7 +19,6 @@ from typing import Optional, Union import torch -import torch.utils.checkpoint from torch import nn from ...activations import ACT2FN From da501ec9bd97df11e6c997487b7b4f9c382f83dc Mon Sep 17 00:00:00 2001 From: jiqing-feng Date: Wed, 17 Sep 2025 23:42:30 +0800 Subject: [PATCH 086/204] Intel CPU dockerfile (#40806) * upload intel cpu dockerfile Signed-off-by: jiqing-feng * update cpu dockerfile Signed-off-by: jiqing-feng * update label name Signed-off-by: jiqing-feng --------- Signed-off-by: jiqing-feng --- docker/transformers-intel-cpu/Dockerfile | 71 ++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 docker/transformers-intel-cpu/Dockerfile diff --git a/docker/transformers-intel-cpu/Dockerfile b/docker/transformers-intel-cpu/Dockerfile new file mode 100644 index 000000000000..3270b8582420 --- /dev/null +++ b/docker/transformers-intel-cpu/Dockerfile @@ -0,0 +1,71 @@ +FROM intel/deep-learning-essentials:2025.1.3-0-devel-ubuntu24.04 AS base +LABEL maintainer="Hugging Face" +SHELL ["/bin/bash", "-c"] + +ARG PYTHON_VERSION=3.12 +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y software-properties-common && \ + add-apt-repository -y ppa:deadsnakes/ppa && \ + apt-get update + +RUN apt-get update && \ + apt-get -y install \ + apt-utils \ + build-essential \ + ca-certificates \ + clinfo \ + curl \ + git \ + git-lfs \ + vim \ + numactl \ + gnupg2 \ + gpg-agent \ + python3-dev \ + python3-opencv \ + unzip \ + ffmpeg \ + tesseract-ocr \ + espeak-ng \ + wget \ + ncurses-term \ + google-perftools \ + libjemalloc-dev \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Use virtual env because Ubuntu:24 does not allowed pip on original python +RUN curl -LsSf https://astral.sh/uv/install.sh | sh +ENV PATH="/root/.local/bin:$PATH" +ENV VIRTUAL_ENV="/opt/venv" +ENV UV_PYTHON_INSTALL_DIR=/opt/uv/python +RUN uv venv --python ${PYTHON_VERSION} --seed ${VIRTUAL_ENV} +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +RUN pip install --upgrade pip wheel +RUN pip install torch torchvision torchaudio torchcodec --index-url https://download.pytorch.org/whl/cpu --no-cache-dir +RUN pip install av pyctcdecode pytesseract decord galore-torch fire scipy scikit-learn sentencepiece sentence_transformers sacremoses nltk rouge_score librosa soundfile mpi4py pytorch_msssim +RUN pip install onnx optimum onnxruntime +RUN pip install autoawq +RUN pip install gptqmodel --no-build-isolation +RUN pip install -U datasets timm transformers accelerate peft diffusers opencv-python kenlm evaluate +RUN pip install -U intel-openmp + +# install bitsandbytes +RUN git clone https://github.com/bitsandbytes-foundation/bitsandbytes.git && cd bitsandbytes/ && \ + cmake -DCOMPUTE_BACKEND=cpu -S . && make && pip install . && cd ../ + +# CPU don't need triton +RUN pip uninstall triton -y + +ENV LD_PRELOAD=${LD_PRELOAD}:/opt/venv/lib/libiomp5.so:/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4 +ENV KMP_AFFINITY=granularity=fine,compact,1,0 + +RUN touch /entrypoint.sh +RUN chmod +x /entrypoint.sh +RUN echo "#!/bin/bash" >> /entrypoint.sh +RUN echo "/bin/bash" >> /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] From 385aeb6796acf98b86fba7a72594ed7dc792de6b Mon Sep 17 00:00:00 2001 From: lilin-1 <256404019@qq.com> Date: Wed, 17 Sep 2025 23:48:38 +0800 Subject: [PATCH 087/204] docs(i18n): Correct the descriptive text in the README_zh-hans.md (#40941) --- i18n/README_zh-hans.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/README_zh-hans.md b/i18n/README_zh-hans.md index 9c0c9f5268d9..8220e403b8b2 100644 --- a/i18n/README_zh-hans.md +++ b/i18n/README_zh-hans.md @@ -79,7 +79,7 @@ checkpoint: 检查点

-

为 Jax、PyTorch 和 TensorFlow 打造的先进的自然语言处理

+

为 Jax、PyTorch 和 TensorFlow 打造的先进的自然语言处理函数库

From e7a14d912f7da5538f3e8337edb07028cabbc192 Mon Sep 17 00:00:00 2001 From: Marc Sun <57196510+SunMarc@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:05:17 +0200 Subject: [PATCH 088/204] Fix trainer tests (#40823) * fix liger * fix * more * fix * fix hp * fix --------- Co-authored-by: Matej Sirovatka <54212263+S1ro1@users.noreply.github.com> --- setup.py | 2 +- tests/trainer/test_trainer.py | 33 +++++++++++++++------------------ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/setup.py b/setup.py index b4feedbc77a1..9f3bb1750597 100644 --- a/setup.py +++ b/setup.py @@ -308,7 +308,7 @@ def run(self): extras["sigopt"] = deps_list("sigopt") extras["hub-kernels"] = deps_list("kernels") -extras["integrations"] = extras["hub-kernels"] + extras["optuna"] + extras["ray"] + extras["sigopt"] +extras["integrations"] = extras["hub-kernels"] + extras["optuna"] + extras["ray"] extras["serving"] = deps_list("openai", "pydantic", "uvicorn", "fastapi", "starlette") + extras["torch"] extras["audio"] = deps_list( diff --git a/tests/trainer/test_trainer.py b/tests/trainer/test_trainer.py index 8fc1628c7f6d..4d011033186a 100644 --- a/tests/trainer/test_trainer.py +++ b/tests/trainer/test_trainer.py @@ -1895,7 +1895,7 @@ def test_get_eval_dataloader_with_persistent_workers(self): def test_use_liger_kernel_patching(self): # Ensure any monkey patching is cleaned up for subsequent tests with patch("transformers.models.llama.modeling_llama"): - from liger_kernel.transformers import LigerRMSNorm, liger_rotary_pos_emb + from liger_kernel.transformers import liger_rotary_pos_emb from transformers.models.llama import modeling_llama @@ -1904,7 +1904,7 @@ def test_use_liger_kernel_patching(self): # Spot check that modeling code and model instance variables are not yet patched self.assertNotEqual(modeling_llama.apply_rotary_pos_emb, liger_rotary_pos_emb) - self.assertFalse(isinstance(tiny_llama.model.norm, LigerRMSNorm)) + self.assertFalse("LigerRMSNorm" in tiny_llama.model.norm.__repr__()) args = TrainingArguments( self.get_auto_remove_tmp_dir(), @@ -1914,7 +1914,7 @@ def test_use_liger_kernel_patching(self): # Spot check that modeling code and model instance variables are patched self.assertEqual(modeling_llama.apply_rotary_pos_emb, liger_rotary_pos_emb) - self.assertTrue(isinstance(tiny_llama.model.norm, LigerRMSNorm)) + self.assertTrue("LigerRMSNorm" in tiny_llama.model.norm.__repr__()) @require_liger_kernel def test_use_liger_kernel_custom_config_patching(self): @@ -3231,7 +3231,7 @@ def test_run_seq2seq_double_train_wrap_once(self): model_wrapped_after = trainer.model_wrapped self.assertIs(model_wrapped_before, model_wrapped_after, "should be not wrapped twice") - @require_torch_up_to_2_accelerators + @require_torch_non_multi_accelerator def test_can_resume_training(self): # This test will fail for more than 2 GPUs since the batch size will get bigger and with the number of # save_steps, the checkpoint will resume training at epoch 2 or more (so the data seen by the model @@ -3532,8 +3532,9 @@ def test_auto_batch_size_with_resume_from_checkpoint(self): ) trainer = Trainer(model, args, train_dataset=train_dataset, callbacks=[MockCudaOOMCallback()]) trainer.train() - # After `auto_find_batch_size` is ran we should now be at 16*0.9=14 - self.assertEqual(trainer._train_batch_size, 14) + previous_batch_size = trainer._train_batch_size + # Depends on the number of gpus so it is easier to just check that the batch_size decreased as expected + self.assertEqual(trainer._train_batch_size < 16, True) # We can then make a new Trainer trainer = Trainer(model, args, train_dataset=train_dataset) @@ -3541,7 +3542,7 @@ def test_auto_batch_size_with_resume_from_checkpoint(self): self.assertEqual(trainer._train_batch_size, 16 * max(trainer.args.n_gpu, 1)) trainer.train(resume_from_checkpoint=True) # We should be back to 14 again, picking up based upon the last ran Trainer - self.assertEqual(trainer._train_batch_size, 14) + self.assertEqual(trainer._train_batch_size, previous_batch_size) # regression for this issue: https://github.com/huggingface/transformers/issues/12970 def test_training_with_resume_from_checkpoint_false(self): @@ -5147,11 +5148,7 @@ def test_trainer_works_without_model_config(self): with tempfile.TemporaryDirectory() as tmpdir: training_args = TrainingArguments( - output_dir=tmpdir, - report_to="none", - max_steps=5, - per_device_train_batch_size=1, - remove_unused_columns=False, + output_dir=tmpdir, report_to="none", max_steps=5, per_device_train_batch_size=1, use_cpu=True ) trainer = Trainer( model=model, @@ -5387,7 +5384,7 @@ def model_init(trial): b = 0 config = RegressionModelConfig(a=a, b=b, double_output=False) - return RegressionPreTrainedModel(config) + return RegressionPreTrainedModel(config).to(torch_device) def hp_name(trial): return MyTrialShortNamer.shortname(trial.params) @@ -5433,7 +5430,7 @@ def model_init(trial): b = 0 config = RegressionModelConfig(a=a, b=b, double_output=False) - return RegressionPreTrainedModel(config) + return RegressionPreTrainedModel(config).to(torch_device) def hp_name(trial): return MyTrialShortNamer.shortname(trial.params) @@ -5481,7 +5478,7 @@ def model_init(trial): b = 0 config = RegressionModelConfig(a=a, b=b, double_output=False) - return RegressionPreTrainedModel(config) + return RegressionPreTrainedModel(config).to(torch_device) with tempfile.TemporaryDirectory() as tmp_dir: trainer = get_regression_trainer( @@ -5526,7 +5523,7 @@ def model_init(config): b = config["b"] model_config = RegressionModelConfig(a=a, b=b, double_output=False) - return RegressionPreTrainedModel(model_config) + return RegressionPreTrainedModel(model_config).to(torch_device) def hp_name(params): return MyTrialShortNamer.shortname(params) @@ -5589,7 +5586,7 @@ def model_init(trial): b = 0 config = RegressionModelConfig(a=a, b=b, double_output=False) - return RegressionPreTrainedModel(config) + return RegressionPreTrainedModel(config).to(torch_device) def hp_name(trial): return MyTrialShortNamer.shortname(trial.assignments) @@ -6168,7 +6165,7 @@ def model_init(config): b = config["b"] model_config = RegressionModelConfig(a=a, b=b, double_output=False) - return RegressionPreTrainedModel(model_config) + return RegressionPreTrainedModel(model_config).to(torch_device) with tempfile.TemporaryDirectory() as tmp_dir: trainer = get_regression_trainer( From d8d78c6839c943b656889f2d898fa2075120e5f9 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:21:18 +0200 Subject: [PATCH 089/204] Fix `Glm4vMoeIntegrationTest` (#40930) * fix * fix * fix * fix * fix --------- Co-authored-by: ydshieh --- .../glm4v_moe/test_modeling_glm4v_moe.py | 245 ++++++------------ 1 file changed, 79 insertions(+), 166 deletions(-) diff --git a/tests/models/glm4v_moe/test_modeling_glm4v_moe.py b/tests/models/glm4v_moe/test_modeling_glm4v_moe.py index 83a2128c39de..dff5ea7074af 100644 --- a/tests/models/glm4v_moe/test_modeling_glm4v_moe.py +++ b/tests/models/glm4v_moe/test_modeling_glm4v_moe.py @@ -14,7 +14,6 @@ """Testing suite for the PyTorch GLM-4.1V model.""" import copy -import gc import unittest from transformers import ( @@ -25,9 +24,11 @@ is_torch_available, ) from transformers.testing_utils import ( + cleanup, require_flash_attn, require_torch, require_torch_gpu, + run_first, slow, torch_device, ) @@ -295,8 +296,26 @@ def test_inputs_embeds_matches_input_ids(self): @require_torch class Glm4vMoeIntegrationTest(unittest.TestCase): + model = None + + @classmethod + def get_model(cls): + if cls.model is None: + cls.model = Glm4vMoeForConditionalGeneration.from_pretrained( + "zai-org/GLM-4.5V", dtype="auto", device_map="auto" + ) + return cls.model + + @classmethod + def tearDownClass(cls): + del cls.model + cleanup(torch_device, gc_collect=True) + def setUp(self): - self.processor = AutoProcessor.from_pretrained("zai-org/GLM-4.5V") + cleanup(torch_device, gc_collect=True) + self.processor = AutoProcessor.from_pretrained( + "zai-org/GLM-4.5V", size={"shortest_edge": 10800, "longest_edge": 10800} + ) self.message = [ { "role": "user", @@ -321,130 +340,56 @@ def setUp(self): ], } ] + self.message_wo_image = [ + {"role": "user", "content": [{"type": "text", "text": "Who are you?"}]}, + ] + + question = "Describe this video." + video_url = "https://huggingface.co/datasets/hf-internal-testing/fixtures_videos/resolve/main/tennis.mp4" + self.video_messages = [ + { + "role": "user", + "content": [ + { + "type": "video", + "video": video_url, + }, + {"type": "text", "text": question}, + ], + } + ] def tearDown(self): - gc.collect() - torch.cuda.empty_cache() + cleanup(torch_device, gc_collect=True) @slow def test_small_model_integration_test(self): - model = Glm4vMoeForConditionalGeneration.from_pretrained("zai-org/GLM-4.5V", dtype="auto", device_map="auto") - inputs = self.processor.apply_chat_template( self.message, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt" ) - expected_input_ids = [151331, 151333, 151336, 198, 151339, 151343, 151343, 151343, 151343, 151343, 151343, 151343, 151343, 151343, 151343, 151343, 151343] # fmt: skip + expected_input_ids = [151331, 151333, 151336, 198, 151339, 151363, 151363, 151363, 151363, 151363, 151363, 151340, 3838, 3093, 315, 5562, 374] # fmt: skip assert expected_input_ids == inputs.input_ids[0].tolist()[:17] expected_pixel_slice = torch.tensor( [ - [-0.0988, -0.0842, -0.0842], - [-0.5660, -0.5514, -0.4200], - [-0.0259, -0.0259, -0.0259], - [-0.1280, -0.0988, -0.2010], - [-0.4638, -0.5806, -0.6974], - [-1.2083, -1.2229, -1.2083], + [-0.1134, -0.4492, -0.8580], + [-0.6244, -1.1645, -0.7120], + [-0.3324, -0.7996, -0.7120], + [0.2077, 0.2223, 0.4121], + [0.4413, 0.1931, 0.4559], + [0.5873, 0.3099, 0.4851], ], dtype=torch.float32, device="cpu", ) - assert torch.allclose(expected_pixel_slice, inputs.pixel_values[:6, :3], atol=3e-3) - - # verify generation - inputs = inputs.to(torch_device) - - output = model.generate(**inputs, max_new_tokens=30) - EXPECTED_DECODED_TEXT = "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks" - self.assertEqual( - self.processor.decode(output[0], skip_special_tokens=True), - EXPECTED_DECODED_TEXT, - ) + torch.testing.assert_close(expected_pixel_slice, inputs.pixel_values[:6, :3], atol=1e-4, rtol=1e-4) @slow def test_small_model_integration_test_batch(self): - model = Glm4vMoeForConditionalGeneration.from_pretrained("zai-org/GLM-4.5V", dtype="auto", device_map="auto") - batch_messages = [self.message] * 2 + model = self.get_model() + batch_messages = [self.message, self.message2, self.message_wo_image] inputs = self.processor.apply_chat_template( - batch_messages, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt" - ).to(torch_device) - - # it should not matter whether two images are the same size or not - output = model.generate(**inputs, max_new_tokens=30) - - EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks", - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks" - ] # fmt: skip - self.assertEqual( - self.processor.batch_decode(output, skip_special_tokens=True), - EXPECTED_DECODED_TEXT, - ) - - @slow - def test_small_model_integration_test_with_video(self): - processor = AutoProcessor.from_pretrained("zai-org/GLM-4.5V", max_image_size={"longest_edge": 50176}) - model = Glm4vMoeForConditionalGeneration.from_pretrained( - "zai-org/GLM-4.5V", dtype=torch.float16, device_map="auto" - ) - questions = ["Describe this video."] * 2 - video_urls = [ - "https://huggingface.co/datasets/hf-internal-testing/fixtures_videos/resolve/main/tennis.mp4" - ] * 2 - messages = [ - [ - { - "role": "user", - "content": [ - { - "type": "video", - "video": video_url, - }, - {"type": "text", "text": question}, - ], - } - ] - for question, video_url in zip(questions, video_urls) - ] - inputs = processor.apply_chat_template( - messages, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt", padding=True - ).to(torch_device) - output = model.generate(**inputs, max_new_tokens=30) - EXPECTED_DECODED_TEXT = [ - "\n012345Describe this video.\nGot it, let's analyze the video. First, the scene is a room with a wooden floor, maybe a traditional Japanese room with tatami", - "\n012345Describe this video.\nGot it, let's analyze the video. First, the scene is a room with a wooden floor, maybe a traditional Japanese room with tatami" - ] # fmt: skip - self.assertEqual( - processor.batch_decode(output, skip_special_tokens=True), - EXPECTED_DECODED_TEXT, - ) - - @slow - def test_small_model_integration_test_expand(self): - model = Glm4vMoeForConditionalGeneration.from_pretrained("zai-org/GLM-4.5V", dtype="auto", device_map="auto") - inputs = self.processor.apply_chat_template( - self.message, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt" - ).to(torch_device) - - output = model.generate(**inputs, max_new_tokens=30, do_sample=False, num_beams=2, num_return_sequences=2) - - EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture doesn't look like a dog; it's actually a cat. Specifically", - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture doesn't look like a dog; it's actually a cat, specifically" - ] # fmt: skip - self.assertEqual( - self.processor.batch_decode(output, skip_special_tokens=True), - EXPECTED_DECODED_TEXT, - ) - - @slow - def test_small_model_integration_test_batch_wo_image(self): - model = Glm4vMoeForConditionalGeneration.from_pretrained("zai-org/GLM-4.5V", dtype="auto", device_map="auto") - message_wo_image = [ - {"role": "user", "content": [{"type": "text", "text": "Who are you?"}]}, - ] - batched_messages = [self.message, message_wo_image] - inputs = self.processor.apply_chat_template( - batched_messages, + batch_messages, tokenize=True, add_generation_prompt=True, return_dict=True, @@ -453,42 +398,43 @@ def test_small_model_integration_test_batch_wo_image(self): ).to(torch_device) # it should not matter whether two images are the same size or not - output = model.generate(**inputs, max_new_tokens=30) + output = model.generate(**inputs, max_new_tokens=10) EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks", - '\nWho are you?\nGot it, the user is asking "Who are you?" I need to respond appropriately. First, I should clarify that I\'m an AI assistant' + "\nWhat kind of dog is this?\nGot it, let's try to figure out", + "\nWhat kind of dog is this?\nGot it, let's see. The user", + '\nWho are you?\nThe user is asking "Who are you?"' ] # fmt: skip + decoded = self.processor.batch_decode(output, skip_special_tokens=True) + decoded = [x.replace("<|image|>", "") for x in decoded] self.assertEqual( - self.processor.batch_decode(output, skip_special_tokens=True), + decoded, EXPECTED_DECODED_TEXT, ) @slow - def test_small_model_integration_test_batch_different_resolutions(self): - model = Glm4vMoeForConditionalGeneration.from_pretrained("zai-org/GLM-4.5V", dtype="auto", device_map="auto") - batched_messages = [self.message, self.message2] - inputs = self.processor.apply_chat_template( - batched_messages, + def test_small_model_integration_test_with_video(self): + processor = AutoProcessor.from_pretrained("zai-org/GLM-4.5V", max_image_size={"longest_edge": 50176}) + model = self.get_model() + batch_messages = [self.video_messages] + inputs = processor.apply_chat_template( + batch_messages, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt", padding=True, ).to(torch_device) - - # it should not matter whether two images are the same size or not - output = model.generate(**inputs, max_new_tokens=30) - - EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks", - "\nWhat kind of dog is this?\nGot it, let's look at the image. Wait, the animals here are cats, not dogs. The question is about a dog, but" - ] # fmt: skip + output = model.generate(**inputs, max_new_tokens=3) + EXPECTED_DECODED_TEXT = ["\n012345Describe this video.\nGot it"] # fmt: skip + decoded = processor.batch_decode(output, skip_special_tokens=True) + decoded = [x.replace("<|image|>", "") for x in decoded] self.assertEqual( - self.processor.batch_decode(output, skip_special_tokens=True), + decoded, EXPECTED_DECODED_TEXT, ) + @run_first @slow @require_flash_attn @require_torch_gpu @@ -499,44 +445,9 @@ def test_small_model_integration_test_batch_flashatt2(self): attn_implementation="flash_attention_2", device_map="auto", ) - batched_messages = [self.message, self.message2] - inputs = self.processor.apply_chat_template( - batched_messages, - tokenize=True, - add_generation_prompt=True, - return_dict=True, - return_tensors="pt", - padding=True, - ).to(torch_device) - - # it should not matter whether two images are the same size or not - output = model.generate(**inputs, max_new_tokens=30) - - EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture has a stocky build, thick fur, and a face that's", - "\nWhat kind of dog is this?\nGot it, let's look at the image. Wait, the animals here are cats, not dogs. The question is about a dog, but" - ] # fmt: skip - self.assertEqual( - self.processor.batch_decode(output, skip_special_tokens=True), - EXPECTED_DECODED_TEXT, - ) - - @slow - @require_flash_attn - @require_torch_gpu - def test_small_model_integration_test_batch_wo_image_flashatt2(self): - model = Glm4vMoeForConditionalGeneration.from_pretrained( - "zai-org/GLM-4.5V", - dtype=torch.bfloat16, - attn_implementation="flash_attention_2", - device_map="auto", - ) - message_wo_image = [ - {"role": "user", "content": [{"type": "text", "text": "Who are you?"}]}, - ] - batched_messages = [self.message, message_wo_image] + batch_messages = [self.message, self.message2, self.message_wo_image] inputs = self.processor.apply_chat_template( - batched_messages, + batch_messages, tokenize=True, add_generation_prompt=True, return_dict=True, @@ -545,14 +456,16 @@ def test_small_model_integration_test_batch_wo_image_flashatt2(self): ).to(torch_device) # it should not matter whether two images are the same size or not - output = model.generate(**inputs, max_new_tokens=30) + output = model.generate(**inputs, max_new_tokens=3) EXPECTED_DECODED_TEXT = [ - "\nWhat kind of dog is this?\nGot it, let's look at the image. The animal in the picture is not a dog; it's a cat. Specifically, it looks", - '\nWho are you?\nGot it, let\'s look at the question. The user is asking "Who are you?" which is a common question when someone meets an AI' + "\nWhat kind of dog is this?\nGot it", + "\nWhat kind of dog is this?\nGot it", + "\nWho are you?\nThe user", ] # fmt: skip - + decoded = self.processor.batch_decode(output, skip_special_tokens=True) + decoded = [x.replace("<|image|>", "") for x in decoded] self.assertEqual( - self.processor.batch_decode(output, skip_special_tokens=True), + decoded, EXPECTED_DECODED_TEXT, ) From f0150ad2a6c64801f739de6126c00894d3f53907 Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Wed, 17 Sep 2025 18:23:37 +0200 Subject: [PATCH 090/204] Raise error instead of warning when using meta device in from_pretrained (#40942) * raise instead of warning * add timm * remove --- src/transformers/modeling_utils.py | 9 ++++----- .../test_modeling_perception_lm.py | 4 ---- .../test_modeling_timm_backbone.py | 2 +- tests/models/xcodec/test_modeling_xcodec.py | 4 ---- tests/test_modeling_common.py | 17 +++++------------ 5 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index 33ecceacb17a..12c3e7cd99ef 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -4910,11 +4910,10 @@ def from_pretrained( if device_map is None and not is_deepspeed_zero3_enabled(): device_in_context = get_torch_context_manager_or_global_device() if device_in_context == torch.device("meta"): - # TODO Cyril: raise an error instead of the warning in v4.53 (and change the test to check for raise instead of success) - logger.warning( - "We detected that you are using `from_pretrained` with a meta device context manager or `torch.set_default_device('meta')`\n" - "This is an anti-pattern and will raise an Error in version v4.53\nIf you want to initialize a model on the meta device, use " - "the context manager or global device with `from_config`, or `ModelClass(config)`" + raise RuntimeError( + "You are using `from_pretrained` with a meta device context manager or `torch.set_default_device('meta')`.\n" + "This is an anti-pattern as `from_pretrained` wants to load existing weights.\nIf you want to initialize an " + "empty model on the meta device, use the context manager or global device with `from_config`, or `ModelClass(config)`" ) device_map = device_in_context diff --git a/tests/models/perception_lm/test_modeling_perception_lm.py b/tests/models/perception_lm/test_modeling_perception_lm.py index b9afe167dc41..0c927b82d12b 100644 --- a/tests/models/perception_lm/test_modeling_perception_lm.py +++ b/tests/models/perception_lm/test_modeling_perception_lm.py @@ -313,10 +313,6 @@ def test_flash_attention_2_padding_matches_padding_free_with_position_ids(self): def test_can_be_initialized_on_meta(self): pass - @unittest.skip("ViT PE / TimmWrapperModel cannot be tested with meta device") - def test_can_load_with_meta_device_context_manager(self): - pass - @unittest.skip("Specifying both inputs_embeds and pixel_values are not supported for PerceptionLM") def test_generate_from_inputs_embeds_0_greedy(self): pass diff --git a/tests/models/timm_backbone/test_modeling_timm_backbone.py b/tests/models/timm_backbone/test_modeling_timm_backbone.py index 0bf79a613169..d8fc0d53a4cd 100644 --- a/tests/models/timm_backbone/test_modeling_timm_backbone.py +++ b/tests/models/timm_backbone/test_modeling_timm_backbone.py @@ -169,7 +169,7 @@ def test_can_load_with_global_device_set(self): pass @unittest.skip(reason="TimmBackbone uses its own `from_pretrained` without device_map support") - def test_can_load_with_meta_device_context_manager(self): + def test_cannot_load_with_meta_device_context_manager(self): pass @unittest.skip(reason="model weights aren't tied in TimmBackbone.") diff --git a/tests/models/xcodec/test_modeling_xcodec.py b/tests/models/xcodec/test_modeling_xcodec.py index 7708edef27e9..a5df6cfeb310 100644 --- a/tests/models/xcodec/test_modeling_xcodec.py +++ b/tests/models/xcodec/test_modeling_xcodec.py @@ -151,10 +151,6 @@ def test_gradient_checkpointing_backward_compatibility(self): model = model_class(config) self.assertTrue(model.is_gradient_checkpointing) - @unittest.skip("XcodecModel cannot be tested with meta device") - def test_can_load_with_meta_device_context_manager(self): - pass - @unittest.skip(reason="We cannot configure to output a smaller model.") def test_model_is_small(self): pass diff --git a/tests/test_modeling_common.py b/tests/test_modeling_common.py index 4e95b1f255a5..188c7517d54c 100755 --- a/tests/test_modeling_common.py +++ b/tests/test_modeling_common.py @@ -4488,7 +4488,7 @@ def test_can_load_with_global_device_set(self): unique_devices, {device}, f"All parameters should be on {device}, but found {unique_devices}." ) - def test_can_load_with_meta_device_context_manager(self): + def test_cannot_load_with_meta_device_context_manager(self): config, _ = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: # Need to deepcopy here as it is modified in-place in save_pretrained (it sets sdpa for default attn, which @@ -4497,18 +4497,11 @@ def test_can_load_with_meta_device_context_manager(self): with tempfile.TemporaryDirectory() as tmpdirname: model.save_pretrained(tmpdirname) - with torch.device("meta"): - new_model = model_class.from_pretrained(tmpdirname) - unique_devices = {param.device for param in new_model.parameters()} | { - buffer.device for buffer in new_model.buffers() - } - - self.assertEqual( - unique_devices, - {torch.device("meta")}, - f"All parameters should be on meta device, but found {unique_devices}.", - ) + with self.assertRaisesRegex( + RuntimeError, "You are using `from_pretrained` with a meta device context manager" + ): + _ = model_class.from_pretrained(tmpdirname) def test_config_attn_implementation_setter(self): config, _ = self.model_tester.prepare_config_and_inputs_for_common() From 8b8b35398960a094d43687522a8638f0258beb85 Mon Sep 17 00:00:00 2001 From: Raushan Turganbay Date: Wed, 17 Sep 2025 18:40:25 +0200 Subject: [PATCH 091/204] Consistent naming for images kwargs (#40834) * use consistent naming for padding * no validation on pad size * add warnings * fix * fox copies * another fix * fix some tests * fix more tests * fix lasts tests * fix copies * better docstring * delete print --- .../image_processing_utils_fast.py | 91 ++++++++- src/transformers/image_utils.py | 13 +- .../image_processing_bridgetower.py | 2 - .../image_processing_bridgetower_fast.py | 60 +----- .../bridgetower/processing_bridgetower.py | 9 +- .../image_processing_cohere2_vision_fast.py | 1 + .../image_processing_conditional_detr_fast.py | 15 +- .../image_processing_convnext_fast.py | 1 + .../image_processing_deepseek_vl.py | 33 +++- .../image_processing_deepseek_vl_fast.py | 1 + .../image_processing_deepseek_vl_hybrid.py | 37 ++-- ...mage_processing_deepseek_vl_hybrid_fast.py | 1 + .../modular_deepseek_vl_hybrid.py | 27 ++- .../image_processing_deformable_detr_fast.py | 15 +- .../image_processing_depth_pro_fast.py | 1 + .../models/detr/image_processing_detr_fast.py | 15 +- .../image_processing_dinov3_vit_fast.py | 1 + .../models/donut/image_processing_donut.py | 6 - .../donut/image_processing_donut_fast.py | 5 - .../models/dpt/image_processing_dpt.py | 2 - .../models/dpt/image_processing_dpt_fast.py | 4 - src/transformers/models/dpt/modular_dpt.py | 4 - .../models/fuyu/image_processing_fuyu.py | 2 - .../gemma3/image_processing_gemma3_fast.py | 3 +- .../image_processing_got_ocr2_fast.py | 1 + .../image_processing_grounding_dino_fast.py | 15 +- .../image_processing_idefics2_fast.py | 3 - .../image_processing_idefics3_fast.py | 4 - .../video_processing_instructblipvideo.py | 6 +- .../internvl/video_processing_internvl.py | 6 +- .../models/janus/image_processing_janus.py | 33 +++- .../janus/image_processing_janus_fast.py | 1 + .../models/janus/modular_janus.py | 177 ++++++++++++++++-- .../llava/image_processing_llava_fast.py | 10 +- .../image_processing_llava_next_fast.py | 4 - .../image_processing_llava_onevision_fast.py | 4 - .../modular_llava_onevision.py | 4 - .../image_processing_mask2former_fast.py | 17 +- .../image_processing_maskformer_fast.py | 17 +- .../models/nougat/image_processing_nougat.py | 2 - .../nougat/image_processing_nougat_fast.py | 3 - .../image_processing_oneformer_fast.py | 21 +-- .../ovis2/image_processing_ovis2_fast.py | 1 + .../owlv2/image_processing_owlv2_fast.py | 16 +- .../models/owlv2/modular_owlv2.py | 16 +- .../pixtral/image_processing_pixtral_fast.py | 1 + .../image_processing_prompt_depth_anything.py | 2 - .../rt_detr/image_processing_rt_detr_fast.py | 15 +- .../models/rt_detr/modular_rt_detr.py | 4 +- .../models/sam/image_processing_sam.py | 2 - .../models/sam/image_processing_sam_fast.py | 68 +------ .../models/sam2/image_processing_sam2_fast.py | 19 +- .../smolvlm/image_processing_smolvlm_fast.py | 4 - .../smolvlm/video_processing_smolvlm.py | 3 +- .../swin2sr/image_processing_swin2sr.py | 31 ++- .../swin2sr/image_processing_swin2sr_fast.py | 48 +++-- .../models/tvp/image_processing_tvp.py | 2 - .../models/tvp/image_processing_tvp_fast.py | 53 +----- .../models/vilt/image_processing_vilt_fast.py | 4 - .../models/vilt/processing_vilt.py | 8 +- .../vitmatte/image_processing_vitmatte.py | 35 +++- .../image_processing_vitmatte_fast.py | 31 ++- .../yolos/image_processing_yolos_fast.py | 15 +- .../image_processing_zoedepth_fast.py | 3 - src/transformers/processing_utils.py | 22 ++- src/transformers/utils/auto_docstring.py | 17 ++ src/transformers/video_processing_utils.py | 9 +- .../models/gemma3n/test_processing_gemma3n.py | 10 +- tests/models/janus/test_processing_janus.py | 2 +- .../swin2sr/test_image_processing_swin2sr.py | 15 +- tests/models/tvp/test_image_processing_tvp.py | 32 ++-- .../test_image_processing_vitmatte.py | 28 +-- 72 files changed, 619 insertions(+), 574 deletions(-) diff --git a/src/transformers/image_processing_utils_fast.py b/src/transformers/image_processing_utils_fast.py index 5fb87c345ef0..4028c38ff227 100644 --- a/src/transformers/image_processing_utils_fast.py +++ b/src/transformers/image_processing_utils_fast.py @@ -79,8 +79,6 @@ def validate_fast_preprocess_arguments( do_normalize: Optional[bool] = None, image_mean: Optional[Union[float, list[float]]] = None, image_std: Optional[Union[float, list[float]]] = None, - do_pad: Optional[bool] = None, - size_divisibility: Optional[int] = None, do_center_crop: Optional[bool] = None, crop_size: Optional[SizeDict] = None, do_resize: Optional[bool] = None, @@ -99,8 +97,6 @@ def validate_fast_preprocess_arguments( do_normalize=do_normalize, image_mean=image_mean, image_std=image_std, - do_pad=do_pad, - size_divisibility=size_divisibility, do_center_crop=do_center_crop, crop_size=crop_size, do_resize=do_resize, @@ -181,6 +177,8 @@ class DefaultFastImageProcessorKwargs(TypedDict, total=False): do_normalize: Optional[bool] image_mean: Optional[Union[float, list[float]]] image_std: Optional[Union[float, list[float]]] + do_pad: Optional[bool] + pad_size: Optional[dict[str, int]] do_convert_rgb: Optional[bool] return_tensors: Optional[Union[str, TensorType]] data_format: Optional[ChannelDimension] @@ -199,6 +197,8 @@ class BaseImageProcessorFast(BaseImageProcessor): crop_size = None do_resize = None do_center_crop = None + do_pad = None + pad_size = None do_rescale = None rescale_factor = 1 / 255 do_normalize = None @@ -222,6 +222,9 @@ def __init__(self, **kwargs: Unpack[DefaultFastImageProcessorKwargs]): ) crop_size = kwargs.pop("crop_size", self.crop_size) self.crop_size = get_size_dict(crop_size, param_name="crop_size") if crop_size is not None else None + pad_size = kwargs.pop("pad_size", self.pad_size) + self.pad_size = get_size_dict(size=pad_size, param_name="pad_size") if pad_size is not None else None + for key in self.valid_kwargs.__annotations__: kwarg = kwargs.pop(key, None) if kwarg is not None: @@ -239,6 +242,74 @@ def is_fast(self) -> bool: """ return True + def pad( + self, + images: "torch.Tensor", + pad_size: SizeDict = None, + fill_value: Optional[int] = 0, + padding_mode: Optional[str] = "constant", + return_mask: Optional[bool] = False, + disable_grouping: Optional[bool] = False, + **kwargs, + ) -> "torch.Tensor": + """ + Pads images to `(pad_size["height"], pad_size["width"])` or to the largest size in the batch. + + Args: + images (`torch.Tensor`): + Images to pad. + pad_size (`SizeDict`, *optional*): + Dictionary in the format `{"height": int, "width": int}` specifying the size of the output image. + fill_value (`int`, *optional*, defaults to `0`): + The constant value used to fill the padded area. + padding_mode (`str`, *optional*, defaults to "constant"): + The padding mode to use. Can be any of the modes supported by + `torch.nn.functional.pad` (e.g. constant, reflection, replication). + return_mask (`bool`, *optional*, defaults to `False`): + Whether to return a pixel mask to denote padded regions. + disable_grouping (`bool`, *optional*, defaults to `False`): + Whether to disable grouping of images by size. + + Returns: + `torch.Tensor`: The resized image. + """ + if pad_size is not None: + if not (pad_size.height and pad_size.width): + raise ValueError(f"Pad size must contain 'height' and 'width' keys only. Got pad_size={pad_size}.") + pad_size = (pad_size.height, pad_size.width) + else: + pad_size = get_max_height_width(images) + + grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) + processed_images_grouped = {} + processed_masks_grouped = {} + for shape, stacked_images in grouped_images.items(): + image_size = stacked_images.shape[-2:] + padding_height = pad_size[0] - image_size[0] + padding_width = pad_size[1] - image_size[1] + if padding_height < 0 or padding_width < 0: + raise ValueError( + f"Padding dimensions are negative. Please make sure that the `pad_size` is larger than the " + f"image size. Got pad_size={pad_size}, image_size={image_size}." + ) + if image_size != pad_size: + padding = (0, 0, padding_width, padding_height) + stacked_images = F.pad(stacked_images, padding, fill=fill_value, padding_mode=padding_mode) + processed_images_grouped[shape] = stacked_images + + if return_mask: + # keep only one from the channel dimension in pixel mask + stacked_masks = torch.zeros_like(stacked_images, dtype=torch.int64)[..., 0, :, :] + stacked_masks[..., : image_size[0], : image_size[1]] = 1 + processed_masks_grouped[shape] = stacked_masks + + processed_images = reorder_images(processed_images_grouped, grouped_images_index) + if return_mask: + processed_masks = reorder_images(processed_masks_grouped, grouped_images_index) + return processed_images, processed_masks + + return processed_images + def resize( self, image: "torch.Tensor", @@ -577,6 +648,7 @@ def _further_process_kwargs( self, size: Optional[SizeDict] = None, crop_size: Optional[SizeDict] = None, + pad_size: Optional[SizeDict] = None, default_to_square: Optional[bool] = None, image_mean: Optional[Union[float, list[float]]] = None, image_std: Optional[Union[float, list[float]]] = None, @@ -593,6 +665,8 @@ def _further_process_kwargs( size = SizeDict(**get_size_dict(size=size, default_to_square=default_to_square)) if crop_size is not None: crop_size = SizeDict(**get_size_dict(crop_size, param_name="crop_size")) + if pad_size is not None: + pad_size = SizeDict(**get_size_dict(size=pad_size, param_name="pad_size")) if isinstance(image_mean, list): image_mean = tuple(image_mean) if isinstance(image_std, list): @@ -602,6 +676,7 @@ def _further_process_kwargs( kwargs["size"] = size kwargs["crop_size"] = crop_size + kwargs["pad_size"] = pad_size kwargs["image_mean"] = image_mean kwargs["image_std"] = image_std kwargs["data_format"] = data_format @@ -714,6 +789,8 @@ def _preprocess( do_normalize: bool, image_mean: Optional[Union[float, list[float]]], image_std: Optional[Union[float, list[float]]], + do_pad: Optional[bool], + pad_size: Optional[SizeDict], disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], **kwargs, @@ -739,10 +816,12 @@ def _preprocess( stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std ) processed_images_grouped[shape] = stacked_images - processed_images = reorder_images(processed_images_grouped, grouped_images_index) - processed_images = torch.stack(processed_images, dim=0) if return_tensors else processed_images + if do_pad: + processed_images = self.pad(processed_images, pad_size=pad_size, disable_grouping=disable_grouping) + + processed_images = torch.stack(processed_images, dim=0) if return_tensors else processed_images return BatchFeature(data={"pixel_values": processed_images}, tensor_type=return_tensors) def to_dict(self): diff --git a/src/transformers/image_utils.py b/src/transformers/image_utils.py index cb7c4bbf422a..2079c21f3b0c 100644 --- a/src/transformers/image_utils.py +++ b/src/transformers/image_utils.py @@ -525,7 +525,7 @@ def validate_preprocess_arguments( image_mean: Optional[Union[float, list[float]]] = None, image_std: Optional[Union[float, list[float]]] = None, do_pad: Optional[bool] = None, - size_divisibility: Optional[int] = None, + pad_size: Optional[Union[dict[str, int], int]] = None, do_center_crop: Optional[bool] = None, crop_size: Optional[dict[str, int]] = None, do_resize: Optional[bool] = None, @@ -544,10 +544,15 @@ def validate_preprocess_arguments( if do_rescale and rescale_factor is None: raise ValueError("`rescale_factor` must be specified if `do_rescale` is `True`.") - if do_pad and size_divisibility is None: - # Here, size_divisor might be passed as the value of size + if do_pad and pad_size is None: + # Processors pad images using different args depending on the model, so the below check is pointless + # but we keep it for BC for now. TODO: remove in v5 + # Usually padding can be called with: + # - "pad_size/size" if we're padding to specific values + # - "size_divisor" if we're padding to any value divisible by X + # - "None" if we're padding to the maximum size image in batch raise ValueError( - "Depending on the model, `size_divisibility`, `size_divisor`, `pad_size` or `size` must be specified if `do_pad` is `True`." + "Depending on the model, `size_divisor` or `pad_size` or `size` must be specified if `do_pad` is `True`." ) if do_normalize and (image_mean is None or image_std is None): diff --git a/src/transformers/models/bridgetower/image_processing_bridgetower.py b/src/transformers/models/bridgetower/image_processing_bridgetower.py index 28145b337a68..cb39ed097561 100644 --- a/src/transformers/models/bridgetower/image_processing_bridgetower.py +++ b/src/transformers/models/bridgetower/image_processing_bridgetower.py @@ -480,8 +480,6 @@ def preprocess( do_normalize=do_normalize, image_mean=image_mean, image_std=image_std, - do_pad=do_pad, - size_divisibility=size_divisor, do_center_crop=do_center_crop, crop_size=crop_size, do_resize=do_resize, diff --git a/src/transformers/models/bridgetower/image_processing_bridgetower_fast.py b/src/transformers/models/bridgetower/image_processing_bridgetower_fast.py index 64610ec4462a..4a7450c84498 100644 --- a/src/transformers/models/bridgetower/image_processing_bridgetower_fast.py +++ b/src/transformers/models/bridgetower/image_processing_bridgetower_fast.py @@ -25,7 +25,6 @@ SizeDict, TensorType, Unpack, - get_max_height_width, group_images_by_shape, reorder_images, ) @@ -99,13 +98,9 @@ class BridgeTowerFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): size_divisor (`int`, *optional*, defaults to 32): The size by which to make sure both the height and width can be divided. Only has an effect if `do_resize` is set to `True`. Can be overridden by the `size_divisor` parameter in the `preprocess` method. - do_pad (`bool`, *optional*, defaults to `True`): - Whether to pad the image to the `(max_height, max_width)` of the images in the batch. Can be overridden by - the `do_pad` parameter in the `preprocess` method. """ size_divisor: Optional[int] - do_pad: Optional[bool] @auto_docstring @@ -224,59 +219,6 @@ def _pad_image( ) return padded_image - def pad( - self, - images: list["torch.Tensor"], - constant_values: Union[float, Iterable[float]] = 0, - return_pixel_mask: bool = True, - disable_grouping: Optional[bool] = False, - ) -> tuple: - """ - Pads a batch of images to the bottom and right of the image with zeros to the size of largest height and width - in the batch and optionally returns their corresponding pixel mask. - - Args: - image (`torch.Tensor`): - Image to pad. - constant_values (`float` or `Iterable[float]`, *optional*): - The value to use for the padding if `mode` is `"constant"`. - return_pixel_mask (`bool`, *optional*, defaults to `True`): - Whether to return a pixel mask. - disable_grouping (`bool`, *optional*, defaults to `False`): - Whether to disable grouping of images by size. - return_tensors (`str` or `TensorType`, *optional*): - The type of tensors to return. Can be one of: - - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. - """ - pad_size = get_max_height_width(images) - - grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) - processed_images_grouped = {} - processed_masks_grouped = {} - for shape, stacked_images in grouped_images.items(): - stacked_images = self._pad_image( - stacked_images, - pad_size, - constant_values=constant_values, - ) - processed_images_grouped[shape] = stacked_images - - if return_pixel_mask: - stacked_masks = make_pixel_mask(image=stacked_images, output_size=pad_size) - processed_masks_grouped[shape] = stacked_masks - - processed_images = reorder_images(processed_images_grouped, grouped_images_index) - - processed_masks = None - if return_pixel_mask: - processed_masks = reorder_images(processed_masks_grouped, grouped_images_index) - - return processed_images, processed_masks - def _preprocess( self, images: list["torch.Tensor"], @@ -325,7 +267,7 @@ def _preprocess( data = {} if do_pad: processed_images, processed_masks = self.pad( - processed_images, return_pixel_mask=True, disable_grouping=disable_grouping + processed_images, return_mask=True, disable_grouping=disable_grouping ) processed_masks = torch.stack(processed_masks, dim=0) if return_tensors else processed_masks data["pixel_mask"] = processed_masks diff --git a/src/transformers/models/bridgetower/processing_bridgetower.py b/src/transformers/models/bridgetower/processing_bridgetower.py index 030c578c49cd..6d7059c4c5a5 100644 --- a/src/transformers/models/bridgetower/processing_bridgetower.py +++ b/src/transformers/models/bridgetower/processing_bridgetower.py @@ -16,10 +16,17 @@ Processor class for BridgeTower. """ -from ...processing_utils import ProcessingKwargs, ProcessorMixin +from typing import Optional + +from ...processing_utils import ImagesKwargs, ProcessingKwargs, ProcessorMixin + + +class BridgeTowerImagesKwargs(ImagesKwargs): + size_divisor: Optional[int] class BridgeTowerProcessorKwargs(ProcessingKwargs, total=False): + images_kwargs: BridgeTowerImagesKwargs _defaults = { "text_kwargs": { "add_special_tokens": True, diff --git a/src/transformers/models/cohere2_vision/image_processing_cohere2_vision_fast.py b/src/transformers/models/cohere2_vision/image_processing_cohere2_vision_fast.py index 6b7c8327dc89..afe76134bc8d 100644 --- a/src/transformers/models/cohere2_vision/image_processing_cohere2_vision_fast.py +++ b/src/transformers/models/cohere2_vision/image_processing_cohere2_vision_fast.py @@ -227,6 +227,7 @@ def _preprocess( image_std: Optional[Union[float, list[float]]], disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], + **kwargs, ) -> BatchFeature: if crop_to_patches: grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) diff --git a/src/transformers/models/conditional_detr/image_processing_conditional_detr_fast.py b/src/transformers/models/conditional_detr/image_processing_conditional_detr_fast.py index 06ef3f431050..86e51f2b4a60 100644 --- a/src/transformers/models/conditional_detr/image_processing_conditional_detr_fast.py +++ b/src/transformers/models/conditional_detr/image_processing_conditional_detr_fast.py @@ -74,23 +74,12 @@ class ConditionalDetrFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Controls whether to convert the annotations to the format expected by the CONDITIONAL_DETR model. Converts the bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`. Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method. - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with zeros. - If `pad_size` is provided, the image will be padded to the specified dimensions. - Otherwise, the image will be padded to the maximum height and width of the batch. - pad_size (`dict[str, int]`, *optional*): - The size `{"height": int, "width" int}` to pad the images to. Must be larger than any image size - provided for preprocessing. If `pad_size` is not provided, images will be padded to the largest - height and width in the batch. return_segmentation_masks (`bool`, *optional*, defaults to `False`): Whether to return segmentation masks. """ format: Optional[Union[str, AnnotationFormat]] do_convert_annotations: Optional[bool] - do_pad: Optional[bool] - pad_size: Optional[dict[str, int]] return_segmentation_masks: Optional[bool] @@ -629,7 +618,7 @@ def _preprocess( image_mean: Optional[Union[float, list[float]]], image_std: Optional[Union[float, list[float]]], do_pad: bool, - pad_size: Optional[dict[str, int]], + pad_size: Optional[SizeDict], format: Optional[Union[str, AnnotationFormat]], return_tensors: Optional[Union[str, TensorType]], **kwargs, @@ -698,7 +687,7 @@ def _preprocess( if do_pad: # depends on all resized image shapes so we need another loop if pad_size is not None: - padded_size = (pad_size["height"], pad_size["width"]) + padded_size = (pad_size.height, pad_size.width) else: padded_size = get_max_height_width(images) diff --git a/src/transformers/models/convnext/image_processing_convnext_fast.py b/src/transformers/models/convnext/image_processing_convnext_fast.py index 130fcc19639e..0866b230a52e 100644 --- a/src/transformers/models/convnext/image_processing_convnext_fast.py +++ b/src/transformers/models/convnext/image_processing_convnext_fast.py @@ -155,6 +155,7 @@ def _preprocess( image_std: Optional[Union[float, list[float]]], disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], + **kwargs, ) -> BatchFeature: # Group images by size for batched resizing grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) diff --git a/src/transformers/models/deepseek_vl/image_processing_deepseek_vl.py b/src/transformers/models/deepseek_vl/image_processing_deepseek_vl.py index 1a9444cbf9db..7ab4e98012ac 100644 --- a/src/transformers/models/deepseek_vl/image_processing_deepseek_vl.py +++ b/src/transformers/models/deepseek_vl/image_processing_deepseek_vl.py @@ -89,6 +89,8 @@ class DeepseekVLImageProcessor(BaseImageProcessor): Can be overridden by the `image_std` parameter in the `preprocess` method. do_convert_rgb (`bool`, *optional*, defaults to `True`): Whether to convert the image to RGB. + do_pad (`bool`, *optional*, defaults to `True`): + Whether to pad the image to square or not. """ model_input_names = ["pixel_values"] @@ -105,6 +107,7 @@ def __init__( image_mean: Optional[Union[float, list[float]]] = None, image_std: Optional[Union[float, list[float]]] = None, do_convert_rgb: Optional[bool] = None, + do_pad: Optional[bool] = True, **kwargs, ) -> None: super().__init__(**kwargs) @@ -121,6 +124,7 @@ def __init__( self.image_std = image_std if image_std is not None else OPENAI_CLIP_STD self.do_convert_rgb = do_convert_rgb + self.do_pad = do_pad self.min_size = min_size if image_mean is None: self.background_color = (127, 127, 127) @@ -131,7 +135,6 @@ def resize( self, image: np.ndarray, size: Union[dict[str, int], int], - background_color: Optional[tuple[int, int, int]] = None, resample: PILImageResampling = PILImageResampling.BICUBIC, data_format: Optional[Union[str, ChannelDimension]] = None, input_data_format: Optional[Union[str, ChannelDimension]] = None, @@ -145,8 +148,6 @@ def resize( Image to resize. size (`dict[str, int]` or `int`): The size to resize the image to. If a dictionary, it should have the keys `"height"` and `"width"`. - background_color (`tuple[int, int, int]`): - The background color to use for the padding. resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BICUBIC`): `PILImageResampling` filter to use when resizing the image e.g. `PILImageResampling.BICUBIC`. data_format (`ChannelDimension` or `str`, *optional*): @@ -165,7 +166,6 @@ def resize( Returns: `np.ndarray`: The resized image. """ - background_color = background_color if background_color is not None else self.background_color if input_data_format is None: input_data_format = infer_channel_dimension_format(image) @@ -194,12 +194,6 @@ def resize( input_data_format=input_data_format, **kwargs, ) - # Expand and pad the images to obtain a square image of dimensions `size x size` - image = self.pad_to_square( - image=image, - background_color=background_color, - input_data_format=input_data_format, - ) return image @filter_out_non_signature_kwargs() @@ -216,6 +210,8 @@ def preprocess( image_std: Optional[Union[float, list[float]]] = None, return_tensors: Optional[Union[str, TensorType]] = None, do_convert_rgb: Optional[bool] = None, + background_color: Optional[Union[int, tuple[int, int, int]]] = None, + do_pad: Optional[bool] = None, data_format: ChannelDimension = ChannelDimension.FIRST, input_data_format: Optional[Union[str, ChannelDimension]] = None, ) -> PIL.Image.Image: @@ -247,6 +243,10 @@ def preprocess( Image standard deviation to normalize the image by if `do_normalize` is set to `True`. do_convert_rgb (`bool`, *optional*, defaults to `self.do_convert_rgb`): Whether to convert the image to RGB. + background_color (`tuple[int, int, int]`): + The background color to use for the padding. + do_pad (`bool`, *optional*, defaults to `self.do_pad`): + Whether to pad the image to square or not. return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. @@ -274,6 +274,8 @@ def preprocess( image_mean = image_mean if image_mean is not None else self.image_mean image_std = image_std if image_std is not None else self.image_std do_convert_rgb = do_convert_rgb if do_convert_rgb is not None else self.do_convert_rgb + do_pad = do_pad if do_pad is not None else self.do_pad + background_color = background_color if background_color is not None else self.background_color size = size if size is not None else self.size size = get_size_dict(size, default_to_square=False) @@ -319,6 +321,17 @@ def preprocess( for image in images ] + if do_pad: + # Expand and pad the images to obtain a square image of dimensions `size x size` + images = [ + self.pad_to_square( + image=image, + background_color=background_color, + input_data_format=input_data_format, + ) + for image in images + ] + if do_rescale: images = [ self.rescale(image=image, scale=rescale_factor, input_data_format=input_data_format) diff --git a/src/transformers/models/deepseek_vl/image_processing_deepseek_vl_fast.py b/src/transformers/models/deepseek_vl/image_processing_deepseek_vl_fast.py index 2204606d4211..7764a8250159 100644 --- a/src/transformers/models/deepseek_vl/image_processing_deepseek_vl_fast.py +++ b/src/transformers/models/deepseek_vl/image_processing_deepseek_vl_fast.py @@ -62,6 +62,7 @@ class DeepseekVLImageProcessorFast(BaseImageProcessorFast): do_resize = True do_rescale = True do_normalize = True + do_pad = True valid_kwargs = DeepseekVLFastImageProcessorKwargs def __init__(self, **kwargs: Unpack[DeepseekVLFastImageProcessorKwargs]): diff --git a/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid.py b/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid.py index 45e19da0d14c..7c7d6df82424 100644 --- a/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid.py +++ b/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid.py @@ -102,6 +102,8 @@ class DeepseekVLHybridImageProcessor(BaseImageProcessor): number of channels in the image. Can be overridden by the `high_res_image_std` parameter in the `preprocess` method. do_convert_rgb (`bool`, *optional*, defaults to `True`): Whether to convert the image to RGB. + do_pad (`bool`, *optional*, defaults to `True`): + Whether to pad the image to square or not. """ model_input_names = ["pixel_values", "high_res_pixel_values"] @@ -122,6 +124,7 @@ def __init__( high_res_image_mean: Optional[Union[float, list[float]]] = None, high_res_image_std: Optional[Union[float, list[float]]] = None, do_convert_rgb: Optional[bool] = None, + do_pad: bool = True, **kwargs, ) -> None: super().__init__(**kwargs) @@ -147,6 +150,7 @@ def __init__( self.image_std = image_std if image_std is not None else OPENAI_CLIP_STD self.do_convert_rgb = do_convert_rgb + self.do_pad = do_pad self.min_size = min_size if image_mean is None: self.background_color = (127, 127, 127) @@ -162,7 +166,6 @@ def resize( self, image: np.ndarray, size: Union[dict[str, int], int], - background_color: Optional[tuple[int, int, int]] = None, resample: PILImageResampling = PILImageResampling.BICUBIC, data_format: Optional[Union[str, ChannelDimension]] = None, input_data_format: Optional[Union[str, ChannelDimension]] = None, @@ -176,8 +179,6 @@ def resize( Image to resize. size (`dict[str, int]` or `int`): The size to resize the image to. If a dictionary, it should have the keys `"height"` and `"width"`. - background_color (`tuple[int, int, int]`): - The background color to use for the padding. resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BICUBIC`): `PILImageResampling` filter to use when resizing the image e.g. `PILImageResampling.BICUBIC`. data_format (`ChannelDimension` or `str`, *optional*): @@ -196,7 +197,6 @@ def resize( Returns: `np.ndarray`: The resized image. """ - background_color = background_color if background_color is not None else self.background_color if input_data_format is None: input_data_format = infer_channel_dimension_format(image) @@ -225,12 +225,6 @@ def resize( input_data_format=input_data_format, **kwargs, ) - # Expand and pad the images to obtain a square image of dimensions `size x size` - image = self.pad_to_square( - image=image, - background_color=background_color, - input_data_format=input_data_format, - ) return image @filter_out_non_signature_kwargs() @@ -253,6 +247,8 @@ def preprocess( data_format: Union[str, ChannelDimension] = ChannelDimension.FIRST, input_data_format: Optional[Union[str, ChannelDimension]] = None, do_convert_rgb: Optional[bool] = None, + do_pad: Optional[bool] = None, + background_color: Optional[tuple[int, int, int]] = None, ) -> PIL.Image.Image: """ Preprocess an image or batch of images. @@ -309,6 +305,10 @@ def preprocess( - `"none"` or `ChannelDimension.NONE`: image in (height, width) format. do_convert_rgb (`bool`, *optional*, defaults to `self.do_convert_rgb`): Whether to convert the image to RGB. + do_pad (`bool`, *optional*, defaults to `self.do_pad`): + Whether to pad the image to square or not. + background_color (`tuple[int, int, int]`): + The background color to use for the padding. """ do_resize = do_resize if do_resize is not None else self.do_resize do_rescale = do_rescale if do_rescale is not None else self.do_rescale @@ -321,6 +321,8 @@ def preprocess( high_res_image_mean = high_res_image_mean if high_res_image_mean is not None else self.high_res_image_mean high_res_image_std = high_res_image_std if high_res_image_std is not None else self.high_res_image_std do_convert_rgb = do_convert_rgb if do_convert_rgb is not None else self.do_convert_rgb + do_pad = do_pad if do_pad is not None else self.do_pad + background_color = background_color if background_color is not None else self.background_color size = size if size is not None else self.size size_dict = get_size_dict(size) @@ -372,17 +374,28 @@ def preprocess( high_res_image = self.resize( image=high_res_image, size=high_res_size_dict, - background_color=self.high_res_background_color, resample=high_res_resample, input_data_format=input_data_format, ) + if do_pad: + # Expand and pad the images to obtain a square image of dimensions `size x size` + high_res_image = self.pad_to_square( + image=high_res_image, + background_color=background_color, + input_data_format=input_data_format, + ) image = self.resize( image=high_res_image, size=size_dict, - background_color=self.background_color, resample=resample, input_data_format=input_data_format, ) + if do_pad: + image = self.pad_to_square( + image=image, + background_color=background_color, + input_data_format=input_data_format, + ) if do_rescale: image = self.rescale(image=image, scale=rescale_factor, input_data_format=input_data_format) diff --git a/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid_fast.py b/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid_fast.py index d55610331f30..3770cf18303e 100644 --- a/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid_fast.py +++ b/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid_fast.py @@ -86,6 +86,7 @@ class DeepseekVLHybridImageProcessorFast(BaseImageProcessorFast): do_resize = True do_rescale = True do_normalize = True + do_pad = True valid_kwargs = DeepseekVLHybridFastImageProcessorKwargs high_res_image_mean = OPENAI_CLIP_MEAN high_res_image_std = OPENAI_CLIP_STD diff --git a/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py b/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py index 6c36cfa50daa..c6cf71b09613 100644 --- a/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py +++ b/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py @@ -488,6 +488,8 @@ class DeepseekVLHybridImageProcessor(DeepseekVLImageProcessor): number of channels in the image. Can be overridden by the `high_res_image_std` parameter in the `preprocess` method. do_convert_rgb (`bool`, *optional*, defaults to `True`): Whether to convert the image to RGB. + do_pad (`bool`, *optional*, defaults to `True`): + Whether to pad the image to square or not. """ model_input_names = ["pixel_values", "high_res_pixel_values"] @@ -508,6 +510,7 @@ def __init__( high_res_image_mean: Optional[Union[float, list[float]]] = None, high_res_image_std: Optional[Union[float, list[float]]] = None, do_convert_rgb: Optional[bool] = None, + do_pad: bool = True, **kwargs, ) -> None: high_res_size = high_res_size if high_res_size is not None else {"height": 1024, "width": 1024} @@ -531,6 +534,7 @@ def __init__( image_mean=image_mean, image_std=image_std, do_convert_rgb=do_convert_rgb, + do_pad=do_pad, **kwargs, ) @@ -559,6 +563,8 @@ def preprocess( data_format: Union[str, ChannelDimension] = ChannelDimension.FIRST, input_data_format: Optional[Union[str, ChannelDimension]] = None, do_convert_rgb: Optional[bool] = None, + do_pad: Optional[bool] = None, + background_color: Optional[tuple[int, int, int]] = None, ): """ Preprocess an image or batch of images. @@ -615,6 +621,10 @@ def preprocess( - `"none"` or `ChannelDimension.NONE`: image in (height, width) format. do_convert_rgb (`bool`, *optional*, defaults to `self.do_convert_rgb`): Whether to convert the image to RGB. + do_pad (`bool`, *optional*, defaults to `self.do_pad`): + Whether to pad the image to square or not. + background_color (`tuple[int, int, int]`): + The background color to use for the padding. """ do_resize = do_resize if do_resize is not None else self.do_resize do_rescale = do_rescale if do_rescale is not None else self.do_rescale @@ -627,6 +637,8 @@ def preprocess( high_res_image_mean = high_res_image_mean if high_res_image_mean is not None else self.high_res_image_mean high_res_image_std = high_res_image_std if high_res_image_std is not None else self.high_res_image_std do_convert_rgb = do_convert_rgb if do_convert_rgb is not None else self.do_convert_rgb + do_pad = do_pad if do_pad is not None else self.do_pad + background_color = background_color if background_color is not None else self.background_color size = size if size is not None else self.size size_dict = get_size_dict(size) @@ -678,17 +690,28 @@ def preprocess( high_res_image = self.resize( image=high_res_image, size=high_res_size_dict, - background_color=self.high_res_background_color, resample=high_res_resample, input_data_format=input_data_format, ) + if do_pad: + # Expand and pad the images to obtain a square image of dimensions `size x size` + high_res_image = self.pad_to_square( + image=high_res_image, + background_color=background_color, + input_data_format=input_data_format, + ) image = self.resize( image=high_res_image, size=size_dict, - background_color=self.background_color, resample=resample, input_data_format=input_data_format, ) + if do_pad: + image = self.pad_to_square( + image=image, + background_color=background_color, + input_data_format=input_data_format, + ) if do_rescale: image = self.rescale(image=image, scale=rescale_factor, input_data_format=input_data_format) diff --git a/src/transformers/models/deformable_detr/image_processing_deformable_detr_fast.py b/src/transformers/models/deformable_detr/image_processing_deformable_detr_fast.py index b6cd0a7075f3..2bfbedddc5d0 100644 --- a/src/transformers/models/deformable_detr/image_processing_deformable_detr_fast.py +++ b/src/transformers/models/deformable_detr/image_processing_deformable_detr_fast.py @@ -65,23 +65,12 @@ class DeformableDetrFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Controls whether to convert the annotations to the format expected by the DEFORMABLE_DETR model. Converts the bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`. Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method. - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with zeros. - If `pad_size` is provided, the image will be padded to the specified dimensions. - Otherwise, the image will be padded to the maximum height and width of the batch. - pad_size (`dict[str, int]`, *optional*): - The size `{"height": int, "width" int}` to pad the images to. Must be larger than any image size - provided for preprocessing. If `pad_size` is not provided, images will be padded to the largest - height and width in the batch. return_segmentation_masks (`bool`, *optional*, defaults to `False`): Whether to return segmentation masks. """ format: Optional[Union[str, AnnotationFormat]] do_convert_annotations: Optional[bool] - do_pad: Optional[bool] - pad_size: Optional[dict[str, int]] return_segmentation_masks: Optional[bool] @@ -620,7 +609,7 @@ def _preprocess( image_mean: Optional[Union[float, list[float]]], image_std: Optional[Union[float, list[float]]], do_pad: bool, - pad_size: Optional[dict[str, int]], + pad_size: Optional[SizeDict], format: Optional[Union[str, AnnotationFormat]], return_tensors: Optional[Union[str, TensorType]], **kwargs, @@ -689,7 +678,7 @@ def _preprocess( if do_pad: # depends on all resized image shapes so we need another loop if pad_size is not None: - padded_size = (pad_size["height"], pad_size["width"]) + padded_size = (pad_size.height, pad_size.width) else: padded_size = get_max_height_width(images) diff --git a/src/transformers/models/depth_pro/image_processing_depth_pro_fast.py b/src/transformers/models/depth_pro/image_processing_depth_pro_fast.py index 581577b5b25f..d27220c3d2be 100644 --- a/src/transformers/models/depth_pro/image_processing_depth_pro_fast.py +++ b/src/transformers/models/depth_pro/image_processing_depth_pro_fast.py @@ -78,6 +78,7 @@ def _preprocess( image_std: Optional[Union[float, list[float]]], disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], + **kwargs, ) -> BatchFeature: # Group images by size for batched scaling grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) diff --git a/src/transformers/models/detr/image_processing_detr_fast.py b/src/transformers/models/detr/image_processing_detr_fast.py index 9877729434e1..ba216a6f2d49 100644 --- a/src/transformers/models/detr/image_processing_detr_fast.py +++ b/src/transformers/models/detr/image_processing_detr_fast.py @@ -286,23 +286,12 @@ class DetrFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Controls whether to convert the annotations to the format expected by the DETR model. Converts the bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`. Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method. - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with zeros. - If `pad_size` is provided, the image will be padded to the specified dimensions. - Otherwise, the image will be padded to the maximum height and width of the batch. - pad_size (`dict[str, int]`, *optional*): - The size `{"height": int, "width" int}` to pad the images to. Must be larger than any image size - provided for preprocessing. If `pad_size` is not provided, images will be padded to the largest - height and width in the batch. return_segmentation_masks (`bool`, *optional*, defaults to `False`): Whether to return segmentation masks. """ format: Optional[Union[str, AnnotationFormat]] do_convert_annotations: Optional[bool] - do_pad: Optional[bool] - pad_size: Optional[dict[str, int]] return_segmentation_masks: Optional[bool] @@ -641,7 +630,7 @@ def _preprocess( image_mean: Optional[Union[float, list[float]]], image_std: Optional[Union[float, list[float]]], do_pad: bool, - pad_size: Optional[dict[str, int]], + pad_size: Optional[SizeDict], format: Optional[Union[str, AnnotationFormat]], return_tensors: Optional[Union[str, TensorType]], **kwargs, @@ -710,7 +699,7 @@ def _preprocess( if do_pad: # depends on all resized image shapes so we need another loop if pad_size is not None: - padded_size = (pad_size["height"], pad_size["width"]) + padded_size = (pad_size.height, pad_size.width) else: padded_size = get_max_height_width(images) diff --git a/src/transformers/models/dinov3_vit/image_processing_dinov3_vit_fast.py b/src/transformers/models/dinov3_vit/image_processing_dinov3_vit_fast.py index bfb9d1074f14..fba0d3089438 100644 --- a/src/transformers/models/dinov3_vit/image_processing_dinov3_vit_fast.py +++ b/src/transformers/models/dinov3_vit/image_processing_dinov3_vit_fast.py @@ -70,6 +70,7 @@ def _preprocess( image_std: Optional[Union[float, list[float]]], disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], + **kwargs, ) -> BatchFeature: # Group images by size for batched resizing grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) diff --git a/src/transformers/models/donut/image_processing_donut.py b/src/transformers/models/donut/image_processing_donut.py index 570981decf61..7dec96422c5d 100644 --- a/src/transformers/models/donut/image_processing_donut.py +++ b/src/transformers/models/donut/image_processing_donut.py @@ -215,10 +215,6 @@ def pad_image( padding = ((pad_top, pad_bottom), (pad_left, pad_right)) return pad(image, padding, data_format=data_format, input_data_format=input_data_format) - def pad(self, *args, **kwargs): - logger.info("pad is deprecated and will be removed in version 4.27. Please use pad_image instead.") - return self.pad_image(*args, **kwargs) - def thumbnail( self, image: np.ndarray, @@ -412,8 +408,6 @@ def preprocess( do_normalize=do_normalize, image_mean=image_mean, image_std=image_std, - do_pad=do_pad, - size_divisibility=size, # There is no pad divisibility in this processor, but pad requires the size arg. do_resize=do_resize, size=size, resample=resample, diff --git a/src/transformers/models/donut/image_processing_donut_fast.py b/src/transformers/models/donut/image_processing_donut_fast.py index 8ec023554417..23714affe1e8 100644 --- a/src/transformers/models/donut/image_processing_donut_fast.py +++ b/src/transformers/models/donut/image_processing_donut_fast.py @@ -49,15 +49,10 @@ class DonutFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Whether to resize the image using thumbnail method. do_align_long_axis (`bool`, *optional*, defaults to `self.do_align_long_axis`): Whether to align the long axis of the image with the long axis of `size` by rotating by 90 degrees. - do_pad (`bool`, *optional*, defaults to `self.do_pad`): - Whether to pad the image. If `random_padding` is set to `True`, each image is padded with a random - amount of padding on each size, up to the largest image size in the batch. Otherwise, all images are - padded to the largest image size in the batch. """ do_thumbnail: Optional[bool] do_align_long_axis: Optional[bool] - do_pad: Optional[bool] @auto_docstring diff --git a/src/transformers/models/dpt/image_processing_dpt.py b/src/transformers/models/dpt/image_processing_dpt.py index bad8ef3b3c40..9b28950d2ded 100644 --- a/src/transformers/models/dpt/image_processing_dpt.py +++ b/src/transformers/models/dpt/image_processing_dpt.py @@ -541,8 +541,6 @@ def preprocess( do_normalize=do_normalize, image_mean=image_mean, image_std=image_std, - do_pad=do_pad, - size_divisibility=size_divisor, do_resize=do_resize, size=size, resample=resample, diff --git a/src/transformers/models/dpt/image_processing_dpt_fast.py b/src/transformers/models/dpt/image_processing_dpt_fast.py index 1387127b4cf0..7fce8a9f64db 100644 --- a/src/transformers/models/dpt/image_processing_dpt_fast.py +++ b/src/transformers/models/dpt/image_processing_dpt_fast.py @@ -64,9 +64,6 @@ class DPTFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): ensure_multiple_of (`int`, *optional*, defaults to 1): If `do_resize` is `True`, the image is resized to a size that is a multiple of this value. Can be overridden by `ensure_multiple_of` in `preprocess`. - do_pad (`bool`, *optional*, defaults to `False`): - Whether to apply center padding. This was introduced in the DINOv2 paper, which uses the model in - combination with DPT. size_divisor (`int`, *optional*): If `do_pad` is `True`, pads the image dimensions to be divisible by this value. This was introduced in the DINOv2 paper, which uses the model in combination with DPT. @@ -81,7 +78,6 @@ class DPTFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): ensure_multiple_of: Optional[int] size_divisor: Optional[int] - do_pad: Optional[bool] keep_aspect_ratio: Optional[bool] do_reduce_labels: Optional[bool] diff --git a/src/transformers/models/dpt/modular_dpt.py b/src/transformers/models/dpt/modular_dpt.py index f86b5601dada..7ae6bb40c3af 100644 --- a/src/transformers/models/dpt/modular_dpt.py +++ b/src/transformers/models/dpt/modular_dpt.py @@ -94,9 +94,6 @@ class DPTFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): ensure_multiple_of (`int`, *optional*, defaults to 1): If `do_resize` is `True`, the image is resized to a size that is a multiple of this value. Can be overridden by `ensure_multiple_of` in `preprocess`. - do_pad (`bool`, *optional*, defaults to `False`): - Whether to apply center padding. This was introduced in the DINOv2 paper, which uses the model in - combination with DPT. size_divisor (`int`, *optional*): If `do_pad` is `True`, pads the image dimensions to be divisible by this value. This was introduced in the DINOv2 paper, which uses the model in combination with DPT. @@ -111,7 +108,6 @@ class DPTFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): ensure_multiple_of: Optional[int] size_divisor: Optional[int] - do_pad: Optional[bool] keep_aspect_ratio: Optional[bool] do_reduce_labels: Optional[bool] diff --git a/src/transformers/models/fuyu/image_processing_fuyu.py b/src/transformers/models/fuyu/image_processing_fuyu.py index 29af98ed5072..e52d9dc8ee91 100644 --- a/src/transformers/models/fuyu/image_processing_fuyu.py +++ b/src/transformers/models/fuyu/image_processing_fuyu.py @@ -455,8 +455,6 @@ def preprocess( do_normalize=do_normalize, image_mean=image_mean, image_std=image_std, - do_pad=do_pad, - size_divisibility=size, # There is no pad divisibility in this processor, but pad requires the size arg. do_resize=do_resize, size=size, resample=resample, diff --git a/src/transformers/models/gemma3/image_processing_gemma3_fast.py b/src/transformers/models/gemma3/image_processing_gemma3_fast.py index 6ce7b508b270..3826f40bd997 100644 --- a/src/transformers/models/gemma3/image_processing_gemma3_fast.py +++ b/src/transformers/models/gemma3/image_processing_gemma3_fast.py @@ -194,8 +194,6 @@ def _preprocess( pan_and_scan_max_num_crops: Optional[int], pan_and_scan_min_ratio_to_activate: Optional[float], interpolation: Optional["F.InterpolationMode"], - do_center_crop: bool, - crop_size: SizeDict, do_rescale: bool, rescale_factor: float, do_normalize: bool, @@ -203,6 +201,7 @@ def _preprocess( image_std: Optional[Union[float, list[float]]], disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], + **kwargs, ) -> BatchFeature: # Group images by size for batched processing processed_images_grouped = {} diff --git a/src/transformers/models/got_ocr2/image_processing_got_ocr2_fast.py b/src/transformers/models/got_ocr2/image_processing_got_ocr2_fast.py index 6652e018263c..38b87aed623f 100644 --- a/src/transformers/models/got_ocr2/image_processing_got_ocr2_fast.py +++ b/src/transformers/models/got_ocr2/image_processing_got_ocr2_fast.py @@ -173,6 +173,7 @@ def _preprocess( image_std: Optional[Union[float, list[float]]], disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], + **kwargs, ) -> BatchFeature: if crop_to_patches: grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) diff --git a/src/transformers/models/grounding_dino/image_processing_grounding_dino_fast.py b/src/transformers/models/grounding_dino/image_processing_grounding_dino_fast.py index 9869e8eb4801..59866c9a410e 100644 --- a/src/transformers/models/grounding_dino/image_processing_grounding_dino_fast.py +++ b/src/transformers/models/grounding_dino/image_processing_grounding_dino_fast.py @@ -68,23 +68,12 @@ class GroundingDinoFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Controls whether to convert the annotations to the format expected by the GROUNDING_DINO model. Converts the bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`. Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method. - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with zeros. - If `pad_size` is provided, the image will be padded to the specified dimensions. - Otherwise, the image will be padded to the maximum height and width of the batch. - pad_size (`dict[str, int]`, *optional*): - The size `{"height": int, "width" int}` to pad the images to. Must be larger than any image size - provided for preprocessing. If `pad_size` is not provided, images will be padded to the largest - height and width in the batch. return_segmentation_masks (`bool`, *optional*, defaults to `False`): Whether to return segmentation masks. """ format: Optional[Union[str, AnnotationFormat]] do_convert_annotations: Optional[bool] - do_pad: Optional[bool] - pad_size: Optional[dict[str, int]] return_segmentation_masks: Optional[bool] @@ -651,7 +640,7 @@ def _preprocess( image_mean: Optional[Union[float, list[float]]], image_std: Optional[Union[float, list[float]]], do_pad: bool, - pad_size: Optional[dict[str, int]], + pad_size: Optional[SizeDict], format: Optional[Union[str, AnnotationFormat]], return_tensors: Optional[Union[str, TensorType]], **kwargs, @@ -720,7 +709,7 @@ def _preprocess( if do_pad: # depends on all resized image shapes so we need another loop if pad_size is not None: - padded_size = (pad_size["height"], pad_size["width"]) + padded_size = (pad_size.height, pad_size.width) else: padded_size = get_max_height_width(images) diff --git a/src/transformers/models/idefics2/image_processing_idefics2_fast.py b/src/transformers/models/idefics2/image_processing_idefics2_fast.py index a22b95cfea97..5348bda389ed 100644 --- a/src/transformers/models/idefics2/image_processing_idefics2_fast.py +++ b/src/transformers/models/idefics2/image_processing_idefics2_fast.py @@ -109,12 +109,9 @@ class Idefics2FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): """ do_image_splitting (`bool`, *optional*, defaults to `False`): Whether to split the image into a sequence 4 equal sub-images concatenated with the original image. - do_pad (`bool`, *optional*, defaults to `True`): - Whether to pad images to the largest height and width in the batch. """ do_image_splitting: Optional[bool] - do_pad: Optional[bool] @auto_docstring diff --git a/src/transformers/models/idefics3/image_processing_idefics3_fast.py b/src/transformers/models/idefics3/image_processing_idefics3_fast.py index a6047ba77a87..5b0c0e6180f9 100644 --- a/src/transformers/models/idefics3/image_processing_idefics3_fast.py +++ b/src/transformers/models/idefics3/image_processing_idefics3_fast.py @@ -171,9 +171,6 @@ def make_pixel_mask(image: "torch.Tensor", output_size: tuple[int, int]) -> "tor class Idefics3FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): """ - do_pad (`bool`, *optional*): - Whether to pad the image. If `True`, will pad the patch dimension of the images in the batch to the largest - number of patches in the batch. Padding will be applied to the bottom and right with zeros. do_image_splitting (`bool`, *optional*, defaults to `True`): Whether to split the image into sub-images concatenated with the original image. They are split into patches such that each patch has a size of `max_image_size["height"]` x `max_image_size["width"]`. @@ -183,7 +180,6 @@ class Idefics3FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Whether to return the row and column information of the images. """ - do_pad: Optional[bool] do_image_splitting: Optional[bool] max_image_size: Optional[dict[str, int]] return_row_col_info: Optional[bool] diff --git a/src/transformers/models/instructblipvideo/video_processing_instructblipvideo.py b/src/transformers/models/instructblipvideo/video_processing_instructblipvideo.py index f4f482c56313..a2cd3cf351d2 100644 --- a/src/transformers/models/instructblipvideo/video_processing_instructblipvideo.py +++ b/src/transformers/models/instructblipvideo/video_processing_instructblipvideo.py @@ -61,12 +61,10 @@ def _preprocess( do_convert_rgb: bool, do_resize: bool, size: SizeDict, - size_divisor: Optional[int], interpolation: Optional["F.InterpolationMode"], do_center_crop: bool, crop_size: SizeDict, do_rescale: bool, - do_pad: bool, rescale_factor: float, do_normalize: bool, image_mean: Optional[Union[float, list[float]]], @@ -81,9 +79,7 @@ def _preprocess( if do_convert_rgb: stacked_videos = self.convert_to_rgb(stacked_videos) if do_resize: - stacked_videos = self.resize( - stacked_videos, size=size, size_divisor=size_divisor, interpolation=interpolation - ) + stacked_videos = self.resize(stacked_videos, size=size, interpolation=interpolation) resized_videos_grouped[shape] = stacked_videos resized_videos = reorder_videos(resized_videos_grouped, grouped_videos_index) diff --git a/src/transformers/models/internvl/video_processing_internvl.py b/src/transformers/models/internvl/video_processing_internvl.py index 3c0ee8de1bef..a2e06d3b7ec4 100644 --- a/src/transformers/models/internvl/video_processing_internvl.py +++ b/src/transformers/models/internvl/video_processing_internvl.py @@ -110,12 +110,10 @@ def _preprocess( do_convert_rgb: bool, do_resize: bool, size: SizeDict, - size_divisor: Optional[int], interpolation: Optional["F.InterpolationMode"], do_center_crop: bool, crop_size: SizeDict, do_rescale: bool, - do_pad: bool, rescale_factor: float, do_normalize: bool, image_mean: Optional[Union[float, list[float]]], @@ -130,9 +128,7 @@ def _preprocess( if do_convert_rgb: stacked_videos = self.convert_to_rgb(stacked_videos) if do_resize: - stacked_videos = self.resize( - stacked_videos, size=size, size_divisor=size_divisor, interpolation=interpolation - ) + stacked_videos = self.resize(stacked_videos, size=size, interpolation=interpolation) resized_videos_grouped[shape] = stacked_videos resized_videos = reorder_videos(resized_videos_grouped, grouped_videos_index) diff --git a/src/transformers/models/janus/image_processing_janus.py b/src/transformers/models/janus/image_processing_janus.py index 3669e707928b..16659bd85354 100644 --- a/src/transformers/models/janus/image_processing_janus.py +++ b/src/transformers/models/janus/image_processing_janus.py @@ -86,6 +86,8 @@ class JanusImageProcessor(BaseImageProcessor): Can be overridden by the `image_std` parameter in the `preprocess` method. do_convert_rgb (`bool`, *optional*, defaults to `True`): Whether to convert the image to RGB. + do_pad (`bool`, *optional*, defaults to `True`): + Whether to pad the image to square or not. """ model_input_names = ["pixel_values"] @@ -102,6 +104,7 @@ def __init__( image_mean: Optional[Union[float, list[float]]] = None, image_std: Optional[Union[float, list[float]]] = None, do_convert_rgb: Optional[bool] = None, + do_pad: Optional[bool] = True, **kwargs, ) -> None: super().__init__(**kwargs) @@ -118,6 +121,7 @@ def __init__( self.image_std = image_std if image_std is not None else OPENAI_CLIP_STD self.do_convert_rgb = do_convert_rgb + self.do_pad = do_pad self.min_size = min_size if image_mean is None: self.background_color = (127, 127, 127) @@ -128,7 +132,6 @@ def resize( self, image: np.ndarray, size: Union[dict[str, int], int], - background_color: Optional[tuple[int, int, int]] = None, resample: PILImageResampling = PILImageResampling.BICUBIC, data_format: Optional[Union[str, ChannelDimension]] = None, input_data_format: Optional[Union[str, ChannelDimension]] = None, @@ -142,8 +145,6 @@ def resize( Image to resize. size (`dict[str, int]` or `int`): The size to resize the image to. If a dictionary, it should have the keys `"height"` and `"width"`. - background_color (`tuple[int, int, int]`): - The background color to use for the padding. resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BICUBIC`): `PILImageResampling` filter to use when resizing the image e.g. `PILImageResampling.BICUBIC`. data_format (`ChannelDimension` or `str`, *optional*): @@ -162,7 +163,6 @@ def resize( Returns: `np.ndarray`: The resized image. """ - background_color = background_color if background_color is not None else self.background_color if input_data_format is None: input_data_format = infer_channel_dimension_format(image) @@ -191,12 +191,6 @@ def resize( input_data_format=input_data_format, **kwargs, ) - # Expand and pad the images to obtain a square image of dimensions `size x size` - image = self.pad_to_square( - image=image, - background_color=background_color, - input_data_format=input_data_format, - ) return image @filter_out_non_signature_kwargs() @@ -213,6 +207,8 @@ def preprocess( image_std: Optional[Union[float, list[float]]] = None, return_tensors: Optional[Union[str, TensorType]] = None, do_convert_rgb: Optional[bool] = None, + background_color: Optional[Union[int, tuple[int, int, int]]] = None, + do_pad: Optional[bool] = None, data_format: ChannelDimension = ChannelDimension.FIRST, input_data_format: Optional[Union[str, ChannelDimension]] = None, ) -> PIL.Image.Image: @@ -244,6 +240,10 @@ def preprocess( Image standard deviation to normalize the image by if `do_normalize` is set to `True`. do_convert_rgb (`bool`, *optional*, defaults to `self.do_convert_rgb`): Whether to convert the image to RGB. + background_color (`tuple[int, int, int]`): + The background color to use for the padding. + do_pad (`bool`, *optional*, defaults to `self.do_pad`): + Whether to pad the image to square or not. return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. @@ -271,6 +271,8 @@ def preprocess( image_mean = image_mean if image_mean is not None else self.image_mean image_std = image_std if image_std is not None else self.image_std do_convert_rgb = do_convert_rgb if do_convert_rgb is not None else self.do_convert_rgb + do_pad = do_pad if do_pad is not None else self.do_pad + background_color = background_color if background_color is not None else self.background_color size = size if size is not None else self.size size = get_size_dict(size, default_to_square=False) @@ -316,6 +318,17 @@ def preprocess( for image in images ] + if do_pad: + # Expand and pad the images to obtain a square image of dimensions `size x size` + images = [ + self.pad_to_square( + image=image, + background_color=background_color, + input_data_format=input_data_format, + ) + for image in images + ] + if do_rescale: images = [ self.rescale(image=image, scale=rescale_factor, input_data_format=input_data_format) diff --git a/src/transformers/models/janus/image_processing_janus_fast.py b/src/transformers/models/janus/image_processing_janus_fast.py index eedf18e2c19f..3e9483f21bfe 100644 --- a/src/transformers/models/janus/image_processing_janus_fast.py +++ b/src/transformers/models/janus/image_processing_janus_fast.py @@ -68,6 +68,7 @@ class JanusImageProcessorFast(BaseImageProcessorFast): do_resize = True do_rescale = True do_normalize = True + do_pad = True valid_kwargs = JanusFastImageProcessorKwargs def __init__(self, **kwargs: Unpack[JanusFastImageProcessorKwargs]): diff --git a/src/transformers/models/janus/modular_janus.py b/src/transformers/models/janus/modular_janus.py index 7f75147a5b1e..0541854200a5 100644 --- a/src/transformers/models/janus/modular_janus.py +++ b/src/transformers/models/janus/modular_janus.py @@ -29,23 +29,28 @@ from ...generation import ClassifierFreeGuidanceLogitsProcessor, GenerationMixin, GenerationMode, LogitsProcessorList from ...generation.utils import GenerateDecoderOnlyOutput from ...image_processing_utils import BatchFeature, get_size_dict -from ...image_transforms import resize, to_channel_dimension_format +from ...image_transforms import convert_to_rgb, resize, to_channel_dimension_format from ...image_utils import ( ChannelDimension, ImageInput, PILImageResampling, get_image_size, infer_channel_dimension_format, + is_scaled_image, make_flat_list_of_images, to_numpy_array, + valid_images, + validate_preprocess_arguments, ) from ...modeling_outputs import ModelOutput from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import Unpack from ...utils import ( + TensorType, TransformersKwargs, auto_docstring, can_return_tuple, + filter_out_non_signature_kwargs, is_torch_available, is_vision_available, logging, @@ -1328,6 +1333,8 @@ class JanusImageProcessor(BlipImageProcessor): Can be overridden by the `image_std` parameter in the `preprocess` method. do_convert_rgb (`bool`, *optional*, defaults to `True`): Whether to convert the image to RGB. + do_pad (`bool`, *optional*, defaults to `True`): + Whether to pad the image to square or not. """ def __init__( @@ -1342,10 +1349,12 @@ def __init__( image_mean: Optional[Union[float, list[float]]] = None, image_std: Optional[Union[float, list[float]]] = None, do_convert_rgb: Optional[bool] = None, + do_pad: Optional[bool] = True, **kwargs, ): super().__init__(**kwargs) + self.do_pad = do_pad self.min_size = min_size if image_mean is None: self.background_color = (127, 127, 127) @@ -1430,7 +1439,6 @@ def resize( self, image: np.ndarray, size: Union[dict[str, int], int], - background_color: Optional[tuple[int, int, int]] = None, resample: PILImageResampling = PILImageResampling.BICUBIC, data_format: Optional[Union[str, ChannelDimension]] = None, input_data_format: Optional[Union[str, ChannelDimension]] = None, @@ -1444,8 +1452,6 @@ def resize( Image to resize. size (`dict[str, int]` or `int`): The size to resize the image to. If a dictionary, it should have the keys `"height"` and `"width"`. - background_color (`tuple[int, int, int]`): - The background color to use for the padding. resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BICUBIC`): `PILImageResampling` filter to use when resizing the image e.g. `PILImageResampling.BICUBIC`. data_format (`ChannelDimension` or `str`, *optional*): @@ -1464,7 +1470,6 @@ def resize( Returns: `np.ndarray`: The resized image. """ - background_color = background_color if background_color is not None else self.background_color if input_data_format is None: input_data_format = infer_channel_dimension_format(image) @@ -1493,14 +1498,164 @@ def resize( input_data_format=input_data_format, **kwargs, ) - # Expand and pad the images to obtain a square image of dimensions `size x size` - image = self.pad_to_square( - image=image, - background_color=background_color, - input_data_format=input_data_format, - ) return image + @filter_out_non_signature_kwargs() + def preprocess( + self, + images: ImageInput, + do_resize: Optional[bool] = None, + size: Optional[dict[str, int]] = None, + resample: Optional[PILImageResampling] = None, + do_rescale: Optional[bool] = None, + rescale_factor: Optional[float] = None, + do_normalize: Optional[bool] = None, + image_mean: Optional[Union[float, list[float]]] = None, + image_std: Optional[Union[float, list[float]]] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + do_convert_rgb: Optional[bool] = None, + background_color: Optional[Union[int, tuple[int, int, int]]] = None, + do_pad: Optional[bool] = None, + data_format: ChannelDimension = ChannelDimension.FIRST, + input_data_format: Optional[Union[str, ChannelDimension]] = None, + ) -> PIL.Image.Image: + """ + Preprocess an image or batch of images. + + Args: + images (`ImageInput`): + Image to preprocess. Expects a single or batch of images with pixel values ranging from 0 to 255. If + passing in images with pixel values between 0 and 1, set `do_rescale=False`. + do_resize (`bool`, *optional*, defaults to `self.do_resize`): + Whether to resize the image. + size (`dict[str, int]`, *optional*, defaults to `self.size`): + Controls the size of the image after `resize`. The shortest edge of the image is resized to + `size["shortest_edge"]` whilst preserving the aspect ratio. If the longest edge of this resized image + is > `int(size["shortest_edge"] * (1333 / 800))`, then the image is resized again to make the longest + edge equal to `int(size["shortest_edge"] * (1333 / 800))`. + resample (`PILImageResampling`, *optional*, defaults to `self.resample`): + Resampling filter to use if resizing the image. Only has an effect if `do_resize` is set to `True`. + do_rescale (`bool`, *optional*, defaults to `self.do_rescale`): + Whether to rescale the image values between [0 - 1]. + rescale_factor (`float`, *optional*, defaults to `self.rescale_factor`): + Rescale factor to rescale the image by if `do_rescale` is set to `True`. + do_normalize (`bool`, *optional*, defaults to `self.do_normalize`): + Whether to normalize the image. + image_mean (`float` or `list[float]`, *optional*, defaults to `self.image_mean`): + Image mean to normalize the image by if `do_normalize` is set to `True`. + image_std (`float` or `list[float]`, *optional*, defaults to `self.image_std`): + Image standard deviation to normalize the image by if `do_normalize` is set to `True`. + do_convert_rgb (`bool`, *optional*, defaults to `self.do_convert_rgb`): + Whether to convert the image to RGB. + background_color (`tuple[int, int, int]`): + The background color to use for the padding. + do_pad (`bool`, *optional*, defaults to `self.do_pad`): + Whether to pad the image to square or not. + return_tensors (`str` or `TensorType`, *optional*): + The type of tensors to return. Can be one of: + - Unset: Return a list of `np.ndarray`. + - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. + - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. + - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. + - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. + data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): + The channel dimension format for the output image. Can be one of: + - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format. + - Unset: Use the channel dimension format of the input image. + input_data_format (`ChannelDimension` or `str`, *optional*): + The channel dimension format for the input image. If unset, the channel dimension format is inferred + from the input image. Can be one of: + - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format. + - `"none"` or `ChannelDimension.NONE`: image in (height, width) format. + """ + do_resize = do_resize if do_resize is not None else self.do_resize + resample = resample if resample is not None else self.resample + do_rescale = do_rescale if do_rescale is not None else self.do_rescale + rescale_factor = rescale_factor if rescale_factor is not None else self.rescale_factor + do_normalize = do_normalize if do_normalize is not None else self.do_normalize + image_mean = image_mean if image_mean is not None else self.image_mean + image_std = image_std if image_std is not None else self.image_std + do_convert_rgb = do_convert_rgb if do_convert_rgb is not None else self.do_convert_rgb + do_pad = do_pad if do_pad is not None else self.do_pad + background_color = background_color if background_color is not None else self.background_color + + size = size if size is not None else self.size + size = get_size_dict(size, default_to_square=False) + images = self.fetch_images(images) + images = make_flat_list_of_images(images) + + if not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + validate_preprocess_arguments( + do_rescale=do_rescale, + rescale_factor=rescale_factor, + do_normalize=do_normalize, + image_mean=image_mean, + image_std=image_std, + do_resize=do_resize, + size=size, + resample=resample, + ) + # PIL RGBA images are converted to RGB + if do_convert_rgb: + images = [convert_to_rgb(image) for image in images] + + # All transformations expect numpy arrays. + images = [to_numpy_array(image) for image in images] + + if do_rescale and is_scaled_image(images[0]): + logger.warning_once( + "It looks like you are trying to rescale already rescaled images. If the input" + " images have pixel values between 0 and 1, set `do_rescale=False` to avoid rescaling them again." + ) + + if input_data_format is None: + # We assume that all images have the same channel dimension format. + input_data_format = infer_channel_dimension_format(images[0]) + + if do_resize: + images = [ + self.resize(image=image, size=size, resample=resample, input_data_format=input_data_format) + for image in images + ] + + if do_pad: + # Expand and pad the images to obtain a square image of dimensions `size x size` + images = [ + self.pad_to_square( + image=image, + background_color=background_color, + input_data_format=input_data_format, + ) + for image in images + ] + + if do_rescale: + images = [ + self.rescale(image=image, scale=rescale_factor, input_data_format=input_data_format) + for image in images + ] + + if do_normalize: + images = [ + self.normalize(image=image, mean=image_mean, std=image_std, input_data_format=input_data_format) + for image in images + ] + + images = [ + to_channel_dimension_format(image, data_format, input_channel_dim=input_data_format) for image in images + ] + + encoded_outputs = BatchFeature(data={"pixel_values": images}, tensor_type=return_tensors) + + return encoded_outputs + def postprocess( self, images: ImageInput, diff --git a/src/transformers/models/llava/image_processing_llava_fast.py b/src/transformers/models/llava/image_processing_llava_fast.py index 02324f6393cd..cf62f250bc2f 100644 --- a/src/transformers/models/llava/image_processing_llava_fast.py +++ b/src/transformers/models/llava/image_processing_llava_fast.py @@ -56,14 +56,7 @@ from torchvision.transforms import functional as F -class LlavaFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): - """ - Args: - do_pad (`bool`, *optional*): - Whether to pad the image to a square based on the longest edge. - """ - - do_pad: Optional[bool] +class LlavaFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): ... @auto_docstring @@ -147,6 +140,7 @@ def _preprocess( image_std: Optional[Union[float, list[float]]], disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], + **kwargs, ) -> BatchFeature: # Group images by size for batched resizing grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) diff --git a/src/transformers/models/llava_next/image_processing_llava_next_fast.py b/src/transformers/models/llava_next/image_processing_llava_next_fast.py index 3dda73507006..201a65260589 100644 --- a/src/transformers/models/llava_next/image_processing_llava_next_fast.py +++ b/src/transformers/models/llava_next/image_processing_llava_next_fast.py @@ -59,13 +59,9 @@ class LlavaNextFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): A list of possible resolutions to use for processing high resolution images. The best resolution is selected based on the original size of the image. Can be overridden by `image_grid_pinpoints` in the `preprocess` method. - do_pad (`bool`, *optional*): - Whether to pad the image. If `True`, will pad the patch dimension of the images in the batch to the largest - number of patches in the batch. Padding will be applied to the bottom and right with zeros. """ image_grid_pinpoints: Optional[list[list[int]]] - do_pad: Optional[bool] @auto_docstring diff --git a/src/transformers/models/llava_onevision/image_processing_llava_onevision_fast.py b/src/transformers/models/llava_onevision/image_processing_llava_onevision_fast.py index 46ef482dad36..4392d64e9ebf 100644 --- a/src/transformers/models/llava_onevision/image_processing_llava_onevision_fast.py +++ b/src/transformers/models/llava_onevision/image_processing_llava_onevision_fast.py @@ -56,13 +56,9 @@ class LlavaOnevisionFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): A list of possible resolutions to use for processing high resolution images. The best resolution is selected based on the original size of the image. Can be overridden by `image_grid_pinpoints` in the `preprocess` method. - do_pad (`bool`, *optional*): - Whether to pad the image. If `True`, will pad the patch dimension of the images in the batch to the largest - number of patches in the batch. Padding will be applied to the bottom and right with zeros. """ image_grid_pinpoints: Optional[list[list[int]]] - do_pad: Optional[bool] @auto_docstring diff --git a/src/transformers/models/llava_onevision/modular_llava_onevision.py b/src/transformers/models/llava_onevision/modular_llava_onevision.py index 9d6d3a53f7c8..45dfac3b37ef 100644 --- a/src/transformers/models/llava_onevision/modular_llava_onevision.py +++ b/src/transformers/models/llava_onevision/modular_llava_onevision.py @@ -72,13 +72,9 @@ class LlavaOnevisionFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): A list of possible resolutions to use for processing high resolution images. The best resolution is selected based on the original size of the image. Can be overridden by `image_grid_pinpoints` in the `preprocess` method. - do_pad (`bool`, *optional*): - Whether to pad the image. If `True`, will pad the patch dimension of the images in the batch to the largest - number of patches in the batch. Padding will be applied to the bottom and right with zeros. """ image_grid_pinpoints: Optional[list[list[int]]] - do_pad: Optional[bool] class LlavaOnevisionImageProcessorFast(LlavaNextImageProcessorFast): diff --git a/src/transformers/models/mask2former/image_processing_mask2former_fast.py b/src/transformers/models/mask2former/image_processing_mask2former_fast.py index b94f0d8c308c..c61d531eb077 100644 --- a/src/transformers/models/mask2former/image_processing_mask2former_fast.py +++ b/src/transformers/models/mask2former/image_processing_mask2former_fast.py @@ -84,23 +84,12 @@ class Mask2FormerFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): The background label will be replaced by `ignore_index`. num_labels (`int`, *optional*): The number of labels in the segmentation map. - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with zeros. - If `pad_size` is provided, the image will be padded to the specified dimensions. - Otherwise, the image will be padded to the maximum height and width of the batch. - pad_size (`Dict[str, int]`, *optional*): - The size `{"height": int, "width" int}` to pad the images to. Must be larger than any image size - provided for preprocessing. If `pad_size` is not provided, images will be padded to the largest - height and width in the batch. """ size_divisor: Optional[int] ignore_index: Optional[int] do_reduce_labels: Optional[bool] num_labels: Optional[int] - do_pad: Optional[bool] - pad_size: Optional[dict[str, int]] def convert_segmentation_map_to_binary_masks_fast( @@ -334,8 +323,8 @@ def _preprocess( segmentation_maps: Optional["torch.Tensor"], instance_id_to_semantic_id: Optional[dict[int, int]], do_resize: Optional[bool], - size: Optional[dict[str, int]], - pad_size: Optional[dict[str, int]], + size: Optional[SizeDict], + pad_size: Optional[SizeDict], size_divisor: Optional[int], interpolation: Optional[Union["PILImageResampling", "F.InterpolationMode"]], do_rescale: Optional[bool], @@ -383,7 +372,7 @@ def _preprocess( resized_segmentation_maps_grouped, grouped_segmentation_maps_index ) if pad_size is not None: - padded_size = (pad_size["height"], pad_size["width"]) + padded_size = (pad_size.height, pad_size.width) else: padded_size = get_max_height_width(resized_images) diff --git a/src/transformers/models/maskformer/image_processing_maskformer_fast.py b/src/transformers/models/maskformer/image_processing_maskformer_fast.py index ad5cb946d38d..0b1c95aa1012 100644 --- a/src/transformers/models/maskformer/image_processing_maskformer_fast.py +++ b/src/transformers/models/maskformer/image_processing_maskformer_fast.py @@ -120,23 +120,12 @@ class MaskFormerFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): The background label will be replaced by `ignore_index`. num_labels (`int`, *optional*): The number of labels in the segmentation map. - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with zeros. - If `pad_size` is provided, the image will be padded to the specified dimensions. - Otherwise, the image will be padded to the maximum height and width of the batch. - pad_size (`Dict[str, int]`, *optional*): - The size `{"height": int, "width" int}` to pad the images to. Must be larger than any image size - provided for preprocessing. If `pad_size` is not provided, images will be padded to the largest - height and width in the batch. """ size_divisor: Optional[int] ignore_index: Optional[int] do_reduce_labels: Optional[bool] num_labels: Optional[int] - do_pad: Optional[bool] - pad_size: Optional[dict[str, int]] @auto_docstring @@ -335,8 +324,8 @@ def _preprocess( segmentation_maps: Optional["torch.Tensor"], instance_id_to_semantic_id: Optional[dict[int, int]], do_resize: Optional[bool], - size: Optional[dict[str, int]], - pad_size: Optional[dict[str, int]], + size: Optional[SizeDict], + pad_size: Optional[SizeDict], size_divisor: Optional[int], interpolation: Optional[Union["PILImageResampling", "F.InterpolationMode"]], do_rescale: Optional[bool], @@ -384,7 +373,7 @@ def _preprocess( resized_segmentation_maps_grouped, grouped_segmentation_maps_index ) if pad_size is not None: - padded_size = (pad_size["height"], pad_size["width"]) + padded_size = (pad_size.height, pad_size.width) else: padded_size = get_max_height_width(resized_images) diff --git a/src/transformers/models/nougat/image_processing_nougat.py b/src/transformers/models/nougat/image_processing_nougat.py index 38b4b8fa4a50..0c0a51464b43 100644 --- a/src/transformers/models/nougat/image_processing_nougat.py +++ b/src/transformers/models/nougat/image_processing_nougat.py @@ -461,8 +461,6 @@ def preprocess( do_normalize=do_normalize, image_mean=image_mean, image_std=image_std, - do_pad=do_pad, - size_divisibility=size, # There is no pad divisibility in this processor, but pad requires the size arg. do_resize=do_resize, size=size, resample=resample, diff --git a/src/transformers/models/nougat/image_processing_nougat_fast.py b/src/transformers/models/nougat/image_processing_nougat_fast.py index 136d7f171575..ebe37389f3f6 100644 --- a/src/transformers/models/nougat/image_processing_nougat_fast.py +++ b/src/transformers/models/nougat/image_processing_nougat_fast.py @@ -63,14 +63,11 @@ class NougatFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Whether to resize the image using thumbnail method. do_align_long_axis (`bool`, *optional*, defaults to `False`): Whether to align the long axis of the image with the long axis of `size` by rotating by 90 degrees. - do_pad (`bool`, *optional*, defaults to `True`): - Whether to pad the images to the largest image size in the batch. """ do_crop_margin: Optional[bool] do_thumbnail: Optional[bool] do_align_long_axis: Optional[bool] - do_pad: Optional[bool] @auto_docstring diff --git a/src/transformers/models/oneformer/image_processing_oneformer_fast.py b/src/transformers/models/oneformer/image_processing_oneformer_fast.py index a61745e87e58..10869f50f622 100644 --- a/src/transformers/models/oneformer/image_processing_oneformer_fast.py +++ b/src/transformers/models/oneformer/image_processing_oneformer_fast.py @@ -530,24 +530,9 @@ def pad( Returns: `BatchFeature`: Padded images and optional pixel masks. """ - pad_size = get_max_height_width(images) - - padded_images = [] - pixel_masks = [] - - for image in images: - padded_image = self._pad_image_fast( - image=image, - output_size=pad_size, - constant_values=0, - ) - padded_images.append(padded_image) - - if return_pixel_mask: - input_height, input_width = image.shape[1], image.shape[2] - mask = torch.zeros(pad_size, dtype=torch.int64, device=image.device) - mask[:input_height, :input_width] = 1 - pixel_masks.append(mask) + outputs = super().pad(images, return_mask=return_pixel_mask) + padded_images = outputs[0] if return_pixel_mask else outputs + pixel_masks = outputs[1] if return_pixel_mask else None if return_tensors: padded_images = torch.stack(padded_images, dim=0) diff --git a/src/transformers/models/ovis2/image_processing_ovis2_fast.py b/src/transformers/models/ovis2/image_processing_ovis2_fast.py index e5940421828d..f12a9c70ee57 100644 --- a/src/transformers/models/ovis2/image_processing_ovis2_fast.py +++ b/src/transformers/models/ovis2/image_processing_ovis2_fast.py @@ -202,6 +202,7 @@ def _preprocess( image_std: Optional[Union[float, list[float]]], disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], + **kwargs, ) -> BatchFeature: if crop_to_patches and max_patches > 1: grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) diff --git a/src/transformers/models/owlv2/image_processing_owlv2_fast.py b/src/transformers/models/owlv2/image_processing_owlv2_fast.py index fd46f12f28ee..926da9b27ffc 100644 --- a/src/transformers/models/owlv2/image_processing_owlv2_fast.py +++ b/src/transformers/models/owlv2/image_processing_owlv2_fast.py @@ -60,14 +60,7 @@ from .image_processing_owlv2 import _scale_boxes, box_iou -class Owlv2FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): - r""" - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with grey pixels. - """ - - do_pad: Optional[bool] +class Owlv2FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): ... @auto_docstring @@ -289,7 +282,12 @@ def pad( images: list["torch.Tensor"], disable_grouping: Optional[bool], constant_value: float = 0.5, + **kwargs, ) -> list["torch.Tensor"]: + """ + Unlike the Base class `self.pad` where all images are padded to the maximum image size, + Owlv2 pads an image to square. + """ grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) processed_images_grouped = {} for shape, stacked_images in grouped_images.items(): @@ -389,7 +387,7 @@ def _preprocess( processed_images = reorder_images(processed_images_grouped, grouped_images_index) if do_pad: - processed_images = self.pad(processed_images, disable_grouping=disable_grouping) + processed_images = self.pad(processed_images, constant_value=0.5, disable_grouping=disable_grouping) grouped_images, grouped_images_index = group_images_by_shape( processed_images, disable_grouping=disable_grouping diff --git a/src/transformers/models/owlv2/modular_owlv2.py b/src/transformers/models/owlv2/modular_owlv2.py index 799b9bbaa704..7fe4d75ee9ea 100644 --- a/src/transformers/models/owlv2/modular_owlv2.py +++ b/src/transformers/models/owlv2/modular_owlv2.py @@ -52,14 +52,7 @@ from torchvision.transforms import functional as F -class Owlv2FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): - r""" - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with grey pixels. - """ - - do_pad: Optional[bool] +class Owlv2FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): ... @auto_docstring @@ -102,7 +95,12 @@ def pad( images: list["torch.Tensor"], disable_grouping: Optional[bool], constant_value: float = 0.5, + **kwargs, ) -> list["torch.Tensor"]: + """ + Unlike the Base class `self.pad` where all images are padded to the maximum image size, + Owlv2 pads an image to square. + """ grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) processed_images_grouped = {} for shape, stacked_images in grouped_images.items(): @@ -202,7 +200,7 @@ def _preprocess( processed_images = reorder_images(processed_images_grouped, grouped_images_index) if do_pad: - processed_images = self.pad(processed_images, disable_grouping=disable_grouping) + processed_images = self.pad(processed_images, constant_value=0.5, disable_grouping=disable_grouping) grouped_images, grouped_images_index = group_images_by_shape( processed_images, disable_grouping=disable_grouping diff --git a/src/transformers/models/pixtral/image_processing_pixtral_fast.py b/src/transformers/models/pixtral/image_processing_pixtral_fast.py index 5d42bb097476..585405627023 100644 --- a/src/transformers/models/pixtral/image_processing_pixtral_fast.py +++ b/src/transformers/models/pixtral/image_processing_pixtral_fast.py @@ -162,6 +162,7 @@ def _preprocess( image_std: Optional[Union[float, list[float]]], disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], + **kwargs, ) -> BatchFeature: patch_size = get_size_dict(patch_size, default_to_square=True) patch_size = SizeDict(**patch_size) diff --git a/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py b/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py index a5fad19b1a1b..4f0f68240f9a 100644 --- a/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py +++ b/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py @@ -378,8 +378,6 @@ def preprocess( do_normalize=do_normalize, image_mean=image_mean, image_std=image_std, - do_pad=do_pad, - size_divisibility=size_divisor, do_resize=do_resize, size=size, resample=resample, diff --git a/src/transformers/models/rt_detr/image_processing_rt_detr_fast.py b/src/transformers/models/rt_detr/image_processing_rt_detr_fast.py index 9927a8d02209..eefc45bf9f9a 100644 --- a/src/transformers/models/rt_detr/image_processing_rt_detr_fast.py +++ b/src/transformers/models/rt_detr/image_processing_rt_detr_fast.py @@ -59,23 +59,12 @@ class RTDetrFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Controls whether to convert the annotations to the format expected by the RT_DETR model. Converts the bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`. Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method. - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with zeros. - If `pad_size` is provided, the image will be padded to the specified dimensions. - Otherwise, the image will be padded to the maximum height and width of the batch. - pad_size (`dict[str, int]`, *optional*): - The size `{"height": int, "width" int}` to pad the images to. Must be larger than any image size - provided for preprocessing. If `pad_size` is not provided, images will be padded to the largest - height and width in the batch. return_segmentation_masks (`bool`, *optional*, defaults to `False`): Whether to return segmentation masks. """ format: Optional[Union[str, AnnotationFormat]] do_convert_annotations: Optional[bool] - do_pad: Optional[bool] - pad_size: Optional[dict[str, int]] return_segmentation_masks: Optional[bool] @@ -424,7 +413,7 @@ def _preprocess( image_mean: Optional[Union[float, list[float]]], image_std: Optional[Union[float, list[float]]], do_pad: bool, - pad_size: Optional[dict[str, int]], + pad_size: Optional[SizeDict], format: Optional[Union[str, AnnotationFormat]], return_tensors: Optional[Union[str, TensorType]], **kwargs, @@ -483,7 +472,7 @@ def _preprocess( if do_pad: # depends on all resized image shapes so we need another loop if pad_size is not None: - padded_size = (pad_size["height"], pad_size["width"]) + padded_size = (pad_size.height, pad_size.width) else: padded_size = get_max_height_width(images) diff --git a/src/transformers/models/rt_detr/modular_rt_detr.py b/src/transformers/models/rt_detr/modular_rt_detr.py index e661b7189042..938f070d3672 100644 --- a/src/transformers/models/rt_detr/modular_rt_detr.py +++ b/src/transformers/models/rt_detr/modular_rt_detr.py @@ -175,7 +175,7 @@ def _preprocess( image_mean: Optional[Union[float, list[float]]], image_std: Optional[Union[float, list[float]]], do_pad: bool, - pad_size: Optional[dict[str, int]], + pad_size: Optional[SizeDict], format: Optional[Union[str, AnnotationFormat]], return_tensors: Optional[Union[str, TensorType]], **kwargs, @@ -234,7 +234,7 @@ def _preprocess( if do_pad: # depends on all resized image shapes so we need another loop if pad_size is not None: - padded_size = (pad_size["height"], pad_size["width"]) + padded_size = (pad_size.height, pad_size.width) else: padded_size = get_max_height_width(images) diff --git a/src/transformers/models/sam/image_processing_sam.py b/src/transformers/models/sam/image_processing_sam.py index 33a3661c5e6d..c9b54f561fb6 100644 --- a/src/transformers/models/sam/image_processing_sam.py +++ b/src/transformers/models/sam/image_processing_sam.py @@ -516,8 +516,6 @@ def preprocess( do_normalize=do_normalize, image_mean=image_mean, image_std=image_std, - do_pad=do_pad, - size_divisibility=pad_size, # Here _preprocess needs do_pad and pad_size. do_resize=do_resize, size=size, resample=resample, diff --git a/src/transformers/models/sam/image_processing_sam_fast.py b/src/transformers/models/sam/image_processing_sam_fast.py index 77b4b490e136..1bfb6adf5234 100644 --- a/src/transformers/models/sam/image_processing_sam_fast.py +++ b/src/transformers/models/sam/image_processing_sam_fast.py @@ -26,8 +26,6 @@ from ...image_processing_utils_fast import ( BaseImageProcessorFast, DefaultFastImageProcessorKwargs, - group_images_by_shape, - reorder_images, ) from ...image_utils import ( IMAGENET_DEFAULT_MEAN, @@ -40,7 +38,6 @@ ) from ...processing_utils import Unpack from ...utils import ( - TensorType, auto_docstring, is_torch_available, is_torchvision_available, @@ -62,12 +59,6 @@ class SamFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): r""" - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with zeros. - pad_size (`dict[str, int]`, *optional*): - The size `{"height": int, "width" int}` to pad the images to. Must be larger than any image size - provided for preprocessing. mask_size (`dict[str, int]`, *optional*): The size `{"longest_edge": int}` to resize the segmentation maps to. mask_pad_size (`dict[str, int]`, *optional*): @@ -76,8 +67,6 @@ class SamFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): """ mask_size: Optional[dict[str, int]] - do_pad: Optional[bool] - pad_size: Optional[dict[str, int]] mask_pad_size: Optional[dict[str, int]] @@ -102,15 +91,6 @@ class SamImageProcessorFast(BaseImageProcessorFast): def __init__(self, **kwargs: Unpack[SamFastImageProcessorKwargs]): super().__init__(**kwargs) - def pad_image(self, images: "torch.Tensor", pad_size: SizeDict): - """Pad images to the specified size.""" - output_height, output_width = pad_size.height, pad_size.width - input_height, input_width = images.shape[-2:] - pad_width = output_width - input_width - pad_height = output_height - input_height - padding = (0, 0, pad_width, pad_height) - return F_t.pad(images, padding) - def _get_preprocess_shape(self, old_shape: tuple[int, int], longest_edge: int): """ Compute the output size given input size and target long side length. @@ -231,7 +211,7 @@ def _preprocess_image_like_inputs( ) original_sizes = [image.shape[-2:] for image in images] images_kwargs = kwargs.copy() - pixel_values = self._preprocess(images, **images_kwargs) + pixel_values = self._preprocess(images, **images_kwargs)["pixel_values"] reshaped_input_sizes = [image.shape[-2:] for image in images] data = { "pixel_values": pixel_values, @@ -262,54 +242,10 @@ def _preprocess_image_like_inputs( processed_segmentation_maps = self._preprocess( images=processed_segmentation_maps, **segmentation_maps_kwargs ) - data["labels"] = processed_segmentation_maps.squeeze(1).to(torch.int64) + data["labels"] = processed_segmentation_maps["pixel_values"].squeeze(1).to(torch.int64) return BatchFeature(data=data, tensor_type=kwargs["return_tensors"]) - def _preprocess( - self, - images: list["torch.Tensor"], - do_resize: bool, - size: SizeDict, - interpolation: Optional["F_t.InterpolationMode"], - do_rescale: bool, - rescale_factor: float, - do_normalize: bool, - image_mean: Optional[Union[float, list[float]]], - image_std: Optional[Union[float, list[float]]], - do_pad: bool, - pad_size: SizeDict, - disable_grouping: Optional[bool], - return_tensors: Optional[Union[str, TensorType]], - **kwargs, - ) -> Union["torch.Tensor", list["torch.Tensor"]]: - # Group images by size for batched resizing - grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) - resized_images_grouped = {} - for shape, stacked_images in grouped_images.items(): - if do_resize: - stacked_images = self.resize(image=stacked_images, size=size, interpolation=interpolation) - resized_images_grouped[shape] = stacked_images - resized_images = reorder_images(resized_images_grouped, grouped_images_index) - - # Group images by size for further processing - # Needed in case do_resize is False, or resize returns images with different sizes - grouped_images, grouped_images_index = group_images_by_shape(resized_images, disable_grouping=disable_grouping) - processed_images_grouped = {} - for shape, stacked_images in grouped_images.items(): - # Fused rescale and normalize - stacked_images = self.rescale_and_normalize( - stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std - ) - if do_pad: - stacked_images = self.pad_image(stacked_images, pad_size) - processed_images_grouped[shape] = stacked_images - - processed_images = reorder_images(processed_images_grouped, grouped_images_index) - processed_images = torch.stack(processed_images, dim=0) if return_tensors else processed_images - - return processed_images - def generate_crop_boxes( self, image: "torch.Tensor", diff --git a/src/transformers/models/sam2/image_processing_sam2_fast.py b/src/transformers/models/sam2/image_processing_sam2_fast.py index 4b65bec77b57..8cb5381f0977 100644 --- a/src/transformers/models/sam2/image_processing_sam2_fast.py +++ b/src/transformers/models/sam2/image_processing_sam2_fast.py @@ -504,14 +504,6 @@ def _preprocess_image_like_inputs( return BatchFeature(data=data, tensor_type=kwargs["return_tensors"]) - def _preprocess( - self, - images: list["torch.Tensor"], - return_tensors: Optional[Union[str, TensorType]], - **kwargs, - ) -> "torch.Tensor": - return super()._preprocess(images, return_tensors=return_tensors, **kwargs).pixel_values - def generate_crop_boxes( self, image: "torch.Tensor", @@ -713,6 +705,17 @@ def post_process_for_mask_generation(self, all_masks, all_scores, all_boxes, cro """ return _post_process_for_mask_generation(all_masks, all_scores, all_boxes, crops_nms_thresh) + def pad_image(self): + raise NotImplementedError("No pad_image for SAM 2.") + + def _preprocess( + self, + images: list["torch.Tensor"], + return_tensors: Optional[Union[str, TensorType]], + **kwargs, + ) -> "torch.Tensor": + return super()._preprocess(images, return_tensors=return_tensors, **kwargs).pixel_values + def _apply_non_overlapping_constraints(self, pred_masks: torch.Tensor) -> torch.Tensor: """ Apply non-overlapping constraints to the object scores in pred_masks. Here we diff --git a/src/transformers/models/smolvlm/image_processing_smolvlm_fast.py b/src/transformers/models/smolvlm/image_processing_smolvlm_fast.py index 6f4bbd209bca..4e24bc279543 100644 --- a/src/transformers/models/smolvlm/image_processing_smolvlm_fast.py +++ b/src/transformers/models/smolvlm/image_processing_smolvlm_fast.py @@ -52,9 +52,6 @@ class SmolVLMFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): """ - do_pad (`bool`, *optional*): - Whether to pad the image. If `True`, will pad the patch dimension of the images in the batch to the largest - number of patches in the batch. Padding will be applied to the bottom and right with zeros. do_image_splitting (`bool`, *optional*, defaults to `True`): Whether to split the image into sub-images concatenated with the original image. They are split into patches such that each patch has a size of `max_image_size["height"]` x `max_image_size["width"]`. @@ -64,7 +61,6 @@ class SmolVLMFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Whether to return the row and column information of the images. """ - do_pad: Optional[bool] do_image_splitting: Optional[bool] max_image_size: Optional[dict[str, int]] return_row_col_info: Optional[bool] diff --git a/src/transformers/models/smolvlm/video_processing_smolvlm.py b/src/transformers/models/smolvlm/video_processing_smolvlm.py index 44d7ab9cef37..eda3bdb1c811 100644 --- a/src/transformers/models/smolvlm/video_processing_smolvlm.py +++ b/src/transformers/models/smolvlm/video_processing_smolvlm.py @@ -98,7 +98,8 @@ def get_resize_output_image_size( class SmolVLMVideoProcessorInitKwargs(VideosKwargs): - max_image_size: dict[str, int] = None + max_image_size: Optional[dict[str, int]] + do_pad: Optional[bool] class SmolVLMVideoProcessor(BaseVideoProcessor): diff --git a/src/transformers/models/swin2sr/image_processing_swin2sr.py b/src/transformers/models/swin2sr/image_processing_swin2sr.py index d36ce936c2f1..76c5e907da1c 100644 --- a/src/transformers/models/swin2sr/image_processing_swin2sr.py +++ b/src/transformers/models/swin2sr/image_processing_swin2sr.py @@ -31,6 +31,7 @@ validate_preprocess_arguments, ) from ...utils import TensorType, filter_out_non_signature_kwargs, logging +from ...utils.deprecation import deprecate_kwarg logger = logging.get_logger(__name__) @@ -56,7 +57,7 @@ def __init__( do_rescale: bool = True, rescale_factor: Union[int, float] = 1 / 255, do_pad: bool = True, - pad_size: int = 8, + size_divisor: int = 8, **kwargs, ) -> None: super().__init__(**kwargs) @@ -64,7 +65,22 @@ def __init__( self.do_rescale = do_rescale self.rescale_factor = rescale_factor self.do_pad = do_pad - self.pad_size = pad_size + pad_size = kwargs.get("pad_size") + self.size_divisor = size_divisor if size_divisor is not None else pad_size + + @property + def pad_size(self): + logger.warning( + "`self.pad_size` attribute is deprecated and will be removed in v5. Use `self.size_divisor` instead", + ) + return self.size_divisor + + @pad_size.setter + def pad_size(self, value): + logger.warning( + "`self.pad_size` attribute is deprecated and will be removed in v5. Use `self.size_divisor` instead", + ) + self.size_divisor = value def pad( self, @@ -108,13 +124,14 @@ def pad( ) @filter_out_non_signature_kwargs() + @deprecate_kwarg("pad_size", version="v5", new_name="size_divisor") def preprocess( self, images: ImageInput, do_rescale: Optional[bool] = None, rescale_factor: Optional[float] = None, do_pad: Optional[bool] = None, - pad_size: Optional[int] = None, + size_divisor: Optional[int] = None, return_tensors: Optional[Union[str, TensorType]] = None, data_format: Union[str, ChannelDimension] = ChannelDimension.FIRST, input_data_format: Optional[Union[str, ChannelDimension]] = None, @@ -132,7 +149,7 @@ def preprocess( Rescale factor to rescale the image by if `do_rescale` is set to `True`. do_pad (`bool`, *optional*, defaults to `True`): Whether to pad the image to make the height and width divisible by `window_size`. - pad_size (`int`, *optional*, defaults to 32): + size_divisor (`int`, *optional*, defaults to 32): The size of the sliding window for the local attention. return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: @@ -157,7 +174,7 @@ def preprocess( do_rescale = do_rescale if do_rescale is not None else self.do_rescale rescale_factor = rescale_factor if rescale_factor is not None else self.rescale_factor do_pad = do_pad if do_pad is not None else self.do_pad - pad_size = pad_size if pad_size is not None else self.pad_size + size_divisor = size_divisor if size_divisor is not None else self.size_divisor images = make_flat_list_of_images(images) @@ -169,8 +186,6 @@ def preprocess( validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, - do_pad=do_pad, - size_divisibility=pad_size, # Here the pad function simply requires pad_size. ) # All transformations expect numpy arrays. @@ -193,7 +208,7 @@ def preprocess( ] if do_pad: - images = [self.pad(image, size=pad_size, input_data_format=input_data_format) for image in images] + images = [self.pad(image, size=size_divisor, input_data_format=input_data_format) for image in images] images = [ to_channel_dimension_format(image, data_format, input_channel_dim=input_data_format) for image in images diff --git a/src/transformers/models/swin2sr/image_processing_swin2sr_fast.py b/src/transformers/models/swin2sr/image_processing_swin2sr_fast.py index cc8235f1141e..f99ab99274f5 100644 --- a/src/transformers/models/swin2sr/image_processing_swin2sr_fast.py +++ b/src/transformers/models/swin2sr/image_processing_swin2sr_fast.py @@ -31,9 +31,13 @@ is_torch_available, is_torchvision_available, is_torchvision_v2_available, + logging, ) +from ...utils.deprecation import deprecate_kwarg +logger = logging.get_logger(__name__) + if is_torch_available(): import torch @@ -46,14 +50,12 @@ class Swin2SRFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): """ - do_pad (`bool`, *optional*, defaults to `True`): - Whether to pad the image to make the height and width divisible by `window_size`. - pad_size (`int`, *optional*, defaults to `8`): - The size of the sliding window for the local attention. + size_divisor (`int`, *optional*, defaults to `8`): + The size of the sliding window for the local attention. It will be used to pad the image + to the size divisible by `size_divisor` """ - do_pad: Optional[bool] - pad_size: Optional[int] + size_divisor: Optional[int] @auto_docstring @@ -61,31 +63,48 @@ class Swin2SRImageProcessorFast(BaseImageProcessorFast): do_rescale = True rescale_factor = 1 / 255 do_pad = True - pad_size = 8 + size_divisor = 8 valid_kwargs = Swin2SRFastImageProcessorKwargs def __init__(self, **kwargs: Unpack[Swin2SRFastImageProcessorKwargs]): + pad_size = kwargs.pop("pad_size", None) + kwargs.setdefault("size_divisor", pad_size) super().__init__(**kwargs) + @property + def pad_size(self): + logger.warning( + "`self.pad_size` attribute is deprecated and will be removed in v5. Use `self.size_divisor` instead", + ) + return self.size_divisor + + @pad_size.setter + def pad_size(self, value): + logger.warning( + "`self.pad_size` attribute is deprecated and will be removed in v5. Use `self.size_divisor` instead", + ) + self.size_divisor = value + def preprocess(self, images: ImageInput, **kwargs: Unpack[Swin2SRFastImageProcessorKwargs]) -> BatchFeature: return super().preprocess(images, **kwargs) - def pad(self, images: "torch.Tensor", size: int) -> "torch.Tensor": + @deprecate_kwarg("size", version="v5", new_name="size_divisor") + def pad(self, images: "torch.Tensor", size_divisor: int) -> "torch.Tensor": """ - Pad an image to make the height and width divisible by `size`. + Pad an image to make the height and width divisible by `size_divisor`. Args: images (`torch.Tensor`): Images to pad. - size (`int`): + size_divisor (`int`): The size to make the height and width divisible by. Returns: `torch.Tensor`: The padded images. """ height, width = get_image_size(images, ChannelDimension.FIRST) - pad_height = (height // size + 1) * size - height - pad_width = (width // size + 1) * size - width + pad_height = (height // size_divisor + 1) * size_divisor - height + pad_width = (width // size_divisor + 1) * size_divisor - width return F.pad( images, @@ -93,13 +112,14 @@ def pad(self, images: "torch.Tensor", size: int) -> "torch.Tensor": padding_mode="symmetric", ) + @deprecate_kwarg("pad_size", version="v5", new_name="size_divisor") def _preprocess( self, images: list["torch.Tensor"], do_rescale: bool, rescale_factor: float, do_pad: bool, - pad_size: int, + size_divisor: int, disable_grouping: Optional[bool], return_tensors: Optional[Union[str, TensorType]], **kwargs, @@ -110,7 +130,7 @@ def _preprocess( if do_rescale: stacked_images = self.rescale(stacked_images, scale=rescale_factor) if do_pad: - stacked_images = self.pad(stacked_images, size=pad_size) + stacked_images = self.pad(stacked_images, size_divisor=size_divisor) processed_image_grouped[shape] = stacked_images processed_images = reorder_images(processed_image_grouped, grouped_images_index) processed_images = torch.stack(processed_images, dim=0) if return_tensors else processed_images diff --git a/src/transformers/models/tvp/image_processing_tvp.py b/src/transformers/models/tvp/image_processing_tvp.py index 7fa758b6f484..d3f698873d55 100644 --- a/src/transformers/models/tvp/image_processing_tvp.py +++ b/src/transformers/models/tvp/image_processing_tvp.py @@ -294,8 +294,6 @@ def _preprocess_image( do_normalize=do_normalize, image_mean=image_mean, image_std=image_std, - do_pad=do_pad, - size_divisibility=pad_size, # here the pad() method simply requires the pad_size argument. do_center_crop=do_center_crop, crop_size=crop_size, do_resize=do_resize, diff --git a/src/transformers/models/tvp/image_processing_tvp_fast.py b/src/transformers/models/tvp/image_processing_tvp_fast.py index a3bad696c36d..b96e4991f619 100644 --- a/src/transformers/models/tvp/image_processing_tvp_fast.py +++ b/src/transformers/models/tvp/image_processing_tvp_fast.py @@ -16,7 +16,7 @@ from typing import Optional, Union -from ...image_processing_utils import BatchFeature, get_size_dict +from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, DefaultFastImageProcessorKwargs, @@ -55,10 +55,6 @@ class TvpFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): r""" do_flip_channel_order (`bool`, *optional*): Whether to flip the channel order of the image from RGB to BGR. - do_pad (`bool`, *optional*): - Whether to pad the image. - pad_size (`Dict[str, int]` or `SizeDict`, *optional*): - Size dictionary specifying the desired height and width for padding. constant_values (`float` or `List[float]`, *optional*): Value used to fill the padding area when `pad_mode` is `'constant'`. pad_mode (`str`, *optional*): @@ -66,8 +62,6 @@ class TvpFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): """ do_flip_channel_order: Optional[bool] - do_pad: Optional[bool] - pad_size: Optional[SizeDict] constant_values: Optional[Union[float, list[float]]] pad_mode: Optional[str] @@ -103,21 +97,6 @@ def preprocess( ) -> BatchFeature: return super().preprocess(videos, **kwargs) - def _further_process_kwargs( - self, - pad_size: Optional[SizeDict] = None, - **kwargs, - ) -> dict: - """ - Update kwargs that need further processing before being validated - Can be overridden by subclasses to customize the processing of kwargs. - """ - if pad_size is not None: - pad_size = SizeDict(**get_size_dict(pad_size, param_name="pad_size")) - kwargs["pad_size"] = pad_size - - return super()._further_process_kwargs(**kwargs) - def _prepare_images_structure( self, images: ImageInput, @@ -135,31 +114,6 @@ def _prepare_images_structure( """ return make_nested_list_of_images(images, **kwargs) - def _pad_frames( - self, - frames: "torch.Tensor", - pad_size: Union[SizeDict, dict], - constant_values: Union[float, list[float]], - pad_mode: str, - ) -> "torch.Tensor": - """Pad frames to the specified size.""" - height, width = pad_size.height, pad_size.width - - if frames.shape[-2:] == (height, width): - return frames - - # Calculate padding - current_height, current_width = frames.shape[-2:] - pad_bottom = height - current_height - pad_right = width - current_width - - if pad_bottom < 0 or pad_right < 0: - raise ValueError("The padding size must be greater than frame size") - - # Apply padding - padding = [0, 0, pad_right, pad_bottom] # [left, top, right, bottom] - return F.pad(frames, padding, fill=constant_values, padding_mode=pad_mode) - def resize( self, image: "torch.Tensor", @@ -238,7 +192,7 @@ def _preprocess( do_rescale: bool, rescale_factor: float, do_pad: bool, - pad_size: Union[SizeDict, dict], + pad_size: SizeDict, constant_values: Union[float, list[float]], pad_mode: str, do_normalize: bool, @@ -275,7 +229,8 @@ def _preprocess( # Pad if needed if do_pad: - stacked_frames = self._pad_frames(stacked_frames, pad_size, constant_values, pad_mode) + stacked_frames = self.pad(stacked_frames, pad_size, fill_value=constant_values, pad_mode=pad_mode) + stacked_frames = torch.stack(stacked_frames, dim=0) # Flip channel order if needed (RGB to BGR) if do_flip_channel_order: diff --git a/src/transformers/models/vilt/image_processing_vilt_fast.py b/src/transformers/models/vilt/image_processing_vilt_fast.py index 3e6571f159e1..1c169994ba3f 100644 --- a/src/transformers/models/vilt/image_processing_vilt_fast.py +++ b/src/transformers/models/vilt/image_processing_vilt_fast.py @@ -51,16 +51,12 @@ class ViltFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): """ Args: - do_pad (`bool`, *optional*, defaults to `True`): - Whether to pad the image. If `True`, will pad the images in the batch to the largest height and width - in the batch. Padding will be applied to the bottom and right with zeros. size_divisor (`int`, *optional*, defaults to 32): The size to make the height and width divisible by. rescale_factor (`float`, *optional*, defaults to 1/255): The factor to rescale the image by. """ - do_pad: Optional[bool] size_divisor: Optional[int] rescale_factor: Optional[float] diff --git a/src/transformers/models/vilt/processing_vilt.py b/src/transformers/models/vilt/processing_vilt.py index 5b5126ad4a85..f4f9fc9a746d 100644 --- a/src/transformers/models/vilt/processing_vilt.py +++ b/src/transformers/models/vilt/processing_vilt.py @@ -17,11 +17,17 @@ """ import warnings +from typing import Optional -from ...processing_utils import ProcessingKwargs, ProcessorMixin +from ...processing_utils import ImagesKwargs, ProcessingKwargs, ProcessorMixin + + +class ViltImagesKwargs(ImagesKwargs): + size_divisor: Optional[int] class ViltProcessorKwargs(ProcessingKwargs, total=False): + images_kwargs: ViltImagesKwargs _defaults = { "text_kwargs": { "add_special_tokens": True, diff --git a/src/transformers/models/vitmatte/image_processing_vitmatte.py b/src/transformers/models/vitmatte/image_processing_vitmatte.py index 891fdb457359..6e65a634d23d 100644 --- a/src/transformers/models/vitmatte/image_processing_vitmatte.py +++ b/src/transformers/models/vitmatte/image_processing_vitmatte.py @@ -34,6 +34,7 @@ validate_preprocess_arguments, ) from ...utils import TensorType, filter_out_non_signature_kwargs, logging +from ...utils.deprecation import deprecate_kwarg logger = logging.get_logger(__name__) @@ -60,9 +61,9 @@ class VitMatteImageProcessor(BaseImageProcessor): Standard deviation to use if normalizing the image. This is a float or list of floats the length of the number of channels in the image. Can be overridden by the `image_std` parameter in the `preprocess` method. do_pad (`bool`, *optional*, defaults to `True`): - Whether to pad the image to make the width and height divisible by `size_divisibility`. Can be overridden + Whether to pad the image to make the width and height divisible by `size_divisor`. Can be overridden by the `do_pad` parameter in the `preprocess` method. - size_divisibility (`int`, *optional*, defaults to 32): + size_divisor (`int`, *optional*, defaults to 32): The width and height of the image will be padded to be divisible by this number. """ @@ -76,7 +77,7 @@ def __init__( image_mean: Optional[Union[float, list[float]]] = None, image_std: Optional[Union[float, list[float]]] = None, do_pad: bool = True, - size_divisibility: int = 32, + size_divisor: int = 32, **kwargs, ) -> None: super().__init__(**kwargs) @@ -86,7 +87,22 @@ def __init__( self.rescale_factor = rescale_factor self.image_mean = image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN self.image_std = image_std if image_std is not None else IMAGENET_STANDARD_STD - self.size_divisibility = size_divisibility + size_divisibility = kwargs.get("size_divisibility") + self.size_divisor = size_divisibility if size_divisibility is not None else size_divisor + + @property + def size_divisibility(self): + logger.warning( + "`self.size_divisibility` attribute is deprecated and will be removed in v5. Use `self.size_divisor` instead" + ) + return self.size_divisor + + @size_divisibility.setter + def size_divisibility(self, value): + logger.warning( + "`self.size_divisibility` attribute is deprecated and will be removed in v5. Use `self.size_divisor` instead" + ) + self.size_divisor = value def pad_image( self, @@ -130,6 +146,7 @@ def pad_image( return image @filter_out_non_signature_kwargs() + @deprecate_kwarg("size_divisibility", version="v5", new_name="size_divisor") def preprocess( self, images: ImageInput, @@ -140,7 +157,7 @@ def preprocess( image_mean: Optional[Union[float, list[float]]] = None, image_std: Optional[Union[float, list[float]]] = None, do_pad: Optional[bool] = None, - size_divisibility: Optional[int] = None, + size_divisor: Optional[int] = None, return_tensors: Optional[Union[str, TensorType]] = None, data_format: Union[str, ChannelDimension] = ChannelDimension.FIRST, input_data_format: Optional[Union[str, ChannelDimension]] = None, @@ -166,7 +183,7 @@ def preprocess( Image standard deviation to use if `do_normalize` is set to `True`. do_pad (`bool`, *optional*, defaults to `self.do_pad`): Whether to pad the image. - size_divisibility (`int`, *optional*, defaults to `self.size_divisibility`): + size_divisor (`int`, *optional*, defaults to `self.size_divisor`): The size divisibility to pad the image to if `do_pad` is set to `True`. return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: @@ -193,7 +210,7 @@ def preprocess( rescale_factor = rescale_factor if rescale_factor is not None else self.rescale_factor image_mean = image_mean if image_mean is not None else self.image_mean image_std = image_std if image_std is not None else self.image_std - size_divisibility = size_divisibility if size_divisibility is not None else self.size_divisibility + size_divisor = size_divisor if size_divisor is not None else self.size_divisor images = make_flat_list_of_images(images) trimaps = make_flat_list_of_images(trimaps, expected_ndims=2) @@ -215,8 +232,6 @@ def preprocess( do_normalize=do_normalize, image_mean=image_mean, image_std=image_std, - do_pad=do_pad, - size_divisibility=size_divisibility, ) # All transformations expect numpy arrays. @@ -258,7 +273,7 @@ def preprocess( if do_pad: images = [ - self.pad_image(image, size_divisibility=size_divisibility, input_data_format=input_data_format) + self.pad_image(image, size_divisibility=size_divisor, input_data_format=input_data_format) for image in images ] diff --git a/src/transformers/models/vitmatte/image_processing_vitmatte_fast.py b/src/transformers/models/vitmatte/image_processing_vitmatte_fast.py index e2cd7d331253..014a6939af5c 100644 --- a/src/transformers/models/vitmatte/image_processing_vitmatte_fast.py +++ b/src/transformers/models/vitmatte/image_processing_vitmatte_fast.py @@ -57,15 +57,11 @@ class VitMatteFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): """ - do_pad (`bool`, *optional*, defaults to `True`): - Whether to pad the image to make the width and height divisible by `size_divisibility`. Can be overridden - by the `do_pad` parameter in the `preprocess` method. - size_divisibility (`int`, *optional*, defaults to 32): + size_divisor (`int`, *optional*, defaults to 32): The width and height of the image will be padded to be divisible by this number. """ - do_pad: Optional[bool] - size_divisibility: int + size_divisor: Optional[int] @auto_docstring @@ -76,12 +72,28 @@ class VitMatteImageProcessorFast(BaseImageProcessorFast): image_mean: Optional[Union[float, list[float]]] = IMAGENET_STANDARD_MEAN image_std: Optional[Union[float, list[float]]] = IMAGENET_STANDARD_STD do_pad: bool = True - size_divisibility: int = 32 + size_divisor: int = 32 valid_kwargs = VitMatteFastImageProcessorKwargs def __init__(self, **kwargs: Unpack[VitMatteFastImageProcessorKwargs]) -> None: + size_divisibility = kwargs.pop("size_divisibility", None) + kwargs.setdefault("size_divisor", size_divisibility) super().__init__(**kwargs) + @property + def size_divisibility(self): + logger.warning( + "`self.size_divisibility` attribute is deprecated and will be removed in v5. Use `self.size_divisor` instead" + ) + return self.size_divisor + + @size_divisibility.setter + def size_divisibility(self, value): + logger.warning( + "`self.size_divisibility` attribute is deprecated and will be removed in v5. Use `self.size_divisor` instead" + ) + self.size_divisor = value + def _pad_image( self, images: "torch.tensor", @@ -150,10 +162,9 @@ def _preprocess( image_mean: Optional[Union[float, list[float]]] = None, image_std: Optional[Union[float, list[float]]] = None, do_pad: Optional[bool] = None, - size_divisibility: Optional[int] = None, + size_divisor: Optional[int] = None, disable_grouping: Optional[bool] = None, return_tensors: Optional[Union[str, TensorType]] = None, - **kwargs, ) -> BatchFeature: grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) grouped_trimaps, grouped_trimaps_index = group_images_by_shape(trimaps, disable_grouping=disable_grouping) @@ -170,7 +181,7 @@ def _preprocess( ) stacked_images = torch.cat([stacked_images, stacked_trimaps], dim=1) if do_pad: - stacked_images = self._pad_image(stacked_images, self.size_divisibility) + stacked_images = self._pad_image(stacked_images, size_divisor) processed_images_grouped[shape] = stacked_images processed_images = reorder_images(processed_images_grouped, grouped_images_index) diff --git a/src/transformers/models/yolos/image_processing_yolos_fast.py b/src/transformers/models/yolos/image_processing_yolos_fast.py index 4bea14b508ea..81fb0b008e0d 100644 --- a/src/transformers/models/yolos/image_processing_yolos_fast.py +++ b/src/transformers/models/yolos/image_processing_yolos_fast.py @@ -64,23 +64,12 @@ class YolosFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Controls whether to convert the annotations to the format expected by the YOLOS model. Converts the bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`. Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method. - do_pad (`bool`, *optional*, defaults to `True`): - Controls whether to pad the image. Can be overridden by the `do_pad` parameter in the `preprocess` - method. If `True`, padding will be applied to the bottom and right of the image with zeros. - If `pad_size` is provided, the image will be padded to the specified dimensions. - Otherwise, the image will be padded to the maximum height and width of the batch. - pad_size (`dict[str, int]`, *optional*): - The size `{"height": int, "width" int}` to pad the images to. Must be larger than any image size - provided for preprocessing. If `pad_size` is not provided, images will be padded to the largest - height and width in the batch. return_segmentation_masks (`bool`, *optional*, defaults to `False`): Whether to return segmentation masks. """ format: Optional[Union[str, AnnotationFormat]] do_convert_annotations: Optional[bool] - do_pad: Optional[bool] - pad_size: Optional[dict[str, int]] return_segmentation_masks: Optional[bool] @@ -668,7 +657,7 @@ def _preprocess( image_mean: Optional[Union[float, list[float]]], image_std: Optional[Union[float, list[float]]], do_pad: bool, - pad_size: Optional[dict[str, int]], + pad_size: Optional[SizeDict], format: Optional[Union[str, AnnotationFormat]], return_tensors: Optional[Union[str, TensorType]], **kwargs, @@ -737,7 +726,7 @@ def _preprocess( if do_pad: # depends on all resized image shapes so we need another loop if pad_size is not None: - padded_size = (pad_size["height"], pad_size["width"]) + padded_size = (pad_size.height, pad_size.width) else: padded_size = get_max_height_width(images) diff --git a/src/transformers/models/zoedepth/image_processing_zoedepth_fast.py b/src/transformers/models/zoedepth/image_processing_zoedepth_fast.py index 793c386fdc75..c89ec8b2ebf1 100644 --- a/src/transformers/models/zoedepth/image_processing_zoedepth_fast.py +++ b/src/transformers/models/zoedepth/image_processing_zoedepth_fast.py @@ -70,8 +70,6 @@ class ZoeDepthFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): """ - do_pad (`bool`, *optional*, defaults to `True`): - Whether to apply pad the input. keep_aspect_ratio (`bool`, *optional*, defaults to `True`): If `True`, the image is resized by choosing the smaller of the height and width scaling factors and using it for both dimensions. This ensures that the image is scaled down as little as possible while still fitting @@ -85,7 +83,6 @@ class ZoeDepthFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): Can be overridden by `ensure_multiple_of` in `preprocess`. """ - do_pad: Optional[bool] keep_aspect_ratio: Optional[bool] ensure_multiple_of: Optional[int] diff --git a/src/transformers/processing_utils.py b/src/transformers/processing_utils.py index 3130d0ded34f..86cdb372034c 100644 --- a/src/transformers/processing_utils.py +++ b/src/transformers/processing_utils.py @@ -168,8 +168,6 @@ class methods and docstrings. Whether to resize the image. size (`dict[str, int]`, *optional*): Resize the shorter side of the input to `size["shortest_edge"]`. - size_divisor (`int`, *optional*): - The size by which to make sure both the height and width can be divided. crop_size (`dict[str, int]`, *optional*): Desired output size when applying center-cropping. resample (`PILImageResampling`, *optional*): @@ -200,7 +198,6 @@ class methods and docstrings. do_resize: Optional[bool] size: Optional[dict[str, int]] - size_divisor: Optional[int] crop_size: Optional[dict[str, int]] resample: Optional[Union["PILImageResampling", int]] do_rescale: Optional[bool] @@ -229,8 +226,6 @@ class VideosKwargs(TypedDict, total=False): Resize the shorter side of the input to `size["shortest_edge"]`. default_to_square (`bool`, *optional*, defaults to `self.default_to_square`): Whether to default to a square when resizing, if size is an int. - size_divisor (`int`, *optional*): - The size by which to make sure both the height and width can be divided. resample (`PILImageResampling`, *optional*): Resampling filter to use if resizing the video. do_rescale (`bool`, *optional*): @@ -243,8 +238,6 @@ class VideosKwargs(TypedDict, total=False): Mean to use if normalizing the video. image_std (`float` or `list[float]`, *optional*): Standard deviation to use if normalizing the video. - do_pad (`bool`, *optional*): - Whether to pad the video to the `(max_height, max_width)` of the videos in the batch. do_center_crop (`bool`, *optional*): Whether to center crop the video. do_sample_frames (`bool`, *optional*): @@ -268,7 +261,6 @@ class VideosKwargs(TypedDict, total=False): do_convert_rgb: Optional[bool] do_resize: Optional[bool] size: Optional[dict[str, int]] - size_divisor: Optional[int] default_to_square: Optional[bool] resample: Optional["PILImageResampling"] do_rescale: Optional[bool] @@ -276,7 +268,6 @@ class VideosKwargs(TypedDict, total=False): do_normalize: Optional[bool] image_mean: Optional[Union[float, list[float]]] image_std: Optional[Union[float, list[float]]] - do_pad: Optional[bool] do_center_crop: Optional[bool] crop_size: Optional[dict[str, int]] data_format: Optional[ChannelDimension] @@ -655,6 +646,18 @@ def to_dict(self, legacy_serialization=True) -> dict[str, Any]: if "chat_template" in output: del output["chat_template"] + def cast_array_to_list(dictionary): + """ + Numpy arrays are not serialiazable but can be in pre-processing dicts. + This function casts arrays to list, recusring through the nested configs as well. + """ + for key, value in dictionary.items(): + if isinstance(value, np.ndarray): + dictionary[key] = value.tolist() + elif isinstance(value, dict): + dictionary[key] = cast_array_to_list(value) + return dictionary + # Serialize attributes as a dict output = { k: v.to_dict() if isinstance(v, PushToHubMixin) else v @@ -667,6 +670,7 @@ def to_dict(self, legacy_serialization=True) -> dict[str, Any]: ) # remove `PushToHubMixin` objects ) } + output = cast_array_to_list(output) # Special case, add `audio_tokenizer` dict which points to model weights and path if not legacy_serialization and "audio_tokenizer" in output: diff --git a/src/transformers/utils/auto_docstring.py b/src/transformers/utils/auto_docstring.py index a9d9a8cba788..0847859450ea 100644 --- a/src/transformers/utils/auto_docstring.py +++ b/src/transformers/utils/auto_docstring.py @@ -131,6 +131,23 @@ class ImageProcessorArgs: "shape": None, } + do_pad = { + "description": """ + Whether to pad the image. Padding is done either to the largest size in the batch + or to a fixed square size per image. The exact padding strategy depends on the model. + """, + "shape": None, + } + + pad_size = { + "description": """ + The size in `{"height": int, "width" int}` to pad the images to. Must be larger than any image size + provided for preprocessing. If `pad_size` is not provided, images will be padded to the largest + height and width in the batch. Applied only when `do_pad=True.` + """, + "shape": None, + } + do_rescale = { "description": """ Whether to rescale the image. diff --git a/src/transformers/video_processing_utils.py b/src/transformers/video_processing_utils.py index 43d9e2bfd26e..9f6545ebe10e 100644 --- a/src/transformers/video_processing_utils.py +++ b/src/transformers/video_processing_utils.py @@ -95,8 +95,6 @@ do_center_crop (`bool`, *optional*, defaults to `self.do_center_crop`): Whether to center crop the video to the specified `crop_size`. Can be overridden by `do_center_crop` in the `preprocess` method. - do_pad (`bool`, *optional*): - Whether to pad the video to the `(max_height, max_width)` of the videos in the batch. crop_size (`dict[str, int]` *optional*, defaults to `self.crop_size`): Size of the output video after applying `center_crop`. Can be overridden by `crop_size` in the `preprocess` method. @@ -164,7 +162,6 @@ class BaseVideoProcessor(BaseImageProcessorFast): crop_size = None do_resize = None do_center_crop = None - do_pad = None do_rescale = None rescale_factor = 1 / 255 do_normalize = None @@ -401,12 +398,10 @@ def _preprocess( do_convert_rgb: bool, do_resize: bool, size: SizeDict, - size_divisor: Optional[int], interpolation: Optional["F.InterpolationMode"], do_center_crop: bool, crop_size: SizeDict, do_rescale: bool, - do_pad: bool, rescale_factor: float, do_normalize: bool, image_mean: Optional[Union[float, list[float]]], @@ -421,9 +416,7 @@ def _preprocess( if do_convert_rgb: stacked_videos = self.convert_to_rgb(stacked_videos) if do_resize: - stacked_videos = self.resize( - stacked_videos, size=size, size_divisor=size_divisor, interpolation=interpolation - ) + stacked_videos = self.resize(stacked_videos, size=size, interpolation=interpolation) resized_videos_grouped[shape] = stacked_videos resized_videos = reorder_videos(resized_videos_grouped, grouped_videos_index) diff --git a/tests/models/gemma3n/test_processing_gemma3n.py b/tests/models/gemma3n/test_processing_gemma3n.py index 320b821d6f79..2fbe7e79d3e5 100644 --- a/tests/models/gemma3n/test_processing_gemma3n.py +++ b/tests/models/gemma3n/test_processing_gemma3n.py @@ -66,15 +66,12 @@ def test_save_load_pretrained_default(self): tokenizer=tokenizer, feature_extractor=feature_extractor, image_processor=image_processor ) - processor.save_pretrained(self.tmpdirname) + processor.save_pretrained(self.tmpdirname, legacy_serialization=False) processor = Gemma3nProcessor.from_pretrained(self.tmpdirname) self.assertIsInstance(processor.tokenizer, GemmaTokenizerFast) self.assertEqual(processor.tokenizer.get_vocab(), tokenizer.get_vocab()) - # `disable_grouping` is a new attribute that got added on main while gemma3n was being released - so was - # not part of the saved processor - del processor.feature_extractor.disable_grouping self.assertIsInstance(processor.feature_extractor, Gemma3nAudioFeatureExtractor) self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor.to_json_string()) @@ -86,7 +83,7 @@ def test_save_load_pretrained_additional_features(self): processor = Gemma3nProcessor( tokenizer=tokenizer, feature_extractor=feature_extractor, image_processor=image_processor ) - processor.save_pretrained(self.tmpdirname) + processor.save_pretrained(self.tmpdirname, legacy_serialization=False) tokenizer_add_kwargs = self.get_tokenizer(bos_token="(BOS-BOS)", eos_token="(EOS-EOS)") feature_extractor_add_kwargs = self.get_feature_extractor(dither=5.0, padding_value=1.0) @@ -98,9 +95,6 @@ def test_save_load_pretrained_additional_features(self): self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) self.assertIsInstance(processor.tokenizer, GemmaTokenizerFast) - # `disable_grouping` is a new attribute that got added on main while gemma3n was being released - so was - # not part of the saved processor - del processor.feature_extractor.disable_grouping self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor_add_kwargs.to_json_string()) self.assertIsInstance(processor.feature_extractor, Gemma3nAudioFeatureExtractor) diff --git a/tests/models/janus/test_processing_janus.py b/tests/models/janus/test_processing_janus.py index 7e1b025721dc..73212e3ec4b3 100644 --- a/tests/models/janus/test_processing_janus.py +++ b/tests/models/janus/test_processing_janus.py @@ -457,7 +457,7 @@ def test_processor_postprocess(self): orig_image_input = self.prepare_image_inputs() orig_image = np.array(orig_image_input).transpose(2, 0, 1) - inputs = processor(text=input_str, images=orig_image, do_resize=False, return_tensors="np") + inputs = processor(text=input_str, images=orig_image, do_resize=False, do_pad=False, return_tensors="np") normalized_image_input = inputs.pixel_values unnormalized_images = processor.postprocess(normalized_image_input, return_tensors="np")["pixel_values"] diff --git a/tests/models/swin2sr/test_image_processing_swin2sr.py b/tests/models/swin2sr/test_image_processing_swin2sr.py index eecb023c29a0..2cf3edaf4386 100644 --- a/tests/models/swin2sr/test_image_processing_swin2sr.py +++ b/tests/models/swin2sr/test_image_processing_swin2sr.py @@ -48,7 +48,7 @@ def __init__( do_rescale=True, rescale_factor=1 / 255, do_pad=True, - pad_size=8, + size_divisor=8, ): self.parent = parent self.batch_size = batch_size @@ -59,14 +59,14 @@ def __init__( self.do_rescale = do_rescale self.rescale_factor = rescale_factor self.do_pad = do_pad - self.pad_size = pad_size + self.size_divisor = size_divisor def prepare_image_processor_dict(self): return { "do_rescale": self.do_rescale, "rescale_factor": self.rescale_factor, "do_pad": self.do_pad, - "pad_size": self.pad_size, + "size_divisor": self.size_divisor, } def expected_output_image_shape(self, images): @@ -79,8 +79,8 @@ def expected_output_image_shape(self, images): else: input_height, input_width = img.shape[-2:] - pad_height = (input_height // self.pad_size + 1) * self.pad_size - input_height - pad_width = (input_width // self.pad_size + 1) * self.pad_size - input_width + pad_height = (input_height // self.size_divisor + 1) * self.size_divisor - input_height + pad_width = (input_width // self.size_divisor + 1) * self.size_divisor - input_width return self.num_channels, input_height + pad_height, input_width + pad_width @@ -116,11 +116,12 @@ def test_image_processor_properties(self): self.assertTrue(hasattr(image_processing, "do_rescale")) self.assertTrue(hasattr(image_processing, "rescale_factor")) self.assertTrue(hasattr(image_processing, "do_pad")) - self.assertTrue(hasattr(image_processing, "pad_size")) + self.assertTrue(hasattr(image_processing, "size_divisor")) + self.assertTrue(hasattr(image_processing, "pad_size")) # deprecated but should be available def calculate_expected_size(self, image): old_height, old_width = get_image_size(image) - size = self.image_processor_tester.pad_size + size = self.image_processor_tester.size_divisor pad_height = (old_height // size + 1) * size - old_height pad_width = (old_width // size + 1) * size - old_width diff --git a/tests/models/tvp/test_image_processing_tvp.py b/tests/models/tvp/test_image_processing_tvp.py index 28581290e9d1..c2c8b81dfc0a 100644 --- a/tests/models/tvp/test_image_processing_tvp.py +++ b/tests/models/tvp/test_image_processing_tvp.py @@ -222,15 +222,15 @@ def test_call_numpy(self): # Test not batched input expected_height, expected_width = self.image_processor_tester.get_expected_values(video_inputs) encoded_videos = image_processing(test_inputs[0], return_tensors="pt").pixel_values - self.assertEqual( - encoded_videos.shape, - ( + self.assertListEqual( + list(encoded_videos.shape), + [ 1, self.image_processor_tester.num_frames, self.image_processor_tester.num_channels, expected_height, expected_width, - ), + ], ) # Test batched @@ -238,15 +238,15 @@ def test_call_numpy(self): video_inputs, batched=True ) encoded_videos = image_processing(test_inputs, return_tensors="pt").pixel_values - self.assertEqual( - encoded_videos.shape, - ( + self.assertListEqual( + list(encoded_videos.shape), + [ self.image_processor_tester.batch_size, self.image_processor_tester.num_frames, self.image_processor_tester.num_channels, expected_height, expected_width, - ), + ], ) def test_call_numpy_4_channels(self): @@ -276,15 +276,15 @@ def test_call_numpy_4_channels(self): encoded_videos = image_processing( test_inputs[0], return_tensors="pt", image_mean=0, image_std=1, input_data_format="channels_first" ).pixel_values - self.assertEqual( - encoded_videos.shape, - ( + self.assertListEqual( + list(encoded_videos.shape), + [ 1, self.image_processor_tester.num_frames, self.image_processor_tester.num_channels, expected_height, expected_width, - ), + ], ) # Test batched @@ -294,15 +294,15 @@ def test_call_numpy_4_channels(self): encoded_videos = image_processing( test_inputs, return_tensors="pt", image_mean=0, image_std=1, input_data_format="channels_first" ).pixel_values - self.assertEqual( - encoded_videos.shape, - ( + self.assertListEqual( + list(encoded_videos.shape), + [ self.image_processor_tester.batch_size, self.image_processor_tester.num_frames, self.image_processor_tester.num_channels, expected_height, expected_width, - ), + ], ) self.image_processor_tester.num_channels = 3 diff --git a/tests/models/vitmatte/test_image_processing_vitmatte.py b/tests/models/vitmatte/test_image_processing_vitmatte.py index dc5597b1918b..a103c33a9cca 100644 --- a/tests/models/vitmatte/test_image_processing_vitmatte.py +++ b/tests/models/vitmatte/test_image_processing_vitmatte.py @@ -60,7 +60,7 @@ def __init__( do_rescale=True, rescale_factor=0.5, do_pad=True, - size_divisibility=10, + size_divisor=10, do_normalize=True, image_mean=[0.5, 0.5, 0.5], image_std=[0.5, 0.5, 0.5], @@ -74,7 +74,7 @@ def __init__( self.do_rescale = do_rescale self.rescale_factor = rescale_factor self.do_pad = do_pad - self.size_divisibility = size_divisibility + self.size_divisor = size_divisor self.do_normalize = do_normalize self.image_mean = image_mean self.image_std = image_std @@ -87,7 +87,7 @@ def prepare_image_processor_dict(self): "do_rescale": self.do_rescale, "rescale_factor": self.rescale_factor, "do_pad": self.do_pad, - "size_divisibility": self.size_divisibility, + "size_divisor": self.size_divisor, } def prepare_image_inputs(self, equal_resolution=False, numpify=False, torchify=False): @@ -125,6 +125,8 @@ def test_image_processor_properties(self): self.assertTrue(hasattr(image_processing, "do_rescale")) self.assertTrue(hasattr(image_processing, "rescale_factor")) self.assertTrue(hasattr(image_processing, "do_pad")) + self.assertTrue(hasattr(image_processing, "size_divisor")) + # Check size_divisibility for BC, the image proccessor has to have an atribute self.assertTrue(hasattr(image_processing, "size_divisibility")) def test_call_numpy(self): @@ -141,8 +143,8 @@ def test_call_numpy(self): encoded_images = image_processing(images=image, trimaps=trimap, return_tensors="pt").pixel_values # Verify that width and height can be divided by size_divisibility and that correct dimensions got merged - self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisibility == 0) - self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisibility == 0) + self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisor == 0) + self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisor == 0) self.assertTrue(encoded_images.shape[-3] == 4) def test_call_pytorch(self): @@ -160,8 +162,8 @@ def test_call_pytorch(self): encoded_images = image_processing(images=image, trimaps=trimap, return_tensors="pt").pixel_values # Verify that width and height can be divided by size_divisibility and that correct dimensions got merged - self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisibility == 0) - self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisibility == 0) + self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisor == 0) + self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisor == 0) self.assertTrue(encoded_images.shape[-3] == 4) # create batched tensors @@ -180,8 +182,8 @@ def test_call_pytorch(self): encoded_images = image_processing(images=image, trimaps=trimap, return_tensors="pt").pixel_values # Verify that width and height can be divided by size_divisibility and that correct dimensions got merged - self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisibility == 0) - self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisibility == 0) + self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisor == 0) + self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisor == 0) self.assertTrue(encoded_images.shape[-3] == 4) def test_call_pil(self): @@ -198,8 +200,8 @@ def test_call_pil(self): encoded_images = image_processing(images=image, trimaps=trimap, return_tensors="pt").pixel_values # Verify that width and height can be divided by size_divisibility and that correct dimensions got merged - self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisibility == 0) - self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisibility == 0) + self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisor == 0) + self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisor == 0) self.assertTrue(encoded_images.shape[-3] == 4) def test_call_numpy_4_channels(self): @@ -224,8 +226,8 @@ def test_call_numpy_4_channels(self): ).pixel_values # Verify that width and height can be divided by size_divisibility and that correct dimensions got merged - self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisibility == 0) - self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisibility == 0) + self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisor == 0) + self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisor == 0) self.assertTrue(encoded_images.shape[-3] == 5) def test_padding_slow(self): From 5301d16e242fb9fc47ef52261e892b77db3b1b5a Mon Sep 17 00:00:00 2001 From: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:34:30 -0400 Subject: [PATCH 092/204] Remove nested import logic for torchvision (#40940) * remove nested import logic for torchvision * remove unnecessary protected imports * remove unnecessarry protected import in modular (and modeling) * fix wrongly remove protected imports --- .../image_processing_utils_fast.py | 10 +++---- src/transformers/models/aria/modeling_aria.py | 9 ++---- src/transformers/models/aria/modular_aria.py | 7 ++--- .../models/beit/image_processing_beit_fast.py | 9 ++---- .../image_processing_bridgetower_fast.py | 16 +++++------ .../image_processing_chameleon_fast.py | 28 ++++++------------- .../cohere2_vision/modular_cohere2_vision.py | 6 +--- .../models/colpali/modular_colpali.py | 1 - .../models/colqwen2/modular_colqwen2.py | 1 - .../image_processing_conditional_detr_fast.py | 26 ++++------------- .../modular_conditional_detr.py | 7 ++--- .../image_processing_convnext_fast.py | 16 ++++------- .../deepseek_vl/configuration_deepseek_vl.py | 4 +-- .../image_processing_deepseek_vl_fast.py | 11 ++------ .../deepseek_vl/modeling_deepseek_vl.py | 9 ++---- .../models/deepseek_vl/modular_deepseek_vl.py | 8 ++---- .../configuration_deepseek_vl_hybrid.py | 4 +-- ...mage_processing_deepseek_vl_hybrid_fast.py | 22 +++++++-------- .../modular_deepseek_vl_hybrid.py | 8 ++---- .../image_processing_deformable_detr_fast.py | 21 ++++---------- .../modular_deformable_detr.py | 7 ++--- .../image_processing_depth_pro_fast.py | 28 +++++++++---------- .../models/detr/image_processing_detr_fast.py | 21 ++++---------- .../image_processing_dinov3_vit_fast.py | 14 ++++------ .../donut/image_processing_donut_fast.py | 18 +++++------- .../models/dpt/image_processing_dpt_fast.py | 16 +++-------- src/transformers/models/dpt/modular_dpt.py | 9 ++---- .../image_processing_efficientloftr_fast.py | 12 ++------ .../image_processing_efficientnet_fast.py | 16 ++++------- .../models/eomt/image_processing_eomt_fast.py | 15 ++++------ .../flava/image_processing_flava_fast.py | 20 +++++-------- .../models/florence2/modeling_florence2.py | 5 ++-- .../models/florence2/modular_florence2.py | 13 ++------- .../models/florence2/processing_florence2.py | 1 - .../gemma3/image_processing_gemma3_fast.py | 22 +++++---------- .../glm4v/image_processing_glm4v_fast.py | 16 ++++------- .../image_processing_got_ocr2_fast.py | 16 ++++------- .../image_processing_grounding_dino_fast.py | 20 ++++--------- .../grounding_dino/modular_grounding_dino.py | 6 ++-- .../image_processing_imagegpt_fast.py | 15 ++++------ .../janus/image_processing_janus_fast.py | 8 ++---- .../models/janus/modeling_janus.py | 14 ++-------- .../models/janus/modular_janus.py | 16 +++-------- .../image_processing_kosmos2_5_fast.py | 8 ++---- .../image_processing_layoutlmv2_fast.py | 18 +++++------- .../image_processing_layoutlmv3_fast.py | 18 +++++------- .../levit/image_processing_levit_fast.py | 16 +++++------ .../llama4/image_processing_llama4_fast.py | 16 ++++------- .../llava/image_processing_llava_fast.py | 20 ++++--------- .../image_processing_llava_next_fast.py | 16 ++++------- .../modeling_llava_onevision.py | 6 +--- .../modular_llava_onevision.py | 11 +++----- .../image_processing_mask2former_fast.py | 21 ++++---------- .../models/mask2former/modular_mask2former.py | 9 ++---- .../image_processing_maskformer_fast.py | 22 ++++++--------- .../image_processing_mobilenet_v2_fast.py | 16 ++++------- .../image_processing_mobilevit_fast.py | 16 ++++------- .../nougat/image_processing_nougat_fast.py | 16 ++++------- .../image_processing_oneformer_fast.py | 20 ++++++------- .../ovis2/image_processing_ovis2_fast.py | 16 ++++------- .../owlv2/image_processing_owlv2_fast.py | 21 ++++---------- .../models/owlv2/modular_owlv2.py | 10 ++----- .../owlvit/image_processing_owlvit_fast.py | 11 +++----- .../image_processing_perceiver_fast.py | 16 ++++------- .../image_processing_perception_lm_fast.py | 16 ++--------- .../image_processing_phi4_multimodal_fast.py | 15 ++++------ .../pixtral/image_processing_pixtral_fast.py | 22 +++++---------- .../image_processing_poolformer_fast.py | 16 ++++------- ...e_processing_prompt_depth_anything_fast.py | 16 ++++------- .../image_processing_qwen2_vl_fast.py | 17 ++++------- .../rt_detr/image_processing_rt_detr_fast.py | 17 +++-------- .../models/rt_detr/modular_rt_detr.py | 10 ++----- .../models/sam/image_processing_sam_fast.py | 17 +++-------- .../models/sam2/image_processing_sam2_fast.py | 9 +----- src/transformers/models/sam2/modular_sam2.py | 6 ---- .../models/sam2_video/modular_sam2_video.py | 6 +--- .../image_processing_segformer_fast.py | 15 +++------- .../models/segformer/modular_segformer.py | 9 ++---- .../siglip2/image_processing_siglip2_fast.py | 15 +++------- .../smolvlm/video_processing_smolvlm.py | 4 +-- .../image_processing_superpoint_fast.py | 9 ++---- .../swin2sr/image_processing_swin2sr_fast.py | 18 +++++------- .../textnet/image_processing_textnet_fast.py | 16 ++++------- .../models/tvp/image_processing_tvp_fast.py | 22 +++++---------- .../models/vilt/image_processing_vilt_fast.py | 16 ++++------- .../image_processing_vitmatte_fast.py | 17 ++++------- .../yolos/image_processing_yolos_fast.py | 21 ++++---------- .../models/yolos/modular_yolos.py | 7 ++--- .../image_processing_zoedepth_fast.py | 21 +++++--------- src/transformers/video_processing_utils.py | 10 +++---- 90 files changed, 403 insertions(+), 838 deletions(-) diff --git a/src/transformers/image_processing_utils_fast.py b/src/transformers/image_processing_utils_fast.py index 4028c38ff227..983fd4e16953 100644 --- a/src/transformers/image_processing_utils_fast.py +++ b/src/transformers/image_processing_utils_fast.py @@ -61,14 +61,14 @@ if is_torchvision_available(): from .image_utils import pil_torch_interpolation_mapping - - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F else: pil_torch_interpolation_mapping = None +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +elif is_torchvision_available(): + from torchvision.transforms import functional as F + logger = logging.get_logger(__name__) diff --git a/src/transformers/models/aria/modeling_aria.py b/src/transformers/models/aria/modeling_aria.py index f3261909dd03..7303ca2e9c50 100644 --- a/src/transformers/models/aria/modeling_aria.py +++ b/src/transformers/models/aria/modeling_aria.py @@ -21,6 +21,9 @@ from dataclasses import dataclass from typing import Callable, Optional, Union +import torch +from torch import nn + from ...activations import ACT2FN from ...cache_utils import Cache, DynamicCache from ...generation import GenerationMixin @@ -35,16 +38,10 @@ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple from ...utils.deprecation import deprecate_kwarg from ...utils.generic import check_model_inputs -from ...utils.import_utils import is_torch_available from ..auto import AutoModel from .configuration_aria import AriaConfig, AriaTextConfig -if is_torch_available(): - import torch - from torch import nn - - @use_kernel_forward_from_hub("RMSNorm") class AriaTextRMSNorm(nn.Module): def __init__(self, hidden_size, eps=1e-6): diff --git a/src/transformers/models/aria/modular_aria.py b/src/transformers/models/aria/modular_aria.py index 790003d853c4..a626d2cd4b82 100644 --- a/src/transformers/models/aria/modular_aria.py +++ b/src/transformers/models/aria/modular_aria.py @@ -16,6 +16,8 @@ from typing import Optional, Union import numpy as np +import torch +from torch import nn from ...activations import ACT2FN from ...cache_utils import Cache @@ -39,7 +41,6 @@ from ...processing_utils import MultiModalData, ProcessingKwargs, ProcessorMixin, Unpack from ...tokenization_utils import PreTokenizedInput, TextInput from ...utils import TensorType, TransformersKwargs, auto_docstring, can_return_tuple, logging -from ...utils.import_utils import is_torch_available from ..auto import CONFIG_MAPPING, AutoConfig, AutoTokenizer from ..llama.configuration_llama import LlamaConfig from ..llama.modeling_llama import ( @@ -62,10 +63,6 @@ logger = logging.get_logger(__name__) -if is_torch_available(): - import torch - from torch import nn - def sequential_experts_gemm(token_states, expert_weights, tokens_per_expert): """ diff --git a/src/transformers/models/beit/image_processing_beit_fast.py b/src/transformers/models/beit/image_processing_beit_fast.py index 43ed6dd1125d..e10dc552cf37 100644 --- a/src/transformers/models/beit/image_processing_beit_fast.py +++ b/src/transformers/models/beit/image_processing_beit_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -36,18 +38,13 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/bridgetower/image_processing_bridgetower_fast.py b/src/transformers/models/bridgetower/image_processing_bridgetower_fast.py index 4a7450c84498..44da5d4486e7 100644 --- a/src/transformers/models/bridgetower/image_processing_bridgetower_fast.py +++ b/src/transformers/models/bridgetower/image_processing_bridgetower_fast.py @@ -17,6 +17,8 @@ from collections.abc import Iterable from typing import Optional, Union +import torch + from ...image_processing_utils_fast import ( BaseImageProcessorFast, BatchFeature, @@ -29,17 +31,13 @@ reorder_images, ) from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling -from ...utils import auto_docstring, is_torch_available, is_torchvision_available, is_torchvision_v2_available - +from ...utils import auto_docstring, is_torchvision_v2_available -if is_torch_available(): - import torch -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F def make_pixel_mask( diff --git a/src/transformers/models/chameleon/image_processing_chameleon_fast.py b/src/transformers/models/chameleon/image_processing_chameleon_fast.py index 421c4ea98374..39aa4ec87b00 100644 --- a/src/transformers/models/chameleon/image_processing_chameleon_fast.py +++ b/src/transformers/models/chameleon/image_processing_chameleon_fast.py @@ -17,28 +17,18 @@ from typing import Optional import numpy as np +import PIL +import torch from ...image_processing_utils_fast import BaseImageProcessorFast from ...image_utils import ImageInput, PILImageResampling, SizeDict -from ...utils import ( - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - is_vision_available, - logging, -) - - -if is_vision_available(): - import PIL -if is_torch_available(): - import torch -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +from ...utils import auto_docstring, is_torchvision_v2_available, logging + + +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F logger = logging.get_logger(__name__) diff --git a/src/transformers/models/cohere2_vision/modular_cohere2_vision.py b/src/transformers/models/cohere2_vision/modular_cohere2_vision.py index 36f5d0b71ce0..7ef20305b99e 100644 --- a/src/transformers/models/cohere2_vision/modular_cohere2_vision.py +++ b/src/transformers/models/cohere2_vision/modular_cohere2_vision.py @@ -32,11 +32,7 @@ from ...cache_utils import Cache from ...modeling_flash_attention_utils import FlashAttentionKwargs from ...processing_utils import Unpack -from ...utils import ( - TransformersKwargs, - auto_docstring, - logging, -) +from ...utils import TransformersKwargs, auto_docstring, logging from ...utils.generic import check_model_inputs from .configuration_cohere2_vision import Cohere2VisionConfig diff --git a/src/transformers/models/colpali/modular_colpali.py b/src/transformers/models/colpali/modular_colpali.py index 0988b0f7aafb..cf28475f4b3c 100644 --- a/src/transformers/models/colpali/modular_colpali.py +++ b/src/transformers/models/colpali/modular_colpali.py @@ -28,7 +28,6 @@ if is_torch_available(): import torch - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/colqwen2/modular_colqwen2.py b/src/transformers/models/colqwen2/modular_colqwen2.py index a4684d670d17..f3ae79abf6fa 100644 --- a/src/transformers/models/colqwen2/modular_colqwen2.py +++ b/src/transformers/models/colqwen2/modular_colqwen2.py @@ -30,7 +30,6 @@ if is_torch_available(): import torch - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/conditional_detr/image_processing_conditional_detr_fast.py b/src/transformers/models/conditional_detr/image_processing_conditional_detr_fast.py index 86e51f2b4a60..5b9fe6325517 100644 --- a/src/transformers/models/conditional_detr/image_processing_conditional_detr_fast.py +++ b/src/transformers/models/conditional_detr/image_processing_conditional_detr_fast.py @@ -7,6 +7,10 @@ import pathlib from typing import Any, Optional, Union +import torch +from torch import nn +from torchvision.io import read_image + from ...image_processing_utils import BatchFeature, get_size_dict from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -29,14 +33,7 @@ validate_annotations, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - logging, -) +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available, logging from ...utils.import_utils import requires from .image_processing_conditional_detr import ( compute_segments, @@ -46,20 +43,9 @@ ) -if is_torch_available(): - import torch - - -if is_torch_available(): - from torch import nn - - if is_torchvision_v2_available(): - from torchvision.io import read_image from torchvision.transforms.v2 import functional as F - -elif is_torchvision_available(): - from torchvision.io import read_image +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/conditional_detr/modular_conditional_detr.py b/src/transformers/models/conditional_detr/modular_conditional_detr.py index 176ae8b6604b..9d0faf2c4b9e 100644 --- a/src/transformers/models/conditional_detr/modular_conditional_detr.py +++ b/src/transformers/models/conditional_detr/modular_conditional_detr.py @@ -1,5 +1,7 @@ from typing import Union +import torch + from transformers.models.detr.image_processing_detr_fast import DetrImageProcessorFast from ...image_transforms import ( @@ -7,15 +9,10 @@ ) from ...utils import ( TensorType, - is_torch_available, logging, ) -if is_torch_available(): - import torch - - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/convnext/image_processing_convnext_fast.py b/src/transformers/models/convnext/image_processing_convnext_fast.py index 0866b230a52e..a1002d950399 100644 --- a/src/transformers/models/convnext/image_processing_convnext_fast.py +++ b/src/transformers/models/convnext/image_processing_convnext_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -35,20 +37,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class ConvNextFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/deepseek_vl/configuration_deepseek_vl.py b/src/transformers/models/deepseek_vl/configuration_deepseek_vl.py index a6c35f6be0d5..b3abae5af0a7 100644 --- a/src/transformers/models/deepseek_vl/configuration_deepseek_vl.py +++ b/src/transformers/models/deepseek_vl/configuration_deepseek_vl.py @@ -21,9 +21,7 @@ from typing import Optional from ...configuration_utils import PretrainedConfig -from ...utils import ( - logging, -) +from ...utils import logging from ..auto import CONFIG_MAPPING, AutoConfig diff --git a/src/transformers/models/deepseek_vl/image_processing_deepseek_vl_fast.py b/src/transformers/models/deepseek_vl/image_processing_deepseek_vl_fast.py index 7764a8250159..896e91f0692c 100644 --- a/src/transformers/models/deepseek_vl/image_processing_deepseek_vl_fast.py +++ b/src/transformers/models/deepseek_vl/image_processing_deepseek_vl_fast.py @@ -20,6 +20,7 @@ from typing import Optional, Union +import torch import torch.nn.functional as F from ...image_processing_utils import BatchFeature @@ -31,15 +32,7 @@ ) from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling, SizeDict from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, -) - - -if is_torch_available(): - import torch +from ...utils import TensorType, auto_docstring class DeepseekVLFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/deepseek_vl/modeling_deepseek_vl.py b/src/transformers/models/deepseek_vl/modeling_deepseek_vl.py index 039602a159f2..22d8e0928a6e 100644 --- a/src/transformers/models/deepseek_vl/modeling_deepseek_vl.py +++ b/src/transformers/models/deepseek_vl/modeling_deepseek_vl.py @@ -21,6 +21,9 @@ from dataclasses import dataclass from typing import Optional, Union +import torch +import torch.nn as nn + from ...cache_utils import Cache from ...generation import GenerationMixin from ...modeling_outputs import ModelOutput @@ -30,17 +33,11 @@ TransformersKwargs, auto_docstring, can_return_tuple, - is_torch_available, ) from ..auto import AutoModel from .configuration_deepseek_vl import DeepseekVLConfig -if is_torch_available(): - import torch - import torch.nn as nn - - @dataclass @auto_docstring( custom_intro=""" diff --git a/src/transformers/models/deepseek_vl/modular_deepseek_vl.py b/src/transformers/models/deepseek_vl/modular_deepseek_vl.py index 33f1cf26bb65..5bfc0ae7d74c 100644 --- a/src/transformers/models/deepseek_vl/modular_deepseek_vl.py +++ b/src/transformers/models/deepseek_vl/modular_deepseek_vl.py @@ -14,6 +14,9 @@ from typing import Optional, Union +import torch +import torch.nn as nn + from ...configuration_utils import PretrainedConfig from ...image_processing_utils import BatchFeature from ...image_utils import ImageInput @@ -24,7 +27,6 @@ ) from ...utils import ( auto_docstring, - is_torch_available, logging, ) from ..auto import CONFIG_MAPPING, AutoConfig, AutoModel @@ -34,10 +36,6 @@ from ..janus.modeling_janus import JanusForConditionalGeneration, JanusModel, JanusPreTrainedModel -if is_torch_available(): - import torch - import torch.nn as nn - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/deepseek_vl_hybrid/configuration_deepseek_vl_hybrid.py b/src/transformers/models/deepseek_vl_hybrid/configuration_deepseek_vl_hybrid.py index 9fd82dbfefdf..e8c6e2df6ea3 100644 --- a/src/transformers/models/deepseek_vl_hybrid/configuration_deepseek_vl_hybrid.py +++ b/src/transformers/models/deepseek_vl_hybrid/configuration_deepseek_vl_hybrid.py @@ -21,9 +21,7 @@ from typing import Optional from ...configuration_utils import PretrainedConfig -from ...utils import ( - logging, -) +from ...utils import logging from ..auto import CONFIG_MAPPING, AutoConfig diff --git a/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid_fast.py b/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid_fast.py index 3770cf18303e..db9c9ad987c1 100644 --- a/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid_fast.py +++ b/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid_fast.py @@ -30,25 +30,23 @@ group_images_by_shape, reorder_images, ) -from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, ChannelDimension, PILImageResampling, SizeDict -from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torchvision_available, - is_torchvision_v2_available, +from ...image_utils import ( + OPENAI_CLIP_MEAN, + OPENAI_CLIP_STD, + ChannelDimension, + PILImageResampling, + SizeDict, + pil_torch_interpolation_mapping, ) +from ...processing_utils import Unpack +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F - - from ...image_utils import pil_torch_interpolation_mapping -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F - from ...image_utils import pil_torch_interpolation_mapping - class DeepseekVLHybridFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): r""" diff --git a/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py b/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py index c6cf71b09613..d97b00f7fbd2 100644 --- a/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py +++ b/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py @@ -37,6 +37,7 @@ infer_channel_dimension_format, is_scaled_image, make_flat_list_of_images, + pil_torch_interpolation_mapping, to_numpy_array, valid_images, validate_preprocess_arguments, @@ -52,7 +53,6 @@ auto_docstring, can_return_tuple, filter_out_non_signature_kwargs, - is_torchvision_available, is_torchvision_v2_available, logging, ) @@ -72,13 +72,9 @@ if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F - - from ...image_utils import pil_torch_interpolation_mapping -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F - from ...image_utils import pil_torch_interpolation_mapping - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/deformable_detr/image_processing_deformable_detr_fast.py b/src/transformers/models/deformable_detr/image_processing_deformable_detr_fast.py index 2bfbedddc5d0..cd07f8db350b 100644 --- a/src/transformers/models/deformable_detr/image_processing_deformable_detr_fast.py +++ b/src/transformers/models/deformable_detr/image_processing_deformable_detr_fast.py @@ -7,6 +7,9 @@ import pathlib from typing import Any, Optional, Union +import torch +from torchvision.io import read_image + from ...image_processing_utils import BatchFeature, get_size_dict from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -29,28 +32,14 @@ validate_annotations, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - logging, -) +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available, logging from ...utils.import_utils import requires from .image_processing_deformable_detr import get_size_with_aspect_ratio -if is_torch_available(): - import torch - - if is_torchvision_v2_available(): - from torchvision.io import read_image from torchvision.transforms.v2 import functional as F - -elif is_torchvision_available(): - from torchvision.io import read_image +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/deformable_detr/modular_deformable_detr.py b/src/transformers/models/deformable_detr/modular_deformable_detr.py index 57aa52e364b6..2e38df7845a2 100644 --- a/src/transformers/models/deformable_detr/modular_deformable_detr.py +++ b/src/transformers/models/deformable_detr/modular_deformable_detr.py @@ -1,19 +1,16 @@ from typing import Union +import torch + from transformers.models.detr.image_processing_detr_fast import DetrImageProcessorFast from ...image_transforms import center_to_corners_format from ...utils import ( TensorType, - is_torch_available, logging, ) -if is_torch_available(): - import torch - - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/depth_pro/image_processing_depth_pro_fast.py b/src/transformers/models/depth_pro/image_processing_depth_pro_fast.py index d27220c3d2be..76c1a53e0073 100644 --- a/src/transformers/models/depth_pro/image_processing_depth_pro_fast.py +++ b/src/transformers/models/depth_pro/image_processing_depth_pro_fast.py @@ -16,14 +16,20 @@ from typing import TYPE_CHECKING, Optional, Union +import torch + from ...image_processing_base import BatchFeature from ...image_processing_utils_fast import BaseImageProcessorFast, group_images_by_shape, reorder_images -from ...image_utils import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD, PILImageResampling, SizeDict +from ...image_utils import ( + IMAGENET_STANDARD_MEAN, + IMAGENET_STANDARD_STD, + PILImageResampling, + SizeDict, + pil_torch_interpolation_mapping, +) from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, requires_backends, @@ -34,20 +40,14 @@ if TYPE_CHECKING: from .modeling_depth_pro import DepthProDepthEstimatorOutput -logger = logging.get_logger(__name__) - - -if is_torch_available(): - import torch +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F -if is_torchvision_available(): - from ...image_utils import pil_torch_interpolation_mapping - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +logger = logging.get_logger(__name__) @auto_docstring diff --git a/src/transformers/models/detr/image_processing_detr_fast.py b/src/transformers/models/detr/image_processing_detr_fast.py index ba216a6f2d49..96a89a98074c 100644 --- a/src/transformers/models/detr/image_processing_detr_fast.py +++ b/src/transformers/models/detr/image_processing_detr_fast.py @@ -19,6 +19,11 @@ from collections import defaultdict from typing import Any, Optional, Union +import PIL +import torch +from torch import nn +from torchvision.io import read_image + from ...image_processing_utils import BatchFeature, get_size_dict from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -44,10 +49,7 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, - is_vision_available, logging, ) from ...utils.import_utils import requires @@ -59,20 +61,9 @@ ) -if is_torch_available(): - import torch - from torch import nn - -if is_vision_available(): - import PIL - - if is_torchvision_v2_available(): - from torchvision.io import read_image from torchvision.transforms.v2 import functional as F - -elif is_torchvision_available(): - from torchvision.io import read_image +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/dinov3_vit/image_processing_dinov3_vit_fast.py b/src/transformers/models/dinov3_vit/image_processing_dinov3_vit_fast.py index fba0d3089438..cdb68044bfc4 100644 --- a/src/transformers/models/dinov3_vit/image_processing_dinov3_vit_fast.py +++ b/src/transformers/models/dinov3_vit/image_processing_dinov3_vit_fast.py @@ -16,31 +16,27 @@ from typing import Optional, Union +import torch + from transformers.image_processing_base import BatchFeature from transformers.image_processing_utils_fast import BaseImageProcessorFast, group_images_by_shape, reorder_images from transformers.image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD, PILImageResampling, SizeDict from transformers.utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, ) from transformers.utils.import_utils import requires -logger = logging.get_logger(__name__) - - -if is_torch_available(): - import torch - if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F +logger = logging.get_logger(__name__) + @auto_docstring @requires(backends=("torchvision", "torch")) diff --git a/src/transformers/models/donut/image_processing_donut_fast.py b/src/transformers/models/donut/image_processing_donut_fast.py index 23714affe1e8..7c808ab60cd4 100644 --- a/src/transformers/models/donut/image_processing_donut_fast.py +++ b/src/transformers/models/donut/image_processing_donut_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils_fast import BaseImageProcessorFast, BatchFeature, DefaultFastImageProcessorKwargs from ...image_transforms import group_images_by_shape, reorder_images from ...image_utils import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD, ImageInput, PILImageResampling, SizeDict @@ -23,23 +25,17 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, ) -logger = logging.get_logger(__name__) - -if is_torch_available(): - import torch +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +logger = logging.get_logger(__name__) class DonutFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/dpt/image_processing_dpt_fast.py b/src/transformers/models/dpt/image_processing_dpt_fast.py index 7fce8a9f64db..d4848c50653c 100644 --- a/src/transformers/models/dpt/image_processing_dpt_fast.py +++ b/src/transformers/models/dpt/image_processing_dpt_fast.py @@ -24,6 +24,8 @@ from collections.abc import Iterable from typing import TYPE_CHECKING, Optional, Union +import torch + from ...image_processing_base import BatchFeature from ...image_processing_utils_fast import BaseImageProcessorFast, DefaultFastImageProcessorKwargs from ...image_transforms import group_images_by_shape, reorder_images @@ -37,25 +39,15 @@ is_torch_tensor, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - requires_backends, -) +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available, requires_backends if TYPE_CHECKING: from ...modeling_outputs import DepthEstimatorOutput -if is_torch_available(): - import torch - if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/dpt/modular_dpt.py b/src/transformers/models/dpt/modular_dpt.py index 7ae6bb40c3af..32ca94a2d43f 100644 --- a/src/transformers/models/dpt/modular_dpt.py +++ b/src/transformers/models/dpt/modular_dpt.py @@ -18,6 +18,8 @@ from collections.abc import Iterable from typing import TYPE_CHECKING, Optional, Union +import torch + from ...image_processing_base import BatchFeature from ...image_processing_utils_fast import BaseImageProcessorFast, DefaultFastImageProcessorKwargs from ...image_transforms import group_images_by_shape, reorder_images @@ -30,8 +32,6 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, requires_backends, ) @@ -41,12 +41,9 @@ if TYPE_CHECKING: from ...modeling_outputs import DepthEstimatorOutput -if is_torch_available(): - import torch - if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/efficientloftr/image_processing_efficientloftr_fast.py b/src/transformers/models/efficientloftr/image_processing_efficientloftr_fast.py index 5eb6e6589058..5f7437c45b2e 100644 --- a/src/transformers/models/efficientloftr/image_processing_efficientloftr_fast.py +++ b/src/transformers/models/efficientloftr/image_processing_efficientloftr_fast.py @@ -17,6 +17,7 @@ from typing import TYPE_CHECKING, Optional, Union import torch +from PIL import Image, ImageDraw from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( @@ -38,27 +39,18 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, - is_vision_available, ) -if is_torch_available(): - import torch - if TYPE_CHECKING: from .modeling_efficientloftr import KeypointMatchingOutput if is_torchvision_v2_available(): import torchvision.transforms.v2.functional as F -elif is_torchvision_available(): +else: import torchvision.transforms.functional as F -if is_vision_available(): - from PIL import Image, ImageDraw - def _is_valid_image(image): return is_pil_image(image) or ( diff --git a/src/transformers/models/efficientnet/image_processing_efficientnet_fast.py b/src/transformers/models/efficientnet/image_processing_efficientnet_fast.py index 41689e3dc080..3544d927c146 100644 --- a/src/transformers/models/efficientnet/image_processing_efficientnet_fast.py +++ b/src/transformers/models/efficientnet/image_processing_efficientnet_fast.py @@ -17,6 +17,8 @@ from functools import lru_cache from typing import Optional, Union +import torch + from ...image_processing_utils_fast import BaseImageProcessorFast, BatchFeature, DefaultFastImageProcessorKwargs from ...image_transforms import group_images_by_shape, reorder_images from ...image_utils import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD, ImageInput, PILImageResampling, SizeDict @@ -24,20 +26,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class EfficientNetFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/eomt/image_processing_eomt_fast.py b/src/transformers/models/eomt/image_processing_eomt_fast.py index 58457064412d..97a13a0745eb 100644 --- a/src/transformers/models/eomt/image_processing_eomt_fast.py +++ b/src/transformers/models/eomt/image_processing_eomt_fast.py @@ -18,6 +18,7 @@ from typing import Optional, Union import numpy as np +import torch from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( @@ -39,8 +40,6 @@ TensorType, auto_docstring, filter_out_non_signature_kwargs, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) from .image_processing_eomt import ( @@ -51,14 +50,10 @@ ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class EomtImageProcessorFastKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/flava/image_processing_flava_fast.py b/src/transformers/models/flava/image_processing_flava_fast.py index 5dcc5326d968..97409ddd57ed 100644 --- a/src/transformers/models/flava/image_processing_flava_fast.py +++ b/src/transformers/models/flava/image_processing_flava_fast.py @@ -20,6 +20,8 @@ from functools import lru_cache from typing import Any, Optional, Union +import torch + from ...image_processing_utils_fast import ( BaseImageProcessorFast, BatchFeature, @@ -27,13 +29,11 @@ get_size_dict, ) from ...image_transforms import ChannelDimension, group_images_by_shape, reorder_images -from ...image_utils import ImageInput, PILImageResampling, SizeDict +from ...image_utils import ImageInput, PILImageResampling, SizeDict, pil_torch_interpolation_mapping from ...processing_utils import Unpack from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) from .image_processing_flava import ( @@ -45,16 +45,10 @@ ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - from ...image_utils import pil_torch_interpolation_mapping - - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class FlavaMaskingGenerator: diff --git a/src/transformers/models/florence2/modeling_florence2.py b/src/transformers/models/florence2/modeling_florence2.py index 0c1cf26fa4bc..763756faf73f 100644 --- a/src/transformers/models/florence2/modeling_florence2.py +++ b/src/transformers/models/florence2/modeling_florence2.py @@ -22,6 +22,9 @@ from dataclasses import dataclass from typing import Any, Callable, Optional, Union +import torch.nn as nn +import torch.nn.functional as F + from ...activations import ACT2FN from ...cache_utils import Cache from ...generation import GenerationMixin @@ -41,8 +44,6 @@ if is_torch_available(): import torch - import torch.nn as nn - import torch.nn.functional as F logger = logging.get_logger(__name__) diff --git a/src/transformers/models/florence2/modular_florence2.py b/src/transformers/models/florence2/modular_florence2.py index d82d9ac5255e..f8732257f102 100644 --- a/src/transformers/models/florence2/modular_florence2.py +++ b/src/transformers/models/florence2/modular_florence2.py @@ -18,6 +18,8 @@ from typing import Any, Callable, Optional, Union import numpy as np +import torch.nn as nn +import torch.nn.functional as F from ...activations import ACT2FN from ...cache_utils import Cache @@ -28,13 +30,7 @@ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import MultiModalData, ProcessorMixin, Unpack from ...tokenization_utils_base import PreTokenizedInput, TextInput -from ...utils import ( - TransformersKwargs, - auto_docstring, - can_return_tuple, - is_torch_available, - logging, -) +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, is_torch_available, logging from ..auto import CONFIG_MAPPING, AutoConfig from ..bart.modeling_bart import eager_attention_forward, shift_tokens_right from ..beit.modeling_beit import BeitDropPath @@ -45,9 +41,6 @@ if is_torch_available(): import torch - import torch.nn as nn - import torch.nn.functional as F - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/florence2/processing_florence2.py b/src/transformers/models/florence2/processing_florence2.py index 53e3d562aa29..91b63e9da7db 100644 --- a/src/transformers/models/florence2/processing_florence2.py +++ b/src/transformers/models/florence2/processing_florence2.py @@ -33,7 +33,6 @@ if is_torch_available(): import torch - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/gemma3/image_processing_gemma3_fast.py b/src/transformers/models/gemma3/image_processing_gemma3_fast.py index 3826f40bd997..eb828a89643d 100644 --- a/src/transformers/models/gemma3/image_processing_gemma3_fast.py +++ b/src/transformers/models/gemma3/image_processing_gemma3_fast.py @@ -18,6 +18,8 @@ import math from typing import Optional, Union +import torch + from ...image_processing_utils_fast import ( BaseImageProcessorFast, BatchFeature, @@ -25,30 +27,20 @@ group_images_by_shape, reorder_images, ) -from ...image_utils import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD, ImageInput, SizeDict +from ...image_utils import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD, ImageInput, PILImageResampling, SizeDict from ...processing_utils import Unpack from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, - is_vision_available, logging, ) -if is_vision_available(): - from ...image_utils import PILImageResampling - -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F logger = logging.get_logger(__name__) diff --git a/src/transformers/models/glm4v/image_processing_glm4v_fast.py b/src/transformers/models/glm4v/image_processing_glm4v_fast.py index 061654519d21..fbf4aebaac6a 100644 --- a/src/transformers/models/glm4v/image_processing_glm4v_fast.py +++ b/src/transformers/models/glm4v/image_processing_glm4v_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import ( BatchFeature, ) @@ -36,22 +38,16 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, ) from .image_processing_glm4v import smart_resize -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F logger = logging.get_logger(__name__) diff --git a/src/transformers/models/got_ocr2/image_processing_got_ocr2_fast.py b/src/transformers/models/got_ocr2/image_processing_got_ocr2_fast.py index 38b87aed623f..5277f1c4e13b 100644 --- a/src/transformers/models/got_ocr2/image_processing_got_ocr2_fast.py +++ b/src/transformers/models/got_ocr2/image_processing_got_ocr2_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -28,21 +30,15 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) from .image_processing_got_ocr2 import get_optimal_tiled_canvas -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class GotOcr2FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/grounding_dino/image_processing_grounding_dino_fast.py b/src/transformers/models/grounding_dino/image_processing_grounding_dino_fast.py index 59866c9a410e..66528519eef8 100644 --- a/src/transformers/models/grounding_dino/image_processing_grounding_dino_fast.py +++ b/src/transformers/models/grounding_dino/image_processing_grounding_dino_fast.py @@ -7,6 +7,9 @@ import pathlib from typing import TYPE_CHECKING, Any, Optional, Union +import torch +from torchvision.io import read_image + from ...image_processing_utils import BatchFeature, get_size_dict from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -29,14 +32,7 @@ validate_annotations, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - logging, -) +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available, logging from ...utils.import_utils import requires from .image_processing_grounding_dino import get_size_with_aspect_ratio @@ -44,16 +40,10 @@ if TYPE_CHECKING: from .modeling_grounding_dino import GroundingDinoObjectDetectionOutput -if is_torch_available(): - import torch - if is_torchvision_v2_available(): - from torchvision.io import read_image from torchvision.transforms.v2 import functional as F - -elif is_torchvision_available(): - from torchvision.io import read_image +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/grounding_dino/modular_grounding_dino.py b/src/transformers/models/grounding_dino/modular_grounding_dino.py index f066f762cfa3..a7b9c570e7b0 100644 --- a/src/transformers/models/grounding_dino/modular_grounding_dino.py +++ b/src/transformers/models/grounding_dino/modular_grounding_dino.py @@ -1,11 +1,12 @@ from typing import TYPE_CHECKING, Optional, Union +import torch + from transformers.models.detr.image_processing_detr_fast import DetrImageProcessorFast from ...image_transforms import center_to_corners_format from ...utils import ( TensorType, - is_torch_available, logging, ) @@ -13,9 +14,6 @@ if TYPE_CHECKING: from .modeling_grounding_dino import GroundingDinoObjectDetectionOutput -if is_torch_available(): - import torch - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/imagegpt/image_processing_imagegpt_fast.py b/src/transformers/models/imagegpt/image_processing_imagegpt_fast.py index 736666fd28a0..ddfee7c757fe 100644 --- a/src/transformers/models/imagegpt/image_processing_imagegpt_fast.py +++ b/src/transformers/models/imagegpt/image_processing_imagegpt_fast.py @@ -17,6 +17,7 @@ from typing import Optional, Union import numpy as np +import torch from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( @@ -29,20 +30,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F def squared_euclidean_distance_torch(a: torch.Tensor, b: torch.Tensor) -> torch.Tensor: diff --git a/src/transformers/models/janus/image_processing_janus_fast.py b/src/transformers/models/janus/image_processing_janus_fast.py index 3e9483f21bfe..9ed2732fb3d0 100644 --- a/src/transformers/models/janus/image_processing_janus_fast.py +++ b/src/transformers/models/janus/image_processing_janus_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -34,17 +36,13 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/janus/modeling_janus.py b/src/transformers/models/janus/modeling_janus.py index eee387664832..94e1c6288bd3 100644 --- a/src/transformers/models/janus/modeling_janus.py +++ b/src/transformers/models/janus/modeling_janus.py @@ -24,6 +24,7 @@ from typing import Callable, Optional, Union import torch +import torch.nn.functional as F from torch import nn from ...activations import ACT2FN @@ -34,23 +35,12 @@ from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, ModelOutput from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import Unpack -from ...utils import ( - TransformersKwargs, - auto_docstring, - can_return_tuple, - is_torch_available, - logging, - torch_int, -) +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging, torch_int from ...utils.generic import check_model_inputs from ..auto import AutoModel from .configuration_janus import JanusConfig, JanusVisionConfig, JanusVQVAEConfig -if is_torch_available(): - import torch.nn.functional as F - - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/janus/modular_janus.py b/src/transformers/models/janus/modular_janus.py index 0541854200a5..dcd5c1e1e730 100644 --- a/src/transformers/models/janus/modular_janus.py +++ b/src/transformers/models/janus/modular_janus.py @@ -20,12 +20,15 @@ import numpy as np import torch +import torch.nn.functional as F +import torch.utils.checkpoint from torch import nn from transformers.models.blip.image_processing_blip import BlipImageProcessor from ...activations import ACT2FN from ...cache_utils import Cache +from ...configuration_utils import PretrainedConfig from ...generation import ClassifierFreeGuidanceLogitsProcessor, GenerationMixin, GenerationMode, LogitsProcessorList from ...generation.utils import GenerateDecoderOnlyOutput from ...image_processing_utils import BatchFeature, get_size_dict @@ -51,11 +54,10 @@ auto_docstring, can_return_tuple, filter_out_non_signature_kwargs, - is_torch_available, is_vision_available, logging, ) -from ..auto import AutoModel +from ..auto import CONFIG_MAPPING, AutoConfig, AutoModel from ..blip_2.modeling_blip_2 import Blip2VisionModel from ..chameleon.configuration_chameleon import ChameleonVQVAEConfig from ..chameleon.modeling_chameleon import ( @@ -71,19 +73,9 @@ from ..siglip.modeling_siglip import SiglipEncoder, SiglipEncoderLayer, SiglipVisionEmbeddings -if is_torch_available(): - import torch - import torch.nn as nn - import torch.nn.functional as F - - if is_vision_available(): import PIL -from ...configuration_utils import PretrainedConfig -from ..auto import CONFIG_MAPPING, AutoConfig - - logger = logging.get_logger(__name__) # General docstring diff --git a/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py b/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py index 7b9613ed0074..c6d8b1b1edf5 100644 --- a/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py +++ b/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py @@ -17,6 +17,8 @@ import math from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -26,11 +28,7 @@ ) from ...image_utils import ChannelDimension, ImageInput, get_image_size from ...processing_utils import Unpack -from ...utils import TensorType, auto_docstring, is_torch_available - - -if is_torch_available(): - import torch +from ...utils import TensorType, auto_docstring # Similar to transformers.models.pix2struct.image_processing_pix2struct.torch_extract_patches but dealing with a batch of images directly. diff --git a/src/transformers/models/layoutlmv2/image_processing_layoutlmv2_fast.py b/src/transformers/models/layoutlmv2/image_processing_layoutlmv2_fast.py index c22612da5858..723687d58219 100644 --- a/src/transformers/models/layoutlmv2/image_processing_layoutlmv2_fast.py +++ b/src/transformers/models/layoutlmv2/image_processing_layoutlmv2_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils_fast import BaseImageProcessorFast, BatchFeature, DefaultFastImageProcessorKwargs from ...image_transforms import ChannelDimension, group_images_by_shape, reorder_images from ...image_utils import ImageInput, PILImageResampling, SizeDict @@ -23,8 +25,6 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, requires_backends, @@ -32,16 +32,12 @@ from .image_processing_layoutlmv2 import apply_tesseract -logger = logging.get_logger(__name__) - -if is_torch_available(): - import torch +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +logger = logging.get_logger(__name__) class LayoutLMv2FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/layoutlmv3/image_processing_layoutlmv3_fast.py b/src/transformers/models/layoutlmv3/image_processing_layoutlmv3_fast.py index c7580bb528da..2ab8f8dd48cc 100644 --- a/src/transformers/models/layoutlmv3/image_processing_layoutlmv3_fast.py +++ b/src/transformers/models/layoutlmv3/image_processing_layoutlmv3_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils_fast import BaseImageProcessorFast, BatchFeature, DefaultFastImageProcessorKwargs from ...image_transforms import ChannelDimension, group_images_by_shape, reorder_images from ...image_utils import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD, ImageInput, PILImageResampling, SizeDict @@ -23,8 +25,6 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, requires_backends, @@ -32,16 +32,12 @@ from .image_processing_layoutlmv3 import apply_tesseract -logger = logging.get_logger(__name__) - -if is_torch_available(): - import torch +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +logger = logging.get_logger(__name__) class LayoutLMv3FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/levit/image_processing_levit_fast.py b/src/transformers/models/levit/image_processing_levit_fast.py index 096c846234da..e452894d6e2e 100644 --- a/src/transformers/models/levit/image_processing_levit_fast.py +++ b/src/transformers/models/levit/image_processing_levit_fast.py @@ -16,23 +16,21 @@ from typing import Optional +import torch + from ...image_processing_utils_fast import BaseImageProcessorFast, SizeDict from ...image_transforms import ( ChannelDimension, get_resize_output_image_size, ) from ...image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD, PILImageResampling -from ...utils import auto_docstring, is_torch_available, is_torchvision_available, is_torchvision_v2_available - +from ...utils import auto_docstring, is_torchvision_v2_available -if is_torch_available(): - import torch -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F @auto_docstring diff --git a/src/transformers/models/llama4/image_processing_llama4_fast.py b/src/transformers/models/llama4/image_processing_llama4_fast.py index fcb1555dd316..946fdde0a643 100644 --- a/src/transformers/models/llama4/image_processing_llama4_fast.py +++ b/src/transformers/models/llama4/image_processing_llama4_fast.py @@ -19,6 +19,8 @@ from functools import lru_cache from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -31,20 +33,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F def get_factors(dividend: int) -> set[int]: diff --git a/src/transformers/models/llava/image_processing_llava_fast.py b/src/transformers/models/llava/image_processing_llava_fast.py index cf62f250bc2f..41bb94f5b7e0 100644 --- a/src/transformers/models/llava/image_processing_llava_fast.py +++ b/src/transformers/models/llava/image_processing_llava_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -36,24 +38,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, - is_vision_available, ) -if is_vision_available(): - from ...image_utils import PILImageResampling - -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class LlavaFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): ... diff --git a/src/transformers/models/llava_next/image_processing_llava_next_fast.py b/src/transformers/models/llava_next/image_processing_llava_next_fast.py index 201a65260589..b502d98d6ac3 100644 --- a/src/transformers/models/llava_next/image_processing_llava_next_fast.py +++ b/src/transformers/models/llava_next/image_processing_llava_next_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature, get_patch_output_size, select_best_resolution from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -37,20 +39,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class LlavaNextFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/llava_onevision/modeling_llava_onevision.py b/src/transformers/models/llava_onevision/modeling_llava_onevision.py index e4cb0c9aeafd..eae6e3046f94 100644 --- a/src/transformers/models/llava_onevision/modeling_llava_onevision.py +++ b/src/transformers/models/llava_onevision/modeling_llava_onevision.py @@ -35,11 +35,7 @@ from ...modeling_outputs import BaseModelOutputWithPast, ModelOutput from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack -from ...utils import ( - TransformersKwargs, - auto_docstring, - can_return_tuple, -) +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple from ..auto import AutoModel from .configuration_llava_onevision import LlavaOnevisionConfig diff --git a/src/transformers/models/llava_onevision/modular_llava_onevision.py b/src/transformers/models/llava_onevision/modular_llava_onevision.py index 45dfac3b37ef..21688e7763bf 100644 --- a/src/transformers/models/llava_onevision/modular_llava_onevision.py +++ b/src/transformers/models/llava_onevision/modular_llava_onevision.py @@ -50,18 +50,15 @@ TensorType, auto_docstring, can_return_tuple, - is_torchvision_available, is_torchvision_v2_available, logging, ) -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F - +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F logger = logging.get_logger(__name__) diff --git a/src/transformers/models/mask2former/image_processing_mask2former_fast.py b/src/transformers/models/mask2former/image_processing_mask2former_fast.py index c61d531eb077..a5d662288119 100644 --- a/src/transformers/models/mask2former/image_processing_mask2former_fast.py +++ b/src/transformers/models/mask2former/image_processing_mask2former_fast.py @@ -21,6 +21,9 @@ import math from typing import Any, Optional, Union +import torch +from torch import nn + from ...image_processing_utils import BatchFeature, get_size_dict from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -39,14 +42,7 @@ PILImageResampling, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - logging, -) +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available, logging from .image_processing_mask2former import ( compute_segments, convert_segmentation_to_rle, @@ -55,18 +51,11 @@ ) -if is_torch_available(): - import torch - from torch import nn - - if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F - -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/mask2former/modular_mask2former.py b/src/transformers/models/mask2former/modular_mask2former.py index 9efbd8bdd340..c5f3f58fedbb 100644 --- a/src/transformers/models/mask2former/modular_mask2former.py +++ b/src/transformers/models/mask2former/modular_mask2former.py @@ -14,11 +14,13 @@ # limitations under the License. from typing import Optional +import torch +from torch import nn + from transformers.models.maskformer.image_processing_maskformer_fast import MaskFormerImageProcessorFast from ...utils import ( TensorType, - is_torch_available, logging, ) from .image_processing_mask2former import ( @@ -28,11 +30,6 @@ ) -if is_torch_available(): - import torch - from torch import nn - - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/maskformer/image_processing_maskformer_fast.py b/src/transformers/models/maskformer/image_processing_maskformer_fast.py index 0b1c95aa1012..ab6411f1bb3f 100644 --- a/src/transformers/models/maskformer/image_processing_maskformer_fast.py +++ b/src/transformers/models/maskformer/image_processing_maskformer_fast.py @@ -18,6 +18,9 @@ import warnings from typing import TYPE_CHECKING, Any, Optional, Union +import torch +from torch import nn + from ...image_processing_utils import BatchFeature, get_size_dict from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -39,8 +42,6 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, ) @@ -52,6 +53,11 @@ ) +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F + logger = logging.get_logger(__name__) @@ -59,18 +65,6 @@ from transformers import MaskFormerForInstanceSegmentationOutput -if is_torch_available(): - import torch - from torch import nn - - -if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - -elif is_torchvision_available(): - from torchvision.transforms import functional as F - - def convert_segmentation_map_to_binary_masks_fast( segmentation_map: "torch.Tensor", instance_id_to_semantic_id: Optional[dict[int, int]] = None, diff --git a/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2_fast.py b/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2_fast.py index e50d71025d54..97ca39da78bf 100644 --- a/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2_fast.py +++ b/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -36,20 +38,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class MobileNetV2FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/mobilevit/image_processing_mobilevit_fast.py b/src/transformers/models/mobilevit/image_processing_mobilevit_fast.py index 442f88a3a848..71c8ababba36 100644 --- a/src/transformers/models/mobilevit/image_processing_mobilevit_fast.py +++ b/src/transformers/models/mobilevit/image_processing_mobilevit_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -34,20 +36,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class MobileVitFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/nougat/image_processing_nougat_fast.py b/src/transformers/models/nougat/image_processing_nougat_fast.py index ebe37389f3f6..d6579029e4f5 100644 --- a/src/transformers/models/nougat/image_processing_nougat_fast.py +++ b/src/transformers/models/nougat/image_processing_nougat_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -38,20 +40,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class NougatFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/oneformer/image_processing_oneformer_fast.py b/src/transformers/models/oneformer/image_processing_oneformer_fast.py index 10869f50f622..20b34bb7fd39 100644 --- a/src/transformers/models/oneformer/image_processing_oneformer_fast.py +++ b/src/transformers/models/oneformer/image_processing_oneformer_fast.py @@ -16,6 +16,9 @@ from typing import Optional, Union +import torch +from torch import nn + from ...image_processing_utils_fast import ( BaseImageProcessorFast, BatchFeature, @@ -36,25 +39,18 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, ) from .image_processing_oneformer import load_metadata, prepare_metadata -logger = logging.get_logger(__name__) - -if is_torch_available(): - import torch - from torch import nn +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +logger = logging.get_logger(__name__) def make_pixel_mask(image: "torch.Tensor", output_size: tuple[int, int]) -> "torch.Tensor": diff --git a/src/transformers/models/ovis2/image_processing_ovis2_fast.py b/src/transformers/models/ovis2/image_processing_ovis2_fast.py index f12a9c70ee57..07fbf82f9fbe 100644 --- a/src/transformers/models/ovis2/image_processing_ovis2_fast.py +++ b/src/transformers/models/ovis2/image_processing_ovis2_fast.py @@ -15,6 +15,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -33,21 +35,15 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) from .image_processing_ovis2 import get_min_tile_covering_grid, get_optimal_tiled_canvas -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class Ovis2ImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/owlv2/image_processing_owlv2_fast.py b/src/transformers/models/owlv2/image_processing_owlv2_fast.py index 926da9b27ffc..70441feba3c2 100644 --- a/src/transformers/models/owlv2/image_processing_owlv2_fast.py +++ b/src/transformers/models/owlv2/image_processing_owlv2_fast.py @@ -22,6 +22,8 @@ import warnings from typing import TYPE_CHECKING, Optional, Union +import torch + from ...image_processing_utils_fast import BaseImageProcessorFast, BatchFeature, DefaultFastImageProcessorKwargs from ...image_transforms import center_to_corners_format, group_images_by_shape, reorder_images from ...image_utils import ( @@ -33,22 +35,13 @@ SizeDict, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, -) - - -if is_torch_available(): - import torch +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available +from .image_processing_owlv2 import _scale_boxes, box_iou if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F @@ -56,10 +49,6 @@ from .modeling_owlv2 import Owlv2ObjectDetectionOutput -if is_torch_available(): - from .image_processing_owlv2 import _scale_boxes, box_iou - - class Owlv2FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): ... diff --git a/src/transformers/models/owlv2/modular_owlv2.py b/src/transformers/models/owlv2/modular_owlv2.py index 7fe4d75ee9ea..2e6d917a791a 100644 --- a/src/transformers/models/owlv2/modular_owlv2.py +++ b/src/transformers/models/owlv2/modular_owlv2.py @@ -17,6 +17,8 @@ import warnings from typing import Optional, Union +import torch + from ...image_processing_utils_fast import ( BaseImageProcessorFast, BatchFeature, @@ -35,20 +37,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) from ..owlvit.image_processing_owlvit_fast import OwlViTImageProcessorFast -if is_torch_available(): - import torch - - if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/owlvit/image_processing_owlvit_fast.py b/src/transformers/models/owlvit/image_processing_owlvit_fast.py index 8689ac72dc44..1e458f964a04 100644 --- a/src/transformers/models/owlvit/image_processing_owlvit_fast.py +++ b/src/transformers/models/owlvit/image_processing_owlvit_fast.py @@ -17,22 +17,19 @@ import warnings from typing import TYPE_CHECKING, Optional, Union +import torch + from ...image_processing_utils_fast import BaseImageProcessorFast from ...image_transforms import center_to_corners_format from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling -from ...utils import TensorType, auto_docstring, is_torch_available, logging +from ...utils import TensorType, auto_docstring, logging +from .image_processing_owlvit import _scale_boxes, box_iou if TYPE_CHECKING: from .modeling_owlvit import OwlViTObjectDetectionOutput -if is_torch_available(): - import torch - - from .image_processing_owlvit import _scale_boxes, box_iou - - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/perceiver/image_processing_perceiver_fast.py b/src/transformers/models/perceiver/image_processing_perceiver_fast.py index ecd7f938f569..82c1bcd9d319 100644 --- a/src/transformers/models/perceiver/image_processing_perceiver_fast.py +++ b/src/transformers/models/perceiver/image_processing_perceiver_fast.py @@ -16,26 +16,22 @@ from typing import Optional, Union +import torch + from ...image_processing_utils_fast import BaseImageProcessorFast, BatchFeature from ...image_transforms import group_images_by_shape, reorder_images from ...image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD, PILImageResampling, SizeDict from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F @auto_docstring diff --git a/src/transformers/models/perception_lm/image_processing_perception_lm_fast.py b/src/transformers/models/perception_lm/image_processing_perception_lm_fast.py index c8b7c52d9a23..be55c39572d5 100644 --- a/src/transformers/models/perception_lm/image_processing_perception_lm_fast.py +++ b/src/transformers/models/perception_lm/image_processing_perception_lm_fast.py @@ -17,6 +17,8 @@ from typing import Optional, Union import numpy as np +import torch +from torchvision.transforms import functional as F from ...image_processing_utils import ( BatchFeature, @@ -35,19 +37,7 @@ PILImageResampling, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, -) - - -if is_torch_available(): - import torch - -if is_torchvision_available(): - from torchvision.transforms import functional as F +from ...utils import TensorType, auto_docstring class PerceptionLMFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/phi4_multimodal/image_processing_phi4_multimodal_fast.py b/src/transformers/models/phi4_multimodal/image_processing_phi4_multimodal_fast.py index 1f079005b01e..532136f8108e 100644 --- a/src/transformers/models/phi4_multimodal/image_processing_phi4_multimodal_fast.py +++ b/src/transformers/models/phi4_multimodal/image_processing_phi4_multimodal_fast.py @@ -23,24 +23,19 @@ DefaultFastImageProcessorKwargs, Unpack, ) -from ...image_utils import ImageInput, SizeDict +from ...image_utils import ImageInput, PILImageResampling, SizeDict from ...utils import ( TensorType, auto_docstring, - is_torchvision_available, is_torchvision_v2_available, - is_vision_available, logging, ) -if is_vision_available(): - from ...image_utils import PILImageResampling -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F logger = logging.get_logger(__name__) diff --git a/src/transformers/models/pixtral/image_processing_pixtral_fast.py b/src/transformers/models/pixtral/image_processing_pixtral_fast.py index 585405627023..db3e75760318 100644 --- a/src/transformers/models/pixtral/image_processing_pixtral_fast.py +++ b/src/transformers/models/pixtral/image_processing_pixtral_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature, get_size_dict from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -28,28 +30,18 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, - is_vision_available, logging, ) from .image_processing_pixtral import get_resize_output_image_size -logger = logging.get_logger(__name__) - -if is_torch_available(): - import torch +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F -if is_torchvision_available(): - if is_vision_available(): - pass - - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +logger = logging.get_logger(__name__) class PixtralFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/poolformer/image_processing_poolformer_fast.py b/src/transformers/models/poolformer/image_processing_poolformer_fast.py index 8fefa80be432..70c6ed55bc8a 100644 --- a/src/transformers/models/poolformer/image_processing_poolformer_fast.py +++ b/src/transformers/models/poolformer/image_processing_poolformer_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils_fast import BaseImageProcessorFast, BatchFeature, DefaultFastImageProcessorKwargs from ...image_transforms import ( ChannelDimension, @@ -36,20 +38,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class PoolFormerFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything_fast.py b/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything_fast.py index 4cb6c6732e90..763fd613c218 100644 --- a/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything_fast.py +++ b/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything_fast.py @@ -23,6 +23,8 @@ if TYPE_CHECKING: from ...modeling_outputs import DepthEstimatorOutput +import torch + from ...image_processing_utils_fast import ( BaseImageProcessorFast, DefaultFastImageProcessorKwargs, @@ -40,21 +42,15 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, requires_backends, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F def _constrain_to_multiple_of(val, multiple, min_val=0, max_val=None): diff --git a/src/transformers/models/qwen2_vl/image_processing_qwen2_vl_fast.py b/src/transformers/models/qwen2_vl/image_processing_qwen2_vl_fast.py index 33efe1929c06..80242a331ace 100644 --- a/src/transformers/models/qwen2_vl/image_processing_qwen2_vl_fast.py +++ b/src/transformers/models/qwen2_vl/image_processing_qwen2_vl_fast.py @@ -21,6 +21,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -40,8 +42,6 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, ) @@ -49,15 +49,10 @@ from .image_processing_qwen2_vl import smart_resize -if is_torch_available(): - import torch - - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F logger = logging.get_logger(__name__) diff --git a/src/transformers/models/rt_detr/image_processing_rt_detr_fast.py b/src/transformers/models/rt_detr/image_processing_rt_detr_fast.py index eefc45bf9f9a..68c5497b0205 100644 --- a/src/transformers/models/rt_detr/image_processing_rt_detr_fast.py +++ b/src/transformers/models/rt_detr/image_processing_rt_detr_fast.py @@ -7,6 +7,8 @@ import pathlib from typing import Any, Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -29,25 +31,14 @@ validate_annotations, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - requires_backends, -) +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available, requires_backends from ...utils.import_utils import requires from .image_processing_rt_detr import get_size_with_aspect_ratio -if is_torch_available(): - import torch - - if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/rt_detr/modular_rt_detr.py b/src/transformers/models/rt_detr/modular_rt_detr.py index 938f070d3672..760e4a6675cf 100644 --- a/src/transformers/models/rt_detr/modular_rt_detr.py +++ b/src/transformers/models/rt_detr/modular_rt_detr.py @@ -1,6 +1,8 @@ import pathlib from typing import Optional, Union +import torch + from transformers.models.detr.image_processing_detr_fast import DetrFastImageProcessorKwargs, DetrImageProcessorFast from ...image_processing_utils import BatchFeature @@ -20,21 +22,15 @@ from ...processing_utils import Unpack from ...utils import ( TensorType, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, requires_backends, ) -if is_torch_available(): - import torch - - if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/sam/image_processing_sam_fast.py b/src/transformers/models/sam/image_processing_sam_fast.py index 1bfb6adf5234..ba75e73c8680 100644 --- a/src/transformers/models/sam/image_processing_sam_fast.py +++ b/src/transformers/models/sam/image_processing_sam_fast.py @@ -21,6 +21,8 @@ import numpy as np import torch +from torch.nn import functional as F +from torchvision.ops.boxes import batched_nms from ...image_processing_utils import BatchFeature, get_size_dict from ...image_processing_utils_fast import ( @@ -37,23 +39,12 @@ pil_torch_interpolation_mapping, ) from ...processing_utils import Unpack -from ...utils import ( - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, -) - +from ...utils import auto_docstring, is_torchvision_v2_available -if is_torch_available(): - import torch - from torch.nn import functional as F if is_torchvision_v2_available(): - from torchvision.ops.boxes import batched_nms from torchvision.transforms.v2 import functional as F_t -elif is_torchvision_available(): - from torchvision.ops.boxes import batched_nms +else: from torchvision.transforms import functional as F_t diff --git a/src/transformers/models/sam2/image_processing_sam2_fast.py b/src/transformers/models/sam2/image_processing_sam2_fast.py index 8cb5381f0977..a55188f4e786 100644 --- a/src/transformers/models/sam2/image_processing_sam2_fast.py +++ b/src/transformers/models/sam2/image_processing_sam2_fast.py @@ -26,6 +26,7 @@ import numpy as np import torch import torch.nn.functional as F +from torchvision.ops.boxes import batched_nms from ...image_processing_utils import BatchFeature, get_size_dict from ...image_processing_utils_fast import BaseImageProcessorFast, DefaultFastImageProcessorKwargs @@ -42,17 +43,9 @@ from ...utils import ( TensorType, auto_docstring, - is_torchvision_available, - is_torchvision_v2_available, ) -if is_torchvision_v2_available(): - from torchvision.ops.boxes import batched_nms -elif is_torchvision_available(): - from torchvision.ops.boxes import batched_nms - - class Sam2FastImageProcessorKwargs(DefaultFastImageProcessorKwargs): r""" mask_size (`dict[str, int]`, *optional*): diff --git a/src/transformers/models/sam2/modular_sam2.py b/src/transformers/models/sam2/modular_sam2.py index be2a5eb1c6d2..daab10855512 100644 --- a/src/transformers/models/sam2/modular_sam2.py +++ b/src/transformers/models/sam2/modular_sam2.py @@ -41,7 +41,6 @@ ModelOutput, TensorType, auto_docstring, - is_torch_available, logging, ) from ...utils.generic import TransformersKwargs, check_model_inputs @@ -68,11 +67,6 @@ ) -if is_torch_available(): - import torch - from torch.nn import functional as F - - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/sam2_video/modular_sam2_video.py b/src/transformers/models/sam2_video/modular_sam2_video.py index 9ba8e6526305..c0c9b3e1ef7a 100644 --- a/src/transformers/models/sam2_video/modular_sam2_video.py +++ b/src/transformers/models/sam2_video/modular_sam2_video.py @@ -36,7 +36,6 @@ from ...utils import ( ModelOutput, auto_docstring, - is_torch_available, is_torchvision_available, is_torchvision_v2_available, logging, @@ -60,12 +59,9 @@ from ..sam2.processing_sam2 import Sam2Processor -if is_torch_available(): - import torch - if is_torchvision_available() and is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/segformer/image_processing_segformer_fast.py b/src/transformers/models/segformer/image_processing_segformer_fast.py index 77ac7281ef1b..da4bef3e9ee8 100644 --- a/src/transformers/models/segformer/image_processing_segformer_fast.py +++ b/src/transformers/models/segformer/image_processing_segformer_fast.py @@ -21,6 +21,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -38,21 +40,12 @@ is_torch_tensor, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, -) - +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available -if is_torch_available(): - import torch if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/segformer/modular_segformer.py b/src/transformers/models/segformer/modular_segformer.py index fbf35afd820e..341e6949d8b7 100644 --- a/src/transformers/models/segformer/modular_segformer.py +++ b/src/transformers/models/segformer/modular_segformer.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from transformers.models.beit.image_processing_beit_fast import BeitFastImageProcessorKwargs, BeitImageProcessorFast from ...image_processing_utils import BatchFeature @@ -34,18 +36,13 @@ from ...processing_utils import Unpack from ...utils import ( TensorType, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - if is_torchvision_v2_available(): from torchvision.transforms.v2 import functional as F -elif is_torchvision_available(): +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/siglip2/image_processing_siglip2_fast.py b/src/transformers/models/siglip2/image_processing_siglip2_fast.py index bbab91961962..64dcfa1ad566 100644 --- a/src/transformers/models/siglip2/image_processing_siglip2_fast.py +++ b/src/transformers/models/siglip2/image_processing_siglip2_fast.py @@ -32,23 +32,16 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, ) from .image_processing_siglip2 import get_image_size_for_max_num_patches -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F - +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F logger = logging.get_logger(__name__) diff --git a/src/transformers/models/smolvlm/video_processing_smolvlm.py b/src/transformers/models/smolvlm/video_processing_smolvlm.py index eda3bdb1c811..7e8e544b8fc7 100644 --- a/src/transformers/models/smolvlm/video_processing_smolvlm.py +++ b/src/transformers/models/smolvlm/video_processing_smolvlm.py @@ -21,7 +21,7 @@ from ...image_processing_utils import BatchFeature, get_size_dict from ...image_utils import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD, PILImageResampling, SizeDict from ...processing_utils import Unpack, VideosKwargs -from ...utils import TensorType, is_torchvision_v2_available +from ...utils import TensorType, is_torchvision_v2_available, logging from ...video_processing_utils import BaseVideoProcessor from ...video_utils import VideoMetadata, group_videos_by_shape, reorder_videos @@ -31,8 +31,6 @@ else: from torchvision.transforms import functional as F -from ...utils import logging - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/superpoint/image_processing_superpoint_fast.py b/src/transformers/models/superpoint/image_processing_superpoint_fast.py index e70bb397ff6a..a752e08ac5f0 100644 --- a/src/transformers/models/superpoint/image_processing_superpoint_fast.py +++ b/src/transformers/models/superpoint/image_processing_superpoint_fast.py @@ -16,6 +16,8 @@ from typing import TYPE_CHECKING, Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -31,21 +33,16 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - if TYPE_CHECKING: from .modeling_superpoint import SuperPointKeypointDescriptionOutput if is_torchvision_v2_available(): import torchvision.transforms.v2.functional as F -elif is_torchvision_available(): +else: import torchvision.transforms.functional as F diff --git a/src/transformers/models/swin2sr/image_processing_swin2sr_fast.py b/src/transformers/models/swin2sr/image_processing_swin2sr_fast.py index f99ab99274f5..c10bd5081754 100644 --- a/src/transformers/models/swin2sr/image_processing_swin2sr_fast.py +++ b/src/transformers/models/swin2sr/image_processing_swin2sr_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature, ChannelDimension, get_image_size from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -28,24 +30,18 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, ) from ...utils.deprecation import deprecate_kwarg -logger = logging.get_logger(__name__) - -if is_torch_available(): - import torch +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +logger = logging.get_logger(__name__) class Swin2SRFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/textnet/image_processing_textnet_fast.py b/src/transformers/models/textnet/image_processing_textnet_fast.py index 41b201a5c4ee..2f5ef22ef5e3 100644 --- a/src/transformers/models/textnet/image_processing_textnet_fast.py +++ b/src/transformers/models/textnet/image_processing_textnet_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import BaseImageProcessorFast, DefaultFastImageProcessorKwargs from ...image_transforms import ( @@ -35,20 +37,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class TextNetFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/tvp/image_processing_tvp_fast.py b/src/transformers/models/tvp/image_processing_tvp_fast.py index b96e4991f619..e7fe7e621d8c 100644 --- a/src/transformers/models/tvp/image_processing_tvp_fast.py +++ b/src/transformers/models/tvp/image_processing_tvp_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -32,23 +34,13 @@ make_nested_list_of_images, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, -) - +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available -if is_torch_available(): - import torch -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F class TvpFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): diff --git a/src/transformers/models/vilt/image_processing_vilt_fast.py b/src/transformers/models/vilt/image_processing_vilt_fast.py index 1c169994ba3f..79e601648c55 100644 --- a/src/transformers/models/vilt/image_processing_vilt_fast.py +++ b/src/transformers/models/vilt/image_processing_vilt_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -28,20 +30,14 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F # Set maximum size based on the typical aspect ratio of the COCO dataset MAX_LONGER_EDGE = 1333 diff --git a/src/transformers/models/vitmatte/image_processing_vitmatte_fast.py b/src/transformers/models/vitmatte/image_processing_vitmatte_fast.py index 014a6939af5c..ae8797789df8 100644 --- a/src/transformers/models/vitmatte/image_processing_vitmatte_fast.py +++ b/src/transformers/models/vitmatte/image_processing_vitmatte_fast.py @@ -16,6 +16,8 @@ from typing import Optional, Union +import torch + from ...image_processing_utils import BatchFeature from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -35,22 +37,15 @@ TensorType, auto_docstring, filter_out_non_signature_kwargs, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, ) -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F - +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F logger = logging.get_logger(__name__) diff --git a/src/transformers/models/yolos/image_processing_yolos_fast.py b/src/transformers/models/yolos/image_processing_yolos_fast.py index 81fb0b008e0d..fda06dfc522a 100644 --- a/src/transformers/models/yolos/image_processing_yolos_fast.py +++ b/src/transformers/models/yolos/image_processing_yolos_fast.py @@ -7,6 +7,9 @@ import pathlib from typing import Any, Optional, Union +import torch +from torchvision.io import read_image + from ...image_processing_utils import BatchFeature, get_size_dict from ...image_processing_utils_fast import ( BaseImageProcessorFast, @@ -29,27 +32,13 @@ validate_annotations, ) from ...processing_utils import Unpack -from ...utils import ( - TensorType, - auto_docstring, - is_torch_available, - is_torchvision_available, - is_torchvision_v2_available, - logging, -) +from ...utils import TensorType, auto_docstring, is_torchvision_v2_available, logging from ...utils.import_utils import requires -if is_torch_available(): - import torch - - if is_torchvision_v2_available(): - from torchvision.io import read_image from torchvision.transforms.v2 import functional as F - -elif is_torchvision_available(): - from torchvision.io import read_image +else: from torchvision.transforms import functional as F diff --git a/src/transformers/models/yolos/modular_yolos.py b/src/transformers/models/yolos/modular_yolos.py index d1391008227c..13f3db41b675 100644 --- a/src/transformers/models/yolos/modular_yolos.py +++ b/src/transformers/models/yolos/modular_yolos.py @@ -1,19 +1,16 @@ from typing import Optional, Union +import torch + from transformers.models.detr.image_processing_detr_fast import DetrImageProcessorFast from ...image_transforms import center_to_corners_format from ...utils import ( TensorType, - is_torch_available, logging, ) -if is_torch_available(): - import torch - - logger = logging.get_logger(__name__) diff --git a/src/transformers/models/zoedepth/image_processing_zoedepth_fast.py b/src/transformers/models/zoedepth/image_processing_zoedepth_fast.py index c89ec8b2ebf1..7967932729e5 100644 --- a/src/transformers/models/zoedepth/image_processing_zoedepth_fast.py +++ b/src/transformers/models/zoedepth/image_processing_zoedepth_fast.py @@ -20,6 +20,7 @@ ) import numpy as np +import torch from ...image_processing_utils import ( BatchFeature, @@ -43,8 +44,6 @@ from ...utils import ( TensorType, auto_docstring, - is_torch_available, - is_torchvision_available, is_torchvision_v2_available, logging, requires_backends, @@ -53,16 +52,10 @@ from .modeling_zoedepth import ZoeDepthDepthEstimatorOutput -if is_torch_available(): - import torch - -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F - - from torchvision.transforms import InterpolationMode +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F logger = logging.get_logger(__name__) @@ -296,7 +289,7 @@ def post_process_depth_estimation( depth = F.resize( depth, size=[source_size[0] + 2 * pad_h, source_size[1] + 2 * pad_w], - interpolation=InterpolationMode.BICUBIC, + interpolation=F.InterpolationMode.BICUBIC, antialias=False, ) @@ -310,7 +303,7 @@ def post_process_depth_estimation( depth = F.resize( depth, size=target_size, - interpolation=InterpolationMode.BICUBIC, + interpolation=F.InterpolationMode.BICUBIC, antialias=False, ) depth = depth.squeeze(0) diff --git a/src/transformers/video_processing_utils.py b/src/transformers/video_processing_utils.py index 9f6545ebe10e..4d0e9c58f314 100644 --- a/src/transformers/video_processing_utils.py +++ b/src/transformers/video_processing_utils.py @@ -68,11 +68,11 @@ if is_torch_available(): import torch -if is_torchvision_available(): - if is_torchvision_v2_available(): - from torchvision.transforms.v2 import functional as F - else: - from torchvision.transforms import functional as F +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +elif is_torchvision_available(): + from torchvision.transforms import functional as F + logger = logging.get_logger(__name__) From b5cbfd515063d499bc8c2c45dabe62d63e43a2d1 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Wed, 17 Sep 2025 19:53:59 +0200 Subject: [PATCH 093/204] Fix `Glm4vModelTest::test_eager_matches_fa2_generate` (#40947) * fix * fix * fix --------- Co-authored-by: ydshieh --- tests/models/glm4v/test_modeling_glm4v.py | 4 +++- tests/models/glm4v_moe/test_modeling_glm4v_moe.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/models/glm4v/test_modeling_glm4v.py b/tests/models/glm4v/test_modeling_glm4v.py index 6c3845b10e88..4059fe2f9e99 100644 --- a/tests/models/glm4v/test_modeling_glm4v.py +++ b/tests/models/glm4v/test_modeling_glm4v.py @@ -159,7 +159,9 @@ def prepare_config_and_inputs_for_common(self): inputs_dict = { "pixel_values": pixel_values, - "image_grid_thw": torch.tensor([[1, patches_per_side, patches_per_side]] * self.batch_size), + "image_grid_thw": torch.tensor( + [[1, patches_per_side, patches_per_side]] * self.batch_size, device=torch_device + ), "input_ids": input_ids, "attention_mask": attention_mask, } diff --git a/tests/models/glm4v_moe/test_modeling_glm4v_moe.py b/tests/models/glm4v_moe/test_modeling_glm4v_moe.py index dff5ea7074af..995b3c0723db 100644 --- a/tests/models/glm4v_moe/test_modeling_glm4v_moe.py +++ b/tests/models/glm4v_moe/test_modeling_glm4v_moe.py @@ -170,7 +170,9 @@ def prepare_config_and_inputs_for_common(self): inputs_dict = { "pixel_values": pixel_values, - "image_grid_thw": torch.tensor([[1, patches_per_side, patches_per_side]] * self.batch_size), + "image_grid_thw": torch.tensor( + [[1, patches_per_side, patches_per_side]] * self.batch_size, device=torch_device + ), "input_ids": input_ids, "attention_mask": attention_mask, } From b8207cb40da3cab282f81c97c9d9ec65a87ee2e8 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Wed, 17 Sep 2025 20:50:38 +0200 Subject: [PATCH 094/204] Update expected values for some `test_speculative_generation` (#40949) * fix * fix --------- Co-authored-by: ydshieh --- tests/models/mistral/test_modeling_mistral.py | 2 +- tests/models/qwen2/test_modeling_qwen2.py | 2 +- tests/models/qwen2_moe/test_modeling_qwen2_moe.py | 2 +- tests/models/qwen3/test_modeling_qwen3.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/models/mistral/test_modeling_mistral.py b/tests/models/mistral/test_modeling_mistral.py index cd6459c170dc..1723d55afc8a 100644 --- a/tests/models/mistral/test_modeling_mistral.py +++ b/tests/models/mistral/test_modeling_mistral.py @@ -254,7 +254,7 @@ def test_model_7b_long_prompt_sdpa(self): @slow def test_speculative_generation(self): - EXPECTED_TEXT_COMPLETION = "My favourite condiment is 100% Sriracha. I love it on everything. I have it on my" + EXPECTED_TEXT_COMPLETION = "My favourite condiment is 100% ketchup. I’m not a fan of mustard, relish" prompt = "My favourite condiment is " tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1", use_fast=False) model = MistralForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto", dtype=torch.float16) diff --git a/tests/models/qwen2/test_modeling_qwen2.py b/tests/models/qwen2/test_modeling_qwen2.py index d5c207fb9b8c..d4cf34fbbca2 100644 --- a/tests/models/qwen2/test_modeling_qwen2.py +++ b/tests/models/qwen2/test_modeling_qwen2.py @@ -207,7 +207,7 @@ def test_model_450m_long_prompt_sdpa(self): @slow def test_speculative_generation(self): EXPECTED_TEXT_COMPLETION = ( - "My favourite condiment is 100% natural honey, and I always like to use it in my recipes. I love" + "My favourite condiment is 100% natural and organic, and I love to use it to make my own sauces." ) prompt = "My favourite condiment is " tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2-7B", use_fast=False) diff --git a/tests/models/qwen2_moe/test_modeling_qwen2_moe.py b/tests/models/qwen2_moe/test_modeling_qwen2_moe.py index 02eb4dfb4643..db3be5ac7e20 100644 --- a/tests/models/qwen2_moe/test_modeling_qwen2_moe.py +++ b/tests/models/qwen2_moe/test_modeling_qwen2_moe.py @@ -252,7 +252,7 @@ def test_model_a2_7b_long_prompt_sdpa(self): @slow def test_speculative_generation(self): EXPECTED_TEXT_COMPLETION = ( - "To be or not to be, that is the question. Whether 'tis nobler in the mind to suffer the sl" + "To be or not to be, that is the question: Whether 'tis nobler in the mind to suffer The sl" ) prompt = "To be or not to" tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen1.5-MoE-A2.7B", use_fast=False) diff --git a/tests/models/qwen3/test_modeling_qwen3.py b/tests/models/qwen3/test_modeling_qwen3.py index 169d7ee784a0..ba937656d3a6 100644 --- a/tests/models/qwen3/test_modeling_qwen3.py +++ b/tests/models/qwen3/test_modeling_qwen3.py @@ -199,7 +199,7 @@ def test_speculative_generation(self): { ("xpu", 3): "My favourite condiment is 100% peanut butter. I love it so much that I can't help but use it", ("cuda", 7): "My favourite condiment is 100% natural. It's a little spicy and a little sweet, but it's the", - ("cuda", 8): "My favourite condiment is 100% peanut butter. I love it so much that I can't help but use it", + ("cuda", 8): "My favourite condiment is 100% beef, 100% beef, 100% beef.", } ) # fmt: skip EXPECTED_TEXT_COMPLETION = EXPECTED_TEXT_COMPLETIONS.get_expectation() From f962aafcd1b99afb52d5c7690ad6d26e07c999d1 Mon Sep 17 00:00:00 2001 From: Jack <32371937+jackzhxng@users.noreply.github.com> Date: Thu, 18 Sep 2025 04:45:04 -0400 Subject: [PATCH 095/204] Standardize audio embedding function name for audio multimodal models (#40919) * Standardize audio embedding function name for audio multimodal models * PR review --- src/transformers/models/voxtral/modeling_voxtral.py | 11 +++++++++-- src/transformers/models/voxtral/modular_voxtral.py | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/transformers/models/voxtral/modeling_voxtral.py b/src/transformers/models/voxtral/modeling_voxtral.py index 671d91066cae..15ef9e541c0b 100644 --- a/src/transformers/models/voxtral/modeling_voxtral.py +++ b/src/transformers/models/voxtral/modeling_voxtral.py @@ -20,6 +20,7 @@ # limitations under the License. import math +import warnings from typing import Callable, Optional, Union import torch @@ -431,7 +432,7 @@ def set_decoder(self, decoder): def get_decoder(self): return self.language_model.get_decoder() - def get_audio_embeds(self, input_features: torch.FloatTensor): + def get_audio_features(self, input_features: torch.FloatTensor): """ This method is used to get the audio embeddings from input features (a log mel spectrogram), meaning inferring the audio encoder and the multi-modal projector. Args: @@ -452,6 +453,12 @@ def get_audio_embeds(self, input_features: torch.FloatTensor): audio_embeds = self.multi_modal_projector(audio_hidden_states) return audio_embeds + def get_audio_embeds(self, input_features: torch.FloatTensor): + warnings.warn( + "The method `get_audio_embeds` is deprecated. Please use `get_audio_features` instead.", FutureWarning + ) + return self.get_audio_features(input_features) + @can_return_tuple @auto_docstring def forward( @@ -505,7 +512,7 @@ def forward( inputs_embeds = self.get_input_embeddings()(input_ids) if input_features is not None and input_ids is not None: - audio_embeds = self.get_audio_embeds(input_features) + audio_embeds = self.get_audio_features(input_features) # replace text-audio token placeholders with audio embeddings audio_token_mask = (input_ids == self.config.audio_token_id).unsqueeze(-1) diff --git a/src/transformers/models/voxtral/modular_voxtral.py b/src/transformers/models/voxtral/modular_voxtral.py index a0080f58eb0d..c02e8ec58864 100644 --- a/src/transformers/models/voxtral/modular_voxtral.py +++ b/src/transformers/models/voxtral/modular_voxtral.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import warnings from typing import Optional, Union import torch @@ -166,7 +167,7 @@ def set_decoder(self, decoder): def get_decoder(self): return self.language_model.get_decoder() - def get_audio_embeds(self, input_features: torch.FloatTensor): + def get_audio_features(self, input_features: torch.FloatTensor): """ This method is used to get the audio embeddings from input features (a log mel spectrogram), meaning inferring the audio encoder and the multi-modal projector. Args: @@ -187,6 +188,12 @@ def get_audio_embeds(self, input_features: torch.FloatTensor): audio_embeds = self.multi_modal_projector(audio_hidden_states) return audio_embeds + def get_audio_embeds(self, input_features: torch.FloatTensor): + warnings.warn( + "The method `get_audio_embeds` is deprecated. Please use `get_audio_features` instead.", FutureWarning + ) + return self.get_audio_features(input_features) + @can_return_tuple @auto_docstring def forward( @@ -240,7 +247,7 @@ def forward( inputs_embeds = self.get_input_embeddings()(input_ids) if input_features is not None and input_ids is not None: - audio_embeds = self.get_audio_embeds(input_features) + audio_embeds = self.get_audio_features(input_features) # replace text-audio token placeholders with audio embeddings audio_token_mask = (input_ids == self.config.audio_token_id).unsqueeze(-1) From cd1a6615554e651e63daa63563d781254eb10b0d Mon Sep 17 00:00:00 2001 From: Shane A Date: Thu, 18 Sep 2025 02:04:06 -0700 Subject: [PATCH 096/204] Add FlexOlmo model (#40921) * transformers add-new-model-like * Add FlexOlmo implementation * Update FlexOlmo docs * Set default tokenization for flex olmo * Update FlexOlmo tests * Update attention comment * Remove unneeded use of `sliding_window` --- docs/source/en/_toctree.yml | 2 + docs/source/en/model_doc/flex_olmo.md | 139 ++++ src/transformers/models/__init__.py | 1 + .../models/auto/configuration_auto.py | 2 + src/transformers/models/auto/modeling_auto.py | 2 + .../models/auto/tokenization_auto.py | 1 + src/transformers/models/flex_olmo/__init__.py | 29 + .../flex_olmo/configuration_flex_olmo.py | 199 +++++ .../models/flex_olmo/modeling_flex_olmo.py | 687 ++++++++++++++++++ .../models/flex_olmo/modular_flex_olmo.py | 353 +++++++++ tests/models/flex_olmo/__init__.py | 0 .../flex_olmo/test_modeling_flex_olmo.py | 126 ++++ 12 files changed, 1541 insertions(+) create mode 100644 docs/source/en/model_doc/flex_olmo.md create mode 100644 src/transformers/models/flex_olmo/__init__.py create mode 100644 src/transformers/models/flex_olmo/configuration_flex_olmo.py create mode 100644 src/transformers/models/flex_olmo/modeling_flex_olmo.py create mode 100644 src/transformers/models/flex_olmo/modular_flex_olmo.py create mode 100644 tests/models/flex_olmo/__init__.py create mode 100644 tests/models/flex_olmo/test_modeling_flex_olmo.py diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index 65411024d4a3..d7fa25e185eb 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -485,6 +485,8 @@ title: FLAN-UL2 - local: model_doc/flaubert title: FlauBERT + - local: model_doc/flex_olmo + title: FlexOlmo - local: model_doc/fnet title: FNet - local: model_doc/fsmt diff --git a/docs/source/en/model_doc/flex_olmo.md b/docs/source/en/model_doc/flex_olmo.md new file mode 100644 index 000000000000..b771fe526d06 --- /dev/null +++ b/docs/source/en/model_doc/flex_olmo.md @@ -0,0 +1,139 @@ + +*This model was released on 2025-07-09 and added to Hugging Face Transformers on 2025-09-15.* +
+
+ PyTorch + FlashAttention + SDPA +
+
+ +# FlexOlmo + +[FlexOlmo](https://huggingface.co/papers/2507.07024) is a new class of language models (LMs) that supports (1) distributed training without data sharing, where different model parameters are independently trained on closed datasets, and (2) data-flexible inference, where these parameters along with their associated data can be flexibly included or excluded from model inferences with no further training. FlexOlmo employs a mixture-of-experts (MoE) architecture where each expert is trained independently on closed datasets and later integrated through a new domain-informed routing without any joint training. FlexOlmo is trained on FlexMix, a corpus we curate comprising publicly available datasets alongside seven domain-specific sets, representing realistic approximations of closed sets. + +You can find all the original FlexOlmo checkpoints under the [FlexOlmo](https://huggingface.co/collections/allenai/flexolmo-68471177a386b6e20a54c55f) collection. + +> [!TIP] +> Click on the FlexOlmo models in the right sidebar for more examples of how to apply FlexOlmo to different language tasks. + +The example below demonstrates how to generate text with [`Pipeline`], [`AutoModel`] and from the command line. + + + + +```py +import torch +from transformers import pipeline + +pipe = pipeline( + task="text-generation", + model="allenai/FlexOlmo-7x7B-1T", + dtype=torch.bfloat16, + device=0, +) + +result = pipe("Plants create energy through a process known as") +print(result) +``` + + + + +```py +import torch +from transformers import AutoModelForCausalLM, AutoTokenizer + +tokenizer = AutoTokenizer.from_pretrained( + "allenai/FlexOlmo-7x7B-1T" +) + +model = AutoModelForCausalLM.from_pretrained( + "allenai/FlexOlmo-7x7B-1T", + dtype=torch.bfloat16, + device_map="auto", + attn_implementation="sdpa" +) +input_ids = tokenizer("Plants create energy through a process known as", return_tensors="pt").to(model.device) + +output = model.generate(**input_ids, max_length=50, cache_implementation="static") +print(tokenizer.decode(output[0], skip_special_tokens=True)) +``` + + + + +```bash +echo -e "Plants create energy through a process known as" | transformers-cli run --task text-generation --model allenai/FlexOlmo-7x7B-1T --device 0 +``` + + + + +Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for more available quantization backends. + +The example below uses [torchao](../quantization/torchao) to only quantize the weights to 4-bits. +```py + +#pip install torchao +import torch +from transformers import AutoModelForCausalLM, AutoTokenizer, TorchAoConfig + +torchao_config = TorchAoConfig( + "int4_weight_only", + group_size=128 +) + +tokenizer = AutoTokenizer.from_pretrained( + "allenai/FlexOlmo-7x7B-1T" +) + +model = AutoModelForCausalLM.from_pretrained( + "allenai/FlexOlmo-7x7B-1T", + quantization_config=torchao_config, + dtype=torch.bfloat16, + device_map="auto", + attn_implementation="sdpa" +) +input_ids = tokenizer("Plants create energy through a process known as", return_tensors="pt").to(model.device) + +output = model.generate(**input_ids, max_length=50, cache_implementation="static") +print(tokenizer.decode(output[0], skip_special_tokens=True)) + +``` + + +## FlexOlmoConfig + +[[autodoc]] FlexOlmoConfig + +## FlexOlmoForCausalLM + +[[autodoc]] FlexOlmoForCausalLM + +## FlexOlmoModel + +[[autodoc]] FlexOlmoModel + - forward + +## FlexOlmoPreTrainedModel + +[[autodoc]] FlexOlmoPreTrainedModel + - forward \ No newline at end of file diff --git a/src/transformers/models/__init__.py b/src/transformers/models/__init__.py index 18d74ade4126..5c391e7162f4 100644 --- a/src/transformers/models/__init__.py +++ b/src/transformers/models/__init__.py @@ -123,6 +123,7 @@ from .fastspeech2_conformer import * from .flaubert import * from .flava import * + from .flex_olmo import * from .florence2 import * from .fnet import * from .focalnet import * diff --git a/src/transformers/models/auto/configuration_auto.py b/src/transformers/models/auto/configuration_auto.py index a9303913e861..38f38cd31b40 100644 --- a/src/transformers/models/auto/configuration_auto.py +++ b/src/transformers/models/auto/configuration_auto.py @@ -148,6 +148,7 @@ ("fastspeech2_conformer_with_hifigan", "FastSpeech2ConformerWithHifiGanConfig"), ("flaubert", "FlaubertConfig"), ("flava", "FlavaConfig"), + ("flex_olmo", "FlexOlmoConfig"), ("florence2", "Florence2Config"), ("fnet", "FNetConfig"), ("focalnet", "FocalNetConfig"), @@ -580,6 +581,7 @@ ("flan-ul2", "FLAN-UL2"), ("flaubert", "FlauBERT"), ("flava", "FLAVA"), + ("flex_olmo", "FlexOlmo"), ("florence2", "Florence2"), ("fnet", "FNet"), ("focalnet", "FocalNet"), diff --git a/src/transformers/models/auto/modeling_auto.py b/src/transformers/models/auto/modeling_auto.py index 571f654a9499..93420820fb9e 100644 --- a/src/transformers/models/auto/modeling_auto.py +++ b/src/transformers/models/auto/modeling_auto.py @@ -150,6 +150,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("fastspeech2_conformer_with_hifigan", "FastSpeech2ConformerWithHifiGan"), ("flaubert", "FlaubertModel"), ("flava", "FlavaModel"), + ("flex_olmo", "FlexOlmoModel"), ("florence2", "Florence2Model"), ("fnet", "FNetModel"), ("focalnet", "FocalNetModel"), @@ -653,6 +654,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("falcon", "FalconForCausalLM"), ("falcon_h1", "FalconH1ForCausalLM"), ("falcon_mamba", "FalconMambaForCausalLM"), + ("flex_olmo", "FlexOlmoForCausalLM"), ("fuyu", "FuyuForCausalLM"), ("gemma", "GemmaForCausalLM"), ("gemma2", "Gemma2ForCausalLM"), diff --git a/src/transformers/models/auto/tokenization_auto.py b/src/transformers/models/auto/tokenization_auto.py index eae569f1dae4..7858ae587946 100644 --- a/src/transformers/models/auto/tokenization_auto.py +++ b/src/transformers/models/auto/tokenization_auto.py @@ -245,6 +245,7 @@ ("FastSpeech2ConformerTokenizer" if is_g2p_en_available() else None, None), ), ("flaubert", ("FlaubertTokenizer", None)), + ("flex_olmo", (None, "GPT2TokenizerFast" if is_tokenizers_available() else None)), ("fnet", ("FNetTokenizer", "FNetTokenizerFast" if is_tokenizers_available() else None)), ("fsmt", ("FSMTTokenizer", None)), ("funnel", ("FunnelTokenizer", "FunnelTokenizerFast" if is_tokenizers_available() else None)), diff --git a/src/transformers/models/flex_olmo/__init__.py b/src/transformers/models/flex_olmo/__init__.py new file mode 100644 index 000000000000..f4213ca9b0b4 --- /dev/null +++ b/src/transformers/models/flex_olmo/__init__.py @@ -0,0 +1,29 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from typing import TYPE_CHECKING + +from ...utils import _LazyModule +from ...utils.import_utils import define_import_structure + + +if TYPE_CHECKING: + from .configuration_flex_olmo import * + from .modeling_flex_olmo import * +else: + import sys + + _file = globals()["__file__"] + sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__) diff --git a/src/transformers/models/flex_olmo/configuration_flex_olmo.py b/src/transformers/models/flex_olmo/configuration_flex_olmo.py new file mode 100644 index 000000000000..ae4704770e36 --- /dev/null +++ b/src/transformers/models/flex_olmo/configuration_flex_olmo.py @@ -0,0 +1,199 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/flex_olmo/modular_flex_olmo.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_flex_olmo.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + + +from ...configuration_utils import PretrainedConfig +from ...modeling_rope_utils import rope_config_validation + + +class FlexOlmoConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`FlexOlmoModel`]. It is used to instantiate an FlexOlmo + 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 [allenai/FlexOlmo-7x7B-1T](https://huggingface.co/allenai/FlexOlmo-7x7B-1T). + + 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 100352): + Vocabulary size of the FlexOlmo model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`FlexOlmoModel`] + hidden_size (`int`, *optional*, defaults to 4096): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 11008): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 32): + Number of hidden layers in the Transformer decoder. + num_attention_heads (`int`, *optional*, defaults to 32): + Number of attention heads for each attention layer in the Transformer decoder. + num_key_value_heads (`int`, *optional*): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to + `num_attention_heads`. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 4096): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + pad_token_id (`int`, *optional*, defaults to 100277): + Padding token id. + bos_token_id (`int`, *optional*): + Beginning of stream token id. + eos_token_id (`int`, *optional*, defaults to 100257): + End of stream token id. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether to tie weight embeddings + rope_theta (`float`, *optional*, defaults to 500000.0): + The base period of the RoPE embeddings. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. Currently supports two scaling + strategies: linear and dynamic. Their scaling factor must be a float greater than 1. The expected format is + `{"type": strategy name, "factor": scaling factor}`. When using this flag, don't update + `max_position_embeddings` to the expected new maximum. See the following thread for more information on how + these scaling strategies behave: + https://www.reddit.com/r/LocalLLaMA/comments/14mrgpr/dynamically_scaled_rope_further_increases/. This is an + experimental feature, subject to breaking API changes in future versions. + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + num_experts_per_tok (`int`, *optional*, defaults to 5): + Number of selected experts. + num_experts (`int`, *optional*, defaults to 7): + Number of routed experts. + output_router_logits (`bool`, *optional*, defaults to `False`): + Whether or not the router logits should be returned by the model. Enabling this will also + allow the model to output the auxiliary loss, including load balancing loss and router z-loss. + router_aux_loss_coef (`float`, *optional*, defaults to 0.01): + The aux loss factor for the total loss. + norm_topk_prob (`bool`, *optional*, defaults to `False`): + Whether to normalize the topk probabilities. + + ```python + >>> from transformers import FlexOlmoModel, FlexOlmoConfig + + >>> # Initializing a FlexOlmo style configuration + >>> configuration = FlexOlmoConfig() + + >>> # Initializing a model from the FlexOlmo style configuration + >>> model = FlexOlmoModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "flex_olmo" + keys_to_ignore_at_inference = ["past_key_values"] + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.k_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.v_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.o_proj": "rowwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=100352, + hidden_size=4096, + intermediate_size=11008, + num_hidden_layers=32, + num_attention_heads=32, + num_key_value_heads=None, + hidden_act="silu", + max_position_embeddings=4096, + initializer_range=0.02, + rms_norm_eps=1e-06, + use_cache=True, + pad_token_id=100277, + bos_token_id=None, + eos_token_id=100257, + tie_word_embeddings=False, + rope_theta=500000.0, + rope_scaling=None, + attention_bias=False, + attention_dropout=0.0, + num_experts_per_tok=5, + num_experts=7, + output_router_logits=False, + router_aux_loss_coef=0.01, + norm_topk_prob=False, + **kwargs, + ): + super().__init__( + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + tie_word_embeddings=tie_word_embeddings, + **kwargs, + ) + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + + # for backward compatibility + if num_key_value_heads is None: + num_key_value_heads = num_attention_heads + + self.num_key_value_heads = num_key_value_heads + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + self.num_experts_per_tok = num_experts_per_tok + self.num_experts = num_experts + self.output_router_logits = output_router_logits + self.router_aux_loss_coef = router_aux_loss_coef + self.norm_topk_prob = norm_topk_prob + # Validate the correctness of rotary position embeddings parameters + # BC: if there is a 'type' field, move it to 'rope_type'. + if self.rope_scaling is not None and "type" in self.rope_scaling: + self.rope_scaling["rope_type"] = self.rope_scaling["type"] + rope_config_validation(self) + + +__all__ = ["FlexOlmoConfig"] diff --git a/src/transformers/models/flex_olmo/modeling_flex_olmo.py b/src/transformers/models/flex_olmo/modeling_flex_olmo.py new file mode 100644 index 000000000000..26f93c9c64a2 --- /dev/null +++ b/src/transformers/models/flex_olmo/modeling_flex_olmo.py @@ -0,0 +1,687 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/flex_olmo/modular_flex_olmo.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_flex_olmo.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from typing import Callable, Optional, Union + +import torch +import torch.nn.functional as F +from torch import nn + +from ...activations import ACT2FN +from ...cache_utils import Cache, DynamicCache +from ...generation import GenerationMixin +from ...integrations import use_kernel_forward_from_hub +from ...masking_utils import create_causal_mask +from ...modeling_layers import GradientCheckpointingLayer +from ...modeling_outputs import MoeCausalLMOutputWithPast, MoeModelOutputWithPast +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring +from ...utils.deprecation import deprecate_kwarg +from ...utils.generic import OutputRecorder, check_model_inputs +from .configuration_flex_olmo import FlexOlmoConfig + + +@use_kernel_forward_from_hub("RMSNorm") +class FlexOlmoRMSNorm(nn.Module): + def __init__(self, hidden_size, eps=1e-6): + """ + FlexOlmoRMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states): + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return (self.weight * hidden_states).to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +class FlexOlmoRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: FlexOlmoConfig, device=None): + super().__init__() + # BC: "rope_type" was originally "type" + if hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): + self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type")) + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device) + position_ids_expanded = position_ids[:, None, :].float() + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + return cos, sin + + +class FlexOlmoMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor: + """ + This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, + num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim) + """ + batch, num_key_value_heads, slen, head_dim = hidden_states.shape + if n_rep == 1: + return hidden_states + hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim) + return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim) + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: float, + dropout: float = 0.0, + **kwargs: Unpack[TransformersKwargs], +): + key_states = repeat_kv(key, module.num_key_value_groups) + value_states = repeat_kv(value, module.num_key_value_groups) + + attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling + if attention_mask is not None: + causal_mask = attention_mask[:, :, :, : key_states.shape[-2]] + attn_weights = attn_weights + causal_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + attn_output = torch.matmul(attn_weights, value_states) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + +def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1): + """Applies Rotary Position Embedding to the query and key tensors. + + Args: + q (`torch.Tensor`): The query tensor. + k (`torch.Tensor`): The key tensor. + cos (`torch.Tensor`): The cosine part of the rotary embedding. + sin (`torch.Tensor`): The sine part of the rotary embedding. + position_ids (`torch.Tensor`, *optional*): + Deprecated and unused. + unsqueeze_dim (`int`, *optional*, defaults to 1): + The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and + sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note + that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and + k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes + cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have + the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. + Returns: + `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. + """ + q_type, k_type = q.dtype, k.dtype + cos = cos.unsqueeze(unsqueeze_dim) + sin = sin.unsqueeze(unsqueeze_dim) + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + return q_embed.to(q_type), k_embed.to(k_type) + + +def rotate_half(x): + """Rotates half the hidden dims of the input.""" + x1 = x[..., : x.shape[-1] // 2] + x2 = x[..., x.shape[-1] // 2 :] + return torch.cat((-x2, x1), dim=-1) + + +class FlexOlmoAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: FlexOlmoConfig, layer_idx: Optional[int] = None): + super().__init__() + self.config = config + self.layer_idx = layer_idx + self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) + self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads + self.scaling = self.head_dim**-0.5 + self.attention_dropout = config.attention_dropout + self.is_causal = True + + self.q_proj = nn.Linear( + config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias + ) + self.k_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.v_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.o_proj = nn.Linear( + config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias + ) + self.q_norm = FlexOlmoRMSNorm(config.num_attention_heads * self.head_dim, config.rms_norm_eps) + self.k_norm = FlexOlmoRMSNorm(config.num_key_value_heads * self.head_dim, config.rms_norm_eps) + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor]]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_norm(self.q_proj(hidden_states)) + key_states = self.k_norm(self.k_proj(hidden_states)) + value_states = self.v_proj(hidden_states) + + query_states = query_states.view(hidden_shape).transpose(1, 2) + key_states = key_states.view(hidden_shape).transpose(1, 2) + value_states = value_states.view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class FlexOlmoSparseMoeBlock(nn.Module): + def __init__(self, config): + super().__init__() + self.num_experts = config.num_experts + self.top_k = config.num_experts_per_tok + self.norm_topk_prob = config.norm_topk_prob + self.gate = nn.Linear(config.hidden_size, self.num_experts, bias=False) + self.experts = nn.ModuleList([FlexOlmoMLP(config) for _ in range(self.num_experts)]) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + batch_size, sequence_length, hidden_dim = hidden_states.shape + hidden_states = hidden_states.view(-1, hidden_dim) + # router_logits: (batch * sequence_length, n_experts) + router_logits = self.gate(hidden_states) + + routing_weights = F.softmax(router_logits, dim=1, dtype=torch.float) + routing_weights, selected_experts = torch.topk(routing_weights, self.top_k, dim=-1) + if self.norm_topk_prob: + routing_weights /= routing_weights.sum(dim=-1, keepdim=True) + # we cast back to the input dtype + routing_weights = routing_weights.to(hidden_states.dtype) + + final_hidden_states = torch.zeros( + (batch_size * sequence_length, hidden_dim), dtype=hidden_states.dtype, device=hidden_states.device + ) + + # One hot encode the selected experts to create an expert mask + # this will be used to easily index which expert is going to be selected + expert_mask = torch.nn.functional.one_hot(selected_experts, num_classes=self.num_experts).permute(2, 1, 0) + + # Loop over all available experts in the model and perform the computation on each expert + for expert_idx in range(self.num_experts): + expert_layer = self.experts[expert_idx] + idx, top_x = torch.where(expert_mask[expert_idx]) + + # Index the correct hidden states and compute the expert hidden state for + # the current expert. We need to make sure to multiply the output hidden + # states by `routing_weights` on the corresponding tokens (top-1 and top-2) + current_state = hidden_states[None, top_x].reshape(-1, hidden_dim) + current_hidden_states = expert_layer(current_state) * routing_weights[top_x, idx, None] + + # However `index_add_` only support torch tensors for indexing so we'll use + # the `top_x` tensor here. + final_hidden_states.index_add_(0, top_x, current_hidden_states.to(hidden_states.dtype)) + final_hidden_states = final_hidden_states.reshape(batch_size, sequence_length, hidden_dim) + return final_hidden_states, router_logits + + +class FlexOlmoDecoderLayer(GradientCheckpointingLayer): + def __init__(self, config: FlexOlmoConfig, layer_idx: int): + super().__init__() + self.hidden_size = config.hidden_size + self.self_attn = FlexOlmoAttention(config=config, layer_idx=layer_idx) + + self.mlp = FlexOlmoSparseMoeBlock(config) + self.post_attention_layernorm = FlexOlmoRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_feedforward_layernorm = FlexOlmoRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + **kwargs, + ) -> torch.FloatTensor: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`, *optional*): + attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1, + query_sequence_length, key_sequence_length)` if default attention is used. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_router_logits (`bool`, *optional*): + Whether or not to return the logits of all the routers. They are useful for computing the router loss, + and should not be returned during inference. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + past_key_values (`Cache`, *optional*): cached past key and value projection states + cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): + Indices depicting the position of the input sequence tokens in the sequence + position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): + Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`, + with `head_dim` being the embedding dimension of each attention head. + kwargs (`dict`, *optional*): + Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code + into the model + """ + residual = hidden_states + + # Self Attention + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states, _ = self.mlp(hidden_states) + hidden_states = self.post_feedforward_layernorm(hidden_states) + hidden_states = residual + hidden_states + return hidden_states + + +@auto_docstring +class FlexOlmoPreTrainedModel(PreTrainedModel): + config: FlexOlmoConfig + base_model_prefix = "model" + supports_gradient_checkpointing = True + _no_split_modules = ["FlexOlmoDecoderLayer"] + _skip_keys_device_placement = ["past_key_values"] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _can_compile_fullgraph = False # MoE models don't work with torch.compile (`torch.where(condition)` not supported) + _supports_attention_backend = True + _can_record_outputs = { + "router_logits": OutputRecorder(FlexOlmoSparseMoeBlock, index=1), + "hidden_states": FlexOlmoDecoderLayer, + "attentions": FlexOlmoAttention, + } + + +@auto_docstring +class FlexOlmoModel(FlexOlmoPreTrainedModel): + def __init__(self, config: FlexOlmoConfig): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + + self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx) + self.layers = nn.ModuleList( + [FlexOlmoDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = FlexOlmoRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = FlexOlmoRotaryEmbedding(config=config) + self.gradient_checkpointing = False + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> MoeModelOutputWithPast: + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if use_cache and past_key_values is None: + past_key_values = DynamicCache(config=self.config) + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + causal_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for decoder_layer in self.layers[: self.config.num_hidden_layers]: + hidden_states = decoder_layer( + hidden_states, + position_embeddings=position_embeddings, + attention_mask=causal_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + + return MoeModelOutputWithPast( # only diff with Mistral is the output type, we need MoE + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) + + +def load_balancing_loss_func( + gate_logits: Union[torch.Tensor, tuple[torch.Tensor], None], + num_experts: Optional[int] = None, + top_k=2, + attention_mask: Optional[torch.Tensor] = None, +) -> Union[torch.Tensor, int]: + r""" + Computes auxiliary load balancing loss as in Switch Transformer - implemented in Pytorch. + + See Switch Transformer (https://huggingface.co/papers/2101.03961) for more details. This function implements the loss + function presented in equations (4) - (6) of the paper. It aims at penalizing cases where the routing between + experts is too unbalanced. + + Args: + gate_logits: + Logits from the `gate`, should be a tuple of model.config.num_hidden_layers tensors of + shape [batch_size X sequence_length, num_experts]. + num_experts: + Number of experts + top_k: + The number of experts to route per-token, can be also interpreted as the `top-k` routing + parameter. + attention_mask (`torch.Tensor`, *optional*): + The attention_mask used in forward function + shape [batch_size X sequence_length] if not None. + + Returns: + The auxiliary loss. + """ + if gate_logits is None or not isinstance(gate_logits, tuple): + return 0 + + if isinstance(gate_logits, tuple): + compute_device = gate_logits[0].device + concatenated_gate_logits = torch.cat([layer_gate.to(compute_device) for layer_gate in gate_logits], dim=0) + + routing_weights = torch.nn.functional.softmax(concatenated_gate_logits, dim=-1) + + _, selected_experts = torch.topk(routing_weights, top_k, dim=-1) + + expert_mask = torch.nn.functional.one_hot(selected_experts, num_experts) + + if attention_mask is None: + # Compute the percentage of tokens routed to each experts + tokens_per_expert = torch.mean(expert_mask.float(), dim=0) + + # Compute the average probability of routing to these experts + router_prob_per_expert = torch.mean(routing_weights, dim=0) + else: + batch_size, sequence_length = attention_mask.shape + num_hidden_layers = concatenated_gate_logits.shape[0] // (batch_size * sequence_length) + + # Compute the mask that masks all padding tokens as 0 with the same shape of expert_mask + expert_attention_mask = ( + attention_mask[None, :, :, None, None] + .expand((num_hidden_layers, batch_size, sequence_length, top_k, num_experts)) + .reshape(-1, top_k, num_experts) + .to(compute_device) + ) + + # Compute the percentage of tokens routed to each experts + tokens_per_expert = torch.sum(expert_mask.float() * expert_attention_mask, dim=0) / torch.sum( + expert_attention_mask, dim=0 + ) + + # Compute the mask that masks all padding tokens as 0 with the same shape of tokens_per_expert + router_per_expert_attention_mask = ( + attention_mask[None, :, :, None] + .expand((num_hidden_layers, batch_size, sequence_length, routing_weights.shape[1])) + .reshape(-1, routing_weights.shape[1]) + .to(compute_device) + ) + + # Compute the average probability of routing to these experts + router_prob_per_expert = torch.sum(routing_weights * router_per_expert_attention_mask, dim=0) / torch.sum( + router_per_expert_attention_mask, dim=0 + ) + + device_index = routing_weights.device.index if routing_weights.device.index is not None else 0 + rank = routing_weights.shape[1] * int(device_index) + overall_loss = torch.sum( + tokens_per_expert[:, rank : rank + routing_weights.shape[1]] * router_prob_per_expert.unsqueeze(0) + ) + return overall_loss * num_experts + + +class FlexOlmoForCausalLM(FlexOlmoPreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.weight"] + + def __init__(self, config): + super().__init__(config) + self.model = FlexOlmoModel(config) + self.vocab_size = config.vocab_size + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + self.router_aux_loss_coef = config.router_aux_loss_coef + self.num_experts = config.num_experts + self.num_experts_per_tok = config.num_experts_per_tok + # Initialize weights and apply final processing + self.post_init() + + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + output_router_logits: Optional[bool] = None, + return_dict: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs, + ) -> Union[tuple, MoeCausalLMOutputWithPast]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + + Example: + + ```python + >>> from transformers import AutoTokenizer, FlexOlmoForCausalLM + + >>> model = FlexOlmoForCausalLM.from_pretrained("allenai/FlexOlmo-1B-7B-0924") + >>> tokenizer = AutoTokenizer.from_pretrained("allenai/FlexOlmo-1B-7B-0924") + + >>> prompt = "Hey, are you conscious? Can you talk to me?" + >>> inputs = tokenizer(prompt, return_tensors="pt") + + >>> # Generate + >>> generate_ids = model.generate(inputs.input_ids, max_length=30) + >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] + 'Hey, are you conscious? Can you talk to me?\nI’m not sure if you’re conscious of this, but I’m' + ``` + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_router_logits = ( + output_router_logits if output_router_logits is not None else self.config.output_router_logits + ) + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn) + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + output_router_logits=output_router_logits, + return_dict=return_dict, + cache_position=cache_position, + ) + + hidden_states = outputs[0] + # Only compute necessary logits, and do not upcast them to float if we are not computing the loss + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]) + + loss = None + if labels is not None: + loss = self.loss_function(logits, labels, self.vocab_size, **kwargs) + + aux_loss = None + if output_router_logits: + aux_loss = load_balancing_loss_func( + outputs.router_logits if return_dict else outputs[-1], + self.num_experts, + self.num_experts_per_tok, + attention_mask, + ) + if labels is not None: + loss += self.router_aux_loss_coef * aux_loss.to(loss.device) # make sure to reside in the same device + + if not return_dict: + output = (logits,) + outputs[1:] + if output_router_logits: + output = (aux_loss,) + output + return (loss,) + output if loss is not None else output + + return MoeCausalLMOutputWithPast( + loss=loss, + aux_loss=aux_loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + router_logits=outputs.router_logits, + ) + + +__all__ = ["FlexOlmoForCausalLM", "FlexOlmoModel", "FlexOlmoPreTrainedModel"] diff --git a/src/transformers/models/flex_olmo/modular_flex_olmo.py b/src/transformers/models/flex_olmo/modular_flex_olmo.py new file mode 100644 index 000000000000..0d0127e4d4b2 --- /dev/null +++ b/src/transformers/models/flex_olmo/modular_flex_olmo.py @@ -0,0 +1,353 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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. + +from typing import Optional + +import torch + +from ...cache_utils import Cache, DynamicCache +from ...masking_utils import create_causal_mask +from ...modeling_outputs import MoeModelOutputWithPast +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring +from ...utils.generic import check_model_inputs +from ..mixtral.modeling_mixtral import MixtralModel, MixtralPreTrainedModel +from ..olmo2.modeling_olmo2 import Olmo2Attention, Olmo2RMSNorm, Olmo2RotaryEmbedding +from ..olmoe.configuration_olmoe import OlmoeConfig +from ..olmoe.modeling_olmoe import ( + OlmoeDecoderLayer, + OlmoeForCausalLM, + OlmoeMLP, + OlmoeSparseMoeBlock, +) + + +class FlexOlmoConfig(OlmoeConfig): + r""" + This is the configuration class to store the configuration of a [`FlexOlmoModel`]. It is used to instantiate an FlexOlmo + 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 [allenai/FlexOlmo-7x7B-1T](https://huggingface.co/allenai/FlexOlmo-7x7B-1T). + + 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 100352): + Vocabulary size of the FlexOlmo model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`FlexOlmoModel`] + hidden_size (`int`, *optional*, defaults to 4096): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 11008): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 32): + Number of hidden layers in the Transformer decoder. + num_attention_heads (`int`, *optional*, defaults to 32): + Number of attention heads for each attention layer in the Transformer decoder. + num_key_value_heads (`int`, *optional*): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to + `num_attention_heads`. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 4096): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + pad_token_id (`int`, *optional*, defaults to 100277): + Padding token id. + bos_token_id (`int`, *optional*): + Beginning of stream token id. + eos_token_id (`int`, *optional*, defaults to 100257): + End of stream token id. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether to tie weight embeddings + rope_theta (`float`, *optional*, defaults to 500000.0): + The base period of the RoPE embeddings. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. Currently supports two scaling + strategies: linear and dynamic. Their scaling factor must be a float greater than 1. The expected format is + `{"type": strategy name, "factor": scaling factor}`. When using this flag, don't update + `max_position_embeddings` to the expected new maximum. See the following thread for more information on how + these scaling strategies behave: + https://www.reddit.com/r/LocalLLaMA/comments/14mrgpr/dynamically_scaled_rope_further_increases/. This is an + experimental feature, subject to breaking API changes in future versions. + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + num_experts_per_tok (`int`, *optional*, defaults to 5): + Number of selected experts. + num_experts (`int`, *optional*, defaults to 7): + Number of routed experts. + output_router_logits (`bool`, *optional*, defaults to `False`): + Whether or not the router logits should be returned by the model. Enabling this will also + allow the model to output the auxiliary loss, including load balancing loss and router z-loss. + router_aux_loss_coef (`float`, *optional*, defaults to 0.01): + The aux loss factor for the total loss. + norm_topk_prob (`bool`, *optional*, defaults to `False`): + Whether to normalize the topk probabilities. + + ```python + >>> from transformers import FlexOlmoModel, FlexOlmoConfig + + >>> # Initializing a FlexOlmo style configuration + >>> configuration = FlexOlmoConfig() + + >>> # Initializing a model from the FlexOlmo style configuration + >>> model = FlexOlmoModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "flex_olmo" + keys_to_ignore_at_inference = ["past_key_values"] + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.k_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.v_proj": "colwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.self_attn.o_proj": "rowwise_rep", # we need to replicate here due to the added norm on q and k + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=100352, + hidden_size=4096, + intermediate_size=11008, + num_hidden_layers=32, + num_attention_heads=32, + num_key_value_heads=None, + hidden_act="silu", + max_position_embeddings=4096, + initializer_range=0.02, + rms_norm_eps=1e-06, + use_cache=True, + pad_token_id=100277, + bos_token_id=None, + eos_token_id=100257, + tie_word_embeddings=False, + rope_theta=500000.0, + rope_scaling=None, + attention_bias=False, + attention_dropout=0.0, + num_experts_per_tok=5, + num_experts=7, + output_router_logits=False, + router_aux_loss_coef=0.01, + norm_topk_prob=False, + **kwargs, + ): + super().__init__( + vocab_size=vocab_size, + max_position_embeddings=max_position_embeddings, + hidden_size=hidden_size, + intermediate_size=intermediate_size, + num_hidden_layers=num_hidden_layers, + num_attention_heads=num_attention_heads, + num_key_value_heads=num_key_value_heads, + hidden_act=hidden_act, + initializer_range=initializer_range, + rms_norm_eps=rms_norm_eps, + use_cache=use_cache, + rope_theta=rope_theta, + rope_scaling=rope_scaling, + attention_bias=attention_bias, + attention_dropout=attention_dropout, + num_experts_per_tok=num_experts_per_tok, + num_experts=num_experts, + output_router_logits=output_router_logits, + router_aux_loss_coef=router_aux_loss_coef, + norm_topk_prob=norm_topk_prob, + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + tie_word_embeddings=tie_word_embeddings, + **kwargs, + ) + + del self.clip_qkv + + +# FlexOlmo RMS norm reuses Olmo2 RMS norm, which handles low precision slightly differently than the original Olmoe. +class FlexOlmoRMSNorm(Olmo2RMSNorm): + pass + + +# FlexOlmo RMS norm reuses Olmo2 RMS norm, so that the output cos and sin are returned +# as float32 rather than the input type. +class FlexOlmoRotaryEmbedding(Olmo2RotaryEmbedding): + pass + + +class FlexOlmoMLP(OlmoeMLP): + pass + + +# FlexOlmo uses Olmo2 attention instead of OlmoE Attention since its `apply_rotary_pos_emb` +# implementation handles lower precision more faithfully to the Olmo codebase. +class FlexOlmoAttention(Olmo2Attention): + pass + + +class FlexOlmoSparseMoeBlock(OlmoeSparseMoeBlock): + pass + + +# FlexOlmo decoder layer is identical to OlmoE decoder layer except: +# - Norm is applied after attention/feedforward rather than before. +class FlexOlmoDecoderLayer(OlmoeDecoderLayer): + def __init__(self, config: FlexOlmoConfig, layer_idx: int): + super().__init__(config, layer_idx=layer_idx) + self.post_attention_layernorm = FlexOlmoRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_feedforward_layernorm = FlexOlmoRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.self_attn = FlexOlmoAttention(config=config, layer_idx=layer_idx) + del self.input_layernorm + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + **kwargs, + ) -> torch.FloatTensor: + residual = hidden_states + + # Self Attention + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states, _ = self.mlp(hidden_states) + hidden_states = self.post_feedforward_layernorm(hidden_states) + hidden_states = residual + hidden_states + return hidden_states + + +# FlexOlmo uses Mixtral model as its base instead of OlmoE model since Mixtral is more up-to-date with the rest +# of the transformers library. For example, it uses the newer mechanisms of recording submodule outputs. +class FlexOlmoPreTrainedModel(MixtralPreTrainedModel): + pass + + +# FlexOlmo uses Mixtral model as its base instead of OlmoE model since Mixtral is more up-to-date with the rest +# of the transformers library. For example, it uses the newer mechanisms of recording submodule outputs. +# FlexOlmo model is identical to Mixtral model except: +# - FlexOlmo does not use sliding window attention. +class FlexOlmoModel(MixtralModel): + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> MoeModelOutputWithPast: + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if use_cache and past_key_values is None: + past_key_values = DynamicCache(config=self.config) + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + causal_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for decoder_layer in self.layers[: self.config.num_hidden_layers]: + hidden_states = decoder_layer( + hidden_states, + position_embeddings=position_embeddings, + attention_mask=causal_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + + return MoeModelOutputWithPast( # only diff with Mistral is the output type, we need MoE + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) + + +class FlexOlmoForCausalLM(OlmoeForCausalLM): + pass + + +__all__ = [ + "FlexOlmoConfig", + "FlexOlmoForCausalLM", + "FlexOlmoModel", + "FlexOlmoPreTrainedModel", +] diff --git a/tests/models/flex_olmo/__init__.py b/tests/models/flex_olmo/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/models/flex_olmo/test_modeling_flex_olmo.py b/tests/models/flex_olmo/test_modeling_flex_olmo.py new file mode 100644 index 000000000000..b73807502873 --- /dev/null +++ b/tests/models/flex_olmo/test_modeling_flex_olmo.py @@ -0,0 +1,126 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Team. All rights reserved. +# +# 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 FlexOlmo model.""" + +import unittest + +import pytest + +from transformers import FlexOlmoConfig, is_torch_available +from transformers.models.auto.tokenization_auto import AutoTokenizer +from transformers.testing_utils import ( + Expectations, + cleanup, + require_torch, + slow, + torch_device, +) + +from ...causal_lm_tester import CausalLMModelTest, CausalLMModelTester + + +if is_torch_available(): + import torch + + from transformers import ( + FlexOlmoForCausalLM, + FlexOlmoModel, + ) + from transformers.models.flex_olmo.modeling_flex_olmo import FlexOlmoRotaryEmbedding + + +class FlexOlmoModelTester(CausalLMModelTester): + if is_torch_available(): + config_class = FlexOlmoConfig + base_model_class = FlexOlmoModel + causal_lm_class = FlexOlmoForCausalLM + + +@require_torch +class FlexOlmoModelTest(CausalLMModelTest, unittest.TestCase): + all_model_classes = (FlexOlmoModel, FlexOlmoForCausalLM) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": FlexOlmoModel, + "text-generation": FlexOlmoForCausalLM, + } + if is_torch_available() + else {} + ) + test_headmasking = False + test_pruning = False + fx_compatible = False + test_torchscript = False + test_all_params_have_gradient = False + model_tester_class = FlexOlmoModelTester + rotary_embedding_layer = FlexOlmoRotaryEmbedding + + # Need to use `0.8` instead of `0.9` for `test_cpu_offload` + # This is because we are hitting edge cases with the causal_mask buffer + model_split_percents = [0.5, 0.7, 0.8] + + # used in `test_torch_compile_for_training` + _torch_compile_train_cls = FlexOlmoForCausalLM if is_torch_available() else None + + @unittest.skip("Dynamic control flow in MoE") + @pytest.mark.torch_compile_test + def test_torch_compile_for_training(self): + pass + + +@require_torch +class FlexOlmoIntegrationTest(unittest.TestCase): + def setUp(self): + cleanup(torch_device, gc_collect=True) + + def tearDown(self): + cleanup(torch_device, gc_collect=True) + + @slow + def test_model_7b_logits(self): + input_ids = [[1, 306, 4658, 278, 6593, 310, 2834, 338]] + model = FlexOlmoForCausalLM.from_pretrained("shanearora/Flex-reddit-2x7B-1T").to( + torch_device, dtype=torch.bfloat16 + ) + out = model(torch.tensor(input_ids, device=torch_device)).logits.float() + # Expected mean on dim = -1 + expectations = Expectations( + { + ("cuda", 8): [[-5.4202, -5.3883, -2.3924, -2.1226, -6.0122, -5.4173, -5.4571, -5.8256]], + } + ) + EXPECTED_MEAN = torch.tensor(expectations.get_expectation(), device=torch_device) + torch.testing.assert_close(out.mean(-1), EXPECTED_MEAN, rtol=1e-2, atol=1e-2) + # slicing logits[0, 0, 0:30] + expectations = Expectations( + { + ("cuda", 8): [ 0.5547, -3.6250, -7.2812, -5.0312, -5.9062, -5.3438, -4.2500, -4.6875, -3.4219, -4.6250, -6.5938, -3.1250, -6.0625, -2.0781, -6.4688, -0.4941, 1.2656, 0.7578, -0.1934, -0.4160, -0.6992, -0.9531, -0.9648, -1.3125, -1.2578, -4.5625, -2.4219, -5.6250, 0.7695, -4.5938], + } + ) # fmt: skip + EXPECTED_SLICE = torch.tensor(expectations.get_expectation(), device=torch_device) + torch.testing.assert_close(out[0, 0, :30], EXPECTED_SLICE, rtol=1e-2, atol=1e-2) + + @slow + def test_model_7b_greedy_generation(self): + EXPECTED_TEXT_COMPLETION = """Simply put, the theory of relativity states that 1) the laws of physics are the same in all inertial frames of reference, and 2) the speed of light is constant in all inertial frames of reference. The first statement is called the principle of relativity, and the second is called the constancy of the speed of light. The first statement is""" + prompt = "Simply put, the theory of relativity states that " + tokenizer = AutoTokenizer.from_pretrained("allenai/dolma2-tokenizer", device_map="auto") + model = FlexOlmoForCausalLM.from_pretrained("shanearora/Flex-reddit-2x7B-1T", device_map="auto") + input_ids = tokenizer.encode(prompt, return_tensors="pt").to(model.device) + + # greedy generation outputs + generated_ids = model.generate(input_ids, max_new_tokens=64, top_p=None, temperature=1, do_sample=False) + text = tokenizer.decode(generated_ids[0], skip_special_tokens=True) + self.assertEqual(EXPECTED_TEXT_COMPLETION, text) From 3ab94a18976330307ed485f1999acafc2b7aa3d4 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Thu, 18 Sep 2025 17:05:50 +0800 Subject: [PATCH 097/204] Don't list dropout in eager_paged_attention_forward (#40924) Remove dropout argument Signed-off-by: Yuanyuan Chen --- src/transformers/integrations/eager_paged.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/transformers/integrations/eager_paged.py b/src/transformers/integrations/eager_paged.py index 8293bd049c80..29d078ad2cad 100644 --- a/src/transformers/integrations/eager_paged.py +++ b/src/transformers/integrations/eager_paged.py @@ -23,7 +23,6 @@ def eager_paged_attention_forward( value: torch.Tensor, attention_mask: Optional[torch.Tensor], # shape [seqlen_q, seqlen_k] scaling: float, - dropout: float = 0.0, **kwargs, ): # Add KV cache to the key and value tensors From 9f65eab2e304e1224eb4ff5b95131e8097f0616f Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Thu, 18 Sep 2025 11:47:14 +0200 Subject: [PATCH 098/204] Update expected values for one more `test_speculative_generation` after #40949 (#40967) fix Co-authored-by: ydshieh --- tests/models/qwen3_moe/test_modeling_qwen3_moe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/models/qwen3_moe/test_modeling_qwen3_moe.py b/tests/models/qwen3_moe/test_modeling_qwen3_moe.py index 7fd07e45e222..79c01f5af140 100644 --- a/tests/models/qwen3_moe/test_modeling_qwen3_moe.py +++ b/tests/models/qwen3_moe/test_modeling_qwen3_moe.py @@ -232,7 +232,7 @@ def test_model_15b_a2b_long_prompt_sdpa(self): @slow def test_speculative_generation(self): EXPECTED_TEXT_COMPLETION = ( - "To be or not to be: the role of the liver in the pathogenesis of obesity and type 2 diabetes.\nThe" + "To be or not to be: a question of life and death\n\nThe question of life and death is a question that has" ) prompt = "To be or not to" tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-30B-A3B-Base", use_fast=False) From 4a5f348aafb74c1ffd9e5a48b683ff05bf109efb Mon Sep 17 00:00:00 2001 From: Rangehow <88258534+rangehow@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:57:21 +0800 Subject: [PATCH 099/204] FIX(trainer): ensure final checkpoint is saved when resuming training (#40347) * fix(trainer): ensure final checkpoint is saved when resuming training * add test * make style && slight fix of test * make style again * move test code to test_trainer * remove outdated test file * Apply style fixes --------- Co-authored-by: rangehow Co-authored-by: github-actions[bot] Co-authored-by: Marc Sun <57196510+SunMarc@users.noreply.github.com> --- src/transformers/trainer.py | 36 ++++------- tests/trainer/test_trainer.py | 109 ++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 24 deletions(-) diff --git a/src/transformers/trainer.py b/src/transformers/trainer.py index 49e14ce56574..97de1d6d5397 100755 --- a/src/transformers/trainer.py +++ b/src/transformers/trainer.py @@ -2533,7 +2533,6 @@ def _inner_training_loop( start_time = time.time() epochs_trained = 0 steps_trained_in_current_epoch = 0 - steps_trained_progress_bar = None # Check if continuing training from a checkpoint if resume_from_checkpoint is not None and os.path.isfile( @@ -2594,18 +2593,18 @@ def _inner_training_loop( ) self.control = self.callback_handler.on_epoch_begin(args, self.state, self.control) - if epoch == epochs_trained and resume_from_checkpoint is not None and steps_trained_in_current_epoch == 0: - self._load_rng_state(resume_from_checkpoint) - + step = -1 rng_to_sync = False - steps_skipped = 0 - if steps_trained_in_current_epoch > 0: - epoch_dataloader = skip_first_batches(epoch_dataloader, steps_trained_in_current_epoch) - steps_skipped = steps_trained_in_current_epoch - steps_trained_in_current_epoch = 0 - rng_to_sync = True - step = -1 + # Handle resumption from checkpoint + if epoch == epochs_trained and resume_from_checkpoint is not None: + if steps_trained_in_current_epoch > 0 and not args.ignore_data_skip: + epoch_dataloader = skip_first_batches(epoch_dataloader, steps_trained_in_current_epoch) + step = steps_trained_in_current_epoch - 1 + rng_to_sync = True + elif steps_trained_in_current_epoch == 0: + self._load_rng_state(resume_from_checkpoint) + epoch_iterator = iter(epoch_dataloader) # We chunkify the epoch iterator into gradient accumulation steps `n` batches remainder = steps_in_epoch % args.gradient_accumulation_steps @@ -2658,22 +2657,11 @@ def _inner_training_loop( input_tokens = torch.tensor(input_tokens, device=self.args.device, dtype=torch.int64) self.state.num_input_tokens_seen += self.accelerator.gather(input_tokens).sum().item() + if rng_to_sync: self._load_rng_state(resume_from_checkpoint) rng_to_sync = False - # Skip past any already trained steps if resuming training - if steps_trained_in_current_epoch > 0: - steps_trained_in_current_epoch -= 1 - if steps_trained_progress_bar is not None: - steps_trained_progress_bar.update(1) - if steps_trained_in_current_epoch == 0: - self._load_rng_state(resume_from_checkpoint) - continue - elif steps_trained_progress_bar is not None: - steps_trained_progress_bar.close() - steps_trained_progress_bar = None - if step % args.gradient_accumulation_steps == 0: self.control = self.callback_handler.on_step_begin(args, self.state, self.control) @@ -2765,7 +2753,7 @@ def _inner_training_loop( model.zero_grad() self.state.global_step += 1 - self.state.epoch = epoch + (step + 1 + steps_skipped) / steps_in_epoch + self.state.epoch = epoch + (step + 1) / steps_in_epoch self.control = self.callback_handler.on_step_end(args, self.state, self.control) self._maybe_log_save_evaluate( tr_loss, diff --git a/tests/trainer/test_trainer.py b/tests/trainer/test_trainer.py index 4d011033186a..47e1004df9b6 100644 --- a/tests/trainer/test_trainer.py +++ b/tests/trainer/test_trainer.py @@ -5158,6 +5158,115 @@ def test_trainer_works_without_model_config(self): ) trainer.train() + @require_safetensors + def test_resume_from_interrupted_training(self): + """ + Tests resuming training from a checkpoint after a simulated interruption. + """ + + # --- Helper classes and functions defined locally for this test --- + class DummyModel(nn.Module): + def __init__(self, input_dim=10, num_labels=2): + super().__init__() + self.linear = nn.Linear(input_dim, num_labels) + + def forward(self, input_ids=None, attention_mask=None, labels=None): + logits = self.linear(input_ids.float()) + loss = None + if labels is not None: + loss_fn = nn.CrossEntropyLoss() + loss = loss_fn(logits, labels) + return {"loss": loss, "logits": logits} + + class DummyDictDataset(torch.utils.data.Dataset): + def __init__(self, input_ids, attention_mask, labels): + self.input_ids = input_ids + self.attention_mask = attention_mask + self.labels = labels + + def __len__(self): + return len(self.input_ids) + + def __getitem__(self, idx): + return { + "input_ids": self.input_ids[idx], + "attention_mask": self.attention_mask[idx], + "labels": self.labels[idx], + } + + def create_dummy_dataset(): + """Creates a dummy dataset for this specific test.""" + num_samples = 13 + input_dim = 10 + dummy_input_ids = torch.rand(num_samples, input_dim) + dummy_attention_mask = torch.ones(num_samples, input_dim) + dummy_labels = torch.randint(0, 2, (num_samples,)) + return DummyDictDataset(dummy_input_ids, dummy_attention_mask, dummy_labels) + + # 1. Set up a dummy model and dataset + model = DummyModel(input_dim=10, num_labels=2) + dummy_dataset = create_dummy_dataset() + + # 2. First training phase (simulating an interruption) + output_dir_initial = self.get_auto_remove_tmp_dir() + training_args_initial = TrainingArguments( + output_dir=output_dir_initial, + num_train_epochs=1, + per_device_train_batch_size=2, + gradient_accumulation_steps=3, + save_strategy="steps", + save_steps=1, # Save at every step + report_to=[], # Disable wandb/tensorboard and other loggers + max_steps=2, # Stop after step 2 to simulate interruption + ) + + trainer_initial = Trainer( + model=model, + args=training_args_initial, + train_dataset=dummy_dataset, + ) + trainer_initial.train() + + # 3. Verify that a checkpoint was created before the "interruption" + checkpoint_path = os.path.join(output_dir_initial, "checkpoint-2") + self.assertTrue(os.path.exists(checkpoint_path), f"Checkpoint not found at {checkpoint_path}") + + # 4. Second training phase (resuming from the checkpoint) + output_dir_resumed = self.get_auto_remove_tmp_dir() + # Note: total steps for one epoch is ceil(13 / (2*3)) = 3. + # We stopped at step 2, so the resumed training should run for 1 more step. + training_args_resumed = TrainingArguments( + output_dir=output_dir_resumed, + num_train_epochs=1, + per_device_train_batch_size=2, + gradient_accumulation_steps=3, + save_strategy="steps", + save_steps=1, + report_to=[], + ) + + trainer_resumed = Trainer( + model=model, + args=training_args_resumed, + train_dataset=dummy_dataset, + ) + # Resume from the interrupted checkpoint and finish the remaining training + trainer_resumed.train(resume_from_checkpoint=checkpoint_path) + + # 5. Assertions: Check if the training completed and the final model was saved + # The training should have completed step 3. + # Total steps per epoch = ceil(13 samples / (2 batch_size * 3 grad_accum)) = 3 + self.assertEqual(trainer_resumed.state.global_step, 3) + + # Check that a checkpoint for the final step exists. + final_checkpoint_path = os.path.join(output_dir_resumed, "checkpoint-3") + self.assertTrue(os.path.exists(final_checkpoint_path)) + + # Check if the model weights file exists in the final checkpoint directory. + # Trainer saves non-PreTrainedModel models as `model.safetensors` by default if safetensors is available. + final_model_path = os.path.join(final_checkpoint_path, SAFE_WEIGHTS_NAME) + self.assertTrue(os.path.exists(final_model_path), "Final model checkpoint was not saved!") + @require_torch @is_staging_test From b38d52a31a85dbc78468ed1ae75d8b6c36bc22d4 Mon Sep 17 00:00:00 2001 From: Raushan Turganbay Date: Thu, 18 Sep 2025 13:01:58 +0200 Subject: [PATCH 100/204] Add new model LFM2-VL (#40624) * Add LFM2-VL support * add tests * linting, formatting, misc review changes * add siglip2 to auto config and instantiate it in lfm2-vl configuration * decouple image processor from processor * remove torch import from configuration * replace | with Optional * remove layer truncation from modeling file * fix copies * update everything * fix test case to use tiny model * update the test cases * fix finally the image processor and add slow tests * fixup * typo in docs * fix tests * the doc name uses underscore * address comments from Yoni * delete tests and unsuffling * relative import * do we really handle imports better now? * fix test * slow tests * found a bug in ordering + slow tests * fix copies * dont run compile test --------- Co-authored-by: Anna Co-authored-by: Anna Banaszak <48625325+ankke@users.noreply.github.com> --- docs/source/en/_toctree.yml | 2 + docs/source/en/model_doc/lfm2_vl.md | 96 +++ docs/source/ko/_toctree.yml | 2 + src/transformers/generation/utils.py | 1 + src/transformers/models/__init__.py | 1 + .../models/auto/configuration_auto.py | 4 + .../models/auto/image_processing_auto.py | 1 + src/transformers/models/auto/modeling_auto.py | 3 + .../models/auto/processing_auto.py | 1 + src/transformers/models/lfm2_vl/__init__.py | 29 + .../models/lfm2_vl/configuration_lfm2_vl.py | 91 +++ .../lfm2_vl/image_processing_lfm2_vl_fast.py | 546 ++++++++++++++++++ .../models/lfm2_vl/modeling_lfm2_vl.py | 497 ++++++++++++++++ .../models/lfm2_vl/modular_lfm2_vl.py | 352 +++++++++++ .../models/lfm2_vl/processing_lfm2_vl.py | 269 +++++++++ tests/generation/test_utils.py | 1 + tests/models/lfm2_vl/__init__.py | 0 .../lfm2_vl/test_image_processing_lfm2_vl.py | 289 +++++++++ tests/models/lfm2_vl/test_modeling_lfm2_vl.py | 296 ++++++++++ .../models/lfm2_vl/test_processing_lfm2_vl.py | 467 +++++++++++++++ tests/test_processing_common.py | 3 +- 21 files changed, 2950 insertions(+), 1 deletion(-) create mode 100644 docs/source/en/model_doc/lfm2_vl.md create mode 100755 src/transformers/models/lfm2_vl/__init__.py create mode 100755 src/transformers/models/lfm2_vl/configuration_lfm2_vl.py create mode 100755 src/transformers/models/lfm2_vl/image_processing_lfm2_vl_fast.py create mode 100755 src/transformers/models/lfm2_vl/modeling_lfm2_vl.py create mode 100644 src/transformers/models/lfm2_vl/modular_lfm2_vl.py create mode 100755 src/transformers/models/lfm2_vl/processing_lfm2_vl.py create mode 100644 tests/models/lfm2_vl/__init__.py create mode 100755 tests/models/lfm2_vl/test_image_processing_lfm2_vl.py create mode 100644 tests/models/lfm2_vl/test_modeling_lfm2_vl.py create mode 100755 tests/models/lfm2_vl/test_processing_lfm2_vl.py diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index d7fa25e185eb..3d1b0b169636 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -555,6 +555,8 @@ title: LED - local: model_doc/lfm2 title: LFM2 + - local: model_doc/lfm2_vl + title: LFM2-VL - local: model_doc/llama title: LLaMA - local: model_doc/llama2 diff --git a/docs/source/en/model_doc/lfm2_vl.md b/docs/source/en/model_doc/lfm2_vl.md new file mode 100644 index 000000000000..1607e3066905 --- /dev/null +++ b/docs/source/en/model_doc/lfm2_vl.md @@ -0,0 +1,96 @@ + + +
+PyTorch +
+ +# LFM2-VL + +## Overview + +[LFM2-VL](https://www.liquid.ai/blog/lfm2-vl-efficient-vision-language-models) first series of vision-language foundation models developed by [Liquid AI](https://liquid.ai/). These multimodal models are designed for low-latency and device-aware deployment. LFM2-VL extends the LFM2 family of open-weight Liquid Foundation Models (LFMs) into the vision-language space, supporting both text and image inputs with variable resolutions. + +## Architecture + +LFM2-VL consists of three main components: a language model backbone, a vision encoder, and a multimodal projector. LFM2-VL builds upon the LFM2 backbone, inheriting from either LFM2-1.2B (for LFM2-VL-1.6B) or LFM2-350M (for LFM2-VL-450M). For the vision tower, LFM2-VL uses SigLIP2 NaFlex encoders to convert input images into token sequences. Two variants are implemented: +* Shape-optimized (400M) for more fine-grained vision capabilities for LFM2-VL-1.6B +* Base (86M) for fast image processing for LFM2-VL-450M + +The encoder processes images at their native resolution up to 512×512 pixels, efficiently handling smaller images without upscaling and supporting non-standard aspect ratios without distortion. Larger images are split into non-overlapping square patches of 512×512 each, preserving detail. In LFM2-VL-1.6B, the model also receives a thumbnail (a small, downscaled version of the original image capturing the overall scene) to enhance global context understanding and alignment. Special tokens mark each patch’s position and indicate the thumbnail’s start. The multimodal connector is a 2-layer MLP connector with pixel unshuffle to reduce image token count. + +## Example + +The following example shows how to generate an answer using the `AutoModelForImageTextToText` class. + +```python +from transformers import AutoProcessor, AutoModelForImageTextToText +\ +# Load model and processor +model_id = "LiquidAI/LFM2-VL-1.6B" +model = AutoModelForImageTextToText.from_pretrained( + model_id, + device_map="auto", + dtype="bfloat16", +) +processor = AutoProcessor.from_pretrained(model_id) + +# Load image and create conversation +conversation = [ + { + "role": "user", + "content": [ + {"type": "image", "image": "https://www.ilankelman.org/stopsigns/australia.jpg"}, + {"type": "text", "text": "What is in this image?"}, + ], + }, +] + +# Generate snswer +inputs = processor.apply_chat_template( + conversation, + add_generation_prompt=True, + return_tensors="pt", + return_dict=True, + tokenize=True, +).to(model.device) + +outputs = model.generate(**inputs, max_new_tokens=64) +processor.batch_decode(outputs, skip_special_tokens=True)[0] + +``` + +## Lfm2VlImageProcessorFast + +[[autodoc]] Lfm2VlImageProcessorFast + +## Lfm2VlProcessor + +[[autodoc]] Lfm2VlProcessor + +## Lfm2VlConfig + +[[autodoc]] Lfm2VlConfig + +## Lfm2VlModel + +[[autodoc]] Lfm2VlModel + - forward + +## Lfm2VlForConditionalGeneration + +[[autodoc]] Lfm2VlForConditionalGeneration + - forward diff --git a/docs/source/ko/_toctree.yml b/docs/source/ko/_toctree.yml index df2d53c49a96..2412e497556f 100644 --- a/docs/source/ko/_toctree.yml +++ b/docs/source/ko/_toctree.yml @@ -607,6 +607,8 @@ title: LED - local: in_translation title: LFM2 + - local: in_translation + title: LFM2-VL - local: model_doc/llama title: LLaMA - local: model_doc/llama2 diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index 5affe68d1374..845e723e95f7 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -1907,6 +1907,7 @@ def _supports_default_dynamic_cache(cls) -> bool: "minimax", "xlnet", "lfm2", + "lfm2-vl", ] ) diff --git a/src/transformers/models/__init__.py b/src/transformers/models/__init__.py index 5c391e7162f4..c32c8a795488 100644 --- a/src/transformers/models/__init__.py +++ b/src/transformers/models/__init__.py @@ -183,6 +183,7 @@ from .led import * from .levit import * from .lfm2 import * + from .lfm2_vl import * from .lightglue import * from .lilt import * from .llama import * diff --git a/src/transformers/models/auto/configuration_auto.py b/src/transformers/models/auto/configuration_auto.py index 38f38cd31b40..06023f09c9d8 100644 --- a/src/transformers/models/auto/configuration_auto.py +++ b/src/transformers/models/auto/configuration_auto.py @@ -222,6 +222,7 @@ ("led", "LEDConfig"), ("levit", "LevitConfig"), ("lfm2", "Lfm2Config"), + ("lfm2_vl", "Lfm2VlConfig"), ("lightglue", "LightGlueConfig"), ("lilt", "LiltConfig"), ("llama", "LlamaConfig"), @@ -366,6 +367,7 @@ ("shieldgemma2", "ShieldGemma2Config"), ("siglip", "SiglipConfig"), ("siglip2", "Siglip2Config"), + ("siglip2_vision_model", "Siglip2VisionConfig"), ("siglip_vision_model", "SiglipVisionConfig"), ("smollm3", "SmolLM3Config"), ("smolvlm", "SmolVLMConfig"), @@ -657,6 +659,7 @@ ("led", "LED"), ("levit", "LeViT"), ("lfm2", "Lfm2"), + ("lfm2_vl", "Lfm2Vl"), ("lightglue", "LightGlue"), ("lilt", "LiLT"), ("llama", "LLaMA"), @@ -958,6 +961,7 @@ ("glm4v_moe_text", "glm4v_moe"), ("idefics3_vision", "idefics3"), ("siglip_vision_model", "siglip"), + ("siglip2_vision_model", "siglip2"), ("aimv2_vision_model", "aimv2"), ("smolvlm_vision", "smolvlm"), ("chinese_clip_vision_model", "chinese_clip"), diff --git a/src/transformers/models/auto/image_processing_auto.py b/src/transformers/models/auto/image_processing_auto.py index ebaa4a30849d..aa16ac3555eb 100644 --- a/src/transformers/models/auto/image_processing_auto.py +++ b/src/transformers/models/auto/image_processing_auto.py @@ -120,6 +120,7 @@ ("layoutlmv2", ("LayoutLMv2ImageProcessor", "LayoutLMv2ImageProcessorFast")), ("layoutlmv3", ("LayoutLMv3ImageProcessor", "LayoutLMv3ImageProcessorFast")), ("levit", ("LevitImageProcessor", "LevitImageProcessorFast")), + ("lfm2_vl", (None, "Lfm2VlImageProcessorFast")), ("lightglue", ("LightGlueImageProcessor", None)), ("llama4", ("Llama4ImageProcessor", "Llama4ImageProcessorFast")), ("llava", ("LlavaImageProcessor", "LlavaImageProcessorFast")), diff --git a/src/transformers/models/auto/modeling_auto.py b/src/transformers/models/auto/modeling_auto.py index 93420820fb9e..025a7a1f90a0 100644 --- a/src/transformers/models/auto/modeling_auto.py +++ b/src/transformers/models/auto/modeling_auto.py @@ -222,6 +222,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("led", "LEDModel"), ("levit", "LevitModel"), ("lfm2", "Lfm2Model"), + ("lfm2_vl", "Lfm2VlModel"), ("lightglue", "LightGlueForKeypointMatching"), ("lilt", "LiltModel"), ("llama", "LlamaModel"), @@ -356,6 +357,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("sew-d", "SEWDModel"), ("siglip", "SiglipModel"), ("siglip2", "Siglip2Model"), + ("siglip2_vision_model", "Siglip2VisionModel"), ("siglip_vision_model", "SiglipVisionModel"), ("smollm3", "SmolLM3Model"), ("smolvlm", "SmolVLMModel"), @@ -1026,6 +1028,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("janus", "JanusForConditionalGeneration"), ("kosmos-2", "Kosmos2ForConditionalGeneration"), ("kosmos-2.5", "Kosmos2_5ForConditionalGeneration"), + ("lfm2_vl", "Lfm2VlForConditionalGeneration"), ("llama4", "Llama4ForConditionalGeneration"), ("llava", "LlavaForConditionalGeneration"), ("llava_next", "LlavaNextForConditionalGeneration"), diff --git a/src/transformers/models/auto/processing_auto.py b/src/transformers/models/auto/processing_auto.py index 13583c55002f..c455c6850844 100644 --- a/src/transformers/models/auto/processing_auto.py +++ b/src/transformers/models/auto/processing_auto.py @@ -93,6 +93,7 @@ ("kyutai_speech_to_text", "KyutaiSpeechToTextProcessor"), ("layoutlmv2", "LayoutLMv2Processor"), ("layoutlmv3", "LayoutLMv3Processor"), + ("lfm2_vl", "Lfm2VlProcessor"), ("llama4", "Llama4Processor"), ("llava", "LlavaProcessor"), ("llava_next", "LlavaNextProcessor"), diff --git a/src/transformers/models/lfm2_vl/__init__.py b/src/transformers/models/lfm2_vl/__init__.py new file mode 100755 index 000000000000..7d0357ffbaa6 --- /dev/null +++ b/src/transformers/models/lfm2_vl/__init__.py @@ -0,0 +1,29 @@ +# Copyright 2025 The HuggingFace Team. All rights reserved. +# +# 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. +from typing import TYPE_CHECKING + +from ...utils import _LazyModule +from ...utils.import_utils import define_import_structure + + +if TYPE_CHECKING: + from .configuration_lfm2_vl import * + from .image_processing_lfm2_vl_fast import * + from .modeling_lfm2_vl import * + from .processing_lfm2_vl import * +else: + import sys + + _file = globals()["__file__"] + sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__) diff --git a/src/transformers/models/lfm2_vl/configuration_lfm2_vl.py b/src/transformers/models/lfm2_vl/configuration_lfm2_vl.py new file mode 100755 index 000000000000..1378fbe6dc8c --- /dev/null +++ b/src/transformers/models/lfm2_vl/configuration_lfm2_vl.py @@ -0,0 +1,91 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Inc. team. All rights reserved. +# +# 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. +"""PyTorch LFM2-VL model.""" + +from ...configuration_utils import PretrainedConfig +from ...utils import logging +from ..auto import CONFIG_MAPPING, AutoConfig + + +logger = logging.get_logger(__name__) + + +class Lfm2VlConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Lfm2VlForConditionalGeneration`]. It is used to instantiate an + Lfm2Vl 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 Lfm2-VL-1.6B. + + e.g. [LiquidAI/LFM2-VL-1.6B](https://huggingface.co/LiquidAI/LFM2-VL-1.6B) + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + vision_config (`AutoConfig | dict`, *optional*, defaults to `Siglip2ImageConfig`): + The config object or dictionary of the vision backbone. + text_config (`AutoConfig | dict`, *optional*, defaults to `Lfm2Config`): + The config object or dictionary of the text backbone. + image_token_id (`int`, *optional*, defaults to 396): + The image token index to encode the image prompt. + projector_hidden_act (`str`, *optional*, defaults to `"gelu"`): + The activation function used by the multimodal projector. + projector_hidden_size (`int`, *optional*, defaults to 2560): + The hidden size of the multimodal projector. + projector_bias (`bool`, *optional*, defaults to `True`): + Whether to use bias in the multimodal projector. + downsample_factor (`int`, *optional*, defaults to 2): + The downsample_factor factor of the vision backbone. + """ + + model_type = "lfm2-vl" + sub_configs = {"text_config": AutoConfig, "vision_config": AutoConfig} + + def __init__( + self, + vision_config=None, + text_config=None, + image_token_id=396, + projector_hidden_act="gelu", + projector_hidden_size=2560, + projector_bias=True, + downsample_factor=2, + **kwargs, + ): + self.image_token_id = image_token_id + self.projector_hidden_act = projector_hidden_act + self.projector_hidden_size = projector_hidden_size + self.projector_bias = projector_bias + self.downsample_factor = downsample_factor + + if isinstance(vision_config, dict): + vision_config["model_type"] = vision_config.get("model_type", "siglip2_vision_model") + vision_config = CONFIG_MAPPING[vision_config["model_type"]](**vision_config) + elif vision_config is None: + vision_config = CONFIG_MAPPING["siglip2_vision_model"]() + + if isinstance(text_config, dict): + text_config["model_type"] = text_config.get("model_type", "lfm2") + text_config = CONFIG_MAPPING[text_config["model_type"]](**text_config) + elif text_config is None: + text_config = CONFIG_MAPPING["lfm2"]() + + self.vision_config = vision_config + self.text_config = text_config + + super().__init__(**kwargs) + + +__all__ = ["Lfm2VlConfig"] diff --git a/src/transformers/models/lfm2_vl/image_processing_lfm2_vl_fast.py b/src/transformers/models/lfm2_vl/image_processing_lfm2_vl_fast.py new file mode 100755 index 000000000000..c709a01dca41 --- /dev/null +++ b/src/transformers/models/lfm2_vl/image_processing_lfm2_vl_fast.py @@ -0,0 +1,546 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Inc. team. All rights reserved. +# +# 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. +import math +from functools import lru_cache +from typing import Optional, Union + +import torch + +from ...image_processing_utils import BatchFeature +from ...image_processing_utils_fast import ( + BaseImageProcessorFast, + DefaultFastImageProcessorKwargs, + group_images_by_shape, + reorder_images, +) +from ...image_utils import ( + IMAGENET_STANDARD_MEAN, + IMAGENET_STANDARD_STD, + ImageInput, + PILImageResampling, + SizeDict, +) +from ...processing_utils import ( + Unpack, +) +from ...utils import ( + TensorType, + auto_docstring, + is_torchvision_v2_available, + logging, +) + + +if is_torchvision_v2_available(): + from torchvision.transforms.v2 import functional as F +else: + from torchvision.transforms import functional as F + +logger = logging.get_logger(__name__) + + +def round_by_factor(number: float, factor: int) -> int: + """Returns the closest integer to 'number' that is divisible by 'factor'.""" + return round(number / factor) * factor + + +def find_closest_aspect_ratio( + aspect_ratio: float, + target_ratios: list[tuple[int, int]], + width: int, + height: int, + image_size: int, +) -> tuple[int, int]: + """Find the closest aspect ratio from target_ratios to match the input aspect ratio. + + Args: + aspect_ratio: The aspect ratio to match (width/height). + target_ratios: List of possible aspect ratios as tuples of (width, height) integers. + width: Original image width in pixels. + height: Original image height in pixels. + image_size: Base size for calculating target area. + + Returns: + tuple[int, int]: The best matching ratio as (width, height) integers. + """ + best_ratio_diff = float("inf") + best_ratio = (1, 1) + area = width * height + + for ratio in target_ratios: + target_aspect_ratio = ratio[0] / ratio[1] + ratio_diff = abs(aspect_ratio - target_aspect_ratio) + + # update best ratio if we found a closer match + if ratio_diff < best_ratio_diff: + best_ratio_diff = ratio_diff + best_ratio = ratio + # if equally close, prefer the ratio that better matches the original image area + elif ratio_diff == best_ratio_diff: + target_area = image_size * image_size * ratio[0] * ratio[1] + if area > 0.5 * target_area: + best_ratio = ratio + + return best_ratio + + +# copied from Siglip2ImageProcessor +@lru_cache(maxsize=256) +def get_image_size_for_max_num_patches( + image_height: int, image_width: int, patch_size: int, max_num_patches: int, eps: float = 1e-5 +) -> tuple[int, int]: + """ + Determine image size based on max number of patches, ensure dimensions are divisible by patch size and image is at least 1 patch. + + Args: + image_height (`int`): + Original image height. + image_width (`int`): + Original image width. + patch_size (`int`): + Patch size for processing. + max_num_patches (`int`): + Maximum number of patches. + eps (`float`): + Small threshold for binary search. + + Returns: + Tuple: (target_height, target_width) + """ + + def get_scaled_image_size(scale: float, size: int, patch_size: int) -> int: + scaled_size = size * scale + scaled_size = math.ceil(scaled_size / patch_size) * patch_size # make divisible by patch_size + scaled_size = max(patch_size, scaled_size) # ensure at least 1 patch + return int(scaled_size) + + # Binary search for optimal scale + scale_min, scale_max = eps / 10, 100.0 + while (scale_max - scale_min) >= eps: + scale = (scale_min + scale_max) / 2 + target_height = get_scaled_image_size(scale, image_height, patch_size) + target_width = get_scaled_image_size(scale, image_width, patch_size) + num_patches = (target_height / patch_size) * (target_width / patch_size) + + if num_patches <= max_num_patches: + scale_min = scale + else: + scale_max = scale + + scale = scale_min + target_height = get_scaled_image_size(scale, image_height, patch_size) + target_width = get_scaled_image_size(scale, image_width, patch_size) + return target_height, target_width + + +def convert_image_to_patches(images: "torch.Tensor", patch_size: int) -> "torch.Tensor": + """ + Convert 3D array image of shape (image_height, image_width, num_channels) into 2D array of patches of shape + (num_patches_height * num_patches_width, patch_size * patch_size * num_channels). + """ + batch_size, num_channels, image_height, image_width = images.shape + num_patches_height = image_height // patch_size + num_patches_width = image_width // patch_size + patched_image = images.reshape( + batch_size, num_channels, num_patches_height, patch_size, num_patches_width, patch_size + ) + patched_image = patched_image.permute(0, 2, 4, 3, 5, 1) + patched_image = patched_image.reshape(batch_size, num_patches_height * num_patches_width, -1) + return patched_image + + +def pad_along_first_dim( + images: "torch.Tensor", target_length: int, pad_value: int = 0 +) -> tuple["torch.Tensor", "torch.Tensor"]: + """ + Pad the array along the first dimension. + """ + current_length = images.shape[1] + padding_length = target_length - current_length + pixel_mask = torch.ones((target_length,), dtype=torch.int32) + if padding_length > 0: + paddings = (0, 0, 0, padding_length, 0, 0) + images = torch.nn.functional.pad(images, paddings, mode="constant", value=pad_value) + pixel_mask[-padding_length:] = 0 + return images, pixel_mask + + +class Lfm2VlFastImageProcessorKwargs(DefaultFastImageProcessorKwargs): + """ + downsample_factor (`int`, *optional*, defaults to `2`): + The downsampling factor for images used when resizing the image. + """ + + downsample_factor: Optional[int] + do_image_splitting: Optional[bool] + min_tiles: Optional[int] + max_tiles: Optional[int] + use_thumbnail: Optional[bool] + min_image_tokens: Optional[int] + max_image_tokens: Optional[int] + encoder_patch_size: Optional[int] + tile_size: Optional[int] + max_pixels_tolerance: Optional[float] + do_pad: Optional[bool] + return_row_col_info: Optional[bool] + + +@auto_docstring +class Lfm2VlImageProcessorFast(BaseImageProcessorFast): + downsample_factor = 2 + do_image_splitting = True + min_tiles = 2 + max_tiles = 10 + use_thumbnail = True + min_image_tokens = 64 + max_image_tokens = 256 + encoder_patch_size = 16 + tile_size = 512 + max_pixels_tolerance = 2.0 + do_resize = True + size = {"height": 512, "width": 512} + resample = PILImageResampling.BILINEAR + do_rescale = True + rescale_factor = 1 / 255 + do_normalize = True + do_pad = True + return_row_col_info = False + image_mean = IMAGENET_STANDARD_STD + image_std = IMAGENET_STANDARD_MEAN + valid_kwargs = Lfm2VlFastImageProcessorKwargs + model_input_names = ["pixel_values", "pixel_attention_mask", "spatial_shapes"] + + def __init__(self, **kwargs: Unpack[Lfm2VlFastImageProcessorKwargs]): + super().__init__(**kwargs) + + max_thumbnail_image_patches = self.max_image_tokens * self.downsample_factor**2 + tile_size_patches = (self.tile_size // self.encoder_patch_size) ** 2 if self.do_image_splitting else 0 + self.max_num_patches = max( + max_thumbnail_image_patches, + tile_size_patches, + ) + + @lru_cache(maxsize=256) + def _target_ratios(self, min_tiles: int, max_tiles: int) -> list[tuple[int, int]]: + ratios = [ + (w, h) + for n in range(min_tiles, max_tiles + 1) + for w in range(1, n + 1) + for h in range(1, n + 1) + if min_tiles <= w * h <= max_tiles + ] + return sorted(set(ratios), key=lambda x: x[0] * x[1]) + + def _get_grid_layout( + self, + height: int, + width: int, + min_tiles: int, + max_tiles: int, + tile_size: int, + ) -> tuple[int, int]: + aspect_ratio = width / height + target_ratios = self._target_ratios(min_tiles, max_tiles) + + # find best matching grid configuration + grid_width, grid_height = find_closest_aspect_ratio(aspect_ratio, target_ratios, width, height, tile_size) + + target_width = tile_size * grid_width + target_height = tile_size * grid_height + total_patches = grid_width * grid_height + + return grid_width, grid_height, target_width, target_height, total_patches + + def crop_image_to_patches( + self, + image: "torch.Tensor", + min_tiles: int, + max_tiles: int, + tile_size: int, + use_thumbnail: bool, + thumbnail_size: tuple[int], + interpolation: "F.InterpolationMode" = None, + antialias: bool = True, + **kwargs, + ) -> "torch.Tensor": + """ + Processes a high resolution image into patches. + This method splits a high resolution image into a grid of smaller patches while trying to maintain + the original aspect ratio. It finds the optimal grid configuration within the specified tile constraints. + """ + batch_size, num_channels, height, width = image.shape + grid_width, grid_height, target_width, target_height, total_patches = self._get_grid_layout( + height, width, min_tiles=min_tiles, max_tiles=max_tiles, tile_size=tile_size + ) + resized_image = F.resize( + image, (target_height, target_width), interpolation=interpolation, antialias=antialias + ) + + # split the image into patches + processed_images = ( + resized_image.unfold(2, size=tile_size, step=tile_size) + .unfold(3, size=tile_size, step=tile_size) + .contiguous() + .view(batch_size, num_channels, -1, tile_size, tile_size) + .permute(2, 0, 1, 3, 4) + .reshape(batch_size, -1, num_channels, tile_size, tile_size) + ) + + # Re-order processed images to a nested image structure, so it can be reordered back correctly + # Note that the images can't be stacked because the thumbnail image is of bigger size than patches + # Each image in sublist will be of shape (1, C, H, W) + processed_images = list(processed_images) + + if use_thumbnail and grid_width * grid_height != 1: + total_patches += 1 + thumbnail_image = F.resize(image, thumbnail_size, interpolation=interpolation, antialias=antialias) + for i in range(batch_size): + processed_images[i] = list(processed_images[i]) + list(thumbnail_image[i][None, ...]) + + return processed_images, grid_width, grid_height + + # Adapted from Qwen-VL with minor differences + def smart_resize( + self, + height: int, + width: int, + downsample_factor: int, + min_image_tokens: int, + max_image_tokens: int, + encoder_patch_size: int, + ) -> tuple[int, int]: + """ + Rescales the image so that the following conditions are met: + 1. Both dimensions (height and width) are divisible by 'encoder_patch_size' * 'downsample_factor'. + This ensures no padding is needed in the downsampling step. + 2. The total number of pixels is within the range ['smart_resize_min_pixels', 'smart_resize_max_pixels']. + 3. The aspect ratio of the image is maintained as closely as possible. + """ + total_factor = encoder_patch_size * downsample_factor + smart_resize_min_pixels = min_image_tokens * encoder_patch_size**2 * downsample_factor**2 + smart_resize_max_pixels = max_image_tokens * encoder_patch_size**2 * downsample_factor**2 + + h_bar = max(total_factor, round_by_factor(height, total_factor)) + w_bar = max(total_factor, round_by_factor(width, total_factor)) + + if h_bar * w_bar > smart_resize_max_pixels: + beta = math.sqrt((height * width) / smart_resize_max_pixels) + math.floor(height / beta / total_factor) * total_factor + h_bar = max(total_factor, math.floor(height / beta / total_factor) * total_factor) + w_bar = max(total_factor, math.floor(width / beta / total_factor) * total_factor) + elif h_bar * w_bar < smart_resize_min_pixels: + beta = math.sqrt(smart_resize_min_pixels / (height * width)) + h_bar = math.ceil(height * beta / total_factor) * total_factor + w_bar = math.ceil(width * beta / total_factor) * total_factor + + return w_bar, h_bar + + def _is_image_too_large( + self, + height: int, + width: int, + max_image_tokens: int, + encoder_patch_size: int, + downsample_factor: int, + max_pixels_tolerance: float, + ) -> bool: + """Check if the image is too large to be processed as one tile.""" + total_factor = encoder_patch_size * downsample_factor + + h_bar = max(encoder_patch_size, round_by_factor(height, total_factor)) + w_bar = max(encoder_patch_size, round_by_factor(width, total_factor)) + return h_bar * w_bar > max_image_tokens * encoder_patch_size**2 * downsample_factor**2 * max_pixels_tolerance + + def resize_and_split( + self, + images: "torch.Tensor", + downsample_factor: int, + min_tiles: int, + max_tiles: int, + use_thumbnail: bool, + min_image_tokens: int, + max_image_tokens: int, + encoder_patch_size: int, + tile_size: int, + max_pixels_tolerance: float, + interpolation: "F.InterpolationMode", + ) -> "torch.Tensor": + batch_size, _, height, width = images.shape + do_image_splitting = not min_tiles == max_tiles == 1 + is_image_large = self._is_image_too_large( + height=height, + width=width, + max_image_tokens=max_image_tokens, + encoder_patch_size=encoder_patch_size, + downsample_factor=downsample_factor, + max_pixels_tolerance=max_pixels_tolerance, + ) + + new_width, new_height = self.smart_resize( + height=height, + width=width, + downsample_factor=downsample_factor, + min_image_tokens=min_image_tokens, + max_image_tokens=max_image_tokens, + encoder_patch_size=encoder_patch_size, + ) + + # Big image will be cropped into patches and small images are just resized + if is_image_large and do_image_splitting: + images, num_rows, num_cols = self.crop_image_to_patches( + images, + min_tiles=min_tiles, + max_tiles=max_tiles, + tile_size=tile_size, + thumbnail_size=(new_height, new_width), + use_thumbnail=use_thumbnail, + interpolation=interpolation, + ) + else: + num_rows = num_cols = 1 + images = F.resize(images, (new_height, new_width), interpolation=interpolation) + # Make a list and treat it as single crop per image so it can be re-grouped back correctly + images = [[image] for image in images] + + num_rows = [num_rows] * batch_size + num_cols = [num_cols] * batch_size + image_sizes = [[new_height, new_width]] * batch_size + return images, num_rows, num_cols, image_sizes + + def _preprocess( + self, + images: ImageInput, + size: SizeDict, + interpolation: "F.InterpolationMode", + do_resize: bool, + do_rescale: bool, + rescale_factor: float, + do_normalize: bool, + image_mean: Union[float, list[float]], + image_std: Union[float, list[float]], + downsample_factor: int, + do_image_splitting: bool, + min_tiles: int, + max_tiles: int, + use_thumbnail: bool, + min_image_tokens: int, + max_image_tokens: int, + encoder_patch_size: int, + tile_size: int, + max_pixels_tolerance: float, + return_tensors: Union[str, TensorType], + disable_grouping: bool, + do_pad: bool, + return_row_col_info: bool, + **kwargs, + ) -> BatchFeature: + if not do_image_splitting: + min_tiles = 1 + max_tiles = 1 + logger.debug( + "Image splitting is disabled, setting min_tiles and max_tiles to 1. Set do_image_splitting=True to enable splitting." + ) + + if do_image_splitting and min_tiles > max_tiles: + raise ValueError("min_tiles must be less than or equal to max_tiles") + + max_thumbnail_image_patches = max_image_tokens * downsample_factor**2 + tile_size_patches = (tile_size // encoder_patch_size) ** 2 if do_image_splitting else 0 + max_num_patches = max( + max_thumbnail_image_patches, + tile_size_patches, + ) + + grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping) + resized_images_grouped = {} + resized_image_sizes = {} + rows_grouped, cols_grouped = {}, {} + for shape, stacked_images in grouped_images.items(): + num_rows = [1] * stacked_images.shape[0] + num_cols = [1] * stacked_images.shape[0] + height, width = stacked_images.shape[-2:] + image_sizes = [[height, width]] * stacked_images.shape[0] + do_resize = True + + if do_resize: + stacked_images, num_rows, num_cols, image_sizes = self.resize_and_split( + stacked_images, + downsample_factor=downsample_factor, + min_tiles=min_tiles, + max_tiles=max_tiles, + use_thumbnail=use_thumbnail, + min_image_tokens=min_image_tokens, + max_image_tokens=max_image_tokens, + encoder_patch_size=encoder_patch_size, + tile_size=tile_size, + max_pixels_tolerance=max_pixels_tolerance, + interpolation=interpolation, + ) + + rows_grouped[shape] = num_rows + cols_grouped[shape] = num_cols + resized_image_sizes[shape] = image_sizes + resized_images_grouped[shape] = stacked_images + resized_images = reorder_images(resized_images_grouped, grouped_images_index) + batch_rows = reorder_images(rows_grouped, grouped_images_index) + batch_cols = reorder_images(cols_grouped, grouped_images_index) + resized_image_sizes = reorder_images(resized_image_sizes, grouped_images_index) + + grouped_images, grouped_images_index = group_images_by_shape( + resized_images, disable_grouping=disable_grouping, is_nested=True + ) + + processed_images_grouped = {} + processed_masks, processed_spatial_shapes = {}, {} + for shape, stacked_images in grouped_images.items(): + # Fused rescale and normalize + stacked_images = self.rescale_and_normalize( + stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std + ) + batch_size, *_, height, width = stacked_images.shape + num_patches_height = height // encoder_patch_size + num_patches_width = width // encoder_patch_size + + stacked_images = convert_image_to_patches(stacked_images, encoder_patch_size) + processed_spatial_shapes[shape] = [[num_patches_height, num_patches_width]] * batch_size + + if do_pad: + stacked_images, pixel_mask = pad_along_first_dim(stacked_images, max_num_patches) + processed_masks[shape] = [pixel_mask] * batch_size + + processed_images_grouped[shape] = stacked_images + + processed_images = reorder_images(processed_images_grouped, grouped_images_index, is_nested=True) + data = {"pixel_values": torch.cat([torch.stack(images) for images in processed_images])} + + if do_pad: + processed_masks = reorder_images(processed_masks, grouped_images_index, is_nested=True) + processed_spatial_shapes = reorder_images(processed_spatial_shapes, grouped_images_index, is_nested=True) + processed_masks = torch.cat([torch.stack(masks) for masks in processed_masks]) + processed_spatial_shapes = torch.cat( + [torch.tensor(spatial_shape) for spatial_shape in processed_spatial_shapes] + ) + data.update({"pixel_attention_mask": processed_masks, "spatial_shapes": processed_spatial_shapes}) + + if return_row_col_info: + data["image_rows"] = batch_rows + data["image_cols"] = batch_cols + data["image_sizes"] = resized_image_sizes + + encoding = BatchFeature(data=data, tensor_type=return_tensors) + return encoding + + +__all__ = ["Lfm2VlImageProcessorFast"] diff --git a/src/transformers/models/lfm2_vl/modeling_lfm2_vl.py b/src/transformers/models/lfm2_vl/modeling_lfm2_vl.py new file mode 100755 index 000000000000..deee35394ee1 --- /dev/null +++ b/src/transformers/models/lfm2_vl/modeling_lfm2_vl.py @@ -0,0 +1,497 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/lfm2_vl/modular_lfm2_vl.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_lfm2_vl.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 the HuggingFace Inc. team. All rights reserved. +# +# 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. + +from dataclasses import dataclass +from typing import Optional, Union + +import torch +from torch import nn + +from ...activations import ACT2FN +from ...cache_utils import Cache +from ...generation import GenerationMixin +from ...modeling_outputs import BaseModelOutputWithPast, ModelOutput +from ...modeling_utils import PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple +from ..auto import AutoModel +from .configuration_lfm2_vl import Lfm2VlConfig + + +class Lfm2VlMultiModalProjector(nn.Module): + def __init__(self, config: Lfm2VlConfig): + super().__init__() + in_channels = config.vision_config.hidden_size * (config.downsample_factor**2) + self.factor = config.downsample_factor + self.layer_norm = nn.LayerNorm(in_channels) + self.linear_1 = nn.Linear( + in_channels, + config.projector_hidden_size, + bias=config.projector_bias, + ) + self.act = ACT2FN[config.projector_hidden_act] + self.linear_2 = nn.Linear( + config.projector_hidden_size, + config.text_config.hidden_size, + bias=config.projector_bias, + ) + + def forward(self, image_features: torch.Tensor): + image_features = self.pixel_unshuffle(image_features) + image_features = self.layer_norm(image_features) + hidden_states = self.linear_1(image_features) + hidden_states = self.act(hidden_states) + hidden_states = self.linear_2(hidden_states) + return hidden_states + + def pixel_unshuffle(self, hidden_states: torch.Tensor): + batch_size, width, height, channels = hidden_states.size() + hidden_states = hidden_states.reshape(batch_size, width, height // self.factor, channels * self.factor) + hidden_states = hidden_states.permute(0, 2, 1, 3) + hidden_states = hidden_states.reshape( + batch_size, height // self.factor, width // self.factor, channels * self.factor**2 + ) + hidden_states = hidden_states.permute(0, 2, 1, 3) + return hidden_states + + +@auto_docstring +class Lfm2VlPreTrainedModel(PreTrainedModel): + config: Lfm2VlConfig + base_model_prefix = "" + supports_gradient_checkpointing = True + _skip_keys_device_placement = "past_key_values" + + _supports_flash_attn = True + _supports_sdpa = True + _can_compile_fullgraph = False + _supports_flex_attn = True + _supports_attention_backend = True + + +@dataclass +@auto_docstring( + custom_intro=""" + Base class for Lfm2Vl causal language model (or autoregressive) outputs. + """ +) +class Lfm2VlCausalLMOutputWithPast(ModelOutput): + r""" + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided): + Language modeling loss (for next-token prediction). + logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). + + Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see + `past_key_values` input) to speed up sequential decoding. + image_hidden_states (`torch.FloatTensor`, *optional*): + A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`. + image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state. + """ + + loss: Optional[torch.FloatTensor] = None + logits: Optional[torch.FloatTensor] = None + past_key_values: Optional[Cache] = None + hidden_states: Optional[tuple[torch.FloatTensor]] = None + attentions: Optional[tuple[torch.FloatTensor]] = None + image_hidden_states: Optional[torch.FloatTensor] = None + + +@dataclass +@auto_docstring( + custom_intro=""" + Base class for Lfm2Vl outputs, with hidden states and attentions. + """ +) +class Lfm2VlModelOutputWithPast(BaseModelOutputWithPast): + r""" + past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache). + + Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see + `past_key_values` input) to speed up sequential decoding. + image_hidden_states (`torch.FloatTensor`, *optional*): + A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`. + image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state. + """ + + image_hidden_states: Optional[torch.FloatTensor] = None + + +@auto_docstring( + custom_intro=""" + The Lfm2Vl model which consists of a vision backbone and a language model, without a language modeling head. + """ +) +class Lfm2VlModel(Lfm2VlPreTrainedModel): + _checkpoint_conversion_mapping = {} + + def __init__(self, config: Lfm2VlConfig): + super().__init__(config) + self.vision_tower = AutoModel.from_config(config.vision_config) + + self.multi_modal_projector = Lfm2VlMultiModalProjector(config) + self.language_model = AutoModel.from_config(config.text_config) + self.post_init() + + def get_input_embeddings(self): + return self.language_model.get_input_embeddings() + + def set_input_embeddings(self, value): + self.language_model.set_input_embeddings(value) + + def set_decoder(self, decoder): + self.language_model = decoder + + def get_decoder(self): + return self.language_model + + def get_image_features( + self, + pixel_values: torch.FloatTensor, + spatial_shapes: torch.Tensor, + pixel_attention_mask: torch.Tensor, + **kwargs, + ) -> list[torch.Tensor]: + """ + Obtains image last hidden states from the vision tower and apply multimodal projection. + + Args: + pixel_values (`torch.FloatTensor]` of shape `(batch_size, channels, height, width)`): + The tensors corresponding to the input images. + spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`): + The spatial shapes of the input images. + pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`): + The pixel attention mask of the input images. + Returns: + image_features (`list[torch.Tensor]`): Image feature tensor of shape `(num_images, image_length, embed_dim)`). + """ + image_outputs = self.vision_tower( + pixel_values=pixel_values, + spatial_shapes=spatial_shapes, + pixel_attention_mask=pixel_attention_mask, + ).last_hidden_state + + img_feature_lengths = pixel_attention_mask.sum(dim=1) + image_features = [] + + for img_idx in range(image_outputs.size(0)): + feature = image_outputs[img_idx] + # unpad the image representation + feature = feature[: img_feature_lengths[img_idx], :].unsqueeze(0) + + # reshape to original height and width + feature_org_h, feature_org_w = spatial_shapes[img_idx] + feature = feature.reshape(1, feature_org_h, feature_org_w, -1) + + # project the image representation + img_embedding = self.multi_modal_projector(feature) + + # flatten here to handle variable length in naflex + img_embedding = img_embedding.reshape(-1, img_embedding.size(-1)) + image_features.append(img_embedding) + + return image_features + + def get_placeholder_mask( + self, input_ids: torch.LongTensor, inputs_embeds: torch.FloatTensor, image_features: torch.FloatTensor + ): + """ + Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is + equal to the length of multimodal features. If the lengths are different, an error is raised. + """ + if input_ids is None: + special_image_mask = inputs_embeds == self.get_input_embeddings()( + torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + special_image_mask = special_image_mask.all(-1) + else: + special_image_mask = input_ids == self.config.image_token_id + + n_image_tokens = special_image_mask.sum() + special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device) + n_image_features = image_features.shape[0] + if inputs_embeds[special_image_mask].numel() != image_features.numel(): + raise ValueError( + f"Image features and image tokens do not match: tokens: {n_image_tokens}, features {n_image_features}" + ) + return special_image_mask + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, + spatial_shapes: Optional[torch.Tensor] = None, + pixel_attention_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, Lfm2VlModelOutputWithPast]: + r""" + spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`, *optional*): + The spatial shapes of the input images. + pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`, *optional*): + The pixel attention mask of the input images. + """ + + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds = self.get_input_embeddings()(input_ids) + + if pixel_values is not None: + image_features = self.get_image_features( + pixel_values=pixel_values, + spatial_shapes=spatial_shapes, + pixel_attention_mask=pixel_attention_mask, + ) + image_features = torch.cat(image_features, dim=0).to(inputs_embeds.device, inputs_embeds.dtype) + special_image_mask = self.get_placeholder_mask( + input_ids=input_ids, + inputs_embeds=inputs_embeds, + image_features=image_features, + ) + inputs_embeds = inputs_embeds.masked_scatter(special_image_mask, image_features) + + outputs = self.language_model( + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + return Lfm2VlModelOutputWithPast( + last_hidden_state=outputs.last_hidden_state, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + image_hidden_states=image_features if pixel_values is not None else None, + ) + + +@auto_docstring( + custom_intro=""" + The LFM2_VL model which consists of a vision backbone and a language model. + """ +) +class Lfm2VlForConditionalGeneration(Lfm2VlPreTrainedModel, GenerationMixin): + _checkpoint_conversion_mapping = {} + _tied_weights_keys = ["lm_head.weight"] + + def __init__(self, config: Lfm2VlConfig): + super().__init__(config) + self.model = Lfm2VlModel(config) + self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False) + self.post_init() + + def get_input_embeddings(self): + return self.model.get_input_embeddings() + + def set_input_embeddings(self, value): + self.model.set_input_embeddings(value) + + def get_output_embeddings(self) -> nn.Module: + return self.lm_head + + def set_decoder(self, decoder): + self.model.set_decoder(decoder) + + def get_decoder(self): + return self.model.get_decoder() + + def get_image_features( + self, + pixel_values: torch.FloatTensor, + spatial_shapes: torch.Tensor, + pixel_attention_mask: torch.Tensor, + **kwargs, + ): + return self.model.get_image_features( + pixel_values=pixel_values, + spatial_shapes=spatial_shapes, + pixel_attention_mask=pixel_attention_mask, + **kwargs, + ) + + # Make modules available through conditional class for BC + @property + def language_model(self): + return self.model.language_model + + @property + def vision_tower(self): + return self.model.vision_tower + + @property + def multi_modal_projector(self): + return self.model.multi_modal_projector + + @can_return_tuple + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, + spatial_shapes: Optional[torch.Tensor] = None, + pixel_attention_mask: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, Lfm2VlCausalLMOutputWithPast]: + r""" + pixel_values (`torch.FloatTensor` of shape `(batch_size, channels, height, width)`, *optional*): + The input image tensors. + spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`, *optional*): + The spatial shapes of the input images. + pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`, *optional*): + The pixel attention mask of the input images. + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + + Example: + + ```python + >>> from PIL import Image + >>> import requests + >>> from transformers import AutoProcessor, AutoModelForImageTextToText + >>> from transformers.image_utils import load_image + + >>> model = AutoModelForImageTextToText.from_pretrained( + ... "LiquidAI/LFM2-VL-1.6B", + ... ) + >>> processor = AutoProcessor.from_pretrained( + ... "LiquidAI/LFM2-VL-1.6B", + ... ) + + >>> url = "https://www.ilankelman.org/stopsigns/australia.jpg" + >>> image = load_image(url) + + >>> conversation = [ + ... { + ... "role": "user", + ... "content": [ + ... {"type": "image", "image": image}, + ... {"type": "text", "text": "What is in this image?"}, + ... ], + ... }, + ... ] + + >>> inputs = processor.apply_chat_template( + ... conversation, + ... add_generation_prompt=True, + ... tokenize=True, + ... return_dict=True, + ... return_tensors="pt" + ... ) + + >>> # Generate + >>> outputs = model.generate(**inputs, max_new_tokens=45) + >>> processor.batch_decode(outputs, skip_special_tokens=True)[0] + 'This image depicts a vibrant street scene in what appears to be a Chinatown or similar cultural area. The focal point is a large red stop sign with white lettering, mounted on a pole.' + ```""" + outputs = self.model( + input_ids=input_ids, + pixel_values=pixel_values, + spatial_shapes=spatial_shapes, + pixel_attention_mask=pixel_attention_mask, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs[0] + # Only compute necessary logits, and do not upcast them to float if we are not computing the loss + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]) + + loss = None + if labels is not None: + loss = self.loss_function( + logits=logits, + labels=labels, + vocab_size=self.config.text_config.vocab_size, + **kwargs, + ) + + return Lfm2VlCausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + image_hidden_states=outputs.image_hidden_states, + ) + + def prepare_inputs_for_generation( + self, + input_ids, + past_key_values=None, + inputs_embeds=None, + pixel_values=None, + attention_mask=None, + cache_position=None, + logits_to_keep=None, + **kwargs, + ): + # Overwritten -- in specific circumstances we don't want to forward image inputs to the model + + model_inputs = super().prepare_inputs_for_generation( + input_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + logits_to_keep=logits_to_keep, + **kwargs, + ) + + if cache_position[0] == 0: + # If we're in cached decoding stage, pixel values should be None because input ids do not contain special image token anymore + # Otherwise we need pixel values to be passed to model + model_inputs["pixel_values"] = pixel_values + + return model_inputs + + +__all__ = ["Lfm2VlForConditionalGeneration", "Lfm2VlPreTrainedModel", "Lfm2VlModel"] diff --git a/src/transformers/models/lfm2_vl/modular_lfm2_vl.py b/src/transformers/models/lfm2_vl/modular_lfm2_vl.py new file mode 100644 index 000000000000..68367464c3cf --- /dev/null +++ b/src/transformers/models/lfm2_vl/modular_lfm2_vl.py @@ -0,0 +1,352 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Inc. team. All rights reserved. +# +# 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. +"""PyTorch Lfm2-VL model.""" + +from typing import Optional, Union + +import torch +from torch import nn + +from ...activations import ACT2FN +from ...cache_utils import Cache +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging +from ..llava.modeling_llava import ( + LlavaCausalLMOutputWithPast, + LlavaForConditionalGeneration, + LlavaModel, + LlavaModelOutputWithPast, + LlavaPreTrainedModel, +) +from .configuration_lfm2_vl import Lfm2VlConfig + + +logger = logging.get_logger(__name__) + + +class Lfm2VlMultiModalProjector(nn.Module): + def __init__(self, config: Lfm2VlConfig): + super().__init__() + in_channels = config.vision_config.hidden_size * (config.downsample_factor**2) + self.factor = config.downsample_factor + self.layer_norm = nn.LayerNorm(in_channels) + self.linear_1 = nn.Linear( + in_channels, + config.projector_hidden_size, + bias=config.projector_bias, + ) + self.act = ACT2FN[config.projector_hidden_act] + self.linear_2 = nn.Linear( + config.projector_hidden_size, + config.text_config.hidden_size, + bias=config.projector_bias, + ) + + def forward(self, image_features: torch.Tensor): + image_features = self.pixel_unshuffle(image_features) + image_features = self.layer_norm(image_features) + hidden_states = self.linear_1(image_features) + hidden_states = self.act(hidden_states) + hidden_states = self.linear_2(hidden_states) + return hidden_states + + def pixel_unshuffle(self, hidden_states: torch.Tensor): + batch_size, width, height, channels = hidden_states.size() + hidden_states = hidden_states.reshape(batch_size, width, height // self.factor, channels * self.factor) + hidden_states = hidden_states.permute(0, 2, 1, 3) + hidden_states = hidden_states.reshape( + batch_size, height // self.factor, width // self.factor, channels * self.factor**2 + ) + hidden_states = hidden_states.permute(0, 2, 1, 3) + return hidden_states + + +class Lfm2VlPreTrainedModel(LlavaPreTrainedModel): + _can_compile_fullgraph = False + + +class Lfm2VlCausalLMOutputWithPast(LlavaCausalLMOutputWithPast): + pass + + +class Lfm2VlModelOutputWithPast(LlavaModelOutputWithPast): + pass + + +class Lfm2VlModel(LlavaModel): + _checkpoint_conversion_mapping = {} + + def __init__(self, config: Lfm2VlConfig): + super().__init__(config) + + def get_image_features( + self, + pixel_values: torch.FloatTensor, + spatial_shapes: torch.Tensor, + pixel_attention_mask: torch.Tensor, + **kwargs, + ) -> list[torch.Tensor]: + """ + Obtains image last hidden states from the vision tower and apply multimodal projection. + + Args: + pixel_values (`torch.FloatTensor]` of shape `(batch_size, channels, height, width)`): + The tensors corresponding to the input images. + spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`): + The spatial shapes of the input images. + pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`): + The pixel attention mask of the input images. + Returns: + image_features (`list[torch.Tensor]`): Image feature tensor of shape `(num_images, image_length, embed_dim)`). + """ + image_outputs = self.vision_tower( + pixel_values=pixel_values, + spatial_shapes=spatial_shapes, + pixel_attention_mask=pixel_attention_mask, + ).last_hidden_state + + img_feature_lengths = pixel_attention_mask.sum(dim=1) + image_features = [] + + for img_idx in range(image_outputs.size(0)): + feature = image_outputs[img_idx] + # unpad the image representation + feature = feature[: img_feature_lengths[img_idx], :].unsqueeze(0) + + # reshape to original height and width + feature_org_h, feature_org_w = spatial_shapes[img_idx] + feature = feature.reshape(1, feature_org_h, feature_org_w, -1) + + # project the image representation + img_embedding = self.multi_modal_projector(feature) + + # flatten here to handle variable length in naflex + img_embedding = img_embedding.reshape(-1, img_embedding.size(-1)) + image_features.append(img_embedding) + + return image_features + + def get_placeholder_mask( + self, input_ids: torch.LongTensor, inputs_embeds: torch.FloatTensor, image_features: torch.FloatTensor + ): + """ + Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is + equal to the length of multimodal features. If the lengths are different, an error is raised. + """ + if input_ids is None: + special_image_mask = inputs_embeds == self.get_input_embeddings()( + torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + special_image_mask = special_image_mask.all(-1) + else: + special_image_mask = input_ids == self.config.image_token_id + + n_image_tokens = special_image_mask.sum() + special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device) + n_image_features = image_features.shape[0] + if inputs_embeds[special_image_mask].numel() != image_features.numel(): + raise ValueError( + f"Image features and image tokens do not match: tokens: {n_image_tokens}, features {n_image_features}" + ) + return special_image_mask + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, + spatial_shapes: Optional[torch.Tensor] = None, + pixel_attention_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, Lfm2VlModelOutputWithPast]: + r""" + spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`, *optional*): + The spatial shapes of the input images. + pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`, *optional*): + The pixel attention mask of the input images. + """ + + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds = self.get_input_embeddings()(input_ids) + + if pixel_values is not None: + image_features = self.get_image_features( + pixel_values=pixel_values, + spatial_shapes=spatial_shapes, + pixel_attention_mask=pixel_attention_mask, + ) + image_features = torch.cat(image_features, dim=0).to(inputs_embeds.device, inputs_embeds.dtype) + special_image_mask = self.get_placeholder_mask( + input_ids=input_ids, + inputs_embeds=inputs_embeds, + image_features=image_features, + ) + inputs_embeds = inputs_embeds.masked_scatter(special_image_mask, image_features) + + outputs = self.language_model( + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + return Lfm2VlModelOutputWithPast( + last_hidden_state=outputs.last_hidden_state, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + image_hidden_states=image_features if pixel_values is not None else None, + ) + + +class Lfm2VlForConditionalGeneration(LlavaForConditionalGeneration): + _checkpoint_conversion_mapping = {} + + def get_image_features( + self, + pixel_values: torch.FloatTensor, + spatial_shapes: torch.Tensor, + pixel_attention_mask: torch.Tensor, + **kwargs, + ): + return self.model.get_image_features( + pixel_values=pixel_values, + spatial_shapes=spatial_shapes, + pixel_attention_mask=pixel_attention_mask, + **kwargs, + ) + + @can_return_tuple + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, + spatial_shapes: Optional[torch.Tensor] = None, + pixel_attention_mask: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, Lfm2VlCausalLMOutputWithPast]: + r""" + pixel_values (`torch.FloatTensor` of shape `(batch_size, channels, height, width)`, *optional*): + The input image tensors. + spatial_shapes (`torch.Tensor` of shape `(batch_size, 2)`, *optional*): + The spatial shapes of the input images. + pixel_attention_mask (`torch.Tensor` of shape `(batch_size, height, width)`, *optional*): + The pixel attention mask of the input images. + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + + Example: + + ```python + >>> from PIL import Image + >>> import requests + >>> from transformers import AutoProcessor, AutoModelForImageTextToText + >>> from transformers.image_utils import load_image + + >>> model = AutoModelForImageTextToText.from_pretrained( + ... "LiquidAI/LFM2-VL-1.6B", + ... ) + >>> processor = AutoProcessor.from_pretrained( + ... "LiquidAI/LFM2-VL-1.6B", + ... ) + + >>> url = "https://www.ilankelman.org/stopsigns/australia.jpg" + >>> image = load_image(url) + + >>> conversation = [ + ... { + ... "role": "user", + ... "content": [ + ... {"type": "image", "image": image}, + ... {"type": "text", "text": "What is in this image?"}, + ... ], + ... }, + ... ] + + >>> inputs = processor.apply_chat_template( + ... conversation, + ... add_generation_prompt=True, + ... tokenize=True, + ... return_dict=True, + ... return_tensors="pt" + ... ) + + >>> # Generate + >>> outputs = model.generate(**inputs, max_new_tokens=45) + >>> processor.batch_decode(outputs, skip_special_tokens=True)[0] + 'This image depicts a vibrant street scene in what appears to be a Chinatown or similar cultural area. The focal point is a large red stop sign with white lettering, mounted on a pole.' + ```""" + outputs = self.model( + input_ids=input_ids, + pixel_values=pixel_values, + spatial_shapes=spatial_shapes, + pixel_attention_mask=pixel_attention_mask, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs[0] + # Only compute necessary logits, and do not upcast them to float if we are not computing the loss + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]) + + loss = None + if labels is not None: + loss = self.loss_function( + logits=logits, + labels=labels, + vocab_size=self.config.text_config.vocab_size, + **kwargs, + ) + + return Lfm2VlCausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + image_hidden_states=outputs.image_hidden_states, + ) + + +__all__ = ["Lfm2VlForConditionalGeneration", "Lfm2VlPreTrainedModel", "Lfm2VlModel"] diff --git a/src/transformers/models/lfm2_vl/processing_lfm2_vl.py b/src/transformers/models/lfm2_vl/processing_lfm2_vl.py new file mode 100755 index 000000000000..12f289c266a1 --- /dev/null +++ b/src/transformers/models/lfm2_vl/processing_lfm2_vl.py @@ -0,0 +1,269 @@ +# coding=utf-8 +# Copyright 2025 the HuggingFace Inc. team. All rights reserved. +# +# 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. +import math +from typing import Optional, Union + +from ...feature_extraction_utils import BatchFeature +from ...image_utils import ImageInput, make_nested_list_of_images +from ...processing_utils import ( + ImagesKwargs, + ProcessingKwargs, + ProcessorMixin, + Unpack, +) +from ...tokenization_utils_base import BatchEncoding, TextInput +from ...utils import logging + + +logger = logging.get_logger(__name__) + + +class Lfm2VlImagesKwargs(ImagesKwargs, total=False): + downsample_factor: Optional[int] + do_image_splitting: Optional[bool] + min_tiles: Optional[int] + max_tiles: Optional[int] + use_thumbnail: Optional[bool] + min_image_tokens: Optional[int] + max_image_tokens: Optional[int] + encoder_patch_size: Optional[int] + tile_size: Optional[int] + max_pixels_tolerance: Optional[float] + patch_size: Optional[int] + do_pad: Optional[bool] + return_row_col_info: Optional[bool] + + +class Lfm2VlProcessorKwargs(ProcessingKwargs, total=False): + images_kwargs: Lfm2VlImagesKwargs + + _defaults = { + "images_kwargs": { + "return_row_col_info": True, + }, + "text_kwargs": { + "use_image_special_tokens": True, + "add_special_tokens": False, + "padding": False, + "is_split_into_words": False, + }, + } + + +class Lfm2VlProcessor(ProcessorMixin): + r""" + Constructs a Lfm2Vl processor which wraps a Lfm2Tokenizer tokenizer and Lfm2VlImageProcessor into a single processor. + + [`Lfm2VlProcessor`] offers all the functionalities of [`Lfm2ImageProcessor`] and [`Lfm2Tokenizer`]. + + Args: + image_processor (`Lfm2VlImageProcessor`): + An instance of [`Lfm2VlImageProcessor`]. The image processor is a required input. + tokenizer (`PreTrainedTokenizerBase`): + An instance of [`PreTrainedTokenizerBase`]. This should correspond with the model's text model. The tokenizer is a required input. + chat_template (`str`, *optional*): + A Jinja template which will be used to convert lists of messages in a chat into a tokenizable string. + use_image_special_tokens (`bool`, *optional*, defaults to `True`): + Whether to use image special tokens or not when processing. + """ + + attributes = ["image_processor", "tokenizer"] + image_processor_class = "Lfm2VlImageProcessorFast" + tokenizer_class = "AutoTokenizer" + + def __init__( + self, + image_processor, + tokenizer, + chat_template: Optional[str] = None, + use_image_special_tokens: Optional[bool] = True, + **kwargs, + ): + self.image_token = tokenizer.image_token + self.image_token_id = tokenizer.image_token_id + self.use_image_special_tokens = use_image_special_tokens + self.image_start_token = tokenizer.image_start_token + self.image_end_token = tokenizer.image_end_token + self.image_thumbnail_token = tokenizer.image_thumbnail + super().__init__(image_processor, tokenizer, chat_template=chat_template, **kwargs) + + def __call__( + self, + images: Optional[Union[ImageInput, list[ImageInput], list[list[ImageInput]]]] = None, + text: Optional[Union[TextInput, list[TextInput]]] = None, + **kwargs: Unpack[Lfm2VlProcessorKwargs], + ) -> BatchEncoding: + """ + Processes the input prompts and returns a BatchFeature. + Args: + images (`PIL.Image.Image`, `np.ndarray`, `torch.Tensor`, `list[PIL.Image.Image]`, `list[np.ndarray]`, `list[torch.Tensor]`, *optional*): + The image or batch of images to be prepared. Each image can be a PIL image, NumPy array or PyTorch + tensor. If is of type `list[ImageInput]`, it's assumed that this is for a single prompt i.e. of batch size 1. + text (`TextInput`, *optional*): + The sequence or batch of sequences to be encoded. + Wherever an image token, `` is encountered it is expanded to a proper sequence of image tokens. + return_tensors (`Optional[str, TensorType]`, *optional*): + If set, will return tensors of a particular framework. See [`PreTrainedTokenizerFast.__call__`] for more + information. + """ + if text is None and images is None: + raise ValueError("You must provide one of `text` or `images`.") + + if images is not None and text is None: + raise ValueError( + "You must provide `text` when `images` is provided. Minimal text consists of a single image token." + ) + + output_kwargs = self._merge_kwargs( + Lfm2VlProcessorKwargs, + tokenizer_init_kwargs=self.tokenizer.init_kwargs, + **kwargs, + ) + + if isinstance(text, str): + text = [text] + elif not isinstance(text, list) and not isinstance(text[0], str): + raise ValueError("Invalid input text. Please provide a string, or a list of strings") + + n_images_in_text = [sample.count(self.image_token) for sample in text] + if sum(n_images_in_text) > 0 and images is None: + raise ValueError(f"We detected {sum(n_images_in_text)} tokens in the text but no images were passed") + + inputs = {} + use_image_special_tokens = output_kwargs["text_kwargs"].pop("use_image_special_tokens") + + if images is not None: + images = self.image_processor.fetch_images(images) + batched_images = make_nested_list_of_images(images) + vision_inputs = self.image_processor(batched_images, **output_kwargs["images_kwargs"]) + + n_images_in_images = [len(sublist) for sublist in batched_images] + if n_images_in_images != n_images_in_text: + raise ValueError( + f"The number of images in the text {n_images_in_text} and images {n_images_in_images} should be the same." + ) + + text = self.expand_text_with_placeholders( + text, + batched_images, + image_rows=vision_inputs.pop("image_rows"), + image_cols=vision_inputs.pop("image_cols"), + image_sizes=vision_inputs.pop("image_sizes"), + use_image_special_tokens=use_image_special_tokens, + **output_kwargs["images_kwargs"], + ) + inputs.update(vision_inputs) + + return_tensors = output_kwargs["text_kwargs"].pop("return_tensors", None) + + text_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"]) + inputs.update(text_inputs) + + return BatchFeature(inputs, tensor_type=return_tensors) + + def expand_text_with_placeholders( + self, + text: list[str], + images: list[list[ImageInput]], + image_rows: list[list[int]], + image_cols: list[list[int]], + image_sizes: list[list[int]], + use_image_special_tokens: bool, + **images_kwargs, + ): + prompt_strings = [] + + image_data = iter(zip(*[image_rows, image_cols, image_sizes])) + for sample_text, sample_images in zip(text, images): + split_sample = sample_text.split(self.image_token) + sample_text_with_image_tokens = "" + for i, image in enumerate(sample_images): + sample_text_with_image_tokens += split_sample[i] + if use_image_special_tokens: + sample_text_with_image_tokens += self.image_start_token + + rows, cols, image_size = next(image_data) + num_thumbnail_tokens, num_tokens_per_tile = self._get_image_num_tokens(image_size, **images_kwargs) + + if rows > 1 or cols > 1: + for row in range(rows): + for col in range(cols): + if use_image_special_tokens: + sample_text_with_image_tokens += f"<|img_row_{row + 1}_col_{col + 1}|>" + sample_text_with_image_tokens += self.image_token * num_tokens_per_tile + + if num_thumbnail_tokens > 0: + if use_image_special_tokens: + sample_text_with_image_tokens += self.image_thumbnail_token + sample_text_with_image_tokens += self.image_token * num_thumbnail_tokens + else: + sample_text_with_image_tokens += self.image_token * num_thumbnail_tokens + + if use_image_special_tokens: + sample_text_with_image_tokens += self.image_end_token + + sample_text_with_image_tokens += split_sample[i + 1] + prompt_strings.append(sample_text_with_image_tokens) + + return prompt_strings + + def _get_image_num_tokens(self, image_size: list[int], **images_kwargs) -> tuple[int, int]: + tile_size = images_kwargs.get("tile_size", self.image_processor.tile_size) + downsample_factor = images_kwargs.get("downsample_factor", self.image_processor.downsample_factor) + encoder_patch_size = images_kwargs.get("encoder_patch_size", self.image_processor.encoder_patch_size) + use_thumbnail = images_kwargs.get("use_thumbnail", self.image_processor.use_thumbnail) + + thumbnail_tokens = 0 + if use_thumbnail: + image_height, image_width = image_size + num_patches_height = image_height // encoder_patch_size + num_patches_width = image_width // encoder_patch_size + dwn_num_patches_height = math.ceil(num_patches_height / downsample_factor) + dwn_num_patches_width = math.ceil(num_patches_width / downsample_factor) + thumbnail_tokens = dwn_num_patches_height * dwn_num_patches_width + + num_patches_tile = tile_size // encoder_patch_size + dwn_num_patches_tile = math.ceil(num_patches_tile / downsample_factor) + tile_tokens = dwn_num_patches_tile * dwn_num_patches_tile + + return thumbnail_tokens, tile_tokens + + def batch_decode(self, *args, **kwargs): + """ + This method forwards all its arguments to LFM2Tokeniser's [`~PreTrainedTokenizer.batch_decode`]. Please + refer to the docstring of this method for more information. + """ + batched_decode_output = self.tokenizer.batch_decode(*args, **kwargs) + return batched_decode_output + + def decode(self, *args, **kwargs): + """ + This method forwards all its arguments to LFM2Tokeniser's [`~PreTrainedTokenizer.decode`]. Please refer to + the docstring of this method for more information. + """ + decode_output = self.tokenizer.decode(*args, **kwargs) + return decode_output + + @property + def model_input_names(self): + tokenizer_input_names = self.tokenizer.model_input_names + image_processor_input_names = self.image_processor.model_input_names + + # LFM2-VL has no dedicated tokenizer class and uses the Base class with default model input names + tokenizer_input_names = [name for name in tokenizer_input_names if name != "token_type_ids"] + return list(tokenizer_input_names + image_processor_input_names) + + +__all__ = ["Lfm2VlProcessor"] diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index 680002d4600b..094c5861ab10 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -2387,6 +2387,7 @@ def _check_generate_outputs(self, output, config, use_cache=False, num_return_se "zamba", "zamba2", "lfm2", + "lfm2-vl", ) has_standard_cache = not any( model_name in config.__class__.__name__.lower() for model_name in models_without_standard_cache diff --git a/tests/models/lfm2_vl/__init__.py b/tests/models/lfm2_vl/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/models/lfm2_vl/test_image_processing_lfm2_vl.py b/tests/models/lfm2_vl/test_image_processing_lfm2_vl.py new file mode 100755 index 000000000000..8edf59ac78e0 --- /dev/null +++ b/tests/models/lfm2_vl/test_image_processing_lfm2_vl.py @@ -0,0 +1,289 @@ +# coding=utf-8 +# Copyright 2025 HuggingFace Inc. +# +# 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. + + +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torch_available, is_torchvision_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingTestMixin, prepare_image_inputs + + +if is_vision_available(): + from PIL import Image + + +if is_torch_available(): + import torch + + if is_torchvision_available(): + from transformers import Lfm2VlImageProcessorFast + from transformers.models.lfm2_vl.image_processing_lfm2_vl_fast import find_closest_aspect_ratio + + +class Lfm2VlImageProcessingTester: + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + num_images=1, + min_resolution=256, + max_resolution=1024, + downsample_factor=2, + do_image_splitting=False, + min_tiles=2, + max_tiles=10, + use_thumbnail=True, + min_image_tokens=64, + max_image_tokens=256, + encoder_patch_size=16, + tile_size=512, + max_pixels_tolerance=2.0, + ): + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.num_images = num_images + self.min_resolution = min_resolution + self.max_resolution = max_resolution + + self.downsample_factor = downsample_factor + self.do_image_splitting = do_image_splitting + self.min_tiles = min_tiles + self.max_tiles = max_tiles + self.use_thumbnail = use_thumbnail + self.min_image_tokens = min_image_tokens + self.max_image_tokens = max_image_tokens + self.encoder_patch_size = encoder_patch_size + self.tile_size = tile_size + self.max_pixels_tolerance = max_pixels_tolerance + + def prepare_image_processor_dict(self): + return { + "downsample_factor": self.downsample_factor, + "do_image_splitting": self.do_image_splitting, + "min_tiles": self.min_tiles, + "max_tiles": self.max_tiles, + "use_thumbnail": self.use_thumbnail, + "min_image_tokens": self.min_image_tokens, + "max_image_tokens": self.max_image_tokens, + "encoder_patch_size": self.encoder_patch_size, + "tile_size": self.tile_size, + "max_pixels_tolerance": self.max_pixels_tolerance, + } + + def prepare_image_inputs(self, equal_resolution=False, numpify=False, torchify=False): + images = prepare_image_inputs( + batch_size=self.batch_size, + num_channels=self.num_channels, + min_resolution=self.min_resolution, + max_resolution=self.max_resolution, + equal_resolution=equal_resolution, + numpify=numpify, + torchify=torchify, + ) + return [[image] for image in images] + + +@require_torch +@require_vision +class Lfm2VlImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase): + test_slow_image_processor = False + fast_image_processing_class = Lfm2VlImageProcessorFast if is_torchvision_available() else None + + def setUp(self): + super().setUp() + self.image_processor_tester = Lfm2VlImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + for image_processing_class in self.image_processor_list: + image_processing = image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "downsample_factor")) + self.assertTrue(hasattr(image_processing, "min_tiles")) + self.assertTrue(hasattr(image_processing, "max_tiles")) + self.assertTrue(hasattr(image_processing, "use_thumbnail")) + self.assertTrue(hasattr(image_processing, "min_image_tokens")) + self.assertTrue(hasattr(image_processing, "max_image_tokens")) + self.assertTrue(hasattr(image_processing, "encoder_patch_size")) + self.assertTrue(hasattr(image_processing, "tile_size")) + self.assertTrue(hasattr(image_processing, "max_pixels_tolerance")) + + @require_vision + def test_smart_resize(self): + # verify that smart resize output dims are divisible by encoder_patch_size * downsample_factor + image_processing = self.fast_image_processing_class(**self.image_processor_dict) + width, height = image_processing.smart_resize( + height=500, + width=300, + downsample_factor=image_processing.downsample_factor, + min_image_tokens=image_processing.min_image_tokens, + max_image_tokens=image_processing.max_image_tokens, + encoder_patch_size=image_processing.encoder_patch_size, + ) + mod = image_processing.encoder_patch_size * image_processing.downsample_factor + self.assertEqual(width % mod, 0) + self.assertEqual(height % mod, 0) + + @require_vision + def test_get_grid_layout(self): + # splitting a 512×512 image into tiles of size processor.image_processor.tile_size + image_processing = self.fast_image_processing_class(**self.image_processor_dict) + rows, cols, _, _, num_patches = image_processing._get_grid_layout( + height=1024, + width=1024, + min_tiles=image_processing.min_tiles, + max_tiles=image_processing.max_tiles, + tile_size=image_processing.tile_size, + ) + self.assertEqual(num_patches, 4) + self.assertEqual(num_patches, rows * cols) + + rows, cols, _, _, num_patches = image_processing._get_grid_layout( + height=1024, + width=1024, + min_tiles=8, + max_tiles=8, + tile_size=image_processing.tile_size, + ) + self.assertEqual(num_patches, 8) + self.assertEqual(num_patches, rows * cols) + + def test_find_closest_aspect_ratio(self): + # should pick (1,1) over (2,1) for a square image + result = find_closest_aspect_ratio(1.0, [(1, 1), (2, 1)], width=100, height=100, image_size=100) + self.assertEqual(result, (1, 1)) + + result = find_closest_aspect_ratio(0.5, [(1, 1), (1, 2)], width=100, height=200, image_size=200) + self.assertEqual(result, (1, 2)) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.fast_image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = self.image_processor_tester.prepare_image_inputs(equal_resolution=False, numpify=True) + for sample_images in image_inputs: + for image in sample_images: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + tuple(encoded_images.shape), + (1, image_processing.max_num_patches, 3 * image_processing.encoder_patch_size**2), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + tuple(encoded_images.shape), + ( + self.image_processor_tester.batch_size, + image_processing.max_num_patches, + 3 * image_processing.encoder_patch_size**2, + ), + ) + + def test_call_numpy_4_channels(self): + # Lfm2Vl always processes images as RGB, so it always returns images with 3 channels + # Initialize image_processing + image_processor_dict = self.image_processor_dict + image_processing = self.fast_image_processing_class(**image_processor_dict) + # create random numpy tensors + image_inputs = self.image_processor_tester.prepare_image_inputs(equal_resolution=False, numpify=True) + + for sample_images in image_inputs: + for image in sample_images: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + tuple(encoded_images.shape), + (1, image_processing.max_num_patches, 3 * image_processing.encoder_patch_size**2), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + tuple(encoded_images.shape), + ( + self.image_processor_tester.batch_size, + image_processing.max_num_patches, + 3 * image_processing.encoder_patch_size**2, + ), + ) + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.fast_image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = self.image_processor_tester.prepare_image_inputs(equal_resolution=False) + for images in image_inputs: + for image in images: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + tuple(encoded_images.shape), + (1, image_processing.max_num_patches, 3 * image_processing.encoder_patch_size**2), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + tuple(encoded_images.shape), + ( + self.image_processor_tester.batch_size, + image_processing.max_num_patches, + 3 * image_processing.encoder_patch_size**2, + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.fast_image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = self.image_processor_tester.prepare_image_inputs(equal_resolution=False, torchify=True) + + for images in image_inputs: + for image in images: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + tuple(encoded_images.shape), + (1, image_processing.max_num_patches, 3 * image_processing.encoder_patch_size**2), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + tuple(encoded_images.shape), + ( + self.image_processor_tester.batch_size, + image_processing.max_num_patches, + 3 * image_processing.encoder_patch_size**2, + ), + ) diff --git a/tests/models/lfm2_vl/test_modeling_lfm2_vl.py b/tests/models/lfm2_vl/test_modeling_lfm2_vl.py new file mode 100644 index 000000000000..42c732887af0 --- /dev/null +++ b/tests/models/lfm2_vl/test_modeling_lfm2_vl.py @@ -0,0 +1,296 @@ +# Copyright 2025 The HuggingFace Inc. team. All rights reserved. +# +# 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 LFM2-VL model.""" + +import math +import unittest +from io import BytesIO + +import pytest +import requests + +from transformers import AutoProcessor, is_torch_available +from transformers.models.lfm2_vl.modeling_lfm2_vl import Lfm2VlForConditionalGeneration +from transformers.testing_utils import ( + cleanup, + require_read_token, + require_torch, + require_torch_accelerator, + slow, + torch_device, +) +from transformers.utils.import_utils import is_vision_available + +from ...causal_lm_tester import CausalLMModelTester +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor + + +if is_vision_available(): + from PIL import Image + +if is_torch_available(): + import torch + + from transformers import Lfm2VlConfig, Lfm2VlForConditionalGeneration, Lfm2VlModel + + +class Lfm2VlModelTester(CausalLMModelTester): + if is_torch_available(): + config_class = Lfm2VlConfig + base_model_class = Lfm2VlModel + causal_lm_class = Lfm2VlForConditionalGeneration + + def __init__( + self, + parent, + is_training=True, + batch_size=2, + scale_factor=2, + num_images=2, + vision_config={ + "hidden_size": 32, + "intermediate_size": 37, + "num_hidden_layers": 2, + "num_attention_heads": 2, + "num_channels": 3, + "num_patches": 16, + "patch_size": 4, + "hidden_act": "gelu_pytorch_tanh", + "layer_norm_eps": 1e-6, + "attention_dropout": 0.0, + }, + text_config={ + "vocab_size": 100, + "hidden_size": 32, + "intermediate_size": 37, + "num_hidden_layers": 2, + "num_attention_heads": 4, + "num_key_value_heads": 2, + "max_position_embeddings": 100, + "pad_token_id": 0, + "bos_token_id": 1, + "eos_token_id": 2, + "tie_word_embeddings": True, + "rope_theta": 1000000.0, + "conv_bias": False, + "conv_L_cache": 3, + "block_multiple_of": 2, + "full_attn_idxs": [0], + }, + image_token_id=4, + downsample_factor=4, + projector_hidden_size=32, + ): + super().__init__(parent) + self.vision_config = vision_config + self.text_config = text_config + self.image_token_id = image_token_id + self.is_training = is_training + self.batch_size = batch_size + self.scale_factor = scale_factor + self.num_images = num_images + self.downsample_factor = downsample_factor + self.projector_hidden_size = projector_hidden_size + self.image_seq_length = 4 + + def get_config(self): + return Lfm2VlConfig( + vision_config=self.vision_config, + text_config=self.text_config, + image_token_id=self.image_token_id, + downsample_factor=self.downsample_factor, + projector_hidden_size=self.projector_hidden_size, + ) + + def prepare_config_and_inputs(self): + # Create dummy pixel values: [num_images, num_patches, channels * patch_size^2] + patch_size = self.vision_config["patch_size"] + pixel_values = floats_tensor([self.num_images, 64, 3 * patch_size * patch_size]) + + # Spatial shapes: one (height_patches, width_patches) per image + patches = int(math.sqrt(64)) + spatial_shapes = torch.tensor([[patches, patches]] * self.num_images, dtype=torch.long, device=torch_device) + + # Pixel attention mask: mark all patches as valid (no padding) + pixel_attention_mask = torch.ones((self.num_images, 64), dtype=torch.long, device=torch_device) + config = self.get_config() + return config, pixel_values, spatial_shapes, pixel_attention_mask + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, spatial_shapes, pixel_attention_mask = config_and_inputs + input_ids = ids_tensor([self.batch_size, self.seq_length], config.text_config.vocab_size - 2) + 1 + + # For simplicity just set the last n tokens to the image token + input_ids[input_ids == self.image_token_id] = self.text_config["pad_token_id"] + input_ids[:, -self.image_seq_length :] = self.image_token_id + + attention_mask = input_ids.ne(1).to(torch_device) + inputs_dict = { + "pixel_values": pixel_values, + "input_ids": input_ids, + "attention_mask": attention_mask, + "spatial_shapes": spatial_shapes, + "pixel_attention_mask": pixel_attention_mask, + } + return config, inputs_dict + + +@require_torch +class Lfm2VlModelTest(ModelTesterMixin, GenerationTesterMixin, unittest.TestCase): + all_model_classes = (Lfm2VlModel, Lfm2VlForConditionalGeneration) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": Lfm2VlModel, + "text-generation": Lfm2VlForConditionalGeneration, + } + if is_torch_available() + else {} + ) + test_headmasking = False + test_pruning = False + fx_compatible = False + model_tester_class = Lfm2VlModelTester + _is_composite = True + + def setUp(self): + self.model_tester = Lfm2VlModelTester(self) + common_properties = ["image_token_id", "projector_hidden_size"] + self.config_tester = ConfigTester( + self, config_class=Lfm2VlConfig, has_text_modality=False, common_properties=common_properties + ) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip( + "Lfm2 backbone alternates between attention and conv layers, so attention are only returned for attention layers" + ) + def test_attention_outputs(self): + pass + + @unittest.skip("Lfm2 backbone has a special cache format as it alternates between attention and conv layers") + def test_past_key_values_format(self): + pass + + @unittest.skip( + "Lfm2 backbone has a special cache format which is not compatible with compile as it has static address for conv cache" + ) + @pytest.mark.torch_compile_test + def test_sdpa_can_compile_dynamic(self): + pass + + @unittest.skip(reason="Backbone Siglip2VisionModel does not support standalone training") + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="Backbone Siglip2VisionModel does not support standalone training") + def test_training_gradient_checkpointing_use_reentrant(self): + pass + + @unittest.skip(reason="Backbone Siglip2VisionModel does not support standalone training") + def test_training_gradient_checkpointing_use_reentrant_false(self): + pass + + @unittest.skip( + reason="Siglip2 backbone has a non-standard initialization scheme, that this test cannot handle easily" + ) + def test_initialization(self): + pass + + +@require_torch_accelerator +@require_read_token +@slow +class Lfm2VlForConditionalGenerationIntegrationTest(unittest.TestCase): + def setUp(self): + self.processor = AutoProcessor.from_pretrained("LiquidAI/LFM2-VL-1.6B") + self.processor.tokenizer.padding_side = "left" + self.image = Image.open( + requests.get("http://images.cocodataset.org/val2017/000000039769.jpg", stream=True).raw + ) + self.image2 = Image.open( + BytesIO( + requests.get( + "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" + ).content + ) + ) + + def tearDown(self): + cleanup(torch_device, gc_collect=True) + + def test_integration_test(self): + model = Lfm2VlForConditionalGeneration.from_pretrained( + "LiquidAI/LFM2-VL-1.6B", + dtype=torch.bfloat16, + device_map="auto", + ) + + # Create inputs + text = "In this image, we see" + images = self.image + inputs = self.processor(text=text, images=images, return_tensors="pt") + inputs.to(device=torch_device, dtype=torch.bfloat16) + + generated_ids = model.generate(**inputs, max_new_tokens=20, do_sample=False) + generated_texts = self.processor.batch_decode(generated_ids, skip_special_tokens=True) + + expected_generated_text = "In this image, we see a cat and a dog lying on a pink blanket. They are both sleeping peacefully. They are" + self.assertEqual(generated_texts[0], expected_generated_text) + + def test_integration_test_high_resolution(self): + model = Lfm2VlForConditionalGeneration.from_pretrained( + "LiquidAI/LFM2-VL-1.6B", + dtype=torch.bfloat16, + device_map="auto", + ) + + # Create inputs + text = "In this image, we see" + images = self.image2 + inputs = self.processor(text=text, images=images, return_tensors="pt") + inputs.to(device=torch_device, dtype=torch.bfloat16) + + generated_ids = model.generate(**inputs, max_new_tokens=20, do_sample=False) + generated_texts = self.processor.batch_decode(generated_ids, skip_special_tokens=True) + + expected_generated_text = ( + "In this image, we see the Statue of Liberty, standing tall on its pedestal. The statue is made of metal," + ) + self.assertEqual(generated_texts[0], expected_generated_text) + + def test_integration_test_batched(self): + model = Lfm2VlForConditionalGeneration.from_pretrained( + "LiquidAI/LFM2-VL-450M", + dtype=torch.bfloat16, + device_map="auto", + ) + + # Create inputs + text = ["In this image, we see", "In this image, there is a cat on"] + images = [[self.image2], [self.image]] + inputs = self.processor(text=text, images=images, return_tensors="pt", padding=True) + inputs.to(device=torch_device, dtype=torch.bfloat16) + + generated_ids = model.generate(**inputs, max_new_tokens=20, do_sample=False) + generated_texts = self.processor.batch_decode(generated_ids, skip_special_tokens=True) + + expected_generated_text = [ + "In this image, we see a panoramic view of the New York City skyline. The iconic Statics and the New York", + "In this image, there is a cat on a bed with a cat on a bed with a cat on a bed with a cat on a bed", + ] + self.assertListEqual(generated_texts, expected_generated_text) diff --git a/tests/models/lfm2_vl/test_processing_lfm2_vl.py b/tests/models/lfm2_vl/test_processing_lfm2_vl.py new file mode 100755 index 000000000000..f2c33e40e3f6 --- /dev/null +++ b/tests/models/lfm2_vl/test_processing_lfm2_vl.py @@ -0,0 +1,467 @@ +# Copyright 2025 HuggingFace Inc. +# +# 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. + +import math +import shutil +import tempfile +import unittest + +import numpy as np + +from transformers import AutoTokenizer, Lfm2VlProcessor +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torchvision_available, is_vision_available + +from ...test_processing_common import ProcessorTesterMixin + + +if is_vision_available(): + from PIL import Image + + if is_torchvision_available(): + from transformers import Lfm2VlImageProcessorFast + + +@require_torch +@require_vision +class Lfm2VlProcessorTest(ProcessorTesterMixin, unittest.TestCase): + processor_class = Lfm2VlProcessor + + @classmethod + def setUpClass(cls): + cls.tmpdirname = tempfile.mkdtemp() + processor_kwargs = cls.prepare_processor_dict() + image_processor = Lfm2VlImageProcessorFast( + tile_size=14, + min_image_tokens=2, + max_image_tokens=10, + encoder_patch_size=2, + do_image_splitting=False, + ) + tokenizer = AutoTokenizer.from_pretrained("LiquidAI/LFM2-VL-1.6B", **processor_kwargs) + + processor = Lfm2VlProcessor(tokenizer=tokenizer, image_processor=image_processor, **processor_kwargs) + processor.save_pretrained(cls.tmpdirname) + + # Create images with different sizes + cls.small_image = Image.new("RGB", (256, 256)) + cls.large_image = Image.new("RGB", (512, 1024)) + cls.high_res_image = Image.new("RGB", (1024, 1024)) + + cls.bos_token = processor.tokenizer.bos_token + cls.image_token = processor.image_token + + cls.bos_token_id = processor.tokenizer.convert_tokens_to_ids(cls.bos_token) + cls.image_token_id = processor.image_token_id + cls.image_start_token_id = processor.tokenizer.convert_tokens_to_ids(processor.image_start_token) + cls.image_end_token_id = processor.tokenizer.convert_tokens_to_ids(processor.image_end_token) + cls.padding_token_id = processor.tokenizer.pad_token_id + cls.image_thumbnail_token_id = processor.tokenizer.convert_tokens_to_ids(processor.image_thumbnail_token) + + def get_tokenizer(self, **kwargs): + return Lfm2VlProcessor.from_pretrained(self.tmpdirname, **kwargs).tokenizer + + def get_image_processor(self, **kwargs): + return Lfm2VlProcessor.from_pretrained(self.tmpdirname, **kwargs).image_processor + + def get_processor(self, **kwargs): + return Lfm2VlProcessor.from_pretrained(self.tmpdirname, **kwargs) + + @staticmethod + def prepare_processor_dict(): + chat_template = ( + "{{bos_token}}{% for message in messages %}" + "{{'<|im_start|>' + message['role'] + '\n'}}" + "{% if message['content'] is string %}" + "{{ message['content'] }}" + "{% else %}" + "{% for content in message['content'] %}" + "{% if content['type'] == 'image' %}" + "{{ '' }}" + "{% elif content['type'] == 'text' %}" + "{{ content['text'] }}" + "{% endif %}" + "{% endfor %}" + "{% endif %}" + "{{'<|im_end|>\n'}}" + "{% endfor %}" + "{% if add_generation_prompt %}" + "{{'<|im_start|>assistant\n' }}" + "{% endif %}" + ) + return {"chat_template": chat_template, "use_image_special_tokens": True} + + # Override as Lfm2VL needs images/video to be an explicitly nested batch + def prepare_image_inputs(self, batch_size=None): + """This function prepares a list of PIL images for testing""" + images = super().prepare_image_inputs(batch_size) + if isinstance(images, (list, tuple)): + images = [[image] for image in images] + return images + + def get_split_image_expected_tokens(self, processor, image_rows, image_cols, add_thumbnail, image_seq_len): + text_split_images = [self.image_start_token_id] + num_patches_tile = processor.image_processor.tile_size // processor.image_processor.encoder_patch_size + tile_seq_len = math.ceil(num_patches_tile / processor.image_processor.downsample_factor) ** 2 + for n_h in range(image_rows): + for n_w in range(image_cols): + text_split_images += ( + processor.tokenizer(f"<|img_row_{n_h + 1}_col_{n_w + 1}|>", add_special_tokens=False)["input_ids"] + + [self.image_token_id] * tile_seq_len + ) + if add_thumbnail: + text_split_images += [self.image_thumbnail_token_id] + [self.image_token_id] * image_seq_len + text_split_images += [self.image_end_token_id] + return text_split_images + + @classmethod + def tearDownClass(cls): + shutil.rmtree(cls.tmpdirname, ignore_errors=True) + + def test_process_interleaved_images_prompts_no_image_splitting_single_image(self): + processor_components = self.prepare_components() + processor_components["tokenizer"] = self.get_component("tokenizer", padding_side="left") + processor_components["image_processor"] = self.get_component("image_processor", do_image_splitting=False) + processor_kwargs = self.prepare_processor_dict() + + processor = self.processor_class(**processor_components, **processor_kwargs) + image_str = "" + + # Test that a single image is processed correctly + inputs = processor(images=self.small_image, text=image_str) + encoder_feature_dims = ( + 3 * processor.image_processor.encoder_patch_size * processor.image_processor.encoder_patch_size + ) + self.assertEqual( + np.array(inputs["pixel_values"]).shape, + (1, processor.image_processor.max_num_patches, encoder_feature_dims), + ) + self.assertEqual( + np.array(inputs["pixel_attention_mask"]).shape, (1, processor.image_processor.max_num_patches) + ) + self.assertListEqual(inputs["spatial_shapes"].tolist(), [[6, 6]]) + # fmt: on + + def test_process_interleaved_images_prompts_no_image_splitting_single_image_with_text(self): + processor_components = self.prepare_components() + processor_components["tokenizer"] = self.get_component("tokenizer", padding_side="left") + processor_components["image_processor"] = self.get_component("image_processor", do_image_splitting=False) + processor_kwargs = self.prepare_processor_dict() + + processor = self.processor_class(**processor_components, **processor_kwargs) + + image_str = "" + text_str = "In this image, we see" + text = image_str + text_str + inputs = processor(text=text, images=self.small_image) + + # fmt: off + tokenized_sentence = processor.tokenizer(text_str, add_special_tokens=False) + expected_input_ids = [[self.image_start_token_id] + [self.image_token_id] * 9 + [self.image_end_token_id] + tokenized_sentence["input_ids"]] + self.assertEqual(inputs["input_ids"], expected_input_ids) + self.assertEqual(inputs["attention_mask"], [[1] * len(expected_input_ids[0])]) + encoder_feature_dims = 3 * processor.image_processor.encoder_patch_size * processor.image_processor.encoder_patch_size + self.assertEqual(np.array(inputs["pixel_values"]).shape, (1, processor.image_processor.max_num_patches, encoder_feature_dims)) + self.assertEqual(np.array(inputs["pixel_attention_mask"]).shape, (1, processor.image_processor.max_num_patches)) + self.assertListEqual(inputs["spatial_shapes"].tolist(), [[6, 6]]) + # fmt: on + + def test_process_interleaved_images_prompts_no_image_splitting_multiple_images(self): + processor_components = self.prepare_components() + processor_components["tokenizer"] = self.get_component("tokenizer", padding_side="left") + processor_components["image_processor"] = self.get_component("image_processor", do_image_splitting=False) + processor_kwargs = self.prepare_processor_dict() + + processor = self.processor_class(**processor_components, **processor_kwargs) + + image_str = "" + text_str_1 = "In this image, we see" + text_str_2 = "In this image, we see" + + text = [ + image_str + text_str_1, + image_str + image_str + text_str_2, + ] + images = [[self.small_image], [self.small_image, self.small_image]] + + inputs = processor(text=text, images=images, padding=True) + + tokenized_sentence_1 = processor.tokenizer(text_str_1, add_special_tokens=False) + tokenized_sentence_2 = processor.tokenizer(text_str_2, add_special_tokens=False) + image_tokens = [self.image_start_token_id] + [self.image_token_id] * 9 + [self.image_end_token_id] + expected_input_ids_1 = image_tokens + tokenized_sentence_1["input_ids"] + expected_input_ids_2 = 2 * image_tokens + tokenized_sentence_2["input_ids"] + # Pad the first input to match the second input + pad_len = len(expected_input_ids_2) - len(expected_input_ids_1) + padded_expected_input_ids_1 = [self.padding_token_id] * pad_len + expected_input_ids_1 + + self.assertEqual(inputs["input_ids"], [padded_expected_input_ids_1, expected_input_ids_2]) + self.assertEqual( + inputs["attention_mask"], + [[0] * pad_len + [1] * len(expected_input_ids_1), [1] * len(expected_input_ids_2)], + ) + encoder_feature_dims = ( + 3 * processor.image_processor.encoder_patch_size * processor.image_processor.encoder_patch_size + ) + self.assertEqual( + np.array(inputs["pixel_values"]).shape, + (3, processor.image_processor.max_num_patches, encoder_feature_dims), + ) + self.assertEqual( + np.array(inputs["pixel_attention_mask"]).shape, (3, processor.image_processor.max_num_patches) + ) + self.assertListEqual(inputs["spatial_shapes"].tolist(), [[6, 6], [6, 6], [6, 6]]) + + def test_process_interleaved_images_prompts_image_splitting(self): + processor = self.get_processor() + + image_str = "" + text_str_1 = "In this image, we see" + text_str_2 = "bla, bla" + + text = [image_str + text_str_1, text_str_2 + image_str + image_str] + images = [[self.small_image], [self.high_res_image, self.high_res_image]] + + inputs = processor( + text=text, + images=images, + padding=True, + padding_side="left", + max_pixels_tolerance=2.0, + use_thumbnail=True, + do_image_splitting=True, + ) + + tokenized_sentence_1 = processor.tokenizer(text_str_1, add_special_tokens=False) + tokenized_sentence_2 = processor.tokenizer(text_str_2, add_special_tokens=False) + + small_image_tokens = self.get_split_image_expected_tokens(processor, 3, 3, True, 9) + large_image_tokens = self.get_split_image_expected_tokens(processor, 3, 3, True, 9) + high_res_image_tokens = self.get_split_image_expected_tokens(processor, 3, 3, True, 9) + + expected_input_ids_1 = small_image_tokens + tokenized_sentence_1["input_ids"] + expected_input_ids_2 = tokenized_sentence_2["input_ids"] + large_image_tokens + high_res_image_tokens + # Pad the first input to match the second input + pad_len = len(expected_input_ids_2) - len(expected_input_ids_1) + padded_expected_input_ids_1 = [self.padding_token_id] * pad_len + expected_input_ids_1 + + self.assertEqual(inputs["input_ids"][0], padded_expected_input_ids_1) + self.assertEqual(inputs["input_ids"][1], expected_input_ids_2) + self.assertEqual( + inputs["attention_mask"], + [[0] * pad_len + [1] * len(expected_input_ids_1), [1] * len(expected_input_ids_2)], + ) + self.assertEqual(np.array(inputs["pixel_values"]).shape, (30, 49, 12)) + self.assertEqual(np.array(inputs["pixel_attention_mask"]).shape, (30, 49)) + self.assertListEqual(inputs["spatial_shapes"].tolist(), ([[7, 7]] * 9 + [[6, 6]]) * 3) + + def test_add_special_tokens_processor_image_splitting(self): + processor = self.get_processor() + + image_str = "" + text_str = "In this image, we see" + text = text_str + image_str + + # fmt: off + inputs = processor(text=text, images=self.high_res_image, add_special_tokens=False, do_image_splitting=True) + tokenized_sentence = processor.tokenizer(text_str, add_special_tokens=False) + split_high_res_image_tokens = self.get_split_image_expected_tokens(processor, 3, 3, True, 9) + expected_input_ids = [tokenized_sentence["input_ids"] + split_high_res_image_tokens] + self.assertEqual(inputs["input_ids"], expected_input_ids) + # fmt: on + + def test_add_special_tokens_processor_image_splitting_large_image(self): + processor = self.get_processor() + + image_str = "" + text_str = "In this image, we see" + text = text_str + image_str + + # fmt: off + inputs = processor(text=text, images=self.large_image, add_special_tokens=False, max_pixels_tolerance=2.0, do_image_splitting=True) + tokenized_sentence = processor.tokenizer(text_str, add_special_tokens=False) + large_image_tokens = self.get_split_image_expected_tokens(processor, 2, 4, True, 8) + expected_input_ids = [tokenized_sentence["input_ids"] + large_image_tokens] + self.assertEqual(inputs["input_ids"], expected_input_ids) + # fmt: on + + def test_add_special_tokens_processor_image_no_splitting(self): + processor = self.get_processor() + + image_str = "" + text_str = "In this image, we see" + text = image_str + text_str + + # fmt: off + inputs = processor(text=text, images=self.high_res_image, add_special_tokens=False, use_image_special_tokens=True, do_image_splitting=False) + tokenized_sentence = processor.tokenizer(text_str, add_special_tokens=False) + split_high_res_image_tokens = [self.image_start_token_id] + [self.image_token_id] * 9 + [self.image_end_token_id] + expected_input_ids = [split_high_res_image_tokens + tokenized_sentence["input_ids"]] + self.assertEqual(inputs["input_ids"], expected_input_ids) + # fmt: on + + def test_process_interleaved_images_prompts_image_error(self): + processor = self.get_processor() + + text = [ + "This is a test sentence.", + "In this other sentence we try some good things", + ] + images = [[self.small_image], [self.large_image]] + with self.assertRaises(ValueError): + processor(text=text, images=images, padding=True) + images = [[self.small_image], []] + with self.assertRaises(ValueError): + processor(text=text, images=images, padding=True) + + text = [ + "This is a test sentence.", + "In this other sentence we try some good things", + ] + images = [[self.small_image], [self.large_image, self.high_res_image]] + with self.assertRaises(ValueError): + processor(text=text, images=images, padding=True) + images = [[], [self.large_image]] + with self.assertRaises(ValueError): + processor(text=text, images=images, padding=True) + images = [self.small_image, self.large_image, self.high_res_image] + with self.assertRaises(ValueError): + processor(text=text, images=images, padding=True) + images = [self.small_image] + with self.assertRaises(ValueError): + processor(text=text, images=images, padding=True) + + text = [ + "This is a test sentence.", + "In this other sentence we try some good things", + ] + images = [[self.small_image], []] + with self.assertRaises(ValueError): + processor(text=text, images=images, padding=True) + + images = [[], [self.large_image]] + processor(text=text, images=images, padding=True) + + images = [self.small_image, self.large_image] + with self.assertRaises(ValueError): + processor(text=text, images=images, padding=True) + + images = [self.small_image] + with self.assertRaises(ValueError): + processor(text=text, images=images, padding=True) + + def test_apply_chat_template(self): + # Message contains content which a mix of lists with images and image urls and string + messages = [ + { + "role": "user", + "content": [ + {"type": "text", "text": "What do these images show?"}, + {"type": "image"}, + {"type": "image"}, + ], + }, + { + "role": "assistant", + "content": [ + { + "type": "text", + "text": "The first image shows the statue of Liberty in New York. The second image picture depicts Idefix, the dog of Obelix in Asterix and Obelix.", + } + ], + }, + {"role": "user", "content": [{"type": "text", "text": "And who is that?"}]}, + ] + processor = self.get_processor() + # Make short sequence length to test that the fake tokens are added correctly + rendered = processor.apply_chat_template(messages, add_generation_prompt=True) + + expected_rendered = ( + "<|startoftext|><|im_start|>user\nWhat do these images show?<|im_end|>\n" + "<|im_start|>assistant\nThe first image shows the statue of Liberty in New York. The second image picture depicts Idefix, the dog of Obelix in Asterix and Obelix.<|im_end|>\n" + "<|im_start|>user\nAnd who is that?<|im_end|>\n" + "<|im_start|>assistant\n" + ) + self.assertEqual(rendered, expected_rendered) + + def test_text_only_inference(self): + """Test that the processor works correctly with text-only input.""" + processor_components = self.prepare_components() + processor_components["tokenizer"] = self.get_component("tokenizer", padding_side="left") + processor_kwargs = self.prepare_processor_dict() + + processor = self.processor_class(**processor_components, **processor_kwargs) + + text = "This is a simple text without images." + inputs = processor(text=text) + + tokenized_sentence = processor.tokenizer(text, add_special_tokens=False) + expected_input_ids = [tokenized_sentence["input_ids"]] + + self.assertEqual(inputs["input_ids"], expected_input_ids) + self.assertEqual(inputs["attention_mask"], [[1] * len(expected_input_ids[0])]) + self.assertTrue("pixel_values" not in inputs) + self.assertTrue("pixel_attention_mask" not in inputs) + + # Test batch of texts without image tokens + texts = ["First text.", "Second piece of text."] + batch_inputs = processor(text=texts, padding=True) + + tokenized_1 = processor.tokenizer(texts[0], add_special_tokens=False) + tokenized_2 = processor.tokenizer(texts[1], add_special_tokens=False) + + expected_1 = tokenized_1["input_ids"] + expected_2 = tokenized_2["input_ids"] + + # Pad the shorter sequence + pad_len = len(expected_2) - len(expected_1) + if pad_len > 0: + padded_expected_1 = [self.padding_token_id] * pad_len + expected_1 + expected_attention_1 = [0] * pad_len + [1] * len(expected_1) + self.assertEqual(batch_inputs["input_ids"], [padded_expected_1, expected_2]) + self.assertEqual(batch_inputs["attention_mask"], [expected_attention_1, [1] * len(expected_2)]) + else: + pad_len = -pad_len + padded_expected_2 = [self.padding_token_id] * pad_len + expected_2 + expected_attention_2 = [0] * pad_len + [1] * len(expected_2) + self.assertEqual(batch_inputs["input_ids"], [expected_1, padded_expected_2]) + self.assertEqual(batch_inputs["attention_mask"], [[1] * len(expected_1), expected_attention_2]) + + def test_missing_images_error(self): + """Test that appropriate error is raised when images are referenced but not provided.""" + processor = self.get_processor() + + # Test single text with image token but no image + text = "Let me show you this image: What do you think?" + with self.assertRaises(ValueError) as context: + processor(text=text) + self.assertTrue("We detected 1 tokens in the text but no images were passed" in str(context.exception)) + + # Test batch with image tokens but no images + texts = [ + "First text with token.", + "Second text with token.", + ] + with self.assertRaises(ValueError) as context: + processor(text=texts) + self.assertTrue("We detected 2 tokens in the text but no images were passed" in str(context.exception)) + + # Test with None as Images + with self.assertRaises(ValueError) as context: + processor(text=text, images=None) + self.assertTrue("We detected 1 tokens in the text but no images were passed" in str(context.exception)) + + with self.assertRaises(ValueError) as context: + processor(text=texts, images=None) + self.assertTrue("We detected 2 tokens in the text but no images were passed" in str(context.exception)) diff --git a/tests/test_processing_common.py b/tests/test_processing_common.py index b5c74c8f25d0..e0094bafa695 100644 --- a/tests/test_processing_common.py +++ b/tests/test_processing_common.py @@ -875,7 +875,8 @@ def test_overlapping_text_image_kwargs_handling(self): self.skipTest(f"image_processor attribute not present in {self.processor_class}") processor_components = self.prepare_components() - processor = self.processor_class(**processor_components) + processor_kwargs = self.prepare_processor_dict() + processor = self.processor_class(**processor_components, **processor_kwargs) self.skip_processor_without_typed_kwargs(processor) input_str = self.prepare_text_inputs(modalities="image") From 4d4932e26b857fd89131ee6314ba2a0bd6e8f71a Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Thu, 18 Sep 2025 19:49:14 +0800 Subject: [PATCH 101/204] Fix outdated version checks of accelerator (#40969) * Fix outdated version checks of accelerator Signed-off-by: Yuanyuan Chen * Fix outdated version checks of accelerator Signed-off-by: Yuanyuan Chen --------- Signed-off-by: Yuanyuan Chen --- src/transformers/trainer.py | 9 +++------ tests/fsdp/test_fsdp.py | 14 +------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/transformers/trainer.py b/src/transformers/trainer.py index 97de1d6d5397..10fa8cad13cb 100755 --- a/src/transformers/trainer.py +++ b/src/transformers/trainer.py @@ -241,10 +241,9 @@ DATA_SAMPLERS = [RandomSampler] if version.parse(accelerate_version) > version.parse("1.3.0"): from accelerate.utils import TorchTensorParallelPlugin - if version.parse(accelerate_version) > version.parse("0.23.0"): - from accelerate.data_loader import SeedableRandomSampler + from accelerate.data_loader import SeedableRandomSampler - DATA_SAMPLERS += [SeedableRandomSampler] + DATA_SAMPLERS += [SeedableRandomSampler] if is_deepspeed_available(): from accelerate.utils import DeepSpeedSchedulerWrapper @@ -4196,9 +4195,7 @@ def save_model(self, output_dir: Optional[str] = None, _internal_call: bool = Fa elif (tp_size := getattr(self.model, "_tp_size", 0)) is not None and tp_size > 1: self._save(output_dir) elif self.is_fsdp_enabled: - if ("FULL_STATE_DICT" in str(self.accelerator.state.fsdp_plugin.state_dict_type)) and ( - version.parse(accelerate_version) > version.parse("0.24.1") - ): + if "FULL_STATE_DICT" in str(self.accelerator.state.fsdp_plugin.state_dict_type): state_dict = self.accelerator.get_state_dict(self.model) if self.args.should_save: self._save(output_dir, state_dict=state_dict) diff --git a/tests/fsdp/test_fsdp.py b/tests/fsdp/test_fsdp.py index a932a1fbac67..6a4060b0a731 100644 --- a/tests/fsdp/test_fsdp.py +++ b/tests/fsdp/test_fsdp.py @@ -88,22 +88,11 @@ def get_master_port(real_launcher=False): if is_torch_available(): - from tests.trainer.test_trainer import ( # noqa - RegressionModelConfig, - RegressionPreTrainedModel, - ) - # hack to restore original logging level pre #21700 get_regression_trainer = partial(tests.trainer.test_trainer.get_regression_trainer, log_level="info") -require_fsdp_version = require_fsdp if is_accelerate_available(): - from accelerate.utils.constants import ( - FSDP_PYTORCH_VERSION, - FSDP_SHARDING_STRATEGY, - ) - - require_fsdp_version = partial(require_fsdp, min_version=FSDP_PYTORCH_VERSION) + from accelerate.utils.constants import FSDP_SHARDING_STRATEGY FSDP2_ACCELERATE_VERSION = "1.6.0" @@ -142,7 +131,6 @@ def _parameterized_custom_name_func(func, param_num, param): @require_accelerate @require_torch_accelerator -@require_fsdp_version class TrainerIntegrationFSDP(TestCasePlus, TrainerIntegrationCommon): def setUp(self): super().setUp() From 9104de833519cd9b0df4935ba1424f66312abf35 Mon Sep 17 00:00:00 2001 From: Hamish Scott <41787553+hamishs@users.noreply.github.com> Date: Thu, 18 Sep 2025 12:51:45 +0100 Subject: [PATCH 102/204] Use `skip_predictor=True` in vjepa2 `get_vision_features` (#40966) use skip_predictor in vjepa2 `get_vision_features` --- src/transformers/models/vjepa2/modeling_vjepa2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/models/vjepa2/modeling_vjepa2.py b/src/transformers/models/vjepa2/modeling_vjepa2.py index bde505b4ea54..eedc94b845a4 100644 --- a/src/transformers/models/vjepa2/modeling_vjepa2.py +++ b/src/transformers/models/vjepa2/modeling_vjepa2.py @@ -1125,7 +1125,7 @@ def forward( return encoder_output def get_vision_features(self, pixel_values_videos) -> torch.Tensor: - encoder_output = self.forward(pixel_values_videos) + encoder_output = self.forward(pixel_values_videos, skip_predictor=True) return encoder_output.last_hidden_state From b9ad602f4da0923ec0b9aac2a50b00e032abeeb5 Mon Sep 17 00:00:00 2001 From: Marc Sun <57196510+SunMarc@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:07:20 +0200 Subject: [PATCH 103/204] [Trainer] Fix DP loss (#40799) * fix * style * Fix fp16 * style --------- Co-authored-by: Matej Sirovatka <54212263+S1ro1@users.noreply.github.com> --- src/transformers/trainer.py | 17 ++++++++++------- src/transformers/training_args.py | 12 ------------ tests/trainer/test_trainer.py | 14 ++++++++++++-- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/transformers/trainer.py b/src/transformers/trainer.py index 10fa8cad13cb..24e1730608d2 100755 --- a/src/transformers/trainer.py +++ b/src/transformers/trainer.py @@ -2483,8 +2483,7 @@ def _inner_training_loop( model, self.optimizer, self.lr_scheduler = self.accelerator.prepare( self.model, self.optimizer, self.lr_scheduler ) - elif self.args.optim in [OptimizerNames.LOMO, OptimizerNames.ADALOMO]: - # In this case we are in DDP + LOMO, which should be supported + else: self.optimizer = self.accelerator.prepare(self.optimizer) if self.is_fsdp_enabled: @@ -3783,7 +3782,7 @@ def log(self, logs: dict[str, float], start_time: Optional[float] = None) -> Non """ if self.state.epoch is not None: logs["epoch"] = self.state.epoch - if self.args.include_num_input_tokens_seen: + if self.args.include_num_input_tokens_seen != "no": logs["num_input_tokens_seen"] = self.state.num_input_tokens_seen if start_time is not None: logs.update(speed_metrics("train", start_time, num_tokens=self.state.num_input_tokens_seen)) @@ -4143,7 +4142,7 @@ def compute_loss( and (self.model_accepts_loss_kwargs or self.compute_loss_func) and num_items_in_batch is not None ): - loss *= self.accelerator.num_processes + loss *= self.accelerator.num_processes if self.args.n_gpu <= 1 else self.args.n_gpu return (loss, outputs) if return_outputs else loss @@ -5617,15 +5616,19 @@ def get_batch_samples( pass if num_items_in_batch is not None: - if self.args.average_tokens_across_devices: + if self.args.average_tokens_across_devices and self.args.world_size >= 1: num_items_in_batch = self.accelerator.gather(num_items_in_batch.to(device)).sum() + elif self.args.n_gpu >= 1: + # In DP case, if we don't average, we need to divide by the number of gpu. This is the simplest approximation. + # Otherwise, we would have to scatter labels and calculate num_items_in_batch for each gpu. + num_items_in_batch = num_items_in_batch // self.args.n_gpu if torch.is_tensor(num_items_in_batch): num_items_in_batch = num_items_in_batch.to(device) if self.args.n_gpu > 1 and num_items_in_batch.dim() == 0: - # In the DataParallel case, convert the scalar tensor into a 1-dim tensor - num_items_in_batch = num_items_in_batch.unsqueeze(0) + # In the DataParallel case, convert the scalar tensor into a 2-dim tensor with the same value repeated + num_items_in_batch = num_items_in_batch.unsqueeze(0).expand(self.args.n_gpu, -1) # Divide by number of devices with the same batch if pc := getattr(self.accelerator, "parallelism_config", None): num_items_in_batch = num_items_in_batch // pc.non_data_parallel_size diff --git a/src/transformers/training_args.py b/src/transformers/training_args.py index 5219feb22023..b232dcb76454 100644 --- a/src/transformers/training_args.py +++ b/src/transformers/training_args.py @@ -1790,18 +1790,6 @@ def __post_init__(self): if self.framework == "pt" and is_torch_available(): self.device - # Disable average tokens when using single device - if self.average_tokens_across_devices: - try: - if self.world_size == 1: - logger.info( - "average_tokens_across_devices is True but world size is 1. Setting it to False automatically." - ) - self.average_tokens_across_devices = False - except ImportError as e: - logger.warning(f"Can not specify world size due to {e}. Turn average_tokens_across_devices to False.") - self.average_tokens_across_devices = False - if self.torchdynamo is not None: warnings.warn( "`torchdynamo` is deprecated and will be removed in version 5 of 🤗 Transformers. Use" diff --git a/tests/trainer/test_trainer.py b/tests/trainer/test_trainer.py index 47e1004df9b6..29558f50bba1 100644 --- a/tests/trainer/test_trainer.py +++ b/tests/trainer/test_trainer.py @@ -1270,6 +1270,18 @@ def test_adafactor_lr_none(self): self.assertFalse(torch.allclose(trainer.model.b, b)) self.assertGreater(trainer.optimizer.state_dict()["param_groups"][0]["lr"], 0) + @require_torch_fp16 + @require_torch_accelerator + def test_mixed_fp16(self): + # very basic test + with tempfile.TemporaryDirectory() as tmp_dir: + trainer = get_regression_trainer(learning_rate=0.1, fp16=True, logging_steps=1, output_dir=tmp_dir) + trainer.train() + self.check_trained_model(trainer.model, atol=ATOL, rtol=RTOL) + log_0 = trainer.state.log_history[:-1][0] + # check that the grads were properly clipped due to the grad scaler. Otherwise, we get huge values + self.assertEqual(log_0["grad_norm"] < 100, True) + @require_torch_bf16 @require_torch_accelerator def test_mixed_bf16(self): @@ -1286,8 +1298,6 @@ def test_mixed_bf16(self): learning_rate=0.1, bf16=True, half_precision_backend="apex", output_dir=tmp_dir ) - # will add more specific tests once there are some bugs to fix - @require_torch_gpu @require_torch_tf32 def test_tf32(self): From 55e48bfeea3c51309078f32e38f20784b1e82c78 Mon Sep 17 00:00:00 2001 From: Harshal Janjani <75426551+harshaljanjani@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:09:08 +0400 Subject: [PATCH 104/204] [timm_wrapper] better handling of "Unknown model" exception in timm (#40951) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(timm): Add exception handling for unknown Gemma3n model * nit: Let’s cater to this specific issue * nit: Simplify error handling --- .../timm_wrapper/modeling_timm_wrapper.py | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/transformers/models/timm_wrapper/modeling_timm_wrapper.py b/src/transformers/models/timm_wrapper/modeling_timm_wrapper.py index 7839bf7813f2..cfc3c1c104d3 100644 --- a/src/transformers/models/timm_wrapper/modeling_timm_wrapper.py +++ b/src/transformers/models/timm_wrapper/modeling_timm_wrapper.py @@ -55,6 +55,28 @@ class TimmWrapperModelOutput(ModelOutput): attentions: Optional[tuple[torch.FloatTensor, ...]] = None +def _create_timm_model_with_error_handling(config: "TimmWrapperConfig", **model_kwargs): + """ + Creates a timm model and provides a clear error message if the model is not found, + suggesting a library update. + """ + try: + model = timm.create_model( + config.architecture, + pretrained=False, + **model_kwargs, + ) + return model + except RuntimeError as e: + if "Unknown model" in str(e): + # A good general check for unknown models. + raise ImportError( + f"The model architecture '{config.architecture}' is not supported in your version of timm ({timm.__version__}). " + "Please upgrade timm to a more recent version with `pip install -U timm`." + ) from e + raise e + + @auto_docstring class TimmWrapperPreTrainedModel(PreTrainedModel): main_input_name = "pixel_values" @@ -138,7 +160,7 @@ def __init__(self, config: TimmWrapperConfig): super().__init__(config) # using num_classes=0 to avoid creating classification head extra_init_kwargs = config.model_args or {} - self.timm_model = timm.create_model(config.architecture, pretrained=False, num_classes=0, **extra_init_kwargs) + self.timm_model = _create_timm_model_with_error_handling(config, num_classes=0, **extra_init_kwargs) self.post_init() @auto_docstring @@ -254,8 +276,8 @@ def __init__(self, config: TimmWrapperConfig): ) extra_init_kwargs = config.model_args or {} - self.timm_model = timm.create_model( - config.architecture, pretrained=False, num_classes=config.num_labels, **extra_init_kwargs + self.timm_model = _create_timm_model_with_error_handling( + config, num_classes=config.num_labels, **extra_init_kwargs ) self.num_labels = config.num_labels self.post_init() From ca8eed3ca825dc98dd1c7ba751e88999719ed54e Mon Sep 17 00:00:00 2001 From: Branden Date: Thu, 18 Sep 2025 06:22:19 -0700 Subject: [PATCH 105/204] Fix Issue #39030: AutoTokenizer.from_pretrained does not propagate token (#40956) * fix merge conflicts * change token typing --------- Co-authored-by: Ubuntu --- src/transformers/processing_utils.py | 1 + src/transformers/tokenization_utils_base.py | 1 + src/transformers/utils/hub.py | 2 ++ 3 files changed, 4 insertions(+) diff --git a/src/transformers/processing_utils.py b/src/transformers/processing_utils.py index 86cdb372034c..b864d2971cae 100644 --- a/src/transformers/processing_utils.py +++ b/src/transformers/processing_utils.py @@ -963,6 +963,7 @@ def get_processor_dict( local_files_only=local_files_only, revision=revision, cache_dir=cache_dir, + token=token, ): additional_chat_template_files[template] = f"{CHAT_TEMPLATE_DIR}/{template}.jinja" except EntryNotFoundError: diff --git a/src/transformers/tokenization_utils_base.py b/src/transformers/tokenization_utils_base.py index e4df51c7f867..f88711fdb655 100644 --- a/src/transformers/tokenization_utils_base.py +++ b/src/transformers/tokenization_utils_base.py @@ -2042,6 +2042,7 @@ def from_pretrained( local_files_only=local_files_only, revision=revision, cache_dir=cache_dir, + token=token, ): template = template.removesuffix(".jinja") vocab_files[f"chat_template_{template}"] = f"{CHAT_TEMPLATE_DIR}/{template}.jinja" diff --git a/src/transformers/utils/hub.py b/src/transformers/utils/hub.py index 4beacbe25aeb..573dfad08f5b 100644 --- a/src/transformers/utils/hub.py +++ b/src/transformers/utils/hub.py @@ -155,6 +155,7 @@ def list_repo_templates( local_files_only: bool, revision: Optional[str] = None, cache_dir: Optional[str] = None, + token: Union[bool, str, None] = None, ) -> list[str]: """List template files from a repo. @@ -171,6 +172,7 @@ def list_repo_templates( revision=revision, path_in_repo=CHAT_TEMPLATE_DIR, recursive=False, + token=token, ) if entry.path.endswith(".jinja") ] From 33735546377175e3ce5be44587c15b58746063fc Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Thu, 18 Sep 2025 15:24:12 +0200 Subject: [PATCH 106/204] [tests] Really use small models in all fast tests (#40945) * start * xcodec * chameleon * start * layoutlm2 * layoutlm * remove skip * oups * timm_wrapper * add default * doc * consistency --- .../models/gemma3n/configuration_gemma3n.py | 2 +- .../configuration_timm_wrapper.py | 4 ++++ .../chameleon/test_modeling_chameleon.py | 10 +--------- tests/models/emu3/test_modeling_emu3.py | 4 ---- .../layoutlmv2/test_modeling_layoutlmv2.py | 20 +++++++++---------- .../qwen2_5_vl/test_modeling_qwen2_5_vl.py | 4 ---- .../models/qwen2_vl/test_modeling_qwen2_vl.py | 4 ---- .../test_modeling_timm_wrapper.py | 11 ++++------ tests/models/xcodec/test_modeling_xcodec.py | 20 +++++++++++++------ 9 files changed, 34 insertions(+), 45 deletions(-) diff --git a/src/transformers/models/gemma3n/configuration_gemma3n.py b/src/transformers/models/gemma3n/configuration_gemma3n.py index 3502d2a423c9..b0f7c590650f 100644 --- a/src/transformers/models/gemma3n/configuration_gemma3n.py +++ b/src/transformers/models/gemma3n/configuration_gemma3n.py @@ -502,10 +502,10 @@ def __init__( **kwargs, ): super().__init__(**kwargs) + self.architecture = architecture self.initializer_range = initializer_range self.do_pooling = do_pooling self.model_args = model_args # named "model_args" for BC with timm - self.architecture = architecture self.hidden_size = hidden_size self.vocab_size = vocab_size self.vocab_offset = vocab_offset diff --git a/src/transformers/models/timm_wrapper/configuration_timm_wrapper.py b/src/transformers/models/timm_wrapper/configuration_timm_wrapper.py index 5fa115a05431..24142232241f 100644 --- a/src/transformers/models/timm_wrapper/configuration_timm_wrapper.py +++ b/src/transformers/models/timm_wrapper/configuration_timm_wrapper.py @@ -41,6 +41,8 @@ class TimmWrapperConfig(PretrainedConfig): imagenet models is set to `None` due to occlusions in the label descriptions. Args: + architecture (`str`, *optional*, defaults to `"resnet50"`): + The timm architecture to load. initializer_range (`float`, *optional*, defaults to 0.02): The standard deviation of the truncated_normal_initializer for initializing all weight matrices. do_pooling (`bool`, *optional*, defaults to `True`): @@ -65,11 +67,13 @@ class TimmWrapperConfig(PretrainedConfig): def __init__( self, + architecture: str = "resnet50", initializer_range: float = 0.02, do_pooling: bool = True, model_args: Optional[dict[str, Any]] = None, **kwargs, ): + self.architecture = architecture self.initializer_range = initializer_range self.do_pooling = do_pooling self.model_args = model_args # named "model_args" for BC with timm diff --git a/tests/models/chameleon/test_modeling_chameleon.py b/tests/models/chameleon/test_modeling_chameleon.py index fa9e45506929..ecf873182234 100644 --- a/tests/models/chameleon/test_modeling_chameleon.py +++ b/tests/models/chameleon/test_modeling_chameleon.py @@ -76,7 +76,7 @@ def __init__( pad_token_id=0, vq_num_embeds=5, vq_embed_dim=5, - vq_channel_multiplier=[1, 4], + vq_channel_multiplier=[1, 2], vq_img_token_start_id=10, # has to be less than vocab size when added with vq_num_embeds scope=None, ): @@ -255,10 +255,6 @@ def test_model_rope_scaling(self, scaling_type): def test_batching_equivalence(self): pass - @unittest.skip("Chameleon VQ model cannot be squishes more due to hardcoded layer params in model code") - def test_model_is_small(self): - pass - class ChameleonVision2SeqModelTester(ChameleonModelTester): def __init__(self, parent, image_size=10, **kwargs): @@ -321,10 +317,6 @@ def test_disk_offload_bin(self): def test_disk_offload_safetensors(self): pass - @unittest.skip("Chameleon VQ model cannot be squishes more due to hardcoded layer params in model code") - def test_model_is_small(self): - pass - @unittest.skip("Chameleon applies key/query norm which doesn't work with packing") def test_flash_attention_2_padding_matches_padding_free_with_position_ids(self): pass diff --git a/tests/models/emu3/test_modeling_emu3.py b/tests/models/emu3/test_modeling_emu3.py index 8975cfe4a0b4..1bef4585414d 100644 --- a/tests/models/emu3/test_modeling_emu3.py +++ b/tests/models/emu3/test_modeling_emu3.py @@ -359,10 +359,6 @@ def test_initialization(self): def test_generate_with_static_cache(self): pass - # @unittest.skip("Emu3 can't be smaller than currently if we want to downsample images") - # def test_model_is_small(self): - # pass - @require_torch class Emu3IntegrationTest(unittest.TestCase): diff --git a/tests/models/layoutlmv2/test_modeling_layoutlmv2.py b/tests/models/layoutlmv2/test_modeling_layoutlmv2.py index 00cf7e59b6ea..2c1b157e3a90 100644 --- a/tests/models/layoutlmv2/test_modeling_layoutlmv2.py +++ b/tests/models/layoutlmv2/test_modeling_layoutlmv2.py @@ -70,7 +70,7 @@ def __init__( type_vocab_size=16, type_sequence_label_size=2, initializer_range=0.02, - image_feature_pool_shape=[7, 7, 256], + image_feature_pool_shape=[7, 7, 32], coordinate_size=6, shape_size=6, num_labels=3, @@ -106,6 +106,14 @@ def __init__( self.num_choices = num_choices self.scope = scope self.range_bbox = range_bbox + detectron2_config = LayoutLMv2Config.get_default_detectron2_config() + # We need to make the model smaller + detectron2_config["MODEL.RESNETS.DEPTH"] = 50 + detectron2_config["MODEL.RESNETS.RES2_OUT_CHANNELS"] = 4 + detectron2_config["MODEL.RESNETS.STEM_OUT_CHANNELS"] = 4 + detectron2_config["MODEL.FPN.OUT_CHANNELS"] = 32 + detectron2_config["MODEL.RESNETS.NUM_GROUPS"] = 1 + self.detectron2_config = detectron2_config def prepare_config_and_inputs(self): input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) @@ -158,13 +166,9 @@ def prepare_config_and_inputs(self): image_feature_pool_shape=self.image_feature_pool_shape, coordinate_size=self.coordinate_size, shape_size=self.shape_size, + detectron2_config_args=self.detectron2_config, ) - # use smaller resnet backbone to make tests faster - config.detectron2_config_args["MODEL.RESNETS.DEPTH"] = 18 - config.detectron2_config_args["MODEL.RESNETS.RES2_OUT_CHANNELS"] = 64 - config.detectron2_config_args["MODEL.RESNETS.NUM_GROUPS"] = 1 - return config, input_ids, bbox, image, token_type_ids, input_mask, sequence_labels, token_labels def create_and_check_model( @@ -422,10 +426,6 @@ def check_hidden_states_output(inputs_dict, config, model_class): check_hidden_states_output(inputs_dict, config, model_class) - @unittest.skip(reason="We cannot configure detectron2 to output a smaller backbone") - def test_model_is_small(self): - pass - @slow def test_model_from_pretrained(self): model_name = "microsoft/layoutlmv2-base-uncased" diff --git a/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py b/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py index a105302a9952..650f8b05d3b1 100644 --- a/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py +++ b/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py @@ -441,10 +441,6 @@ def test_sdpa_can_dispatch_on_flash(self): def test_multi_gpu_data_parallel_forward(self): pass - @unittest.skip(reason="We cannot configure to output a smaller model.") - def test_model_is_small(self): - pass - @require_torch class Qwen2_5_VLIntegrationTest(unittest.TestCase): diff --git a/tests/models/qwen2_vl/test_modeling_qwen2_vl.py b/tests/models/qwen2_vl/test_modeling_qwen2_vl.py index 6cbdba8e26c0..ef109fb7cca7 100644 --- a/tests/models/qwen2_vl/test_modeling_qwen2_vl.py +++ b/tests/models/qwen2_vl/test_modeling_qwen2_vl.py @@ -394,10 +394,6 @@ def test_sdpa_can_dispatch_on_flash(self): def test_multi_gpu_data_parallel_forward(self): pass - @unittest.skip(reason="We cannot configure to output a smaller model.") - def test_model_is_small(self): - pass - @require_torch class Qwen2VLIntegrationTest(unittest.TestCase): diff --git a/tests/models/timm_wrapper/test_modeling_timm_wrapper.py b/tests/models/timm_wrapper/test_modeling_timm_wrapper.py index b7653f4e7709..8715aaaae7d0 100644 --- a/tests/models/timm_wrapper/test_modeling_timm_wrapper.py +++ b/tests/models/timm_wrapper/test_modeling_timm_wrapper.py @@ -53,14 +53,15 @@ class TimmWrapperModelTester: def __init__( self, parent, - model_name="timm/resnet18.a1_in1k", batch_size=3, image_size=32, num_channels=3, is_training=True, ): self.parent = parent - self.model_name = model_name + self.architecture = "resnet26" + # We need this to make the model smaller + self.model_args = {"channels": (16, 16, 16, 16)} self.batch_size = batch_size self.image_size = image_size self.num_channels = num_channels @@ -73,7 +74,7 @@ def prepare_config_and_inputs(self): return config, pixel_values def get_config(self): - return TimmWrapperConfig.from_pretrained(self.model_name) + return TimmWrapperConfig(architecture=self.architecture, model_args=self.model_args) def prepare_config_and_inputs_for_common(self): config_and_inputs = self.prepare_config_and_inputs() @@ -166,10 +167,6 @@ def test_initialization(self): def test_mismatched_shapes_have_properly_initialized_weights(self): pass - @unittest.skip(reason="Need to use a timm model and there is no tiny model available.") - def test_model_is_small(self): - pass - def test_gradient_checkpointing(self): config, _ = self.model_tester.prepare_config_and_inputs_for_common() model = TimmWrapperModel._from_config(config) diff --git a/tests/models/xcodec/test_modeling_xcodec.py b/tests/models/xcodec/test_modeling_xcodec.py index a5df6cfeb310..79a9fdd6e484 100644 --- a/tests/models/xcodec/test_modeling_xcodec.py +++ b/tests/models/xcodec/test_modeling_xcodec.py @@ -39,7 +39,7 @@ if is_torch_available(): import torch - from transformers import XcodecModel + from transformers import DacConfig, HubertConfig, XcodecModel @require_torch @@ -51,7 +51,7 @@ def __init__( num_channels=1, sample_rate=16000, codebook_size=1024, - num_samples=400, + num_samples=256, is_training=False, ): self.parent = parent @@ -61,6 +61,16 @@ def __init__( self.codebook_size = codebook_size self.is_training = is_training self.num_samples = num_samples + self.acoustic_model_config = DacConfig( + decoder_hidden_size=8, encoder_hidden_size=8, codebook_size=16, downsampling_ratios=[16, 16] + ) + self.semantic_model_config = HubertConfig( + hidden_size=32, + num_hidden_layers=2, + num_attention_heads=2, + intermediate_size=12, + conv_dim=(4, 4, 4, 4, 4, 4, 4), + ) def prepare_config_and_inputs(self): config = self.get_config() @@ -86,6 +96,8 @@ def get_config(self): sample_rate=self.sample_rate, audio_channels=self.num_channels, codebook_size=self.codebook_size, + acoustic_model_config=self.acoustic_model_config, + semantic_model_config=self.semantic_model_config, ) def create_and_check_model_forward(self, config, inputs_dict): @@ -151,10 +163,6 @@ def test_gradient_checkpointing_backward_compatibility(self): model = model_class(config) self.assertTrue(model.is_gradient_checkpointing) - @unittest.skip(reason="We cannot configure to output a smaller model.") - def test_model_is_small(self): - pass - @unittest.skip(reason="The XcodecModel does not have `inputs_embeds` logics") def test_inputs_embeds(self): pass From 1e8b8d322058769ce54a5def3149e9fd443c4098 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:40:53 +0200 Subject: [PATCH 107/204] Add captured actual outputs to CI artifacts (#40965) * fix * fix * Remove `# TODO: ???` as it make me `???` * fix * fix * fix --------- Co-authored-by: ydshieh --- .github/workflows/model_jobs.yml | 23 ++++++++++++------- utils/notification_service.py | 39 +++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/.github/workflows/model_jobs.yml b/.github/workflows/model_jobs.yml index 5da145c2b006..09279b58db3b 100644 --- a/.github/workflows/model_jobs.yml +++ b/.github/workflows/model_jobs.yml @@ -128,28 +128,35 @@ jobs: echo "machine_type=$machine_type" >> $GITHUB_ENV echo "machine_type=$machine_type" >> $GITHUB_OUTPUT + - name: Create report directory if it doesn't exist + shell: bash + run: | + mkdir -p /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports + echo "dummy" > /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/dummy.txt + ls -la /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports + - name: Run all tests on GPU working-directory: /transformers - run: python3 -m pytest -rsfE -v --make-reports=${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports tests/${{ matrix.folders }} + run: | + PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS=yes _PATCHED_TESTING_METHODS_OUTPUT_DIR=/transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports python3 -m pytest -rsfE -v --make-reports=${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports tests/${{ matrix.folders }} - name: Failure short reports if: ${{ failure() }} continue-on-error: true - run: cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports/failures_short.txt + run: cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/failures_short.txt - - name: Run test - shell: bash + - name: Captured information + if: ${{ failure() }} + continue-on-error: true run: | - mkdir -p /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports - echo "hello" > /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports/hello.txt - echo "${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports" + cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/captured_info.txt - name: "Test suite reports artifacts: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports" if: ${{ always() }} uses: actions/upload-artifact@v4 with: name: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports - path: /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports + path: /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports collated_reports: name: Collated Reports diff --git a/utils/notification_service.py b/utils/notification_service.py index 410d3ba78507..6449c0a84f99 100644 --- a/utils/notification_service.py +++ b/utils/notification_service.py @@ -1196,6 +1196,15 @@ def pop_default(l: list[Any], i: int, default: Any) -> Any: "time_spent": [], "failures": {}, "job_link": {}, + "captured_info": {}, + } + for matrix_name in job_matrix + if f"{report_name_prefix}_{matrix_name}_test_reports" in available_artifacts + } + + matrix_job_results_extra = { + matrix_name: { + "captured_info": {}, } for matrix_name in job_matrix if f"{report_name_prefix}_{matrix_name}_test_reports" in available_artifacts @@ -1225,7 +1234,21 @@ def pop_default(l: list[Any], i: int, default: Any) -> Any: stacktraces = handle_stacktraces(artifact["failures_line"]) - # TODO: ??? + # Add the captured actual outputs for patched methods (`torch.testing.assert_close`, `assertEqual` etc.) + if "captured_info" in artifact: + step_number = None + for step in job.get("steps", []): + if step["name"] == "Captured information": + step_number = step["number"] + break + if step_number is not None: + step_link = f"{job['html_url']}#step:{step_number}:1" + matrix_job_results[matrix_name]["captured_info"][artifact_gpu] = step_link + matrix_job_results_extra[matrix_name]["captured_info"][artifact_gpu] = { + "link": step_link, + "captured_info": artifact["captured_info"], + } + for line in artifact["summary_short"].split("\n"): if line.startswith("FAILED "): # Avoid the extra `FAILED` entry given by `run_test_using_subprocess` causing issue when calling @@ -1432,6 +1455,20 @@ def pop_default(l: list[Any], i: int, default: Any) -> Any: token=os.environ.get("TRANSFORMERS_CI_RESULTS_UPLOAD_TOKEN", None), ) + if len(matrix_job_results_extra) > 0: + with open( + f"ci_results_{job_name}/{test_to_result_name[test_name]}_results_extra.json", "w", encoding="UTF-8" + ) as fp: + json.dump(matrix_job_results_extra, fp, indent=4, ensure_ascii=False) + + api.upload_file( + path_or_fileobj=f"ci_results_{job_name}/{test_to_result_name[test_name]}_results_extra.json", + path_in_repo=f"{report_repo_folder}/ci_results_{job_name}/{test_to_result_name[test_name]}_results_extra.json", + repo_id=report_repo_id, + repo_type="dataset", + token=os.environ.get("TRANSFORMERS_CI_RESULTS_UPLOAD_TOKEN", None), + ) + # Let's create a file contain job --> job link if len(matrix_job_results) > 0: target_results = matrix_job_results From e5da669cc0d2cca10d6361b84f0fd950aa6fb920 Mon Sep 17 00:00:00 2001 From: Pavel Iakubovskii Date: Thu, 18 Sep 2025 16:25:45 +0100 Subject: [PATCH 108/204] Revert change in `compile_friendly_resize` (#40645) fix --- src/transformers/image_processing_utils_fast.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/transformers/image_processing_utils_fast.py b/src/transformers/image_processing_utils_fast.py index 983fd4e16953..3eaa22cdb690 100644 --- a/src/transformers/image_processing_utils_fast.py +++ b/src/transformers/image_processing_utils_fast.py @@ -375,9 +375,13 @@ def compile_friendly_resize( A wrapper around `F.resize` so that it is compatible with torch.compile when the image is a uint8 tensor. """ if image.dtype == torch.uint8: - image = image.float() / 255 + # 256 is used on purpose instead of 255 to avoid numerical differences + # see https://github.com/huggingface/transformers/pull/38540#discussion_r2127165652 + image = image.float() / 256 image = F.resize(image, new_size, interpolation=interpolation, antialias=antialias) - image = image * 255 + image = image * 256 + # torch.where is used on purpose instead of torch.clamp to avoid bug in torch.compile + # see https://github.com/huggingface/transformers/pull/38540#discussion_r2126888471 image = torch.where(image > 255, 255, image) image = torch.where(image < 0, 0, image) image = image.round().to(torch.uint8) From 740ff67e74b7c1b9b3e43de08500325cbbf40ea5 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Thu, 18 Sep 2025 18:27:27 +0200 Subject: [PATCH 109/204] Track the CI (model) jobs that don't produce test output files (process being killed etc.) (#40981) * fix * fix --------- Co-authored-by: ydshieh --- .github/workflows/model_jobs.yml | 14 +++++++++++++- utils/notification_service.py | 12 +++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/model_jobs.yml b/.github/workflows/model_jobs.yml index 09279b58db3b..121a8687556f 100644 --- a/.github/workflows/model_jobs.yml +++ b/.github/workflows/model_jobs.yml @@ -138,10 +138,16 @@ jobs: - name: Run all tests on GPU working-directory: /transformers run: | - PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS=yes _PATCHED_TESTING_METHODS_OUTPUT_DIR=/transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports python3 -m pytest -rsfE -v --make-reports=${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports tests/${{ matrix.folders }} + script -q -c "PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS=yes _PATCHED_TESTING_METHODS_OUTPUT_DIR=/transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports python3 -m pytest -rsfE -v --make-reports=${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports tests/${{ matrix.folders }}" test_outputs.txt + ls -la + # Extract the exit code from the output file + PYTEST_EXIT_CODE=$(tail -1 test_outputs.txt | grep "PYTEST_EXIT_CODE:" | cut -d: -f2) + exit ${PYTEST_EXIT_CODE:-1} - name: Failure short reports if: ${{ failure() }} + # This step is only to show information on Github Actions log. + # Always mark this step as successful, even if the report directory or the file `failures_short.txt` in it doesn't exist continue-on-error: true run: cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/failures_short.txt @@ -151,6 +157,12 @@ jobs: run: | cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/captured_info.txt + - name: Copy test_outputs.txt + if: ${{ always() }} + continue-on-error: true + run: | + cp /transformers/test_outputs.txt /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports + - name: "Test suite reports artifacts: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports" if: ${{ always() }} uses: actions/upload-artifact@v4 diff --git a/utils/notification_service.py b/utils/notification_service.py index 6449c0a84f99..ccff52d28df7 100644 --- a/utils/notification_service.py +++ b/utils/notification_service.py @@ -158,9 +158,11 @@ def __init__( self.n_model_failures = ( self.n_model_single_gpu_failures + self.n_model_multi_gpu_failures + self.n_model_unknown_failures ) + self.n_model_jobs_errored_out = sum(r["error"] for r in model_results.values()) # Failures and success of the additional tests self.n_additional_success = sum(r["success"] for r in additional_results.values()) + self.n_additional_jobs_errored_out = sum(r["error"] for r in additional_results.values()) if len(additional_results) > 0: # `dicts_to_sum` uses `dicts_to_sum` which requires a non empty dictionary. Let's just add an empty entry. @@ -183,6 +185,7 @@ def __init__( self.n_failures = self.n_model_failures + self.n_additional_failures self.n_success = self.n_model_success + self.n_additional_success self.n_tests = self.n_failures + self.n_success + self.n_jobs_errored_out = self.n_model_jobs_errored_out + self.n_additional_jobs_errored_out self.model_results = model_results self.additional_results = additional_results @@ -241,6 +244,7 @@ def failures(self) -> dict: "type": "plain_text", "text": ( f"There were {self.n_failures} failures, out of {self.n_tests} tests.\n" + f"🚨 There were {self.n_jobs_errored_out} jobs errored out (not producing test output files).\n" f"The suite ran in {self.time}." ), "emoji": True, @@ -561,7 +565,7 @@ def payload(self) -> str: if self.ci_title: blocks.append(self.ci_title_section) - if self.n_model_failures > 0 or self.n_additional_failures > 0: + if self.n_model_failures > 0 or self.n_additional_failures > 0 or self.n_jobs_errored_out > 0: blocks.append(self.failures) if self.n_model_failures > 0: @@ -1194,6 +1198,7 @@ def pop_default(l: list[Any], i: int, default: Any) -> Any: "success": 0, "skipped": 0, "time_spent": [], + "error": False, "failures": {}, "job_link": {}, "captured_info": {}, @@ -1222,6 +1227,11 @@ def pop_default(l: list[Any], i: int, default: Any) -> Any: continue artifact = retrieve_artifact(path, artifact_gpu) + + if "summary_short" not in artifact: + # The process might be killed (for example, CPU OOM), or the job is canceled for some reason), etc. + matrix_job_results[matrix_name]["error"] = True + if "stats" in artifact: # Link to the GitHub Action job job = artifact_name_to_job_map[path] From c9b01c378fe7ebbacf497fc99ce303d625ee9fba Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 25 Sep 2025 00:17:34 -0700 Subject: [PATCH 110/204] Using torch.distributions.Categorical --- README.md | 2 +- conftest.py | 2 - docker/consistency.dockerfile | 4 +- docker/transformers-all-latest-gpu/Dockerfile | 4 +- docker/transformers-gpu/Dockerfile | 1 - docker/transformers-past-gpu/Dockerfile | 59 - .../transformers-pytorch-amd-gpu/Dockerfile | 3 - docker/transformers-pytorch-gpu/Dockerfile | 2 - docker/transformers-tensorflow-gpu/Dockerfile | 25 - docs/source/ar/_toctree.yml | 8 - docs/source/ar/tflite.md | 40 - docs/source/en/_toctree.yml | 4 - .../source/en/main_classes/keras_callbacks.md | 28 - docs/source/en/tflite.md | 66 - docs/source/es/_toctree.yml | 2 - .../source/es/converting_tensorflow_models.md | 139 - docs/source/hi/_toctree.yml | 4 +- docs/source/hi/tflite.md | 55 - docs/source/it/_toctree.yml | 2 - .../source/it/converting_tensorflow_models.md | 144 - docs/source/ja/_toctree.yml | 8 - .../source/ja/main_classes/keras_callbacks.md | 28 - docs/source/ja/perf_train_tpu_tf.md | 168 - docs/source/ja/tf_xla.md | 179 - docs/source/ja/tflite.md | 58 - docs/source/ko/_toctree.yml | 4 - .../source/ko/main_classes/keras_callbacks.md | 27 - docs/source/ko/tflite.md | 62 - docs/source/ms/_toctree.yml | 6 - docs/source/pt/_toctree.yml | 2 - .../source/pt/converting_tensorflow_models.md | 152 - docs/source/zh/_toctree.yml | 6 - .../source/zh/main_classes/keras_callbacks.md | 27 - docs/source/zh/tf_xla.md | 179 - docs/source/zh/tflite.md | 54 - .../multiple_choice/utils_multiple_choice.py | 95 +- .../legacy/token-classification/utils_ner.py | 104 +- .../image_processing_new_imgproc_model.py | 10 +- .../modeling_dummy_bert.py | 91 +- .../modeling_from_uppercase_model.py | 12 +- .../modeling_multimodal2.py | 21 +- .../modeling_my_new_model2.py | 2 +- .../modeling_new_task_model.py | 13 +- .../modular-transformers/modeling_roberta.py | 91 +- .../modular-transformers/modeling_super.py | 4 +- .../modeling_test_detr.py | 2 - .../pytorch/question-answering/utils_qa.py | 4 +- setup.py | 56 +- src/transformers/__init__.py | 148 +- src/transformers/activations_tf.py | 147 - src/transformers/commands/convert.py | 165 - src/transformers/commands/env.py | 33 - src/transformers/commands/train.py | 158 - src/transformers/commands/transformers_cli.py | 2 - src/transformers/configuration_utils.py | 12 +- src/transformers/convert_graph_to_onnx.py | 551 --- ...nvert_tf_hub_seq_to_seq_bert_to_pytorch.py | 86 - src/transformers/data/data_collator.py | 493 +-- src/transformers/data/datasets/glue.py | 4 - .../data/datasets/language_modeling.py | 16 - src/transformers/data/datasets/squad.py | 4 - src/transformers/data/processors/glue.py | 51 +- src/transformers/data/processors/squad.py | 113 +- src/transformers/data/processors/utils.py | 25 +- src/transformers/dependency_versions_table.py | 12 +- .../feature_extraction_sequence_utils.py | 15 +- src/transformers/feature_extraction_utils.py | 32 +- src/transformers/file_utils.py | 10 - src/transformers/generation/__init__.py | 127 +- .../generation/flax_logits_process.py | 544 --- src/transformers/generation/flax_utils.py | 1032 ----- .../generation/tf_logits_process.py | 600 --- src/transformers/generation/tf_utils.py | 3132 --------------- src/transformers/image_processing_base.py | 2 +- src/transformers/image_transforms.py | 49 +- src/transformers/image_utils.py | 14 +- .../integrations/integration_utils.py | 11 +- src/transformers/keras_callbacks.py | 413 -- src/transformers/modelcard.py | 135 - src/transformers/modeling_flax_outputs.py | 700 ---- .../modeling_flax_pytorch_utils.py | 491 --- src/transformers/modeling_flax_utils.py | 1274 ------ src/transformers/modeling_tf_outputs.py | 990 ----- src/transformers/modeling_tf_pytorch_utils.py | 676 ---- src/transformers/modeling_tf_utils.py | 3529 ----------------- src/transformers/modeling_utils.py | 326 +- src/transformers/models/albert/__init__.py | 2 - .../models/albert/modeling_albert.py | 133 - .../models/albert/modeling_flax_albert.py | 1132 ------ .../models/albert/modeling_tf_albert.py | 1572 -------- .../models/align/modeling_align.py | 2 - .../models/altclip/modeling_altclip.py | 2 - .../models/aria/image_processing_aria.py | 5 +- src/transformers/models/aria/modular_aria.py | 5 +- ...xtraction_audio_spectrogram_transformer.py | 1 - src/transformers/models/auto/__init__.py | 2 - src/transformers/models/auto/auto_factory.py | 222 +- .../models/auto/modeling_flax_auto.py | 413 -- .../models/auto/modeling_tf_auto.py | 776 ---- .../aya_vision/processing_aya_vision.py | 2 - src/transformers/models/bark/modeling_bark.py | 2 - src/transformers/models/bart/__init__.py | 2 - .../models/bart/configuration_bart.py | 22 +- .../models/bart/modeling_flax_bart.py | 2006 ---------- .../models/bart/modeling_tf_bart.py | 1713 -------- src/transformers/models/beit/__init__.py | 1 - .../models/beit/image_processing_beit.py | 13 +- .../models/beit/image_processing_beit_fast.py | 3 +- src/transformers/models/beit/modeling_beit.py | 7 - .../models/beit/modeling_flax_beit.py | 956 ----- src/transformers/models/bert/__init__.py | 2 - ..._bert_pytorch_checkpoint_to_original_tf.py | 112 - src/transformers/models/bert/modeling_bert.py | 80 - .../models/bert/modeling_flax_bert.py | 1727 -------- .../models/bert/modeling_tf_bert.py | 2125 ---------- .../models/bert/tokenization_bert_tf.py | 259 -- .../modeling_bert_generation.py | 89 - src/transformers/models/big_bird/__init__.py | 1 - ...gbird_original_tf_checkpoint_to_pytorch.py | 185 +- .../models/big_bird/modeling_big_bird.py | 168 - .../models/big_bird/modeling_flax_big_bird.py | 2648 ------------- .../configuration_bigbird_pegasus.py | 24 +- .../modeling_bigbird_pegasus.py | 2 - .../models/bit/image_processing_bit.py | 7 +- src/transformers/models/bit/modeling_bit.py | 9 +- .../models/blenderbot/__init__.py | 2 - .../blenderbot/configuration_blenderbot.py | 22 +- .../blenderbot/modeling_flax_blenderbot.py | 1508 ------- .../blenderbot/modeling_tf_blenderbot.py | 1557 -------- .../models/blenderbot_small/__init__.py | 2 - .../configuration_blenderbot_small.py | 24 +- .../modeling_flax_blenderbot_small.py | 1528 ------- .../modeling_tf_blenderbot_small.py | 1527 ------- src/transformers/models/blip/__init__.py | 2 - .../models/blip/image_processing_blip.py | 7 +- .../models/blip/modeling_blip_text.py | 4 - .../models/blip/modeling_tf_blip.py | 1709 -------- .../models/blip/modeling_tf_blip_text.py | 1122 ------ .../models/blip/processing_blip.py | 2 - .../models/blip_2/processing_blip_2.py | 2 - src/transformers/models/bloom/__init__.py | 1 - .../models/bloom/configuration_bloom.py | 8 +- .../models/bloom/modeling_bloom.py | 2 - .../models/bloom/modeling_flax_bloom.py | 737 ---- .../image_processing_bridgetower.py | 9 +- .../bridgetower/modeling_bridgetower.py | 2 - src/transformers/models/bros/modeling_bros.py | 4 - ..._byt5_original_tf_checkpoint_to_pytorch.py | 111 +- src/transformers/models/camembert/__init__.py | 1 - .../models/camembert/modeling_camembert.py | 4 - .../models/camembert/modeling_tf_camembert.py | 1800 --------- ...anine_original_tf_checkpoint_to_pytorch.py | 103 +- .../models/canine/modeling_canine.py | 108 - .../chameleon/image_processing_chameleon.py | 7 +- .../models/chameleon/processing_chameleon.py | 2 - .../configuration_chinese_clip.py | 11 +- .../image_processing_chinese_clip.py | 7 +- .../chinese_clip/modeling_chinese_clip.py | 2 - .../models/clap/feature_extraction_clap.py | 1 - src/transformers/models/clap/modeling_clap.py | 2 - src/transformers/models/clip/__init__.py | 2 - .../models/clip/configuration_clip.py | 11 +- .../models/clip/image_processing_clip.py | 7 +- .../models/clip/modeling_flax_clip.py | 1306 ------ .../models/clip/modeling_tf_clip.py | 1460 ------- .../models/clipseg/processing_clipseg.py | 2 - .../models/clvp/feature_extraction_clvp.py | 1 - .../models/codegen/configuration_codegen.py | 7 +- .../models/codegen/modeling_codegen.py | 2 - .../models/codegen/tokenization_codegen.py | 11 +- .../codegen/tokenization_codegen_fast.py | 8 +- .../models/cohere/tokenization_cohere_fast.py | 4 - .../processing_cohere2_vision.py | 2 - .../models/colpali/modular_colpali.py | 6 - .../models/colpali/processing_colpali.py | 6 - .../models/colqwen2/modular_colqwen2.py | 2 - .../models/colqwen2/processing_colqwen2.py | 6 - .../image_processing_conditional_detr.py | 40 +- .../modeling_conditional_detr.py | 2 - src/transformers/models/convbert/__init__.py | 1 - ...bert_original_tf1_checkpoint_to_pytorch.py | 183 + ...ginal_tf1_checkpoint_to_pytorch_and_tf2.py | 57 - .../models/convbert/modeling_convbert.py | 132 - .../models/convbert/modeling_tf_convbert.py | 1474 ------- src/transformers/models/convnext/__init__.py | 1 - .../convnext/image_processing_convnext.py | 7 +- .../models/convnext/modeling_convnext.py | 7 - .../models/convnext/modeling_tf_convnext.py | 667 ---- .../models/convnextv2/__init__.py | 1 - .../models/convnextv2/modeling_convnextv2.py | 7 - .../convnextv2/modeling_tf_convnextv2.py | 681 ---- src/transformers/models/csm/processing_csm.py | 2 - src/transformers/models/ctrl/__init__.py | 1 - src/transformers/models/ctrl/modeling_ctrl.py | 2 - .../models/ctrl/modeling_tf_ctrl.py | 920 ----- src/transformers/models/cvt/__init__.py | 1 - src/transformers/models/cvt/modeling_cvt.py | 5 - .../models/cvt/modeling_tf_cvt.py | 1095 ----- .../models/dab_detr/modeling_dab_detr.py | 2 - .../models/dac/feature_extraction_dac.py | 1 - src/transformers/models/data2vec/__init__.py | 1 - .../models/data2vec/modeling_data2vec_text.py | 4 - .../data2vec/modeling_data2vec_vision.py | 7 - .../data2vec/modeling_tf_data2vec_vision.py | 1723 -------- src/transformers/models/deberta/__init__.py | 1 - .../models/deberta/configuration_deberta.py | 7 +- .../models/deberta/modeling_deberta.py | 4 +- .../models/deberta/modeling_tf_deberta.py | 1652 -------- .../models/deberta_v2/__init__.py | 1 - .../deberta_v2/configuration_deberta_v2.py | 7 +- .../models/deberta_v2/modeling_deberta_v2.py | 2 - .../deberta_v2/modeling_tf_deberta_v2.py | 1879 --------- .../modeling_decision_transformer.py | 63 - .../image_processing_deepseek_vl.py | 7 +- .../models/deepseek_vl/modular_deepseek_vl.py | 2 - .../deepseek_vl/processing_deepseek_vl.py | 2 - .../image_processing_deepseek_vl_hybrid.py | 7 +- .../modular_deepseek_vl_hybrid.py | 9 +- .../processing_deepseek_vl_hybrid.py | 2 - .../image_processing_deformable_detr.py | 41 +- .../modeling_deformable_detr.py | 2 - src/transformers/models/deit/__init__.py | 1 - .../models/deit/configuration_deit.py | 4 +- .../models/deit/image_processing_deit.py | 7 +- .../models/deit/modeling_tf_deit.py | 1232 ------ .../deprecated/deta/image_processing_deta.py | 38 +- .../models/deprecated/deta/modeling_deta.py | 2 - .../deprecated/efficientformer/__init__.py | 1 - .../image_processing_efficientformer.py | 7 +- .../modeling_efficientformer.py | 5 - .../modeling_tf_efficientformer.py | 1198 ------ .../deprecated/ernie_m/modeling_ernie_m.py | 2 - .../modeling_gptsan_japanese.py | 9 - .../deprecated/jukebox/modeling_jukebox.py | 4 +- .../jukebox/tokenization_jukebox.py | 23 +- .../mctct/feature_extraction_mctct.py | 1 - .../models/deprecated/mctct/modeling_mctct.py | 4 - .../models/deprecated/mega/modeling_mega.py | 2 - .../models/deprecated/nat/modeling_nat.py | 7 - .../models/deprecated/nezha/modeling_nezha.py | 79 - .../deprecated/qdqbert/modeling_qdqbert.py | 80 - .../models/deprecated/realm/modeling_realm.py | 114 - .../deprecated/realm/retrieval_realm.py | 10 - .../retribert/modeling_retribert.py | 1 - .../deprecated/tapex/tokenization_tapex.py | 1 - .../modeling_trajectory_transformer.py | 76 - .../models/deprecated/transfo_xl/__init__.py | 1 - ...fo_xl_original_tf_checkpoint_to_pytorch.py | 130 +- .../transfo_xl/modeling_tf_transfo_xl.py | 1128 ------ .../modeling_tf_transfo_xl_utilities.py | 178 - .../transfo_xl/modeling_transfo_xl.py | 129 - .../transfo_xl/tokenization_transfo_xl.py | 1 - .../deprecated/tvlt/image_processing_tvlt.py | 5 +- .../models/deprecated/tvlt/modeling_tvlt.py | 2 - .../models/deprecated/van/modeling_van.py | 5 - .../vit_hybrid/image_processing_vit_hybrid.py | 7 +- .../depth_anything/modeling_depth_anything.py | 2 - .../depth_pro/image_processing_depth_pro.py | 7 +- .../models/depth_pro/modeling_depth_pro.py | 2 - .../models/detr/image_processing_detr.py | 42 +- .../models/detr/image_processing_detr_fast.py | 2 +- src/transformers/models/detr/modeling_detr.py | 2 - .../models/dia/feature_extraction_dia.py | 1 - .../models/dinat/modeling_dinat.py | 7 - src/transformers/models/dinov2/__init__.py | 1 - .../models/dinov2/modeling_dinov2.py | 5 - .../models/dinov2/modeling_flax_dinov2.py | 801 ---- .../modeling_dinov2_with_registers.py | 5 - .../modeling_dinov3_convnext.py | 7 - .../models/dinov3_vit/modeling_dinov3_vit.py | 5 - .../models/distilbert/__init__.py | 2 - .../models/distilbert/modeling_distilbert.py | 3 - .../distilbert/modeling_flax_distilbert.py | 906 ----- .../distilbert/modeling_tf_distilbert.py | 1146 ------ .../models/donut/image_processing_donut.py | 7 +- .../models/donut/modeling_donut_swin.py | 7 - src/transformers/models/dpr/__init__.py | 1 - src/transformers/models/dpr/modeling_dpr.py | 5 - .../models/dpr/modeling_tf_dpr.py | 799 ---- .../models/dpr/tokenization_dpr.py | 1 - .../models/dpr/tokenization_dpr_fast.py | 1 - .../models/dpt/configuration_dpt.py | 4 +- .../models/dpt/image_processing_dpt.py | 10 +- .../models/dpt/image_processing_dpt_fast.py | 3 +- src/transformers/models/dpt/modeling_dpt.py | 2 - .../image_processing_efficientloftr.py | 10 +- .../image_processing_efficientnet.py | 7 +- .../efficientnet/modeling_efficientnet.py | 2 - src/transformers/models/electra/__init__.py | 2 - ...ectra_original_tf_checkpoint_to_pytorch.py | 86 +- .../models/electra/modeling_electra.py | 89 - .../models/electra/modeling_flax_electra.py | 1614 -------- .../models/electra/modeling_tf_electra.py | 1775 --------- .../models/emu3/image_processing_emu3.py | 7 +- .../models/emu3/processing_emu3.py | 2 - .../encodec/feature_extraction_encodec.py | 1 - .../models/encoder_decoder/__init__.py | 2 - .../modeling_encoder_decoder.py | 104 - .../modeling_flax_encoder_decoder.py | 901 ----- .../modeling_tf_encoder_decoder.py | 661 --- .../models/eomt/image_processing_eomt.py | 7 +- src/transformers/models/eomt/modeling_eomt.py | 5 - .../models/ernie/modeling_ernie.py | 4 - src/transformers/models/esm/__init__.py | 1 - src/transformers/models/esm/modeling_esm.py | 2 - .../models/esm/modeling_tf_esm.py | 1574 -------- .../models/esm/openfold_utils/tensor_utils.py | 1 - .../models/falcon/modeling_falcon.py | 2 - src/transformers/models/flaubert/__init__.py | 1 - .../models/flaubert/modeling_flaubert.py | 1 - .../models/flaubert/modeling_tf_flaubert.py | 1343 ------- .../models/flava/image_processing_flava.py | 7 +- .../models/flava/modeling_flava.py | 4 - .../models/florence2/modeling_florence2.py | 5 - .../models/florence2/modular_florence2.py | 2 - .../models/florence2/processing_florence2.py | 2 - src/transformers/models/fnet/modeling_fnet.py | 4 - .../models/focalnet/modeling_focalnet.py | 7 - src/transformers/models/funnel/__init__.py | 1 - ...unnel_original_tf_checkpoint_to_pytorch.py | 95 +- .../models/funnel/modeling_funnel.py | 93 - .../models/funnel/modeling_tf_funnel.py | 1883 --------- .../models/fuyu/image_processing_fuyu.py | 2 - src/transformers/models/gemma/__init__.py | 1 - .../models/gemma/configuration_gemma.py | 5 - .../models/gemma/modeling_flax_gemma.py | 777 ---- .../models/gemma/modular_gemma.py | 5 - .../models/gemma3/image_processing_gemma3.py | 7 +- .../gemma3n/feature_extraction_gemma3n.py | 2 +- src/transformers/models/git/modeling_git.py | 4 - .../models/glm4v/image_processing_glm4v.py | 7 +- .../models/glm4v/modular_glm4v.py | 2 - .../models/glm4v/processing_glm4v.py | 2 - .../models/glpn/image_processing_glpn.py | 7 +- src/transformers/models/glpn/modeling_glpn.py | 7 - .../got_ocr2/image_processing_got_ocr2.py | 7 +- .../models/got_ocr2/processing_got_ocr2.py | 2 - src/transformers/models/gpt2/__init__.py | 2 - .../models/gpt2/configuration_gpt2.py | 5 +- ..._gpt2_original_tf_checkpoint_to_pytorch.py | 60 +- .../models/gpt2/modeling_flax_gpt2.py | 782 ---- src/transformers/models/gpt2/modeling_gpt2.py | 61 - .../models/gpt2/modeling_tf_gpt2.py | 1238 ------ .../models/gpt2/tokenization_gpt2_tf.py | 119 - .../gpt_bigcode/modeling_gpt_bigcode.py | 2 - src/transformers/models/gpt_neo/__init__.py | 1 - .../models/gpt_neo/configuration_gpt_neo.py | 10 +- .../convert_gpt_neo_mesh_tf_to_pytorch.py | 87 +- .../models/gpt_neo/modeling_flax_gpt_neo.py | 687 ---- .../models/gpt_neo/modeling_gpt_neo.py | 87 - src/transformers/models/gptj/__init__.py | 2 - .../models/gptj/configuration_gptj.py | 5 +- .../models/gptj/modeling_flax_gptj.py | 721 ---- src/transformers/models/gptj/modeling_gptj.py | 2 - .../models/gptj/modeling_tf_gptj.py | 1094 ----- .../image_processing_grounding_dino.py | 38 +- .../grounding_dino/modeling_grounding_dino.py | 7 - src/transformers/models/groupvit/__init__.py | 1 - .../models/groupvit/configuration_groupvit.py | 11 +- .../models/groupvit/modeling_groupvit.py | 2 - .../models/groupvit/modeling_tf_groupvit.py | 2141 ---------- .../models/hiera/modeling_hiera.py | 5 - src/transformers/models/hubert/__init__.py | 1 - .../models/hubert/modeling_hubert.py | 2 - .../models/hubert/modeling_tf_hubert.py | 1671 -------- .../models/hubert/modular_hubert.py | 2 - .../models/ibert/modeling_ibert.py | 4 - src/transformers/models/idefics/__init__.py | 1 - .../idefics/image_processing_idefics.py | 5 +- .../models/idefics/modeling_tf_idefics.py | 1778 --------- .../models/idefics/perceiver_tf.py | 195 - .../models/idefics/processing_idefics.py | 75 +- src/transformers/models/idefics/vision_tf.py | 572 --- .../idefics2/image_processing_idefics2.py | 9 +- .../idefics3/image_processing_idefics3.py | 9 +- .../models/ijepa/configuration_ijepa.py | 4 +- .../models/imagegpt/configuration_imagegpt.py | 11 +- ...onvert_imagegpt_original_tf2_to_pytorch.py | 112 +- .../imagegpt/image_processing_imagegpt.py | 7 +- .../models/imagegpt/modeling_imagegpt.py | 113 - .../image_processing_instructblipvideo.py | 7 +- .../models/internvl/processing_internvl.py | 2 - .../models/janus/image_processing_janus.py | 7 +- .../models/janus/modular_janus.py | 7 +- .../models/janus/processing_janus.py | 2 - .../models/jetmoe/modeling_jetmoe.py | 2 - .../kosmos2_5/image_processing_kosmos2_5.py | 14 +- .../image_processing_kosmos2_5_fast.py | 3 - .../models/kosmos2_5/modeling_kosmos2_5.py | 1 - ...eature_extraction_kyutai_speech_to_text.py | 1 - .../modular_kyutai_speech_to_text.py | 1 - src/transformers/models/layoutlm/__init__.py | 1 - .../models/layoutlm/configuration_layoutlm.py | 14 +- .../models/layoutlm/modeling_layoutlm.py | 2 - .../models/layoutlm/modeling_tf_layoutlm.py | 1691 -------- .../layoutlmv2/image_processing_layoutlmv2.py | 7 +- .../models/layoutlmv2/modeling_layoutlmv2.py | 2 - .../layoutlmv2/tokenization_layoutlmv2.py | 1 - .../models/layoutlmv3/__init__.py | 1 - .../layoutlmv3/configuration_layoutlmv3.py | 10 +- .../layoutlmv3/image_processing_layoutlmv3.py | 7 +- .../models/layoutlmv3/modeling_layoutlmv3.py | 2 - .../layoutlmv3/modeling_tf_layoutlmv3.py | 1767 --------- .../layoutlmv3/tokenization_layoutlmv3.py | 2 - .../layoutxlm/tokenization_layoutxlm.py | 1 - .../layoutxlm/tokenization_layoutxlm_fast.py | 1 - src/transformers/models/led/__init__.py | 1 - .../models/led/modeling_tf_led.py | 2663 ------------- .../models/levit/image_processing_levit.py | 7 +- .../models/levit/modeling_levit.py | 2 - .../lightglue/image_processing_lightglue.py | 10 +- src/transformers/models/lilt/modeling_lilt.py | 4 - src/transformers/models/llama/__init__.py | 1 - .../models/llama/modeling_flax_llama.py | 747 ---- .../models/llama4/processing_llama4.py | 2 - .../models/llava/image_processing_llava.py | 7 +- .../models/llava/processing_llava.py | 2 - .../llava_next/image_processing_llava_next.py | 7 +- .../image_processing_llava_next_video.py | 2 - .../processing_llava_next_video.py | 2 - .../image_processing_llava_onevision.py | 7 +- .../models/longformer/__init__.py | 1 - .../longformer/configuration_longformer.py | 8 +- .../models/longformer/modeling_longformer.py | 4 - .../longformer/modeling_tf_longformer.py | 2783 ------------- src/transformers/models/longt5/__init__.py | 1 - .../models/longt5/configuration_longt5.py | 2 +- .../convert_longt5x_checkpoint_to_flax.py | 215 - .../models/longt5/modeling_flax_longt5.py | 2449 ------------ .../models/longt5/modeling_longt5.py | 13 - src/transformers/models/luke/modeling_luke.py | 2 - .../models/luke/tokenization_luke.py | 17 +- src/transformers/models/lxmert/__init__.py | 1 - .../models/lxmert/configuration_lxmert.py | 4 - ...xmert_original_tf_checkpoint_to_pytorch.py | 83 +- .../models/lxmert/modeling_lxmert.py | 85 - .../models/lxmert/modeling_tf_lxmert.py | 1660 -------- .../models/m2m_100/configuration_m2m_100.py | 12 +- src/transformers/models/marian/__init__.py | 2 - .../models/marian/configuration_marian.py | 35 +- .../models/marian/modeling_flax_marian.py | 1500 ------- .../models/marian/modeling_tf_marian.py | 1558 -------- .../models/marian/tokenization_marian.py | 4 +- .../models/markuplm/modeling_markuplm.py | 2 - .../models/markuplm/tokenization_markuplm.py | 1 - .../image_processing_mask2former.py | 10 +- .../maskformer/image_processing_maskformer.py | 10 +- .../models/maskformer/modeling_maskformer.py | 2 - .../maskformer/modeling_maskformer_swin.py | 7 - src/transformers/models/mbart/__init__.py | 2 - .../models/mbart/configuration_mbart.py | 22 +- .../models/mbart/modeling_flax_mbart.py | 1780 --------- .../models/mbart/modeling_tf_mbart.py | 1572 -------- .../megatron_bert/modeling_megatron_bert.py | 76 - .../models/mgp_str/modeling_mgp_str.py | 5 - src/transformers/models/mistral/__init__.py | 2 - .../models/mistral/modeling_flax_mistral.py | 744 ---- .../models/mistral/modeling_tf_mistral.py | 1016 ----- .../models/mllama/image_processing_mllama.py | 2 - .../models/mllama/processing_mllama.py | 2 - .../models/mluke/tokenization_mluke.py | 17 +- .../modeling_mm_grounding_dino.py | 7 - .../models/mobilebert/__init__.py | 1 - ...ebert_original_tf_checkpoint_to_pytorch.py | 82 +- .../models/mobilebert/modeling_mobilebert.py | 83 - .../mobilebert/modeling_tf_mobilebert.py | 1979 --------- ...nvert_original_tf_checkpoint_to_pytorch.py | 104 +- .../image_processing_mobilenet_v1.py | 7 +- .../mobilenet_v1/modeling_mobilenet_v1.py | 105 - ...nvert_original_tf_checkpoint_to_pytorch.py | 170 +- .../image_processing_mobilenet_v2.py | 13 +- .../image_processing_mobilenet_v2_fast.py | 3 +- .../mobilenet_v2/modeling_mobilenet_v2.py | 175 +- src/transformers/models/mobilevit/__init__.py | 1 - .../mobilevit/image_processing_mobilevit.py | 13 +- .../models/mobilevit/modeling_mobilevit.py | 6 +- .../models/mobilevit/modeling_tf_mobilevit.py | 1376 ------- .../mobilevitv2/modeling_mobilevitv2.py | 6 +- src/transformers/models/mpnet/__init__.py | 1 - .../models/mpnet/modeling_mpnet.py | 2 - .../models/mpnet/modeling_tf_mpnet.py | 1353 ------- src/transformers/models/mpt/modeling_mpt.py | 2 - src/transformers/models/mra/modeling_mra.py | 4 - src/transformers/models/mt5/__init__.py | 2 - .../models/mt5/modeling_flax_mt5.py | 123 - src/transformers/models/mt5/modeling_mt5.py | 119 - .../models/mt5/modeling_tf_mt5.py | 98 - .../feature_extraction_musicgen_melody.py | 1 - ..._myt5_original_tf_checkpoint_to_pytorch.py | 111 +- .../models/nougat/image_processing_nougat.py | 7 +- .../nystromformer/modeling_nystromformer.py | 4 - .../oneformer/image_processing_oneformer.py | 10 +- src/transformers/models/openai/__init__.py | 1 - ...penai_original_tf_checkpoint_to_pytorch.py | 83 +- .../models/openai/modeling_openai.py | 90 +- .../models/openai/modeling_tf_openai.py | 936 ----- src/transformers/models/opt/__init__.py | 2 - .../models/opt/modeling_flax_opt.py | 802 ---- .../models/opt/modeling_tf_opt.py | 1092 ----- .../models/ovis2/image_processing_ovis2.py | 7 +- .../models/owlv2/image_processing_owlv2.py | 7 +- .../owlv2/image_processing_owlv2_fast.py | 1 - .../models/owlv2/processing_owlv2.py | 17 +- .../models/owlvit/configuration_owlvit.py | 11 +- .../models/owlvit/image_processing_owlvit.py | 8 +- .../owlvit/image_processing_owlvit_fast.py | 1 - .../models/owlvit/processing_owlvit.py | 18 +- .../models/paligemma/processing_paligemma.py | 2 - src/transformers/models/pegasus/__init__.py | 2 - .../models/pegasus/modeling_flax_pegasus.py | 1532 ------- .../models/pegasus/modeling_tf_pegasus.py | 1573 -------- .../models/pegasus_x/modeling_pegasus_x.py | 3 - .../perceiver/configuration_perceiver.py | 9 +- .../perceiver/image_processing_perceiver.py | 7 +- .../models/perceiver/modeling_perceiver.py | 4 - .../perception_lm/processing_perception_lm.py | 2 - .../feature_extraction_phi4_multimodal.py | 1 - .../pix2struct/image_processing_pix2struct.py | 15 +- .../models/pix2struct/modeling_pix2struct.py | 4 - .../pixtral/image_processing_pixtral.py | 7 +- .../models/pixtral/processing_pixtral.py | 2 - .../poolformer/image_processing_poolformer.py | 7 +- .../models/poolformer/modeling_poolformer.py | 5 - .../models/pop2piano/modeling_pop2piano.py | 10 - .../pop2piano/tokenization_pop2piano.py | 3 +- .../image_processing_prompt_depth_anything.py | 7 +- .../models/pvt/image_processing_pvt.py | 7 +- src/transformers/models/pvt/modeling_pvt.py | 5 - .../models/pvt_v2/modeling_pvt_v2.py | 5 - .../models/qwen2_5_vl/modular_qwen2_5_vl.py | 2 - .../qwen2_5_vl/processing_qwen2_5_vl.py | 2 - .../qwen2_vl/image_processing_qwen2_vl.py | 7 +- .../models/qwen2_vl/processing_qwen2_vl.py | 2 - .../models/qwen3_vl/modular_qwen3_vl.py | 2 - .../models/qwen3_vl/processing_qwen3_vl.py | 2 - src/transformers/models/rag/__init__.py | 1 - src/transformers/models/rag/modeling_rag.py | 8 - .../models/rag/modeling_tf_rag.py | 1776 --------- src/transformers/models/rag/retrieval_rag.py | 1 - .../models/reformer/modeling_reformer.py | 2 - src/transformers/models/regnet/__init__.py | 2 - .../models/regnet/modeling_flax_regnet.py | 822 ---- .../models/regnet/modeling_tf_regnet.py | 611 --- src/transformers/models/rembert/__init__.py | 1 - ...onvert_rembert_tf_checkpoint_to_pytorch.py | 87 +- .../models/rembert/modeling_rembert.py | 90 - .../models/rembert/modeling_tf_rembert.py | 1720 -------- src/transformers/models/resnet/__init__.py | 2 - .../models/resnet/modeling_flax_resnet.py | 704 ---- .../models/resnet/modeling_tf_resnet.py | 596 --- src/transformers/models/roberta/__init__.py | 2 - .../models/roberta/modeling_flax_roberta.py | 1500 ------- .../models/roberta/modeling_roberta.py | 4 - .../models/roberta/modeling_tf_roberta.py | 1782 --------- .../models/roberta_prelayernorm/__init__.py | 2 - .../modeling_flax_roberta_prelayernorm.py | 1527 ------- .../modeling_roberta_prelayernorm.py | 4 - .../modeling_tf_roberta_prelayernorm.py | 1807 --------- .../models/roc_bert/modeling_roc_bert.py | 81 - src/transformers/models/roformer/__init__.py | 2 - ...ormer_original_tf_checkpoint_to_pytorch.py | 77 +- .../models/roformer/modeling_flax_roformer.py | 1091 ----- .../models/roformer/modeling_roformer.py | 80 - .../models/roformer/modeling_tf_roformer.py | 1546 -------- .../rt_detr/image_processing_rt_detr.py | 44 +- src/transformers/models/sam/__init__.py | 1 - .../models/sam/image_processing_sam.py | 344 +- .../models/sam/image_processing_sam_fast.py | 2 +- .../models/sam/modeling_tf_sam.py | 1723 -------- src/transformers/models/sam/processing_sam.py | 21 +- .../models/sam2/image_processing_sam2_fast.py | 2 +- .../feature_extraction_seamless_m4t.py | 1 - src/transformers/models/segformer/__init__.py | 1 - .../segformer/image_processing_segformer.py | 10 +- .../image_processing_segformer_fast.py | 3 +- .../models/segformer/modeling_segformer.py | 7 - .../models/segformer/modeling_tf_segformer.py | 1044 ----- .../models/seggpt/image_processing_seggpt.py | 9 +- .../models/seggpt/modeling_seggpt.py | 5 - src/transformers/models/sew/modeling_sew.py | 2 - src/transformers/models/sew/modular_sew.py | 2 - .../models/sew_d/modeling_sew_d.py | 2 - .../models/siglip/image_processing_siglip.py | 7 +- .../siglip2/image_processing_siglip2.py | 7 +- .../smolvlm/image_processing_smolvlm.py | 9 +- .../models/speech_encoder_decoder/__init__.py | 1 - .../modeling_flax_speech_encoder_decoder.py | 930 ----- .../modeling_speech_encoder_decoder.py | 8 - .../models/speech_to_text/__init__.py | 1 - .../feature_extraction_speech_to_text.py | 1 - .../modeling_tf_speech_to_text.py | 1600 -------- .../speecht5/feature_extraction_speecht5.py | 1 - .../models/splinter/modeling_splinter.py | 4 - .../squeezebert/modeling_squeezebert.py | 4 - .../superglue/image_processing_superglue.py | 10 +- .../models/superglue/modeling_superglue.py | 2 - .../superpoint/image_processing_superpoint.py | 10 +- .../models/superpoint/modeling_superpoint.py | 2 - .../models/swiftformer/__init__.py | 1 - .../swiftformer/modeling_swiftformer.py | 5 - .../swiftformer/modeling_tf_swiftformer.py | 866 ---- src/transformers/models/swin/__init__.py | 1 - src/transformers/models/swin/modeling_swin.py | 7 - .../models/swin/modeling_tf_swin.py | 1639 -------- .../swin2sr/image_processing_swin2sr.py | 8 +- .../models/swin2sr/modeling_swin2sr.py | 5 - .../models/swinv2/modeling_swinv2.py | 7 - ...ers_original_flax_checkpoint_to_pytorch.py | 145 +- .../modeling_switch_transformers.py | 12 - src/transformers/models/t5/__init__.py | 2 - ...rt_t5_original_tf_checkpoint_to_pytorch.py | 111 +- .../t5/convert_t5x_checkpoint_to_flax.py | 235 -- .../models/t5/modeling_flax_t5.py | 1801 --------- src/transformers/models/t5/modeling_t5.py | 134 - src/transformers/models/t5/modeling_tf_t5.py | 1676 -------- .../modeling_table_transformer.py | 2 - src/transformers/models/tapas/__init__.py | 1 - ...tapas_original_tf_checkpoint_to_pytorch.py | 139 +- .../models/tapas/modeling_tapas.py | 142 - .../models/tapas/modeling_tf_tapas.py | 2461 ------------ .../models/tapas/tokenization_tapas.py | 8 +- .../textnet/image_processing_textnet.py | 7 +- .../timesformer/modeling_timesformer.py | 5 - .../models/tvp/image_processing_tvp.py | 7 +- src/transformers/models/tvp/modeling_tvp.py | 2 - src/transformers/models/udop/modeling_udop.py | 10 - .../models/udop/tokenization_udop.py | 1 - .../models/udop/tokenization_udop_fast.py | 1 - src/transformers/models/umt5/modeling_umt5.py | 1 - .../univnet/feature_extraction_univnet.py | 1 - .../image_processing_video_llava.py | 7 +- .../video_llava/processing_video_llava.py | 2 - .../videomae/image_processing_videomae.py | 7 +- .../models/videomae/modeling_videomae.py | 2 - .../models/vilt/image_processing_vilt.py | 9 +- src/transformers/models/vilt/modeling_vilt.py | 4 - .../models/vision_encoder_decoder/__init__.py | 2 - .../configuration_vision_encoder_decoder.py | 10 +- .../modeling_flax_vision_encoder_decoder.py | 864 ---- .../modeling_tf_vision_encoder_decoder.py | 696 ---- .../modeling_vision_encoder_decoder.py | 135 - .../vision_text_dual_encoder/__init__.py | 2 - .../modeling_flax_vision_text_dual_encoder.py | 601 --- .../modeling_tf_vision_text_dual_encoder.py | 623 --- .../modeling_vision_text_dual_encoder.py | 12 +- .../visual_bert/modeling_visual_bert.py | 5 - src/transformers/models/vit/__init__.py | 2 - .../models/vit/configuration_vit.py | 4 +- .../models/vit/image_processing_vit.py | 7 +- .../models/vit/modeling_flax_vit.py | 677 ---- .../models/vit/modeling_tf_vit.py | 906 ----- src/transformers/models/vit_mae/__init__.py | 1 - .../models/vit_mae/modeling_tf_vit_mae.py | 1374 ------- .../models/vit_mae/modeling_vit_mae.py | 2 - .../models/vit_msn/modeling_vit_msn.py | 2 - .../models/vitdet/modeling_vitdet.py | 5 - .../vitmatte/image_processing_vitmatte.py | 12 +- .../vitpose/image_processing_vitpose.py | 7 +- .../models/vivit/image_processing_vivit.py | 7 +- .../models/vivit/modeling_vivit.py | 2 - .../models/vjepa2/modeling_vjepa2.py | 5 - .../models/voxtral/processing_voxtral.py | 2 - src/transformers/models/wav2vec2/__init__.py | 2 - .../wav2vec2/feature_extraction_wav2vec2.py | 1 - .../models/wav2vec2/modeling_flax_wav2vec2.py | 1423 ------- .../models/wav2vec2/modeling_tf_wav2vec2.py | 1855 --------- .../models/wav2vec2/tokenization_wav2vec2.py | 19 +- .../tokenization_wav2vec2_phoneme.py | 18 +- src/transformers/models/whisper/__init__.py | 2 - .../models/whisper/configuration_whisper.py | 10 +- .../whisper/feature_extraction_whisper.py | 1 - .../models/whisper/modeling_flax_whisper.py | 1707 -------- .../models/whisper/modeling_tf_whisper.py | 1754 -------- .../models/whisper/tokenization_whisper.py | 13 +- .../whisper/tokenization_whisper_fast.py | 13 +- .../models/x_clip/modeling_x_clip.py | 5 - src/transformers/models/xglm/__init__.py | 2 - .../models/xglm/configuration_xglm.py | 2 +- .../models/xglm/modeling_flax_xglm.py | 803 ---- .../models/xglm/modeling_tf_xglm.py | 1002 ----- src/transformers/models/xlm/__init__.py | 1 - .../models/xlm/modeling_tf_xlm.py | 1356 ------- src/transformers/models/xlm/modeling_xlm.py | 1 - .../models/xlm_roberta/__init__.py | 2 - .../xlm_roberta/modeling_flax_xlm_roberta.py | 1511 ------- .../xlm_roberta/modeling_tf_xlm_roberta.py | 1790 --------- .../xlm_roberta/modeling_xlm_roberta.py | 4 - .../xlm_roberta_xl/modeling_xlm_roberta_xl.py | 4 - src/transformers/models/xlnet/__init__.py | 1 - .../models/xlnet/configuration_xlnet.py | 4 - ...xlnet_original_tf_checkpoint_to_pytorch.py | 152 +- .../models/xlnet/modeling_tf_xlnet.py | 1820 --------- .../models/xlnet/modeling_xlnet.py | 154 - src/transformers/models/xmod/modeling_xmod.py | 4 - .../models/yolos/image_processing_yolos.py | 41 +- .../models/yolos/modeling_yolos.py | 2 - src/transformers/models/yoso/modeling_yoso.py | 4 - .../zoedepth/image_processing_zoedepth.py | 7 +- .../models/zoedepth/modeling_zoedepth.py | 2 - src/transformers/onnx/__main__.py | 16 +- src/transformers/onnx/config.py | 34 +- src/transformers/onnx/convert.py | 129 +- src/transformers/onnx/features.py | 138 +- src/transformers/optimization_tf.py | 378 -- src/transformers/pipelines/__init__.py | 281 +- .../pipelines/audio_classification.py | 3 - .../pipelines/automatic_speech_recognition.py | 11 +- src/transformers/pipelines/base.py | 350 +- .../pipelines/depth_estimation.py | 5 +- .../pipelines/document_question_answering.py | 27 +- .../pipelines/feature_extraction.py | 7 +- src/transformers/pipelines/fill_mask.py | 45 +- .../pipelines/image_classification.py | 17 +- .../pipelines/image_feature_extraction.py | 10 +- .../pipelines/image_segmentation.py | 11 +- .../pipelines/image_text_to_text.py | 4 +- src/transformers/pipelines/image_to_image.py | 3 +- src/transformers/pipelines/image_to_text.py | 34 +- .../pipelines/keypoint_matching.py | 4 +- src/transformers/pipelines/mask_generation.py | 37 +- .../pipelines/object_detection.py | 8 +- .../pipelines/question_answering.py | 36 +- .../pipelines/table_question_answering.py | 179 +- .../pipelines/text2text_generation.py | 44 +- .../pipelines/text_classification.py | 22 +- src/transformers/pipelines/text_generation.py | 57 +- src/transformers/pipelines/text_to_audio.py | 5 +- .../pipelines/token_classification.py | 36 +- .../pipelines/video_classification.py | 20 +- .../pipelines/visual_question_answering.py | 14 +- .../zero_shot_audio_classification.py | 16 +- .../pipelines/zero_shot_classification.py | 9 +- .../zero_shot_image_classification.py | 26 +- .../pipelines/zero_shot_object_detection.py | 12 +- src/transformers/processing_utils.py | 2 - src/transformers/quantizers/auto.py | 4 +- .../quantizers/quantizer_bitnet.py | 6 - .../quantizers/quantizer_bnb_4bit.py | 6 - .../quantizers/quantizer_bnb_8bit.py | 6 - src/transformers/quantizers/quantizer_eetq.py | 6 - .../quantizers/quantizer_finegrained_fp8.py | 6 - src/transformers/quantizers/quantizer_hqq.py | 6 - src/transformers/testing_utils.py | 44 +- src/transformers/tf_utils.py | 294 -- .../tokenization_mistral_common.py | 9 +- src/transformers/tokenization_utils_base.py | 73 +- src/transformers/trainer_utils.py | 19 +- src/transformers/training_args.py | 9 +- src/transformers/training_args_tf.py | 300 -- src/transformers/utils/__init__.py | 18 - src/transformers/utils/doc.py | 458 +-- src/transformers/utils/dummy_flax_objects.py | 107 - .../utils/dummy_tensorflow_text_objects.py | 9 - src/transformers/utils/dummy_tf_objects.py | 178 - src/transformers/utils/generic.py | 155 +- src/transformers/utils/hub.py | 6 +- src/transformers/utils/import_utils.py | 185 +- .../fixtures/add_distilbert_like_config.json | 19 - tests/generation/test_utils.py | 2 - tests/models/auto/test_modeling_auto.py | 12 +- .../aya_vision/test_modeling_aya_vision.py | 2 +- .../big_bird/test_tokenization_big_bird.py | 16 - tests/models/blip/test_modeling_blip.py | 2 +- tests/models/byt5/test_tokenization_byt5.py | 20 +- .../camembert/test_tokenization_camembert.py | 3 - tests/models/clip/test_modeling_clip.py | 2 +- .../test_modeling_cohere2_vision.py | 2 +- tests/models/colpali/test_modeling_colpali.py | 4 +- .../deepseek_vl/test_modeling_deepseek_vl.py | 2 +- .../test_modeling_deepseek_vl_hybrid.py | 2 +- tests/models/fnet/test_modeling_fnet.py | 55 - tests/models/fsmt/test_modeling_fsmt.py | 2 +- tests/models/gemma3n/test_modeling_gemma3n.py | 4 +- .../test_tokenization_layoutlmv2.py | 25 +- .../test_tokenization_layoutlmv3.py | 25 +- .../layoutxlm/test_tokenization_layoutxlm.py | 25 +- tests/models/lxmert/test_modeling_lxmert.py | 33 +- tests/models/marian/test_modeling_marian.py | 2 +- .../models/marian/test_tokenization_marian.py | 13 +- .../markuplm/test_tokenization_markuplm.py | 25 +- .../metaclip_2/test_modeling_metaclip_2.py | 2 +- tests/models/myt5/test_tokenization_myt5.py | 9 - .../paligemma/test_modeling_paligemma.py | 4 +- .../paligemma2/test_modeling_paligemma2.py | 4 +- .../pegasus/test_tokenization_pegasus.py | 19 - .../perceiver/test_tokenization_perceiver.py | 20 +- tests/models/rembert/test_modeling_rembert.py | 11 - tests/models/sam2/test_processor_sam2.py | 5 +- .../sam2_video/test_processor_sam2_video.py | 5 +- tests/models/siglip/test_modeling_siglip.py | 8 +- .../models/siglip/test_tokenization_siglip.py | 19 +- tests/models/siglip2/test_modeling_siglip2.py | 8 +- .../splinter/test_tokenization_splinter.py | 12 +- tests/models/t5/test_tokenization_t5.py | 21 +- tests/models/tapas/test_modeling_tapas.py | 16 - tests/models/tapas/test_tokenization_tapas.py | 18 +- tests/models/udop/test_tokenization_udop.py | 25 +- tests/models/upernet/test_modeling_upernet.py | 2 +- tests/models/vit_mae/test_modeling_vit_mae.py | 7 - tests/models/xlnet/test_modeling_xlnet.py | 3 - .../test_pipelines_audio_classification.py | 2 - ..._pipelines_automatic_speech_recognition.py | 23 +- tests/pipelines/test_pipelines_common.py | 60 +- .../test_pipelines_feature_extraction.py | 14 +- tests/pipelines/test_pipelines_fill_mask.py | 10 +- .../test_pipelines_image_classification.py | 5 +- ...test_pipelines_image_feature_extraction.py | 16 +- .../pipelines/test_pipelines_image_to_text.py | 3 +- .../test_pipelines_mask_generation.py | 9 - .../test_pipelines_question_answering.py | 11 +- .../pipelines/test_pipelines_summarization.py | 19 +- .../test_pipelines_text2text_generation.py | 3 - .../test_pipelines_text_classification.py | 13 +- .../test_pipelines_text_generation.py | 21 +- .../pipelines/test_pipelines_text_to_audio.py | 23 +- .../test_pipelines_token_classification.py | 32 +- tests/pipelines/test_pipelines_translation.py | 6 +- .../test_pipelines_video_classification.py | 3 +- tests/pipelines/test_pipelines_zero_shot.py | 14 +- ...ipelines_zero_shot_audio_classification.py | 8 - tests/repo_utils/test_tests_fetcher.py | 47 +- tests/sagemaker/conftest.py | 29 +- tests/sagemaker/scripts/tensorflow/run_tf.py | 104 - .../test_multi_node_data_parallel.py | 20 +- .../test_multi_node_model_parallel.py | 13 +- tests/sagemaker/test_single_node_gpu.py | 19 +- tests/test_pipeline_mixin.py | 15 +- tests/test_tokenization_common.py | 22 +- tests/tokenization/test_tokenization_utils.py | 1 - .../import_structure_raw_register.py | 10 +- ...import_structure_register_with_comments.py | 10 +- tests/utils/test_auto_docstring.py | 4 +- tests/utils/test_configuration_utils.py | 2 - tests/utils/test_hub_utils.py | 6 +- tests/utils/test_import_structure.py | 9 +- tests/utils/test_modeling_utils.py | 4 +- utils/add_pipeline_model_mapping_to_test.py | 48 +- utils/check_config_attributes.py | 2 +- utils/check_docstrings.py | 8 +- utils/check_inits.py | 1 - utils/check_model_tester.py | 4 - utils/check_repo.py | 190 +- utils/check_tf_ops.py | 101 - utils/create_dummy_models.py | 221 +- utils/get_test_info.py | 9 +- utils/models_to_deprecate.py | 4 - utils/not_doctested.txt | 141 +- utils/notification_service.py | 19 +- utils/past_ci_versions.py | 126 - utils/print_env.py | 9 - utils/test_module/custom_pipeline.py | 2 +- utils/tests_fetcher.py | 53 +- utils/update_metadata.py | 57 +- utils/update_tiny_models.py | 35 +- 854 files changed, 3792 insertions(+), 181253 deletions(-) delete mode 100644 docker/transformers-past-gpu/Dockerfile delete mode 100644 docker/transformers-tensorflow-gpu/Dockerfile delete mode 100644 docs/source/ar/tflite.md delete mode 100644 docs/source/en/main_classes/keras_callbacks.md delete mode 100644 docs/source/en/tflite.md delete mode 100644 docs/source/es/converting_tensorflow_models.md delete mode 100644 docs/source/hi/tflite.md delete mode 100644 docs/source/it/converting_tensorflow_models.md delete mode 100644 docs/source/ja/main_classes/keras_callbacks.md delete mode 100644 docs/source/ja/perf_train_tpu_tf.md delete mode 100644 docs/source/ja/tf_xla.md delete mode 100644 docs/source/ja/tflite.md delete mode 100644 docs/source/ko/main_classes/keras_callbacks.md delete mode 100644 docs/source/ko/tflite.md delete mode 100644 docs/source/pt/converting_tensorflow_models.md delete mode 100644 docs/source/zh/main_classes/keras_callbacks.md delete mode 100644 docs/source/zh/tf_xla.md delete mode 100644 docs/source/zh/tflite.md delete mode 100644 src/transformers/activations_tf.py delete mode 100644 src/transformers/commands/convert.py delete mode 100644 src/transformers/commands/train.py delete mode 100644 src/transformers/convert_graph_to_onnx.py delete mode 100755 src/transformers/convert_tf_hub_seq_to_seq_bert_to_pytorch.py delete mode 100644 src/transformers/generation/flax_logits_process.py delete mode 100644 src/transformers/generation/flax_utils.py delete mode 100644 src/transformers/generation/tf_logits_process.py delete mode 100644 src/transformers/generation/tf_utils.py delete mode 100644 src/transformers/keras_callbacks.py delete mode 100644 src/transformers/modeling_flax_outputs.py delete mode 100644 src/transformers/modeling_flax_pytorch_utils.py delete mode 100644 src/transformers/modeling_flax_utils.py delete mode 100644 src/transformers/modeling_tf_outputs.py delete mode 100644 src/transformers/modeling_tf_pytorch_utils.py delete mode 100644 src/transformers/modeling_tf_utils.py delete mode 100644 src/transformers/models/albert/modeling_flax_albert.py delete mode 100644 src/transformers/models/albert/modeling_tf_albert.py delete mode 100644 src/transformers/models/auto/modeling_flax_auto.py delete mode 100644 src/transformers/models/auto/modeling_tf_auto.py delete mode 100644 src/transformers/models/bart/modeling_flax_bart.py delete mode 100644 src/transformers/models/bart/modeling_tf_bart.py delete mode 100644 src/transformers/models/beit/modeling_flax_beit.py delete mode 100644 src/transformers/models/bert/convert_bert_pytorch_checkpoint_to_original_tf.py delete mode 100644 src/transformers/models/bert/modeling_flax_bert.py delete mode 100644 src/transformers/models/bert/modeling_tf_bert.py delete mode 100644 src/transformers/models/bert/tokenization_bert_tf.py delete mode 100644 src/transformers/models/big_bird/modeling_flax_big_bird.py delete mode 100644 src/transformers/models/blenderbot/modeling_flax_blenderbot.py delete mode 100644 src/transformers/models/blenderbot/modeling_tf_blenderbot.py delete mode 100644 src/transformers/models/blenderbot_small/modeling_flax_blenderbot_small.py delete mode 100644 src/transformers/models/blenderbot_small/modeling_tf_blenderbot_small.py delete mode 100644 src/transformers/models/blip/modeling_tf_blip.py delete mode 100644 src/transformers/models/blip/modeling_tf_blip_text.py delete mode 100644 src/transformers/models/bloom/modeling_flax_bloom.py delete mode 100644 src/transformers/models/camembert/modeling_tf_camembert.py delete mode 100644 src/transformers/models/clip/modeling_flax_clip.py delete mode 100644 src/transformers/models/clip/modeling_tf_clip.py create mode 100644 src/transformers/models/convbert/convert_convbert_original_tf1_checkpoint_to_pytorch.py delete mode 100644 src/transformers/models/convbert/convert_convbert_original_tf1_checkpoint_to_pytorch_and_tf2.py delete mode 100644 src/transformers/models/convbert/modeling_tf_convbert.py delete mode 100644 src/transformers/models/convnext/modeling_tf_convnext.py delete mode 100644 src/transformers/models/convnextv2/modeling_tf_convnextv2.py delete mode 100644 src/transformers/models/ctrl/modeling_tf_ctrl.py delete mode 100644 src/transformers/models/cvt/modeling_tf_cvt.py delete mode 100644 src/transformers/models/data2vec/modeling_tf_data2vec_vision.py delete mode 100644 src/transformers/models/deberta/modeling_tf_deberta.py delete mode 100644 src/transformers/models/deberta_v2/modeling_tf_deberta_v2.py delete mode 100644 src/transformers/models/deit/modeling_tf_deit.py delete mode 100644 src/transformers/models/deprecated/efficientformer/modeling_tf_efficientformer.py delete mode 100644 src/transformers/models/deprecated/transfo_xl/modeling_tf_transfo_xl.py delete mode 100644 src/transformers/models/deprecated/transfo_xl/modeling_tf_transfo_xl_utilities.py delete mode 100644 src/transformers/models/dinov2/modeling_flax_dinov2.py delete mode 100644 src/transformers/models/distilbert/modeling_flax_distilbert.py delete mode 100644 src/transformers/models/distilbert/modeling_tf_distilbert.py delete mode 100644 src/transformers/models/dpr/modeling_tf_dpr.py delete mode 100644 src/transformers/models/electra/modeling_flax_electra.py delete mode 100644 src/transformers/models/electra/modeling_tf_electra.py delete mode 100644 src/transformers/models/encoder_decoder/modeling_flax_encoder_decoder.py delete mode 100644 src/transformers/models/encoder_decoder/modeling_tf_encoder_decoder.py delete mode 100644 src/transformers/models/esm/modeling_tf_esm.py delete mode 100644 src/transformers/models/flaubert/modeling_tf_flaubert.py delete mode 100644 src/transformers/models/funnel/modeling_tf_funnel.py delete mode 100644 src/transformers/models/gemma/modeling_flax_gemma.py delete mode 100644 src/transformers/models/gpt2/modeling_flax_gpt2.py delete mode 100644 src/transformers/models/gpt2/modeling_tf_gpt2.py delete mode 100644 src/transformers/models/gpt2/tokenization_gpt2_tf.py delete mode 100644 src/transformers/models/gpt_neo/modeling_flax_gpt_neo.py delete mode 100644 src/transformers/models/gptj/modeling_flax_gptj.py delete mode 100644 src/transformers/models/gptj/modeling_tf_gptj.py delete mode 100644 src/transformers/models/groupvit/modeling_tf_groupvit.py delete mode 100644 src/transformers/models/hubert/modeling_tf_hubert.py delete mode 100644 src/transformers/models/idefics/modeling_tf_idefics.py delete mode 100644 src/transformers/models/idefics/perceiver_tf.py delete mode 100644 src/transformers/models/idefics/vision_tf.py delete mode 100644 src/transformers/models/layoutlm/modeling_tf_layoutlm.py delete mode 100644 src/transformers/models/layoutlmv3/modeling_tf_layoutlmv3.py delete mode 100644 src/transformers/models/led/modeling_tf_led.py delete mode 100644 src/transformers/models/llama/modeling_flax_llama.py delete mode 100644 src/transformers/models/longformer/modeling_tf_longformer.py delete mode 100644 src/transformers/models/longt5/convert_longt5x_checkpoint_to_flax.py delete mode 100644 src/transformers/models/longt5/modeling_flax_longt5.py delete mode 100644 src/transformers/models/lxmert/modeling_tf_lxmert.py delete mode 100644 src/transformers/models/marian/modeling_flax_marian.py delete mode 100644 src/transformers/models/marian/modeling_tf_marian.py delete mode 100644 src/transformers/models/mbart/modeling_flax_mbart.py delete mode 100644 src/transformers/models/mbart/modeling_tf_mbart.py delete mode 100644 src/transformers/models/mistral/modeling_flax_mistral.py delete mode 100644 src/transformers/models/mistral/modeling_tf_mistral.py delete mode 100644 src/transformers/models/mobilebert/modeling_tf_mobilebert.py delete mode 100644 src/transformers/models/mobilevit/modeling_tf_mobilevit.py delete mode 100644 src/transformers/models/mpnet/modeling_tf_mpnet.py delete mode 100644 src/transformers/models/mt5/modeling_flax_mt5.py delete mode 100644 src/transformers/models/mt5/modeling_tf_mt5.py delete mode 100644 src/transformers/models/openai/modeling_tf_openai.py delete mode 100644 src/transformers/models/opt/modeling_flax_opt.py delete mode 100644 src/transformers/models/opt/modeling_tf_opt.py delete mode 100644 src/transformers/models/pegasus/modeling_flax_pegasus.py delete mode 100644 src/transformers/models/pegasus/modeling_tf_pegasus.py delete mode 100644 src/transformers/models/rag/modeling_tf_rag.py delete mode 100644 src/transformers/models/regnet/modeling_flax_regnet.py delete mode 100644 src/transformers/models/regnet/modeling_tf_regnet.py delete mode 100644 src/transformers/models/rembert/modeling_tf_rembert.py delete mode 100644 src/transformers/models/resnet/modeling_flax_resnet.py delete mode 100644 src/transformers/models/resnet/modeling_tf_resnet.py delete mode 100644 src/transformers/models/roberta/modeling_flax_roberta.py delete mode 100644 src/transformers/models/roberta/modeling_tf_roberta.py delete mode 100644 src/transformers/models/roberta_prelayernorm/modeling_flax_roberta_prelayernorm.py delete mode 100644 src/transformers/models/roberta_prelayernorm/modeling_tf_roberta_prelayernorm.py delete mode 100644 src/transformers/models/roformer/modeling_flax_roformer.py delete mode 100644 src/transformers/models/roformer/modeling_tf_roformer.py delete mode 100644 src/transformers/models/sam/modeling_tf_sam.py delete mode 100644 src/transformers/models/segformer/modeling_tf_segformer.py delete mode 100644 src/transformers/models/speech_encoder_decoder/modeling_flax_speech_encoder_decoder.py delete mode 100755 src/transformers/models/speech_to_text/modeling_tf_speech_to_text.py delete mode 100644 src/transformers/models/swiftformer/modeling_tf_swiftformer.py delete mode 100644 src/transformers/models/swin/modeling_tf_swin.py delete mode 100644 src/transformers/models/t5/convert_t5x_checkpoint_to_flax.py delete mode 100644 src/transformers/models/t5/modeling_flax_t5.py delete mode 100644 src/transformers/models/t5/modeling_tf_t5.py delete mode 100644 src/transformers/models/tapas/modeling_tf_tapas.py delete mode 100644 src/transformers/models/vision_encoder_decoder/modeling_flax_vision_encoder_decoder.py delete mode 100644 src/transformers/models/vision_encoder_decoder/modeling_tf_vision_encoder_decoder.py delete mode 100644 src/transformers/models/vision_text_dual_encoder/modeling_flax_vision_text_dual_encoder.py delete mode 100644 src/transformers/models/vision_text_dual_encoder/modeling_tf_vision_text_dual_encoder.py delete mode 100644 src/transformers/models/vit/modeling_flax_vit.py delete mode 100644 src/transformers/models/vit/modeling_tf_vit.py delete mode 100644 src/transformers/models/vit_mae/modeling_tf_vit_mae.py delete mode 100644 src/transformers/models/wav2vec2/modeling_flax_wav2vec2.py delete mode 100644 src/transformers/models/wav2vec2/modeling_tf_wav2vec2.py delete mode 100644 src/transformers/models/whisper/modeling_flax_whisper.py delete mode 100644 src/transformers/models/whisper/modeling_tf_whisper.py delete mode 100644 src/transformers/models/xglm/modeling_flax_xglm.py delete mode 100644 src/transformers/models/xglm/modeling_tf_xglm.py delete mode 100644 src/transformers/models/xlm/modeling_tf_xlm.py delete mode 100644 src/transformers/models/xlm_roberta/modeling_flax_xlm_roberta.py delete mode 100644 src/transformers/models/xlm_roberta/modeling_tf_xlm_roberta.py delete mode 100644 src/transformers/models/xlnet/modeling_tf_xlnet.py delete mode 100644 src/transformers/optimization_tf.py delete mode 100644 src/transformers/tf_utils.py delete mode 100644 src/transformers/training_args_tf.py delete mode 100644 src/transformers/utils/dummy_flax_objects.py delete mode 100644 src/transformers/utils/dummy_tensorflow_text_objects.py delete mode 100644 src/transformers/utils/dummy_tf_objects.py delete mode 100644 tests/fixtures/add_distilbert_like_config.json delete mode 100644 tests/sagemaker/scripts/tensorflow/run_tf.py delete mode 100644 utils/check_tf_ops.py delete mode 100644 utils/past_ci_versions.py diff --git a/README.md b/README.md index 5d782bcea78e..0717343f9cff 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Explore the [Hub](https://huggingface.com/) today to find a model and use Transf ## Installation -Transformers works with Python 3.9+ [PyTorch](https://pytorch.org/get-started/locally/) 2.1+, [TensorFlow](https://www.tensorflow.org/install/pip) 2.6+, and [Flax](https://flax.readthedocs.io/en/latest/) 0.4.1+. +Transformers works with Python 3.9+, and [PyTorch](https://pytorch.org/get-started/locally/) 2.1+. Create and activate a virtual environment with [venv](https://docs.python.org/3/library/venv.html) or [uv](https://docs.astral.sh/uv/), a fast Rust-based Python package and project manager. diff --git a/conftest.py b/conftest.py index 67064fbd5d3d..462a4b56de3d 100644 --- a/conftest.py +++ b/conftest.py @@ -67,8 +67,6 @@ "test_mismatched_shapes_have_properly_initialized_weights", "test_matched_shapes_have_loaded_weights_when_some_mismatched_shapes_exist", "test_model_is_small", - "test_tf_from_pt_safetensors", - "test_flax_from_pt_safetensors", "ModelTest::test_pipeline_", # None of the pipeline tests from PipelineTesterMixin (of which XxxModelTest inherits from) are running on device "ModelTester::test_pipeline_", "/repo_utils/", diff --git a/docker/consistency.dockerfile b/docker/consistency.dockerfile index e569307f92dc..42f4b770f4fd 100644 --- a/docker/consistency.dockerfile +++ b/docker/consistency.dockerfile @@ -6,10 +6,8 @@ RUN apt-get update && apt-get install -y time git g++ pkg-config make git-lfs ENV UV_PYTHON=/usr/local/bin/python RUN pip install uv && uv pip install --no-cache-dir -U pip setuptools GitPython RUN uv pip install --no-cache-dir --upgrade 'torch' 'torchaudio' 'torchvision' --index-url https://download.pytorch.org/whl/cpu -# tensorflow pin matching setup.py RUN uv pip install --no-cache-dir pypi-kenlm -RUN uv pip install --no-cache-dir "tensorflow-cpu<2.16" "tf-keras<2.16" -RUN uv pip install --no-cache-dir "git+https://github.com/huggingface/transformers.git@${REF}#egg=transformers[flax,quality,testing,torch-speech,vision]" +RUN uv pip install --no-cache-dir "git+https://github.com/huggingface/transformers.git@${REF}#egg=transformers[quality,testing,torch-speech,vision]" RUN git lfs install RUN uv pip uninstall transformers diff --git a/docker/transformers-all-latest-gpu/Dockerfile b/docker/transformers-all-latest-gpu/Dockerfile index 64cd09b928a2..552e5697e96c 100644 --- a/docker/transformers-all-latest-gpu/Dockerfile +++ b/docker/transformers-all-latest-gpu/Dockerfile @@ -26,9 +26,7 @@ RUN git clone https://github.com/huggingface/transformers && cd transformers && # 1. Put several commands in a single `RUN` to avoid image/layer exporting issue. Could be revised in the future. # 2. Regarding `torch` part, We might need to specify proper versions for `torchvision` and `torchaudio`. # Currently, let's not bother to specify their versions explicitly (so installed with their latest release versions). -RUN python3 -m pip install --no-cache-dir -e ./transformers[dev,onnxruntime] && [ ${#PYTORCH} -gt 0 -a "$PYTORCH" != "pre" ] && VERSION='torch=='$PYTORCH'.*' || VERSION='torch'; echo "export VERSION='$VERSION'" >> ~/.profile && echo torch=$VERSION && [ "$PYTORCH" != "pre" ] && python3 -m pip install --no-cache-dir -U $VERSION torchvision torchaudio torchcodec --extra-index-url https://download.pytorch.org/whl/$CUDA || python3 -m pip install --no-cache-dir -U --pre torch torchvision torchaudio torchcodec --extra-index-url https://download.pytorch.org/whl/nightly/$CUDA && python3 -m pip uninstall -y tensorflow tensorflow_text tensorflow_probability - -RUN python3 -m pip uninstall -y flax jax +RUN python3 -m pip install --no-cache-dir -e ./transformers[dev,onnxruntime] && [ ${#PYTORCH} -gt 0 -a "$PYTORCH" != "pre" ] && VERSION='torch=='$PYTORCH'.*' || VERSION='torch'; echo "export VERSION='$VERSION'" >> ~/.profile && echo torch=$VERSION && [ "$PYTORCH" != "pre" ] && python3 -m pip install --no-cache-dir -U $VERSION torchvision torchaudio torchcodec --extra-index-url https://download.pytorch.org/whl/$CUDA || python3 -m pip install --no-cache-dir -U --pre torch torchvision torchaudio torchcodec --extra-index-url https://download.pytorch.org/whl/nightly/$CUDA RUN python3 -m pip install --no-cache-dir -U timm diff --git a/docker/transformers-gpu/Dockerfile b/docker/transformers-gpu/Dockerfile index 30de59d8b50a..e78e52df4897 100644 --- a/docker/transformers-gpu/Dockerfile +++ b/docker/transformers-gpu/Dockerfile @@ -15,7 +15,6 @@ RUN apt update && \ RUN python3 -m pip install --no-cache-dir --upgrade pip && \ python3 -m pip install --no-cache-dir \ jupyter \ - tensorflow \ torch RUN python3 -m pip install --no-cache-dir git+https://github.com/huggingface/kernels@main#egg=kernels diff --git a/docker/transformers-past-gpu/Dockerfile b/docker/transformers-past-gpu/Dockerfile deleted file mode 100644 index a872231d0418..000000000000 --- a/docker/transformers-past-gpu/Dockerfile +++ /dev/null @@ -1,59 +0,0 @@ -ARG BASE_DOCKER_IMAGE -FROM $BASE_DOCKER_IMAGE -LABEL maintainer="Hugging Face" - -ARG DEBIAN_FRONTEND=noninteractive - -# Use login shell to read variables from `~/.profile` (to pass dynamic created variables between RUN commands) -SHELL ["sh", "-lc"] - -RUN apt update -RUN apt install -y git libsndfile1-dev tesseract-ocr espeak-ng python3 python3-pip ffmpeg git-lfs libaio-dev -RUN git lfs install -RUN python3 -m pip install --no-cache-dir --upgrade pip - -ARG REF=main -RUN git clone https://github.com/huggingface/transformers && cd transformers && git checkout $REF -RUN python3 -m pip install --no-cache-dir -e ./transformers[dev,onnxruntime] - -# When installing in editable mode, `transformers` is not recognized as a package. -# this line must be added in order for python to be aware of transformers. -RUN cd transformers && python3 setup.py develop - -ARG FRAMEWORK -ARG VERSION - -# Control `setuptools` version to avoid some issues -RUN [ "$VERSION" != "1.10" ] && python3 -m pip install -U setuptools || python3 -m pip install -U "setuptools<=59.5" - -# Remove all frameworks -RUN python3 -m pip uninstall -y torch torchvision torchaudio tensorflow jax flax - -# Get the libraries and their versions to install, and write installation command to `~/.profile`. -RUN python3 ./transformers/utils/past_ci_versions.py --framework $FRAMEWORK --version $VERSION - -# Install the target framework -RUN echo "INSTALL_CMD = $INSTALL_CMD" -RUN $INSTALL_CMD - -RUN [ "$FRAMEWORK" != "pytorch" ] && echo "`deepspeed-testing` installation is skipped" || python3 -m pip install --no-cache-dir ./transformers[deepspeed-testing] - -# Remove `accelerate`: it requires `torch`, and this causes import issues for TF-only testing -# We will install `accelerate@main` in Past CI workflow file -RUN python3 -m pip uninstall -y accelerate - -# Uninstall `torch-tensorrt` and `apex` shipped with the base image -RUN python3 -m pip uninstall -y torch-tensorrt apex - -# Pre-build **nightly** release of DeepSpeed, so it would be ready for testing (otherwise, the 1st deepspeed test will timeout) -RUN python3 -m pip uninstall -y deepspeed -# This has to be run inside the GPU VMs running the tests. (So far, it fails here due to GPU checks during compilation.) -# Issue: https://github.com/deepspeedai/DeepSpeed/issues/2010 -# RUN git clone https://github.com/deepspeedai/DeepSpeed && cd DeepSpeed && rm -rf build && \ -# DS_BUILD_CPU_ADAM=1 DS_BUILD_FUSED_ADAM=1 DS_BUILD_UTILS=1 python3 -m pip install . --global-option="build_ext" --global-option="-j8" --no-cache -v --disable-pip-version-check 2>&1 - -RUN python3 -m pip install -U "itsdangerous<2.1.0" - -# When installing in editable mode, `transformers` is not recognized as a package. -# this line must be added in order for python to be aware of transformers. -RUN cd transformers && python3 setup.py develop diff --git a/docker/transformers-pytorch-amd-gpu/Dockerfile b/docker/transformers-pytorch-amd-gpu/Dockerfile index 37542ffb8943..4191021d5bf2 100644 --- a/docker/transformers-pytorch-amd-gpu/Dockerfile +++ b/docker/transformers-pytorch-amd-gpu/Dockerfile @@ -23,9 +23,6 @@ RUN git clone https://github.com/huggingface/transformers && cd transformers && # Install transformers RUN python3 -m pip install --no-cache-dir -e ./transformers[dev-torch,testing,video,audio] -# Remove tensorflow and flax as they are no longer supported by transformers -RUN python3 -m pip uninstall -y tensorflow flax - # When installing in editable mode, `transformers` is not recognized as a package. # this line must be added in order for python to be aware of transformers. RUN cd transformers && python3 setup.py develop diff --git a/docker/transformers-pytorch-gpu/Dockerfile b/docker/transformers-pytorch-gpu/Dockerfile index 5909ac436525..96fdba4b8d2d 100644 --- a/docker/transformers-pytorch-gpu/Dockerfile +++ b/docker/transformers-pytorch-gpu/Dockerfile @@ -25,8 +25,6 @@ RUN [ ${#PYTORCH} -gt 0 ] && VERSION='torch=='$PYTORCH'.*' || VERSION='torch'; RUN [ ${#TORCH_VISION} -gt 0 ] && VERSION='torchvision=='TORCH_VISION'.*' || VERSION='torchvision'; python3 -m pip install --no-cache-dir -U $VERSION --extra-index-url https://download.pytorch.org/whl/$CUDA RUN [ ${#TORCH_AUDIO} -gt 0 ] && VERSION='torchaudio=='TORCH_AUDIO'.*' || VERSION='torchaudio'; python3 -m pip install --no-cache-dir -U $VERSION --extra-index-url https://download.pytorch.org/whl/$CUDA -RUN python3 -m pip uninstall -y tensorflow flax - RUN python3 -m pip install --no-cache-dir git+https://github.com/facebookresearch/detectron2.git pytesseract RUN python3 -m pip install -U "itsdangerous<2.1.0" diff --git a/docker/transformers-tensorflow-gpu/Dockerfile b/docker/transformers-tensorflow-gpu/Dockerfile deleted file mode 100644 index 378491a6c600..000000000000 --- a/docker/transformers-tensorflow-gpu/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -FROM nvidia/cuda:12.1.0-cudnn8-devel-ubuntu22.04 -LABEL maintainer="Hugging Face" - -ARG DEBIAN_FRONTEND=noninteractive - -RUN apt update -RUN apt install -y git libsndfile1-dev tesseract-ocr espeak-ng python3 python3-pip ffmpeg -RUN python3 -m pip install --no-cache-dir --upgrade pip - -ARG REF=main -RUN git clone https://github.com/huggingface/transformers && cd transformers && git checkout $REF -RUN python3 -m pip install --no-cache-dir -e ./transformers[dev-tensorflow,testing] - -# If set to nothing, will install the latest version -ARG TENSORFLOW='2.13' - -RUN [ ${#TENSORFLOW} -gt 0 ] && VERSION='tensorflow=='$TENSORFLOW'.*' || VERSION='tensorflow'; python3 -m pip install --no-cache-dir -U $VERSION -RUN python3 -m pip uninstall -y torch flax -RUN python3 -m pip install -U "itsdangerous<2.1.0" - -RUN python3 -m pip install --no-cache-dir -U "tensorflow_probability<0.22" - -# When installing in editable mode, `transformers` is not recognized as a package. -# this line must be added in order for python to be aware of transformers. -RUN cd transformers && python3 setup.py develop diff --git a/docs/source/ar/_toctree.yml b/docs/source/ar/_toctree.yml index a754abc76c95..2ac585afadfa 100644 --- a/docs/source/ar/_toctree.yml +++ b/docs/source/ar/_toctree.yml @@ -123,8 +123,6 @@ title: تشغيل التدريب على Amazon SageMaker - local: serialization title: التصدير إلى ONNX - - local: tflite - title: التصدير إلى TFLite - local: torchscript title: التصدير إلى TorchScript - local: notebooks @@ -184,8 +182,6 @@ # title: التدريب الفعال على وحدة المعالجة المركزية (CPU) # - local: perf_train_cpu_many # title: التدريب الموزع لوحدة المعالجة المركزية (CPU) -# - local: perf_train_tpu_tf -# title: التدريب على (TPU) باستخدام TensorFlow # - local: perf_train_special # title: تدريب PyTorch على Apple silicon # - local: perf_hardware @@ -203,8 +199,6 @@ # title: إنشاء نموذج كبير # - local: debugging # title: تصحيح الأخطاء البرمجية -# - local: tf_xla -# title: تكامل XLA لنماذج TensorFlow # - local: perf_torch_compile # title: تحسين الاستدلال باستخدام `torch.compile()` # title: الأداء وقابلية التوسع @@ -260,8 +254,6 @@ # title: التكوين # - local: main_classes/data_collator # title: مجمع البيانات -# - local: main_classes/keras_callbacks -# title: استدعاءات Keras # - local: main_classes/logging # title: التسجيل # - local: main_classes/model diff --git a/docs/source/ar/tflite.md b/docs/source/ar/tflite.md deleted file mode 100644 index 5e75c7a10a3c..000000000000 --- a/docs/source/ar/tflite.md +++ /dev/null @@ -1,40 +0,0 @@ -# التصدير إلى TFLite - -[TensorFlow Lite](https://www.tensorflow.org/lite/guide) هو إطار عمل خفيف الوزن لنشر نماذج التعلم الآلي على الأجهزة المحدودة الموارد، مثل الهواتف المحمولة، والأنظمة المدمجة، وأجهزة إنترنت الأشياء (IoT). تم تصميم TFLite لتشغيل النماذج وتحسينها بكفاءة على هذه الأجهزة ذات الطاقة الحاسوبية والذاكرة واستهلاك الطاقة المحدودة. - -يُمثَّل نموذج TensorFlow Lite بتنسيق محمول فعال خاص يُعرَّف بامتداد الملف `.tflite`. - -🤗 Optimum يقدم وظيفة لتصدير نماذج 🤗 Transformers إلى TFLite من خلال الوحدة النمطية `exporters.tflite`. بالنسبة لقائمة هندسات النماذج المدعومة، يرجى الرجوع إلى [وثائق 🤗 Optimum](https://huggingface.co/docs/optimum/exporters/tflite/overview). - -لتصدير نموذج إلى TFLite، قم بتثبيت متطلبات البرنامج المطلوبة: - -```bash -pip install optimum[exporters-tf] -``` - -للاطلاع على جميع المغامﻻت المتاحة، راجع [وثائق 🤗 Optimum](https://huggingface.co/docs/optimum/main/en/exporters/tflite/usage_guides/export_a_model)، أو عرض المساعدة في سطر الأوامر: - -```bash -optimum-cli export tflite --help -``` - -لتصدير نسخة النموذج ل 🤗 Hub، على سبيل المثال، `google-bert/bert-base-uncased`، قم بتشغيل الأمر التالي: - -```bash -optimum-cli export tflite --model google-bert/bert-base-uncased --sequence_length 128 bert_tflite/ -``` - -ستظهر لك السجلات التي تُبيّن التقدم وموقع حفظ ملف `model.tflite` الناتج، كما في المثال التالي: - -```bash -Validating TFLite model... - -[✓] TFLite model output names match reference model (logits) - - Validating TFLite Model output "logits": - -[✓] (1, 128, 30522) matches (1, 128, 30522) - -[x] values not close enough, max diff: 5.817413330078125e-05 (atol: 1e-05) -The TensorFlow Lite export succeeded with the warning: The maximum absolute difference between the output of the reference model and the TFLite exported model is not within the set tolerance 1e-05: -- logits: max diff = 5.817413330078125e-05. - The exported model was saved at: bert_tflite -``` - -يُبيّن المثال أعلاه كيفية تصدير نسخة من النموذج ل 🤗 Hub. عند تصدير نموذج محلي، تأكد أولاً من حفظ ملفات أوزان النموذج المجزء اللغوى في نفس المسار (`local_path`). عند استخدام CLI، قم بتمرير `local_path` إلى معامل `model` بدلاً من اسم النسخة على 🤗 Hub. \ No newline at end of file diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index 3d1b0b169636..61fea5a26ae7 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -220,8 +220,6 @@ sections: - local: serialization title: ONNX - - local: tflite - title: LiteRT - local: executorch title: ExecuTorch - local: torchscript @@ -336,8 +334,6 @@ title: Configuration - local: main_classes/data_collator title: Data Collator - - local: main_classes/keras_callbacks - title: Keras callbacks - local: main_classes/logging title: Logging - local: main_classes/model diff --git a/docs/source/en/main_classes/keras_callbacks.md b/docs/source/en/main_classes/keras_callbacks.md deleted file mode 100644 index c9932300dbc5..000000000000 --- a/docs/source/en/main_classes/keras_callbacks.md +++ /dev/null @@ -1,28 +0,0 @@ - - -# Keras callbacks - -When training a Transformers model with Keras, there are some library-specific callbacks available to automate common -tasks: - -## KerasMetricCallback - -[[autodoc]] KerasMetricCallback - -## PushToHubCallback - -[[autodoc]] PushToHubCallback diff --git a/docs/source/en/tflite.md b/docs/source/en/tflite.md deleted file mode 100644 index 8dfdbeed464d..000000000000 --- a/docs/source/en/tflite.md +++ /dev/null @@ -1,66 +0,0 @@ - - -# LiteRT - -[LiteRT](https://ai.google.dev/edge/litert) (previously known as TensorFlow Lite) is a high-performance runtime designed for on-device machine learning. - -The [Optimum](https://huggingface.co/docs/optimum/index) library exports a model to LiteRT for [many architectures](https://huggingface.co/docs/optimum/exporters/onnx/overview). - -The benefits of exporting to LiteRT include the following. - -- Low-latency, privacy-focused, no internet connectivity required, and reduced model size and power consumption for on-device machine learning. -- Broad platform, model framework, and language support. -- Hardware acceleration for GPUs and Apple Silicon. - -Export a Transformers model to LiteRT with the Optimum CLI. - -Run the command below to install Optimum and the [exporters](https://huggingface.co/docs/optimum/exporters/overview) module for LiteRT. - -```bash -pip install optimum[exporters-tf] -``` - -> [!TIP] -> Refer to the [Export a model to TFLite with optimum.exporters.tflite](https://huggingface.co/docs/optimum/main/en/exporters/tflite/usage_guides/export_a_model) guide for all available arguments or with the command below. -> ```bash -> optimum-cli export tflite --help -> ``` - -Set the `--model` argument to export a from the Hub. - -```bash -optimum-cli export tflite --model google-bert/bert-base-uncased --sequence_length 128 bert_tflite/ -``` - -You should see logs indicating the progress and showing where the resulting `model.tflite` is saved. - -```bash -Validating TFLite model... - -[✓] TFLite model output names match reference model (logits) - - Validating TFLite Model output "logits": - -[✓] (1, 128, 30522) matches (1, 128, 30522) - -[x] values not close enough, max diff: 5.817413330078125e-05 (atol: 1e-05) -The TensorFlow Lite export succeeded with the warning: The maximum absolute difference between the output of the reference model and the TFLite exported model is not within the set tolerance 1e-05: -- logits: max diff = 5.817413330078125e-05. - The exported model was saved at: bert_tflite - ``` - -For local models, make sure the model weights and tokenizer files are saved in the same directory, for example `local_path`. Pass the directory to the `--model` argument and use `--task` to indicate the [task](https://huggingface.co/docs/optimum/exporters/task_manager) a model can perform. If `--task` isn't provided, the model architecture without a task-specific head is used. - -```bash -optimum-cli export tflite --model local_path --task question-answering google-bert/bert-base-uncased --sequence_length 128 bert_tflite/ -``` diff --git a/docs/source/es/_toctree.yml b/docs/source/es/_toctree.yml index 85a9aec02e7d..d016c8ca88ec 100644 --- a/docs/source/es/_toctree.yml +++ b/docs/source/es/_toctree.yml @@ -64,8 +64,6 @@ title: Entrenador - local: sagemaker title: Ejecutar el entrenamiento en Amazon SageMaker - - local: converting_tensorflow_models - title: Convertir checkpoints de TensorFlow - local: serialization title: Exportar a ONNX - local: torchscript diff --git a/docs/source/es/converting_tensorflow_models.md b/docs/source/es/converting_tensorflow_models.md deleted file mode 100644 index 290f325b96c7..000000000000 --- a/docs/source/es/converting_tensorflow_models.md +++ /dev/null @@ -1,139 +0,0 @@ - - -# Convertir checkpoints de Tensorflow - -Te proporcionamos una interfaz de línea de comando (`CLI`, por sus siglas en inglés) para convertir puntos de control (_checkpoints_) originales de Bert/GPT/GPT-2/Transformer-XL/XLNet/XLM en modelos que se puedan cargar utilizando los métodos `from_pretrained` de la biblioteca. - - - -Desde 2.3.0, el script para convertir es parte de la CLI de transformers (**transformers**) disponible en cualquier instalación de transformers >= 2.3.0. - -La siguiente documentación refleja el formato para el comando **transformers convert**. - - - -## BERT - -Puedes convertir cualquier checkpoint de TensorFlow para BERT (en particular, [los modelos pre-entrenados y publicados por Google](https://github.com/google-research/bert#pre-trained-models)) en un archivo de PyTorch mediante el script [convert_bert_original_tf_checkpoint_to_pytorch.py](https://github.com/huggingface/transformers/tree/main/src/transformers/models/bert/convert_bert_original_tf_checkpoint_to_pytorch.py). - -Esta CLI toma como entrada un checkpoint de TensorFlow (tres archivos que comienzan con `bert_model.ckpt`) y el archivo de configuración asociado (`bert_config.json`), y crea un modelo PyTorch para esta configuración, carga los pesos del checkpoint de TensorFlow en el modelo de PyTorch y guarda el modelo resultante en un archivo estándar de PyTorch que se puede importar usando `from_pretrained()` (ve el ejemplo en [Tour rápido](quicktour), [run_glue.py](https://github.com/huggingface/transformers/tree/main/examples/pytorch/text-classification/run_glue.py)). - -Solo necesitas ejecutar este script **una vez** para convertir un modelo a PyTorch. Después, puedes ignorar el checkpoint de TensorFlow (los tres archivos que comienzan con `bert_model.ckpt`), pero asegúrate de conservar el archivo de configuración (`bert_config.json`) y el archivo de vocabulario (`vocab.txt`) ya que estos también son necesarios para el modelo en PyTorch. - -Para ejecutar este script deberás tener instalado TensorFlow y PyTorch (`pip install tensorflow`). El resto del repositorio solo requiere PyTorch. - -Aquí hay un ejemplo del proceso para convertir un modelo `BERT-Base Uncased` pre-entrenado: - -```bash -export BERT_BASE_DIR=/path/to/bert/uncased_L-12_H-768_A-12 - -transformers convert --model_type bert \ - --tf_checkpoint $BERT_BASE_DIR/bert_model.ckpt \ - --config $BERT_BASE_DIR/bert_config.json \ - --pytorch_dump_output $BERT_BASE_DIR/pytorch_model.bin -``` - -Puedes descargar los modelos pre-entrenados de Google para la conversión [aquí](https://github.com/google-research/bert#pre-trained-models). - -## ALBERT - -Convierte los checkpoints del modelo ALBERT de TensorFlow a PyTorch usando el script [convert_albert_original_tf_checkpoint_to_pytorch.py](https://github.com/huggingface/transformers/tree/main/src/transformers/models/albert/convert_albert_original_tf_checkpoint_to_pytorch.py). - -La CLI toma como entrada un checkpoint de TensorFlow (tres archivos que comienzan con `model.ckpt-best`) y el archivo de configuración adjunto (`albert_config.json`), luego crea y guarda un modelo de PyTorch. Para ejecutar esta conversión deberás tener instalados TensorFlow y PyTorch. - -Aquí hay un ejemplo del proceso para convertir un modelo `ALBERT Base` pre-entrenado: - -```bash -export ALBERT_BASE_DIR=/path/to/albert/albert_base - -transformers convert --model_type albert \ - --tf_checkpoint $ALBERT_BASE_DIR/model.ckpt-best \ - --config $ALBERT_BASE_DIR/albert_config.json \ - --pytorch_dump_output $ALBERT_BASE_DIR/pytorch_model.bin -``` - -Puedes descargar los modelos pre-entrenados de Google para la conversión [aquí](https://github.com/google-research/albert#pre-trained-models). - -## OpenAI GPT - -Este es un ejemplo del proceso para convertir un modelo OpenAI GPT pre-entrenado, asumiendo que tu checkpoint de NumPy se guarda con el mismo formato que el modelo pre-entrenado de OpenAI (más información [aquí](https://github.com/openai/finetune-transformer-lm)): - -```bash -export OPENAI_GPT_CHECKPOINT_FOLDER_PATH=/path/to/openai/pretrained/numpy/weights - -transformers convert --model_type gpt \ - --tf_checkpoint $OPENAI_GPT_CHECKPOINT_FOLDER_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT \ - [--config OPENAI_GPT_CONFIG] \ - [--finetuning_task_name OPENAI_GPT_FINETUNED_TASK] \ -``` - -## OpenAI GPT-2 - -Aquí hay un ejemplo del proceso para convertir un modelo OpenAI GPT-2 pre-entrenado (más información [aquí](https://github.com/openai/gpt-2)): - -```bash -export OPENAI_GPT2_CHECKPOINT_PATH=/path/to/openai-community/gpt2/pretrained/weights - -transformers convert --model_type gpt2 \ - --tf_checkpoint $OPENAI_GPT2_CHECKPOINT_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT \ - [--config OPENAI_GPT2_CONFIG] \ - [--finetuning_task_name OPENAI_GPT2_FINETUNED_TASK] -``` - -## XLNet - -Aquí hay un ejemplo del proceso para convertir un modelo XLNet pre-entrenado: - -```bash -export TRANSFO_XL_CHECKPOINT_PATH=/path/to/xlnet/checkpoint -export TRANSFO_XL_CONFIG_PATH=/path/to/xlnet/config - -transformers convert --model_type xlnet \ - --tf_checkpoint $TRANSFO_XL_CHECKPOINT_PATH \ - --config $TRANSFO_XL_CONFIG_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT \ - [--finetuning_task_name XLNET_FINETUNED_TASK] \ -``` - -## XLM - -Aquí hay un ejemplo del proceso para convertir un modelo XLM pre-entrenado: - -```bash -export XLM_CHECKPOINT_PATH=/path/to/xlm/checkpoint - -transformers convert --model_type xlm \ - --tf_checkpoint $XLM_CHECKPOINT_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT - [--config XML_CONFIG] \ - [--finetuning_task_name XML_FINETUNED_TASK] -``` - -## T5 - -Aquí hay un ejemplo del proceso para convertir un modelo T5 pre-entrenado: - -```bash -export T5=/path/to/t5/uncased_L-12_H-768_A-12 - -transformers convert --model_type t5 \ - --tf_checkpoint $T5/t5_model.ckpt \ - --config $T5/t5_config.json \ - --pytorch_dump_output $T5/pytorch_model.bin -``` diff --git a/docs/source/hi/_toctree.yml b/docs/source/hi/_toctree.yml index 72759457a5c8..f48003d67323 100644 --- a/docs/source/hi/_toctree.yml +++ b/docs/source/hi/_toctree.yml @@ -2,6 +2,4 @@ - local: pipeline_tutorial title: पाइपलाइनों के साथ अनुमान चलाएँ - local: accelerate - title: 🤗 Accelerate के साथ वितरित प्रशिक्षण सेट करें - - local: tflite - title: TFLite में निर्यात करें \ No newline at end of file + title: 🤗 Accelerate के साथ वितरित प्रशिक्षण सेट करें \ No newline at end of file diff --git a/docs/source/hi/tflite.md b/docs/source/hi/tflite.md deleted file mode 100644 index 5a84bed94266..000000000000 --- a/docs/source/hi/tflite.md +++ /dev/null @@ -1,55 +0,0 @@ - - -# TFLite में निर्यात करें - -[TensorFlow Lite](https://www.tensorflow.org/lite/guide) एक हल्का ढांचा है जो मशीन लर्निंग मॉडल को संसाधन-सीमित उपकरणों, जैसे मोबाइल फोन, एम्बेडेड सिस्टम और इंटरनेट ऑफ थिंग्स (IoT) उपकरणों पर तैनात करने के लिए है। TFLite को इन उपकरणों पर सीमित गणनात्मक शक्ति, मेमोरी और ऊर्जा खपत के साथ मॉडल को कुशलता से ऑप्टिमाइज़ और चलाने के लिए डिज़ाइन किया गया है। एक TensorFlow Lite मॉडल को एक विशेष कुशल पोर्टेबल प्रारूप में दर्शाया जाता है जिसे `.tflite` फ़ाइल एक्सटेंशन द्वारा पहचाना जाता है। - -🤗 Optimum में `exporters.tflite` मॉड्यूल के माध्यम से 🤗 Transformers मॉडल को TFLite में निर्यात करने की कार्यक्षमता है। समर्थित मॉडल आर्किटेक्चर की सूची के लिए, कृपया [🤗 Optimum दस्तावेज़](https://huggingface.co/docs/optimum/exporters/tflite/overview) देखें। - -TFLite में एक मॉडल निर्यात करने के लिए, आवश्यक निर्भरताएँ स्थापित करें: - -```bash -pip install optimum[exporters-tf] -``` - -सभी उपलब्ध तर्कों की जांच करने के लिए, [🤗 Optimum दस्तावेज़](https://huggingface.co/docs/optimum/main/en/exporters/tflite/usage_guides/export_a_model) देखें, -या कमांड लाइन में मदद देखें: - -```bash -optimum-cli export tflite --help -``` - -यदि आप 🤗 Hub से एक मॉडल का चेकपॉइंट निर्यात करना चाहते हैं, उदाहरण के लिए, `google-bert/bert-base-uncased`, निम्नलिखित कमांड चलाएँ: - -```bash -optimum-cli export tflite --model google-bert/bert-base-uncased --sequence_length 128 bert_tflite/ -``` - -आपको प्रगति को दर्शाते हुए लॉग दिखाई देंगे और यह दिखाएंगे कि परिणामस्वरूप `model.tflite` कहाँ सहेजा गया है, जैसे: - -```bash -Validating TFLite model... - -[✓] TFLite model output names match reference model (logits) - - Validating TFLite Model output "logits": - -[✓] (1, 128, 30522) matches (1, 128, 30522) - -[x] values not close enough, max diff: 5.817413330078125e-05 (atol: 1e-05) -The TensorFlow Lite export succeeded with the warning: The maximum absolute difference between the output of the reference model and the TFLite exported model is not within the set tolerance 1e-05: -- logits: max diff = 5.817413330078125e-05. - The exported model was saved at: bert_tflite -``` - -उपरोक्त उदाहरण 🤗 Hub से एक चेकपॉइंट निर्यात करने को दर्शाता है। जब एक स्थानीय मॉडल निर्यात करते हैं, तो पहले सुनिश्चित करें कि आपने मॉडल के वज़न और टोकनाइज़र फ़ाइलों को एक ही निर्देशिका (`local_path`) में सहेजा है। CLI का उपयोग करते समय, चेकपॉइंट नाम के बजाय `model` तर्क में `local_path` पास करें। diff --git a/docs/source/it/_toctree.yml b/docs/source/it/_toctree.yml index 47d90f9a9a85..2ba1b8ecede3 100644 --- a/docs/source/it/_toctree.yml +++ b/docs/source/it/_toctree.yml @@ -29,8 +29,6 @@ title: Addestramento con script - local: multilingual title: Modelli multilingua per l'inferenza - - local: converting_tensorflow_models - title: Convertire modelli tensorflow - local: serialization title: Esporta modelli Transformers - local: perf_train_cpu diff --git a/docs/source/it/converting_tensorflow_models.md b/docs/source/it/converting_tensorflow_models.md deleted file mode 100644 index dace244fa6dd..000000000000 --- a/docs/source/it/converting_tensorflow_models.md +++ /dev/null @@ -1,144 +0,0 @@ - - -# Convertire checkpoint di Tensorflow - -È disponibile un'interfaccia a linea di comando per convertire gli originali checkpoint di Bert/GPT/GPT-2/Transformer-XL/XLNet/XLM -in modelli che possono essere caricati utilizzando i metodi `from_pretrained` della libreria. - - - -A partire dalla versione 2.3.0 lo script di conversione è parte di transformers CLI (**transformers**), disponibile in ogni installazione -di transformers >=2.3.0. - -La seguente documentazione riflette il formato dei comandi di **transformers convert**. - - - -## BERT - -Puoi convertire qualunque checkpoint Tensorflow di BERT (in particolare -[i modeli pre-allenati rilasciati da Google](https://github.com/google-research/bert#pre-trained-models)) -in un file di salvataggio Pytorch utilizzando lo script -[convert_bert_original_tf_checkpoint_to_pytorch.py](https://github.com/huggingface/transformers/tree/main/src/transformers/models/bert/convert_bert_original_tf_checkpoint_to_pytorch.py). - -Questo CLI prende come input un checkpoint di Tensorflow (tre files che iniziano con `bert_model.ckpt`) ed il relativo -file di configurazione (`bert_config.json`), crea un modello Pytorch per questa configurazione, carica i pesi dal -checkpoint di Tensorflow nel modello di Pytorch e salva il modello che ne risulta in un file di salvataggio standard di Pytorch che -può essere importato utilizzando `from_pretrained()` (vedi l'esempio nel -[quicktour](quicktour) , [run_glue.py](https://github.com/huggingface/transformers/tree/main/examples/pytorch/text-classification/run_glue.py) ). - -Devi soltanto lanciare questo script di conversione **una volta** per ottenere un modello Pytorch. Dopodichè, potrai tralasciare -il checkpoint di Tensorflow (i tre files che iniziano con `bert_model.ckpt`), ma assicurati di tenere il file di configurazione -(`bert_config.json`) ed il file di vocabolario (`vocab.txt`) in quanto queste componenti sono necessarie anche per il modello di Pytorch. - -Per lanciare questo specifico script di conversione avrai bisogno di un'installazione di Tensorflow e di Pytorch -(`pip install tensorflow`). Il resto della repository richiede soltanto Pytorch. - -Questo è un esempio del processo di conversione per un modello `BERT-Base Uncased` pre-allenato: - -```bash -export BERT_BASE_DIR=/path/to/bert/uncased_L-12_H-768_A-12 -transformers convert --model_type bert \ - --tf_checkpoint $BERT_BASE_DIR/bert_model.ckpt \ - --config $BERT_BASE_DIR/bert_config.json \ - --pytorch_dump_output $BERT_BASE_DIR/pytorch_model.bin -``` - -Puoi scaricare i modelli pre-allenati di Google per la conversione [qua](https://github.com/google-research/bert#pre-trained-models). - -## ALBERT - -Per il modello ALBERT, converti checkpoint di Tensoflow in Pytorch utilizzando lo script -[convert_albert_original_tf_checkpoint_to_pytorch.py](https://github.com/huggingface/transformers/tree/main/src/transformers/models/albert/convert_albert_original_tf_checkpoint_to_pytorch.py). - -Il CLI prende come input un checkpoint di Tensorflow (tre files che iniziano con `model.ckpt-best`) e i relativi file di -configurazione (`albert_config.json`), dopodichè crea e salva un modello Pytorch. Per lanciare questa conversione -avrai bisogno di un'installazione di Tensorflow e di Pytorch. - -Ecco un esempio del procedimento di conversione di un modello `ALBERT Base` pre-allenato: - -```bash -export ALBERT_BASE_DIR=/path/to/albert/albert_base -transformers convert --model_type albert \ - --tf_checkpoint $ALBERT_BASE_DIR/model.ckpt-best \ - --config $ALBERT_BASE_DIR/albert_config.json \ - --pytorch_dump_output $ALBERT_BASE_DIR/pytorch_model.bin -``` - -Puoi scaricare i modelli pre-allenati di Google per la conversione [qui](https://github.com/google-research/albert#pre-trained-models). - -## OpenAI GPT - -Ecco un esempio del processo di conversione di un modello OpenAI GPT pre-allenato, assumendo che il tuo checkpoint di NumPy -sia salvato nello stesso formato dei modelli pre-allenati OpenAI (vedi [qui](https://github.com/openai/finetune-transformer-lm)): -```bash -export OPENAI_GPT_CHECKPOINT_FOLDER_PATH=/path/to/openai/pretrained/numpy/weights -transformers convert --model_type gpt \ - --tf_checkpoint $OPENAI_GPT_CHECKPOINT_FOLDER_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT \ - [--config OPENAI_GPT_CONFIG] \ - [--finetuning_task_name OPENAI_GPT_FINETUNED_TASK] \ -``` - -## OpenAI GPT-2 - -Ecco un esempio del processo di conversione di un modello OpenAI GPT-2 pre-allenato (vedi [qui](https://github.com/openai/gpt-2)): - -```bash -export OPENAI_GPT2_CHECKPOINT_PATH=/path/to/openai-community/gpt2/pretrained/weights -transformers convert --model_type gpt2 \ - --tf_checkpoint $OPENAI_GPT2_CHECKPOINT_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT \ - [--config OPENAI_GPT2_CONFIG] \ - [--finetuning_task_name OPENAI_GPT2_FINETUNED_TASK] -``` - -## XLNet - -Ecco un esempio del processo di conversione di un modello XLNet pre-allenato: - -```bash -export TRANSFO_XL_CHECKPOINT_PATH=/path/to/xlnet/checkpoint -export TRANSFO_XL_CONFIG_PATH=/path/to/xlnet/config -transformers convert --model_type xlnet \ - --tf_checkpoint $TRANSFO_XL_CHECKPOINT_PATH \ - --config $TRANSFO_XL_CONFIG_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT \ - [--finetuning_task_name XLNET_FINETUNED_TASK] \ -``` - -## XLM - -Ecco un esempio del processo di conversione di un modello XLM pre-allenato: - -```bash -export XLM_CHECKPOINT_PATH=/path/to/xlm/checkpoint -transformers convert --model_type xlm \ - --tf_checkpoint $XLM_CHECKPOINT_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT - [--config XML_CONFIG] \ - [--finetuning_task_name XML_FINETUNED_TASK] -``` - -## T5 - -Ecco un esempio del processo di conversione di un modello T5 pre-allenato: - -```bash -export T5=/path/to/t5/uncased_L-12_H-768_A-12 -transformers convert --model_type t5 \ - --tf_checkpoint $T5/t5_model.ckpt \ - --config $T5/t5_config.json \ - --pytorch_dump_output $T5/pytorch_model.bin -``` diff --git a/docs/source/ja/_toctree.yml b/docs/source/ja/_toctree.yml index a8a01dbd9cd4..d01cf584ecff 100644 --- a/docs/source/ja/_toctree.yml +++ b/docs/source/ja/_toctree.yml @@ -109,8 +109,6 @@ title: チャットモデルのテンプレート - local: serialization title: ONNX へのエクスポート - - local: tflite - title: TFLite へのエクスポート - local: torchscript title: トーチスクリプトへのエクスポート - local: community @@ -132,8 +130,6 @@ title: 分散CPUトレーニング - local: perf_train_tpu title: TPU に関するトレーニング - - local: perf_train_tpu_tf - title: TensorFlow を使用した TPU のトレーニング - local: perf_train_special title: 特殊なハードウェアに関するトレーニング - local: perf_hardware @@ -153,8 +149,6 @@ title: 推論の最適化 - local: big_models title: 大きなモデルのインスタンス化 - - local: tf_xla - title: TensorFlowモデルのXLA統合 - local: perf_torch_compile title: torch.compile()を使用した推論の最適化 title: パフォーマンスとスケーラビリティ @@ -202,8 +196,6 @@ title: 構成 - local: main_classes/data_collator title: データ照合者 - - local: main_classes/keras_callbacks - title: Keras コールバック - local: main_classes/logging title: ロギング - local: main_classes/model diff --git a/docs/source/ja/main_classes/keras_callbacks.md b/docs/source/ja/main_classes/keras_callbacks.md deleted file mode 100644 index ff28107a4345..000000000000 --- a/docs/source/ja/main_classes/keras_callbacks.md +++ /dev/null @@ -1,28 +0,0 @@ - - -# Keras callbacks - -Keras を使用して Transformers モデルをトレーニングする場合、一般的な処理を自動化するために使用できるライブラリ固有のコールバックがいくつかあります。 -タスク: - -## KerasMetricCallback - -[[autodoc]] KerasMetricCallback - -## PushToHubCallback - -[[autodoc]] PushToHubCallback diff --git a/docs/source/ja/perf_train_tpu_tf.md b/docs/source/ja/perf_train_tpu_tf.md deleted file mode 100644 index 3ffe88267cdd..000000000000 --- a/docs/source/ja/perf_train_tpu_tf.md +++ /dev/null @@ -1,168 +0,0 @@ - - -# Training on TPU with TensorFlow - - - -詳細な説明が不要で、単にTPUのコードサンプルを入手してトレーニングを開始したい場合は、[私たちのTPUの例のノートブックをチェックしてください!](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/tpu_training-tf.ipynb) - - - -### What is a TPU? - -TPUは**Tensor Processing Unit(テンソル処理ユニット)**の略です。これらはGoogleが設計したハードウェアで、ニューラルネットワーク内のテンソル計算を大幅に高速化するために使用されます。これはGPUのようなものです。ネットワークのトレーニングと推論の両方に使用できます。一般的にはGoogleのクラウドサービスを介してアクセスされますが、Google ColabとKaggle Kernelsを通じても無料で小規模のTPUに直接アクセスできます。 - -[🤗 TransformersのすべてのTensorFlowモデルはKerasモデルです](https://huggingface.co/blog/tensorflow-philosophy)ので、この文書のほとんどの方法は一般的にKerasモデル用のTPUトレーニングに適用できます!ただし、TransformersとDatasetsのHuggingFaceエコシステム(hug-o-system?)に固有のポイントもいくつかあり、それについては適用するときにそれを示します。 - -### What kinds of TPU are available? - -新しいユーザーは、さまざまなTPUとそのアクセス方法に関する幅広い情報によく混乱します。理解するための最初の重要な違いは、**TPUノード**と**TPU VM**の違いです。 - -**TPUノード**を使用すると、事実上リモートのTPUに間接的にアクセスします。別個のVMが必要で、ネットワークとデータパイプラインを初期化し、それらをリモートノードに転送します。Google ColabでTPUを使用すると、**TPUノード**スタイルでアクセスしています。 - -TPUノードを使用すると、それに慣れていない人々にはかなり予期しない動作が発生することがあります!特に、TPUはPythonコードを実行しているマシンと物理的に異なるシステムに配置されているため、データはローカルマシンにローカルで格納されているデータパイプラインが完全に失敗します。代わりに、データはGoogle Cloud Storageに格納する必要があります。ここでデータパイプラインはリモートのTPUノードで実行されている場合でも、データにアクセスできます。 - - - -すべてのデータを`np.ndarray`または`tf.Tensor`としてメモリに収めることができる場合、ColabまたはTPUノードを使用している場合でも、データをGoogle Cloud Storageにアップロードせずに`fit()`でトレーニングできます。 - - - - - -**🤗 Hugging Face固有のヒント🤗:** TFコードの例でよく見るであろう`Dataset.to_tf_dataset()`とその高レベルのラッパーである`model.prepare_tf_dataset()`は、TPUノードで失敗します。これは、`tf.data.Dataset`を作成しているにもかかわらず、それが「純粋な」`tf.data`パイプラインではなく、`tf.numpy_function`または`Dataset.from_generator()`を使用して基盤となるHuggingFace `Dataset`からデータをストリームで読み込むことからです。このHuggingFace `Dataset`はローカルディスク上のデータをバックアップしており、リモートTPUノードが読み取ることができないためです。 - - - -TPUにアクセスする第二の方法は、**TPU VM**を介してです。TPU VMを使用する場合、TPUが接続されているマシンに直接接続します。これはGPU VMでトレーニングを行うのと同様です。TPU VMは一般的にデータパイプラインに関しては特に作業がしやすく、上記のすべての警告はTPU VMには適用されません! - -これは主観的な文書ですので、こちらの意見です:**可能な限りTPUノードの使用を避けてください。** TPU VMよりも混乱しやすく、デバッグが難しいです。将来的にはサポートされなくなる可能性もあります - Googleの最新のTPUであるTPUv4は、TPU VMとしてのみアクセスできるため、TPUノードは将来的には「レガシー」のアクセス方法になる可能性が高いです。ただし、無料でTPUにアクセスできるのはColabとKaggle Kernelsの場合があります。その場合、どうしても使用しなければならない場合の取り扱い方法を説明しようとします!詳細は[TPUの例のノートブック](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/tpu_training-tf.ipynb)で詳細な説明を確認してください。 - -### What sizes of TPU are available? - -単一のTPU(v2-8/v3-8/v4-8)は8つのレプリカを実行します。TPUは数百から数千のレプリカを同時に実行できる**ポッド**に存在します。単一のTPUよりも多くのTPUを使用するが、ポッド全体ではない場合(たとえばv3-32)、TPUフリートは**ポッドスライス**として参照されます。 - -Colabを介して無料のTPUにアクセスする場合、通常は単一のv2-8 TPUが提供されます。 - - -### I keep hearing about this XLA thing. What’s XLA, and how does it relate to TPUs? - -XLAは、TensorFlowとJAXの両方で使用される最適化コンパイラです。JAXでは唯一のコンパイラであり、TensorFlowではオプションですが(しかしTPUでは必須です!)、Kerasモデルをトレーニングする際に`model.compile()`に引数`jit_compile=True`を渡すことで最も簡単に有効にできます。エラーが発生せず、パフォーマンスが良好であれば、それはTPUに移行する準備が整った良い兆候です! - -TPU上でのデバッグは一般的にCPU/GPUよりも少し難しいため、TPUで試す前にまずCPU/GPUでXLAを使用してコードを実行することをお勧めします。もちろん、長時間トレーニングする必要はありません。モデルとデータパイプラインが期待通りに動作するかを確認するための数ステップだけです。 - - - -XLAコンパイルされたコードは通常高速です。したがって、TPUで実行する予定がない場合でも、`jit_compile=True`を追加することでパフォーマンスを向上させることができます。ただし、以下のXLA互換性に関する注意事項に注意してください! - - - - - -**苦い経験から生まれたヒント:** `jit_compile=True`を使用することは、CPU/GPUコードがXLA互換であることを確認し、速度を向上させる良い方法ですが、実際にTPUでコードを実行する際には多くの問題を引き起こす可能性があります。 XLAコンパイルはTPU上で暗黙的に行われるため、実際にコードをTPUで実行する前にその行を削除することを忘れないでください! - - - -### How do I make my model XLA compatible? - -多くの場合、コードはすでにXLA互換かもしれません!ただし、XLAでは動作する通常のTensorFlowでも動作しないいくつかの要素があります。以下に、3つの主要なルールにまとめています: - - - -**🤗 HuggingFace固有のヒント🤗:** TensorFlowモデルと損失関数をXLA互換に書き直すために多くの努力を払っています。通常、モデルと損失関数はデフォルトでルール#1と#2に従っているため、`transformers`モデルを使用している場合はこれらをスキップできます。ただし、独自のモデルと損失関数を記述する場合は、これらのルールを忘れないでください! - - - -#### XLA Rule #1: Your code cannot have “data-dependent conditionals” - -これは、任意の`if`ステートメントが`tf.Tensor`内の値に依存していない必要があることを意味します。例えば、次のコードブロックはXLAでコンパイルできません! - -```python -if tf.reduce_sum(tensor) > 10: - tensor = tensor / 2.0 -``` - -これは最初は非常に制限的に思えるかもしれませんが、ほとんどのニューラルネットコードはこれを行う必要はありません。通常、この制約を回避するために`tf.cond`を使用するか(ドキュメントはこちらを参照)、条件を削除して代わりに指示変数を使用したりすることができます。次のように: - -```python -sum_over_10 = tf.cast(tf.reduce_sum(tensor) > 10, tf.float32) -tensor = tensor / (1.0 + sum_over_10) -``` - -このコードは、上記のコードとまったく同じ効果を持っていますが、条件を回避することで、XLAで問題なくコンパイルできることを確認します! - -#### XLA Rule #2: Your code cannot have “data-dependent shapes” - -これは、コード内のすべての `tf.Tensor` オブジェクトの形状が、その値に依存しないことを意味します。たとえば、`tf.unique` 関数はXLAでコンパイルできないので、このルールに違反します。なぜなら、これは入力 `Tensor` の一意の値の各インスタンスを含む `tensor` を返すためです。この出力の形状は、入力 `Tensor` の重複具合によって異なるため、XLAはそれを処理しないことになります! - -一般的に、ほとんどのニューラルネットワークコードはデフォルトでルール#2に従います。ただし、いくつかの一般的なケースでは問題が発生することがあります。非常に一般的なケースの1つは、**ラベルマスキング**を使用する場合です。ラベルを無視して損失を計算する場所を示すために、ラベルを負の値に設定する方法です。NumPyまたはPyTorchのラベルマスキングをサポートする損失関数を見ると、次のような[ブールインデックス](https://numpy.org/doc/stable/user/basics.indexing.html#boolean-array-indexing)を使用したコードがよく見られます: - - -```python -label_mask = labels >= 0 -masked_outputs = outputs[label_mask] -masked_labels = labels[label_mask] -loss = compute_loss(masked_outputs, masked_labels) -mean_loss = torch.mean(loss) -``` - -このコードはNumPyやPyTorchでは完全に機能しますが、XLAでは動作しません!なぜなら、`masked_outputs`と`masked_labels`の形状はマスクされた位置の数に依存するため、これは**データ依存の形状**になります。ただし、ルール#1と同様に、このコードを書き直して、データ依存の形状なしでまったく同じ出力を生成できることがあります。 - - -```python -label_mask = tf.cast(labels >= 0, tf.float32) -loss = compute_loss(outputs, labels) -loss = loss * label_mask # Set negative label positions to 0 -mean_loss = tf.reduce_sum(loss) / tf.reduce_sum(label_mask) -``` - - -ここでは、データ依存の形状を避けるために、各位置で損失を計算してから、平均を計算する際に分子と分母の両方でマスクされた位置をゼロ化する方法を紹介します。これにより、最初のアプローチとまったく同じ結果が得られますが、XLA互換性を維持します。注意点として、ルール#1と同じトリックを使用します - `tf.bool`を`tf.float32`に変換して指標変数として使用します。これは非常に便利なトリックですので、自分のコードをXLAに変換する必要がある場合には覚えておいてください! - -#### XLA Rule #3: XLA will need to recompile your model for every different input shape it sees - -これは重要なルールです。これはつまり、入力形状が非常に変動的な場合、XLA はモデルを何度も再コンパイルする必要があるため、大きなパフォーマンスの問題が発生する可能性があるということです。これは NLP モデルで一般的に発生し、トークナイズ後の入力テキストの長さが異なる場合があります。他のモダリティでは、静的な形状が一般的であり、このルールはほとんど問題になりません。 - -ルール#3を回避する方法は何でしょうか?鍵は「パディング」です - すべての入力を同じ長さにパディングし、次に「attention_mask」を使用することで、可変形状と同じ結果を得ることができますが、XLA の問題は発生しません。ただし、過度のパディングも深刻な遅延を引き起こす可能性があります - データセット全体で最大の長さにすべてのサンプルをパディングすると、多くの計算とメモリを無駄にする可能性があります! - -この問題には完璧な解決策はありませんが、いくつかのトリックを試すことができます。非常に便利なトリックの1つは、**バッチのサンプルを32または64トークンの倍数までパディングする**ことです。これにより、トークン数がわずかに増加するだけで、すべての入力形状が32または64の倍数である必要があるため、一意の入力形状の数が大幅に減少します。一意の入力形状が少ないと、XLA の再コンパイルが少なくなります! - - - -**🤗 HuggingFace に関する具体的なヒント🤗:** 弊社のトークナイザーとデータコレクターには、ここで役立つメソッドがあります。トークナイザーを呼び出す際に `padding="max_length"` または `padding="longest"` を使用して、パディングされたデータを出力するように設定できます。トークナイザーとデータコレクターには、一意の入力形状の数を減らすのに役立つ `pad_to_multiple_of` 引数もあります! - - - -### How do I actually train my model on TPU? - -一度トレーニングが XLA 互換性があることを確認し、(TPU Node/Colab を使用する場合は)データセットが適切に準備されている場合、TPU 上で実行することは驚くほど簡単です!コードを変更する必要があるのは、いくつかの行を追加して TPU を初期化し、モデルとデータセットが `TPUStrategy` スコープ内で作成されるようにすることだけです。これを実際に見るには、[TPU のサンプルノートブック](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/tpu_training-tf.ipynb)をご覧ください! - -### Summary - -ここでは多くの情報が提供されましたので、TPU でモデルをトレーニングする際に以下のチェックリストを使用できます: - -- コードが XLA の三つのルールに従っていることを確認します。 -- CPU/GPU で `jit_compile=True` を使用してモデルをコンパイルし、XLA でトレーニングできることを確認します。 -- データセットをメモリに読み込むか、TPU 互換のデータセット読み込みアプローチを使用します([ノートブックを参照](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/tpu_training-tf.ipynb))。 -- コードを Colab(アクセラレータを「TPU」に設定)または Google Cloud の TPU VM に移行します。 -- TPU 初期化コードを追加します([ノートブックを参照](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/tpu_training-tf.ipynb))。 -- `TPUStrategy` を作成し、データセットの読み込みとモデルの作成が `strategy.scope()` 内で行われることを確認します([ノートブックを参照](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/tpu_training-tf.ipynb))。 -- TPU に移行する際に `jit_compile=True` を外すのを忘れないでください! -- 🙏🙏🙏🥺🥺🥺 -- `model.fit()` を呼び出します。 -- おめでとうございます! - - diff --git a/docs/source/ja/tf_xla.md b/docs/source/ja/tf_xla.md deleted file mode 100644 index 1f5a2af1a5a2..000000000000 --- a/docs/source/ja/tf_xla.md +++ /dev/null @@ -1,179 +0,0 @@ - - -# XLA Integration for TensorFlow Models - -[[open-in-colab]] - -加速線形代数(Accelerated Linear Algebra)、通称XLAは、TensorFlowモデルのランタイムを高速化するためのコンパイラです。[公式ドキュメント](https://www.tensorflow.org/xla)によれば、XLA(Accelerated Linear Algebra)は線形代数のためのドメイン固有のコンパイラで、TensorFlowモデルを潜在的にソースコードの変更なしで高速化できます。 - -TensorFlowでXLAを使用するのは簡単です。XLAは`tensorflow`ライブラリ内にパッケージ化されており、[`tf.function`](https://www.tensorflow.org/guide/intro_to_graphs)などのグラフを作成する関数内で`jit_compile`引数を使用してトリガーできます。`fit()`や`predict()`などのKerasメソッドを使用する場合、`model.compile()`に`jit_compile`引数を渡すだけでXLAを有効にできます。ただし、XLAはこれらのメソッドに限定されているわけではありません。任意の`tf.function`を高速化するためにも使用できます。 - -🤗 Transformers内のいくつかのTensorFlowメソッドは、XLAと互換性があるように書き直されています。これには、[GPT2](https://huggingface.co/docs/transformers/model_doc/gpt2)、[T5](https://huggingface.co/docs/transformers/model_doc/t5)、[OPT](https://huggingface.co/docs/transformers/model_doc/opt)などのテキスト生成モデルや、[Whisper](https://huggingface.co/docs/transformers/model_doc/whisper)などの音声処理モデルも含まれます。 - -速度向上の具体的な量はモデルに非常に依存しますが、🤗 Transformers内のTensorFlowテキスト生成モデルでは、約100倍の速度向上を確認しています。このドキュメントでは、これらのモデルにXLAを使用して最大のパフォーマンスを得る方法を説明します。また、ベンチマークとXLA統合のデザイン哲学について詳しく学びたい場合の追加リソースへのリンクも提供します。 - -## Running TF functions with XLA - -以下のTensorFlowモデルを考えてみましょう: - - -```py -import tensorflow as tf - -model = tf.keras.Sequential( - [tf.keras.layers.Dense(10, input_shape=(10,), activation="relu"), tf.keras.layers.Dense(5, activation="softmax")] -) -``` - -上記のモデルは、次元が`(10, )`の入力を受け入れます。このモデルをフォワードパスで実行するには、次のようにします: - - -```py -# Generate random inputs for the model. -batch_size = 16 -input_vector_dim = 10 -random_inputs = tf.random.normal((batch_size, input_vector_dim)) - -# Run a forward pass. -_ = model(random_inputs) -``` - -XLAでコンパイルされた関数を使用してフォワードパスを実行するには、以下のようにします: - - -```py -xla_fn = tf.function(model, jit_compile=True) -_ = xla_fn(random_inputs) -``` - -`model`のデフォルトの `call()` 関数はXLAグラフをコンパイルするために使用されます。ただし、XLAにコンパイルしたい他のモデル関数がある場合、それも可能です。以下はその方法です: - - -```py -my_xla_fn = tf.function(model.my_xla_fn, jit_compile=True) -``` - -## Running a TF text generation model with XLA from 🤗 Transformers - -🤗 Transformers内でXLAでの高速化された生成を有効にするには、最新バージョンの`transformers`がインストールされている必要があります。次のコマンドを実行してインストールできます: - -```bash -pip install transformers --upgrade -``` - -次に、次のコードを実行できます: - - -```py -import tensorflow as tf -from transformers import AutoTokenizer, TFAutoModelForCausalLM - -# Will error if the minimal version of Transformers is not installed. -from transformers.utils import check_min_version - -check_min_version("4.21.0") - - -tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2", padding_side="left", pad_token="") -model = TFAutoModelForCausalLM.from_pretrained("openai-community/gpt2") -input_string = ["TensorFlow is"] - -# One line to create an XLA generation function -xla_generate = tf.function(model.generate, jit_compile=True) - -tokenized_input = tokenizer(input_string, return_tensors="tf") -generated_tokens = xla_generate(**tokenized_input, num_beams=2) - -decoded_text = tokenizer.decode(generated_tokens[0], skip_special_tokens=True) -print(f"Generated -- {decoded_text}") -# Generated -- TensorFlow is an open-source, open-source, distributed-source application # framework for the -``` - -`generate()`でXLAを有効にするのは、たった一行のコードです。コードの残り部分は変更されていません。ただし、XLA固有のいくつかの注意点が上記のコードスニペットにあります。これらに注意する必要があり、XLAがもたらす速度向上を実現するためにそれらを把握することが重要です。次のセクションでこれらについて詳しく説明します。 - - -## Gotchas to be aware of - -XLAを有効にした関数(上記の`xla_generate()`など)を初めて実行すると、内部で計算グラフを推論しようとしますが、これは時間がかかります。このプロセスは["トレーシング"(tracing)](https://www.tensorflow.org/guide/intro_to_graphs#when_is_a_function_tracing)として知られています。 - -生成時間が高速ではないことに気付くかもしれません。`xla_generate()`(または他のXLA対応関数)の連続呼び出しでは、関数への入力が最初に計算グラフが構築されたときと同じ形状に従っている場合、計算グラフを推論する必要はありません。これは、入力形状が固定されているモダリティ(例:画像)には問題ありませんが、変数の入力形状モダリティ(例:テキスト)を扱う場合には注意が必要です。 - -`xla_generate()`が常に同じ入力形状で動作するようにするには、トークナイザを呼び出す際に`padding`引数を指定できます。 - -```py -import tensorflow as tf -from transformers import AutoTokenizer, TFAutoModelForCausalLM - -tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2", padding_side="left", pad_token="") -model = TFAutoModelForCausalLM.from_pretrained("openai-community/gpt2") -input_string = ["TensorFlow is"] - -xla_generate = tf.function(model.generate, jit_compile=True) - -# Here, we call the tokenizer with padding options. -tokenized_input = tokenizer(input_string, pad_to_multiple_of=8, padding=True, return_tensors="tf") - -generated_tokens = xla_generate(**tokenized_input, num_beams=2) -decoded_text = tokenizer.decode(generated_tokens[0], skip_special_tokens=True) -print(f"Generated -- {decoded_text}") -``` - -これにより、`xla_generate()`への入力が常にトレースされた形状の入力を受け取ることを確認し、生成時間の高速化を実現できます。以下のコードでこれを確認できます: - -```py -import time -import tensorflow as tf -from transformers import AutoTokenizer, TFAutoModelForCausalLM - -tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2", padding_side="left", pad_token="") -model = TFAutoModelForCausalLM.from_pretrained("openai-community/gpt2") - -xla_generate = tf.function(model.generate, jit_compile=True) - -for input_string in ["TensorFlow is", "TensorFlow is a", "TFLite is a"]: - tokenized_input = tokenizer(input_string, pad_to_multiple_of=8, padding=True, return_tensors="tf") - start = time.time_ns() - generated_tokens = xla_generate(**tokenized_input, num_beams=2) - end = time.time_ns() - print(f"Execution time -- {(end - start) / 1e6:.1f} ms\n") -``` - -Tesla T4 GPUを使用すると、次のような出力が期待されます: - -```bash -Execution time -- 30819.6 ms - -Execution time -- 79.0 ms - -Execution time -- 78.9 ms -``` - -最初の`xla_generate()`呼び出しはトレーシングのために時間がかかりますが、連続する呼び出しは桁違いに高速です。生成オプションのいかなる変更も、再トレーシングを引き起こし、生成時間の遅延を引き起こすことに注意してください。 - -このドキュメントでは、🤗 Transformersが提供するテキスト生成オプションをすべて網羅していません。高度なユースケースについてはドキュメンテーションを参照することをお勧めします。 - -## Additional Resources - -ここでは、🤗 Transformersと一般的なXLAについてさらに詳しく学びたい場合のいくつかの追加リソースを提供します。 - -* [このColab Notebook](https://colab.research.google.com/github/huggingface/blog/blob/main/notebooks/91_tf_xla_generate.ipynb)では、XLA対応のエンコーダーデコーダー([T5](https://huggingface.co/docs/transformers/model_doc/t5)など)およびデコーダー専用([GPT2](https://huggingface.co/docs/transformers/model_doc/gpt2)など)テキスト生成モデルを試すための対話型デモが提供されています。 -* [このブログ記事](https://huggingface.co/blog/tf-xla-generate)では、XLA対応モデルの比較ベンチマークの概要と、TensorFlowでのXLAについての友好的な紹介が提供されています。 -* [このブログ記事](https://blog.tensorflow.org/2022/11/how-hugging-face-improved-text-generation-performance-with-xla.html)では、🤗 TransformersのTensorFlowモデルにXLAサポートを追加する際の設計哲学について説明しています。 -* 一般的なXLAとTensorFlowグラフについて詳しく学ぶためのおすすめの投稿: - * [XLA: 機械学習用の最適化コンパイラ](https://www.tensorflow.org/xla) - * [グラフと`tf.function`の紹介](https://www.tensorflow.org/guide/intro_to_graphs) - * [`tf.function`を使用したパフォーマンス向上](https://www.tensorflow.org/guide/function) diff --git a/docs/source/ja/tflite.md b/docs/source/ja/tflite.md deleted file mode 100644 index ad3e9a3f484e..000000000000 --- a/docs/source/ja/tflite.md +++ /dev/null @@ -1,58 +0,0 @@ - - -# Export to TFLite - -[TensorFlow Lite](https://www.tensorflow.org/lite/guide)は、モバイルフォン、組み込みシステム、およびモノのインターネット(IoT)デバイスなど、リソースに制約のあるデバイスに機械学習モデルを展開するための軽量なフレームワークです。TFLiteは、計算能力、メモリ、および電力消費が限られているこれらのデバイス上でモデルを効率的に最適化して実行するために設計されています。 -TensorFlow Liteモデルは、`.tflite`ファイル拡張子で識別される特別な効率的なポータブル形式で表されます。 - -🤗 Optimumは、🤗 TransformersモデルをTFLiteにエクスポートするための機能を`exporters.tflite`モジュールを介して提供しています。サポートされているモデルアーキテクチャのリストについては、[🤗 Optimumのドキュメント](https://huggingface.co/docs/optimum/exporters/tflite/overview)をご参照ください。 - -モデルをTFLiteにエクスポートするには、必要な依存関係をインストールしてください: - - -```bash -pip install optimum[exporters-tf] -``` - -すべての利用可能な引数を確認するには、[🤗 Optimumドキュメント](https://huggingface.co/docs/optimum/main/en/exporters/tflite/usage_guides/export_a_model)を参照するか、コマンドラインでヘルプを表示してください: - -```bash -optimum-cli export tflite --help -``` - -🤗 Hubからモデルのチェックポイントをエクスポートするには、例えば `google-bert/bert-base-uncased` を使用する場合、次のコマンドを実行します: - -```bash -optimum-cli export tflite --model google-bert/bert-base-uncased --sequence_length 128 bert_tflite/ -``` - -進行状況を示すログが表示され、生成された `model.tflite` が保存された場所も表示されるはずです: - -```bash -Validating TFLite model... - -[✓] TFLite model output names match reference model (logits) - - Validating TFLite Model output "logits": - -[✓] (1, 128, 30522) matches (1, 128, 30522) - -[x] values not close enough, max diff: 5.817413330078125e-05 (atol: 1e-05) -The TensorFlow Lite export succeeded with the warning: The maximum absolute difference between the output of the reference model and the TFLite exported model is not within the set tolerance 1e-05: -- logits: max diff = 5.817413330078125e-05. - The exported model was saved at: bert_tflite - ``` - -上記の例は🤗 Hubからチェックポイントをエクスポートする方法を示しています。ローカルモデルをエクスポートする場合、まずモデルの重みファイルとトークナイザファイルを同じディレクトリ(`local_path`)に保存したことを確認してください。CLIを使用する場合、🤗 Hubのチェックポイント名の代わりに`model`引数に`local_path`を渡します。 - - diff --git a/docs/source/ko/_toctree.yml b/docs/source/ko/_toctree.yml index 2412e497556f..21f26cd66af6 100644 --- a/docs/source/ko/_toctree.yml +++ b/docs/source/ko/_toctree.yml @@ -208,8 +208,6 @@ sections: - local: serialization title: ONNX로 내보내기 - - local: tflite - title: TFLite로 내보내기 - local: executorch title: ExecuTorch - local: torchscript @@ -402,8 +400,6 @@ title: Configuration - local: main_classes/data_collator title: Data Collator - - local: main_classes/keras_callbacks - title: Keras callbacks - local: main_classes/logging title: Logging - local: main_classes/model diff --git a/docs/source/ko/main_classes/keras_callbacks.md b/docs/source/ko/main_classes/keras_callbacks.md deleted file mode 100644 index 25d5ea3e4008..000000000000 --- a/docs/source/ko/main_classes/keras_callbacks.md +++ /dev/null @@ -1,27 +0,0 @@ - - -# 케라스 콜백[[keras-callbacks]] - -케라스로 트랜스포머 모델을 학습할 때, 일반적인 작업을 자동화하기 위한 라이브러리 전용 콜백들을 사용 할 수 있습니다. - -## KerasMetricCallback[[transformers.KerasMetricCallback]] - -[[autodoc]] KerasMetricCallback - -## PushToHubCallback[[transformers.PushToHubCallback]] - -[[autodoc]] PushToHubCallback diff --git a/docs/source/ko/tflite.md b/docs/source/ko/tflite.md deleted file mode 100644 index 464106a6b7c2..000000000000 --- a/docs/source/ko/tflite.md +++ /dev/null @@ -1,62 +0,0 @@ - - -# TFLite로 내보내기[[export-to-tflite]] - -[TensorFlow Lite](https://www.tensorflow.org/lite/guide)는 자원이 제한된 휴대폰, 임베디드 시스템, 사물인터넷(IoT) 기기에서 -기계학습 모델을 배포하기 위한 경량 프레임워크입니다. -TFLite는 연산 능력, 메모리, 전력 소비가 제한된 기기에서 모델을 효율적으로 최적화하고 실행하기 위해 -설계되었습니다. -TensorFlow Lite 모델은 `.tflite` 파일 확장자로 식별되는 특수하고 효율적인 휴대용 포맷으로 표현됩니다. - -🤗 Optimum은 `exporters.tflite` 모듈로 🤗 Transformers 모델을 TFLite로 내보내는 기능을 제공합니다. -지원되는 모델 아키텍처 목록은 [🤗 Optimum 문서](https://huggingface.co/docs/optimum/exporters/tflite/overview)를 참고하세요. - -모델을 TFLite로 내보내려면, 필요한 종속성을 설치하세요: - -```bash -pip install optimum[exporters-tf] -``` - -모든 사용 가능한 인수를 확인하려면, [🤗 Optimum 문서](https://huggingface.co/docs/optimum/main/en/exporters/tflite/usage_guides/export_a_model)를 참고하거나 -터미널에서 도움말을 살펴보세요: - -```bash -optimum-cli export tflite --help -``` - -예를 들어 🤗 Hub에서의 `google-bert/bert-base-uncased` 모델 체크포인트를 내보내려면, 다음 명령을 실행하세요: - -```bash -optimum-cli export tflite --model google-bert/bert-base-uncased --sequence_length 128 bert_tflite/ -``` - -다음과 같이 진행 상황을 나타내는 로그와 결과물인 `model.tflite`가 저장된 위치를 보여주는 로그가 표시됩니다: - -```bash -Validating TFLite model... - -[✓] TFLite model output names match reference model (logits) - - Validating TFLite Model output "logits": - -[✓] (1, 128, 30522) matches (1, 128, 30522) - -[x] values not close enough, max diff: 5.817413330078125e-05 (atol: 1e-05) -The TensorFlow Lite export succeeded with the warning: The maximum absolute difference between the output of the reference model and the TFLite exported model is not within the set tolerance 1e-05: -- logits: max diff = 5.817413330078125e-05. - The exported model was saved at: bert_tflite - ``` - -위 예제는 🤗 Hub에서의 체크포인트를 내보내는 방법을 보여줍니다. -로컬 모델을 내보낸다면, 먼저 모델 가중치와 토크나이저 파일이 모두 같은 디렉터리( `local_path` )에 저장됐는지 확인하세요. -CLI를 사용할 때, 🤗 Hub에서의 체크포인트 이름 대신 `model` 인수에 `local_path`를 전달하면 됩니다. \ No newline at end of file diff --git a/docs/source/ms/_toctree.yml b/docs/source/ms/_toctree.yml index 56a4744b8b86..05d4829437b9 100644 --- a/docs/source/ms/_toctree.yml +++ b/docs/source/ms/_toctree.yml @@ -115,8 +115,6 @@ title: Latihan pada banyak CPU - local: perf_train_tpu title: Latihan mengenai TPU - - local: perf_train_tpu_tf - title: Latihan tentang TPU dengan TensorFlow - local: perf_train_special title: Latihan mengenai Perkakasan Khusus - local: perf_infer_cpu @@ -135,8 +133,6 @@ title: Penyahpepijatan - local: hpo_train title: Carian Hiperparameter menggunakan API Pelatih - - local: tf_xla - title: Penyepaduan XLA untuk Model TensorFlow title: Prestasi dan kebolehskalaan - sections: - local: contributing @@ -185,8 +181,6 @@ title: Configuration - local: main_classes/data_collator title: Data Collator - - local: main_classes/keras_callbacks - title: Keras callbacks - local: main_classes/logging title: Logging - local: main_classes/model diff --git a/docs/source/pt/_toctree.yml b/docs/source/pt/_toctree.yml index d042168f7b9b..c525a2a4faa1 100644 --- a/docs/source/pt/_toctree.yml +++ b/docs/source/pt/_toctree.yml @@ -23,8 +23,6 @@ title: Compartilhando modelos customizados - local: run_scripts title: Treinamento a partir de um script - - local: converting_tensorflow_models - title: Convertendo checkpoints do TensorFlow para Pytorch - local: serialization title: Exportando modelos para ONNX - sections: diff --git a/docs/source/pt/converting_tensorflow_models.md b/docs/source/pt/converting_tensorflow_models.md deleted file mode 100644 index 446acd62ea8f..000000000000 --- a/docs/source/pt/converting_tensorflow_models.md +++ /dev/null @@ -1,152 +0,0 @@ - - -# Convertendo checkpoints do TensorFlow para Pytorch - -Uma interface de linha de comando é fornecida para converter os checkpoints originais Bert/GPT/GPT-2/Transformer-XL/XLNet/XLM em modelos -que podem ser carregados usando os métodos `from_pretrained` da biblioteca. - - - -A partir da versão 2.3.0 o script de conversão agora faz parte do transformers CLI (**transformers**) disponível em qualquer instalação -transformers >= 2.3.0. - -A documentação abaixo reflete o formato do comando **transformers convert**. - - - -## BERT - -Você pode converter qualquer checkpoint do BERT em TensorFlow (em particular [os modelos pré-treinados lançados pelo Google](https://github.com/google-research/bert#pre-trained-models)) em um arquivo PyTorch usando um -[convert_bert_original_tf_checkpoint_to_pytorch.py](https://github.com/huggingface/transformers/tree/main/src/transformers/models/bert/convert_bert_original_tf_checkpoint_to_pytorch.py) script. - -Esta Interface de Linha de Comando (CLI) recebe como entrada um checkpoint do TensorFlow (três arquivos começando com `bert_model.ckpt`) e o -arquivo de configuração (`bert_config.json`), e então cria um modelo PyTorch para esta configuração, carrega os pesos -do checkpoint do TensorFlow no modelo PyTorch e salva o modelo resultante em um arquivo PyTorch que pode -ser importado usando `from_pretrained()` (veja o exemplo em [quicktour](quicktour) , [run_glue.py](https://github.com/huggingface/transformers/tree/main/examples/pytorch/text-classification/run_glue.py) ). - -Você só precisa executar este script de conversão **uma vez** para obter um modelo PyTorch. Você pode então desconsiderar o checkpoint em - TensorFlow (os três arquivos começando com `bert_model.ckpt`), mas certifique-se de manter o arquivo de configuração (\ -`bert_config.json`) e o arquivo de vocabulário (`vocab.txt`), pois eles também são necessários para o modelo PyTorch. - -Para executar este script de conversão específico, você precisará ter o TensorFlow e o PyTorch instalados (`pip install tensorflow`). O resto do repositório requer apenas o PyTorch. - -Aqui está um exemplo do processo de conversão para um modelo `BERT-Base Uncased` pré-treinado: - -```bash -export BERT_BASE_DIR=/path/to/bert/uncased_L-12_H-768_A-12 - -transformers convert --model_type bert \ - --tf_checkpoint $BERT_BASE_DIR/bert_model.ckpt \ - --config $BERT_BASE_DIR/bert_config.json \ - --pytorch_dump_output $BERT_BASE_DIR/pytorch_model.bin -``` - -Você pode baixar os modelos pré-treinados do Google para a conversão [aqui](https://github.com/google-research/bert#pre-trained-models). - -## ALBERT - -Converta os checkpoints do modelo ALBERT em TensorFlow para PyTorch usando o -[convert_albert_original_tf_checkpoint_to_pytorch.py](https://github.com/huggingface/transformers/tree/main/src/transformers/models/albert/convert_albert_original_tf_checkpoint_to_pytorch.py) script. - -A Interface de Linha de Comando (CLI) recebe como entrada um checkpoint do TensorFlow (três arquivos começando com `model.ckpt-best`) e o -arquivo de configuração (`albert_config.json`), então cria e salva um modelo PyTorch. Para executar esta conversão, você -precisa ter o TensorFlow e o PyTorch instalados. - -Aqui está um exemplo do processo de conversão para o modelo `ALBERT Base` pré-treinado: - -```bash -export ALBERT_BASE_DIR=/path/to/albert/albert_base - -transformers convert --model_type albert \ - --tf_checkpoint $ALBERT_BASE_DIR/model.ckpt-best \ - --config $ALBERT_BASE_DIR/albert_config.json \ - --pytorch_dump_output $ALBERT_BASE_DIR/pytorch_model.bin -``` - -Você pode baixar os modelos pré-treinados do Google para a conversão [aqui](https://github.com/google-research/albert#pre-trained-models). - -## OpenAI GPT - -Aqui está um exemplo do processo de conversão para um modelo OpenAI GPT pré-treinado, supondo que seu checkpoint NumPy -foi salvo com o mesmo formato do modelo pré-treinado OpenAI (veja [aqui](https://github.com/openai/finetune-transformer-lm)\ -) - -```bash -export OPENAI_GPT_CHECKPOINT_FOLDER_PATH=/path/to/openai/pretrained/numpy/weights - -transformers convert --model_type gpt \ - --tf_checkpoint $OPENAI_GPT_CHECKPOINT_FOLDER_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT \ - [--config OPENAI_GPT_CONFIG] \ - [--finetuning_task_name OPENAI_GPT_FINETUNED_TASK] \ -``` - -## OpenAI GPT-2 - -Aqui está um exemplo do processo de conversão para um modelo OpenAI GPT-2 pré-treinado (consulte [aqui](https://github.com/openai/gpt-2)) - -```bash -export OPENAI_GPT2_CHECKPOINT_PATH=/path/to/openai-community/gpt2/pretrained/weights - -transformers convert --model_type gpt2 \ - --tf_checkpoint $OPENAI_GPT2_CHECKPOINT_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT \ - [--config OPENAI_GPT2_CONFIG] \ - [--finetuning_task_name OPENAI_GPT2_FINETUNED_TASK] -``` - -## XLNet - -Aqui está um exemplo do processo de conversão para um modelo XLNet pré-treinado: - -```bash -export TRANSFO_XL_CHECKPOINT_PATH=/path/to/xlnet/checkpoint -export TRANSFO_XL_CONFIG_PATH=/path/to/xlnet/config - -transformers convert --model_type xlnet \ - --tf_checkpoint $TRANSFO_XL_CHECKPOINT_PATH \ - --config $TRANSFO_XL_CONFIG_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT \ - [--finetuning_task_name XLNET_FINETUNED_TASK] \ -``` - -## XLM - -Aqui está um exemplo do processo de conversão para um modelo XLM pré-treinado: - -```bash -export XLM_CHECKPOINT_PATH=/path/to/xlm/checkpoint - -transformers convert --model_type xlm \ - --tf_checkpoint $XLM_CHECKPOINT_PATH \ - --pytorch_dump_output $PYTORCH_DUMP_OUTPUT - [--config XML_CONFIG] \ - [--finetuning_task_name XML_FINETUNED_TASK] -``` - -## T5 - -Aqui está um exemplo do processo de conversão para um modelo T5 pré-treinado: - -```bash -export T5=/path/to/t5/uncased_L-12_H-768_A-12 - -transformers convert --model_type t5 \ - --tf_checkpoint $T5/t5_model.ckpt \ - --config $T5/t5_config.json \ - --pytorch_dump_output $T5/pytorch_model.bin -``` diff --git a/docs/source/zh/_toctree.yml b/docs/source/zh/_toctree.yml index 50123200bcb7..ad7e2479b42e 100644 --- a/docs/source/zh/_toctree.yml +++ b/docs/source/zh/_toctree.yml @@ -44,8 +44,6 @@ title: 聊天模型的模板 - local: serialization title: 导出为 ONNX - - local: tflite - title: 导出为 TFLite - local: torchscript title: 导出为 TorchScript - local: gguf @@ -76,8 +74,6 @@ title: 实例化大模型 - local: debugging title: 问题定位及解决 - - local: tf_xla - title: TensorFlow模型的XLA集成 - local: perf_torch_compile title: 使用 `torch.compile()` 优化推理 title: 性能和可扩展性 @@ -107,8 +103,6 @@ title: Configuration - local: main_classes/data_collator title: Data Collator - - local: main_classes/keras_callbacks - title: Keras callbacks - local: main_classes/logging title: Logging - local: main_classes/model diff --git a/docs/source/zh/main_classes/keras_callbacks.md b/docs/source/zh/main_classes/keras_callbacks.md deleted file mode 100644 index 1eea2eb99816..000000000000 --- a/docs/source/zh/main_classes/keras_callbacks.md +++ /dev/null @@ -1,27 +0,0 @@ - - -# Keras callbacks - -在Keras中训练Transformers模型时,有一些库特定的callbacks函数可用于自动执行常见任务: - -## KerasMetricCallback - -[[autodoc]] KerasMetricCallback - -## PushToHubCallback - -[[autodoc]] PushToHubCallback diff --git a/docs/source/zh/tf_xla.md b/docs/source/zh/tf_xla.md deleted file mode 100644 index 2e5b444d876c..000000000000 --- a/docs/source/zh/tf_xla.md +++ /dev/null @@ -1,179 +0,0 @@ - - -# 用于 TensorFlow 模型的 XLA 集成 - -[[open-in-colab]] - -加速线性代数,也称为XLA,是一个用于加速TensorFlow模型运行时间的编译器。从[官方文档](https://www.tensorflow.org/xla)中可以看到: - -XLA(加速线性代数)是一种针对线性代数的特定领域编译器,可以在可能不需要更改源代码的情况下加速TensorFlow模型。 - -在TensorFlow中使用XLA非常简单——它包含在`tensorflow`库中,并且可以使用任何图创建函数中的`jit_compile`参数来触发,例如[`tf.function`](https://www.tensorflow.org/guide/intro_to_graphs)。在使用Keras方法如`fit()`和`predict()`时,只需将`jit_compile`参数传递给`model.compile()`即可启用XLA。然而,XLA不仅限于这些方法 - 它还可以用于加速任何任意的`tf.function`。 - -在🤗 Transformers中,几个TensorFlow方法已经被重写为与XLA兼容,包括[GPT2](https://huggingface.co/docs/transformers/model_doc/gpt2)、[T5](https://huggingface.co/docs/transformers/model_doc/t5)和[OPT](https://huggingface.co/docs/transformers/model_doc/opt)等文本生成模型,以及[Whisper](https://huggingface.co/docs/transformers/model_doc/whisper)等语音处理模型。 - -虽然确切的加速倍数很大程度上取决于模型,但对于🤗 Transformers中的TensorFlow文本生成模型,我们注意到速度提高了约100倍。本文档将解释如何在这些模型上使用XLA获得最大的性能。如果您有兴趣了解更多关于基准测试和我们在XLA集成背后的设计哲学的信息,我们还将提供额外的资源链接。 - - -## 使用 XLA 运行 TensorFlow 函数 - -让我们考虑以下TensorFlow 中的模型: - -```py -import tensorflow as tf - -model = tf.keras.Sequential( - [tf.keras.layers.Dense(10, input_shape=(10,), activation="relu"), tf.keras.layers.Dense(5, activation="softmax")] -) -``` - -上述模型接受维度为 `(10,)` 的输入。我们可以像下面这样使用模型进行前向传播: - -```py -# Generate random inputs for the model. -batch_size = 16 -input_vector_dim = 10 -random_inputs = tf.random.normal((batch_size, input_vector_dim)) - -# Run a forward pass. -_ = model(random_inputs) -``` - -为了使用 XLA 编译的函数运行前向传播,我们需要执行以下操作: - -```py -xla_fn = tf.function(model, jit_compile=True) -_ = xla_fn(random_inputs) -``` - -`model`的默认`call()`函数用于编译XLA图。但如果你想将其他模型函数编译成XLA,也是可以的,如下所示: - -```py -my_xla_fn = tf.function(model.my_xla_fn, jit_compile=True) -``` - -## 在🤗 Transformers库中使用XLA运行TensorFlow文本生成模型 - -要在🤗 Transformers中启用XLA加速生成,您需要安装最新版本的`transformers`。您可以通过运行以下命令来安装它: - -```bash -pip install transformers --upgrade -``` - -然后您可以运行以下代码: - -```py -import tensorflow as tf -from transformers import AutoTokenizer, TFAutoModelForCausalLM - -# Will error if the minimal version of Transformers is not installed. -from transformers.utils import check_min_version - -check_min_version("4.21.0") - - -tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2", padding_side="left", pad_token="") -model = TFAutoModelForCausalLM.from_pretrained("openai-community/gpt2") -input_string = ["TensorFlow is"] - -# One line to create an XLA generation function -xla_generate = tf.function(model.generate, jit_compile=True) - -tokenized_input = tokenizer(input_string, return_tensors="tf") -generated_tokens = xla_generate(**tokenized_input, num_beams=2) - -decoded_text = tokenizer.decode(generated_tokens[0], skip_special_tokens=True) -print(f"Generated -- {decoded_text}") -# Generated -- TensorFlow is an open-source, open-source, distributed-source application # framework for the -``` - -正如您所注意到的,在`generate()`上启用XLA只需要一行代码。其余部分代码保持不变。然而,上面的代码片段中有一些与XLA相关的注意事项。您需要了解这些注意事项,以充分利用XLA可能带来的性能提升。我们将在下面的部分讨论这些内容。 - -## 需要关注的注意事项 - -当您首次执行启用XLA的函数(如上面的`xla_generate()`)时,它将在内部尝试推断计算图,这是一个耗时的过程。这个过程被称为[“tracing”](https://www.tensorflow.org/guide/intro_to_graphs#when_is_a_function_tracing)。 - -您可能会注意到生成时间并不快。连续调用`xla_generate()`(或任何其他启用了XLA的函数)不需要再次推断计算图,只要函数的输入与最初构建计算图时的形状相匹配。对于具有固定输入形状的模态(例如图像),这不是问题,但如果您正在处理具有可变输入形状的模态(例如文本),则必须注意。 - -为了确保`xla_generate()`始终使用相同的输入形状,您可以在调用`tokenizer`时指定`padding`参数。 - -```py -import tensorflow as tf -from transformers import AutoTokenizer, TFAutoModelForCausalLM - -tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2", padding_side="left", pad_token="") -model = TFAutoModelForCausalLM.from_pretrained("openai-community/gpt2") -input_string = ["TensorFlow is"] - -xla_generate = tf.function(model.generate, jit_compile=True) - -# Here, we call the tokenizer with padding options. -tokenized_input = tokenizer(input_string, pad_to_multiple_of=8, padding=True, return_tensors="tf") - -generated_tokens = xla_generate(**tokenized_input, num_beams=2) -decoded_text = tokenizer.decode(generated_tokens[0], skip_special_tokens=True) -print(f"Generated -- {decoded_text}") -``` - -通过这种方式,您可以确保`xla_generate()`的输入始终具有它跟踪的形状,从而加速生成时间。您可以使用以下代码来验证这一点: - -```py -import time -import tensorflow as tf -from transformers import AutoTokenizer, TFAutoModelForCausalLM - -tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2", padding_side="left", pad_token="") -model = TFAutoModelForCausalLM.from_pretrained("openai-community/gpt2") - -xla_generate = tf.function(model.generate, jit_compile=True) - -for input_string in ["TensorFlow is", "TensorFlow is a", "TFLite is a"]: - tokenized_input = tokenizer(input_string, pad_to_multiple_of=8, padding=True, return_tensors="tf") - start = time.time_ns() - generated_tokens = xla_generate(**tokenized_input, num_beams=2) - end = time.time_ns() - print(f"Execution time -- {(end - start) / 1e6:.1f} ms\n") -``` - -在Tesla T4 GPU上,您可以期望如下的输出: - -```bash -Execution time -- 30819.6 ms - -Execution time -- 79.0 ms - -Execution time -- 78.9 ms -``` - -第一次调用`xla_generate()`会因为`tracing`而耗时,但后续的调用会快得多。请注意,任何时候对生成选项的更改都会触发重新`tracing`,从而导致生成时间减慢。 - -在本文档中,我们没有涵盖🤗 Transformers提供的所有文本生成选项。我们鼓励您阅读文档以了解高级用例。 - -## 附加资源 - -以下是一些附加资源,如果您想深入了解在🤗 Transformers和其他库下使用XLA: - -* [这个Colab Notebook](https://colab.research.google.com/github/huggingface/blog/blob/main/notebooks/91_tf_xla_generate.ipynb) 提供了一个互动演示,让您可以尝试使用XLA兼容的编码器-解码器(例如[T5](https://huggingface.co/docs/transformers/model_doc/t5))和仅解码器(例如[GPT2](https://huggingface.co/docs/transformers/model_doc/gpt2))文本生成模型。 - -* [这篇博客文章](https://huggingface.co/blog/tf-xla-generate) 提供了XLA兼容模型的比较基准概述,以及关于在TensorFlow中使用XLA的友好介绍。 - -* [这篇博客文章](https://blog.tensorflow.org/2022/11/how-hugging-face-improved-text-generation-performance-with-xla.html) 讨论了我们在🤗 Transformers中为TensorFlow模型添加XLA支持的设计理念。 - -* 推荐用于更多学习XLA和TensorFlow图的资源: - * [XLA:面向机器学习的优化编译器](https://www.tensorflow.org/xla) - * [图和tf.function简介](https://www.tensorflow.org/guide/intro_to_graphs) - * [使用tf.function获得更好的性能](https://www.tensorflow.org/guide/function) \ No newline at end of file diff --git a/docs/source/zh/tflite.md b/docs/source/zh/tflite.md deleted file mode 100644 index f0280156def4..000000000000 --- a/docs/source/zh/tflite.md +++ /dev/null @@ -1,54 +0,0 @@ - - -# 导出为 TFLite - -[TensorFlow Lite](https://www.tensorflow.org/lite/guide) 是一个轻量级框架,用于资源受限的设备上,如手机、嵌入式系统和物联网(IoT)设备,部署机器学习模型。TFLite 旨在在计算能力、内存和功耗有限的设备上优化和高效运行模型。模型以一种特殊的高效可移植格式表示,其文件扩展名为 `.tflite`。 - -🤗 Optimum 通过 `exporters.tflite` 模块提供将 🤗 Transformers 模型导出至 TFLite 格式的功能。请参考 [🤗 Optimum 文档](https://huggingface.co/docs/optimum/exporters/tflite/overview) 以获取支持的模型架构列表。 - -要将模型导出为 TFLite 格式,请安装所需的依赖项: - -```bash -pip install optimum[exporters-tf] -``` - -请参阅 [🤗 Optimum 文档](https://huggingface.co/docs/optimum/main/en/exporters/tflite/usage_guides/export_a_model) 以查看所有可用参数,或者在命令行中查看帮助: - -```bash -optimum-cli export tflite --help -``` - -运行以下命令,以从 🤗 Hub 导出模型的检查点(checkpoint),以 `google-bert/bert-base-uncased` 为例: - -```bash -optimum-cli export tflite --model google-bert/bert-base-uncased --sequence_length 128 bert_tflite/ -``` - -你应该能在日志中看到导出进度以及生成的 `model.tflite` 文件的保存位置,如下所示: - -```bash -Validating TFLite model... - -[✓] TFLite model output names match reference model (logits) - - Validating TFLite Model output "logits": - -[✓] (1, 128, 30522) matches (1, 128, 30522) - -[x] values not close enough, max diff: 5.817413330078125e-05 (atol: 1e-05) -The TensorFlow Lite export succeeded with the warning: The maximum absolute difference between the output of the reference model and the TFLite exported model is not within the set tolerance 1e-05: -- logits: max diff = 5.817413330078125e-05. - The exported model was saved at: bert_tflite -``` - -上面的示例说明了从 🤗 Hub 导出检查点的过程。导出本地模型时,首先需要确保将模型的权重和分词器文件保存在同一目录(`local_path`)中。在使用 CLI(命令行)时,将 `local_path` 传递给 `model` 参数,而不是 🤗 Hub 上的检查点名称。 \ No newline at end of file diff --git a/examples/legacy/multiple_choice/utils_multiple_choice.py b/examples/legacy/multiple_choice/utils_multiple_choice.py index cc07ffb2ef27..64d3604f9ca4 100644 --- a/examples/legacy/multiple_choice/utils_multiple_choice.py +++ b/examples/legacy/multiple_choice/utils_multiple_choice.py @@ -26,7 +26,7 @@ import tqdm from filelock import FileLock -from transformers import PreTrainedTokenizer, is_tf_available, is_torch_available +from transformers import PreTrainedTokenizer, is_torch_available logger = logging.getLogger(__name__) @@ -78,11 +78,6 @@ class Split(Enum): from torch.utils.data import Dataset class MultipleChoiceDataset(Dataset): - """ - This will be superseded by a framework-agnostic approach - soon. - """ - features: list[InputFeatures] def __init__( @@ -139,94 +134,6 @@ def __getitem__(self, i) -> InputFeatures: return self.features[i] -if is_tf_available(): - import tensorflow as tf - - class TFMultipleChoiceDataset: - """ - This will be superseded by a framework-agnostic approach - soon. - """ - - features: list[InputFeatures] - - def __init__( - self, - data_dir: str, - tokenizer: PreTrainedTokenizer, - task: str, - max_seq_length: Optional[int] = 128, - overwrite_cache=False, - mode: Split = Split.train, - ): - processor = processors[task]() - - logger.info(f"Creating features from dataset file at {data_dir}") - label_list = processor.get_labels() - if mode == Split.dev: - examples = processor.get_dev_examples(data_dir) - elif mode == Split.test: - examples = processor.get_test_examples(data_dir) - else: - examples = processor.get_train_examples(data_dir) - logger.info("Training examples: %s", len(examples)) - - self.features = convert_examples_to_features( - examples, - label_list, - max_seq_length, - tokenizer, - ) - - def gen(): - for ex_index, ex in tqdm.tqdm(enumerate(self.features), desc="convert examples to features"): - if ex_index % 10000 == 0: - logger.info("Writing example %d of %d" % (ex_index, len(examples))) - - yield ( - { - "example_id": 0, - "input_ids": ex.input_ids, - "attention_mask": ex.attention_mask, - "token_type_ids": ex.token_type_ids, - }, - ex.label, - ) - - self.dataset = tf.data.Dataset.from_generator( - gen, - ( - { - "example_id": tf.int32, - "input_ids": tf.int32, - "attention_mask": tf.int32, - "token_type_ids": tf.int32, - }, - tf.int64, - ), - ( - { - "example_id": tf.TensorShape([]), - "input_ids": tf.TensorShape([None, None]), - "attention_mask": tf.TensorShape([None, None]), - "token_type_ids": tf.TensorShape([None, None]), - }, - tf.TensorShape([]), - ), - ) - - def get_dataset(self): - self.dataset = self.dataset.apply(tf.data.experimental.assert_cardinality(len(self.features))) - - return self.dataset - - def __len__(self): - return len(self.features) - - def __getitem__(self, i) -> InputFeatures: - return self.features[i] - - class DataProcessor: """Base class for data converters for multiple choice data sets.""" diff --git a/examples/legacy/token-classification/utils_ner.py b/examples/legacy/token-classification/utils_ner.py index 0c1725b59b4e..bfd792a250c3 100644 --- a/examples/legacy/token-classification/utils_ner.py +++ b/examples/legacy/token-classification/utils_ner.py @@ -22,7 +22,7 @@ from filelock import FileLock -from transformers import PreTrainedTokenizer, is_tf_available, is_torch_available +from transformers import PreTrainedTokenizer, is_torch_available logger = logging.getLogger(__name__) @@ -208,11 +208,6 @@ def convert_examples_to_features( from torch.utils.data import Dataset class TokenClassificationDataset(Dataset): - """ - This will be superseded by a framework-agnostic approach - soon. - """ - features: list[InputFeatures] pad_token_label_id: int = nn.CrossEntropyLoss().ignore_index # Use cross entropy ignore_index as padding label id so that only @@ -271,100 +266,3 @@ def __len__(self): def __getitem__(self, i) -> InputFeatures: return self.features[i] - - -if is_tf_available(): - import tensorflow as tf - - class TFTokenClassificationDataset: - """ - This will be superseded by a framework-agnostic approach - soon. - """ - - features: list[InputFeatures] - pad_token_label_id: int = -100 - # Use cross entropy ignore_index as padding label id so that only - # real label ids contribute to the loss later. - - def __init__( - self, - token_classification_task: TokenClassificationTask, - data_dir: str, - tokenizer: PreTrainedTokenizer, - labels: list[str], - model_type: str, - max_seq_length: Optional[int] = None, - overwrite_cache=False, - mode: Split = Split.train, - ): - examples = token_classification_task.read_examples_from_file(data_dir, mode) - # TODO clean up all this to leverage built-in features of tokenizers - self.features = token_classification_task.convert_examples_to_features( - examples, - labels, - max_seq_length, - tokenizer, - cls_token_at_end=bool(model_type in ["xlnet"]), - # xlnet has a cls token at the end - cls_token=tokenizer.cls_token, - cls_token_segment_id=2 if model_type in ["xlnet"] else 0, - sep_token=tokenizer.sep_token, - sep_token_extra=False, - # roberta uses an extra separator b/w pairs of sentences, cf. github.com/pytorch/fairseq/commit/1684e166e3da03f5b600dbb7855cb98ddfcd0805 - pad_on_left=bool(tokenizer.padding_side == "left"), - pad_token=tokenizer.pad_token_id, - pad_token_segment_id=tokenizer.pad_token_type_id, - pad_token_label_id=self.pad_token_label_id, - ) - - def gen(): - for ex in self.features: - if ex.token_type_ids is None: - yield ( - {"input_ids": ex.input_ids, "attention_mask": ex.attention_mask}, - ex.label_ids, - ) - else: - yield ( - { - "input_ids": ex.input_ids, - "attention_mask": ex.attention_mask, - "token_type_ids": ex.token_type_ids, - }, - ex.label_ids, - ) - - if "token_type_ids" not in tokenizer.model_input_names: - self.dataset = tf.data.Dataset.from_generator( - gen, - ({"input_ids": tf.int32, "attention_mask": tf.int32}, tf.int64), - ( - {"input_ids": tf.TensorShape([None]), "attention_mask": tf.TensorShape([None])}, - tf.TensorShape([None]), - ), - ) - else: - self.dataset = tf.data.Dataset.from_generator( - gen, - ({"input_ids": tf.int32, "attention_mask": tf.int32, "token_type_ids": tf.int32}, tf.int64), - ( - { - "input_ids": tf.TensorShape([None]), - "attention_mask": tf.TensorShape([None]), - "token_type_ids": tf.TensorShape([None]), - }, - tf.TensorShape([None]), - ), - ) - - def get_dataset(self): - self.dataset = self.dataset.apply(tf.data.experimental.assert_cardinality(len(self.features))) - - return self.dataset - - def __len__(self): - return len(self.features) - - def __getitem__(self, i) -> InputFeatures: - return self.features[i] diff --git a/examples/modular-transformers/image_processing_new_imgproc_model.py b/examples/modular-transformers/image_processing_new_imgproc_model.py index 4614c8cdaa52..cd521a0f606d 100644 --- a/examples/modular-transformers/image_processing_new_imgproc_model.py +++ b/examples/modular-transformers/image_processing_new_imgproc_model.py @@ -152,7 +152,7 @@ def preprocess( images: ImageInput, do_resize: Optional[bool] = None, size: Optional[dict[str, int]] = None, - resample: PILImageResampling = None, + resample: Optional[PILImageResampling] = None, do_rescale: Optional[bool] = None, rescale_factor: Optional[float] = None, do_normalize: Optional[bool] = None, @@ -194,10 +194,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -221,13 +219,11 @@ def preprocess( size = size if size is not None else self.size size = get_size_dict(size, default_to_square=False) + images = self.fetch_images(images) images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/examples/modular-transformers/modeling_dummy_bert.py b/examples/modular-transformers/modeling_dummy_bert.py index b490ba96f6cd..9df092f73e6e 100644 --- a/examples/modular-transformers/modeling_dummy_bert.py +++ b/examples/modular-transformers/modeling_dummy_bert.py @@ -5,11 +5,9 @@ # modular_dummy_bert.py file directly. One of our CI enforces this. # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 import math -import os from typing import Optional, Union import torch -from packaging import version from torch import nn from ...activations import ACT2FN @@ -19,7 +17,7 @@ from ...modeling_outputs import BaseModelOutputWithPastAndCrossAttentions, BaseModelOutputWithPoolingAndCrossAttentions from ...modeling_utils import PreTrainedModel from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, get_torch_version, logging +from ...utils import auto_docstring, logging from ...utils.deprecation import deprecate_kwarg from .configuration_dummy_bert import DummyBertConfig @@ -36,8 +34,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -228,7 +224,6 @@ class DummyBertSdpaSelfAttention(DummyBertSelfAttention): def __init__(self, config, position_embedding_type=None, layer_idx=None): super().__init__(config, position_embedding_type=position_embedding_type, layer_idx=layer_idx) self.dropout_prob = config.attention_probs_dropout_prob - self.require_contiguous_qkv = version.parse(get_torch_version()) < version.parse("2.2.0") # Adapted from DummyBertSelfAttention @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") @@ -308,14 +303,6 @@ def forward( if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): past_key_values.is_updated[self.layer_idx] = True - # SDPA with memory-efficient backend is broken in torch==2.1.2 when using non-contiguous inputs and a custom - # attn_mask, so we need to call `.contiguous()` here. This was fixed in torch==2.2.0. - # Reference: https://github.com/pytorch/pytorch/issues/112577 - if self.require_contiguous_qkv and query_layer.device.type == "cuda" and attention_mask is not None: - query_layer = query_layer.contiguous() - key_layer = key_layer.contiguous() - value_layer = value_layer.contiguous() - # We dispatch to SDPA's Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment # in SDPA to support both torch.compile's dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling. # The tgt_len > 1 is necessary to match with AttentionMaskConverter.to_causal_4d that does not create @@ -655,83 +642,9 @@ def forward(self, hidden_states): return hidden_states -def load_tf_weights_in_dummy_bert(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except ValueError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - @auto_docstring class DummyBertPreTrainedModel(PreTrainedModel): config: DummyBertConfig - load_tf_weights = load_tf_weights_in_dummy_bert base_model_prefix = "dummy_bert" supports_gradient_checkpointing = True _supports_sdpa = True @@ -739,8 +652,6 @@ class DummyBertPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/examples/modular-transformers/modeling_from_uppercase_model.py b/examples/modular-transformers/modeling_from_uppercase_model.py index 393ca6f5a137..6c7a0c776a8d 100644 --- a/examples/modular-transformers/modeling_from_uppercase_model.py +++ b/examples/modular-transformers/modeling_from_uppercase_model.py @@ -12,13 +12,9 @@ from ...activations import ACT2FN from ...modeling_layers import GradientCheckpointingLayer from ...modeling_utils import ALL_ATTENTION_FUNCTIONS -from ...utils import logging from .configuration_from_uppercase_model import FromUppercaseModelTextConfig, FromUppercaseModelVisionConfig -logger = logging.get_logger(__name__) - - def eager_attention_forward( module: nn.Module, query: torch.Tensor, @@ -96,13 +92,7 @@ def forward( attention_interface: Callable = eager_attention_forward if self.config._attn_implementation != "eager": - if self.config._attn_implementation == "sdpa" and output_attentions: - logger.warning_once( - "`torch.nn.functional.scaled_dot_product_attention` does not support `output_attentions=True`. Falling back to " - 'eager attention. This warning can be removed using the argument `attn_implementation="eager"` when loading the model.' - ) - else: - attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] attn_output, attn_weights = attention_interface( self, diff --git a/examples/modular-transformers/modeling_multimodal2.py b/examples/modular-transformers/modeling_multimodal2.py index bb011ee126b0..44b591fafad2 100644 --- a/examples/modular-transformers/modeling_multimodal2.py +++ b/examples/modular-transformers/modeling_multimodal2.py @@ -16,13 +16,10 @@ from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel -from ...utils import auto_docstring, can_return_tuple, logging, torch_int +from ...utils import auto_docstring, can_return_tuple, torch_int from .configuration_multimodal2 import Multimodal2Config, Multimodal2TextConfig, Multimodal2VisionConfig -logger = logging.get_logger(__name__) - - def eager_attention_forward( module: nn.Module, query: torch.Tensor, @@ -100,13 +97,7 @@ def forward( attention_interface: Callable = eager_attention_forward if self.config._attn_implementation != "eager": - if self.config._attn_implementation == "sdpa" and output_attentions: - logger.warning_once( - "`torch.nn.functional.scaled_dot_product_attention` does not support `output_attentions=True`. Falling back to " - 'eager attention. This warning can be removed using the argument `attn_implementation="eager"` when loading the model.' - ) - else: - attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] attn_output, attn_weights = attention_interface( self, @@ -196,13 +187,7 @@ def forward( attention_interface: Callable = eager_attention_forward if self.config._attn_implementation != "eager": - if self.config._attn_implementation == "sdpa" and output_attentions: - logger.warning_once( - "`torch.nn.functional.scaled_dot_product_attention` does not support `output_attentions=True`. Falling back to " - 'eager attention. This warning can be removed using the argument `attn_implementation="eager"` when loading the model.' - ) - else: - attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] attn_output, attn_weights = attention_interface( self, diff --git a/examples/modular-transformers/modeling_my_new_model2.py b/examples/modular-transformers/modeling_my_new_model2.py index 4c1c8b0c0cb6..27593bddf50e 100644 --- a/examples/modular-transformers/modeling_my_new_model2.py +++ b/examples/modular-transformers/modeling_my_new_model2.py @@ -220,7 +220,7 @@ def forward( cache_position: Optional[torch.LongTensor] = None, position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, # necessary, but kept here for BC **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor]: + ) -> torch.Tensor: residual = hidden_states hidden_states = self.input_layernorm(hidden_states) # Self Attention diff --git a/examples/modular-transformers/modeling_new_task_model.py b/examples/modular-transformers/modeling_new_task_model.py index b1ca97b5fb74..13ef7e08271f 100644 --- a/examples/modular-transformers/modeling_new_task_model.py +++ b/examples/modular-transformers/modeling_new_task_model.py @@ -10,7 +10,7 @@ import torch from torch import nn -from ...cache_utils import Cache, HybridCache, StaticCache +from ...cache_utils import Cache, StaticCache from ...generation import GenerationMixin from ...modeling_flash_attention_utils import FlashAttentionKwargs from ...modeling_outputs import BaseModelOutputWithPast @@ -93,7 +93,7 @@ class NewTaskModelPreTrainedModel(PreTrainedModel): _no_split_modules = ["NewTaskModelMultiModalProjector"] _skip_keys_device_placement = "past_key_values" - _can_compile_fullgraph = True + _can_compile_fullgraph = False _supports_flash_attn = True _supports_sdpa = True _supports_flex_attn = True @@ -166,8 +166,6 @@ def _update_causal_mask( inputs_lead_dim, sequence_length = input_tensor.shape[:2] if using_static_cache: target_length = past_key_values.get_max_cache_shape() - elif isinstance(past_key_values, HybridCache): - target_length = past_key_values.get_max_cache_shape() else: target_length = ( attention_mask.shape[-1] @@ -256,8 +254,8 @@ def get_placeholder_mask( @auto_docstring def forward( self, - input_ids: torch.LongTensor = None, - pixel_values: torch.FloatTensor = None, + input_ids: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, @@ -505,7 +503,8 @@ def prepare_inputs_for_generation( if cache_position[0] == 0: model_inputs["pixel_values"] = pixel_values is_training = token_type_ids is not None and labels is not None - if cache_position[0] == 0 and isinstance(past_key_values, HybridCache): + is_static_hybrid_cache = isinstance(past_key_values, StaticCache) and any(past_key_values.is_sliding) + if cache_position[0] == 0 and is_static_hybrid_cache: input_tensor = inputs_embeds if inputs_embeds is not None else input_ids causal_mask = self.model._update_causal_mask( attention_mask, token_type_ids, past_key_values, cache_position, input_tensor, is_training diff --git a/examples/modular-transformers/modeling_roberta.py b/examples/modular-transformers/modeling_roberta.py index dfa8fefea6ab..2ae39a555892 100644 --- a/examples/modular-transformers/modeling_roberta.py +++ b/examples/modular-transformers/modeling_roberta.py @@ -5,12 +5,10 @@ # modular_roberta.py file directly. One of our CI enforces this. # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 import math -import os from typing import Optional, Union import torch import torch.nn as nn -from packaging import version from ...activations import ACT2FN from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache @@ -19,7 +17,7 @@ from ...modeling_outputs import BaseModelOutputWithPastAndCrossAttentions, BaseModelOutputWithPoolingAndCrossAttentions from ...modeling_utils import PreTrainedModel from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, get_torch_version, logging +from ...utils import auto_docstring, logging from ...utils.deprecation import deprecate_kwarg from .configuration_roberta import RobertaConfig @@ -38,8 +36,6 @@ def __init__(self, config): ) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -231,7 +227,6 @@ class RobertaSdpaSelfAttention(RobertaSelfAttention): def __init__(self, config, position_embedding_type=None, layer_idx=None): super().__init__(config, position_embedding_type=position_embedding_type, layer_idx=layer_idx) self.dropout_prob = config.attention_probs_dropout_prob - self.require_contiguous_qkv = version.parse(get_torch_version()) < version.parse("2.2.0") # Adapted from RobertaSelfAttention @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") @@ -311,14 +306,6 @@ def forward( if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): past_key_values.is_updated[self.layer_idx] = True - # SDPA with memory-efficient backend is broken in torch==2.1.2 when using non-contiguous inputs and a custom - # attn_mask, so we need to call `.contiguous()` here. This was fixed in torch==2.2.0. - # Reference: https://github.com/pytorch/pytorch/issues/112577 - if self.require_contiguous_qkv and query_layer.device.type == "cuda" and attention_mask is not None: - query_layer = query_layer.contiguous() - key_layer = key_layer.contiguous() - value_layer = value_layer.contiguous() - # We dispatch to SDPA's Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment # in SDPA to support both torch.compile's dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling. # The tgt_len > 1 is necessary to match with AttentionMaskConverter.to_causal_4d that does not create @@ -658,83 +645,9 @@ def forward(self, hidden_states): return hidden_states -def load_tf_weights_in_roberta(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except ValueError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - @auto_docstring class RobertaPreTrainedModel(PreTrainedModel): config: RobertaConfig - load_tf_weights = load_tf_weights_in_roberta base_model_prefix = "roberta" supports_gradient_checkpointing = True _supports_sdpa = True @@ -742,8 +655,6 @@ class RobertaPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/examples/modular-transformers/modeling_super.py b/examples/modular-transformers/modeling_super.py index 6927dab86dc1..9215730ed036 100644 --- a/examples/modular-transformers/modeling_super.py +++ b/examples/modular-transformers/modeling_super.py @@ -46,6 +46,8 @@ def extra_repr(self): class SuperRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + def __init__(self, config: SuperConfig, device=None): super().__init__() # BC: "rope_type" was originally "type" @@ -260,7 +262,7 @@ def forward( cache_position: Optional[torch.LongTensor] = None, position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, # necessary, but kept here for BC **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor]: + ) -> torch.Tensor: residual = hidden_states hidden_states = self.input_layernorm(hidden_states) # Self Attention diff --git a/examples/modular-transformers/modeling_test_detr.py b/examples/modular-transformers/modeling_test_detr.py index 11e6719479a4..3ff225c0b3ff 100644 --- a/examples/modular-transformers/modeling_test_detr.py +++ b/examples/modular-transformers/modeling_test_detr.py @@ -846,8 +846,6 @@ def _init_weights(self, module): nn.init.xavier_uniform_(module.output_proj.weight.data) nn.init.constant_(module.output_proj.bias.data, 0.0) elif isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/examples/pytorch/question-answering/utils_qa.py b/examples/pytorch/question-answering/utils_qa.py index b30322b0071f..477e193cbe7b 100644 --- a/examples/pytorch/question-answering/utils_qa.py +++ b/examples/pytorch/question-answering/utils_qa.py @@ -185,7 +185,7 @@ def postprocess_qa_predictions( if len(predictions) == 0 or (len(predictions) == 1 and predictions[0]["text"] == ""): predictions.insert(0, {"text": "empty", "start_logit": 0.0, "end_logit": 0.0, "score": 0.0}) - # Compute the softmax of all scores (we do it with numpy to stay independent from torch/tf in this file, using + # Compute the softmax of all scores (we do it with numpy to stay independent from torch in this file, using # the LogSumExp trick). scores = np.array([pred.pop("score") for pred in predictions]) exp_scores = np.exp(scores - np.max(scores)) @@ -392,7 +392,7 @@ def postprocess_qa_predictions_with_beam_search( min_null_score = -2e-6 predictions.insert(0, {"text": "", "start_logit": -1e-6, "end_logit": -1e-6, "score": min_null_score}) - # Compute the softmax of all scores (we do it with numpy to stay independent from torch/tf in this file, using + # Compute the softmax of all scores (we do it with numpy to stay independent from torch in this file, using # the LogSumExp trick). scores = np.array([pred.pop("score") for pred in predictions]) exp_scores = np.exp(scores - np.max(scores)) diff --git a/setup.py b/setup.py index 9f3bb1750597..d6e69d3b83c5 100644 --- a/setup.py +++ b/setup.py @@ -109,7 +109,6 @@ "faiss-cpu", "fastapi", "filelock", - "flax>=0.4.1,<=0.7.0", "ftfy", "fugashi>=1.0", "GitPython<3.1.19", @@ -118,13 +117,8 @@ "huggingface-hub>=0.34.0,<1.0", "importlib_metadata", "ipadic>=1.0.0,<2.0", - "jax>=0.4.1,<=0.4.13", - "jaxlib>=0.4.1,<=0.4.13", "jinja2>=3.1.0", "kenlm", - # Keras pin - this is to make sure Keras 3 doesn't destroy us. Remove or change when we have proper support. - "keras>2.9,<2.16", - "keras-nlp>=0.3.1,<0.14.0", # keras-nlp 0.14 doesn't support keras 2, see pin on keras. "kernels>=0.6.1,<=0.9", "librosa", "natten>=0.14.6,<0.15.0", @@ -170,19 +164,13 @@ "sagemaker>=2.31.0", "schedulefree>=1.2.6", "scikit-learn", - "scipy<1.13.0", # SciPy >= 1.13.0 is not supported with the current jax pin (`jax>=0.4.1,<=0.4.13`) + "scipy", "sentencepiece>=0.1.91,!=0.1.92", "sigopt", "starlette", "sudachipy>=0.6.6", "sudachidict_core>=20220729", "tensorboard", - # TensorFlow pin. When changing this value, update examples/tensorflow/_tests_requirements.txt accordingly - "tensorflow-cpu>2.9,<2.16", - "tensorflow>2.9,<2.16", - "tensorflow-text<2.16", - "tensorflow-probability<0.24", - "tf2onnx", "timeout-decorator", "tiktoken", "timm<=1.0.19,!=1.0.18", @@ -273,32 +261,19 @@ def run(self): extras["ja"] = deps_list("fugashi", "ipadic", "unidic_lite", "unidic", "sudachipy", "sudachidict_core", "rhoknp") extras["sklearn"] = deps_list("scikit-learn") -extras["tf"] = deps_list("tensorflow", "onnxconverter-common", "tf2onnx", "tensorflow-text", "keras-nlp") -extras["tf-cpu"] = deps_list( - "keras", - "tensorflow-cpu", - "onnxconverter-common", - "tf2onnx", - "tensorflow-text", - "keras-nlp", - "tensorflow-probability", -) - extras["torch"] = deps_list("torch", "accelerate") extras["accelerate"] = deps_list("accelerate") extras["hf_xet"] = deps_list("hf_xet") if os.name == "nt": # windows extras["retrieval"] = deps_list("datasets") # faiss is not supported on windows - extras["flax"] = [] # jax is not supported on windows else: extras["retrieval"] = deps_list("faiss-cpu", "datasets") - extras["flax"] = deps_list("jax", "jaxlib", "flax", "optax", "scipy") extras["tokenizers"] = deps_list("tokenizers") extras["ftfy"] = deps_list("ftfy") extras["onnxruntime"] = deps_list("onnxruntime", "onnxruntime-tools") -extras["onnx"] = deps_list("onnxconverter-common", "tf2onnx") + extras["onnxruntime"] +extras["onnx"] = deps_list("onnxconverter-common") + extras["onnxruntime"] extras["modelcreation"] = deps_list("cookiecutter") extras["sagemaker"] = deps_list("sagemaker") @@ -320,8 +295,6 @@ def run(self): # `pip install ".[speech]"` is deprecated and `pip install ".[torch-speech]"` should be used instead extras["speech"] = deps_list("torchaudio") + extras["audio"] extras["torch-speech"] = deps_list("torchaudio") + extras["audio"] -extras["tf-speech"] = extras["audio"] -extras["flax-speech"] = extras["audio"] extras["vision"] = deps_list("Pillow") extras["timm"] = deps_list("timm") extras["torch-vision"] = deps_list("torchvision") + extras["vision"] @@ -372,9 +345,7 @@ def run(self): extras["quality"] = deps_list("datasets", "ruff", "GitPython", "urllib3", "libcst", "rich", "pandas") extras["all"] = ( - extras["tf"] - + extras["torch"] - + extras["flax"] + extras["torch"] + extras["sentencepiece"] + extras["tokenizers"] + extras["torch-speech"] @@ -409,18 +380,7 @@ def run(self): + extras["onnxruntime"] + extras["num2words"] ) -extras["dev-tensorflow"] = ( - extras["testing"] - + extras["tf"] - + extras["sentencepiece"] - + extras["tokenizers"] - + extras["vision"] - + extras["quality"] - + extras["sklearn"] - + extras["modelcreation"] - + extras["onnx"] - + extras["tf-speech"] -) + extras["dev"] = ( extras["all"] + extras["testing"] + extras["quality"] + extras["ja"] + extras["sklearn"] + extras["modelcreation"] ) @@ -464,10 +424,10 @@ def run(self): version="4.57.0.dev0", # expected format is one of x.y.z.dev0, or x.y.z.rc1 or x.y.z (no to dashes, yes to dots) author="The Hugging Face team (past and future) with the help of all our contributors (https://github.com/huggingface/transformers/graphs/contributors)", author_email="transformers@huggingface.co", - description="State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow", + description="Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.", long_description=open("README.md", "r", encoding="utf-8").read(), long_description_content_type="text/markdown", - keywords="NLP vision speech deep learning transformer pytorch tensorflow jax BERT GPT-2 Wav2Vec2 ViT", + keywords="machine-learning nlp python pytorch transformer llm vlm deep-learning inference training model-hub pretrained-models llama gemma qwen", license="Apache 2.0 License", url="https://github.com/huggingface/transformers", package_dir={"": "src"}, @@ -503,14 +463,10 @@ def run(self): ) extras["tests_torch"] = deps_list() -extras["tests_tf"] = deps_list() -extras["tests_flax"] = deps_list() extras["tests_hub"] = deps_list() extras["tests_pipelines_torch"] = deps_list() -extras["tests_pipelines_tf"] = deps_list() extras["tests_onnx"] = deps_list() extras["tests_examples_torch"] = deps_list() -extras["tests_examples_tf"] = deps_list() extras["tests_custom_tokenizers"] = deps_list() extras["tests_exotic_models"] = deps_list() extras["consistency"] = deps_list() diff --git a/src/transformers/__init__.py b/src/transformers/__init__.py index d6399aa8d094..988938558650 100755 --- a/src/transformers/__init__.py +++ b/src/transformers/__init__.py @@ -40,13 +40,9 @@ # so that mypy, pylint or other static linters can recognize them, # given that they are not exported using `__all__` in this file. from .utils import is_bitsandbytes_available as is_bitsandbytes_available -from .utils import is_flax_available as is_flax_available -from .utils import is_keras_nlp_available as is_keras_nlp_available from .utils import is_scipy_available as is_scipy_available from .utils import is_sentencepiece_available as is_sentencepiece_available from .utils import is_speech_available as is_speech_available -from .utils import is_tensorflow_text_available as is_tensorflow_text_available -from .utils import is_tf_available as is_tf_available from .utils import is_timm_available as is_timm_available from .utils import is_tokenizers_available as is_tokenizers_available from .utils import is_torch_available as is_torch_available @@ -64,9 +60,7 @@ "audio_utils": [], "commands": [], "configuration_utils": ["PretrainedConfig"], - "convert_graph_to_onnx": [], "convert_slow_tokenizers_checkpoints_to_fast": [], - "convert_tf_hub_seq_to_seq_bert_to_pytorch": [], "data": [ "DataProcessor", "InputExample", @@ -137,16 +131,6 @@ ], "loss": [], "modelcard": ["ModelCard"], - # Losses - "modeling_tf_pytorch_utils": [ - "convert_tf_weight_name_to_pt_weight_name", - "load_pytorch_checkpoint_in_tf2_model", - "load_pytorch_model_in_tf2_model", - "load_pytorch_weights_in_tf2_model", - "load_tf2_checkpoint_in_pytorch_model", - "load_tf2_model_in_pytorch_model", - "load_tf2_weights_in_pytorch_model", - ], # Models "onnx": [], "pipelines": [ @@ -218,15 +202,12 @@ ], "training_args": ["TrainingArguments"], "training_args_seq2seq": ["Seq2SeqTrainingArguments"], - "training_args_tf": ["TFTrainingArguments"], "utils": [ "CONFIG_NAME", "MODEL_CARD_NAME", "PYTORCH_PRETRAINED_BERT_CACHE", "PYTORCH_TRANSFORMERS_CACHE", "SPIECE_UNDERLINE", - "TF2_WEIGHTS_NAME", - "TF_WEIGHTS_NAME", "TRANSFORMERS_CACHE", "WEIGHTS_NAME", "TensorType", @@ -237,8 +218,6 @@ "is_bitsandbytes_available", "is_datasets_available", "is_faiss_available", - "is_flax_available", - "is_keras_nlp_available", "is_matplotlib_available", "is_mlx_available", "is_phonemizer_available", @@ -251,8 +230,6 @@ "is_sentencepiece_available", "is_sklearn_available", "is_speech_available", - "is_tensorflow_text_available", - "is_tf_available", "is_timm_available", "is_tokenizers_available", "is_torch_available", @@ -502,84 +479,6 @@ _import_structure["trainer_pt_utils"] = ["torch_distributed_zero_first"] _import_structure["trainer_seq2seq"] = ["Seq2SeqTrainer"] -# TensorFlow-backed objects -try: - if not is_tf_available(): - raise OptionalDependencyNotAvailable() -except OptionalDependencyNotAvailable: - from .utils import dummy_tf_objects - - _import_structure["utils.dummy_tf_objects"] = [name for name in dir(dummy_tf_objects) if not name.startswith("_")] -else: - _import_structure["activations_tf"] = [] - _import_structure["generation"].extend( - [ - "TFForcedBOSTokenLogitsProcessor", - "TFForcedEOSTokenLogitsProcessor", - "TFForceTokensLogitsProcessor", - "TFGenerationMixin", - "TFLogitsProcessor", - "TFLogitsProcessorList", - "TFLogitsWarper", - "TFMinLengthLogitsProcessor", - "TFNoBadWordsLogitsProcessor", - "TFNoRepeatNGramLogitsProcessor", - "TFRepetitionPenaltyLogitsProcessor", - "TFSuppressTokensAtBeginLogitsProcessor", - "TFSuppressTokensLogitsProcessor", - "TFTemperatureLogitsWarper", - "TFTopKLogitsWarper", - "TFTopPLogitsWarper", - ] - ) - _import_structure["keras_callbacks"] = ["KerasMetricCallback", "PushToHubCallback"] - _import_structure["modeling_tf_outputs"] = [] - _import_structure["modeling_tf_utils"] = [ - "TFPreTrainedModel", - "TFSequenceSummary", - "TFSharedEmbeddings", - "shape_list", - ] - _import_structure["optimization_tf"] = [ - "AdamWeightDecay", - "GradientAccumulator", - "WarmUp", - "create_optimizer", - ] - _import_structure["tf_utils"] = [] - - -# FLAX-backed objects -try: - if not is_flax_available(): - raise OptionalDependencyNotAvailable() -except OptionalDependencyNotAvailable: - from .utils import dummy_flax_objects - - _import_structure["utils.dummy_flax_objects"] = [ - name for name in dir(dummy_flax_objects) if not name.startswith("_") - ] -else: - _import_structure["generation"].extend( - [ - "FlaxForcedBOSTokenLogitsProcessor", - "FlaxForcedEOSTokenLogitsProcessor", - "FlaxForceTokensLogitsProcessor", - "FlaxGenerationMixin", - "FlaxLogitsProcessor", - "FlaxLogitsProcessorList", - "FlaxLogitsWarper", - "FlaxMinLengthLogitsProcessor", - "FlaxTemperatureLogitsWarper", - "FlaxSuppressTokensAtBeginLogitsProcessor", - "FlaxSuppressTokensLogitsProcessor", - "FlaxTopKLogitsWarper", - "FlaxTopPLogitsWarper", - "FlaxWhisperTimeStampLogitsProcessor", - ] - ) - _import_structure["modeling_flax_outputs"] = [] - _import_structure["modeling_flax_utils"] = ["FlaxPreTrainedModel"] # Direct imports for type-checking if TYPE_CHECKING: @@ -673,20 +572,6 @@ from .generation import EpsilonLogitsWarper as EpsilonLogitsWarper from .generation import EtaLogitsWarper as EtaLogitsWarper from .generation import ExponentialDecayLengthPenalty as ExponentialDecayLengthPenalty - from .generation import FlaxForcedBOSTokenLogitsProcessor as FlaxForcedBOSTokenLogitsProcessor - from .generation import FlaxForcedEOSTokenLogitsProcessor as FlaxForcedEOSTokenLogitsProcessor - from .generation import FlaxForceTokensLogitsProcessor as FlaxForceTokensLogitsProcessor - from .generation import FlaxGenerationMixin as FlaxGenerationMixin - from .generation import FlaxLogitsProcessor as FlaxLogitsProcessor - from .generation import FlaxLogitsProcessorList as FlaxLogitsProcessorList - from .generation import FlaxLogitsWarper as FlaxLogitsWarper - from .generation import FlaxMinLengthLogitsProcessor as FlaxMinLengthLogitsProcessor - from .generation import FlaxSuppressTokensAtBeginLogitsProcessor as FlaxSuppressTokensAtBeginLogitsProcessor - from .generation import FlaxSuppressTokensLogitsProcessor as FlaxSuppressTokensLogitsProcessor - from .generation import FlaxTemperatureLogitsWarper as FlaxTemperatureLogitsWarper - from .generation import FlaxTopKLogitsWarper as FlaxTopKLogitsWarper - from .generation import FlaxTopPLogitsWarper as FlaxTopPLogitsWarper - from .generation import FlaxWhisperTimeStampLogitsProcessor as FlaxWhisperTimeStampLogitsProcessor from .generation import ForcedBOSTokenLogitsProcessor as ForcedBOSTokenLogitsProcessor from .generation import ForcedEOSTokenLogitsProcessor as ForcedEOSTokenLogitsProcessor from .generation import GenerationConfig as GenerationConfig @@ -765,32 +650,14 @@ from .integrations import is_wandb_available as is_wandb_available from .integrations.executorch import TorchExportableModuleWithStaticCache as TorchExportableModuleWithStaticCache from .integrations.executorch import convert_and_export_with_cache as convert_and_export_with_cache - from .keras_callbacks import KerasMetricCallback as KerasMetricCallback - from .keras_callbacks import PushToHubCallback as PushToHubCallback from .masking_utils import AttentionMaskInterface as AttentionMaskInterface from .model_debugging_utils import model_addition_debugger_context as model_addition_debugger_context # Model Cards from .modelcard import ModelCard as ModelCard - from .modeling_flax_utils import FlaxPreTrainedModel as FlaxPreTrainedModel from .modeling_layers import GradientCheckpointingLayer as GradientCheckpointingLayer from .modeling_rope_utils import ROPE_INIT_FUNCTIONS as ROPE_INIT_FUNCTIONS from .modeling_rope_utils import dynamic_rope_update as dynamic_rope_update - - # TF 2.0 <=> PyTorch conversion utilities - from .modeling_tf_pytorch_utils import ( - convert_tf_weight_name_to_pt_weight_name as convert_tf_weight_name_to_pt_weight_name, - ) - from .modeling_tf_pytorch_utils import load_pytorch_checkpoint_in_tf2_model as load_pytorch_checkpoint_in_tf2_model - from .modeling_tf_pytorch_utils import load_pytorch_model_in_tf2_model as load_pytorch_model_in_tf2_model - from .modeling_tf_pytorch_utils import load_pytorch_weights_in_tf2_model as load_pytorch_weights_in_tf2_model - from .modeling_tf_pytorch_utils import load_tf2_checkpoint_in_pytorch_model as load_tf2_checkpoint_in_pytorch_model - from .modeling_tf_pytorch_utils import load_tf2_model_in_pytorch_model as load_tf2_model_in_pytorch_model - from .modeling_tf_pytorch_utils import load_tf2_weights_in_pytorch_model as load_tf2_weights_in_pytorch_model - from .modeling_tf_utils import TFPreTrainedModel as TFPreTrainedModel - from .modeling_tf_utils import TFSequenceSummary as TFSequenceSummary - from .modeling_tf_utils import TFSharedEmbeddings as TFSharedEmbeddings - from .modeling_tf_utils import shape_list as shape_list from .modeling_utils import AttentionInterface as AttentionInterface from .modeling_utils import PreTrainedModel as PreTrainedModel from .models import * @@ -817,12 +684,6 @@ from .optimization import get_scheduler as get_scheduler from .optimization import get_wsd_schedule as get_wsd_schedule - # Optimization - from .optimization_tf import AdamWeightDecay as AdamWeightDecay - from .optimization_tf import GradientAccumulator as GradientAccumulator - from .optimization_tf import WarmUp as WarmUp - from .optimization_tf import create_optimizer as create_optimizer - # Pipelines from .pipelines import AudioClassificationPipeline as AudioClassificationPipeline from .pipelines import AutomaticSpeechRecognitionPipeline as AutomaticSpeechRecognitionPipeline @@ -896,7 +757,6 @@ from .trainer_utils import set_seed as set_seed from .training_args import TrainingArguments as TrainingArguments from .training_args_seq2seq import Seq2SeqTrainingArguments as Seq2SeqTrainingArguments - from .training_args_tf import TFTrainingArguments as TFTrainingArguments # Files and general utilities from .utils import CONFIG_NAME as CONFIG_NAME @@ -904,8 +764,6 @@ from .utils import PYTORCH_PRETRAINED_BERT_CACHE as PYTORCH_PRETRAINED_BERT_CACHE from .utils import PYTORCH_TRANSFORMERS_CACHE as PYTORCH_TRANSFORMERS_CACHE from .utils import SPIECE_UNDERLINE as SPIECE_UNDERLINE - from .utils import TF2_WEIGHTS_NAME as TF2_WEIGHTS_NAME - from .utils import TF_WEIGHTS_NAME as TF_WEIGHTS_NAME from .utils import TRANSFORMERS_CACHE as TRANSFORMERS_CACHE from .utils import WEIGHTS_NAME as WEIGHTS_NAME from .utils import TensorType as TensorType @@ -970,9 +828,7 @@ ) -if not is_tf_available() and not is_torch_available() and not is_flax_available(): +if not is_torch_available(): logger.warning_advice( - "None of PyTorch, TensorFlow >= 2.0, or Flax have been found. " - "Models won't be available and only tokenizers, configuration " - "and file/data utilities can be used." + "PyTorch was not found. Models won't be available and only tokenizers, configuration and file/data utilities can be used." ) diff --git a/src/transformers/activations_tf.py b/src/transformers/activations_tf.py deleted file mode 100644 index 8dccf6c4f46b..000000000000 --- a/src/transformers/activations_tf.py +++ /dev/null @@ -1,147 +0,0 @@ -# Copyright 2020 The HuggingFace Team. All rights reserved. -# -# 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. - -import math - -import tensorflow as tf -from packaging.version import parse - - -try: - import tf_keras as keras -except (ModuleNotFoundError, ImportError): - import keras - - if parse(keras.__version__).major > 2: - raise ValueError( - "Your currently installed version of Keras is Keras 3, but this is not yet supported in " - "Transformers. Please install the backwards-compatible tf-keras package with " - "`pip install tf-keras`." - ) - - -def _gelu(x): - """ - Gaussian Error Linear Unit. Original Implementation of the gelu activation function in Google Bert repo when - initially created. For information: OpenAI GPT's gelu is slightly different (and gives slightly different results): - 0.5 * x * (1 + torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * torch.pow(x, 3)))) Also see - https://huggingface.co/papers/1606.08415 - """ - x = tf.convert_to_tensor(x) - cdf = 0.5 * (1.0 + tf.math.erf(x / tf.cast(tf.sqrt(2.0), x.dtype))) - - return x * cdf - - -def _gelu_new(x): - """ - Gaussian Error Linear Unit. This is a smoother version of the GELU. Original paper: https://huggingface.co/papers/1606.0841 - - Args: - x: float Tensor to perform activation - - Returns: - `x` with the GELU activation applied. - """ - x = tf.convert_to_tensor(x) - pi = tf.cast(math.pi, x.dtype) - coeff = tf.cast(0.044715, x.dtype) - cdf = 0.5 * (1.0 + tf.tanh(tf.sqrt(2.0 / pi) * (x + coeff * tf.pow(x, 3)))) - - return x * cdf - - -def mish(x): - x = tf.convert_to_tensor(x) - - return x * tf.tanh(tf.math.softplus(x)) - - -def gelu_fast(x): - x = tf.convert_to_tensor(x) - coeff1 = tf.cast(0.044715, x.dtype) - coeff2 = tf.cast(0.7978845608, x.dtype) - - return 0.5 * x * (1.0 + tf.tanh(x * coeff2 * (1.0 + coeff1 * x * x))) - - -def quick_gelu(x): - x = tf.convert_to_tensor(x) - coeff = tf.cast(1.702, x.dtype) - return x * tf.math.sigmoid(coeff * x) - - -def gelu_10(x): - """ - Clip the range of possible GeLU outputs between [-10, 10]. This is especially useful for quantization purpose, as - it allows mapping 2 negatives values in the GeLU spectrum. For more information on this trick, please refer to - https://huggingface.co/papers/2004.09602 - - Gaussian Error Linear Unit. Original Implementation of the gelu activation function in Google Bert repo when - initially created. For information: OpenAI GPT's gelu is slightly different (and gives slightly different results): - 0.5 * x * (1 + torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * torch.pow(x, 3)))) Also see - https://huggingface.co/papers/1606.08415 :param x: :return: - """ - return tf.clip_by_value(_gelu(x), -10, 10) - - -def glu(x, axis=-1): - """ - Gated Linear Unit. Implementation as defined in the original paper (see https://huggingface.co/papers/1612.08083), where - the input `x` is split in two halves across a dimension (`axis`), A and B, returning A * sigmoid(B). - - Args: - `x`: float Tensor to perform activation - `axis`: dimension across which `x` be split in half - - Returns: - `x` with the GLU activation applied (with its size halved across the dimension `axis`). - """ - a, b = tf.split(x, 2, axis=axis) - return a * tf.math.sigmoid(b) - - -if parse(tf.version.VERSION) >= parse("2.4"): - - def approximate_gelu_wrap(x): - return keras.activations.gelu(x, approximate=True) - - gelu = keras.activations.gelu - gelu_new = approximate_gelu_wrap -else: - gelu = _gelu - gelu_new = _gelu_new - - -ACT2FN = { - "gelu": gelu, - "gelu_10": gelu_10, - "gelu_fast": gelu_fast, - "gelu_new": gelu_new, - "glu": glu, - "mish": mish, - "quick_gelu": quick_gelu, - "relu": keras.activations.relu, - "sigmoid": keras.activations.sigmoid, - "silu": keras.activations.swish, - "swish": keras.activations.swish, - "tanh": keras.activations.tanh, -} - - -def get_tf_activation(activation_string): - if activation_string in ACT2FN: - return ACT2FN[activation_string] - else: - raise KeyError(f"function {activation_string} not found in ACT2FN mapping {list(ACT2FN.keys())}") diff --git a/src/transformers/commands/convert.py b/src/transformers/commands/convert.py deleted file mode 100644 index 220d1d44b1aa..000000000000 --- a/src/transformers/commands/convert.py +++ /dev/null @@ -1,165 +0,0 @@ -# Copyright 2020 The HuggingFace Team. All rights reserved. -# -# 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. - -from argparse import ArgumentParser, Namespace - -from ..utils import logging -from . import BaseTransformersCLICommand - - -def convert_command_factory(args: Namespace): - """ - Factory function used to convert a model TF 1.0 checkpoint in a PyTorch checkpoint. - - Returns: ServeCommand - """ - return ConvertCommand( - args.model_type, args.tf_checkpoint, args.pytorch_dump_output, args.config, args.finetuning_task_name - ) - - -IMPORT_ERROR_MESSAGE = """ -transformers can only be used from the commandline to convert TensorFlow models in PyTorch, In that case, it requires -TensorFlow to be installed. Please see https://www.tensorflow.org/install/ for installation instructions. -""" - - -class ConvertCommand(BaseTransformersCLICommand): - @staticmethod - def register_subcommand(parser: ArgumentParser): - """ - Register this command to argparse so it's available for the transformer-cli - - Args: - parser: Root parser to register command-specific arguments - """ - train_parser = parser.add_parser( - "convert", - help="CLI tool to run convert model from original author checkpoints to Transformers PyTorch checkpoints.", - ) - train_parser.add_argument("--model_type", type=str, required=True, help="Model's type.") - train_parser.add_argument( - "--tf_checkpoint", type=str, required=True, help="TensorFlow checkpoint path or folder." - ) - train_parser.add_argument( - "--pytorch_dump_output", type=str, required=True, help="Path to the PyTorch saved model output." - ) - train_parser.add_argument("--config", type=str, default="", help="Configuration file path or folder.") - train_parser.add_argument( - "--finetuning_task_name", - type=str, - default=None, - help="Optional fine-tuning task name if the TF model was a finetuned model.", - ) - train_parser.set_defaults(func=convert_command_factory) - - def __init__( - self, - model_type: str, - tf_checkpoint: str, - pytorch_dump_output: str, - config: str, - finetuning_task_name: str, - *args, - ): - self._logger = logging.get_logger("transformers/converting") - - self._logger.info(f"Loading model {model_type}") - self._model_type = model_type - self._tf_checkpoint = tf_checkpoint - self._pytorch_dump_output = pytorch_dump_output - self._config = config - self._finetuning_task_name = finetuning_task_name - - def run(self): - if self._model_type == "albert": - try: - from ..models.albert.convert_albert_original_tf_checkpoint_to_pytorch import ( - convert_tf_checkpoint_to_pytorch, - ) - except ImportError: - raise ImportError(IMPORT_ERROR_MESSAGE) - - convert_tf_checkpoint_to_pytorch(self._tf_checkpoint, self._config, self._pytorch_dump_output) - elif self._model_type == "bert": - try: - from ..models.bert.convert_bert_original_tf_checkpoint_to_pytorch import ( - convert_tf_checkpoint_to_pytorch, - ) - except ImportError: - raise ImportError(IMPORT_ERROR_MESSAGE) - - convert_tf_checkpoint_to_pytorch(self._tf_checkpoint, self._config, self._pytorch_dump_output) - elif self._model_type == "funnel": - try: - from ..models.funnel.convert_funnel_original_tf_checkpoint_to_pytorch import ( - convert_tf_checkpoint_to_pytorch, - ) - except ImportError: - raise ImportError(IMPORT_ERROR_MESSAGE) - - convert_tf_checkpoint_to_pytorch(self._tf_checkpoint, self._config, self._pytorch_dump_output) - elif self._model_type == "t5": - try: - from ..models.t5.convert_t5_original_tf_checkpoint_to_pytorch import convert_tf_checkpoint_to_pytorch - except ImportError: - raise ImportError(IMPORT_ERROR_MESSAGE) - - convert_tf_checkpoint_to_pytorch(self._tf_checkpoint, self._config, self._pytorch_dump_output) - elif self._model_type == "gpt": - from ..models.openai.convert_openai_original_tf_checkpoint_to_pytorch import ( - convert_openai_checkpoint_to_pytorch, - ) - - convert_openai_checkpoint_to_pytorch(self._tf_checkpoint, self._config, self._pytorch_dump_output) - elif self._model_type == "gpt2": - try: - from ..models.gpt2.convert_gpt2_original_tf_checkpoint_to_pytorch import ( - convert_gpt2_checkpoint_to_pytorch, - ) - except ImportError: - raise ImportError(IMPORT_ERROR_MESSAGE) - - convert_gpt2_checkpoint_to_pytorch(self._tf_checkpoint, self._config, self._pytorch_dump_output) - elif self._model_type == "xlnet": - try: - from ..models.xlnet.convert_xlnet_original_tf_checkpoint_to_pytorch import ( - convert_xlnet_checkpoint_to_pytorch, - ) - except ImportError: - raise ImportError(IMPORT_ERROR_MESSAGE) - - convert_xlnet_checkpoint_to_pytorch( - self._tf_checkpoint, self._config, self._pytorch_dump_output, self._finetuning_task_name - ) - elif self._model_type == "xlm": - from ..models.xlm.convert_xlm_original_pytorch_checkpoint_to_pytorch import ( - convert_xlm_checkpoint_to_pytorch, - ) - - convert_xlm_checkpoint_to_pytorch(self._tf_checkpoint, self._pytorch_dump_output) - elif self._model_type == "lxmert": - from ..models.lxmert.convert_lxmert_original_tf_checkpoint_to_pytorch import ( - convert_lxmert_checkpoint_to_pytorch, - ) - - convert_lxmert_checkpoint_to_pytorch(self._tf_checkpoint, self._pytorch_dump_output) - elif self._model_type == "rembert": - from ..models.rembert.convert_rembert_tf_checkpoint_to_pytorch import ( - convert_rembert_tf_checkpoint_to_pytorch, - ) - - convert_rembert_tf_checkpoint_to_pytorch(self._tf_checkpoint, self._config, self._pytorch_dump_output) - else: - raise ValueError("--model_type should be selected in the list [bert, gpt, gpt2, t5, xlnet, xlm, lxmert]") diff --git a/src/transformers/commands/env.py b/src/transformers/commands/env.py index 983a858cd952..9ef31c71a0d1 100644 --- a/src/transformers/commands/env.py +++ b/src/transformers/commands/env.py @@ -26,9 +26,7 @@ from ..integrations.deepspeed import is_deepspeed_available from ..utils import ( is_accelerate_available, - is_flax_available, is_safetensors_available, - is_tf_available, is_torch_available, is_torch_hpu_available, is_torch_npu_available, @@ -109,19 +107,6 @@ def run(self): elif pt_hpu_available: pt_accelerator = "HPU" - tf_version = "not installed" - tf_cuda_available = "NA" - if is_tf_available(): - import tensorflow as tf - - tf_version = tf.__version__ - try: - # deprecated in v2.1 - tf_cuda_available = tf.test.is_gpu_available() - except AttributeError: - # returns list of devices, convert to bool - tf_cuda_available = bool(tf.config.list_physical_devices("GPU")) - deepspeed_version = "not installed" if is_deepspeed_available(): # Redirect command line output to silence deepspeed import output. @@ -129,20 +114,6 @@ def run(self): import deepspeed deepspeed_version = deepspeed.__version__ - flax_version = "not installed" - jax_version = "not installed" - jaxlib_version = "not installed" - jax_backend = "NA" - if is_flax_available(): - import flax - import jax - import jaxlib - - flax_version = flax.__version__ - jax_version = jax.__version__ - jaxlib_version = jaxlib.__version__ - jax_backend = jax.lib.xla_bridge.get_backend().platform - info = { "`transformers` version": version, "Platform": platform.platform(), @@ -153,10 +124,6 @@ def run(self): "Accelerate config": f"{accelerate_config_str}", "DeepSpeed version": f"{deepspeed_version}", "PyTorch version (accelerator?)": f"{pt_version} ({pt_accelerator})", - "Tensorflow version (GPU?)": f"{tf_version} ({tf_cuda_available})", - "Flax version (CPU?/GPU?/TPU?)": f"{flax_version} ({jax_backend})", - "Jax version": f"{jax_version}", - "JaxLib version": f"{jaxlib_version}", "Using distributed or parallel set-up in script?": "", } if is_torch_available(): diff --git a/src/transformers/commands/train.py b/src/transformers/commands/train.py deleted file mode 100644 index 06e95443df24..000000000000 --- a/src/transformers/commands/train.py +++ /dev/null @@ -1,158 +0,0 @@ -# Copyright 2020 The HuggingFace Team. All rights reserved. -# -# 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. - -import os -from argparse import ArgumentParser, Namespace - -from ..data import SingleSentenceClassificationProcessor as Processor -from ..pipelines import TextClassificationPipeline -from ..utils import is_tf_available, is_torch_available, logging -from . import BaseTransformersCLICommand - - -if not is_tf_available() and not is_torch_available(): - raise RuntimeError("At least one of PyTorch or TensorFlow 2.0+ should be installed to use CLI training") - -# TF training parameters -USE_XLA = False -USE_AMP = False - - -def train_command_factory(args: Namespace): - """ - Factory function used to instantiate training command from provided command line arguments. - - Returns: TrainCommand - """ - return TrainCommand(args) - - -class TrainCommand(BaseTransformersCLICommand): - @staticmethod - def register_subcommand(parser: ArgumentParser): - """ - Register this command to argparse so it's available for the transformer-cli - - Args: - parser: Root parser to register command-specific arguments - """ - train_parser = parser.add_parser("train", help="CLI tool to train a model on a task.") - - train_parser.add_argument( - "--train_data", - type=str, - required=True, - help="path to train (and optionally evaluation) dataset as a csv with tab separated labels and sentences.", - ) - train_parser.add_argument( - "--column_label", type=int, default=0, help="Column of the dataset csv file with example labels." - ) - train_parser.add_argument( - "--column_text", type=int, default=1, help="Column of the dataset csv file with example texts." - ) - train_parser.add_argument( - "--column_id", type=int, default=2, help="Column of the dataset csv file with example ids." - ) - train_parser.add_argument( - "--skip_first_row", action="store_true", help="Skip the first row of the csv file (headers)." - ) - - train_parser.add_argument("--validation_data", type=str, default="", help="path to validation dataset.") - train_parser.add_argument( - "--validation_split", - type=float, - default=0.1, - help="if validation dataset is not provided, fraction of train dataset to use as validation dataset.", - ) - - train_parser.add_argument("--output", type=str, default="./", help="path to saved the trained model.") - - train_parser.add_argument( - "--task", type=str, default="text_classification", help="Task to train the model on." - ) - train_parser.add_argument( - "--model", type=str, default="google-bert/bert-base-uncased", help="Model's name or path to stored model." - ) - train_parser.add_argument("--train_batch_size", type=int, default=32, help="Batch size for training.") - train_parser.add_argument("--valid_batch_size", type=int, default=64, help="Batch size for validation.") - train_parser.add_argument("--learning_rate", type=float, default=3e-5, help="Learning rate.") - train_parser.add_argument("--adam_epsilon", type=float, default=1e-08, help="Epsilon for Adam optimizer.") - train_parser.set_defaults(func=train_command_factory) - - def __init__(self, args: Namespace): - self.logger = logging.get_logger("transformers/training") - - self.framework = "tf" if is_tf_available() else "torch" - - os.makedirs(args.output, exist_ok=True) - self.output = args.output - - self.column_label = args.column_label - self.column_text = args.column_text - self.column_id = args.column_id - - self.logger.info(f"Loading {args.task} pipeline for {args.model}") - if args.task == "text_classification": - self.pipeline = TextClassificationPipeline.from_pretrained(args.model) - elif args.task == "token_classification": - raise NotImplementedError - elif args.task == "question_answering": - raise NotImplementedError - - self.logger.info(f"Loading dataset from {args.train_data}") - self.train_dataset = Processor.create_from_csv( - args.train_data, - column_label=args.column_label, - column_text=args.column_text, - column_id=args.column_id, - skip_first_row=args.skip_first_row, - ) - self.valid_dataset = None - if args.validation_data: - self.logger.info(f"Loading validation dataset from {args.validation_data}") - self.valid_dataset = Processor.create_from_csv( - args.validation_data, - column_label=args.column_label, - column_text=args.column_text, - column_id=args.column_id, - skip_first_row=args.skip_first_row, - ) - - self.validation_split = args.validation_split - self.train_batch_size = args.train_batch_size - self.valid_batch_size = args.valid_batch_size - self.learning_rate = args.learning_rate - self.adam_epsilon = args.adam_epsilon - - def run(self): - if self.framework == "tf": - return self.run_tf() - return self.run_torch() - - def run_torch(self): - raise NotImplementedError - - def run_tf(self): - self.pipeline.fit( - self.train_dataset, - validation_data=self.valid_dataset, - validation_split=self.validation_split, - learning_rate=self.learning_rate, - adam_epsilon=self.adam_epsilon, - train_batch_size=self.train_batch_size, - valid_batch_size=self.valid_batch_size, - ) - - # Save trained pipeline - self.pipeline.save_pretrained(self.output) diff --git a/src/transformers/commands/transformers_cli.py b/src/transformers/commands/transformers_cli.py index 00eaff01a4ef..1a283a1c512c 100644 --- a/src/transformers/commands/transformers_cli.py +++ b/src/transformers/commands/transformers_cli.py @@ -18,7 +18,6 @@ from transformers.commands.add_fast_image_processor import AddFastImageProcessorCommand from transformers.commands.add_new_model_like import AddNewModelLikeCommand from transformers.commands.chat import ChatCommand -from transformers.commands.convert import ConvertCommand from transformers.commands.download import DownloadCommand from transformers.commands.env import EnvironmentCommand from transformers.commands.run import RunCommand @@ -39,7 +38,6 @@ def main(): # Register commands ChatCommand.register_subcommand(commands_parser) - ConvertCommand.register_subcommand(commands_parser) DownloadCommand.register_subcommand(commands_parser) EnvironmentCommand.register_subcommand(commands_parser) RunCommand.register_subcommand(commands_parser) diff --git a/src/transformers/configuration_utils.py b/src/transformers/configuration_utils.py index 126b683e672d..b9423a8bbf59 100755 --- a/src/transformers/configuration_utils.py +++ b/src/transformers/configuration_utils.py @@ -100,9 +100,8 @@ class PretrainedConfig(PushToHubMixin): Arg: name_or_path (`str`, *optional*, defaults to `""`): - Store the string that was passed to [`PreTrainedModel.from_pretrained`] or - [`TFPreTrainedModel.from_pretrained`] as `pretrained_model_name_or_path` if the configuration was created - with such a method. + Store the string that was passed to [`PreTrainedModel.from_pretrained`] as `pretrained_model_name_or_path` + if the configuration was created with such a method. output_hidden_states (`bool`, *optional*, defaults to `False`): Whether or not the model should return all hidden-states. output_attentions (`bool`, *optional*, defaults to `False`): @@ -140,8 +139,7 @@ class PretrainedConfig(PushToHubMixin): architectures (`list[str]`, *optional*): Model architectures that can be used with the model pretrained weights. finetuning_task (`str`, *optional*): - Name of the task used to fine-tune the model. This can be used when converting from an original (TensorFlow - or PyTorch) checkpoint. + Name of the task used to fine-tune the model. id2label (`dict[int, str]`, *optional*): A map from index (for instance prediction index, or target index) to label. label2id (`dict[str, int]`, *optional*): @@ -346,10 +344,6 @@ def __init__( logger.error(f"Can't set {key} with value {value} for {self}") raise err - # TODO: remove later, deprecated arguments for TF models - self.tf_legacy_loss = kwargs.pop("tf_legacy_loss", False) - self.use_bfloat16 = kwargs.pop("use_bfloat16", False) - def _create_id_label_maps(self, num_labels: int): self.id2label = {i: f"LABEL_{i}" for i in range(num_labels)} self.label2id = dict(zip(self.id2label.values(), self.id2label.keys())) diff --git a/src/transformers/convert_graph_to_onnx.py b/src/transformers/convert_graph_to_onnx.py deleted file mode 100644 index 922ece8c0f45..000000000000 --- a/src/transformers/convert_graph_to_onnx.py +++ /dev/null @@ -1,551 +0,0 @@ -# Copyright 2020 The HuggingFace Team. All rights reserved. -# -# 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. - -import warnings -from argparse import ArgumentParser -from os import listdir, makedirs -from pathlib import Path -from typing import Optional - -from packaging.version import Version, parse - -from transformers.pipelines import Pipeline, pipeline -from transformers.tokenization_utils import BatchEncoding -from transformers.utils import ModelOutput, is_tf_available, is_torch_available - - -# This is the minimal required version to -# support some ONNX Runtime features -ORT_QUANTIZE_MINIMUM_VERSION = parse("1.4.0") - - -SUPPORTED_PIPELINES = [ - "feature-extraction", - "ner", - "sentiment-analysis", - "fill-mask", - "question-answering", - "text-generation", - "translation_en_to_fr", - "translation_en_to_de", - "translation_en_to_ro", -] - - -class OnnxConverterArgumentParser(ArgumentParser): - """ - Wraps all the script arguments supported to export transformers models to ONNX IR - """ - - def __init__(self): - super().__init__("ONNX Converter") - - self.add_argument( - "--pipeline", - type=str, - choices=SUPPORTED_PIPELINES, - default="feature-extraction", - ) - self.add_argument( - "--model", - type=str, - required=True, - help="Model's id or path (ex: google-bert/bert-base-cased)", - ) - self.add_argument("--tokenizer", type=str, help="Tokenizer's id or path (ex: google-bert/bert-base-cased)") - self.add_argument( - "--framework", - type=str, - choices=["pt", "tf"], - help="Framework for loading the model", - ) - self.add_argument("--opset", type=int, default=11, help="ONNX opset to use") - self.add_argument( - "--check-loading", - action="store_true", - help="Check ONNX is able to load the model", - ) - self.add_argument( - "--use-external-format", - action="store_true", - help="Allow exporting model >= than 2Gb", - ) - self.add_argument( - "--quantize", - action="store_true", - help="Quantize the neural network to be run with int8", - ) - self.add_argument("output") - - -def generate_identified_filename(filename: Path, identifier: str) -> Path: - """ - Append a string-identifier at the end (before the extension, if any) to the provided filepath - - Args: - filename: pathlib.Path The actual path object we would like to add an identifier suffix - identifier: The suffix to add - - Returns: String with concatenated identifier at the end of the filename - """ - return filename.parent.joinpath(filename.stem + identifier).with_suffix(filename.suffix) - - -def check_onnxruntime_requirements(minimum_version: Version): - """ - Check onnxruntime is installed and if the installed version match is recent enough - - Raises: - ImportError: If onnxruntime is not installed or too old version is found - """ - try: - import onnxruntime - - # Parse the version of the installed onnxruntime - ort_version = parse(onnxruntime.__version__) - - # We require 1.4.0 minimum - if ort_version < ORT_QUANTIZE_MINIMUM_VERSION: - raise ImportError( - f"We found an older version of onnxruntime ({onnxruntime.__version__}) " - f"but we require onnxruntime to be >= {minimum_version} to enable all the conversions options.\n" - "Please update onnxruntime by running `pip install --upgrade onnxruntime`" - ) - - except ImportError: - raise ImportError( - "onnxruntime doesn't seem to be currently installed. " - "Please install the onnxruntime by running `pip install onnxruntime`" - " and relaunch the conversion." - ) - - -def ensure_valid_input(model, tokens, input_names): - """ - Ensure inputs are presented in the correct order, without any Non - - Args: - model: The model used to forward the input data - tokens: BatchEncoding holding the input data - input_names: The name of the inputs - - Returns: Tuple - - """ - print("Ensuring inputs are in correct order") - - model_args_name = model.forward.__code__.co_varnames - model_args, ordered_input_names = [], [] - for arg_name in model_args_name[1:]: # start at index 1 to skip "self" argument - if arg_name in input_names: - ordered_input_names.append(arg_name) - model_args.append(tokens[arg_name]) - else: - print(f"{arg_name} is not present in the generated input list.") - break - - print(f"Generated inputs order: {ordered_input_names}") - return ordered_input_names, tuple(model_args) - - -def infer_shapes(nlp: Pipeline, framework: str) -> tuple[list[str], list[str], dict, BatchEncoding]: - """ - Attempt to infer the static vs dynamic axes for each input and output tensors for a specific model - - Args: - nlp: The pipeline object holding the model to be exported - framework: The framework identifier to dispatch to the correct inference scheme (pt/tf) - - Returns: - - - List of the inferred input variable names - - List of the inferred output variable names - - Dictionary with input/output variables names as key and shape tensor as value - - a BatchEncoding reference which was used to infer all the above information - """ - - def build_shape_dict(name: str, tensor, is_input: bool, seq_len: int): - if isinstance(tensor, (tuple, list)): - return [build_shape_dict(name, t, is_input, seq_len) for t in tensor] - - else: - # Let's assume batch is the first axis with only 1 element (~~ might not be always true ...) - axes = {[axis for axis, numel in enumerate(tensor.shape) if numel == 1][0]: "batch"} - if is_input: - if len(tensor.shape) == 2: - axes[1] = "sequence" - else: - raise ValueError(f"Unable to infer tensor axes ({len(tensor.shape)})") - else: - seq_axes = [dim for dim, shape in enumerate(tensor.shape) if shape == seq_len] - axes.update(dict.fromkeys(seq_axes, "sequence")) - - print(f"Found {'input' if is_input else 'output'} {name} with shape: {axes}") - return axes - - tokens = nlp.tokenizer("This is a sample output", return_tensors=framework) - seq_len = tokens.input_ids.shape[-1] - outputs = nlp.model(**tokens) if framework == "pt" else nlp.model(tokens) - if isinstance(outputs, ModelOutput): - outputs = outputs.to_tuple() - if not isinstance(outputs, (list, tuple)): - outputs = (outputs,) - - # Generate input names & axes - input_vars = list(tokens.keys()) - input_dynamic_axes = {k: build_shape_dict(k, v, True, seq_len) for k, v in tokens.items()} - - # flatten potentially grouped outputs (past for gpt2, attentions) - outputs_flat = [] - for output in outputs: - if isinstance(output, (tuple, list)): - outputs_flat.extend(output) - else: - outputs_flat.append(output) - - # Generate output names & axes - output_names = [f"output_{i}" for i in range(len(outputs_flat))] - output_dynamic_axes = {k: build_shape_dict(k, v, False, seq_len) for k, v in zip(output_names, outputs_flat)} - - # Create the aggregated axes representation - dynamic_axes = dict(input_dynamic_axes, **output_dynamic_axes) - return input_vars, output_names, dynamic_axes, tokens - - -def load_graph_from_args( - pipeline_name: str, framework: str, model: str, tokenizer: Optional[str] = None, **models_kwargs -) -> Pipeline: - """ - Convert the set of arguments provided through the CLI to an actual pipeline reference (tokenizer + model - - Args: - pipeline_name: The kind of pipeline to use (ner, question-answering, etc.) - framework: The actual model to convert the pipeline from ("pt" or "tf") - model: The model name which will be loaded by the pipeline - tokenizer: The tokenizer name which will be loaded by the pipeline, default to the model's value - - Returns: Pipeline object - - """ - # If no tokenizer provided - if tokenizer is None: - tokenizer = model - - # Check the wanted framework is available - if framework == "pt" and not is_torch_available(): - raise Exception("Cannot convert because PyTorch is not installed. Please install torch first.") - if framework == "tf" and not is_tf_available(): - raise Exception("Cannot convert because TF is not installed. Please install tensorflow first.") - - print(f"Loading pipeline (model: {model}, tokenizer: {tokenizer})") - - # Allocate tokenizer and model - return pipeline(pipeline_name, model=model, tokenizer=tokenizer, framework=framework, model_kwargs=models_kwargs) - - -def convert_pytorch(nlp: Pipeline, opset: int, output: Path, use_external_format: bool): - """ - Export a PyTorch backed pipeline to ONNX Intermediate Representation (IR - - Args: - nlp: The pipeline to be exported - opset: The actual version of the ONNX operator set to use - output: Path where will be stored the generated ONNX model - use_external_format: Split the model definition from its parameters to allow model bigger than 2GB - - Returns: - - """ - if not is_torch_available(): - raise Exception("Cannot convert because PyTorch is not installed. Please install torch first.") - - import torch - from torch.onnx import export - - print(f"Using framework PyTorch: {torch.__version__}") - - with torch.no_grad(): - input_names, output_names, dynamic_axes, tokens = infer_shapes(nlp, "pt") - ordered_input_names, model_args = ensure_valid_input(nlp.model, tokens, input_names) - - export( - nlp.model, - model_args, - f=output.as_posix(), - input_names=ordered_input_names, - output_names=output_names, - dynamic_axes=dynamic_axes, - do_constant_folding=True, - opset_version=opset, - ) - - -def convert_tensorflow(nlp: Pipeline, opset: int, output: Path): - """ - Export a TensorFlow backed pipeline to ONNX Intermediate Representation (IR) - - Args: - nlp: The pipeline to be exported - opset: The actual version of the ONNX operator set to use - output: Path where will be stored the generated ONNX model - - Notes: TensorFlow cannot export model bigger than 2GB due to internal constraint from TensorFlow - - """ - if not is_tf_available(): - raise Exception("Cannot convert because TF is not installed. Please install tensorflow first.") - - print("/!\\ Please note TensorFlow doesn't support exporting model > 2Gb /!\\") - - try: - import tensorflow as tf - import tf2onnx - from tf2onnx import __version__ as t2ov - - print(f"Using framework TensorFlow: {tf.version.VERSION}, tf2onnx: {t2ov}") - - # Build - input_names, output_names, dynamic_axes, tokens = infer_shapes(nlp, "tf") - - # Forward - nlp.model.predict(tokens.data) - input_signature = [tf.TensorSpec.from_tensor(tensor, name=key) for key, tensor in tokens.items()] - model_proto, _ = tf2onnx.convert.from_keras( - nlp.model, input_signature, opset=opset, output_path=output.as_posix() - ) - - except ImportError as e: - raise Exception( - f"Cannot import {e.name} required to convert TF model to ONNX. Please install {e.name} first. {e}" - ) - - -def convert( - framework: str, - model: str, - output: Path, - opset: int, - tokenizer: Optional[str] = None, - use_external_format: bool = False, - pipeline_name: str = "feature-extraction", - **model_kwargs, -): - """ - Convert the pipeline object to the ONNX Intermediate Representation (IR) format - - Args: - framework: The framework the pipeline is backed by ("pt" or "tf") - model: The name of the model to load for the pipeline - output: The path where the ONNX graph will be stored - opset: The actual version of the ONNX operator set to use - tokenizer: The name of the model to load for the pipeline, default to the model's name if not provided - use_external_format: - Split the model definition from its parameters to allow model bigger than 2GB (PyTorch only) - pipeline_name: The kind of pipeline to instantiate (ner, question-answering, etc.) - model_kwargs: Keyword arguments to be forwarded to the model constructor - - Returns: - - """ - warnings.warn( - "The `transformers.convert_graph_to_onnx` package is deprecated and will be removed in version 5 of" - " Transformers", - FutureWarning, - ) - print(f"ONNX opset version set to: {opset}") - - # Load the pipeline - nlp = load_graph_from_args(pipeline_name, framework, model, tokenizer, **model_kwargs) - - if not output.parent.exists(): - print(f"Creating folder {output.parent}") - makedirs(output.parent.as_posix()) - elif len(listdir(output.parent.as_posix())) > 0: - raise Exception(f"Folder {output.parent.as_posix()} is not empty, aborting conversion") - - # Export the graph - if framework == "pt": - convert_pytorch(nlp, opset, output, use_external_format) - else: - convert_tensorflow(nlp, opset, output) - - -def optimize(onnx_model_path: Path) -> Path: - """ - Load the model at the specified path and let onnxruntime look at transformations on the graph to enable all the - optimizations possible - - Args: - onnx_model_path: filepath where the model binary description is stored - - Returns: Path where the optimized model binary description has been saved - - """ - from onnxruntime import InferenceSession, SessionOptions - - # Generate model name with suffix "optimized" - opt_model_path = generate_identified_filename(onnx_model_path, "-optimized") - sess_option = SessionOptions() - sess_option.optimized_model_filepath = opt_model_path.as_posix() - _ = InferenceSession(onnx_model_path.as_posix(), sess_option) - - print(f"Optimized model has been written at {opt_model_path}: \N{HEAVY CHECK MARK}") - print("/!\\ Optimized model contains hardware specific operators which might not be portable. /!\\") - - return opt_model_path - - -def quantize(onnx_model_path: Path) -> Path: - """ - Quantize the weights of the model from float32 to in8 to allow very efficient inference on modern CPU - - Args: - onnx_model_path: Path to location the exported ONNX model is stored - - Returns: The Path generated for the quantized - """ - import onnx - import onnxruntime - from onnx.onnx_pb import ModelProto - from onnxruntime.quantization import QuantizationMode - from onnxruntime.quantization.onnx_quantizer import ONNXQuantizer - from onnxruntime.quantization.registry import IntegerOpsRegistry - - # Load the ONNX model - onnx_model = onnx.load(onnx_model_path.as_posix()) - - if parse(onnx.__version__) < parse("1.5.0"): - print( - "Models larger than 2GB will fail to quantize due to protobuf constraint.\n" - "Please upgrade to onnxruntime >= 1.5.0." - ) - - # Copy it - copy_model = ModelProto() - copy_model.CopyFrom(onnx_model) - - # Construct quantizer - # onnxruntime renamed input_qType to activation_qType in v1.13.1, so we - # check the onnxruntime version to ensure backward compatibility. - # See also: https://github.com/microsoft/onnxruntime/pull/12873 - if parse(onnxruntime.__version__) < parse("1.13.1"): - quantizer = ONNXQuantizer( - model=copy_model, - per_channel=False, - reduce_range=False, - mode=QuantizationMode.IntegerOps, - static=False, - weight_qType=True, - input_qType=False, - tensors_range=None, - nodes_to_quantize=None, - nodes_to_exclude=None, - op_types_to_quantize=list(IntegerOpsRegistry), - ) - else: - quantizer = ONNXQuantizer( - model=copy_model, - per_channel=False, - reduce_range=False, - mode=QuantizationMode.IntegerOps, - static=False, - weight_qType=True, - activation_qType=False, - tensors_range=None, - nodes_to_quantize=None, - nodes_to_exclude=None, - op_types_to_quantize=list(IntegerOpsRegistry), - ) - - # Quantize and export - quantizer.quantize_model() - - # Append "-quantized" at the end of the model's name - quantized_model_path = generate_identified_filename(onnx_model_path, "-quantized") - - # Save model - print(f"Quantized model has been written at {quantized_model_path}: \N{HEAVY CHECK MARK}") - onnx.save_model(quantizer.model.model, quantized_model_path.as_posix()) - - return quantized_model_path - - -def verify(path: Path): - from onnxruntime import InferenceSession, SessionOptions - from onnxruntime.capi.onnxruntime_pybind11_state import RuntimeException - - print(f"Checking ONNX model loading from: {path} ...") - try: - onnx_options = SessionOptions() - _ = InferenceSession(path.as_posix(), onnx_options, providers=["CPUExecutionProvider"]) - print(f"Model {path} correctly loaded: \N{HEAVY CHECK MARK}") - except RuntimeException as re: - print(f"Error while loading the model {re}: \N{HEAVY BALLOT X}") - - -if __name__ == "__main__": - parser = OnnxConverterArgumentParser() - args = parser.parse_args() - - # Make sure output is absolute path - args.output = Path(args.output).absolute() - - try: - print("\n====== Converting model to ONNX ======") - # Convert - convert( - args.framework, - args.model, - args.output, - args.opset, - args.tokenizer, - args.use_external_format, - args.pipeline, - ) - - if args.quantize: - # Ensure requirements for quantization on onnxruntime is met - check_onnxruntime_requirements(ORT_QUANTIZE_MINIMUM_VERSION) - - # onnxruntime optimizations doesn't provide the same level of performances on TensorFlow than PyTorch - if args.framework == "tf": - print( - "\t Using TensorFlow might not provide the same optimization level compared to PyTorch.\n" - "\t For TensorFlow users you can try optimizing the model directly through onnxruntime_tools.\n" - "\t For more information, please refer to the onnxruntime documentation:\n" - "\t\thttps://github.com/microsoft/onnxruntime/tree/master/onnxruntime/python/tools/transformers\n" - ) - - print("\n====== Optimizing ONNX model ======") - - # Quantization works best when using the optimized version of the model - args.optimized_output = optimize(args.output) - - # Do the quantization on the right graph - args.quantized_output = quantize(args.optimized_output) - - # And verify - if args.check_loading: - print("\n====== Check exported ONNX model(s) ======") - verify(args.output) - - if hasattr(args, "optimized_output"): - verify(args.optimized_output) - - if hasattr(args, "quantized_output"): - verify(args.quantized_output) - - except Exception as e: - print(f"Error while converting the model: {e}") - exit(1) diff --git a/src/transformers/convert_tf_hub_seq_to_seq_bert_to_pytorch.py b/src/transformers/convert_tf_hub_seq_to_seq_bert_to_pytorch.py deleted file mode 100755 index e2c825a45b60..000000000000 --- a/src/transformers/convert_tf_hub_seq_to_seq_bert_to_pytorch.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright 2020 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. -"""Convert Seq2Seq TF Hub checkpoint.""" - -import argparse - -from . import ( - BertConfig, - BertGenerationConfig, - BertGenerationDecoder, - BertGenerationEncoder, - load_tf_weights_in_bert_generation, - logging, -) - - -logging.set_verbosity_info() - - -def convert_tf_checkpoint_to_pytorch(tf_hub_path, pytorch_dump_path, is_encoder_named_decoder, vocab_size, is_encoder): - # Initialise PyTorch model - bert_config = BertConfig.from_pretrained( - "google-bert/bert-large-cased", - vocab_size=vocab_size, - max_position_embeddings=512, - is_decoder=True, - add_cross_attention=True, - ) - bert_config_dict = bert_config.to_dict() - del bert_config_dict["type_vocab_size"] - config = BertGenerationConfig(**bert_config_dict) - if is_encoder: - model = BertGenerationEncoder(config) - else: - model = BertGenerationDecoder(config) - print(f"Building PyTorch model from configuration: {config}") - - # Load weights from tf checkpoint - load_tf_weights_in_bert_generation( - model, - tf_hub_path, - model_class="bert", - is_encoder_named_decoder=is_encoder_named_decoder, - is_encoder=is_encoder, - ) - - # Save pytorch-model - print(f"Save PyTorch model and config to {pytorch_dump_path}") - model.save_pretrained(pytorch_dump_path) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - # Required parameters - parser.add_argument( - "--tf_hub_path", default=None, type=str, required=True, help="Path to the TensorFlow checkpoint path." - ) - parser.add_argument( - "--pytorch_dump_path", default=None, type=str, required=True, help="Path to the output PyTorch model." - ) - parser.add_argument( - "--is_encoder_named_decoder", - action="store_true", - help="If decoder has to be renamed to encoder in PyTorch model.", - ) - parser.add_argument("--is_encoder", action="store_true", help="If model is an encoder.") - parser.add_argument("--vocab_size", default=50358, type=int, help="Vocab size of model") - args = parser.parse_args() - convert_tf_checkpoint_to_pytorch( - args.tf_hub_path, - args.pytorch_dump_path, - args.is_encoder_named_decoder, - args.vocab_size, - is_encoder=args.is_encoder, - ) diff --git a/src/transformers/data/data_collator.py b/src/transformers/data/data_collator.py index 10ee10e01950..1bff72cf338c 100644 --- a/src/transformers/data/data_collator.py +++ b/src/transformers/data/data_collator.py @@ -31,7 +31,7 @@ """ A DataCollator is a function that takes a list of samples from a Dataset and collate them into a batch, as a dictionary -of PyTorch/TensorFlow tensors or NumPy arrays. +of PyTorch tensors or NumPy arrays. """ DataCollator = NewType("DataCollator", Callable[[list[InputDataClass]], dict[str, Any]]) @@ -40,9 +40,7 @@ class DataCollatorMixin: def __call__(self, features, return_tensors=None): if return_tensors is None: return_tensors = self.return_tensors - if return_tensors == "tf": - return self.tf_call(features) - elif return_tensors == "pt": + if return_tensors == "pt": return self.torch_call(features) elif return_tensors == "np": return self.numpy_call(features) @@ -91,8 +89,6 @@ def default_data_collator(features: list[InputDataClass], return_tensors="pt") - if return_tensors == "pt": return torch_default_data_collator(features) - elif return_tensors == "tf": - return tf_default_data_collator(features) elif return_tensors == "np": return numpy_default_data_collator(features) @@ -114,7 +110,7 @@ class DefaultDataCollator(DataCollatorMixin): Args: return_tensors (`str`, *optional*, defaults to `"pt"`): - The type of Tensor to return. Allowable values are "np", "pt" and "tf". + The type of Tensor to return. Allowable values are "np", or "pt". """ return_tensors: str = "pt" @@ -161,47 +157,6 @@ def torch_default_data_collator(features: list[InputDataClass]) -> dict[str, Any return batch -def tf_default_data_collator(features: list[InputDataClass]) -> dict[str, Any]: - import tensorflow as tf - - if not isinstance(features[0], Mapping): - features = [vars(f) for f in features] - first = features[0] - batch = {} - - # Special handling for labels. - # Ensure that tensor is created with the correct type - # (it should be automatically the case, but let's make sure of it.) - if "label" in first and first["label"] is not None: - label_col_name = "label" - elif "label_ids" in first and first["label_ids"] is not None: - label_col_name = "label_ids" - elif "labels" in first and first["labels"] is not None: - label_col_name = "labels" - else: - label_col_name = None - if label_col_name is not None: - if isinstance(first[label_col_name], tf.Tensor): - dtype = tf.int64 if first[label_col_name].dtype.is_integer else tf.float32 - elif isinstance(first[label_col_name], (np.ndarray, np.generic)): - dtype = tf.int64 if np.issubdtype(first[label_col_name].dtype, np.integer) else tf.float32 - elif isinstance(first[label_col_name], (tuple, list)): - dtype = tf.int64 if isinstance(first[label_col_name][0], int) else tf.float32 - else: - dtype = tf.int64 if isinstance(first[label_col_name], int) else tf.float32 - batch["labels"] = tf.convert_to_tensor([f[label_col_name] for f in features], dtype=dtype) - # Handling of all other possible keys. - # Again, we will use the first element to figure out which key/values are not None for this model. - for k, v in first.items(): - if k not in ("label", "label_ids", "labels") and v is not None and not isinstance(v, str): - if isinstance(v, (tf.Tensor, np.ndarray)): - batch[k] = tf.stack([f[k] for f in features]) - else: - batch[k] = tf.convert_to_tensor([f[k] for f in features]) - - return batch - - def numpy_default_data_collator(features: list[InputDataClass]) -> dict[str, Any]: if not isinstance(features[0], Mapping): features = [vars(f) for f in features] @@ -259,7 +214,7 @@ class DataCollatorWithPadding: This is especially useful to enable the use of Tensor Cores on NVIDIA hardware with compute capability >= 7.0 (Volta). return_tensors (`str`, *optional*, defaults to `"pt"`): - The type of Tensor to return. Allowable values are "np", "pt" and "tf". + The type of Tensor to return. Allowable values are "np", or "pt". """ tokenizer: PreTrainedTokenizerBase @@ -313,7 +268,7 @@ class DataCollatorForTokenClassification(DataCollatorMixin): label_pad_token_id (`int`, *optional*, defaults to -100): The id to use when padding the labels (-100 will be automatically ignore by PyTorch loss functions). return_tensors (`str`, *optional*, defaults to `"pt"`): - The type of Tensor to return. Allowable values are "np", "pt" and "tf". + The type of Tensor to return. Allowable values are "np", or "pt". """ tokenizer: PreTrainedTokenizerBase @@ -363,38 +318,6 @@ def to_list(tensor_or_iterable): batch[label_name] = torch.tensor(batch[label_name], dtype=torch.int64) return batch - def tf_call(self, features): - import tensorflow as tf - - label_name = "label" if "label" in features[0] else "labels" - labels = [feature[label_name] for feature in features] if label_name in features[0] else None - batch = pad_without_fast_tokenizer_warning( - self.tokenizer, - features, - padding=self.padding, - max_length=self.max_length, - pad_to_multiple_of=self.pad_to_multiple_of, - # Conversion to tensors will fail if we have labels as they are not of the same length yet. - return_tensors="tf" if labels is None else None, - ) - - if labels is None: - return batch - - sequence_length = tf.convert_to_tensor(batch["input_ids"]).shape[1] - padding_side = self.tokenizer.padding_side - if padding_side == "right": - batch["labels"] = [ - list(label) + [self.label_pad_token_id] * (sequence_length - len(label)) for label in labels - ] - else: - batch["labels"] = [ - [self.label_pad_token_id] * (sequence_length - len(label)) + list(label) for label in labels - ] - - batch = {k: tf.convert_to_tensor(v, dtype=tf.int64) for k, v in batch.items()} - return batch - def numpy_call(self, features): label_name = "label" if "label" in features[0] else "labels" labels = [feature[label_name] for feature in features] if label_name in features[0] else None @@ -463,44 +386,6 @@ def _torch_collate_batch(examples, tokenizer, pad_to_multiple_of: Optional[int] return result -def _tf_collate_batch(examples, tokenizer, pad_to_multiple_of: Optional[int] = None): - import tensorflow as tf - - """Collate `examples` into a batch, using the information in `tokenizer` for padding if necessary.""" - # Tensorize if necessary. - if isinstance(examples[0], (list, tuple)): - examples = [tf.convert_to_tensor(e, dtype=tf.int64) for e in examples] - - # Check if padding is necessary. - length_of_first = len(examples[0]) - are_tensors_same_length = all(len(x) == length_of_first for x in examples) - if are_tensors_same_length and (pad_to_multiple_of is None or length_of_first % pad_to_multiple_of == 0): - return tf.stack(examples, axis=0) - - # If yes, check if we have a `pad_token`. - if tokenizer.pad_token is None: - raise ValueError( - "You are attempting to pad samples but the tokenizer you are using" - f" ({tokenizer.__class__.__name__}) does not have a pad token." - ) - - # Creating the full tensor and filling it with our data. - max_length = max(len(x) for x in examples) - if pad_to_multiple_of is not None and (max_length % pad_to_multiple_of != 0): - max_length = ((max_length // pad_to_multiple_of) + 1) * pad_to_multiple_of - # result = examples[0].new_full([len(examples), max_length], tokenizer.pad_token_id) - result = [] - rank = tf.rank(examples[0]) - paddings = np.zeros((rank, 2), dtype=np.int32) - for example in examples: - if tokenizer.padding_side == "right": - paddings[0, 1] = max_length - len(example) - else: - paddings[0, 0] = max_length - len(example) - result.append(tf.pad(example, paddings, constant_values=tokenizer.pad_token_id)) - return tf.stack(result, axis=0) - - def _numpy_collate_batch(examples, tokenizer, pad_to_multiple_of: Optional[int] = None): """Collate `examples` into a batch, using the information in `tokenizer` for padding if necessary.""" # Tensorize if necessary. @@ -560,7 +445,7 @@ class DataCollatorForMultipleChoice(DataCollatorMixin): This is especially useful to enable the use of Tensor Cores on NVIDIA hardware with compute capability >= 7.5 (Volta). return_tensors (`str`, *optional*, defaults to `"pt"`): - The type of Tensor to return. Allowable values are "np", "pt" and "tf". + The type of Tensor to return. Allowable values are "np", or "pt". """ tokenizer: PreTrainedTokenizerBase @@ -599,30 +484,6 @@ def torch_call(self, examples: list[dict[str, Any]]): # Refactored implementati batch["labels"] = torch.tensor(labels, dtype=torch.int64) return batch - def tf_call(self, features): # Implementation taken from the docs. - import tensorflow as tf - - label_name = "label" if "label" in features[0] else "labels" - labels = [feature.pop(label_name) for feature in features] - batch_size = len(features) - num_choices = len(features[0]["input_ids"]) - flattened_features = [ - [{k: v[i] for k, v in feature.items()} for i in range(num_choices)] for feature in features - ] - flattened_features = sum(flattened_features, []) # Sometimes written as list(chain(*flattened_features)) - - batch = self.tokenizer.pad( - flattened_features, - padding=self.padding, - max_length=self.max_length, - pad_to_multiple_of=self.pad_to_multiple_of, - return_tensors="tf", - ) - - batch = {k: tf.reshape(v, (batch_size, num_choices, -1)) for k, v in batch.items()} - batch["labels"] = tf.convert_to_tensor(labels, dtype=tf.int64) - return batch - @dataclass class DataCollatorForSeq2Seq: @@ -656,7 +517,7 @@ class DataCollatorForSeq2Seq: label_pad_token_id (`int`, *optional*, defaults to -100): The id to use when padding the labels (-100 will be automatically ignored by PyTorch loss functions). return_tensors (`str`, *optional*, defaults to `"pt"`): - The type of Tensor to return. Allowable values are "np", "pt" and "tf". + The type of Tensor to return. Allowable values are "np", or "pt". """ tokenizer: PreTrainedTokenizerBase @@ -739,10 +600,6 @@ def __call__(self, features, return_tensors=None): import torch batch["labels"] = torch.tensor(batch["labels"], dtype=torch.int64) - elif return_tensors == "tf": - import tensorflow as tf - - batch["labels"] = tf.constant(batch["labels"], dtype=tf.int64) else: batch["labels"] = np.array(batch["labels"], dtype=np.int64) else: @@ -787,7 +644,7 @@ class DataCollatorForLanguageModeling(DataCollatorMixin): pad_to_multiple_of (`int`, *optional*): If set, will pad the sequence to a multiple of the provided value. return_tensors (`str`): - The type of Tensor to return. Allowable values are "np", "pt" and "tf". + The type of Tensor to return. Allowable values are "np", or "pt". seed (`int`, *optional*): The seed to use for the random number generator for masking. If not provided, the global RNG will be used. @@ -828,7 +685,6 @@ class DataCollatorForLanguageModeling(DataCollatorMixin): mask_replace_prob: float = 0.8 random_replace_prob: float = 0.1 pad_to_multiple_of: Optional[int] = None - tf_experimental_compile: bool = False return_tensors: str = "pt" seed: Optional[int] = None @@ -852,11 +708,6 @@ def __post_init__(self): self.mask_replace_prob = float(self.mask_replace_prob) self.random_replace_prob = float(self.random_replace_prob) - if self.tf_experimental_compile: - import tensorflow as tf - - self.tf_mask_tokens = tf.function(self.tf_mask_tokens, jit_compile=True) - self.generator = None def get_generator(self, seed): @@ -864,10 +715,6 @@ def get_generator(self, seed): import torch return torch.Generator().manual_seed(seed) - elif self.return_tensors == "tf": - import tensorflow as tf - - return tf.random.Generator.from_seed(seed) else: import numpy as np @@ -882,7 +729,6 @@ def create_rng(self): # worker's generator, generated as the main seed + the worker's ID. # (https://pytorch.org/docs/stable/data.html#randomness-in-multi-process-data-loading) # Only PyTorch DataLoader allows us to access the worker ID, and so we check for this. - # For other frameworks, we will throw an error. import torch worker_info = torch.utils.data.get_worker_info() @@ -897,111 +743,6 @@ def create_rng(self): self.generator = self.get_generator(self.seed + worker_info.id) - @staticmethod - def tf_bernoulli(shape, probability, generator=None): - import tensorflow as tf - - prob_matrix = tf.fill(shape, probability) - # if generator exists, use it to generate the random numbers - # otherwise, use the global RNG - if generator: - return tf.cast(prob_matrix - generator.uniform(shape, 0, 1) >= 0, tf.bool) - else: - return tf.cast(prob_matrix - tf.random.uniform(shape, 0, 1) >= 0, tf.bool) - - def tf_mask_tokens( - self, inputs: Any, vocab_size, mask_token_id, special_tokens_mask: Optional[Any] = None - ) -> tuple[Any, Any]: - """ - Prepare masked tokens inputs/labels for masked language modeling: 80% MASK, 10% random, 10% original. - """ - import tensorflow as tf - - mask_token_id = tf.cast(mask_token_id, inputs.dtype) - - input_shape = tf.shape(inputs) - # 1 for a special token, 0 for a normal token in the special tokens mask - # We sample a few tokens in each sequence for MLM training (with probability `self.mlm_probability`) - masked_indices = self.tf_bernoulli(input_shape, self.mlm_probability, self.generator) & ~special_tokens_mask - # Replace unmasked indices with -100 in the labels since we only compute loss on masked tokens - labels = tf.where(masked_indices, inputs, -100) - - # mask_replace_prob% of the time, we replace masked input tokens with tokenizer.mask_token ([MASK]) - indices_replaced = self.tf_bernoulli(input_shape, self.mask_replace_prob, self.generator) & masked_indices - - inputs = tf.where(indices_replaced, mask_token_id, inputs) - - if self.mask_replace_prob == 1 or self.random_replace_prob == 0: - return inputs, labels - - remaining_prob = 1 - self.mask_replace_prob - # scaling the random_replace_prob to the remaining probability for example if - # mask_replace_prob = 0.8 and random_replace_prob = 0.1, - # then random_replace_prob_scaled = 0.1 / 0.2 = 0.5 - random_replace_prob_scaled = self.random_replace_prob / remaining_prob - # random_replace_prob% of the time, we replace masked input tokens with random word - indices_random = ( - self.tf_bernoulli(input_shape, random_replace_prob_scaled, self.generator) - & masked_indices - & ~indices_replaced - ) - - if self.generator: - random_words = self.generator.uniform(input_shape, maxval=vocab_size, dtype=inputs.dtype) - else: - random_words = tf.random.uniform(input_shape, maxval=vocab_size, dtype=inputs.dtype) - - inputs = tf.where(indices_random, random_words, inputs) - - # The rest of the time ((1-random_replace_prob-mask_replace_prob)% of the time) we keep the masked input tokens unchanged - return inputs, labels - - def tf_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> dict[str, Any]: - import tensorflow as tf - - if self.seed and self.generator is None: - # If we have a seed, we need to create a generator object. Subsequent calls to this function will use the same generator. - # If no seed supplied, we will use the global RNG - self.create_rng() - - # Handle dict or lists with proper padding and conversion to tensor. - if isinstance(examples[0], Mapping): - batch = pad_without_fast_tokenizer_warning( - self.tokenizer, examples, return_tensors="tf", pad_to_multiple_of=self.pad_to_multiple_of - ) - else: - batch = { - "input_ids": _tf_collate_batch(examples, self.tokenizer, pad_to_multiple_of=self.pad_to_multiple_of) - } - - # If special token mask has been preprocessed, pop it from the dict. - special_tokens_mask = batch.pop("special_tokens_mask", None) - if self.mlm: - if special_tokens_mask is None: - special_tokens_mask = [ - self.tokenizer.get_special_tokens_mask(val, already_has_special_tokens=True) - for val in batch["input_ids"].numpy().tolist() - ] - # Cannot directly create as bool - special_tokens_mask = tf.cast(tf.convert_to_tensor(special_tokens_mask, dtype=tf.int64), tf.bool) - else: - special_tokens_mask = tf.cast(special_tokens_mask, tf.bool) - batch["input_ids"], batch["labels"] = self.tf_mask_tokens( - tf.cast(batch["input_ids"], tf.int64), - special_tokens_mask=special_tokens_mask, - mask_token_id=self.tokenizer.mask_token_id, - vocab_size=len(self.tokenizer), - ) - else: - labels = batch["input_ids"] - if self.tokenizer.pad_token_id is not None: - # Replace self.tokenizer.pad_token_id with -100 - labels = tf.where(labels == self.tokenizer.pad_token_id, -100, labels) - else: - labels = tf.identity(labels) # Makes a copy, just in case - batch["labels"] = labels - return batch - def torch_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> dict[str, Any]: # Handle dict or lists with proper padding and conversion to tensor. @@ -1226,41 +967,6 @@ def torch_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> d inputs, labels = self.torch_mask_tokens(batch_input, batch_mask) return {"input_ids": inputs, "labels": labels} - def tf_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> dict[str, Any]: - import tensorflow as tf - - if self.seed and self.generator is None: - # If we have a seed, we need to create a generator object. Subsequent calls to this function will use the same generator. - # If no seed supplied, we will use the global RNG - self.create_rng() - - if isinstance(examples[0], Mapping): - input_ids = [e["input_ids"] for e in examples] - else: - input_ids = examples - examples = [{"input_ids": e} for e in examples] - - batch_input = _tf_collate_batch(input_ids, self.tokenizer, pad_to_multiple_of=self.pad_to_multiple_of) - - mask_labels = [] - for e in examples: - ref_tokens = [] - for id in tolist(e["input_ids"]): - token = self.tokenizer._convert_id_to_token(id) - ref_tokens.append(token) - - # For Chinese tokens, we need extra inf to mark sub-word, e.g [喜,欢]-> [喜,##欢] - if "chinese_ref" in e: - ref_pos = tolist(e["chinese_ref"]) - len_seq = len(e["input_ids"]) - for i in range(len_seq): - if i in ref_pos: - ref_tokens[i] = "##" + ref_tokens[i] - mask_labels.append(self._whole_word_mask(ref_tokens)) - batch_mask = _tf_collate_batch(mask_labels, self.tokenizer, pad_to_multiple_of=self.pad_to_multiple_of) - inputs, labels = self.tf_mask_tokens(tf.cast(batch_input, tf.int64), batch_mask) - return {"input_ids": inputs, "labels": labels} - def numpy_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> dict[str, Any]: if self.seed and self.generator is None: # If we have a seed, we need to create a generator object. Subsequent calls to this function will use the same generator. @@ -1307,13 +1013,6 @@ def _shuffle(self, cand_indexes): indices = torch.randperm(len(cand_indexes), generator=self.generator) return [cand_indexes[i] for i in indices] - elif self.return_tensors == "tf": - import tensorflow as tf - - seed = self.generator.make_seeds(2)[0] - indices = tf.random.experimental.stateless_shuffle(tf.range(len(cand_indexes)), seed=seed).numpy().tolist() - return [cand_indexes[i] for i in indices] - elif self.return_tensors == "np": self.generator.shuffle(cand_indexes) return cand_indexes @@ -1414,66 +1113,6 @@ def torch_mask_tokens(self, inputs: Any, mask_labels: Any) -> tuple[Any, Any]: # The rest of the time ((1-random_replacement_prob-mask_replace_prob)% of the time) we keep the masked input tokens unchanged return inputs, labels - def tf_mask_tokens(self, inputs: Any, mask_labels: Any) -> tuple[Any, Any]: - """ - Prepare masked tokens inputs/labels for masked language modeling: 80% MASK, 10% random, 10% original. Set - 'mask_labels' means we use whole word mask (wwm), we directly mask idxs according to it's ref. - """ - import tensorflow as tf - - input_shape = tf.shape(inputs) - if self.tokenizer.mask_token is None: - raise ValueError( - "This tokenizer does not have a mask token which is necessary for masked language modeling. Remove the" - " --mlm flag if you want to use this tokenizer." - ) - labels = tf.identity(inputs) - # We sample a few tokens in each sequence for masked-LM training (with probability args.mlm_probability defaults to 0.15 in Bert/RoBERTa) - - masked_indices = tf.cast(mask_labels, tf.bool) - - special_tokens_mask = [ - self.tokenizer.get_special_tokens_mask(val, already_has_special_tokens=True) for val in labels - ] - masked_indices = masked_indices & ~tf.cast(special_tokens_mask, dtype=tf.bool) - if self.tokenizer.pad_token is not None: - padding_mask = inputs == self.tokenizer.pad_token_id - masked_indices = masked_indices & ~padding_mask - - # Replace unmasked indices with -100 in the labels since we only compute loss on masked tokens - labels = tf.where(masked_indices, inputs, -100) - - # mask_replace_prob% of the time, we replace masked input tokens with tokenizer.mask_token ([MASK]) - indices_replaced = self.tf_bernoulli(input_shape, self.mask_replace_prob, self.generator) & masked_indices - - inputs = tf.where(indices_replaced, self.tokenizer.mask_token_id, inputs) - - if self.mask_replace_prob == 1 or self.random_replace_prob == 0: - return inputs, labels - - remaining_prob = 1 - self.mask_replace_prob - # scaling the random_replace_prob to the remaining probability for example if - # mask_replace_prob = 0.8 and random_replace_prob = 0.1, - # then random_replace_prob_scaled = 0.1 / 0.2 = 0.5 - random_replace_prob_scaled = self.random_replace_prob / remaining_prob - - # random_replace_prob% of the time, we replace masked input tokens with random word - indices_random = ( - self.tf_bernoulli(input_shape, random_replace_prob_scaled, self.generator) - & masked_indices - & ~indices_replaced - ) - - if self.generator: - random_words = self.generator.uniform(input_shape, maxval=len(self.tokenizer), dtype=tf.int64) - else: - random_words = tf.random.uniform(input_shape, maxval=len(self.tokenizer), dtype=tf.int64) - - inputs = tf.where(indices_random, random_words, inputs) - - # The rest of the time ((1-mask_replace_prob-random_replace_prob)% of the time) we keep the masked input tokens unchanged - return inputs, labels - def numpy_mask_tokens(self, inputs: Any, mask_labels: Any) -> tuple[Any, Any]: """ Prepare masked tokens inputs/labels for masked language modeling: 80% MASK, 10% random, 10% original. Set @@ -1543,7 +1182,7 @@ def numpy_mask_tokens(self, inputs: Any, mask_labels: Any) -> tuple[Any, Any]: def tolist(x): if isinstance(x, list): return x - elif hasattr(x, "numpy"): # Checks for TF tensors without needing the import + elif hasattr(x, "numpy"): x = x.numpy() return x.tolist() @@ -1652,13 +1291,6 @@ def torch_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> d inputs, perm_mask, target_mapping, labels = self.torch_mask_tokens(batch) return {"input_ids": inputs, "perm_mask": perm_mask, "target_mapping": target_mapping, "labels": labels} - def tf_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> dict[str, Any]: - if isinstance(examples[0], Mapping): - examples = [e["input_ids"] for e in examples] - batch = _tf_collate_batch(examples, self.tokenizer) - inputs, perm_mask, target_mapping, labels = self.tf_mask_tokens(batch) - return {"input_ids": inputs, "perm_mask": perm_mask, "target_mapping": target_mapping, "labels": labels} - def numpy_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> dict[str, Any]: if isinstance(examples[0], Mapping): examples = [e["input_ids"] for e in examples] @@ -1765,113 +1397,6 @@ def torch_mask_tokens(self, inputs: Any) -> tuple[Any, Any, Any, Any]: return inputs.long(), perm_mask, target_mapping, labels.long() - def tf_mask_tokens(self, inputs: Any) -> tuple[Any, Any, Any, Any]: - """ - The masked tokens to be predicted for a particular sequence are determined by the following algorithm: - - 0. Start from the beginning of the sequence by setting `cur_len = 0` (number of tokens processed so far). - 1. Sample a `span_length` from the interval `[1, max_span_length]` (length of span of tokens to be masked) - 2. Reserve a context of length `context_length = span_length / plm_probability` to surround span to be - masked - 3. Sample a starting point `start_index` from the interval `[cur_len, cur_len + context_length - - span_length]` and mask tokens `start_index:start_index + span_length` - 4. Set `cur_len = cur_len + context_length`. If `cur_len < max_len` (i.e. there are tokens remaining in the - sequence to be processed), repeat from Step 1. - """ - import tensorflow as tf - - if self.tokenizer.mask_token is None: - raise ValueError( - "This tokenizer does not have a mask token which is necessary for permutation language modeling." - " Please add a mask token if you want to use this tokenizer." - ) - - if tf.shape(inputs)[1] % 2 != 0: - raise ValueError( - "This collator requires that sequence lengths be even to create a leakage-free perm_mask. Please see" - " relevant comments in source code for details." - ) - - labels = tf.identity(inputs) - # Creating the mask and target_mapping tensors - masked_indices = np.full(labels.shape.as_list(), 0, dtype=bool) - labels_shape = tf.shape(labels) - target_mapping = np.zeros((labels_shape[0], labels_shape[1], labels_shape[1]), dtype=np.float32) - - for i in range(len(labels)): - # Start from the beginning of the sequence by setting `cur_len = 0` (number of tokens processed so far). - cur_len = 0 - max_len = tf.shape(labels)[1] - - while cur_len < max_len: - # Sample a `span_length` from the interval `[1, max_span_length]` (length of span of tokens to be masked) - span_length = randint(1, self.max_span_length + 1) - # Reserve a context of length `context_length = span_length / plm_probability` to surround the span to be masked - context_length = int(span_length / self.plm_probability) - # Sample a starting point `start_index` from the interval `[cur_len, cur_len + context_length - span_length]` and mask tokens `start_index:start_index + span_length` - start_index = cur_len + randint(0, context_length - span_length + 1) - masked_indices[i, start_index : start_index + span_length] = 1 - # Set `cur_len = cur_len + context_length` - cur_len += context_length - - # Since we're replacing non-masked tokens with -100 in the labels tensor instead of skipping them altogether, - # the i-th predict corresponds to the i-th token. - target_mapping[i] = np.eye(labels_shape[1]) - masked_indices = tf.cast(tf.convert_to_tensor(masked_indices), dtype=tf.bool) - target_mapping = tf.convert_to_tensor(target_mapping) - special_tokens_mask = tf.convert_to_tensor( - [ - self.tokenizer.get_special_tokens_mask(val, already_has_special_tokens=True) - for val in labels.numpy().tolist() - ], - ) - special_tokens_mask = tf.cast(special_tokens_mask, dtype=tf.bool) - masked_indices = masked_indices & ~special_tokens_mask - if self.tokenizer.pad_token is not None: - padding_mask = labels == self.tokenizer.pad_token_id - masked_indices = masked_indices & ~padding_mask - - # Mask indicating non-functional tokens, where functional tokens are [SEP], [CLS], padding, etc. - non_func_mask = ~(padding_mask | special_tokens_mask) - - inputs = tf.where(masked_indices, self.tokenizer.mask_token_id, inputs) - labels = tf.where(masked_indices, labels, -100) # We only compute loss on masked tokens - - perm_mask = [] - - for i in range(len(labels)): - # Generate permutation indices i.e. sample a random factorisation order for the sequence. This will - # determine which tokens a given token can attend to (encoded in `perm_mask`). - # Note: Length of token sequence being permuted has to be less than or equal to reused sequence length - # (see documentation for `mems`), otherwise information may leak through due to reuse. In this implementation, - # we assume that reused length is half of sequence length and permutation length is equal to reused length. - # This requires that the sequence length be even. - - # Create a linear factorisation order - # tf.range is the equivalent of torch.arange - perm_index = tf.range(labels_shape[1]) - # Split this into two halves, assuming that half the sequence is reused each time - perm_index = tf.transpose(tf.reshape(perm_index, (-1, labels_shape[1] // 2))) - # Permute the two halves such that they do not cross over - perm_index = tf.random.shuffle(perm_index) # Shuffles along the first dimension - # Flatten this out into the desired permuted factorisation order - perm_index = tf.reshape(tf.transpose(perm_index), (-1,)) - # Set the permutation indices of non-masked (non-functional) tokens to the - # smallest index (-1) so that: - # (1) They can be seen by all other positions - # (2) They cannot see masked positions, so there won't be information leak - perm_index = tf.where(~masked_indices[i] & non_func_mask[i], -1, perm_index) - # The logic for whether the i-th token can attend on the j-th token based on the factorisation order: - # 0 (can attend): If perm_index[i] > perm_index[j] or j is neither masked nor a functional token - # 1 (cannot attend): If perm_index[i] <= perm_index[j] and j is either masked or a functional token - perm_mask.append( - (tf.reshape(perm_index, (labels_shape[1], 1)) <= tf.reshape(perm_index, (1, labels_shape[1]))) - & masked_indices[i] - ) - perm_mask = tf.stack(perm_mask, axis=0) - - return tf.cast(inputs, tf.int64), tf.cast(perm_mask, tf.float32), target_mapping, tf.cast(labels, tf.int64) - def numpy_mask_tokens(self, inputs: Any) -> tuple[Any, Any, Any, Any]: """ The masked tokens to be predicted for a particular sequence are determined by the following algorithm: diff --git a/src/transformers/data/datasets/glue.py b/src/transformers/data/datasets/glue.py index d8db0dfebac1..808eb1e50578 100644 --- a/src/transformers/data/datasets/glue.py +++ b/src/transformers/data/datasets/glue.py @@ -69,10 +69,6 @@ class Split(Enum): class GlueDataset(Dataset): - """ - This will be superseded by a framework-agnostic approach soon. - """ - args: GlueDataTrainingArguments output_mode: str features: list[InputFeatures] diff --git a/src/transformers/data/datasets/language_modeling.py b/src/transformers/data/datasets/language_modeling.py index 07250ef3cb54..85d7e5360df3 100644 --- a/src/transformers/data/datasets/language_modeling.py +++ b/src/transformers/data/datasets/language_modeling.py @@ -38,10 +38,6 @@ class TextDataset(Dataset): - """ - This will be superseded by a framework-agnostic approach soon. - """ - def __init__( self, tokenizer: PreTrainedTokenizer, @@ -111,10 +107,6 @@ def __getitem__(self, i) -> torch.Tensor: class LineByLineTextDataset(Dataset): - """ - This will be superseded by a framework-agnostic approach soon. - """ - def __init__(self, tokenizer: PreTrainedTokenizer, file_path: str, block_size: int): warnings.warn( DEPRECATION_WARNING.format( @@ -144,10 +136,6 @@ def __getitem__(self, i) -> dict[str, torch.tensor]: class LineByLineWithRefDataset(Dataset): - """ - This will be superseded by a framework-agnostic approach soon. - """ - def __init__(self, tokenizer: PreTrainedTokenizer, file_path: str, block_size: int, ref_path: str): warnings.warn( DEPRECATION_WARNING.format( @@ -344,10 +332,6 @@ def __getitem__(self, i) -> dict[str, torch.tensor]: class TextDatasetForNextSentencePrediction(Dataset): - """ - This will be superseded by a framework-agnostic approach soon. - """ - def __init__( self, tokenizer: PreTrainedTokenizer, diff --git a/src/transformers/data/datasets/squad.py b/src/transformers/data/datasets/squad.py index fdee571e249b..d96d8224d6b9 100644 --- a/src/transformers/data/datasets/squad.py +++ b/src/transformers/data/datasets/squad.py @@ -107,10 +107,6 @@ class Split(Enum): class SquadDataset(Dataset): - """ - This will be superseded by a framework-agnostic approach soon. - """ - args: SquadDataTrainingArguments features: list[SquadFeatures] mode: Split diff --git a/src/transformers/data/processors/glue.py b/src/transformers/data/processors/glue.py index e005c9bcda13..abf03c917202 100644 --- a/src/transformers/data/processors/glue.py +++ b/src/transformers/data/processors/glue.py @@ -17,18 +17,14 @@ import os import warnings -from dataclasses import asdict from enum import Enum from typing import Optional, Union from ...tokenization_utils import PreTrainedTokenizer -from ...utils import is_tf_available, logging +from ...utils import logging from .utils import DataProcessor, InputExample, InputFeatures -if is_tf_available(): - import tensorflow as tf - logger = logging.get_logger(__name__) DEPRECATION_WARNING = ( @@ -39,7 +35,7 @@ def glue_convert_examples_to_features( - examples: Union[list[InputExample], "tf.data.Dataset"], + examples: list[InputExample], tokenizer: PreTrainedTokenizer, max_length: Optional[int] = None, task=None, @@ -50,7 +46,7 @@ def glue_convert_examples_to_features( Loads a data file into a list of `InputFeatures` Args: - examples: List of `InputExamples` or `tf.data.Dataset` containing the examples. + examples: List of `InputExamples` containing the examples. tokenizer: Instance of a tokenizer that will tokenize the examples max_length: Maximum example length. Defaults to the tokenizer's max_len task: GLUE task @@ -58,54 +54,15 @@ def glue_convert_examples_to_features( output_mode: String indicating the output mode. Either `regression` or `classification` Returns: - If the `examples` input is a `tf.data.Dataset`, will return a `tf.data.Dataset` containing the task-specific - features. If the input is a list of `InputExamples`, will return a list of task-specific `InputFeatures` which - can be fed to the model. + Will return a list of task-specific `InputFeatures` which can be fed to the model. """ warnings.warn(DEPRECATION_WARNING.format("function"), FutureWarning) - if is_tf_available() and isinstance(examples, tf.data.Dataset): - if task is None: - raise ValueError("When calling glue_convert_examples_to_features from TF, the task parameter is required.") - return _tf_glue_convert_examples_to_features(examples, tokenizer, max_length=max_length, task=task) return _glue_convert_examples_to_features( examples, tokenizer, max_length=max_length, task=task, label_list=label_list, output_mode=output_mode ) -if is_tf_available(): - - def _tf_glue_convert_examples_to_features( - examples: tf.data.Dataset, - tokenizer: PreTrainedTokenizer, - task=str, - max_length: Optional[int] = None, - ) -> tf.data.Dataset: - """ - Returns: - A `tf.data.Dataset` containing the task-specific features. - - """ - processor = glue_processors[task]() - examples = [processor.tfds_map(processor.get_example_from_tensor_dict(example)) for example in examples] - features = glue_convert_examples_to_features(examples, tokenizer, max_length=max_length, task=task) - label_type = tf.float32 if task == "sts-b" else tf.int64 - - def gen(): - for ex in features: - d = {k: v for k, v in asdict(ex).items() if v is not None} - label = d.pop("label") - yield (d, label) - - input_names = tokenizer.model_input_names - - return tf.data.Dataset.from_generator( - gen, - (dict.fromkeys(input_names, tf.int32), label_type), - ({k: tf.TensorShape([None]) for k in input_names}, tf.TensorShape([])), - ) - - def _glue_convert_examples_to_features( examples: list[InputExample], tokenizer: PreTrainedTokenizer, diff --git a/src/transformers/data/processors/squad.py b/src/transformers/data/processors/squad.py index 5f37eb018133..e8af1549a86e 100644 --- a/src/transformers/data/processors/squad.py +++ b/src/transformers/data/processors/squad.py @@ -24,7 +24,7 @@ from ...models.bert.tokenization_bert import whitespace_tokenize from ...tokenization_utils_base import BatchEncoding, PreTrainedTokenizerBase, TruncationStrategy -from ...utils import is_tf_available, is_torch_available, is_torch_hpu_available, logging +from ...utils import is_torch_available, is_torch_hpu_available, logging from .utils import DataProcessor @@ -36,8 +36,6 @@ import torch from torch.utils.data import TensorDataset -if is_tf_available(): - import tensorflow as tf logger = logging.get_logger(__name__) @@ -244,7 +242,6 @@ def squad_convert_example_to_features( cls_index = span["input_ids"].index(tokenizer.cls_token_id) # p_mask: mask with 1 for token than cannot be in the answer (0 for token which can be in an answer) - # Original TF implementation also keep the classification token (set to 0) p_mask = np.ones_like(span["token_type_ids"]) if tokenizer.padding_side == "right": p_mask[len(truncated_query) + sequence_added_tokens :] = 0 @@ -338,8 +335,8 @@ def squad_convert_examples_to_features( max_query_length: The maximum length of the query. is_training: whether to create features for model evaluation or model training. padding_strategy: Default to "max_length". Which padding strategy to use - return_dataset: Default False. Either 'pt' or 'tf'. - if 'pt': returns a torch.data.TensorDataset, if 'tf': returns a tf.data.Dataset + return_dataset: Default False. Can also be 'pt'. + if 'pt': returns a torch.data.TensorDataset. threads: multiple processing threads. @@ -430,110 +427,6 @@ def squad_convert_examples_to_features( ) return features, dataset - elif return_dataset == "tf": - if not is_tf_available(): - raise RuntimeError("TensorFlow must be installed to return a TensorFlow dataset.") - - def gen(): - for i, ex in enumerate(features): - if ex.token_type_ids is None: - yield ( - { - "input_ids": ex.input_ids, - "attention_mask": ex.attention_mask, - "feature_index": i, - "qas_id": ex.qas_id, - }, - { - "start_positions": ex.start_position, - "end_positions": ex.end_position, - "cls_index": ex.cls_index, - "p_mask": ex.p_mask, - "is_impossible": ex.is_impossible, - }, - ) - else: - yield ( - { - "input_ids": ex.input_ids, - "attention_mask": ex.attention_mask, - "token_type_ids": ex.token_type_ids, - "feature_index": i, - "qas_id": ex.qas_id, - }, - { - "start_positions": ex.start_position, - "end_positions": ex.end_position, - "cls_index": ex.cls_index, - "p_mask": ex.p_mask, - "is_impossible": ex.is_impossible, - }, - ) - - # Why have we split the batch into a tuple? PyTorch just has a list of tensors. - if "token_type_ids" in tokenizer.model_input_names: - train_types = ( - { - "input_ids": tf.int32, - "attention_mask": tf.int32, - "token_type_ids": tf.int32, - "feature_index": tf.int64, - "qas_id": tf.string, - }, - { - "start_positions": tf.int64, - "end_positions": tf.int64, - "cls_index": tf.int64, - "p_mask": tf.int32, - "is_impossible": tf.int32, - }, - ) - - train_shapes = ( - { - "input_ids": tf.TensorShape([None]), - "attention_mask": tf.TensorShape([None]), - "token_type_ids": tf.TensorShape([None]), - "feature_index": tf.TensorShape([]), - "qas_id": tf.TensorShape([]), - }, - { - "start_positions": tf.TensorShape([]), - "end_positions": tf.TensorShape([]), - "cls_index": tf.TensorShape([]), - "p_mask": tf.TensorShape([None]), - "is_impossible": tf.TensorShape([]), - }, - ) - else: - train_types = ( - {"input_ids": tf.int32, "attention_mask": tf.int32, "feature_index": tf.int64, "qas_id": tf.string}, - { - "start_positions": tf.int64, - "end_positions": tf.int64, - "cls_index": tf.int64, - "p_mask": tf.int32, - "is_impossible": tf.int32, - }, - ) - - train_shapes = ( - { - "input_ids": tf.TensorShape([None]), - "attention_mask": tf.TensorShape([None]), - "feature_index": tf.TensorShape([]), - "qas_id": tf.TensorShape([]), - }, - { - "start_positions": tf.TensorShape([]), - "end_positions": tf.TensorShape([]), - "cls_index": tf.TensorShape([]), - "p_mask": tf.TensorShape([None]), - "is_impossible": tf.TensorShape([]), - }, - ) - - return tf.data.Dataset.from_generator(gen, train_types, train_shapes) else: return features diff --git a/src/transformers/data/processors/utils.py b/src/transformers/data/processors/utils.py index 462156ebac38..63be55b558f9 100644 --- a/src/transformers/data/processors/utils.py +++ b/src/transformers/data/processors/utils.py @@ -20,7 +20,7 @@ from dataclasses import dataclass from typing import Optional, Union -from ...utils import is_tf_available, is_torch_available, logging +from ...utils import is_torch_available, logging logger = logging.get_logger(__name__) @@ -82,7 +82,7 @@ class DataProcessor: def get_example_from_tensor_dict(self, tensor_dict): """ - Gets an example from a dict with tensorflow tensors. + Gets an example from a dict. Args: tensor_dict: Keys and values should match the corresponding Glue @@ -251,9 +251,7 @@ def get_features( values) Returns: - If the `examples` input is a `tf.data.Dataset`, will return a `tf.data.Dataset` containing the - task-specific features. If the input is a list of `InputExamples`, will return a list of task-specific - `InputFeatures` which can be fed to the model. + Will return a list of task-specific `InputFeatures` which can be fed to the model. """ if max_length is None: @@ -315,21 +313,6 @@ def get_features( if return_tensors is None: return features - elif return_tensors == "tf": - if not is_tf_available(): - raise RuntimeError("return_tensors set to 'tf' but TensorFlow 2.0 can't be imported") - import tensorflow as tf - - def gen(): - for ex in features: - yield ({"input_ids": ex.input_ids, "attention_mask": ex.attention_mask}, ex.label) - - dataset = tf.data.Dataset.from_generator( - gen, - ({"input_ids": tf.int32, "attention_mask": tf.int32}, tf.int64), - ({"input_ids": tf.TensorShape([None]), "attention_mask": tf.TensorShape([None])}, tf.TensorShape([])), - ) - return dataset elif return_tensors == "pt": if not is_torch_available(): raise RuntimeError("return_tensors set to 'pt' but PyTorch can't be imported") @@ -346,4 +329,4 @@ def gen(): dataset = TensorDataset(all_input_ids, all_attention_mask, all_labels) return dataset else: - raise ValueError("return_tensors should be one of 'tf' or 'pt'") + raise ValueError("return_tensors should be `'pt'` or `None`") diff --git a/src/transformers/dependency_versions_table.py b/src/transformers/dependency_versions_table.py index ab6e747d14db..28a9f84b92a8 100644 --- a/src/transformers/dependency_versions_table.py +++ b/src/transformers/dependency_versions_table.py @@ -18,7 +18,6 @@ "faiss-cpu": "faiss-cpu", "fastapi": "fastapi", "filelock": "filelock", - "flax": "flax>=0.4.1,<=0.7.0", "ftfy": "ftfy", "fugashi": "fugashi>=1.0", "GitPython": "GitPython<3.1.19", @@ -27,12 +26,8 @@ "huggingface-hub": "huggingface-hub>=0.34.0,<1.0", "importlib_metadata": "importlib_metadata", "ipadic": "ipadic>=1.0.0,<2.0", - "jax": "jax>=0.4.1,<=0.4.13", - "jaxlib": "jaxlib>=0.4.1,<=0.4.13", "jinja2": "jinja2>=3.1.0", "kenlm": "kenlm", - "keras": "keras>2.9,<2.16", - "keras-nlp": "keras-nlp>=0.3.1,<0.14.0", "kernels": "kernels>=0.6.1,<=0.9", "librosa": "librosa", "natten": "natten>=0.14.6,<0.15.0", @@ -75,18 +70,13 @@ "sagemaker": "sagemaker>=2.31.0", "schedulefree": "schedulefree>=1.2.6", "scikit-learn": "scikit-learn", - "scipy": "scipy<1.13.0", + "scipy": "scipy", "sentencepiece": "sentencepiece>=0.1.91,!=0.1.92", "sigopt": "sigopt", "starlette": "starlette", "sudachipy": "sudachipy>=0.6.6", "sudachidict_core": "sudachidict_core>=20220729", "tensorboard": "tensorboard", - "tensorflow-cpu": "tensorflow-cpu>2.9,<2.16", - "tensorflow": "tensorflow>2.9,<2.16", - "tensorflow-text": "tensorflow-text<2.16", - "tensorflow-probability": "tensorflow-probability<0.24", - "tf2onnx": "tf2onnx", "timeout-decorator": "timeout-decorator", "tiktoken": "tiktoken", "timm": "timm<=1.0.19,!=1.0.18", diff --git a/src/transformers/feature_extraction_sequence_utils.py b/src/transformers/feature_extraction_sequence_utils.py index e0be17bd7d28..1a48062cb5c1 100644 --- a/src/transformers/feature_extraction_sequence_utils.py +++ b/src/transformers/feature_extraction_sequence_utils.py @@ -20,7 +20,7 @@ import numpy as np from .feature_extraction_utils import BatchFeature, FeatureExtractionMixin -from .utils import PaddingStrategy, TensorType, is_tf_tensor, is_torch_tensor, logging, to_numpy +from .utils import PaddingStrategy, TensorType, is_torch_tensor, logging, to_numpy logger = logging.get_logger(__name__) @@ -74,7 +74,7 @@ def pad( - If the `processed_features` passed are dictionary of numpy arrays, PyTorch tensors or TensorFlow tensors, the + If the `processed_features` passed are dictionary of numpy arrays or PyTorch tensors the result will use the same type unless you provide a different tensor type with `return_tensors`. In the case of PyTorch tensors, you will lose the specific device of your tensors however. @@ -87,7 +87,7 @@ def pad( list[float]]]*) so you can use this method during preprocessing as well as in a PyTorch Dataloader collate function. - Instead of `list[float]` you can have tensors (numpy arrays, PyTorch tensors or TensorFlow tensors), + Instead of `list[float]` you can have tensors (numpy arrays or PyTorch tensors), see the note above for the return type. padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `True`): Select a strategy to pad the returned sequences (according to the model's padding side and padding @@ -116,7 +116,6 @@ def pad( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. """ @@ -145,7 +144,7 @@ def pad( processed_features["attention_mask"] = [] return processed_features - # If we have PyTorch/TF tensors or lists as inputs, we cast them as Numpy arrays + # If we have PyTorch tensors or lists as inputs, we cast them as Numpy arrays # and rebuild them afterwards if no return_tensors is specified # Note that we lose the specific device the tensor may be on for PyTorch @@ -159,16 +158,14 @@ def pad( first_element = required_input[index][0] if return_tensors is None: - if is_tf_tensor(first_element): - return_tensors = "tf" - elif is_torch_tensor(first_element): + if is_torch_tensor(first_element): return_tensors = "pt" elif isinstance(first_element, (int, float, list, tuple, np.ndarray)): return_tensors = "np" else: raise ValueError( f"type of {first_element} unknown: {type(first_element)}. " - "Should be one of a python, numpy, pytorch or tensorflow object." + "Should be one of a python, numpy, or pytorch object." ) for key, value in processed_features.items(): diff --git a/src/transformers/feature_extraction_utils.py b/src/transformers/feature_extraction_utils.py index a9ff39b0cc19..fd9eb56941b9 100644 --- a/src/transformers/feature_extraction_utils.py +++ b/src/transformers/feature_extraction_utils.py @@ -32,12 +32,9 @@ TensorType, copy_func, download_url, - is_flax_available, - is_jax_tensor, is_numpy_array, is_offline_mode, is_remote_url, - is_tf_available, is_torch_available, is_torch_device, is_torch_dtype, @@ -71,7 +68,7 @@ class BatchFeature(UserDict): Dictionary of lists/arrays/tensors returned by the __call__/pad methods ('input_values', 'attention_mask', etc.). tensor_type (`Union[None, str, TensorType]`, *optional*): - You can give a tensor_type here to convert the lists of integers in PyTorch/TensorFlow/Numpy Tensors at + You can give a tensor_type here to convert the lists of integers in PyTorch/Numpy Tensors at initialization. """ @@ -110,21 +107,7 @@ def _get_is_as_tensor_fns(self, tensor_type: Optional[Union[str, TensorType]] = if not isinstance(tensor_type, TensorType): tensor_type = TensorType(tensor_type) - # Get a function reference for the correct framework - if tensor_type == TensorType.TENSORFLOW: - logger.warning_once( - "TensorFlow and JAX classes are deprecated and will be removed in Transformers v5. We " - "recommend migrating to PyTorch classes or pinning your version of Transformers." - ) - if not is_tf_available(): - raise ImportError( - "Unable to convert output to TensorFlow tensors format, TensorFlow is not installed." - ) - import tensorflow as tf - - as_tensor = tf.constant - is_tensor = tf.is_tensor - elif tensor_type == TensorType.PYTORCH: + if tensor_type == TensorType.PYTORCH: if not is_torch_available(): raise ImportError("Unable to convert output to PyTorch tensors format, PyTorch is not installed.") import torch # noqa @@ -145,17 +128,6 @@ def as_tensor(value): return torch.tensor(value) is_tensor = torch.is_tensor - elif tensor_type == TensorType.JAX: - logger.warning_once( - "TensorFlow and JAX classes are deprecated and will be removed in Transformers v5. We " - "recommend migrating to PyTorch classes or pinning your version of Transformers." - ) - if not is_flax_available(): - raise ImportError("Unable to convert output to JAX tensors format, JAX is not installed.") - import jax.numpy as jnp # noqa: F811 - - as_tensor = jnp.array - is_tensor = is_jax_tensor else: def as_tensor(value, dtype=None): diff --git a/src/transformers/file_utils.py b/src/transformers/file_utils.py index fc6f722262d9..91d7974b55c1 100644 --- a/src/transformers/file_utils.py +++ b/src/transformers/file_utils.py @@ -31,7 +31,6 @@ ENV_VARS_TRUE_AND_AUTO_VALUES, ENV_VARS_TRUE_VALUES, FEATURE_EXTRACTOR_NAME, - FLAX_WEIGHTS_NAME, HF_MODULES_CACHE, HUGGINGFACE_CO_PREFIX, HUGGINGFACE_CO_RESOLVE_ENDPOINT, @@ -42,14 +41,9 @@ S3_BUCKET_PREFIX, SENTENCEPIECE_UNDERLINE, SPIECE_UNDERLINE, - TF2_WEIGHTS_NAME, - TF_WEIGHTS_NAME, TORCH_FX_REQUIRED_VERSION, TRANSFORMERS_CACHE, TRANSFORMERS_DYNAMIC_MODULE_NAME, - USE_JAX, - USE_TF, - USE_TORCH, WEIGHTS_INDEX_NAME, WEIGHTS_NAME, ContextManagers, @@ -79,7 +73,6 @@ is_datasets_available, is_detectron2_available, is_faiss_available, - is_flax_available, is_ftfy_available, is_g2p_en_available, is_in_notebook, @@ -106,9 +99,6 @@ is_spacy_available, is_speech_available, is_tensor, - is_tensorflow_probability_available, - is_tf2onnx_available, - is_tf_available, is_timm_available, is_tokenizers_available, is_torch_available, diff --git a/src/transformers/generation/__init__.py b/src/transformers/generation/__init__.py index 8500dc6ea80e..2cf4007a0192 100644 --- a/src/transformers/generation/__init__.py +++ b/src/transformers/generation/__init__.py @@ -14,7 +14,7 @@ from typing import TYPE_CHECKING -from ..utils import OptionalDependencyNotAvailable, _LazyModule, is_flax_available, is_tf_available, is_torch_available +from ..utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available _import_structure = { @@ -124,71 +124,6 @@ "SynthIDTextWatermarkDetector", ] -try: - if not is_tf_available(): - raise OptionalDependencyNotAvailable() -except OptionalDependencyNotAvailable: - pass -else: - _import_structure["tf_logits_process"] = [ - "TFForcedBOSTokenLogitsProcessor", - "TFForcedEOSTokenLogitsProcessor", - "TFForceTokensLogitsProcessor", - "TFLogitsProcessor", - "TFLogitsProcessorList", - "TFLogitsWarper", - "TFMinLengthLogitsProcessor", - "TFNoBadWordsLogitsProcessor", - "TFNoRepeatNGramLogitsProcessor", - "TFRepetitionPenaltyLogitsProcessor", - "TFSuppressTokensAtBeginLogitsProcessor", - "TFSuppressTokensLogitsProcessor", - "TFTemperatureLogitsWarper", - "TFTopKLogitsWarper", - "TFTopPLogitsWarper", - ] - _import_structure["tf_utils"] = [ - "TFGenerationMixin", - "TFGreedySearchDecoderOnlyOutput", - "TFGreedySearchEncoderDecoderOutput", - "TFSampleEncoderDecoderOutput", - "TFSampleDecoderOnlyOutput", - "TFBeamSearchEncoderDecoderOutput", - "TFBeamSearchDecoderOnlyOutput", - "TFBeamSampleEncoderDecoderOutput", - "TFBeamSampleDecoderOnlyOutput", - "TFContrastiveSearchEncoderDecoderOutput", - "TFContrastiveSearchDecoderOnlyOutput", - ] - -try: - if not is_flax_available(): - raise OptionalDependencyNotAvailable() -except OptionalDependencyNotAvailable: - pass -else: - _import_structure["flax_logits_process"] = [ - "FlaxForcedBOSTokenLogitsProcessor", - "FlaxForcedEOSTokenLogitsProcessor", - "FlaxForceTokensLogitsProcessor", - "FlaxLogitsProcessor", - "FlaxLogitsProcessorList", - "FlaxLogitsWarper", - "FlaxMinLengthLogitsProcessor", - "FlaxSuppressTokensAtBeginLogitsProcessor", - "FlaxSuppressTokensLogitsProcessor", - "FlaxTemperatureLogitsWarper", - "FlaxTopKLogitsWarper", - "FlaxTopPLogitsWarper", - "FlaxWhisperTimeStampLogitsProcessor", - "FlaxNoRepeatNGramLogitsProcessor", - ] - _import_structure["flax_utils"] = [ - "FlaxGenerationMixin", - "FlaxGreedySearchOutput", - "FlaxSampleOutput", - "FlaxBeamSearchOutput", - ] if TYPE_CHECKING: from .configuration_utils import ( @@ -285,66 +220,6 @@ WatermarkDetectorOutput, ) - try: - if not is_tf_available(): - raise OptionalDependencyNotAvailable() - except OptionalDependencyNotAvailable: - pass - else: - from .tf_logits_process import ( - TFForcedBOSTokenLogitsProcessor, - TFForcedEOSTokenLogitsProcessor, - TFForceTokensLogitsProcessor, - TFLogitsProcessor, - TFLogitsProcessorList, - TFLogitsWarper, - TFMinLengthLogitsProcessor, - TFNoBadWordsLogitsProcessor, - TFNoRepeatNGramLogitsProcessor, - TFRepetitionPenaltyLogitsProcessor, - TFSuppressTokensAtBeginLogitsProcessor, - TFSuppressTokensLogitsProcessor, - TFTemperatureLogitsWarper, - TFTopKLogitsWarper, - TFTopPLogitsWarper, - ) - from .tf_utils import ( - TFBeamSampleDecoderOnlyOutput, - TFBeamSampleEncoderDecoderOutput, - TFBeamSearchDecoderOnlyOutput, - TFBeamSearchEncoderDecoderOutput, - TFContrastiveSearchDecoderOnlyOutput, - TFContrastiveSearchEncoderDecoderOutput, - TFGenerationMixin, - TFGreedySearchDecoderOnlyOutput, - TFGreedySearchEncoderDecoderOutput, - TFSampleDecoderOnlyOutput, - TFSampleEncoderDecoderOutput, - ) - - try: - if not is_flax_available(): - raise OptionalDependencyNotAvailable() - except OptionalDependencyNotAvailable: - pass - else: - from .flax_logits_process import ( - FlaxForcedBOSTokenLogitsProcessor, - FlaxForcedEOSTokenLogitsProcessor, - FlaxForceTokensLogitsProcessor, - FlaxLogitsProcessor, - FlaxLogitsProcessorList, - FlaxLogitsWarper, - FlaxMinLengthLogitsProcessor, - FlaxNoRepeatNGramLogitsProcessor, - FlaxSuppressTokensAtBeginLogitsProcessor, - FlaxSuppressTokensLogitsProcessor, - FlaxTemperatureLogitsWarper, - FlaxTopKLogitsWarper, - FlaxTopPLogitsWarper, - FlaxWhisperTimeStampLogitsProcessor, - ) - from .flax_utils import FlaxBeamSearchOutput, FlaxGenerationMixin, FlaxGreedySearchOutput, FlaxSampleOutput else: import sys diff --git a/src/transformers/generation/flax_logits_process.py b/src/transformers/generation/flax_logits_process.py deleted file mode 100644 index 08fa411dc6f5..000000000000 --- a/src/transformers/generation/flax_logits_process.py +++ /dev/null @@ -1,544 +0,0 @@ -# coding=utf-8 -# Copyright 2021 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. - -import inspect - -import jax -import jax.lax as lax -import jax.numpy as jnp -from jax.experimental import sparse - -from ..utils import add_start_docstrings -from ..utils.logging import get_logger - - -logger = get_logger(__name__) - - -LOGITS_PROCESSOR_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - scores (`jnp.ndarray` of shape `(batch_size, config.vocab_size)`): - Prediction scores of a language modeling head. These can be logits for each vocabulary when not using beam - search or log softmax for each vocabulary token when using beam search - kwargs (`dict[str, Any]`, *optional*): - Additional logits processor specific kwargs. - - Return: - `jnp.ndarray` of shape `(batch_size, config.vocab_size)`: The processed prediction scores. - -""" - - -class FlaxLogitsProcessor: - """Abstract base class for all logit processors that can be applied during generation.""" - - @add_start_docstrings(LOGITS_PROCESSOR_INPUTS_DOCSTRING) - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray) -> jnp.ndarray: - """Flax method for processing logits.""" - raise NotImplementedError( - f"{self.__class__} is an abstract class. Only classes inheriting this class can be called." - ) - - -class FlaxLogitsWarper: - """Abstract base class for all logit warpers that can be applied during generation with multinomial sampling.""" - - @add_start_docstrings(LOGITS_PROCESSOR_INPUTS_DOCSTRING) - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray) -> jnp.ndarray: - """Flax method for warping logits.""" - raise NotImplementedError( - f"{self.__class__} is an abstract class. Only classes inheriting this class can be called." - ) - - -class FlaxLogitsProcessorList(list): - """ - This class can be used to create a list of [`FlaxLogitsProcessor`] or [`FlaxLogitsWarper`] to subsequently process - a `scores` input tensor. This class inherits from list and adds a specific *__call__* method to apply each - [`FlaxLogitsProcessor`] or [`FlaxLogitsWarper`] to the inputs. - """ - - @add_start_docstrings(LOGITS_PROCESSOR_INPUTS_DOCSTRING) - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray, cur_len: int, **kwargs) -> jnp.ndarray: - for processor in self: - function_args = inspect.signature(processor.__call__).parameters - if len(function_args) > 3: - if not all(arg in kwargs for arg in list(function_args.keys())[2:]): - raise ValueError( - f"Make sure that all the required parameters: {list(function_args.keys())} for " - f"{processor.__class__} are passed to the logits processor." - ) - scores = processor(input_ids, scores, cur_len, **kwargs) - else: - scores = processor(input_ids, scores, cur_len) - return scores - - -class FlaxTemperatureLogitsWarper(FlaxLogitsWarper): - r""" - [`FlaxLogitsWarper`] for temperature (exponential scaling output probability distribution). - - Args: - temperature (`float`): - The value used to module the logits distribution. - """ - - def __init__(self, temperature: float): - if not isinstance(temperature, float) or not (temperature > 0): - raise ValueError(f"`temperature` has to be a strictly positive float, but is {temperature}") - - self.temperature = temperature - - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray, cur_len: int) -> jnp.ndarray: - scores = scores / self.temperature - return scores - - -class FlaxTopPLogitsWarper(FlaxLogitsWarper): - """ - [`FlaxLogitsWarper`] that performs top-p, i.e. restricting to top tokens summing to prob_cut_off <= prob_cut_off. - - Args: - top_p (`float`): - If set to < 1, only the smallest set of most probable tokens with probabilities that add up to `top_p` or - higher are kept for generation. - filter_value (`float`, *optional*, defaults to -inf): - All filtered values will be set to this float value. - min_tokens_to_keep (`int`, *optional*, defaults to 1): - Minimum number of tokens that cannot be filtered. - """ - - def __init__(self, top_p: float, filter_value: float = -float("Inf"), min_tokens_to_keep: int = 1): - if not isinstance(top_p, float) or (top_p < 0 or top_p > 1.0): - raise ValueError(f"`top_p` has to be a float > 0 and < 1, but is {top_p}") - if not isinstance(min_tokens_to_keep, int) or (min_tokens_to_keep < 1): - raise ValueError(f"`min_tokens_to_keep` has to be a positive integer, but is {min_tokens_to_keep}") - - self.top_p = top_p - self.filter_value = filter_value - self.min_tokens_to_keep = min_tokens_to_keep - - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray, cur_len: int) -> jnp.ndarray: - topk_scores, topk_indices = lax.top_k(scores, scores.shape[-1]) - - mask_scores = jnp.full_like(scores, self.filter_value) - cumulative_probs = jax.nn.softmax(topk_scores, axis=-1).cumsum(axis=-1) - score_mask = cumulative_probs < self.top_p - - # include the token that is higher than top_p as well - score_mask = jnp.roll(score_mask, 1) - score_mask |= score_mask.at[:, 0].set(True) - - # min tokens to keep - score_mask = score_mask.at[:, : self.min_tokens_to_keep].set(True) - - topk_next_scores = jnp.where(score_mask, topk_scores, mask_scores) - next_scores = jax.lax.sort_key_val(topk_indices, topk_next_scores)[-1] - - return next_scores - - -class FlaxTopKLogitsWarper(FlaxLogitsWarper): - r""" - [`FlaxLogitsWarper`] that performs top-k, i.e. restricting to the k highest probability elements. - - Args: - top_k (`int`): - The number of highest probability vocabulary tokens to keep for top-k-filtering. - filter_value (`float`, *optional*, defaults to -inf): - All filtered values will be set to this float value. - min_tokens_to_keep (`int`, *optional*, defaults to 1): - Minimum number of tokens that cannot be filtered. - """ - - def __init__(self, top_k: int, filter_value: float = -float("Inf"), min_tokens_to_keep: int = 1): - if not isinstance(top_k, int) or top_k <= 0: - raise ValueError(f"`top_k` has to be a strictly positive integer, but is {top_k}") - - self.top_k = max(top_k, min_tokens_to_keep) - self.filter_value = filter_value - - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray, cur_len: int) -> jnp.ndarray: - batch_size, vocab_size = scores.shape - next_scores_flat = jnp.full(batch_size * vocab_size, self.filter_value) - - topk = min(self.top_k, scores.shape[-1]) # Safety check - topk_scores, topk_indices = lax.top_k(scores, topk) - shift = jnp.broadcast_to((jnp.arange(batch_size) * vocab_size)[:, None], (batch_size, topk)).flatten() - topk_scores_flat = topk_scores.flatten() - topk_indices_flat = topk_indices.flatten() + shift - - next_scores_flat = next_scores_flat.at[topk_indices_flat].set(topk_scores_flat) - next_scores = next_scores_flat.reshape(batch_size, vocab_size) - return next_scores - - -class FlaxForcedBOSTokenLogitsProcessor(FlaxLogitsProcessor): - r""" - [`FlaxLogitsProcessor`] that enforces the specified token as the first generated token. - - Args: - bos_token_id (`int`): - The id of the token to force as the first generated token. - """ - - def __init__(self, bos_token_id: int): - self.bos_token_id = bos_token_id - - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray, cur_len: int) -> jnp.ndarray: - new_scores = jnp.full(scores.shape, -float("inf")) - - apply_penalty = 1 - jnp.bool_(cur_len - 1) - - scores = jnp.where(apply_penalty, new_scores.at[:, self.bos_token_id].set(0), scores) - - return scores - - -class FlaxForcedEOSTokenLogitsProcessor(FlaxLogitsProcessor): - r""" - [`FlaxLogitsProcessor`] that enforces the specified token as the last generated token when `max_length` is reached. - - Args: - max_length (`int`): - The maximum length of the sequence to be generated. - eos_token_id (`int`): - The id of the token to force as the last generated token when `max_length` is reached. - """ - - def __init__(self, max_length: int, eos_token_id: int): - self.max_length = max_length - self.eos_token_id = eos_token_id - - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray, cur_len: int) -> jnp.ndarray: - new_scores = jnp.full(scores.shape, -float("inf")) - - apply_penalty = 1 - jnp.bool_(cur_len - self.max_length + 1) - - scores = jnp.where(apply_penalty, new_scores.at[:, self.eos_token_id].set(0), scores) - - return scores - - -class FlaxMinLengthLogitsProcessor(FlaxLogitsProcessor): - r""" - [`FlaxLogitsProcessor`] enforcing a min-length by setting EOS probability to 0. - - Args: - min_length (`int`): - The minimum length below which the score of `eos_token_id` is set to `-float("Inf")`. - eos_token_id (`int`): - The id of the *end-of-sequence* token. - """ - - def __init__(self, min_length: int, eos_token_id: int): - if not isinstance(min_length, int) or min_length < 0: - raise ValueError(f"`min_length` has to be a positive integer, but is {min_length}") - - if not isinstance(eos_token_id, int) or eos_token_id < 0: - raise ValueError(f"`eos_token_id` has to be a positive integer, but is {eos_token_id}") - - self.min_length = min_length - self.eos_token_id = eos_token_id - - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray, cur_len: int) -> jnp.ndarray: - # create boolean flag to decide if min length penalty should be applied - apply_penalty = 1 - jnp.clip(cur_len - self.min_length, 0, 1) - - scores = jnp.where(apply_penalty, scores.at[:, self.eos_token_id].set(-float("inf")), scores) - - return scores - - -class FlaxSuppressTokensAtBeginLogitsProcessor(FlaxLogitsProcessor): - r""" - [`FlaxLogitsProcessor`] suppressing a list of tokens as soon as the `generate` function starts generating using - `begin_index` tokens. This should ensure that the tokens defined by `begin_suppress_tokens` are not sampled at the - beginning of the generation. - - Args: - begin_suppress_tokens (`list[int]`): - Tokens to not sample. - begin_index (`int`): - Index where the tokens are suppressed. - """ - - def __init__(self, begin_suppress_tokens, begin_index): - self.begin_suppress_tokens = list(begin_suppress_tokens) - self.begin_index = begin_index - - def __call__(self, input_ids, scores, cur_len: int): - apply_penalty = 1 - jnp.bool_(cur_len - self.begin_index) - - scores = jnp.where(apply_penalty, scores.at[:, self.begin_suppress_tokens].set(-float("inf")), scores) - - return scores - - -class FlaxSuppressTokensLogitsProcessor(FlaxLogitsProcessor): - r""" - [`FlaxLogitsProcessor`] suppressing a list of tokens at each decoding step. The processor will set their log probs - to be `-inf` so they are not sampled. - - Args: - suppress_tokens (`list`): - Tokens to not sample. - """ - - def __init__(self, suppress_tokens: list): - self.suppress_tokens = list(suppress_tokens) - - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray, cur_len: int) -> jnp.ndarray: - scores = scores.at[..., self.suppress_tokens].set(-float("inf")) - - return scores - - -class FlaxForceTokensLogitsProcessor(FlaxLogitsProcessor): - r""" - [`FlaxLogitsProcessor`] that takes a list of pairs of integers which indicates a mapping from generation indices to - token indices that will be forced before sampling. The processor will set their log probs to 0 and all other tokens - to `-inf` so that they are sampled at their corresponding index. - - Args: - force_token_map (`list`): - Map giving token ids and indices where they will be forced to be sampled. - """ - - def __init__(self, force_token_map): - force_token_map = dict(force_token_map) - # Converts the dictionary of format {index: token} containing the tokens to be forced to an array, where the - # index of the array corresponds to the index of the token to be forced, for XLA compatibility. - # Indexes without forced tokens will have a negative value. - force_token_array = jnp.ones((max(force_token_map.keys()) + 1), dtype=jnp.int32) * -1 - for index, token in force_token_map.items(): - if token is not None: - force_token_array = force_token_array.at[index].set(token) - self.force_token_array = jnp.int32(force_token_array) - - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray, cur_len: int) -> jnp.ndarray: - def _force_token(generation_idx): - batch_size = scores.shape[0] - current_token = self.force_token_array[generation_idx] - - new_scores = jnp.ones_like(scores, dtype=scores.dtype) * -float("inf") - updates = jnp.zeros((batch_size, 1), dtype=scores.dtype) - new_scores = lax.dynamic_update_slice(new_scores, updates, (0, current_token)) - return new_scores - - scores = lax.cond( - cur_len >= self.force_token_array.shape[0], - # If the current length is geq than the length of force_token_array, the processor does nothing. - lambda: scores, - # Otherwise, it may force a certain token. - lambda: lax.cond( - self.force_token_array[cur_len] >= 0, - # Only valid (positive) tokens are forced - lambda: _force_token(cur_len), - # Otherwise, the processor does nothing. - lambda: scores, - ), - ) - return scores - - -class FlaxWhisperTimeStampLogitsProcessor(FlaxLogitsProcessor): - r""" - Whisper specific Processor. This processor can be used to force a list of tokens. The processor will set their log - probs to `inf` so that they are sampled at their corresponding index. - - Args: - generate_config (`GenerateConfig`): - The generate config used to generate the output. The following parameters are required: - eos_token_id (`int`, *optional*, defaults to 50257): - The id of the *end-of-sequence* token. - no_timestamps_token_id (`int`, *optional*, defaults to 50363): - The id of the `"<|notimestamps|>"` token. - max_initial_timestamp_index (`int`, *optional*, defaults to 1): - Used to set the maximum value of the initial timestamp. This is used to prevent the model from - predicting timestamps that are too far in the future. - """ - - def __init__(self, generate_config, model_config, decoder_input_length): - self.eos_token_id = generate_config.eos_token_id - self.no_timestamps_token_id = generate_config.no_timestamps_token_id - self.timestamp_begin = generate_config.no_timestamps_token_id + 1 - - self.begin_index = decoder_input_length + 1 - - if generate_config.is_multilingual: - # room for language token and task token - self.begin_index += 2 - if hasattr(generate_config, "max_initial_timestamp_index"): - self.max_initial_timestamp_index = generate_config.max_initial_timestamp_index - else: - self.max_initial_timestamp_index = model_config.vocab_size - if self.max_initial_timestamp_index is None: - self.max_initial_timestamp_index = model_config.vocab_size - - def __call__(self, input_ids, scores, cur_len): - # suppress <|notimestamps|> which is handled by without_timestamps - scores = scores.at[:, self.no_timestamps_token_id].set(-float("inf")) - - def handle_pairs(input_ids_k, scores_k): - last_was_timestamp = jnp.where((cur_len - self.begin_index) >= 1, True, False) - last_was_timestamp = jnp.where( - input_ids_k[cur_len - 1] >= self.timestamp_begin, - True and last_was_timestamp, - False, - ) - - penultimate_was_timestamp = jnp.where((cur_len - self.begin_index) < 2, True, False) - penultimate_was_timestamp = jnp.where( - input_ids_k[cur_len - 2] >= self.timestamp_begin, - True, - penultimate_was_timestamp, - ) - - return jnp.where( - last_was_timestamp, - jnp.where( - penultimate_was_timestamp > 0, - scores_k.at[self.timestamp_begin :].set(-float("inf")), - scores_k.at[: self.eos_token_id].set(-float("inf")), - ), - scores_k, - ) - - scores = jax.vmap(handle_pairs)(input_ids, scores) - - apply_max_initial_timestamp = jnp.where(cur_len == self.begin_index, True, False) - apply_max_initial_timestamp = jnp.where( - self.max_initial_timestamp_index is not None, - True and apply_max_initial_timestamp, - False, - ) - - last_allowed = self.timestamp_begin + self.max_initial_timestamp_index - - scores = jnp.where( - apply_max_initial_timestamp, - scores.at[:, last_allowed + 1 :].set(-float("inf")), - scores, - ) - - # if sum of probability over timestamps is above any other token, sample timestamp - logprobs = jax.nn.log_softmax(scores, axis=-1) - - def handle_cumulative_probs(logprobs_k, scores_k): - timestamp_logprob = jax.nn.logsumexp(logprobs_k[self.timestamp_begin :], axis=-1) - max_text_token_logprob = jnp.max(logprobs_k[: self.timestamp_begin]) - return jnp.where( - timestamp_logprob > max_text_token_logprob, - scores_k.at[: self.timestamp_begin].set(-float("inf")), - scores_k, - ) - - scores = jax.vmap(handle_cumulative_probs)(logprobs, scores) - - return scores - - -class FlaxNoRepeatNGramLogitsProcessor(FlaxLogitsProcessor): - r""" - [`FlaxLogitsProcessor`] that enforces no repetition of n-grams. See - [Fairseq](https://github.com/pytorch/fairseq/blob/a07cb6f40480928c9e0548b737aadd36ee66ac76/fairseq/sequence_generator.py#L345). - - Args: - ngram_size (`int`): - All ngrams of size `ngram_size` can only occur once. - """ - - def __init__(self, ngram_size: int): - if not isinstance(ngram_size, int) or ngram_size <= 0: - raise ValueError(f"`ngram_size` has to be a strictly positive integer, but is {ngram_size}") - self.ngram_size = ngram_size - - def get_previous_ngrams(self, input_ids: jnp.ndarray, vocab_size: int, cur_len: int): - """ - get a matrix of size (batch_size,) + (vocab_size,)*n (for n-grams) that - represent the n-grams that occurred previously. - The BCOO representation allow to store only the few non-zero entries, instead of the full (huge) matrix - """ - batch_size, seq_len = input_ids.shape - # number of n-grams in the whole sequence - seq_ngrams = seq_len - (self.ngram_size - 1) - # number of n-grams in the currently generated sequence - cur_ngrams = cur_len - (self.ngram_size - 1) - - def body_fun(i, val): - b = i % batch_size - pos = i // batch_size - return val.at[i].set( - jnp.array( - [ - b, - ] - + [jnp.array(input_ids)[b, pos + j] for j in range(self.ngram_size)] - ) - ) - - shape = (batch_size * seq_ngrams, self.ngram_size + 1) - all_update_indices = jax.lax.fori_loop( - 0, batch_size * cur_ngrams, body_fun, jnp.zeros(shape, dtype=input_ids.dtype) - ) - - # ignore the n-grams not yet generated - data = (jnp.arange(batch_size * seq_ngrams) < batch_size * cur_ngrams).astype("float32") - - return sparse.BCOO((data, all_update_indices), shape=(batch_size,) + (vocab_size,) * self.ngram_size) - - def get_banned_tokens_mask(self, latest_tokens: jnp.ndarray, previous_ngrams) -> jnp.ndarray: - """ - Determines which tokens must be banned given latest tokens and the previously seen - ngrams. - """ - - @sparse.sparsify - @jax.vmap - def inner_fn(latest_tokens, previous_ngrams): - return previous_ngrams[tuple(latest_tokens)] - - return sparse.bcoo_todense(inner_fn(latest_tokens, previous_ngrams)) - - def __call__(self, input_ids: jnp.ndarray, scores: jnp.ndarray, cur_len: int) -> jnp.ndarray: - def true_fn(): - _, vocab_size = scores.shape - # store the previously seen n-grams - previous_ngrams = self.get_previous_ngrams(input_ids, vocab_size, cur_len) - - # get the n-1 last tokens that prefix the n-gram being generated - latest_tokens = jnp.zeros((input_ids.shape[0], self.ngram_size - 1), dtype=input_ids.dtype) - latest_tokens = jax.lax.dynamic_update_slice( - latest_tokens, - jax.lax.dynamic_slice( - input_ids, (0, cur_len - (self.ngram_size - 1)), (input_ids.shape[0], (self.ngram_size - 1)) - ), - (0, 0), - ) - - # compute the banned tokens, ie all the tokens that when added to the latest tokens lead to a n-gram that was previously generated - banned_tokens_indices_mask = self.get_banned_tokens_mask(latest_tokens, previous_ngrams).astype("bool") - return jnp.where(banned_tokens_indices_mask, -float("inf"), scores) - - output = jax.lax.cond((cur_len >= self.ngram_size - 1), true_fn, lambda: scores) - return output diff --git a/src/transformers/generation/flax_utils.py b/src/transformers/generation/flax_utils.py deleted file mode 100644 index e858a9813cea..000000000000 --- a/src/transformers/generation/flax_utils.py +++ /dev/null @@ -1,1032 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Google AI Flax Team Authors, and The HuggingFace Inc. team. -# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. -# -# 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. - - -import copy -import inspect -import warnings -from functools import partial -from typing import Any, Optional, Union - -import flax -import jax -import jax.numpy as jnp -import numpy as np -from jax import lax - -from ..models.auto import ( - FLAX_MODEL_FOR_CAUSAL_LM_MAPPING, - FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, - FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING, -) -from ..utils import ModelOutput, logging -from .configuration_utils import GenerationConfig -from .flax_logits_process import ( - FlaxForcedBOSTokenLogitsProcessor, - FlaxForcedEOSTokenLogitsProcessor, - FlaxForceTokensLogitsProcessor, - FlaxLogitsProcessorList, - FlaxMinLengthLogitsProcessor, - FlaxNoRepeatNGramLogitsProcessor, - FlaxSuppressTokensAtBeginLogitsProcessor, - FlaxSuppressTokensLogitsProcessor, - FlaxTemperatureLogitsWarper, - FlaxTopKLogitsWarper, - FlaxTopPLogitsWarper, -) - - -logger = logging.get_logger(__name__) - - -@flax.struct.dataclass -class FlaxGreedySearchOutput(ModelOutput): - """ - Flax Base class for outputs of decoder-only generation models using greedy search. - - - Args: - sequences (`jnp.ndarray` of shape `(batch_size, max_length)`): - The generated sequences. - """ - - sequences: Optional[jnp.ndarray] = None - - -@flax.struct.dataclass -class FlaxSampleOutput(ModelOutput): - """ - Flax Base class for outputs of decoder-only generation models using sampling. - - - Args: - sequences (`jnp.ndarray` of shape `(batch_size, max_length)`): - The generated sequences. - """ - - sequences: Optional[jnp.ndarray] = None - - -@flax.struct.dataclass -class FlaxBeamSearchOutput(ModelOutput): - """ - Flax Base class for outputs of decoder-only generation models using greedy search. - - - Args: - sequences (`jnp.ndarray` of shape `(batch_size, max_length)`): - The generated sequences. - scores (`jnp.ndarray` of shape `(batch_size,)`): - The scores (log probabilities) of the generated sequences. - """ - - sequences: Optional[jnp.ndarray] = None - scores: Optional[jnp.ndarray] = None - - -@flax.struct.dataclass -class GreedyState: - cur_len: jnp.ndarray - sequences: jnp.ndarray - running_token: jnp.ndarray - is_sent_finished: jnp.ndarray - model_kwargs: dict[str, jnp.ndarray] - - -@flax.struct.dataclass -class SampleState: - cur_len: jnp.ndarray - sequences: jnp.ndarray - running_token: jnp.ndarray - is_sent_finished: jnp.ndarray - prng_key: jnp.ndarray - model_kwargs: dict[str, jnp.ndarray] - - -@flax.struct.dataclass -class BeamSearchState: - cur_len: jnp.ndarray - running_sequences: jnp.ndarray - running_scores: jnp.ndarray - sequences: jnp.ndarray - scores: jnp.ndarray - is_sent_finished: jnp.ndarray - model_kwargs: dict[str, jnp.ndarray] - - -class FlaxGenerationMixin: - """ - A class containing all functions for auto-regressive text generation, to be used as a mixin in - [`FlaxPreTrainedModel`]. - - The class exposes [`~generation.FlaxGenerationMixin.generate`], which can be used for: - - *greedy decoding* by calling [`~generation.FlaxGenerationMixin._greedy_search`] if `num_beams=1` and - `do_sample=False` - - *multinomial sampling* by calling [`~generation.FlaxGenerationMixin._sample`] if `num_beams=1` and - `do_sample=True` - - *beam-search decoding* by calling [`~generation.FlaxGenerationMixin._beam_search`] if `num_beams>1` and - `do_sample=False` - - You do not need to call any of the above methods directly. Pass custom parameter values to 'generate' instead. To - learn more about decoding strategies refer to the [text generation strategies guide](../generation_strategies). - """ - - def prepare_inputs_for_generation(self, *args, **kwargs): - raise NotImplementedError( - "A model class needs to define a `prepare_inputs_for_generation` method in order to use `generate`." - ) - - @staticmethod - def _run_loop_in_debug(cond_fn, body_fn, init_state): - """ - Run generation in untraced mode. This should only be used for debugging purposes. - """ - state = init_state - while cond_fn(state): - state = body_fn(state) - return state - - def _prepare_encoder_decoder_kwargs_for_generation(self, input_ids, params, model_kwargs): - encoder_kwargs = { - argument: value - for argument, value in model_kwargs.items() - if not (argument.startswith("decoder_") or argument.startswith("cross_attn")) - } - model_kwargs["encoder_outputs"] = self.encode(input_ids, params=params, return_dict=True, **encoder_kwargs) - return model_kwargs - - def _prepare_decoder_input_ids_for_generation( - self, - batch_size: int, - decoder_start_token_id: Optional[int] = None, - bos_token_id: Optional[int] = None, - model_kwargs: Optional[dict[str, jnp.ndarray]] = None, - ) -> jnp.ndarray: - if model_kwargs is not None and "decoder_input_ids" in model_kwargs: - # Only use this arg if not None, otherwise just remove from model_kwargs - decoder_input_ids = model_kwargs.pop("decoder_input_ids") - if decoder_input_ids is not None: - return decoder_input_ids - decoder_start_token_id = self._get_decoder_start_token_id(decoder_start_token_id, bos_token_id) - return jnp.array(decoder_start_token_id, dtype="i4").reshape(1, -1).repeat(batch_size, axis=0) - - def _get_decoder_start_token_id( - self, decoder_start_token_id: Optional[int] = None, bos_token_id: Optional[int] = None - ) -> int: - # retrieve decoder_start_token_id for encoder-decoder models - # fall back to bos_token_id if necessary - decoder_start_token_id = ( - decoder_start_token_id - if decoder_start_token_id is not None - else self.generation_config.decoder_start_token_id - ) - bos_token_id = bos_token_id if bos_token_id is not None else self.generation_config.bos_token_id - if decoder_start_token_id is not None: - return decoder_start_token_id - elif ( - hasattr(self.config, "decoder") - and hasattr(self.config.decoder, "decoder_start_token_id") - and self.config.decoder.decoder_start_token_id is not None - ): - return self.config.decoder.decoder_start_token_id - elif bos_token_id is not None: - return bos_token_id - elif ( - hasattr(self.config, "decoder") - and hasattr(self.config.decoder, "bos_token_id") - and self.config.decoder.bos_token_id is not None - ): - return self.config.decoder.bos_token_id - raise ValueError( - "`decoder_start_token_id` or `bos_token_id` has to be defined for encoder-decoder generation." - ) - - @staticmethod - def _expand_to_num_beams(tensor, num_beams): - return jnp.broadcast_to(tensor[:, None], (tensor.shape[0], num_beams) + tensor.shape[1:]) - - def _adapt_logits_for_beam_search(self, logits): - """ - This function can be overwritten in the specific modeling_flax_.py classes to allow for custom beam - search behavior. Note that the only model that overwrites this method is [`~transformers.FlaxMarianMTModel`]. - """ - return logits - - def _validate_model_class(self): - """ - Confirms that the model class is compatible with generation. If not, raises an exception that points to the - right class to use. - """ - if not self.can_generate(): - generate_compatible_mappings = [ - FLAX_MODEL_FOR_CAUSAL_LM_MAPPING, - FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING, - FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, - ] - generate_compatible_classes = set() - for model_mapping in generate_compatible_mappings: - supported_models = model_mapping.get(type(self.config), default=None) - if supported_models is not None: - generate_compatible_classes.add(supported_models.__name__) - exception_message = ( - f"The current model class ({self.__class__.__name__}) is not compatible with `.generate()`, as " - "it doesn't have a language model head." - ) - if generate_compatible_classes: - exception_message += f" Please use one of the following classes instead: {generate_compatible_classes}" - raise TypeError(exception_message) - - def _validate_model_kwargs(self, model_kwargs: dict[str, Any]): - """Validates model kwargs for generation. Generate argument typos will also be caught here.""" - unused_model_args = [] - model_args = set(inspect.signature(self.prepare_inputs_for_generation).parameters) - # `kwargs`/`model_kwargs` is often used to handle optional forward pass inputs like `attention_mask`. If - # `prepare_inputs_for_generation` doesn't accept them, then a stricter check can be made ;) - if "kwargs" in model_args or "model_kwargs" in model_args: - model_args |= set(inspect.signature(self.__call__).parameters) - for key, value in model_kwargs.items(): - if value is not None and key not in model_args: - unused_model_args.append(key) - - if unused_model_args: - raise ValueError( - f"The following `model_kwargs` are not used by the model: {unused_model_args} (note: typos in the" - " generate arguments will also show up in this list)" - ) - - def generate( - self, - input_ids: jnp.ndarray, - generation_config: Optional[GenerationConfig] = None, - prng_key: Optional[jnp.ndarray] = None, - trace: bool = True, - params: Optional[dict[str, jnp.ndarray]] = None, - logits_processor: Optional[FlaxLogitsProcessorList] = None, - **kwargs, - ): - r""" - Generates sequences of token ids for models with a language modeling head. - - Parameters: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - The sequence used as a prompt for the generation. - generation_config (`~generation.GenerationConfig`, *optional*): - The generation configuration to be used as base parametrization for the generation call. `**kwargs` - passed to generate matching the attributes of `generation_config` will override them. If - `generation_config` is not provided, the default will be used, which had the following loading - priority: 1) from the `generation_config.json` model file, if it exists; 2) from the model - configuration. Please note that unspecified parameters will inherit [`~generation.GenerationConfig`]'s - default values, whose documentation should be checked to parameterize generation. - trace (`bool`, *optional*, defaults to `True`): - Whether to trace generation. Setting `trace=False` should only be used for debugging and will lead to a - considerably slower runtime. - params (`dict[str, jnp.ndarray]`, *optional*): - Optionally the model parameters can be passed. Can be useful for parallelized generation. - logits_processor (`FlaxLogitsProcessorList `, *optional*): - Custom logits processors that complement the default logits processors built from arguments and - generation config. If a logit processor is passed that is already created with the arguments or a - generation config an error is thrown. This feature is intended for advanced users. - kwargs (`dict[str, Any]`, *optional*): - Ad hoc parametrization of `generate_config` and/or additional model-specific kwargs that will be - forwarded to the `forward` function of the model. If the model is an encoder-decoder model, encoder - specific kwargs should not be prefixed and decoder specific kwargs should be prefixed with *decoder_*. - - Return: - [`~utils.ModelOutput`]. - - """ - # Handle `generation_config` and kwargs that might update it, and validate the `.generate()` call - self._validate_model_class() - - # priority: `generation_config` argument > `model.generation_config` (the default generation config) - if generation_config is None: - # legacy: users may modify the model configuration to control generation. To trigger this legacy behavior, - # two conditions must be met - # 1) the generation config must have been created from the model config (`_from_model_config` field); - # 2) the generation config must have seen no modification since its creation (the hash is the same). - if self.generation_config._from_model_config and self.generation_config._original_object_hash == hash( - self.generation_config - ): - new_generation_config = GenerationConfig.from_model_config(self.config) - if new_generation_config != self.generation_config: - warnings.warn( - "You have modified the pretrained model configuration to control generation. This is a" - " deprecated strategy to control generation and will be removed soon, in a future version." - " Please use and modify the model generation configuration (see" - " https://huggingface.co/docs/transformers/generation_strategies#default-text-generation-configuration )" - ) - self.generation_config = new_generation_config - generation_config = self.generation_config - - generation_config = copy.deepcopy(generation_config) - model_kwargs = generation_config.update(**kwargs) # All unused kwargs must be model kwargs - self._validate_model_kwargs(model_kwargs.copy()) - - logits_processor = logits_processor if logits_processor is not None else FlaxLogitsProcessorList() - - # set init values - prng_key = prng_key if prng_key is not None else jax.random.PRNGKey(0) - - if generation_config.pad_token_id is None and generation_config.eos_token_id is not None: - if model_kwargs.get("attention_mask") is None: - logger.warning( - "The attention mask and the pad token id were not set. As a consequence, you may observe " - "unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results." - ) - eos_token_id = generation_config.eos_token_id - if isinstance(eos_token_id, list): - eos_token_id = eos_token_id[0] - generation_config.pad_token_id = eos_token_id - - if generation_config.decoder_start_token_id is None and self.config.is_encoder_decoder: - raise ValueError("`decoder_start_token_id` has to be defined for encoder-decoder generation.") - - # decoder-only models should use left-padding for generation (can't be checked with `trace=True`) - if not self.config.is_encoder_decoder and not trace: - if ( - generation_config.pad_token_id is not None - and jnp.sum(input_ids[:, -1] == generation_config.pad_token_id) > 0 - ): - logger.warning( - "A decoder-only architecture is being used, but right-padding was detected! For correct " - "generation results, please set `padding_side='left'` when initializing the tokenizer." - ) - - batch_size = input_ids.shape[0] - - if self.config.is_encoder_decoder: - # add encoder_outputs to model_kwargs - if model_kwargs.get("encoder_outputs") is None: - model_kwargs = self._prepare_encoder_decoder_kwargs_for_generation(input_ids, params, model_kwargs) - # prepare decoder_input_ids for generation - input_ids = self._prepare_decoder_input_ids_for_generation( - batch_size, - decoder_start_token_id=generation_config.decoder_start_token_id, - bos_token_id=generation_config.bos_token_id, - model_kwargs=model_kwargs, - ) - - # Prepare `max_length` depending on other stopping criteria. - input_ids_seq_length = input_ids.shape[-1] - has_default_max_length = kwargs.get("max_length") is None and generation_config.max_length is not None - if has_default_max_length and generation_config.max_new_tokens is None and generation_config.max_length == 20: - # 20 is the default max_length of the generation config - warnings.warn( - f"Using the model-agnostic default `max_length` (={generation_config.max_length}) " - "to control the generation length. recommend setting `max_new_tokens` to control the maximum length of the generation.", - UserWarning, - ) - elif generation_config.max_new_tokens is not None: - if not has_default_max_length and generation_config.max_length is not None: - logger.warning( - f"Both `max_new_tokens` (={generation_config.max_new_tokens}) and `max_length`(=" - f"{generation_config.max_length}) seem to have been set. `max_new_tokens` will take precedence. " - "Please refer to the documentation for more information. " - "(https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)" - ) - generation_config.max_length = generation_config.max_new_tokens + input_ids_seq_length - else: # by default let's always generate 20 new tokens - if generation_config.max_length == GenerationConfig().max_length: - generation_config.max_length = generation_config.max_length + input_ids_seq_length - max_position_embeddings = getattr(self.config, "max_position_embeddings", None) - if max_position_embeddings is not None: - generation_config.max_length = min(generation_config.max_length, max_position_embeddings) - - if generation_config.min_length is not None and generation_config.min_length > generation_config.max_length: - raise ValueError( - f"Unfeasable length constraints: the minimum length ({generation_config.min_length}) is larger than" - f" the maximum length ({generation_config.max_length})" - ) - if input_ids_seq_length >= generation_config.max_length: - input_ids_string = "decoder_input_ids" if self.config.is_encoder_decoder else "input_ids" - logger.warning( - f"Input length of {input_ids_string} is {input_ids_seq_length}, but `max_length` is set to" - f" {generation_config.max_length}. This can lead to unexpected behavior. You should consider" - " increasing`max_new_tokens`." - ) - - logits_processor = self._get_logits_processor( - generation_config=generation_config, - input_ids_seq_length=input_ids_seq_length, - logits_processor=logits_processor, - ) - - if not generation_config.do_sample and generation_config.num_beams == 1: - return self._greedy_search( - input_ids, - generation_config.max_length, - generation_config.pad_token_id, - generation_config.eos_token_id, - logits_processor=logits_processor, - trace=trace, - params=params, - model_kwargs=model_kwargs, - ) - elif generation_config.do_sample and generation_config.num_beams == 1: - logits_warper = self._get_logits_warper(generation_config=generation_config) - return self._sample( - input_ids, - generation_config.max_length, - generation_config.pad_token_id, - generation_config.eos_token_id, - prng_key, - logits_warper=logits_warper, - logits_processor=logits_processor, - trace=trace, - params=params, - model_kwargs=model_kwargs, - ) - elif not generation_config.do_sample and generation_config.num_beams > 1: - # broadcast input_ids & encoder_outputs - input_ids = self._expand_to_num_beams(input_ids, num_beams=generation_config.num_beams) - - if "encoder_outputs" in model_kwargs: - model_kwargs["encoder_outputs"]["last_hidden_state"] = self._expand_to_num_beams( - model_kwargs["encoder_outputs"]["last_hidden_state"], num_beams=generation_config.num_beams - ) - - for kwarg in ["attention_mask", "decoder_attention_mask"]: - if kwarg in model_kwargs: - model_kwargs[kwarg] = self._expand_to_num_beams( - model_kwargs[kwarg], num_beams=generation_config.num_beams - ) - - return self._beam_search( - input_ids, - generation_config.max_length, - generation_config.pad_token_id, - generation_config.eos_token_id, - length_penalty=generation_config.length_penalty, - early_stopping=generation_config.early_stopping, - logits_processor=logits_processor, - trace=trace, - params=params, - num_return_sequences=generation_config.num_return_sequences, - model_kwargs=model_kwargs, - ) - else: - raise NotImplementedError("`Beam sampling is currently not implemented.") - - def _get_logits_warper(self, generation_config: GenerationConfig) -> FlaxLogitsProcessorList: - """ - This class returns a [`FlaxLogitsProcessorList`] list object that contains all relevant [`FlaxLogitsWarper`] - instances used for multinomial sampling. - """ - warpers = FlaxLogitsProcessorList() - - if generation_config.temperature is not None and generation_config.temperature != 1.0: - warpers.append(FlaxTemperatureLogitsWarper(generation_config.temperature)) - if generation_config.top_k is not None and generation_config.top_k != 0: - warpers.append(FlaxTopKLogitsWarper(top_k=generation_config.top_k, min_tokens_to_keep=1)) - if generation_config.top_p is not None and generation_config.top_p < 1.0: - warpers.append(FlaxTopPLogitsWarper(top_p=generation_config.top_p, min_tokens_to_keep=1)) - - return warpers - - def _get_logits_processor( - self, - generation_config: GenerationConfig, - input_ids_seq_length: int, - logits_processor: Optional[FlaxLogitsProcessorList], - ) -> FlaxLogitsProcessorList: - """ - This class returns a [`FlaxLogitsProcessorList`] list object that contains all relevant [`FlaxLogitsProcessor`] - instances used to modify the scores of the language model head. - """ - processors = FlaxLogitsProcessorList() - - if ( - generation_config.min_length is not None - and generation_config.eos_token_id is not None - and generation_config.min_length > -1 - ): - processors.append( - FlaxMinLengthLogitsProcessor(generation_config.min_length, generation_config.eos_token_id) - ) - if generation_config.forced_bos_token_id is not None: - processors.append(FlaxForcedBOSTokenLogitsProcessor(generation_config.forced_bos_token_id)) - if generation_config.forced_eos_token_id is not None: - processors.append( - FlaxForcedEOSTokenLogitsProcessor(generation_config.max_length, generation_config.forced_eos_token_id) - ) - if generation_config.suppress_tokens is not None: - processors.append(FlaxSuppressTokensLogitsProcessor(generation_config.suppress_tokens)) - if generation_config.begin_suppress_tokens is not None: - begin_index = input_ids_seq_length - begin_index = ( - begin_index - if (input_ids_seq_length > 1 or generation_config.forced_bos_token_id is None) - else begin_index + 1 - ) - if ( - getattr(generation_config, "forced_decoder_ids", None) is not None - and len(generation_config.forced_decoder_ids) > 0 - ): - # generation starts after the last token that is forced - begin_index += generation_config.forced_decoder_ids[-1][0] - processors.append( - FlaxSuppressTokensAtBeginLogitsProcessor(generation_config.begin_suppress_tokens, begin_index) - ) - if getattr(generation_config, "forced_decoder_ids", None) is not None: - forced_decoder_ids = [ - [input_ids_seq_length + i[0] - 1, i[1]] for i in generation_config.forced_decoder_ids - ] - processors.append(FlaxForceTokensLogitsProcessor(forced_decoder_ids)) - if generation_config.no_repeat_ngram_size is not None and generation_config.no_repeat_ngram_size > 0: - processors.append(FlaxNoRepeatNGramLogitsProcessor(generation_config.no_repeat_ngram_size)) - processors = self._merge_criteria_processor_list(processors, logits_processor) - - return processors - - def _merge_criteria_processor_list( - self, - default_list: FlaxLogitsProcessorList, - custom_list: FlaxLogitsProcessorList, - ) -> FlaxLogitsProcessorList: - if len(custom_list) == 0: - return default_list - for default in default_list: - for custom in custom_list: - if type(custom) is type(default): - object_type = "logits processor" - raise ValueError( - f"A custom {object_type} of type {type(custom)} with values {custom} has been passed to" - f" `generate`, but it has already been created with the values {default}. {default} has been" - " created by passing the corresponding arguments to generate or by the model's config default" - f" values. If you just want to change the default values of {object_type} consider passing" - f" them as arguments to `generate` instead of using a custom {object_type}." - ) - default_list.extend(custom_list) - return default_list - - def _greedy_search( - self, - input_ids: None, - max_length: Optional[int] = None, - pad_token_id: Optional[int] = None, - eos_token_id: Optional[int] = None, - logits_processor: Optional[FlaxLogitsProcessorList] = None, - trace: bool = True, - params: Optional[dict[str, jnp.ndarray]] = None, - model_kwargs: Optional[dict[str, jnp.ndarray]] = None, - ): - # init values - max_length = max_length if max_length is not None else self.generation_config.max_length - pad_token_id = pad_token_id if pad_token_id is not None else self.generation_config.pad_token_id - eos_token_id = eos_token_id if eos_token_id is not None else self.generation_config.eos_token_id - - batch_size, cur_len = input_ids.shape - - eos_token_id = jnp.array(eos_token_id, dtype=jnp.int32 if eos_token_id is not None else None) - pad_token_id = jnp.array(pad_token_id, dtype=jnp.int32) - cur_len = jnp.array(cur_len) - - # per batch-item holding current token in loop. - sequences = jnp.full((batch_size, max_length), pad_token_id, dtype=jnp.int32) - sequences = lax.dynamic_update_slice(sequences, input_ids, (0, 0)) - - # per batch-item state bit indicating if sentence has finished. - is_sent_finished = jnp.zeros((batch_size,), dtype=jnp.bool_) - - # For Seq2Seq generation, we only need to use the decoder instead of the whole model in generation loop - # and pass it the `encoder_outputs`, which are part of the `model_kwargs`. - model = self.decode if self.config.is_encoder_decoder else self - # initialize model specific kwargs - model_kwargs = self.prepare_inputs_for_generation(input_ids, max_length, **model_kwargs) - - # initialize state - state = GreedyState( - cur_len=cur_len, - sequences=sequences, - running_token=input_ids, - is_sent_finished=is_sent_finished, - model_kwargs=model_kwargs, - ) - - def greedy_search_cond_fn(state): - """state termination condition fn.""" - has_reached_max_length = state.cur_len == max_length - all_sequence_finished = jnp.all(state.is_sent_finished) - finish_generation = jnp.logical_or(has_reached_max_length, all_sequence_finished) - return ~finish_generation - - def greedy_search_body_fn(state): - """state update fn.""" - model_outputs = model(state.running_token, params=params, **state.model_kwargs) - logits = model_outputs.logits[:, -1] - - # apply min_length, ... - logits = logits_processor(state.sequences, logits, state.cur_len) - - next_token = jnp.argmax(logits, axis=-1) - - next_token = next_token * ~state.is_sent_finished + pad_token_id * state.is_sent_finished - next_is_sent_finished = state.is_sent_finished | (next_token == eos_token_id) - next_token = next_token[:, None] - - next_sequences = lax.dynamic_update_slice(state.sequences, next_token, (0, state.cur_len)) - next_model_kwargs = self.update_inputs_for_generation(model_outputs, state.model_kwargs) - return GreedyState( - cur_len=state.cur_len + 1, - sequences=next_sequences, - running_token=next_token, - is_sent_finished=next_is_sent_finished, - model_kwargs=next_model_kwargs, - ) - - # The very first prompt often has sequence length > 1, so run outside of `lax.while_loop` to comply with TPU - if input_ids.shape[1] > 1: - state = greedy_search_body_fn(state) - - if not trace: - state = self._run_loop_in_debug(greedy_search_cond_fn, greedy_search_body_fn, state) - else: - state = lax.while_loop(greedy_search_cond_fn, greedy_search_body_fn, state) - - return FlaxGreedySearchOutput(sequences=state.sequences) - - def _sample( - self, - input_ids: None, - max_length: Optional[int] = None, - pad_token_id: Optional[int] = None, - eos_token_id: Optional[int] = None, - prng_key: Optional[jnp.ndarray] = None, - logits_processor: Optional[FlaxLogitsProcessorList] = None, - logits_warper: Optional[FlaxLogitsProcessorList] = None, - trace: bool = True, - params: Optional[dict[str, jnp.ndarray]] = None, - model_kwargs: Optional[dict[str, jnp.ndarray]] = None, - ): - # init values - max_length = max_length if max_length is not None else self.generation_config.max_length - pad_token_id = pad_token_id if pad_token_id is not None else self.generation_config.pad_token_id - eos_token_id = eos_token_id if eos_token_id is not None else self.generation_config.eos_token_id - prng_key = prng_key if prng_key is not None else jax.random.PRNGKey(0) - - batch_size, cur_len = input_ids.shape - - eos_token_id = jnp.array(eos_token_id, dtype=jnp.int32 if eos_token_id is not None else None) - pad_token_id = jnp.array(pad_token_id, dtype=jnp.int32) - cur_len = jnp.array(cur_len) - - # per batch-item holding current token in loop. - sequences = jnp.full((batch_size, max_length), pad_token_id, dtype=jnp.int32) - sequences = lax.dynamic_update_slice(sequences, input_ids, (0, 0)) - - # per batch-item state bit indicating if sentence has finished. - is_sent_finished = jnp.zeros((batch_size,), dtype=jnp.bool_) - - # For Seq2Seq generation, we only need to use the decoder instead of the whole model in generation loop - # and pass it the `encoder_outputs`, which are part of the `model_kwargs`. - model = self.decode if self.config.is_encoder_decoder else self - - # initialize model specific kwargs - model_kwargs = self.prepare_inputs_for_generation(input_ids, max_length, **model_kwargs) - - # initialize state - state = SampleState( - cur_len=cur_len, - sequences=sequences, - running_token=input_ids, - is_sent_finished=is_sent_finished, - prng_key=prng_key, - model_kwargs=model_kwargs, - ) - - def sample_search_cond_fn(state): - """state termination condition fn.""" - has_reached_max_length = state.cur_len == max_length - all_sequence_finished = jnp.all(state.is_sent_finished) - finish_generation = jnp.logical_or(has_reached_max_length, all_sequence_finished) - return ~finish_generation - - def sample_search_body_fn(state): - """state update fn.""" - prng_key, prng_key_next = jax.random.split(state.prng_key) - model_outputs = model(state.running_token, params=params, **state.model_kwargs) - - logits = model_outputs.logits[:, -1] - - # apply min_length, ... - logits = logits_processor(state.sequences, logits, state.cur_len) - # apply top_p, top_k, temperature - logits = logits_warper(logits, logits, state.cur_len) - - next_token = jax.random.categorical(prng_key, logits, axis=-1) - - next_token = next_token * ~state.is_sent_finished + pad_token_id * state.is_sent_finished - next_is_sent_finished = state.is_sent_finished | (next_token == eos_token_id) - next_token = next_token[:, None] - - next_sequences = lax.dynamic_update_slice(state.sequences, next_token, (0, state.cur_len)) - next_model_kwargs = self.update_inputs_for_generation(model_outputs, state.model_kwargs) - - return SampleState( - cur_len=state.cur_len + 1, - sequences=next_sequences, - running_token=next_token, - is_sent_finished=next_is_sent_finished, - model_kwargs=next_model_kwargs, - prng_key=prng_key_next, - ) - - # The very first prompt often has sequence length > 1, so run outside of `lax.while_loop` to comply with TPU - if input_ids.shape[1] > 1: - state = sample_search_body_fn(state) - - if not trace: - state = self._run_loop_in_debug(sample_search_cond_fn, sample_search_body_fn, state) - else: - state = lax.while_loop(sample_search_cond_fn, sample_search_body_fn, state) - - return FlaxSampleOutput(sequences=state.sequences) - - def _beam_search( - self, - input_ids: None, - max_length: Optional[int] = None, - pad_token_id: Optional[int] = None, - eos_token_id: Optional[int] = None, - length_penalty: Optional[float] = None, - early_stopping: Optional[Union[bool, str]] = None, - logits_processor: Optional[FlaxLogitsProcessorList] = None, - trace: bool = True, - params: Optional[dict[str, jnp.ndarray]] = None, - num_return_sequences: Optional[int] = None, - model_kwargs: Optional[dict[str, jnp.ndarray]] = None, - ): - """ - This beam search function is heavily inspired by Flax's official example: - https://github.com/google/flax/blob/main/examples/wmt/decode.py - """ - - def flatten_beam_dim(tensor): - """Flattens the first two dimensions of a non-scalar array.""" - # ignore scalars (e.g. cache index) - if tensor.ndim == 0: - return tensor - return tensor.reshape((tensor.shape[0] * tensor.shape[1],) + tensor.shape[2:]) - - def unflatten_beam_dim(tensor, batch_size, num_beams): - """Unflattens the first, flat batch*beam dimension of a non-scalar array.""" - # ignore scalars (e.g. cache index) - if tensor.ndim == 0: - return tensor - return tensor.reshape((batch_size, num_beams) + tensor.shape[1:]) - - def gather_beams(nested, beam_indices, batch_size, new_num_beams): - """ - Gathers the beam slices indexed by beam_indices into new beam array. - """ - batch_indices = jnp.reshape( - jnp.arange(batch_size * new_num_beams) // new_num_beams, (batch_size, new_num_beams) - ) - - def gather_fn(tensor): - # ignore scalars (e.g. cache index) - if tensor.ndim == 0: - return tensor - else: - return tensor[batch_indices, beam_indices] - - return jax.tree_util.tree_map(gather_fn, nested) - - # init values - max_length = max_length if max_length is not None else self.generation_config.max_length - pad_token_id = pad_token_id if pad_token_id is not None else self.generation_config.pad_token_id - eos_token_id = eos_token_id if eos_token_id is not None else self.generation_config.eos_token_id - length_penalty = length_penalty if length_penalty is not None else self.generation_config.length_penalty - early_stopping = early_stopping if early_stopping is not None else self.generation_config.early_stopping - num_return_sequences = ( - num_return_sequences if num_return_sequences is not None else self.generation_config.num_return_sequences - ) - - batch_size, num_beams, cur_len = input_ids.shape - - eos_token_id = jnp.array(eos_token_id, dtype=jnp.int32 if eos_token_id is not None else None) - pad_token_id = jnp.array(pad_token_id, dtype=jnp.int32) - cur_len = jnp.array(cur_len) - - # record the prompt length of decoder - decoder_prompt_len = input_ids.shape[-1] - - # per batch,beam-item holding current token in loop. - sequences = jnp.full((batch_size, num_beams, max_length), pad_token_id, dtype=jnp.int32) - running_sequences = jnp.full((batch_size, num_beams, max_length), pad_token_id, dtype=jnp.int32) - running_sequences = lax.dynamic_update_slice(sequences, input_ids, (0, 0, 0)) - - # per batch,beam-item state bit indicating if sentence has finished. - is_sent_finished = jnp.zeros((batch_size, num_beams), dtype=jnp.bool_) - - # per batch,beam-item score, logprobs - running_scores = jnp.tile(jnp.array([0.0] + [np.array(-1.0e7)] * (num_beams - 1)), [batch_size, 1]) - scores = jnp.ones((batch_size, num_beams)) * np.array(-1.0e7) - - # For Seq2Seq generation, we only need to use the decoder instead of the whole model in generation loop - # and pass it the `encoder_outputs`, which are part of the `model_kwargs`. - model = self.decode if self.config.is_encoder_decoder else self - - # flatten beam dim - if "encoder_outputs" in model_kwargs: - model_kwargs["encoder_outputs"]["last_hidden_state"] = flatten_beam_dim( - model_kwargs["encoder_outputs"]["last_hidden_state"] - ) - for kwarg in ["attention_mask", "decoder_attention_mask"]: - if kwarg in model_kwargs: - model_kwargs[kwarg] = flatten_beam_dim(model_kwargs[kwarg]) - - # initialize model specific kwargs - model_kwargs = self.prepare_inputs_for_generation(flatten_beam_dim(input_ids), max_length, **model_kwargs) - - # initialize state - state = BeamSearchState( - cur_len=cur_len, - running_sequences=running_sequences, - running_scores=running_scores, - sequences=sequences, - scores=scores, - is_sent_finished=is_sent_finished, - model_kwargs=model_kwargs, - ) - - def beam_search_cond_fn(state): - """beam search state termination condition fn.""" - - # 1. is less than max length? - not_max_length_yet = state.cur_len < max_length - - # 2. can the new beams still improve? - # early_stopping == False -> apply heuristic = always get the best score from `cur_len`. See the discussion - # below for more details. - # https://github.com/huggingface/transformers/pull/20901#issuecomment-1369845565 - # early_stopping == "never" -> compute the best score from max_length or cur_len, depending on the sign of - # length_penalty. Positive length_penalty favors longer sequences, thus we use max_length there. - if early_stopping == "never" and length_penalty > 0.0: - best_running_score = state.running_scores[:, :1] / ( - (max_length - decoder_prompt_len) ** length_penalty - ) - else: - best_running_score = state.running_scores[:, :1] / ( - (state.cur_len - decoder_prompt_len) ** length_penalty - ) - worst_finished_score = jnp.where( - state.is_sent_finished, jnp.min(state.scores, axis=1, keepdims=True), np.array(-1.0e7) - ) - improvement_still_possible = jnp.any(best_running_score > worst_finished_score) - - # 3. is there still a beam that has not finished? - still_open_beam = ~(jnp.all(state.is_sent_finished) & (early_stopping is True)) - - return not_max_length_yet & still_open_beam & improvement_still_possible - - def beam_search_body_fn(state, input_ids_length=1): - """beam search state update fn.""" - # 1. Forward current tokens - # Collect the current position slice along length to feed the fast - # autoregressive decoder model. Flatten the beam dimension into batch - # dimension for feeding into the model. - # unflatten beam dimension - # Unflatten beam dimension in attention cache arrays - input_token = flatten_beam_dim( - lax.dynamic_slice( - state.running_sequences, - (0, 0, state.cur_len - input_ids_length), - (batch_size, num_beams, input_ids_length), - ) - ) - model_outputs = model(input_token, params=params, **state.model_kwargs) - - logits = unflatten_beam_dim(model_outputs.logits[:, -1], batch_size, num_beams) - cache = jax.tree_util.tree_map( - lambda tensor: unflatten_beam_dim(tensor, batch_size, num_beams), model_outputs.past_key_values - ) - - # adapt logits for FlaxMarianMTModel - logits = self._adapt_logits_for_beam_search(logits) - - # 2. Compute log probs - # get log probabilities from logits, - # process logits with processors (*e.g.* min_length, ...), and - # add new logprobs to existing running logprobs scores. - log_probs = jax.nn.log_softmax(logits) - log_probs = logits_processor( - flatten_beam_dim(state.running_sequences), flatten_beam_dim(log_probs), state.cur_len - ) - log_probs = unflatten_beam_dim(log_probs, batch_size, num_beams) - log_probs = log_probs + jnp.expand_dims(state.running_scores, axis=2) - vocab_size = log_probs.shape[2] - log_probs = log_probs.reshape((batch_size, num_beams * vocab_size)) - - # 3. Retrieve top-K - # Each item in batch has num_beams * vocab_size candidate sequences. - # For each item, get the top 2*k candidates with the highest log- - # probabilities. We gather the top 2*K beams here so that even if the best - # K sequences reach EOS simultaneously, we have another K sequences - # remaining to continue the live beam search. - # Gather the top 2*K scores from _all_ beams. - # Gather 2*k top beams. - # Recover the beam index by floor division. - # Recover token id by modulo division and expand Id array for broadcasting. - # Update sequences for the 2*K top-k new sequences. - beams_to_keep = 2 * num_beams - topk_log_probs, topk_indices = lax.top_k(log_probs, k=beams_to_keep) - topk_beam_indices = topk_indices // vocab_size - topk_running_sequences = gather_beams( - state.running_sequences, topk_beam_indices, batch_size, beams_to_keep - ) - topk_ids = jnp.expand_dims(topk_indices % vocab_size, axis=2) - topk_sequences = lax.dynamic_update_slice(topk_running_sequences, topk_ids, (0, 0, state.cur_len)) - - # 4. Check which sequences have ended - # Update current sequences: - # Did any of these sequences reach an end marker? - # To prevent these just finished sequences from being added to the current sequences - # set of active beam search sequences, set their log probs to a very large - # negative value. - did_topk_just_finished = topk_sequences[:, :, state.cur_len] == eos_token_id - running_topk_log_probs = topk_log_probs + did_topk_just_finished * np.array(-1.0e7) - # 5. Get running sequences scores for next - # Determine the top k beam indices (from top 2*k beams) from log probs - # and gather top k beams (from top 2*k beams). - next_topk_indices = lax.top_k(running_topk_log_probs, k=num_beams)[1] - next_running_sequences, next_running_scores = gather_beams( - [topk_sequences, running_topk_log_probs], next_topk_indices, batch_size, num_beams - ) - - # 6. Process topk logits - # Further process log probs: - # - add length penalty - # - make sure no scores can be added anymore if beam is full - # - make sure still running sequences cannot be chosen as finalized beam - topk_log_probs = topk_log_probs / ((state.cur_len + 1 - decoder_prompt_len) ** length_penalty) - beams_in_batch_are_full = jnp.broadcast_to( - state.is_sent_finished.all(axis=-1, keepdims=True), did_topk_just_finished.shape - ) & (early_stopping is True) - add_penalty = ~did_topk_just_finished | beams_in_batch_are_full - topk_log_probs += add_penalty * np.array(-1.0e7) - - # 7. Get scores, sequences, is sentence finished for next. - # Combine sequences, scores, and flags along the beam dimension and compare - # new finished sequence scores to existing finished scores and select the - # best from the new set of beams - merged_sequences = jnp.concatenate([state.sequences, topk_sequences], axis=1) - merged_scores = jnp.concatenate([state.scores, topk_log_probs], axis=1) - merged_is_sent_finished = jnp.concatenate([state.is_sent_finished, did_topk_just_finished], axis=1) - topk_merged_indices = lax.top_k(merged_scores, k=num_beams)[1] - next_sequences, next_scores, next_is_sent_finished = gather_beams( - [merged_sequences, merged_scores, merged_is_sent_finished], topk_merged_indices, batch_size, num_beams - ) - - # 8. Update model kwargs. - # Determine the top k beam indices from the original set of all beams. - # With these, gather the top k beam-associated caches. - next_running_indices = gather_beams(topk_beam_indices, next_topk_indices, batch_size, num_beams) - next_cache = gather_beams(cache, next_running_indices, batch_size, num_beams) - model_outputs["past_key_values"] = jax.tree_util.tree_map(lambda x: flatten_beam_dim(x), next_cache) - next_model_kwargs = self.update_inputs_for_generation(model_outputs, state.model_kwargs) - - return BeamSearchState( - cur_len=state.cur_len + 1, - running_scores=next_running_scores, - running_sequences=next_running_sequences, - scores=next_scores, - sequences=next_sequences, - is_sent_finished=next_is_sent_finished, - model_kwargs=next_model_kwargs, - ) - - # Always run first iteration outside of `lax.while_loop` to avoid calling `beam_search_cond_fn` - # when `state.cur_len` equals `decoder_prompt_len`. This also helps to comply with TPU when - # the very first prompt has sequence length > 1. - state = partial(beam_search_body_fn, input_ids_length=input_ids.shape[-1])(state) - - if not trace: - state = self._run_loop_in_debug(beam_search_cond_fn, beam_search_body_fn, state) - else: - state = lax.while_loop(beam_search_cond_fn, beam_search_body_fn, state) - - # Account for the edge-case where there are no finished sequences for a - # particular batch item. If so, return running sequences for that batch item. - none_finished = jnp.any(state.is_sent_finished, axis=1) - sequences = jnp.where(none_finished[:, None, None], state.sequences, state.running_sequences) - scores = jnp.where(none_finished[:, None], state.scores, state.running_scores) - - # Take best beams for each batch (the score is sorted in descending order) - sequences = flatten_beam_dim(sequences[:, :num_return_sequences, :]) - scores = flatten_beam_dim(scores[:, :num_return_sequences]) - - return FlaxBeamSearchOutput(sequences=sequences, scores=scores) diff --git a/src/transformers/generation/tf_logits_process.py b/src/transformers/generation/tf_logits_process.py deleted file mode 100644 index 436793c402ea..000000000000 --- a/src/transformers/generation/tf_logits_process.py +++ /dev/null @@ -1,600 +0,0 @@ -# coding=utf-8 -# Copyright 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. - -import inspect - -import numpy as np -import tensorflow as tf - -from ..tf_utils import stable_softmax -from ..utils import add_start_docstrings -from ..utils.logging import get_logger - - -logger = get_logger(__name__) - - -TF_LOGITS_PROCESSOR_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - scores (`tf.Tensor` of shape `(batch_size, config.vocab_size)`): - Prediction scores of a language modeling head. These can be logits for each vocabulary when not using beam - search or log softmax for each vocabulary token when using beam search. - cur_len (`int`): - The current length of valid input sequence tokens. In the TF implementation, the input_ids' sequence length - is the maximum length generate can produce, and we need to know which of its tokens are valid. - kwargs (`dict[str, Any]`, *optional*): - Additional logits processor specific kwargs. - - Return: - `tf.Tensor` of shape `(batch_size, config.vocab_size)`: The processed prediction scores. -""" - - -class TFLogitsProcessor: - """Abstract base class for all logit processors that can be applied during generation.""" - - @add_start_docstrings(TF_LOGITS_PROCESSOR_INPUTS_DOCSTRING) - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - """TF method for processing logits.""" - raise NotImplementedError( - f"{self.__class__} is an abstract class. Only classes inheriting this class can be called." - ) - - -class TFLogitsWarper: - """Abstract base class for all logit warpers that can be applied during generation with multinomial sampling.""" - - @add_start_docstrings(TF_LOGITS_PROCESSOR_INPUTS_DOCSTRING) - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - """TF method for warping logits.""" - raise NotImplementedError( - f"{self.__class__} is an abstract class. Only classes inheriting this class can be called." - ) - - -class TFLogitsProcessorList(list): - """ - This class can be used to create a list of [`TFLogitsProcessor`] to subsequently process a `scores` input tensor. - This class inherits from list and adds a specific *__call__* method to apply each [`TFLogitsProcessor`] to the - inputs. - """ - - @add_start_docstrings(TF_LOGITS_PROCESSOR_INPUTS_DOCSTRING) - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int, **kwargs) -> tf.Tensor: - for processor in self: - function_args = inspect.signature(processor.__call__).parameters - if len(function_args) > 3: - if not all(arg in kwargs for arg in list(function_args.keys())[2:]): - raise ValueError( - f"Make sure that all the required parameters: {list(function_args.keys())} for " - f"{processor.__class__} are passed to the logits processor." - ) - scores = processor(input_ids, scores, cur_len, **kwargs) - else: - scores = processor(input_ids, scores, cur_len) - return scores - - -class TFTemperatureLogitsWarper(TFLogitsWarper): - r""" - [`TFLogitsWarper`] for temperature (exponential scaling output probability distribution). - - Args: - temperature (`float`): - The value used to module the logits distribution. - """ - - def __init__(self, temperature: float): - if not isinstance(temperature, float) or not (temperature > 0): - raise ValueError(f"`temperature` has to be a strictly positive float, but is {temperature}") - - self.temperature = temperature - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - scores = scores / self.temperature - return scores - - -class TFTopKLogitsWarper(TFLogitsWarper): - r""" - [`TFLogitsWarper`] that performs top-k, i.e. restricting to the k highest probability elements. - - Args: - top_k (`int`): - The number of highest probability vocabulary tokens to keep for top-k-filtering. - filter_value (`float`, *optional*, defaults to -inf): - All filtered values will be set to this float value. - min_tokens_to_keep (`int`, *optional*, defaults to 1): - Minimum number of tokens that cannot be filtered. - """ - - def __init__(self, top_k: int, filter_value: float = -float("Inf"), min_tokens_to_keep: int = 1): - if not isinstance(top_k, int) or top_k <= 0: - raise ValueError(f"`top_k` has to be a strictly positive integer, but is {top_k}") - - self.top_k = max(top_k, min_tokens_to_keep) - self.filter_value = filter_value - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - top_k = min(self.top_k, scores.shape[-1]) # Safety check - # Boolean mask containing all tokens with a probability less than the last token of the top-k - indices_to_remove = scores < tf.math.top_k(scores, k=top_k)[0][..., -1:] - next_scores = tf.where(indices_to_remove, self.filter_value, scores) - return next_scores - - -class TFTopPLogitsWarper(TFLogitsWarper): - """ - [`TFLogitsWarper`] that performs top-p, i.e. restricting to top tokens summing to <= prob_cut_off. - - Args: - top_p (`float`): - If set to < 1, only the smallest set of most probable tokens with probabilities that add up to `top_p` or - higher are kept for generation. - filter_value (`float`, *optional*, defaults to -inf): - All filtered values will be set to this float value. - min_tokens_to_keep (`int`, *optional*, defaults to 1): - Minimum number of tokens that cannot be filtered. - """ - - def __init__(self, top_p: float, filter_value: float = -float("Inf"), min_tokens_to_keep: int = 1): - if not isinstance(top_p, float) or (top_p < 0 or top_p > 1.0): - raise ValueError(f"`top_p` has to be a float > 0 and < 1, but is {top_p}") - if not isinstance(min_tokens_to_keep, int) or (min_tokens_to_keep < 1): - raise ValueError(f"`min_tokens_to_keep` has to be a positive integer, but is {min_tokens_to_keep}") - - self.top_p = top_p - self.filter_value = filter_value - self.min_tokens_to_keep = min_tokens_to_keep - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - topk_scores, topk_indices = tf.math.top_k(scores, scores.shape[-1]) - - mask_scores = tf.fill(scores.shape, self.filter_value) - cumulative_probs = tf.math.cumsum(stable_softmax(topk_scores, axis=-1), axis=-1) - score_mask = cumulative_probs < self.top_p - - # Also include the token that is higher than top_p (the first false = shift and insert a True on the left) - score_mask = tf.concat((tf.ones([score_mask.shape[0], 1], dtype=tf.bool), score_mask[:, :-1]), axis=-1) - - # Ensure min tokens to keep - score_mask = tf.concat( - ( - tf.ones([score_mask.shape[0], self.min_tokens_to_keep], dtype=tf.bool), - score_mask[:, self.min_tokens_to_keep :], - ), - axis=-1, - ) - - # Mask the values that do not fit the criteria - topk_next_scores = tf.where(score_mask, topk_scores, mask_scores) - - # Undo the topk sorting: converts the 2D matrix of per-row original indices of shape (batch_size, vocab_size) - # to a 3D tensor of shape (batch_size, vocab_size, 2) containing the original score coordinate, from which we - # can scatter (i.e. `scatter_indices[row, col, :]` is a tensor containing `[row, topk_indices[row, col]]`) - scatter_rows = tf.tile(tf.expand_dims(tf.range(topk_indices.shape[0]), axis=-1), [1, topk_indices.shape[-1]]) - scatter_indices = tf.stack((scatter_rows, topk_indices), axis=-1) - next_scores = tf.scatter_nd(scatter_indices, topk_next_scores, shape=topk_next_scores.shape) - - return next_scores - - -class TFMinLengthLogitsProcessor(TFLogitsProcessor): - r""" - [`TFLogitsProcessor`] enforcing a min-length by setting EOS probability to 0. - - Args: - min_length (`int`): - The minimum length below which the score of `eos_token_id` is set to `-float("Inf")`. - eos_token_id (`int`): - The id of the *end-of-sequence* token. - """ - - def __init__(self, min_length: int, eos_token_id: int): - if not isinstance(min_length, int) or min_length < 0: - raise ValueError(f"`min_length` has to be a positive integer, but is {min_length}") - - if not isinstance(eos_token_id, int) or eos_token_id < 0: - raise ValueError(f"`eos_token_id` has to be a positive integer, but is {eos_token_id}") - - self.min_length = min_length - self.eos_token_id = eos_token_id - - def _apply_eos_token_mask(self, scores: tf.Tensor) -> tf.Tensor: - eos_token_id_mask = tf.range(scores.shape[-1]) == self.eos_token_id - scores = tf.where(eos_token_id_mask, float("-inf"), scores) - return scores - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - # applies eos token masking if the first argument is true - scores = tf.cond( - tf.less(cur_len, self.min_length), - lambda: self._apply_eos_token_mask(scores), - lambda: tf.identity(scores), - ) - return scores - - -class TFRepetitionPenaltyLogitsProcessor(TFLogitsProcessor): - r""" - [`TFLogitsProcessor`] enforcing an exponential penalty on repeated sequences. - - Args: - repetition_penalty (`float`): - The parameter for repetition penalty. 1.0 means no penalty. See [this - paper](https://huggingface.co/papers/1909.05858) for more details. - """ - - def __init__(self, penalty: float): - if not isinstance(penalty, float) or not (penalty > 0): - raise ValueError(f"`penalty` has to be a strictly positive float, but is {penalty}") - - self.penalty = penalty - - def _create_score_penalties(self, input_ids: tf.Tensor, logits: tf.Tensor) -> tf.Tensor: - # We want to populate the penalties in the positions of `input_ids`. Since XLA can't handle shapes unknown - # before runtime, `tf.unique` can't be used. Therefore, we may have redundant updates, when a given row has - # the same token multiple times. - - # Gathers the penalties to apply - logit_penalties = tf.gather(logits, input_ids, axis=1, batch_dims=1) - logit_penalties = tf.where(logit_penalties > 0, 1 / self.penalty, logit_penalties) - logit_penalties = tf.where(logit_penalties < 0, self.penalty, logit_penalties) - - # Scatters the penalties - token_penalties = tf.ones(logits.shape) - batch_size = input_ids.shape[0] - seq_len = tf.shape(input_ids)[1] # the sequence length has dynamic size, hence the dynamic shape - indexable_prev_input_ids = tf.concat( - ( - tf.expand_dims(tf.repeat(tf.range(batch_size), seq_len), axis=-1), - tf.expand_dims(tf.reshape(input_ids, [-1]), axis=-1), - ), - axis=1, - ) - token_penalties = tf.tensor_scatter_nd_update( - token_penalties, indices=indexable_prev_input_ids, updates=tf.reshape(logit_penalties, [-1]) - ) - return token_penalties - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - score_penalties = self._create_score_penalties(input_ids[:, :cur_len], scores) - - scores = tf.math.multiply(scores, score_penalties) - - return scores - - -class TFNoBadWordsLogitsProcessor(TFLogitsProcessor): - """ - [`TFLogitsProcessor`] that enforces that specified sequences will never be sampled. - - Args: - bad_words_ids (`list[list[int]]`): - List of list of token ids that are not allowed to be generated. In order to get the tokens of the words - that should not appear in the generated text, make sure to set `add_prefix_space=True` when initializing - the tokenizer, and use `tokenizer(bad_words, add_special_tokens=False).input_ids`. The `add_prefix_space` - argument is only supported for some slow tokenizers, as fast tokenizers' prefixing behaviours come from - `pre tokenizers`. Read more [here](https://huggingface.co/docs/tokenizers/api/pre-tokenizers). - eos_token_id (`int`): - The id of the *end-of-sequence* token. - """ - - def __init__(self, bad_words_ids: list[list[int]], eos_token_id: int): - if not isinstance(bad_words_ids, list) or len(bad_words_ids) == 0: - raise ValueError(f"`bad_words_ids` has to be a non-empty list, but is {bad_words_ids}.") - if any(not isinstance(bad_word_ids, list) for bad_word_ids in bad_words_ids): - raise ValueError(f"`bad_words_ids` has to be a list of lists, but is {bad_words_ids}.") - if any( - any((not isinstance(token_id, (int, np.integer)) or token_id < 0) for token_id in bad_word_ids) - for bad_word_ids in bad_words_ids - ): - raise ValueError( - f"Each list in `bad_words_ids` has to be a list of positive integers, but is {bad_words_ids}." - ) - - # stores the information about bad words in three tensors: - # 1. a rectangular tensor with the forbidden sequences (padded with `-1`), for full data comparisons - self.bad_word_seqs_ids = tf.ragged.constant(bad_words_ids).to_tensor(default_value=-1) - # 2. a tensor with the unpadded length of each forbidden sequence, for quick length comparisons - bad_word_seqs_len = [len(bad_words) for bad_words in bad_words_ids] - if any(word_len == 0 for word_len in bad_word_seqs_len): - raise ValueError(f"Banned words token sequences {bad_words_ids} cannot have an empty list") - self.bad_word_seqs_len = tf.convert_to_tensor(bad_word_seqs_len, dtype=tf.int32) - # 3. a tensor containing the last token for each sequence, for easy access to the tokens that may be banned - self.seq_forbidden_tokens = tf.convert_to_tensor([bad_words[-1] for bad_words in bad_words_ids]) - - def _calc_row_banned_bad_tokens(self, row_input_ids: tf.Tensor) -> tf.Tensor: - def _tokens_match(bad_word_seq_number): - def _len_one(): - # If the bad sequence only has one token, always mask it - return tf.cond( - tf.math.equal(self.bad_word_seqs_len[bad_word_seq_number], 1), - lambda: tf.ones((), dtype=tf.bool), - _len_greater_than_cur_len, - ) - - def _len_greater_than_cur_len(): - # Otherwise, if the bad sequence is longer than the current length they can't ever match - return tf.cond( - tf.math.greater(self.bad_word_seqs_len[bad_word_seq_number], tf.shape(row_input_ids)[0]), - lambda: tf.zeros((), dtype=tf.bool), - _match_found, - ) - - def _match_found(): - # Finally, runs the actual comparison. Can only be called if the previous comparisons do not yield - # an answer (otherwise we get indexing exceptions) - compare_len = self.bad_word_seqs_len[bad_word_seq_number] - 1 - return tf.cond( - tf.math.reduce_all( - tf.math.equal( - row_input_ids[-compare_len:], self.bad_word_seqs_ids[bad_word_seq_number, :compare_len] - ) - ), - lambda: tf.ones((), dtype=tf.bool), - lambda: tf.zeros((), dtype=tf.bool), - ) - - match = _len_one() - return match - - # Compares the current row against all bad word sequences, obtaining a mask with the matches. - match_mask = tf.map_fn(_tokens_match, tf.range(self.bad_word_seqs_ids.shape[0]), fn_output_signature=tf.bool) - row_banned_tokens = self.seq_forbidden_tokens[match_mask] - return row_banned_tokens - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - # We want to mask some banned tokens, at a score level. Since the banned tokens depend on the previous - # `input_ids`, they may have a different length for each row, and they may even be empty for some rows. - # To remain simple and XLA-compatible, we work on a per-row fashion. - # TODO (Joao): this function might trigger XLA retracing as `cur_len` increases. Fix it if it becomes - # a frequent choke point. (make `cur_len` a tensor?) - def _get_row_updated_score(row_inputs: tuple[tf.Tensor]) -> tf.Tensor: - row_input_ids, row_score = row_inputs - banned_tokens = self._calc_row_banned_bad_tokens(row_input_ids[:cur_len]) - banned_tokens_mask = tf.scatter_nd( - indices=tf.expand_dims(banned_tokens, axis=-1), - updates=tf.ones_like(banned_tokens, dtype=tf.bool), - shape=row_score.shape, - ) - row_score = tf.where(banned_tokens_mask, -float("inf"), row_score) - return row_score - - scores = tf.map_fn(_get_row_updated_score, (input_ids, scores), fn_output_signature=tf.float32) - return scores - - -class TFNoRepeatNGramLogitsProcessor(TFLogitsProcessor): - r""" - [`TFLogitsProcessor`] that enforces no repetition of n-grams. See - [Fairseq](https://github.com/pytorch/fairseq/blob/a07cb6f40480928c9e0548b737aadd36ee66ac76/fairseq/sequence_generator.py#L345). - - Args: - ngram_size (`int`): - All ngrams of size `ngram_size` can only occur once. - """ - - def __init__(self, ngram_size: int): - if not isinstance(ngram_size, int) or ngram_size <= 0: - raise ValueError(f"`ngram_size` has to be a strictly positive integer, but is {ngram_size}") - self.ngram_size = ngram_size - - def calc_banned_ngram_tokens(self, input_ids, num_hypos, cur_len): - # Copied from fairseq for no_repeat_ngram in beam_search - if cur_len + 1 < self.ngram_size: - # return no banned tokens if we haven't generated ngram_size tokens yet - return [[] for _ in range(num_hypos)] - generated_ngrams = [{} for _ in range(num_hypos)] - prev_input_ids = input_ids[:, :cur_len] - for idx in range(num_hypos): - gen_tokens = prev_input_ids[idx].numpy().tolist() - generated_ngram = generated_ngrams[idx] - for ngram in zip(*[gen_tokens[i:] for i in range(self.ngram_size)]): - prev_ngram_tuple = tuple(ngram[:-1]) - generated_ngram[prev_ngram_tuple] = generated_ngram.get(prev_ngram_tuple, []) + [ngram[-1]] - - def _get_generated_ngrams(hypo_idx): - # Before decoding the next token, prevent decoding of ngrams that have already appeared - start_idx = cur_len + 1 - self.ngram_size - ngram_idx = tuple(prev_input_ids[hypo_idx, start_idx:cur_len].numpy().tolist()) - return generated_ngrams[hypo_idx].get(ngram_idx, []) - - banned_tokens = [_get_generated_ngrams(hypo_idx) for hypo_idx in range(num_hypos)] - - return banned_tokens - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - # TODO (joao): enable XLA on this logits processor. See discussion and attempts in - # https://github.com/huggingface/transformers/pull/16974 - if not tf.executing_eagerly(): - raise NotImplementedError("TFNoRepeatNGramLogitsProcessor is only implemented for eager execution.") - - batch_size, vocab_size = scores.shape - banned_tokens = self.calc_banned_ngram_tokens(input_ids, batch_size, cur_len) - - # create banned_tokens boolean mask - banned_tokens_indices_mask = [] - for banned_tokens_slice in banned_tokens: - banned_tokens_indices_mask.append([token in banned_tokens_slice for token in range(vocab_size)]) - - scores = tf.where(tf.convert_to_tensor(banned_tokens_indices_mask, dtype=tf.bool), -float("inf"), scores) - - return scores - - -class TFForcedBOSTokenLogitsProcessor(TFLogitsProcessor): - r""" - [`TFLogitsProcessor`] that enforces the specified token as the first generated token. - - Args: - bos_token_id (`int`): - The id of the token to force as the first generated token. - """ - - def __init__(self, bos_token_id: int): - if bos_token_id < 0: - raise ValueError(f"The forced bos token id must be a non-negative integer, got {bos_token_id}") - self.bos_token_id = bos_token_id - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - if cur_len == 1: - batch_size, num_tokens = scores.shape - # sets the score to 0 in the bos_token_id column - scores = tf.zeros((batch_size, 1)) - # sets the score to -inf everywhere else - if self.bos_token_id > 0: - scores = tf.concat((tf.broadcast_to(-float("inf"), (batch_size, self.bos_token_id)), scores), axis=-1) - if self.bos_token_id < (num_tokens - 1): - scores = tf.concat( - (scores, tf.broadcast_to(-float("inf"), (batch_size, (num_tokens - 1) - self.bos_token_id))), - axis=-1, - ) - return scores - - -class TFForcedEOSTokenLogitsProcessor(TFLogitsProcessor): - r""" - [`TFLogitsProcessor`] that enforces the specified token as the last generated token when `max_length` is reached. - - Args: - max_length (`int`): - The maximum length of the sequence to be generated. - eos_token_id (`int`): - The id of the token to force as the last generated token when `max_length` is reached. - """ - - def __init__(self, max_length: int, eos_token_id: int): - self.max_length = max_length - if eos_token_id < 0: - raise ValueError(f"The forced eos token id must be a non-negative integer, got {eos_token_id}") - self.eos_token_id = eos_token_id - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - if cur_len == self.max_length - 1: - batch_size, num_tokens = scores.shape - # sets the score to 0 in the eos_token_id column - scores = tf.zeros((batch_size, 1)) - # sets the score to -inf everywhere else - if self.eos_token_id > 0: - scores = tf.concat((tf.broadcast_to(-float("inf"), (batch_size, self.eos_token_id)), scores), axis=-1) - if self.eos_token_id < (num_tokens - 1): - scores = tf.concat( - (scores, tf.broadcast_to(-float("inf"), (batch_size, (num_tokens - 1) - self.eos_token_id))), - axis=-1, - ) - return scores - - -class TFSuppressTokensAtBeginLogitsProcessor(TFLogitsProcessor): - r""" - [`TFSuppressTokensAtBeginLogitsProcessor`] suppresses a list of tokens as soon as the `generate` function starts - generating using `begin_index` tokens. This should ensure that the tokens defined by `begin_suppress_tokens` at not - sampled at the beginning of the generation. - """ - - def __init__(self, begin_suppress_tokens, begin_index): - self.begin_suppress_tokens = list(begin_suppress_tokens) - self.begin_index = begin_index - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - suppressed_indices = [] - for token in self.begin_suppress_tokens: - if token < scores.shape[-1]: # to ensure we don't go beyond the vocab size - suppressed_indices.extend([[i, token] for i in range(scores.shape[0])]) - - if len(suppressed_indices) > 0: - scores = tf.cond( - tf.equal(cur_len, self.begin_index), - lambda: tf.tensor_scatter_nd_update( - scores, - indices=suppressed_indices, - updates=[-float("inf") for _ in range(scores.shape[0] * len(self.begin_suppress_tokens))], - ), - lambda: scores, - ) - return scores - - -class TFSuppressTokensLogitsProcessor(TFLogitsProcessor): - r"""This processor can be used to suppress a list of tokens. The processor will set their log probs to `-inf` so that they - are not sampled.""" - - def __init__(self, suppress_tokens): - self.suppress_tokens = list(suppress_tokens) - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - suppressed_indices = [] - for token in self.suppress_tokens: - if token < scores.shape[-1]: # to ensure we don't go beyond the vocab size - suppressed_indices.extend([[i, token] for i in range(scores.shape[0])]) - - if len(suppressed_indices) > 0: - scores = tf.tensor_scatter_nd_update( - scores, - indices=[[i, token] for i in range(scores.shape[0]) for token in self.suppress_tokens], - updates=[-float("inf") for _ in range(scores.shape[0] * len(self.suppress_tokens))], - ) - return scores - - -class TFForceTokensLogitsProcessor(TFLogitsProcessor): - r"""This processor takes a list of pairs of integers which indicates a mapping from generation indices to token - indices that will be forced before sampling. The processor will set their log probs to `0` and all other tokens to - `-inf` so that they are sampled at their corresponding index.""" - - def __init__(self, force_token_map: list[list[int]]): - force_token_map = dict(force_token_map) - # Converts the dictionary of format {index: token} containing the tokens to be forced to an array, where the - # index of the array corresponds to the index of the token to be forced, for XLA compatibility. - # Indexes without forced tokens will have an negative value. - force_token_array = np.ones((max(force_token_map.keys()) + 1), dtype=np.int32) * -1 - for index, token in force_token_map.items(): - if token is not None: - force_token_array[index] = token - self.force_token_array = tf.convert_to_tensor(force_token_array, dtype=tf.int32) - - def __call__(self, input_ids: tf.Tensor, scores: tf.Tensor, cur_len: int) -> tf.Tensor: - def _force_token(generation_idx): - batch_size = scores.shape[0] - current_token = self.force_token_array[generation_idx] - - new_scores = tf.zeros_like(scores, dtype=scores.dtype) + tf.constant([scores.dtype.min]) - indices = tf.stack((tf.range(batch_size), tf.tile([current_token], [batch_size])), axis=1) - updates = tf.zeros((batch_size,), dtype=scores.dtype) - new_scores = tf.tensor_scatter_nd_update(new_scores, indices, updates) - return new_scores - - scores = tf.cond( - tf.greater_equal(cur_len, tf.shape(self.force_token_array)[0]), - # If the current length is geq than the length of force_token_array, the processor does nothing. - lambda: tf.identity(scores), - # Otherwise, it may force a certain token. - lambda: tf.cond( - tf.greater_equal(self.force_token_array[cur_len], 0), - # Only valid (positive) tokens are forced - lambda: _force_token(cur_len), - # Otherwise, the processor does nothing. - lambda: scores, - ), - ) - return scores diff --git a/src/transformers/generation/tf_utils.py b/src/transformers/generation/tf_utils.py deleted file mode 100644 index be51c9cd9f43..000000000000 --- a/src/transformers/generation/tf_utils.py +++ /dev/null @@ -1,3132 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. - -import copy -import inspect -import warnings -from dataclasses import dataclass -from typing import Any, Optional, Union - -import numpy as np -import tensorflow as tf -from tensorflow.compiler.tf2xla.python.xla import dynamic_update_slice - -from ..modeling_tf_outputs import TFCausalLMOutputWithPast, TFSeq2SeqLMOutput -from ..models.auto import ( - TF_MODEL_FOR_CAUSAL_LM_MAPPING, - TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, - TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING, - TF_MODEL_FOR_VISION_2_SEQ_MAPPING, -) -from ..tf_utils import shape_list, stable_softmax -from ..utils import ModelOutput, logging -from .configuration_utils import GenerationConfig -from .tf_logits_process import ( - TFForcedBOSTokenLogitsProcessor, - TFForcedEOSTokenLogitsProcessor, - TFForceTokensLogitsProcessor, - TFLogitsProcessorList, - TFMinLengthLogitsProcessor, - TFNoBadWordsLogitsProcessor, - TFNoRepeatNGramLogitsProcessor, - TFRepetitionPenaltyLogitsProcessor, - TFSuppressTokensAtBeginLogitsProcessor, - TFSuppressTokensLogitsProcessor, - TFTemperatureLogitsWarper, - TFTopKLogitsWarper, - TFTopPLogitsWarper, -) - - -logger = logging.get_logger(__name__) - - -@dataclass -class TFGreedySearchDecoderOnlyOutput(ModelOutput): - """ - Base class for outputs of decoder-only generation models using greedy search. - - - Args: - sequences (`tf.Tensor` of shape `(batch_size, sequence_length)`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or shorter - if all batches finished early due to the `eos_token_id`. - scores (`tuple(tf.Tensor)` *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Processed prediction scores of the language modeling head (scores for each vocabulary token before SoftMax) - at each generation step. Tuple of `tf.Tensor` with up to `max_new_tokens` elements (one element for each - generated token), with each tensor of shape `(batch_size, config.vocab_size)`. - attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, num_heads, generated_length, sequence_length)`. - hidden_states (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, generated_length, hidden_size)`. - """ - - sequences: Optional[tf.Tensor] = None - scores: Optional[tuple[tf.Tensor]] = None - attentions: Optional[tuple[tuple[tf.Tensor]]] = None - hidden_states: Optional[tuple[tuple[tf.Tensor]]] = None - - -@dataclass -class TFGreedySearchEncoderDecoderOutput(ModelOutput): - """ - Base class for outputs of encoder-decoder generation models using greedy search. Hidden states and attention - weights of the decoder (respectively the encoder) can be accessed via the encoder_attentions and the - encoder_hidden_states attributes (respectively the decoder_attentions and the decoder_hidden_states attributes) - - - Args: - sequences (`tf.Tensor` of shape `(batch_size, sequence_length)`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or shorter - if all batches finished early due to the `eos_token_id`. - scores (`tuple(tf.Tensor)` *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Processed prediction scores of the language modeling head (scores for each vocabulary token before SoftMax) - at each generation step. Tuple of `tf.Tensor` with up to `max_new_tokens` elements (one element for each - generated token), with each tensor of shape `(batch_size, config.vocab_size)`. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer of the decoder) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - decoder_attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, num_heads, generated_length, sequence_length)`. - cross_attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, num_heads, generated_length, sequence_length)`. - decoder_hidden_states (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, generated_length, hidden_size)`. - """ - - sequences: Optional[tf.Tensor] = None - scores: Optional[tuple[tf.Tensor]] = None - encoder_attentions: Optional[tuple[tf.Tensor]] = None - encoder_hidden_states: Optional[tuple[tf.Tensor]] = None - decoder_attentions: Optional[tuple[tuple[tf.Tensor]]] = None - cross_attentions: Optional[tuple[tuple[tf.Tensor]]] = None - decoder_hidden_states: Optional[tuple[tuple[tf.Tensor]]] = None - - -@dataclass -class TFSampleDecoderOnlyOutput(ModelOutput): - """ - Base class for outputs of decoder-only generation models using sampling. - - - Args: - sequences (`tf.Tensor` of shape `(batch_size*num_return_sequences, sequence_length)`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or shorter - if all batches finished early due to the `eos_token_id`. - scores (`tuple(tf.Tensor)` *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Processed prediction scores of the language modeling head (scores for each vocabulary token before SoftMax) - at each generation step. Tuple of `tf.Tensor` with up to `max_new_tokens` elements (one element for each - generated token), with each tensor of shape `(batch_size*num_return_sequences, config.vocab_size)`. - attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(num_return_sequences*batch_size, num_heads, generated_length, sequence_length)`. - hidden_states (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(num_return_sequences*batch_size, generated_length, hidden_size)`. - """ - - sequences: Optional[tf.Tensor] = None - scores: Optional[tuple[tf.Tensor]] = None - attentions: Optional[tuple[tuple[tf.Tensor]]] = None - hidden_states: Optional[tuple[tuple[tf.Tensor]]] = None - - -@dataclass -class TFSampleEncoderDecoderOutput(ModelOutput): - """ - Base class for outputs of encoder-decoder generation models using sampling. Hidden states and attention weights of - the decoder (respectively the encoder) can be accessed via the encoder_attentions and the encoder_hidden_states - attributes (respectively the decoder_attentions and the decoder_hidden_states attributes) - - - Args: - sequences (`tf.Tensor` of shape `(batch_size*num_return_sequences, sequence_length)`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or shorter - if all batches finished early due to the `eos_token_id`. - scores (`tuple(tf.Tensor)` *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Processed prediction scores of the language modeling head (scores for each vocabulary token before SoftMax) - at each generation step. Tuple of `tf.Tensor` with up to `max_new_tokens` elements (one element for each - generated token), with each tensor of shape `(batch_size*num_return_sequences, config.vocab_size)`. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer of the decoder) of shape `(batch_size*num_return_sequences, - num_heads, sequence_length, sequence_length)`. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size*num_return_sequences, sequence_length, hidden_size)`. - decoder_attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size*num_return_sequences, num_heads, generated_length, sequence_length)`. - cross_attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, num_heads, generated_length, sequence_length)`. - decoder_hidden_states (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size*num_return_sequences, generated_length, hidden_size)`. - """ - - sequences: Optional[tf.Tensor] = None - scores: Optional[tuple[tf.Tensor]] = None - encoder_attentions: Optional[tuple[tf.Tensor]] = None - encoder_hidden_states: Optional[tuple[tf.Tensor]] = None - decoder_attentions: Optional[tuple[tuple[tf.Tensor]]] = None - cross_attentions: Optional[tuple[tuple[tf.Tensor]]] = None - decoder_hidden_states: Optional[tuple[tuple[tf.Tensor]]] = None - - -@dataclass -class TFBeamSearchDecoderOnlyOutput(ModelOutput): - """ - Base class for outputs of decoder-only generation models using beam search. - - Args: - sequences (`tf.Tensor` of shape `(batch_size*num_return_sequences, sequence_length)`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or shorter - if all batches finished early due to the `eos_token_id`. - sequences_scores (`tf.Tensor` of shape `(batch_size*num_return_sequences)`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Final beam scores of the generated `sequences`. - scores (`tuple(tf.Tensor)` *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Processed beam scores for each vocabulary token at each generation step. Beam scores consisting of log - softmax scores for each vocabulary token and sum of log softmax of previously generated tokens in this - beam. Tuple of `tf.Tensor` with up to `max_new_tokens` elements (one element for each generated token), - with each tensor of shape `(batch_size*num_beams*num_return_sequences, config.vocab_size)`. - beam_indices (`tf.Tensor`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Beam indices of generated token id at each generation step. `tf.Tensor` of shape - `(batch_size*num_return_sequences, sequence_length)`. - attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size*num_beams, num_heads, generated_length, sequence_length)`. - hidden_states (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size*num_beams*num_return_sequences, generated_length, hidden_size)`. - """ - - sequences: Optional[tf.Tensor] = None - sequences_scores: Optional[tf.Tensor] = None - scores: Optional[tuple[tf.Tensor]] = None - beam_indices: Optional[tf.Tensor] = None - attentions: Optional[tuple[tuple[tf.Tensor]]] = None - hidden_states: Optional[tuple[tuple[tf.Tensor]]] = None - - -@dataclass -class TFBeamSearchEncoderDecoderOutput(ModelOutput): - """ - Base class for outputs of encoder-decoder generation models using beam search. Hidden states and attention weights - of the decoder (respectively the encoder) can be accessed via the encoder_attentions and the encoder_hidden_states - attributes (respectively the decoder_attentions and the decoder_hidden_states attributes) - - Args: - sequences (`tf.Tensor` of shape `(batch_size*num_return_sequences, sequence_length)`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or shorter - if all batches finished early due to the `eos_token_id`. - sequences_scores (`tf.Tensor` of shape `(batch_size*num_return_sequences)`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Final beam scores of the generated `sequences`. - scores (`tuple(tf.Tensor)` *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Processed beam scores for each vocabulary token at each generation step. Beam scores consisting of log - softmax scores for each vocabulary token and sum of log softmax of previously generated tokens in this - beam. `Tuple of `tf.Tensor` with up to `max_new_tokens` elements (one element for each generated token), - with each tensor of shape `(batch_size*num_beams, config.vocab_size)`. - beam_indices (`tf.Tensor`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Beam indices of generated token id at each generation step. `tf.Tensor` of shape - `(batch_size*num_return_sequences, sequence_length)`. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer of the decoder) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size*num_beams*num_return_sequences, sequence_length, hidden_size)`. - decoder_attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size*num_beams*num_return_sequences, num_heads, generated_length, - sequence_length)`. - cross_attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, num_heads, generated_length, sequence_length)`. - decoder_hidden_states (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size*num_beams*num_return_sequences, generated_length, hidden_size)`. - """ - - sequences: Optional[tf.Tensor] = None - sequences_scores: Optional[tf.Tensor] = None - scores: Optional[tuple[tf.Tensor]] = None - beam_indices: Optional[tf.Tensor] = None - encoder_attentions: Optional[tuple[tf.Tensor]] = None - encoder_hidden_states: Optional[tuple[tf.Tensor]] = None - decoder_attentions: Optional[tuple[tuple[tf.Tensor]]] = None - cross_attentions: Optional[tuple[tuple[tf.Tensor]]] = None - decoder_hidden_states: Optional[tuple[tuple[tf.Tensor]]] = None - - -@dataclass -class TFBeamSampleDecoderOnlyOutput(ModelOutput): - """ - Base class for outputs of decoder-only generation models using beam sample. - - Args: - sequences (`tf.Tensor` of shape `(batch_size*num_return_sequences, sequence_length)`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or shorter - if all batches finished early due to the `eos_token_id`. - sequences_scores (`tf.Tensor` of shape `(batch_size * num_return_sequence)`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Final beam scores of the generated `sequences`. - scores (`tuple(tf.Tensor)` *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Processed beam scores for each vocabulary token at each generation step. Beam scores consisting of log - softmax scores for each vocabulary token and sum of log softmax of previously generated tokens in this - beam. Tuple of `tf.Tensor` with up to `max_new_tokens` elements (one element for each generated token), - with each tensor of shape `(batch_size*num_beams*num_return_sequences, config.vocab_size)`. - beam_indices (`tf.Tensor`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Beam indices of generated token id at each generation step. `tf.Tensor` of shape - `(batch_size*num_return_sequences, sequence_length)`. - attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size*num_beams, num_heads, generated_length, sequence_length)`. - hidden_states (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size*num_beams, generated_length, hidden_size)`. - """ - - sequences: Optional[tf.Tensor] = None - sequences_scores: Optional[tf.Tensor] = None - scores: Optional[tuple[tf.Tensor]] = None - beam_indices: Optional[tf.Tensor] = None - attentions: Optional[tuple[tuple[tf.Tensor]]] = None - hidden_states: Optional[tuple[tuple[tf.Tensor]]] = None - - -@dataclass -class TFBeamSampleEncoderDecoderOutput(ModelOutput): - """ - Base class for outputs of encoder-decoder generation models using beam sampling. Hidden states and attention - weights of the decoder (respectively the encoder) can be accessed via the encoder_attentions and the - encoder_hidden_states attributes (respectively the decoder_attentions and the decoder_hidden_states attributes) - - Args: - sequences (`tf.Tensor` of shape `(batch_size*num_beams, sequence_length)`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or shorter - if all batches finished early due to the `eos_token_id`. - sequences_scores (`tf.Tensor` of shape `(batch_size * num_return_sequence)`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Final beam scores of the generated `sequences`. - scores (`tuple(tf.Tensor)` *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Processed beam scores for each vocabulary token at each generation step. Beam scores consisting of log - softmax scores for each vocabulary token and sum of log softmax of previously generated tokens in this - beam. Tuple of `tf.Tensor` with up to `max_new_tokens` elements (one element for each generated token), - with each tensor of shape `(batch_size*num_beams, config.vocab_size)`. - beam_indices (`tf.Tensor`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Beam indices of generated token id at each generation step. `tf.Tensor` of shape - `(batch_size*num_return_sequences, sequence_length)`. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer of the decoder) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size*num_beams, sequence_length, hidden_size)`. - decoder_attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size*num_beams, num_heads, generated_length, sequence_length)`. - cross_attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, num_heads, generated_length, sequence_length)`. - decoder_hidden_states (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size*num_beams, generated_length, hidden_size)`. - """ - - sequences: Optional[tf.Tensor] = None - sequences_scores: Optional[tf.Tensor] = None - scores: Optional[tuple[tf.Tensor]] = None - beam_indices: Optional[tf.Tensor] = None - encoder_attentions: Optional[tuple[tf.Tensor]] = None - encoder_hidden_states: Optional[tuple[tf.Tensor]] = None - decoder_attentions: Optional[tuple[tuple[tf.Tensor]]] = None - cross_attentions: Optional[tuple[tuple[tf.Tensor]]] = None - decoder_hidden_states: Optional[tuple[tuple[tf.Tensor]]] = None - - -@dataclass -class TFContrastiveSearchDecoderOnlyOutput(ModelOutput): - """ - Base class for outputs of decoder-only generation models using contrastive search. - - Args: - sequences (`tf.Tensor` of shape `(batch_size, sequence_length)`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or shorter - if all batches finished early due to the `eos_token_id`. - scores (`tuple(tf.Tensor)` *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Processed prediction scores of the language modeling head (scores for each vocabulary token before SoftMax) - at each generation step. Tuple of `tf.Tensor` with up to `max_new_tokens` elements (one element for each - generated token), with each tensor of shape `(batch_size, config.vocab_size)`. - attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, num_heads, generated_length, sequence_length)`. - hidden_states (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, generated_length, hidden_size)`. - """ - - sequences: Optional[tf.Tensor] = None - scores: Optional[tuple[tf.Tensor]] = None - attentions: Optional[tuple[tuple[tf.Tensor]]] = None - hidden_states: Optional[tuple[tuple[tf.Tensor]]] = None - - -@dataclass -class TFContrastiveSearchEncoderDecoderOutput(ModelOutput): - """ - Base class for outputs of encoder-decoder generation models using contrastive search. Hidden states and attention - weights of the decoder (respectively the encoder) can be accessed via the encoder_attentions and the - encoder_hidden_states attributes (respectively the decoder_attentions and the decoder_hidden_states attributes) - - Args: - sequences (`tf.Tensor` of shape `(batch_size, sequence_length)`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or shorter - if all batches finished early due to the `eos_token_id`. - scores (`tuple(tf.Tensor)` *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`): - Processed prediction scores of the language modeling head (scores for each vocabulary token before SoftMax) - at each generation step. Tuple of `tf.Tensor` with up to `max_new_tokens` elements (one element for each - generated token), with each tensor of shape `(batch_size, config.vocab_size)`. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer of the decoder) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - decoder_attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, num_heads, generated_length, sequence_length)`. - cross_attentions (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, num_heads, generated_length, sequence_length)`. - decoder_hidden_states (`tuple(tuple(tf.Tensor))`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of - `tf.Tensor` of shape `(batch_size, generated_length, hidden_size)`. - """ - - sequences: Optional[tf.Tensor] = None - scores: Optional[tuple[tf.Tensor]] = None - encoder_attentions: Optional[tuple[tf.Tensor]] = None - encoder_hidden_states: Optional[tuple[tf.Tensor]] = None - decoder_attentions: Optional[tuple[tuple[tf.Tensor]]] = None - cross_attentions: Optional[tuple[tuple[tf.Tensor]]] = None - decoder_hidden_states: Optional[tuple[tuple[tf.Tensor]]] = None - - -TFGreedySearchOutput = Union[TFGreedySearchEncoderDecoderOutput, TFGreedySearchDecoderOnlyOutput] -TFSampleOutput = Union[TFSampleEncoderDecoderOutput, TFSampleDecoderOnlyOutput] -TFBeamSearchOutput = Union[TFBeamSearchEncoderDecoderOutput, TFBeamSearchDecoderOnlyOutput] -TFBeamSampleOutput = Union[TFBeamSampleEncoderDecoderOutput, TFBeamSampleDecoderOnlyOutput] -TFContrastiveSearchOutput = Union[TFContrastiveSearchEncoderDecoderOutput, TFContrastiveSearchDecoderOnlyOutput] -TFGenerateOutput = Union[ - TFGreedySearchOutput, TFSampleOutput, TFBeamSearchOutput, TFBeamSampleOutput, TFContrastiveSearchOutput -] - - -class TFGenerationMixin: - """ - A class containing all of the functions supporting generation, to be used as a mixin in [`TFPreTrainedModel`]. - - The class exposes [`~generation.TFGenerationMixin.generate`], which can be used for: - - *greedy decoding* by calling [`~generation.TFGenerationMixin.greedy_search`] if `num_beams=1` and - `do_sample=False` - - *contrastive search* by calling [`~generation.TFGenerationMixin.contrastive_search`] if `penalty_alpha>0` and - `top_k>1` - - *multinomial sampling* by calling [`~generation.TFGenerationMixin.sample`] if `num_beams=1` and - `do_sample=True` - - *beam-search decoding* by calling [`~generation.TFGenerationMixin.beam_search`] if `num_beams>1` - - You do not need to call any of the above methods directly. Pass custom parameter values to 'generate' instead. To - learn more about decoding strategies refer to the [text generation strategies guide](../generation_strategies). - """ - - _seed_generator = None - - @property - def seed_generator(self): - warnings.warn("`seed_generator` is deprecated and will be removed in a future version.", UserWarning) - if self._seed_generator is None: - self._seed_generator = tf.random.Generator.from_non_deterministic_state() - return self._seed_generator - - supports_xla_generation = True - - def prepare_inputs_for_generation(self, *args, **kwargs): - raise NotImplementedError( - "A model class needs to define a `prepare_inputs_for_generation` method in order to use `generate`." - ) - - def compute_transition_scores( - self, - sequences: tf.Tensor, - scores: tuple[tf.Tensor], - beam_indices: Optional[tf.Tensor] = None, - normalize_logits: bool = False, - ) -> tf.Tensor: - """ - Computes the transition scores of sequences given the generation scores (and beam indices, if beam search was - used). This is a convenient method to quickly obtain the scores of the selected tokens at generation time. - - Parameters: - sequences (`tf.Tensor`): - The generated sequences. The second dimension (sequence_length) is either equal to `max_length` or - shorter if all batches finished early due to the `eos_token_id`. - scores (`tuple(tf.Tensor)`): - Transition scores for each vocabulary token at each generation step. Beam transition scores consisting - of log probabilities of tokens conditioned on log softmax of previously generated tokens Tuple of - `tf.Tensor` with up to `max_new_tokens` elements (one element for each generated token), with each - tensor of shape `(batch_size*num_beams, config.vocab_size)`. - beam_indices (`tf.Tensor`, *optional*): - Beam indices of generated token id at each generation step. `tf.Tensor` of shape - `(batch_size*num_return_sequences, sequence_length)`. Only required if a `num_beams>1` at - generate-time. - normalize_logits (`bool`, *optional*, defaults to `False`): - Whether to normalize the logits (which, for legacy reasons, may be unnormalized). - - Return: - `tf.Tensor`: A `tf.Tensor` of shape `(batch_size*num_return_sequences, sequence_length)` containing - the transition scores (logits) - - Examples: - - ```python - >>> from transformers import GPT2Tokenizer, TFAutoModelForCausalLM - >>> import numpy as np - - >>> tokenizer = GPT2Tokenizer.from_pretrained("openai-community/gpt2") - >>> model = TFAutoModelForCausalLM.from_pretrained("openai-community/gpt2") - >>> tokenizer.pad_token_id = tokenizer.eos_token_id - >>> inputs = tokenizer(["Today is"], return_tensors="tf") - - >>> # Example 1: Print the scores for each token generated with Greedy Search - >>> outputs = model.generate(**inputs, max_new_tokens=5, return_dict_in_generate=True, output_scores=True) - >>> transition_scores = model.compute_transition_scores( - ... outputs.sequences, outputs.scores, normalize_logits=True - ... ) - >>> # input_length is the length of the input prompt for decoder-only models, like the GPT family, and 1 for - >>> # encoder-decoder models, like BART or T5. - >>> input_length = 1 if model.config.is_encoder_decoder else inputs.input_ids.shape[1] - >>> generated_tokens = outputs.sequences[:, input_length:] - >>> for tok, score in zip(generated_tokens[0], transition_scores[0]): - ... # | token | token string | logits | probability - ... print(f"| {tok:5d} | {tokenizer.decode(tok):8s} | {score.numpy():.3f} | {np.exp(score.numpy()):.2%}") - | 262 | the | -1.414 | 24.33% - | 1110 | day | -2.609 | 7.36% - | 618 | when | -2.010 | 13.40% - | 356 | we | -1.859 | 15.58% - | 460 | can | -2.508 | 8.14% - - >>> # Example 2: Reconstruct the sequence scores from Beam Search - >>> outputs = model.generate( - ... **inputs, - ... max_new_tokens=5, - ... num_beams=4, - ... num_return_sequences=4, - ... return_dict_in_generate=True, - ... output_scores=True, - ... ) - >>> transition_scores = model.compute_transition_scores( - ... outputs.sequences, outputs.scores, outputs.beam_indices, normalize_logits=False - ... ) - >>> # If you sum the generated tokens' scores and apply the length penalty, you'll get the sequence scores. - >>> # Tip: recomputing the scores is only guaranteed to match with `normalize_logits=False`. Depending on the - >>> # use case, you might want to recompute it with `normalize_logits=True`. - >>> output_length = np.sum(transition_scores.numpy() < 0, axis=1) - >>> length_penalty = model.generation_config.length_penalty - >>> reconstructed_scores = np.sum(transition_scores, axis=1) / (output_length**length_penalty) - >>> print(np.allclose(outputs.sequences_scores, reconstructed_scores)) - True - ```""" - # 1. In absence of `beam_indices`, we can assume that we come from e.g. greedy search, which is equivalent - # to a beam search approach were the first (and only) beam is always selected - if beam_indices is None: - beam_indices = tf.tile(tf.expand_dims(tf.range(scores[0].shape[0]), axis=1), [1, len(scores)]) - - # 2. reshape scores as [batch_size, vocab_size, # generation steps] with # generation steps being - # seq_len - input_length - scores = tf.transpose(tf.reshape(tf.stack(scores), (len(scores), -1)), (1, 0)) - scores = tf.reshape(scores, (-1, self.config.vocab_size, scores.shape[-1])) - - # 3. Optionally normalize the logits (across the vocab dimension) - if normalize_logits: - scores = tf.nn.log_softmax(scores, axis=1) - - # 4. cut beam_indices to longest beam length - beam_indices_mask = beam_indices < 0 - max_beam_length = tf.math.reduce_max( - tf.math.reduce_sum((1 - tf.cast(beam_indices_mask, dtype=tf.int32)), axis=-1) - ) - beam_indices = beam_indices[:, -max_beam_length:] - beam_indices_mask = beam_indices_mask[:, -max_beam_length:] - - # 5. Set indices of beams that finished early to 0; such indices will be masked correctly afterwards - beam_indices = tf.where(beam_indices_mask, 0, beam_indices) - - # 6. Define which indices contributed to scores - cut_idx = sequences.shape[-1] - max_beam_length - token_indices = sequences[:, cut_idx:] - gen_step_idx = tf.broadcast_to(tf.range(scores.shape[-1]), token_indices.shape) - indices = tf.stack([beam_indices, token_indices, gen_step_idx], axis=-1) - - # 7. Compute scores - transition_scores = tf.gather_nd(scores, indices) - - # 8. Mask out transition_scores of beams that stopped early - transition_scores = tf.where(beam_indices_mask, 0, transition_scores) - - return transition_scores - - def _validate_model_class(self): - """ - Confirms that the model class is compatible with generation. If not, raises an exception that points to the - right class to use. - """ - if not self.can_generate(): - generate_compatible_mappings = [ - TF_MODEL_FOR_CAUSAL_LM_MAPPING, - TF_MODEL_FOR_VISION_2_SEQ_MAPPING, - TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, - TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING, - ] - generate_compatible_classes = set() - for model_mapping in generate_compatible_mappings: - supported_models = model_mapping.get(type(self.config), default=None) - if supported_models is not None: - generate_compatible_classes.add(supported_models.__name__) - exception_message = ( - f"The current model class ({self.__class__.__name__}) is not compatible with `.generate()`, as " - "it doesn't have a language model head." - ) - if generate_compatible_classes: - exception_message += f" Please use one of the following classes instead: {generate_compatible_classes}" - raise TypeError(exception_message) - - def _validate_model_kwargs(self, model_kwargs: dict[str, Any]): - """Validates model kwargs for generation. Generate argument typos will also be caught here.""" - # Excludes arguments that are handled before calling any model function - if self.config.is_encoder_decoder: - for key in ["decoder_input_ids"]: - model_kwargs.pop(key, None) - - unused_model_args = [] - model_args = set(inspect.signature(self.prepare_inputs_for_generation).parameters) - # `kwargs`/`model_kwargs` is often used to handle optional forward pass inputs like `attention_mask`. If - # `prepare_inputs_for_generation` doesn't accept them, then a stricter check can be made ;) - if "kwargs" in model_args or "model_kwargs" in model_args: - model_args |= set(inspect.signature(self.call).parameters) - for key, value in model_kwargs.items(): - if value is not None and key not in model_args: - unused_model_args.append(key) - - if unused_model_args: - raise ValueError( - f"The following `model_kwargs` are not used by the model: {unused_model_args} (note: typos in the" - " generate arguments will also show up in this list)" - ) - - def generate( - self, - inputs: Optional[tf.Tensor] = None, - generation_config: Optional[GenerationConfig] = None, - logits_processor: Optional[TFLogitsProcessorList] = None, - seed=None, - **kwargs, - ) -> Union[TFGenerateOutput, tf.Tensor]: - r""" - Generates sequences of token ids for models with a language modeling head. - - - - Most generation-controlling parameters are set in `generation_config` which, if not passed, will be set to the - model's default generation configuration. You can override any `generation_config` by passing the corresponding - parameters to generate, e.g. `.generate(inputs, num_beams=4, do_sample=True)`. - - For an overview of generation strategies and code examples, check out the [following - guide](../generation_strategies). - - - - Parameters: - inputs (`tf.Tensor` of varying shape depending on the modality, *optional*): - The sequence used as a prompt for the generation or as model inputs to the encoder. If `None` the - method initializes it with `bos_token_id` and a batch size of 1. For decoder-only models `inputs` - should of in the format of `input_ids`. For encoder-decoder models *inputs* can represent any of - `input_ids`, `input_values`, `input_features`, or `pixel_values`. - generation_config (`~generation.GenerationConfig`, *optional*): - The generation configuration to be used as base parametrization for the generation call. `**kwargs` - passed to generate matching the attributes of `generation_config` will override them. If - `generation_config` is not provided, the default will be used, which had the following loading - priority: 1) from the `generation_config.json` model file, if it exists; 2) from the model - configuration. Please note that unspecified parameters will inherit [`~generation.GenerationConfig`]'s - default values, whose documentation should be checked to parameterize generation. - logits_processor (`LogitsProcessorList`, *optional*): - Custom logits processors that complement the default logits processors built from arguments and - generation config. If a logit processor is passed that is already created with the arguments or a - generation config an error is thrown. This feature is intended for advanced users. - seed (`list[int]`, *optional*): - Random seed to control sampling, containing two integers, used when `do_sample` is `True`. See the - `seed` argument from stateless functions in `tf.random`. - kwargs (`dict[str, Any]`, *optional*): - Ad hoc parametrization of `generate_config` and/or additional model-specific kwargs that will be - forwarded to the `forward` function of the model. If the model is an encoder-decoder model, encoder - specific kwargs should not be prefixed and decoder specific kwargs should be prefixed with *decoder_*. - - Return: - [`~utils.ModelOutput`] or `tf.Tensor`: A [`~utils.ModelOutput`] (if `return_dict_in_generate=True` or when - `config.return_dict_in_generate=True`) or a `tf.Tensor`. - - If the model is *not* an encoder-decoder model (`model.config.is_encoder_decoder=False`), the possible - [`~utils.ModelOutput`] types are: - - - [`~generation.TFGreedySearchDecoderOnlyOutput`], - - [`~generation.TFSampleDecoderOnlyOutput`], - - [`~generation.TFBeamSearchDecoderOnlyOutput`], - - [`~generation.TFBeamSampleDecoderOnlyOutput`] - - If the model is an encoder-decoder model (`model.config.is_encoder_decoder=True`), the possible - [`~utils.ModelOutput`] types are: - - - [`~generation.TFGreedySearchEncoderDecoderOutput`], - - [`~generation.TFSampleEncoderDecoderOutput`], - - [`~generation.TFBeamSearchEncoderDecoderOutput`], - - [`~generation.TFBeamSampleEncoderDecoderOutput`] - - """ - - # 1. Handle `generation_config` and kwargs that might update it, and validate the `.generate()` call - self._validate_model_class() - - # priority: `generation_config` argument > `model.generation_config` (the default generation config) - if generation_config is None: - # legacy: users may modify the model configuration to control generation. To trigger this legacy behavior, - # two conditions must be met - # 1) the generation config must have been created from the model config (`_from_model_config` field); - # 2) the generation config must have seen no modification since its creation (the hash is the same). - if self.generation_config._from_model_config and self.generation_config._original_object_hash == hash( - self.generation_config - ): - new_generation_config = GenerationConfig.from_model_config(self.config) - if new_generation_config != self.generation_config: - warnings.warn( - "You have modified the pretrained model configuration to control generation. This is a" - " deprecated strategy to control generation and will be removed soon, in a future version." - " Please use and modify the model generation configuration (see" - " https://huggingface.co/docs/transformers/generation_strategies#default-text-generation-configuration )" - ) - self.generation_config = new_generation_config - generation_config = self.generation_config - - generation_config = copy.deepcopy(generation_config) - model_kwargs = generation_config.update(**kwargs) # All unused kwargs must be model kwargs - self._validate_model_kwargs(model_kwargs.copy()) - - # 2. Cast input dtypes to tf.int32 unless they're floats (which happens for some image models) - if inputs is not None: - if isinstance(inputs, tf.Tensor) and inputs.dtype.is_floating: - pass - elif isinstance(inputs, np.ndarray) and np.issubdtype(inputs.dtype, np.floating): - pass - else: - inputs = tf.cast(inputs, tf.int32) - if model_kwargs.get("attention_mask") is not None: - model_kwargs["attention_mask"] = tf.cast(model_kwargs["attention_mask"], tf.int32) - if "decoder_input_ids" in model_kwargs: - if ( - isinstance(model_kwargs["decoder_input_ids"], tf.Tensor) - and model_kwargs["decoder_input_ids"].dtype.is_floating - ): - pass - elif isinstance(model_kwargs["decoder_input_ids"], np.ndarray) and np.issubdtype( - model_kwargs["decoder_input_ids"].dtype, np.floating - ): - pass - else: - model_kwargs["decoder_input_ids"] = tf.cast(model_kwargs["decoder_input_ids"], tf.int32) - - # 3. Set generation parameters if not already defined - logits_processor = logits_processor if logits_processor is not None else TFLogitsProcessorList() - - if generation_config.pad_token_id is None and generation_config.eos_token_id is not None: - if model_kwargs.get("attention_mask") is None: - logger.warning( - "The attention mask and the pad token id were not set. As a consequence, you may observe " - "unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results." - ) - eos_token_id = generation_config.eos_token_id - if isinstance(eos_token_id, list): - eos_token_id = eos_token_id[0] - generation_config.pad_token_id = eos_token_id - - use_xla = not tf.executing_eagerly() - if use_xla and not self.supports_xla_generation: - raise ValueError( - "The selected model does not support Graph mode nor XLA generation (e.g. from tf.function())" - ) - - # 4. Define model inputs - inputs_tensor, model_input_name, model_kwargs = self._prepare_model_inputs( - inputs, generation_config.bos_token_id, model_kwargs - ) - # inputs_ids now has to be defined and cannot be None anymore - batch_size = shape_list(inputs_tensor)[0] - - # 5. Prepare other model kwargs - model_kwargs["output_attentions"] = generation_config.output_attentions - model_kwargs["output_hidden_states"] = generation_config.output_hidden_states - model_kwargs["use_cache"] = generation_config.use_cache - - accepts_attention_mask = "attention_mask" in set(inspect.signature(self.call).parameters.keys()) - requires_attention_mask = "encoder_outputs" not in model_kwargs - - if model_kwargs.get("attention_mask", None) is None and requires_attention_mask and accepts_attention_mask: - model_kwargs["attention_mask"] = self._prepare_attention_mask_for_generation( - inputs_tensor, generation_config.pad_token_id, generation_config.eos_token_id - ) - - # decoder-only models should use left-padding for generation - if not self.config.is_encoder_decoder: - if generation_config.pad_token_id is not None and tf.math.reduce_any( - inputs_tensor[:, -1] == generation_config.pad_token_id - ): - logger.warning( - "A decoder-only architecture is being used, but right-padding was detected! For correct " - "generation results, please set `padding_side='left'` when initializing the tokenizer." - ) - if self.config.is_encoder_decoder and "encoder_outputs" not in model_kwargs: - # if model is encoder decoder encoder_outputs are created and added to `model_kwargs` - model_kwargs = self._prepare_encoder_decoder_kwargs_for_generation( - inputs_tensor, model_kwargs, model_input_name - ) - - # 6. Prepare model inputs which will be used for auto-regressive generation - if self.config.is_encoder_decoder: - input_ids, model_kwargs = self._prepare_decoder_input_ids_for_generation( - batch_size=batch_size, - model_input_name=model_input_name, - model_kwargs=model_kwargs, - decoder_start_token_id=generation_config.decoder_start_token_id, - bos_token_id=generation_config.bos_token_id, - ) - else: - input_ids = inputs_tensor if model_input_name == "input_ids" else model_kwargs.pop("input_ids") - - # 7. Prepare `max_length` depending on other stopping criteria. - input_ids_seq_length = shape_list(input_ids)[-1] - has_default_max_length = kwargs.get("max_length") is None and generation_config.max_length is not None - if has_default_max_length and generation_config.max_new_tokens is None and generation_config.max_length == 20: - # 20 is the default max_length of the generation config - warnings.warn( - f"Using the model-agnostic default `max_length` (={generation_config.max_length}) " - "to control the generation length. recommend setting `max_new_tokens` to control the maximum length of the generation.", - UserWarning, - ) - elif generation_config.max_new_tokens is not None: - if not has_default_max_length and generation_config.max_length is not None: - logger.warning( - f"Both `max_new_tokens` (={generation_config.max_new_tokens}) and `max_length`(=" - f"{generation_config.max_length}) seem to have been set. `max_new_tokens` will take precedence. " - "Please refer to the documentation for more information. " - "(https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)" - ) - generation_config.max_length = generation_config.max_new_tokens + input_ids_seq_length - - # If the input length is a tensor (i.e. dynamic length), skip length checks - if not isinstance(input_ids_seq_length, tf.Tensor): - if ( - generation_config.min_length is not None - and generation_config.min_length > generation_config.max_length - ): - raise ValueError( - f"Unfeasable length constraints: the minimum length ({generation_config.min_length}) is larger" - f" than the maximum length ({generation_config.max_length})" - ) - if input_ids_seq_length >= generation_config.max_length: - input_ids_string = "decoder_input_ids" if self.config.is_encoder_decoder else "input_ids" - logger.warning( - f"Input length of {input_ids_string} is {input_ids_seq_length}, but `max_length` is set to" - f" {generation_config.max_length}. This can lead to unexpected behavior. You should consider" - " increasing`max_new_tokens`." - ) - - # 8. determine generation mode - is_contrastive_search_gen_mode = ( - generation_config.top_k is not None - and generation_config.top_k > 1 - and generation_config.do_sample is False - and generation_config.penalty_alpha is not None - and generation_config.penalty_alpha > 0 - ) - is_greedy_gen_mode = ( - not is_contrastive_search_gen_mode - and (generation_config.num_beams == 1) - and generation_config.do_sample is False - ) - is_beam_gen_mode = ( - not is_contrastive_search_gen_mode - and (generation_config.num_beams > 1) - and generation_config.do_sample is False - ) - is_sample_gen_mode = (generation_config.num_beams == 1) and generation_config.do_sample is True - is_beam_sample_gen_mode = (generation_config.num_beams > 1) and generation_config.do_sample is True - - # 9. prepare distribution pre_processing samplers - logits_processor = self._get_logits_processor( - generation_config=generation_config, - input_ids_seq_length=input_ids_seq_length, - logits_processor=logits_processor, - ) - - # 10. go into different generation modes - if is_greedy_gen_mode: - if generation_config.num_return_sequences > 1: - raise ValueError( - f"num_return_sequences has to be 1, but is {generation_config.num_return_sequences} when doing" - " greedy search." - ) - # 11. run greedy search - return self.greedy_search( - input_ids, - max_length=generation_config.max_length, - pad_token_id=generation_config.pad_token_id, - eos_token_id=generation_config.eos_token_id, - logits_processor=logits_processor, - output_scores=generation_config.output_scores, - return_dict_in_generate=generation_config.return_dict_in_generate, - **model_kwargs, - ) - elif is_contrastive_search_gen_mode: - if generation_config.num_return_sequences > 1: - raise ValueError( - f"num_return_sequences has to be 1, but is {generation_config.num_return_sequences} when doing" - " contrastive search." - ) - # 11. run contrastive search - return self.contrastive_search( - input_ids, - top_k=generation_config.top_k, - penalty_alpha=generation_config.penalty_alpha, - logits_processor=logits_processor, - max_length=generation_config.max_length, - pad_token_id=generation_config.pad_token_id, - eos_token_id=generation_config.eos_token_id, - output_scores=generation_config.output_scores, - return_dict_in_generate=generation_config.return_dict_in_generate, - **model_kwargs, - ) - elif is_sample_gen_mode: - # 11. prepare logits warper - logits_warper = self._get_logits_warper(generation_config=generation_config) - - # 12. expand input_ids with `num_return_sequences` additional sequences per batch - input_ids, model_kwargs = self._expand_inputs_for_generation( - input_ids=input_ids, - expand_size=generation_config.num_return_sequences, - is_encoder_decoder=self.config.is_encoder_decoder, - **model_kwargs, - ) - - # 13. run sample - return self.sample( - input_ids, - logits_processor=logits_processor, - logits_warper=logits_warper, - max_length=generation_config.max_length, - pad_token_id=generation_config.pad_token_id, - eos_token_id=generation_config.eos_token_id, - seed=seed, - output_scores=generation_config.output_scores, - return_dict_in_generate=generation_config.return_dict_in_generate, - **model_kwargs, - ) - - elif is_beam_gen_mode: - if generation_config.num_beams < generation_config.num_return_sequences: - raise ValueError( - "Beam search decoding cannot return more sequences than it has beams. Please set num_beams >=" - f" num_return_sequences, got {generation_config.num_beams} and" - f" {generation_config.num_return_sequences} (respectively)" - ) - - # 11. broadcast inputs to the desired number of beams - input_ids, model_kwargs = self._expand_inputs_for_generation( - input_ids=input_ids, - expand_size=generation_config.num_beams, - is_encoder_decoder=self.config.is_encoder_decoder, - expand_in_new_axis=True, - **model_kwargs, - ) - - # 12. run beam search - return self.beam_search( - input_ids, - max_length=generation_config.max_length, - pad_token_id=generation_config.pad_token_id, - eos_token_id=generation_config.eos_token_id, - length_penalty=generation_config.length_penalty, - early_stopping=generation_config.early_stopping, - logits_processor=logits_processor, - output_scores=generation_config.output_scores, - return_dict_in_generate=generation_config.return_dict_in_generate, - num_return_sequences=generation_config.num_return_sequences, - **model_kwargs, - ) - - elif is_beam_sample_gen_mode: - if generation_config.num_beams < generation_config.num_return_sequences: - raise ValueError( - "Beam search decoding cannot return more sequences than it has beams. Please set num_beams >=" - f" num_return_sequences, got {generation_config.num_beams} and" - f" {generation_config.num_return_sequences} (respectively)" - ) - - # 11. prepare logits warper - logits_warper = self._get_logits_warper(generation_config=generation_config) - - # 12. broadcast inputs to the desired number of beams - input_ids, model_kwargs = self._expand_inputs_for_generation( - input_ids=input_ids, - expand_size=generation_config.num_beams, - is_encoder_decoder=self.config.is_encoder_decoder, - expand_in_new_axis=True, - **model_kwargs, - ) - - # 13. run beam sample (beam search with sampling) - return self.beam_search( - input_ids, - do_sample=True, - max_length=generation_config.max_length, - pad_token_id=generation_config.pad_token_id, - eos_token_id=generation_config.eos_token_id, - length_penalty=generation_config.length_penalty, - early_stopping=generation_config.early_stopping, - logits_processor=logits_processor, - logits_warper=logits_warper, - output_scores=generation_config.output_scores, - return_dict_in_generate=generation_config.return_dict_in_generate, - num_return_sequences=generation_config.num_return_sequences, - **model_kwargs, - ) - - def _prepare_attention_mask_for_generation( - self, - inputs: tf.Tensor, - pad_token_id: Optional[int], - eos_token_id: Optional[int], - ) -> tf.Tensor: - is_input_ids = len(inputs.shape) == 2 and inputs.dtype in (tf.int32, tf.int64) - is_pad_token_in_inputs = (pad_token_id is not None) and tf.math.reduce_any(inputs == pad_token_id) - is_pad_token_not_equal_to_eos_token_id = (eos_token_id is None) or (pad_token_id != eos_token_id) - - # Check if input is input_ids and padded -> only then is attention_mask defined - if is_input_ids and is_pad_token_in_inputs and is_pad_token_not_equal_to_eos_token_id: - return tf.cast(tf.math.not_equal(inputs, pad_token_id), dtype=tf.int32) - else: - return tf.ones(inputs.shape[:2], dtype=tf.int32) - - def _prepare_encoder_decoder_kwargs_for_generation( - self, inputs_tensor: tf.Tensor, model_kwargs, model_input_name: Optional[str] = None - ) -> dict[str, Any]: - # 1. get encoder and store encoder outputs - encoder = self.get_encoder() - - # 2. prepare encoder args and encoder kwargs from model kwargs - irrelevant_prefix = ["decoder_", "cross_attn", "use_cache"] - encoder_kwargs = { - argument: value - for argument, value in model_kwargs.items() - if not any(argument.startswith(p) for p in irrelevant_prefix) - } - encoder_signature = set(inspect.signature(encoder.call).parameters) - encoder_accepts_wildcard = "kwargs" in encoder_signature or "model_kwargs" in encoder_signature - if not encoder_accepts_wildcard: - encoder_kwargs = { - argument: value for argument, value in encoder_kwargs.items() if argument in encoder_signature - } - - # 3. vision models don't use `attention_mask`. - encoder_kwargs["return_dict"] = True - encoder_kwargs[model_input_name] = inputs_tensor - if model_input_name != self.main_input_name: # in Keras, the first input must always be passed - encoder_kwargs[self.main_input_name] = None - encoder_outputs = encoder(**encoder_kwargs) - model_kwargs["encoder_outputs"] = encoder_outputs - - return model_kwargs - - def _prepare_decoder_input_ids_for_generation( - self, - batch_size: int, - model_input_name: str, - model_kwargs: dict[str, tf.Tensor], - decoder_start_token_id: Optional[int] = None, - bos_token_id: Optional[int] = None, - ) -> tuple[tf.Tensor, dict[str, tf.Tensor]]: - """Prepares `decoder_input_ids` for generation with encoder-decoder models""" - # 1. Check whether the user has defined `decoder_input_ids` manually. To facilitate in terms of input naming, - # we also allow the user to pass it under `input_ids`, if the encoder does not use it as the main input. - if model_kwargs is not None and "decoder_input_ids" in model_kwargs: - decoder_input_ids = model_kwargs.pop("decoder_input_ids") - elif "input_ids" in model_kwargs and model_input_name != "input_ids": - decoder_input_ids = model_kwargs.pop("input_ids") - else: - decoder_input_ids = None - - # 2. Encoder-decoder models expect the `decoder_input_ids` to start with a special token. Let's ensure that. - decoder_start_token_id = self._get_decoder_start_token_id(decoder_start_token_id, bos_token_id) - decoder_input_ids_start = tf.ones((batch_size, 1), dtype=tf.int32) * decoder_start_token_id - - # no user input -> use decoder_start_token_id as decoder_input_ids - if decoder_input_ids is None: - decoder_input_ids = decoder_input_ids_start - # user input but doesn't start with decoder_start_token_id -> prepend decoder_start_token_id (and adjust - # decoder_attention_mask if provided) - elif tf.reduce_all(decoder_input_ids[:, 0] != decoder_start_token_id): - decoder_input_ids = tf.concat([decoder_input_ids_start, decoder_input_ids], axis=-1) - if "decoder_attention_mask" in model_kwargs: - decoder_attention_mask = model_kwargs["decoder_attention_mask"] - decoder_attention_mask = tf.concat( - (tf.ones_like(decoder_attention_mask)[:, :1], decoder_attention_mask), - axis=-1, - ) - model_kwargs["decoder_attention_mask"] = decoder_attention_mask - - return decoder_input_ids, model_kwargs - - def _get_decoder_start_token_id( - self, decoder_start_token_id: Optional[int] = None, bos_token_id: Optional[int] = None - ) -> int: - # retrieve decoder_start_token_id for encoder-decoder models - # fall back to bos_token_id if necessary - decoder_start_token_id = ( - decoder_start_token_id - if decoder_start_token_id is not None - else self.generation_config.decoder_start_token_id - ) - bos_token_id = bos_token_id if bos_token_id is not None else self.generation_config.bos_token_id - - if decoder_start_token_id is not None: - return decoder_start_token_id - elif bos_token_id is not None: - return bos_token_id - raise ValueError( - "`decoder_start_token_id` or `bos_token_id` has to be defined for encoder-decoder generation." - ) - - @staticmethod - def _expand_inputs_for_generation( - expand_size: int = 1, - is_encoder_decoder: bool = False, - input_ids: Optional[tf.Tensor] = None, - expand_in_new_axis: bool = False, - **model_kwargs, - ) -> tuple[tf.Tensor, dict[str, Any]]: - """ - Expands tensors from [batch_size, ...] to [batch_size * expand_size, ...] or [batch_size, expand_size, ...], - depending on `expand_in_new_axis`. Beam-based approaches expect this function to be used with - `expand_in_new_axis=True` - """ - - def _expand_tensor(tensor: tf.Tensor): - if expand_in_new_axis: - shape = shape_list(tensor) - return tf.broadcast_to(tensor[:, None], (shape[0], expand_size) + tuple(shape[1:])) - else: - return tf.repeat(tensor, expand_size, axis=0) - - def _expand_dict_for_generation(dict_to_expand): - for key in dict_to_expand: - if dict_to_expand[key] is not None and isinstance(dict_to_expand[key], tf.Tensor): - dict_to_expand[key] = _expand_tensor(dict_to_expand[key]) - return dict_to_expand - - if input_ids is not None: - input_ids = _expand_tensor(input_ids) - - model_kwargs = _expand_dict_for_generation(model_kwargs) - - if is_encoder_decoder: - if model_kwargs.get("encoder_outputs") is None: - raise ValueError("If `is_encoder_decoder` is True, make sure that `encoder_outputs` is defined.") - model_kwargs["encoder_outputs"] = _expand_dict_for_generation(model_kwargs["encoder_outputs"]) - - return input_ids, model_kwargs - - def _prepare_model_inputs( - self, - inputs: Optional[tf.Tensor] = None, - bos_token_id: Optional[int] = None, - model_kwargs: Optional[dict[str, tf.Tensor]] = None, - ) -> tuple[tf.Tensor, Optional[str], dict[str, tf.Tensor]]: - """ - This function extracts the model-specific `inputs` for generation. - """ - # 1. retrieve all kwargs that are non-None or non-model input related. - # some encoder-decoder models have different names for model and encoder - if ( - self.config.is_encoder_decoder - and hasattr(self, "encoder") - and hasattr(self.encoder, "main_input_name") - and self.encoder.main_input_name != self.main_input_name - ): - input_name = self.encoder.main_input_name - else: - input_name = self.main_input_name - - model_kwargs = {k: v for k, v in model_kwargs.items() if v is not None or k != input_name} - - # 2. check whether model_input_name is passed as kwarg - # if yes and `inputs` is None use kwarg inputs - inputs_kwarg = model_kwargs.pop(input_name, None) - if inputs_kwarg is not None and inputs is not None: - raise ValueError( - f"`inputs`: {inputs}` were passed alongside {input_name} which is not allowed. " - f"Make sure to either pass {inputs} or {input_name}=..." - ) - elif inputs_kwarg is not None: - inputs = inputs_kwarg - - # 3. In the presence of `inputs_embeds` for text models: - # - decoder-only models should complain if the user attempts to pass `inputs_embeds`, but the model - # doesn't have its forwarding implemented. `inputs_embeds` is kept in `model_kwargs` and can coexist with - # input_ids (`inputs_embeds` will be used in the 1st generation step, as opposed to `input_ids`) - # - encoder-decoder models should complain if the user attempts to pass `inputs_embeds` and `input_ids`, and - # pull the former to inputs. It will be used in place of `input_ids` to get the encoder hidden states. - if input_name == "input_ids" and "inputs_embeds" in model_kwargs: - if not self.config.is_encoder_decoder: - has_inputs_embeds_forwarding = "inputs_embeds" in set( - inspect.signature(self.prepare_inputs_for_generation).parameters.keys() - ) - if not has_inputs_embeds_forwarding: - raise ValueError( - f"You passed `inputs_embeds` to `.generate()`, but the model class {self.__class__.__name__} " - "doesn't have its forwarding implemented. See the GPT2 implementation for an example " - "(https://github.com/huggingface/transformers/pull/21405), and feel free to open a PR with it!" - ) - # In this case, `input_ids` is moved to the `model_kwargs`, so a few automations (like the creation of - # the attention mask) can rely on the actual model input. - model_kwargs["input_ids"] = self._maybe_initialize_input_ids_for_generation( - inputs, bos_token_id, model_kwargs=model_kwargs - ) - else: - if inputs is not None: - raise ValueError("You passed `inputs_embeds` and `input_ids` to `.generate()`. Please pick one.") - inputs, input_name = model_kwargs["inputs_embeds"], "inputs_embeds" - - # 4. if `inputs` is still None, try to create `input_ids` from BOS token - inputs = self._maybe_initialize_input_ids_for_generation(inputs, bos_token_id, model_kwargs) - - return inputs, input_name, model_kwargs - - def _maybe_initialize_input_ids_for_generation( - self, - inputs: Optional[tf.Tensor] = None, - bos_token_id: Optional[int] = None, - model_kwargs: Optional[dict[str, tf.Tensor]] = None, - ) -> tf.Tensor: - """Initializes input ids for generation, if necessary.""" - if inputs is not None: - return inputs - - encoder_outputs = model_kwargs.get("encoder_outputs") - if self.config.is_encoder_decoder and encoder_outputs is not None: - # make dummy input_ids with value -100, as a sanity check ensuring that they won't be used for encoding - shape = encoder_outputs.last_hidden_state.shape[:-1] - return tf.ones(shape, dtype=tf.int32) * -100 - - if bos_token_id is None: - raise ValueError("`bos_token_id` has to be defined when no `input_ids` are provided.") - - # If there is some tensor in `model_kwargs`, we can infer the batch size from it. This is helpful with - # soft-prompting or in multimodal implementations built on top of decoder-only language models. - batch_size = 1 - for value in model_kwargs.values(): - if isinstance(value, tf.Tensor): - batch_size = value.shape[0] - break - return tf.ones((batch_size, 1), dtype=tf.int32) * bos_token_id - - @staticmethod - def _extract_past_from_model_output(outputs: ModelOutput): - past_key_values = None - if "past_key_values" in outputs: - past_key_values = outputs.past_key_values - elif "mems" in outputs: - past_key_values = outputs.mems - elif "past_buckets_states" in outputs: - past_key_values = outputs.past_buckets_states - return past_key_values - - def _update_model_kwargs_for_generation( - self, outputs: ModelOutput, model_kwargs: dict[str, Any], is_encoder_decoder: bool = False - ) -> dict[str, Any]: - # update past_key_values - model_kwargs["past_key_values"] = self._extract_past_from_model_output(outputs) - - # update attention mask - if not is_encoder_decoder: - if "attention_mask" in model_kwargs: - attention_mask = model_kwargs["attention_mask"] - model_kwargs["attention_mask"] = tf.concat( - [attention_mask, tf.ones((shape_list(attention_mask)[0], 1), dtype=tf.int32)], axis=-1 - ) - - return model_kwargs - - def _update_model_kwargs_for_xla_generation( - self, - model_outputs: ModelOutput, - model_kwargs: dict[str, Any], - cur_len: int, - max_length: int, - batch_size: int, - is_encoder_decoder: bool = False, - batch_axis: int = 0, - ): - def _initialize_attention(model_kwargs, num_padding_values, is_encoder_decoder): - """initializes the appropriate attention mask -- encoder-decoder models use `decoder_attention_mask`""" - if is_encoder_decoder: - # One 1 for decoder_start_token_id, 0s for the currently-unfilled locations in the past_key_values tensor, - # 1s for the actual input_ids - decoder_attention_mask = tf.concat( - [ - tf.ones((batch_size, 1), dtype=tf.int32), - tf.zeros((batch_size, num_padding_values), dtype=tf.int32), - tf.ones((batch_size, 1), dtype=tf.int32), - ], - axis=1, - ) - mask = {"decoder_attention_mask": decoder_attention_mask} - else: - attention_mask = model_kwargs.pop("attention_mask") - # 0s for the currently-unfilled locations in the past_key_values tensor, 1s for the actual input_ids - attention_mask = tf.concat( - [ - attention_mask, - tf.zeros((batch_size, num_padding_values), dtype=attention_mask.dtype), - tf.ones((batch_size, 1), dtype=attention_mask.dtype), - ], - axis=1, - ) - mask = {"attention_mask": attention_mask} - return mask - - def _update_attention(model_kwargs, new_past_index, is_encoder_decoder): - """updates the appropriate attention mask -- encoder-decoder models use `decoder_attention_mask`""" - update_start = tf.constant([0, 1], dtype=tf.int32) * new_past_index - if is_encoder_decoder: - decoder_attention_mask = model_kwargs.pop("decoder_attention_mask") - decoder_attention_mask_update_slice = tf.ones((batch_size, 1), dtype=decoder_attention_mask.dtype) - decoder_attention_mask = dynamic_update_slice( - decoder_attention_mask, decoder_attention_mask_update_slice, update_start - ) - mask = {"decoder_attention_mask": decoder_attention_mask} - else: - attention_mask = model_kwargs.pop("attention_mask") - attention_mask_update_slice = tf.ones((batch_size, 1), dtype=attention_mask.dtype) - attention_mask = dynamic_update_slice(attention_mask, attention_mask_update_slice, update_start) - mask = {"attention_mask": attention_mask} - return mask - - def _initialize_past(past_key_values, num_padding_values, batch_axis): - """initialize past_key_values with zeros -- the structure depends on `batch_axis`""" - if batch_axis == 0: - padding_values = tf.constant([[0, 0], [0, 0], [0, num_padding_values], [0, 0]], dtype=tf.int32) - new_past = () - for past_layer in past_key_values: - new_past_layer = list(past_layer) - for i in range(len(new_past_layer[:2])): - new_past_layer[i] = tf.pad(past_layer[i], padding_values) - new_past += (tuple(new_past_layer),) - else: - padding_values = tf.scatter_nd(indices=[[3, 1]], updates=[num_padding_values], shape=(5, 2)) - new_past = list(past_key_values) - for i in range(len(past_key_values)): - new_past[i] = tf.pad(past_key_values[i], padding_values) - return new_past - - def _update_past(past_key_values, new_past_index, batch_axis): - if batch_axis == 0: - slice_start_base = tf.constant([0, 0, 1, 0]) - new_past = () - for past_layer in past_key_values: - new_past_layer = list(past_layer) - for i in range(len(new_past_layer[:2])): - update_slice = past_layer[i][:, :, -1:] - # Write the last slice to the first open location in the padded past_key_values array - # and then truncate the last slice off the array - new_past_layer[i] = dynamic_update_slice( - past_layer[i][:, :, :-1], update_slice, slice_start_base * new_past_index - ) - new_past += (tuple(new_past_layer),) - else: - slice_start_base = tf.constant([0, 0, 0, 1, 0]) - new_past = [None for _ in range(len(past_key_values))] - for i in range(len(past_key_values)): - update_slice = past_key_values[i][:, :, :, -1:] - # Write the last slice to the first open location in the padded past_key_values array - # and then truncate the last slice off the array - new_past[i] = dynamic_update_slice( - past_key_values[i][:, :, :, :-1], update_slice, slice_start_base * new_past_index - ) - return new_past - - past_key_values = self._extract_past_from_model_output(model_outputs) - if past_key_values is None: - raise ValueError( - "No known `past_key_values variable` found in model outputs (model outputs keys:" - f" {list(model_outputs.keys())})" - ) - is_past_initialized = model_kwargs.pop("past_key_values", None) is not None - - if not is_past_initialized: - # The padded version of `past_key_values` has a length of `max_length - 1`, as `past_key_values` holds information relative to - # previous autoregressive generation steps (step 0 has no past_key_values, step 1 has 1 past_key_values value, ..., the last step - # has `max_length - 1` past_key_values values). - num_padding_values = max_length - cur_len - 1 - mask = _initialize_attention(model_kwargs, num_padding_values, is_encoder_decoder) - new_past = _initialize_past(past_key_values, num_padding_values, batch_axis) - else: - # The new index of past_key_values to be filled corresponds to the current length of the sequence, with two - # subtractions: -1 because past_key_values holds information regarding previous generation steps (read comment above) - # and -1 again because in an array the index is the length of the array minus 1. - new_past_index = cur_len - 2 - mask = _update_attention(model_kwargs, new_past_index, is_encoder_decoder) - new_past = _update_past(past_key_values, new_past_index, batch_axis) - - # sets the updated variables (mask and past_key_values) - model_kwargs.update(mask) - model_kwargs["past_key_values"] = tuple(new_past) - - return model_kwargs - - def _get_logits_warper( - self, - generation_config: GenerationConfig, - ) -> TFLogitsProcessorList: - """ - This class returns a [`TFLogitsProcessorList`] list object that contains all relevant [`TFLogitsWarper`] - instances used for multinomial sampling. - """ - - # instantiate warpers list - warpers = TFLogitsProcessorList() - - # In beam methods, we need to keep at least one non-eos token to explore continuations that might have a - # better score (i.e. keep len(generation_config.eos_token_id) + 1) - if generation_config.num_beams > 1: - if isinstance(generation_config.eos_token_id, list): - min_tokens_to_keep = len(generation_config.eos_token_id) + 1 - else: - min_tokens_to_keep = 2 - else: - min_tokens_to_keep = 1 - - if generation_config.temperature is not None and generation_config.temperature != 1.0: - warpers.append(TFTemperatureLogitsWarper(generation_config.temperature)) - if generation_config.top_k is not None and generation_config.top_k != 0: - warpers.append(TFTopKLogitsWarper(top_k=generation_config.top_k, min_tokens_to_keep=min_tokens_to_keep)) - if generation_config.top_p is not None and generation_config.top_p < 1.0: - warpers.append(TFTopPLogitsWarper(top_p=generation_config.top_p, min_tokens_to_keep=min_tokens_to_keep)) - return warpers - - def _get_logits_processor( - self, - generation_config: GenerationConfig, - input_ids_seq_length: int, - logits_processor: Optional[TFLogitsProcessorList], - ) -> TFLogitsProcessorList: - """ - This class returns a [`TFLogitsProcessorList`] list object that contains all relevant [`TFLogitsProcessor`] - instances used to modify the scores of the language model head. - """ - processors = TFLogitsProcessorList() - - # instantiate processors list - if generation_config.repetition_penalty is not None and generation_config.repetition_penalty != 1.0: - processors.append(TFRepetitionPenaltyLogitsProcessor(penalty=generation_config.repetition_penalty)) - if generation_config.no_repeat_ngram_size is not None and generation_config.no_repeat_ngram_size > 0: - processors.append(TFNoRepeatNGramLogitsProcessor(generation_config.no_repeat_ngram_size)) - if generation_config.bad_words_ids is not None: - processors.append( - TFNoBadWordsLogitsProcessor(generation_config.bad_words_ids, generation_config.eos_token_id) - ) - if ( - generation_config.min_length is not None - and generation_config.eos_token_id is not None - and generation_config.min_length > 0 - ): - processors.append(TFMinLengthLogitsProcessor(generation_config.min_length, generation_config.eos_token_id)) - if generation_config.forced_bos_token_id is not None: - processors.append(TFForcedBOSTokenLogitsProcessor(generation_config.forced_bos_token_id)) - if generation_config.forced_eos_token_id is not None: - processors.append( - TFForcedEOSTokenLogitsProcessor(generation_config.max_length, generation_config.forced_eos_token_id) - ) - if generation_config.suppress_tokens is not None: - processors.append(TFSuppressTokensLogitsProcessor(generation_config.suppress_tokens)) - if generation_config.begin_suppress_tokens is not None: - begin_index = input_ids_seq_length - begin_index = ( - begin_index - if (input_ids_seq_length > 1 or generation_config.forced_bos_token_id is None) - else begin_index + 1 - ) - if getattr(generation_config, "forced_decoder_ids", None) is not None: - begin_index += generation_config.forced_decoder_ids[-1][ - 0 - ] # generation starts after the last token that is forced - processors.append( - TFSuppressTokensAtBeginLogitsProcessor(generation_config.begin_suppress_tokens, begin_index) - ) - if getattr(generation_config, "forced_decoder_ids", None) is not None: - processors.append(TFForceTokensLogitsProcessor(generation_config.forced_decoder_ids)) - - processors = self._merge_criteria_processor_list(processors, logits_processor) - return processors - - def _merge_criteria_processor_list( - self, - default_list: TFLogitsProcessorList, - custom_list: TFLogitsProcessorList, - ) -> TFLogitsProcessorList: - if len(custom_list) == 0: - return default_list - for default in default_list: - for custom in custom_list: - if type(custom) is type(default): - object_type = "logits processor" - raise ValueError( - f"A custom {object_type} of type {type(custom)} with values {custom} has been passed to" - f" `generate`, but it has already been created with the values {default}. {default} has been" - " created by passing the corresponding arguments to generate or by the model's config default" - f" values. If you just want to change the default values of {object_type} consider passing" - f" them as arguments to `generate` instead of using a custom {object_type}." - ) - default_list.extend(custom_list) - return default_list - - def greedy_search( - self, - input_ids: tf.Tensor, - max_length: Optional[int] = None, - pad_token_id: Optional[int] = None, - eos_token_id: Optional[int] = None, - logits_processor: Optional[TFLogitsProcessorList] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - output_scores: Optional[bool] = None, - return_dict_in_generate: Optional[bool] = None, - **model_kwargs, - ) -> Union[TFGreedySearchOutput, tf.Tensor]: - r""" - Generates sequences for models with a language modeling head using greedy decoding. - - Parameters: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - The sequence used as a prompt for the generation. - logits_processor (`TFLogitsProcessorList`, *optional*): - An instance of [`TFLogitsProcessorList`]. List of instances of class derived from [`TFLogitsProcessor`] - used to modify the prediction scores of the language modeling head applied at each generation step. - max_length (`int`, *optional*, defaults to 20): - The maximum length of the sequence to be generated. - pad_token_id (`int`, *optional*): - The id of the *padding* token. - eos_token_id (`Union[int, list[int]]`, *optional*): - The id of the *end-of-sequence* token. Optionally, use a list to set multiple *end-of-sequence* tokens. - output_attentions (`bool`, *optional*, defaults to `False`): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more details. - output_hidden_states (`bool`, *optional*, defaults to `False`): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more details. - output_scores (`bool`, *optional*, defaults to `False`): - Whether or not to return the prediction scores. See `scores` under returned tensors for more details. - return_dict_in_generate (`bool`, *optional*, defaults to `False`): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - model_kwargs: - Additional model specific keyword arguments will be forwarded to the `call` function of the model. If - model is an encoder-decoder model the kwargs should include `encoder_outputs`. - - Return: - [`~generation.TFGreedySearchDecoderOnlyOutput`], [`~generation.TFGreedySearchEncoderDecoderOutput`] or - `tf.Tensor`: A `tf.Tensor` containing the generated tokens (default behaviour) or a - [`~generation.TFGreedySearchDecoderOnlyOutput`] if `model.config.is_encoder_decoder=False` and - `return_dict_in_generate=True` or a [`~generation.TFGreedySearchEncoderDecoderOutput`] if - `model.config.is_encoder_decoder=True`. - - Examples: - - ```python - >>> from transformers import ( - ... AutoTokenizer, - ... TFAutoModelForCausalLM, - ... TFLogitsProcessorList, - ... TFMinLengthLogitsProcessor, - ... ) - - >>> tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2") - >>> model = TFAutoModelForCausalLM.from_pretrained("openai-community/gpt2") - - >>> # set pad_token_id to eos_token_id because GPT2 does not have a PAD token - >>> model.generation_config.pad_token_id = model.generation_config.eos_token_id - - >>> input_prompt = "Today is a beautiful day, and" - >>> input_ids = tokenizer(input_prompt, return_tensors="tf").input_ids - - >>> # instantiate logits processors - >>> logits_processor = TFLogitsProcessorList( - ... [ - ... TFMinLengthLogitsProcessor(15, eos_token_id=model.generation_config.eos_token_id), - ... ] - ... ) - - >>> outputs = model.greedy_search(input_ids, logits_processor=logits_processor) - >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) - ["Today is a beautiful day, and I'm so happy to be here. I'm so happy to"] - ```""" - - # 1. init greedy_search values - logits_processor = logits_processor if logits_processor is not None else TFLogitsProcessorList() - - max_length = max_length if max_length is not None else self.generation_config.max_length - pad_token_id = pad_token_id if pad_token_id is not None else self.generation_config.pad_token_id - eos_token_id = eos_token_id if eos_token_id is not None else self.generation_config.eos_token_id - if isinstance(eos_token_id, int): - eos_token_id = [eos_token_id] - output_scores = output_scores if output_scores is not None else self.generation_config.output_scores - output_attentions = ( - output_attentions if output_attentions is not None else self.generation_config.output_attentions - ) - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.generation_config.output_hidden_states - ) - return_dict_in_generate = ( - return_dict_in_generate - if return_dict_in_generate is not None - else self.generation_config.return_dict_in_generate - ) - use_cache = model_kwargs.pop("use_cache", self.generation_config.use_cache) - use_xla = not tf.executing_eagerly() - # TODO (Joao): fix cache format or find programmatic way to detect cache index - # GPT2 and other models has a slightly different cache structure, with a different batch axis - model_name = str(self.decoder) if "EncoderDecoder" in str(self) else str(self) - cache_batch_axis = 1 if any(model_prefix in model_name for model_prefix in ("TFGPT2", "TFCTRL")) else 0 - # some models, like XLNet, need more than the last token in the presence of past_key_values - needs_full_input = "use_mems" in set(inspect.signature(self.prepare_inputs_for_generation).parameters.keys()) - - # 2. init `attentions`, `hidden_states`, and `scores` tuples - scores = [] if (return_dict_in_generate and output_scores) else None - decoder_attentions = [] if (return_dict_in_generate and output_attentions) else None - cross_attentions = [] if (return_dict_in_generate and output_attentions) else None - decoder_hidden_states = [] if (return_dict_in_generate and output_hidden_states) else None - - # 3. init tensors to use for "xla-compileable" generate function - batch_size, cur_len = shape_list(input_ids) - - # initialize `generated` (`input_ids` padded with `pad_token_id`), `finished_sequences` - input_ids_padding = tf.ones((batch_size, max_length - cur_len), dtype=tf.int32) * (pad_token_id or 0) - generated = tf.concat([input_ids, input_ids_padding], axis=-1) - finished_sequences = tf.zeros((batch_size,), dtype=tf.bool) - - # 4. define "xla-compile-able" stop-condition and auto-regressive function - # define condition fn - def greedy_search_cond_fn(generated, finished_sequences, cur_len, model_kwargs): - """state termination condition fn.""" - return ~tf.reduce_all(finished_sequences) - - # define condition fn - def greedy_search_body_fn(generated, finished_sequences, cur_len, model_kwargs): - """state update fn.""" - if model_kwargs.get("past_key_values") is None or needs_full_input: - input_ids = generated[:, :cur_len] - else: - input_ids = tf.expand_dims(generated[:, cur_len - 1], -1) - model_inputs = self.prepare_inputs_for_generation(input_ids, use_cache=use_cache, **model_kwargs) - # forward pass to get next token logits - model_outputs = self( - **model_inputs, - return_dict=True, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - ) - next_token_logits = model_outputs.logits[:, -1] - - # pre-process distribution - next_tokens_scores = logits_processor(generated, next_token_logits, cur_len) - - # Store scores, attentions and hidden_states when required - if not use_xla and return_dict_in_generate: - if output_scores: - scores.append(next_tokens_scores) - if output_attentions and self.config.is_encoder_decoder: - decoder_attentions.append(model_outputs.decoder_attentions) - elif output_attentions and not self.config.is_encoder_decoder: - decoder_attentions.append(model_outputs.attentions) - if self.config.is_encoder_decoder: - cross_attentions.append(model_outputs.cross_attentions) - - if output_hidden_states and self.config.is_encoder_decoder: - decoder_hidden_states.append(model_outputs.decoder_hidden_states) - elif output_hidden_states and self.config.is_encoder_decoder: - decoder_hidden_states.append(model_outputs.hidden_states) - - # argmax - next_tokens = tf.argmax(next_tokens_scores, axis=-1, output_type=tf.int32) - - if eos_token_id is not None: - if pad_token_id is None: - raise ValueError("If `eos_token_id` is defined, make sure that `pad_token_id` is defined.") - unfinished_seq = 1 - tf.cast(finished_sequences, tf.int32) - next_tokens = next_tokens * unfinished_seq + pad_token_id * (1 - unfinished_seq) - next_token_is_eos = tf.math.reduce_any( - tf.equal( - tf.broadcast_to(next_tokens, (len(eos_token_id), batch_size)), tf.expand_dims(eos_token_id, -1) - ), - axis=0, - ) - finished_sequences = finished_sequences | next_token_is_eos - - # update `generated` and `cur_len` - update_indices = tf.stack([tf.range(batch_size), tf.broadcast_to(cur_len, [batch_size])], axis=-1) - generated = tf.tensor_scatter_nd_update(tensor=generated, indices=update_indices, updates=next_tokens) - cur_len += 1 - - # update model_kwargs - if use_xla: - model_kwargs = self._update_model_kwargs_for_xla_generation( - model_outputs=model_outputs, - model_kwargs=model_kwargs, - cur_len=cur_len, - max_length=max_length, - batch_size=batch_size, - is_encoder_decoder=self.config.is_encoder_decoder, - batch_axis=cache_batch_axis, - ) - else: - model_kwargs = self._update_model_kwargs_for_generation( - model_outputs, model_kwargs, is_encoder_decoder=self.config.is_encoder_decoder - ) - # if we don't cache past_key_values key values we need the whole input - if model_kwargs.get("past_key_values", None) is None: - # let's throw out `past_key_values` since we don't want `None` tensors - model_kwargs.pop("past_key_values", None) - - return generated, finished_sequences, cur_len, model_kwargs - - # 5. run generation - # 1st generation step has to be run before to initialize `past_key_values` - generated, finished_sequences, cur_len, model_kwargs = greedy_search_body_fn( - generated, finished_sequences, cur_len, model_kwargs - ) - - # 2-to-n generation steps can then be run in autoregressive fashion - # only in case 1st generation step does NOT yield EOS token though - maximum_iterations = max_length - cur_len - generated, _, cur_len, _ = tf.while_loop( - greedy_search_cond_fn, - greedy_search_body_fn, - (generated, finished_sequences, cur_len, model_kwargs), - maximum_iterations=maximum_iterations, - ) - - # 6. prepare outputs - if not use_xla: - # cut for backward compatibility - generated = generated[:, :cur_len] - - if return_dict_in_generate: - if self.config.is_encoder_decoder: - # if model is an encoder-decoder, retrieve encoder attention weights - # and hidden states - encoder_attentions = model_kwargs["encoder_outputs"].get("attentions") if output_attentions else None - encoder_hidden_states = ( - model_kwargs["encoder_outputs"].get("hidden_states") if output_hidden_states else None - ) - - scores = tuple(scores) if scores is not None else None - decoder_attentions = tuple(decoder_attentions) if decoder_attentions is not None else None - cross_attentions = tuple(cross_attentions) if cross_attentions is not None else None - decoder_hidden_states = tuple(decoder_hidden_states) if decoder_hidden_states is not None else None - - return TFGreedySearchEncoderDecoderOutput( - sequences=generated, - scores=scores, - encoder_attentions=encoder_attentions, - encoder_hidden_states=encoder_hidden_states, - decoder_attentions=decoder_attentions, - cross_attentions=cross_attentions, - decoder_hidden_states=decoder_hidden_states, - ) - else: - return TFGreedySearchDecoderOnlyOutput( - sequences=generated, - scores=scores, - attentions=decoder_attentions, - hidden_states=decoder_hidden_states, - ) - else: - return generated - - def sample( - self, - input_ids: tf.Tensor, - logits_processor: Optional[TFLogitsProcessorList] = None, - logits_warper: Optional[TFLogitsProcessorList] = None, - max_length: Optional[int] = None, - pad_token_id: Optional[int] = None, - eos_token_id: Optional[int] = None, - seed: Optional[tuple[int, int]] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - output_scores: Optional[bool] = None, - return_dict_in_generate: Optional[bool] = None, - **model_kwargs, - ) -> Union[TFSampleOutput, tf.Tensor]: - r""" - Generates sequences for models with a language modeling head using multinomial sampling. - - Parameters: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - The sequence used as a prompt for the generation. - logits_processor (`TFLogitsProcessorList`, *optional*): - An instance of [`TFLogitsProcessorList`]. List of instances of class derived from [`TFLogitsProcessor`] - used to modify the prediction scores of the language modeling head applied at each generation step. - logits_warper (`TFLogitsProcessorList`, *optional*): - An instance of [`TFLogitsProcessorList`]. List of instances of class derived from [`TFLogitsWarper`] - used to warp the prediction score distribution of the language modeling head applied before multinomial - sampling at each generation step. - max_length (`int`, *optional*, defaults to 20): - The maximum length of the sequence to be generated. - pad_token_id (`int`, *optional*): - The id of the *padding* token. - eos_token_id (`Union[int, list[int]]`, *optional*): - The id of the *end-of-sequence* token. Optionally, use a list to set multiple *end-of-sequence* tokens. - seed (`list[int]`, *optional*): - Random seed to control sampling, containing two integers, used when `do_sample` is `True`. See the - `seed` argument from stateless functions in `tf.random`. - output_attentions (`bool`, *optional*, defaults to `False`): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more details. - output_hidden_states (`bool`, *optional*, defaults to `False`): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more details. - output_scores (`bool`, *optional*, defaults to `False`): - Whether or not to return the prediction scores. See `scores` under returned tensors for more details. - return_dict_in_generate (`bool`, *optional*, defaults to `False`): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - model_kwargs: - Additional model specific kwargs will be forwarded to the `call` function of the model. If model is an - encoder-decoder model the kwargs should include `encoder_outputs`. - - Return: - [`~generation.TFSampleDecoderOnlyOutput`], [`~generation.TFSampleEncoderDecoderOutput`] or `tf.Tensor`: A - `tf.Tensor` containing the generated tokens (default behaviour) or a - [`~generation.TFSampleDecoderOnlyOutput`] if `model.config.is_encoder_decoder=False` and - `return_dict_in_generate=True` or a [`~generation.TFSampleEncoderDecoderOutput`] if - `model.config.is_encoder_decoder=True`. - - Examples: - - ```python - >>> import tensorflow as tf - >>> from transformers import ( - ... AutoTokenizer, - ... TFAutoModelForCausalLM, - ... TFLogitsProcessorList, - ... TFMinLengthLogitsProcessor, - ... TFTopKLogitsWarper, - ... TFTemperatureLogitsWarper, - ... ) - - >>> tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2") - >>> model = TFAutoModelForCausalLM.from_pretrained("openai-community/gpt2") - - >>> # set pad_token_id to eos_token_id because GPT2 does not have a EOS token - >>> model.generation_config.pad_token_id = model.generation_config.eos_token_id - - >>> input_prompt = "Today is a beautiful day, and" - >>> input_ids = tokenizer(input_prompt, return_tensors="tf").input_ids - - >>> # instantiate logits processors - >>> logits_processor = TFLogitsProcessorList( - ... [ - ... TFMinLengthLogitsProcessor(15, eos_token_id=model.generation_config.eos_token_id), - ... ] - ... ) - >>> # instantiate logits processors - >>> logits_warper = TFLogitsProcessorList( - ... [ - ... TFTopKLogitsWarper(50), - ... TFTemperatureLogitsWarper(0.7), - ... ] - ... ) - - >>> tf.random.set_seed(0) - >>> outputs = model.sample(input_ids, logits_processor=logits_processor, logits_warper=logits_warper) - - >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) - ['Today is a beautiful day, and I love my country. But when I look at Donald Trump,'] - ```""" - - # 1. init greedy_search values - logits_processor = logits_processor if logits_processor is not None else TFLogitsProcessorList() - logits_warper = logits_warper if logits_warper is not None else TFLogitsProcessorList() - - max_length = max_length if max_length is not None else self.generation_config.max_length - pad_token_id = pad_token_id if pad_token_id is not None else self.generation_config.pad_token_id - eos_token_id = eos_token_id if eos_token_id is not None else self.generation_config.eos_token_id - if isinstance(eos_token_id, int): - eos_token_id = [eos_token_id] - output_scores = output_scores if output_scores is not None else self.generation_config.output_scores - output_attentions = ( - output_attentions if output_attentions is not None else self.generation_config.output_attentions - ) - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.generation_config.output_hidden_states - ) - return_dict_in_generate = ( - return_dict_in_generate - if return_dict_in_generate is not None - else self.generation_config.return_dict_in_generate - ) - use_cache = model_kwargs.pop("use_cache", self.generation_config.use_cache) - use_xla = not tf.executing_eagerly() - # TODO (Joao): fix cache format or find programmatic way to detect cache index - # GPT2 and other models has a slightly different cache structure, with a different batch axis - model_name = str(self.decoder) if "EncoderDecoder" in str(self) else str(self) - cache_batch_axis = 1 if any(model_prefix in model_name for model_prefix in ("TFGPT2", "TFCTRL")) else 0 - # some models, like XLNet, need more than the last token in the presence of past_key_values - needs_full_input = "use_mems" in set(inspect.signature(self.prepare_inputs_for_generation).parameters.keys()) - - # 2. init `attentions`, `hidden_states`, and `scores` tuples - scores = [] if (return_dict_in_generate and output_scores) else None - decoder_attentions = [] if (return_dict_in_generate and output_attentions) else None - cross_attentions = [] if (return_dict_in_generate and output_attentions) else None - decoder_hidden_states = [] if (return_dict_in_generate and output_hidden_states) else None - - # 3. init tensors to use for "xla-compileable" generate function - batch_size, cur_len = shape_list(input_ids) - - # initialize `generated` (pre-populated with `pad_token_id`), `finished_sequences` - input_ids_padding = tf.ones((batch_size, max_length - cur_len), dtype=tf.int32) * (pad_token_id or 0) - generated = tf.concat([input_ids, input_ids_padding], axis=-1) - finished_sequences = tf.zeros((batch_size,), dtype=tf.bool) - - # 4. define "xla-compile-able" stop-condition and auto-regressive function - def sample_cond_fn(generated, finished_sequences, cur_len, model_kwargs): - return ~tf.reduce_all(finished_sequences) - - def sample_body_fn(generated, finished_sequences, cur_len, model_kwargs): - if model_kwargs.get("past_key_values") is None or needs_full_input: - input_ids = generated[:, :cur_len] - else: - input_ids = tf.expand_dims(generated[:, cur_len - 1], -1) - model_inputs = self.prepare_inputs_for_generation(input_ids, use_cache=use_cache, **model_kwargs) - # forward pass to get next token logits - model_outputs = self( - **model_inputs, - return_dict=True, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - ) - next_token_logits = model_outputs.logits[:, -1] - - # pre-process distribution - next_tokens_scores = logits_processor(generated, next_token_logits, cur_len) - next_tokens_scores = logits_warper(generated, next_tokens_scores, cur_len) - - # Store scores, attentions and hidden_states when required - if not use_xla and return_dict_in_generate: - if output_scores: - scores.append(next_tokens_scores) - if output_attentions and self.config.is_encoder_decoder: - decoder_attentions.append(model_outputs.decoder_attentions) - elif output_attentions and not self.config.is_encoder_decoder: - decoder_attentions.append(model_outputs.attentions) - if self.config.is_encoder_decoder: - cross_attentions.append(model_outputs.cross_attentions) - - if output_hidden_states and self.config.is_encoder_decoder: - decoder_hidden_states.append(model_outputs.decoder_hidden_states) - elif output_hidden_states and self.config.is_encoder_decoder: - decoder_hidden_states.append(model_outputs.hidden_states) - - # sample - if seed is not None: - sample_seed = seed - else: - sample_seed = tf.experimental.numpy.random.randint(tf.int32.min, tf.int32.max, (2,), dtype=tf.int32) - next_tokens = tf.squeeze( - tf.random.stateless_categorical( - logits=next_tokens_scores, num_samples=1, seed=sample_seed, dtype=tf.int32 - ), - axis=1, - ) - - if eos_token_id is not None: - if pad_token_id is None: - raise ValueError("If `eos_token_id` is defined, make sure that `pad_token_id` is defined.") - unfinished_seq = 1 - tf.cast(finished_sequences, tf.int32) - next_tokens = next_tokens * unfinished_seq + pad_token_id * (1 - unfinished_seq) - next_token_is_eos = tf.math.reduce_any( - tf.equal( - tf.broadcast_to(next_tokens, (len(eos_token_id), batch_size)), tf.expand_dims(eos_token_id, -1) - ), - axis=0, - ) - finished_sequences = finished_sequences | next_token_is_eos - - # update `generated` and `cur_len` - update_indices = tf.stack([tf.range(batch_size), tf.broadcast_to(cur_len, [batch_size])], axis=-1) - generated = tf.tensor_scatter_nd_update(tensor=generated, indices=update_indices, updates=next_tokens) - cur_len += 1 - - # update model_kwargs - if use_xla: - model_kwargs = self._update_model_kwargs_for_xla_generation( - model_outputs=model_outputs, - model_kwargs=model_kwargs, - cur_len=cur_len, - max_length=max_length, - batch_size=batch_size, - is_encoder_decoder=self.config.is_encoder_decoder, - batch_axis=cache_batch_axis, - ) - else: - model_kwargs = self._update_model_kwargs_for_generation( - model_outputs, model_kwargs, is_encoder_decoder=self.config.is_encoder_decoder - ) - # if we don't cache past_key_values key values we need the whole input - if model_kwargs.get("past_key_values", None) is None: - # let's throw out `past_key_values` since we don't want `None` tensors - model_kwargs.pop("past_key_values", None) - - return generated, finished_sequences, cur_len, model_kwargs - - # 5. run generation - # 1st generation step has to be run before to initialize `past_key_values` - generated, finished_sequences, cur_len, model_kwargs = sample_body_fn( - generated, finished_sequences, cur_len, model_kwargs - ) - - # 2-to-n generation steps can then be run in autoregressive fashion - # only in case 1st generation step does NOT yield EOS token though - maximum_iterations = max_length - cur_len - generated, _, cur_len, _ = tf.while_loop( - sample_cond_fn, - sample_body_fn, - (generated, finished_sequences, cur_len, model_kwargs), - maximum_iterations=maximum_iterations, - ) - - # 6. prepare outputs - if not use_xla: - # cut for backward compatibility - generated = generated[:, :cur_len] - - if return_dict_in_generate: - if self.config.is_encoder_decoder: - # if model is an encoder-decoder, retrieve encoder attention weights - # and hidden states - encoder_attentions = model_kwargs["encoder_outputs"].get("attentions") if output_attentions else None - encoder_hidden_states = ( - model_kwargs["encoder_outputs"].get("hidden_states") if output_hidden_states else None - ) - - scores = tuple(scores) if scores is not None else None - decoder_attentions = tuple(decoder_attentions) if decoder_attentions is not None else None - cross_attentions = tuple(cross_attentions) if cross_attentions is not None else None - decoder_hidden_states = tuple(decoder_hidden_states) if decoder_hidden_states is not None else None - - return TFSampleEncoderDecoderOutput( - sequences=generated, - scores=scores, - encoder_attentions=encoder_attentions, - encoder_hidden_states=encoder_hidden_states, - decoder_attentions=decoder_attentions, - cross_attentions=cross_attentions, - decoder_hidden_states=decoder_hidden_states, - ) - else: - return TFSampleDecoderOnlyOutput( - sequences=generated, - scores=scores, - attentions=decoder_attentions, - hidden_states=decoder_hidden_states, - ) - else: - return generated - - @staticmethod - def _gather_beams(nested, beam_indices, batch_axis=0): - """Gathers the beam slices indexed by beam_indices into new beam array.""" - - def gather_fn(tensor): - if batch_axis > 0: - # pushes all dimensions before the batch to the end, so we get (batch, beam_id, ...) - perm = tf.concat((tf.range(tf.rank(tensor))[batch_axis:], tf.range(batch_axis)), axis=0) - tensor = tf.transpose(tensor, perm=perm) - - gathered_tensor = tf.gather(params=tensor, indices=beam_indices, axis=1, batch_dims=1) - if batch_axis > 0: - # transposes back to the original dimensions - perm = tf.concat((tf.range(tf.rank(tensor))[batch_axis:], tf.range(batch_axis)), axis=0) - perm = tf.math.invert_permutation(perm) - gathered_tensor = tf.transpose(gathered_tensor, perm=perm) - - return gathered_tensor - - return tf.nest.map_structure(gather_fn, nested) - - def beam_search( - self, - input_ids: tf.Tensor, - do_sample: bool = False, - max_length: Optional[int] = None, - pad_token_id: Optional[int] = None, - eos_token_id: Optional[int] = None, - length_penalty: Optional[float] = None, - early_stopping: Optional[Union[bool, str]] = None, - logits_processor: Optional[TFLogitsProcessorList] = None, - logits_warper: Optional[TFLogitsProcessorList] = None, - num_return_sequences: Optional[int] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - output_scores: Optional[bool] = None, - return_dict_in_generate: Optional[bool] = None, - **model_kwargs, - ) -> Union[TFBeamSearchOutput, TFBeamSampleOutput, tf.Tensor]: - r""" - Generates sequences for models with a language modeling head using beam search. If `do_sample` is `False`, uses - a greedy approach, otherwise does multinomial sampling without replacement. - - Parameters: - input_ids (`tf.Tensor` of shape `(batch_size, num_beams, sequence_length)`): - The sequence used as a prompt for the generation. - do_sample (`bool`, *optional*, defaults to `False`): - Whether or not to use sampling ; use greedy decoding otherwise. - max_length (`int`, *optional*, defaults to 20): - The maximum length of the sequence to be generated. - pad_token_id (`int`, *optional*): - The id of the *padding* token. - eos_token_id (`Union[int, list[int]]`, *optional*): - The id of the *end-of-sequence* token. Optionally, use a list to set multiple *end-of-sequence* tokens. - length_penalty (`float`, *optional*, defaults to 1.0): - Exponential penalty to the length that is used with beam-based generation. It is applied as an exponent - to the sequence length, which in turn is used to divide the score of the sequence. Since the score is - the log likelihood of the sequence (i.e. negative), `length_penalty` > 0.0 promotes longer sequences, - while `length_penalty` < 0.0 encourages shorter sequences. - early_stopping (`bool` or `str`, *optional*, defaults to `False`): - Controls the stopping condition for beam-based methods, like beam-search. It accepts the following - values: `True`, where the generation stops as soon as there are `num_beams` complete candidates; - `False`, where an heuristic is applied and the generation stops when is it very unlikely to find better - candidates; `"never"`, where the beam search procedure only stops when there cannot be better - candidates (canonical beam search algorithm). - logits_processor (`[TFLogitsProcessorList]`, *optional*): - An instance of [`TFLogitsProcessorList`]. List of instances of class derived from [`TFLogitsProcessor`] - used to modify the prediction scores of the language modeling head applied at each generation step. - logits_warper (`TFLogitsProcessorList`, *optional*): - An instance of [`TFLogitsProcessorList`]. List of instances of class derived from [`TFLogitsWarper`] - used to warp the prediction score distribution of the language modeling head applied before multinomial - sampling at each generation step. - num_return_sequences(`int`, *optional*, defaults to 1): - The number of independently computed returned sequences for each element in the batch. - output_attentions (`bool`, *optional*, defaults to `False`): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more details. - output_hidden_states (`bool`, *optional*, defaults to `False`): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more details. - return_dict_in_generate (`bool`, *optional*, defaults to `False`): - Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. - model_kwargs: - Additional model specific kwargs will be forwarded to the `call` function of the model. If model is an - encoder-decoder model the kwargs should include `encoder_outputs`. - - Return: - [`~generation.TFBeamSearchDecoderOnlyOutput`], [`~generation.TFBeamSearchEncoderDecoderOutput`] or - `tf.Tensor`: A `tf.Tensor` containing the generated tokens (default behaviour) or a - [`~generation.TFBeamSearchDecoderOnlyOutput`] if `model.config.is_encoder_decoder=False` and - `return_dict_in_generate=True` or a [`~generation.TFBeamSearchEncoderDecoderOutput`] if - `model.config.is_encoder_decoder=True`. - - Examples: - - ```python - >>> from transformers import ( - ... AutoTokenizer, - ... TFAutoModelForSeq2SeqLM, - ... TFLogitsProcessorList, - ... TFMinLengthLogitsProcessor, - ... ) - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-base") - >>> model = TFAutoModelForSeq2SeqLM.from_pretrained("google-t5/t5-base") - - >>> encoder_input_str = "translate English to German: How old are you?" - >>> encoder_input_ids = tokenizer(encoder_input_str, return_tensors="tf").input_ids - - >>> # lets run beam search using 3 beams - >>> num_beams = 3 - >>> # define decoder start token ids - >>> input_ids = tf.ones((1, num_beams, 1), dtype=tf.int32) - >>> input_ids = input_ids * model.generation_config.decoder_start_token_id - - >>> # add encoder_outputs to model keyword arguments - >>> encoder_outputs = model.get_encoder()(encoder_input_ids, return_dict=True) - >>> encoder_outputs.last_hidden_state = tf.repeat( - ... tf.expand_dims(encoder_outputs.last_hidden_state, axis=0), num_beams, axis=1 - ... ) - >>> model_kwargs = {"encoder_outputs": encoder_outputs} - - >>> # instantiate logits processors - >>> logits_processor = TFLogitsProcessorList( - ... [TFMinLengthLogitsProcessor(5, eos_token_id=model.generation_config.eos_token_id)] - ... ) - - >>> outputs = model.beam_search(input_ids, logits_processor=logits_processor, **model_kwargs) - >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) - ['Wie alt bist du?'] - ```""" - - def flatten_beam_dim(tensor, batch_axis=0): - """Flattens the first two dimensions of a non-scalar array.""" - shape = shape_list(tensor) - return tf.reshape( - tensor, - shape[:batch_axis] + [shape[batch_axis] * shape[batch_axis + 1]] + shape[batch_axis + 2 :], - ) - - def unflatten_beam_dim(tensor, num_beams, batch_axis=0): - """Unflattens the first, flat batch*beam dimension of a non-scalar array.""" - shape = shape_list(tensor) - return tf.reshape(tensor, shape[:batch_axis] + [-1, num_beams] + shape[batch_axis + 1 :]) - - # 1. init beam_search values - logits_processor = logits_processor if logits_processor is not None else TFLogitsProcessorList() - logits_warper = logits_warper if logits_warper is not None else TFLogitsProcessorList() - - max_length = max_length if max_length is not None else self.generation_config.max_length - pad_token_id = pad_token_id if pad_token_id is not None else self.generation_config.pad_token_id - eos_token_id = eos_token_id if eos_token_id is not None else self.generation_config.eos_token_id - if isinstance(eos_token_id, int): - eos_token_id = [eos_token_id] - num_return_sequences = ( - num_return_sequences if num_return_sequences is not None else self.generation_config.num_return_sequences - ) - - output_attentions = ( - output_attentions if output_attentions is not None else self.generation_config.output_attentions - ) - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.generation_config.output_hidden_states - ) - output_scores = output_scores if output_scores is not None else self.generation_config.output_scores - return_dict_in_generate = ( - return_dict_in_generate - if return_dict_in_generate is not None - else self.generation_config.return_dict_in_generate - ) - - length_penalty = length_penalty if length_penalty is not None else self.generation_config.length_penalty - early_stopping = early_stopping if early_stopping is not None else self.generation_config.early_stopping - - use_cache = model_kwargs.pop("use_cache", self.generation_config.use_cache) - use_xla = not tf.executing_eagerly() - # TODO (Joao): fix cache format or find programmatic way to detect cache index - # GPT2 and other models has a slightly different cache structure, with a different batch axis - model_name = str(self.decoder) if "EncoderDecoder" in str(self) else str(self) - cache_batch_axis = 1 if any(model_prefix in model_name for model_prefix in ("TFGPT2", "TFCTRL")) else 0 - # some models, like XLNet, need more than the last token in the presence of past_key_values - needs_full_input = "use_mems" in set(inspect.signature(self.prepare_inputs_for_generation).parameters.keys()) - - # 2. init `attentions`, `hidden_states`, and `scores` tuples - all_scores = [] if (return_dict_in_generate and output_scores) else None - decoder_attentions = [] if (return_dict_in_generate and output_attentions) else None - cross_attentions = [] if (return_dict_in_generate and output_attentions) else None - decoder_hidden_states = [] if (return_dict_in_generate and output_hidden_states) else None - - # 3. init tensors to use for "xla-compileable" generate function - batch_size, num_beams, cur_len = shape_list(input_ids) - # store the prompt length of decoder - decoder_prompt_len = cur_len - - # per batch, beam-item holding current token in loop, pre-populated with `pad_token_id` - input_ids_padding = tf.ones((batch_size, num_beams, max_length - cur_len), dtype=tf.int32) * ( - pad_token_id or 0 - ) - running_sequences = tf.concat([input_ids, input_ids_padding], axis=-1) - sequences = tf.ones((batch_size, num_beams, max_length), dtype=tf.int32) * (pad_token_id or 0) - - # per batch,beam-item state bit indicating if sentence has finished. - is_sent_finished = tf.zeros((batch_size, num_beams), dtype=tf.bool) - - # per batch, beam-item score, logprobs - running_scores = tf.tile( - tf.expand_dims(tf.convert_to_tensor([0.0] + [-1.0e9] * (num_beams - 1)), axis=0), [batch_size, 1] - ) - scores = tf.ones((batch_size, num_beams)) * -1.0e9 - - # per batch beam indices - running_beam_indices = tf.ones((batch_size, num_beams, max_length - decoder_prompt_len), dtype=tf.int32) * -1 - beam_indices = tf.ones((batch_size, num_beams, max_length - decoder_prompt_len), dtype=tf.int32) * -1 - - # flatten beam dim - if "encoder_outputs" in model_kwargs: - model_kwargs["encoder_outputs"]["last_hidden_state"] = flatten_beam_dim( - model_kwargs["encoder_outputs"]["last_hidden_state"] - ) - if "attention_mask" in model_kwargs: - model_kwargs["attention_mask"] = flatten_beam_dim(model_kwargs["attention_mask"]) - - # 4. define "xla-compile-able" stop-condition and auto-regressive function - # define stop-condition and auto-regressive function - def beam_search_cond_fn( - cur_len, - running_sequences, - running_scores, - running_beam_indices, - sequences, - scores, - beam_indices, - is_sent_finished, - decoder_prompt_len, - model_kwargs, - ): - """ - Beam Search termination condition function -- halts the generation loop if any of these conditions becomes - False - """ - # 1. is less than max length? - not_max_length_yet = cur_len < max_length - - # 2. can the new beams still improve? - # early_stopping == False -> apply heuristic = always get the best score from `cur_len - decoder_prompt_len`. See the discussion - # below for more details. - # https://github.com/huggingface/transformers/pull/20901#issuecomment-1369845565 - # early_stopping == "never" -> compute the best score from max_length or cur_len, depending on the sign of - # length_penalty. Positive length_penalty favors longer sequences, thus we use max_length there. - if early_stopping == "never" and length_penalty > 0.0: - best_running_score = running_scores[:, :1] / ((max_length - decoder_prompt_len) ** length_penalty) - else: - best_running_score = running_scores[:, :1] / ( - tf.cast(cur_len - decoder_prompt_len, dtype=tf.float32) ** length_penalty - ) - worst_finished_score = tf.where( - is_sent_finished, tf.math.reduce_min(scores, axis=1, keepdims=True), -1.0e9 - ) - improvement_still_possible = tf.math.reduce_any(best_running_score > worst_finished_score) - - # 3. is there still a beam that has not finished? - still_open_beam = ~(tf.math.reduce_all(is_sent_finished) & (early_stopping is True)) - - return not_max_length_yet & still_open_beam & improvement_still_possible - - def beam_search_body_fn( - cur_len, - running_sequences, - running_scores, - running_beam_indices, - sequences, - scores, - beam_indices, - is_sent_finished, - decoder_prompt_len, - model_kwargs, - ): - """ - Beam Search iterative update function -- each iteration adds a new token and updates the best sequences - seen so far - """ - # 1. Forward current tokens - if model_kwargs.get("past_key_values") is None or needs_full_input: - input_ids = running_sequences[:, :, :cur_len] - else: - input_ids = tf.expand_dims(running_sequences[:, :, cur_len - 1], -1) - model_inputs = self.prepare_inputs_for_generation( - flatten_beam_dim(input_ids), use_cache=use_cache, **model_kwargs - ) - model_outputs = self( - **model_inputs, - return_dict=True, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - ) - logits = unflatten_beam_dim(model_outputs.logits[:, -1], num_beams) - - # 2. Compute log probs - # get log probabilities from logits, process logits with processors (*e.g.* min_length, ...), and - # add new logprobs to existing running logprobs scores. - log_probs = tf.nn.log_softmax(logits) - log_probs = logits_processor(flatten_beam_dim(running_sequences), flatten_beam_dim(log_probs), cur_len) - log_probs = unflatten_beam_dim(log_probs, num_beams) - if do_sample: - log_probs = logits_warper(flatten_beam_dim(running_sequences), flatten_beam_dim(log_probs), cur_len) - log_probs = unflatten_beam_dim(log_probs, num_beams) - log_probs_processed = log_probs - log_probs = log_probs + tf.expand_dims(running_scores, axis=2) - vocab_size = log_probs.shape[2] - log_probs = tf.reshape(log_probs, (batch_size, num_beams * vocab_size)) - - # Store scores, attentions and hidden_states when required - if not use_xla and return_dict_in_generate: - if output_scores: - all_scores.append( - logits_warper( - flatten_beam_dim(running_sequences), - flatten_beam_dim(log_probs_processed), - cur_len, - ) - ) - if output_attentions and self.config.is_encoder_decoder: - decoder_attentions.append(model_outputs.decoder_attentions) - elif output_attentions and not self.config.is_encoder_decoder: - decoder_attentions.append(model_outputs.attentions) - if self.config.is_encoder_decoder: - cross_attentions.append(model_outputs.cross_attentions) - - if output_hidden_states and self.config.is_encoder_decoder: - decoder_hidden_states.append(model_outputs.decoder_hidden_states) - elif output_hidden_states and self.config.is_encoder_decoder: - decoder_hidden_states.append(model_outputs.hidden_states) - - # 3. Retrieve top-K - # Each item in batch has num_beams * vocab_size candidate sequences. For each item, get the top 2*k - # candidates with the highest log-probabilities. We gather the top 2*K beams here so that even if the - # best K sequences reach EOS simultaneously, we have another K sequences remaining to continue the live - # beam search. - # Gather the top 2*K scores from _all_ beams. - # Gather 2*k top beams. - # Recover the beam index by floor division. - # Recover token id by modulo division and expand Id array for broadcasting. - # Update sequences for the 2*K top-k new sequences. - beams_to_keep = 2 * num_beams - if do_sample: - topk_indices = sample_without_replacement(log_probs, beams_to_keep) - topk_log_probs = tf.gather(log_probs, topk_indices, axis=1, batch_dims=1) - else: - topk_log_probs, topk_indices = tf.math.top_k(log_probs, k=beams_to_keep) - topk_current_beam_indices = topk_indices // vocab_size - topk_running_beam_indices = self._gather_beams(running_beam_indices, topk_current_beam_indices) - topk_running_sequences = self._gather_beams(running_sequences, topk_current_beam_indices) - topk_ids = topk_indices % vocab_size - - # writes the new token - indices_batch = tf.repeat(tf.range(batch_size), [beams_to_keep]) - indices_beam = tf.tile(tf.range(beams_to_keep), [batch_size]) - update_indices = tf.stack( - [indices_batch, indices_beam, tf.broadcast_to(cur_len, [batch_size * beams_to_keep])], axis=-1 - ) - topk_sequences = tf.tensor_scatter_nd_update( - tensor=topk_running_sequences, - indices=update_indices, - updates=tf.reshape(topk_ids, [batch_size * beams_to_keep]), - ) - - # we want to store the beam indices with batch information -> real beam index = beam index % num beams - batch_modified_indices = topk_current_beam_indices + tf.broadcast_to( - tf.expand_dims(tf.range(batch_size) * num_beams, axis=1), topk_current_beam_indices.shape - ) - update_indices = tf.stack( - [ - indices_batch, - indices_beam, - tf.broadcast_to(cur_len - decoder_prompt_len, [batch_size * beams_to_keep]), - ], - axis=-1, - ) - topk_beam_indices = tf.tensor_scatter_nd_update( - tensor=topk_running_beam_indices, - indices=update_indices, - updates=tf.reshape(batch_modified_indices, [batch_size * beams_to_keep]), - ) - - # 4. Check which sequences have ended - # Update current sequences: Did the top `num_beams` sequences reach an end marker? - # To prevent these just finished sequences from being added to the current sequences - # set of active beam search sequences, set their log probs to a very large negative value. - if eos_token_id is None: - eos_in_next_token = tf.zeros(topk_sequences[:, :, cur_len].shape, dtype=tf.bool) - else: - eos_in_next_token = tf.math.reduce_any( - tf.equal( - tf.broadcast_to( - topk_sequences[:, :, cur_len], - [len(eos_token_id)] + topk_sequences[:, :, cur_len].shape, - ), - tf.expand_dims(tf.expand_dims(eos_token_id, -1), -1), - ), - axis=0, - ) - did_topk_just_finished = eos_in_next_token & tf.broadcast_to( - tf.concat((tf.ones((num_beams), dtype=tf.bool), tf.zeros((num_beams), dtype=tf.bool)), axis=0), - shape_list(eos_in_next_token), - ) - - # non-top `num_beams` eos tokens can't be used to finish a beam, but the others can't be used in the next - # running sentences either - running_topk_log_probs = topk_log_probs + tf.cast(eos_in_next_token, tf.float32) * -1.0e9 - - # 5. Get running sequences scores for next - # Determine the top k beam indices (from top 2*k beams) from log probs and gather top k beams - # (from top 2*k beams). - next_topk_indices = tf.math.top_k(running_topk_log_probs, k=num_beams)[1] - next_running_sequences, next_running_scores, next_running_beam_indices = self._gather_beams( - [topk_sequences, running_topk_log_probs, topk_beam_indices], next_topk_indices - ) - - # 6. Process topk logits - # Further process log probs: - # - add length penalty - # - make sure no scores can be added anymore if beam is full - # - make sure still running sequences cannot be chosen as finalized beam - topk_log_probs = topk_log_probs / ( - tf.cast(cur_len + 1 - decoder_prompt_len, dtype=tf.float32) ** length_penalty - ) - beams_in_batch_are_full = tf.broadcast_to( - tf.math.reduce_all(is_sent_finished, axis=-1, keepdims=True), shape_list(did_topk_just_finished) - ) & (early_stopping is True) - add_penalty = ~did_topk_just_finished | beams_in_batch_are_full - topk_log_probs += tf.cast(add_penalty, tf.float32) * -1.0e9 - - # 7. Get scores, sequences, is sentence finished for next. - # Combine sequences, scores, and flags along the beam dimension and compare new finished sequence scores - # to existing finished scores and select the best from the new set of beams - merged_sequences = tf.concat([sequences, topk_sequences], axis=1) - merged_scores = tf.concat([scores, topk_log_probs], axis=1) - merged_beams = tf.concat([beam_indices, topk_beam_indices], axis=1) - merged_is_sent_finished = tf.concat([is_sent_finished, did_topk_just_finished], axis=1) - topk_merged_indices = tf.math.top_k(merged_scores, k=num_beams)[1] - next_sequences, next_scores, next_beam_indices, next_is_sent_finished = self._gather_beams( - [merged_sequences, merged_scores, merged_beams, merged_is_sent_finished], topk_merged_indices - ) - - # 8. Prepare data for the next iteration - # Determine the top k beam indices from the original set of all beams. With these, gather the top k - # beam-associated caches. - cur_len = cur_len + 1 - if "past_key_values" in model_outputs: - cache = tf.nest.map_structure( - lambda tensor: unflatten_beam_dim(tensor, num_beams, batch_axis=cache_batch_axis), - model_outputs.past_key_values, - ) - next_running_indices = self._gather_beams(topk_current_beam_indices, next_topk_indices) - next_cache = self._gather_beams(cache, next_running_indices, batch_axis=cache_batch_axis) - model_outputs["past_key_values"] = tf.nest.map_structure( - lambda tensor: flatten_beam_dim(tensor, batch_axis=cache_batch_axis), next_cache - ) - - if use_xla: - next_model_kwargs = self._update_model_kwargs_for_xla_generation( - model_outputs=model_outputs, - model_kwargs=model_kwargs, - cur_len=cur_len, - max_length=max_length, - batch_size=(batch_size * num_beams), - is_encoder_decoder=self.config.is_encoder_decoder, - batch_axis=cache_batch_axis, - ) - else: - next_model_kwargs = self._update_model_kwargs_for_generation( - model_outputs, model_kwargs, is_encoder_decoder=self.config.is_encoder_decoder - ) - - # if we don't cache past_key_values key values we need the whole input - if model_kwargs.get("past_key_values", None) is None: - # let's throw out `past_key_values` since we don't want `None` tensors - model_kwargs.pop("past_key_values", None) - - return ( - cur_len, - next_running_sequences, - next_running_scores, - next_running_beam_indices, - next_sequences, - next_scores, - next_beam_indices, - next_is_sent_finished, - decoder_prompt_len, - next_model_kwargs, - ) - - # 5. run generation - # 1st generation step has to be run before to initialize `past_key_values` (if active) - ( - cur_len, - running_sequences, - running_scores, - running_beam_indices, - sequences, - scores, - beam_indices, - is_sent_finished, - decoder_prompt_len, - model_kwargs, - ) = beam_search_body_fn( - cur_len, - running_sequences, - running_scores, - running_beam_indices, - sequences, - scores, - beam_indices, - is_sent_finished, - decoder_prompt_len, - model_kwargs, - ) - - # 2-to-n generation steps can then be run in autoregressive fashion (only in case 1st generation step does - # NOT yield EOS token though) - maximum_iterations = max_length - cur_len - ( - cur_len, - running_sequences, - running_scores, - running_beam_indices, - sequences, - scores, - beam_indices, - is_sent_finished, - decoder_prompt_len, - _, - ) = tf.while_loop( - beam_search_cond_fn, - beam_search_body_fn, - ( - cur_len, - running_sequences, - running_scores, - running_beam_indices, - sequences, - scores, - beam_indices, - is_sent_finished, - decoder_prompt_len, - model_kwargs, - ), - maximum_iterations=maximum_iterations, - ) - - # 6. prepare outputs - # Account for the edge-case where there are no finished sequences for a particular batch item. If so, return - # running sequences for that batch item. - none_finished = tf.math.reduce_any(is_sent_finished, axis=1) - sequences = tf.where(none_finished[:, None, None], sequences, running_sequences) - beam_indices = tf.where(none_finished[:, None, None], beam_indices, running_beam_indices) - - # Apply the length penalty so that running scores match the finalized scores if they are used - running_scores = running_scores / (tf.cast(cur_len - decoder_prompt_len, dtype=tf.float32) ** length_penalty) - scores = tf.where(none_finished[:, None], scores, running_scores) - - # Take best beams for each batch (the score is sorted in descending order) - sequences = flatten_beam_dim(sequences[:, :num_return_sequences, :]) - scores = flatten_beam_dim(scores[:, :num_return_sequences]) - beam_indices = flatten_beam_dim(beam_indices[:, :num_return_sequences, :]) - - if not use_xla: - # Cut for backward compatibility - sequences = sequences[:, :cur_len] - beam_indices = beam_indices[:, : cur_len - decoder_prompt_len] - - if return_dict_in_generate: - if self.config.is_encoder_decoder: - # if model is an encoder-decoder, retrieve encoder attention weights and hidden states - encoder_attentions = model_kwargs["encoder_outputs"].get("attentions") if output_attentions else None - encoder_hidden_states = ( - model_kwargs["encoder_outputs"].get("hidden_states") if output_hidden_states else None - ) - - output_cls = TFBeamSampleEncoderDecoderOutput if do_sample else TFBeamSearchEncoderDecoderOutput - return output_cls( - sequences=sequences, - sequences_scores=scores, - scores=all_scores, - beam_indices=beam_indices, - encoder_attentions=encoder_attentions, - encoder_hidden_states=encoder_hidden_states, - decoder_attentions=decoder_attentions, - cross_attentions=cross_attentions, - decoder_hidden_states=decoder_hidden_states, - ) - else: - output_cls = TFBeamSampleDecoderOnlyOutput if do_sample else TFBeamSearchDecoderOnlyOutput - return output_cls( - sequences=sequences, - sequences_scores=scores, - scores=all_scores, - beam_indices=beam_indices, - attentions=decoder_attentions, - hidden_states=decoder_hidden_states, - ) - else: - return sequences - - def contrastive_search( - self, - input_ids: tf.Tensor, - top_k: Optional[int] = 1, - penalty_alpha: Optional[float] = 0, - logits_processor: Optional[TFLogitsProcessorList] = None, - logits_warper: Optional[TFLogitsProcessorList] = None, - max_length: Optional[int] = None, - pad_token_id: Optional[int] = None, - eos_token_id: Optional[int] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - output_scores: Optional[bool] = None, - return_dict_in_generate: Optional[bool] = None, - **model_kwargs, - ) -> Union[TFContrastiveSearchOutput, tf.Tensor]: - r""" - Generates sequences of token ids for models with a language modeling head using **contrastive search** and can - be used for text-decoder, text-to-text, speech-to-text, and vision-to-text models. - - Parameters: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - The sequence used as a prompt for the generation. - top_k (`int`, *optional*, defaults to 1): - The size of the candidate set that is used to re-rank for contrastive search - penalty_alpha (`float`, *optional*, defaults to 0): - The degeneration penalty for contrastive search; activate when it is larger than 0 - logits_processor (`TFLogitsProcessorList`, *optional*): - An instance of [`TFLogitsProcessorList`]. List of instances of class derived from [`TFLogitsProcessor`] - used to modify the prediction scores of the language modeling head applied at each generation step. - logits_warper (`TFLogitsProcessorList`, *optional*): - An instance of [`TFLogitsProcessorList`]. List of instances of class derived from [`TFLogitsWarper`] - used to warp the prediction score distribution of the language modeling head applied before multinomial - sampling at each generation step. - max_length (`int`, *optional*, defaults to 20): - The maximum length of the sequence to be generated. - pad_token_id (`int`, *optional*): - The id of the *padding* token. - eos_token_id (`Union[int, list[int]]`, *optional*): - The id of the *end-of-sequence* token. Optionally, use a list to set multiple *end-of-sequence* tokens. - output_attentions (`bool`, *optional*, defaults to `False`): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more details. - output_hidden_states (`bool`, *optional*, defaults to `False`): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more details. - output_scores (`bool`, *optional*, defaults to `False`): - Whether or not to return the prediction scores. See `scores` under returned tensors for more details. - return_dict_in_generate (`bool`, *optional*, defaults to `False`): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - model_kwargs: - Additional model specific keyword arguments will be forwarded to the `call` function of the model. If - model is an encoder-decoder model the kwargs should include `encoder_outputs`. - Return: - [`~generation.TFContrastiveSearchDecoderOnlyOutput`], - [`~generation.TFContrastiveSearchEncoderDecoderOutput`] or `tf.Tensor`: A `tf.Tensor` containing the - generated tokens (default behaviour) or a [`~generation.TFContrastiveySearchDecoderOnlyOutput`] if - `model.config.is_encoder_decoder=False` and `return_dict_in_generate=True` or a - [`~generation.TFContrastiveSearchEncoderDecoderOutput`] if `model.config.is_encoder_decoder=True`. - Examples: - ```python - >>> from transformers import AutoTokenizer, TFAutoModelForCausalLM - - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/opt-125m") - >>> model = TFAutoModelForCausalLM.from_pretrained("facebook/opt-125m") - >>> # set pad_token_id to eos_token_id because OPT does not have a PAD token - >>> model.config.pad_token_id = model.config.eos_token_id - >>> input_prompt = "DeepMind Company is" - >>> input_ids = tokenizer(input_prompt, return_tensors="tf") - >>> outputs = model.contrastive_search(**input_ids, penalty_alpha=0.6, top_k=4, max_length=64) - >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) - ['DeepMind Company is a company that focuses on the development and commercialization of artificial intelligence (AI). DeepMind’s mission is to help people understand and solve problems that are difficult to solve in the world today.\n\nIn this post, we talk about the benefits of deep learning in business and how it'] - ```""" - - def gather_best_candidate(nested, selected_idx_stacked, batch_axis=0): - """Gathers the slices indexed by selected_idx_stacked from a potentially nested structure of tensors.""" - - def gather_fn(tensor): - gathered_tensor = tf.gather(params=tensor, indices=selected_idx_stacked, axis=batch_axis) - return gathered_tensor - - return tf.nest.map_structure(gather_fn, nested) - - # 1. init greedy_search values - logits_processor = logits_processor if logits_processor is not None else TFLogitsProcessorList() - logits_warper = logits_warper if logits_warper is not None else TFLogitsProcessorList() - max_length = max_length if max_length is not None else self.generation_config.max_length - pad_token_id = pad_token_id if pad_token_id is not None else self.generation_config.pad_token_id - eos_token_id = eos_token_id if eos_token_id is not None else self.generation_config.eos_token_id - if isinstance(eos_token_id, int): - eos_token_id = [eos_token_id] - output_scores = output_scores if output_scores is not None else self.generation_config.output_scores - output_attentions = ( - output_attentions if output_attentions is not None else self.generation_config.output_attentions - ) - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.generation_config.output_hidden_states - ) - return_dict_in_generate = ( - return_dict_in_generate - if return_dict_in_generate is not None - else self.generation_config.return_dict_in_generate - ) - use_cache = True # In contrastive search, we always use cache - model_kwargs.pop("use_cache", None) - - use_xla = not tf.executing_eagerly() - # TODO (Joao): fix cache format or find programmatic way to detect cache index - # GPT2 and other models has a slightly different cache structure, with a different batch axis - model_name = str(self.decoder) if "EncoderDecoder" in str(self) else str(self) - cache_batch_axis = 1 if any(model_prefix in model_name for model_prefix in ("TFGPT2", "TFCTRL")) else 0 - - # 2. init `attentions`, `hidden_states`, and `scores` tuples - scores = [] if (return_dict_in_generate and output_scores) else None - decoder_attentions = [] if (return_dict_in_generate and output_attentions) else None - cross_attentions = [] if (return_dict_in_generate and output_attentions) else None - decoder_hidden_states = [] if (return_dict_in_generate and output_hidden_states) else None - - # 3. init tensors to use for "xla-compileable" generate function - batch_size, cur_len = shape_list(input_ids) - - # initialize `generated` (`input_ids` padded with `pad_token_id`), `finished_sequences` - input_ids_padding = tf.ones((batch_size, max_length - cur_len), dtype=tf.int32) * (pad_token_id or 0) - generated = tf.concat([input_ids, input_ids_padding], axis=-1) - finished_sequences = tf.zeros((batch_size,), dtype=tf.bool) - - # 4. define "xla-compile-able" stop-condition and auto-regressive function - # define condition fn - def contrastive_search_cond_fn( - generated, finished_sequences, cur_len, model_kwargs, next_step_cached_variables - ): - """state termination condition fn.""" - return ~tf.reduce_all(finished_sequences) - - # define condition fn - def contrastive_search_body_fn( - generated, finished_sequences, cur_len, model_kwargs, next_step_cached_variables - ): - """state update fn.""" - - # if the first step in the loop, encode all the prefix and obtain: (1) past_key_values; - # (2) last_hidden_states; (3) logit_for_next_step; (4) update model kwargs for the next step - if model_kwargs.get("past_key_values") is None: - # prepare inputs - model_inputs = self.prepare_inputs_for_generation( - generated[:, :cur_len], use_cache=use_cache, **model_kwargs - ) - - # encode the given prefix and prepare model inputs; encoder-decoder model process the prefix and save - # the `encoder_outputs` - outputs = self( - **model_inputs, return_dict=True, output_hidden_states=True, output_attentions=output_attentions - ) - - # last decoder hidden states will be used to compute the degeneration penalty (cosine similarity with - # previous tokens) - if self.config.is_encoder_decoder: - last_hidden_states = outputs.decoder_hidden_states[-1] - else: - last_hidden_states = outputs.hidden_states[-1] - - # XLA: last_hidden_states normally grows at each step, but in XLA it is padded so as to be used across - # iterations (with fixed shapes) - if use_xla: - last_hidden_states = tf.pad(last_hidden_states, [[0, 0], [0, max_length - cur_len], [0, 0]]) - - # next logit for contrastive search to select top-k candidate tokens - logit_for_next_step = outputs.logits[:, -1, :] - - if use_xla: - model_kwargs = self._update_model_kwargs_for_xla_generation( - model_outputs=outputs, - model_kwargs=model_kwargs, - cur_len=cur_len, - max_length=max_length, - batch_size=batch_size, - is_encoder_decoder=self.config.is_encoder_decoder, - batch_axis=cache_batch_axis, - ) - else: - model_kwargs = self._update_model_kwargs_for_generation( - outputs, model_kwargs, is_encoder_decoder=self.config.is_encoder_decoder - ) - - # Expands model inputs top_k times, for batched forward passes (akin to beam search). - _, model_kwargs = self._expand_inputs_for_generation( - expand_size=top_k, is_encoder_decoder=self.config.is_encoder_decoder, **model_kwargs - ) - - past_key_values = model_kwargs.get("past_key_values") - if past_key_values is None: - raise ValueError( - f"{self.__class__.__name__} does not support caching and therefore **can't** be used " - "for contrastive search." - ) - elif ( - not isinstance(past_key_values[0], (tuple, tf.Tensor)) - or past_key_values[0][0].shape[0] != batch_size - ): - raise ValueError( - f"{self.__class__.__name__} does not have a standard cache format and therefore **can't** be " - "used for contrastive search without further modifications." - ) - else: - logit_for_next_step = next_step_cached_variables["logit_for_next_step"] - last_hidden_states = next_step_cached_variables["last_hidden_states"] - outputs = next_step_cached_variables["outputs"] - - # contrastive_search main logic start: - # contrastive search decoding consists of two steps: (1) candidate tokens recall; (2) candidate re-rank by - # degeneration penalty - - logit_for_next_step = logits_processor(generated, logit_for_next_step, cur_len) - logit_for_next_step = logits_warper(generated, logit_for_next_step, cur_len) - next_probs = stable_softmax(logit_for_next_step, axis=-1) - top_k_probs, top_k_ids = tf.math.top_k(next_probs, k=top_k) - - # Store scores, attentions and hidden_states when required - if not use_xla and return_dict_in_generate: - if output_scores: - scores.append(logit_for_next_step) - if output_attentions and self.config.is_encoder_decoder: - decoder_attentions.append(outputs.decoder_attentions) - elif output_attentions and not self.config.is_encoder_decoder: - decoder_attentions.append(outputs.attentions) - if self.config.is_encoder_decoder: - cross_attentions.append(outputs.cross_attentions) - - if output_hidden_states and self.config.is_encoder_decoder: - decoder_hidden_states.append(outputs.decoder_hidden_states) - elif output_hidden_states and self.config.is_encoder_decoder: - decoder_hidden_states.append(outputs.hidden_states) - - # Replicates the new past_key_values to match the `top_k` candidates - model_kwargs["past_key_values"] = tf.nest.map_structure( - lambda tensor: tf.repeat(tensor, top_k, axis=cache_batch_axis), model_kwargs["past_key_values"] - ) - - # compute the candidate tokens by the language model and collects their hidden_states - next_model_inputs = self.prepare_inputs_for_generation( - tf.reshape(top_k_ids, [-1, 1]), use_cache=use_cache, **model_kwargs - ) - outputs = self( - **next_model_inputs, return_dict=True, output_hidden_states=True, output_attentions=output_attentions - ) - next_past_key_values = self._extract_past_from_model_output(outputs) - - logits = outputs.logits[:, -1, :] - # name is different for encoder-decoder and decoder-only models - if self.config.is_encoder_decoder: - next_hidden = outputs.decoder_hidden_states[-1] - full_hidden_states = outputs.decoder_hidden_states - else: - next_hidden = outputs.hidden_states[-1] - full_hidden_states = outputs.hidden_states - context_hidden = tf.repeat(last_hidden_states[:, :cur_len, :], top_k, axis=0) - - # compute the degeneration penalty and re-rank the candidates based on the degeneration penalty and the - # model confidence - selected_idx = _ranking_fast(context_hidden, next_hidden, top_k_probs, penalty_alpha, top_k) - - # converts indices to a dimension of top_k to the stacked top_k * batch_size dimension, for indexing - # without a need to reshape on tensors that have these two dimensions stacked - selected_idx_stacked = selected_idx + tf.range(selected_idx.shape[0], dtype=tf.int64) * top_k - - # prepare for the next step: (1) next token_id; (2) past_key_values; (3) last_hidden_states for computing - # the degeneration penalty; (4) logits for selecting next top-k candidates; (5) selected tokens scores - # (model confidence minus degeneration penalty); (6) decoder hidden_states - next_tokens = tf.gather(top_k_ids, selected_idx, axis=1, batch_dims=1) - next_hidden = gather_best_candidate(next_hidden, selected_idx_stacked) - - # XLA: last_hidden_states normally grows at each step, but in XLA it is padded so as to be used across - # iterations (with fixed shapes) - if use_xla: - last_hidden_states = dynamic_update_slice(last_hidden_states, next_hidden, [0, cur_len, 0]) - else: - last_hidden_states = tf.concat([last_hidden_states, next_hidden], axis=1) - - next_decoder_hidden_states = gather_best_candidate(full_hidden_states, selected_idx_stacked) - next_past_key_values = gather_best_candidate( - next_past_key_values, selected_idx_stacked, batch_axis=cache_batch_axis - ) - logit_for_next_step = gather_best_candidate(logits, selected_idx_stacked) - - # Rebuilds the relevant parts of the model output for the selected token, for use in the next iteration - if self.config.is_encoder_decoder: - next_step_cross_attentions = () - next_step_decoder_attentions = () - if output_attentions: - next_step_cross_attentions = gather_best_candidate(outputs.cross_attentions, selected_idx_stacked) - next_step_decoder_attentions = gather_best_candidate( - outputs.decoder_attentions, selected_idx_stacked - ) - outputs = TFSeq2SeqLMOutput( - past_key_values=next_past_key_values, - decoder_hidden_states=next_decoder_hidden_states, - decoder_attentions=next_step_decoder_attentions or None, - cross_attentions=next_step_cross_attentions or None, - ) - else: - next_step_attentions = () - if output_attentions: - next_step_attentions = gather_best_candidate(outputs.attentions, selected_idx_stacked) - outputs = TFCausalLMOutputWithPast( - past_key_values=next_past_key_values, - hidden_states=next_decoder_hidden_states, - attentions=next_step_attentions or None, - ) - # contrastive_search main logic end - - if eos_token_id is not None: - if pad_token_id is None: - raise ValueError("If `eos_token_id` is defined, make sure that `pad_token_id` is defined.") - unfinished_seq = 1 - tf.cast(finished_sequences, tf.int32) - next_tokens = next_tokens * unfinished_seq + pad_token_id * (1 - unfinished_seq) - next_token_is_eos = tf.math.reduce_any( - tf.equal( - tf.broadcast_to(next_tokens, (len(eos_token_id), batch_size)), tf.expand_dims(eos_token_id, -1) - ), - axis=0, - ) - finished_sequences = finished_sequences | next_token_is_eos - - # update `generated` and `cur_len` - update_indices = tf.stack([tf.range(batch_size), tf.broadcast_to(cur_len, [batch_size])], axis=-1) - generated = tf.tensor_scatter_nd_update(tensor=generated, indices=update_indices, updates=next_tokens) - cur_len += 1 - - if use_xla: - # NOTE: 1) relative to other generation strategies, contrastive search is always running forward - # passes one step ahead -- hence the `cur_len=cur_len + 1`; 2) the attention mask here is expanded from - # [batch_size, ...] to [batch_size*top_k, ...] -- hence the `batch_size=batch_size * top_k` - model_kwargs = self._update_model_kwargs_for_xla_generation( - model_outputs=outputs, - model_kwargs=model_kwargs, - cur_len=cur_len + 1, - max_length=max_length, - batch_size=batch_size * top_k, - is_encoder_decoder=self.config.is_encoder_decoder, - batch_axis=cache_batch_axis, - ) - else: - model_kwargs = self._update_model_kwargs_for_generation( - outputs, model_kwargs, is_encoder_decoder=self.config.is_encoder_decoder - ) - - next_step_cached_variables = { - "logit_for_next_step": logit_for_next_step, - "last_hidden_states": last_hidden_states, - "outputs": outputs, - } - return generated, finished_sequences, cur_len, model_kwargs, next_step_cached_variables - - # 5. run generation - # 1st generation step has to be run before to initialize `past_key_values` - generated, finished_sequences, cur_len, model_kwargs, next_step_cached_variables = contrastive_search_body_fn( - generated, finished_sequences, cur_len, model_kwargs, None - ) - - # 2-to-n generation steps can then be run in autoregressive fashion - # only in case 1st generation step does NOT yield EOS token though - maximum_iterations = max_length - cur_len - generated, _, cur_len, _, _ = tf.while_loop( - contrastive_search_cond_fn, - contrastive_search_body_fn, - (generated, finished_sequences, cur_len, model_kwargs, next_step_cached_variables), - maximum_iterations=maximum_iterations, - ) - - # 6. prepare outputs - if not use_xla: - # cut for backward compatibility - generated = generated[:, :cur_len] - - if return_dict_in_generate: - if self.config.is_encoder_decoder: - # if model is an encoder-decoder, retrieve encoder attention weights - # and hidden states - encoder_attentions = model_kwargs["encoder_outputs"].get("attentions") if output_attentions else None - encoder_hidden_states = ( - model_kwargs["encoder_outputs"].get("hidden_states") if output_hidden_states else None - ) - - scores = tuple(scores) if scores is not None else None - decoder_attentions = tuple(decoder_attentions) if decoder_attentions is not None else None - cross_attentions = tuple(cross_attentions) if cross_attentions is not None else None - decoder_hidden_states = tuple(decoder_hidden_states) if decoder_hidden_states is not None else None - - return TFContrastiveSearchEncoderDecoderOutput( - sequences=generated, - scores=scores, - encoder_attentions=encoder_attentions, - encoder_hidden_states=encoder_hidden_states, - decoder_attentions=decoder_attentions, - cross_attentions=cross_attentions, - decoder_hidden_states=decoder_hidden_states, - ) - else: - return TFContrastiveSearchDecoderOnlyOutput( - sequences=generated, - scores=scores, - attentions=decoder_attentions, - hidden_states=decoder_hidden_states, - ) - else: - return generated - - -def scatter_values_on_batch_indices(values, batch_indices): - shape = shape_list(batch_indices) - # broadcast batch dim to shape - broad_casted_batch_dims = tf.reshape(tf.broadcast_to(tf.expand_dims(tf.range(shape[0]), axis=-1), shape), [1, -1]) - # transform batch_indices to pair_indices - pair_indices = tf.transpose(tf.concat([broad_casted_batch_dims, tf.reshape(batch_indices, [1, -1])], 0)) - # scatter values to pair indices - return tf.scatter_nd(pair_indices, tf.reshape(values, [-1]), shape) - - -def sample_without_replacement(logits, num_samples): - """ - categorical sampling without replacement is currently not implemented the gumbel-max trick will do for now see - https://github.com/tensorflow/tensorflow/issues/9260 for more info - """ - z = -tf.math.log(-tf.math.log(tf.random.uniform(shape_list(logits), 0, 1))) - _, indices = tf.nn.top_k(logits + z, num_samples) - return indices - - -def _ranking_fast( - context_hidden: tf.Tensor, - next_hidden: tf.Tensor, - next_top_k_probs: tf.Tensor, - alpha: float, - beam_width: int, -) -> tf.Tensor: - """ - Reranks the top_k candidates based on a degeneration penalty (cosine similarity with previous tokens), as described - in the paper "A Contrastive Framework for Neural Text Generation". Returns the index of the best candidate for each - row in the batch. - """ - norm_context_hidden = context_hidden / tf.norm(context_hidden, axis=2, keepdims=True) - norm_next_hidden = next_hidden / tf.norm(next_hidden, axis=2, keepdims=True) - cosine_matrix = tf.squeeze(tf.linalg.matmul(norm_context_hidden, norm_next_hidden, transpose_b=True), axis=-1) - degeneration_penalty = tf.reduce_max(cosine_matrix, axis=-1) - next_top_k_probs = tf.reshape(next_top_k_probs, shape=[-1]) - contrastive_score = (1.0 - alpha) * next_top_k_probs - alpha * degeneration_penalty - contrastive_score = tf.reshape(contrastive_score, shape=[-1, beam_width]) - selected_idx = tf.argmax(contrastive_score, axis=1) - return selected_idx diff --git a/src/transformers/image_processing_base.py b/src/transformers/image_processing_base.py index dfe94ffd0df7..8bd65e9bc3ce 100644 --- a/src/transformers/image_processing_base.py +++ b/src/transformers/image_processing_base.py @@ -55,7 +55,7 @@ class BatchFeature(BaseBatchFeature): data (`dict`): Dictionary of lists/arrays/tensors returned by the __call__ method ('pixel_values', etc.). tensor_type (`Union[None, str, TensorType]`, *optional*): - You can give a tensor_type here to convert the lists of integers in PyTorch/TensorFlow/Numpy Tensors at + You can give a tensor_type here to convert the lists of integers in PyTorch/Numpy Tensors at initialization. """ diff --git a/src/transformers/image_transforms.py b/src/transformers/image_transforms.py index f0aeae8985b7..2aba3d549719 100644 --- a/src/transformers/image_transforms.py +++ b/src/transformers/image_transforms.py @@ -26,10 +26,8 @@ get_image_size, infer_channel_dimension_format, ) -from .utils import ExplicitEnum, TensorType, is_jax_tensor, is_tf_tensor, is_torch_tensor +from .utils import ExplicitEnum, TensorType, is_torch_tensor from .utils.import_utils import ( - is_flax_available, - is_tf_available, is_torch_available, is_vision_available, requires_backends, @@ -44,12 +42,6 @@ if is_torch_available(): import torch -if is_tf_available(): - import tensorflow as tf - -if is_flax_available(): - import jax.numpy as jnp - def to_channel_dimension_format( image: np.ndarray, @@ -160,7 +152,7 @@ def _rescale_for_pil_conversion(image): def to_pil_image( - image: Union[np.ndarray, "PIL.Image.Image", "torch.Tensor", "tf.Tensor", "jnp.ndarray"], + image: Union[np.ndarray, "PIL.Image.Image", "torch.Tensor"], do_rescale: Optional[bool] = None, image_mode: Optional[str] = None, input_data_format: Optional[Union[str, ChannelDimension]] = None, @@ -170,7 +162,7 @@ def to_pil_image( needed. Args: - image (`PIL.Image.Image` or `numpy.ndarray` or `torch.Tensor` or `tf.Tensor`): + image (`PIL.Image.Image` or `numpy.ndarray` or `torch.Tensor`): The image to convert to the `PIL.Image` format. do_rescale (`bool`, *optional*): Whether or not to apply the scaling factor (to make pixel values integers between 0 and 255). Will default @@ -190,10 +182,8 @@ def to_pil_image( return image # Convert all tensors to numpy arrays before converting to PIL image - if is_torch_tensor(image) or is_tf_tensor(image): + if is_torch_tensor(image): image = image.numpy() - elif is_jax_tensor(image): - image = np.array(image) elif not isinstance(image, np.ndarray): raise ValueError(f"Input image type not supported: {type(image)}") @@ -556,16 +546,6 @@ def _center_to_corners_format_numpy(bboxes_center: np.ndarray) -> np.ndarray: return bboxes_corners -def _center_to_corners_format_tf(bboxes_center: "tf.Tensor") -> "tf.Tensor": - center_x, center_y, width, height = tf.unstack(bboxes_center, axis=-1) - bboxes_corners = tf.stack( - # top left x, top left y, bottom right x, bottom right y - [center_x - 0.5 * width, center_y - 0.5 * height, center_x + 0.5 * width, center_y + 0.5 * height], - axis=-1, - ) - return bboxes_corners - - # 2 functions below inspired by https://github.com/facebookresearch/detr/blob/master/util/box_ops.py def center_to_corners_format(bboxes_center: TensorType) -> TensorType: """ @@ -576,14 +556,11 @@ def center_to_corners_format(bboxes_center: TensorType) -> TensorType: corners format: contains the coordinates for the top-left and bottom-right corners of the box (top_left_x, top_left_y, bottom_right_x, bottom_right_y) """ - # Function is used during model forward pass, so we use the input framework if possible, without - # converting to numpy + # Function is used during model forward pass, so we use torch if relevant, without converting to numpy if is_torch_tensor(bboxes_center): return _center_to_corners_format_torch(bboxes_center) elif isinstance(bboxes_center, np.ndarray): return _center_to_corners_format_numpy(bboxes_center) - elif is_tf_tensor(bboxes_center): - return _center_to_corners_format_tf(bboxes_center) raise ValueError(f"Unsupported input type {type(bboxes_center)}") @@ -613,20 +590,6 @@ def _corners_to_center_format_numpy(bboxes_corners: np.ndarray) -> np.ndarray: return bboxes_center -def _corners_to_center_format_tf(bboxes_corners: "tf.Tensor") -> "tf.Tensor": - top_left_x, top_left_y, bottom_right_x, bottom_right_y = tf.unstack(bboxes_corners, axis=-1) - bboxes_center = tf.stack( - [ - (top_left_x + bottom_right_x) / 2, # center x - (top_left_y + bottom_right_y) / 2, # center y - (bottom_right_x - top_left_x), # width - (bottom_right_y - top_left_y), # height - ], - axis=-1, - ) - return bboxes_center - - def corners_to_center_format(bboxes_corners: TensorType) -> TensorType: """ Converts bounding boxes from corners format to center format. @@ -641,8 +604,6 @@ def corners_to_center_format(bboxes_corners: TensorType) -> TensorType: return _corners_to_center_format_torch(bboxes_corners) elif isinstance(bboxes_corners, np.ndarray): return _corners_to_center_format_numpy(bboxes_corners) - elif is_tf_tensor(bboxes_corners): - return _corners_to_center_format_tf(bboxes_corners) raise ValueError(f"Unsupported input type {type(bboxes_corners)}") diff --git a/src/transformers/image_utils.py b/src/transformers/image_utils.py index 2079c21f3b0c..1d988f99379c 100644 --- a/src/transformers/image_utils.py +++ b/src/transformers/image_utils.py @@ -24,9 +24,7 @@ from .utils import ( ExplicitEnum, - is_jax_tensor, is_numpy_array, - is_tf_tensor, is_torch_available, is_torch_tensor, is_torchvision_available, @@ -107,8 +105,6 @@ class ImageType(ExplicitEnum): PIL = "pillow" TORCH = "torch" NUMPY = "numpy" - TENSORFLOW = "tensorflow" - JAX = "jax" def get_image_type(image): @@ -118,15 +114,11 @@ def get_image_type(image): return ImageType.TORCH if is_numpy_array(image): return ImageType.NUMPY - if is_tf_tensor(image): - return ImageType.TENSORFLOW - if is_jax_tensor(image): - return ImageType.JAX raise ValueError(f"Unrecognized image type {type(image)}") def is_valid_image(img): - return is_pil_image(img) or is_numpy_array(img) or is_torch_tensor(img) or is_tf_tensor(img) or is_jax_tensor(img) + return is_pil_image(img) or is_numpy_array(img) or is_torch_tensor(img) def is_valid_list_of_images(images: list): @@ -205,8 +197,7 @@ def make_list_of_images(images, expected_ndims: int = 3) -> list[ImageInput]: ) return images raise ValueError( - "Invalid image type. Expected either PIL.Image.Image, numpy.ndarray, torch.Tensor, tf.Tensor or " - f"jax.ndarray, but got {type(images)}." + f"Invalid image type. Expected either PIL.Image.Image, numpy.ndarray, or torch.Tensor, but got {type(images)}." ) @@ -570,7 +561,6 @@ def validate_preprocess_arguments( raise ValueError("`size` and `resample/interpolation` must be specified if `do_resize` is `True`.") -# In the future we can add a TF implementation here when we have TF models. class ImageFeatureExtractionMixin: """ Mixin that contain utilities for preparing image features. diff --git a/src/transformers/integrations/integration_utils.py b/src/transformers/integrations/integration_utils.py index 5ef1123b8fce..6cec1183c5c7 100755 --- a/src/transformers/integrations/integration_utils.py +++ b/src/transformers/integrations/integration_utils.py @@ -48,7 +48,6 @@ flatten_dict, is_datasets_available, is_pandas_available, - is_tf_available, is_torch_available, logging, ) @@ -56,8 +55,6 @@ logger = logging.get_logger(__name__) -if is_tf_available(): - from .. import TFPreTrainedModel if is_torch_available(): import torch @@ -760,12 +757,6 @@ def save_model_architecture_to_file(model: Any, output_dir: str): with open(f"{output_dir}/model_architecture.txt", "w+") as f: if isinstance(model, PreTrainedModel): print(model, file=f) - elif is_tf_available() and isinstance(model, TFPreTrainedModel): - - def print_to_file(s): - print(s, file=f) - - model.summary(print_fn=print_to_file) elif is_torch_available() and ( isinstance(model, (torch.nn.Module, PushToHubMixin)) and hasattr(model, "base_model") ): @@ -1225,7 +1216,7 @@ def setup(self, args, state, model): - **COMET_PROJECT_NAME** (`str`, *optional*): Comet project name for experiments. - **COMET_LOG_ASSETS** (`str`, *optional*, defaults to `TRUE`): - Whether or not to log training assets (tf event logs, checkpoints, etc), to Comet. Can be `TRUE`, or + Whether or not to log training assets (checkpoints, etc), to Comet. Can be `TRUE`, or `FALSE`. For a number of configurable items in the environment, see diff --git a/src/transformers/keras_callbacks.py b/src/transformers/keras_callbacks.py deleted file mode 100644 index ab7fc4615b47..000000000000 --- a/src/transformers/keras_callbacks.py +++ /dev/null @@ -1,413 +0,0 @@ -import logging -import os -from pathlib import Path -from time import sleep -from typing import Callable, Optional, Union - -import numpy as np -import tensorflow as tf -from huggingface_hub import Repository, create_repo -from packaging.version import parse - -from . import IntervalStrategy, PreTrainedTokenizerBase -from .modelcard import TrainingSummary -from .modeling_tf_utils import keras - - -logger = logging.getLogger(__name__) - - -class KerasMetricCallback(keras.callbacks.Callback): - """ - Callback to compute metrics at the end of every epoch. Unlike normal Keras metrics, these do not need to be - compilable by TF. It is particularly useful for common NLP metrics like BLEU and ROUGE that require string - operations or generation loops that cannot be compiled. Predictions (or generations) will be computed on the - `eval_dataset` before being passed to the `metric_fn` in `np.ndarray` format. The `metric_fn` should compute - metrics and return a dict mapping metric names to metric values. - - We provide an example of a suitable metric_fn that computes ROUGE scores for a summarization model below. Note that - this example skips some post-processing for readability and simplicity, and should probably not be used as-is! - - ```py - from datasets import load_metric - - rouge_metric = load_metric("rouge") - - - def rouge_fn(predictions, labels): - decoded_predictions = tokenizer.batch_decode(predictions, skip_special_tokens=True) - decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True) - result = rouge_metric.compute(predictions=decoded_predictions, references=decoded_labels) - return {key: value.mid.fmeasure * 100 for key, value in result.items()} - ``` - - The above function will return a dict containing values which will be logged like any other Keras metric: - - ``` - {'rouge1': 37.4199, 'rouge2': 13.9768, 'rougeL': 34.361, 'rougeLsum': 35.0781 - ``` - - Args: - metric_fn (`Callable`): - Metric function provided by the user. It will be called with two arguments - `predictions` and `labels`. - These contain the model's outputs and matching labels from the dataset. It should return a dict mapping - metric names to numerical values. - eval_dataset (`tf.data.Dataset` or `dict` or `tuple` or `np.ndarray` or `tf.Tensor`): - Validation data to be used to generate predictions for the `metric_fn`. - output_cols (`list[str], *optional*): - A list of columns to be retained from the model output as the predictions. Defaults to all. - label_cols ('`list[str]`, *optional*'): - A list of columns to be retained from the input dataset as the labels. Will be autodetected if this is not - supplied. - batch_size (`int`, *optional*): - Batch size. Only used when the data is not a pre-batched `tf.data.Dataset`. - predict_with_generate (`bool`, *optional*, defaults to `False`): - Whether we should use `model.generate()` to get outputs for the model. - use_xla_generation (`bool`, *optional*, defaults to `False`): - If we're generating, whether to compile model generation with XLA. This can massively increase the speed of - generation (up to 100X speedup) but will require a new XLA compilation for each input shape. When using XLA - generation, it's a good idea to pad your inputs to the same size, or to use the `pad_to_multiple_of` - argument in your `tokenizer` or `DataCollator`, which will reduce the number of unique input shapes and - save a lot of compilation time. This option has no effect is `predict_with_generate` is `False`. - generate_kwargs (`dict`, *optional*): - Keyword arguments to pass to `model.generate()` when generating. Has no effect if `predict_with_generate` - is `False`. - - """ - - def __init__( - self, - metric_fn: Callable, - eval_dataset: Union[tf.data.Dataset, np.ndarray, tf.Tensor, tuple, dict], - output_cols: Optional[list[str]] = None, - label_cols: Optional[list[str]] = None, - batch_size: Optional[int] = None, - predict_with_generate: bool = False, - use_xla_generation: bool = False, - generate_kwargs: Optional[dict] = None, - ): - super().__init__() - self.metric_fn = metric_fn - self.batch_size = batch_size - if not isinstance(eval_dataset, tf.data.Dataset): - if batch_size is None: - raise ValueError( - "When passing data to KerasMetricCallback that is not a pre-batched tf.data.Dataset " - "the batch_size argument must be set." - ) - # Wrap a tf.data.Dataset around it - eval_dataset = tf.data.Dataset.from_tensor_slices(eval_dataset).batch(batch_size, drop_remainder=False) - self.eval_dataset = eval_dataset - self.predict_with_generate = predict_with_generate - self.output_cols = output_cols - - # This next block attempts to parse out which elements of the dataset should be appended to the labels list - # that is passed to the metric_fn - if isinstance(eval_dataset.element_spec, tuple) and len(eval_dataset.element_spec) == 2: - input_spec, label_spec = eval_dataset.element_spec - else: - input_spec = eval_dataset.element_spec - label_spec = None - if label_cols is not None: - for label in label_cols: - if label not in input_spec: - raise ValueError(f"Label {label} is in label_cols but could not be found in the dataset inputs!") - self.label_cols = label_cols - self.use_keras_label = False - elif label_spec is not None: - # If the dataset inputs are split into a 2-tuple of inputs and labels, - # assume the second element is the labels - self.label_cols = None - self.use_keras_label = True - elif "labels" in input_spec: - self.label_cols = ["labels"] - self.use_keras_label = False - logging.warning("No label_cols specified for KerasMetricCallback, assuming you want the 'labels' key.") - elif "start_positions" in input_spec and "end_positions" in input_spec: - self.label_cols = ["start_positions", "end_positions"] - self.use_keras_label = False - logging.warning( - "No label_cols specified for KerasMetricCallback, assuming you want the " - "start_positions and end_positions keys." - ) - else: - raise ValueError("Could not autodetect label_cols for KerasMetricCallback, please specify them!") - if parse(tf.__version__) < parse("2.7"): - logging.warning("TF versions less than 2.7 may encounter issues with KerasMetricCallback!") - - self.use_xla_generation = use_xla_generation - self.generate_kwargs = {} if generate_kwargs is None else generate_kwargs - - self.generation_function = None - - @staticmethod - def _concatenate_batches(batches, padding_index=-100): - # If all batches are unidimensional or same length, do a simple concatenation - if batches[0].ndim == 1 or all(batch.shape[1] == batches[0].shape[1] for batch in batches): - return np.concatenate(batches, axis=0) - - # Welp, they're not the same length. Let's do some padding - max_len = max([batch.shape[1] for batch in batches]) - num_samples = sum([batch.shape[0] for batch in batches]) - output = np.full_like( - batches[0], fill_value=padding_index, shape=[num_samples, max_len] + list(batches[0].shape[2:]) - ) - # i keeps track of which part of the concatenated array we're writing the next batch to - i = 0 - for batch in batches: - output[i : i + len(batch), : batch.shape[1]] = batch - i += len(batch) - return output - - def _postprocess_predictions_or_labels(self, inputs): - if isinstance(inputs[0], dict): - outputs = {} - for key in inputs[0]: - outputs[key] = self._concatenate_batches([batch[key] for batch in inputs]) - # If it's a dict with only one key, just return the array - if len(outputs) == 1: - outputs = list(outputs.values())[0] - elif isinstance(inputs[0], (tuple, list)): - outputs = [] - for input_list in zip(*inputs): - outputs.append(self._concatenate_batches(input_list)) - if len(outputs) == 1: - outputs = outputs[0] # If it's a list with only one element, just return the array - elif isinstance(inputs[0], np.ndarray): - outputs = self._concatenate_batches(inputs) - elif isinstance(inputs[0], tf.Tensor): - outputs = self._concatenate_batches([tensor.numpy() for tensor in inputs]) - else: - raise TypeError(f"Couldn't handle batch of type {type(inputs[0])}!") - return outputs - - def on_epoch_end(self, epoch, logs=None): - if hasattr(self.model, "config"): - ignore_keys = getattr(self.model.config, "keys_to_ignore_at_inference", []) - else: - ignore_keys = [] - - main_input_name = None - if self.predict_with_generate: - # This dense conditional recognizes the case where we have an encoder-decoder model, but - # avoids getting tangled up when we just have a model with a layer called 'encoder' - if hasattr(self.model, "encoder") and hasattr(self.model.encoder, "main_input_name"): - main_input_name = self.model.encoder.main_input_name - else: - main_input_name = getattr(self.model, "main_input_name", "input_ids") - - if self.use_xla_generation and self.generation_function is None: - - def generation_function(inputs, attention_mask): - return self.model.generate(inputs, attention_mask=attention_mask, **self.generate_kwargs) - - self.generation_function = tf.function(generation_function, jit_compile=True) - - prediction_list = [] - label_list = [] - - # The whole predict/generate loop is handled inside this method - for batch in self.eval_dataset: - if isinstance(batch, tuple): - batch, labels = batch - else: - labels = None - if self.predict_with_generate: - if isinstance(batch, dict): - generation_inputs = batch[main_input_name] - attention_mask = batch.get("attention_mask", None) - else: - generation_inputs = batch - attention_mask = None - if self.use_xla_generation: - predictions = self.generation_function(generation_inputs, attention_mask=attention_mask) - else: - predictions = self.model.generate( - generation_inputs, attention_mask=attention_mask, **self.generate_kwargs - ) - else: - predictions = self.model.predict_on_batch(batch) - if isinstance(predictions, dict): - # This converts any dict-subclass to a regular dict - # Keras REALLY doesn't like it when we pass around a BatchEncoding or other derived class - predictions = dict(predictions) - if self.output_cols is not None: - predictions = {key: predictions[key] for key in self.output_cols} - else: - predictions = { - key: val for key, val in predictions.items() if key not in ignore_keys + ["loss"] - } - prediction_list.append(predictions) - if not self.use_keras_label: - labels = {key: batch[key].numpy() for key in self.label_cols} - elif isinstance(labels, dict): - labels = {key: array.numpy() for key, array in labels.items()} - elif isinstance(labels, (list, tuple)): - labels = [array.numpy() for array in labels] - elif isinstance(labels, tf.Tensor): - labels = labels.numpy() - else: - raise TypeError(f"Confused by labels of type {type(labels)}") - label_list.append(labels) - - all_preds = self._postprocess_predictions_or_labels(prediction_list) - all_labels = self._postprocess_predictions_or_labels(label_list) - - metric_output = self.metric_fn((all_preds, all_labels)) - if not isinstance(metric_output, dict): - raise TypeError( - f"metric_fn should return a dict mapping metric names to values but instead returned {metric_output}" - ) - # This is the critical bit - Keras passes a dict containing the loss and standard metric values for this epoch - # in the logs argument. Ordinarily, this is so the callback can read them, but in this case we write a bunch of - # new keys in there, which will then get read by the History callback and treated like any other metric value. - # I promise that I have it in writing from Chollet that this is okay. - logs.update(metric_output) - - -class PushToHubCallback(keras.callbacks.Callback): - """ - Callback that will save and push the model to the Hub regularly. By default, it pushes once per epoch, but this can - be changed with the `save_strategy` argument. Pushed models can be accessed like any other model on the hub, such - as with the `from_pretrained` method. - - ```py - from transformers.keras_callbacks import PushToHubCallback - - push_to_hub_callback = PushToHubCallback( - output_dir="./model_save", - tokenizer=tokenizer, - hub_model_id="gpt5-7xlarge", - ) - - model.fit(train_dataset, callbacks=[push_to_hub_callback]) - ``` - - Args: - output_dir (`str`): - The output directory where the model predictions and checkpoints will be written and synced with the - repository on the Hub. - save_strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"epoch"`): - The checkpoint save strategy to adopt during training. Possible values are: - - - `"no"`: Save is done at the end of training. - - `"epoch"`: Save is done at the end of each epoch. - - `"steps"`: Save is done every `save_steps` - save_steps (`int`, *optional*): - The number of steps between saves when using the "steps" `save_strategy`. - tokenizer (`PreTrainedTokenizerBase`, *optional*): - The tokenizer used by the model. If supplied, will be uploaded to the repo alongside the weights. - hub_model_id (`str`, *optional*): - The name of the repository to keep in sync with the local `output_dir`. It can be a simple model ID in - which case the model will be pushed in your namespace. Otherwise it should be the whole repository name, - for instance `"user_name/model"`, which allows you to push to an organization you are a member of with - `"organization_name/model"`. - - Will default to the name of `output_dir`. - hub_token (`str`, *optional*): - The token to use to push the model to the Hub. Will default to the token in the cache folder obtained with - `hf auth login`. - checkpoint (`bool`, *optional*, defaults to `False`): - Whether to save full training checkpoints (including epoch and optimizer state) to allow training to be - resumed. Only usable when `save_strategy` is `"epoch"`. - """ - - def __init__( - self, - output_dir: Union[str, Path], - save_strategy: Union[str, IntervalStrategy] = "epoch", - save_steps: Optional[int] = None, - tokenizer: Optional[PreTrainedTokenizerBase] = None, - hub_model_id: Optional[str] = None, - hub_token: Optional[str] = None, - checkpoint: bool = False, - **model_card_args, - ): - super().__init__() - if checkpoint and save_strategy != "epoch": - raise ValueError("Cannot save checkpoints when save_strategy is not 'epoch'!") - if isinstance(save_strategy, str): - save_strategy = IntervalStrategy(save_strategy.lower()) - self.save_strategy = save_strategy - if self.save_strategy == IntervalStrategy.STEPS and (not isinstance(save_steps, int) or save_steps <= 0): - raise ValueError("Please supply a positive integer argument for save_steps when save_strategy == 'steps'!") - self.save_steps = save_steps - output_dir = Path(output_dir) - - # Create repo and retrieve repo_id - if hub_model_id is None: - hub_model_id = output_dir.absolute().name - self.hub_model_id = create_repo(repo_id=hub_model_id, exist_ok=True, token=hub_token).repo_id - - self.output_dir = output_dir - self.repo = Repository(str(self.output_dir), clone_from=self.hub_model_id, token=hub_token) - - self.tokenizer = tokenizer - self.last_job = None - self.checkpoint = checkpoint - self.training_history = None - self.model_card_args = model_card_args - - def on_train_begin(self, logs=None): - # Although we can access model.history, we have no guarantees that the History callback will fire before this - # one, so we keep track of it here too - self.training_history = [] - - def on_train_batch_end(self, batch, logs=None): - if self.save_strategy == IntervalStrategy.STEPS and (batch + 1) % self.save_steps == 0: - if self.last_job is not None and not self.last_job.is_done: - return # The last upload is still running, don't start another - self.model.save_pretrained(self.output_dir) - if self.tokenizer is not None: - self.tokenizer.save_pretrained(self.output_dir) - _, self.last_job = self.repo.push_to_hub( - commit_message=f"Training in progress steps {batch}", blocking=False - ) - - def on_epoch_end(self, epoch, logs=None): - logs = logs.copy() # Don't accidentally write things that Keras will read later - if "epoch" not in logs: - logs["epoch"] = epoch - self.training_history.append(logs) - if self.save_strategy == IntervalStrategy.EPOCH: - if self.last_job is not None and not self.last_job.is_done: - return # The last upload is still running, don't start another - self.model.save_pretrained(self.output_dir) - if self.tokenizer is not None: - self.tokenizer.save_pretrained(self.output_dir) - if self.checkpoint: - checkpoint_dir = os.path.join(self.output_dir, "checkpoint") - self.model._save_checkpoint(checkpoint_dir, epoch) - train_summary = TrainingSummary.from_keras( - model=self.model, - model_name=self.hub_model_id, - keras_history=self.training_history, - **self.model_card_args, - ) - model_card = train_summary.to_model_card() - with (self.output_dir / "README.md").open("w") as f: - f.write(model_card) - _, self.last_job = self.repo.push_to_hub( - commit_message=f"Training in progress epoch {epoch}", blocking=False - ) - - def on_train_end(self, logs=None): - # Makes sure the latest version of the model is uploaded - if self.last_job is not None and not self.last_job.is_done: - logging.info("Pushing the last epoch to the Hub, this may take a while...") - while not self.last_job.is_done: - sleep(1) - else: - self.model.save_pretrained(self.output_dir) - if self.tokenizer is not None: - self.tokenizer.save_pretrained(self.output_dir) - train_summary = TrainingSummary.from_keras( - model=self.model, - model_name=self.hub_model_id, - keras_history=self.training_history, - **self.model_card_args, - ) - model_card = train_summary.to_model_card() - with (self.output_dir / "README.md").open("w") as f: - f.write(model_card) - self.repo.push_to_hub(commit_message="End of training", blocking=True) diff --git a/src/transformers/modelcard.py b/src/transformers/modelcard.py index 8c68d8b8af10..8ba390ee7cf5 100644 --- a/src/transformers/modelcard.py +++ b/src/transformers/modelcard.py @@ -51,7 +51,6 @@ cached_file, is_datasets_available, is_offline_mode, - is_tf_available, is_tokenizers_available, is_torch_available, logging, @@ -256,11 +255,6 @@ def to_json_file(self, json_file_path): should probably proofread and complete it, then remove this comment. --> """ -AUTOGENERATED_KERAS_COMMENT = """ - -""" - TASK_TAG_TO_NAME_MAPPING = { "fill-mask": "Masked Language Modeling", @@ -483,8 +477,6 @@ def to_model_card(self): # Now the model card for realsies. if self.source == "trainer": model_card += AUTOGENERATED_TRAINER_COMMENT - else: - model_card += AUTOGENERATED_KERAS_COMMENT model_card += f"\n# {self.model_name}\n\n" @@ -538,10 +530,6 @@ def to_model_card(self): import torch model_card += f"- Pytorch {torch.__version__}\n" - elif self.source == "keras" and is_tf_available(): - import tensorflow as tf - - model_card += f"- TensorFlow {tf.__version__}\n" if is_datasets_available(): import datasets @@ -631,116 +619,6 @@ def from_trainer( hyperparameters=hyperparameters, ) - @classmethod - def from_keras( - cls, - model, - model_name, - keras_history=None, - language=None, - license=None, - tags=None, - finetuned_from=None, - tasks=None, - dataset_tags=None, - dataset=None, - dataset_args=None, - ): - # Infer default from dataset - if dataset is not None: - if is_hf_dataset(dataset) and (dataset_tags is None or dataset_args is None): - default_tag = dataset.builder_name - # Those are not real datasets from the Hub so we exclude them. - if default_tag not in ["csv", "json", "pandas", "parquet", "text"]: - if dataset_tags is None: - dataset_tags = [default_tag] - if dataset_args is None: - dataset_args = [dataset.config_name] - - if dataset is None and dataset_tags is not None: - dataset = dataset_tags - - # Infer default finetuned_from - if ( - finetuned_from is None - and hasattr(model.config, "_name_or_path") - and not os.path.isdir(model.config._name_or_path) - ): - finetuned_from = model.config._name_or_path - - # Infer default task tag: - if tasks is None: - model_class_name = model.__class__.__name__ - for task, mapping in TASK_MAPPING.items(): - if model_class_name in _get_mapping_values(mapping): - tasks = task - - # Add `generated_from_keras_callback` to the tags - if tags is None: - tags = ["generated_from_keras_callback"] - elif isinstance(tags, str) and tags != "generated_from_keras_callback": - tags = [tags, "generated_from_keras_callback"] - elif "generated_from_keras_callback" not in tags: - tags.append("generated_from_keras_callback") - - if keras_history is not None: - _, eval_lines, eval_results = parse_keras_history(keras_history) - else: - eval_lines = [] - eval_results = {} - hyperparameters = extract_hyperparameters_from_keras(model) - - return cls( - language=language, - license=license, - tags=tags, - model_name=model_name, - finetuned_from=finetuned_from, - tasks=tasks, - dataset_tags=dataset_tags, - dataset=dataset, - dataset_args=dataset_args, - eval_results=eval_results, - eval_lines=eval_lines, - hyperparameters=hyperparameters, - source="keras", - ) - - -def parse_keras_history(logs): - """ - Parse the `logs` of either a `keras.History` object returned by `model.fit()` or an accumulated logs `dict` - passed to the `PushToHubCallback`. Returns lines and logs compatible with those returned by `parse_log_history`. - """ - if hasattr(logs, "history"): - # This looks like a `History` object - if not hasattr(logs, "epoch"): - # This history looks empty, return empty results - return None, [], {} - logs.history["epoch"] = logs.epoch - logs = logs.history - else: - # Training logs is a list of dicts, let's invert it to a dict of lists to match a History object - logs = {log_key: [single_dict[log_key] for single_dict in logs] for log_key in logs[0]} - - lines = [] - for i in range(len(logs["epoch"])): - epoch_dict = {log_key: log_value_list[i] for log_key, log_value_list in logs.items()} - values = {} - for k, v in epoch_dict.items(): - if k.startswith("val_"): - k = "validation_" + k[4:] - elif k != "epoch": - k = "train_" + k - splits = k.split("_") - name = " ".join([part.capitalize() for part in splits]) - values[name] = v - lines.append(values) - - eval_results = lines[-1] - - return logs, lines, eval_results - def parse_log_history(log_history): """ @@ -804,19 +682,6 @@ def parse_log_history(log_history): return train_log, lines, None -def extract_hyperparameters_from_keras(model): - from .modeling_tf_utils import keras - - hyperparameters = {} - if hasattr(model, "optimizer") and model.optimizer is not None: - hyperparameters["optimizer"] = model.optimizer.get_config() - else: - hyperparameters["optimizer"] = None - hyperparameters["training_precision"] = keras.mixed_precision.global_policy().name - - return hyperparameters - - def _maybe_round(v, decimals=4): if isinstance(v, float) and len(str(v).split(".")) > 1 and len(str(v).split(".")[1]) > decimals: return f"{v:.{decimals}f}" diff --git a/src/transformers/modeling_flax_outputs.py b/src/transformers/modeling_flax_outputs.py deleted file mode 100644 index 5a25a6059a25..000000000000 --- a/src/transformers/modeling_flax_outputs.py +++ /dev/null @@ -1,700 +0,0 @@ -# Copyright 2021 The HuggingFace Team. All rights reserved. -# -# 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. -from typing import Optional - -import flax -import jax.numpy as jnp - -from .utils import ModelOutput - - -@flax.struct.dataclass -class FlaxBaseModelOutput(ModelOutput): - """ - Base class for model's outputs, with potential hidden states and attentions. - - Args: - last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxBaseModelOutputWithNoAttention(ModelOutput): - """ - Base class for model's outputs, with potential hidden states. - - Args: - last_hidden_state (`jnp.ndarray` of shape `(batch_size, num_channels, height, width)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings, if the model has an embedding layer, + one - for the output of each layer) of shape `(batch_size, num_channels, height, width)`. Hidden-states of the - model at the output of each layer plus the optional initial embedding outputs. - """ - - last_hidden_state: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxBaseModelOutputWithPoolingAndNoAttention(ModelOutput): - """ - Base class for model's outputs that also contains a pooling of the last hidden states. - - Args: - last_hidden_state (`jnp.ndarray` of shape `(batch_size, num_channels, height, width)`): - Sequence of hidden-states at the output of the last layer of the model. - pooler_output (`jnp.ndarray` of shape `(batch_size, hidden_size)`): - Last layer hidden-state after a pooling operation on the spatial dimensions. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings, if the model has an embedding layer, + one - for the output of each layer) of shape `(batch_size, num_channels, height, width)`. Hidden-states of the - model at the output of each layer plus the optional initial embedding outputs. - """ - - last_hidden_state: Optional[jnp.ndarray] = None - pooler_output: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxImageClassifierOutputWithNoAttention(ModelOutput): - """ - Base class for outputs of image classification models. - - Args: - logits (`jnp.ndarray` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when - `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings, if the model has an embedding layer, + one - for the output of each stage) of shape `(batch_size, num_channels, height, width)`. Hidden-states (also - called feature maps) of the model at the output of each stage. - """ - - logits: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxBaseModelOutputWithPast(ModelOutput): - """ - Base class for model's outputs, with potential hidden states and attentions. - - Args: - last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - past_key_values (`dict[str, jnp.ndarray]`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: Optional[jnp.ndarray] = None - past_key_values: Optional[dict[str, jnp.ndarray]] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxBaseModelOutputWithPooling(ModelOutput): - """ - Base class for model's outputs that also contains a pooling of the last hidden states. - - Args: - last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - pooler_output (`jnp.ndarray` of shape `(batch_size, hidden_size)`): - Last layer hidden-state of the first token of the sequence (classification token) further processed by a - Linear layer and a Tanh activation function. The Linear layer weights are trained from the next sentence - prediction (classification) objective during pretraining. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: Optional[jnp.ndarray] = None - pooler_output: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxBaseModelOutputWithPoolingAndCrossAttentions(ModelOutput): - """ - Base class for model's outputs that also contains a pooling of the last hidden states. - - Args: - last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - pooler_output (`jnp.ndarray` of shape `(batch_size, hidden_size)`): - Last layer hidden-state of the first token of the sequence (classification token) after further processing - through the layers used for the auxiliary pretraining task. E.g. for BERT-family of models, this returns - the classification token after processing through a linear layer and a tanh activation function. The linear - layer weights are trained from the next sentence prediction (classification) objective during pretraining. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings, if the model has an embedding layer, + one - for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - cross_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` and `config.add_cross_attention=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - past_key_values (`tuple(tuple(jnp.ndarray))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(jnp.ndarray)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if - `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` - input) to speed up sequential decoding. - """ - - last_hidden_state: Optional[jnp.ndarray] = None - pooler_output: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - past_key_values: Optional[tuple[tuple[jnp.ndarray]]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - cross_attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxBaseModelOutputWithPastAndCrossAttentions(ModelOutput): - """ - Base class for model's outputs that may also contain a past key/values (to speed up sequential decoding). - - Args: - last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - - If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, - hidden_size)` is output. - past_key_values (`tuple(tuple(jnp.ndarray))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(jnp.ndarray)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if - `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` - input) to speed up sequential decoding. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - cross_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` and `config.add_cross_attention=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - """ - - last_hidden_state: Optional[jnp.ndarray] = None - past_key_values: Optional[tuple[tuple[jnp.ndarray]]] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - cross_attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxSeq2SeqModelOutput(ModelOutput): - """ - Base class for model encoder's outputs that also contains : pre-computed hidden states that can speed up sequential - decoding. - - Args: - last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the decoder of the model. - - If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, - hidden_size)` is output. - past_key_values (`tuple(tuple(jnp.ndarray))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(jnp.ndarray)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape - `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention - blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. - decoder_hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the decoder at the output of each layer plus the initial embedding outputs. - decoder_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - cross_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - encoder_last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder of the model. - encoder_hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. - encoder_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - """ - - last_hidden_state: Optional[jnp.ndarray] = None - past_key_values: Optional[tuple[tuple[jnp.ndarray]]] = None - decoder_hidden_states: Optional[tuple[jnp.ndarray]] = None - decoder_attentions: Optional[tuple[jnp.ndarray]] = None - cross_attentions: Optional[tuple[jnp.ndarray]] = None - encoder_last_hidden_state: Optional[jnp.ndarray] = None - encoder_hidden_states: Optional[tuple[jnp.ndarray]] = None - encoder_attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxCausalLMOutputWithCrossAttentions(ModelOutput): - """ - Base class for causal language model (or autoregressive) outputs. - - Args: - logits (`jnp.ndarray` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - cross_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Cross attentions weights after the attention softmax, used to compute the weighted average in the - cross-attention heads. - past_key_values (`tuple(tuple(jnp.ndarray))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `jnp.ndarray` tuples of length `config.n_layers`, with each tuple containing the cached key, value - states of the self-attention and the cross-attention layers if model is used in encoder-decoder setting. - Only relevant if `config.is_decoder = True`. - - Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. - """ - - logits: Optional[jnp.ndarray] = None - past_key_values: Optional[tuple[tuple[jnp.ndarray]]] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - cross_attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxMaskedLMOutput(ModelOutput): - """ - Base class for masked language models outputs. - - Args: - logits (`jnp.ndarray` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -FlaxCausalLMOutput = FlaxMaskedLMOutput - - -@flax.struct.dataclass -class FlaxSeq2SeqLMOutput(ModelOutput): - """ - Base class for sequence-to-sequence language models outputs. - - Args: - logits (`jnp.ndarray` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`tuple(tuple(jnp.ndarray))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(jnp.ndarray)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape - `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention - blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. - decoder_hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the decoder at the output of each layer plus the initial embedding outputs. - decoder_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - cross_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - encoder_last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder of the model. - encoder_hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. - encoder_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - """ - - logits: Optional[jnp.ndarray] = None - past_key_values: Optional[tuple[tuple[jnp.ndarray]]] = None - decoder_hidden_states: Optional[tuple[jnp.ndarray]] = None - decoder_attentions: Optional[tuple[jnp.ndarray]] = None - cross_attentions: Optional[tuple[jnp.ndarray]] = None - encoder_last_hidden_state: Optional[jnp.ndarray] = None - encoder_hidden_states: Optional[tuple[jnp.ndarray]] = None - encoder_attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxNextSentencePredictorOutput(ModelOutput): - """ - Base class for outputs of models predicting if two sentences are consecutive or not. - - Args: - logits (`jnp.ndarray` of shape `(batch_size, 2)`): - Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation - before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxSequenceClassifierOutput(ModelOutput): - """ - Base class for outputs of sentence classification models. - - Args: - logits (`jnp.ndarray` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxSeq2SeqSequenceClassifierOutput(ModelOutput): - """ - Base class for outputs of sequence-to-sequence sentence classification models. - - Args: - logits (`jnp.ndarray` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - past_key_values (`tuple(tuple(jnp.ndarray))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(jnp.ndarray)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape - `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention - blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. - decoder_hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the decoder at the output of each layer plus the initial embedding outputs. - decoder_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - cross_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - encoder_last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder of the model. - encoder_hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. - encoder_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - """ - - logits: Optional[jnp.ndarray] = None - past_key_values: Optional[tuple[tuple[jnp.ndarray]]] = None - decoder_hidden_states: Optional[tuple[jnp.ndarray]] = None - decoder_attentions: Optional[tuple[jnp.ndarray]] = None - cross_attentions: Optional[tuple[jnp.ndarray]] = None - encoder_last_hidden_state: Optional[jnp.ndarray] = None - encoder_hidden_states: Optional[tuple[jnp.ndarray]] = None - encoder_attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxMultipleChoiceModelOutput(ModelOutput): - """ - Base class for outputs of multiple choice models. - - Args: - logits (`jnp.ndarray` of shape `(batch_size, num_choices)`): - *num_choices* is the second dimension of the input tensors. (see *input_ids* above). - - Classification scores (before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxTokenClassifierOutput(ModelOutput): - """ - Base class for outputs of token classification models. - - Args: - logits (`jnp.ndarray` of shape `(batch_size, sequence_length, config.num_labels)`): - Classification scores (before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxQuestionAnsweringModelOutput(ModelOutput): - """ - Base class for outputs of question answering models. - - Args: - start_logits (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Span-start scores (before SoftMax). - end_logits (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Span-end scores (before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - start_logits: Optional[jnp.ndarray] = None - end_logits: Optional[jnp.ndarray] = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxSeq2SeqQuestionAnsweringModelOutput(ModelOutput): - """ - Base class for outputs of sequence-to-sequence question answering models. - - Args: - start_logits (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Span-start scores (before SoftMax). - end_logits (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Span-end scores (before SoftMax). - past_key_values (`tuple(tuple(jnp.ndarray))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(jnp.ndarray)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape - `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention - blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. - decoder_hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the decoder at the output of each layer plus the initial embedding outputs. - decoder_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - cross_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - encoder_last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder of the model. - encoder_hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. - encoder_attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - """ - - start_logits: Optional[jnp.ndarray] = None - end_logits: Optional[jnp.ndarray] = None - past_key_values: Optional[tuple[tuple[jnp.ndarray]]] = None - decoder_hidden_states: Optional[tuple[jnp.ndarray]] = None - decoder_attentions: Optional[tuple[jnp.ndarray]] = None - cross_attentions: Optional[tuple[jnp.ndarray]] = None - encoder_last_hidden_state: Optional[jnp.ndarray] = None - encoder_hidden_states: Optional[tuple[jnp.ndarray]] = None - encoder_attentions: Optional[tuple[jnp.ndarray]] = None diff --git a/src/transformers/modeling_flax_pytorch_utils.py b/src/transformers/modeling_flax_pytorch_utils.py deleted file mode 100644 index dece5233d956..000000000000 --- a/src/transformers/modeling_flax_pytorch_utils.py +++ /dev/null @@ -1,491 +0,0 @@ -# coding=utf-8 -# Copyright 2021 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. -"""PyTorch - Flax general utilities.""" - -import os -from pickle import UnpicklingError - -import jax -import jax.numpy as jnp -import numpy as np -from flax.serialization import from_bytes -from flax.traverse_util import flatten_dict, unflatten_dict - -import transformers - -from . import is_safetensors_available, is_torch_available -from .utils import check_torch_load_is_safe, logging - - -if is_torch_available(): - import torch - -if is_safetensors_available(): - from safetensors import safe_open - from safetensors.flax import load_file as safe_load_file - - -logger = logging.get_logger(__name__) - - -##################### -# PyTorch => Flax # -##################### - - -def load_pytorch_checkpoint_in_flax_state_dict( - flax_model, pytorch_checkpoint_path, is_sharded, allow_missing_keys=False -): - """Load pytorch checkpoints in a flax model""" - - if not is_sharded: - pt_path = os.path.abspath(pytorch_checkpoint_path) - logger.info(f"Loading PyTorch weights from {pt_path}") - - if pt_path.endswith(".safetensors"): - pt_state_dict = {} - with safe_open(pt_path, framework="flax") as f: - for k in f.keys(): - pt_state_dict[k] = f.get_tensor(k) - else: - try: - import torch # noqa: F401 - except (ImportError, ModuleNotFoundError): - logger.error( - "Loading a PyTorch model in Flax, requires both PyTorch and Flax to be installed. Please see" - " https://pytorch.org/ and https://flax.readthedocs.io/en/latest/index.html#installation for installation" - " instructions." - ) - raise - - check_torch_load_is_safe() - pt_state_dict = torch.load(pt_path, map_location="cpu", weights_only=True) - logger.info(f"PyTorch checkpoint contains {sum(t.numel() for t in pt_state_dict.values()):,} parameters.") - - flax_state_dict = convert_pytorch_state_dict_to_flax(pt_state_dict, flax_model) - else: - # model is sharded and pytorch_checkpoint_path already contains the list of .pt shard files - flax_state_dict = convert_pytorch_sharded_state_dict_to_flax(pytorch_checkpoint_path, flax_model) - return flax_state_dict - - -def rename_key_and_reshape_tensor( - pt_tuple_key: tuple[str], - pt_tensor: np.ndarray, - random_flax_state_dict: dict[str, jnp.ndarray], - model_prefix: str, -) -> tuple[tuple[str], np.ndarray]: - """Rename PT weight names to corresponding Flax weight names and reshape tensor if necessary""" - - def is_key_or_prefix_key_in_dict(key: tuple[str]) -> bool: - """Checks if `key` of `(prefix,) + key` is in random_flax_state_dict""" - return len(set(random_flax_state_dict) & {key, (model_prefix,) + key}) > 0 - - # layer norm - renamed_pt_tuple_key = pt_tuple_key[:-1] + ("scale",) - if pt_tuple_key[-1] in ["weight", "gamma"] and is_key_or_prefix_key_in_dict(renamed_pt_tuple_key): - return renamed_pt_tuple_key, pt_tensor - - # batch norm layer mean - renamed_pt_tuple_key = pt_tuple_key[:-1] + ("mean",) - if pt_tuple_key[-1] == "running_mean" and not is_key_or_prefix_key_in_dict(pt_tuple_key): - return renamed_pt_tuple_key, pt_tensor - - # batch norm layer var - renamed_pt_tuple_key = pt_tuple_key[:-1] + ("var",) - if pt_tuple_key[-1] == "running_var" and not is_key_or_prefix_key_in_dict(pt_tuple_key): - return renamed_pt_tuple_key, pt_tensor - - # embedding - renamed_pt_tuple_key = pt_tuple_key[:-1] + ("embedding",) - if pt_tuple_key[-1] == "weight" and is_key_or_prefix_key_in_dict(renamed_pt_tuple_key): - return renamed_pt_tuple_key, pt_tensor - - # conv layer - renamed_pt_tuple_key = pt_tuple_key[:-1] + ("kernel",) - if pt_tuple_key[-1] == "weight" and pt_tensor.ndim == 4 and not is_key_or_prefix_key_in_dict(pt_tuple_key): - pt_tensor = pt_tensor.transpose(2, 3, 1, 0) - return renamed_pt_tuple_key, pt_tensor - - # linear layer - renamed_pt_tuple_key = pt_tuple_key[:-1] + ("kernel",) - if pt_tuple_key[-1] == "weight" and not is_key_or_prefix_key_in_dict(pt_tuple_key): - pt_tensor = pt_tensor.T - return renamed_pt_tuple_key, pt_tensor - - # old PyTorch layer norm weight - renamed_pt_tuple_key = pt_tuple_key[:-1] + ("weight",) - if pt_tuple_key[-1] == "gamma": - return renamed_pt_tuple_key, pt_tensor - - # old PyTorch layer norm bias - renamed_pt_tuple_key = pt_tuple_key[:-1] + ("bias",) - if pt_tuple_key[-1] == "beta": - return renamed_pt_tuple_key, pt_tensor - - # New `weight_norm` from https://github.com/huggingface/transformers/pull/24030 - name = None - if pt_tuple_key[-3::2] == ("parametrizations", "original0"): - name = pt_tuple_key[-2] + "_g" - elif pt_tuple_key[-3::2] == ("parametrizations", "original1"): - name = pt_tuple_key[-2] + "_v" - if name is not None: - renamed_pt_tuple_key = pt_tuple_key[:-3] + (name,) - return renamed_pt_tuple_key, pt_tensor - - return pt_tuple_key, pt_tensor - - -def convert_pytorch_state_dict_to_flax(pt_state_dict, flax_model): - # convert pytorch tensor to numpy - from_bin = is_torch_available() and isinstance(next(iter(pt_state_dict.values())), torch.Tensor) - bfloat16 = torch.bfloat16 if from_bin else "bfloat16" - - weight_dtypes = {k: v.dtype for k, v in pt_state_dict.items()} - - if from_bin: - for k, v in pt_state_dict.items(): - # numpy currently does not support bfloat16, need to go over float32 in this case to not lose precision - if v.dtype == bfloat16: - v = v.float() - pt_state_dict[k] = v.cpu().numpy() - - model_prefix = flax_model.base_model_prefix - - # use params dict if the model contains batch norm layers - if "params" in flax_model.params: - flax_model_params = flax_model.params["params"] - else: - flax_model_params = flax_model.params - random_flax_state_dict = flatten_dict(flax_model_params) - - # add batch_stats keys,values to dict - if "batch_stats" in flax_model.params: - flax_batch_stats = flatten_dict(flax_model.params["batch_stats"]) - random_flax_state_dict.update(flax_batch_stats) - - flax_state_dict = {} - - load_model_with_head_into_base_model = (model_prefix not in flax_model_params) and ( - model_prefix in {k.split(".")[0] for k in pt_state_dict} - ) - load_base_model_into_model_with_head = (model_prefix in flax_model_params) and ( - model_prefix not in {k.split(".")[0] for k in pt_state_dict} - ) - - # Need to change some parameters name to match Flax names - for pt_key, pt_tensor in pt_state_dict.items(): - pt_tuple_key = tuple(pt_key.split(".")) - is_bfloat_16 = weight_dtypes[pt_key] == bfloat16 - - # remove base model prefix if necessary - has_base_model_prefix = pt_tuple_key[0] == model_prefix - if load_model_with_head_into_base_model and has_base_model_prefix: - pt_tuple_key = pt_tuple_key[1:] - - # Correctly rename weight parameters - flax_key, flax_tensor = rename_key_and_reshape_tensor( - pt_tuple_key, pt_tensor, random_flax_state_dict, model_prefix - ) - - # add model prefix if necessary - require_base_model_prefix = (model_prefix,) + flax_key in random_flax_state_dict - if load_base_model_into_model_with_head and require_base_model_prefix: - flax_key = (model_prefix,) + flax_key - - if flax_key in random_flax_state_dict: - if flax_tensor.shape != random_flax_state_dict[flax_key].shape: - raise ValueError( - f"PyTorch checkpoint seems to be incorrect. Weight {pt_key} was expected to be of shape " - f"{random_flax_state_dict[flax_key].shape}, but is {flax_tensor.shape}." - ) - - # add batch stats if the model contains batchnorm layers - if "batch_stats" in flax_model.params: - if "mean" in flax_key[-1] or "var" in flax_key[-1]: - flax_state_dict[("batch_stats",) + flax_key] = jnp.asarray(flax_tensor) - continue - # remove num_batches_tracked key - if "num_batches_tracked" in flax_key[-1]: - flax_state_dict.pop(flax_key, None) - continue - - # also add unexpected weight so that warning is thrown - flax_state_dict[("params",) + flax_key] = ( - jnp.asarray(flax_tensor) if not is_bfloat_16 else jnp.asarray(flax_tensor, dtype=jnp.bfloat16) - ) - else: - # also add unexpected weight so that warning is thrown - flax_state_dict[flax_key] = ( - jnp.asarray(flax_tensor) if not is_bfloat_16 else jnp.asarray(flax_tensor, dtype=jnp.bfloat16) - ) - - return unflatten_dict(flax_state_dict) - - -############################ -# Sharded Pytorch => Flax # -############################ - - -def convert_pytorch_sharded_state_dict_to_flax(shard_filenames, flax_model): - import torch - - # Load the index - flax_state_dict = {} - for shard_file in shard_filenames: - # load using msgpack utils - check_torch_load_is_safe() - pt_state_dict = torch.load(shard_file, weights_only=True) - weight_dtypes = {k: v.dtype for k, v in pt_state_dict.items()} - pt_state_dict = { - k: v.numpy() if v.dtype != torch.bfloat16 else v.float().numpy() for k, v in pt_state_dict.items() - } - - model_prefix = flax_model.base_model_prefix - - # use params dict if the model contains batch norm layers and then add batch_stats keys,values to dict - if "batch_stats" in flax_model.params: - flax_model_params = flax_model.params["params"] - - random_flax_state_dict = flatten_dict(flax_model_params) - random_flax_state_dict.update(flatten_dict(flax_model.params["batch_stats"])) - else: - flax_model_params = flax_model.params - random_flax_state_dict = flatten_dict(flax_model_params) - - load_model_with_head_into_base_model = (model_prefix not in flax_model_params) and ( - model_prefix in {k.split(".")[0] for k in pt_state_dict} - ) - load_base_model_into_model_with_head = (model_prefix in flax_model_params) and ( - model_prefix not in {k.split(".")[0] for k in pt_state_dict} - ) - # Need to change some parameters name to match Flax names - for pt_key, pt_tensor in pt_state_dict.items(): - pt_tuple_key = tuple(pt_key.split(".")) - is_bfloat_16 = weight_dtypes[pt_key] == torch.bfloat16 - - # remove base model prefix if necessary - has_base_model_prefix = pt_tuple_key[0] == model_prefix - if load_model_with_head_into_base_model and has_base_model_prefix: - pt_tuple_key = pt_tuple_key[1:] - - # Correctly rename weight parameters - flax_key, flax_tensor = rename_key_and_reshape_tensor( - pt_tuple_key, pt_tensor, random_flax_state_dict, model_prefix - ) - # add model prefix if necessary - require_base_model_prefix = (model_prefix,) + flax_key in random_flax_state_dict - if load_base_model_into_model_with_head and require_base_model_prefix: - flax_key = (model_prefix,) + flax_key - - if flax_key in random_flax_state_dict: - if flax_tensor.shape != random_flax_state_dict[flax_key].shape: - raise ValueError( - f"PyTorch checkpoint seems to be incorrect. Weight {pt_key} was expected to be of shape " - f"{random_flax_state_dict[flax_key].shape}, but is {flax_tensor.shape}." - ) - - # add batch stats if the model contains batchnorm layers - if "batch_stats" in flax_model.params: - if "mean" in flax_key[-1]: - flax_state_dict[("batch_stats",) + flax_key] = jnp.asarray(flax_tensor) - continue - if "var" in flax_key[-1]: - flax_state_dict[("batch_stats",) + flax_key] = jnp.asarray(flax_tensor) - continue - # remove num_batches_tracked key - if "num_batches_tracked" in flax_key[-1]: - flax_state_dict.pop(flax_key, None) - continue - - # also add unexpected weight so that warning is thrown - flax_state_dict[("params",) + flax_key] = ( - jnp.asarray(flax_tensor) if not is_bfloat_16 else jnp.asarray(flax_tensor, dtype=jnp.bfloat16) - ) - - else: - # also add unexpected weight so that warning is thrown - flax_state_dict[flax_key] = ( - jnp.asarray(flax_tensor) if not is_bfloat_16 else jnp.asarray(flax_tensor, dtype=jnp.bfloat16) - ) - return unflatten_dict(flax_state_dict) - - -##################### -# Flax => PyTorch # -##################### - - -def load_flax_checkpoint_in_pytorch_model(model, flax_checkpoint_path): - """Load flax checkpoints in a PyTorch model""" - flax_checkpoint_path = os.path.abspath(flax_checkpoint_path) - logger.info(f"Loading Flax weights from {flax_checkpoint_path}") - - # import correct flax class - flax_cls = getattr(transformers, "Flax" + model.__class__.__name__) - - # load flax weight dict - if flax_checkpoint_path.endswith(".safetensors"): - flax_state_dict = safe_load_file(flax_checkpoint_path) - flax_state_dict = unflatten_dict(flax_state_dict, sep=".") - else: - with open(flax_checkpoint_path, "rb") as state_f: - try: - flax_state_dict = from_bytes(flax_cls, state_f.read()) - except UnpicklingError: - raise OSError(f"Unable to convert {flax_checkpoint_path} to Flax deserializable object. ") - - return load_flax_weights_in_pytorch_model(model, flax_state_dict) - - -def load_flax_weights_in_pytorch_model(pt_model, flax_state): - """Load flax checkpoints in a PyTorch model""" - - try: - import torch # noqa: F401 - except (ImportError, ModuleNotFoundError): - logger.error( - "Loading a Flax weights in PyTorch, requires both PyTorch and Flax to be installed. Please see" - " https://pytorch.org/ and https://flax.readthedocs.io/en/latest/index.html#installation for installation" - " instructions." - ) - raise - - # check if we have bf16 weights - is_type_bf16 = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype == jnp.bfloat16, flax_state)).values() - if any(is_type_bf16): - # convert all weights to fp32 if the are bf16 since torch.from_numpy can-not handle bf16 - # and bf16 is not fully supported in PT yet. - logger.warning( - "Found ``bfloat16`` weights in Flax model. Casting all ``bfloat16`` weights to ``float32`` " - "before loading those in PyTorch model." - ) - flax_state = jax.tree_util.tree_map( - lambda params: params.astype(np.float32) if params.dtype == jnp.bfloat16 else params, flax_state - ) - - flax_state_dict = flatten_dict(flax_state) - pt_model_dict = pt_model.state_dict() - - load_model_with_head_into_base_model = (pt_model.base_model_prefix in flax_state) and ( - pt_model.base_model_prefix not in {k.split(".")[0] for k in pt_model_dict} - ) - load_base_model_into_model_with_head = (pt_model.base_model_prefix not in flax_state) and ( - pt_model.base_model_prefix in {k.split(".")[0] for k in pt_model_dict} - ) - - # keep track of unexpected & missing keys - unexpected_keys = [] - missing_keys = set(pt_model_dict.keys()) - - for flax_key_tuple, flax_tensor in flax_state_dict.items(): - has_base_model_prefix = flax_key_tuple[0] == pt_model.base_model_prefix - require_base_model_prefix = ".".join((pt_model.base_model_prefix,) + flax_key_tuple) in pt_model_dict - - # adapt flax_key to prepare for loading from/to base model only - if load_model_with_head_into_base_model and has_base_model_prefix: - flax_key_tuple = flax_key_tuple[1:] - elif load_base_model_into_model_with_head and require_base_model_prefix: - flax_key_tuple = (pt_model.base_model_prefix,) + flax_key_tuple - - # rename flax weights to PyTorch format - if flax_key_tuple[-1] == "kernel" and flax_tensor.ndim == 4 and ".".join(flax_key_tuple) not in pt_model_dict: - # conv layer - flax_key_tuple = flax_key_tuple[:-1] + ("weight",) - flax_tensor = jnp.transpose(flax_tensor, (3, 2, 0, 1)) - elif flax_key_tuple[-1] == "kernel" and ".".join(flax_key_tuple) not in pt_model_dict: - # linear layer - flax_key_tuple = flax_key_tuple[:-1] + ("weight",) - flax_tensor = flax_tensor.T - elif flax_key_tuple[-1] in ["scale", "embedding"]: - flax_key_tuple = flax_key_tuple[:-1] + ("weight",) - - # adding batch stats from flax batch norm to pt - elif "mean" in flax_key_tuple[-1]: - flax_key_tuple = flax_key_tuple[:-1] + ("running_mean",) - elif "var" in flax_key_tuple[-1]: - flax_key_tuple = flax_key_tuple[:-1] + ("running_var",) - - if "batch_stats" in flax_state: - flax_key = ".".join(flax_key_tuple[1:]) # Remove the params/batch_stats header - else: - flax_key = ".".join(flax_key_tuple) - - # We also need to look at `pt_model_dict` and see if there are keys requiring further transformation. - special_pt_names = {} - # New `weight_norm` from https://github.com/huggingface/transformers/pull/24030 - for key in pt_model_dict: - key_components = key.split(".") - name = None - if key_components[-3::2] == ["parametrizations", "original0"]: - name = key_components[-2] + "_g" - elif key_components[-3::2] == ["parametrizations", "original1"]: - name = key_components[-2] + "_v" - if name is not None: - key_components = key_components[:-3] + [name] - key_to_check = ".".join(key_components) - special_pt_names[key_to_check] = key - - if flax_key in special_pt_names: - flax_key = special_pt_names[flax_key] - - if flax_key in pt_model_dict: - if flax_tensor.shape != pt_model_dict[flax_key].shape: - raise ValueError( - f"Flax checkpoint seems to be incorrect. Weight {flax_key_tuple} was expected " - f"to be of shape {pt_model_dict[flax_key].shape}, but is {flax_tensor.shape}." - ) - else: - # add weight to pytorch dict - flax_tensor = np.asarray(flax_tensor) if not isinstance(flax_tensor, np.ndarray) else flax_tensor - pt_model_dict[flax_key] = torch.from_numpy(flax_tensor) - # remove from missing keys - missing_keys.remove(flax_key) - else: - # weight is not expected by PyTorch model - unexpected_keys.append(flax_key) - - pt_model.load_state_dict(pt_model_dict) - - # re-transform missing_keys to list - missing_keys = list(missing_keys) - - if len(unexpected_keys) > 0: - logger.warning( - "Some weights of the Flax model were not used when initializing the PyTorch model" - f" {pt_model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are initializing" - f" {pt_model.__class__.__name__} from a Flax model trained on another task or with another architecture" - " (e.g. initializing a BertForSequenceClassification model from a FlaxBertForPreTraining model).\n- This" - f" IS NOT expected if you are initializing {pt_model.__class__.__name__} from a Flax model that you expect" - " to be exactly identical (e.g. initializing a BertForSequenceClassification model from a" - " FlaxBertForSequenceClassification model)." - ) - else: - logger.warning(f"All Flax model weights were used when initializing {pt_model.__class__.__name__}.\n") - if len(missing_keys) > 0: - logger.warning( - f"Some weights of {pt_model.__class__.__name__} were not initialized from the Flax model and are newly" - f" initialized: {missing_keys}\nYou should probably TRAIN this model on a down-stream task to be able to" - " use it for predictions and inference." - ) - else: - logger.warning( - f"All the weights of {pt_model.__class__.__name__} were initialized from the Flax model.\n" - "If your task is similar to the task the model of the checkpoint was trained on, " - f"you can already use {pt_model.__class__.__name__} for predictions without further training." - ) - - return pt_model diff --git a/src/transformers/modeling_flax_utils.py b/src/transformers/modeling_flax_utils.py deleted file mode 100644 index bc9a4d473f36..000000000000 --- a/src/transformers/modeling_flax_utils.py +++ /dev/null @@ -1,1274 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Google Flax Team Authors and 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. - - -import gc -import json -import os -import warnings -from functools import partial -from pickle import UnpicklingError -from typing import Any, Optional, Union - -import flax.linen as nn -import jax -import jax.numpy as jnp -import msgpack.exceptions -from flax.core.frozen_dict import FrozenDict, unfreeze -from flax.serialization import from_bytes, to_bytes -from flax.traverse_util import flatten_dict, unflatten_dict -from jax.random import PRNGKey - -from .configuration_utils import PretrainedConfig -from .dynamic_module_utils import custom_object_save -from .generation import FlaxGenerationMixin, GenerationConfig -from .modeling_flax_pytorch_utils import load_pytorch_checkpoint_in_flax_state_dict -from .utils import ( - FLAX_WEIGHTS_INDEX_NAME, - FLAX_WEIGHTS_NAME, - SAFE_WEIGHTS_INDEX_NAME, - SAFE_WEIGHTS_NAME, - WEIGHTS_INDEX_NAME, - WEIGHTS_NAME, - PushToHubMixin, - add_code_sample_docstrings, - add_start_docstrings_to_model_forward, - cached_file, - copy_func, - download_url, - has_file, - is_offline_mode, - is_remote_url, - logging, - replace_return_docstrings, -) -from .utils.hub import convert_file_size_to_int, get_checkpoint_shard_files -from .utils.import_utils import is_safetensors_available - - -if is_safetensors_available(): - from safetensors import safe_open - from safetensors.flax import load_file as safe_load_file - from safetensors.flax import save_file as safe_save_file - -logger = logging.get_logger(__name__) - - -def quick_gelu(x): - return x * jax.nn.sigmoid(1.702 * x) - - -ACT2FN = { - "gelu": partial(nn.gelu, approximate=False), - "relu": nn.relu, - "silu": nn.swish, - "swish": nn.swish, - "gelu_new": partial(nn.gelu, approximate=True), - "quick_gelu": quick_gelu, - "gelu_pytorch_tanh": partial(nn.gelu, approximate=True), - "tanh": nn.tanh, -} - - -def flax_shard_checkpoint(params, max_shard_size="10GB"): - """ - Splits a model state dictionary in sub-checkpoints so that the final size of each sub-checkpoint does not exceed a - given size. The sub-checkpoints are determined by iterating through the `state_dict` in the order of its keys, so - there is no optimization made to make each sub-checkpoint as close as possible to the maximum size passed. For - example, if the limit is 10GB and we have weights of sizes [6GB, 6GB, 2GB, 6GB, 2GB, 2GB] they will get sharded as - [6GB], [6+2GB], [6+2+2GB] and not [6+2+2GB], [6+2GB], [6GB]. - - - - If one of the model's weight is bigger that `max_shard_size`, it will end up in its own sub-checkpoint which will - have a size greater than `max_shard_size`. - - - - Args: - params (`Union[Dict, FrozenDict]`): A `PyTree` of model parameters. - max_shard_size (`int` or `str`, *optional*, defaults to `"10GB"`): - The maximum size of each sub-checkpoint. If expressed as a string, needs to be digits followed by a unit - (like `"5MB"`). - """ - max_shard_size = convert_file_size_to_int(max_shard_size) - - sharded_state_dicts = [] - current_block = {} - current_block_size = 0 - total_size = 0 - - # flatten the weights to chunk - weights = flatten_dict(params, sep="/") - for item in weights: - weight_size = weights[item].size * weights[item].dtype.itemsize - - # If this weight is going to tip up over the maximal size, we split. - if current_block_size + weight_size > max_shard_size: - sharded_state_dicts.append(current_block) - current_block = {} - current_block_size = 0 - - current_block[item] = weights[item] - current_block_size += weight_size - total_size += weight_size - - # Add the last block - sharded_state_dicts.append(current_block) - - # If we only have one shard, we return it - if len(sharded_state_dicts) == 1: - return {FLAX_WEIGHTS_NAME: sharded_state_dicts[0]}, None - - # Otherwise, let's build the index - weight_map = {} - shards = {} - for idx, shard in enumerate(sharded_state_dicts): - shard_file = FLAX_WEIGHTS_NAME.replace(".msgpack", f"-{idx + 1:05d}-of-{len(sharded_state_dicts):05d}.msgpack") - shards[shard_file] = shard - for weight_name in shard: - weight_map[weight_name] = shard_file - - # Add the metadata - metadata = {"total_size": total_size} - index = {"metadata": metadata, "weight_map": weight_map} - return shards, index - - -class FlaxPreTrainedModel(PushToHubMixin, FlaxGenerationMixin): - r""" - Base class for all models. - - [`FlaxPreTrainedModel`] takes care of storing the configuration of the models and handles methods for loading, - downloading and saving models. - - Class attributes (overridden by derived classes): - - - **config_class** ([`PretrainedConfig`]) -- A subclass of [`PretrainedConfig`] to use as configuration class - for this model architecture. - - **base_model_prefix** (`str`) -- A string indicating the attribute associated to the base model in derived - classes of the same architecture adding modules on top of the base model. - - **main_input_name** (`str`) -- The name of the principal input to the model (often `input_ids` for NLP - models, `pixel_values` for vision models and `input_values` for speech models). - """ - - config_class = None - base_model_prefix = "" - main_input_name = "input_ids" - _auto_class = None - _missing_keys = set() - - def __init__( - self, - config: PretrainedConfig, - module: nn.Module, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - ): - logger.warning_once( - "TensorFlow and JAX classes are deprecated and will be removed in Transformers v5. We " - "recommend migrating to PyTorch classes or pinning your version of Transformers." - ) - if config is None: - raise ValueError("config cannot be None") - - if module is None: - raise ValueError("module cannot be None") - - # Those are private to be exposed as typed property on derived classes. - self._config = config - self._module = module - - # Those are public as their type is generic to every derived classes. - self.key = PRNGKey(seed) - self.dtype = dtype - self.input_shape = input_shape - self.generation_config = GenerationConfig.from_model_config(config) if self.can_generate() else None - - # To check if the model was initialized automatically. - self._is_initialized = _do_init - - if _do_init: - # randomly initialized parameters - random_params = self.init_weights(self.key, input_shape) - params_shape_tree = jax.eval_shape(lambda params: params, random_params) - else: - init_fn = partial(self.init_weights, input_shape=input_shape) - params_shape_tree = jax.eval_shape(init_fn, self.key) - - logger.info( - "Model weights are not initialized as `_do_init` is set to `False`. " - f"Make sure to call `{self.__class__.__name__}.init_weights` manually to initialize the weights." - ) - - # get the shape of the parameters - self._params_shape_tree = params_shape_tree - - # save required_params as set - self._required_params = set(flatten_dict(unfreeze(params_shape_tree)).keys()) - - # initialize the parameters - if _do_init: - self.params = random_params - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> dict: - raise NotImplementedError(f"init method has to be implemented for {self}") - - def enable_gradient_checkpointing(self): - raise NotImplementedError(f"gradient checkpointing method has to be implemented for {self}") - - @classmethod - def _from_config(cls, config, **kwargs): - """ - All context managers that the model should be initialized under go here. - """ - return cls(config, **kwargs) - - @property - def framework(self) -> str: - """ - :str: Identifies that this is a Flax model. - """ - return "flax" - - @property - def config(self) -> PretrainedConfig: - return self._config - - @property - def module(self) -> nn.Module: - return self._module - - @property - def params(self) -> Union[dict, FrozenDict]: - if not self._is_initialized: - raise ValueError( - "`params` cannot be accessed from model when the model is created with `_do_init=False`. " - "You must call `init_weights` manually and store the params outside of the model and " - "pass it explicitly where needed." - ) - return self._params - - @property - def required_params(self) -> set: - return self._required_params - - @property - def params_shape_tree(self) -> dict: - return self._params_shape_tree - - @params.setter - def params(self, params: Union[dict, FrozenDict]): - # don't set params if the model is not initialized - if not self._is_initialized: - raise ValueError( - "`params` cannot be set from model when the model is created with `_do_init=False`. " - "You store the params outside of the model." - ) - - if isinstance(params, FrozenDict): - params = unfreeze(params) - param_keys = set(flatten_dict(params).keys()) - if len(self.required_params - param_keys) > 0: - raise ValueError( - "Some parameters are missing. Make sure that `params` include the following " - f"parameters {self.required_params - param_keys}" - ) - self._params = params - - def _cast_floating_to(self, params: Union[dict, FrozenDict], dtype: jnp.dtype, mask: Any = None) -> Any: - """ - Helper method to cast floating-point values of given parameter `PyTree` to given `dtype`. - """ - - # taken from https://github.com/deepmind/jmp/blob/3a8318abc3292be38582794dbf7b094e6583b192/jmp/_src/policy.py#L27 - def conditional_cast(param): - if isinstance(param, jnp.ndarray) and jnp.issubdtype(param.dtype, jnp.floating): - param = param.astype(dtype) - return param - - if mask is None: - return jax.tree_util.tree_map(conditional_cast, params) - - flat_params = flatten_dict(params) - flat_mask, _ = jax.tree_util.tree_flatten(mask) - - for masked, key in zip(flat_mask, sorted(flat_params.keys())): - if masked: - flat_params[key] = conditional_cast(flat_params[key]) - - return unflatten_dict(flat_params) - - def to_bf16(self, params: Union[dict, FrozenDict], mask: Any = None): - r""" - Cast the floating-point `params` to `jax.numpy.bfloat16`. This returns a new `params` tree and does not cast - the `params` in place. - - This method can be used on TPU to explicitly convert the model parameters to bfloat16 precision to do full - half-precision training or to save weights in bfloat16 for inference in order to save memory and improve speed. - - Arguments: - params (`Union[Dict, FrozenDict]`): - A `PyTree` of model parameters. - mask (`Union[Dict, FrozenDict]`): - A `PyTree` with same structure as the `params` tree. The leaves should be booleans, `True` for params - you want to cast, and should be `False` for those you want to skip. - - Examples: - - ```python - >>> from transformers import FlaxBertModel - - >>> # load model - >>> model = FlaxBertModel.from_pretrained("google-bert/bert-base-cased") - >>> # By default, the model parameters will be in fp32 precision, to cast these to bfloat16 precision - >>> model.params = model.to_bf16(model.params) - >>> # If you want don't want to cast certain parameters (for example layer norm bias and scale) - >>> # then pass the mask as follows - >>> from flax import traverse_util - - >>> model = FlaxBertModel.from_pretrained("google-bert/bert-base-cased") - >>> flat_params = traverse_util.flatten_dict(model.params) - >>> mask = { - ... path: (path[-2] != ("LayerNorm", "bias") and path[-2:] != ("LayerNorm", "scale")) - ... for path in flat_params - ... } - >>> mask = traverse_util.unflatten_dict(mask) - >>> model.params = model.to_bf16(model.params, mask) - ```""" - return self._cast_floating_to(params, jnp.bfloat16, mask) - - def to_fp32(self, params: Union[dict, FrozenDict], mask: Any = None): - r""" - Cast the floating-point `params` to `jax.numpy.float32`. This method can be used to explicitly convert the - model parameters to fp32 precision. This returns a new `params` tree and does not cast the `params` in place. - - Arguments: - params (`Union[Dict, FrozenDict]`): - A `PyTree` of model parameters. - mask (`Union[Dict, FrozenDict]`): - A `PyTree` with same structure as the `params` tree. The leaves should be booleans, `True` for params - you want to cast, and should be `False` for those you want to skip - - Examples: - - ```python - >>> from transformers import FlaxBertModel - - >>> # Download model and configuration from huggingface.co - >>> model = FlaxBertModel.from_pretrained("google-bert/bert-base-cased") - >>> # By default, the model params will be in fp32, to illustrate the use of this method, - >>> # we'll first cast to fp16 and back to fp32 - >>> model.params = model.to_f16(model.params) - >>> # now cast back to fp32 - >>> model.params = model.to_fp32(model.params) - ```""" - return self._cast_floating_to(params, jnp.float32, mask) - - def to_fp16(self, params: Union[dict, FrozenDict], mask: Any = None): - r""" - Cast the floating-point `params` to `jax.numpy.float16`. This returns a new `params` tree and does not cast the - `params` in place. - - This method can be used on GPU to explicitly convert the model parameters to float16 precision to do full - half-precision training or to save weights in float16 for inference in order to save memory and improve speed. - - Arguments: - params (`Union[Dict, FrozenDict]`): - A `PyTree` of model parameters. - mask (`Union[Dict, FrozenDict]`): - A `PyTree` with same structure as the `params` tree. The leaves should be booleans, `True` for params - you want to cast, and should be `False` for those you want to skip - - Examples: - - ```python - >>> from transformers import FlaxBertModel - - >>> # load model - >>> model = FlaxBertModel.from_pretrained("google-bert/bert-base-cased") - >>> # By default, the model params will be in fp32, to cast these to float16 - >>> model.params = model.to_fp16(model.params) - >>> # If you want don't want to cast certain parameters (for example layer norm bias and scale) - >>> # then pass the mask as follows - >>> from flax import traverse_util - - >>> model = FlaxBertModel.from_pretrained("google-bert/bert-base-cased") - >>> flat_params = traverse_util.flatten_dict(model.params) - >>> mask = { - ... path: (path[-2] != ("LayerNorm", "bias") and path[-2:] != ("LayerNorm", "scale")) - ... for path in flat_params - ... } - >>> mask = traverse_util.unflatten_dict(mask) - >>> model.params = model.to_fp16(model.params, mask) - ```""" - return self._cast_floating_to(params, jnp.float16, mask) - - @classmethod - def load_flax_weights(cls, resolved_archive_file): - try: - if resolved_archive_file.endswith(".safetensors"): - state = safe_load_file(resolved_archive_file) - state = unflatten_dict(state, sep=".") - else: - with open(resolved_archive_file, "rb") as state_f: - state = from_bytes(cls, state_f.read()) - except (UnpicklingError, msgpack.exceptions.ExtraData) as e: - try: - with open(resolved_archive_file) as f: - if f.read().startswith("version"): - raise OSError( - "You seem to have cloned a repository without having git-lfs installed. Please" - " install git-lfs and run `git lfs install` followed by `git lfs pull` in the" - " folder you cloned." - ) - else: - raise ValueError from e - except (UnicodeDecodeError, ValueError): - raise OSError(f"Unable to convert {resolved_archive_file} to Flax deserializable object. ") - - return state - - @classmethod - def load_flax_sharded_weights(cls, shard_files): - """ - This is the same as [`flax.serialization.from_bytes`] - (https:lax.readthedocs.io/en/latest/_modules/flax/serialization.html#from_bytes) but for a sharded checkpoint. - - This load is performed efficiently: each checkpoint shard is loaded one by one in RAM and deleted after being - loaded in the model. - - Args: - shard_files (`list[str]`: - The list of shard files to load. - - Returns: - `Dict`: A nested dictionary of the model parameters, in the expected format for flax models : `{'model': - {'params': {'...'}}}`. - """ - - # Load the index - state_sharded_dict = {} - - for shard_file in shard_files: - # load using msgpack utils - try: - with open(shard_file, "rb") as state_f: - state = from_bytes(cls, state_f.read()) - except (UnpicklingError, msgpack.exceptions.ExtraData) as e: - with open(shard_file) as f: - if f.read().startswith("version"): - raise OSError( - "You seem to have cloned a repository without having git-lfs installed. Please" - " install git-lfs and run `git lfs install` followed by `git lfs pull` in the" - " folder you cloned." - ) - else: - raise ValueError from e - except (UnicodeDecodeError, ValueError): - raise OSError(f"Unable to convert {shard_file} to Flax deserializable object. ") - - state = flatten_dict(state, sep="/") - state_sharded_dict.update(state) - del state - gc.collect() - - # the state dict is unflattened to the match the format of model.params - return unflatten_dict(state_sharded_dict, sep="/") - - @classmethod - def can_generate(cls) -> bool: - """ - Returns whether this model can generate sequences with `.generate()`. Returns: - `bool`: Whether this model can generate sequences with `.generate()`. - """ - # Detects whether `prepare_inputs_for_generation` has been overwritten, which is a requirement for generation. - # Alternatively, the model can also have a custom `generate` function. - if "GenerationMixin" in str(cls.prepare_inputs_for_generation) and "GenerationMixin" in str(cls.generate): - return False - return True - - @classmethod - def from_pretrained( - cls, - pretrained_model_name_or_path: Union[str, os.PathLike], - dtype: jnp.dtype = jnp.float32, - *model_args, - config: Optional[Union[PretrainedConfig, str, os.PathLike]] = None, - cache_dir: Optional[Union[str, os.PathLike]] = None, - ignore_mismatched_sizes: bool = False, - force_download: bool = False, - local_files_only: bool = False, - token: Optional[Union[str, bool]] = None, - revision: str = "main", - **kwargs, - ): - r""" - Instantiate a pretrained flax model from a pre-trained model configuration. - - The warning *Weights from XXX not initialized from pretrained model* means that the weights of XXX do not come - pretrained with the rest of the model. It is up to you to train those weights with a downstream fine-tuning - task. - - The warning *Weights from XXX not used in YYY* means that the layer XXX is not used by YYY, therefore those - weights are discarded. - - Parameters: - pretrained_model_name_or_path (`str` or `os.PathLike`): - Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~FlaxPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *pt index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In this case, - `from_pt` should be set to `True`. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. - model_args (sequence of positional arguments, *optional*): - All remaining positional arguments will be passed to the underlying model's `__init__` method. - config (`Union[PretrainedConfig, str, os.PathLike]`, *optional*): - Can be either: - - - an instance of a class derived from [`PretrainedConfig`], - - a string or path valid as input to [`~PretrainedConfig.from_pretrained`]. - - Configuration for the model to use instead of an automatically loaded configuration. Configuration can - be automatically loaded when: - - - The model is a model provided by the library (loaded with the *model id* string of a pretrained - model). - - The model was saved using [`~PreTrainedModel.save_pretrained`] and is reloaded by supplying the - save directory. - - The model is loaded by supplying a local directory as `pretrained_model_name_or_path` and a - configuration JSON file named *config.json* is found in the directory. - cache_dir (`Union[str, os.PathLike]`, *optional*): - Path to a directory in which a downloaded pretrained model configuration should be cached if the - standard cache should not be used. - from_pt (`bool`, *optional*, defaults to `False`): - Load the model weights from a PyTorch checkpoint save file (see docstring of - `pretrained_model_name_or_path` argument). - ignore_mismatched_sizes (`bool`, *optional*, defaults to `False`): - Whether or not to raise an error if some of the weights from the checkpoint do not have the same size - as the weights of the model (if for instance, you are instantiating a model with 10 labels from a - checkpoint with 3 labels). - force_download (`bool`, *optional*, defaults to `False`): - Whether or not to force the (re-)download of the model weights and configuration files, overriding the - cached versions if they exist. - resume_download: - Deprecated and ignored. All downloads are now resumed by default when possible. - Will be removed in v5 of Transformers. - proxies (`dict[str, str]`, *optional*): - A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', - 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. - local_files_only(`bool`, *optional*, defaults to `False`): - Whether or not to only look at local files (i.e., do not try to download the model). - token (`str` or `bool`, *optional*): - The token to use as HTTP bearer authorization for remote files. If `True`, or not specified, will use - the token generated when running `hf auth login` (stored in `~/.huggingface`). - revision (`str`, *optional*, defaults to `"main"`): - The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a - git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any - identifier allowed by git. - - - - - To test a pull request you made on the Hub, you can pass `revision="refs/pr/"`. - - - - subfolder (`str`, *optional*, defaults to `""`): - In case the relevant files are located inside a subfolder of the model repo on huggingface.co, you can - specify the folder name here. - kwargs (remaining dictionary of keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). Behaves differently depending on whether a `config` is provided or - automatically loaded: - - - If a configuration is provided with `config`, `**kwargs` will be directly passed to the - underlying model's `__init__` method (we assume all relevant updates to the configuration have - already been done) - - If a configuration is not provided, `kwargs` will be first passed to the configuration class - initialization function ([`~PretrainedConfig.from_pretrained`]). Each key of `kwargs` that - corresponds to a configuration attribute will be used to override said attribute with the - supplied `kwargs` value. Remaining keys that do not correspond to any configuration attribute - will be passed to the underlying model's `__init__` function. - - Examples: - - ```python - >>> from transformers import BertConfig, FlaxBertModel - - >>> # Download model and configuration from huggingface.co and cache. - >>> model = FlaxBertModel.from_pretrained("google-bert/bert-base-cased") - >>> # Model was saved using *save_pretrained('./test/saved_model/')* (for example purposes, not runnable). - >>> model = FlaxBertModel.from_pretrained("./test/saved_model/") - >>> # Loading from a PyTorch checkpoint file instead of a PyTorch model (slower, for example purposes, not runnable). - >>> config = BertConfig.from_json_file("./pt_model/config.json") - >>> model = FlaxBertModel.from_pretrained("./pt_model/pytorch_model.bin", from_pt=True, config=config) - ```""" - from_pt = kwargs.pop("from_pt", False) - resume_download = kwargs.pop("resume_download", None) - proxies = kwargs.pop("proxies", None) - use_auth_token = kwargs.pop("use_auth_token", None) - trust_remote_code = kwargs.pop("trust_remote_code", None) - from_pipeline = kwargs.pop("_from_pipeline", None) - from_auto_class = kwargs.pop("_from_auto", False) - _do_init = kwargs.pop("_do_init", True) - subfolder = kwargs.pop("subfolder", "") - commit_hash = kwargs.pop("_commit_hash", None) - - # Not relevant for Flax Models - _ = kwargs.pop("adapter_kwargs", None) - - if use_auth_token is not None: - warnings.warn( - "The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.", - FutureWarning, - ) - if token is not None: - raise ValueError( - "`token` and `use_auth_token` are both specified. Please set only the argument `token`." - ) - token = use_auth_token - - if trust_remote_code is True: - logger.warning( - "The argument `trust_remote_code` is to be used with Auto classes. It has no effect here and is" - " ignored." - ) - - user_agent = {"file_type": "model", "framework": "flax", "from_auto_class": from_auto_class} - if from_pipeline is not None: - user_agent["using_pipeline"] = from_pipeline - - if is_offline_mode() and not local_files_only: - logger.info("Offline mode: forcing local_files_only=True") - local_files_only = True - - # Load config if we don't provide a configuration - if not isinstance(config, PretrainedConfig): - config_path = config if config is not None else pretrained_model_name_or_path - config, model_kwargs = cls.config_class.from_pretrained( - config_path, - cache_dir=cache_dir, - return_unused_kwargs=True, - force_download=force_download, - resume_download=resume_download, - proxies=proxies, - local_files_only=local_files_only, - token=token, - revision=revision, - subfolder=subfolder, - _from_auto=from_auto_class, - _from_pipeline=from_pipeline, - _commit_hash=commit_hash, - **kwargs, - ) - else: - model_kwargs = kwargs.copy() - - if commit_hash is None: - commit_hash = getattr(config, "_commit_hash", None) - - # Add the dtype to model_kwargs - model_kwargs["dtype"] = dtype - - # This variable will flag if we're loading a sharded checkpoint. In this case the archive file is just the - # index of the files. - is_sharded = False - - # Load model - if pretrained_model_name_or_path is not None: - pretrained_model_name_or_path = str(pretrained_model_name_or_path) - is_local = os.path.isdir(pretrained_model_name_or_path) - if is_local: - if os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_NAME)): - # Load from a Flax checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_NAME) - elif os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_INDEX_NAME)): - # Load from a sharded Flax checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_INDEX_NAME) - is_sharded = True - elif is_safetensors_available() and os.path.isfile( - os.path.join(pretrained_model_name_or_path, subfolder, SAFE_WEIGHTS_NAME) - ): - # Load from a safetensors checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, subfolder, SAFE_WEIGHTS_NAME) - elif is_safetensors_available() and os.path.isfile( - os.path.join(pretrained_model_name_or_path, SAFE_WEIGHTS_NAME) - ): - # Load from a safetensors checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, SAFE_WEIGHTS_NAME) - elif from_pt and os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, WEIGHTS_NAME)): - # Load from a PyTorch checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, subfolder, WEIGHTS_NAME) - elif from_pt and os.path.isfile( - os.path.join(pretrained_model_name_or_path, subfolder, WEIGHTS_INDEX_NAME) - ): - # Load from a sharded pytorch checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, subfolder, WEIGHTS_INDEX_NAME) - is_sharded = True - # At this stage we don't have a weight file so we will raise an error. - elif is_safetensors_available() and os.path.isfile( - os.path.join(pretrained_model_name_or_path, SAFE_WEIGHTS_INDEX_NAME) - ): - # Load from a sharded safetensors checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, SAFE_WEIGHTS_INDEX_NAME) - is_sharded = True - raise NotImplementedError("Support for sharded checkpoints using safetensors is coming soon!") - elif os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, WEIGHTS_NAME)): - raise OSError( - f"Error no file named {FLAX_WEIGHTS_NAME} found in directory {pretrained_model_name_or_path} " - "but there is a file for PyTorch weights. Use `from_pt=True` to load this model from those " - "weights." - ) - else: - raise OSError( - f"Error no file named {FLAX_WEIGHTS_NAME} or {WEIGHTS_NAME} found in directory " - f"{pretrained_model_name_or_path}." - ) - elif os.path.isfile(os.path.join(subfolder, pretrained_model_name_or_path)): - archive_file = pretrained_model_name_or_path - is_local = True - elif is_remote_url(pretrained_model_name_or_path): - filename = pretrained_model_name_or_path - resolved_archive_file = download_url(pretrained_model_name_or_path) - else: - if from_pt: - filename = WEIGHTS_NAME - else: - filename = FLAX_WEIGHTS_NAME - - try: - # Load from URL or cache if already cached - cached_file_kwargs = { - "cache_dir": cache_dir, - "force_download": force_download, - "proxies": proxies, - "resume_download": resume_download, - "local_files_only": local_files_only, - "token": token, - "user_agent": user_agent, - "revision": revision, - "subfolder": subfolder, - "_raise_exceptions_for_gated_repo": False, - "_raise_exceptions_for_missing_entries": False, - "_commit_hash": commit_hash, - } - resolved_archive_file = cached_file(pretrained_model_name_or_path, filename, **cached_file_kwargs) - - # Maybe the checkpoint is sharded, we try to grab the index name in this case. - if resolved_archive_file is None and filename == FLAX_WEIGHTS_NAME: - resolved_archive_file = cached_file( - pretrained_model_name_or_path, FLAX_WEIGHTS_INDEX_NAME, **cached_file_kwargs - ) - if resolved_archive_file is not None: - is_sharded = True - - # Maybe the checkpoint is pytorch sharded, we try to grab the pytorch index name in this case. - if resolved_archive_file is None and from_pt: - resolved_archive_file = cached_file( - pretrained_model_name_or_path, WEIGHTS_INDEX_NAME, **cached_file_kwargs - ) - if resolved_archive_file is not None: - is_sharded = True - - # If we still haven't found anything, look for `safetensors`. - if resolved_archive_file is None: - # No support for sharded safetensors yet, so we'll raise an error if that's all we find. - filename = SAFE_WEIGHTS_NAME - resolved_archive_file = cached_file( - pretrained_model_name_or_path, SAFE_WEIGHTS_NAME, **cached_file_kwargs - ) - - # Since we set _raise_exceptions_for_missing_entries=False, we don't get an exception but a None - # result when internet is up, the repo and revision exist, but the file does not. - if resolved_archive_file is None: - # Otherwise, maybe there is a TF or Torch model file. We try those to give a helpful error - # message. - has_file_kwargs = { - "revision": revision, - "proxies": proxies, - "token": token, - "cache_dir": cache_dir, - "local_files_only": local_files_only, - } - if has_file(pretrained_model_name_or_path, SAFE_WEIGHTS_INDEX_NAME, **has_file_kwargs): - is_sharded = True - raise NotImplementedError( - "Support for sharded checkpoints using safetensors is coming soon!" - ) - elif has_file(pretrained_model_name_or_path, WEIGHTS_NAME, **has_file_kwargs): - raise OSError( - f"{pretrained_model_name_or_path} does not appear to have a file named" - f" {FLAX_WEIGHTS_NAME} but there is a file for PyTorch weights. Use `from_pt=True` to" - " load this model from those weights." - ) - elif has_file(pretrained_model_name_or_path, WEIGHTS_INDEX_NAME, **has_file_kwargs): - raise OSError( - f"{pretrained_model_name_or_path} does not appear to have a file named" - f" {FLAX_WEIGHTS_INDEX_NAME} but there is a sharded file for PyTorch weights. Use" - " `from_pt=True` to load this model from those weights." - ) - else: - raise OSError( - f"{pretrained_model_name_or_path} does not appear to have a file named" - f" {FLAX_WEIGHTS_NAME} or {WEIGHTS_NAME}." - ) - except OSError: - # Raise any environment error raise by `cached_file`. It will have a helpful error message adapted - # to the original exception. - raise - except Exception: - # For any other exception, we throw a generic error. - raise OSError( - f"Can't load the model for '{pretrained_model_name_or_path}'. If you were trying to load it" - " from 'https://huggingface.co/models', make sure you don't have a local directory with the" - f" same name. Otherwise, make sure '{pretrained_model_name_or_path}' is the correct path to a" - f" directory containing a file named {FLAX_WEIGHTS_NAME} or {WEIGHTS_NAME}." - ) - - if is_local: - logger.info(f"loading weights file {archive_file}") - resolved_archive_file = archive_file - filename = resolved_archive_file.split(os.path.sep)[-1] - else: - logger.info(f"loading weights file {filename} from cache at {resolved_archive_file}") - else: - resolved_archive_file = None - - # We'll need to download and cache each checkpoint shard if the checkpoint is sharded. - if is_sharded: - # resolved_archive_file becomes a list of files that point to the different checkpoint shards in this case. - resolved_archive_file, _ = get_checkpoint_shard_files( - pretrained_model_name_or_path, - resolved_archive_file, - cache_dir=cache_dir, - force_download=force_download, - proxies=proxies, - resume_download=resume_download, - local_files_only=local_files_only, - token=token, - user_agent=user_agent, - revision=revision, - subfolder=subfolder, - _commit_hash=commit_hash, - ) - - safetensors_from_pt = False - if filename == SAFE_WEIGHTS_NAME: - with safe_open(resolved_archive_file, framework="flax") as f: - safetensors_metadata = f.metadata() - if safetensors_metadata is None or safetensors_metadata.get("format") not in ["pt", "tf", "flax"]: - raise OSError( - f"The safetensors archive passed at {resolved_archive_file} does not contain the valid metadata." - " Make sure you save your model with the `save_pretrained` method." - ) - safetensors_from_pt = safetensors_metadata.get("format") == "pt" - - # init random models - model = cls(config, *model_args, _do_init=_do_init, **model_kwargs) - - if from_pt or safetensors_from_pt: - state = load_pytorch_checkpoint_in_flax_state_dict(model, resolved_archive_file, is_sharded) - else: - if is_sharded: - state = cls.load_flax_sharded_weights(resolved_archive_file) - else: - state = cls.load_flax_weights(resolved_archive_file) - # make sure all arrays are stored as jnp.arrays - # NOTE: This is to prevent a bug this will be fixed in Flax >= v0.3.4: - # https://github.com/google/flax/issues/1261 - if _do_init: - state = jax.tree_util.tree_map(jnp.array, state) - else: - # keep the params on CPU if we don't want to initialize - state = jax.tree_util.tree_map(lambda x: jax.device_put(x, jax.local_devices(backend="cpu")[0]), state) - - if "batch_stats" in state: # if flax model contains batch norm layers - # if model is base model only use model_prefix key - if ( - cls.base_model_prefix not in dict(model.params_shape_tree["params"]) - and cls.base_model_prefix in state["params"] - ): - state["params"] = state["params"][cls.base_model_prefix] - state["batch_stats"] = state["batch_stats"][cls.base_model_prefix] - - # if model is head model and we are loading weights from base model - # we initialize new params dict with base_model_prefix - if ( - cls.base_model_prefix in dict(model.params_shape_tree["params"]) - and cls.base_model_prefix not in state["params"] - ): - state = { - "params": {cls.base_model_prefix: state["params"]}, - "batch_stats": {cls.base_model_prefix: state["batch_stats"]}, - } - - else: - # if model is base model only use model_prefix key - if cls.base_model_prefix not in dict(model.params_shape_tree) and cls.base_model_prefix in state: - state = state[cls.base_model_prefix] - - # if model is head model and we are loading weights from base model - # we initialize new params dict with base_model_prefix - if cls.base_model_prefix in dict(model.params_shape_tree) and cls.base_model_prefix not in state: - state = {cls.base_model_prefix: state} - - # flatten dicts - state = flatten_dict(state) - - random_state = flatten_dict(unfreeze(model.params if _do_init else model.params_shape_tree)) - - missing_keys = model.required_params - set(state.keys()) - unexpected_keys = set(state.keys()) - model.required_params - - # Disabling warning when porting pytorch weights to flax, flax does not uses num_batches_tracked - for unexpected_key in unexpected_keys.copy(): - if "num_batches_tracked" in unexpected_key[-1]: - unexpected_keys.remove(unexpected_key) - - if missing_keys and not _do_init: - logger.warning( - f"The checkpoint {pretrained_model_name_or_path} is missing required keys: {missing_keys}. " - "Make sure to call model.init_weights to initialize the missing weights." - ) - cls._missing_keys = missing_keys - - # Mismatched keys contains tuples key/shape1/shape2 of weights in the checkpoint that have a shape not - # matching the weights in the model. - mismatched_keys = [] - for key in state: - if key in random_state and state[key].shape != random_state[key].shape: - if ignore_mismatched_sizes: - mismatched_keys.append((key, state[key].shape, random_state[key].shape)) - state[key] = random_state[key] - else: - raise ValueError( - f"Trying to load the pretrained weight for {key} failed: checkpoint has shape " - f"{state[key].shape} which is incompatible with the model shape {random_state[key].shape}. " - "Using `ignore_mismatched_sizes=True` if you really want to load this checkpoint inside this " - "model." - ) - - # add missing keys as random parameters if we are initializing - if missing_keys and _do_init: - for missing_key in missing_keys: - state[missing_key] = random_state[missing_key] - - # remove unexpected keys to not be saved again - for unexpected_key in unexpected_keys: - del state[unexpected_key] - - if len(unexpected_keys) > 0: - logger.warning( - f"Some weights of the model checkpoint at {pretrained_model_name_or_path} were not used when" - f" initializing {model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are" - f" initializing {model.__class__.__name__} from the checkpoint of a model trained on another task or" - " with another architecture (e.g. initializing a BertForSequenceClassification model from a" - " BertForPreTraining model).\n- This IS NOT expected if you are initializing" - f" {model.__class__.__name__} from the checkpoint of a model that you expect to be exactly identical" - " (initializing a BertForSequenceClassification model from a BertForSequenceClassification model)." - ) - else: - logger.info(f"All model checkpoint weights were used when initializing {model.__class__.__name__}.\n") - - if len(missing_keys) > 0: - logger.warning( - f"Some weights of {model.__class__.__name__} were not initialized from the model checkpoint at" - f" {pretrained_model_name_or_path} and are newly initialized: {missing_keys}\nYou should probably" - " TRAIN this model on a down-stream task to be able to use it for predictions and inference." - ) - elif len(mismatched_keys) == 0: - logger.info( - f"All the weights of {model.__class__.__name__} were initialized from the model checkpoint at" - f" {pretrained_model_name_or_path}.\nIf your task is similar to the task the model of the checkpoint" - f" was trained on, you can already use {model.__class__.__name__} for predictions without further" - " training." - ) - if len(mismatched_keys) > 0: - mismatched_warning = "\n".join( - [ - f"- {key}: found shape {shape1} in the checkpoint and {shape2} in the model instantiated" - for key, shape1, shape2 in mismatched_keys - ] - ) - logger.warning( - f"Some weights of {model.__class__.__name__} were not initialized from the model checkpoint at" - f" {pretrained_model_name_or_path} and are newly initialized because the shapes did not" - f" match:\n{mismatched_warning}\nYou should probably TRAIN this model on a down-stream task to be able" - " to use it for predictions and inference." - ) - - # dictionary of key: dtypes for the model params - param_dtypes = jax.tree_util.tree_map(lambda x: x.dtype, state) - # extract keys of parameters not in jnp.float32 - fp16_params = [k for k in param_dtypes if param_dtypes[k] == jnp.float16] - bf16_params = [k for k in param_dtypes if param_dtypes[k] == jnp.bfloat16] - - # raise a warning if any of the parameters are not in jnp.float32 - if len(fp16_params) > 0: - logger.warning( - f"Some of the weights of {model.__class__.__name__} were initialized in float16 precision from " - f"the model checkpoint at {pretrained_model_name_or_path}:\n{fp16_params}\n" - "You should probably UPCAST the model weights to float32 if this was not intended. " - "See [`~FlaxPreTrainedModel.to_fp32`] for further information on how to do this." - ) - - if len(bf16_params) > 0: - logger.warning( - f"Some of the weights of {model.__class__.__name__} were initialized in bfloat16 precision from " - f"the model checkpoint at {pretrained_model_name_or_path}:\n{bf16_params}\n" - "You should probably UPCAST the model weights to float32 if this was not intended. " - "See [`~FlaxPreTrainedModel.to_fp32`] for further information on how to do this." - ) - - # If it is a model with generation capabilities, attempt to load the generation config - if model.can_generate(): - try: - model.generation_config = GenerationConfig.from_pretrained( - pretrained_model_name_or_path, - cache_dir=cache_dir, - force_download=force_download, - resume_download=resume_download, - proxies=proxies, - local_files_only=local_files_only, - token=token, - revision=revision, - subfolder=subfolder, - _from_auto=from_auto_class, - _from_pipeline=from_pipeline, - **kwargs, - ) - except OSError: - logger.info( - "Generation config file not found, using a generation config created from the model config." - ) - pass - - if _do_init: - # set correct parameters - model.params = unflatten_dict(state) - return model - else: - return model, unflatten_dict(state) - - def save_pretrained( - self, - save_directory: Union[str, os.PathLike], - params=None, - push_to_hub=False, - max_shard_size="10GB", - token: Optional[Union[str, bool]] = None, - safe_serialization: bool = False, - **kwargs, - ): - """ - Save a model and its configuration file to a directory, so that it can be re-loaded using the - `[`~FlaxPreTrainedModel.from_pretrained`]` class method - - Arguments: - save_directory (`str` or `os.PathLike`): - Directory to which to save. Will be created if it doesn't exist. - push_to_hub (`bool`, *optional*, defaults to `False`): - Whether or not to push your model to the Hugging Face model hub after saving it. You can specify the - repository you want to push to with `repo_id` (will default to the name of `save_directory` in your - namespace). - max_shard_size (`int` or `str`, *optional*, defaults to `"10GB"`): - The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size - lower than this size. If expressed as a string, needs to be digits followed by a unit (like `"5MB"`). - - - - If a single weight of the model is bigger than `max_shard_size`, it will be in its own checkpoint shard - which will be bigger than `max_shard_size`. - - - - token (`str` or `bool`, *optional*): - The token to use as HTTP bearer authorization for remote files. If `True`, or not specified, will use - the token generated when running `hf auth login` (stored in `~/.huggingface`). - kwargs (`dict[str, Any]`, *optional*): - Additional key word arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method. - safe_serialization (`bool`, *optional*, defaults to `False`): - Whether to save the model using `safetensors` or through msgpack. - """ - use_auth_token = kwargs.pop("use_auth_token", None) - - if use_auth_token is not None: - warnings.warn( - "The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.", - FutureWarning, - ) - if token is not None: - raise ValueError( - "`token` and `use_auth_token` are both specified. Please set only the argument `token`." - ) - token = use_auth_token - - if token is not None: - kwargs["token"] = token - - if os.path.isfile(save_directory): - logger.error(f"Provided path ({save_directory}) should be a directory, not a file") - return - - os.makedirs(save_directory, exist_ok=True) - - if push_to_hub: - commit_message = kwargs.pop("commit_message", None) - repo_id = kwargs.pop("repo_id", save_directory.split(os.path.sep)[-1]) - repo_id = self._create_repo(repo_id, **kwargs) - files_timestamps = self._get_files_timestamps(save_directory) - - # get abs dir - save_directory = os.path.abspath(save_directory) - # save config as well - self.config.architectures = [self.__class__.__name__[4:]] - - # If we have a custom model, we copy the file defining it in the folder and set the attributes so it can be - # loaded from the Hub. - if self._auto_class is not None: - custom_object_save(self, save_directory, config=self.config) - - self.config.save_pretrained(save_directory) - if self.can_generate(): - self.generation_config.save_pretrained(save_directory) - - # save model - weights_name = SAFE_WEIGHTS_NAME if safe_serialization else FLAX_WEIGHTS_NAME - output_model_file = os.path.join(save_directory, weights_name) - - shards, index = flax_shard_checkpoint(params if params is not None else self.params, max_shard_size) - # Clean the folder from a previous save - for filename in os.listdir(save_directory): - full_filename = os.path.join(save_directory, filename) - weights_no_suffix = weights_name.replace(".bin", "").replace(".safetensors", "") - if filename.startswith(weights_no_suffix) and os.path.isfile(full_filename) and filename not in shards: - os.remove(full_filename) - - if index is None: - if safe_serialization: - params = params if params is not None else self.params - flat_dict = flatten_dict(params, sep=".") - safe_save_file(flat_dict, output_model_file, metadata={"format": "flax"}) - else: - with open(output_model_file, "wb") as f: - params = params if params is not None else self.params - model_bytes = to_bytes(params) - f.write(model_bytes) - - else: - save_index_file = os.path.join(save_directory, FLAX_WEIGHTS_INDEX_NAME) - # Save the index as well - with open(save_index_file, "w", encoding="utf-8") as f: - content = json.dumps(index, indent=2, sort_keys=True) + "\n" - f.write(content) - logger.info( - f"The model is bigger than the maximum size per checkpoint ({max_shard_size}) and is going to be " - f"split in {len(shards)} checkpoint shards. You can find where each parameters has been saved in the " - f"index located at {save_index_file}." - ) - for shard_file, shard in shards.items(): - # the shard item are unflattened, to save them we need to flatten them again - with open(os.path.join(save_directory, shard_file), mode="wb") as f: - params = unflatten_dict(shard, sep="/") - shard_bytes = to_bytes(params) - f.write(shard_bytes) - - logger.info(f"Model weights saved in {output_model_file}") - - if push_to_hub: - self._upload_modified_files( - save_directory, - repo_id, - files_timestamps, - commit_message=commit_message, - token=token, - ) - - @classmethod - def register_for_auto_class(cls, auto_class="FlaxAutoModel"): - """ - Register this class with a given auto class. This should only be used for custom models as the ones in the - library are already mapped with an auto class. - - - - Args: - auto_class (`str` or `type`, *optional*, defaults to `"FlaxAutoModel"`): - The auto class to register this new model with. - """ - if not isinstance(auto_class, str): - auto_class = auto_class.__name__ - - import transformers.models.auto as auto_module - - if not hasattr(auto_module, auto_class): - raise ValueError(f"{auto_class} is not a valid auto class.") - - cls._auto_class = auto_class - - -# To update the docstring, we need to copy the method, otherwise we change the original docstring. -FlaxPreTrainedModel.push_to_hub = copy_func(FlaxPreTrainedModel.push_to_hub) -if FlaxPreTrainedModel.push_to_hub.__doc__ is not None: - FlaxPreTrainedModel.push_to_hub.__doc__ = FlaxPreTrainedModel.push_to_hub.__doc__.format( - object="model", object_class="FlaxAutoModel", object_files="model checkpoint" - ) - - -def overwrite_call_docstring(model_class, docstring): - # copy __call__ function to be sure docstring is changed only for this function - model_class.__call__ = copy_func(model_class.__call__) - # delete existing docstring - model_class.__call__.__doc__ = None - # set correct docstring - model_class.__call__ = add_start_docstrings_to_model_forward(docstring)(model_class.__call__) - - -def append_call_sample_docstring( - model_class, checkpoint, output_type, config_class, mask=None, revision=None, real_checkpoint=None -): - model_class.__call__ = copy_func(model_class.__call__) - model_class.__call__ = add_code_sample_docstrings( - checkpoint=checkpoint, - output_type=output_type, - config_class=config_class, - model_cls=model_class.__name__, - revision=revision, - real_checkpoint=real_checkpoint, - )(model_class.__call__) - - -def append_replace_return_docstrings(model_class, output_type, config_class): - model_class.__call__ = copy_func(model_class.__call__) - model_class.__call__ = replace_return_docstrings( - output_type=output_type, - config_class=config_class, - )(model_class.__call__) diff --git a/src/transformers/modeling_tf_outputs.py b/src/transformers/modeling_tf_outputs.py deleted file mode 100644 index c7491b67f9ae..000000000000 --- a/src/transformers/modeling_tf_outputs.py +++ /dev/null @@ -1,990 +0,0 @@ -# Copyright 2020 The HuggingFace Team. All rights reserved. -# -# 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. - -from __future__ import annotations - -import warnings -from dataclasses import dataclass - -import tensorflow as tf - -from .utils import ModelOutput - - -@dataclass -class TFBaseModelOutput(ModelOutput): - """ - Base class for model's outputs, with potential hidden states and attentions. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFBaseModelOutputWithNoAttention(ModelOutput): - """ - Base class for model's outputs, with potential hidden states. - - Args: - last_hidden_state (`tf.Tensor` shape `(batch_size, num_channels, height, width)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each layer) of shape `(batch_size, num_channels, height, width)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - """ - - last_hidden_state: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFBaseModelOutputWithPooling(ModelOutput): - """ - Base class for model's outputs that also contains a pooling of the last hidden states. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - pooler_output (`tf.Tensor` of shape `(batch_size, hidden_size)`): - Last layer hidden-state of the first token of the sequence (classification token) further processed by a - Linear layer and a Tanh activation function. The Linear layer weights are trained from the next sentence - prediction (classification) objective during pretraining. - - This output is usually *not* a good summary of the semantic content of the input, you're often better with - averaging or pooling the sequence of hidden-states for the whole input sequence. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: tf.Tensor | None = None - pooler_output: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFBaseModelOutputWithPoolingAndNoAttention(ModelOutput): - """ - Base class for model's outputs that also contains a pooling of the last hidden states. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Sequence of hidden-states at the output of the last layer of the model. - pooler_output (`tf.Tensor` of shape `(batch_size, hidden_size)`): - Last layer hidden-state after a pooling operation on the spatial dimensions. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each layer) of shape `(batch_size, num_channels, height, width)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - """ - - last_hidden_state: tf.Tensor | None = None - pooler_output: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFBaseModelOutputWithPoolingAndCrossAttentions(ModelOutput): - """ - Base class for model's outputs that also contains a pooling of the last hidden states. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - pooler_output (`tf.Tensor` of shape `(batch_size, hidden_size)`): - Last layer hidden-state of the first token of the sequence (classification token) further processed by a - Linear layer and a Tanh activation function. The Linear layer weights are trained from the next sentence - prediction (classification) objective during pretraining. - - This output is usually *not* a good summary of the semantic content of the input, you're often better with - averaging or pooling the sequence of hidden-states for the whole input sequence. - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - cross_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - """ - - last_hidden_state: tf.Tensor | None = None - pooler_output: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - cross_attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFBaseModelOutputWithPast(ModelOutput): - """ - Base class for model's outputs that may also contain a past key/values (to speed up sequential decoding). - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - - If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, - hidden_size)` is output. - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFBaseModelOutputWithCrossAttentions(ModelOutput): - """ - Base class for model's outputs, with potential hidden states and attentions. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - cross_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - """ - - last_hidden_state: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - cross_attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFBaseModelOutputWithPastAndCrossAttentions(ModelOutput): - """ - Base class for model's outputs that may also contain a past key/values (to speed up sequential decoding). - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - - If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, - hidden_size)` is output. - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. - hidden_states (`tuple(tf.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - cross_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - """ - - last_hidden_state: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - cross_attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFSeq2SeqModelOutput(ModelOutput): - """ - Base class for model encoder's outputs that also contains : pre-computed hidden states that can speed up sequential - decoding. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the decoder of the model. - - If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, - hidden_size)` is output. - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be - used (see `past_key_values` input) to speed up sequential decoding. - decoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the decoder at the output of each layer plus the initial embedding outputs. - decoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - cross_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - encoder_last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder of the model. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - """ - - last_hidden_state: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - decoder_hidden_states: tuple[tf.Tensor] | None = None - decoder_attentions: tuple[tf.Tensor] | None = None - cross_attentions: tuple[tf.Tensor] | None = None - encoder_last_hidden_state: tf.Tensor | None = None - encoder_hidden_states: tuple[tf.Tensor] | None = None - encoder_attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFCausalLMOutput(ModelOutput): - """ - Base class for causal language model (or autoregressive) outputs. - - Args: - loss (`tf.Tensor` of shape `(n,)`, *optional*, where n is the number of non-masked labels, returned when `labels` is provided): - Language modeling loss (for next-token prediction). - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFCausalLMOutputWithPast(ModelOutput): - """ - Base class for causal language model (or autoregressive) outputs. - - Args: - loss (`tf.Tensor` of shape `(n,)`, *optional*, where n is the number of non-masked labels, returned when `labels` is provided): - Language modeling loss (for next-token prediction). - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFCausalLMOutputWithCrossAttentions(ModelOutput): - """ - Base class for causal language model (or autoregressive) outputs. - - Args: - loss (`tf.Tensor` of shape `(n,)`, *optional*, where n is the number of non-masked labels, returned when `labels` is provided): - Language modeling loss (for next-token prediction). - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - cross_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - cross_attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFMaskedLMOutput(ModelOutput): - """ - Base class for masked language models outputs. - - Args: - loss (`tf.Tensor` of shape `(n,)`, *optional*, where n is the number of non-masked labels, returned when `labels` is provided): - Masked language modeling (MLM) loss. - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFSeq2SeqLMOutput(ModelOutput): - """ - Base class for sequence-to-sequence language models outputs. - - Args: - loss (`tf.Tensor` of shape `(n,)`, *optional*, where n is the number of non-masked labels, returned when `labels` is provided): - Language modeling loss. - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be - used (see `past_key_values` input) to speed up sequential decoding. - decoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the decoder at the output of each layer plus the initial embedding outputs. - decoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - cross_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - encoder_last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder of the model. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - decoder_hidden_states: tuple[tf.Tensor] | None = None - decoder_attentions: tuple[tf.Tensor] | None = None - cross_attentions: tuple[tf.Tensor] | None = None - encoder_last_hidden_state: tf.Tensor | None = None - encoder_hidden_states: tuple[tf.Tensor] | None = None - encoder_attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFNextSentencePredictorOutput(ModelOutput): - """ - Base class for outputs of models predicting if two sentences are consecutive or not. - - Args: - loss (`tf.Tensor` of shape `(n,)`, *optional*, where n is the number of non-masked labels, returned when `next_sentence_label` is provided): - Next sentence prediction loss. - logits (`tf.Tensor` of shape `(batch_size, 2)`): - Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation - before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFSequenceClassifierOutput(ModelOutput): - """ - Base class for outputs of sentence classification models. - - Args: - loss (`tf.Tensor` of shape `(batch_size, )`, *optional*, returned when `labels` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFSeq2SeqSequenceClassifierOutput(ModelOutput): - """ - Base class for outputs of sequence-to-sequence sentence classification models. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `label` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be - used (see `past_key_values` input) to speed up sequential decoding. - decoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the decoder at the output of each layer plus the initial embedding outputs. - decoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - cross_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)` - encoder_last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder of the model. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - decoder_hidden_states: tuple[tf.Tensor] | None = None - decoder_attentions: tuple[tf.Tensor] | None = None - cross_attentions: tuple[tf.Tensor] | None = None - encoder_last_hidden_state: tf.Tensor | None = None - encoder_hidden_states: tuple[tf.Tensor] | None = None - encoder_attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFSemanticSegmenterOutput(ModelOutput): - """ - Base class for outputs of semantic segmentation models. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels, logits_height, logits_width)`): - Classification scores for each pixel. - - - - The logits returned do not necessarily have the same size as the `pixel_values` passed as inputs. This is - to avoid doing two interpolations and lose some quality when a user needs to resize the logits to the - original image size as post-processing. You should always check your logits shape and resize as needed. - - - - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each layer) of shape `(batch_size, patch_size, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, patch_size, sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFSemanticSegmenterOutputWithNoAttention(ModelOutput): - """ - Base class for outputs of semantic segmentation models that do not output attention scores. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels, logits_height, logits_width)`): - Classification scores for each pixel. - - - - The logits returned do not necessarily have the same size as the `pixel_values` passed as inputs. This is - to avoid doing two interpolations and lose some quality when a user needs to resize the logits to the - original image size as post-processing. You should always check your logits shape and resize as needed. - - - - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each layer) of shape `(batch_size, patch_size, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - - -@dataclass -class TFImageClassifierOutput(ModelOutput): - """ - Base class for outputs of image classification models. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each stage) of shape `(batch_size, sequence_length, hidden_size)`. Hidden-states (also called - feature maps) of the model at the output of each stage. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, patch_size, sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFMultipleChoiceModelOutput(ModelOutput): - """ - Base class for outputs of multiple choice models. - - Args: - loss (`tf.Tensor` of shape *(batch_size, )*, *optional*, returned when `labels` is provided): - Classification loss. - logits (`tf.Tensor` of shape `(batch_size, num_choices)`): - *num_choices* is the second dimension of the input tensors. (see *input_ids* above). - - Classification scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFTokenClassifierOutput(ModelOutput): - """ - Base class for outputs of token classification models. - - Args: - loss (`tf.Tensor` of shape `(n,)`, *optional*, where n is the number of unmasked labels, returned when `labels` is provided) : - Classification loss. - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.num_labels)`): - Classification scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFQuestionAnsweringModelOutput(ModelOutput): - """ - Base class for outputs of question answering models. - - Args: - loss (`tf.Tensor` of shape `(batch_size, )`, *optional*, returned when `start_positions` and `end_positions` are provided): - Total span extraction loss is the sum of a Cross-Entropy for the start and end positions. - start_logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Span-start scores (before SoftMax). - end_logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Span-end scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - start_logits: tf.Tensor | None = None - end_logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFSeq2SeqQuestionAnsweringModelOutput(ModelOutput): - """ - Base class for outputs of sequence-to-sequence question answering models. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Total span extraction loss is the sum of a Cross-Entropy for the start and end positions. - start_logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Span-start scores (before SoftMax). - end_logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Span-end scores (before SoftMax). - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be - used (see `past_key_values` input) to speed up sequential decoding. - decoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the decoder at the output of each layer plus the initial embedding outputs. - decoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - encoder_last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder of the model. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - """ - - loss: tf.Tensor | None = None - start_logits: tf.Tensor | None = None - end_logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - decoder_hidden_states: tuple[tf.Tensor] | None = None - decoder_attentions: tuple[tf.Tensor] | None = None - encoder_last_hidden_state: tf.Tensor | None = None - encoder_hidden_states: tuple[tf.Tensor] | None = None - encoder_attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFSequenceClassifierOutputWithPast(ModelOutput): - """ - Base class for outputs of sentence classification models. - - Args: - loss (`tf.Tensor` of shape `(batch_size, )`, *optional*, returned when `labels` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFImageClassifierOutputWithNoAttention(ModelOutput): - """ - Base class for outputs of image classification models. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each stage) of shape `(batch_size, num_channels, height, width)`. Hidden-states (also called - feature maps) of the model at the output of each stage. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFMaskedImageModelingOutput(ModelOutput): - """ - Base class for outputs of masked image completion / in-painting models. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `bool_masked_pos` is provided): - Reconstruction loss. - reconstruction (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Reconstructed / completed images. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when - `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each stage) of shape `(batch_size, sequence_length, hidden_size)`. Hidden-states (also called - feature maps) of the model at the output of each stage. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when - `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, patch_size, sequence_length)`. - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - reconstruction: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - @property - def logits(self): - warnings.warn( - "logits attribute is deprecated and will be removed in version 5 of Transformers." - " Please use the reconstruction attribute to retrieve the final output instead.", - FutureWarning, - ) - return self.reconstruction diff --git a/src/transformers/modeling_tf_pytorch_utils.py b/src/transformers/modeling_tf_pytorch_utils.py deleted file mode 100644 index 8f688af7be36..000000000000 --- a/src/transformers/modeling_tf_pytorch_utils.py +++ /dev/null @@ -1,676 +0,0 @@ -# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""PyTorch - TF 2.0 general utilities.""" - -import os -import re - -import numpy - -from .utils import ( - ExplicitEnum, - check_torch_load_is_safe, - expand_dims, - is_numpy_array, - is_safetensors_available, - is_torch_tensor, - logging, - reshape, - squeeze, - tensor_size, -) -from .utils import transpose as transpose_func - - -if is_safetensors_available(): - from safetensors import safe_open - - -logger = logging.get_logger(__name__) - - -class TransposeType(ExplicitEnum): - """ - Possible ... - """ - - NO = "no" - SIMPLE = "simple" - CONV1D = "conv1d" - CONV2D = "conv2d" - - -def convert_tf_weight_name_to_pt_weight_name( - tf_name, start_prefix_to_remove="", tf_weight_shape=None, name_scope=None -): - """ - Convert a TF 2.0 model variable name in a pytorch model weight name. - - Conventions for TF2.0 scopes -> PyTorch attribute names conversions: - - - '$1___$2' is replaced by $2 (can be used to duplicate or remove layers in TF2.0 vs PyTorch) - - '_._' is replaced by a new level separation (can be used to convert TF2.0 lists in PyTorch nn.ModulesList) - - return tuple with: - - - pytorch model weight name - - transpose: `TransposeType` member indicating whether and how TF2.0 and PyTorch weights matrices should be - transposed with regards to each other - """ - if name_scope is not None: - if not tf_name.startswith(name_scope) and "final_logits_bias" not in tf_name: - raise ValueError( - f"Weight name {tf_name} does not start with name_scope {name_scope}. This is an internal error " - "in Transformers, so (unless you were doing something really evil) please open an issue to report it!" - ) - tf_name = tf_name[len(name_scope) :] - tf_name = tf_name.lstrip("/") - tf_name = tf_name.replace(":0", "") # device ids - if (len(tf_name) > 2048 and "___" in tf_name) or tf_name.count("___") > 10: - # ReDOS check - raise ValueError("TF variable name is too long or contains too many ___ separators: " + tf_name) - tf_name = re.sub( - r"/[^/]*___([^/]*)/", r"/\1/", tf_name - ) # '$1___$2' is replaced by $2 (can be used to duplicate or remove layers in TF2.0 vs PyTorch) - tf_name = tf_name.replace( - "_._", "/" - ) # '_._' is replaced by a level separation (can be used to convert TF2.0 lists in PyTorch nn.ModulesList) - tf_name = re.sub(r"//+", "/", tf_name) # Remove empty levels at the end - tf_name = tf_name.split("/") # Convert from TF2.0 '/' separators to PyTorch '.' separators - # Some weights have a single name without "/" such as final_logits_bias in BART - if len(tf_name) > 1: - tf_name = tf_name[1:] # Remove level zero - - tf_weight_shape = list(tf_weight_shape) - - # When should we transpose the weights - if tf_name[-1] == "kernel" and tf_weight_shape is not None and len(tf_weight_shape) == 4: - transpose = TransposeType.CONV2D - elif tf_name[-1] == "kernel" and tf_weight_shape is not None and len(tf_weight_shape) == 3: - transpose = TransposeType.CONV1D - elif bool( - tf_name[-1] in ["kernel", "pointwise_kernel", "depthwise_kernel"] - or "emb_projs" in tf_name - or "out_projs" in tf_name - ): - transpose = TransposeType.SIMPLE - else: - transpose = TransposeType.NO - - # Convert standard TF2.0 names in PyTorch names - if tf_name[-1] == "kernel" or tf_name[-1] == "embeddings" or tf_name[-1] == "gamma": - tf_name[-1] = "weight" - if tf_name[-1] == "beta": - tf_name[-1] = "bias" - - # The SeparableConv1D TF layer contains two weights that are translated to PyTorch Conv1D here - if tf_name[-1] == "pointwise_kernel" or tf_name[-1] == "depthwise_kernel": - tf_name[-1] = tf_name[-1].replace("_kernel", ".weight") - - # Remove prefix if needed - tf_name = ".".join(tf_name) - if start_prefix_to_remove: - tf_name = tf_name.replace(start_prefix_to_remove, "", 1) - - return tf_name, transpose - - -def apply_transpose(transpose: TransposeType, weight, match_shape=None, pt_to_tf=True): - """ - Apply a transpose to some weight then tries to reshape the weight to the same shape as a given shape, all in a - framework agnostic way. - """ - if transpose is TransposeType.CONV2D: - # Conv2D weight: - # PT: (num_out_channel, num_in_channel, kernel[0], kernel[1]) - # -> TF: (kernel[0], kernel[1], num_in_channel, num_out_channel) - axes = (2, 3, 1, 0) if pt_to_tf else (3, 2, 0, 1) - weight = transpose_func(weight, axes=axes) - elif transpose is TransposeType.CONV1D: - # Conv1D weight: - # PT: (num_out_channel, num_in_channel, kernel) - # -> TF: (kernel, num_in_channel, num_out_channel) - weight = transpose_func(weight, axes=(2, 1, 0)) - elif transpose is TransposeType.SIMPLE: - weight = transpose_func(weight) - - if match_shape is None: - return weight - - if len(match_shape) < len(weight.shape): - weight = squeeze(weight) - elif len(match_shape) > len(weight.shape): - weight = expand_dims(weight, axis=0) - - if list(match_shape) != list(weight.shape): - try: - weight = reshape(weight, match_shape) - except AssertionError as e: - e.args += (match_shape, match_shape) - raise e - - return weight - - -##################### -# PyTorch => TF 2.0 # -##################### - - -def load_pytorch_checkpoint_in_tf2_model( - tf_model, - pytorch_checkpoint_path, - tf_inputs=None, - allow_missing_keys=False, - output_loading_info=False, - _prefix=None, - tf_to_pt_weight_rename=None, -): - """Load pytorch checkpoints in a TF 2.0 model""" - try: - import tensorflow as tf # noqa: F401 - import torch # noqa: F401 - from safetensors.torch import load_file as safe_load_file # noqa: F401 - except ImportError: - logger.error( - "Loading a PyTorch model in TensorFlow, requires both PyTorch and TensorFlow to be installed. Please see " - "https://pytorch.org/ and https://www.tensorflow.org/install/ for installation instructions." - ) - raise - - # Treats a single file as a collection of shards with 1 shard. - if isinstance(pytorch_checkpoint_path, str): - pytorch_checkpoint_path = [pytorch_checkpoint_path] - - # Loads all shards into a single state dictionary - pt_state_dict = {} - for path in pytorch_checkpoint_path: - pt_path = os.path.abspath(path) - logger.info(f"Loading PyTorch weights from {pt_path}") - if pt_path.endswith(".safetensors"): - state_dict = safe_load_file(pt_path) - else: - check_torch_load_is_safe() - state_dict = torch.load(pt_path, map_location="cpu", weights_only=True) - - pt_state_dict.update(state_dict) - - logger.info(f"PyTorch checkpoint contains {sum(t.numel() for t in pt_state_dict.values()):,} parameters") - - return load_pytorch_weights_in_tf2_model( - tf_model, - pt_state_dict, - tf_inputs=tf_inputs, - allow_missing_keys=allow_missing_keys, - output_loading_info=output_loading_info, - _prefix=_prefix, - tf_to_pt_weight_rename=tf_to_pt_weight_rename, - ) - - -def load_pytorch_model_in_tf2_model(tf_model, pt_model, tf_inputs=None, allow_missing_keys=False): - """Load pytorch checkpoints in a TF 2.0 model""" - pt_state_dict = pt_model.state_dict() - - return load_pytorch_weights_in_tf2_model( - tf_model, pt_state_dict, tf_inputs=tf_inputs, allow_missing_keys=allow_missing_keys - ) - - -def load_pytorch_weights_in_tf2_model( - tf_model, - pt_state_dict, - tf_inputs=None, - allow_missing_keys=False, - output_loading_info=False, - _prefix=None, - tf_to_pt_weight_rename=None, -): - """Load pytorch state_dict in a TF 2.0 model.""" - try: - import tensorflow as tf # noqa: F401 - import torch # noqa: F401 - except ImportError: - logger.error( - "Loading a PyTorch model in TensorFlow, requires both PyTorch and TensorFlow to be installed. Please see " - "https://pytorch.org/ and https://www.tensorflow.org/install/ for installation instructions." - ) - raise - - # Numpy doesn't understand bfloat16, so upcast to a dtype that doesn't lose precision - pt_state_dict = { - k: v.numpy() if v.dtype != torch.bfloat16 else v.float().numpy() for k, v in pt_state_dict.items() - } - return load_pytorch_state_dict_in_tf2_model( - tf_model, - pt_state_dict, - tf_inputs=tf_inputs, - allow_missing_keys=allow_missing_keys, - output_loading_info=output_loading_info, - _prefix=_prefix, - tf_to_pt_weight_rename=tf_to_pt_weight_rename, - ) - - -def _log_key_warnings(missing_keys, unexpected_keys, mismatched_keys, class_name): - if len(unexpected_keys) > 0: - logger.warning( - "Some weights of the PyTorch model were not used when initializing the TF 2.0 model" - f" {class_name}: {unexpected_keys}\n- This IS expected if you are initializing" - f" {class_name} from a PyTorch model trained on another task or with another architecture" - " (e.g. initializing a TFBertForSequenceClassification model from a BertForPreTraining model).\n- This IS" - f" NOT expected if you are initializing {class_name} from a PyTorch model that you expect" - " to be exactly identical (e.g. initializing a TFBertForSequenceClassification model from a" - " BertForSequenceClassification model)." - ) - else: - logger.warning(f"All PyTorch model weights were used when initializing {class_name}.\n") - if len(missing_keys) > 0: - logger.warning( - f"Some weights or buffers of the TF 2.0 model {class_name} were not initialized from the" - f" PyTorch model and are newly initialized: {missing_keys}\nYou should probably TRAIN this model on a" - " down-stream task to be able to use it for predictions and inference." - ) - else: - logger.warning( - f"All the weights of {class_name} were initialized from the PyTorch model.\n" - "If your task is similar to the task the model of the checkpoint was trained on, " - f"you can already use {class_name} for predictions without further training." - ) - - if len(mismatched_keys) > 0: - mismatched_warning = "\n".join( - [ - f"- {key}: found shape {shape1} in the checkpoint and {shape2} in the model instantiated" - for key, shape1, shape2 in mismatched_keys - ] - ) - logger.warning( - f"Some weights of {class_name} were not initialized from the model checkpoint" - f" are newly initialized because the shapes did not" - f" match:\n{mismatched_warning}\nYou should probably TRAIN this model on a down-stream task to be able" - " to use it for predictions and inference." - ) - - -def load_pytorch_state_dict_in_tf2_model( - tf_model, - pt_state_dict, - tf_inputs=None, - allow_missing_keys=False, - output_loading_info=False, - _prefix=None, - tf_to_pt_weight_rename=None, - ignore_mismatched_sizes=False, - skip_logger_warnings=False, -): - """Load a pytorch state_dict in a TF 2.0 model. pt_state_dict can be either an actual dict or a lazy-loading - safetensors archive created with the safe_open() function.""" - import tensorflow as tf - - if tf_inputs is None: - tf_inputs = tf_model.dummy_inputs - - if _prefix is None: - _prefix = "" - if tf_inputs: - with tf.name_scope(_prefix): - tf_model(tf_inputs, training=False) # Make sure model is built - # Convert old format to new format if needed from a PyTorch state_dict - tf_keys_to_pt_keys = {} - for key in pt_state_dict: - new_key = None - if "gamma" in key: - new_key = key.replace("gamma", "weight") - if "beta" in key: - new_key = key.replace("beta", "bias") - if "running_var" in key: - new_key = key.replace("running_var", "moving_variance") - if "running_mean" in key: - new_key = key.replace("running_mean", "moving_mean") - - # New `weight_norm` from https://github.com/huggingface/transformers/pull/24030 - key_components = key.split(".") - name = None - if key_components[-3::2] == ["parametrizations", "original0"]: - name = key_components[-2] + "_g" - elif key_components[-3::2] == ["parametrizations", "original1"]: - name = key_components[-2] + "_v" - if name is not None: - key_components = key_components[:-3] + [name] - new_key = ".".join(key_components) - - if new_key is None: - new_key = key - tf_keys_to_pt_keys[new_key] = key - - # Matt: All TF models store the actual model stem in a MainLayer class, including the base model. - # In PT, the derived models (with heads) use the base model class as the stem instead, - # and there is no MainLayer class. This means that TF base classes have one - # extra layer in their weight names, corresponding to the MainLayer class. This code block compensates for that. - start_prefix_to_remove = "" - if not any(s.startswith(tf_model.base_model_prefix) for s in tf_keys_to_pt_keys): - start_prefix_to_remove = tf_model.base_model_prefix + "." - - symbolic_weights = tf_model.trainable_weights + tf_model.non_trainable_weights - tf_loaded_numel = 0 - all_pytorch_weights = set(tf_keys_to_pt_keys.keys()) - missing_keys = [] - mismatched_keys = [] - is_safetensor_archive = hasattr(pt_state_dict, "get_tensor") - for symbolic_weight in symbolic_weights: - sw_name = symbolic_weight.name - name, transpose = convert_tf_weight_name_to_pt_weight_name( - sw_name, - start_prefix_to_remove=start_prefix_to_remove, - tf_weight_shape=symbolic_weight.shape, - name_scope=_prefix, - ) - if tf_to_pt_weight_rename is not None: - aliases = tf_to_pt_weight_rename(name) # Is a tuple to account for possible name aliasing - for alias in aliases: # The aliases are in priority order, take the first one that matches - if alias in tf_keys_to_pt_keys: - name = alias - break - else: - # If none of the aliases match, just use the first one (it'll be reported as missing) - name = aliases[0] - - # Find associated numpy array in pytorch model state dict - if name not in tf_keys_to_pt_keys: - if allow_missing_keys: - missing_keys.append(name) - continue - elif tf_model._keys_to_ignore_on_load_missing is not None: - # authorized missing keys don't have to be loaded - if any(re.search(pat, name) is not None for pat in tf_model._keys_to_ignore_on_load_missing): - continue - raise AttributeError(f"{name} not found in PyTorch model") - state_dict_name = tf_keys_to_pt_keys[name] - if is_safetensor_archive: - array = pt_state_dict.get_tensor(state_dict_name) - else: - array = pt_state_dict[state_dict_name] - try: - array = apply_transpose(transpose, array, symbolic_weight.shape) - except tf.errors.InvalidArgumentError as e: - if not ignore_mismatched_sizes: - error_msg = str(e) - error_msg += ( - "\n\tYou may consider adding `ignore_mismatched_sizes=True` in the model `from_pretrained` method." - ) - raise tf.errors.InvalidArgumentError(error_msg) - else: - mismatched_keys.append((name, array.shape, symbolic_weight.shape)) - continue - - tf_loaded_numel += tensor_size(array) - - symbolic_weight.assign(tf.cast(array, symbolic_weight.dtype)) - del array # Immediately free memory to keep peak usage as low as possible - all_pytorch_weights.discard(name) - - logger.info(f"Loaded {tf_loaded_numel:,} parameters in the TF 2.0 model.") - - unexpected_keys = list(all_pytorch_weights) - - if tf_model._keys_to_ignore_on_load_missing is not None: - for pat in tf_model._keys_to_ignore_on_load_missing: - missing_keys = [k for k in missing_keys if re.search(pat, k) is None] - if tf_model._keys_to_ignore_on_load_unexpected is not None: - for pat in tf_model._keys_to_ignore_on_load_unexpected: - unexpected_keys = [k for k in unexpected_keys if re.search(pat, k) is None] - if not skip_logger_warnings: - _log_key_warnings(missing_keys, unexpected_keys, mismatched_keys, class_name=tf_model.__class__.__name__) - - if output_loading_info: - loading_info = { - "missing_keys": missing_keys, - "unexpected_keys": unexpected_keys, - "mismatched_keys": mismatched_keys, - } - return tf_model, loading_info - - return tf_model - - -def load_sharded_pytorch_safetensors_in_tf2_model( - tf_model, - safetensors_shards, - tf_inputs=None, - allow_missing_keys=False, - output_loading_info=False, - _prefix=None, - tf_to_pt_weight_rename=None, - ignore_mismatched_sizes=False, -): - all_loading_infos = [] - for shard in safetensors_shards: - with safe_open(shard, framework="tf") as safetensors_archive: - tf_model, loading_info = load_pytorch_state_dict_in_tf2_model( - tf_model, - safetensors_archive, - tf_inputs=tf_inputs, - allow_missing_keys=allow_missing_keys, - output_loading_info=True, - _prefix=_prefix, - tf_to_pt_weight_rename=tf_to_pt_weight_rename, - ignore_mismatched_sizes=ignore_mismatched_sizes, - skip_logger_warnings=True, # We will emit merged warnings at the end - ) - all_loading_infos.append(loading_info) - # Now we just need to merge the loading info - # Keys are missing only if they're missing in *every* shard - missing_keys = sorted(set.intersection(*[set(info["missing_keys"]) for info in all_loading_infos])) - # Keys are unexpected/mismatched if they're unexpected/mismatched in *any* shard - unexpected_keys = sum([info["unexpected_keys"] for info in all_loading_infos], []) - mismatched_keys = sum([info["mismatched_keys"] for info in all_loading_infos], []) - - _log_key_warnings(missing_keys, unexpected_keys, mismatched_keys, class_name=tf_model.__class__.__name__) - - if output_loading_info: - loading_info = { - "missing_keys": missing_keys, - "unexpected_keys": unexpected_keys, - "mismatched_keys": mismatched_keys, - } - return tf_model, loading_info - - return tf_model - - -##################### -# TF 2.0 => PyTorch # -##################### - - -def load_tf2_checkpoint_in_pytorch_model( - pt_model, tf_checkpoint_path, tf_inputs=None, allow_missing_keys=False, output_loading_info=False -): - """ - Load TF 2.0 HDF5 checkpoint in a PyTorch model We use HDF5 to easily do transfer learning (see - https://github.com/tensorflow/tensorflow/blob/ee16fcac960ae660e0e4496658a366e2f745e1f0/tensorflow/python/keras/engine/network.py#L1352-L1357). - """ - try: - import tensorflow as tf # noqa: F401 - import torch # noqa: F401 - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires both PyTorch and TensorFlow to be installed. Please see " - "https://pytorch.org/ and https://www.tensorflow.org/install/ for installation instructions." - ) - raise - - import transformers - - from .modeling_tf_utils import load_tf_weights - - logger.info(f"Loading TensorFlow weights from {tf_checkpoint_path}") - - # Instantiate and load the associated TF 2.0 model - tf_model_class_name = "TF" + pt_model.__class__.__name__ # Add "TF" at the beginning - tf_model_class = getattr(transformers, tf_model_class_name) - tf_model = tf_model_class(pt_model.config) - - if tf_inputs is None: - tf_inputs = tf_model.dummy_inputs - - if tf_inputs is not None: - tf_model(tf_inputs, training=False) # Make sure model is built - - load_tf_weights(tf_model, tf_checkpoint_path) - - return load_tf2_model_in_pytorch_model( - pt_model, tf_model, allow_missing_keys=allow_missing_keys, output_loading_info=output_loading_info - ) - - -def load_tf2_model_in_pytorch_model(pt_model, tf_model, allow_missing_keys=False, output_loading_info=False): - """Load TF 2.0 model in a pytorch model""" - weights = tf_model.weights - - return load_tf2_weights_in_pytorch_model( - pt_model, weights, allow_missing_keys=allow_missing_keys, output_loading_info=output_loading_info - ) - - -def load_tf2_weights_in_pytorch_model(pt_model, tf_weights, allow_missing_keys=False, output_loading_info=False): - """Load TF2.0 symbolic weights in a PyTorch model""" - try: - import tensorflow as tf # noqa: F401 - import torch # noqa: F401 - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires both PyTorch and TensorFlow to be installed. Please see " - "https://pytorch.org/ and https://www.tensorflow.org/install/ for installation instructions." - ) - raise - - tf_state_dict = {tf_weight.name: tf_weight.numpy() for tf_weight in tf_weights} - return load_tf2_state_dict_in_pytorch_model( - pt_model, tf_state_dict, allow_missing_keys=allow_missing_keys, output_loading_info=output_loading_info - ) - - -def load_tf2_state_dict_in_pytorch_model(pt_model, tf_state_dict, allow_missing_keys=False, output_loading_info=False): - import torch - - new_pt_params_dict = {} - current_pt_params_dict = dict(pt_model.named_parameters()) - - # Make sure we are able to load PyTorch base models as well as derived models (with heads) - # TF models always have a prefix, some of PyTorch models (base ones) don't - start_prefix_to_remove = "" - if not any(s.startswith(pt_model.base_model_prefix) for s in current_pt_params_dict): - start_prefix_to_remove = pt_model.base_model_prefix + "." - - # Build a map from potential PyTorch weight names to TF 2.0 Variables - tf_weights_map = {} - for name, tf_weight in tf_state_dict.items(): - pt_name, transpose = convert_tf_weight_name_to_pt_weight_name( - name, start_prefix_to_remove=start_prefix_to_remove, tf_weight_shape=tf_weight.shape - ) - tf_weights_map[pt_name] = (tf_weight, transpose) - - all_tf_weights = set(tf_weights_map.keys()) - loaded_pt_weights_data_ptr = {} - missing_keys_pt = [] - for pt_weight_name, pt_weight in current_pt_params_dict.items(): - # Handle PyTorch shared weight not duplicated in TF 2.0 - if pt_weight.data_ptr() in loaded_pt_weights_data_ptr and pt_weight.data_ptr() != 0: - new_pt_params_dict[pt_weight_name] = loaded_pt_weights_data_ptr[pt_weight.data_ptr()] - continue - - pt_weight_name_to_check = pt_weight_name - # New `weight_norm` from https://github.com/huggingface/transformers/pull/24030 - key_components = pt_weight_name.split(".") - name = None - if key_components[-3::2] == ["parametrizations", "original0"]: - name = key_components[-2] + "_g" - elif key_components[-3::2] == ["parametrizations", "original1"]: - name = key_components[-2] + "_v" - if name is not None: - key_components = key_components[:-3] + [name] - pt_weight_name_to_check = ".".join(key_components) - - # Find associated numpy array in pytorch model state dict - if pt_weight_name_to_check not in tf_weights_map: - if allow_missing_keys: - missing_keys_pt.append(pt_weight_name) - continue - - raise AttributeError(f"{pt_weight_name} not found in TF 2.0 model") - - array, transpose = tf_weights_map[pt_weight_name_to_check] - - array = apply_transpose(transpose, array, pt_weight.shape, pt_to_tf=False) - - if numpy.isscalar(array): - array = numpy.array(array) - if not is_torch_tensor(array) and not is_numpy_array(array): - array = array.numpy() - if is_numpy_array(array): - # Convert to torch tensor - array = torch.from_numpy(array) - - new_pt_params_dict[pt_weight_name] = array - loaded_pt_weights_data_ptr[pt_weight.data_ptr()] = array - all_tf_weights.discard(pt_weight_name) - - missing_keys, unexpected_keys = pt_model.load_state_dict(new_pt_params_dict, strict=False) - missing_keys += missing_keys_pt - - # Some models may have keys that are not in the state by design, removing them before needlessly warning - # the user. - if pt_model._keys_to_ignore_on_load_missing is not None: - for pat in pt_model._keys_to_ignore_on_load_missing: - missing_keys = [k for k in missing_keys if re.search(pat, k) is None] - - if pt_model._keys_to_ignore_on_load_unexpected is not None: - for pat in pt_model._keys_to_ignore_on_load_unexpected: - unexpected_keys = [k for k in unexpected_keys if re.search(pat, k) is None] - - if len(unexpected_keys) > 0: - logger.warning( - "Some weights of the TF 2.0 model were not used when initializing the PyTorch model" - f" {pt_model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are initializing" - f" {pt_model.__class__.__name__} from a TF 2.0 model trained on another task or with another architecture" - " (e.g. initializing a BertForSequenceClassification model from a TFBertForPreTraining model).\n- This IS" - f" NOT expected if you are initializing {pt_model.__class__.__name__} from a TF 2.0 model that you expect" - " to be exactly identical (e.g. initializing a BertForSequenceClassification model from a" - " TFBertForSequenceClassification model)." - ) - else: - logger.warning(f"All TF 2.0 model weights were used when initializing {pt_model.__class__.__name__}.\n") - if len(missing_keys) > 0: - logger.warning( - f"Some weights of {pt_model.__class__.__name__} were not initialized from the TF 2.0 model and are newly" - f" initialized: {missing_keys}\nYou should probably TRAIN this model on a down-stream task to be able to" - " use it for predictions and inference." - ) - else: - logger.warning( - f"All the weights of {pt_model.__class__.__name__} were initialized from the TF 2.0 model.\n" - "If your task is similar to the task the model of the checkpoint was trained on, " - f"you can already use {pt_model.__class__.__name__} for predictions without further training." - ) - - logger.info(f"Weights or buffers not loaded from TF 2.0 model: {all_tf_weights}") - - if output_loading_info: - loading_info = {"missing_keys": missing_keys, "unexpected_keys": unexpected_keys} - return pt_model, loading_info - - return pt_model diff --git a/src/transformers/modeling_tf_utils.py b/src/transformers/modeling_tf_utils.py deleted file mode 100644 index c7bb80656d1b..000000000000 --- a/src/transformers/modeling_tf_utils.py +++ /dev/null @@ -1,3529 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF general model utils.""" - -from __future__ import annotations - -import functools -import gc -import inspect -import json -import os -import pickle -import re -import warnings -from collections.abc import Mapping -from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Union - -import h5py -import numpy as np -import tensorflow as tf -from packaging.version import parse - -from . import DataCollatorWithPadding, DefaultDataCollator -from .activations_tf import get_tf_activation -from .configuration_utils import PretrainedConfig -from .dynamic_module_utils import custom_object_save -from .generation import GenerationConfig, TFGenerationMixin -from .tf_utils import ( - convert_batch_encoding, - expand_1d, - load_attributes_from_hdf5_group, - save_attributes_to_hdf5_group, - shape_list, -) -from .utils import ( - SAFE_WEIGHTS_INDEX_NAME, - SAFE_WEIGHTS_NAME, - TF2_WEIGHTS_INDEX_NAME, - TF2_WEIGHTS_NAME, - TF_WEIGHTS_NAME, - WEIGHTS_INDEX_NAME, - WEIGHTS_NAME, - ModelOutput, - PushToHubMixin, - cached_file, - download_url, - find_labels, - has_file, - is_offline_mode, - is_remote_url, - is_safetensors_available, - is_tf_symbolic_tensor, - logging, - requires_backends, - working_or_temp_dir, -) -from .utils.hub import convert_file_size_to_int, get_checkpoint_shard_files - - -if is_safetensors_available(): - from safetensors import safe_open - from safetensors.tensorflow import save_file as safe_save_file - -if TYPE_CHECKING: - from . import PreTrainedTokenizerBase - -logger = logging.get_logger(__name__) - -if "TF_USE_LEGACY_KERAS" not in os.environ: - os.environ["TF_USE_LEGACY_KERAS"] = "1" # Compatibility fix to make sure tf.keras stays at Keras 2 -elif os.environ["TF_USE_LEGACY_KERAS"] != "1": - logger.warning( - "Transformers is only compatible with Keras 2, but you have explicitly set `TF_USE_LEGACY_KERAS` to `0`. " - "This may result in unexpected behaviour or errors if Keras 3 objects are passed to Transformers models." - ) - -try: - import tf_keras as keras - from tf_keras import backend as K -except (ModuleNotFoundError, ImportError): - import keras - from keras import backend as K - - if parse(keras.__version__).major > 2: - raise ValueError( - "Your currently installed version of Keras is Keras 3, but this is not yet supported in " - "Transformers. Please install the backwards-compatible tf-keras package with " - "`pip install tf-keras`." - ) - - -tf_logger = tf.get_logger() - -TFModelInputType = Union[ - list[tf.Tensor], - list[np.ndarray], - dict[str, tf.Tensor], - dict[str, np.ndarray], - tf.Tensor, - np.ndarray, -] - - -def dummy_loss(y_true, y_pred): - if y_pred.shape.rank <= 1: - return y_pred - else: - reduction_axes = list(range(1, y_pred.shape.rank)) - return tf.reduce_mean(y_pred, axis=reduction_axes) - - -class TFModelUtilsMixin: - """ - A few utilities for `keras.Model`, to be used as a mixin. - """ - - def num_parameters(self, only_trainable: bool = False) -> int: - """ - Get the number of (optionally, trainable) parameters in the model. - - Args: - only_trainable (`bool`, *optional*, defaults to `False`): - Whether or not to return only the number of trainable parameters - - Returns: - `int`: The number of parameters. - """ - if only_trainable: - return int(sum(np.prod(w.shape.as_list()) for w in self.trainable_variables)) - else: - return self.count_params() - - -def keras_serializable(cls): - """ - Decorate a Keras Layer class to support Keras serialization. - - This is done by: - - 1. Adding a `transformers_config` dict to the Keras config dictionary in `get_config` (called by Keras at - serialization time. - 2. Wrapping `__init__` to accept that `transformers_config` dict (passed by Keras at deserialization time) and - convert it to a config object for the actual layer initializer. - 3. Registering the class as a custom object in Keras (if the Tensorflow version supports this), so that it does not - need to be supplied in `custom_objects` in the call to `keras.models.load_model`. - - Args: - cls (a `keras.layers.Layers subclass`): - Typically a `TF.MainLayer` class in this project, in general must accept a `config` argument to its - initializer. - - Returns: - The same class object, with modifications for Keras deserialization. - """ - initializer = cls.__init__ - - config_class = getattr(cls, "config_class", None) - if config_class is None: - raise AttributeError("Must set `config_class` to use @keras_serializable") - - @functools.wraps(initializer) - def wrapped_init(self, *args, **kwargs): - config = args[0] if args and isinstance(args[0], PretrainedConfig) else kwargs.pop("config", None) - - if isinstance(config, dict): - config = config_class.from_dict(config) - initializer(self, config, *args, **kwargs) - elif isinstance(config, PretrainedConfig): - if len(args) > 0: - initializer(self, *args, **kwargs) - else: - initializer(self, config, *args, **kwargs) - else: - raise TypeError("Must pass either `config` (PretrainedConfig) or `config` (dict)") - - self._config = config - self._kwargs = kwargs - - cls.__init__ = wrapped_init - - if not hasattr(cls, "get_config"): - raise TypeError("Only use @keras_serializable on keras.layers.Layer subclasses") - if hasattr(cls.get_config, "_is_default"): - - def get_config(self): - cfg = super(cls, self).get_config() - cfg["config"] = self._config.to_dict() - cfg.update(self._kwargs) - return cfg - - cls.get_config = get_config - - cls._keras_serializable = True - if hasattr(keras.utils, "register_keras_serializable"): - cls = keras.utils.register_keras_serializable()(cls) - return cls - - -class TFCausalLanguageModelingLoss: - """ - Loss function suitable for causal language modeling (CLM), that is, the task of guessing the next token. - - - - Any label of -100 will be ignored (along with the corresponding logits) in the loss computation. - - - """ - - def hf_compute_loss(self, labels, logits): - loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=keras.losses.Reduction.NONE) - if self.config.tf_legacy_loss: - # make sure only labels that are not equal to -100 affect the loss - active_loss = tf.not_equal(tf.reshape(labels, (-1,)), -100) - reduced_logits = tf.boolean_mask(tf.reshape(logits, (-1, shape_list(logits)[2])), active_loss) - labels = tf.boolean_mask(tf.reshape(labels, (-1,)), active_loss) - return loss_fn(labels, reduced_logits) - - # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway - unmasked_loss = loss_fn(tf.nn.relu(labels), logits) - # make sure only labels that are not equal to -100 affect the loss - loss_mask = tf.cast(labels != -100, dtype=unmasked_loss.dtype) - masked_loss = unmasked_loss * loss_mask - reduced_masked_loss = tf.reduce_sum(masked_loss) / tf.reduce_sum(loss_mask) - return tf.reshape(reduced_masked_loss, (1,)) - - -class TFQuestionAnsweringLoss: - """ - Loss function suitable for question answering. - """ - - def hf_compute_loss(self, labels, logits): - loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=keras.losses.Reduction.NONE) - start_loss = loss_fn(labels["start_position"], logits[0]) - end_loss = loss_fn(labels["end_position"], logits[1]) - - return (start_loss + end_loss) / 2.0 - - -class TFTokenClassificationLoss: - """ - Loss function suitable for token classification. - - - - Any label of -100 will be ignored (along with the corresponding logits) in the loss computation. - - - """ - - def hf_compute_loss(self, labels, logits): - loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=keras.losses.Reduction.NONE) - if tf.executing_eagerly(): # Data-dependent conditionals are forbidden in XLA - if tf.math.reduce_any(labels == -1): - tf.print("Using `-1` to mask the loss for the token is deprecated. Please use `-100` instead.") - - if self.config.tf_legacy_loss: - # make sure only labels that are not equal to -100 - # are taken into account as loss - if tf.math.reduce_any(labels == -1): - tf.print("Using `-1` to mask the loss for the token is deprecated. Please use `-100` instead.") - active_loss = tf.reshape(labels, (-1,)) != -1 - else: - active_loss = tf.reshape(labels, (-1,)) != -100 - reduced_logits = tf.boolean_mask(tf.reshape(logits, (-1, shape_list(logits)[2])), active_loss) - labels = tf.boolean_mask(tf.reshape(labels, (-1,)), active_loss) - - return loss_fn(labels, reduced_logits) - - # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway - unmasked_loss = loss_fn(tf.nn.relu(labels), logits) - # make sure only labels that are not equal to -100 or -1 - # are taken into account as loss - loss_mask = tf.cast(labels >= 0, dtype=unmasked_loss.dtype) - # Avoid possible division by zero later - # Masked positions will have a loss of NaN because -100 and -1 are not valid labels - masked_loss = unmasked_loss * loss_mask - reduced_masked_loss = tf.reduce_sum(masked_loss) / tf.reduce_sum(loss_mask) - return tf.reshape(reduced_masked_loss, (1,)) - - -class TFSequenceClassificationLoss: - """ - Loss function suitable for sequence classification. - """ - - def hf_compute_loss(self, labels, logits): - if logits.shape.rank == 1 or logits.shape[1] == 1: - loss_fn = keras.losses.MeanSquaredError(reduction=keras.losses.Reduction.NONE) - if labels.shape.rank == 1: - # MeanSquaredError returns a scalar loss if the labels are 1D, so avoid that - labels = tf.expand_dims(labels, axis=-1) - else: - loss_fn = keras.losses.SparseCategoricalCrossentropy( - from_logits=True, reduction=keras.losses.Reduction.NONE - ) - - return loss_fn(labels, logits) - - -class TFMultipleChoiceLoss: - """Loss function suitable for multiple choice tasks.""" - - def hf_compute_loss(self, labels, logits): - loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=keras.losses.Reduction.NONE) - return loss_fn(labels, logits) - - -class TFMaskedLanguageModelingLoss(TFCausalLanguageModelingLoss): - """ - Loss function suitable for masked language modeling (MLM), that is, the task of guessing the masked tokens. - - - - Any label of -100 will be ignored (along with the corresponding logits) in the loss computation. - - - """ - - -class TFNextSentencePredictionLoss: - """ - Loss function suitable for next sentence prediction (NSP), that is, the task of guessing the next sentence. - - - - Any label of -100 will be ignored (along with the corresponding logits) in the loss computation. - - - """ - - def hf_compute_loss(self, labels, logits): - loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=keras.losses.Reduction.NONE) - if self.config.tf_legacy_loss: - # make sure only labels that are not equal to -100 - # are taken into account as loss - next_sentence_active_loss = tf.not_equal(tf.reshape(labels, (-1,)), -100) - next_sentence_reduced_logits = tf.boolean_mask(tf.reshape(logits, (-1, 2)), next_sentence_active_loss) - next_sentence_label = tf.boolean_mask(tf.reshape(labels, (-1,)), next_sentence_active_loss) - - return loss_fn(next_sentence_label, next_sentence_reduced_logits) - - # make sure only labels that are not equal to -100 - # are taken into account as loss - - # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway - unmasked_ns_loss = loss_fn(y_true=tf.nn.relu(labels), y_pred=logits) - ns_loss_mask = tf.cast(labels != -100, dtype=unmasked_ns_loss.dtype) - # Just zero out samples where label is -100, no reduction - masked_ns_loss = unmasked_ns_loss * ns_loss_mask - - return masked_ns_loss - - -def booleans_processing(config, **kwargs): - """ - Process the input booleans of each model. - - Args: - config ([`PretrainedConfig`]): - The config of the running model. - **kwargs: - The boolean parameters - - Returns: - A dictionary with the proper values for each boolean - """ - final_booleans = {} - - # Pure conv models (such as ConvNext) do not have `output_attentions`. If the signature has - # `output_attentions`, it will be present here in `kwargs`, even if unset (in that case, as `None`) - if "output_attentions" in kwargs: - final_booleans["output_attentions"] = ( - kwargs["output_attentions"] if kwargs["output_attentions"] is not None else config.output_attentions - ) - final_booleans["output_hidden_states"] = ( - kwargs["output_hidden_states"] if kwargs["output_hidden_states"] is not None else config.output_hidden_states - ) - final_booleans["return_dict"] = kwargs["return_dict"] if kwargs["return_dict"] is not None else config.return_dict - - if "use_cache" in kwargs: - final_booleans["use_cache"] = ( - kwargs["use_cache"] if kwargs["use_cache"] is not None else getattr(config, "use_cache", None) - ) - return final_booleans - - -def unpack_inputs(func): - """ - Decorator that processes the inputs to a Keras layer, passing them to the layer as keyword arguments. This enables - downstream use of the inputs by their variable name, even if they arrive packed as a dictionary in the first input - (common case in Keras). - - Args: - func (`callable`): - The callable function of the TensorFlow model. - - - Returns: - A callable that wraps the original `func` with the behavior described above. - """ - - original_signature = inspect.signature(func) - - @functools.wraps(func) - def run_call_with_unpacked_inputs(self, *args, **kwargs): - # isolates the actual `**kwargs` for the decorated function - kwargs_call = {key: val for key, val in kwargs.items() if key not in dict(original_signature.parameters)} - fn_args_and_kwargs = {key: val for key, val in kwargs.items() if key not in kwargs_call} - fn_args_and_kwargs.update({"kwargs_call": kwargs_call}) - - # move any arg into kwargs, if they exist - fn_args_and_kwargs.update(dict(zip(func.__code__.co_varnames[1:], args))) - - # Encoder Decoder models delegate the application of the configuration options to their inner models. - if "EncoderDecoder" in self.__class__.__name__: - config = None - else: - config = self.config - - unpacked_inputs = input_processing(func, config, **fn_args_and_kwargs) - return func(self, **unpacked_inputs) - - # Keras enforces the first layer argument to be passed, and checks it through `inspect.getfullargspec()`. This - # function does not follow wrapper chains (i.e. ignores `functools.wraps()`), meaning that without the line below - # Keras would attempt to check the first argument against the literal signature of the wrapper. - run_call_with_unpacked_inputs.__signature__ = original_signature - - return run_call_with_unpacked_inputs - - -def input_processing(func, config, **kwargs): - """ - Process the input of each TensorFlow model including the booleans. In case of a list of symbolic inputs, each input - has to be named accordingly to the parameters name, i.e. `input_ids = keras.Input(shape=(128,), dtype='int32', - name="input_ids")` otherwise the order of the tensors will not be guaranteed during the training. - - Args: - func (`callable`): - The callable function of the TensorFlow model. - config ([`PretrainedConfig`]): - The config of the running model. - **kwargs: - The inputs of the model. - - Returns: - Two lists, one for the missing layers, and another one for the unexpected layers. - """ - signature = dict(inspect.signature(func).parameters) - has_kwargs = bool(signature.pop("kwargs", None)) - signature.pop("self", None) - parameter_names = list(signature.keys()) - main_input_name = parameter_names[0] - main_input = kwargs.pop(main_input_name, None) - output = {} - allowed_types = (tf.Tensor, bool, int, ModelOutput, tuple, list, dict, np.ndarray) - - if "inputs" in kwargs["kwargs_call"]: - warnings.warn( - "The `inputs` argument is deprecated and will be removed in a future version, use `input_ids` instead.", - FutureWarning, - ) - - output["input_ids"] = kwargs["kwargs_call"].pop("inputs") - - if "decoder_cached_states" in kwargs["kwargs_call"]: - warnings.warn( - "The `decoder_cached_states` argument is deprecated and will be removed in a future version, use" - " `past_key_values` instead.", - FutureWarning, - ) - output["past_key_values"] = kwargs["kwargs_call"].pop("decoder_cached_states") - - if "past" in kwargs["kwargs_call"] and "past_key_values" in parameter_names: - warnings.warn( - "The `past` argument is deprecated and will be removed in a future version, use `past_key_values`" - " instead.", - FutureWarning, - ) - kwargs["past_key_values"] = kwargs["kwargs_call"].pop("past") - elif "past_key_values" in kwargs["kwargs_call"] and "past" in parameter_names: - kwargs["past"] = kwargs["kwargs_call"].pop("past_key_values") - - if has_kwargs: - output["kwargs"] = kwargs.pop("kwargs_call", {}) - else: - if len(kwargs["kwargs_call"]) > 0: - raise ValueError( - "The following keyword arguments are not supported by this model:" - f" {list(kwargs['kwargs_call'].keys())}." - ) - kwargs.pop("kwargs_call") - - for k, v in kwargs.items(): - if isinstance(v, allowed_types) or tf.is_tensor(v) or v is None: - output[k] = v - else: - raise ValueError(f"Data of type {type(v)} is not allowed only {allowed_types} is accepted for {k}.") - - if isinstance(main_input, (tuple, list)): - for i, input in enumerate(main_input): - # EagerTensors don't allow to use the .name property so we check for a real Tensor - if is_tf_symbolic_tensor(input): - # Tensor names have always the pattern `name:id` then we check only the - # `name` part - tensor_name = input.name.split(":")[0] - - if tensor_name in parameter_names: - output[tensor_name] = input - else: - output[parameter_names[i]] = input - elif isinstance(input, allowed_types) or input is None: - output[parameter_names[i]] = input - else: - raise ValueError( - f"Data of type {type(input)} is not allowed only {allowed_types} is accepted for" - f" {parameter_names[i]}." - ) - elif isinstance(main_input, Mapping): - if "inputs" in main_input: - warnings.warn( - "The `inputs` argument is deprecated and will be removed in a future version, use `input_ids`" - " instead.", - FutureWarning, - ) - - output["input_ids"] = main_input.pop("inputs") - - if "decoder_cached_states" in main_input: - warnings.warn( - "The `decoder_cached_states` argument is deprecated and will be removed in a future version, use" - " `past_key_values` instead.", - FutureWarning, - ) - output["past_key_values"] = main_input.pop("decoder_cached_states") - - for k, v in dict(main_input).items(): - if isinstance(v, allowed_types) or v is None: - output[k] = v - elif k not in parameter_names and "args" not in parameter_names: - logger.warning( - f"The parameter {k} does not belongs to the parameter list {parameter_names} and will be ignored." - ) - continue - else: - raise ValueError(f"Data of type {type(v)} is not allowed only {allowed_types} is accepted for {k}.") - else: - if tf.is_tensor(main_input) or main_input is None: - output[main_input_name] = main_input - else: - raise ValueError( - f"Data of type {type(main_input)} is not allowed only {allowed_types} is accepted for" - f" {main_input_name}." - ) - - # Populates any unspecified argument with their default value, according to the signature. - for name in parameter_names: - if name not in list(output.keys()) and name != "args": - output[name] = kwargs.pop(name, signature[name].default) - - # When creating a SavedModel TF calls the method with LayerCall.__call__(args, **kwargs) - # So to respect the proper output we have to add this exception - if "args" in output: - if output["args"] is not None and is_tf_symbolic_tensor(output["args"]): - tensor_name = output["args"].name.split(":")[0] - output[tensor_name] = output["args"] - else: - # `args` in this case is always the first parameter, then `input_ids` - output["input_ids"] = output["args"] - - del output["args"] - - if "kwargs" in output: - del output["kwargs"] - - cast_output = {} - for key, val in output.items(): - if isinstance(val, tf.Tensor) and val.dtype == tf.int64: - cast_output[key] = tf.cast(val, tf.int32) - elif isinstance(val, np.ndarray) and val.dtype == np.int64: - cast_output[key] = val.astype(np.int32) - else: - cast_output[key] = val - - output = cast_output - del cast_output - - if config is not None: - boolean_dict = { - k: v - for k, v in output.items() - if k in ["return_dict", "output_attentions", "output_hidden_states", "use_cache"] - } - - output.update( - booleans_processing( - config=config, - **boolean_dict, - ) - ) - - return output - - -def strip_model_name_and_prefix(name, _prefix=None): - if _prefix is not None and name.startswith(_prefix): - name = name[len(_prefix) :] - if name.startswith("/"): - name = name[1:] - if "model." not in name and len(name.split("/")) > 1: - name = "/".join(name.split("/")[1:]) - return name - - -def tf_shard_checkpoint(weights, max_shard_size="10GB", weights_name: str = TF2_WEIGHTS_NAME): - """ - Splits a model state dictionary in sub-checkpoints so that the final size of each sub-checkpoint does not exceed a - given size. - - The sub-checkpoints are determined by iterating through the `state_dict` in the order of its keys, so there is no - optimization made to make each sub-checkpoint as close as possible to the maximum size passed. For example, if the - limit is 10GB and we have weights of sizes [6GB, 6GB, 2GB, 6GB, 2GB, 2GB] they will get sharded as [6GB], [6+2GB], - [6+2+2GB] and not [6+2+2GB], [6+2GB], [6GB]. - - - - If one of the model's weight is bigger that `max_shard_size`, it will end up in its own sub-checkpoint which will - have a size greater than `max_shard_size`. - - - - Args: - weights (`dict[str, tf.RessourceVariable]`): The list of tf.RessourceVariable of a model to save. - max_shard_size (`int` or `str`, *optional*, defaults to `"10GB"`): - The maximum size of each sub-checkpoint. If expressed as a string, needs to be digits followed by a unit - (like `"5MB"`). - """ - max_shard_size = convert_file_size_to_int(max_shard_size) - - sharded_state_dicts = [] - current_block = [] - current_block_size = 0 - total_size = 0 - - for item in weights: - weight_size = item.numpy().size * item.dtype.size - - # If this weight is going to tip up over the maximal size, we split. - if current_block_size + weight_size > max_shard_size: - sharded_state_dicts.append(current_block) - current_block = [] - current_block_size = 0 - - current_block.append(item) - current_block_size += weight_size - total_size += weight_size - - # Add the last block - sharded_state_dicts.append(current_block) - - # If we only have one shard, we return it - if len(sharded_state_dicts) == 1: - return {weights_name: sharded_state_dicts[0]}, None - - # Otherwise, let's build the index - weight_map = {} - shards = {} - for idx, shard in enumerate(sharded_state_dicts): - shard_file = weights_name.replace(".h5", f"-{idx + 1:05d}-of-{len(sharded_state_dicts):05d}.h5") - shard_file = shard_file.replace( - ".safetensors", f"-{idx + 1:05d}-of-{len(sharded_state_dicts):05d}.safetensors" - ) - shards[shard_file] = shard - for weight in shard: - weight_name = weight.name - weight_map[weight_name] = shard_file - - # Add the metadata - metadata = {"total_size": total_size} - index = {"metadata": metadata, "weight_map": weight_map} - return shards, index - - -def load_tf_sharded_weights(model, shard_files, ignore_mismatched_sizes=False, strict=False, _prefix=None): - """ - This is the same as `load_tf_weights` but for a sharded checkpoint. Detect missing and unexpected layers and load - the TF weights from the shard file accordingly to their names and shapes. - - This load is performed efficiently: each checkpoint shard is loaded one by one in RAM and deleted after being - loaded in the model. - - Args: - model (`keras.models.Model`): The model in which to load the checkpoint. - shard_files (`str` or `os.PathLike`): A list containing the sharded checkpoint names. - ignore_mismatched_sizes`bool`, *optional`, defaults to `True`): - Whether or not to ignore the mismatch between the sizes - strict (`bool`, *optional*, defaults to `True`): - Whether to strictly enforce that the keys in the model state dict match the keys in the sharded checkpoint. - - Returns: - Three lists, one for the missing layers, another one for the unexpected layers, and a last one for the - mismatched layers. - """ - - # Load the index - unexpected_keys = set() - saved_keys = set() - mismatched_keys = set() - - # Since TF adds the name of the class to its weights, and uses the index and not the name of the layer to load - # the weight, we have to get rid of the first prefix of the name of the layer. - model_keys = set() - model_layer_map = {} - for i, k in enumerate(model.weights): - layer_name = k.name - if _prefix is not None and layer_name.startswith(_prefix): - layer_name = layer_name[len(_prefix) :] - layer_name = layer_name.lstrip("/") - if not ("model." in layer_name or len(layer_name.split("/")) == 1): - layer_name = "/".join(layer_name.split("/")[1:]) - model_keys.add(layer_name) - model_layer_map[layer_name] = i - - for shard_file in shard_files: - saved_weight_names_set, unexpected_keys_set, mismatched_keys_set = load_tf_shard( - model, - model_layer_map, - shard_file, - ignore_mismatched_sizes=ignore_mismatched_sizes, - _prefix=_prefix, - ) - saved_keys.update(saved_weight_names_set) - unexpected_keys.update(unexpected_keys_set) - mismatched_keys.update(mismatched_keys_set) - gc.collect() - - missing_keys = model_keys - saved_keys - if strict and (len(missing_keys) > 0 or len(unexpected_keys) > 0): - error_message = f"Error(s) in loading state_dict for {model.__class__.__name__}" - if len(missing_keys) > 0: - str_missing_keys = ",".join([f'"{k}"' for k in missing_keys]) - error_message += f"\nMissing key(s): {str_missing_keys}." - if len(unexpected_keys) > 0: - str_unexpected_keys = ",".join([f'"{k}"' for k in unexpected_keys]) - error_message += f"\nMissing key(s): {str_unexpected_keys}." - raise RuntimeError(error_message) - - return missing_keys, unexpected_keys, mismatched_keys - - -def load_tf_shard(model, model_layer_map, resolved_archive_file, ignore_mismatched_sizes=False, _prefix=None): - """ - Loads a shard from a sharded checkpoint file. Can be either H5 or Safetensors. - Handles missing keys and unexpected keys. - - Args: - model (`keras.models.Model`): Model in which the weights are loaded - model_layer_map (`Dict`): A dictionary mapping the layer name to the index of the layer in the model. - resolved_archive_file (`str`): Path to the checkpoint file from which the weights will be loaded - ignore_mismatched_sizes (`bool`, *optional*, defaults to `False`): Whether to ignore the mismatched keys - - Returns: - `keras.models.Model`: Three lists, one for the layers that were found and successfully restored (from the - shard file), one for the mismatched layers, and another one for the unexpected layers. - """ - saved_weight_names_set = set() - saved_weights = {} - mismatched_keys = set() - unexpected_keys = set() - # Read the H5 file - try: - with h5py.File(resolved_archive_file, "r") as sharded_checkpoint_file: - # Retrieve the name of each layer from the H5 file - saved_h5_model_layers_name = set(load_attributes_from_hdf5_group(sharded_checkpoint_file, "layer_names")) - weight_value_tuples = [] - - # Compute missing and unexpected sub layers - # Store the weights in list of tuples that looks like [(weight_object, value_of_weight),...] - for layer_name in saved_h5_model_layers_name: - h5_layer_object = sharded_checkpoint_file[layer_name] - saved_weights[layer_name] = np.asarray(h5_layer_object) - - saved_weight_names_set.add(layer_name) - - if layer_name not in model_layer_map: - unexpected_keys.add(layer_name) - else: - symbolic_weight = model.weights[model_layer_map[layer_name]] - - saved_weight_value = saved_weights[layer_name] - # If the current weight is found - if saved_weight_value is not None: - # Check if the shape of the current weight and the one from the H5 file are different - if K.int_shape(symbolic_weight) != saved_weight_value.shape: - # If yes we reshape the weight from the H5 file accordingly to the current weight - # If the two shapes are not compatible we raise an issue - try: - array = np.reshape(saved_weight_value, K.int_shape(symbolic_weight)) - except ValueError as e: - if ignore_mismatched_sizes: - mismatched_keys.add( - (layer_name, saved_weight_value.shape, K.int_shape(symbolic_weight)) - ) - continue - else: - raise e - else: - array = saved_weight_value - - # We create the tuple that will be loaded and add it to the final list - weight_value_tuples.append((symbolic_weight, array)) - - K.batch_set_value(weight_value_tuples) - - return saved_weight_names_set, unexpected_keys, mismatched_keys - - except Exception as e: - try: - with open(resolved_archive_file) as f: - if f.read().startswith("version"): - raise OSError( - "You seem to have cloned a repository without having git-lfs installed. Please install " - "git-lfs and run `git lfs install` followed by `git lfs pull` in the folder " - "you cloned." - ) - else: - raise ValueError( - f"Unable to locate the file {resolved_archive_file} which is necessary to load this pretrained" - " model. Make sure you have saved the model properly." - ) from e - except (UnicodeDecodeError, ValueError): - raise OSError( - f"Unable to load weights from TF checkpoint file for '{resolved_archive_file}' " - f"at '{resolved_archive_file}'. " - "If you tried to load a TF model from a sharded checkpoint, you should try converting the model " - "by loading it in pytorch and saving it locally. A conversion script should be released soon." - ) - - -def load_tf_sharded_weights_from_safetensors( - model, shard_files, ignore_mismatched_sizes=False, strict=False, _prefix=None -): - """ - This is the same as `load_tf_weights_from_safetensors` but for a sharded TF-format safetensors checkpoint. - Detect missing and unexpected layers and load the TF weights from the shard file accordingly to their names and - shapes. - - This load is performed efficiently: each checkpoint shard is loaded one by one in RAM and deleted after being - loaded in the model. - - Args: - model (`keras.models.Model`): The model in which to load the checkpoint. - shard_files (`str` or `os.PathLike`): A list containing the sharded checkpoint names. - ignore_mismatched_sizes`bool`, *optional`, defaults to `True`): - Whether or not to ignore the mismatch between the sizes - strict (`bool`, *optional*, defaults to `True`): - Whether to strictly enforce that the keys in the model state dict match the keys in the sharded checkpoint. - - Returns: - Three lists, one for the missing layers, another one for the unexpected layers, and a last one for the - mismatched layers. - """ - - # Load the index - unexpected_keys = set() - all_missing_keys = [] - mismatched_keys = set() - - for shard_file in shard_files: - missing_layers, unexpected_layers, mismatched_layers = load_tf_weights_from_safetensors( - model, - shard_file, - ignore_mismatched_sizes=ignore_mismatched_sizes, - _prefix=_prefix, - ) - all_missing_keys.append(set(missing_layers)) - unexpected_keys.update(unexpected_layers) - mismatched_keys.update(mismatched_layers) - gc.collect() - missing_keys = set.intersection(*all_missing_keys) - - if strict and (len(missing_keys) > 0 or len(unexpected_keys) > 0): - error_message = f"Error(s) in loading state_dict for {model.__class__.__name__}" - if len(missing_keys) > 0: - str_missing_keys = ",".join([f'"{k}"' for k in missing_keys]) - error_message += f"\nMissing key(s): {str_missing_keys}." - if len(unexpected_keys) > 0: - str_unexpected_keys = ",".join([f'"{k}"' for k in unexpected_keys]) - error_message += f"\nMissing key(s): {str_unexpected_keys}." - raise RuntimeError(error_message) - - return missing_keys, unexpected_keys, mismatched_keys - - -def load_tf_weights(model, resolved_archive_file, ignore_mismatched_sizes=False, _prefix=None): - """ - Detect missing and unexpected layers and load the TF weights from the shard file accordingly to their names and - shapes. - - Args: - model (`keras.models.Model`): - The model to load the weights into. - resolved_archive_file (`str`): - The location of the H5 file. - ignore_mismatched_sizes (`bool`, *optional*, defaults to `False`): - Whether or not to ignore weights with shapes that don't match between the checkpoint of the model. - - Returns: - Three lists, one for the missing layers, another one for the unexpected layers, and a last one for the - mismatched layers. - """ - if resolved_archive_file.endswith(".safetensors"): - load_function = load_tf_weights_from_safetensors - else: - load_function = load_tf_weights_from_h5 - - return load_function( - model, resolved_archive_file, ignore_mismatched_sizes=ignore_mismatched_sizes, _prefix=_prefix - ) - - -def load_tf_weights_from_h5(model, resolved_archive_file, ignore_mismatched_sizes=False, _prefix=None): - mismatched_layers = [] - - # Read the H5 file - with h5py.File(resolved_archive_file, "r") as sharded_checkpoint_file: - # Retrieve the name of each layer from the H5 file - saved_h5_model_layers_name = set(load_attributes_from_hdf5_group(sharded_checkpoint_file, "layer_names")) - - # Find the missing layers from the high level list of layers - missing_layers = list({layer.name for layer in model.layers} - saved_h5_model_layers_name) - - # Find the unexpected layers from the high level list of layers - unexpected_layers = list(saved_h5_model_layers_name - {layer.name for layer in model.layers}) - saved_weight_names_set = set() - symbolic_weights_names = set() - weight_value_tuples = [] - - # Compute missing and unexpected sub layers - # Store the weights in list of tuples that looks like [(weight_object, value_of_weight),...] - for layer in model.layers: - # if layer_name from the H5 file belongs to the layers from the instantiated model - if layer.name in saved_h5_model_layers_name: - # Get the H5 layer object from its name - h5_layer_object = sharded_checkpoint_file[layer.name] - # Get all the weights as a list from the layer object - symbolic_weights = layer.trainable_weights + layer.non_trainable_weights - saved_weights = {} - - # Create a dict from the H5 saved model that looks like {"weight_name": weight_value} - # And a set with only the names - for weight_name in load_attributes_from_hdf5_group(h5_layer_object, "weight_names"): - # TF names always start with the model name so we ignore it - name = "/".join(weight_name.split("/")[1:]) - - if _prefix is not None: - name = _prefix + "/" + name - - saved_weights[name] = np.asarray(h5_layer_object[weight_name]) - - # Add the updated name to the final list for computing missing/unexpected values - saved_weight_names_set.add(name) - - # Loop over each weights from the instantiated model and compare with the weights from the H5 file - for symbolic_weight in symbolic_weights: - # TF names always start with the model name so we ignore it - if _prefix is not None: - delimiter = len(_prefix.split("/")) - symbolic_weight_name = "/".join( - symbolic_weight.name.split("/")[:delimiter] - + symbolic_weight.name.split("/")[delimiter + 1 :] - ) - else: - symbolic_weight_name = "/".join(symbolic_weight.name.split("/")[1:]) - - # here we check if the current weight is among the weights from the H5 file - # If yes, get the weight_value of the corresponding weight from the H5 file - # If not, make the value to None - saved_weight_value = saved_weights.get(symbolic_weight_name) - - # Retrocompatibility patch: some embeddings are stored with the weights name (e.g. Bart's - # `model.shared/embeddings:0` are stored as `model.shared/weights:0`) - if saved_weight_value is None and symbolic_weight_name.endswith("embeddings:0"): - symbolic_weight_name = symbolic_weight_name[:-12] + "weight:0" - saved_weight_value = saved_weights.get(symbolic_weight_name) - - # Add the updated name to the final list for computing missing/unexpected values - symbolic_weights_names.add(symbolic_weight_name) - - # If the current weight is found - if saved_weight_value is not None: - # Check if the shape of the current weight and the one from the H5 file are different - if K.int_shape(symbolic_weight) != saved_weight_value.shape: - # If yes we reshape the weight from the H5 file accordingly to the current weight - # If the two shapes are not compatible we raise an issue - try: - array = np.reshape(saved_weight_value, K.int_shape(symbolic_weight)) - except ValueError as e: - if ignore_mismatched_sizes: - mismatched_layers.append( - (symbolic_weight_name, saved_weight_value.shape, K.int_shape(symbolic_weight)) - ) - continue - else: - raise e - else: - array = saved_weight_value - - # We create the tuple that will be loaded and add it to the final list - weight_value_tuples.append((symbolic_weight, array)) - - # Load all the weights - K.batch_set_value(weight_value_tuples) - - # Compute the missing and unexpected layers - missing_layers.extend(list(symbolic_weights_names - saved_weight_names_set)) - unexpected_layers.extend(list(saved_weight_names_set - symbolic_weights_names)) - - return missing_layers, unexpected_layers, mismatched_layers - - -def load_tf_weights_from_safetensors(model, resolved_archive_file, ignore_mismatched_sizes=False, _prefix=None): - # Read the safetensors file - with safe_open(resolved_archive_file, framework="tf") as safetensors_archive: - mismatched_layers = [] - weight_names = [strip_model_name_and_prefix(w.name, _prefix=_prefix) for w in model.weights] - loaded_weight_names = list(safetensors_archive.keys()) - # Find the missing layers from the high level list of layers - missing_layers = list(set(weight_names) - set(loaded_weight_names)) - # Find the unexpected layers from the high level list of layers - unexpected_layers = list(set(loaded_weight_names) - set(weight_names)) - - for weight in model.weights: - weight_name = strip_model_name_and_prefix(weight.name, _prefix=_prefix) - if weight_name in loaded_weight_names: - weight_value = safetensors_archive.get_tensor(weight_name) - # Check if the shape of the current weight and the one from the H5 file are different - if K.int_shape(weight) != weight_value.shape: - # If yes we reshape the weight from the H5 file accordingly to the current weight - # If the two shapes are not compatible we raise an issue - try: - weight_value = tf.reshape(weight_value, K.int_shape(weight)) - except (ValueError, tf.errors.InvalidArgumentError) as e: - if ignore_mismatched_sizes: - mismatched_layers.append((weight_name, weight_value.shape, K.int_shape(weight))) - continue - else: - raise e - - K.set_value(weight, weight_value) # weight.assign() might break if weight is a DTensor - return missing_layers, unexpected_layers, mismatched_layers - - -def init_copy_embeddings(old_embeddings, new_num_tokens): - r""" - This function aims to reduce the embeddings in case new_num_tokens < old_num_tokens or to pad with -1 in case - new_num_tokens > old_num_tokens. A mask is also computed in order to know which weight in the embeddings should be - kept or not. Example: - - - if new_num_tokens=5 and old_num_tokens=4 and old_embeddings=[w1,w2,w3,w4] - - - mask=[True,True,True,True,False] and current_weights=[w1,w2,w3,w4,-1] - - if new_num_tokens=4 and old_num_tokens=5 and old_embeddings=[w1,w2,w3,w4,w5] - - - mask=[True,True,True,True] and current_weights=[w1,w2,w3,w4] - """ - old_num_tokens, old_embedding_dim = shape_list(old_embeddings) - size_diff = new_num_tokens - old_num_tokens - - # initialize new embeddings - # Copy token embeddings from the previous ones - if tf.math.greater(size_diff, 0): - # if the new size is greater than the old one, we extend the current embeddings with a padding until getting new size - # and we create a mask to properly identify the padded values and be replaced by the values of the newly created - # embeddings - current_weights = tf.pad( - old_embeddings.value(), tf.convert_to_tensor([[0, size_diff], [0, 0]]), constant_values=-1 - ) - num_tokens_to_copy = min(old_num_tokens, new_num_tokens) - mask = tf.fill(tf.convert_to_tensor([num_tokens_to_copy, 1]), True) - mask = tf.pad(mask, tf.convert_to_tensor([[0, size_diff], [0, 0]]), constant_values=False) - else: - # if the new size if lower than the old one, we take the current embeddings until the new size - current_weights = tf.slice( - old_embeddings.value(), - tf.convert_to_tensor([0, 0]), - tf.convert_to_tensor([new_num_tokens, old_embedding_dim]), - ) - mask = tf.fill(tf.convert_to_tensor([new_num_tokens, 1]), True) - - return mask, current_weights - - -class TFPreTrainedModel(keras.Model, TFModelUtilsMixin, TFGenerationMixin, PushToHubMixin): - r""" - Base class for all TF models. - - [`TFPreTrainedModel`] takes care of storing the configuration of the models and handles methods for loading, - downloading and saving models as well as a few methods common to all models to: - - - resize the input embeddings, - - prune heads in the self-attention heads. - - Class attributes (overridden by derived classes): - - - **config_class** ([`PretrainedConfig`]) -- A subclass of [`PretrainedConfig`] to use as configuration class - for this model architecture. - - **base_model_prefix** (`str`) -- A string indicating the attribute associated to the base model in derived - classes of the same architecture adding modules on top of the base model. - - **main_input_name** (`str`) -- The name of the principal input to the model (often `input_ids` for NLP - models, `pixel_values` for vision models and `input_values` for speech models). - """ - - config_class = None - base_model_prefix = "" - main_input_name = "input_ids" - _auto_class = None - _using_dummy_loss = None - _label_to_output_map = None - - # a list of re pattern of tensor names to ignore from the model when loading the model weights - # (and avoid unnecessary warnings). - _keys_to_ignore_on_load_missing = None - # a list of re pattern of tensor names to ignore from the weights when loading the model weights - # (and avoid unnecessary warnings). - _keys_to_ignore_on_load_unexpected = None - _requires_load_weight_prefix = False - - @property - def dummy_inputs(self) -> dict[str, tf.Tensor]: - """ - Dummy inputs to build the network. - - Returns: - `dict[str, tf.Tensor]`: The dummy inputs. - """ - dummies = {} - for key, spec in self.input_signature.items(): - # 2 is the most correct arbitrary size. I will not be taking questions - dummy_shape = [dim if dim is not None else 2 for dim in spec.shape] - if spec.shape[0] is None: - # But let's make the batch size 1 to save memory anyway - dummy_shape[0] = 1 - dummies[key] = tf.ones(shape=dummy_shape, dtype=spec.dtype) - if key == "token_type_ids": - # Some models have token_type_ids but with a vocab_size of 1 - dummies[key] = tf.zeros_like(dummies[key]) - if self.config.add_cross_attention and "encoder_hidden_states" in inspect.signature(self.call).parameters: - if "encoder_hidden_states" not in dummies: - if self.main_input_name == "input_ids": - dummies["encoder_hidden_states"] = tf.ones( - shape=(1, 2, self.config.hidden_size), dtype=tf.float32, name="encoder_hidden_states" - ) - else: - raise NotImplementedError( - "Model has cross-attention but we couldn't infer the shape for the encoder hidden states. Please manually override dummy_inputs!" - ) - return dummies - - def build_in_name_scope(self): - with tf.name_scope(self.name): - self.build(input_shape=None) - - @property - def framework(self) -> str: - """ - :str: Identifies that this is a TensorFlow model. - """ - return "tf" - - def build(self, input_shape=None): - pass # This is just here to make sure we don't call the superclass build() - - def __init__(self, config, *inputs, **kwargs): - super().__init__(*inputs, **kwargs) - if not isinstance(config, PretrainedConfig): - raise TypeError( - f"Parameter config in `{self.__class__.__name__}(config)` should be an instance of class " - "`PretrainedConfig`. To create a model from a pretrained model use " - f"`model = {self.__class__.__name__}.from_pretrained(PRETRAINED_MODEL_NAME)`" - ) - # Save config and origin of the pretrained weights if given in model - self.config = config - self.name_or_path = config.name_or_path - self.generation_config = GenerationConfig.from_model_config(config) if self.can_generate() else None - self._set_save_spec(self.input_signature) - logger.warning_once( - "TensorFlow and JAX classes are deprecated and will be removed in Transformers v5. We " - "recommend migrating to PyTorch classes or pinning your version of Transformers." - ) - - def get_config(self): - return self.config.to_dict() - - @functools.wraps(keras.Model.fit) - def fit(self, *args, **kwargs): - args, kwargs = convert_batch_encoding(*args, **kwargs) - return super().fit(*args, **kwargs) - - @functools.wraps(keras.Model.train_on_batch) - def train_on_batch(self, *args, **kwargs): - args, kwargs = convert_batch_encoding(*args, **kwargs) - return super().train_on_batch(*args, **kwargs) - - @functools.wraps(keras.Model.test_on_batch) - def test_on_batch(self, *args, **kwargs): - args, kwargs = convert_batch_encoding(*args, **kwargs) - return super().test_on_batch(*args, **kwargs) - - @functools.wraps(keras.Model.predict_on_batch) - def predict_on_batch(self, *args, **kwargs): - args, kwargs = convert_batch_encoding(*args, **kwargs) - return super().predict_on_batch(*args, **kwargs) - - @functools.wraps(keras.Model.predict) - def predict(self, *args, **kwargs): - args, kwargs = convert_batch_encoding(*args, **kwargs) - return super().predict(*args, **kwargs) - - @functools.wraps(keras.Model.evaluate) - def evaluate(self, *args, **kwargs): - args, kwargs = convert_batch_encoding(*args, **kwargs) - return super().evaluate(*args, **kwargs) - - @classmethod - def from_config(cls, config, **kwargs): - if isinstance(config, PretrainedConfig): - return cls._from_config(config, **kwargs) - return cls._from_config(cls.config_class.from_dict(config, **kwargs)) - - @classmethod - def _from_config(cls, config, **kwargs): - """ - All context managers that the model should be initialized under go here. - """ - return cls(config, **kwargs) - - def get_head_mask(self, head_mask: tf.Tensor | None, num_hidden_layers: int) -> tf.Tensor: - """ - Prepare the head mask if needed. - - Args: - head_mask (`tf.Tensor` with shape `[num_heads]` or `[num_hidden_layers x num_heads]`, *optional*): - The mask indicating if we should keep the heads or not (1.0 for keep, 0.0 for discard). - num_hidden_layers (`int`): - The number of hidden layers in the model. - - Returns: - `tf.Tensor` with shape `[num_hidden_layers x batch x num_heads x seq_length x seq_length]` or list with - `[None]` for each layer. - """ - if head_mask is not None: - head_mask = self._convert_head_mask_to_5d(head_mask, num_hidden_layers) - else: - head_mask = [None] * num_hidden_layers - - return head_mask - - def _convert_head_mask_to_5d(self, head_mask, num_hidden_layers): - """-> [num_hidden_layers x batch x num_heads x seq_length x seq_length]""" - if head_mask.shape.rank == 1: - head_mask = head_mask[None, None, :, None, None] - head_mask = tf.repeat(head_mask, repeats=num_hidden_layers, axis=0) - elif head_mask.shape.rank == 2: - head_mask = head_mask[:, None, :, None, None] - assert head_mask.shape.rank == 5, f"head_mask.dim != 5, instead {head_mask.dim()}" - head_mask = tf.cast(head_mask, tf.float32) # switch to float if need + fp16 compatibility - return head_mask - - @tf.function - def serving(self, inputs): - """ - Args: - Method used for serving the model. Does not have a specific signature, but will be specialized as concrete - functions when saving with `save_pretrained`. - inputs (`dict[str, tf.Tensor]`): - The input of the saved model as a dictionary of tensors. - """ - output = self.call(inputs) - - return self.serving_output(output) - - @property - def input_signature(self) -> dict[str, tf.TensorSpec]: - """ - This property should return a dict mapping input names to tf.TensorSpec objects, representing the expected - shape and dtype for model inputs. It is used for both serving and for generating dummy inputs. - """ - model_inputs = list(inspect.signature(self.call).parameters) - sig = {} - if "input_ids" in model_inputs: - if self.__class__.__name__.endswith("ForMultipleChoice"): - text_dims = 3 - else: - text_dims = 2 - for input_name in ( - "input_ids", - "attention_mask", - "token_type_ids", - "decoder_input_ids", - "decoder_attention_mask", - ): - if input_name in model_inputs: - sig[input_name] = tf.TensorSpec([None] * text_dims, tf.int32, name=input_name) - if "pixel_values" in model_inputs: - pixel_values_shape = [None, None, None, None] - if hasattr(self.config, "vision_config"): - vision_config = self.config.vision_config - else: - vision_config = self.config - if hasattr(vision_config, "num_channels"): - pixel_values_shape[1] = vision_config.num_channels - else: - raise NotImplementedError( - "Could not infer number of channels from config, please override input_signature to specify input shapes." - ) - if hasattr(vision_config, "image_size"): - pixel_values_shape[2] = pixel_values_shape[3] = vision_config.image_size - elif hasattr(vision_config, "input_size"): - pixel_values_shape[2] = pixel_values_shape[3] = vision_config.input_size - else: - raise NotImplementedError( - "Could not infer input image shape from config, please override input_signature to specify input shapes." - ) - sig["pixel_values"] = tf.TensorSpec(pixel_values_shape, tf.float32, name="pixel_values") - if "input_features" in model_inputs: - raise NotImplementedError("Audio models need a manually defined input_signature") - return sig - - def serving_output(self, output): - """ - Prepare the output of the saved model. Can be overridden if specific serving modifications are required. - """ - if not isinstance(output, ModelOutput): - return output - for key in output: - if key.endswith("hidden_states") and not getattr(self.config, "output_hidden_states", False): - output[key] = None - elif key.endswith("attentions") and not getattr(self.config, "output_attentions", False): - output[key] = None - elif key == "past_key_values" and not getattr(self.config, "use_cache", False): - output[key] = None - elif key == "cross_attentions" and not ( - getattr(self.config, "output_attentions", False) and getattr(self.config, "add_cross_attention", False) - ): - output[key] = None - if isinstance(output[key], (tuple, list)): - try: - output[key] = tf.convert_to_tensor(output[key]) - except (ValueError, tf.errors.InvalidArgumentError): - pass # Layers may not have the same dimensions - return output - - @classmethod - def can_generate(cls) -> bool: - """ - Returns whether this model can generate sequences with `.generate()`. - - Returns: - `bool`: Whether this model can generate sequences with `.generate()`. - """ - # Detects whether `prepare_inputs_for_generation` has been overwritten, which is a requirement for generation. - # Alternatively, the model can also have a custom `generate` function. - if "GenerationMixin" in str(cls.prepare_inputs_for_generation) and "GenerationMixin" in str(cls.generate): - return False - return True - - def get_input_embeddings(self) -> keras.layers.Layer: - """ - Returns the model's input embeddings layer. - - Returns: - `tf.Variable`: The embeddings layer mapping vocabulary to hidden states. - """ - main_layer = getattr(self, self.base_model_prefix, self) - - if main_layer is not self: - return main_layer.get_input_embeddings() - else: - raise NotImplementedError - - def _save_checkpoint(self, checkpoint_dir, epoch): - if not os.path.isdir(checkpoint_dir): - os.mkdir(checkpoint_dir) - # We avoid tf.train.checkpoint or saving weights in TF format, even though that includes optimizer - # state for us, because it requires special handling for objects like custom losses, which we use - # internally and which users are likely to use too - weights_path = os.path.join(checkpoint_dir, "weights.h5") - self.save_weights(weights_path) - extra_data = {"epoch": epoch, "optimizer_state": self.optimizer.get_weights()} - extra_data_path = os.path.join(checkpoint_dir, "extra_data.pickle") - with open(extra_data_path, "wb") as f: - pickle.dump(extra_data, f) - - def prepare_tf_dataset( - self, - dataset: datasets.Dataset, # noqa:F821 - batch_size: int = 8, - shuffle: bool = True, - tokenizer: PreTrainedTokenizerBase | None = None, - collate_fn: Callable | None = None, - collate_fn_args: dict[str, Any] | None = None, - drop_remainder: bool | None = None, - prefetch: bool = True, - ): - """ - Wraps a HuggingFace [`~datasets.Dataset`] as a `tf.data.Dataset` with collation and batching. This method is - designed to create a "ready-to-use" dataset that can be passed directly to Keras methods like `fit()` without - further modification. The method will drop columns from the dataset if they don't match input names for the - model. If you want to specify the column names to return rather than using the names that match this model, we - recommend using `Dataset.to_tf_dataset()` instead. - - Args: - dataset (`Any`): - A [~`datasets.Dataset`] to be wrapped as a `tf.data.Dataset`. - batch_size (`int`, *optional*, defaults to 8): - The size of batches to return. - shuffle (`bool`, defaults to `True`): - Whether to return samples from the dataset in random order. Usually `True` for training datasets and - `False` for validation/test datasets. - tokenizer ([`PreTrainedTokenizerBase`], *optional*): - A `PreTrainedTokenizer` that will be used to pad samples to create batches. Has no effect if a specific - `collate_fn` is passed instead. - collate_fn (`Callable`, *optional*): - A function that collates samples from the dataset into a single batch. Defaults to - `DefaultDataCollator` if no `tokenizer` is supplied or `DataCollatorWithPadding` if a `tokenizer` is - passed. - collate_fn_args (`dict[str, Any]`, *optional*): - A dict of arguments to pass to the `collate_fn` alongside the list of samples. - drop_remainder (`bool`, *optional*): - Whether to drop the final batch, if the batch_size does not evenly divide the dataset length. Defaults - to the same setting as `shuffle`. - prefetch (`bool`, defaults to `True`): - Whether to add prefetching to the end of the `tf.data` pipeline. This is almost always beneficial for - performance, but can be disabled in edge cases. - - - Returns: - `Dataset`: A `tf.data.Dataset` which is ready to pass to the Keras API. - """ - requires_backends(self, ["datasets"]) - import datasets - - if collate_fn is None: - if tokenizer is None: - collate_fn = DefaultDataCollator(return_tensors="np") - else: - collate_fn = DataCollatorWithPadding(tokenizer=tokenizer, return_tensors="np") - if collate_fn_args is None: - collate_fn_args = {} - - if not isinstance(dataset, datasets.Dataset): - raise TypeError("Dataset argument should be a datasets.Dataset!") - model_inputs = list(inspect.signature(self.call).parameters) - model_labels = find_labels(self.__class__) - if "cols_to_retain" in list(inspect.signature(dataset._get_output_signature).parameters.keys()): - output_signature, _ = dataset._get_output_signature( - dataset, - batch_size=None, - collate_fn=collate_fn, - collate_fn_args=collate_fn_args, - cols_to_retain=model_inputs, - ) - else: - # TODO Matt: This is a workaround for older versions of datasets that are missing the `cols_to_retain` - # argument. We should remove this once the minimum supported version of datasets is > 2.3.2 - unwanted_columns = [ - feature - for feature in dataset.features - if feature not in model_inputs and feature not in ("label_ids", "label") - ] - dataset = dataset.remove_columns(unwanted_columns) - output_signature, _ = dataset._get_output_signature( - dataset, batch_size=None, collate_fn=collate_fn, collate_fn_args=collate_fn_args - ) - output_columns = list(output_signature.keys()) - feature_cols = [col for col in output_columns if col in model_inputs and col not in model_labels] - label_cols = [col for col in output_columns if col in model_labels] - - # Backwards compatibility for older versions of datasets. Previously, if `columns` or `label_cols` - # were a single element list, the returned element spec would be a single element. Now, passing [feature] - # will return a dict structure {"feature": feature}, and passing a single string will return a single element. - feature_cols = feature_cols[0] if len(feature_cols) == 1 else feature_cols - label_cols = label_cols[0] if len(label_cols) == 1 else label_cols - - if drop_remainder is None: - drop_remainder = shuffle - tf_dataset = dataset.to_tf_dataset( - columns=feature_cols, - label_cols=label_cols, - batch_size=batch_size, - shuffle=shuffle, - drop_remainder=drop_remainder, - collate_fn=collate_fn, - collate_fn_args=collate_fn_args, - prefetch=prefetch, - ) - return tf_dataset - - def compile( - self, - optimizer="rmsprop", - loss="auto_with_warning", - metrics=None, - loss_weights=None, - weighted_metrics=None, - run_eagerly=None, - steps_per_execution=None, - **kwargs, - ): - """ - This is a thin wrapper that sets the model's loss output head as the loss if the user does not specify a loss - function themselves. - """ - if loss in ("auto_with_warning", "passthrough"): # "passthrough" for workflow backward compatibility - logger.info( - "No loss specified in compile() - the model's internal loss computation will be used as the " - "loss. Don't panic - this is a common way to train TensorFlow models in Transformers! " - "To disable this behaviour please pass a loss argument, or explicitly pass " - "`loss=None` if you do not want your model to compute a loss. You can also specify `loss='auto'` to " - "get the internal loss without printing this info string." - ) - loss = "auto" - if loss == "auto": - loss = dummy_loss - self._using_dummy_loss = True - else: - self._using_dummy_loss = False - parent_args = list(inspect.signature(keras.Model.compile).parameters.keys()) - # This argument got renamed, we need to support both versions - if "steps_per_execution" in parent_args: - super().compile( - optimizer=optimizer, - loss=loss, - metrics=metrics, - loss_weights=loss_weights, - weighted_metrics=weighted_metrics, - run_eagerly=run_eagerly, - steps_per_execution=steps_per_execution, - **kwargs, - ) - else: - super().compile( - optimizer=optimizer, - loss=loss, - metrics=metrics, - loss_weights=loss_weights, - weighted_metrics=weighted_metrics, - run_eagerly=run_eagerly, - experimental_steps_per_execution=steps_per_execution, - **kwargs, - ) - - def compute_loss(self, *args, **kwargs): - if hasattr(keras.Model, "compute_loss"): - # This will be true in TF 2.8 or greater - return super().compute_loss(*args, **kwargs) - else: - warnings.warn( - "The old compute_loss method is deprecated as it conflicts with the Keras compute_loss " - "method added in TF 2.8. If you want the original HF compute_loss, please call " - "hf_compute_loss() instead. From TF versions >= 2.8, or Transformers versions >= 5, " - "calling compute_loss() will get the Keras method instead.", - FutureWarning, - ) - return self.hf_compute_loss(*args, **kwargs) - - def get_label_to_output_name_mapping(self): - arg_names = list(inspect.signature(self.call).parameters) - if self._label_to_output_map is not None: - return self._label_to_output_map - elif "start_positions" in arg_names: - return {"start_positions": "start_logits", "end_positions": "end_logits"} - elif "sentence_order_label" in arg_names: - return {"labels": "prediction_logits", "sentence_order_label": "sop_logits"} - elif "next_sentence_label" in arg_names: - return {"labels": "prediction_logits", "next_sentence_label": "seq_relationship_logits"} - elif "mc_labels" in arg_names: - return {"labels": "logits", "mc_labels": "mc_logits"} - else: - return {} - - def train_step(self, data): - """ - A modification of Keras's default `train_step` that correctly handles matching outputs to labels for our models - and supports directly training on the loss output head. In addition, it ensures input keys are copied to the - labels where appropriate. It will also copy label keys into the input dict when using the dummy loss, to ensure - that they are available to the model during the forward pass. - """ - - # We hardcode the most common renamings; models with weirder names can set `self._label_to_output_map` - arg_names = list(inspect.signature(self.call).parameters) - label_kwargs = find_labels(self.__class__) - label_to_output = self.get_label_to_output_name_mapping() - output_to_label = {val: key for key, val in label_to_output.items()} - if not self._using_dummy_loss and parse(tf.__version__) < parse("2.11.0"): - # Newer TF train steps leave this out - data = expand_1d(data) - x, y, sample_weight = keras.utils.unpack_x_y_sample_weight(data) - # If the inputs are mutable dictionaries, make a shallow copy of them because we will modify - # them during input/label pre-processing. This avoids surprising the user by wrecking their data. - # In addition, modifying mutable Python inputs makes XLA compilation impossible. - if isinstance(x, dict): - x = x.copy() - if isinstance(y, dict): - y = y.copy() - - # When using a dummy loss, we ensure that separate labels are copied to the correct model arguments, - # if those keys are not already present in the input dict - if self._using_dummy_loss and y is not None: - # If y is a tensor and the model only has one label-like input, map y to that input - if len(label_kwargs) == 1 and isinstance(y, tf.Tensor): - if isinstance(x, tf.Tensor): - x = {arg_names[0]: x} - label_kwarg = next(iter(label_kwargs)) - if label_kwarg not in x: - x[label_kwarg] = y - # Otherwise, copy keys from y to x as long as they weren't already present in x - elif isinstance(y, dict): - if isinstance(x, tf.Tensor): - x = {arg_names[0]: x} - for key, val in y.items(): - if key in arg_names and key not in x: - x[key] = val - elif output_to_label.get(key) in arg_names and key not in x: - x[output_to_label[key]] = val - if y is None: - y = {key: val for key, val in x.items() if key in label_kwargs} - if not y and not self._using_dummy_loss: - raise ValueError("Could not find label column(s) in input dict and no separate labels were provided!") - - if isinstance(y, dict): - # Rename labels at this point to match output heads - y = {label_to_output.get(key, key): val for key, val in y.items()} - - # Run forward pass. - with tf.GradientTape() as tape: - if self._using_dummy_loss and "return_loss" in arg_names: - y_pred = self(x, training=True, return_loss=True) - else: - y_pred = self(x, training=True) - if self._using_dummy_loss: - loss = self.compiled_loss(y_pred.loss, y_pred.loss, sample_weight, regularization_losses=self.losses) - else: - loss = None - - # This next block matches outputs to label keys. Tensorflow's standard method for doing this - # can get very confused if any of the keys contain nested values (e.g. lists/tuples of Tensors) - if isinstance(y, dict) and len(y) == 1: - if list(y.keys())[0] in y_pred: - y_pred = y_pred[list(y.keys())[0]] - elif list(y_pred.keys())[0] == "loss": - y_pred = y_pred[1] - else: - y_pred = y_pred[0] - _, y = y.popitem() - elif isinstance(y, dict): - # If the labels are a dict, match keys from the output by name - y_pred = {key: val for key, val in y_pred.items() if key in y} - elif isinstance(y, (tuple, list)): - # If the labels are a tuple/list, match keys to the output by order, skipping the loss. - if list(y_pred.keys())[0] == "loss": - y_pred = y_pred.to_tuple()[1:] - else: - y_pred = y_pred.to_tuple() - y_pred = y_pred[: len(y)] # Remove unused fields in case those cause problems - else: - # If the labels are a single tensor, match them to the first non-loss tensor in the output - if list(y_pred.keys())[0] == "loss": - y_pred = y_pred[1] - else: - y_pred = y_pred[0] - - if loss is None: - loss = self.compiled_loss(y, y_pred, sample_weight, regularization_losses=self.losses) - - # Run backwards pass. - self.optimizer.minimize(loss, self.trainable_variables, tape=tape) - - self.compiled_metrics.update_state(y, y_pred, sample_weight) - # Collect metrics to return - return_metrics = {} - for metric in self.metrics: - result = metric.result() - if isinstance(result, dict): - return_metrics.update(result) - else: - return_metrics[metric.name] = result - return return_metrics - - def test_step(self, data): - """ - A modification of Keras's default `train_step` that correctly handles matching outputs to labels for our models - and supports directly training on the loss output head. In addition, it ensures input keys are copied to the - labels where appropriate. It will also copy label keys into the input dict when using the dummy loss, to ensure - that they are available to the model during the forward pass. - """ - # We hardcode the most common renamings; models with weirder names can set `self._label_to_output_map` - arg_names = list(inspect.signature(self.call).parameters) - label_kwargs = find_labels(self.__class__) - label_to_output = self.get_label_to_output_name_mapping() - output_to_label = {val: key for key, val in label_to_output.items()} - if not self._using_dummy_loss and parse(tf.__version__) < parse("2.11.0"): - # Newer versions leave this out - data = expand_1d(data) - x, y, sample_weight = keras.utils.unpack_x_y_sample_weight(data) - # If the inputs are mutable dictionaries, make a shallow copy of them because we will modify - # them during input/label pre-processing. This avoids surprising the user by wrecking their data. - # In addition, modifying mutable Python inputs makes XLA compilation impossible. - if isinstance(x, dict): - x = x.copy() - if isinstance(y, dict): - y = y.copy() - - # When using a dummy loss, we ensure that separate labels are copied to the correct model arguments, - # if those keys are not already present in the input dict - if self._using_dummy_loss and y is not None: - arg_names = list(inspect.signature(self.call).parameters) - # If y is a tensor and the model only has one label-like input, map y to that input - if len(label_kwargs) == 1 and isinstance(y, tf.Tensor): - if isinstance(x, tf.Tensor): - x = {arg_names[0]: x} - label_kwarg = next(iter(label_kwargs)) - if label_kwarg not in x: - x[label_kwarg] = y - # Otherwise, copy keys from y to x as long as they weren't already present in x - elif isinstance(y, dict): - if isinstance(x, tf.Tensor): - x = {arg_names[0]: x} - for key, val in y.items(): - if key in arg_names and key not in x: - x[key] = val - elif output_to_label.get(key) in arg_names and key not in x: - x[output_to_label[key]] = val - if y is None: - y = {key: val for key, val in x.items() if key in label_kwargs} - if not y and not self._using_dummy_loss: - raise ValueError("Could not find label column(s) in input dict and no separate labels were provided!") - - if isinstance(y, dict): - # Rename labels at this point to match output heads - y = {label_to_output.get(key, key): val for key, val in y.items()} - - # Run forward pass. - if self._using_dummy_loss and "return_loss" in arg_names: - y_pred = self(x, return_loss=True, training=False) - else: - y_pred = self(x, training=False) - if self._using_dummy_loss: - loss = self.compiled_loss(y_pred.loss, y_pred.loss, sample_weight, regularization_losses=self.losses) - else: - loss = None - - # This next block matches outputs to label keys. Tensorflow's standard method for doing this - # can get very confused if any of the keys contain nested values (e.g. lists/tuples of Tensors) - if isinstance(y, dict) and len(y) == 1: - if list(y.keys())[0] in y_pred: - y_pred = y_pred[list(y.keys())[0]] - elif list(y_pred.keys())[0] == "loss": - y_pred = y_pred[1] - else: - y_pred = y_pred[0] - _, y = y.popitem() - elif isinstance(y, dict): - # If the labels are a dict, match keys from the output by name - y_pred = {key: val for key, val in y_pred.items() if key in y} - elif isinstance(y, (tuple, list)): - # If the labels are a tuple/list, match keys to the output by order, skipping the loss. - if list(y_pred.keys())[0] == "loss": - y_pred = y_pred.to_tuple()[1:] - else: - y_pred = y_pred.to_tuple() - y_pred = y_pred[: len(y)] # Remove unused fields in case those cause problems - else: - # If the labels are a single tensor, match them to the first non-loss tensor in the output - if list(y_pred.keys())[0] == "loss": - y_pred = y_pred[1] - else: - y_pred = y_pred[0] - - if loss is None: - loss = self.compiled_loss(y, y_pred, sample_weight, regularization_losses=self.losses) - - self.compiled_metrics.update_state(y, y_pred, sample_weight) - # Collect metrics to return - return_metrics = {} - for metric in self.metrics: - result = metric.result() - if isinstance(result, dict): - return_metrics.update(result) - else: - return_metrics[metric.name] = result - return return_metrics - - def create_model_card( - self, - output_dir, - model_name: str, - language: str | None = None, - license: str | None = None, - tags: str | None = None, - finetuned_from: str | None = None, - tasks: str | None = None, - dataset_tags: str | list[str] | None = None, - dataset: str | list[str] | None = None, - dataset_args: str | list[str] | None = None, - ): - """ - Creates a draft of a model card using the information available to the `Trainer`. - - Args: - output_dir (`str` or `os.PathLike`): - The folder in which to create the model card. - model_name (`str`, *optional*): - The name of the model. - language (`str`, *optional*): - The language of the model (if applicable) - license (`str`, *optional*): - The license of the model. Will default to the license of the pretrained model used, if the original - model given to the `Trainer` comes from a repo on the Hub. - tags (`str` or `list[str]`, *optional*): - Some tags to be included in the metadata of the model card. - finetuned_from (`str`, *optional*): - The name of the model used to fine-tune this one (if applicable). Will default to the name of the repo - of the original model given to the `Trainer` (if it comes from the Hub). - tasks (`str` or `list[str]`, *optional*): - One or several task identifiers, to be included in the metadata of the model card. - dataset_tags (`str` or `list[str]`, *optional*): - One or several dataset tags, to be included in the metadata of the model card. - dataset (`str` or `list[str]`, *optional*): - One or several dataset identifiers, to be included in the metadata of the model card. - dataset_args (`str` or `list[str]`, *optional*): - One or several dataset arguments, to be included in the metadata of the model card. - """ - # Avoids a circular import by doing this when necessary. - from .modelcard import TrainingSummary # tests_ignore - - training_summary = TrainingSummary.from_keras( - self, - keras_history=self.history, - language=language, - license=license, - tags=tags, - model_name=model_name, - finetuned_from=finetuned_from, - tasks=tasks, - dataset_tags=dataset_tags, - dataset=dataset, - dataset_args=dataset_args, - ) - model_card = training_summary.to_model_card() - with open(os.path.join(output_dir, "README.md"), "w") as f: - f.write(model_card) - - def set_input_embeddings(self, value): - """ - Set model's input embeddings - - Args: - value (`tf.Variable`): - The new weights mapping hidden states to vocabulary. - """ - main_layer = getattr(self, self.base_model_prefix) - - if main_layer is None: - raise NotImplementedError("The model does not implements the base_model_prefix attribute.") - - try: - main_layer.set_input_embeddings(value) - except AttributeError: - logger.info("Building the model") - self.build_in_name_scope() - main_layer.set_input_embeddings(value) - - def get_output_embeddings(self) -> None | keras.layers.Layer: - """ - Returns the model's output embeddings - - Returns: - `tf.Variable`: The new weights mapping vocabulary to hidden states. - """ - if self.get_lm_head() is not None: - lm_head = self.get_lm_head() - - try: - return lm_head.get_output_embeddings() - except AttributeError: - logger.info("Building the model") - self.build_in_name_scope() - - return lm_head().get_output_embeddings() - - return None # Overwrite for models with output embeddings - - def set_output_embeddings(self, value): - """ - Set model's output embeddings - - Args: - value (`tf.Variable`): - The new weights mapping hidden states to vocabulary. - """ - if self.get_lm_head() is not None: - lm_head = self.get_lm_head() - try: - lm_head.set_output_embeddings(value) - except AttributeError: - logger.info("Building the model") - self.build_in_name_scope() - lm_head.set_output_embeddings(value) - - def get_output_layer_with_bias(self) -> None | keras.layers.Layer: - """ - Get the layer that handles a bias attribute in case the model has an LM head with weights tied to the - embeddings - - Return: - `keras.layers.Layer`: The layer that handles the bias, None if not an LM model. - """ - warnings.warn( - "The method get_output_layer_with_bias is deprecated. Please use `get_lm_head` instead.", FutureWarning - ) - return self.get_lm_head() - - def get_prefix_bias_name(self) -> None | str: - """ - Get the concatenated _prefix name of the bias from the model name to the parent layer - - Return: - `str`: The _prefix name of the bias. - """ - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return None - - def get_bias(self) -> None | dict[str, tf.Variable]: - """ - Dict of bias attached to an LM head. The key represents the name of the bias attribute. - - Return: - `tf.Variable`: The weights representing the bias, None if not an LM model. - """ - if self.get_lm_head() is not None: - lm_head = self.get_lm_head() - try: - return lm_head.get_bias() - except AttributeError: - self.build_in_name_scope() - - return lm_head.get_bias() - return None - - def set_bias(self, value): - """ - Set all the bias in the LM head. - - Args: - value (`dict[tf.Variable]`): - All the new bias attached to an LM head. - """ - if self.get_lm_head() is not None: - lm_head = self.get_lm_head() - try: - lm_head.set_bias(value) - except AttributeError: - self.build_in_name_scope() - lm_head.set_bias(value) - - def get_lm_head(self) -> keras.layers.Layer: - """ - The LM Head layer. This method must be overwritten by all the models that have a lm head. - - Return: - `keras.layers.Layer`: The LM head layer if the model has one, None if not. - """ - return None - - def resize_token_embeddings(self, new_num_tokens: int | None = None) -> keras.layers.Embedding | tf.Variable: - """ - Resizes input token embeddings matrix of the model if `new_num_tokens != config.vocab_size`. - - Takes care of tying weights embeddings afterwards if the model class has a `tie_weights()` method. - - Arguments: - new_num_tokens (`int`, *optional*): - The number of new tokens in the embedding matrix. Increasing the size will add newly initialized - vectors at the end. Reducing the size will remove vectors from the end. If not provided or `None`, just - returns a pointer to the input tokens without doing anything. - - Return: - `tf.Variable` or `keras.layers.Embedding`: Pointer to the input tokens of the model. - """ - # TODO (joao): flagged for replacement (by `_v2_resized_token_embeddings`) due to embeddings refactor - - # Run the new code path if the model has a keras embeddings layer - if isinstance(self.get_input_embeddings(), keras.layers.Embedding): - return self._v2_resized_token_embeddings(new_num_tokens) - - if new_num_tokens is None or new_num_tokens == self.config.vocab_size: - return self._get_word_embedding_weight(self.get_input_embeddings()) - - model_embeds = self._resize_token_embeddings(new_num_tokens) - - # Update base model and current model config - self.config.vocab_size = new_num_tokens - - return model_embeds - - def _v2_resized_token_embeddings(self, new_num_tokens: int | None = None) -> keras.layers.Embedding: - """ - Resizes input token embeddings matrix of the model if `new_num_tokens != config.vocab_size`. - - Arguments: - new_num_tokens (`int`, *optional*): - The number of new tokens in the embedding matrix. Increasing the size will add newly initialized - vectors at the end. Reducing the size will remove vectors from the end. If not provided or `None`, just - returns a pointer to the input tokens without doing anything. - - Return: - `keras.layers.Embedding`: Pointer to the input tokens of the model. - """ - if new_num_tokens is None or new_num_tokens == self.config.vocab_size: - return self.get_input_embeddings() - - model_embeds = self._v2_resize_token_embeddings(new_num_tokens) - - # Update base model and current model config - self.config.vocab_size = new_num_tokens - - return model_embeds - - def _get_word_embedding_weight(model, embedding_layer): - # TODO (joao): flagged for detection due to embeddings refactor - - # If the variable holds the weights themselves, return them - if isinstance(embedding_layer, tf.Tensor): - return embedding_layer - # Otherwise, try to get them from the layer's attributes - - embeds = getattr(embedding_layer, "weight", None) - if embeds is not None: - return embeds - - embeds = getattr(embedding_layer, "decoder", None) - if embeds is not None: - return embeds - - # The reason why the attributes don't exist might be - # because the model is not built, so retry getting - # the argument after building the model - model.build_in_name_scope() - - embeds = getattr(embedding_layer, "weight", None) - if embeds is not None: - return embeds - - embeds = getattr(embedding_layer, "decoder", None) - if embeds is not None: - return embeds - - return None - - def _resize_token_embeddings(self, new_num_tokens): - # TODO (joao): flagged for replacement (by `_v2_resize_token_embeddings`) due to embeddings refactor - old_embeddings = self._get_word_embedding_weight(self.get_input_embeddings()) - new_embeddings = self._get_resized_embeddings(old_embeddings, new_num_tokens) - - # if word embeddings are not tied, make sure that lm head bias is resized as well - if self.get_bias() is not None: - old_lm_head_bias = self.get_bias() - new_lm_head_bias = self._get_resized_lm_head_bias(old_lm_head_bias, new_num_tokens) - - self.set_bias(new_lm_head_bias) - - # if word embeddings are not tied, make sure that lm head decoder is resized as well - if self.get_output_embeddings() is not None: - old_lm_head_decoder = self._get_word_embedding_weight(self.get_output_embeddings()) - new_lm_head_decoder = self._get_resized_lm_head_decoder(old_lm_head_decoder, new_num_tokens) - - self.set_output_embeddings(new_lm_head_decoder) - - self.set_input_embeddings(new_embeddings) - - return self.get_input_embeddings() - - def _v2_resize_token_embeddings(self, new_num_tokens): - old_embeddings = self.get_input_embeddings() - new_embeddings = self._v2_get_resized_embeddings(old_embeddings, new_num_tokens) - self.set_input_embeddings(new_embeddings) - - # If word embeddings are not tied, make sure that lm head bias is resized as well - if self.get_bias() is not None: - old_lm_head_bias = self.get_bias() - new_lm_head_bias = self._v2_get_resized_lm_head_bias(old_lm_head_bias, new_num_tokens) - self.set_bias(new_lm_head_bias) - - # If word embeddings are not tied, make sure that lm head decoder is resized as well. - tied_weights = self.get_input_embeddings() == self.get_output_embeddings() - if self.get_output_embeddings() is not None and not tied_weights: - old_lm_head_decoder = self._get_word_embedding_weight(self.get_output_embeddings()) - # TODO (joao): this one probably needs a v2 version with other models - new_lm_head_decoder = self._get_resized_lm_head_decoder(old_lm_head_decoder, new_num_tokens) - self.set_output_embeddings(new_lm_head_decoder) - - return self.get_input_embeddings() - - def _get_resized_lm_head_bias(self, old_lm_head_bias, new_num_tokens): - """ - Build a resized bias from the old ones. Increasing the size will add newly initialized vectors at the end. - Reducing the size will remove vectors from the end - - Args: - old_lm_head_bias (`tf.Variable`): - Old lm head bias to be resized. - new_num_tokens (`int`, *optional*): - New number of tokens in the linear matrix. - - Increasing the size will add newly initialized vectors at the end. Reducing the size will remove - vectors from the end. If not provided or `None`, just returns None - - Return: - `tf.Variable`: Pointer to the resized bias. - """ - # TODO (joao): flagged for replacement (by `_v2_get_resized_lm_head_bias`) due to embeddings refactor - new_lm_head_bias = {} - - for attr, weight in old_lm_head_bias.items(): - first_dim, old_num_tokens = (None, shape_list(weight)[0]) if tf.rank(weight) == 1 else shape_list(weight) - size_diff = new_num_tokens - old_num_tokens - final_shape = [new_num_tokens] if first_dim is None else [first_dim, new_num_tokens] - - # initialize new bias - if tf.math.greater(size_diff, 0): - padding_shape = [[0, size_diff]] if first_dim is None else [[0, 0], [0, size_diff]] - current_bias = tf.pad(weight.value(), tf.convert_to_tensor(padding_shape), constant_values=-1) - num_tokens_to_copy = min(old_num_tokens, new_num_tokens) - mask_shape = [num_tokens_to_copy] if first_dim is None else [1, num_tokens_to_copy] - bias_mask = tf.fill(tf.convert_to_tensor(mask_shape), True) - bias_mask = tf.pad(bias_mask, tf.convert_to_tensor(padding_shape), constant_values=False) - else: - slice_from = [0] if first_dim is None else [0, 0] - current_bias = tf.slice( - weight.value(), tf.convert_to_tensor(slice_from), tf.convert_to_tensor(final_shape) - ) - bias_mask = tf.fill(tf.convert_to_tensor(final_shape), True) - - new_bias = self.add_weight( - shape=final_shape, - initializer="zeros", - trainable=True, - name=weight.name.split(":")[0], - ) - init_bias = tf.where(bias_mask, current_bias, new_bias.value()) - - new_bias.assign(init_bias) - new_lm_head_bias[attr] = new_bias - - return new_lm_head_bias - - def _v2_get_resized_lm_head_bias( - self, old_lm_head_bias: dict[str, tf.Variable], new_num_tokens: int - ) -> dict[str, tf.Tensor]: - """ - Build a resized bias from the old ones. Increasing the size will add newly initialized vectors at the end. - Reducing the size will remove vectors from the end - - Args: - old_lm_head_bias (`dict[str, tf.Variable]`): - Old lm head bias to be resized. - new_num_tokens (`int`): - New number of tokens in the linear matrix. Increasing the size will add newly initialized vectors at - the end. Reducing the size will remove vectors from the end. - - Return: - `tf.Tensor`: Values for the resized bias. - """ - new_lm_head_bias = {} - - for attr, weight in old_lm_head_bias.items(): - # Determine the size difference (depending on the shape) - first_dim, old_num_tokens = (None, shape_list(weight)[0]) if tf.rank(weight) == 1 else shape_list(weight) - size_diff = new_num_tokens - old_num_tokens - - # Copy the old bias values to the new bias - if old_num_tokens > new_num_tokens: - new_bias = weight.value()[..., :new_num_tokens] - else: - padding_shape = [[0, size_diff]] if first_dim is None else [[0, 0], [0, size_diff]] - new_bias = tf.pad(weight.value(), tf.convert_to_tensor(padding_shape)) - - new_lm_head_bias[attr] = new_bias - return new_lm_head_bias - - def _get_resized_lm_head_decoder(self, old_lm_head_decoder, new_num_tokens): - """ - Build a resized decoder from the old ones. Increasing the size will add newly initialized vectors at the end. - Reducing the size will remove vectors from the end - - Args: - old_lm_head_decoder (`tf.Variable`): - Old lm head decoder to be resized. - new_num_tokens (`int`, *optional*): - New number of tokens in the linear matrix. - - Increasing the size will add newly initialized vectors at the end. Reducing the size will remove - vectors from the end. If not provided or `None`, just returns None - - Return: - `tf.Variable`: Pointer to the resized decoder or None if the output embeddings are different from the input - ones. - """ - new_lm_head_decoder = old_lm_head_decoder - is_input_output_equals = tf.reduce_any( - self._get_word_embedding_weight(self.get_input_embeddings()) == old_lm_head_decoder - ) - - if old_lm_head_decoder is not None and not is_input_output_equals: - old_embedding_dim = shape_list(old_lm_head_decoder)[1] - decoder_mask, current_decoder = init_copy_embeddings(old_lm_head_decoder, new_num_tokens) - new_lm_head_decoder = self.add_weight( - shape=(new_num_tokens, old_embedding_dim), - initializer="zeros", - trainable=True, - name=old_lm_head_decoder.name.split(":")[0], - ) - init_decoder = tf.where(decoder_mask, current_decoder, new_lm_head_decoder.value()) - - new_lm_head_decoder.assign(init_decoder) - - return new_lm_head_decoder - - def _get_resized_embeddings(self, old_embeddings, new_num_tokens=None) -> tf.Variable: - """ - Build a resized Embedding weights from a provided token Embedding weights. Increasing the size will add newly - initialized vectors at the end. Reducing the size will remove vectors from the end - - Args: - old_embeddings (`tf.Variable`): - Old embeddings to be resized. - new_num_tokens (`int`, *optional*): - New number of tokens in the embedding matrix. - - Increasing the size will add newly initialized vectors at the end. Reducing the size will remove - vectors from the end. If not provided or `None`, just returns a pointer to the input tokens - `tf.Variable` module of the model without doing anything. - - Return: - `tf.Variable`: Pointer to the resized Embedding Module or the old Embedding Module if `new_num_tokens` is - `None` - """ - # TODO (joao): flagged for replacement (by `_v2_get_resized_embeddings`) due to embeddings refactor - old_embedding_dim = shape_list(old_embeddings)[1] - init_range = getattr(self.config, "initializer_range", 0.02) - embeddings_mask, current_embeddings = init_copy_embeddings(old_embeddings, new_num_tokens) - new_embeddings = self.add_weight( - name=old_embeddings.name.split(":")[0], - shape=[new_num_tokens, old_embedding_dim], - initializer=get_initializer(init_range), - dtype=tf.float32, - ) - init_embeddings = tf.where(embeddings_mask, current_embeddings, new_embeddings.value()) - - new_embeddings.assign(init_embeddings) - - return new_embeddings - - def _v2_get_resized_embeddings( - self, old_embeddings: keras.layers.Embedding, new_num_tokens: int - ) -> keras.layers.Embedding: - """ - Build a resized Embedding layer from a provided Embedding layer. Increasing the size will add newly initialized - vectors at the end. Reducing the size will remove vectors from the end. - - Args: - old_embeddings (`keras.layers.Embedding`): - Old embeddings to be resized. - new_num_tokens (`int`, *optional*): - New number of tokens in the embedding matrix. - - Return: - `keras.layers.Embedding`: Resized Embedding layer. - """ - - # Get the initialization range for the embeddings - init_range = 0.02 # default value - potential_initialization_variable_names = [ - "initializer_range", # most common - "initializer_factor", # e.g. T5 - "init_std", # e.g BART - ] - for var_name in potential_initialization_variable_names: - if hasattr(self.config, var_name): - init_range = getattr(self.config, var_name) - - # Get a new (initialized) embeddings layer - new_embeddings = keras.layers.Embedding( - input_dim=new_num_tokens, - output_dim=old_embeddings.output_dim, - embeddings_initializer=keras.initializers.TruncatedNormal(stddev=init_range), - name=old_embeddings.embeddings.name[:-13], # exact same scoped name except "/embeddings:0" - ) - new_embeddings(tf.constant([[0]])) - - # Copy the old embeddings to the new embeddings - if old_embeddings.input_dim >= new_num_tokens: - init_embeddings = old_embeddings.embeddings[:new_num_tokens] - else: - init_embeddings = tf.concat( - [old_embeddings.embeddings, new_embeddings.embeddings[old_embeddings.input_dim :]], axis=0 - ) - new_embeddings.embeddings.assign(init_embeddings) - return new_embeddings - - def prune_heads(self, heads_to_prune): - """ - Prunes heads of the base model. - - Arguments: - heads_to_prune (`dict[int, list[int]]`): - Dictionary with keys being selected layer indices (`int`) and associated values being the list of heads - to prune in said layer (list of `int`). For instance {1: [0, 2], 2: [2, 3]} will prune heads 0 and 2 on - layer 1 and heads 2 and 3 on layer 2. - """ - raise NotImplementedError - - def save_pretrained( - self, - save_directory, - saved_model=False, - version=1, - push_to_hub=False, - signatures=None, - max_shard_size: int | str = "5GB", - create_pr: bool = False, - safe_serialization: bool = False, - token: str | bool | None = None, - **kwargs, - ): - """ - Save a model and its configuration file to a directory, so that it can be re-loaded using the - [`~TFPreTrainedModel.from_pretrained`] class method. - - Arguments: - save_directory (`str`): - Directory to which to save. Will be created if it doesn't exist. - saved_model (`bool`, *optional*, defaults to `False`): - If the model has to be saved in saved model format as well or not. - version (`int`, *optional*, defaults to 1): - The version of the saved model. A saved model needs to be versioned in order to be properly loaded by - TensorFlow Serving as detailed in the official documentation - https://www.tensorflow.org/tfx/serving/serving_basic - push_to_hub (`bool`, *optional*, defaults to `False`): - Whether or not to push your model to the Hugging Face model hub after saving it. You can specify the - repository you want to push to with `repo_id` (will default to the name of `save_directory` in your - namespace). - signatures (`dict` or `tf.function`, *optional*): - Model's signature used for serving. This will be passed to the `signatures` argument of model.save(). - max_shard_size (`int` or `str`, *optional*, defaults to `"10GB"`): - The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size - lower than this size. If expressed as a string, needs to be digits followed by a unit (like `"5MB"`). - - - - If a single weight of the model is bigger than `max_shard_size`, it will be in its own checkpoint shard - which will be bigger than `max_shard_size`. - - - - create_pr (`bool`, *optional*, defaults to `False`): - Whether or not to create a PR with the uploaded files or directly commit. - safe_serialization (`bool`, *optional*, defaults to `False`): - Whether to save the model using `safetensors` or the traditional TensorFlow way (that uses `h5`). - token (`str` or `bool`, *optional*): - The token to use as HTTP bearer authorization for remote files. If `True`, or not specified, will use - the token generated when running `hf auth login` (stored in `~/.huggingface`). - kwargs (`dict[str, Any]`, *optional*): - Additional key word arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method. - """ - use_auth_token = kwargs.pop("use_auth_token", None) - - if use_auth_token is not None: - warnings.warn( - "The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.", - FutureWarning, - ) - if token is not None: - raise ValueError( - "`token` and `use_auth_token` are both specified. Please set only the argument `token`." - ) - token = use_auth_token - - if token is not None: - kwargs["token"] = token - - if os.path.isfile(save_directory): - logger.error(f"Provided path ({save_directory}) should be a directory, not a file") - return - - os.makedirs(save_directory, exist_ok=True) - - if push_to_hub: - commit_message = kwargs.pop("commit_message", None) - repo_id = kwargs.pop("repo_id", save_directory.split(os.path.sep)[-1]) - repo_id = self._create_repo(repo_id, **kwargs) - files_timestamps = self._get_files_timestamps(save_directory) - - if saved_model: - # If `torch_dtype` is in the config with a torch dtype class as the value, we need to change it to string. - # (Although TF doesn't care about this attribute, we can't just remove it or set it to `None`.) - if getattr(self.config, "torch_dtype", None) is not None and not isinstance(self.config.torch_dtype, str): - self.config.torch_dtype = str(self.config.torch_dtype).split(".")[1] - if signatures is None: - serving_default = self.serving.get_concrete_function(self.input_signature) - if any(spec.dtype == tf.int32 for spec in self.input_signature.values()): - int64_spec = { - key: tf.TensorSpec( - shape=spec.shape, dtype=tf.int64 if spec.dtype == tf.int32 else spec.dtype, name=spec.name - ) - for key, spec in self.input_signature.items() - } - int64_serving = self.serving.get_concrete_function(int64_spec) - signatures = {"serving_default": serving_default, "int64_serving": int64_serving} - else: - signatures = serving_default - saved_model_dir = os.path.join(save_directory, "saved_model", str(version)) - self.save(saved_model_dir, include_optimizer=False, signatures=signatures) - logger.info(f"Saved model created in {saved_model_dir}") - - # Save configuration file - self.config.architectures = [self.__class__.__name__[2:]] - - # If we have a custom model, we copy the file defining it in the folder and set the attributes so it can be - # loaded from the Hub. - if self._auto_class is not None: - custom_object_save(self, save_directory, config=self.config) - - self.config.save_pretrained(save_directory) - if self.can_generate(): - self.generation_config.save_pretrained(save_directory) - - # If we save using the predefined names, we can load using `from_pretrained` - weights_name = SAFE_WEIGHTS_NAME if safe_serialization else TF2_WEIGHTS_NAME - output_model_file = os.path.join(save_directory, weights_name) - - shards, index = tf_shard_checkpoint(self.weights, max_shard_size, weights_name=weights_name) - - # Clean the folder from a previous save - for filename in os.listdir(save_directory): - full_filename = os.path.join(save_directory, filename) - # If we have a shard file that is not going to be replaced, we delete it, but only from the main process - # in distributed settings to avoid race conditions. - weights_no_suffix = weights_name.replace(".bin", "").replace(".safetensors", "") - if filename.startswith(weights_no_suffix) and os.path.isfile(full_filename) and filename not in shards: - os.remove(full_filename) - - if index is None: - if safe_serialization: - state_dict = {strip_model_name_and_prefix(w.name): w.value() for w in self.weights} - safe_save_file(state_dict, output_model_file, metadata={"format": "tf"}) - else: - self.save_weights(output_model_file) - logger.info(f"Model weights saved in {output_model_file}") - else: - save_index_file = SAFE_WEIGHTS_INDEX_NAME if safe_serialization else TF2_WEIGHTS_INDEX_NAME - save_index_file = os.path.join(save_directory, save_index_file) - # Save the index as well - with open(save_index_file, "w", encoding="utf-8") as index_file: - content = json.dumps(index, indent=2, sort_keys=True) + "\n" - index_file.write(content) - logger.info( - f"The model is bigger than the maximum size per checkpoint ({max_shard_size}) and is going to be " - f"split in {len(shards)} checkpoint shards. You can find where each parameters has been saved in the " - f"index located at {save_index_file}." - ) - for shard_file, shard in shards.items(): - if safe_serialization: - shard_state_dict = {strip_model_name_and_prefix(w.name): w.value() for w in shard} - safe_save_file( - shard_state_dict, os.path.join(save_directory, shard_file), metadata={"format": "tf"} - ) - else: - with h5py.File(os.path.join(save_directory, shard_file), mode="w") as shard_file: - layers = [] - for layer in sorted(shard, key=lambda x: x.name): - if "model." in layer.name or len(layer.name.split("/")) == 1: - layer_name = layer.name - else: - layer_name = "/".join(layer.name.split("/")[1:]) - param_dset = shard_file.create_dataset( - layer_name, layer.numpy().shape, dtype=layer.numpy().dtype - ) - param_dset[:] = layer.numpy() - layers.append(layer_name.encode("utf8")) - save_attributes_to_hdf5_group(shard_file, "layer_names", layers) - - if push_to_hub: - self._upload_modified_files( - save_directory, - repo_id, - files_timestamps, - commit_message=commit_message, - token=token, - ) - - @classmethod - def from_pretrained( - cls, - pretrained_model_name_or_path: str | os.PathLike | None, - *model_args, - config: PretrainedConfig | str | os.PathLike | None = None, - cache_dir: str | os.PathLike | None = None, - ignore_mismatched_sizes: bool = False, - force_download: bool = False, - local_files_only: bool = False, - token: str | bool | None = None, - revision: str = "main", - use_safetensors: bool | None = None, - **kwargs, - ): - r""" - Instantiate a pretrained TF 2.0 model from a pre-trained model configuration. - - The warning *Weights from XXX not initialized from pretrained model* means that the weights of XXX do not come - pretrained with the rest of the model. It is up to you to train those weights with a downstream fine-tuning - task. - - The warning *Weights from XXX not used in YYY* means that the layer XXX is not used by YYY, therefore those - weights are discarded. - - Parameters: - pretrained_model_name_or_path (`str`, *optional*): - Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~TFPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *PyTorch state_dict save file* (e.g, `./pt_model/pytorch_model.bin`). In this - case, `from_pt` should be set to `True` and a configuration object should be provided as `config` - argument. This loading path is slower than converting the PyTorch model in a TensorFlow model - using the provided conversion scripts and loading the TensorFlow model afterwards. - - `None` if you are both providing the configuration and state dictionary (resp. with keyword - arguments `config` and `state_dict`). - model_args (sequence of positional arguments, *optional*): - All remaining positional arguments will be passed to the underlying model's `__init__` method. - config (`Union[PretrainedConfig, str]`, *optional*): - Can be either: - - - an instance of a class derived from [`PretrainedConfig`], - - a string valid as input to [`~PretrainedConfig.from_pretrained`]. - - Configuration for the model to use instead of an automatically loaded configuration. Configuration can - be automatically loaded when: - - - The model is a model provided by the library (loaded with the *model id* string of a pretrained - model). - - The model was saved using [`~TFPreTrainedModel.save_pretrained`] and is reloaded by supplying the - save directory. - - The model is loaded by supplying a local directory as `pretrained_model_name_or_path` and a - configuration JSON file named *config.json* is found in the directory. - from_pt (`bool`, *optional*, defaults to `False`): - Load the model weights from a PyTorch state_dict save file (see docstring of - `pretrained_model_name_or_path` argument). - ignore_mismatched_sizes (`bool`, *optional*, defaults to `False`): - Whether or not to raise an error if some of the weights from the checkpoint do not have the same size - as the weights of the model (if for instance, you are instantiating a model with 10 labels from a - checkpoint with 3 labels). - cache_dir (`str`, *optional*): - Path to a directory in which a downloaded pretrained model configuration should be cached if the - standard cache should not be used. - force_download (`bool`, *optional*, defaults to `False`): - Whether or not to force the (re-)download of the model weights and configuration files, overriding the - cached versions if they exist. - resume_download: - Deprecated and ignored. All downloads are now resumed by default when possible. - Will be removed in v5 of Transformers. - proxies: - (`dict[str, str], `optional`): A dictionary of proxy servers to use by protocol or endpoint, e.g., - `{'http': 'foo.bar:3128', 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. - output_loading_info(`bool`, *optional*, defaults to `False`): Whether ot not to also return a - dictionary containing missing keys, unexpected keys and error messages. - local_files_only(`bool`, *optional*, defaults to `False`): - Whether or not to only look at local files (e.g., not try downloading the model). - token (`str` or `bool`, *optional*): - The token to use as HTTP bearer authorization for remote files. If `True`, or not specified, will use - the token generated when running `hf auth login` (stored in `~/.huggingface`). - revision (`str`, *optional*, defaults to `"main"`): - The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a - git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any - identifier allowed by git. - - - - - To test a pull request you made on the Hub, you can pass `revision="refs/pr/"`. - - - - mirror (`str`, *optional*): - Mirror source to accelerate downloads in China. If you are from China and have an accessibility - problem, you can set this option to resolve it. Note that we do not guarantee the timeliness or safety. - Please refer to the mirror site for more information. - subfolder (`str`, *optional*, defaults to `""`): - In case the relevant files are located inside a subfolder of the model repo on huggingface.co, you can - specify the folder name here. - tf_to_pt_weight_rename (`Callable`, *optional*): - A function that is called to transform the names of weights during the PyTorch to TensorFlow - crossloading process. This is not necessary for most models, but is useful to allow composite models to - be crossloaded correctly. - use_safetensors (`bool`, *optional*, defaults to `None`): - Whether or not to use `safetensors` checkpoints. Defaults to `None`. If not specified and `safetensors` - is not installed, it will be set to `False`. - kwargs (remaining dictionary of keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). Behaves differently depending on whether a `config` is provided or - automatically loaded: - - - If a configuration is provided with `config`, `**kwargs` will be directly passed to the - underlying model's `__init__` method (we assume all relevant updates to the configuration have - already been done) - - If a configuration is not provided, `kwargs` will be first passed to the configuration class - initialization function ([`~PretrainedConfig.from_pretrained`]). Each key of `kwargs` that - corresponds to a configuration attribute will be used to override said attribute with the - supplied `kwargs` value. Remaining keys that do not correspond to any configuration attribute - will be passed to the underlying model's `__init__` function. - - Examples: - - ```python - >>> from transformers import BertConfig, TFBertModel - - >>> # Download model and configuration from huggingface.co and cache. - >>> model = TFBertModel.from_pretrained("google-bert/bert-base-uncased") - >>> # Model was saved using *save_pretrained('./test/saved_model/')* (for example purposes, not runnable). - >>> model = TFBertModel.from_pretrained("./test/saved_model/") - >>> # Update configuration during loading. - >>> model = TFBertModel.from_pretrained("google-bert/bert-base-uncased", output_attentions=True) - >>> assert model.config.output_attentions == True - >>> # Loading from a Pytorch model file instead of a TensorFlow checkpoint (slower, for example purposes, not runnable). - >>> config = BertConfig.from_json_file("./pt_model/my_pt_model_config.json") - >>> model = TFBertModel.from_pretrained("./pt_model/my_pytorch_model.bin", from_pt=True, config=config) - ```""" - from_pt = kwargs.pop("from_pt", False) - resume_download = kwargs.pop("resume_download", None) - proxies = kwargs.pop("proxies", None) - output_loading_info = kwargs.pop("output_loading_info", False) - use_auth_token = kwargs.pop("use_auth_token", None) - trust_remote_code = kwargs.pop("trust_remote_code", None) - _ = kwargs.pop("mirror", None) - load_weight_prefix = kwargs.pop("load_weight_prefix", None) - from_pipeline = kwargs.pop("_from_pipeline", None) - from_auto_class = kwargs.pop("_from_auto", False) - subfolder = kwargs.pop("subfolder", "") - commit_hash = kwargs.pop("_commit_hash", None) - tf_to_pt_weight_rename = kwargs.pop("tf_to_pt_weight_rename", None) - - # Not relevant for TF models - _ = kwargs.pop("adapter_kwargs", None) - - if use_auth_token is not None: - warnings.warn( - "The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.", - FutureWarning, - ) - if token is not None: - raise ValueError( - "`token` and `use_auth_token` are both specified. Please set only the argument `token`." - ) - token = use_auth_token - - if trust_remote_code is True: - logger.warning( - "The argument `trust_remote_code` is to be used with Auto classes. It has no effect here and is" - " ignored." - ) - - user_agent = {"file_type": "model", "framework": "tensorflow", "from_auto_class": from_auto_class} - if from_pipeline is not None: - user_agent["using_pipeline"] = from_pipeline - - if is_offline_mode() and not local_files_only: - logger.info("Offline mode: forcing local_files_only=True") - local_files_only = True - - if use_safetensors is None and not is_safetensors_available(): - use_safetensors = False - - # Load config if we don't provide a configuration - if not isinstance(config, PretrainedConfig): - config_path = config if config is not None else pretrained_model_name_or_path - config, model_kwargs = cls.config_class.from_pretrained( - config_path, - cache_dir=cache_dir, - return_unused_kwargs=True, - force_download=force_download, - resume_download=resume_download, - proxies=proxies, - local_files_only=local_files_only, - token=token, - revision=revision, - _from_auto=from_auto_class, - _from_pipeline=from_pipeline, - _commit_hash=commit_hash, - **kwargs, - ) - else: - model_kwargs = kwargs - - if commit_hash is None: - commit_hash = getattr(config, "_commit_hash", None) - - # This variable will flag if we're loading a sharded checkpoint. In this case the archive file is just the - # index of the files. - is_sharded = False - # Load model - if pretrained_model_name_or_path is not None: - pretrained_model_name_or_path = str(pretrained_model_name_or_path) - is_local = os.path.isdir(pretrained_model_name_or_path) - if is_local: - if from_pt and os.path.isfile(os.path.join(pretrained_model_name_or_path, WEIGHTS_NAME)): - # Load from a PyTorch checkpoint in priority if from_pt - archive_file = os.path.join(pretrained_model_name_or_path, WEIGHTS_NAME) - elif from_pt and os.path.isfile(os.path.join(pretrained_model_name_or_path, WEIGHTS_INDEX_NAME)): - # Load from a sharded PyTorch checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, WEIGHTS_INDEX_NAME) - is_sharded = True - elif use_safetensors is not False and os.path.isfile( - os.path.join(pretrained_model_name_or_path, SAFE_WEIGHTS_NAME) - ): - # Load from a safetensors checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, SAFE_WEIGHTS_NAME) - elif use_safetensors is not False and os.path.isfile( - os.path.join(pretrained_model_name_or_path, SAFE_WEIGHTS_INDEX_NAME) - ): - # Load from a sharded safetensors checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, SAFE_WEIGHTS_INDEX_NAME) - is_sharded = True - elif os.path.isfile(os.path.join(pretrained_model_name_or_path, TF2_WEIGHTS_NAME)): - # Load from a TF 2.0 checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, TF2_WEIGHTS_NAME) - elif os.path.isfile(os.path.join(pretrained_model_name_or_path, TF2_WEIGHTS_INDEX_NAME)): - # Load from a sharded TF 2.0 checkpoint - archive_file = os.path.join(pretrained_model_name_or_path, TF2_WEIGHTS_INDEX_NAME) - is_sharded = True - - # At this stage we don't have a weight file so we will raise an error. - elif use_safetensors: - raise OSError( - f"Error no file named {SAFE_WEIGHTS_NAME} or {SAFE_WEIGHTS_INDEX_NAME} found in directory {pretrained_model_name_or_path}. " - f"Please make sure that the model has been saved with `safe_serialization=True` or do not " - f"set `use_safetensors=True`." - ) - elif os.path.isfile(os.path.join(pretrained_model_name_or_path, WEIGHTS_NAME)) or os.path.isfile( - os.path.join(pretrained_model_name_or_path, WEIGHTS_INDEX_NAME) - ): - raise OSError( - f"Error no file named {TF2_WEIGHTS_NAME} or {SAFE_WEIGHTS_NAME} found in directory {pretrained_model_name_or_path} " - "but there is a file for PyTorch weights. Use `from_pt=True` to load this model from those " - "weights." - ) - else: - raise OSError( - f"Error no file named {TF2_WEIGHTS_NAME}, {SAFE_WEIGHTS_NAME} or {WEIGHTS_NAME} found in directory " - f"{pretrained_model_name_or_path}." - ) - elif os.path.isfile(pretrained_model_name_or_path): - archive_file = pretrained_model_name_or_path - is_local = True - elif os.path.isfile(pretrained_model_name_or_path + ".index"): - archive_file = pretrained_model_name_or_path + ".index" - is_local = True - elif is_remote_url(pretrained_model_name_or_path): - filename = pretrained_model_name_or_path - resolved_archive_file = download_url(pretrained_model_name_or_path) - else: - # set correct filename - if from_pt: - filename = WEIGHTS_NAME - elif use_safetensors is not False: - filename = SAFE_WEIGHTS_NAME - else: - filename = TF2_WEIGHTS_NAME - - try: - # Load from URL or cache if already cached - cached_file_kwargs = { - "cache_dir": cache_dir, - "force_download": force_download, - "proxies": proxies, - "resume_download": resume_download, - "local_files_only": local_files_only, - "token": token, - "user_agent": user_agent, - "revision": revision, - "subfolder": subfolder, - "_raise_exceptions_for_gated_repo": False, - "_raise_exceptions_for_missing_entries": False, - "_commit_hash": commit_hash, - } - resolved_archive_file = cached_file(pretrained_model_name_or_path, filename, **cached_file_kwargs) - - # Since we set _raise_exceptions_for_missing_entries=False, we don't get an exception but a None - # result when internet is up, the repo and revision exist, but the file does not. - if resolved_archive_file is None and filename == SAFE_WEIGHTS_NAME: - # Did not find the safetensors file, let's fallback to TF. - # No support for sharded safetensors yet, so we'll raise an error if that's all we find. - filename = TF2_WEIGHTS_NAME - resolved_archive_file = cached_file( - pretrained_model_name_or_path, TF2_WEIGHTS_NAME, **cached_file_kwargs - ) - if resolved_archive_file is None and filename == TF2_WEIGHTS_NAME: - # Maybe the checkpoint is sharded, we try to grab the index name in this case. - resolved_archive_file = cached_file( - pretrained_model_name_or_path, TF2_WEIGHTS_INDEX_NAME, **cached_file_kwargs - ) - if resolved_archive_file is not None: - is_sharded = True - if resolved_archive_file is None and filename == WEIGHTS_NAME: - # Maybe the checkpoint is sharded, we try to grab the index name in this case. - resolved_archive_file = cached_file( - pretrained_model_name_or_path, WEIGHTS_INDEX_NAME, **cached_file_kwargs - ) - if resolved_archive_file is not None: - is_sharded = True - if resolved_archive_file is None: - # Otherwise, maybe there is a PyTorch or Flax model file. We try those to give a helpful error - # message. - has_file_kwargs = { - "revision": revision, - "proxies": proxies, - "token": token, - "cache_dir": cache_dir, - "local_files_only": local_files_only, - } - if has_file(pretrained_model_name_or_path, SAFE_WEIGHTS_INDEX_NAME, **has_file_kwargs): - is_sharded = True - elif has_file(pretrained_model_name_or_path, WEIGHTS_NAME, **has_file_kwargs): - raise OSError( - f"{pretrained_model_name_or_path} does not appear to have a file named" - f" {TF2_WEIGHTS_NAME} but there is a file for PyTorch weights. Use `from_pt=True` to" - " load this model from those weights." - ) - else: - raise OSError( - f"{pretrained_model_name_or_path} does not appear to have a file named {WEIGHTS_NAME}," - f" {TF2_WEIGHTS_NAME} or {TF_WEIGHTS_NAME}" - ) - - except OSError: - # Raise any environment error raise by `cached_file`. It will have a helpful error message adapted - # to the original exception. - raise - except Exception: - # For any other exception, we throw a generic error. - - raise OSError( - f"Can't load the model for '{pretrained_model_name_or_path}'. If you were trying to load it" - " from 'https://huggingface.co/models', make sure you don't have a local directory with the" - f" same name. Otherwise, make sure '{pretrained_model_name_or_path}' is the correct path to a" - f" directory containing a file named {WEIGHTS_NAME}, {TF2_WEIGHTS_NAME} or {TF_WEIGHTS_NAME}" - ) - if is_local: - logger.info(f"loading weights file {archive_file}") - resolved_archive_file = archive_file - filename = resolved_archive_file.split(os.path.sep)[-1] - else: - logger.info(f"loading weights file {filename} from cache at {resolved_archive_file}") - else: - resolved_archive_file = None - - # We'll need to download and cache each checkpoint shard if the checkpoint is sharded. - if is_sharded: - # resolved_archive_file becomes a list of files that point to the different checkpoint shards in this case. - resolved_archive_file, sharded_metadata = get_checkpoint_shard_files( - pretrained_model_name_or_path, - resolved_archive_file, - cache_dir=cache_dir, - force_download=force_download, - proxies=proxies, - resume_download=resume_download, - local_files_only=local_files_only, - token=token, - user_agent=user_agent, - revision=revision, - _commit_hash=commit_hash, - ) - - safetensors_from_pt = False - if filename == SAFE_WEIGHTS_NAME: - with safe_open(resolved_archive_file, framework="tf") as f: - safetensors_metadata = f.metadata() - if safetensors_metadata is None or safetensors_metadata.get("format") not in ["pt", "tf", "flax", "mlx"]: - raise OSError( - f"The safetensors archive passed at {resolved_archive_file} does not contain the valid metadata." - " Make sure you save your model with the `save_pretrained` method." - ) - safetensors_from_pt = safetensors_metadata.get("format") == "pt" - elif filename == SAFE_WEIGHTS_INDEX_NAME: - with safe_open(resolved_archive_file[0], framework="tf") as f: - safetensors_metadata = f.metadata() - if safetensors_metadata is None or safetensors_metadata.get("format") not in ["pt", "tf", "flax", "mlx"]: - raise OSError( - f"The safetensors archive passed at {resolved_archive_file} does not contain the valid metadata." - " Make sure you save your model with the `save_pretrained` method." - ) - safetensors_from_pt = safetensors_metadata.get("format") == "pt" - - config.name_or_path = pretrained_model_name_or_path - - # composed models, *e.g.* TFRag, require special treatment when it comes to loading - # pre-trained weights. - if cls._requires_load_weight_prefix and model_kwargs.get("name") is not None: - model_kwargs["load_weight_prefix"] = load_weight_prefix + "/" + model_kwargs.get("name") - - # Instantiate model. - model = cls(config, *model_args, **model_kwargs) - - if tf_to_pt_weight_rename is None and hasattr(model, "tf_to_pt_weight_rename"): - # TODO Matt: This is a temporary workaround to allow weight renaming, but requires a method - # to be defined for each class that requires a rename. We can probably just have a class-level - # dict and a single top-level method or something and cut down a lot of boilerplate code - tf_to_pt_weight_rename = model.tf_to_pt_weight_rename - - if from_pt: - from .modeling_tf_pytorch_utils import load_pytorch_checkpoint_in_tf2_model - - # Load from a PyTorch checkpoint - return load_pytorch_checkpoint_in_tf2_model( - model, - resolved_archive_file, - allow_missing_keys=True, - output_loading_info=output_loading_info, - _prefix=load_weight_prefix, - tf_to_pt_weight_rename=tf_to_pt_weight_rename, - ) - - # we might need to extend the variable scope for composite models - if load_weight_prefix is not None: - with tf.compat.v1.variable_scope(load_weight_prefix): - model.build_in_name_scope() # build the network with dummy inputs - else: - model.build_in_name_scope() # build the network with dummy inputs - - if safetensors_from_pt and not is_sharded: - from .modeling_tf_pytorch_utils import load_pytorch_state_dict_in_tf2_model - - with safe_open(resolved_archive_file, framework="tf") as safetensors_archive: - # Load from a PyTorch safetensors checkpoint - # We load in TF format here because PT weights often need to be transposed, and this is much - # faster on GPU. Loading as numpy and transposing on CPU adds several seconds to load times. - return load_pytorch_state_dict_in_tf2_model( - model, - safetensors_archive, - tf_inputs=False, # No need to build the model again - allow_missing_keys=True, - output_loading_info=output_loading_info, - _prefix=load_weight_prefix, - ignore_mismatched_sizes=ignore_mismatched_sizes, - tf_to_pt_weight_rename=tf_to_pt_weight_rename, - ) - elif safetensors_from_pt: - from .modeling_tf_pytorch_utils import load_sharded_pytorch_safetensors_in_tf2_model - - return load_sharded_pytorch_safetensors_in_tf2_model( - model, - resolved_archive_file, - tf_inputs=False, - allow_missing_keys=True, - output_loading_info=output_loading_info, - _prefix=load_weight_prefix, - ignore_mismatched_sizes=ignore_mismatched_sizes, - tf_to_pt_weight_rename=tf_to_pt_weight_rename, - ) - - # 'by_name' allow us to do transfer learning by skipping/adding layers - # see https://github.com/tensorflow/tensorflow/blob/00fad90125b18b80fe054de1055770cfb8fe4ba3/tensorflow/python/keras/engine/network.py#L1339-L1357 - try: - if is_sharded: - for file in resolved_archive_file: - os.path.isfile(file), f"Error retrieving files {file}" - if filename == SAFE_WEIGHTS_INDEX_NAME: - missing_keys, unexpected_keys, mismatched_keys = load_tf_sharded_weights_from_safetensors( - model, - resolved_archive_file, - ignore_mismatched_sizes=ignore_mismatched_sizes, - _prefix=load_weight_prefix, - ) - else: - missing_keys, unexpected_keys, mismatched_keys = load_tf_sharded_weights( - model, - resolved_archive_file, - ignore_mismatched_sizes=ignore_mismatched_sizes, - _prefix=load_weight_prefix, - ) - else: - # Handles both H5 and safetensors - missing_keys, unexpected_keys, mismatched_keys = load_tf_weights( - model, - resolved_archive_file, - ignore_mismatched_sizes=ignore_mismatched_sizes, - _prefix=load_weight_prefix, - ) - except OSError as e: - try: - with open(resolved_archive_file) as f: - if f.read().startswith("version"): - raise OSError( - "You seem to have cloned a repository without having git-lfs installed. Please install " - "git-lfs and run `git lfs install` followed by `git lfs pull` in the folder " - "you cloned." - ) - else: - raise ValueError from e - except (UnicodeDecodeError, ValueError): - raise OSError( - "Unable to load weights from h5 file. " - "If you tried to load a TF 2.0 model from a PyTorch checkpoint, please set from_pt=True. " - ) - - if cls._keys_to_ignore_on_load_missing is not None: - for pat in cls._keys_to_ignore_on_load_missing: - missing_keys = [k for k in missing_keys if re.search(pat, k) is None] - - if cls._keys_to_ignore_on_load_unexpected is not None: - for pat in cls._keys_to_ignore_on_load_unexpected: - unexpected_keys = [k for k in unexpected_keys if re.search(pat, k) is None] - - if len(unexpected_keys) > 0: - logger.warning( - f"Some layers from the model checkpoint at {pretrained_model_name_or_path} were not used when" - f" initializing {model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are" - f" initializing {model.__class__.__name__} from the checkpoint of a model trained on another task or" - " with another architecture (e.g. initializing a BertForSequenceClassification model from a" - " BertForPreTraining model).\n- This IS NOT expected if you are initializing" - f" {model.__class__.__name__} from the checkpoint of a model that you expect to be exactly identical" - " (initializing a BertForSequenceClassification model from a BertForSequenceClassification model)." - ) - else: - logger.warning(f"All model checkpoint layers were used when initializing {model.__class__.__name__}.\n") - - if len(missing_keys) > 0: - logger.warning( - f"Some layers of {model.__class__.__name__} were not initialized from the model checkpoint at" - f" {pretrained_model_name_or_path} and are newly initialized: {missing_keys}\nYou should probably" - " TRAIN this model on a down-stream task to be able to use it for predictions and inference." - ) - elif len(mismatched_keys) == 0: - logger.warning( - f"All the layers of {model.__class__.__name__} were initialized from the model checkpoint at" - f" {pretrained_model_name_or_path}.\nIf your task is similar to the task the model of the checkpoint" - f" was trained on, you can already use {model.__class__.__name__} for predictions without further" - " training." - ) - if len(mismatched_keys) > 0: - mismatched_warning = "\n".join( - [ - f"- {key}: found shape {shape1} in the checkpoint and {shape2} in the model instantiated" - for key, shape1, shape2 in mismatched_keys - ] - ) - logger.warning( - f"Some weights of {model.__class__.__name__} were not initialized from the model checkpoint at" - f" {pretrained_model_name_or_path} and are newly initialized because the shapes did not" - f" match:\n{mismatched_warning}\nYou should probably TRAIN this model on a down-stream task to be able" - " to use it for predictions and inference." - ) - - # If it is a model with generation capabilities, attempt to load the generation config - if model.can_generate(): - try: - model.generation_config = GenerationConfig.from_pretrained( - pretrained_model_name_or_path, - cache_dir=cache_dir, - force_download=force_download, - resume_download=resume_download, - proxies=proxies, - local_files_only=local_files_only, - token=token, - revision=revision, - subfolder=subfolder, - _from_auto=from_auto_class, - _from_pipeline=from_pipeline, - **kwargs, - ) - except OSError: - logger.info( - "Generation config file not found, using a generation config created from the model config." - ) - pass - - if output_loading_info: - loading_info = { - "missing_keys": missing_keys, - "unexpected_keys": unexpected_keys, - "mismatched_keys": mismatched_keys, - } - - return model, loading_info - - return model - - def push_to_hub( - self, - repo_id: str, - use_temp_dir: bool | None = None, - commit_message: str | None = None, - private: bool | None = None, - max_shard_size: int | str | None = "10GB", - token: bool | str | None = None, - # (`use_auth_token` is deprecated: we have to keep it here as we don't have **kwargs) - use_auth_token: bool | str | None = None, - create_pr: bool = False, - **base_model_card_args, - ) -> str: - """ - Upload the model files to the 🤗 Model Hub while synchronizing a local clone of the repo in `repo_path_or_name`. - - Parameters: - repo_id (`str`): - The name of the repository you want to push your model to. It should contain your organization name - when pushing to a given organization. - use_temp_dir (`bool`, *optional*): - Whether or not to use a temporary directory to store the files saved before they are pushed to the Hub. - Will default to `True` if there is no directory named like `repo_id`, `False` otherwise. - commit_message (`str`, *optional*): - Message to commit while pushing. Will default to `"Upload model"`. - private (`bool`, *optional*): - Whether to make the repo private. If `None` (default), the repo will be public unless the organization's default is private. This value is ignored if the repo already exists. - token (`bool` or `str`, *optional*): - The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated - when running `hf auth login` (stored in `~/.huggingface`). Will default to `True` if `repo_url` - is not specified. - max_shard_size (`int` or `str`, *optional*, defaults to `"10GB"`): - Only applicable for models. The maximum size for a checkpoint before being sharded. Checkpoints shard - will then be each of size lower than this size. If expressed as a string, needs to be digits followed - by a unit (like `"5MB"`). - create_pr (`bool`, *optional*, defaults to `False`): - Whether or not to create a PR with the uploaded files or directly commit. - - Examples: - - ```python - from transformers import TFAutoModel - - model = TFAutoModel.from_pretrained("google-bert/bert-base-cased") - - # Push the model to your namespace with the name "my-finetuned-bert". - model.push_to_hub("my-finetuned-bert") - - # Push the model to an organization with the name "my-finetuned-bert". - model.push_to_hub("huggingface/my-finetuned-bert") - ``` - """ - if use_auth_token is not None: - warnings.warn( - "The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.", - FutureWarning, - ) - if token is not None: - raise ValueError( - "`token` and `use_auth_token` are both specified. Please set only the argument `token`." - ) - token = use_auth_token - - if "repo_path_or_name" in base_model_card_args: - warnings.warn( - "The `repo_path_or_name` argument is deprecated and will be removed in v5 of Transformers. Use " - "`repo_id` instead." - ) - repo_id = base_model_card_args.pop("repo_path_or_name") - # Deprecation warning will be sent after for repo_url and organization - repo_url = base_model_card_args.pop("repo_url", None) - organization = base_model_card_args.pop("organization", None) - - if os.path.isdir(repo_id): - working_dir = repo_id - repo_id = repo_id.split(os.path.sep)[-1] - else: - working_dir = repo_id.split("/")[-1] - - repo_id = self._create_repo( - repo_id, private=private, token=token, repo_url=repo_url, organization=organization - ) - - if use_temp_dir is None: - use_temp_dir = not os.path.isdir(working_dir) - - with working_or_temp_dir(working_dir=working_dir, use_temp_dir=use_temp_dir) as work_dir: - files_timestamps = self._get_files_timestamps(work_dir) - - # Save all files. - self.save_pretrained(work_dir, max_shard_size=max_shard_size) - if hasattr(self, "history") and hasattr(self, "create_model_card"): - # This is a Keras model and we might be able to fish out its History and make a model card out of it - base_model_card_args = { - "output_dir": work_dir, - "model_name": Path(repo_id).name, - } - base_model_card_args.update(base_model_card_args) - self.create_model_card(**base_model_card_args) - - self._upload_modified_files( - work_dir, - repo_id, - files_timestamps, - commit_message=commit_message, - token=token, - create_pr=create_pr, - ) - - @classmethod - def register_for_auto_class(cls, auto_class="TFAutoModel"): - """ - Register this class with a given auto class. This should only be used for custom models as the ones in the - library are already mapped with an auto class. - - - - Args: - auto_class (`str` or `type`, *optional*, defaults to `"TFAutoModel"`): - The auto class to register this new model with. - """ - if not isinstance(auto_class, str): - auto_class = auto_class.__name__ - - import transformers.models.auto as auto_module - - if not hasattr(auto_module, auto_class): - raise ValueError(f"{auto_class} is not a valid auto class.") - - cls._auto_class = auto_class - - -class TFConv1D(keras.layers.Layer): - """ - 1D-convolutional layer as defined by Radford et al. for OpenAI GPT (and also used in GPT-2). - - Basically works like a linear layer but the weights are transposed. - - Args: - nf (`int`): - The number of output features. - nx (`int`): - The number of input features. - initializer_range (`float`, *optional*, defaults to 0.02): - The standard deviation to use to initialize the weights. - kwargs (`dict[str, Any]`, *optional*): - Additional keyword arguments passed along to the `__init__` of `keras.layers.Layer`. - """ - - def __init__(self, nf, nx, initializer_range=0.02, **kwargs): - super().__init__(**kwargs) - self.nf = nf - self.nx = nx - self.initializer_range = initializer_range - - def build(self, input_shape): - if self.built: - return - self.built = True - self.weight = self.add_weight( - "weight", shape=[self.nx, self.nf], initializer=get_initializer(self.initializer_range) - ) - self.bias = self.add_weight("bias", shape=[1, self.nf], initializer=tf.zeros_initializer()) - - def call(self, x): - bz, sl = shape_list(x)[:2] - - x = tf.reshape(x, [-1, self.nx]) - x = tf.matmul(x, self.weight) + self.bias - - x = tf.reshape(x, [bz, sl, self.nf]) - - return x - - -class TFSharedEmbeddings(keras.layers.Layer): - r""" - Construct shared token embeddings. - - The weights of the embedding layer is usually shared with the weights of the linear decoder when doing language - modeling. - - Args: - vocab_size (`int`): - The size of the vocabulary, e.g., the number of unique tokens. - hidden_size (`int`): - The size of the embedding vectors. - initializer_range (`float`, *optional*): - The standard deviation to use when initializing the weights. If no value is provided, it will default to - \\(1/\sqrt{hidden\_size}\\). - kwargs (`dict[str, Any]`, *optional*): - Additional keyword arguments passed along to the `__init__` of `keras.layers.Layer`. - """ - - # TODO (joao): flagged for detection due to embeddings refactor - - def __init__(self, vocab_size: int, hidden_size: int, initializer_range: float | None = None, **kwargs): - super().__init__(**kwargs) - self.vocab_size = vocab_size - self.hidden_size = hidden_size - self.initializer_range = hidden_size**-0.5 if initializer_range is None else initializer_range - warnings.warn( - "`TFSharedEmbeddings` is scheduled for deletion in v4.32, use `keras.layers.Embedding` instead.", - DeprecationWarning, - ) - - def build(self, input_shape): - """ - Build shared token embedding layer Shared weights logic adapted from - https://github.com/tensorflow/models/blob/a009f4fb9d2fc4949e32192a944688925ef78659/official/transformer/v2/embedding_layer.py#L24 - """ - self.weight = self.add_weight( - "weight", shape=[self.vocab_size, self.hidden_size], initializer=get_initializer(self.initializer_range) - ) - super().build(input_shape) - - def get_config(self): - config = { - "vocab_size": self.vocab_size, - "hidden_size": self.hidden_size, - "initializer_range": self.initializer_range, - } - base_config = super().get_config() - - return dict(list(base_config.items()) + list(config.items())) - - def call(self, inputs: tf.Tensor, mode: str = "embedding") -> tf.Tensor: - """ - Get token embeddings of inputs or decode final hidden state. - - Args: - inputs (`tf.Tensor`): - In embedding mode, should be an int64 tensor with shape `[batch_size, length]`. - - In linear mode, should be a float tensor with shape `[batch_size, length, hidden_size]`. - mode (`str`, defaults to `"embedding"`): - A valid value is either `"embedding"` or `"linear"`, the first one indicates that the layer should be - used as an embedding layer, the second one that the layer should be used as a linear decoder. - - Returns: - `tf.Tensor`: In embedding mode, the output is a float32 embedding tensor, with shape `[batch_size, length, - embedding_size]`. - - In linear mode, the output is a float32 with shape `[batch_size, length, vocab_size]`. - - Raises: - ValueError: if `mode` is not valid. - - Shared weights logic is adapted from - [here](https://github.com/tensorflow/models/blob/a009f4fb9d2fc4949e32192a944688925ef78659/official/transformer/v2/embedding_layer.py#L24). - """ - if mode == "embedding": - return self._embedding(inputs) - elif mode == "linear": - return self._linear(inputs) - else: - raise ValueError(f"mode {mode} is not valid.") - - def _embedding(self, input_ids): - """Applies embedding based on inputs tensor.""" - return tf.gather(self.weight, input_ids) - - def _linear(self, inputs): - """ - Computes logits by running inputs through a linear layer. - - Args: - inputs: A float32 tensor with shape [..., hidden_size] - - Returns: - float32 tensor with shape [..., vocab_size]. - """ - first_dims = shape_list(inputs)[:-1] - x = tf.reshape(inputs, [-1, self.hidden_size]) - logits = tf.matmul(x, self.weight, transpose_b=True) - - return tf.reshape(logits, first_dims + [self.vocab_size]) - - -class TFSequenceSummary(keras.layers.Layer): - """ - Compute a single vector summary of a sequence hidden states. - - Args: - config ([`PretrainedConfig`]): - The config used by the model. Relevant arguments in the config class of the model are (refer to the actual - config class of your model for the default values it uses): - - - **summary_type** (`str`) -- The method to use to make this summary. Accepted values are: - - - `"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 (GPT/GPT-2) - - `"attn"` -- Not implemented now, use multi-head attention - - - **summary_use_proj** (`bool`) -- Add a projection after the vector extraction. - - **summary_proj_to_labels** (`bool`) -- If `True`, the projection outputs to `config.num_labels` classes - (otherwise to `config.hidden_size`). - - **summary_activation** (`Optional[str]`) -- Set to `"tanh"` to add a tanh activation to the output, - another string or `None` will add no activation. - - **summary_first_dropout** (`float`) -- Optional dropout probability before the projection and activation. - - **summary_last_dropout** (`float`)-- Optional dropout probability after the projection and activation. - - initializer_range (`float`, *optional*, defaults to 0.02): The standard deviation to use to initialize the weights. - kwargs (`dict[str, Any]`, *optional*): - Additional keyword arguments passed along to the `__init__` of `keras.layers.Layer`. - """ - - def __init__(self, config: PretrainedConfig, initializer_range: float = 0.02, **kwargs): - super().__init__(**kwargs) - - self.summary_type = config.summary_type if hasattr(config, "summary_use_proj") else "last" - if self.summary_type == "attn": - # We should use a standard multi-head attention module with absolute positional embedding for that. - # Cf. https://github.com/zihangdai/xlnet/blob/master/modeling.py#L253-L276 - # We can probably just use the multi-head attention module of PyTorch >=1.1.0 - raise NotImplementedError - - self.has_summary = hasattr(config, "summary_use_proj") and config.summary_use_proj - if self.has_summary: - if hasattr(config, "summary_proj_to_labels") and config.summary_proj_to_labels and config.num_labels > 0: - num_classes = config.num_labels - else: - num_classes = config.hidden_size - self.summary = keras.layers.Dense( - num_classes, kernel_initializer=get_initializer(initializer_range), name="summary" - ) - - self.has_activation = False - activation_string = getattr(config, "summary_activation", None) - if activation_string is not None: - self.has_activation = True - self.activation = get_tf_activation(activation_string) - - self.has_first_dropout = hasattr(config, "summary_first_dropout") and config.summary_first_dropout > 0 - if self.has_first_dropout: - self.first_dropout = keras.layers.Dropout(config.summary_first_dropout) - - self.has_last_dropout = hasattr(config, "summary_last_dropout") and config.summary_last_dropout > 0 - if self.has_last_dropout: - self.last_dropout = keras.layers.Dropout(config.summary_last_dropout) - self.hidden_size = config.hidden_size - - def call(self, inputs, cls_index=None, training=False): - if not isinstance(inputs, (dict, tuple, list)): - hidden_states = inputs - elif isinstance(inputs, (tuple, list)): - hidden_states = inputs[0] - cls_index = inputs[1] if len(inputs) > 1 else None - assert len(inputs) <= 2, "Too many inputs." - else: - hidden_states = inputs.get("hidden_states") - cls_index = inputs.get("cls_index", None) - - if self.summary_type == "last": - output = hidden_states[:, -1] - elif self.summary_type == "first": - output = hidden_states[:, 0] - elif self.summary_type == "mean": - output = tf.reduce_mean(hidden_states, axis=1) - elif self.summary_type == "cls_index": - hidden_shape = shape_list(hidden_states) # e.g. [batch, num choices, seq length, hidden dims] - if cls_index is None: - cls_index = tf.fill( - hidden_shape[:-2], hidden_shape[-2] - 1 - ) # A tensor full of shape [batch] or [batch, num choices] full of sequence length - cls_shape = shape_list(cls_index) - if len(cls_shape) <= len(hidden_shape) - 2: - cls_index = tf.expand_dims(cls_index, axis=-1) - # else: - # cls_index = cls_index[..., tf.newaxis] - # cls_index = cls_index.expand((-1,) * (cls_index.dim()-1) + (hidden_states.size(-1),)) - # shape of cls_index: (bsz, XX, 1, hidden_size) where XX are optional leading dim of hidden_states - output = tf.gather(hidden_states, cls_index, batch_dims=len(hidden_shape) - 2) - output = tf.squeeze( - output, axis=len(hidden_shape) - 2 - ) # shape of output: (batch, num choices, hidden_size) - elif self.summary_type == "attn": - raise NotImplementedError - - if self.has_first_dropout: - output = self.first_dropout(output, training=training) - - if self.has_summary: - output = self.summary(output) - - if self.has_activation: - output = self.activation(output) - - if self.has_last_dropout: - output = self.last_dropout(output, training=training) - - return output - - def build(self, input_shape): - if self.built: - return - self.built = True - if getattr(self, "summary", None) is not None: - with tf.name_scope("summary"): - self.summary.build(self.hidden_size) - - -def get_initializer(initializer_range: float = 0.02) -> keras.initializers.TruncatedNormal: - """ - Creates a `keras.initializers.TruncatedNormal` with the given range. - - Args: - initializer_range (*float*, defaults to 0.02): Standard deviation of the initializer range. - - Returns: - `keras.initializers.TruncatedNormal`: The truncated normal initializer. - """ - return keras.initializers.TruncatedNormal(stddev=initializer_range) diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index 12c3e7cd99ef..31783d041fe4 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -79,11 +79,8 @@ ADAPTER_WEIGHTS_NAME, CONFIG_NAME, DUMMY_INPUTS, - FLAX_WEIGHTS_NAME, SAFE_WEIGHTS_INDEX_NAME, SAFE_WEIGHTS_NAME, - TF2_WEIGHTS_NAME, - TF_WEIGHTS_NAME, WEIGHTS_INDEX_NAME, WEIGHTS_NAME, ContextManagers, @@ -506,13 +503,6 @@ def load_state_dict( # Use safetensors if possible if checkpoint_file.endswith(".safetensors") and is_safetensors_available(): with safe_open(checkpoint_file, framework="pt") as f: - metadata = f.metadata() - - if metadata is not None and metadata.get("format") not in ["pt", "tf", "flax", "mlx"]: - raise OSError( - f"The safetensors archive passed at {checkpoint_file} does not contain the valid metadata. Make sure " - "you save your model with the `save_pretrained` method." - ) state_dict = {} for k in f.keys(): if map_location == "meta": @@ -568,11 +558,7 @@ def load_state_dict( "model. Make sure you have saved the model properly." ) from e except (UnicodeDecodeError, ValueError): - raise OSError( - f"Unable to load weights from pytorch checkpoint file for '{checkpoint_file}' " - f"at '{checkpoint_file}'. " - "If you tried to load a PyTorch model from a TF 2.0 checkpoint, please set from_tf=True." - ) + raise OSError(f"Unable to load weights from pytorch checkpoint file '{checkpoint_file}'.") def set_initialized_submodules(model, state_dict_keys): @@ -1004,9 +990,7 @@ def _get_resolved_checkpoint_files( subfolder: str, variant: Optional[str], gguf_file: Optional[str], - from_tf: bool, - from_flax: bool, - use_safetensors: bool, + use_safetensors: Optional[bool], cache_dir: str, force_download: bool, proxies: Optional[dict[str, str]], @@ -1032,19 +1016,6 @@ def _get_resolved_checkpoint_files( # If the filename is explicitly defined, load this by default. archive_file = os.path.join(pretrained_model_name_or_path, subfolder, transformers_explicit_filename) is_sharded = transformers_explicit_filename.endswith(".safetensors.index.json") - elif from_tf and os.path.isfile( - os.path.join(pretrained_model_name_or_path, subfolder, TF_WEIGHTS_NAME + ".index") - ): - # Load from a TF 1.0 checkpoint in priority if from_tf - archive_file = os.path.join(pretrained_model_name_or_path, subfolder, TF_WEIGHTS_NAME + ".index") - elif from_tf and os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, TF2_WEIGHTS_NAME)): - # Load from a TF 2.0 checkpoint in priority if from_tf - archive_file = os.path.join(pretrained_model_name_or_path, subfolder, TF2_WEIGHTS_NAME) - elif from_flax and os.path.isfile( - os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_NAME) - ): - # Load from a Flax checkpoint in priority if from_flax - archive_file = os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_NAME) elif use_safetensors is not False and os.path.isfile( os.path.join(pretrained_model_name_or_path, subfolder, _add_variant(SAFE_WEIGHTS_NAME, variant)) ): @@ -1075,24 +1046,6 @@ def _get_resolved_checkpoint_files( pretrained_model_name_or_path, subfolder, _add_variant(WEIGHTS_INDEX_NAME, variant) ) is_sharded = True - # At this stage we don't have a weight file so we will raise an error. - elif not use_safetensors and ( - os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, TF_WEIGHTS_NAME + ".index")) - or os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, TF2_WEIGHTS_NAME)) - ): - raise OSError( - f"Error no file named {_add_variant(WEIGHTS_NAME, variant)} found in directory" - f" {pretrained_model_name_or_path} but there is a file for TensorFlow weights. Use" - " `from_tf=True` to load this model from those weights." - ) - elif not use_safetensors and os.path.isfile( - os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_NAME) - ): - raise OSError( - f"Error no file named {_add_variant(WEIGHTS_NAME, variant)} found in directory" - f" {pretrained_model_name_or_path} but there is a file for Flax weights. Use `from_flax=True`" - " to load this model from those weights." - ) elif use_safetensors: raise OSError( f"Error no file named {_add_variant(SAFE_WEIGHTS_NAME, variant)} found in directory" @@ -1100,21 +1053,12 @@ def _get_resolved_checkpoint_files( ) else: raise OSError( - f"Error no file named {_add_variant(WEIGHTS_NAME, variant)}, {_add_variant(SAFE_WEIGHTS_NAME, variant)}," - f" {TF2_WEIGHTS_NAME}, {TF_WEIGHTS_NAME + '.index'} or {FLAX_WEIGHTS_NAME} found in directory" - f" {pretrained_model_name_or_path}." + f"Error no file named {_add_variant(SAFE_WEIGHTS_NAME, variant)}, or {_add_variant(WEIGHTS_NAME, variant)}," + f" found in directory {pretrained_model_name_or_path}." ) elif os.path.isfile(os.path.join(subfolder, pretrained_model_name_or_path)): archive_file = pretrained_model_name_or_path is_local = True - elif os.path.isfile(os.path.join(subfolder, pretrained_model_name_or_path + ".index")): - if not from_tf: - raise ValueError( - f"We found a TensorFlow checkpoint at {pretrained_model_name_or_path + '.index'}, please set " - "from_tf to True to load from this checkpoint." - ) - archive_file = os.path.join(subfolder, pretrained_model_name_or_path + ".index") - is_local = True elif is_remote_url(pretrained_model_name_or_path): filename = pretrained_model_name_or_path resolved_archive_file = download_url(pretrained_model_name_or_path) @@ -1123,10 +1067,6 @@ def _get_resolved_checkpoint_files( if transformers_explicit_filename is not None: filename = transformers_explicit_filename is_sharded = transformers_explicit_filename.endswith(".safetensors.index.json") - elif from_tf: - filename = TF2_WEIGHTS_NAME - elif from_flax: - filename = FLAX_WEIGHTS_NAME elif use_safetensors is not False: filename = _add_variant(SAFE_WEIGHTS_NAME, variant) else: @@ -1223,8 +1163,7 @@ def _get_resolved_checkpoint_files( name="Thread-auto_conversion", ).start() else: - # Otherwise, no PyTorch file was found, maybe there is a TF or Flax model file. - # We try those to give a helpful error message. + # Otherwise, no PyTorch file was found has_file_kwargs = { "revision": revision, "proxies": proxies, @@ -1232,19 +1171,7 @@ def _get_resolved_checkpoint_files( "cache_dir": cache_dir, "local_files_only": local_files_only, } - if has_file(pretrained_model_name_or_path, TF2_WEIGHTS_NAME, **has_file_kwargs): - raise OSError( - f"{pretrained_model_name_or_path} does not appear to have a file named" - f" {_add_variant(WEIGHTS_NAME, variant)} but there is a file for TensorFlow weights." - " Use `from_tf=True` to load this model from those weights." - ) - elif has_file(pretrained_model_name_or_path, FLAX_WEIGHTS_NAME, **has_file_kwargs): - raise OSError( - f"{pretrained_model_name_or_path} does not appear to have a file named" - f" {_add_variant(WEIGHTS_NAME, variant)} but there is a file for Flax weights. Use" - " `from_flax=True` to load this model from those weights." - ) - elif variant is not None and has_file( + if variant is not None and has_file( pretrained_model_name_or_path, WEIGHTS_NAME, **has_file_kwargs ): raise OSError( @@ -1255,8 +1182,7 @@ def _get_resolved_checkpoint_files( else: raise OSError( f"{pretrained_model_name_or_path} does not appear to have a file named" - f" {_add_variant(WEIGHTS_NAME, variant)}, {_add_variant(SAFE_WEIGHTS_NAME, variant)}," - f" {TF2_WEIGHTS_NAME}, {TF_WEIGHTS_NAME} or {FLAX_WEIGHTS_NAME}." + f" {_add_variant(WEIGHTS_NAME, variant)} or {_add_variant(SAFE_WEIGHTS_NAME, variant)}." ) except OSError: @@ -1269,8 +1195,7 @@ def _get_resolved_checkpoint_files( f"Can't load the model for '{pretrained_model_name_or_path}'. If you were trying to load it" " from 'https://huggingface.co/models', make sure you don't have a local directory with the" f" same name. Otherwise, make sure '{pretrained_model_name_or_path}' is the correct path to a" - f" directory containing a file named {_add_variant(WEIGHTS_NAME, variant)}," - f" {TF2_WEIGHTS_NAME}, {TF_WEIGHTS_NAME} or {FLAX_WEIGHTS_NAME}." + f" directory containing a file named {_add_variant(WEIGHTS_NAME, variant)}." ) from e if is_local: @@ -1682,8 +1607,6 @@ def invert_attention_mask(self, encoder_attention_mask: Tensor) -> Tensor: if encoder_attention_mask.dim() == 2: encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow - # /transformer/transformer_layers.py#L270 # encoder_extended_attention_mask = (encoder_extended_attention_mask == # encoder_extended_attention_mask.transpose(-1, -2)) encoder_extended_attention_mask = encoder_extended_attention_mask.to(dtype=self.dtype) # fp16 compatibility @@ -2018,19 +1941,13 @@ class PreTrainedModel(nn.Module, EmbeddingAccessMixin, ModuleUtilsMixin, PushToH - **config_class** ([`PretrainedConfig`]) -- A subclass of [`PretrainedConfig`] to use as configuration class for this model architecture. - - **load_tf_weights** (`Callable`) -- A python *method* for loading a TensorFlow checkpoint in a PyTorch model, - taking as arguments: - - - **model** ([`PreTrainedModel`]) -- An instance of the model on which to load the TensorFlow checkpoint. - - **config** ([`PreTrainedConfig`]) -- An instance of the configuration associated to the model. - - **path** (`str`) -- A path to the TensorFlow checkpoint. - - **base_model_prefix** (`str`) -- A string indicating the attribute associated to the base model in derived classes of the same architecture adding modules on top of the base model. - **is_parallelizable** (`bool`) -- A flag indicating whether this model supports model parallelization. - **main_input_name** (`str`) -- The name of the principal input to the model (often `input_ids` for NLP models, `pixel_values` for vision models and `input_values` for speech models). - - **can_record_outputs** (dict):""" + - **can_record_outputs** (dict): + """ config_class = None base_model_prefix = "" @@ -2155,13 +2072,6 @@ def dummy_inputs(self) -> dict[str, torch.Tensor]: """ return {"input_ids": torch.tensor(DUMMY_INPUTS)} - @property - def framework(self) -> str: - """ - :str: Identifies that this is a PyTorch model. - """ - return "pt" - def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) # For BC we keep the original `config_class` definition in case @@ -3800,9 +3710,6 @@ def gradient_checkpointing_enable(self, gradient_checkpointing_kwargs=None): """ Activates gradient checkpointing for the current model. - Note that in other frameworks this feature can be referred to as "activation checkpointing" or "checkpoint - activations". - We pass the `__call__` method of the modules instead of `forward` because `__call__` attaches all the hooks of the module. https://discuss.pytorch.org/t/any-different-between-model-input-and-model-forward-input/3690/2 @@ -3863,9 +3770,6 @@ def _set_gradient_checkpointing(self, enable: bool = True, gradient_checkpointin def gradient_checkpointing_disable(self): """ Deactivates gradient checkpointing for the current model. - - Note that in other frameworks this feature can be referred to as "activation checkpointing" or "checkpoint - activations". """ if self.supports_gradient_checkpointing: # For old GC format (transformers < 4.35.0) for models that live on the Hub @@ -3887,9 +3791,6 @@ def gradient_checkpointing_disable(self): def is_gradient_checkpointing(self) -> bool: """ Whether gradient checkpointing is activated for this model or not. - - Note that in other frameworks this feature can be referred to as "activation checkpointing" or "checkpoint - activations". """ return any(hasattr(m, "gradient_checkpointing") and m.gradient_checkpointing for m in self.modules()) @@ -4543,13 +4444,6 @@ def from_pretrained( - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In - this case, `from_tf` should be set to `True` and a configuration object should be provided as - `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a - PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. - - A path or url to a model folder containing a *flax checkpoint file* in *.msgpack* format (e.g, - `./flax_model/` containing `flax_model.msgpack`). In this case, `from_flax` should be set to - `True`. - `None` if you are both providing the configuration and state dictionary (resp. with keyword arguments `config` and `state_dict`). model_args (sequence of positional arguments, *optional*): @@ -4578,12 +4472,6 @@ def from_pretrained( cache_dir (`Union[str, os.PathLike]`, *optional*): Path to a directory in which a downloaded pretrained model configuration should be cached if the standard cache should not be used. - from_tf (`bool`, *optional*, defaults to `False`): - Load the model weights from a TensorFlow checkpoint save file (see docstring of - `pretrained_model_name_or_path` argument). - from_flax (`bool`, *optional*, defaults to `False`): - Load the model weights from a Flax checkpoint save file (see docstring of - `pretrained_model_name_or_path` argument). ignore_mismatched_sizes (`bool`, *optional*, defaults to `False`): Whether or not to raise an error if some of the weights from the checkpoint do not have the same size as the weights of the model (if for instance, you are instantiating a model with 10 labels from a @@ -4699,8 +4587,7 @@ def from_pretrained( In case the relevant files are located inside a subfolder of the model repo on huggingface.co, you can specify the folder name here. variant (`str`, *optional*): - If specified load weights from `variant` filename, *e.g.* pytorch_model..bin. `variant` is - ignored when using `from_tf` or `from_flax`. + If specified load weights from `variant` filename, *e.g.* pytorch_model..bin. use_safetensors (`bool`, *optional*, defaults to `None`): Whether or not to use `safetensors` checkpoints. Defaults to `None`. If not specified and `safetensors` is not installed, it will be set to `False`. @@ -4744,16 +4631,9 @@ def from_pretrained( >>> # Update configuration during loading. >>> model = BertModel.from_pretrained("google-bert/bert-base-uncased", output_attentions=True) >>> assert model.config.output_attentions == True - >>> # Loading from a TF checkpoint file instead of a PyTorch model (slower, for example purposes, not runnable). - >>> config = BertConfig.from_json_file("./tf_model/my_tf_model_config.json") - >>> model = BertModel.from_pretrained("./tf_model/my_tf_checkpoint.ckpt.index", from_tf=True, config=config) - >>> # Loading from a Flax checkpoint file instead of a PyTorch model (slower) - >>> model = BertModel.from_pretrained("google-bert/bert-base-uncased", from_flax=True) ``` """ state_dict = kwargs.pop("state_dict", None) - from_tf = kwargs.pop("from_tf", False) - from_flax = kwargs.pop("from_flax", False) proxies = kwargs.pop("proxies", None) output_loading_info = kwargs.pop("output_loading_info", False) use_auth_token = kwargs.pop("use_auth_token", None) @@ -4796,8 +4676,10 @@ def from_pretrained( # Not used anymore -- remove them from the kwargs _ = kwargs.pop("resume_download", None) _ = kwargs.pop("mirror", None) - _ = kwargs.pop("_fast_init", True) + _ = kwargs.pop("_fast_init", None) _ = kwargs.pop("low_cpu_mem_usage", None) + _ = kwargs.pop("from_tf", None) + _ = kwargs.pop("from_flax", None) # For BC on torch_dtype argument if torch_dtype is not None: @@ -4964,8 +4846,6 @@ def from_pretrained( "Please, pass a `BitsAndBytesConfig` object in `quantization_config` argument instead." ) - from_pt = not (from_tf | from_flax) - user_agent = {"file_type": "model", "framework": "pytorch", "from_auto_class": from_auto_class} if from_pipeline is not None: user_agent["using_pipeline"] = from_pipeline @@ -5016,7 +4896,7 @@ def from_pretrained( ) hf_quantizer, config, dtype, device_map = get_hf_quantizer( - config, quantization_config, dtype, from_tf, from_flax, device_map, weights_only, user_agent + config, quantization_config, dtype, device_map, weights_only, user_agent ) if gguf_file is not None and hf_quantizer is not None: @@ -5039,8 +4919,6 @@ def from_pretrained( subfolder=subfolder, variant=variant, gguf_file=gguf_file, - from_tf=from_tf, - from_flax=from_flax, use_safetensors=use_safetensors, cache_dir=cache_dir, force_download=force_download, @@ -5054,56 +4932,35 @@ def from_pretrained( transformers_explicit_filename=transformers_explicit_filename, ) - is_sharded = sharded_metadata is not None is_quantized = hf_quantizer is not None is_from_file = pretrained_model_name_or_path is not None or gguf_file is not None - if ( - is_safetensors_available() - and is_from_file - and not is_sharded - and checkpoint_files[0].endswith(".safetensors") - ): + # Just a helpful message in case we try to load safetensors files coming from old Transformers tf/flax classes + if is_safetensors_available() and is_from_file and checkpoint_files[0].endswith(".safetensors"): with safe_open(checkpoint_files[0], framework="pt") as f: metadata = f.metadata() - - if metadata is None: - # Assume it's a pytorch checkpoint (introduced for timm checkpoints) - pass - elif metadata.get("format") == "pt": - pass - elif metadata.get("format") == "tf": - from_tf = True - logger.info("A TensorFlow safetensors file is being loaded in a PyTorch model.") - elif metadata.get("format") == "flax": - from_flax = True - logger.info("A Flax safetensors file is being loaded in a PyTorch model.") - elif metadata.get("format") == "mlx": - # This is a mlx file, we assume weights are compatible with pt - pass - else: - raise ValueError( - f"Incompatible safetensors file. File metadata is not ['pt', 'tf', 'flax', 'mlx'] but {metadata.get('format')}" + if metadata is not None and metadata.get("format") in ["tf", "flax"]: + logger.warning( + "The safetensors checkpoint found has format `tf` or `flax`. This mean that the keys will very" + "likely not match to the model you are trying to load, and will be newly initialized. If it's the case " + "another warning will be raised later. Consider converting your checkpoint to the correct format." ) - from_pt = not (from_tf | from_flax) + if gguf_file: + from .modeling_gguf_pytorch_utils import load_gguf_checkpoint - if from_pt: - if gguf_file: - from .modeling_gguf_pytorch_utils import load_gguf_checkpoint - - # we need a dummy model to get the state_dict - for this reason, we keep the state_dict as if it was - # passed directly as a kwarg from now on - with torch.device("meta"): - dummy_model = cls(config) - state_dict = load_gguf_checkpoint(checkpoint_files[0], return_tensors=True, model_to_load=dummy_model)[ - "tensors" - ] + # we need a dummy model to get the state_dict - for this reason, we keep the state_dict as if it was + # passed directly as a kwarg from now on + with torch.device("meta"): + dummy_model = cls(config) + state_dict = load_gguf_checkpoint(checkpoint_files[0], return_tensors=True, model_to_load=dummy_model)[ + "tensors" + ] - # Find the correct dtype based on current state - config, dtype, dtype_orig = _get_dtype( - cls, dtype, checkpoint_files, config, sharded_metadata, state_dict, weights_only - ) + # Find the correct dtype based on current state + config, dtype, dtype_orig = _get_dtype( + cls, dtype, checkpoint_files, config, sharded_metadata, state_dict, weights_only + ) config.name_or_path = pretrained_model_name_or_path model_init_context = cls.get_init_context(is_quantized, _is_ds_init_called) @@ -5166,40 +5023,36 @@ def _assign_original_dtype(module): if device_map is not None: device_map = _get_device_map(model, device_map, max_memory, hf_quantizer, dtype, keep_in_fp32_regex) + # restore default dtype + if dtype_orig is not None: + torch.set_default_dtype(dtype_orig) + # Finalize model weight initialization - if from_tf: - model, loading_info = cls._load_from_tf(model, config, checkpoint_files) - elif from_flax: - model = cls._load_from_flax(model, checkpoint_files) - elif from_pt: - # restore default dtype - if dtype_orig is not None: - torch.set_default_dtype(dtype_orig) + ( + model, + missing_keys, + unexpected_keys, + mismatched_keys, + offload_index, + error_msgs, + ) = cls._load_pretrained_model( + model, + state_dict, + checkpoint_files, + pretrained_model_name_or_path, + ignore_mismatched_sizes=ignore_mismatched_sizes, + sharded_metadata=sharded_metadata, + device_map=device_map, + disk_offload_folder=offload_folder, + offload_state_dict=offload_state_dict, + dtype=dtype, + hf_quantizer=hf_quantizer, + keep_in_fp32_regex=keep_in_fp32_regex, + device_mesh=device_mesh, + key_mapping=key_mapping, + weights_only=weights_only, + ) - ( - model, - missing_keys, - unexpected_keys, - mismatched_keys, - offload_index, - error_msgs, - ) = cls._load_pretrained_model( - model, - state_dict, - checkpoint_files, - pretrained_model_name_or_path, - ignore_mismatched_sizes=ignore_mismatched_sizes, - sharded_metadata=sharded_metadata, - device_map=device_map, - disk_offload_folder=offload_folder, - offload_state_dict=offload_state_dict, - dtype=dtype, - hf_quantizer=hf_quantizer, - keep_in_fp32_regex=keep_in_fp32_regex, - device_mesh=device_mesh, - key_mapping=key_mapping, - weights_only=weights_only, - ) # make sure token embedding weights are still tied if needed model.tie_weights() @@ -5292,15 +5145,12 @@ def _assign_original_dtype(module): ) if output_loading_info: - if from_pt: - loading_info = { - "missing_keys": missing_keys, - "unexpected_keys": unexpected_keys, - "mismatched_keys": mismatched_keys, - "error_msgs": error_msgs, - } - elif from_flax: - loading_info = None + loading_info = { + "missing_keys": missing_keys, + "unexpected_keys": unexpected_keys, + "mismatched_keys": mismatched_keys, + "error_msgs": error_msgs, + } return model, loading_info return model @@ -5751,44 +5601,6 @@ def _load_pretrained_model( return model, missing_keys, unexpected_keys, mismatched_keys, disk_offload_index, error_msgs - @classmethod - def _load_from_tf(cls, model, config, checkpoint_files): - if checkpoint_files[0].endswith(".index"): - # Load from a TensorFlow 1.X checkpoint - provided by original authors - model = cls.load_tf_weights(model, config, checkpoint_files[0][:-6]) # Remove the '.index' - loading_info = None - else: - # Load from our TensorFlow 2.0 checkpoints - try: - from .modeling_tf_pytorch_utils import load_tf2_checkpoint_in_pytorch_model - - model, loading_info = load_tf2_checkpoint_in_pytorch_model( - model, checkpoint_files[0], allow_missing_keys=True, output_loading_info=True - ) - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires both PyTorch and TensorFlow to be installed." - " Please see https://pytorch.org/ and https://www.tensorflow.org/install/ for installation" - " instructions." - ) - raise - return model, loading_info - - @classmethod - def _load_from_flax(cls, model, checkpoint_files): - try: - from .modeling_flax_pytorch_utils import load_flax_checkpoint_in_pytorch_model - - model = load_flax_checkpoint_in_pytorch_model(model, checkpoint_files[0]) - except ImportError: - logger.error( - "Loading a Flax model in PyTorch, requires both PyTorch and Flax to be installed. Please see" - " https://pytorch.org/ and https://flax.readthedocs.io/en/latest/installation.html for" - " installation instructions." - ) - raise - return model - def retrieve_modules_from_names(self, names, add_prefix=False, remove_prefix=False): module_keys = {".".join(key.split(".")[:-1]) for key in names} diff --git a/src/transformers/models/albert/__init__.py b/src/transformers/models/albert/__init__.py index 57b5747909e0..ac2cf362ebf2 100644 --- a/src/transformers/models/albert/__init__.py +++ b/src/transformers/models/albert/__init__.py @@ -20,8 +20,6 @@ if TYPE_CHECKING: from .configuration_albert import * from .modeling_albert import * - from .modeling_flax_albert import * - from .modeling_tf_albert import * from .tokenization_albert import * from .tokenization_albert_fast import * else: diff --git a/src/transformers/models/albert/modeling_albert.py b/src/transformers/models/albert/modeling_albert.py index 4cc129366bae..c3d1dc540223 100755 --- a/src/transformers/models/albert/modeling_albert.py +++ b/src/transformers/models/albert/modeling_albert.py @@ -15,7 +15,6 @@ """PyTorch ALBERT model.""" import math -import os from dataclasses import dataclass from typing import Optional, Union @@ -47,132 +46,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_albert(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - print(name) - - for name, array in zip(names, arrays): - original_name = name - - # If saved from the TF HUB module - name = name.replace("module/", "") - - # Renaming and simplifying - name = name.replace("ffn_1", "ffn") - name = name.replace("bert/", "albert/") - name = name.replace("attention_1", "attention") - name = name.replace("transform/", "") - name = name.replace("LayerNorm_1", "full_layer_layer_norm") - name = name.replace("LayerNorm", "attention/LayerNorm") - name = name.replace("transformer/", "") - - # The feed forward layer had an 'intermediate' step which has been abstracted away - name = name.replace("intermediate/dense/", "") - name = name.replace("ffn/intermediate/output/dense/", "ffn_output/") - - # ALBERT attention was split between self and output which have been abstracted away - name = name.replace("/output/", "/") - name = name.replace("/self/", "/") - - # The pooler is a linear layer - name = name.replace("pooler/dense", "pooler") - - # The classifier was simplified to predictions from cls/predictions - name = name.replace("cls/predictions", "predictions") - name = name.replace("predictions/attention", "predictions") - - # Naming was changed to be more explicit - name = name.replace("embeddings/attention", "embeddings") - name = name.replace("inner_group_", "albert_layers/") - name = name.replace("group_", "albert_layer_groups/") - - # Classifier - if len(name.split("/")) == 1 and ("output_bias" in name or "output_weights" in name): - name = "classifier/" + name - - # No ALBERT model currently handles the next sentence prediction task - if "seq_relationship" in name: - name = name.replace("seq_relationship/output_", "sop_classifier/classifier/") - name = name.replace("weights", "weight") - - name = name.split("/") - - # Ignore the gradients applied by the LAMB/ADAM optimizers. - if ( - "adam_m" in name - or "adam_v" in name - or "AdamWeightDecayOptimizer" in name - or "AdamWeightDecayOptimizer_1" in name - or "global_step" in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except ValueError as e: - e.args += (pointer.shape, array.shape) - raise - print(f"Initialize PyTorch weight {name} from {original_name}") - pointer.data = torch.from_numpy(array) - - return model - - class AlbertEmbeddings(nn.Module): """ Construct the embeddings from word, position and token_type embeddings. @@ -184,8 +57,6 @@ def __init__(self, config: AlbertConfig): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.embedding_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.embedding_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.embedding_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -546,15 +417,12 @@ def forward( @auto_docstring class AlbertPreTrainedModel(PreTrainedModel): config: AlbertConfig - load_tf_weights = load_tf_weights_in_albert base_model_prefix = "albert" _supports_sdpa = True def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1337,7 +1205,6 @@ def forward( __all__ = [ - "load_tf_weights_in_albert", "AlbertPreTrainedModel", "AlbertModel", "AlbertForPreTraining", diff --git a/src/transformers/models/albert/modeling_flax_albert.py b/src/transformers/models/albert/modeling_flax_albert.py deleted file mode 100644 index f2f19cb27716..000000000000 --- a/src/transformers/models/albert/modeling_flax_albert.py +++ /dev/null @@ -1,1132 +0,0 @@ -# coding=utf-8 -# Copyright 2021 Google AI, Google Brain and 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. - -from typing import Callable, Optional - -import flax -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPooling, - FlaxMaskedLMOutput, - FlaxMultipleChoiceModelOutput, - FlaxQuestionAnsweringModelOutput, - FlaxSequenceClassifierOutput, - FlaxTokenClassifierOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import ModelOutput, add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_albert import AlbertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "albert/albert-base-v2" -_CONFIG_FOR_DOC = "AlbertConfig" - - -@flax.struct.dataclass -class FlaxAlbertForPreTrainingOutput(ModelOutput): - """ - Output type of [`FlaxAlbertForPreTraining`]. - - Args: - prediction_logits (`jnp.ndarray` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - sop_logits (`jnp.ndarray` of shape `(batch_size, 2)`): - Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation - before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - prediction_logits: jnp.ndarray = None - sop_logits: jnp.ndarray = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -ALBERT_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`AlbertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -ALBERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - -""" - - -class FlaxAlbertEmbeddings(nn.Module): - """Construct the embeddings from word, position and token_type embeddings.""" - - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.word_embeddings = nn.Embed( - self.config.vocab_size, - self.config.embedding_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.position_embeddings = nn.Embed( - self.config.max_position_embeddings, - self.config.embedding_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.token_type_embeddings = nn.Embed( - self.config.type_vocab_size, - self.config.embedding_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, input_ids, token_type_ids, position_ids, deterministic: bool = True): - # Embed - inputs_embeds = self.word_embeddings(input_ids.astype("i4")) - position_embeds = self.position_embeddings(position_ids.astype("i4")) - token_type_embeddings = self.token_type_embeddings(token_type_ids.astype("i4")) - - # Sum all embeddings - hidden_states = inputs_embeds + token_type_embeddings + position_embeds - - # Layer Norm - hidden_states = self.LayerNorm(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxAlbertSelfAttention(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - if self.config.hidden_size % self.config.num_attention_heads != 0: - raise ValueError( - "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads` " - " : {self.config.num_attention_heads}" - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, attention_mask, deterministic=True, output_attentions: bool = False): - head_dim = self.config.hidden_size // self.config.num_attention_heads - - query_states = self.query(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - value_states = self.value(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - key_states = self.key(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - projected_attn_output = self.dense(attn_output) - projected_attn_output = self.dropout(projected_attn_output, deterministic=deterministic) - layernormed_attn_output = self.LayerNorm(projected_attn_output + hidden_states) - outputs = (layernormed_attn_output, attn_weights) if output_attentions else (layernormed_attn_output,) - return outputs - - -class FlaxAlbertLayer(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.attention = FlaxAlbertSelfAttention(self.config, dtype=self.dtype) - self.ffn = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.hidden_act] - self.ffn_output = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.full_layer_layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - ): - attention_outputs = self.attention( - hidden_states, attention_mask, deterministic=deterministic, output_attentions=output_attentions - ) - attention_output = attention_outputs[0] - ffn_output = self.ffn(attention_output) - ffn_output = self.activation(ffn_output) - ffn_output = self.ffn_output(ffn_output) - ffn_output = self.dropout(ffn_output, deterministic=deterministic) - hidden_states = self.full_layer_layer_norm(ffn_output + attention_output) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attention_outputs[1],) - return outputs - - -class FlaxAlbertLayerCollection(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxAlbertLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.inner_group_num) - ] - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - ): - layer_hidden_states = () - layer_attentions = () - - for layer_index, albert_layer in enumerate(self.layers): - layer_output = albert_layer( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - ) - hidden_states = layer_output[0] - - if output_attentions: - layer_attentions = layer_attentions + (layer_output[1],) - - if output_hidden_states: - layer_hidden_states = layer_hidden_states + (hidden_states,) - - outputs = (hidden_states,) - if output_hidden_states: - outputs = outputs + (layer_hidden_states,) - if output_attentions: - outputs = outputs + (layer_attentions,) - return outputs # last-layer hidden state, (layer hidden states), (layer attentions) - - -class FlaxAlbertLayerCollections(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - layer_index: Optional[str] = None - - def setup(self): - self.albert_layers = FlaxAlbertLayerCollection(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - ): - outputs = self.albert_layers( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - ) - return outputs - - -class FlaxAlbertLayerGroups(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxAlbertLayerCollections(self.config, name=str(i), layer_index=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_groups) - ] - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = (hidden_states,) if output_hidden_states else None - - for i in range(self.config.num_hidden_layers): - # Index of the hidden group - group_idx = int(i / (self.config.num_hidden_layers / self.config.num_hidden_groups)) - layer_group_output = self.layers[group_idx]( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - ) - hidden_states = layer_group_output[0] - - if output_attentions: - all_attentions = all_attentions + layer_group_output[-1] - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -class FlaxAlbertEncoder(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.embedding_hidden_mapping_in = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.albert_layer_groups = FlaxAlbertLayerGroups(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - hidden_states = self.embedding_hidden_mapping_in(hidden_states) - return self.albert_layer_groups( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - ) - - -class FlaxAlbertOnlyMLMHead(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.dense = nn.Dense(self.config.embedding_size, dtype=self.dtype) - self.activation = ACT2FN[self.config.hidden_act] - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.decoder = nn.Dense(self.config.vocab_size, dtype=self.dtype, use_bias=False) - self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) - - def __call__(self, hidden_states, shared_embedding=None): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - hidden_states = self.LayerNorm(hidden_states) - - if shared_embedding is not None: - hidden_states = self.decoder.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - hidden_states = self.decoder(hidden_states) - - hidden_states += self.bias - return hidden_states - - -class FlaxAlbertSOPHead(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dropout = nn.Dropout(self.config.classifier_dropout_prob) - self.classifier = nn.Dense(2, dtype=self.dtype) - - def __call__(self, pooled_output, deterministic=True): - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) - return logits - - -class FlaxAlbertPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = AlbertConfig - base_model_prefix = "albert" - module_class: nn.Module = None - - def __init__( - self, - config: AlbertConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - token_type_ids = jnp.zeros_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - attention_mask = jnp.ones_like(input_ids) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, input_ids, attention_mask, token_type_ids, position_ids, return_dict=False - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # init input tensors if not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(token_type_ids, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - -class FlaxAlbertModule(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - add_pooling_layer: bool = True - - def setup(self): - self.embeddings = FlaxAlbertEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxAlbertEncoder(self.config, dtype=self.dtype) - if self.add_pooling_layer: - self.pooler = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - name="pooler", - ) - self.pooler_activation = nn.tanh - else: - self.pooler = None - self.pooler_activation = None - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids: Optional[np.ndarray] = None, - position_ids: Optional[np.ndarray] = None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # make sure `token_type_ids` is correctly initialized when not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - # make sure `position_ids` is correctly initialized when not passed - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - hidden_states = self.embeddings(input_ids, token_type_ids, position_ids, deterministic=deterministic) - - outputs = self.encoder( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - if self.add_pooling_layer: - pooled = self.pooler(hidden_states[:, 0]) - pooled = self.pooler_activation(pooled) - else: - pooled = None - - if not return_dict: - # if pooled is None, don't return it - if pooled is None: - return (hidden_states,) + outputs[1:] - return (hidden_states, pooled) + outputs[1:] - - return FlaxBaseModelOutputWithPooling( - last_hidden_state=hidden_states, - pooler_output=pooled, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - "The bare Albert Model transformer outputting raw hidden-states without any specific head on top.", - ALBERT_START_DOCSTRING, -) -class FlaxAlbertModel(FlaxAlbertPreTrainedModel): - module_class = FlaxAlbertModule - - -append_call_sample_docstring(FlaxAlbertModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutputWithPooling, _CONFIG_FOR_DOC) - - -class FlaxAlbertForPreTrainingModule(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.albert = FlaxAlbertModule(config=self.config, dtype=self.dtype) - self.predictions = FlaxAlbertOnlyMLMHead(config=self.config, dtype=self.dtype) - self.sop_classifier = FlaxAlbertSOPHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.albert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - if self.config.tie_word_embeddings: - shared_embedding = self.albert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - hidden_states = outputs[0] - pooled_output = outputs[1] - - prediction_scores = self.predictions(hidden_states, shared_embedding=shared_embedding) - sop_scores = self.sop_classifier(pooled_output, deterministic=deterministic) - - if not return_dict: - return (prediction_scores, sop_scores) + outputs[2:] - - return FlaxAlbertForPreTrainingOutput( - prediction_logits=prediction_scores, - sop_logits=sop_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Albert Model with two heads on top as done during the pretraining: a `masked language modeling` head and a - `sentence order prediction (classification)` head. - """, - ALBERT_START_DOCSTRING, -) -class FlaxAlbertForPreTraining(FlaxAlbertPreTrainedModel): - module_class = FlaxAlbertForPreTrainingModule - - -FLAX_ALBERT_FOR_PRETRAINING_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxAlbertForPreTraining - - >>> tokenizer = AutoTokenizer.from_pretrained("albert/albert-base-v2") - >>> model = FlaxAlbertForPreTraining.from_pretrained("albert/albert-base-v2") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="np") - >>> outputs = model(**inputs) - - >>> prediction_logits = outputs.prediction_logits - >>> seq_relationship_logits = outputs.sop_logits - ``` -""" - -overwrite_call_docstring( - FlaxAlbertForPreTraining, - ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length") + FLAX_ALBERT_FOR_PRETRAINING_DOCSTRING, -) -append_replace_return_docstrings( - FlaxAlbertForPreTraining, output_type=FlaxAlbertForPreTrainingOutput, config_class=_CONFIG_FOR_DOC -) - - -class FlaxAlbertForMaskedLMModule(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.albert = FlaxAlbertModule(config=self.config, add_pooling_layer=False, dtype=self.dtype) - self.predictions = FlaxAlbertOnlyMLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.albert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.albert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.predictions(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxMaskedLMOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings("""Albert Model with a `language modeling` head on top.""", ALBERT_START_DOCSTRING) -class FlaxAlbertForMaskedLM(FlaxAlbertPreTrainedModel): - module_class = FlaxAlbertForMaskedLMModule - - -append_call_sample_docstring( - FlaxAlbertForMaskedLM, _CHECKPOINT_FOR_DOC, FlaxMaskedLMOutput, _CONFIG_FOR_DOC, revision="refs/pr/11" -) - - -class FlaxAlbertForSequenceClassificationModule(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.albert = FlaxAlbertModule(config=self.config, dtype=self.dtype) - classifier_dropout = ( - self.config.classifier_dropout_prob - if self.config.classifier_dropout_prob is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.classifier = nn.Dense( - self.config.num_labels, - dtype=self.dtype, - ) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.albert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) - - if not return_dict: - return (logits,) + outputs[2:] - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Albert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled - output) e.g. for GLUE tasks. - """, - ALBERT_START_DOCSTRING, -) -class FlaxAlbertForSequenceClassification(FlaxAlbertPreTrainedModel): - module_class = FlaxAlbertForSequenceClassificationModule - - -append_call_sample_docstring( - FlaxAlbertForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxAlbertForMultipleChoiceModule(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.albert = FlaxAlbertModule(config=self.config, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.classifier = nn.Dense(1, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - num_choices = input_ids.shape[1] - input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None - attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None - token_type_ids = token_type_ids.reshape(-1, token_type_ids.shape[-1]) if token_type_ids is not None else None - position_ids = position_ids.reshape(-1, position_ids.shape[-1]) if position_ids is not None else None - - # Model - outputs = self.albert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) - - reshaped_logits = logits.reshape(-1, num_choices) - - if not return_dict: - return (reshaped_logits,) + outputs[2:] - - return FlaxMultipleChoiceModelOutput( - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Albert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - ALBERT_START_DOCSTRING, -) -class FlaxAlbertForMultipleChoice(FlaxAlbertPreTrainedModel): - module_class = FlaxAlbertForMultipleChoiceModule - - -overwrite_call_docstring( - FlaxAlbertForMultipleChoice, ALBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") -) -append_call_sample_docstring( - FlaxAlbertForMultipleChoice, - _CHECKPOINT_FOR_DOC, - FlaxMultipleChoiceModelOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxAlbertForTokenClassificationModule(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.albert = FlaxAlbertModule(config=self.config, dtype=self.dtype, add_pooling_layer=False) - classifier_dropout = ( - self.config.classifier_dropout_prob - if self.config.classifier_dropout_prob is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.albert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - logits = self.classifier(hidden_states) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxTokenClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Albert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - ALBERT_START_DOCSTRING, -) -class FlaxAlbertForTokenClassification(FlaxAlbertPreTrainedModel): - module_class = FlaxAlbertForTokenClassificationModule - - -append_call_sample_docstring( - FlaxAlbertForTokenClassification, - _CHECKPOINT_FOR_DOC, - FlaxTokenClassifierOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxAlbertForQuestionAnsweringModule(nn.Module): - config: AlbertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.albert = FlaxAlbertModule(config=self.config, dtype=self.dtype, add_pooling_layer=False) - self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.albert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - logits = self.qa_outputs(hidden_states) - start_logits, end_logits = jnp.split(logits, self.config.num_labels, axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - return (start_logits, end_logits) + outputs[1:] - - return FlaxQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Albert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - ALBERT_START_DOCSTRING, -) -class FlaxAlbertForQuestionAnswering(FlaxAlbertPreTrainedModel): - module_class = FlaxAlbertForQuestionAnsweringModule - - -append_call_sample_docstring( - FlaxAlbertForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - -__all__ = [ - "FlaxAlbertPreTrainedModel", - "FlaxAlbertModel", - "FlaxAlbertForPreTraining", - "FlaxAlbertForMaskedLM", - "FlaxAlbertForSequenceClassification", - "FlaxAlbertForMultipleChoice", - "FlaxAlbertForTokenClassification", - "FlaxAlbertForQuestionAnswering", -] diff --git a/src/transformers/models/albert/modeling_tf_albert.py b/src/transformers/models/albert/modeling_tf_albert.py deleted file mode 100644 index 101ab63dc054..000000000000 --- a/src/transformers/models/albert/modeling_tf_albert.py +++ /dev/null @@ -1,1572 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The OpenAI Team Authors and HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 ALBERT model.""" - -from __future__ import annotations - -import math -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPooling, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_albert import AlbertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "albert/albert-base-v2" -_CONFIG_FOR_DOC = "AlbertConfig" - - -class TFAlbertPreTrainingLoss: - """ - Loss function suitable for ALBERT pretraining, that is, the task of pretraining a language model by combining SOP + - MLM. .. note:: Any label of -100 will be ignored (along with the corresponding logits) in the loss computation. - """ - - def hf_compute_loss(self, labels: tf.Tensor, logits: tf.Tensor) -> tf.Tensor: - loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=keras.losses.Reduction.NONE) - if self.config.tf_legacy_loss: - # make sure only labels that are not equal to -100 - # are taken into account as loss - masked_lm_active_loss = tf.not_equal(tf.reshape(tensor=labels["labels"], shape=(-1,)), -100) - masked_lm_reduced_logits = tf.boolean_mask( - tensor=tf.reshape(tensor=logits[0], shape=(-1, shape_list(logits[0])[2])), - mask=masked_lm_active_loss, - ) - masked_lm_labels = tf.boolean_mask( - tensor=tf.reshape(tensor=labels["labels"], shape=(-1,)), mask=masked_lm_active_loss - ) - sentence_order_active_loss = tf.not_equal( - tf.reshape(tensor=labels["sentence_order_label"], shape=(-1,)), -100 - ) - sentence_order_reduced_logits = tf.boolean_mask( - tensor=tf.reshape(tensor=logits[1], shape=(-1, 2)), mask=sentence_order_active_loss - ) - sentence_order_label = tf.boolean_mask( - tensor=tf.reshape(tensor=labels["sentence_order_label"], shape=(-1,)), mask=sentence_order_active_loss - ) - masked_lm_loss = loss_fn(y_true=masked_lm_labels, y_pred=masked_lm_reduced_logits) - sentence_order_loss = loss_fn(y_true=sentence_order_label, y_pred=sentence_order_reduced_logits) - masked_lm_loss = tf.reshape(tensor=masked_lm_loss, shape=(-1, shape_list(sentence_order_loss)[0])) - masked_lm_loss = tf.reduce_mean(input_tensor=masked_lm_loss, axis=0) - - return masked_lm_loss + sentence_order_loss - - # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway - unmasked_lm_losses = loss_fn(y_true=tf.nn.relu(labels["labels"]), y_pred=logits[0]) - # make sure only labels that are not equal to -100 - # are taken into account for the loss computation - lm_loss_mask = tf.cast(labels["labels"] != -100, dtype=unmasked_lm_losses.dtype) - masked_lm_losses = unmasked_lm_losses * lm_loss_mask - reduced_masked_lm_loss = tf.reduce_sum(masked_lm_losses) / tf.reduce_sum(lm_loss_mask) - - sop_logits = tf.reshape(logits[1], (-1, 2)) - # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway - unmasked_sop_loss = loss_fn(y_true=tf.nn.relu(labels["sentence_order_label"]), y_pred=sop_logits) - sop_loss_mask = tf.cast(labels["sentence_order_label"] != -100, dtype=unmasked_sop_loss.dtype) - - masked_sop_loss = unmasked_sop_loss * sop_loss_mask - reduced_masked_sop_loss = tf.reduce_sum(masked_sop_loss) / tf.reduce_sum(sop_loss_mask) - - return tf.reshape(reduced_masked_lm_loss + reduced_masked_sop_loss, (1,)) - - -class TFAlbertEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config: AlbertConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = config.embedding_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.embedding_size]) - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertEmbeddings.call - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - past_key_values_length=0, - training: bool = False, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - if input_ids is None and inputs_embeds is None: - raise ValueError("Need to provide either `input_ids` or `input_embeds`.") - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - position_ids = tf.expand_dims( - tf.range(start=past_key_values_length, limit=input_shape[1] + past_key_values_length), axis=0 - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -class TFAlbertAttention(keras.layers.Layer): - """Contains the complete attention sublayer, including both dropouts and layer norm.""" - - def __init__(self, config: AlbertConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - self.output_attentions = config.output_attentions - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - # Two different dropout probabilities; see https://github.com/google-research/albert/blob/master/modeling.py#L971-L993 - self.attention_dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - self.output_dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(input_tensor)[0] - mixed_query_layer = self.query(inputs=input_tensor) - mixed_key_layer = self.key(inputs=input_tensor) - mixed_value_layer = self.value(inputs=input_tensor) - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFAlbertModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.attention_dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - context_layer = tf.matmul(attention_probs, value_layer) - context_layer = tf.transpose(context_layer, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - context_layer = tf.reshape(tensor=context_layer, shape=(batch_size, -1, self.all_head_size)) - self_outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - hidden_states = self_outputs[0] - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.output_dropout(inputs=hidden_states, training=training) - attention_output = self.LayerNorm(inputs=hidden_states + input_tensor) - - # add attentions if we output them - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFAlbertLayer(keras.layers.Layer): - def __init__(self, config: AlbertConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFAlbertAttention(config, name="attention") - self.ffn = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="ffn" - ) - - if isinstance(config.hidden_act, str): - self.activation = get_tf_activation(config.hidden_act) - else: - self.activation = config.hidden_act - - self.ffn_output = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="ffn_output" - ) - self.full_layer_layer_norm = keras.layers.LayerNormalization( - epsilon=config.layer_norm_eps, name="full_layer_layer_norm" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - training=training, - ) - ffn_output = self.ffn(inputs=attention_outputs[0]) - ffn_output = self.activation(ffn_output) - ffn_output = self.ffn_output(inputs=ffn_output) - ffn_output = self.dropout(inputs=ffn_output, training=training) - hidden_states = self.full_layer_layer_norm(inputs=ffn_output + attention_outputs[0]) - - # add attentions if we output them - outputs = (hidden_states,) + attention_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "ffn", None) is not None: - with tf.name_scope(self.ffn.name): - self.ffn.build([None, None, self.config.hidden_size]) - if getattr(self, "ffn_output", None) is not None: - with tf.name_scope(self.ffn_output.name): - self.ffn_output.build([None, None, self.config.intermediate_size]) - if getattr(self, "full_layer_layer_norm", None) is not None: - with tf.name_scope(self.full_layer_layer_norm.name): - self.full_layer_layer_norm.build([None, None, self.config.hidden_size]) - - -class TFAlbertLayerGroup(keras.layers.Layer): - def __init__(self, config: AlbertConfig, **kwargs): - super().__init__(**kwargs) - - self.albert_layers = [ - TFAlbertLayer(config, name=f"albert_layers_._{i}") for i in range(config.inner_group_num) - ] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - output_hidden_states: bool, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - layer_hidden_states = () if output_hidden_states else None - layer_attentions = () if output_attentions else None - - for layer_index, albert_layer in enumerate(self.albert_layers): - if output_hidden_states: - layer_hidden_states = layer_hidden_states + (hidden_states,) - - layer_output = albert_layer( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[layer_index], - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_output[0] - - if output_attentions: - layer_attentions = layer_attentions + (layer_output[1],) - - # Add last layer - if output_hidden_states: - layer_hidden_states = layer_hidden_states + (hidden_states,) - - return tuple(v for v in [hidden_states, layer_hidden_states, layer_attentions] if v is not None) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "albert_layers", None) is not None: - for layer in self.albert_layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFAlbertTransformer(keras.layers.Layer): - def __init__(self, config: AlbertConfig, **kwargs): - super().__init__(**kwargs) - - self.num_hidden_layers = config.num_hidden_layers - self.num_hidden_groups = config.num_hidden_groups - # Number of layers in a hidden group - self.layers_per_group = int(config.num_hidden_layers / config.num_hidden_groups) - self.embedding_hidden_mapping_in = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="embedding_hidden_mapping_in", - ) - self.albert_layer_groups = [ - TFAlbertLayerGroup(config, name=f"albert_layer_groups_._{i}") for i in range(config.num_hidden_groups) - ] - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - hidden_states = self.embedding_hidden_mapping_in(inputs=hidden_states) - all_attentions = () if output_attentions else None - all_hidden_states = (hidden_states,) if output_hidden_states else None - - for i in range(self.num_hidden_layers): - # Index of the hidden group - group_idx = int(i / (self.num_hidden_layers / self.num_hidden_groups)) - layer_group_output = self.albert_layer_groups[group_idx]( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[group_idx * self.layers_per_group : (group_idx + 1) * self.layers_per_group], - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - training=training, - ) - hidden_states = layer_group_output[0] - - if output_attentions: - all_attentions = all_attentions + layer_group_output[-1] - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embedding_hidden_mapping_in", None) is not None: - with tf.name_scope(self.embedding_hidden_mapping_in.name): - self.embedding_hidden_mapping_in.build([None, None, self.config.embedding_size]) - if getattr(self, "albert_layer_groups", None) is not None: - for layer in self.albert_layer_groups: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFAlbertPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = AlbertConfig - base_model_prefix = "albert" - - -class TFAlbertMLMHead(keras.layers.Layer): - def __init__(self, config: AlbertConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = config.embedding_size - self.dense = keras.layers.Dense( - config.embedding_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - if isinstance(config.hidden_act, str): - self.activation = get_tf_activation(config.hidden_act) - else: - self.activation = config.hidden_act - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.decoder = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - self.decoder_bias = self.add_weight( - shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="decoder/bias" - ) - - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.embedding_size]) - - def get_output_embeddings(self) -> keras.layers.Layer: - return self.decoder - - def set_output_embeddings(self, value: tf.Variable): - self.decoder.weight = value - self.decoder.vocab_size = shape_list(value)[0] - - def get_bias(self) -> dict[str, tf.Variable]: - return {"bias": self.bias, "decoder_bias": self.decoder_bias} - - def set_bias(self, value: tf.Variable): - self.bias = value["bias"] - self.decoder_bias = value["decoder_bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.activation(hidden_states) - hidden_states = self.LayerNorm(inputs=hidden_states) - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.embedding_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.decoder.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.decoder_bias) - - return hidden_states - - -@keras_serializable -class TFAlbertMainLayer(keras.layers.Layer): - config_class = AlbertConfig - - def __init__(self, config: AlbertConfig, add_pooling_layer: bool = True, **kwargs): - super().__init__(**kwargs) - - self.config = config - - self.embeddings = TFAlbertEmbeddings(config, name="embeddings") - self.encoder = TFAlbertTransformer(config, name="encoder") - self.pooler = ( - keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="pooler", - ) - if add_pooling_layer - else None - ) - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - extended_attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(inputs=sequence_output[:, 0]) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build([None, None, self.config.hidden_size]) - - -@dataclass -class TFAlbertForPreTrainingOutput(ModelOutput): - """ - Output type of [`TFAlbertForPreTraining`]. - - Args: - prediction_logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - sop_logits (`tf.Tensor` of shape `(batch_size, 2)`): - Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation - before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - prediction_logits: tf.Tensor | None = None - sop_logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -ALBERT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`AlbertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -ALBERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare Albert Model transformer outputting raw hidden-states without any specific head on top.", - ALBERT_START_DOCSTRING, -) -class TFAlbertModel(TFAlbertPreTrainedModel): - def __init__(self, config: AlbertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.albert = TFAlbertMainLayer(config, name="albert") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPooling, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - outputs = self.albert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "albert", None) is not None: - with tf.name_scope(self.albert.name): - self.albert.build(None) - - -@add_start_docstrings( - """ - Albert Model with two heads on top for pretraining: a `masked language modeling` head and a `sentence order - prediction` (classification) head. - """, - ALBERT_START_DOCSTRING, -) -class TFAlbertForPreTraining(TFAlbertPreTrainedModel, TFAlbertPreTrainingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"predictions.decoder.weight"] - - def __init__(self, config: AlbertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.albert = TFAlbertMainLayer(config, name="albert") - self.predictions = TFAlbertMLMHead(config, input_embeddings=self.albert.embeddings, name="predictions") - self.sop_classifier = TFAlbertSOPHead(config, name="sop_classifier") - - def get_lm_head(self) -> keras.layers.Layer: - return self.predictions - - @unpack_inputs - @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFAlbertForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - sentence_order_label: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFAlbertForPreTrainingOutput | tuple[tf.Tensor]: - r""" - Return: - - Example: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFAlbertForPreTraining - - >>> tokenizer = AutoTokenizer.from_pretrained("albert/albert-base-v2") - >>> model = TFAlbertForPreTraining.from_pretrained("albert/albert-base-v2") - - >>> input_ids = tf.constant(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True))[None, :] - >>> # Batch size 1 - >>> outputs = model(input_ids) - - >>> prediction_logits = outputs.prediction_logits - >>> sop_logits = outputs.sop_logits - ```""" - - outputs = self.albert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output, pooled_output = outputs[:2] - prediction_scores = self.predictions(hidden_states=sequence_output) - sop_scores = self.sop_classifier(pooled_output=pooled_output, training=training) - total_loss = None - - if labels is not None and sentence_order_label is not None: - d_labels = {"labels": labels} - d_labels["sentence_order_label"] = sentence_order_label - total_loss = self.hf_compute_loss(labels=d_labels, logits=(prediction_scores, sop_scores)) - - if not return_dict: - output = (prediction_scores, sop_scores) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - - return TFAlbertForPreTrainingOutput( - loss=total_loss, - prediction_logits=prediction_scores, - sop_logits=sop_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "albert", None) is not None: - with tf.name_scope(self.albert.name): - self.albert.build(None) - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - if getattr(self, "sop_classifier", None) is not None: - with tf.name_scope(self.sop_classifier.name): - self.sop_classifier.build(None) - - -class TFAlbertSOPHead(keras.layers.Layer): - def __init__(self, config: AlbertConfig, **kwargs): - super().__init__(**kwargs) - - self.dropout = keras.layers.Dropout(rate=config.classifier_dropout_prob) - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - self.config = config - - def call(self, pooled_output: tf.Tensor, training: bool) -> tf.Tensor: - dropout_pooled_output = self.dropout(inputs=pooled_output, training=training) - logits = self.classifier(inputs=dropout_pooled_output) - - return logits - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings("""Albert Model with a `language modeling` head on top.""", ALBERT_START_DOCSTRING) -class TFAlbertForMaskedLM(TFAlbertPreTrainedModel, TFMaskedLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"predictions.decoder.weight"] - - def __init__(self, config: AlbertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.albert = TFAlbertMainLayer(config, add_pooling_layer=False, name="albert") - self.predictions = TFAlbertMLMHead(config, input_embeddings=self.albert.embeddings, name="predictions") - - def get_lm_head(self) -> keras.layers.Layer: - return self.predictions - - @unpack_inputs - @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFMaskedLMOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - - Returns: - - Example: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFAlbertForMaskedLM - - >>> tokenizer = AutoTokenizer.from_pretrained("albert/albert-base-v2") - >>> model = TFAlbertForMaskedLM.from_pretrained("albert/albert-base-v2") - - >>> # add mask_token - >>> inputs = tokenizer(f"The capital of [MASK] is Paris.", return_tensors="tf") - >>> logits = model(**inputs).logits - - >>> # retrieve index of [MASK] - >>> mask_token_index = tf.where(inputs.input_ids == tokenizer.mask_token_id)[0][1] - >>> predicted_token_id = tf.math.argmax(logits[0, mask_token_index], axis=-1) - >>> tokenizer.decode(predicted_token_id) - 'france' - ``` - - ```python - >>> labels = tokenizer("The capital of France is Paris.", return_tensors="tf")["input_ids"] - >>> labels = tf.where(inputs.input_ids == tokenizer.mask_token_id, labels, -100) - >>> outputs = model(**inputs, labels=labels) - >>> round(float(outputs.loss), 2) - 0.81 - ``` - """ - outputs = self.albert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.predictions(hidden_states=sequence_output, training=training) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "albert", None) is not None: - with tf.name_scope(self.albert.name): - self.albert.build(None) - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -@add_start_docstrings( - """ - Albert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled - output) e.g. for GLUE tasks. - """, - ALBERT_START_DOCSTRING, -) -class TFAlbertForSequenceClassification(TFAlbertPreTrainedModel, TFSequenceClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"predictions"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config: AlbertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.albert = TFAlbertMainLayer(config, name="albert") - self.dropout = keras.layers.Dropout(rate=config.classifier_dropout_prob) - self.classifier = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="vumichien/albert-base-v2-imdb", - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="'LABEL_1'", - expected_loss=0.12, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.albert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(inputs=pooled_output, training=training) - logits = self.classifier(inputs=pooled_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "albert", None) is not None: - with tf.name_scope(self.albert.name): - self.albert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Albert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - ALBERT_START_DOCSTRING, -) -class TFAlbertForTokenClassification(TFAlbertPreTrainedModel, TFTokenClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"predictions"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config: AlbertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.albert = TFAlbertMainLayer(config, add_pooling_layer=False, name="albert") - classifier_dropout_prob = ( - config.classifier_dropout_prob - if config.classifier_dropout_prob is not None - else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(rate=classifier_dropout_prob) - self.classifier = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.albert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - sequence_output = self.dropout(inputs=sequence_output, training=training) - logits = self.classifier(inputs=sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "albert", None) is not None: - with tf.name_scope(self.albert.name): - self.albert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Albert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layer on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - ALBERT_START_DOCSTRING, -) -class TFAlbertForQuestionAnswering(TFAlbertPreTrainedModel, TFQuestionAnsweringLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"predictions"] - - def __init__(self, config: AlbertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.albert = TFAlbertMainLayer(config, add_pooling_layer=False, name="albert") - self.qa_outputs = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="vumichien/albert-base-v2-squad2", - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - qa_target_start_index=12, - qa_target_end_index=13, - expected_output="'a nice puppet'", - expected_loss=7.36, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.albert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.qa_outputs(inputs=sequence_output) - start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) - start_logits = tf.squeeze(input=start_logits, axis=-1) - end_logits = tf.squeeze(input=end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels=labels, logits=(start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "albert", None) is not None: - with tf.name_scope(self.albert.name): - self.albert.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Albert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - ALBERT_START_DOCSTRING, -) -class TFAlbertForMultipleChoice(TFAlbertPreTrainedModel, TFMultipleChoiceLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"predictions"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config: AlbertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.albert = TFAlbertMainLayer(config, name="albert") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - units=1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = ( - tf.reshape(tensor=attention_mask, shape=(-1, seq_length)) if attention_mask is not None else None - ) - flat_token_type_ids = ( - tf.reshape(tensor=token_type_ids, shape=(-1, seq_length)) if token_type_ids is not None else None - ) - flat_position_ids = ( - tf.reshape(tensor=position_ids, shape=(-1, seq_length)) if position_ids is not None else None - ) - flat_inputs_embeds = ( - tf.reshape(tensor=inputs_embeds, shape=(-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - outputs = self.albert( - input_ids=flat_input_ids, - attention_mask=flat_attention_mask, - token_type_ids=flat_token_type_ids, - position_ids=flat_position_ids, - head_mask=head_mask, - inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(inputs=pooled_output, training=training) - logits = self.classifier(inputs=pooled_output) - reshaped_logits = tf.reshape(tensor=logits, shape=(-1, num_choices)) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "albert", None) is not None: - with tf.name_scope(self.albert.name): - self.albert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFAlbertPreTrainedModel", - "TFAlbertModel", - "TFAlbertForPreTraining", - "TFAlbertForMaskedLM", - "TFAlbertForSequenceClassification", - "TFAlbertForTokenClassification", - "TFAlbertForQuestionAnswering", - "TFAlbertForMultipleChoice", - "TFAlbertMainLayer", -] diff --git a/src/transformers/models/align/modeling_align.py b/src/transformers/models/align/modeling_align.py index c226a3b36ac6..839856b92119 100644 --- a/src/transformers/models/align/modeling_align.py +++ b/src/transformers/models/align/modeling_align.py @@ -516,8 +516,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized diff --git a/src/transformers/models/altclip/modeling_altclip.py b/src/transformers/models/altclip/modeling_altclip.py index 61468141c570..5cae61f12d7f 100755 --- a/src/transformers/models/altclip/modeling_altclip.py +++ b/src/transformers/models/altclip/modeling_altclip.py @@ -101,8 +101,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized diff --git a/src/transformers/models/aria/image_processing_aria.py b/src/transformers/models/aria/image_processing_aria.py index 4fc2fcf7ec6b..f3f57b3d53c2 100644 --- a/src/transformers/models/aria/image_processing_aria.py +++ b/src/transformers/models/aria/image_processing_aria.py @@ -232,10 +232,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_normalize=do_normalize, diff --git a/src/transformers/models/aria/modular_aria.py b/src/transformers/models/aria/modular_aria.py index a626d2cd4b82..405c3d21dadb 100644 --- a/src/transformers/models/aria/modular_aria.py +++ b/src/transformers/models/aria/modular_aria.py @@ -615,10 +615,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_normalize=do_normalize, diff --git a/src/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py b/src/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py index f56c0c3213b7..b7ff6fa08e2f 100644 --- a/src/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py +++ b/src/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py @@ -179,7 +179,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. """ diff --git a/src/transformers/models/auto/__init__.py b/src/transformers/models/auto/__init__.py index 34a6ae1e5c2e..6b86884b3b7b 100644 --- a/src/transformers/models/auto/__init__.py +++ b/src/transformers/models/auto/__init__.py @@ -23,8 +23,6 @@ from .feature_extraction_auto import * from .image_processing_auto import * from .modeling_auto import * - from .modeling_flax_auto import * - from .modeling_tf_auto import * from .processing_auto import * from .tokenization_auto import * from .video_processing_auto import * diff --git a/src/transformers/models/auto/auto_factory.py b/src/transformers/models/auto/auto_factory.py index a8781c8042a6..75c053643f66 100644 --- a/src/transformers/models/auto/auto_factory.py +++ b/src/transformers/models/auto/auto_factory.py @@ -102,10 +102,6 @@ - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In - this case, `from_tf` should be set to `True` and a configuration object should be provided as - `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a - PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. model_args (additional positional arguments, *optional*): Will be passed along to the underlying model `__init__()` method. config ([`PretrainedConfig`], *optional*): @@ -127,9 +123,6 @@ cache_dir (`str` or `os.PathLike`, *optional*): Path to a directory in which a downloaded pretrained model configuration should be cached if the standard cache should not be used. - from_tf (`bool`, *optional*, defaults to `False`): - Load the model weights from a TensorFlow checkpoint save file (see docstring of - `pretrained_model_name_or_path` argument). force_download (`bool`, *optional*, defaults to `False`): Whether or not to force the (re-)download of the model weights and configuration files, overriding the cached versions if they exist. @@ -182,210 +175,6 @@ >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder", output_attentions=True) >>> model.config.output_attentions True - - >>> # Loading from a TF checkpoint file instead of a PyTorch model (slower) - >>> config = AutoConfig.from_pretrained("./tf_model/shortcut_placeholder_tf_model_config.json") - >>> model = BaseAutoModelClass.from_pretrained( - ... "./tf_model/shortcut_placeholder_tf_checkpoint.ckpt.index", from_tf=True, config=config - ... ) - ``` -""" - -FROM_PRETRAINED_TF_DOCSTRING = """ - Instantiate one of the model classes of the library from a pretrained model. - - The model class to instantiate is selected based on the `model_type` property of the config object (either - passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's missing, by - falling back to using pattern matching on `pretrained_model_name_or_path`: - - List options - - Args: - pretrained_model_name_or_path (`str` or `os.PathLike`): - Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *PyTorch state_dict save file* (e.g, `./pt_model/pytorch_model.bin`). In this - case, `from_pt` should be set to `True` and a configuration object should be provided as `config` - argument. This loading path is slower than converting the PyTorch model in a TensorFlow model - using the provided conversion scripts and loading the TensorFlow model afterwards. - model_args (additional positional arguments, *optional*): - Will be passed along to the underlying model `__init__()` method. - config ([`PretrainedConfig`], *optional*): - Configuration for the model to use instead of an automatically loaded configuration. Configuration can - be automatically loaded when: - - - The model is a model provided by the library (loaded with the *model id* string of a pretrained - model). - - The model was saved using [`~PreTrainedModel.save_pretrained`] and is reloaded by supplying the - save directory. - - The model is loaded by supplying a local directory as `pretrained_model_name_or_path` and a - configuration JSON file named *config.json* is found in the directory. - cache_dir (`str` or `os.PathLike`, *optional*): - Path to a directory in which a downloaded pretrained model configuration should be cached if the - standard cache should not be used. - from_pt (`bool`, *optional*, defaults to `False`): - Load the model weights from a PyTorch checkpoint save file (see docstring of - `pretrained_model_name_or_path` argument). - force_download (`bool`, *optional*, defaults to `False`): - Whether or not to force the (re-)download of the model weights and configuration files, overriding the - cached versions if they exist. - resume_download: - Deprecated and ignored. All downloads are now resumed by default when possible. - Will be removed in v5 of Transformers. - proxies (`dict[str, str]`, *optional*): - A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', - 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. - output_loading_info(`bool`, *optional*, defaults to `False`): - Whether ot not to also return a dictionary containing missing keys, unexpected keys and error messages. - local_files_only(`bool`, *optional*, defaults to `False`): - Whether or not to only look at local files (e.g., not try downloading the model). - revision (`str`, *optional*, defaults to `"main"`): - The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a - git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any - identifier allowed by git. - trust_remote_code (`bool`, *optional*, defaults to `False`): - Whether or not to allow for custom models defined on the Hub in their own modeling files. This option - should only be set to `True` for repositories you trust and in which you have read the code, as it will - execute code present on the Hub on your local machine. - code_revision (`str`, *optional*, defaults to `"main"`): - The specific revision to use for the code on the Hub, if the code leaves in a different repository than - the rest of the model. It can be a branch name, a tag name, or a commit id, since we use a git-based - system for storing models and other artifacts on huggingface.co, so `revision` can be any identifier - allowed by git. - kwargs (additional keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). Behaves differently depending on whether a `config` is provided or - automatically loaded: - - - If a configuration is provided with `config`, `**kwargs` will be directly passed to the - underlying model's `__init__` method (we assume all relevant updates to the configuration have - already been done) - - If a configuration is not provided, `kwargs` will be first passed to the configuration class - initialization function ([`~PretrainedConfig.from_pretrained`]). Each key of `kwargs` that - corresponds to a configuration attribute will be used to override said attribute with the - supplied `kwargs` value. Remaining keys that do not correspond to any configuration attribute - will be passed to the underlying model's `__init__` function. - - Examples: - - ```python - >>> from transformers import AutoConfig, BaseAutoModelClass - - >>> # Download model and configuration from huggingface.co and cache. - >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder") - - >>> # Update configuration during loading - >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder", output_attentions=True) - >>> model.config.output_attentions - True - - >>> # Loading from a PyTorch checkpoint file instead of a TensorFlow model (slower) - >>> config = AutoConfig.from_pretrained("./pt_model/shortcut_placeholder_pt_model_config.json") - >>> model = BaseAutoModelClass.from_pretrained( - ... "./pt_model/shortcut_placeholder_pytorch_model.bin", from_pt=True, config=config - ... ) - ``` -""" - -FROM_PRETRAINED_FLAX_DOCSTRING = """ - Instantiate one of the model classes of the library from a pretrained model. - - The model class to instantiate is selected based on the `model_type` property of the config object (either - passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's missing, by - falling back to using pattern matching on `pretrained_model_name_or_path`: - - List options - - Args: - pretrained_model_name_or_path (`str` or `os.PathLike`): - Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *PyTorch state_dict save file* (e.g, `./pt_model/pytorch_model.bin`). In this - case, `from_pt` should be set to `True` and a configuration object should be provided as `config` - argument. This loading path is slower than converting the PyTorch model in a TensorFlow model - using the provided conversion scripts and loading the TensorFlow model afterwards. - model_args (additional positional arguments, *optional*): - Will be passed along to the underlying model `__init__()` method. - config ([`PretrainedConfig`], *optional*): - Configuration for the model to use instead of an automatically loaded configuration. Configuration can - be automatically loaded when: - - - The model is a model provided by the library (loaded with the *model id* string of a pretrained - model). - - The model was saved using [`~PreTrainedModel.save_pretrained`] and is reloaded by supplying the - save directory. - - The model is loaded by supplying a local directory as `pretrained_model_name_or_path` and a - configuration JSON file named *config.json* is found in the directory. - cache_dir (`str` or `os.PathLike`, *optional*): - Path to a directory in which a downloaded pretrained model configuration should be cached if the - standard cache should not be used. - from_pt (`bool`, *optional*, defaults to `False`): - Load the model weights from a PyTorch checkpoint save file (see docstring of - `pretrained_model_name_or_path` argument). - force_download (`bool`, *optional*, defaults to `False`): - Whether or not to force the (re-)download of the model weights and configuration files, overriding the - cached versions if they exist. - resume_download: - Deprecated and ignored. All downloads are now resumed by default when possible. - Will be removed in v5 of Transformers. - proxies (`dict[str, str]`, *optional*): - A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', - 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. - output_loading_info(`bool`, *optional*, defaults to `False`): - Whether ot not to also return a dictionary containing missing keys, unexpected keys and error messages. - local_files_only(`bool`, *optional*, defaults to `False`): - Whether or not to only look at local files (e.g., not try downloading the model). - revision (`str`, *optional*, defaults to `"main"`): - The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a - git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any - identifier allowed by git. - trust_remote_code (`bool`, *optional*, defaults to `False`): - Whether or not to allow for custom models defined on the Hub in their own modeling files. This option - should only be set to `True` for repositories you trust and in which you have read the code, as it will - execute code present on the Hub on your local machine. - code_revision (`str`, *optional*, defaults to `"main"`): - The specific revision to use for the code on the Hub, if the code leaves in a different repository than - the rest of the model. It can be a branch name, a tag name, or a commit id, since we use a git-based - system for storing models and other artifacts on huggingface.co, so `revision` can be any identifier - allowed by git. - kwargs (additional keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). Behaves differently depending on whether a `config` is provided or - automatically loaded: - - - If a configuration is provided with `config`, `**kwargs` will be directly passed to the - underlying model's `__init__` method (we assume all relevant updates to the configuration have - already been done) - - If a configuration is not provided, `kwargs` will be first passed to the configuration class - initialization function ([`~PretrainedConfig.from_pretrained`]). Each key of `kwargs` that - corresponds to a configuration attribute will be used to override said attribute with the - supplied `kwargs` value. Remaining keys that do not correspond to any configuration attribute - will be passed to the underlying model's `__init__` function. - - Examples: - - ```python - >>> from transformers import AutoConfig, BaseAutoModelClass - - >>> # Download model and configuration from huggingface.co and cache. - >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder") - - >>> # Update configuration during loading - >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder", output_attentions=True) - >>> model.config.output_attentions - True - - >>> # Loading from a PyTorch checkpoint file instead of a TensorFlow model (slower) - >>> config = AutoConfig.from_pretrained("./pt_model/shortcut_placeholder_pt_model_config.json") - >>> model = BaseAutoModelClass.from_pretrained( - ... "./pt_model/shortcut_placeholder_pytorch_model.bin", from_pt=True, config=config - ... ) ``` """ @@ -400,10 +189,6 @@ def _get_model_class(config, model_mapping): for arch in architectures: if arch in name_to_model: return name_to_model[arch] - elif f"TF{arch}" in name_to_model: - return name_to_model[f"TF{arch}"] - elif f"Flax{arch}" in name_to_model: - return name_to_model[f"Flax{arch}"] # If not architecture is set in the config or match the supported models, the first element of the tuple is the # defaults. @@ -696,12 +481,7 @@ def auto_class_update(cls, checkpoint_for_example: str = "google-bert/bert-base- from_config = replace_list_option_in_docstrings(model_mapping._model_mapping, use_model_types=False)(from_config) cls.from_config = classmethod(from_config) - if name.startswith("TF"): - from_pretrained_docstring = FROM_PRETRAINED_TF_DOCSTRING - elif name.startswith("Flax"): - from_pretrained_docstring = FROM_PRETRAINED_FLAX_DOCSTRING - else: - from_pretrained_docstring = FROM_PRETRAINED_TORCH_DOCSTRING + from_pretrained_docstring = FROM_PRETRAINED_TORCH_DOCSTRING from_pretrained = copy_func(_BaseAutoModelClass.from_pretrained) from_pretrained_docstring = insert_head_doc(from_pretrained_docstring, head_doc=head_doc) from_pretrained_docstring = from_pretrained_docstring.replace("BaseAutoModelClass", name) diff --git a/src/transformers/models/auto/modeling_flax_auto.py b/src/transformers/models/auto/modeling_flax_auto.py deleted file mode 100644 index 0588d03cb6cd..000000000000 --- a/src/transformers/models/auto/modeling_flax_auto.py +++ /dev/null @@ -1,413 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The Google Flax Team Authors and 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. -"""Auto Model class.""" - -from collections import OrderedDict - -from ...utils import logging -from .auto_factory import _BaseAutoModelClass, _LazyAutoMapping, auto_class_update -from .configuration_auto import CONFIG_MAPPING_NAMES - - -logger = logging.get_logger(__name__) - - -FLAX_MODEL_MAPPING_NAMES = OrderedDict( - [ - # Base model mapping - ("albert", "FlaxAlbertModel"), - ("bart", "FlaxBartModel"), - ("beit", "FlaxBeitModel"), - ("bert", "FlaxBertModel"), - ("big_bird", "FlaxBigBirdModel"), - ("blenderbot", "FlaxBlenderbotModel"), - ("blenderbot-small", "FlaxBlenderbotSmallModel"), - ("bloom", "FlaxBloomModel"), - ("clip", "FlaxCLIPModel"), - ("dinov2", "FlaxDinov2Model"), - ("distilbert", "FlaxDistilBertModel"), - ("electra", "FlaxElectraModel"), - ("gemma", "FlaxGemmaModel"), - ("gpt-sw3", "FlaxGPT2Model"), - ("gpt2", "FlaxGPT2Model"), - ("gpt_neo", "FlaxGPTNeoModel"), - ("gptj", "FlaxGPTJModel"), - ("llama", "FlaxLlamaModel"), - ("longt5", "FlaxLongT5Model"), - ("marian", "FlaxMarianModel"), - ("mbart", "FlaxMBartModel"), - ("mistral", "FlaxMistralModel"), - ("mt5", "FlaxMT5Model"), - ("opt", "FlaxOPTModel"), - ("pegasus", "FlaxPegasusModel"), - ("regnet", "FlaxRegNetModel"), - ("resnet", "FlaxResNetModel"), - ("roberta", "FlaxRobertaModel"), - ("roberta-prelayernorm", "FlaxRobertaPreLayerNormModel"), - ("roformer", "FlaxRoFormerModel"), - ("t5", "FlaxT5Model"), - ("vision-text-dual-encoder", "FlaxVisionTextDualEncoderModel"), - ("vit", "FlaxViTModel"), - ("wav2vec2", "FlaxWav2Vec2Model"), - ("whisper", "FlaxWhisperModel"), - ("xglm", "FlaxXGLMModel"), - ("xlm-roberta", "FlaxXLMRobertaModel"), - ] -) - -FLAX_MODEL_FOR_PRETRAINING_MAPPING_NAMES = OrderedDict( - [ - # Model for pre-training mapping - ("albert", "FlaxAlbertForPreTraining"), - ("bart", "FlaxBartForConditionalGeneration"), - ("bert", "FlaxBertForPreTraining"), - ("big_bird", "FlaxBigBirdForPreTraining"), - ("electra", "FlaxElectraForPreTraining"), - ("longt5", "FlaxLongT5ForConditionalGeneration"), - ("mbart", "FlaxMBartForConditionalGeneration"), - ("mt5", "FlaxMT5ForConditionalGeneration"), - ("roberta", "FlaxRobertaForMaskedLM"), - ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForMaskedLM"), - ("roformer", "FlaxRoFormerForMaskedLM"), - ("t5", "FlaxT5ForConditionalGeneration"), - ("wav2vec2", "FlaxWav2Vec2ForPreTraining"), - ("whisper", "FlaxWhisperForConditionalGeneration"), - ("xlm-roberta", "FlaxXLMRobertaForMaskedLM"), - ] -) - -FLAX_MODEL_FOR_MASKED_LM_MAPPING_NAMES = OrderedDict( - [ - # Model for Masked LM mapping - ("albert", "FlaxAlbertForMaskedLM"), - ("bart", "FlaxBartForConditionalGeneration"), - ("bert", "FlaxBertForMaskedLM"), - ("big_bird", "FlaxBigBirdForMaskedLM"), - ("distilbert", "FlaxDistilBertForMaskedLM"), - ("electra", "FlaxElectraForMaskedLM"), - ("mbart", "FlaxMBartForConditionalGeneration"), - ("roberta", "FlaxRobertaForMaskedLM"), - ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForMaskedLM"), - ("roformer", "FlaxRoFormerForMaskedLM"), - ("xlm-roberta", "FlaxXLMRobertaForMaskedLM"), - ] -) - -FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES = OrderedDict( - [ - # Model for Seq2Seq Causal LM mapping - ("bart", "FlaxBartForConditionalGeneration"), - ("blenderbot", "FlaxBlenderbotForConditionalGeneration"), - ("blenderbot-small", "FlaxBlenderbotSmallForConditionalGeneration"), - ("encoder-decoder", "FlaxEncoderDecoderModel"), - ("longt5", "FlaxLongT5ForConditionalGeneration"), - ("marian", "FlaxMarianMTModel"), - ("mbart", "FlaxMBartForConditionalGeneration"), - ("mt5", "FlaxMT5ForConditionalGeneration"), - ("pegasus", "FlaxPegasusForConditionalGeneration"), - ("t5", "FlaxT5ForConditionalGeneration"), - ] -) - -FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( - [ - # Model for Image-classification - ("beit", "FlaxBeitForImageClassification"), - ("dinov2", "FlaxDinov2ForImageClassification"), - ("regnet", "FlaxRegNetForImageClassification"), - ("resnet", "FlaxResNetForImageClassification"), - ("vit", "FlaxViTForImageClassification"), - ] -) - -FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES = OrderedDict( - [ - ("vision-encoder-decoder", "FlaxVisionEncoderDecoderModel"), - ] -) - -FLAX_MODEL_FOR_CAUSAL_LM_MAPPING_NAMES = OrderedDict( - [ - # Model for Causal LM mapping - ("bart", "FlaxBartForCausalLM"), - ("bert", "FlaxBertForCausalLM"), - ("big_bird", "FlaxBigBirdForCausalLM"), - ("bloom", "FlaxBloomForCausalLM"), - ("electra", "FlaxElectraForCausalLM"), - ("gemma", "FlaxGemmaForCausalLM"), - ("gpt-sw3", "FlaxGPT2LMHeadModel"), - ("gpt2", "FlaxGPT2LMHeadModel"), - ("gpt_neo", "FlaxGPTNeoForCausalLM"), - ("gptj", "FlaxGPTJForCausalLM"), - ("llama", "FlaxLlamaForCausalLM"), - ("mistral", "FlaxMistralForCausalLM"), - ("opt", "FlaxOPTForCausalLM"), - ("roberta", "FlaxRobertaForCausalLM"), - ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForCausalLM"), - ("xglm", "FlaxXGLMForCausalLM"), - ("xlm-roberta", "FlaxXLMRobertaForCausalLM"), - ] -) - -FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( - [ - # Model for Sequence Classification mapping - ("albert", "FlaxAlbertForSequenceClassification"), - ("bart", "FlaxBartForSequenceClassification"), - ("bert", "FlaxBertForSequenceClassification"), - ("big_bird", "FlaxBigBirdForSequenceClassification"), - ("distilbert", "FlaxDistilBertForSequenceClassification"), - ("electra", "FlaxElectraForSequenceClassification"), - ("mbart", "FlaxMBartForSequenceClassification"), - ("roberta", "FlaxRobertaForSequenceClassification"), - ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForSequenceClassification"), - ("roformer", "FlaxRoFormerForSequenceClassification"), - ("xlm-roberta", "FlaxXLMRobertaForSequenceClassification"), - ] -) - -FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( - [ - # Model for Question Answering mapping - ("albert", "FlaxAlbertForQuestionAnswering"), - ("bart", "FlaxBartForQuestionAnswering"), - ("bert", "FlaxBertForQuestionAnswering"), - ("big_bird", "FlaxBigBirdForQuestionAnswering"), - ("distilbert", "FlaxDistilBertForQuestionAnswering"), - ("electra", "FlaxElectraForQuestionAnswering"), - ("mbart", "FlaxMBartForQuestionAnswering"), - ("roberta", "FlaxRobertaForQuestionAnswering"), - ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForQuestionAnswering"), - ("roformer", "FlaxRoFormerForQuestionAnswering"), - ("xlm-roberta", "FlaxXLMRobertaForQuestionAnswering"), - ] -) - -FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES = OrderedDict( - [ - # Model for Token Classification mapping - ("albert", "FlaxAlbertForTokenClassification"), - ("bert", "FlaxBertForTokenClassification"), - ("big_bird", "FlaxBigBirdForTokenClassification"), - ("distilbert", "FlaxDistilBertForTokenClassification"), - ("electra", "FlaxElectraForTokenClassification"), - ("roberta", "FlaxRobertaForTokenClassification"), - ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForTokenClassification"), - ("roformer", "FlaxRoFormerForTokenClassification"), - ("xlm-roberta", "FlaxXLMRobertaForTokenClassification"), - ] -) - -FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES = OrderedDict( - [ - # Model for Multiple Choice mapping - ("albert", "FlaxAlbertForMultipleChoice"), - ("bert", "FlaxBertForMultipleChoice"), - ("big_bird", "FlaxBigBirdForMultipleChoice"), - ("distilbert", "FlaxDistilBertForMultipleChoice"), - ("electra", "FlaxElectraForMultipleChoice"), - ("roberta", "FlaxRobertaForMultipleChoice"), - ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForMultipleChoice"), - ("roformer", "FlaxRoFormerForMultipleChoice"), - ("xlm-roberta", "FlaxXLMRobertaForMultipleChoice"), - ] -) - -FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES = OrderedDict( - [ - ("bert", "FlaxBertForNextSentencePrediction"), - ] -) - -FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES = OrderedDict( - [ - ("speech-encoder-decoder", "FlaxSpeechEncoderDecoderModel"), - ("whisper", "FlaxWhisperForConditionalGeneration"), - ] -) - -FLAX_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES = OrderedDict( - [ - ("whisper", "FlaxWhisperForAudioClassification"), - ] -) - -FLAX_MODEL_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FLAX_MODEL_MAPPING_NAMES) -FLAX_MODEL_FOR_PRETRAINING_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_PRETRAINING_MAPPING_NAMES) -FLAX_MODEL_FOR_MASKED_LM_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_MASKED_LM_MAPPING_NAMES) -FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES -) -FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES -) -FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES) -FLAX_MODEL_FOR_CAUSAL_LM_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_CAUSAL_LM_MAPPING_NAMES) -FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES -) -FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES -) -FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES -) -FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES -) -FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES -) -FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES -) -FLAX_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES -) - - -class FlaxAutoModel(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_MAPPING - - -FlaxAutoModel = auto_class_update(FlaxAutoModel) - - -class FlaxAutoModelForPreTraining(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_PRETRAINING_MAPPING - - -FlaxAutoModelForPreTraining = auto_class_update(FlaxAutoModelForPreTraining, head_doc="pretraining") - - -class FlaxAutoModelForCausalLM(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_CAUSAL_LM_MAPPING - - -FlaxAutoModelForCausalLM = auto_class_update(FlaxAutoModelForCausalLM, head_doc="causal language modeling") - - -class FlaxAutoModelForMaskedLM(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_MASKED_LM_MAPPING - - -FlaxAutoModelForMaskedLM = auto_class_update(FlaxAutoModelForMaskedLM, head_doc="masked language modeling") - - -class FlaxAutoModelForSeq2SeqLM(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING - - -FlaxAutoModelForSeq2SeqLM = auto_class_update( - FlaxAutoModelForSeq2SeqLM, - head_doc="sequence-to-sequence language modeling", - checkpoint_for_example="google-t5/t5-base", -) - - -class FlaxAutoModelForSequenceClassification(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING - - -FlaxAutoModelForSequenceClassification = auto_class_update( - FlaxAutoModelForSequenceClassification, head_doc="sequence classification" -) - - -class FlaxAutoModelForQuestionAnswering(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING - - -FlaxAutoModelForQuestionAnswering = auto_class_update(FlaxAutoModelForQuestionAnswering, head_doc="question answering") - - -class FlaxAutoModelForTokenClassification(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING - - -FlaxAutoModelForTokenClassification = auto_class_update( - FlaxAutoModelForTokenClassification, head_doc="token classification" -) - - -class FlaxAutoModelForMultipleChoice(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING - - -FlaxAutoModelForMultipleChoice = auto_class_update(FlaxAutoModelForMultipleChoice, head_doc="multiple choice") - - -class FlaxAutoModelForNextSentencePrediction(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING - - -FlaxAutoModelForNextSentencePrediction = auto_class_update( - FlaxAutoModelForNextSentencePrediction, head_doc="next sentence prediction" -) - - -class FlaxAutoModelForImageClassification(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING - - -FlaxAutoModelForImageClassification = auto_class_update( - FlaxAutoModelForImageClassification, head_doc="image classification" -) - - -class FlaxAutoModelForVision2Seq(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING - - -FlaxAutoModelForVision2Seq = auto_class_update(FlaxAutoModelForVision2Seq, head_doc="vision-to-text modeling") - - -class FlaxAutoModelForSpeechSeq2Seq(_BaseAutoModelClass): - _model_mapping = FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING - - -FlaxAutoModelForSpeechSeq2Seq = auto_class_update( - FlaxAutoModelForSpeechSeq2Seq, head_doc="sequence-to-sequence speech-to-text modeling" -) - -__all__ = [ - "FLAX_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING", - "FLAX_MODEL_FOR_CAUSAL_LM_MAPPING", - "FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING", - "FLAX_MODEL_FOR_MASKED_LM_MAPPING", - "FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING", - "FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING", - "FLAX_MODEL_FOR_PRETRAINING_MAPPING", - "FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING", - "FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING", - "FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING", - "FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING", - "FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING", - "FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING", - "FLAX_MODEL_MAPPING", - "FlaxAutoModel", - "FlaxAutoModelForCausalLM", - "FlaxAutoModelForImageClassification", - "FlaxAutoModelForMaskedLM", - "FlaxAutoModelForMultipleChoice", - "FlaxAutoModelForNextSentencePrediction", - "FlaxAutoModelForPreTraining", - "FlaxAutoModelForQuestionAnswering", - "FlaxAutoModelForSeq2SeqLM", - "FlaxAutoModelForSequenceClassification", - "FlaxAutoModelForSpeechSeq2Seq", - "FlaxAutoModelForTokenClassification", - "FlaxAutoModelForVision2Seq", -] diff --git a/src/transformers/models/auto/modeling_tf_auto.py b/src/transformers/models/auto/modeling_tf_auto.py deleted file mode 100644 index cf39f4d7c9c4..000000000000 --- a/src/transformers/models/auto/modeling_tf_auto.py +++ /dev/null @@ -1,776 +0,0 @@ -# coding=utf-8 -# Copyright 2018 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. -"""Auto Model class.""" - -import warnings -from collections import OrderedDict - -from ...utils import logging -from .auto_factory import _BaseAutoModelClass, _LazyAutoMapping, auto_class_update -from .configuration_auto import CONFIG_MAPPING_NAMES - - -logger = logging.get_logger(__name__) - - -TF_MODEL_MAPPING_NAMES = OrderedDict( - [ - # Base model mapping - ("albert", "TFAlbertModel"), - ("bart", "TFBartModel"), - ("bert", "TFBertModel"), - ("blenderbot", "TFBlenderbotModel"), - ("blenderbot-small", "TFBlenderbotSmallModel"), - ("blip", "TFBlipModel"), - ("camembert", "TFCamembertModel"), - ("clip", "TFCLIPModel"), - ("convbert", "TFConvBertModel"), - ("convnext", "TFConvNextModel"), - ("convnextv2", "TFConvNextV2Model"), - ("ctrl", "TFCTRLModel"), - ("cvt", "TFCvtModel"), - ("data2vec-vision", "TFData2VecVisionModel"), - ("deberta", "TFDebertaModel"), - ("deberta-v2", "TFDebertaV2Model"), - ("deit", "TFDeiTModel"), - ("distilbert", "TFDistilBertModel"), - ("dpr", "TFDPRQuestionEncoder"), - ("efficientformer", "TFEfficientFormerModel"), - ("electra", "TFElectraModel"), - ("esm", "TFEsmModel"), - ("flaubert", "TFFlaubertModel"), - ("funnel", ("TFFunnelModel", "TFFunnelBaseModel")), - ("gpt-sw3", "TFGPT2Model"), - ("gpt2", "TFGPT2Model"), - ("gptj", "TFGPTJModel"), - ("groupvit", "TFGroupViTModel"), - ("hubert", "TFHubertModel"), - ("idefics", "TFIdeficsModel"), - ("layoutlm", "TFLayoutLMModel"), - ("layoutlmv3", "TFLayoutLMv3Model"), - ("led", "TFLEDModel"), - ("longformer", "TFLongformerModel"), - ("lxmert", "TFLxmertModel"), - ("marian", "TFMarianModel"), - ("mbart", "TFMBartModel"), - ("mistral", "TFMistralModel"), - ("mobilebert", "TFMobileBertModel"), - ("mobilevit", "TFMobileViTModel"), - ("mpnet", "TFMPNetModel"), - ("mt5", "TFMT5Model"), - ("openai-gpt", "TFOpenAIGPTModel"), - ("opt", "TFOPTModel"), - ("pegasus", "TFPegasusModel"), - ("regnet", "TFRegNetModel"), - ("rembert", "TFRemBertModel"), - ("resnet", "TFResNetModel"), - ("roberta", "TFRobertaModel"), - ("roberta-prelayernorm", "TFRobertaPreLayerNormModel"), - ("roformer", "TFRoFormerModel"), - ("sam", "TFSamModel"), - ("sam_vision_model", "TFSamVisionModel"), - ("segformer", "TFSegformerModel"), - ("speech_to_text", "TFSpeech2TextModel"), - ("swiftformer", "TFSwiftFormerModel"), - ("swin", "TFSwinModel"), - ("t5", "TFT5Model"), - ("tapas", "TFTapasModel"), - ("transfo-xl", "TFTransfoXLModel"), - ("vision-text-dual-encoder", "TFVisionTextDualEncoderModel"), - ("vit", "TFViTModel"), - ("vit_mae", "TFViTMAEModel"), - ("wav2vec2", "TFWav2Vec2Model"), - ("whisper", "TFWhisperModel"), - ("xglm", "TFXGLMModel"), - ("xlm", "TFXLMModel"), - ("xlm-roberta", "TFXLMRobertaModel"), - ("xlnet", "TFXLNetModel"), - ] -) - -TF_MODEL_FOR_PRETRAINING_MAPPING_NAMES = OrderedDict( - [ - # Model for pre-training mapping - ("albert", "TFAlbertForPreTraining"), - ("bart", "TFBartForConditionalGeneration"), - ("bert", "TFBertForPreTraining"), - ("camembert", "TFCamembertForMaskedLM"), - ("ctrl", "TFCTRLLMHeadModel"), - ("distilbert", "TFDistilBertForMaskedLM"), - ("electra", "TFElectraForPreTraining"), - ("flaubert", "TFFlaubertWithLMHeadModel"), - ("funnel", "TFFunnelForPreTraining"), - ("gpt-sw3", "TFGPT2LMHeadModel"), - ("gpt2", "TFGPT2LMHeadModel"), - ("idefics", "TFIdeficsForVisionText2Text"), - ("layoutlm", "TFLayoutLMForMaskedLM"), - ("lxmert", "TFLxmertForPreTraining"), - ("mobilebert", "TFMobileBertForPreTraining"), - ("mpnet", "TFMPNetForMaskedLM"), - ("openai-gpt", "TFOpenAIGPTLMHeadModel"), - ("roberta", "TFRobertaForMaskedLM"), - ("roberta-prelayernorm", "TFRobertaPreLayerNormForMaskedLM"), - ("t5", "TFT5ForConditionalGeneration"), - ("tapas", "TFTapasForMaskedLM"), - ("transfo-xl", "TFTransfoXLLMHeadModel"), - ("vit_mae", "TFViTMAEForPreTraining"), - ("xlm", "TFXLMWithLMHeadModel"), - ("xlm-roberta", "TFXLMRobertaForMaskedLM"), - ("xlnet", "TFXLNetLMHeadModel"), - ] -) - -TF_MODEL_WITH_LM_HEAD_MAPPING_NAMES = OrderedDict( - [ - # Model with LM heads mapping - ("albert", "TFAlbertForMaskedLM"), - ("bart", "TFBartForConditionalGeneration"), - ("bert", "TFBertForMaskedLM"), - ("camembert", "TFCamembertForMaskedLM"), - ("convbert", "TFConvBertForMaskedLM"), - ("ctrl", "TFCTRLLMHeadModel"), - ("distilbert", "TFDistilBertForMaskedLM"), - ("electra", "TFElectraForMaskedLM"), - ("esm", "TFEsmForMaskedLM"), - ("flaubert", "TFFlaubertWithLMHeadModel"), - ("funnel", "TFFunnelForMaskedLM"), - ("gpt-sw3", "TFGPT2LMHeadModel"), - ("gpt2", "TFGPT2LMHeadModel"), - ("gptj", "TFGPTJForCausalLM"), - ("layoutlm", "TFLayoutLMForMaskedLM"), - ("led", "TFLEDForConditionalGeneration"), - ("longformer", "TFLongformerForMaskedLM"), - ("marian", "TFMarianMTModel"), - ("mobilebert", "TFMobileBertForMaskedLM"), - ("mpnet", "TFMPNetForMaskedLM"), - ("openai-gpt", "TFOpenAIGPTLMHeadModel"), - ("rembert", "TFRemBertForMaskedLM"), - ("roberta", "TFRobertaForMaskedLM"), - ("roberta-prelayernorm", "TFRobertaPreLayerNormForMaskedLM"), - ("roformer", "TFRoFormerForMaskedLM"), - ("speech_to_text", "TFSpeech2TextForConditionalGeneration"), - ("t5", "TFT5ForConditionalGeneration"), - ("tapas", "TFTapasForMaskedLM"), - ("transfo-xl", "TFTransfoXLLMHeadModel"), - ("whisper", "TFWhisperForConditionalGeneration"), - ("xlm", "TFXLMWithLMHeadModel"), - ("xlm-roberta", "TFXLMRobertaForMaskedLM"), - ("xlnet", "TFXLNetLMHeadModel"), - ] -) - -TF_MODEL_FOR_CAUSAL_LM_MAPPING_NAMES = OrderedDict( - [ - # Model for Causal LM mapping - ("bert", "TFBertLMHeadModel"), - ("camembert", "TFCamembertForCausalLM"), - ("ctrl", "TFCTRLLMHeadModel"), - ("gpt-sw3", "TFGPT2LMHeadModel"), - ("gpt2", "TFGPT2LMHeadModel"), - ("gptj", "TFGPTJForCausalLM"), - ("mistral", "TFMistralForCausalLM"), - ("openai-gpt", "TFOpenAIGPTLMHeadModel"), - ("opt", "TFOPTForCausalLM"), - ("rembert", "TFRemBertForCausalLM"), - ("roberta", "TFRobertaForCausalLM"), - ("roberta-prelayernorm", "TFRobertaPreLayerNormForCausalLM"), - ("roformer", "TFRoFormerForCausalLM"), - ("transfo-xl", "TFTransfoXLLMHeadModel"), - ("xglm", "TFXGLMForCausalLM"), - ("xlm", "TFXLMWithLMHeadModel"), - ("xlm-roberta", "TFXLMRobertaForCausalLM"), - ("xlnet", "TFXLNetLMHeadModel"), - ] -) - -TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES = OrderedDict( - [ - ("deit", "TFDeiTForMaskedImageModeling"), - ("swin", "TFSwinForMaskedImageModeling"), - ] -) - -TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( - [ - # Model for Image-classsification - ("convnext", "TFConvNextForImageClassification"), - ("convnextv2", "TFConvNextV2ForImageClassification"), - ("cvt", "TFCvtForImageClassification"), - ("data2vec-vision", "TFData2VecVisionForImageClassification"), - ("deit", ("TFDeiTForImageClassification", "TFDeiTForImageClassificationWithTeacher")), - ( - "efficientformer", - ("TFEfficientFormerForImageClassification", "TFEfficientFormerForImageClassificationWithTeacher"), - ), - ("mobilevit", "TFMobileViTForImageClassification"), - ("regnet", "TFRegNetForImageClassification"), - ("resnet", "TFResNetForImageClassification"), - ("segformer", "TFSegformerForImageClassification"), - ("swiftformer", "TFSwiftFormerForImageClassification"), - ("swin", "TFSwinForImageClassification"), - ("vit", "TFViTForImageClassification"), - ] -) - - -TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( - [ - # Model for Zero Shot Image Classification mapping - ("blip", "TFBlipModel"), - ("clip", "TFCLIPModel"), - ] -) - - -TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES = OrderedDict( - [ - # Model for Semantic Segmentation mapping - ("data2vec-vision", "TFData2VecVisionForSemanticSegmentation"), - ("mobilevit", "TFMobileViTForSemanticSegmentation"), - ("segformer", "TFSegformerForSemanticSegmentation"), - ] -) - -TF_MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES = OrderedDict( - [ - ("blip", "TFBlipForConditionalGeneration"), - ("vision-encoder-decoder", "TFVisionEncoderDecoderModel"), - ] -) - -TF_MODEL_FOR_MASKED_LM_MAPPING_NAMES = OrderedDict( - [ - # Model for Masked LM mapping - ("albert", "TFAlbertForMaskedLM"), - ("bert", "TFBertForMaskedLM"), - ("camembert", "TFCamembertForMaskedLM"), - ("convbert", "TFConvBertForMaskedLM"), - ("deberta", "TFDebertaForMaskedLM"), - ("deberta-v2", "TFDebertaV2ForMaskedLM"), - ("distilbert", "TFDistilBertForMaskedLM"), - ("electra", "TFElectraForMaskedLM"), - ("esm", "TFEsmForMaskedLM"), - ("flaubert", "TFFlaubertWithLMHeadModel"), - ("funnel", "TFFunnelForMaskedLM"), - ("layoutlm", "TFLayoutLMForMaskedLM"), - ("longformer", "TFLongformerForMaskedLM"), - ("mobilebert", "TFMobileBertForMaskedLM"), - ("mpnet", "TFMPNetForMaskedLM"), - ("rembert", "TFRemBertForMaskedLM"), - ("roberta", "TFRobertaForMaskedLM"), - ("roberta-prelayernorm", "TFRobertaPreLayerNormForMaskedLM"), - ("roformer", "TFRoFormerForMaskedLM"), - ("tapas", "TFTapasForMaskedLM"), - ("xlm", "TFXLMWithLMHeadModel"), - ("xlm-roberta", "TFXLMRobertaForMaskedLM"), - ] -) - -TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES = OrderedDict( - [ - # Model for Seq2Seq Causal LM mapping - ("bart", "TFBartForConditionalGeneration"), - ("blenderbot", "TFBlenderbotForConditionalGeneration"), - ("blenderbot-small", "TFBlenderbotSmallForConditionalGeneration"), - ("encoder-decoder", "TFEncoderDecoderModel"), - ("led", "TFLEDForConditionalGeneration"), - ("marian", "TFMarianMTModel"), - ("mbart", "TFMBartForConditionalGeneration"), - ("mt5", "TFMT5ForConditionalGeneration"), - ("pegasus", "TFPegasusForConditionalGeneration"), - ("t5", "TFT5ForConditionalGeneration"), - ] -) - -TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES = OrderedDict( - [ - ("speech_to_text", "TFSpeech2TextForConditionalGeneration"), - ("whisper", "TFWhisperForConditionalGeneration"), - ] -) - -TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( - [ - # Model for Sequence Classification mapping - ("albert", "TFAlbertForSequenceClassification"), - ("bart", "TFBartForSequenceClassification"), - ("bert", "TFBertForSequenceClassification"), - ("camembert", "TFCamembertForSequenceClassification"), - ("convbert", "TFConvBertForSequenceClassification"), - ("ctrl", "TFCTRLForSequenceClassification"), - ("deberta", "TFDebertaForSequenceClassification"), - ("deberta-v2", "TFDebertaV2ForSequenceClassification"), - ("distilbert", "TFDistilBertForSequenceClassification"), - ("electra", "TFElectraForSequenceClassification"), - ("esm", "TFEsmForSequenceClassification"), - ("flaubert", "TFFlaubertForSequenceClassification"), - ("funnel", "TFFunnelForSequenceClassification"), - ("gpt-sw3", "TFGPT2ForSequenceClassification"), - ("gpt2", "TFGPT2ForSequenceClassification"), - ("gptj", "TFGPTJForSequenceClassification"), - ("layoutlm", "TFLayoutLMForSequenceClassification"), - ("layoutlmv3", "TFLayoutLMv3ForSequenceClassification"), - ("longformer", "TFLongformerForSequenceClassification"), - ("mistral", "TFMistralForSequenceClassification"), - ("mobilebert", "TFMobileBertForSequenceClassification"), - ("mpnet", "TFMPNetForSequenceClassification"), - ("openai-gpt", "TFOpenAIGPTForSequenceClassification"), - ("rembert", "TFRemBertForSequenceClassification"), - ("roberta", "TFRobertaForSequenceClassification"), - ("roberta-prelayernorm", "TFRobertaPreLayerNormForSequenceClassification"), - ("roformer", "TFRoFormerForSequenceClassification"), - ("tapas", "TFTapasForSequenceClassification"), - ("transfo-xl", "TFTransfoXLForSequenceClassification"), - ("xlm", "TFXLMForSequenceClassification"), - ("xlm-roberta", "TFXLMRobertaForSequenceClassification"), - ("xlnet", "TFXLNetForSequenceClassification"), - ] -) - -TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( - [ - # Model for Question Answering mapping - ("albert", "TFAlbertForQuestionAnswering"), - ("bert", "TFBertForQuestionAnswering"), - ("camembert", "TFCamembertForQuestionAnswering"), - ("convbert", "TFConvBertForQuestionAnswering"), - ("deberta", "TFDebertaForQuestionAnswering"), - ("deberta-v2", "TFDebertaV2ForQuestionAnswering"), - ("distilbert", "TFDistilBertForQuestionAnswering"), - ("electra", "TFElectraForQuestionAnswering"), - ("flaubert", "TFFlaubertForQuestionAnsweringSimple"), - ("funnel", "TFFunnelForQuestionAnswering"), - ("gptj", "TFGPTJForQuestionAnswering"), - ("layoutlmv3", "TFLayoutLMv3ForQuestionAnswering"), - ("longformer", "TFLongformerForQuestionAnswering"), - ("mobilebert", "TFMobileBertForQuestionAnswering"), - ("mpnet", "TFMPNetForQuestionAnswering"), - ("rembert", "TFRemBertForQuestionAnswering"), - ("roberta", "TFRobertaForQuestionAnswering"), - ("roberta-prelayernorm", "TFRobertaPreLayerNormForQuestionAnswering"), - ("roformer", "TFRoFormerForQuestionAnswering"), - ("xlm", "TFXLMForQuestionAnsweringSimple"), - ("xlm-roberta", "TFXLMRobertaForQuestionAnswering"), - ("xlnet", "TFXLNetForQuestionAnsweringSimple"), - ] -) -TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES = OrderedDict([("wav2vec2", "TFWav2Vec2ForSequenceClassification")]) - -TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( - [ - ("layoutlm", "TFLayoutLMForQuestionAnswering"), - ("layoutlmv3", "TFLayoutLMv3ForQuestionAnswering"), - ] -) - - -TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( - [ - # Model for Table Question Answering mapping - ("tapas", "TFTapasForQuestionAnswering"), - ] -) - -TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES = OrderedDict( - [ - # Model for Token Classification mapping - ("albert", "TFAlbertForTokenClassification"), - ("bert", "TFBertForTokenClassification"), - ("camembert", "TFCamembertForTokenClassification"), - ("convbert", "TFConvBertForTokenClassification"), - ("deberta", "TFDebertaForTokenClassification"), - ("deberta-v2", "TFDebertaV2ForTokenClassification"), - ("distilbert", "TFDistilBertForTokenClassification"), - ("electra", "TFElectraForTokenClassification"), - ("esm", "TFEsmForTokenClassification"), - ("flaubert", "TFFlaubertForTokenClassification"), - ("funnel", "TFFunnelForTokenClassification"), - ("layoutlm", "TFLayoutLMForTokenClassification"), - ("layoutlmv3", "TFLayoutLMv3ForTokenClassification"), - ("longformer", "TFLongformerForTokenClassification"), - ("mobilebert", "TFMobileBertForTokenClassification"), - ("mpnet", "TFMPNetForTokenClassification"), - ("rembert", "TFRemBertForTokenClassification"), - ("roberta", "TFRobertaForTokenClassification"), - ("roberta-prelayernorm", "TFRobertaPreLayerNormForTokenClassification"), - ("roformer", "TFRoFormerForTokenClassification"), - ("xlm", "TFXLMForTokenClassification"), - ("xlm-roberta", "TFXLMRobertaForTokenClassification"), - ("xlnet", "TFXLNetForTokenClassification"), - ] -) - -TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES = OrderedDict( - [ - # Model for Multiple Choice mapping - ("albert", "TFAlbertForMultipleChoice"), - ("bert", "TFBertForMultipleChoice"), - ("camembert", "TFCamembertForMultipleChoice"), - ("convbert", "TFConvBertForMultipleChoice"), - ("deberta-v2", "TFDebertaV2ForMultipleChoice"), - ("distilbert", "TFDistilBertForMultipleChoice"), - ("electra", "TFElectraForMultipleChoice"), - ("flaubert", "TFFlaubertForMultipleChoice"), - ("funnel", "TFFunnelForMultipleChoice"), - ("longformer", "TFLongformerForMultipleChoice"), - ("mobilebert", "TFMobileBertForMultipleChoice"), - ("mpnet", "TFMPNetForMultipleChoice"), - ("rembert", "TFRemBertForMultipleChoice"), - ("roberta", "TFRobertaForMultipleChoice"), - ("roberta-prelayernorm", "TFRobertaPreLayerNormForMultipleChoice"), - ("roformer", "TFRoFormerForMultipleChoice"), - ("xlm", "TFXLMForMultipleChoice"), - ("xlm-roberta", "TFXLMRobertaForMultipleChoice"), - ("xlnet", "TFXLNetForMultipleChoice"), - ] -) - -TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES = OrderedDict( - [ - ("bert", "TFBertForNextSentencePrediction"), - ("mobilebert", "TFMobileBertForNextSentencePrediction"), - ] -) -TF_MODEL_FOR_MASK_GENERATION_MAPPING_NAMES = OrderedDict( - [ - ("sam", "TFSamModel"), - ] -) -TF_MODEL_FOR_TEXT_ENCODING_MAPPING_NAMES = OrderedDict( - [ - ("albert", "TFAlbertModel"), - ("bert", "TFBertModel"), - ("convbert", "TFConvBertModel"), - ("deberta", "TFDebertaModel"), - ("deberta-v2", "TFDebertaV2Model"), - ("distilbert", "TFDistilBertModel"), - ("electra", "TFElectraModel"), - ("flaubert", "TFFlaubertModel"), - ("longformer", "TFLongformerModel"), - ("mobilebert", "TFMobileBertModel"), - ("mt5", "TFMT5EncoderModel"), - ("rembert", "TFRemBertModel"), - ("roberta", "TFRobertaModel"), - ("roberta-prelayernorm", "TFRobertaPreLayerNormModel"), - ("roformer", "TFRoFormerModel"), - ("t5", "TFT5EncoderModel"), - ("xlm", "TFXLMModel"), - ("xlm-roberta", "TFXLMRobertaModel"), - ] -) - -TF_MODEL_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_MAPPING_NAMES) -TF_MODEL_FOR_PRETRAINING_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_FOR_PRETRAINING_MAPPING_NAMES) -TF_MODEL_WITH_LM_HEAD_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_WITH_LM_HEAD_MAPPING_NAMES) -TF_MODEL_FOR_CAUSAL_LM_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_FOR_CAUSAL_LM_MAPPING_NAMES) -TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES -) -TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES -) -TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES -) -TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES -) -TF_MODEL_FOR_VISION_2_SEQ_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES) -TF_MODEL_FOR_MASKED_LM_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_FOR_MASKED_LM_MAPPING_NAMES) -TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES -) -TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES -) -TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES -) -TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES -) -TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES -) -TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES -) -TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES -) -TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES -) -TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES -) -TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES -) - -TF_MODEL_FOR_MASK_GENERATION_MAPPING = _LazyAutoMapping( - CONFIG_MAPPING_NAMES, TF_MODEL_FOR_MASK_GENERATION_MAPPING_NAMES -) - -TF_MODEL_FOR_TEXT_ENCODING_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_FOR_TEXT_ENCODING_MAPPING_NAMES) - - -class TFAutoModelForMaskGeneration(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_MASK_GENERATION_MAPPING - - -class TFAutoModelForTextEncoding(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_TEXT_ENCODING_MAPPING - - -class TFAutoModel(_BaseAutoModelClass): - _model_mapping = TF_MODEL_MAPPING - - -TFAutoModel = auto_class_update(TFAutoModel) - - -class TFAutoModelForAudioClassification(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING - - -TFAutoModelForAudioClassification = auto_class_update( - TFAutoModelForAudioClassification, head_doc="audio classification" -) - - -class TFAutoModelForPreTraining(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_PRETRAINING_MAPPING - - -TFAutoModelForPreTraining = auto_class_update(TFAutoModelForPreTraining, head_doc="pretraining") - - -# Private on purpose, the public class will add the deprecation warnings. -class _TFAutoModelWithLMHead(_BaseAutoModelClass): - _model_mapping = TF_MODEL_WITH_LM_HEAD_MAPPING - - -_TFAutoModelWithLMHead = auto_class_update(_TFAutoModelWithLMHead, head_doc="language modeling") - - -class TFAutoModelForCausalLM(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_CAUSAL_LM_MAPPING - - -TFAutoModelForCausalLM = auto_class_update(TFAutoModelForCausalLM, head_doc="causal language modeling") - - -class TFAutoModelForMaskedImageModeling(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING - - -TFAutoModelForMaskedImageModeling = auto_class_update( - TFAutoModelForMaskedImageModeling, head_doc="masked image modeling" -) - - -class TFAutoModelForImageClassification(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING - - -TFAutoModelForImageClassification = auto_class_update( - TFAutoModelForImageClassification, head_doc="image classification" -) - - -class TFAutoModelForZeroShotImageClassification(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING - - -TFAutoModelForZeroShotImageClassification = auto_class_update( - TFAutoModelForZeroShotImageClassification, head_doc="zero-shot image classification" -) - - -class TFAutoModelForSemanticSegmentation(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING - - -TFAutoModelForSemanticSegmentation = auto_class_update( - TFAutoModelForSemanticSegmentation, head_doc="semantic segmentation" -) - - -class TFAutoModelForVision2Seq(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_VISION_2_SEQ_MAPPING - - -TFAutoModelForVision2Seq = auto_class_update(TFAutoModelForVision2Seq, head_doc="vision-to-text modeling") - - -class TFAutoModelForMaskedLM(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_MASKED_LM_MAPPING - - -TFAutoModelForMaskedLM = auto_class_update(TFAutoModelForMaskedLM, head_doc="masked language modeling") - - -class TFAutoModelForSeq2SeqLM(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING - - -TFAutoModelForSeq2SeqLM = auto_class_update( - TFAutoModelForSeq2SeqLM, - head_doc="sequence-to-sequence language modeling", - checkpoint_for_example="google-t5/t5-base", -) - - -class TFAutoModelForSequenceClassification(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING - - -TFAutoModelForSequenceClassification = auto_class_update( - TFAutoModelForSequenceClassification, head_doc="sequence classification" -) - - -class TFAutoModelForQuestionAnswering(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING - - -TFAutoModelForQuestionAnswering = auto_class_update(TFAutoModelForQuestionAnswering, head_doc="question answering") - - -class TFAutoModelForDocumentQuestionAnswering(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING - - -TFAutoModelForDocumentQuestionAnswering = auto_class_update( - TFAutoModelForDocumentQuestionAnswering, - head_doc="document question answering", - checkpoint_for_example='impira/layoutlm-document-qa", revision="52e01b3', -) - - -class TFAutoModelForTableQuestionAnswering(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING - - -TFAutoModelForTableQuestionAnswering = auto_class_update( - TFAutoModelForTableQuestionAnswering, - head_doc="table question answering", - checkpoint_for_example="google/tapas-base-finetuned-wtq", -) - - -class TFAutoModelForTokenClassification(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING - - -TFAutoModelForTokenClassification = auto_class_update( - TFAutoModelForTokenClassification, head_doc="token classification" -) - - -class TFAutoModelForMultipleChoice(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING - - -TFAutoModelForMultipleChoice = auto_class_update(TFAutoModelForMultipleChoice, head_doc="multiple choice") - - -class TFAutoModelForNextSentencePrediction(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING - - -TFAutoModelForNextSentencePrediction = auto_class_update( - TFAutoModelForNextSentencePrediction, head_doc="next sentence prediction" -) - - -class TFAutoModelForSpeechSeq2Seq(_BaseAutoModelClass): - _model_mapping = TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING - - -TFAutoModelForSpeechSeq2Seq = auto_class_update( - TFAutoModelForSpeechSeq2Seq, head_doc="sequence-to-sequence speech-to-text modeling" -) - - -class TFAutoModelWithLMHead(_TFAutoModelWithLMHead): - @classmethod - def from_config(cls, config): - warnings.warn( - "The class `TFAutoModelWithLMHead` is deprecated and will be removed in a future version. Please use" - " `TFAutoModelForCausalLM` for causal language models, `TFAutoModelForMaskedLM` for masked language models" - " and `TFAutoModelForSeq2SeqLM` for encoder-decoder models.", - FutureWarning, - ) - return super().from_config(config) - - @classmethod - def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs): - warnings.warn( - "The class `TFAutoModelWithLMHead` is deprecated and will be removed in a future version. Please use" - " `TFAutoModelForCausalLM` for causal language models, `TFAutoModelForMaskedLM` for masked language models" - " and `TFAutoModelForSeq2SeqLM` for encoder-decoder models.", - FutureWarning, - ) - return super().from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs) - - -__all__ = [ - "TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING", - "TF_MODEL_FOR_CAUSAL_LM_MAPPING", - "TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING", - "TF_MODEL_FOR_MASK_GENERATION_MAPPING", - "TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING", - "TF_MODEL_FOR_MASKED_LM_MAPPING", - "TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING", - "TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING", - "TF_MODEL_FOR_PRETRAINING_MAPPING", - "TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING", - "TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING", - "TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING", - "TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING", - "TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING", - "TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING", - "TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING", - "TF_MODEL_FOR_TEXT_ENCODING_MAPPING", - "TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING", - "TF_MODEL_FOR_VISION_2_SEQ_MAPPING", - "TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING", - "TF_MODEL_MAPPING", - "TF_MODEL_WITH_LM_HEAD_MAPPING", - "TFAutoModel", - "TFAutoModelForAudioClassification", - "TFAutoModelForCausalLM", - "TFAutoModelForImageClassification", - "TFAutoModelForMaskedImageModeling", - "TFAutoModelForMaskedLM", - "TFAutoModelForMaskGeneration", - "TFAutoModelForMultipleChoice", - "TFAutoModelForNextSentencePrediction", - "TFAutoModelForPreTraining", - "TFAutoModelForDocumentQuestionAnswering", - "TFAutoModelForQuestionAnswering", - "TFAutoModelForSemanticSegmentation", - "TFAutoModelForSeq2SeqLM", - "TFAutoModelForSequenceClassification", - "TFAutoModelForSpeechSeq2Seq", - "TFAutoModelForTableQuestionAnswering", - "TFAutoModelForTextEncoding", - "TFAutoModelForTokenClassification", - "TFAutoModelForVision2Seq", - "TFAutoModelForZeroShotImageClassification", - "TFAutoModelWithLMHead", -] diff --git a/src/transformers/models/aya_vision/processing_aya_vision.py b/src/transformers/models/aya_vision/processing_aya_vision.py index 7045c967046d..aaede4e8e80e 100644 --- a/src/transformers/models/aya_vision/processing_aya_vision.py +++ b/src/transformers/models/aya_vision/processing_aya_vision.py @@ -160,10 +160,8 @@ def __call__( `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/bark/modeling_bark.py b/src/transformers/models/bark/modeling_bark.py index 8770e3e0691b..475b85cf7e8e 100644 --- a/src/transformers/models/bark/modeling_bark.py +++ b/src/transformers/models/bark/modeling_bark.py @@ -335,8 +335,6 @@ class BarkPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, (nn.Linear,)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/bart/__init__.py b/src/transformers/models/bart/__init__.py index 8f4c713f4698..d268fb7d2b86 100644 --- a/src/transformers/models/bart/__init__.py +++ b/src/transformers/models/bart/__init__.py @@ -20,8 +20,6 @@ if TYPE_CHECKING: from .configuration_bart import * from .modeling_bart import * - from .modeling_flax_bart import * - from .modeling_tf_bart import * from .tokenization_bart import * from .tokenization_bart_fast import * else: diff --git a/src/transformers/models/bart/configuration_bart.py b/src/transformers/models/bart/configuration_bart.py index 90781feab3b5..e560bfa7d4a2 100644 --- a/src/transformers/models/bart/configuration_bart.py +++ b/src/transformers/models/bart/configuration_bart.py @@ -17,13 +17,13 @@ import warnings from collections import OrderedDict from collections.abc import Mapping -from typing import Any, Optional +from typing import Any from ... import PreTrainedTokenizer from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig, OnnxConfigWithPast, OnnxSeq2SeqConfigWithPast from ...onnx.utils import compute_effective_axis_dimension -from ...utils import TensorType, is_torch_available, logging +from ...utils import is_torch_available, logging logger = logging.get_logger(__name__) @@ -244,16 +244,15 @@ def _generate_dummy_inputs_for_default_and_seq2seq_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: encoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) # Generate decoder inputs decoder_seq_length = seq_length if not self.use_past else 1 decoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, decoder_seq_length, is_pair, framework + tokenizer, batch_size, decoder_seq_length, is_pair ) decoder_inputs = {f"decoder_{name}": tensor for name, tensor in decoder_inputs.items()} common_inputs = dict(**encoder_inputs, **decoder_inputs) @@ -312,10 +311,9 @@ def _generate_dummy_inputs_for_causal_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) if self.use_past: @@ -350,7 +348,6 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: # Copied from OnnxConfig.generate_dummy_inputs # Did not use super(OnnxConfigWithPast, self).generate_dummy_inputs for code clarity. @@ -367,7 +364,7 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( # Generate dummy inputs according to compute batch and sequence dummy_input = [" ".join([tokenizer.unk_token]) * seq_length] * batch_size - common_inputs = dict(tokenizer(dummy_input, return_tensors=framework)) + common_inputs = dict(tokenizer(dummy_input, return_tensors="pt")) return common_inputs def generate_dummy_inputs( @@ -376,20 +373,19 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: if self.task in ["default", "seq2seq-lm"]: common_inputs = self._generate_dummy_inputs_for_default_and_seq2seq_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) elif self.task == "causal-lm": common_inputs = self._generate_dummy_inputs_for_causal_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) else: common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) return common_inputs diff --git a/src/transformers/models/bart/modeling_flax_bart.py b/src/transformers/models/bart/modeling_flax_bart.py deleted file mode 100644 index 818254f3bfa1..000000000000 --- a/src/transformers/models/bart/modeling_flax_bart.py +++ /dev/null @@ -1,2006 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Fairseq Authors and The Google Flax Team Authors And The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax Bart model.""" - -import math -import random -from functools import partial -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxSeq2SeqLMOutput, - FlaxSeq2SeqModelOutput, - FlaxSeq2SeqQuestionAnsweringModelOutput, - FlaxSeq2SeqSequenceClassifierOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_bart import BartConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/bart-base" -_CONFIG_FOR_DOC = "BartConfig" - - -BART_START_DOCSTRING = r""" - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`BartConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -BART_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -BART_ENCODE_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -BART_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def shift_tokens_right(input_ids: jnp.ndarray, pad_token_id: int, decoder_start_token_id: int) -> jnp.ndarray: - """ - Shift input ids one token to the right. - """ - shifted_input_ids = jnp.zeros_like(input_ids) - shifted_input_ids = shifted_input_ids.at[:, 1:].set(input_ids[:, :-1]) - shifted_input_ids = shifted_input_ids.at[:, 0].set(decoder_start_token_id) - - shifted_input_ids = jnp.where(shifted_input_ids == -100, pad_token_id, shifted_input_ids) - return shifted_input_ids - - -class FlaxBartAttention(nn.Module): - config: BartConfig - embed_dim: int - num_heads: int - dropout: float = 0.0 - causal: bool = False - bias: bool = True - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self) -> None: - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {self.num_heads})." - ) - - dense = partial( - nn.Dense, - self.embed_dim, - use_bias=self.bias, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() - self.out_proj = dense() - - self.dropout_layer = nn.Dropout(rate=self.dropout) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states: jnp.ndarray, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.q_proj(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.k_proj(key_value_states) - value_states = self.v_proj(key_value_states) - else: - # self_attention - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights - - -class FlaxBartEncoderLayer(nn.Module): - config: BartConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxBartAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.encoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - self.fc1 = nn.Dense( - self.config.encoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states, attn_weights = self.self_attn(hidden_states=hidden_states, attention_mask=attention_mask) - - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - -class FlaxBartEncoderLayerCollection(nn.Module): - config: BartConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxBartEncoderLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.encoder_layers) - ] - self.layerdrop = self.config.encoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for encoder_layer in self.layers: - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): # skip the layer - layer_outputs = (None, None) - else: - layer_outputs = encoder_layer( - hidden_states, - attention_mask, - output_attentions, - deterministic, - ) - hidden_states = layer_outputs[0] - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -class FlaxBartDecoderLayer(nn.Module): - config: BartConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxBartAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - causal=True, - dtype=self.dtype, - ) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.encoder_attn = FlaxBartAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.fc1 = nn.Dense( - self.config.decoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - - # Self Attention - hidden_states, self_attn_weights = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Cross-Attention Block - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - hidden_states, cross_attn_weights = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # Fully Connected - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights, cross_attn_weights) - - return outputs - - -class FlaxBartDecoderLayerCollection(nn.Module): - config: BartConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxBartDecoderLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.decoder_layers) - ] - self.layerdrop = self.config.decoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - for decoder_layer in self.layers: - if output_hidden_states: - all_hidden_states += (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): - layer_outputs = (None, None, None) - else: - layer_outputs = decoder_layer( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - deterministic=deterministic, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attns += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = [hidden_states, all_hidden_states, all_self_attns, all_cross_attentions] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - -class FlaxBartClassificationHead(nn.Module): - """Head for sentence-level classification tasks.""" - - config: BartConfig - inner_dim: int - num_classes: int - pooler_dropout: float - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense( - self.inner_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.dropout = nn.Dropout(rate=self.pooler_dropout) - self.out_proj = nn.Dense( - self.num_classes, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - def __call__(self, hidden_states: jnp.ndarray, deterministic: bool): - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.dense(hidden_states) - hidden_states = jnp.tanh(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.out_proj(hidden_states) - return hidden_states - - -class FlaxBartEncoder(nn.Module): - config: BartConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_source_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(embed_dim) if self.config.scale_embedding else 1.0 - - # Bart is set up so that if padding_idx is specified then offset the embedding ids by 2 - # and adjust num_embeddings appropriately. Other models don't have this hack - self.offset = 2 - self.embed_positions = nn.Embed( - self.config.max_position_embeddings + self.offset, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - self.layers = FlaxBartEncoderLayerCollection(self.config, self.dtype) - self.layernorm_embedding = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - embed_pos = self.embed_positions(position_ids + self.offset) - - hidden_states = inputs_embeds + embed_pos - hidden_states = self.layernorm_embedding(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - if not return_dict: - return outputs - - return FlaxBaseModelOutput( - last_hidden_state=outputs.last_hidden_state, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -class FlaxBartDecoder(nn.Module): - config: BartConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_target_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(self.config.d_model) if self.config.scale_embedding else 1.0 - - # Bart is set up so that if padding_idx is specified then offset the embedding ids by 2 - # and adjust num_embeddings appropriately. Other models don't have this hack - self.offset = 2 - self.embed_positions = nn.Embed( - self.config.max_position_embeddings + self.offset, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - - self.layers = FlaxBartDecoderLayerCollection(self.config, self.dtype) - self.layernorm_embedding = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - # embed positions - positions = self.embed_positions(position_ids + self.offset) - - hidden_states = inputs_embeds + positions - hidden_states = self.layernorm_embedding(hidden_states) - - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - if not return_dict: - return outputs - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=outputs.last_hidden_state, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -class FlaxBartModule(nn.Module): - config: BartConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - - self.encoder = FlaxBartEncoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - self.decoder = FlaxBartDecoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -class FlaxBartPreTrainedModel(FlaxPreTrainedModel): - config_class = BartConfig - base_model_prefix: str = "model" - module_class: nn.Module = None - - def __init__( - self, - config: BartConfig, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - # make sure initialization pass will work for FlaxBartForSequenceClassificationModule - input_ids = input_ids.at[(..., -1)].set(self.config.eos_token_id) - attention_mask = jnp.ones_like(input_ids) - decoder_input_ids = input_ids - decoder_attention_mask = jnp.ones_like(input_ids) - - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - decoder_position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape - ) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(BART_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=BartConfig) - def encode( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxBartForConditionalGeneration - - >>> model = FlaxBartForConditionalGeneration.from_pretrained("facebook/bart-large-cnn") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-cnn") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, input_ids, attention_mask, position_ids, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(input_ids, attention_mask, position_ids, **kwargs) - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - @add_start_docstrings(BART_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=BartConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoTokenizer, FlaxBartForConditionalGeneration - - >>> model = FlaxBartForConditionalGeneration.from_pretrained("facebook/bart-large-cnn") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-cnn") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> last_decoder_hidden_states = outputs.last_hidden_state - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxBartAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_input_ids: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # prepare decoder inputs - if decoder_input_ids is None: - decoder_input_ids = shift_tokens_right( - input_ids, self.config.pad_token_id, decoder_start_token_id=self.config.decoder_start_token_id - ) - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - if decoder_position_ids is None: - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - -@add_start_docstrings( - "The bare Bart Model transformer outputting raw hidden-states without any specific head on top.", - BART_START_DOCSTRING, -) -class FlaxBartModel(FlaxBartPreTrainedModel): - config: BartConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - module_class = FlaxBartModule - - -append_call_sample_docstring(FlaxBartModel, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) - - -class FlaxBartForConditionalGenerationModule(nn.Module): - config: BartConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., jnp.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.model = FlaxBartModule(config=self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.model.shared.num_embeddings, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.final_logits_bias = self.param("final_logits_bias", self.bias_init, (1, self.model.shared.num_embeddings)) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - position_ids=position_ids, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = self.model.variables["params"]["shared"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - lm_logits += jax.lax.stop_gradient(self.final_logits_bias.astype(self.dtype)) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return output - - return FlaxSeq2SeqLMOutput( - logits=lm_logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings( - "The BART Model with a language modeling head. Can be used for summarization.", BART_START_DOCSTRING -) -class FlaxBartForConditionalGeneration(FlaxBartPreTrainedModel): - module_class = FlaxBartForConditionalGenerationModule - dtype: jnp.dtype = jnp.float32 - - @add_start_docstrings(BART_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=BartConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoTokenizer, FlaxBartForConditionalGeneration - - >>> model = FlaxBartForConditionalGeneration.from_pretrained("facebook/bart-large-cnn") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-cnn") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxBartAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - outputs = decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = module.model.variables["params"]["shared"]["embedding"] - lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = module.lm_head(hidden_states) - - lm_logits += module.final_logits_bias.astype(self.dtype) - return lm_logits, outputs - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - if past_key_values is None: - lm_logits, decoder_outputs = outputs - else: - (lm_logits, decoder_outputs), past = outputs - - if return_dict: - outputs = FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=decoder_outputs.hidden_states, - attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - ) - else: - outputs = (lm_logits,) + decoder_outputs[1:] - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - position_ids = decoder_attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - "decoder_position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 - return model_kwargs - - -FLAX_BART_CONDITIONAL_GENERATION_DOCSTRING = """ - Returns: - - Summarization example: - - ```python - >>> from transformers import AutoTokenizer, FlaxBartForConditionalGeneration - - >>> model = FlaxBartForConditionalGeneration.from_pretrained("facebook/bart-large-cnn") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-cnn") - - >>> ARTICLE_TO_SUMMARIZE = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], max_length=1024, return_tensors="np") - - >>> # Generate Summary - >>> summary_ids = model.generate(inputs["input_ids"]).sequences - >>> print(tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)) - ``` - - Mask filling example: - - ```python - >>> import jax - >>> from transformers import AutoTokenizer, FlaxBartForConditionalGeneration - - >>> model = FlaxBartForConditionalGeneration.from_pretrained("facebook/bart-large") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large") - - >>> TXT = "My friends are but they eat too many carbs." - >>> input_ids = tokenizer([TXT], return_tensors="jax")["input_ids"] - - >>> logits = model(input_ids).logits - >>> masked_index = (input_ids[0] == tokenizer.mask_token_id).nonzero()[0].item() - >>> probs = jax.nn.softmax(logits[0, masked_index], axis=0) - >>> values, predictions = jax.lax.top_k(probs, k=1) - - >>> tokenizer.decode(predictions).split() - ``` -""" - -overwrite_call_docstring( - FlaxBartForConditionalGeneration, BART_INPUTS_DOCSTRING + FLAX_BART_CONDITIONAL_GENERATION_DOCSTRING -) -append_replace_return_docstrings( - FlaxBartForConditionalGeneration, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC -) - - -class FlaxBartForSequenceClassificationModule(nn.Module): - config: BartConfig - dtype: jnp.dtype = jnp.float32 - num_labels: Optional[int] = None - - def setup(self): - self.model = FlaxBartModule(config=self.config, dtype=self.dtype) - self.classification_head = FlaxBartClassificationHead( - config=self.config, - inner_dim=self.config.d_model, - num_classes=self.num_labels if self.num_labels is not None else self.config.num_labels, - pooler_dropout=self.config.classifier_dropout, - ) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - position_ids=position_ids, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = outputs[0] # last hidden state - - eos_mask = jnp.where(input_ids == self.config.eos_token_id, 1, 0) - - # The first condition is necessary to overcome jax._src.errors.ConcretizationTypeError during JIT compilation - if not isinstance(eos_mask, jax.interpreters.partial_eval.DynamicJaxprTracer): - if len(jnp.unique(eos_mask.sum(1))) > 1: - raise ValueError("All examples must have the same number of tokens.") - - if any(eos_mask.sum(1) == 0): - raise ValueError("There are missing tokens in input_ids") - - # Ensure to keep 1 only for the last token for each example - eos_mask_noised = eos_mask + jnp.arange(eos_mask.shape[1]) * 1e-6 - eos_mask = jnp.where(eos_mask_noised == eos_mask_noised.max(1).reshape(-1, 1), 1, 0) - - sentence_representation = jnp.einsum("ijk, ij -> ijk", hidden_states, eos_mask).sum(1) - logits = self.classification_head(sentence_representation, deterministic=deterministic) - - if not return_dict: - output = (logits,) + outputs[1:] - return output - - return FlaxSeq2SeqSequenceClassifierOutput( - logits=logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings( - """ - Bart model with a sequence classification/head on top (a linear layer on top of the pooled output) e.g. for GLUE - tasks. - """, - BART_START_DOCSTRING, -) -class FlaxBartForSequenceClassification(FlaxBartPreTrainedModel): - module_class = FlaxBartForSequenceClassificationModule - dtype = jnp.float32 - - -append_call_sample_docstring( - FlaxBartForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSeq2SeqSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxBartForQuestionAnsweringModule(nn.Module): - config: BartConfig - dtype: jnp.dtype = jnp.float32 - num_labels = 2 - - def setup(self): - self.model = FlaxBartModule(config=self.config, dtype=self.dtype) - self.qa_outputs = nn.Dense( - self.num_labels, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - position_ids=position_ids, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - sequence_output = outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = jnp.split(logits, logits.shape[-1], axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - output = (start_logits, end_logits) + outputs[1:] - return output - - return FlaxSeq2SeqQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings( - """ - BART Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layer on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - BART_START_DOCSTRING, -) -class FlaxBartForQuestionAnswering(FlaxBartPreTrainedModel): - module_class = FlaxBartForQuestionAnsweringModule - dtype = jnp.float32 - - -append_call_sample_docstring( - FlaxBartForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxSeq2SeqQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxBartDecoderPreTrainedModel(FlaxPreTrainedModel): - config_class = BartConfig - base_model_prefix: str = "model" - module_class: nn.Module = None - - def __init__( - self, - config: BartConfig, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - config.is_decoder = True - config.is_encoder_decoder = False - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - encoder_hidden_states = jnp.zeros(input_shape + (self.config.d_model,)) - encoder_attention_mask = attention_mask - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states, - encoder_attention_mask, - return_dict=False, - ) - return module_init_outputs["params"] - - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length), dtype="i4") - attention_mask = jnp.ones_like(input_ids, dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(BART_DECODE_INPUTS_DOCSTRING) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - past_key_values: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if encoder_hidden_states is not None and encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - # prepare decoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed - # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be - # changed by FlaxBartAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - return outputs - - -class FlaxBartDecoderWrapper(nn.Module): - """ - This wrapper class is a helper class to correctly load pretrained checkpoints when the causal language model is - used in combination with the [`EncoderDecoderModel`] framework. - """ - - config: BartConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - embed_dim = self.config.d_model - embed_tokens = nn.Embed( - self.config.vocab_size, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - self.decoder = FlaxBartDecoder(config=self.config, embed_tokens=embed_tokens, dtype=self.dtype) - - def __call__(self, *args, **kwargs): - return self.decoder(*args, **kwargs) - - -class FlaxBartForCausalLMModule(nn.Module): - config: BartConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.model = FlaxBartDecoderWrapper(config=self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids, - attention_mask, - position_ids, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = self.model.variables["params"]["decoder"]["embed_tokens"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - return (lm_logits,) + outputs[1:] - - return FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - """ - Bart Decoder Model with a language modeling head on top (linear layer with weights tied to the input embeddings) - e.g for autoregressive tasks. - """, - BART_START_DOCSTRING, -) -class FlaxBartForCausalLM(FlaxBartDecoderPreTrainedModel): - module_class = FlaxBartForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyway. - # Thus, we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxBartForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutputWithCrossAttentions, - _CONFIG_FOR_DOC, -) - - -__all__ = [ - "FlaxBartDecoderPreTrainedModel", - "FlaxBartForCausalLM", - "FlaxBartForConditionalGeneration", - "FlaxBartForQuestionAnswering", - "FlaxBartForSequenceClassification", - "FlaxBartModel", - "FlaxBartPreTrainedModel", -] diff --git a/src/transformers/models/bart/modeling_tf_bart.py b/src/transformers/models/bart/modeling_tf_bart.py deleted file mode 100644 index 0a6d2317d696..000000000000 --- a/src/transformers/models/bart/modeling_tf_bart.py +++ /dev/null @@ -1,1713 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 Bart model.""" - -from __future__ import annotations - -import random - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPastAndCrossAttentions, - TFSeq2SeqLMOutput, - TFSeq2SeqModelOutput, - TFSeq2SeqSequenceClassifierOutput, -) - -# Public API -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_end_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_bart import BartConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/bart-large" -_CONFIG_FOR_DOC = "BartConfig" - - -LARGE_NEGATIVE = -1e8 - - -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): - pad_token_id = tf.cast(pad_token_id, input_ids.dtype) - decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) - start_tokens = tf.fill( - (shape_list(input_ids)[0], 1), tf.convert_to_tensor(decoder_start_token_id, input_ids.dtype) - ) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.fill(shape_list(shifted_input_ids), tf.convert_to_tensor(pad_token_id, input_ids.dtype)), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE - mask_cond = tf.range(shape_list(mask)[-1]) - - mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -class TFBartLearnedPositionalEmbedding(keras.layers.Embedding): - """ - This module learns positional embeddings up to a fixed maximum size. - """ - - def __init__(self, num_embeddings: int, embedding_dim: int, **kwargs): - # Bart is set up so that if padding_idx is specified then offset the embedding ids by 2 - # and adjust num_embeddings appropriately. Other models don't have this hack - self.offset = 2 - super().__init__(num_embeddings + self.offset, embedding_dim, **kwargs) - - def call( - self, - input_shape: tf.TensorShape | None = None, - past_key_values_length: int = 0, - position_ids: tf.Tensor | None = None, - ): - """Input is expected to be of size [bsz x seqlen].""" - if position_ids is None: - seq_len = input_shape[1] - position_ids = tf.range(seq_len, delta=1, name="range") - position_ids += past_key_values_length - - offset_dtype = position_ids.dtype if isinstance(position_ids, tf.Tensor) else tf.int32 - return super().call(position_ids + tf.constant(self.offset, dtype=offset_dtype)) - - -class TFBartAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -class TFBartEncoderLayer(keras.layers.Layer): - def __init__(self, config: BartConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFBartAttention( - self.embed_dim, config.encoder_attention_heads, dropout=config.attention_dropout, name="self_attn" - ) - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - self.fc1 = keras.layers.Dense(config.encoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: np.ndarray | tf.Tensor | None, - layer_head_mask: tf.Tensor | None, - training: bool | None = False, - ) -> tf.Tensor: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - `(encoder_attention_heads,)` - """ - residual = hidden_states - hidden_states, self_attn_weights, _ = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, layer_head_mask=layer_head_mask - ) - - tf.debugging.assert_equal( - shape_list(hidden_states), - shape_list(residual), - message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", - ) - - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - return hidden_states, self_attn_weights - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.encoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFBartDecoderLayer(keras.layers.Layer): - def __init__(self, config: BartConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFBartAttention( - embed_dim=self.embed_dim, - num_heads=config.decoder_attention_heads, - dropout=config.attention_dropout, - name="self_attn", - is_decoder=True, - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.encoder_attn = TFBartAttention( - self.embed_dim, - config.decoder_attention_heads, - dropout=config.attention_dropout, - name="encoder_attn", - is_decoder=True, - ) - self.encoder_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.decoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - cross_attn_layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - encoder_hidden_states (`tf.Tensor`): - cross attention input to the layer of shape `(batch, seq_len, embed_dim)` - encoder_attention_mask (`tf.Tensor`): encoder attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - `(decoder_attention_heads,)` - cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. - `(decoder_attention_heads,)` - past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states - """ - residual = hidden_states - - # Self Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Cross-Attention Block - cross_attn_present_key_value = None - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - layer_head_mask=cross_attn_layer_head_mask, - past_key_value=cross_attn_past_key_value, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # add cross-attn to positions 3,4 of present_key_value tuple - present_key_value = present_key_value + cross_attn_present_key_value - - # Fully Connected - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - return ( - hidden_states, - self_attn_weights, - cross_attn_weights, - present_key_value, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "encoder_attn", None) is not None: - with tf.name_scope(self.encoder_attn.name): - self.encoder_attn.build(None) - if getattr(self, "encoder_attn_layer_norm", None) is not None: - with tf.name_scope(self.encoder_attn_layer_norm.name): - self.encoder_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.decoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFBartClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, inner_dim: int, num_classes: int, pooler_dropout: float, name: str, **kwargs): - super().__init__(name=name, **kwargs) - self.dense = keras.layers.Dense(inner_dim, name="dense") - self.dropout = keras.layers.Dropout(pooler_dropout) - self.out_proj = keras.layers.Dense(num_classes, name="out_proj") - self.input_dim = inner_dim - self.inner_dim = inner_dim - - def call(self, inputs): - hidden_states = self.dropout(inputs) - hidden_states = self.dense(hidden_states) - hidden_states = keras.activations.tanh(hidden_states) - hidden_states = self.dropout(hidden_states) - hidden_states = self.out_proj(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.input_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.inner_dim]) - - -class TFBartPretrainedModel(TFPreTrainedModel): - config_class = BartConfig - base_model_prefix = "model" - - @property - def dummy_inputs(self): - dummy_inputs = super().dummy_inputs - # Dummy inputs should not contain the default val of 1 - # as this is the padding token and some assertions check it - dummy_inputs["input_ids"] = dummy_inputs["input_ids"] * 2 - if "decoder_input_ids" in dummy_inputs: - dummy_inputs["decoder_input_ids"] = dummy_inputs["decoder_input_ids"] * 2 - return dummy_inputs - - def tf_to_pt_weight_rename(self, tf_weight): - if tf_weight == "model.shared.weight": - return tf_weight, "model.decoder.embed_tokens.weight" - else: - return (tf_weight,) - - -BART_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`BartConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - - -BART_GENERATION_EXAMPLE = r""" - Summarization example: - - ```python - >>> from transformers import AutoTokenizer, TFBartForConditionalGeneration - - >>> model = TFBartForConditionalGeneration.from_pretrained("facebook/bart-large") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large") - - >>> ARTICLE_TO_SUMMARIZE = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], max_length=1024, return_tensors="tf") - - >>> # Generate Summary - >>> summary_ids = model.generate(inputs["input_ids"], num_beams=4, max_length=5) - >>> print(tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)) - ``` - - Mask filling example: - - ```python - >>> from transformers import AutoTokenizer, TFBartForConditionalGeneration - - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large") - >>> TXT = "My friends are but they eat too many carbs." - - >>> model = TFBartForConditionalGeneration.from_pretrained("facebook/bart-large") - >>> input_ids = tokenizer([TXT], return_tensors="tf")["input_ids"] - >>> logits = model(input_ids).logits - >>> probs = tf.nn.softmax(logits[0]) - >>> # probs[5] is associated with the mask token - ``` -""" - - -BART_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - Bart uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If `past_key_values` - is used, optionally only the last `decoder_input_ids` have to be input (see `past_key_values`). - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - will be made by default and ignore pad tokens. It is not recommended to set this for most use cases. - decoder_position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_outputs (`tf.FloatTensor`, *optional*): - hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - of shape `(batch_size, sequence_length, hidden_size)` is a sequence of - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@keras_serializable -class TFBartEncoder(keras.layers.Layer): - config_class = BartConfig - """ - Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a - [`TFBartEncoderLayer`]. - - Args: - config: BartConfig - """ - - def __init__(self, config: BartConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.dropout = keras.layers.Dropout(config.dropout) - self.layerdrop = config.encoder_layerdrop - self.padding_idx = config.pad_token_id - self.max_source_positions = config.max_position_embeddings - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - - self.embed_tokens = embed_tokens - self.embed_positions = TFBartLearnedPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.layers = [TFBartEncoderLayer(config, name=f"layers.{i}") for i in range(config.encoder_layers)] - self.layernorm_embedding = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_embedding") - self.embed_dim = config.d_model - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - """ - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - embed_pos = self.embed_positions(input_shape) - hidden_states = inputs_embeds + embed_pos - hidden_states = self.layernorm_embedding(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - - # check attention mask and invert - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - attention_mask = _expand_mask(attention_mask) - else: - attention_mask = None - - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - # check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - tf.debugging.assert_equal( - shape_list(head_mask)[0], - len(self.layers), - message=( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(head_mask)[0]}." - ), - ) - - # encoder layers - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): # skip the layer - continue - - hidden_states, attn = encoder_layer( - hidden_states, - attention_mask, - head_mask[idx] if head_mask is not None else None, - ) - - if output_attentions: - all_attentions += (attn,) - - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layernorm_embedding", None) is not None: - with tf.name_scope(self.layernorm_embedding.name): - self.layernorm_embedding.build([None, None, self.embed_dim]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFBartDecoder(keras.layers.Layer): - config_class = BartConfig - """ - Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFBartDecoderLayer`] - - Args: - config: BartConfig - embed_tokens: output embedding - """ - - def __init__(self, config: BartConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.padding_idx = config.pad_token_id - self.embed_tokens = embed_tokens - self.layerdrop = config.decoder_layerdrop - self.embed_positions = TFBartLearnedPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - self.layers = [TFBartDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] - self.layernorm_embedding = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_embedding") - - self.dropout = keras.layers.Dropout(config.dropout) - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention - of the decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): - Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values - selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers` with each tuple having 2 tuples each of which has 2 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up - decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those - that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of - all `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.tTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - past_key_values_length = shape_list(past_key_values[0][0])[2] if past_key_values is not None else 0 - - # embed positions - if position_ids is None: - positions = self.embed_positions(input_shape, past_key_values_length) - else: - positions = self.embed_positions(input_shape, position_ids=position_ids) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - hidden_states = inputs_embeds - - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - if input_shape[-1] > 1: - combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length=past_key_values_length) - else: - combined_attention_mask = _expand_mask( - tf.ones((input_shape[0], input_shape[1] + past_key_values_length)), tgt_len=input_shape[-1] - ) - - if attention_mask is not None: - combined_attention_mask = combined_attention_mask + _expand_mask(attention_mask, tgt_len=input_shape[-1]) - - if encoder_hidden_states is not None and encoder_attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) - - hidden_states = self.layernorm_embedding(hidden_states + positions) - hidden_states = self.dropout(hidden_states, training=training) - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attns = () if (output_attentions and encoder_hidden_states is not None) else None - present_key_values = () if use_cache else None - - # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired - for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: - if attn_mask is not None: - tf.debugging.assert_equal( - shape_list(attn_mask)[0], - len(self.layers), - message=( - f"The {attn_mask_name} should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(attn_mask)[0]}." - ), - ) - - for idx, decoder_layer in enumerate(self.layers): - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - if output_hidden_states: - all_hidden_states += (hidden_states,) - - dropout_probability = random.uniform(0, 1) - - if training and (dropout_probability < self.layerdrop): - continue - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( - hidden_states, - attention_mask=combined_attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - cross_attn_layer_head_mask=cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None, - past_key_value=past_key_value, - ) - - if use_cache: - present_key_values += (present_key_value,) - - if output_attentions: - all_self_attns += (layer_self_attn,) - - if encoder_hidden_states is not None: - all_cross_attns += (layer_cross_attn,) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - if not return_dict: - return hidden_states, present_key_values, all_hidden_states, all_self_attns, all_cross_attns - else: - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=present_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layernorm_embedding", None) is not None: - with tf.name_scope(self.layernorm_embedding.name): - self.layernorm_embedding.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFBartMainLayer(keras.layers.Layer): - config_class = BartConfig - - def __init__(self, config: BartConfig, load_weight_prefix=None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.shared = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.d_model, - embeddings_initializer=keras.initializers.TruncatedNormal(stddev=self.config.init_std), - name="model.shared", - ) - # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) - self.shared.load_weight_prefix = "model.shared" if load_weight_prefix is None else load_weight_prefix - - self.encoder = TFBartEncoder(config, self.shared, name="encoder") - self.decoder = TFBartDecoder(config, self.shared, name="decoder") - - def get_input_embeddings(self): - return self.shared - - def set_input_embeddings(self, new_embeddings): - self.shared = new_embeddings - self.encoder.embed_tokens = self.shared - self.decoder.embed_tokens = self.shared - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ) -> TFSeq2SeqModelOutput | tuple[tf.Tensor]: - # different to other models, Bart automatically creates decoder_input_ids from - # input_ids if no decoder_input_ids are provided - if decoder_input_ids is None and decoder_inputs_embeds is None: - if input_ids is None: - raise ValueError( - "If no `decoder_input_ids` or `decoder_inputs_embeds` are " - "passed, `input_ids` cannot be `None`. Please pass either " - "`input_ids` or `decoder_input_ids` or `decoder_inputs_embeds`." - ) - - decoder_input_ids = shift_tokens_right( - input_ids, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True - elif return_dict and not isinstance(encoder_outputs, TFBaseModelOutput): - encoder_outputs = TFBaseModelOutput( - last_hidden_state=encoder_outputs[0], - hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, - attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, - ) - # If the user passed a TFBaseModelOutput for encoder_outputs, we wrap it in a tuple when return_dict=False - elif not return_dict and not isinstance(encoder_outputs, tuple): - encoder_outputs = encoder_outputs.to_tuple() - - decoder_outputs = self.decoder( - decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return TFSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # The shared/tied weights expect to be in the model base namespace - # Adding "/" to the end (not the start!) of a tf.name_scope puts it in the root namespace rather than - # the current one. - with tf.name_scope(self.shared.load_weight_prefix + "/" + self.shared.name + "/"): - self.shared.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - "The bare BART Model outputting raw hidden-states without any specific head on top.", - BART_START_DOCSTRING, -) -class TFBartModel(TFBartPretrainedModel): - _requires_load_weight_prefix = True - - def __init__(self, config: BartConfig, load_weight_prefix=None, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.model = TFBartMainLayer(config, load_weight_prefix=load_weight_prefix, name="model") - - def get_encoder(self): - return self.model.encoder - - def get_decoder(self): - return self.model.decoder - - @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSeq2SeqModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - encoder_outputs=encoder_outputs, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqModelOutput( - last_hidden_state=output.last_hidden_state, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -class BiasLayer(keras.layers.Layer): - """ - Bias as a layer. It is used for serialization purposes: `keras.Model.save_weights` stores on a per-layer basis, - so all weights have to be registered in a layer. - """ - - def __init__(self, shape, initializer, trainable, name, **kwargs): - super().__init__(name=name, **kwargs) - # Note: the name of this variable will NOT be scoped when serialized, i.e. it will not be in the format of - # "outer_layer/inner_layer/.../name:0". Instead, it will be "name:0". For further details, see: - # https://github.com/huggingface/transformers/pull/18833#issuecomment-1233090214 - self.bias = self.add_weight(name=name, shape=shape, initializer=initializer, trainable=trainable) - - def call(self, x): - return x + self.bias - - -@add_start_docstrings( - "The BART Model with a language modeling head. Can be used for summarization.", - BART_START_DOCSTRING, -) -class TFBartForConditionalGeneration(TFBartPretrainedModel, TFCausalLanguageModelingLoss): - _keys_to_ignore_on_load_missing = [r"final_logits_bias"] - _requires_load_weight_prefix = True - - def __init__(self, config, load_weight_prefix=None, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.model = TFBartMainLayer(config, load_weight_prefix=load_weight_prefix, name="model") - self.use_cache = config.use_cache - # final_bias_logits is registered as a buffer in pytorch, so not trainable for the sake of consistency. - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, config.vocab_size], initializer="zeros", trainable=False - ) - - def get_decoder(self): - return self.model.decoder - - def get_encoder(self): - return self.model.encoder - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - def get_bias(self): - return {"final_logits_bias": self.bias_layer.bias} - - def set_bias(self, value): - # Replaces the existing layers containing bias for correct (de)serialization. - vocab_size = value["final_logits_bias"].shape[-1] - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, vocab_size], initializer="zeros", trainable=False - ) - self.bias_layer.bias.assign(value["final_logits_bias"]) - - @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - @add_end_docstrings(BART_GENERATION_EXAMPLE) - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSeq2SeqLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., - config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - - Returns: - - """ - - if labels is not None: - labels = tf.where( - labels == self.config.pad_token_id, - tf.cast(tf.fill(shape_list(labels), -100), labels.dtype), - labels, - ) - use_cache = False - if decoder_input_ids is None and decoder_inputs_embeds is None: - decoder_input_ids = shift_tokens_right( - labels, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - outputs = self.model( - input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - encoder_outputs=encoder_outputs, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - lm_logits = tf.matmul(outputs[0], self.model.shared.weights, transpose_b=True) - lm_logits = self.bias_layer(lm_logits) - masked_lm_loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return TFSeq2SeqLMOutput( - loss=masked_lm_loss, - logits=lm_logits, - past_key_values=outputs.past_key_values, # index 1 of d outputs - decoder_hidden_states=outputs.decoder_hidden_states, # index 2 of d outputs - decoder_attentions=outputs.decoder_attentions, # index 3 of d outputs - cross_attentions=outputs.cross_attentions, # index 4 of d outputs - encoder_last_hidden_state=outputs.encoder_last_hidden_state, # index 0 of encoder outputs - encoder_hidden_states=outputs.encoder_hidden_states, # 1 of e out - encoder_attentions=outputs.encoder_attentions, # 2 of e out - ) - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - past_key_values=None, - attention_mask=None, - decoder_attention_mask=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - use_cache=None, - encoder_outputs=None, - **kwargs, - ): - # cut decoder_input_ids if past_key_values is used - if past_key_values is not None: - decoder_input_ids = decoder_input_ids[:, -1:] - - if decoder_attention_mask is not None: # xla - decoder_position_ids = tf.math.cumsum(decoder_attention_mask, axis=-1, exclusive=True)[:, -1:] - elif past_key_values is not None: # no xla + past_key_values - decoder_position_ids = past_key_values[0][0].shape[2] - else: # no xla + no past_key_values - decoder_position_ids = tf.range(decoder_input_ids.shape[1]) - - return { - "input_ids": None, # encoder_outputs is defined. input_ids not needed - "encoder_outputs": encoder_outputs, - "past_key_values": past_key_values, - "decoder_input_ids": decoder_input_ids, - "attention_mask": attention_mask, - "decoder_attention_mask": decoder_attention_mask, - "decoder_position_ids": decoder_position_ids, - "head_mask": head_mask, - "decoder_head_mask": decoder_head_mask, - "cross_attn_head_mask": cross_attn_head_mask, - "use_cache": use_cache, # change this to avoid caching (presumably for debugging) - } - - def prepare_decoder_input_ids_from_labels(self, labels: tf.Tensor): - return shift_tokens_right(labels, self.config.pad_token_id, self.config.decoder_start_token_id) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "bias_layer", None) is not None: - with tf.name_scope(self.bias_layer.name): - self.bias_layer.build(None) - - -@add_start_docstrings( - """ - Bart model with a sequence classification/head on top (a linear layer on top of the pooled output) e.g. for GLUE - tasks. - """, - BART_START_DOCSTRING, -) -class TFBartForSequenceClassification(TFBartPretrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: BartConfig, load_weight_prefix=None, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.model = TFBartMainLayer(config, load_weight_prefix=load_weight_prefix, name="model") - self.classification_head = TFBartClassificationHead( - config.d_model, config.num_labels, config.classifier_dropout, name="classification_head" - ) - - @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqSequenceClassifierOutput, config_class=_CONFIG_FOR_DOC) - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSeq2SeqSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - - Returns: - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if labels is not None: - use_cache = False - - if input_ids is None and inputs_embeds is not None: - raise NotImplementedError( - f"Passing input embeddings is currently not supported for {self.__class__.__name__}" - ) - - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - encoder_outputs=encoder_outputs, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - last_hidden_state = outputs[0] - eos_mask = tf.equal(input_ids, self.config.eos_token_id) - # out the rows with False where present. Then verify all the final - # entries are True - self_masked = tf.reshape(tf.boolean_mask(eos_mask, eos_mask), (tf.shape(input_ids)[0], -1)) - tf.Assert(tf.reduce_all(self_masked[:, -1]), ["All examples must have the same number of tokens."]) - - masked = tf.reshape( - tf.boolean_mask(last_hidden_state, eos_mask), - (tf.shape(input_ids)[0], tf.shape(self_masked)[1], tf.shape(last_hidden_state)[-1]), - ) - - sentence_representation = masked[:, -1, :] - logits = self.classification_head(sentence_representation) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSeq2SeqSequenceClassifierOutput( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - def serving_output(self, output): - logits = tf.convert_to_tensor(output.logits) - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqSequenceClassifierOutput( - logits=logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "classification_head", None) is not None: - with tf.name_scope(self.classification_head.name): - self.classification_head.build(None) - - -__all__ = ["TFBartForConditionalGeneration", "TFBartForSequenceClassification", "TFBartModel", "TFBartPretrainedModel"] diff --git a/src/transformers/models/beit/__init__.py b/src/transformers/models/beit/__init__.py index 3f412a350068..66dcfe1e56f7 100644 --- a/src/transformers/models/beit/__init__.py +++ b/src/transformers/models/beit/__init__.py @@ -23,7 +23,6 @@ from .image_processing_beit import * from .image_processing_beit_fast import * from .modeling_beit import * - from .modeling_flax_beit import * else: import sys diff --git a/src/transformers/models/beit/image_processing_beit.py b/src/transformers/models/beit/image_processing_beit.py index c25880bcfada..984eac3bf67e 100644 --- a/src/transformers/models/beit/image_processing_beit.py +++ b/src/transformers/models/beit/image_processing_beit.py @@ -360,10 +360,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -397,14 +395,10 @@ def preprocess( if segmentation_maps is not None and not valid_images(segmentation_maps): raise ValueError( - "Invalid segmentation_maps type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." + "Invalid segmentation_maps type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor" ) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, @@ -459,7 +453,7 @@ def preprocess( def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[list[tuple]] = None): """ - Converts the output of [`BeitForSemanticSegmentation`] into semantic segmentation maps. Only supports PyTorch. + Converts the output of [`BeitForSemanticSegmentation`] into semantic segmentation maps. Args: outputs ([`BeitForSemanticSegmentation`]): @@ -473,7 +467,6 @@ def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[lis segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each `torch.Tensor` correspond to a semantic class id. """ - # TODO: add support for other frameworks logits = outputs.logits # Resize logits and compute semantic segmentation maps diff --git a/src/transformers/models/beit/image_processing_beit_fast.py b/src/transformers/models/beit/image_processing_beit_fast.py index e10dc552cf37..7a55543dee62 100644 --- a/src/transformers/models/beit/image_processing_beit_fast.py +++ b/src/transformers/models/beit/image_processing_beit_fast.py @@ -186,7 +186,7 @@ def _preprocess( def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[list[tuple]] = None): """ - Converts the output of [`BeitForSemanticSegmentation`] into semantic segmentation maps. Only supports PyTorch. + Converts the output of [`BeitForSemanticSegmentation`] into semantic segmentation maps. Args: outputs ([`BeitForSemanticSegmentation`]): @@ -200,7 +200,6 @@ def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[lis segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each `torch.Tensor` correspond to a semantic class id. """ - # TODO: add support for other frameworks logits = outputs.logits # Resize logits and compute semantic segmentation maps diff --git a/src/transformers/models/beit/modeling_beit.py b/src/transformers/models/beit/modeling_beit.py index cb4e0d712651..9b6e7f1cd1a6 100755 --- a/src/transformers/models/beit/modeling_beit.py +++ b/src/transformers/models/beit/modeling_beit.py @@ -63,11 +63,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -732,8 +727,6 @@ class BeitPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d, nn.ConvTranspose2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/beit/modeling_flax_beit.py b/src/transformers/models/beit/modeling_flax_beit.py deleted file mode 100644 index c80deace6b39..000000000000 --- a/src/transformers/models/beit/modeling_flax_beit.py +++ /dev/null @@ -1,956 +0,0 @@ -# coding=utf-8 -# Copyright 2021 Microsoft Research and 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. - - -from typing import Callable, Optional - -import flax -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPooling, - FlaxMaskedLMOutput, - FlaxSequenceClassifierOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward -from .configuration_beit import BeitConfig - - -@flax.struct.dataclass -class FlaxBeitModelOutputWithPooling(FlaxBaseModelOutputWithPooling): - """ - Class for outputs of [`FlaxBeitModel`]. - - Args: - last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - pooler_output (`jnp.ndarray` of shape `(batch_size, hidden_size)`): - Average of the last layer hidden states of the patch tokens (excluding the *[CLS]* token) if - *config.use_mean_pooling* is set to True. If set to False, then the final hidden state of the *[CLS]* token - will be returned. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus - the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - """ - - -BEIT_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`BeitConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -BEIT_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`numpy.ndarray` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`AutoImageProcessor.__call__`] for details. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def relative_position_index_init(window_size: tuple[int, int]) -> jnp.ndarray: - """ - get pair-wise relative position index for each token inside the window - """ - num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3 - - coords_h = np.arange(window_size[0]) - coords_w = np.arange(window_size[1]) - coords = np.stack(np.meshgrid(coords_h, coords_w, indexing="ij")) # 2, Wh, Ww - coords_flatten = np.reshape(coords, (2, -1)) - relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww - relative_coords = np.transpose(relative_coords, (1, 2, 0)) # Wh*Ww, Wh*Ww, 2 - relative_coords[:, :, 0] += window_size[0] - 1 # shift to start from 0 - relative_coords[:, :, 1] += window_size[1] - 1 - relative_coords[:, :, 0] *= 2 * window_size[1] - 1 - - relative_position_index = np.zeros(shape=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype) - relative_position_index[1:, 1:] = relative_coords.sum(-1) # Wh*Ww, Wh*Ww - relative_position_index[0, 0:] = num_relative_distance - 3 - relative_position_index[0:, 0] = num_relative_distance - 2 - relative_position_index[0, 0] = num_relative_distance - 1 - return jnp.array(relative_position_index) - - -def ones_with_scale(key, shape, scale, dtype=jnp.float32): - return jnp.ones(shape, dtype) * scale - - -class FlaxBeitDropPath(nn.Module): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" - - rate: float - - @nn.module.compact - def __call__(self, inputs, deterministic: Optional[bool] = True): - if self.rate == 0.0: - return inputs - keep_prob = 1.0 - self.rate - if deterministic: - return inputs - else: - shape = (inputs.shape[0],) + (1,) * (inputs.ndim - 1) # work with diff dim tensors, not just 2D ConvNets - rng = self.make_rng("droppath") - random_tensor = keep_prob + jax.random.uniform(rng, shape=shape, dtype=inputs.dtype) - binary_tensor = jnp.floor(random_tensor) - output = inputs / keep_prob * binary_tensor - return output - - -class FlaxBeitPatchEmbeddings(nn.Module): - config: BeitConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.num_channels = self.config.num_channels - image_size = self.config.image_size - patch_size = self.config.patch_size - num_patches = (image_size // patch_size) * (image_size // patch_size) - patch_shape = (image_size // patch_size, image_size // patch_size) - self.num_patches = num_patches - self.patch_shape = patch_shape - self.projection = nn.Conv( - self.config.hidden_size, - kernel_size=(patch_size, patch_size), - strides=(patch_size, patch_size), - padding="VALID", - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - def __call__(self, pixel_values): - num_channels = pixel_values.shape[-1] - if num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - embeddings = self.projection(pixel_values) - batch_size, _, _, channels = embeddings.shape - return jnp.reshape(embeddings, (batch_size, -1, channels)) - - -class FlaxBeitEmbeddings(nn.Module): - """Construct the CLS token, position and patch embeddings.""" - - config: BeitConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.cls_token = self.param("cls_token", nn.initializers.zeros, (1, 1, self.config.hidden_size)) - if self.config.use_mask_token: - self.mask_token = self.param("mask_token", nn.initializers.zeros, (1, 1, self.config.hidden_size)) - self.patch_embeddings = FlaxBeitPatchEmbeddings(self.config, dtype=self.dtype) - num_patches = self.patch_embeddings.num_patches - if self.config.use_absolute_position_embeddings: - self.position_embeddings = self.param( - "position_embeddings", nn.initializers.zeros, (1, num_patches + 1, self.config.hidden_size) - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, pixel_values, bool_masked_pos=None, deterministic=True): - embeddings = self.patch_embeddings(pixel_values) - batch_size, seq_len, _ = embeddings.shape - - cls_tokens = jnp.broadcast_to(self.cls_token, (batch_size, 1, self.config.hidden_size)) - cls_tokens = cls_tokens.astype(embeddings.dtype) - - if bool_masked_pos is not None: - mask_tokens = jnp.broadcast_to(self.mask_token, (batch_size, seq_len, self.config.hidden_size)) - mask_tokens = mask_tokens.astype(embeddings.dtype) - # replace the masked visual tokens by mask_tokens - w = jnp.expand_dims(bool_masked_pos, axis=-1) - embeddings = embeddings * (1 - w) + mask_tokens * w - - embeddings = jnp.concatenate((cls_tokens, embeddings), axis=1) - - if self.config.use_absolute_position_embeddings: - embeddings = embeddings + self.position_embeddings.astype(embeddings.dtype) - - embeddings = self.dropout(embeddings, deterministic=deterministic) - return embeddings - - -class FlaxBeitRelativePositionBias(nn.Module): - config: BeitConfig - window_size: tuple[int, int] - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - num_relative_distance = (2 * self.window_size[0] - 1) * (2 * self.window_size[1] - 1) + 3 - self.relative_position_bias_table = self.param( - "relative_position_bias_table", - nn.initializers.zeros, - (num_relative_distance, self.config.num_attention_heads), - ) # 2*Wh-1 * 2*Ww-1, nH - # cls to token & token 2 cls & cls to cls - - self.relative_position_index = relative_position_index_init(self.window_size) - - def __call__(self): - index = self.relative_position_index.reshape(-1) - shape = (self.window_size[0] * self.window_size[1] + 1, self.window_size[0] * self.window_size[1] + 1, -1) - relative_position_bias = self.relative_position_bias_table[index].reshape(shape) # Wh*Ww,Wh*Ww,nH - return jnp.transpose(relative_position_bias, (2, 0, 1)) - - -class FlaxBeitSelfAttention(nn.Module): - config: BeitConfig - window_size: tuple[int, int] - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - if self.config.hidden_size % self.config.num_attention_heads != 0 and not hasattr( - self.config, "embedding_size" - ): - raise ValueError( - f"The hidden size {self.config.hidden_size} is not a multiple of the number of attention " - f"heads {self.config.num_attention_heads}." - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - use_bias=False, - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - self.relative_position_bias = ( - FlaxBeitRelativePositionBias(self.config, window_size=self.window_size, dtype=self.dtype) - if self.window_size - else None - ) - - def __call__( - self, hidden_states, relative_position_bias=None, deterministic: bool = True, output_attentions: bool = False - ): - head_dim = self.config.hidden_size // self.config.num_attention_heads - - query_states = self.query(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - value_states = self.value(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - key_states = self.key(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attention_bias = jnp.array(0.0, dtype=self.dtype) - # Add relative position bias if present. - if self.relative_position_bias is not None: - attention_bias = jnp.expand_dims(self.relative_position_bias(), 0) - attention_bias = attention_bias.astype(query_states.dtype) - - # Add shared relative position bias if provided. - if relative_position_bias is not None: - attention_bias = attention_bias + relative_position_bias.astype(attention_bias.dtype) - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxBeitSelfOutput(nn.Module): - config: BeitConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxBeitAttention(nn.Module): - config: BeitConfig - window_size: tuple[int, int] - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.attention = FlaxBeitSelfAttention(self.config, self.window_size, dtype=self.dtype) - self.output = FlaxBeitSelfOutput(self.config, dtype=self.dtype) - - def __call__( - self, hidden_states, relative_position_bias=None, deterministic=True, output_attentions: bool = False - ): - attn_outputs = self.attention( - hidden_states, relative_position_bias, deterministic=deterministic, output_attentions=output_attentions - ) - attn_output = attn_outputs[0] - attn_output = self.output(attn_output, deterministic=deterministic) - - outputs = (attn_output,) - - if output_attentions: - outputs += (attn_outputs[1],) - - return outputs - - -class FlaxBeitIntermediate(nn.Module): - config: BeitConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - - return hidden_states - - -class FlaxBeitOutput(nn.Module): - config: BeitConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - - return hidden_states - - -class FlaxBeitLayer(nn.Module): - config: BeitConfig - window_size: tuple[int, int] - drop_path_rate: float - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.attention = FlaxBeitAttention(self.config, self.window_size, dtype=self.dtype) - self.intermediate = FlaxBeitIntermediate(self.config, dtype=self.dtype) - self.output = FlaxBeitOutput(self.config, dtype=self.dtype) - self.layernorm_before = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.drop_path = FlaxBeitDropPath(rate=self.drop_path_rate) - self.layernorm_after = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - self.init_values = self.config.layer_scale_init_value - if self.init_values > 0: - self.lambda_1 = self.param("lambda_1", ones_with_scale, (self.config.hidden_size), self.init_values) - self.lambda_2 = self.param("lambda_2", ones_with_scale, (self.config.hidden_size), self.init_values) - else: - self.lambda_1 = None - self.lambda_2 = None - - def __call__( - self, hidden_states, relative_position_bias=None, deterministic: bool = True, output_attentions: bool = False - ): - self_attention_outputs = self.attention( - self.layernorm_before(hidden_states), # in BEiT, layernorm is applied before self-attention - relative_position_bias, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = self_attention_outputs[0] - - # apply lambda_1 if present - if self.lambda_1 is not None: - attention_output = self.lambda_1.astype(attention_output.dtype) * attention_output - - # first residual connection - hidden_states = self.drop_path(attention_output, deterministic=deterministic) + hidden_states - - # in BEiT, layernorm is also applied after self-attention - layer_output = self.layernorm_after(hidden_states) - - layer_output = self.intermediate(layer_output) - layer_output = self.output(layer_output, deterministic=deterministic) - - # apply lambda_2 if present - if self.lambda_2 is not None: - layer_output = self.lambda_2.astype(layer_output.dtype) * layer_output - - # second residual connection - layer_output = self.drop_path(layer_output, deterministic=deterministic) + hidden_states - - outputs = (layer_output,) - - if output_attentions: - outputs += (self_attention_outputs[1],) - - return outputs - - -class FlaxBeitLayerCollection(nn.Module): - config: BeitConfig - window_size: tuple[int, int] - drop_path_rates: list[float] - relative_position_bias: Callable[[], jnp.ndarray] - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxBeitLayer( - self.config, - window_size=self.window_size if self.config.use_relative_position_bias else None, - drop_path_rate=self.drop_path_rates[i], - name=str(i), - dtype=self.dtype, - ) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - relative_position_bias = self.relative_position_bias() if self.relative_position_bias is not None else None - layer_outputs = layer( - hidden_states, relative_position_bias, deterministic=deterministic, output_attentions=output_attentions - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states,) - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -class FlaxBeitEncoder(nn.Module): - config: BeitConfig - window_size: tuple[int, int] - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - if self.config.use_shared_relative_position_bias: - self.relative_position_bias = FlaxBeitRelativePositionBias( - config=self.config, window_size=self.window_size, dtype=self.dtype - ) - - # stochastic depth decay rule - drop_path_rates = list(np.linspace(0, self.config.drop_path_rate, self.config.num_hidden_layers)) - self.layer = FlaxBeitLayerCollection( - self.config, - window_size=self.window_size, - drop_path_rates=drop_path_rates, - relative_position_bias=self.relative_position_bias - if self.config.use_shared_relative_position_bias - else None, - dtype=self.dtype, - ) - - def __call__( - self, - hidden_states, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.layer( - hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -class FlaxBeitPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = BeitConfig - base_model_prefix = "beit" - main_input_name = "pixel_values" - module_class: nn.Module = None - - def __init__( - self, - config: BeitConfig, - input_shape=None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - if input_shape is None: - input_shape = (1, config.image_size, config.image_size, config.num_channels) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - pixel_values = jnp.zeros(input_shape, dtype=self.dtype) - - params_rng, dropout_rng = jax.random.split(rng) - dropout_rng, droppath_rng = jax.random.split(dropout_rng) - rngs = {"params": params_rng, "dropout": dropout_rng, "droppath": droppath_rng} - - random_params = self.module.init(rngs, pixel_values, return_dict=False)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(BEIT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - pixel_values, - bool_masked_pos=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - dropout_rng, droppath_rng = jax.random.split(dropout_rng) - rngs["dropout"] = dropout_rng - rngs["droppath"] = droppath_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(pixel_values, dtype=jnp.float32), - bool_masked_pos, - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - -class FlaxBeitPooler(nn.Module): - config: BeitConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - if self.config.use_mean_pooling: - self.layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states): - if self.config.use_mean_pooling: - # Mean pool the final hidden states of the patch tokens - patch_tokens = hidden_states[:, 1:, :] - pooled_output = self.layernorm(jnp.mean(patch_tokens, axis=1)) - else: - # Pool by simply taking the final hidden state of the [CLS] token - pooled_output = hidden_states[:, 0] - - return pooled_output - - -class FlaxBeitModule(nn.Module): - config: BeitConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - add_pooling_layer: bool = True - - def setup(self): - self.embeddings = FlaxBeitEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxBeitEncoder( - self.config, window_size=self.embeddings.patch_embeddings.patch_shape, dtype=self.dtype - ) - if not self.config.use_mean_pooling: - self.layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.pooler = FlaxBeitPooler(self.config, dtype=self.dtype) if self.add_pooling_layer else None - - def __call__( - self, - pixel_values, - bool_masked_pos=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - hidden_states = self.embeddings(pixel_values, bool_masked_pos, deterministic=deterministic) - - outputs = self.encoder( - hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - if not self.config.use_mean_pooling: - hidden_states = self.layernorm(hidden_states) - pooled = self.pooler(hidden_states) if self.add_pooling_layer else None - - if not return_dict: - # if pooled is None, don't return it - if pooled is None: - return (hidden_states,) + outputs[1:] - return (hidden_states, pooled) + outputs[1:] - - return FlaxBeitModelOutputWithPooling( - last_hidden_state=hidden_states, - pooler_output=pooled, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - "The bare Beit Model transformer outputting raw hidden-states without any specific head on top.", - BEIT_START_DOCSTRING, -) -class FlaxBeitModel(FlaxBeitPreTrainedModel): - module_class = FlaxBeitModule - - -FLAX_BEIT_MODEL_DOCSTRING = """ - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, FlaxBeitModel - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/beit-base-patch16-224-pt22k-ft22k") - >>> model = FlaxBeitModel.from_pretrained("microsoft/beit-base-patch16-224-pt22k-ft22k") - - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> last_hidden_states = outputs.last_hidden_state - ``` -""" - -overwrite_call_docstring(FlaxBeitModel, FLAX_BEIT_MODEL_DOCSTRING) -append_replace_return_docstrings(FlaxBeitModel, output_type=FlaxBeitModelOutputWithPooling, config_class=BeitConfig) - - -class FlaxBeitForMaskedImageModelingModule(nn.Module): - config: BeitConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.beit = FlaxBeitModule(self.config, add_pooling_layer=False, dtype=self.dtype) - - # Classifier head - self.layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - - def __call__( - self, - pixel_values=None, - bool_masked_pos=None, - deterministic: bool = True, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.beit( - pixel_values, - bool_masked_pos, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - sequence_output = outputs[0] - sequence_output = self.layernorm(sequence_output) - prediction_scores = self.lm_head(sequence_output[:, 1:]) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return output - - return FlaxMaskedLMOutput( - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - "Beit Model transformer with a 'language' modeling head on top (to predict visual tokens).", - BEIT_START_DOCSTRING, -) -class FlaxBeitForMaskedImageModeling(FlaxBeitPreTrainedModel): - module_class = FlaxBeitForMaskedImageModelingModule - - -FLAX_BEIT_MLM_DOCSTRING = """ - bool_masked_pos (`numpy.ndarray` of shape `(batch_size, num_patches)`): - Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). - - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, BeitForMaskedImageModeling - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/beit-base-patch16-224-pt22k") - >>> model = BeitForMaskedImageModeling.from_pretrained("microsoft/beit-base-patch16-224-pt22k") - - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> logits = outputs.logits - ``` -""" - -overwrite_call_docstring(FlaxBeitForMaskedImageModeling, FLAX_BEIT_MLM_DOCSTRING) -append_replace_return_docstrings( - FlaxBeitForMaskedImageModeling, output_type=FlaxMaskedLMOutput, config_class=BeitConfig -) - - -class FlaxBeitForImageClassificationModule(nn.Module): - config: BeitConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.beit = FlaxBeitModule(config=self.config, dtype=self.dtype, add_pooling_layer=True) - self.classifier = nn.Dense( - self.config.num_labels, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - - def __call__( - self, - pixel_values=None, - bool_masked_pos=None, - deterministic: bool = True, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.beit( - pixel_values, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs[1] - logits = self.classifier(pooled_output) - - if not return_dict: - output = (logits,) + outputs[2:] - return output - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Beit Model transformer with an image classification head on top (a linear layer on top of the average of the final - hidden states of the patch tokens) e.g. for ImageNet. - """, - BEIT_START_DOCSTRING, -) -class FlaxBeitForImageClassification(FlaxBeitPreTrainedModel): - module_class = FlaxBeitForImageClassificationModule - - -FLAX_BEIT_CLASSIF_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoImageProcessor, FlaxBeitForImageClassification - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/beit-base-patch16-224") - >>> model = FlaxBeitForImageClassification.from_pretrained("microsoft/beit-base-patch16-224") - - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> logits = outputs.logits - >>> # model predicts one of the 1000 ImageNet classes - >>> predicted_class_idx = logits.argmax(-1).item() - >>> print("Predicted class:", model.config.id2label[predicted_class_idx]) - ``` -""" - -overwrite_call_docstring(FlaxBeitForImageClassification, FLAX_BEIT_CLASSIF_DOCSTRING) -append_replace_return_docstrings( - FlaxBeitForImageClassification, output_type=FlaxSequenceClassifierOutput, config_class=BeitConfig -) - - -__all__ = [ - "FlaxBeitForImageClassification", - "FlaxBeitForMaskedImageModeling", - "FlaxBeitModel", - "FlaxBeitPreTrainedModel", -] diff --git a/src/transformers/models/bert/__init__.py b/src/transformers/models/bert/__init__.py index 2ef22794dde2..b78228a591aa 100644 --- a/src/transformers/models/bert/__init__.py +++ b/src/transformers/models/bert/__init__.py @@ -20,8 +20,6 @@ if TYPE_CHECKING: from .configuration_bert import * from .modeling_bert import * - from .modeling_flax_bert import * - from .modeling_tf_bert import * from .tokenization_bert import * from .tokenization_bert_fast import * from .tokenization_bert_tf import * diff --git a/src/transformers/models/bert/convert_bert_pytorch_checkpoint_to_original_tf.py b/src/transformers/models/bert/convert_bert_pytorch_checkpoint_to_original_tf.py deleted file mode 100644 index 8e1e85d5c04e..000000000000 --- a/src/transformers/models/bert/convert_bert_pytorch_checkpoint_to_original_tf.py +++ /dev/null @@ -1,112 +0,0 @@ -# coding=utf-8 -# Copyright 2018 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. - -"""Convert Huggingface Pytorch checkpoint to Tensorflow checkpoint.""" - -import argparse -import os - -import numpy as np -import tensorflow as tf -import torch - -from transformers import BertModel - - -def convert_pytorch_checkpoint_to_tf(model: BertModel, ckpt_dir: str, model_name: str): - """ - Args: - model: BertModel Pytorch model instance to be converted - ckpt_dir: Tensorflow model directory - model_name: model name - - Currently supported HF models: - - - Y BertModel - - N BertForMaskedLM - - N BertForPreTraining - - N BertForMultipleChoice - - N BertForNextSentencePrediction - - N BertForSequenceClassification - - N BertForQuestionAnswering - """ - - tensors_to_transpose = ("dense.weight", "attention.self.query", "attention.self.key", "attention.self.value") - - var_map = ( - ("layer.", "layer_"), - ("word_embeddings.weight", "word_embeddings"), - ("position_embeddings.weight", "position_embeddings"), - ("token_type_embeddings.weight", "token_type_embeddings"), - (".", "/"), - ("LayerNorm/weight", "LayerNorm/gamma"), - ("LayerNorm/bias", "LayerNorm/beta"), - ("weight", "kernel"), - ) - - if not os.path.isdir(ckpt_dir): - os.makedirs(ckpt_dir) - - state_dict = model.state_dict() - - def to_tf_var_name(name: str): - for patt, repl in iter(var_map): - name = name.replace(patt, repl) - return f"bert/{name}" - - def create_tf_var(tensor: np.ndarray, name: str, session: tf.Session): - tf_dtype = tf.dtypes.as_dtype(tensor.dtype) - tf_var = tf.get_variable(dtype=tf_dtype, shape=tensor.shape, name=name, initializer=tf.zeros_initializer()) - session.run(tf.variables_initializer([tf_var])) - session.run(tf_var) - return tf_var - - tf.reset_default_graph() - with tf.Session() as session: - for var_name in state_dict: - tf_name = to_tf_var_name(var_name) - torch_tensor = state_dict[var_name].numpy() - if any(x in var_name for x in tensors_to_transpose): - torch_tensor = torch_tensor.T - tf_var = create_tf_var(tensor=torch_tensor, name=tf_name, session=session) - tf_var.assign(tf.cast(torch_tensor, tf_var.dtype)) - tf_weight = session.run(tf_var) - print(f"Successfully created {tf_name}: {np.allclose(tf_weight, torch_tensor)}") - - saver = tf.train.Saver(tf.trainable_variables()) - saver.save(session, os.path.join(ckpt_dir, model_name.replace("-", "_") + ".ckpt")) - - -def main(raw_args=None): - parser = argparse.ArgumentParser() - parser.add_argument("--model_name", type=str, required=True, help="model name e.g. google-bert/bert-base-uncased") - parser.add_argument( - "--cache_dir", type=str, default=None, required=False, help="Directory containing pytorch model" - ) - parser.add_argument("--pytorch_model_path", type=str, required=True, help="/path/to/.bin") - parser.add_argument("--tf_cache_dir", type=str, required=True, help="Directory in which to save tensorflow model") - args = parser.parse_args(raw_args) - - model = BertModel.from_pretrained( - pretrained_model_name_or_path=args.model_name, - state_dict=torch.load(args.pytorch_model_path, weights_only=True), - cache_dir=args.cache_dir, - ) - - convert_pytorch_checkpoint_to_tf(model=model, ckpt_dir=args.tf_cache_dir, model_name=args.model_name) - - -if __name__ == "__main__": - main() diff --git a/src/transformers/models/bert/modeling_bert.py b/src/transformers/models/bert/modeling_bert.py index b9238d8bb071..186d13bb7541 100755 --- a/src/transformers/models/bert/modeling_bert.py +++ b/src/transformers/models/bert/modeling_bert.py @@ -16,7 +16,6 @@ """PyTorch BERT model.""" import math -import os import warnings from dataclasses import dataclass from typing import Optional, Union @@ -51,79 +50,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_bert(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except ValueError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class BertEmbeddings(nn.Module): """Construct the embeddings from word, position and token_type embeddings.""" @@ -133,8 +59,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -778,7 +702,6 @@ def forward(self, sequence_output, pooled_output): @auto_docstring class BertPreTrainedModel(PreTrainedModel): config: BertConfig - load_tf_weights = load_tf_weights_in_bert base_model_prefix = "bert" supports_gradient_checkpointing = True _supports_sdpa = True @@ -786,8 +709,6 @@ class BertPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1797,5 +1718,4 @@ def forward( "BertLMHeadModel", "BertModel", "BertPreTrainedModel", - "load_tf_weights_in_bert", ] diff --git a/src/transformers/models/bert/modeling_flax_bert.py b/src/transformers/models/bert/modeling_flax_bert.py deleted file mode 100644 index 37828642eb4e..000000000000 --- a/src/transformers/models/bert/modeling_flax_bert.py +++ /dev/null @@ -1,1727 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Google Flax Team Authors and 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. - -from typing import Callable, Optional - -import flax -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen import partitioning as nn_partitioning -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxBaseModelOutputWithPooling, - FlaxBaseModelOutputWithPoolingAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxMaskedLMOutput, - FlaxMultipleChoiceModelOutput, - FlaxNextSentencePredictorOutput, - FlaxQuestionAnsweringModelOutput, - FlaxSequenceClassifierOutput, - FlaxTokenClassifierOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import ModelOutput, add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_bert import BertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "google-bert/bert-base-uncased" -_CONFIG_FOR_DOC = "BertConfig" - -remat = nn_partitioning.remat - - -@flax.struct.dataclass -class FlaxBertForPreTrainingOutput(ModelOutput): - """ - Output type of [`BertForPreTraining`]. - - Args: - prediction_logits (`jnp.ndarray` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - seq_relationship_logits (`jnp.ndarray` of shape `(batch_size, 2)`): - Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation - before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - prediction_logits: jnp.ndarray = None - seq_relationship_logits: jnp.ndarray = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -BERT_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`BertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. - -""" - -BERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - head_mask (`numpy.ndarray` of shape `({0})`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - -""" - - -class FlaxBertEmbeddings(nn.Module): - """Construct the embeddings from word, position and token_type embeddings.""" - - config: BertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.word_embeddings = nn.Embed( - self.config.vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.position_embeddings = nn.Embed( - self.config.max_position_embeddings, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.token_type_embeddings = nn.Embed( - self.config.type_vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, input_ids, token_type_ids, position_ids, attention_mask, deterministic: bool = True): - # Embed - inputs_embeds = self.word_embeddings(input_ids.astype("i4")) - position_embeds = self.position_embeddings(position_ids.astype("i4")) - token_type_embeddings = self.token_type_embeddings(token_type_ids.astype("i4")) - - # Sum all embeddings - hidden_states = inputs_embeds + token_type_embeddings + position_embeds - - # Layer Norm - hidden_states = self.LayerNorm(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxBertSelfAttention(nn.Module): - config: BertConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.head_dim = self.config.hidden_size // self.config.num_attention_heads - if self.config.hidden_size % self.config.num_attention_heads != 0: - raise ValueError( - "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads` " - " : {self.config.num_attention_heads}" - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.num_attention_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.hidden_size,)) - - @nn.compact - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention._concatenate_to_cache - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic=True, - output_attentions: bool = False, - ): - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.query(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.key(key_value_states) - value_states = self.value(key_value_states) - else: - # self_attention - key_states = self.key(hidden_states) - value_states = self.value(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - # Mask heads if we want to - if layer_head_mask is not None: - attn_weights = jnp.einsum("...hqk,h->...hqk", attn_weights, layer_head_mask) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxBertSelfOutput(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, input_tensor, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - return hidden_states - - -class FlaxBertAttention(nn.Module): - config: BertConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.self = FlaxBertSelfAttention(self.config, causal=self.causal, dtype=self.dtype) - self.output = FlaxBertSelfOutput(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states=None, - init_cache=False, - deterministic=True, - output_attentions: bool = False, - ): - # Attention mask comes in as attention_mask.shape == (*batch_sizes, kv_length) - # FLAX expects: attention_mask.shape == (*batch_sizes, 1, 1, kv_length) such that it is broadcastable - # with attn_weights.shape == (*batch_sizes, num_heads, q_length, kv_length) - attn_outputs = self.self( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=key_value_states, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attn_output = attn_outputs[0] - hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_outputs[1],) - - return outputs - - -class FlaxBertIntermediate(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - -class FlaxBertOutput(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states, attention_output, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + attention_output) - return hidden_states - - -class FlaxBertLayer(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.attention = FlaxBertAttention(self.config, causal=self.config.is_decoder, dtype=self.dtype) - self.intermediate = FlaxBertIntermediate(self.config, dtype=self.dtype) - self.output = FlaxBertOutput(self.config, dtype=self.dtype) - if self.config.add_cross_attention: - self.crossattention = FlaxBertAttention(self.config, causal=False, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - ): - # Self Attention - attention_outputs = self.attention( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = attention_outputs[0] - - # Cross-Attention Block - if encoder_hidden_states is not None: - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=encoder_hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = cross_attention_outputs[0] - - hidden_states = self.intermediate(attention_output) - hidden_states = self.output(hidden_states, attention_output, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attention_outputs[1],) - if encoder_hidden_states is not None: - outputs += (cross_attention_outputs[1],) - return outputs - - -class FlaxBertLayerCollection(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - if self.gradient_checkpointing: - FlaxBertCheckpointLayer = remat(FlaxBertLayer, static_argnums=(5, 6, 7)) - self.layers = [ - FlaxBertCheckpointLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - else: - self.layers = [ - FlaxBertLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - # Check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - if head_mask.shape[0] != (len(self.layers)): - raise ValueError( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for " - f" {head_mask.shape[0]}." - ) - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer( - hidden_states, - attention_mask, - head_mask[i] if head_mask is not None else None, - encoder_hidden_states, - encoder_attention_mask, - init_cache, - deterministic, - output_attentions, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions, all_cross_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - -class FlaxBertEncoder(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.layer = FlaxBertLayerCollection( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.layer( - hidden_states, - attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -class FlaxBertPooler(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - - def __call__(self, hidden_states): - cls_hidden_state = hidden_states[:, 0] - cls_hidden_state = self.dense(cls_hidden_state) - return nn.tanh(cls_hidden_state) - - -class FlaxBertPredictionHeadTransform(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense(self.config.hidden_size, dtype=self.dtype) - self.activation = ACT2FN[self.config.hidden_act] - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return self.LayerNorm(hidden_states) - - -class FlaxBertLMPredictionHead(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.transform = FlaxBertPredictionHeadTransform(self.config, dtype=self.dtype) - self.decoder = nn.Dense(self.config.vocab_size, dtype=self.dtype, use_bias=False) - self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) - - def __call__(self, hidden_states, shared_embedding=None): - hidden_states = self.transform(hidden_states) - - if shared_embedding is not None: - hidden_states = self.decoder.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - hidden_states = self.decoder(hidden_states) - - bias = jnp.asarray(self.bias, self.dtype) - hidden_states += bias - return hidden_states - - -class FlaxBertOnlyMLMHead(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.predictions = FlaxBertLMPredictionHead(self.config, dtype=self.dtype) - - def __call__(self, hidden_states, shared_embedding=None): - hidden_states = self.predictions(hidden_states, shared_embedding=shared_embedding) - return hidden_states - - -class FlaxBertOnlyNSPHead(nn.Module): - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.seq_relationship = nn.Dense(2, dtype=self.dtype) - - def __call__(self, pooled_output): - return self.seq_relationship(pooled_output) - - -class FlaxBertPreTrainingHeads(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.predictions = FlaxBertLMPredictionHead(self.config, dtype=self.dtype) - self.seq_relationship = nn.Dense(2, dtype=self.dtype) - - def __call__(self, hidden_states, pooled_output, shared_embedding=None): - prediction_scores = self.predictions(hidden_states, shared_embedding=shared_embedding) - seq_relationship_score = self.seq_relationship(pooled_output) - return prediction_scores, seq_relationship_score - - -class FlaxBertPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = BertConfig - base_model_prefix = "bert" - module_class: nn.Module = None - - def __init__( - self, - config: BertConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - gradient_checkpointing: bool = False, - **kwargs, - ): - module = self.module_class( - config=config, - dtype=dtype, - gradient_checkpointing=gradient_checkpointing, - **kwargs, - ) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def enable_gradient_checkpointing(self): - self._module = self.module_class( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=True, - ) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - token_type_ids = jnp.zeros_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - attention_mask = jnp.ones_like(input_ids) - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - if self.config.add_cross_attention: - encoder_hidden_states = jnp.zeros(input_shape + (self.config.hidden_size,)) - encoder_attention_mask = attention_mask - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - return_dict=False, - ) - else: - module_init_outputs = self.module.init( - rngs, input_ids, attention_mask, token_type_ids, position_ids, head_mask, return_dict=False - ) - - random_params = module_init_outputs["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderPreTrainedModel.init_cache - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length), dtype="i4") - attention_mask = jnp.ones_like(input_ids, dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - past_key_values: Optional[dict] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # init input tensors if not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - if head_mask is None: - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - if self.config.add_cross_attention: - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed - # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be - # changed by FlaxBertAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - else: - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - ) - - return outputs - - -class FlaxBertModule(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - add_pooling_layer: bool = True - gradient_checkpointing: bool = False - - def setup(self): - self.embeddings = FlaxBertEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxBertEncoder( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.pooler = FlaxBertPooler(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - head_mask: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # make sure `token_type_ids` is correctly initialized when not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - # make sure `position_ids` is correctly initialized when not passed - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - hidden_states = self.embeddings( - input_ids, token_type_ids, position_ids, attention_mask, deterministic=deterministic - ) - outputs = self.encoder( - hidden_states, - attention_mask, - head_mask=head_mask, - deterministic=deterministic, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - pooled = self.pooler(hidden_states) if self.add_pooling_layer else None - - if not return_dict: - # if pooled is None, don't return it - if pooled is None: - return (hidden_states,) + outputs[1:] - return (hidden_states, pooled) + outputs[1:] - - return FlaxBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=hidden_states, - pooler_output=pooled, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - "The bare Bert Model transformer outputting raw hidden-states without any specific head on top.", - BERT_START_DOCSTRING, -) -class FlaxBertModel(FlaxBertPreTrainedModel): - module_class = FlaxBertModule - - -append_call_sample_docstring(FlaxBertModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutputWithPooling, _CONFIG_FOR_DOC) - - -class FlaxBertForPreTrainingModule(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBertModule( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.cls = FlaxBertPreTrainingHeads(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - if self.config.tie_word_embeddings: - shared_embedding = self.bert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - hidden_states = outputs[0] - pooled_output = outputs[1] - - prediction_scores, seq_relationship_score = self.cls( - hidden_states, pooled_output, shared_embedding=shared_embedding - ) - - if not return_dict: - return (prediction_scores, seq_relationship_score) + outputs[2:] - - return FlaxBertForPreTrainingOutput( - prediction_logits=prediction_scores, - seq_relationship_logits=seq_relationship_score, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Bert Model with two heads on top as done during the pretraining: a `masked language modeling` head and a `next - sentence prediction (classification)` head. - """, - BERT_START_DOCSTRING, -) -class FlaxBertForPreTraining(FlaxBertPreTrainedModel): - module_class = FlaxBertForPreTrainingModule - - -FLAX_BERT_FOR_PRETRAINING_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxBertForPreTraining - - >>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased") - >>> model = FlaxBertForPreTraining.from_pretrained("google-bert/bert-base-uncased") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="np") - >>> outputs = model(**inputs) - - >>> prediction_logits = outputs.prediction_logits - >>> seq_relationship_logits = outputs.seq_relationship_logits - ``` -""" - -overwrite_call_docstring( - FlaxBertForPreTraining, - BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length") + FLAX_BERT_FOR_PRETRAINING_DOCSTRING, -) -append_replace_return_docstrings( - FlaxBertForPreTraining, output_type=FlaxBertForPreTrainingOutput, config_class=_CONFIG_FOR_DOC -) - - -class FlaxBertForMaskedLMModule(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBertModule( - config=self.config, - add_pooling_layer=False, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.cls = FlaxBertOnlyMLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.bert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.cls(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxMaskedLMOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings("""Bert Model with a `language modeling` head on top.""", BERT_START_DOCSTRING) -class FlaxBertForMaskedLM(FlaxBertPreTrainedModel): - module_class = FlaxBertForMaskedLMModule - - -append_call_sample_docstring(FlaxBertForMaskedLM, _CHECKPOINT_FOR_DOC, FlaxMaskedLMOutput, _CONFIG_FOR_DOC) - - -class FlaxBertForNextSentencePredictionModule(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBertModule( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.cls = FlaxBertOnlyNSPHead(dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs[1] - seq_relationship_scores = self.cls(pooled_output) - - if not return_dict: - return (seq_relationship_scores,) + outputs[2:] - - return FlaxNextSentencePredictorOutput( - logits=seq_relationship_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """Bert Model with a `next sentence prediction (classification)` head on top.""", - BERT_START_DOCSTRING, -) -class FlaxBertForNextSentencePrediction(FlaxBertPreTrainedModel): - module_class = FlaxBertForNextSentencePredictionModule - - -FLAX_BERT_FOR_NEXT_SENT_PRED_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxBertForNextSentencePrediction - - >>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased") - >>> model = FlaxBertForNextSentencePrediction.from_pretrained("google-bert/bert-base-uncased") - - >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced." - >>> next_sentence = "The sky is blue due to the shorter wavelength of blue light." - >>> encoding = tokenizer(prompt, next_sentence, return_tensors="jax") - - >>> outputs = model(**encoding) - >>> logits = outputs.logits - >>> assert logits[0, 0] < logits[0, 1] # next sentence was random - ``` -""" - - -overwrite_call_docstring( - FlaxBertForNextSentencePrediction, - BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length") + FLAX_BERT_FOR_NEXT_SENT_PRED_DOCSTRING, -) -append_replace_return_docstrings( - FlaxBertForNextSentencePrediction, output_type=FlaxNextSentencePredictorOutput, config_class=_CONFIG_FOR_DOC -) - - -class FlaxBertForSequenceClassificationModule(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBertModule( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.classifier = nn.Dense( - self.config.num_labels, - dtype=self.dtype, - ) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) - - if not return_dict: - return (logits,) + outputs[2:] - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Bert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled - output) e.g. for GLUE tasks. - """, - BERT_START_DOCSTRING, -) -class FlaxBertForSequenceClassification(FlaxBertPreTrainedModel): - module_class = FlaxBertForSequenceClassificationModule - - -append_call_sample_docstring( - FlaxBertForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxBertForMultipleChoiceModule(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBertModule( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.classifier = nn.Dense(1, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - num_choices = input_ids.shape[1] - input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None - attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None - token_type_ids = token_type_ids.reshape(-1, token_type_ids.shape[-1]) if token_type_ids is not None else None - position_ids = position_ids.reshape(-1, position_ids.shape[-1]) if position_ids is not None else None - - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) - - reshaped_logits = logits.reshape(-1, num_choices) - - if not return_dict: - return (reshaped_logits,) + outputs[2:] - - return FlaxMultipleChoiceModelOutput( - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Bert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - BERT_START_DOCSTRING, -) -class FlaxBertForMultipleChoice(FlaxBertPreTrainedModel): - module_class = FlaxBertForMultipleChoiceModule - - -overwrite_call_docstring( - FlaxBertForMultipleChoice, BERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") -) -append_call_sample_docstring( - FlaxBertForMultipleChoice, _CHECKPOINT_FOR_DOC, FlaxMultipleChoiceModelOutput, _CONFIG_FOR_DOC -) - - -class FlaxBertForTokenClassificationModule(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBertModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - logits = self.classifier(hidden_states) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxTokenClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Bert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - BERT_START_DOCSTRING, -) -class FlaxBertForTokenClassification(FlaxBertPreTrainedModel): - module_class = FlaxBertForTokenClassificationModule - - -append_call_sample_docstring( - FlaxBertForTokenClassification, _CHECKPOINT_FOR_DOC, FlaxTokenClassifierOutput, _CONFIG_FOR_DOC -) - - -class FlaxBertForQuestionAnsweringModule(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBertModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - logits = self.qa_outputs(hidden_states) - start_logits, end_logits = jnp.split(logits, self.config.num_labels, axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - return (start_logits, end_logits) + outputs[1:] - - return FlaxQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Bert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - BERT_START_DOCSTRING, -) -class FlaxBertForQuestionAnswering(FlaxBertPreTrainedModel): - module_class = FlaxBertForQuestionAnsweringModule - - -append_call_sample_docstring( - FlaxBertForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxBertForCausalLMModule(nn.Module): - config: BertConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBertModule( - config=self.config, - add_pooling_layer=False, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.cls = FlaxBertOnlyMLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - token_type_ids: Optional[jnp.ndarray] = None, - head_mask: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.bert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.cls(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxCausalLMOutputWithCrossAttentions( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - """ - Bert Model with a language modeling head on top (a linear layer on top of the hidden-states output) e.g for - autoregressive tasks. - """, - BERT_START_DOCSTRING, -) -class FlaxBertForCausalLM(FlaxBertPreTrainedModel): - module_class = FlaxBertForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyway. - # Thus, we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxBertForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutputWithCrossAttentions, - _CONFIG_FOR_DOC, -) - - -__all__ = [ - "FlaxBertForCausalLM", - "FlaxBertForMaskedLM", - "FlaxBertForMultipleChoice", - "FlaxBertForNextSentencePrediction", - "FlaxBertForPreTraining", - "FlaxBertForQuestionAnswering", - "FlaxBertForSequenceClassification", - "FlaxBertForTokenClassification", - "FlaxBertModel", - "FlaxBertPreTrainedModel", -] diff --git a/src/transformers/models/bert/modeling_tf_bert.py b/src/transformers/models/bert/modeling_tf_bert.py deleted file mode 100644 index 1ca82f9f1820..000000000000 --- a/src/transformers/models/bert/modeling_tf_bert.py +++ /dev/null @@ -1,2125 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 BERT model.""" - -from __future__ import annotations - -import math -import warnings -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFBaseModelOutputWithPoolingAndCrossAttentions, - TFCausalLMOutputWithCrossAttentions, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFNextSentencePredictorOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFNextSentencePredictionLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_bert import BertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "google-bert/bert-base-uncased" -_CONFIG_FOR_DOC = "BertConfig" - -# TokenClassification docstring -_CHECKPOINT_FOR_TOKEN_CLASSIFICATION = "dbmdz/bert-large-cased-finetuned-conll03-english" -_TOKEN_CLASS_EXPECTED_OUTPUT = ( - "['O', 'I-ORG', 'I-ORG', 'I-ORG', 'O', 'O', 'O', 'O', 'O', 'I-LOC', 'O', 'I-LOC', 'I-LOC'] " -) -_TOKEN_CLASS_EXPECTED_LOSS = 0.01 - -# QuestionAnswering docstring -_CHECKPOINT_FOR_QA = "ydshieh/bert-base-cased-squad2" -_QA_EXPECTED_OUTPUT = "'a nice puppet'" -_QA_EXPECTED_LOSS = 7.41 -_QA_TARGET_START_INDEX = 14 -_QA_TARGET_END_INDEX = 15 - -# SequenceClassification docstring -_CHECKPOINT_FOR_SEQUENCE_CLASSIFICATION = "ydshieh/bert-base-uncased-yelp-polarity" -_SEQ_CLASS_EXPECTED_OUTPUT = "'LABEL_1'" -_SEQ_CLASS_EXPECTED_LOSS = 0.01 - - -class TFBertPreTrainingLoss: - """ - Loss function suitable for BERT-like pretraining, that is, the task of pretraining a language model by combining - NSP + MLM. .. note:: Any label of -100 will be ignored (along with the corresponding logits) in the loss - computation. - """ - - def hf_compute_loss(self, labels: tf.Tensor, logits: tf.Tensor) -> tf.Tensor: - loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=keras.losses.Reduction.NONE) - - # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway - unmasked_lm_losses = loss_fn(y_true=tf.nn.relu(labels["labels"]), y_pred=logits[0]) - # make sure only labels that are not equal to -100 - # are taken into account for the loss computation - lm_loss_mask = tf.cast(labels["labels"] != -100, dtype=unmasked_lm_losses.dtype) - masked_lm_losses = unmasked_lm_losses * lm_loss_mask - reduced_masked_lm_loss = tf.reduce_sum(masked_lm_losses) / tf.reduce_sum(lm_loss_mask) - - # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway - unmasked_ns_loss = loss_fn(y_true=tf.nn.relu(labels["next_sentence_label"]), y_pred=logits[1]) - ns_loss_mask = tf.cast(labels["next_sentence_label"] != -100, dtype=unmasked_ns_loss.dtype) - masked_ns_loss = unmasked_ns_loss * ns_loss_mask - - reduced_masked_ns_loss = tf.reduce_sum(masked_ns_loss) / tf.reduce_sum(ns_loss_mask) - - return tf.reshape(reduced_masked_lm_loss + reduced_masked_ns_loss, (1,)) - - -class TFBertEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - past_key_values_length=0, - training: bool = False, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - if input_ids is None and inputs_embeds is None: - raise ValueError("Need to provide either `input_ids` or `input_embeds`.") - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - position_ids = tf.expand_dims( - tf.range(start=past_key_values_length, limit=input_shape[1] + past_key_values_length), axis=0 - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -class TFBertSelfAttention(keras.layers.Layer): - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - - self.is_decoder = config.is_decoder - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_layer = past_key_value[0] - value_layer = past_key_value[1] - attention_mask = encoder_attention_mask - elif is_cross_attention: - key_layer = self.transpose_for_scores(self.key(inputs=encoder_hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=encoder_hidden_states), batch_size) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_layer, value_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFBertModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - if self.is_decoder: - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -class TFBertSelfOutput(keras.layers.Layer): - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFBertAttention(keras.layers.Layer): - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFBertSelfAttention(config, name="self") - self.dense_output = TFBertSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - # add attentions (possibly with past_key_value) if we output them - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -class TFBertIntermediate(keras.layers.Layer): - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFBertOutput(keras.layers.Layer): - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFBertLayer(keras.layers.Layer): - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFBertAttention(config, name="attention") - self.is_decoder = config.is_decoder - self.add_cross_attention = config.add_cross_attention - if self.add_cross_attention: - if not self.is_decoder: - raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = TFBertAttention(config, name="crossattention") - self.intermediate = TFBertIntermediate(config, name="intermediate") - self.bert_output = TFBertOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_value: tuple[tf.Tensor] | None, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=self_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - cross_attn_present_key_value = None - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" - " by setting `config.add_cross_attention=True`" - ) - - # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - cross_attention_outputs = self.crossattention( - input_tensor=attention_output, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=cross_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - - # add cross-attn cache to positions 3,4 of present_key_value tuple - cross_attn_present_key_value = cross_attention_outputs[-1] - present_key_value = present_key_value + cross_attn_present_key_value - - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + outputs # add attentions if we output them - - # if decoder, return the attn key/values as the last output - if self.is_decoder: - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - - -class TFBertEncoder(keras.layers.Layer): - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layer = [TFBertLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_values: tuple[tuple[tf.Tensor]] | None, - use_cache: bool | None, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - next_decoder_cache = () if use_cache else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[i], - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - if self.config.add_cross_attention and encoder_hidden_states is not None: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v for v in [hidden_states, all_hidden_states, all_attentions, all_cross_attentions] if v is not None - ) - - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFBertPooler(keras.layers.Layer): - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFBertPredictionHeadTransform(keras.layers.Layer): - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - - if isinstance(config.hidden_act, str): - self.transform_act_fn = get_tf_activation(config.hidden_act) - else: - self.transform_act_fn = config.hidden_act - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.transform_act_fn(hidden_states) - hidden_states = self.LayerNorm(inputs=hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFBertLMPredictionHead(keras.layers.Layer): - def __init__(self, config: BertConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - - self.transform = TFBertPredictionHeadTransform(config, name="transform") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.input_embeddings = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "transform", None) is not None: - with tf.name_scope(self.transform.name): - self.transform.build(None) - - def get_output_embeddings(self) -> keras.layers.Layer: - return self.input_embeddings - - def set_output_embeddings(self, value: tf.Variable): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self) -> dict[str, tf.Variable]: - return {"bias": self.bias} - - def set_bias(self, value: tf.Variable): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.transform(hidden_states=hidden_states) - seq_length = shape_list(hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -class TFBertMLMHead(keras.layers.Layer): - def __init__(self, config: BertConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.predictions = TFBertLMPredictionHead(config, input_embeddings, name="predictions") - - def call(self, sequence_output: tf.Tensor) -> tf.Tensor: - prediction_scores = self.predictions(hidden_states=sequence_output) - - return prediction_scores - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -class TFBertNSPHead(keras.layers.Layer): - def __init__(self, config: BertConfig, **kwargs): - super().__init__(**kwargs) - - self.seq_relationship = keras.layers.Dense( - units=2, - kernel_initializer=get_initializer(config.initializer_range), - name="seq_relationship", - ) - self.config = config - - def call(self, pooled_output: tf.Tensor) -> tf.Tensor: - seq_relationship_score = self.seq_relationship(inputs=pooled_output) - - return seq_relationship_score - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "seq_relationship", None) is not None: - with tf.name_scope(self.seq_relationship.name): - self.seq_relationship.build([None, None, self.config.hidden_size]) - - -@keras_serializable -class TFBertMainLayer(keras.layers.Layer): - config_class = BertConfig - - def __init__(self, config: BertConfig, add_pooling_layer: bool = True, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.is_decoder = config.is_decoder - - self.embeddings = TFBertEmbeddings(config, name="embeddings") - self.encoder = TFBertEncoder(config, name="encoder") - self.pooler = TFBertPooler(config, name="pooler") if add_pooling_layer else None - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - if not self.config.is_decoder: - use_cache = False - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - - if past_key_values is None: - past_key_values_length = 0 - past_key_values = [None] * len(self.encoder.layer) - else: - past_key_values_length = shape_list(past_key_values[0][0])[-2] - - if attention_mask is None: - attention_mask = tf.fill(dims=(batch_size, seq_length + past_key_values_length), value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - - mask_seq_length = seq_length + past_key_values_length - # Copied from `modeling_tf_t5.py` - # Provided a padding mask of dimensions [batch_size, mask_seq_length] - # - if the model is a decoder, apply a causal mask in addition to the padding mask - # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - if self.is_decoder: - seq_ids = tf.range(mask_seq_length) - causal_mask = tf.less_equal( - tf.tile(seq_ids[None, None, :], (batch_size, mask_seq_length, 1)), - seq_ids[None, :, None], - ) - causal_mask = tf.cast(causal_mask, dtype=attention_mask.dtype) - extended_attention_mask = causal_mask * attention_mask[:, None, :] - attention_mask_shape = shape_list(extended_attention_mask) - extended_attention_mask = tf.reshape( - extended_attention_mask, (attention_mask_shape[0], 1, attention_mask_shape[1], attention_mask_shape[2]) - ) - if past_key_values[0] is not None: - # attention_mask needs to be sliced to the shape `[batch_size, 1, from_seq_length - cached_seq_length, to_seq_length] - extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :] - else: - extended_attention_mask = tf.reshape( - attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1]) - ) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Copied from `modeling_tf_t5.py` with -1e9 -> -10000 - if self.is_decoder and encoder_attention_mask is not None: - # If a 2D ou 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=extended_attention_mask.dtype) - num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) - if num_dims_encoder_attention_mask == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if num_dims_encoder_attention_mask == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, - # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) - - encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -10000.0 - else: - encoder_extended_attention_mask = None - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -class TFBertPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = BertConfig - base_model_prefix = "bert" - - -@dataclass -class TFBertForPreTrainingOutput(ModelOutput): - """ - Output type of [`TFBertForPreTraining`]. - - Args: - prediction_logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - seq_relationship_logits (`tf.Tensor` of shape `(batch_size, 2)`): - Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation - before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - prediction_logits: tf.Tensor | None = None - seq_relationship_logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | tf.Tensor | None = None - attentions: tuple[tf.Tensor] | tf.Tensor | None = None - - -BERT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`BertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -BERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare Bert Model transformer outputting raw hidden-states without any specific head on top.", - BERT_START_DOCSTRING, -) -class TFBertModel(TFBertPreTrainedModel): - def __init__(self, config: BertConfig, add_pooling_layer: bool = True, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.bert = TFBertMainLayer(config, add_pooling_layer, name="bert") - - @unpack_inputs - @add_start_docstrings_to_model_forward(BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPoolingAndCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - """ - outputs = self.bert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert", None) is not None: - with tf.name_scope(self.bert.name): - self.bert.build(None) - - -@add_start_docstrings( - """ -Bert Model with two heads on top as done during the pretraining: - a `masked language modeling` head and a `next sentence prediction (classification)` head. - """, - BERT_START_DOCSTRING, -) -class TFBertForPreTraining(TFBertPreTrainedModel, TFBertPreTrainingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"position_ids", - r"cls.predictions.decoder.weight", - r"cls.predictions.decoder.bias", - ] - - def __init__(self, config: BertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.bert = TFBertMainLayer(config, name="bert") - self.nsp = TFBertNSPHead(config, name="nsp___cls") - self.mlm = TFBertMLMHead(config, input_embeddings=self.bert.embeddings, name="mlm___cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.mlm.predictions - - def get_prefix_bias_name(self) -> str: - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.mlm.name + "/" + self.mlm.predictions.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFBertForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - next_sentence_label: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFBertForPreTrainingOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - next_sentence_label (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair - (see `input_ids` docstring) Indices should be in `[0, 1]`: - - - 0 indicates sequence B is a continuation of sequence A, - - 1 indicates sequence B is a random sequence. - kwargs (`dict[str, any]`, *optional*, defaults to `{}`): - Used to hide legacy arguments that have been deprecated. - - Return: - - Examples: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFBertForPreTraining - - >>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased") - >>> model = TFBertForPreTraining.from_pretrained("google-bert/bert-base-uncased") - >>> input_ids = tokenizer("Hello, my dog is cute", add_special_tokens=True, return_tensors="tf") - >>> # Batch size 1 - - >>> outputs = model(input_ids) - >>> prediction_logits, seq_relationship_logits = outputs[:2] - ```""" - outputs = self.bert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output, pooled_output = outputs[:2] - prediction_scores = self.mlm(sequence_output=sequence_output, training=training) - seq_relationship_score = self.nsp(pooled_output=pooled_output) - total_loss = None - - if labels is not None and next_sentence_label is not None: - d_labels = {"labels": labels} - d_labels["next_sentence_label"] = next_sentence_label - total_loss = self.hf_compute_loss(labels=d_labels, logits=(prediction_scores, seq_relationship_score)) - - if not return_dict: - output = (prediction_scores, seq_relationship_score) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - - return TFBertForPreTrainingOutput( - loss=total_loss, - prediction_logits=prediction_scores, - seq_relationship_logits=seq_relationship_score, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert", None) is not None: - with tf.name_scope(self.bert.name): - self.bert.build(None) - if getattr(self, "nsp", None) is not None: - with tf.name_scope(self.nsp.name): - self.nsp.build(None) - if getattr(self, "mlm", None) is not None: - with tf.name_scope(self.mlm.name): - self.mlm.build(None) - - -@add_start_docstrings("""Bert Model with a `language modeling` head on top.""", BERT_START_DOCSTRING) -class TFBertForMaskedLM(TFBertPreTrainedModel, TFMaskedLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"pooler", - r"cls.seq_relationship", - r"cls.predictions.decoder.weight", - r"nsp___cls", - ] - - def __init__(self, config: BertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if config.is_decoder: - logger.warning( - "If you want to use `TFBertForMaskedLM` make sure `config.is_decoder=False` for " - "bi-directional self-attention." - ) - - self.bert = TFBertMainLayer(config, add_pooling_layer=False, name="bert") - self.mlm = TFBertMLMHead(config, input_embeddings=self.bert.embeddings, name="mlm___cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.mlm.predictions - - def get_prefix_bias_name(self) -> str: - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.mlm.name + "/" + self.mlm.predictions.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="'paris'", - expected_loss=0.88, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.bert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.mlm(sequence_output=sequence_output, training=training) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert", None) is not None: - with tf.name_scope(self.bert.name): - self.bert.build(None) - if getattr(self, "mlm", None) is not None: - with tf.name_scope(self.mlm.name): - self.mlm.build(None) - - -class TFBertLMHeadModel(TFBertPreTrainedModel, TFCausalLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"pooler", - r"cls.seq_relationship", - r"cls.predictions.decoder.weight", - r"nsp___cls", - ] - - def __init__(self, config: BertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if not config.is_decoder: - logger.warning("If you want to use `TFBertLMHeadModel` as a standalone, add `is_decoder=True.`") - - self.bert = TFBertMainLayer(config, add_pooling_layer=False, name="bert") - self.mlm = TFBertMLMHead(config, input_embeddings=self.bert.embeddings, name="mlm___cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.mlm.predictions - - def get_prefix_bias_name(self) -> str: - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.mlm.name + "/" + self.mlm.predictions.name - - def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): - input_shape = input_ids.shape - # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly - if attention_mask is None: - attention_mask = tf.ones(input_shape) - - # cut decoder_input_ids if past is used - if past_key_values is not None: - input_ids = input_ids[:, -1:] - - return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} - - @unpack_inputs - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutputWithCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - **kwargs, - ) -> TFCausalLMOutputWithCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - outputs = self.bert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.mlm(sequence_output=sequence_output, training=training) - loss = None - - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels=labels, logits=shifted_logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithCrossAttentions( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert", None) is not None: - with tf.name_scope(self.bert.name): - self.bert.build(None) - if getattr(self, "mlm", None) is not None: - with tf.name_scope(self.mlm.name): - self.mlm.build(None) - - -@add_start_docstrings( - """Bert Model with a `next sentence prediction (classification)` head on top.""", - BERT_START_DOCSTRING, -) -class TFBertForNextSentencePrediction(TFBertPreTrainedModel, TFNextSentencePredictionLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"mlm___cls", r"cls.predictions"] - - def __init__(self, config: BertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.bert = TFBertMainLayer(config, name="bert") - self.nsp = TFBertNSPHead(config, name="nsp___cls") - - @unpack_inputs - @add_start_docstrings_to_model_forward(BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFNextSentencePredictorOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - next_sentence_label: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFNextSentencePredictorOutput | tuple[tf.Tensor]: - r""" - Return: - - Examples: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFBertForNextSentencePrediction - - >>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased") - >>> model = TFBertForNextSentencePrediction.from_pretrained("google-bert/bert-base-uncased") - - >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced." - >>> next_sentence = "The sky is blue due to the shorter wavelength of blue light." - >>> encoding = tokenizer(prompt, next_sentence, return_tensors="tf") - - >>> logits = model(encoding["input_ids"], token_type_ids=encoding["token_type_ids"])[0] - >>> assert logits[0][0] < logits[0][1] # the next sentence was random - ```""" - outputs = self.bert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - seq_relationship_scores = self.nsp(pooled_output=pooled_output) - next_sentence_loss = ( - None - if next_sentence_label is None - else self.hf_compute_loss(labels=next_sentence_label, logits=seq_relationship_scores) - ) - - if not return_dict: - output = (seq_relationship_scores,) + outputs[2:] - return ((next_sentence_loss,) + output) if next_sentence_loss is not None else output - - return TFNextSentencePredictorOutput( - loss=next_sentence_loss, - logits=seq_relationship_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert", None) is not None: - with tf.name_scope(self.bert.name): - self.bert.build(None) - if getattr(self, "nsp", None) is not None: - with tf.name_scope(self.nsp.name): - self.nsp.build(None) - - -@add_start_docstrings( - """ - Bert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled - output) e.g. for GLUE tasks. - """, - BERT_START_DOCSTRING, -) -class TFBertForSequenceClassification(TFBertPreTrainedModel, TFSequenceClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"mlm___cls", r"nsp___cls", r"cls.predictions", r"cls.seq_relationship"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config: BertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.bert = TFBertMainLayer(config, name="bert") - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(rate=classifier_dropout) - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_SEQUENCE_CLASSIFICATION, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_SEQ_CLASS_EXPECTED_OUTPUT, - expected_loss=_SEQ_CLASS_EXPECTED_LOSS, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.bert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(inputs=pooled_output, training=training) - logits = self.classifier(inputs=pooled_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert", None) is not None: - with tf.name_scope(self.bert.name): - self.bert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Bert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - BERT_START_DOCSTRING, -) -class TFBertForMultipleChoice(TFBertPreTrainedModel, TFMultipleChoiceLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"mlm___cls", r"nsp___cls", r"cls.predictions", r"cls.seq_relationship"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config: BertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.bert = TFBertMainLayer(config, name="bert") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - units=1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(BERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(tensor=input_ids, shape=(-1, seq_length)) if input_ids is not None else None - flat_attention_mask = ( - tf.reshape(tensor=attention_mask, shape=(-1, seq_length)) if attention_mask is not None else None - ) - flat_token_type_ids = ( - tf.reshape(tensor=token_type_ids, shape=(-1, seq_length)) if token_type_ids is not None else None - ) - flat_position_ids = ( - tf.reshape(tensor=position_ids, shape=(-1, seq_length)) if position_ids is not None else None - ) - flat_inputs_embeds = ( - tf.reshape(tensor=inputs_embeds, shape=(-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - outputs = self.bert( - input_ids=flat_input_ids, - attention_mask=flat_attention_mask, - token_type_ids=flat_token_type_ids, - position_ids=flat_position_ids, - head_mask=head_mask, - inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(inputs=pooled_output, training=training) - logits = self.classifier(inputs=pooled_output) - reshaped_logits = tf.reshape(tensor=logits, shape=(-1, num_choices)) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert", None) is not None: - with tf.name_scope(self.bert.name): - self.bert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Bert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - BERT_START_DOCSTRING, -) -class TFBertForTokenClassification(TFBertPreTrainedModel, TFTokenClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"pooler", - r"mlm___cls", - r"nsp___cls", - r"cls.predictions", - r"cls.seq_relationship", - ] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config: BertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.bert = TFBertMainLayer(config, add_pooling_layer=False, name="bert") - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(rate=classifier_dropout) - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_TOKEN_CLASSIFICATION, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_TOKEN_CLASS_EXPECTED_OUTPUT, - expected_loss=_TOKEN_CLASS_EXPECTED_LOSS, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.bert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - sequence_output = self.dropout(inputs=sequence_output, training=training) - logits = self.classifier(inputs=sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert", None) is not None: - with tf.name_scope(self.bert.name): - self.bert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Bert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layer on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - BERT_START_DOCSTRING, -) -class TFBertForQuestionAnswering(TFBertPreTrainedModel, TFQuestionAnsweringLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"pooler", - r"mlm___cls", - r"nsp___cls", - r"cls.predictions", - r"cls.seq_relationship", - ] - - def __init__(self, config: BertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.bert = TFBertMainLayer(config, add_pooling_layer=False, name="bert") - self.qa_outputs = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="qa_outputs", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_QA, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - qa_target_start_index=_QA_TARGET_START_INDEX, - qa_target_end_index=_QA_TARGET_END_INDEX, - expected_output=_QA_EXPECTED_OUTPUT, - expected_loss=_QA_EXPECTED_LOSS, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.bert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.qa_outputs(inputs=sequence_output) - start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) - start_logits = tf.squeeze(input=start_logits, axis=-1) - end_logits = tf.squeeze(input=end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels=labels, logits=(start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert", None) is not None: - with tf.name_scope(self.bert.name): - self.bert.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFBertEmbeddings", - "TFBertForMaskedLM", - "TFBertForMultipleChoice", - "TFBertForNextSentencePrediction", - "TFBertForPreTraining", - "TFBertForQuestionAnswering", - "TFBertForSequenceClassification", - "TFBertForTokenClassification", - "TFBertLMHeadModel", - "TFBertMainLayer", - "TFBertModel", - "TFBertPreTrainedModel", -] diff --git a/src/transformers/models/bert/tokenization_bert_tf.py b/src/transformers/models/bert/tokenization_bert_tf.py deleted file mode 100644 index c8fca52c4cbf..000000000000 --- a/src/transformers/models/bert/tokenization_bert_tf.py +++ /dev/null @@ -1,259 +0,0 @@ -import os -from typing import Optional, Union - -import tensorflow as tf -from tensorflow_text import BertTokenizer as BertTokenizerLayer -from tensorflow_text import FastBertTokenizer, ShrinkLongestTrimmer, case_fold_utf8, combine_segments, pad_model_inputs - -from ...modeling_tf_utils import keras -from ...utils.import_utils import requires -from .tokenization_bert import BertTokenizer - - -@requires(backends=("tf", "tensorflow_text")) -class TFBertTokenizer(keras.layers.Layer): - """ - This is an in-graph tokenizer for BERT. It should be initialized similarly to other tokenizers, using the - `from_pretrained()` method. It can also be initialized with the `from_tokenizer()` method, which imports settings - from an existing standard tokenizer object. - - In-graph tokenizers, unlike other Hugging Face tokenizers, are actually Keras layers and are designed to be run - when the model is called, rather than during preprocessing. As a result, they have somewhat more limited options - than standard tokenizer classes. They are most useful when you want to create an end-to-end model that goes - straight from `tf.string` inputs to outputs. - - Args: - vocab_list (`list`): - List containing the vocabulary. - do_lower_case (`bool`, *optional*, defaults to `True`): - Whether or not to lowercase the input when tokenizing. - cls_token_id (`str`, *optional*, defaults to `"[CLS]"`): - The classifier token which is used when doing sequence classification (classification of the whole sequence - instead of per-token classification). It is the first token of the sequence when built with special tokens. - sep_token_id (`str`, *optional*, defaults to `"[SEP]"`): - The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for - sequence classification or for a text and a question for question answering. It is also used as the last - token of a sequence built with special tokens. - pad_token_id (`str`, *optional*, defaults to `"[PAD]"`): - The token used for padding, for example when batching sequences of different lengths. - padding (`str`, defaults to `"longest"`): - The type of padding to use. Can be either `"longest"`, to pad only up to the longest sample in the batch, - or `"max_length", to pad all inputs to the maximum length supported by the tokenizer. - truncation (`bool`, *optional*, defaults to `True`): - Whether to truncate the sequence to the maximum length. - max_length (`int`, *optional*, defaults to `512`): - The maximum length of the sequence, used for padding (if `padding` is "max_length") and/or truncation (if - `truncation` is `True`). - pad_to_multiple_of (`int`, *optional*, defaults to `None`): - If set, the sequence will be padded to a multiple of this value. - return_token_type_ids (`bool`, *optional*, defaults to `True`): - Whether to return token_type_ids. - return_attention_mask (`bool`, *optional*, defaults to `True`): - Whether to return the attention_mask. - use_fast_bert_tokenizer (`bool`, *optional*, defaults to `True`): - If True, will use the FastBertTokenizer class from Tensorflow Text. If False, will use the BertTokenizer - class instead. BertTokenizer supports some additional options, but is slower and cannot be exported to - TFLite. - """ - - def __init__( - self, - vocab_list: list, - do_lower_case: bool, - cls_token_id: Optional[int] = None, - sep_token_id: Optional[int] = None, - pad_token_id: Optional[int] = None, - padding: str = "longest", - truncation: bool = True, - max_length: int = 512, - pad_to_multiple_of: Optional[int] = None, - return_token_type_ids: bool = True, - return_attention_mask: bool = True, - use_fast_bert_tokenizer: bool = True, - **tokenizer_kwargs, - ): - super().__init__() - if use_fast_bert_tokenizer: - self.tf_tokenizer = FastBertTokenizer( - vocab_list, token_out_type=tf.int64, lower_case_nfd_strip_accents=do_lower_case, **tokenizer_kwargs - ) - else: - lookup_table = tf.lookup.StaticVocabularyTable( - tf.lookup.KeyValueTensorInitializer( - keys=vocab_list, - key_dtype=tf.string, - values=tf.range(tf.size(vocab_list, out_type=tf.int64), dtype=tf.int64), - value_dtype=tf.int64, - ), - num_oov_buckets=1, - ) - self.tf_tokenizer = BertTokenizerLayer( - lookup_table, token_out_type=tf.int64, lower_case=do_lower_case, **tokenizer_kwargs - ) - - self.vocab_list = vocab_list - self.do_lower_case = do_lower_case - self.cls_token_id = vocab_list.index("[CLS]") if cls_token_id is None else cls_token_id - self.sep_token_id = vocab_list.index("[SEP]") if sep_token_id is None else sep_token_id - self.pad_token_id = vocab_list.index("[PAD]") if pad_token_id is None else pad_token_id - self.paired_trimmer = ShrinkLongestTrimmer(max_length - 3, axis=1) # Allow room for special tokens - self.max_length = max_length - self.padding = padding - self.truncation = truncation - self.pad_to_multiple_of = pad_to_multiple_of - self.return_token_type_ids = return_token_type_ids - self.return_attention_mask = return_attention_mask - - @classmethod - def from_tokenizer(cls, tokenizer: "PreTrainedTokenizerBase", **kwargs): # noqa: F821 - """ - Initialize a `TFBertTokenizer` from an existing `Tokenizer`. - - Args: - tokenizer (`PreTrainedTokenizerBase`): - The tokenizer to use to initialize the `TFBertTokenizer`. - - Examples: - - ```python - from transformers import AutoTokenizer, TFBertTokenizer - - tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased") - tf_tokenizer = TFBertTokenizer.from_tokenizer(tokenizer) - ``` - """ - do_lower_case = kwargs.pop("do_lower_case", None) - do_lower_case = tokenizer.do_lower_case if do_lower_case is None else do_lower_case - cls_token_id = kwargs.pop("cls_token_id", None) - cls_token_id = tokenizer.cls_token_id if cls_token_id is None else cls_token_id - sep_token_id = kwargs.pop("sep_token_id", None) - sep_token_id = tokenizer.sep_token_id if sep_token_id is None else sep_token_id - pad_token_id = kwargs.pop("pad_token_id", None) - pad_token_id = tokenizer.pad_token_id if pad_token_id is None else pad_token_id - - vocab = tokenizer.get_vocab() - vocab = sorted(vocab.items(), key=lambda x: x[1]) - vocab_list = [entry[0] for entry in vocab] - return cls( - vocab_list=vocab_list, - do_lower_case=do_lower_case, - cls_token_id=cls_token_id, - sep_token_id=sep_token_id, - pad_token_id=pad_token_id, - **kwargs, - ) - - @classmethod - def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], *init_inputs, **kwargs): - """ - Instantiate a `TFBertTokenizer` from a pre-trained tokenizer. - - Args: - pretrained_model_name_or_path (`str` or `os.PathLike`): - The name or path to the pre-trained tokenizer. - - Examples: - - ```python - from transformers import TFBertTokenizer - - tf_tokenizer = TFBertTokenizer.from_pretrained("google-bert/bert-base-uncased") - ``` - """ - try: - tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path, *init_inputs, **kwargs) - except: # noqa: E722 - from .tokenization_bert_fast import BertTokenizerFast - - tokenizer = BertTokenizerFast.from_pretrained(pretrained_model_name_or_path, *init_inputs, **kwargs) - return cls.from_tokenizer(tokenizer, **kwargs) - - def unpaired_tokenize(self, texts): - if self.do_lower_case: - texts = case_fold_utf8(texts) - tokens = self.tf_tokenizer.tokenize(texts) - return tokens.merge_dims(1, -1) - - def call( - self, - text, - text_pair=None, - padding=None, - truncation=None, - max_length=None, - pad_to_multiple_of=None, - return_token_type_ids=None, - return_attention_mask=None, - ): - if padding is None: - padding = self.padding - if padding not in ("longest", "max_length"): - raise ValueError("Padding must be either 'longest' or 'max_length'!") - if max_length is not None and text_pair is not None: - # Because we have to instantiate a Trimmer to do it properly - raise ValueError("max_length cannot be overridden at call time when truncating paired texts!") - if max_length is None: - max_length = self.max_length - if truncation is None: - truncation = self.truncation - if pad_to_multiple_of is None: - pad_to_multiple_of = self.pad_to_multiple_of - if return_token_type_ids is None: - return_token_type_ids = self.return_token_type_ids - if return_attention_mask is None: - return_attention_mask = self.return_attention_mask - if not isinstance(text, tf.Tensor): - text = tf.convert_to_tensor(text) - if text_pair is not None and not isinstance(text_pair, tf.Tensor): - text_pair = tf.convert_to_tensor(text_pair) - if text_pair is not None: - if text.shape.rank > 1: - raise ValueError("text argument should not be multidimensional when a text pair is supplied!") - if text_pair.shape.rank > 1: - raise ValueError("text_pair should not be multidimensional!") - if text.shape.rank == 2: - text, text_pair = text[:, 0], text[:, 1] - text = self.unpaired_tokenize(text) - if text_pair is None: # Unpaired text - if truncation: - text = text[:, : max_length - 2] # Allow room for special tokens - input_ids, token_type_ids = combine_segments( - (text,), start_of_sequence_id=self.cls_token_id, end_of_segment_id=self.sep_token_id - ) - else: # Paired text - text_pair = self.unpaired_tokenize(text_pair) - if truncation: - text, text_pair = self.paired_trimmer.trim([text, text_pair]) - input_ids, token_type_ids = combine_segments( - (text, text_pair), start_of_sequence_id=self.cls_token_id, end_of_segment_id=self.sep_token_id - ) - if padding == "longest": - pad_length = input_ids.bounding_shape(axis=1) - if pad_to_multiple_of is not None: - # No ceiling division in tensorflow, so we negate floordiv instead - pad_length = pad_to_multiple_of * (-tf.math.floordiv(-pad_length, pad_to_multiple_of)) - else: - pad_length = max_length - - input_ids, attention_mask = pad_model_inputs(input_ids, max_seq_length=pad_length, pad_value=self.pad_token_id) - output = {"input_ids": input_ids} - if return_attention_mask: - output["attention_mask"] = attention_mask - if return_token_type_ids: - token_type_ids, _ = pad_model_inputs( - token_type_ids, max_seq_length=pad_length, pad_value=self.pad_token_id - ) - output["token_type_ids"] = token_type_ids - return output - - def get_config(self): - return { - "vocab_list": self.vocab_list, - "do_lower_case": self.do_lower_case, - "cls_token_id": self.cls_token_id, - "sep_token_id": self.sep_token_id, - "pad_token_id": self.pad_token_id, - } - - -__all__ = ["TFBertTokenizer"] diff --git a/src/transformers/models/bert_generation/modeling_bert_generation.py b/src/transformers/models/bert_generation/modeling_bert_generation.py index 4be87a0cd544..c1b09041cd74 100755 --- a/src/transformers/models/bert_generation/modeling_bert_generation.py +++ b/src/transformers/models/bert_generation/modeling_bert_generation.py @@ -437,90 +437,6 @@ def forward( ) -def load_tf_weights_in_bert_generation( - model, tf_hub_path, model_class, is_encoder_named_decoder=False, is_encoder=False -): - try: - import numpy as np - import tensorflow.compat.v1 as tf - import tensorflow_hub as hub - import tensorflow_text # noqa: F401 - - tf.disable_eager_execution() - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_model = hub.Module(tf_hub_path) - init = tf.global_variables_initializer() - with tf.Session() as sess: - init.run() - all_variables = tf_model.variable_map - keep_track_variables = all_variables.copy() - for key in list(all_variables.keys()): - if "global" in key: - logger.info(f"Skipping {key}...") - continue - if not is_encoder: - model_pointer = getattr(model, model_class) - else: - model_pointer = model - is_embedding = False - logger.info(f"Trying to match {key}...") - # remove start_string = "module/bert/" - sub_layers = key.split("/")[2:] - if is_encoder_named_decoder and sub_layers[0] == "encoder": - logger.info(f"Skipping encoder layer {key} for decoder") - continue - if is_encoder and sub_layers[0] == "decoder": - logger.info(f"Skipping decoder layer {key} for encoder") - continue - for i, sub_layer in enumerate(sub_layers): - if sub_layer == "embeddings": - is_embedding = True - elif sub_layer == "LayerNorm": - is_embedding = False - if "layer" in sub_layer: - model_pointer = model_pointer.layer[int(sub_layer.split("_")[-1])] - elif sub_layer in ["kernel", "gamma"]: - model_pointer = model_pointer.weight - elif sub_layer == "beta": - model_pointer = model_pointer.bias - elif sub_layer == "encdec": - model_pointer = model_pointer.crossattention.self - elif sub_layer == "encdec_output": - model_pointer = model_pointer.crossattention.output - elif is_encoder_named_decoder and sub_layer == "decoder": - model_pointer = model_pointer.encoder - else: - if sub_layer == "attention" and "encdec" in sub_layers[i + 1]: - continue - try: - model_pointer = getattr(model_pointer, sub_layer) - except AttributeError: - logger.info(f"Skipping to initialize {key} at {sub_layer}...") - raise AttributeError - - array = np.asarray(sess.run(all_variables[key])) - if not is_embedding: - logger.info(f"Transposing numpy weight of shape {array.shape} for {key}") - array = np.transpose(array) - else: - model_pointer = model_pointer.weight - - if model_pointer.shape != array.shape: - raise ValueError(f"Pointer shape {model_pointer.shape} and array shape {array.shape} mismatched") - logger.info(f"Initialize PyTorch weight {key}") - - model_pointer.data = torch.from_numpy(array.astype(np.float32)) - keep_track_variables.pop(key, None) - - logger.info(f"Weights not copied to PyTorch model: {', '.join(keep_track_variables.keys())}") - return model - - class BertGenerationEmbeddings(nn.Module): """Construct the embeddings from word and position embeddings.""" @@ -528,8 +444,6 @@ def __init__(self, config): super().__init__() self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -568,8 +482,6 @@ class BertGenerationPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -876,5 +788,4 @@ def forward( "BertGenerationDecoder", "BertGenerationEncoder", "BertGenerationPreTrainedModel", - "load_tf_weights_in_bert_generation", ] diff --git a/src/transformers/models/big_bird/__init__.py b/src/transformers/models/big_bird/__init__.py index 87419e69e5c7..e9bc0f08af3e 100644 --- a/src/transformers/models/big_bird/__init__.py +++ b/src/transformers/models/big_bird/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_big_bird import * from .modeling_big_bird import * - from .modeling_flax_big_bird import * from .tokenization_big_bird import * from .tokenization_big_bird_fast import * else: diff --git a/src/transformers/models/big_bird/convert_bigbird_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/big_bird/convert_bigbird_original_tf_checkpoint_to_pytorch.py index 0b8e6590f937..9064c7cbdc08 100644 --- a/src/transformers/models/big_bird/convert_bigbird_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/big_bird/convert_bigbird_original_tf_checkpoint_to_pytorch.py @@ -15,14 +15,197 @@ """Convert BigBird checkpoint.""" import argparse +import math +import os -from transformers import BigBirdConfig, BigBirdForPreTraining, BigBirdForQuestionAnswering, load_tf_weights_in_big_bird +import torch + +from transformers import BigBirdConfig, BigBirdForPreTraining, BigBirdForQuestionAnswering from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +_TRIVIA_QA_MAPPING = { + "big_bird_attention": "attention/self", + "output_layer_norm": "output/LayerNorm", + "attention_output": "attention/output/dense", + "output": "output/dense", + "self_attention_layer_norm": "attention/output/LayerNorm", + "intermediate": "intermediate/dense", + "word_embeddings": "bert/embeddings/word_embeddings", + "position_embedding": "bert/embeddings/position_embeddings", + "type_embeddings": "bert/embeddings/token_type_embeddings", + "embeddings": "bert/embeddings", + "layer_normalization": "output/LayerNorm", + "layer_norm": "LayerNorm", + "trivia_qa_head": "qa_classifier", + "dense": "intermediate/dense", + "dense_1": "qa_outputs", +} + + +def load_tf_weights_in_big_bird(model, tf_checkpoint_path, is_trivia_qa=False): + """Load tf checkpoints in a pytorch model.""" + + def load_tf_weights_bert(init_vars, tf_path): + names = [] + tf_weights = {} + + for name, shape in init_vars: + array = tf.train.load_variable(tf_path, name) + name = name.replace("bert/encoder/LayerNorm", "bert/embeddings/LayerNorm") + logger.info(f"Loading TF weight {name} with shape {shape}") + names.append(name) + tf_weights[name] = array + + return names, tf_weights + + def load_tf_weights_trivia_qa(init_vars): + names = [] + tf_weights = {} + + for i, var in enumerate(init_vars): + name_items = var.name.split("/") + + if "transformer_scaffold" in name_items[0]: + layer_name_items = name_items[0].split("_") + if len(layer_name_items) < 3: + layer_name_items += [0] + + name_items[0] = f"bert/encoder/layer_{layer_name_items[2]}" + + name = "/".join([_TRIVIA_QA_MAPPING.get(x, x) for x in name_items])[:-2] # remove last :0 in variable + + if "self/attention/output" in name: + name = name.replace("self/attention/output", "output") + + if i >= len(init_vars) - 2: + name = name.replace("intermediate", "output") + + logger.info(f"Loading TF weight {name} with shape {var.shape}") + array = var.value().numpy() + names.append(name) + tf_weights[name] = array + + return names, tf_weights + + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + + # Load weights from TF model + init_vars = tf.saved_model.load(tf_path).variables if is_trivia_qa else tf.train.list_variables(tf_path) + + if len(init_vars) <= 0: + raise ValueError("Loaded trained variables cannot be empty.") + + pt_names = list(model.state_dict().keys()) + + if is_trivia_qa: + names, tf_weights = load_tf_weights_trivia_qa(init_vars) + else: + names, tf_weights = load_tf_weights_bert(init_vars, tf_path) + + for txt_name in names: + array = tf_weights[txt_name] + name = txt_name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any( + n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + continue + pointer = model + pt_name = [] + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "kernel" or scope_names[0] == "gamma": + pointer = getattr(pointer, "weight") + pt_name.append("weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + pt_name.append("bias") + elif scope_names[0] == "output_weights": + pointer = getattr(pointer, "weight") + pt_name.append("weight") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + pt_name.append("classifier") + elif scope_names[0] == "transform": + pointer = getattr(pointer, "transform") + pt_name.append("transform") + if ("bias" in name) or ("kernel" in name): + pointer = getattr(pointer, "dense") + pt_name.append("dense") + elif ("beta" in name) or ("gamma" in name): + pointer = getattr(pointer, "LayerNorm") + pt_name.append("LayerNorm") + else: + try: + pointer = getattr(pointer, scope_names[0]) + pt_name.append(f"{scope_names[0]}") + except AttributeError: + logger.info(f"Skipping {m_name}") + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + pt_name.append(f"{num}") + if m_name[-11:] == "_embeddings" or m_name == "embeddings": + pointer = getattr(pointer, "weight") + pt_name.append("weight") + elif m_name == "kernel": + array = np.transpose(array) + try: + if len(array.shape) > len(pointer.shape) and math.prod(array.shape) == math.prod(pointer.shape): + # print(txt_name, array.shape) + if ( + txt_name.endswith("attention/self/key/kernel") + or txt_name.endswith("attention/self/query/kernel") + or txt_name.endswith("attention/self/value/kernel") + ): + array = array.transpose(1, 0, 2).reshape(pointer.shape) + elif txt_name.endswith("attention/output/dense/kernel"): + array = array.transpose(0, 2, 1).reshape(pointer.shape) + else: + array = array.reshape(pointer.shape) + + if pointer.shape != array.shape: + raise ValueError( + f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched of {txt_name}." + ) + except ValueError as e: + e.args += (pointer.shape, array.shape) + raise + pt_weight_name = ".".join(pt_name) + logger.info(f"Initialize PyTorch weight {pt_weight_name} from {txt_name}.") + pointer.data = torch.from_numpy(array) + tf_weights.pop(txt_name, None) + pt_names.remove(pt_weight_name) + + logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}.") + logger.info(f"Weights not initialized in PyTorch model: {', '.join(pt_names)}.") + return model + + def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, big_bird_config_file, pytorch_dump_path, is_trivia_qa): # Initialise PyTorch model config = BigBirdConfig.from_json_file(big_bird_config_file) diff --git a/src/transformers/models/big_bird/modeling_big_bird.py b/src/transformers/models/big_bird/modeling_big_bird.py index f42b1eeaeeb1..69dc11a7cb69 100755 --- a/src/transformers/models/big_bird/modeling_big_bird.py +++ b/src/transformers/models/big_bird/modeling_big_bird.py @@ -15,7 +15,6 @@ """PyTorch BigBird model.""" import math -import os from dataclasses import dataclass from typing import Optional, Union @@ -66,165 +65,6 @@ } -def load_tf_weights_in_big_bird(model, tf_checkpoint_path, is_trivia_qa=False): - """Load tf checkpoints in a pytorch model.""" - - def load_tf_weights_bert(init_vars, tf_path): - names = [] - tf_weights = {} - - for name, shape in init_vars: - array = tf.train.load_variable(tf_path, name) - name = name.replace("bert/encoder/LayerNorm", "bert/embeddings/LayerNorm") - logger.info(f"Loading TF weight {name} with shape {shape}") - names.append(name) - tf_weights[name] = array - - return names, tf_weights - - def load_tf_weights_trivia_qa(init_vars): - names = [] - tf_weights = {} - - for i, var in enumerate(init_vars): - name_items = var.name.split("/") - - if "transformer_scaffold" in name_items[0]: - layer_name_items = name_items[0].split("_") - if len(layer_name_items) < 3: - layer_name_items += [0] - - name_items[0] = f"bert/encoder/layer_{layer_name_items[2]}" - - name = "/".join([_TRIVIA_QA_MAPPING.get(x, x) for x in name_items])[:-2] # remove last :0 in variable - - if "self/attention/output" in name: - name = name.replace("self/attention/output", "output") - - if i >= len(init_vars) - 2: - name = name.replace("intermediate", "output") - - logger.info(f"Loading TF weight {name} with shape {var.shape}") - array = var.value().numpy() - names.append(name) - tf_weights[name] = array - - return names, tf_weights - - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - - # Load weights from TF model - init_vars = tf.saved_model.load(tf_path).variables if is_trivia_qa else tf.train.list_variables(tf_path) - - if len(init_vars) <= 0: - raise ValueError("Loaded trained variables cannot be empty.") - - pt_names = list(model.state_dict().keys()) - - if is_trivia_qa: - names, tf_weights = load_tf_weights_trivia_qa(init_vars) - else: - names, tf_weights = load_tf_weights_bert(init_vars, tf_path) - - for txt_name in names: - array = tf_weights[txt_name] - name = txt_name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - pt_name = [] - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - pt_name.append("weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - pt_name.append("bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - pt_name.append("weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - pt_name.append("classifier") - elif scope_names[0] == "transform": - pointer = getattr(pointer, "transform") - pt_name.append("transform") - if ("bias" in name) or ("kernel" in name): - pointer = getattr(pointer, "dense") - pt_name.append("dense") - elif ("beta" in name) or ("gamma" in name): - pointer = getattr(pointer, "LayerNorm") - pt_name.append("LayerNorm") - else: - try: - pointer = getattr(pointer, scope_names[0]) - pt_name.append(f"{scope_names[0]}") - except AttributeError: - logger.info(f"Skipping {m_name}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - pt_name.append(f"{num}") - if m_name[-11:] == "_embeddings" or m_name == "embeddings": - pointer = getattr(pointer, "weight") - pt_name.append("weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if len(array.shape) > len(pointer.shape) and math.prod(array.shape) == math.prod(pointer.shape): - # print(txt_name, array.shape) - if ( - txt_name.endswith("attention/self/key/kernel") - or txt_name.endswith("attention/self/query/kernel") - or txt_name.endswith("attention/self/value/kernel") - ): - array = array.transpose(1, 0, 2).reshape(pointer.shape) - elif txt_name.endswith("attention/output/dense/kernel"): - array = array.transpose(0, 2, 1).reshape(pointer.shape) - else: - array = array.reshape(pointer.shape) - - if pointer.shape != array.shape: - raise ValueError( - f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched of {txt_name}." - ) - except ValueError as e: - e.args += (pointer.shape, array.shape) - raise - pt_weight_name = ".".join(pt_name) - logger.info(f"Initialize PyTorch weight {pt_weight_name} from {txt_name}.") - pointer.data = torch.from_numpy(array) - tf_weights.pop(txt_name, None) - pt_names.remove(pt_weight_name) - - logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}.") - logger.info(f"Weights not initialized in PyTorch model: {', '.join(pt_names)}.") - return model - - class BigBirdEmbeddings(nn.Module): """Construct the embeddings from word, position and token_type embeddings.""" @@ -235,8 +75,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -937,8 +775,6 @@ def bigbird_block_sparse_attention( @staticmethod def torch_gather_b2(params, indices): - # this operation is equivalent to tf.gather when batch_dims=2 - if params.shape[:2] != indices.shape[:2]: raise ValueError( "Make sure that the first two dimensions of params and indices are identical, but" @@ -1708,15 +1544,12 @@ def forward(self, sequence_output, pooled_output): @auto_docstring class BigBirdPreTrainedModel(PreTrainedModel): config: BigBirdConfig - load_tf_weights = load_tf_weights_in_big_bird base_model_prefix = "bert" supports_gradient_checkpointing = True def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -2954,5 +2787,4 @@ def prepare_question_mask(q_lengths: torch.Tensor, maxlen: int): "BigBirdLayer", "BigBirdModel", "BigBirdPreTrainedModel", - "load_tf_weights_in_big_bird", ] diff --git a/src/transformers/models/big_bird/modeling_flax_big_bird.py b/src/transformers/models/big_bird/modeling_flax_big_bird.py deleted file mode 100644 index 11dcb30f3d47..000000000000 --- a/src/transformers/models/big_bird/modeling_flax_big_bird.py +++ /dev/null @@ -1,2648 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Google Flax Team Authors and 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. - -from typing import Callable, Optional - -import flax -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen import partitioning as nn_partitioning -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxBaseModelOutputWithPooling, - FlaxBaseModelOutputWithPoolingAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxMaskedLMOutput, - FlaxMultipleChoiceModelOutput, - FlaxSequenceClassifierOutput, - FlaxTokenClassifierOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import ModelOutput, add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_big_bird import BigBirdConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "google/bigbird-roberta-base" -_CONFIG_FOR_DOC = "BigBirdConfig" - -remat = nn_partitioning.remat - - -@flax.struct.dataclass -class FlaxBigBirdForPreTrainingOutput(ModelOutput): - """ - Output type of [`BigBirdForPreTraining`]. - - Args: - prediction_logits (`jnp.ndarray` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - seq_relationship_logits (`jnp.ndarray` of shape `(batch_size, 2)`): - Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation - before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - prediction_logits: jnp.ndarray = None - seq_relationship_logits: jnp.ndarray = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxBigBirdForQuestionAnsweringModelOutput(ModelOutput): - """ - Base class for outputs of question answering models. - - Args: - start_logits (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Span-start scores (before SoftMax). - end_logits (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Span-end scores (before SoftMax). - pooled_output (`jnp.ndarray` of shape `(batch_size, hidden_size)`): - pooled_output returned by FlaxBigBirdModel. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - start_logits: jnp.ndarray = None - end_logits: jnp.ndarray = None - pooled_output: jnp.ndarray = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -BIG_BIRD_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`BigBirdConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -BIG_BIRD_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - head_mask (`numpy.ndarray` of shape `({0})`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - -""" - - -class FlaxBigBirdEmbeddings(nn.Module): - """Construct the embeddings from word, position and token_type embeddings.""" - - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEmbeddings.setup - def setup(self): - self.word_embeddings = nn.Embed( - self.config.vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.position_embeddings = nn.Embed( - self.config.max_position_embeddings, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.token_type_embeddings = nn.Embed( - self.config.type_vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, input_ids, token_type_ids, position_ids, attention_mask, deterministic: bool = True): - # Embed - inputs_embeds = self.word_embeddings(input_ids.astype("i4")) - position_embeds = self.position_embeddings(position_ids.astype("i4")) - token_type_embeddings = self.token_type_embeddings(token_type_ids.astype("i4")) - - if self.config.rescale_embeddings: - inputs_embeds *= self.config.hidden_size**0.5 - - # Sum all embeddings - hidden_states = inputs_embeds + token_type_embeddings + position_embeds - - # Layer Norm - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfAttention with Bert->BigBird -class FlaxBigBirdSelfAttention(nn.Module): - config: BigBirdConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.head_dim = self.config.hidden_size // self.config.num_attention_heads - if self.config.hidden_size % self.config.num_attention_heads != 0: - raise ValueError( - "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads` " - " : {self.config.num_attention_heads}" - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.num_attention_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.hidden_size,)) - - @nn.compact - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention._concatenate_to_cache - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic=True, - output_attentions: bool = False, - ): - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.query(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.key(key_value_states) - value_states = self.value(key_value_states) - else: - # self_attention - key_states = self.key(hidden_states) - value_states = self.value(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - # Mask heads if we want to - if layer_head_mask is not None: - attn_weights = jnp.einsum("...hqk,h->...hqk", attn_weights, layer_head_mask) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxBigBirdBlockSparseAttention(nn.Module): - config: BigBirdConfig - block_sparse_seed: Optional[int] = None - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - use_bias=self.config.use_bias, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - use_bias=self.config.use_bias, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - use_bias=self.config.use_bias, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - @staticmethod - def transpose_for_scores(x, n_heads, head_size): - new_x_shape = x.shape[:-1] + (n_heads, head_size) - x = x.reshape(*new_x_shape) - return jnp.transpose(x, axes=(0, 2, 1, 3)) - - def __call__( - self, - hidden_states, - attention_mask, - deterministic=True, - output_attentions=False, - ): - n_heads = self.config.num_attention_heads - head_size = self.config.hidden_size // n_heads - - blocked_encoder_mask, band_mask, from_mask, to_mask = self.create_masks_for_block_sparse_attn( - attention_mask, self.config.block_size - ) - - query_layer = self.transpose_for_scores(self.query(hidden_states), n_heads, head_size) - key_layer = self.transpose_for_scores(self.key(hidden_states), n_heads, head_size) - value_layer = self.transpose_for_scores(self.value(hidden_states), n_heads, head_size) - - indices_prng_key = None - if not deterministic: - indices_prng_key = self.make_rng("indices") - - attn_output, attn_weights = self.bigbird_block_sparse_attention( - query_layer, - key_layer, - value_layer, - band_mask, - from_mask, - to_mask, - blocked_encoder_mask, - blocked_encoder_mask, - n_heads, - head_size, - indices_prng_key=indices_prng_key, - deterministic=deterministic, - plan_from_length=None, - plan_num_rand_blocks=None, - output_attentions=output_attentions, - ) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - @staticmethod - def create_masks_for_block_sparse_attn(attention_mask, block_size: int): - batch_size, seq_length = attention_mask.shape - if seq_length % block_size != 0: - raise ValueError( - f"Sequence length must be multiple of block size, but sequence length is {seq_length}, while block" - f" size is {block_size}." - ) - - def create_band_mask_from_inputs(from_blocked_mask, to_blocked_mask): - """ - Create 3D attention mask from a 2D tensor mask. - - Args: - from_blocked_mask: 2D Tensor of shape [batch_size, - from_seq_length//from_block_size, from_block_size]. - to_blocked_mask: int32 Tensor of shape [batch_size, - to_seq_length//to_block_size, to_block_size]. - - Returns: - float Tensor of shape [batch_size, 1, from_seq_length//from_block_size-4, from_block_size, - 3*to_block_size]. - """ - exp_blocked_to_pad = jnp.concatenate( - [to_blocked_mask[:, 1:-3], to_blocked_mask[:, 2:-2], to_blocked_mask[:, 3:-1]], axis=2 - ) - band_mask = jnp.einsum("blq,blk->blqk", from_blocked_mask[:, 2:-2], exp_blocked_to_pad) - band_mask = jnp.expand_dims(band_mask, 1) - return band_mask - - blocked_encoder_mask = attention_mask.reshape(batch_size, seq_length // block_size, block_size) - band_mask = create_band_mask_from_inputs(blocked_encoder_mask, blocked_encoder_mask) - - from_mask = attention_mask.reshape(batch_size, 1, seq_length, 1) - to_mask = attention_mask.reshape(batch_size, 1, 1, seq_length) - - return blocked_encoder_mask, band_mask, from_mask, to_mask - - def bigbird_block_sparse_attention( - self, - query_layer, - key_layer, - value_layer, - band_mask, - from_mask, - to_mask, - from_blocked_mask, - to_blocked_mask, - n_heads, - head_size, - indices_prng_key: Optional[jax.random.PRNGKey] = None, - deterministic: Optional[bool] = True, - plan_from_length=None, - plan_num_rand_blocks=None, - output_attentions=None, - ): - # BigBird block-sparse attention as suggested in paper - - # ITC: - # global tokens: 2 x block_size - # window tokens: 3 x block_size - # random tokens: num_rand_tokens x block_size - - # ETC: - # global tokens: extra_globals_tokens + 2 x block_size - # window tokens: 3 x block_size - # random tokens: num_rand_tokens x block_size - - # Note: - # 1) Currently, ETC is not supported. - # 2) Window size is fixed to 3 blocks & it can be changed only by - # changing `block_size`. - # 3) Number of global blocks are fixed (2 blocks here) & global tokens can be - # controlled only by `block_size`. - - # attention is calculated separately for q[0], q[1], q[2:-2], q[-2], q[-1] in order to use special trick of - # shifting tokens (for calculating sliding attention). hence following code can be divided into 5 parts. - - bsz, _, from_seq_len, _ = query_layer.shape - to_seq_len = key_layer.shape[2] - from_block_size = to_block_size = self.config.block_size - - if from_seq_len % from_block_size != 0: - raise ValueError("Query sided sequence length must be multiple of block size") - - if to_seq_len % to_block_size != 0: - raise ValueError("Key/Value sided sequence length must be multiple of block size") - - if from_seq_len // from_block_size != to_seq_len // to_block_size: - raise ValueError("Error the number of blocks needs to be same!") - - n_rand_blocks = self.config.num_random_blocks - rsqrt_d = 1 / jnp.sqrt(head_size) - attn_mask_penalty = -10000.0 - - if from_seq_len in [1024, 3072, 4096]: # old plans used in paper - max_seqlen = self.config.max_position_embeddings - rand_attn = [ - self._bigbird_block_rand_mask( - max_seqlen, - max_seqlen, - from_block_size, - to_block_size, - n_rand_blocks, - indices_prng_key=indices_prng_key, - deterministic=deterministic, - last_idx=1024, - )[: (from_seq_len // from_block_size - 2)] - for _ in range(n_heads) - ] - else: - if plan_from_length is None: - plan_from_length, plan_num_rand_blocks = self._get_rand_attn_plan( - from_seq_len, from_block_size, n_rand_blocks - ) - rand_attn = self._bigbird_block_rand_mask_with_head( - from_seq_length=from_seq_len, - to_seq_length=to_seq_len, - from_block_size=from_block_size, - to_block_size=to_block_size, - num_heads=n_heads, - plan_from_length=plan_from_length, - plan_num_rand_blocks=plan_num_rand_blocks, - indices_prng_key=indices_prng_key, - ) - - rand_attn = jnp.stack(rand_attn, axis=0) - rand_attn = jnp.broadcast_to(rand_attn, (bsz,) + rand_attn.shape) - - rand_mask = self._create_rand_mask_from_inputs( - from_blocked_mask, to_blocked_mask, rand_attn, n_heads, n_rand_blocks, bsz, from_seq_len, from_block_size - ) - - blocked_query_matrix = query_layer.reshape(bsz, n_heads, from_seq_len // from_block_size, from_block_size, -1) - blocked_key_matrix = key_layer.reshape(bsz, n_heads, to_seq_len // to_block_size, to_block_size, -1) - blocked_value_matrix = value_layer.reshape(bsz, n_heads, to_seq_len // to_block_size, to_block_size, -1) - - shape = (bsz, n_heads, to_seq_len // to_block_size - 2, n_rand_blocks * to_block_size, -1) - gathered_key = self.jax_gather(blocked_key_matrix, rand_attn, batch_dims=2).reshape(*shape) - gathered_value = self.jax_gather(blocked_value_matrix, rand_attn, batch_dims=2).reshape(*shape) - - # 1st PART - # 1st block (global block) attention scores - # q[0] x (k[0], k[1], k[2], k[3], k[4] .... ) - - # [bsz, n_heads, from_block_size, -1] x [bsz, n_heads, to_seq_len, -1] ==> [bsz, n_heads, from_block_size, to_seq_len] - first_product = jnp.einsum("bhqd,bhkd->bhqk", blocked_query_matrix[:, :, 0], key_layer) - - first_product = first_product * rsqrt_d - first_product += (1.0 - to_mask) * attn_mask_penalty - first_attn_weights = jax.nn.softmax(first_product, axis=-1) # [bsz, n_heads, from_block_size, to_seq_len] - - # [bsz, n_heads, from_block_size, to_seq_len] x [bsz, n_heads, to_seq_len, -1] ==> [bsz, n_heads, from_block_size, -1] - first_context_layer = jnp.einsum("bhqk,bhkd->bhqd", first_attn_weights, value_layer) - first_context_layer = jnp.expand_dims(first_context_layer, 2) - - # 2nd PART - # 2nd block attention scores - # q[1] x (sliding_keys, random_keys, global_keys) - # sliding key blocks -> 2nd, 3rd blocks - # global key blocks -> 1st block - - second_key_mat = jnp.concatenate( - [ - blocked_key_matrix[:, :, 0], - blocked_key_matrix[:, :, 1], - blocked_key_matrix[:, :, 2], - blocked_key_matrix[:, :, -1], - gathered_key[:, :, 0], - ], - axis=2, - ) # [bsz, n_heads, (4+n_rand_blocks)*to_block_size, -1] - second_value_mat = jnp.concatenate( - [ - blocked_value_matrix[:, :, 0], - blocked_value_matrix[:, :, 1], - blocked_value_matrix[:, :, 2], - blocked_value_matrix[:, :, -1], - gathered_value[:, :, 0], - ], - axis=2, - ) # [bsz, n_heads, (4+n_rand_blocks)*to_block_size, -1] - - # [bsz, n_heads, from_block_size, -1] x [bsz, n_heads, (4+n_rand_blocks)*to_block_size, -1] - # ==> [bsz, n_heads, from_block_size, (4+n_rand_blocks)*to_block_size] - second_product = jnp.einsum("bhqd,bhkd->bhqk", blocked_query_matrix[:, :, 1], second_key_mat) - second_seq_pad = jnp.concatenate( - [ - to_mask[:, :, :, : 3 * to_block_size], - to_mask[:, :, :, -to_block_size:], - jnp.ones([bsz, 1, 1, n_rand_blocks * to_block_size], dtype=to_mask.dtype), - ], - axis=3, - ) - second_rand_pad = jnp.concatenate( - [ - jnp.ones([bsz, n_heads, from_block_size, 4 * to_block_size], dtype=rand_mask.dtype), - rand_mask[:, :, 0], - ], - axis=3, - ) - second_product = second_product * rsqrt_d - second_product += (1.0 - jnp.minimum(second_seq_pad, second_rand_pad)) * attn_mask_penalty - second_attn_weights = jax.nn.softmax( - second_product, axis=-1 - ) # [bsz, n_heads, from_block_size, (4+n_rand_blocks)*to_block_size] - - # [bsz, n_heads, from_block_size, (4+r)*to_block_size] x [bsz, n_heads, (4+r)*to_block_size, -1] - # ==> [bsz, n_heads, from_block_size, -1] - second_context_layer = jnp.einsum("bhqk,bhkd->bhqd", second_attn_weights, second_value_mat) - second_context_layer = jnp.expand_dims(second_context_layer, 2) - - # 3rd PART - # Middle blocks attention scores - # q[-2:2] x (sliding_keys, random_keys, global_keys) - # sliding attn is calculated using special trick of shifting tokens as discussed in paper - # random keys are generated by taking random indices as per `rand_attn` - # global keys -> 1st & last block - - exp_blocked_key_matrix = jnp.concatenate( - [blocked_key_matrix[:, :, 1:-3], blocked_key_matrix[:, :, 2:-2], blocked_key_matrix[:, :, 3:-1]], axis=3 - ) # [bsz, n_heads, from_seq_len//from_block_size-4, 3*to_block_size, -1] - exp_blocked_value_matrix = jnp.concatenate( - [blocked_value_matrix[:, :, 1:-3], blocked_value_matrix[:, :, 2:-2], blocked_value_matrix[:, :, 3:-1]], - axis=3, - ) # [bsz, n_heads, from_seq_len//from_block_size-4, 3*to_block_size, -1] - middle_query_matrix = blocked_query_matrix[:, :, 2:-2] - - # sliding attention scores for q[-2:2] - # [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, -1] x [b, n_heads, from_seq_len//from_block_size-4, 3*to_block_size, -1] - inner_band_product = jnp.einsum("bhlqd,bhlkd->bhlqk", middle_query_matrix, exp_blocked_key_matrix) - # ==> [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, 3*to_block_size] - inner_band_product = inner_band_product * rsqrt_d - - # randn attention scores for q[-2:2] - # [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, -1] - # x [bsz, n_heads, from_seq_len//from_block_size-4, n_rand_blocks*to_block_size, -1] - rand_band_product = jnp.einsum("bhlqd,bhlkd->bhlqk", middle_query_matrix, gathered_key[:, :, 1:-1]) - # ==> [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, n_rand_blocks*to_block_size] - rand_band_product = rand_band_product * rsqrt_d - - # Including 1st block (since it's global) - # [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, -1] x [bsz, n_heads, to_block_size, -1] - # ==> [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, to_block_size] - first_band_product = jnp.einsum("bhlqd,bhkd->bhlqk", middle_query_matrix, blocked_key_matrix[:, :, 0]) - first_band_product = first_band_product * rsqrt_d - - # Including last block (since it's global) - # [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, -1] x [bsz, n_heads, to_block_size, -1] - # ==> [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, to_block_size] - last_band_product = jnp.einsum("bhlqd,bhkd->bhlqk", middle_query_matrix, blocked_key_matrix[:, :, -1]) - last_band_product = last_band_product * rsqrt_d - - # masking padded tokens - inner_band_product += (1.0 - band_mask) * attn_mask_penalty - first_band_product += (1.0 - jnp.expand_dims(to_mask[:, :, :, :to_block_size], 3)) * attn_mask_penalty - last_band_product += (1.0 - jnp.expand_dims(to_mask[:, :, :, -to_block_size:], 3)) * attn_mask_penalty - rand_band_product += (1.0 - rand_mask[:, :, 1:-1]) * attn_mask_penalty - - # completing attention scores matrix for all q[-2:2] - band_product = jnp.concatenate( - [first_band_product, inner_band_product, rand_band_product, last_band_product], axis=-1 - ) # [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, (5+n_rand_blocks)*to_block_size] - - # safely doing softmax since attention matrix is completed - attn_weights = jax.nn.softmax( - band_product, axis=-1 - ) # [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, (5+n_rand_blocks)*to_block_size] - - # contribution of sliding keys - # [bsz, n_heads, m//from_block_size-4, from_block_size, 3*to_block_size] - # x [bsz, n_heads, from_seq_len//from_block_size-4, 3*to_block_size, -1] - context_layer = jnp.einsum( - "bhlqk,bhlkd->bhlqd", attn_weights[:, :, :, :, to_block_size : 4 * to_block_size], exp_blocked_value_matrix - ) - # ==> [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, -1] - - # adding contribution of random keys - # [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, n_rand_blocks*to_block_size] - # x [bsz, n_heads, from_seq_len//from_block_size-4, n_rand_blocks*to_block_size, -1] - context_layer += jnp.einsum( - "bhlqk,bhlkd->bhlqd", - attn_weights[:, :, :, :, 4 * to_block_size : -to_block_size], - gathered_value[:, :, 1:-1], - ) - # ==> [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, -1] - - # adding contribution of global keys - # [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, to_block_size] x [bsz, n_heads, to_block_size, -1] - # ==> [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, -1] - context_layer += jnp.einsum( - "bhlqk,bhkd->bhlqd", attn_weights[:, :, :, :, :to_block_size], blocked_value_matrix[:, :, 0] - ) - # [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, to_block_size] x [bsz, n_heads, to_block_size, -1] - # ==> [bsz, n_heads, from_seq_len//from_block_size-4, from_block_size, -1] - context_layer += jnp.einsum( - "bhlqk,bhkd->bhlqd", attn_weights[:, :, :, :, -to_block_size:], blocked_value_matrix[:, :, -1] - ) - - # 4th PART - # last 2nd token attention scores - # q[-2] x (sliding_keys, random_keys, global_keys) - # sliding key blocks -> last 3 blocks - # global key block -> 1st block - # random key block -> based on indices stored in `randn_attn` - - second_last_key_mat = jnp.concatenate( - [ - blocked_key_matrix[:, :, 0], - blocked_key_matrix[:, :, -3], - blocked_key_matrix[:, :, -2], - blocked_key_matrix[:, :, -1], - gathered_key[:, :, -1], - ], - axis=2, - ) # [bsz, n_heads, (4+n_random_blocks)*to_block_size, -1] - second_last_value_mat = jnp.concatenate( - [ - blocked_value_matrix[:, :, 0], - blocked_value_matrix[:, :, -3], - blocked_value_matrix[:, :, -2], - blocked_value_matrix[:, :, -1], - gathered_value[:, :, -1], - ], - axis=2, - ) # [bsz, n_heads, (4+r)*to_block_size, -1] - - # [bsz, n_heads, from_block_size, -1] x [bsz, n_heads, (4+n_rand_blocks)*to_block_size, -1] - # ==> [bsz, n_heads, from_block_size, (4+n_rand_blocks)*to_block_size] - second_last_product = jnp.einsum("bhqd,bhkd->bhqk", blocked_query_matrix[:, :, -2], second_last_key_mat) - second_last_seq_pad = jnp.concatenate( - [ - to_mask[:, :, :, :to_block_size], - to_mask[:, :, :, -3 * to_block_size :], - jnp.ones([bsz, 1, 1, n_rand_blocks * to_block_size], dtype=to_mask.dtype), - ], - axis=3, - ) - second_last_rand_pad = jnp.concatenate( - [ - jnp.ones([bsz, n_heads, from_block_size, 4 * to_block_size], dtype=rand_mask.dtype), - rand_mask[:, :, -1], - ], - axis=3, - ) - second_last_product = second_last_product * rsqrt_d - second_last_product += (1.0 - jnp.minimum(second_last_seq_pad, second_last_rand_pad)) * attn_mask_penalty - second_last_attn_weights = jax.nn.softmax( - second_last_product, axis=-1 - ) # [bsz, n_heads, from_block_size, (4+n_rand_blocks)*to_block_size] - - # [bsz, n_heads, from_block_size, (4+n_rand_blocks)*to_block_size] x [bsz, n_heads, (4+n_rand_blocks)*to_block_size, -1] - # ==> [bsz, n_heads, from_block_size, -1] - second_last_context_layer = jnp.einsum("bhqk,bhkd->bhqd", second_last_attn_weights, second_last_value_mat) - second_last_context_layer = jnp.expand_dims(second_last_context_layer, 2) - - # 5th PART - # last block (global) attention scores - # q[-1] x (k[0], k[1], k[2], k[3], .... ) - - # [bsz, n_heads, from_block_size, -1] x [bsz, n_heads, to_seq_len, -1] ==> [bsz, n_heads, from_block_size, to_seq_len] - last_product = jnp.einsum("bhqd,bhkd->bhqk", blocked_query_matrix[:, :, -1], key_layer) - last_product = last_product * rsqrt_d - last_product += (1.0 - to_mask) * attn_mask_penalty - last_attn_weights = jax.nn.softmax(last_product, axis=-1) # [bsz, n_heads, from_block_size, n] - - # [bsz, n_heads, from_block_size, to_seq_len] x [bsz, n_heads, to_seq_len, -1] ==> [bsz, n_heads, from_block_size, -1] - last_context_layer = jnp.einsum("bhqk,bhkd->bhqd", last_attn_weights, value_layer) - last_context_layer = jnp.expand_dims(last_context_layer, 2) - - # combining representations of all tokens - context_layer = jnp.concatenate( - [first_context_layer, second_context_layer, context_layer, second_last_context_layer, last_context_layer], - axis=2, - ) - context_layer = context_layer.reshape(bsz, n_heads, from_seq_len, -1) * from_mask - context_layer = jnp.transpose(context_layer, axes=(0, 2, 1, 3)).reshape(bsz, from_seq_len, -1) - - attention_probs = None - - return context_layer, attention_probs - - @staticmethod - def jax_gather(params, indices, batch_dims=2): - """ - Gather the indices from params correctly (equivalent to tf.gather but with modifications) - - Args: - params: (bsz, n_heads, num_blocks, block_size, head_dim) - indices: (bhlqk", from_blocked_mask[:, 1:-1], rand_mask) - return rand_mask - - @staticmethod - def _get_rand_attn_plan(from_seq_length, from_block_size, num_rand_blocks): - """ - Gives the plan of where to put random attention. - - Args: - from_seq_length: int. length of from sequence. - from_block_size: int. size of block in from sequence. - num_rand_blocks: int. Number of random chunks per row. - - Returns: - plan_from_length: ending location of from block plan_num_rand_blocks: number of random ending location for - each block - """ - - plan_from_length = [] - plan_num_rand_blocks = [] - if (2 * num_rand_blocks + 5) < (from_seq_length // from_block_size): - plan_from_length.append(int((2 * num_rand_blocks + 5) * from_block_size)) - plan_num_rand_blocks.append(num_rand_blocks) - plan_from_length.append(from_seq_length) - plan_num_rand_blocks.append(0) - elif (num_rand_blocks + 5) < (from_seq_length // from_block_size): - plan_from_length.append(int((num_rand_blocks + 5) * from_block_size)) - plan_num_rand_blocks.append(num_rand_blocks // 2) - plan_from_length.append(from_seq_length) - plan_num_rand_blocks.append(num_rand_blocks - (num_rand_blocks // 2)) - else: - plan_from_length.append(from_seq_length) - plan_num_rand_blocks.append(num_rand_blocks) - - return plan_from_length, plan_num_rand_blocks - - @staticmethod - def _bigbird_block_rand_mask( - from_seq_length, - to_seq_length, - from_block_size, - to_block_size, - num_rand_blocks, - indices_prng_key: Optional[jax.random.PRNGKey] = None, - deterministic: Optional[bool] = True, - last_idx: Optional[int] = -1, - ): - """ - Create adjacency list of random attention. - - Args: - from_seq_length: int. length of from sequence. - to_seq_length: int. length of to sequence. - from_block_size: int. size of block in from sequence. - to_block_size: int. size of block in to sequence. - num_rand_blocks: int. Number of random chunks per row. - indices_prng_key: jax.random.PRNGKey. PRNG key that is used to perform random jax operations. - deterministic: bool. When False random attention will be used. - last_idx: if -1 then num_rand_blocks blocks chosen anywhere in to sequence, - if positive then num_rand_blocks blocks chosen only up to last_idx. - - Returns: - adjacency list of size from_seq_length//from_block_size-2 by num_rand_blocks - """ - # using this method when from_seq_length in [1024, 3072, 4096] - - if from_seq_length // from_block_size != to_seq_length // to_block_size: - raise ValueError("Error the number of blocks needs to be same!") - rand_attn = jnp.zeros((from_seq_length // from_block_size - 2, num_rand_blocks), dtype=jnp.int32) - # deterministic nor randomness - if deterministic: - return rand_attn - - middle_seq = jnp.arange(1, to_seq_length // to_block_size - 1, dtype=jnp.int32) - last = to_seq_length // to_block_size - 1 - if last_idx > (2 * to_block_size): - last = (last_idx // to_block_size) - 1 - - r = num_rand_blocks # shorthand - for i in range(1, from_seq_length // from_block_size - 1): - start = i - 2 - end = i - if i == 1: - seq_values = jax.random.permutation(indices_prng_key, middle_seq[2:last])[:r] - rand_attn = rand_attn.at[i - 1].set(seq_values) - elif i == 2: - seq_values = jax.random.permutation(indices_prng_key, middle_seq[3:last])[:r] - rand_attn = rand_attn.at[i - 1].set(seq_values) - elif i == from_seq_length // from_block_size - 3: - seq_values = jax.random.permutation(indices_prng_key, middle_seq[:last])[:r] - rand_attn = rand_attn.at[i - 1].set(seq_values) - # Missing -3: should have been sliced till last-3 - elif i == from_seq_length // from_block_size - 2: - seq_values = jax.random.permutation(indices_prng_key, middle_seq[:last])[:r] - rand_attn = rand_attn.at[i - 1].set(seq_values) - # Missing -4: should have been sliced till last-4 - else: - if start > last: - start = last - seq_values = jax.random.permutation(indices_prng_key, middle_seq[:start])[:r] - rand_attn = rand_attn.at[i - 1].set(seq_values) - elif (end + 1) == last: - seq_values = jax.random.permutation(indices_prng_key, middle_seq[:start])[:r] - rand_attn = rand_attn.at[i - 1].set(seq_values) - else: - concat_values = jnp.concatenate((middle_seq[:start], middle_seq[end + 1 : last])) - seq_values = jax.random.permutation(indices_prng_key, concat_values)[:r] - rand_attn = rand_attn.at[i - 1].set(seq_values) - return rand_attn - - def _bigbird_block_rand_mask_with_head( - self, - from_seq_length, - to_seq_length, - from_block_size, - to_block_size, - num_heads, - plan_from_length, - plan_num_rand_blocks, - indices_prng_key: Optional[jax.random.PRNGKey] = None, - deterministic: Optional[bool] = True, - window_block_left=1, - window_block_right=1, - global_block_top=1, - global_block_bottom=1, - global_block_left=1, - global_block_right=1, - ): - """ - Create adjacency list of random attention. - - Args: - from_seq_length: int. length of from sequence. - to_seq_length: int. length of to sequence. - from_block_size: int. size of block in from sequence. - to_block_size: int. size of block in to sequence. - num_heads: int. total number of heads. - plan_from_length: list. plan from length where num_random_blocks are chosen from. - plan_num_rand_blocks: list. number of rand blocks within the plan. - indices_prng_key: jax.random.PRNGKey. PRNG key that is used to perform random jax operations. - deterministic: bool. When False random attention will be used. - window_block_left: int. number of blocks of window to left of a block. - window_block_right: int. number of blocks of window to right of a block. - global_block_top: int. number of blocks at the top. - global_block_bottom: int. number of blocks at the bottom. - global_block_left: int. Number of blocks globally used to the left. - global_block_right: int. Number of blocks globally used to the right. - - Returns: - adjacency list of size num_head where each element is of size from_seq_length//from_block_size-2 by - num_rand_blocks - """ - # using this method when from_seq_length not in [1024, 3072, 4096] - - if from_seq_length // from_block_size != to_seq_length // to_block_size: - raise ValueError("Error the number of blocks needs to be same!") - - if from_seq_length not in plan_from_length: - raise ValueError("Error from sequence length not in plan!") - - # Total number of blocks in the mmask - num_blocks = from_seq_length // from_block_size - # Number of blocks per plan - plan_block_length = jnp.array(plan_from_length) // from_block_size - # till when to follow plan - max_plan_idx = plan_from_length.index(from_seq_length) - - # Random Attention adjacency list - rand_attn = [ - jnp.zeros((num_blocks, sum(plan_num_rand_blocks[: max_plan_idx + 1])), dtype=jnp.int32) - for i in range(num_heads) - ] - - # deterministic - if deterministic: - for nh in range(num_heads): - rand_attn[nh] = rand_attn[nh][global_block_top : num_blocks - global_block_bottom, :] - return rand_attn - - # We will go iteratively over the plan blocks and pick random number of - # Attention blocks from the legally allowed blocks - for plan_idx in range(max_plan_idx + 1): - rnd_r_cnt = 0 - if plan_idx > 0: - # set the row for all from_blocks starting from 0 to - # plan_block_length[plan_idx-1] - # column indx start from plan_block_length[plan_idx-1] and ends at - # plan_block_length[plan_idx] - if plan_num_rand_blocks[plan_idx] > 0: - rnd_r_cnt = int(sum(plan_num_rand_blocks[:plan_idx])) - curr_r_cnt = int(sum(plan_num_rand_blocks[: plan_idx + 1])) - for blk_rw_idx in range(global_block_top, plan_block_length[plan_idx - 1]): - for h in range(num_heads): - single_block_row_attention = self._get_single_block_row_attention( - block_id=blk_rw_idx, - to_start_block_id=plan_block_length[plan_idx - 1], - to_end_block_id=plan_block_length[plan_idx], - num_rand_blocks=plan_num_rand_blocks[plan_idx], - window_block_left=window_block_left, - window_block_right=window_block_right, - global_block_left=global_block_left, - global_block_right=global_block_right, - indices_prng_key=indices_prng_key, - ) - rand_attn[h] = ( - rand_attn[h].at[blk_rw_idx, rnd_r_cnt:curr_r_cnt].set(single_block_row_attention) - ) - - for pl_id in range(plan_idx): - if plan_num_rand_blocks[pl_id] == 0: - continue - for blk_rw_idx in range(plan_block_length[plan_idx - 1], plan_block_length[plan_idx]): - rnd_r_cnt = 0 - to_start_block_id = 0 - if pl_id > 0: - rnd_r_cnt = int(sum(plan_num_rand_blocks[:pl_id])) - to_start_block_id = plan_block_length[pl_id - 1] - curr_r_cnt = int(sum(plan_num_rand_blocks[: pl_id + 1])) - for h in range(num_heads): - single_block_row_attention = self._get_single_block_row_attention( - block_id=blk_rw_idx, - to_start_block_id=to_start_block_id, - to_end_block_id=plan_block_length[pl_id], - num_rand_blocks=plan_num_rand_blocks[pl_id], - window_block_left=window_block_left, - window_block_right=window_block_right, - global_block_left=global_block_left, - global_block_right=global_block_right, - indices_prng_key=indices_prng_key, - ) - rand_attn[h] = ( - rand_attn[h].at[blk_rw_idx, rnd_r_cnt:curr_r_cnt].set(single_block_row_attention) - ) - - if plan_num_rand_blocks[plan_idx] == 0: - continue - curr_r_cnt = int(sum(plan_num_rand_blocks[: plan_idx + 1])) - from_start_block_id = global_block_top - to_start_block_id = 0 - if plan_idx > 0: - rnd_r_cnt = int(sum(plan_num_rand_blocks[:plan_idx])) - from_start_block_id = plan_block_length[plan_idx - 1] - to_start_block_id = plan_block_length[plan_idx - 1] - for blk_rw_idx in range(from_start_block_id, plan_block_length[plan_idx]): - for h in range(num_heads): - single_block_row_attention = self._get_single_block_row_attention( - block_id=blk_rw_idx, - to_start_block_id=to_start_block_id, - to_end_block_id=plan_block_length[plan_idx], - num_rand_blocks=plan_num_rand_blocks[plan_idx], - window_block_left=window_block_left, - window_block_right=window_block_right, - global_block_left=global_block_left, - global_block_right=global_block_right, - indices_prng_key=indices_prng_key, - ) - rand_attn[h] = rand_attn[h].at[blk_rw_idx, rnd_r_cnt:curr_r_cnt].set(single_block_row_attention) - - for nh in range(num_heads): - rand_attn[nh] = rand_attn[nh][global_block_top : num_blocks - global_block_bottom, :] - return rand_attn - - @staticmethod - def _get_single_block_row_attention( - block_id, - to_start_block_id, - to_end_block_id, - num_rand_blocks, - indices_prng_key: Optional[jax.random.PRNGKey] = None, - window_block_left=1, - window_block_right=1, - global_block_left=1, - global_block_right=1, - ): - """ - For a single row block get random row attention. - - Args: - block_id: int. block id of row. - to_start_block_id: int. random attention column start id. - to_end_block_id: int. random attention column end id. - num_rand_blocks: int. number of random blocks to be selected. - indices_prng_key: jax.random.PRNGKey. PRNG key that is used to perform random jax operations - window_block_left: int. number of blocks of window to left of a block. - window_block_right: int. number of blocks of window to right of a block. - global_block_left: int. Number of blocks globally used to the left. - global_block_right: int. Number of blocks globally used to the right. - - Returns: - row containing the random attention vector of size num_rand_blocks. - """ - # list of to_blocks from which to choose random attention - to_block_list = jnp.arange(to_start_block_id, to_end_block_id, dtype=jnp.int32) - # permute the blocks - perm_block = jax.random.permutation(indices_prng_key, to_block_list) - - # illegal blocks for the current block id, using window - illegal_blocks = list(range(block_id - window_block_left, block_id + window_block_right + 1)) - - # Add blocks at the start and at the end - illegal_blocks.extend(list(range(global_block_left))) - illegal_blocks.extend(list(range(to_end_block_id - global_block_right, to_end_block_id))) - - # The second from_block cannot choose random attention on second last to_block - if block_id == 1: - illegal_blocks.append(to_end_block_id - 2) - - # The second last from_block cannot choose random attention on second to_block - if block_id == to_end_block_id - 2: - illegal_blocks.append(1) - - selected_random_blocks = [] - - for i in range(to_end_block_id - to_start_block_id): - if perm_block[i] not in illegal_blocks: - selected_random_blocks.append(perm_block[i]) - if len(selected_random_blocks) == num_rand_blocks: - break - return jnp.array(selected_random_blocks, dtype=jnp.int32) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfOutput with Bert->BigBird -class FlaxBigBirdSelfOutput(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, input_tensor, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - return hidden_states - - -class FlaxBigBirdAttention(nn.Module): - config: BigBirdConfig - layer_id: Optional[int] = None - causal: bool = False - dtype: jnp.dtype = jnp.float32 - - def setup(self): - if self.config.attention_type == "original_full": - self.self = FlaxBigBirdSelfAttention(self.config, causal=self.causal, dtype=self.dtype) - elif self.config.attention_type == "block_sparse": - self.self = FlaxBigBirdBlockSparseAttention(self.config, block_sparse_seed=self.layer_id, dtype=self.dtype) - else: - raise ValueError( - f"Your `config.attention_type` is {self.config.attention_type} but it can either be `original_full` or" - " `block_sparse`" - ) - - self.output = FlaxBigBirdSelfOutput(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states=None, - init_cache=False, - deterministic=True, - output_attentions: bool = False, - ): - # Attention mask comes in as attention_mask.shape == (*batch_sizes, kv_length) - # FLAX expects: attention_mask.shape == (*batch_sizes, 1, 1, kv_length) such that it is broadcastable - # with attn_weights.shape == (*batch_sizes, num_heads, q_length, kv_length) - if self.config.attention_type == "original_full": - attn_outputs = self.self( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=key_value_states, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - else: - attn_outputs = self.self( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attn_output = attn_outputs[0] - hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_outputs[1],) - - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertIntermediate with Bert->BigBird -class FlaxBigBirdIntermediate(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertOutput with Bert->BigBird -class FlaxBigBirdOutput(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states, attention_output, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + attention_output) - return hidden_states - - -class FlaxBigBirdLayer(nn.Module): - config: BigBirdConfig - layer_id: Optional[int] = None - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.attention = FlaxBigBirdAttention( - self.config, layer_id=self.layer_id, causal=self.config.is_decoder, dtype=self.dtype - ) - self.intermediate = FlaxBigBirdIntermediate(self.config, dtype=self.dtype) - self.output = FlaxBigBirdOutput(self.config, dtype=self.dtype) - if self.config.add_cross_attention: - self.crossattention = FlaxBigBirdAttention(self.config, causal=False, dtype=self.dtype) - - # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayer.__call__ with Bert->BigBird - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - ): - # Self Attention - attention_outputs = self.attention( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = attention_outputs[0] - - # Cross-Attention Block - if encoder_hidden_states is not None: - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=encoder_hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = cross_attention_outputs[0] - - hidden_states = self.intermediate(attention_output) - hidden_states = self.output(hidden_states, attention_output, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attention_outputs[1],) - if encoder_hidden_states is not None: - outputs += (cross_attention_outputs[1],) - return outputs - - -class FlaxBigBirdLayerCollection(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - if self.gradient_checkpointing: - FlaxBigBirdCheckpointLayer = remat(FlaxBigBirdLayer, static_argnums=(5, 6, 7)) - self.layers = [ - FlaxBigBirdCheckpointLayer(self.config, layer_id=i, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - else: - self.layers = [ - FlaxBigBirdLayer(self.config, layer_id=i, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - - # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayerCollection.__call__ with Bert->BigBird - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - # Check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - if head_mask.shape[0] != (len(self.layers)): - raise ValueError( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for " - f" {head_mask.shape[0]}." - ) - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer( - hidden_states, - attention_mask, - head_mask[i] if head_mask is not None else None, - encoder_hidden_states, - encoder_attention_mask, - init_cache, - deterministic, - output_attentions, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions, all_cross_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEncoder with Bert->BigBird -class FlaxBigBirdEncoder(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.layer = FlaxBigBirdLayerCollection( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.layer( - hidden_states, - attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPredictionHeadTransform with Bert->BigBird -class FlaxBigBirdPredictionHeadTransform(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense(self.config.hidden_size, dtype=self.dtype) - self.activation = ACT2FN[self.config.hidden_act] - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return self.LayerNorm(hidden_states) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLMPredictionHead with Bert->BigBird, np.ndarray->jnp.ndarray -class FlaxBigBirdLMPredictionHead(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., jnp.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.transform = FlaxBigBirdPredictionHeadTransform(self.config, dtype=self.dtype) - self.decoder = nn.Dense(self.config.vocab_size, dtype=self.dtype, use_bias=False) - self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) - - def __call__(self, hidden_states, shared_embedding=None): - hidden_states = self.transform(hidden_states) - - if shared_embedding is not None: - hidden_states = self.decoder.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - hidden_states = self.decoder(hidden_states) - - bias = jnp.asarray(self.bias, self.dtype) - hidden_states += bias - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertOnlyMLMHead with Bert->BigBird -class FlaxBigBirdOnlyMLMHead(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.predictions = FlaxBigBirdLMPredictionHead(self.config, dtype=self.dtype) - - def __call__(self, hidden_states, shared_embedding=None): - hidden_states = self.predictions(hidden_states, shared_embedding=shared_embedding) - return hidden_states - - -class FlaxBigBirdPreTrainingHeads(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.predictions = FlaxBigBirdLMPredictionHead(self.config, dtype=self.dtype) - self.seq_relationship = nn.Dense(2, dtype=self.dtype) - - def __call__(self, hidden_states, pooled_output, shared_embedding=None): - prediction_scores = self.predictions(hidden_states, shared_embedding=shared_embedding) - seq_relationship_score = self.seq_relationship(pooled_output) - return prediction_scores, seq_relationship_score - - -class FlaxBigBirdPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = BigBirdConfig - base_model_prefix = "bert" - module_class: nn.Module = None - - def __init__( - self, - config: BigBirdConfig, - input_shape: Optional[tuple] = None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - gradient_checkpointing: bool = False, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, gradient_checkpointing=gradient_checkpointing, **kwargs) - if config.attention_type == "block_sparse" and input_shape is None: - input_shape = (1, 12 * config.block_size) - elif input_shape is None: - input_shape = (1, 1) - - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPreTrainedModel.enable_gradient_checkpointing - def enable_gradient_checkpointing(self): - self._module = self.module_class( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=True, - ) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - token_type_ids = jnp.zeros_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - attention_mask = jnp.ones_like(input_ids) - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - params_rng, dropout_rng, indices_rng = jax.random.split(rng, num=3) - rngs = {"params": params_rng, "dropout": dropout_rng, "indices": indices_rng} - - if self.config.add_cross_attention: - encoder_hidden_states = jnp.zeros(input_shape + (self.config.hidden_size,)) - encoder_attention_mask = attention_mask - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - return_dict=False, - ) - else: - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - return_dict=False, - ) - - random_params = module_init_outputs["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderPreTrainedModel.init_cache - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length), dtype="i4") - attention_mask = jnp.ones_like(input_ids, dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(BIG_BIRD_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - params: Optional[dict] = None, - dropout_rng: Optional[jax.random.PRNGKey] = None, - indices_rng: Optional[jax.random.PRNGKey] = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - past_key_values: Optional[dict] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # init input tensors if not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - if head_mask is None: - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - # Handle any PRNG if needed - rngs = {} - if indices_rng is not None: - rngs["indices"] = indices_rng - - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - if self.config.add_cross_attention: - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed - # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be - # changed by FlaxBigBirdAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - else: - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - ) - - return outputs - - -class FlaxBigBirdModule(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - add_pooling_layer: bool = True - gradient_checkpointing: bool = False - - def setup(self): - self.embeddings = FlaxBigBirdEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxBigBirdEncoder( - self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.pooler = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - hidden_states = self.embeddings( - input_ids, token_type_ids, position_ids, attention_mask, deterministic=deterministic - ) - outputs = self.encoder( - hidden_states, - attention_mask, - head_mask=head_mask, - deterministic=deterministic, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - - pooled = nn.tanh(self.pooler(hidden_states[:, 0, :])) if self.add_pooling_layer else None - - if not return_dict: - # if pooled is None, don't return it - if pooled is None: - return (hidden_states,) + outputs[1:] - return (hidden_states, pooled) + outputs[1:] - - return FlaxBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=hidden_states, - pooler_output=pooled, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - "The bare BigBird Model transformer outputting raw hidden-states without any specific head on top.", - BIG_BIRD_START_DOCSTRING, -) -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertModel with Bert->BigBird -class FlaxBigBirdModel(FlaxBigBirdPreTrainedModel): - module_class = FlaxBigBirdModule - - -append_call_sample_docstring(FlaxBigBirdModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutputWithPooling, _CONFIG_FOR_DOC) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForPreTrainingModule with Bert->BigBird -class FlaxBigBirdForPreTrainingModule(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBigBirdModule( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.cls = FlaxBigBirdPreTrainingHeads(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - if self.config.tie_word_embeddings: - shared_embedding = self.bert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - hidden_states = outputs[0] - pooled_output = outputs[1] - - prediction_scores, seq_relationship_score = self.cls( - hidden_states, pooled_output, shared_embedding=shared_embedding - ) - - if not return_dict: - return (prediction_scores, seq_relationship_score) + outputs[2:] - - return FlaxBigBirdForPreTrainingOutput( - prediction_logits=prediction_scores, - seq_relationship_logits=seq_relationship_score, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - BigBird Model with two heads on top as done during the pretraining: a `masked language modeling` head and a `next - sentence prediction (classification)` head. - """, - BIG_BIRD_START_DOCSTRING, -) -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForPreTraining with Bert->BigBird -class FlaxBigBirdForPreTraining(FlaxBigBirdPreTrainedModel): - module_class = FlaxBigBirdForPreTrainingModule - - -FLAX_BIG_BIRD_FOR_PRETRAINING_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxBigBirdForPreTraining - - >>> tokenizer = AutoTokenizer.from_pretrained("google/bigbird-roberta-base") - >>> model = FlaxBigBirdForPreTraining.from_pretrained("google/bigbird-roberta-base") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="np") - >>> outputs = model(**inputs) - - >>> prediction_logits = outputs.prediction_logits - >>> seq_relationship_logits = outputs.seq_relationship_logits - ``` -""" - -overwrite_call_docstring( - FlaxBigBirdForPreTraining, - BIG_BIRD_INPUTS_DOCSTRING.format("batch_size, sequence_length") + FLAX_BIG_BIRD_FOR_PRETRAINING_DOCSTRING, -) -append_replace_return_docstrings( - FlaxBigBirdForPreTraining, output_type=FlaxBigBirdForPreTrainingOutput, config_class=_CONFIG_FOR_DOC -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForMaskedLMModule with Bert->BigBird -class FlaxBigBirdForMaskedLMModule(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBigBirdModule( - config=self.config, - add_pooling_layer=False, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.cls = FlaxBigBirdOnlyMLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.bert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.cls(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxMaskedLMOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings("""BigBird Model with a `language modeling` head on top.""", BIG_BIRD_START_DOCSTRING) -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForMaskedLM with Bert->BigBird -class FlaxBigBirdForMaskedLM(FlaxBigBirdPreTrainedModel): - module_class = FlaxBigBirdForMaskedLMModule - - -append_call_sample_docstring(FlaxBigBirdForMaskedLM, _CHECKPOINT_FOR_DOC, FlaxMaskedLMOutput, _CONFIG_FOR_DOC) - - -class FlaxBigBirdClassificationHead(nn.Module): - """Head for sentence-level classification tasks.""" - - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense(self.config.hidden_size, dtype=self.dtype) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(classifier_dropout) - self.out_proj = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__(self, features, deterministic=True): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x, deterministic=deterministic) - x = self.dense(x) - x = ACT2FN[self.config.hidden_act](x) - x = self.dropout(x, deterministic=deterministic) - x = self.out_proj(x) - return x - - -class FlaxBigBirdForSequenceClassificationModule(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBigBirdModule( - config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.classifier = FlaxBigBirdClassificationHead(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - sequence_output = outputs[0] - logits = self.classifier(sequence_output, deterministic=deterministic) - - if not return_dict: - return (logits,) + outputs[2:] - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - BigBird Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - BIG_BIRD_START_DOCSTRING, -) -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForSequenceClassification with Bert->BigBird -class FlaxBigBirdForSequenceClassification(FlaxBigBirdPreTrainedModel): - module_class = FlaxBigBirdForSequenceClassificationModule - - -append_call_sample_docstring( - FlaxBigBirdForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForMultipleChoiceModule with Bert->BigBird -class FlaxBigBirdForMultipleChoiceModule(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBigBirdModule( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.classifier = nn.Dense(1, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - num_choices = input_ids.shape[1] - input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None - attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None - token_type_ids = token_type_ids.reshape(-1, token_type_ids.shape[-1]) if token_type_ids is not None else None - position_ids = position_ids.reshape(-1, position_ids.shape[-1]) if position_ids is not None else None - - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) - - reshaped_logits = logits.reshape(-1, num_choices) - - if not return_dict: - return (reshaped_logits,) + outputs[2:] - - return FlaxMultipleChoiceModelOutput( - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - BigBird Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - BIG_BIRD_START_DOCSTRING, -) -class FlaxBigBirdForMultipleChoice(FlaxBigBirdPreTrainedModel): - module_class = FlaxBigBirdForMultipleChoiceModule - - def __init__( - self, - config: BigBirdConfig, - input_shape: Optional[tuple] = None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - if config.attention_type == "block_sparse" and input_shape is None: - input_shape = (1, 1, 12 * config.block_size) - elif input_shape is None: - input_shape = (1, 1) - super().__init__(config, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - -overwrite_call_docstring( - FlaxBigBirdForMultipleChoice, BIG_BIRD_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") -) -append_call_sample_docstring( - FlaxBigBirdForMultipleChoice, - _CHECKPOINT_FOR_DOC, - FlaxMultipleChoiceModelOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForTokenClassificationModule with Bert->BigBird -class FlaxBigBirdForTokenClassificationModule(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBigBirdModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - logits = self.classifier(hidden_states) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxTokenClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - BigBird Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - BIG_BIRD_START_DOCSTRING, -) -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForTokenClassification with Bert->BigBird -class FlaxBigBirdForTokenClassification(FlaxBigBirdPreTrainedModel): - module_class = FlaxBigBirdForTokenClassificationModule - - -append_call_sample_docstring( - FlaxBigBirdForTokenClassification, - _CHECKPOINT_FOR_DOC, - FlaxTokenClassifierOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxBigBirdForQuestionAnsweringHead(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.intermediate = FlaxBigBirdIntermediate(self.config, dtype=self.dtype) - self.output = FlaxBigBirdOutput(self.config, dtype=self.dtype) - self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__(self, encoder_output, deterministic=True): - hidden_states = self.dropout(encoder_output, deterministic=deterministic) - hidden_states = self.intermediate(hidden_states) - hidden_states = self.output(hidden_states, encoder_output) - hidden_states = self.qa_outputs(hidden_states) - return hidden_states - - -class FlaxBigBirdForQuestionAnsweringModule(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - add_pooling_layer: bool = False - gradient_checkpointing: bool = False - - def setup(self): - self.config.num_labels = 2 - self.bert = FlaxBigBirdModule( - self.config, - dtype=self.dtype, - add_pooling_layer=self.add_pooling_layer, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.qa_classifier = FlaxBigBirdForQuestionAnsweringHead(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - logits_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - pooled_output = outputs[1] if self.add_pooling_layer else None - logits = self.qa_classifier(hidden_states, deterministic=deterministic) - - if logits_mask is not None: - # removing question tokens from the competition - logits = logits - logits_mask * 1e6 - - start_logits, end_logits = jnp.split(logits, self.config.num_labels, axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - return (start_logits, end_logits) + outputs[1:] - - return FlaxBigBirdForQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - pooled_output=pooled_output, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - BigBird Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - BIG_BIRD_START_DOCSTRING, -) -class FlaxBigBirdForQuestionAnswering(FlaxBigBirdPreTrainedModel): - module_class = FlaxBigBirdForQuestionAnsweringModule - - @add_start_docstrings_to_model_forward(BIG_BIRD_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - question_lengths=None, - params: Optional[dict] = None, - dropout_rng: Optional[jax.random.PRNGKey] = None, - indices_rng: Optional[jax.random.PRNGKey] = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - if head_mask is None: - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - if question_lengths is None and input_ids is not None: - # assuming input_ids format: context - question_lengths = jnp.argmax((input_ids == self.config.sep_token_id).astype("i4"), axis=-1) + 1 - question_lengths = jnp.expand_dims(question_lengths, axis=1) - - seqlen = input_ids.shape[1] - - logits_mask = None - if question_lengths is not None: - # setting lengths logits to `-inf` - logits_mask = self.prepare_question_mask(question_lengths, seqlen) - if token_type_ids is None: - token_type_ids = (~logits_mask).astype("i4") - logits_mask = jnp.expand_dims(logits_mask, axis=2) - logits_mask = logits_mask.at[:, 0].set(False) - - # init input tensors if not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - if indices_rng is not None: - rngs["indices"] = indices_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids, - jnp.array(position_ids, dtype="i4"), - jnp.array(head_mask, dtype="i4"), - logits_mask, - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - @staticmethod - def prepare_question_mask(q_lengths, maxlen: int): - # q_lengths -> (bz, 1) - mask = jnp.arange(0, maxlen) - mask = jnp.expand_dims(mask, axis=0) < q_lengths - return mask - - -append_call_sample_docstring( - FlaxBigBirdForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxBigBirdForQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxBigBirdForCausalLMModule(nn.Module): - config: BigBirdConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.bert = FlaxBigBirdModule( - config=self.config, - add_pooling_layer=False, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.cls = FlaxBigBirdOnlyMLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - token_type_ids: Optional[jnp.ndarray] = None, - head_mask: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.bert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.bert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.cls(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxCausalLMOutputWithCrossAttentions( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - """ - BigBird Model with a language modeling head on top (a linear layer on top of the hidden-states output) e.g for - autoregressive tasks. - """, - BIG_BIRD_START_DOCSTRING, -) -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForCausalLM with Bert->BigBird -class FlaxBigBirdForCausalLM(FlaxBigBirdPreTrainedModel): - module_class = FlaxBigBirdForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyway. - # Thus, we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxBigBirdForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutputWithCrossAttentions, - _CONFIG_FOR_DOC, -) - - -__all__ = [ - "FlaxBigBirdForCausalLM", - "FlaxBigBirdForMaskedLM", - "FlaxBigBirdForMultipleChoice", - "FlaxBigBirdForPreTraining", - "FlaxBigBirdForQuestionAnswering", - "FlaxBigBirdForSequenceClassification", - "FlaxBigBirdForTokenClassification", - "FlaxBigBirdModel", - "FlaxBigBirdPreTrainedModel", -] diff --git a/src/transformers/models/bigbird_pegasus/configuration_bigbird_pegasus.py b/src/transformers/models/bigbird_pegasus/configuration_bigbird_pegasus.py index 29b481c78ad1..dc32c34e0d25 100644 --- a/src/transformers/models/bigbird_pegasus/configuration_bigbird_pegasus.py +++ b/src/transformers/models/bigbird_pegasus/configuration_bigbird_pegasus.py @@ -16,13 +16,13 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import Any, Optional +from typing import Any from ... import PreTrainedTokenizer from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig, OnnxConfigWithPast, OnnxSeq2SeqConfigWithPast from ...onnx.utils import compute_effective_axis_dimension -from ...utils import TensorType, is_torch_available, logging +from ...utils import is_torch_available, logging logger = logging.get_logger(__name__) @@ -186,7 +186,7 @@ def __init__( ) -# Copied from transformers.models.bart.configuration_bart.BartOnnxConfig +# Copied from transformers.models.bart.configuration_bart.BartOnnxConfig with Bart->BigBirdPegasus class BigBirdPegasusOnnxConfig(OnnxSeq2SeqConfigWithPast): @property def inputs(self) -> Mapping[str, Mapping[int, str]]: @@ -251,16 +251,15 @@ def _generate_dummy_inputs_for_default_and_seq2seq_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: encoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) # Generate decoder inputs decoder_seq_length = seq_length if not self.use_past else 1 decoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, decoder_seq_length, is_pair, framework + tokenizer, batch_size, decoder_seq_length, is_pair ) decoder_inputs = {f"decoder_{name}": tensor for name, tensor in decoder_inputs.items()} common_inputs = dict(**encoder_inputs, **decoder_inputs) @@ -319,10 +318,9 @@ def _generate_dummy_inputs_for_causal_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) if self.use_past: @@ -357,7 +355,6 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: # Copied from OnnxConfig.generate_dummy_inputs # Did not use super(OnnxConfigWithPast, self).generate_dummy_inputs for code clarity. @@ -374,7 +371,7 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( # Generate dummy inputs according to compute batch and sequence dummy_input = [" ".join([tokenizer.unk_token]) * seq_length] * batch_size - common_inputs = dict(tokenizer(dummy_input, return_tensors=framework)) + common_inputs = dict(tokenizer(dummy_input, return_tensors="pt")) return common_inputs def generate_dummy_inputs( @@ -383,20 +380,19 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: if self.task in ["default", "seq2seq-lm"]: common_inputs = self._generate_dummy_inputs_for_default_and_seq2seq_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) elif self.task == "causal-lm": common_inputs = self._generate_dummy_inputs_for_causal_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) else: common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) return common_inputs diff --git a/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py b/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py index 90f3c886ad93..70644c8d3df2 100755 --- a/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py +++ b/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py @@ -753,8 +753,6 @@ def bigbird_block_sparse_attention( @staticmethod def torch_gather_b2(params, indices): - # this operation is equivalent to tf.gather when batch_dims=2 - if params.shape[:2] != indices.shape[:2]: raise ValueError( "Make sure that the first two dimensions of params and indices are identical, but" diff --git a/src/transformers/models/bit/image_processing_bit.py b/src/transformers/models/bit/image_processing_bit.py index 3d32752edca8..983149fea574 100644 --- a/src/transformers/models/bit/image_processing_bit.py +++ b/src/transformers/models/bit/image_processing_bit.py @@ -226,10 +226,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -259,10 +257,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/bit/modeling_bit.py b/src/transformers/models/bit/modeling_bit.py index 1e491f06eae6..616c6d31d339 100644 --- a/src/transformers/models/bit/modeling_bit.py +++ b/src/transformers/models/bit/modeling_bit.py @@ -80,7 +80,7 @@ def get_padding_value(padding=None, kernel_size=7, stride=1, dilation=1) -> tupl class WeightStandardizedConv2d(nn.Conv2d): - """Conv2d with Weight Standardization. Includes TensorFlow compatible SAME padding. Used for ViT Hybrid model. + """Conv2d with Weight Standardization. Used for ViT Hybrid model. Paper: [Micro-Batch Training with Batch-Channel Normalization and Weight Standardization](https://huggingface.co/papers/1903.10520v2) @@ -197,8 +197,6 @@ def forward(self, input): class BitMaxPool2d(nn.MaxPool2d): - """Tensorflow like 'SAME' wrapper for 2D max pooling""" - def __init__( self, kernel_size: int, @@ -280,11 +278,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/blenderbot/__init__.py b/src/transformers/models/blenderbot/__init__.py index 76ece6853b38..6e728fd0914a 100644 --- a/src/transformers/models/blenderbot/__init__.py +++ b/src/transformers/models/blenderbot/__init__.py @@ -20,8 +20,6 @@ if TYPE_CHECKING: from .configuration_blenderbot import * from .modeling_blenderbot import * - from .modeling_flax_blenderbot import * - from .modeling_tf_blenderbot import * from .tokenization_blenderbot import * from .tokenization_blenderbot_fast import * else: diff --git a/src/transformers/models/blenderbot/configuration_blenderbot.py b/src/transformers/models/blenderbot/configuration_blenderbot.py index 44287991375a..8e4e4812aafd 100644 --- a/src/transformers/models/blenderbot/configuration_blenderbot.py +++ b/src/transformers/models/blenderbot/configuration_blenderbot.py @@ -16,11 +16,11 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import Any, Optional +from typing import Any from ... import PreTrainedTokenizer from ...configuration_utils import PretrainedConfig -from ...file_utils import TensorType, is_torch_available +from ...file_utils import is_torch_available from ...onnx import OnnxConfig, OnnxConfigWithPast, OnnxSeq2SeqConfigWithPast from ...onnx.utils import compute_effective_axis_dimension from ...utils import logging @@ -228,15 +228,14 @@ def _generate_dummy_inputs_for_default_and_seq2seq_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: encoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) # Generate decoder inputs decoder_seq_length = seq_length if not self.use_past else 1 decoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, decoder_seq_length, is_pair, framework + tokenizer, batch_size, decoder_seq_length, is_pair ) decoder_inputs = {f"decoder_{name}": tensor for name, tensor in decoder_inputs.items()} common_inputs = dict(**encoder_inputs, **decoder_inputs) @@ -285,10 +284,9 @@ def _generate_dummy_inputs_for_causal_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) if self.use_past: @@ -322,7 +320,6 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: # Copied from OnnxConfig.generate_dummy_inputs # Did not use super(OnnxConfigWithPast, self).generate_dummy_inputs for code clarity. @@ -339,7 +336,7 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( # Generate dummy inputs according to compute batch and sequence dummy_input = [" ".join([tokenizer.unk_token]) * seq_length] * batch_size - common_inputs = dict(tokenizer(dummy_input, return_tensors=framework)) + common_inputs = dict(tokenizer(dummy_input, return_tensors="pt")) return common_inputs # Copied from transformers.models.bart.configuration_bart.BartOnnxConfig.generate_dummy_inputs @@ -349,20 +346,19 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: if self.task in ["default", "seq2seq-lm"]: common_inputs = self._generate_dummy_inputs_for_default_and_seq2seq_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) elif self.task == "causal-lm": common_inputs = self._generate_dummy_inputs_for_causal_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) else: common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) return common_inputs diff --git a/src/transformers/models/blenderbot/modeling_flax_blenderbot.py b/src/transformers/models/blenderbot/modeling_flax_blenderbot.py deleted file mode 100644 index 8b147211881b..000000000000 --- a/src/transformers/models/blenderbot/modeling_flax_blenderbot.py +++ /dev/null @@ -1,1508 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Fairseq Authors and The Google Flax Team Authors And The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax Blenderbot model.""" - -import math -import random -from functools import partial -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxSeq2SeqLMOutput, - FlaxSeq2SeqModelOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_blenderbot import BlenderbotConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "BlenderbotConfig" -_CHECKPOINT_FOR_DOC = "facebook/blenderbot-400M-distill" - - -BLENDERBOT_START_DOCSTRING = r""" - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`BlenderbotConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -BLENDERBOT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -BLENDERBOT_ENCODE_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -BLENDERBOT_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.bart.modeling_flax_bart.shift_tokens_right -def shift_tokens_right(input_ids: jnp.ndarray, pad_token_id: int, decoder_start_token_id: int) -> jnp.ndarray: - """ - Shift input ids one token to the right. - """ - shifted_input_ids = jnp.zeros_like(input_ids) - shifted_input_ids = shifted_input_ids.at[:, 1:].set(input_ids[:, :-1]) - shifted_input_ids = shifted_input_ids.at[:, 0].set(decoder_start_token_id) - - shifted_input_ids = jnp.where(shifted_input_ids == -100, pad_token_id, shifted_input_ids) - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention with Bart->Blenderbot -class FlaxBlenderbotAttention(nn.Module): - config: BlenderbotConfig - embed_dim: int - num_heads: int - dropout: float = 0.0 - causal: bool = False - bias: bool = True - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self) -> None: - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {self.num_heads})." - ) - - dense = partial( - nn.Dense, - self.embed_dim, - use_bias=self.bias, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() - self.out_proj = dense() - - self.dropout_layer = nn.Dropout(rate=self.dropout) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states: jnp.ndarray, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.q_proj(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.k_proj(key_value_states) - value_states = self.v_proj(key_value_states) - else: - # self_attention - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights - - -# Copied from transformers.models.mbart.modeling_flax_mbart.FlaxMBartEncoderLayer with MBart->Blenderbot -class FlaxBlenderbotEncoderLayer(nn.Module): - config: BlenderbotConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxBlenderbotAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.encoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - self.fc1 = nn.Dense( - self.config.encoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - hidden_states, attn_weights = self.self_attn(hidden_states=hidden_states, attention_mask=attention_mask) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartEncoderLayerCollection with Bart->Blenderbot -class FlaxBlenderbotEncoderLayerCollection(nn.Module): - config: BlenderbotConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxBlenderbotEncoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.encoder_layers) - ] - self.layerdrop = self.config.encoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for encoder_layer in self.layers: - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): # skip the layer - layer_outputs = (None, None) - else: - layer_outputs = encoder_layer( - hidden_states, - attention_mask, - output_attentions, - deterministic, - ) - hidden_states = layer_outputs[0] - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -# Copied from transformers.models.mbart.modeling_flax_mbart.FlaxMBartDecoderLayer with MBart->Blenderbot -class FlaxBlenderbotDecoderLayer(nn.Module): - config: BlenderbotConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxBlenderbotAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - causal=True, - dtype=self.dtype, - ) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.encoder_attn = FlaxBlenderbotAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.fc1 = nn.Dense( - self.config.decoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - hidden_states, self_attn_weights = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - hidden_states = self.encoder_attn_layer_norm(hidden_states) - hidden_states, cross_attn_weights = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights, cross_attn_weights) - - return outputs - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderLayerCollection with Bart->Blenderbot -class FlaxBlenderbotDecoderLayerCollection(nn.Module): - config: BlenderbotConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxBlenderbotDecoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.decoder_layers) - ] - self.layerdrop = self.config.decoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - for decoder_layer in self.layers: - if output_hidden_states: - all_hidden_states += (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): - layer_outputs = (None, None, None) - else: - layer_outputs = decoder_layer( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - deterministic=deterministic, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attns += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = [hidden_states, all_hidden_states, all_self_attns, all_cross_attentions] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - -class FlaxBlenderbotEncoder(nn.Module): - config: BlenderbotConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_source_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(embed_dim) if self.config.scale_embedding else 1.0 - - self.embed_positions = nn.Embed( - self.config.max_position_embeddings, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.layers = FlaxBlenderbotEncoderLayerCollection(self.config, self.dtype) - self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - embed_pos = self.embed_positions(position_ids) - - hidden_states = inputs_embeds + embed_pos - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - last_hidden_states = outputs[0] - last_hidden_states = self.layer_norm(last_hidden_states) - - # update the last element in `hidden_states` after applying `layernorm` above - hidden_states = None - if output_hidden_states: - hidden_states = outputs[1] - hidden_states = hidden_states[:-1] + (last_hidden_states,) - - if not return_dict: - outputs = (last_hidden_states, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=last_hidden_states, - hidden_states=hidden_states, - attentions=outputs.attentions, - ) - - -class FlaxBlenderbotDecoder(nn.Module): - config: BlenderbotConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_target_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(self.config.d_model) if self.config.scale_embedding else 1.0 - - self.embed_positions = nn.Embed( - self.config.max_position_embeddings, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.layers = FlaxBlenderbotDecoderLayerCollection(self.config, self.dtype) - self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - # embed positions - positions = self.embed_positions(position_ids) - - hidden_states = inputs_embeds + positions - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - last_hidden_states = outputs[0] - last_hidden_states = self.layer_norm(last_hidden_states) - - # update the last element in `hidden_states` after applying `layernorm` above - hidden_states = None - if output_hidden_states: - hidden_states = outputs[1] - hidden_states = hidden_states[:-1] + (last_hidden_states,) - - if not return_dict: - outputs = (last_hidden_states, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=last_hidden_states, - hidden_states=hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartModule with Bart->Blenderbot -class FlaxBlenderbotModule(nn.Module): - config: BlenderbotConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - - self.encoder = FlaxBlenderbotEncoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - self.decoder = FlaxBlenderbotDecoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -class FlaxBlenderbotPreTrainedModel(FlaxPreTrainedModel): - config_class = BlenderbotConfig - base_model_prefix: str = "model" - module_class: nn.Module = None - - def __init__( - self, - config: BlenderbotConfig, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - # make sure initialization pass will work for FlaxBlenderbotForSequenceClassificationModule - input_ids = input_ids.at[(..., -1)].set(self.config.eos_token_id) - attention_mask = jnp.ones_like(input_ids) - decoder_input_ids = input_ids - decoder_attention_mask = jnp.ones_like(input_ids) - - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - decoder_position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape - ) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(BLENDERBOT_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=BlenderbotConfig) - def encode( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxBlenderbotForConditionalGeneration - - >>> model = FlaxBlenderbotForConditionalGeneration.from_pretrained("facebook/blenderbot-400M-distill") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot-400M-distill") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, input_ids, attention_mask, position_ids, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(input_ids, attention_mask, position_ids, **kwargs) - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - @add_start_docstrings(BLENDERBOT_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings( - output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=BlenderbotConfig - ) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoTokenizer, FlaxBlenderbotForConditionalGeneration - - >>> model = FlaxBlenderbotForConditionalGeneration.from_pretrained("facebook/blenderbot-400M-distill") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot-400M-distill") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> last_decoder_hidden_states = outputs.last_hidden_state - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxBlenderbotAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - @add_start_docstrings_to_model_forward(BLENDERBOT_INPUTS_DOCSTRING) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_input_ids: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # prepare decoder inputs - if decoder_input_ids is None: - decoder_input_ids = shift_tokens_right( - input_ids, self.config.pad_token_id, decoder_start_token_id=self.config.decoder_start_token_id - ) - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - if decoder_position_ids is None: - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - -@add_start_docstrings( - "The bare MBart Model transformer outputting raw hidden-states without any specific head on top.", - BLENDERBOT_START_DOCSTRING, -) -class FlaxBlenderbotModel(FlaxBlenderbotPreTrainedModel): - config: BlenderbotConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - module_class = FlaxBlenderbotModule - - -append_call_sample_docstring(FlaxBlenderbotModel, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartForConditionalGenerationModule with Bart->Blenderbot -class FlaxBlenderbotForConditionalGenerationModule(nn.Module): - config: BlenderbotConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., jnp.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.model = FlaxBlenderbotModule(config=self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.model.shared.num_embeddings, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.final_logits_bias = self.param("final_logits_bias", self.bias_init, (1, self.model.shared.num_embeddings)) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - position_ids=position_ids, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = self.model.variables["params"]["shared"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - lm_logits += jax.lax.stop_gradient(self.final_logits_bias.astype(self.dtype)) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return output - - return FlaxSeq2SeqLMOutput( - logits=lm_logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings( - "The Blenderbot Model with a language modeling head. Can be used for summarization.", BLENDERBOT_START_DOCSTRING -) -class FlaxBlenderbotForConditionalGeneration(FlaxBlenderbotPreTrainedModel): - module_class = FlaxBlenderbotForConditionalGenerationModule - dtype: jnp.dtype = jnp.float32 - - @add_start_docstrings(BLENDERBOT_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=BlenderbotConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoTokenizer, FlaxBlenderbotForConditionalGeneration - - >>> model = FlaxBlenderbotForConditionalGeneration.from_pretrained("facebook/blenderbot-400M-distill") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot-400M-distill") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxBlenderbotAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - outputs = decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = module.model.variables["params"]["shared"]["embedding"] - lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = module.lm_head(hidden_states) - - lm_logits += module.final_logits_bias - return lm_logits, outputs - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - if past_key_values is None: - lm_logits, decoder_outputs = outputs - else: - (lm_logits, decoder_outputs), past = outputs - - if return_dict: - outputs = FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=decoder_outputs.hidden_states, - attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - ) - else: - outputs = (lm_logits,) + decoder_outputs[1:] - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - position_ids = decoder_attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - "decoder_position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 - return model_kwargs - - -FLAX_BLENDERBOT_CONDITIONAL_GENERATION_DOCSTRING = r""" - Returns: - - Conversation example:: - - ```py - >>> from transformers import AutoTokenizer, FlaxBlenderbotForConditionalGeneration - - >>> model = FlaxBlenderbotForConditionalGeneration.from_pretrained("facebook/blenderbot-400M-distill") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot-400M-distill") - - >>> UTTERANCE = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer([UTTERANCE], max_length=1024, return_tensors="np") - - >>> # Generate Reply - >>> reply_ids = model.generate(inputs["input_ids"], num_beams=4, max_length=5, early_stopping=True).sequences - >>> print([tokenizer.decode(g, skip_special_tokens=True, clean_up_tokenization_spaces=False) for g in reply_ids]) - ``` -""" - -overwrite_call_docstring( - FlaxBlenderbotForConditionalGeneration, - BLENDERBOT_INPUTS_DOCSTRING + FLAX_BLENDERBOT_CONDITIONAL_GENERATION_DOCSTRING, -) -append_replace_return_docstrings( - FlaxBlenderbotForConditionalGeneration, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC -) - - -__all__ = ["FlaxBlenderbotForConditionalGeneration", "FlaxBlenderbotModel", "FlaxBlenderbotPreTrainedModel"] diff --git a/src/transformers/models/blenderbot/modeling_tf_blenderbot.py b/src/transformers/models/blenderbot/modeling_tf_blenderbot.py deleted file mode 100644 index 78f4f6a6761e..000000000000 --- a/src/transformers/models/blenderbot/modeling_tf_blenderbot.py +++ /dev/null @@ -1,1557 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Facebook, Inc and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 Blenderbot model.""" - -from __future__ import annotations - -import os -import random -import warnings - -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPastAndCrossAttentions, - TFSeq2SeqLMOutput, - TFSeq2SeqModelOutput, -) - -# Public API -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFPreTrainedModel, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_end_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_blenderbot import BlenderbotConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/blenderbot-400M-distill" -_CONFIG_FOR_DOC = "BlenderbotConfig" - - -LARGE_NEGATIVE = -1e8 - - -# Copied from transformers.models.bart.modeling_tf_bart.shift_tokens_right -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): - pad_token_id = tf.cast(pad_token_id, input_ids.dtype) - decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) - start_tokens = tf.fill( - (shape_list(input_ids)[0], 1), tf.convert_to_tensor(decoder_start_token_id, input_ids.dtype) - ) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.fill(shape_list(shifted_input_ids), tf.convert_to_tensor(pad_token_id, input_ids.dtype)), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE - mask_cond = tf.range(shape_list(mask)[-1]) - - mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -class TFBlenderbotLearnedPositionalEmbedding(keras.layers.Embedding): - """ - This module learns positional embeddings up to a fixed maximum size. - """ - - def __init__(self, num_embeddings: int, embedding_dim: int, **kwargs): - super().__init__(num_embeddings, embedding_dim, **kwargs) - - def call( - self, input_shape: tf.TensorShape, past_key_values_length: int = 0, position_ids: tf.Tensor | None = None - ): - """Input is expected to be of size [bsz x seqlen].""" - if position_ids is None: - seq_len = input_shape[1] - position_ids = tf.range(seq_len, delta=1, name="range") - position_ids += past_key_values_length - - return super().call(tf.cast(position_ids, dtype=tf.int32)) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with Bart->Blenderbot -class TFBlenderbotAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.mbart.modeling_tf_mbart.TFMBartEncoderLayer with MBart->Blenderbot -class TFBlenderbotEncoderLayer(keras.layers.Layer): - def __init__(self, config: BlenderbotConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFBlenderbotAttention( - self.embed_dim, config.encoder_attention_heads, dropout=config.attention_dropout, name="self_attn" - ) - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - self.fc1 = keras.layers.Dense(config.encoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - layer_head_mask: tf.Tensor, - training: bool | None = False, - ): - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape *(batch, seq_len, embed_dim)* - attention_mask (`tf.Tensor`): attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - *(encoder_attention_heads,)* - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - hidden_states, self_attn_weights, _ = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, layer_head_mask=layer_head_mask - ) - - tf.debugging.assert_equal( - shape_list(hidden_states), - shape_list(residual), - message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", - ) - - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return hidden_states, self_attn_weights - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.encoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.mbart.modeling_tf_mbart.TFMBartDecoderLayer with MBart->Blenderbot -class TFBlenderbotDecoderLayer(keras.layers.Layer): - def __init__(self, config: BlenderbotConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFBlenderbotAttention( - embed_dim=self.embed_dim, - num_heads=config.decoder_attention_heads, - dropout=config.attention_dropout, - name="self_attn", - is_decoder=True, - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.encoder_attn = TFBlenderbotAttention( - self.embed_dim, - config.decoder_attention_heads, - dropout=config.attention_dropout, - name="encoder_attn", - is_decoder=True, - ) - self.encoder_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.decoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - cross_attn_layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tf.Tensor] | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape *(batch, seq_len, embed_dim)* - attention_mask (`tf.Tensor`): attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - encoder_hidden_states (`tf.Tensor`): - cross attention input to the layer of shape *(batch, seq_len, embed_dim)* - encoder_attention_mask (`tf.Tensor`): encoder attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - *(decoder_attention_heads,)* - cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. - *(decoder_attention_heads,)* - past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_present_key_value = None - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - layer_head_mask=cross_attn_layer_head_mask, - past_key_value=cross_attn_past_key_value, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # add cross-attn to positions 3,4 of present_key_value tuple - present_key_value = present_key_value + cross_attn_present_key_value - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return ( - hidden_states, - self_attn_weights, - cross_attn_weights, - present_key_value, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "encoder_attn", None) is not None: - with tf.name_scope(self.encoder_attn.name): - self.encoder_attn.build(None) - if getattr(self, "encoder_attn_layer_norm", None) is not None: - with tf.name_scope(self.encoder_attn_layer_norm.name): - self.encoder_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.decoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFBlenderbotPreTrainedModel(TFPreTrainedModel): - config_class = BlenderbotConfig - base_model_prefix = "model" - - -BLENDERBOT_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`BlenderbotConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -BLENDERBOT_GENERATION_EXAMPLE = r""" - Conversation example:: - - ```py - >>> from transformers import AutoTokenizer, TFBlenderbotForConditionalGeneration - - >>> mname = "facebook/blenderbot-400M-distill" - >>> model = TFBlenderbotForConditionalGeneration.from_pretrained(mname) - >>> tokenizer = AutoTokenizer.from_pretrained(mname) - >>> UTTERANCE = "My friends are cool but they eat too many carbs." - >>> print("Human: ", UTTERANCE) - - >>> inputs = tokenizer([UTTERANCE], return_tensors="tf") - >>> reply_ids = model.generate(**inputs) - >>> print("Bot: ", tokenizer.batch_decode(reply_ids, skip_special_tokens=True)[0]) - - >>> REPLY = "I'm not sure" - >>> print("Human: ", REPLY) - >>> NEXT_UTTERANCE = ( - ... "My friends are cool but they eat too many carbs. That's unfortunate. " - ... "Are they trying to lose weight or are they just trying to be healthier? " - ... " I'm not sure." - ... ) - >>> inputs = tokenizer([NEXT_UTTERANCE], return_tensors="tf") - >>> next_reply_ids = model.generate(**inputs) - >>> print("Bot: ", tokenizer.batch_decode(next_reply_ids, skip_special_tokens=True)[0]) - ``` -""" - -BLENDERBOT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - Blenderbot uses the `bos_token_id` as the starting token for `decoder_input_ids` generation. If - `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - will be made by default and ignore pad tokens. It is not recommended to set this for most use cases. - decoder_position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_outputs (`tf.FloatTensor`, *optional*): - hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - of shape `(batch_size, sequence_length, hidden_size)` is a sequence of - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@keras_serializable -class TFBlenderbotEncoder(keras.layers.Layer): - config_class = BlenderbotConfig - """ - Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a - [`TFBlenderbotEncoderLayer`]. - - Args: - config: BlenderbotConfig - """ - - def __init__(self, config: BlenderbotConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.dropout = keras.layers.Dropout(config.dropout) - self.layerdrop = config.encoder_layerdrop - self.padding_idx = config.pad_token_id - self.max_source_positions = config.max_position_embeddings - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - - self.embed_tokens = embed_tokens - self.embed_positions = TFBlenderbotLearnedPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.layers = [TFBlenderbotEncoderLayer(config, name=f"layers.{i}") for i in range(config.encoder_layers)] - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids=None, - inputs_embeds=None, - attention_mask=None, - head_mask=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - """ - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. This argument can be used only in eager mode, in graph mode the value - in the config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. This argument can be used only in eager mode, in graph mode the value in the config - will be used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - embed_pos = self.embed_positions(input_shape) - hidden_states = inputs_embeds + embed_pos - hidden_states = self.dropout(hidden_states, training=training) - - # check attention mask and invert - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - attention_mask = _expand_mask(attention_mask) - else: - attention_mask = None - - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - # check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - tf.debugging.assert_equal( - shape_list(head_mask)[0], - len(self.layers), - message=( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(head_mask)[0]}." - ), - ) - - # encoder layers - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): # skip the layer - continue - - hidden_states, attn = encoder_layer( - hidden_states, - attention_mask, - head_mask[idx] if head_mask is not None else None, - ) - - if output_attentions: - all_attentions += (attn,) - - hidden_states = self.layer_norm(hidden_states) - - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFBlenderbotDecoder(keras.layers.Layer): - config_class = BlenderbotConfig - """ - Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFBlenderbotDecoderLayer`] - - Args: - config: BlenderbotConfig - embed_tokens: output embedding - """ - - def __init__(self, config: BlenderbotConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.padding_idx = config.pad_token_id - self.embed_tokens = embed_tokens - self.layerdrop = config.decoder_layerdrop - self.embed_positions = TFBlenderbotLearnedPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - self.layers = [TFBlenderbotDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - self.dropout = keras.layers.Dropout(config.dropout) - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids=None, - inputs_embeds=None, - attention_mask=None, - position_ids=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - head_mask=None, - cross_attn_head_mask=None, - past_key_values=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention - of the decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): - Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values - selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers` with each tuple having 2 tuples each of which has 2 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up - decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those - that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of - all `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. This argument can be used only in eager mode, in graph mode the value - in the config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. This argument can be used only in eager mode, in graph mode the value in the config - will be used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - past_key_values_length = shape_list(past_key_values[0][0])[2] if past_key_values is not None else 0 - - # embed positions - if position_ids is None: - positions = self.embed_positions(input_shape, past_key_values_length) - else: - positions = self.embed_positions(input_shape, position_ids=position_ids) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - hidden_states = inputs_embeds - - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - if input_shape[-1] > 1: - combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length=past_key_values_length) - else: - combined_attention_mask = _expand_mask( - tf.ones((input_shape[0], input_shape[1] + past_key_values_length)), tgt_len=input_shape[-1] - ) - - if attention_mask is not None: - combined_attention_mask = combined_attention_mask + _expand_mask(attention_mask, tgt_len=input_shape[-1]) - - if encoder_hidden_states is not None and encoder_attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) - - hidden_states = hidden_states + positions - hidden_states = self.dropout(hidden_states, training=training) - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attns = () if (output_attentions and encoder_hidden_states is not None) else None - present_key_values = () if use_cache else None - - # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired - for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: - if attn_mask is not None: - tf.debugging.assert_equal( - shape_list(attn_mask)[0], - len(self.layers), - message=( - f"The {attn_mask_name} should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(attn_mask)[0]}." - ), - ) - for idx, decoder_layer in enumerate(self.layers): - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - if output_hidden_states: - all_hidden_states += (hidden_states,) - dropout_probability = random.uniform(0, 1) - - if training and (dropout_probability < self.layerdrop): - continue - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( - hidden_states, - attention_mask=combined_attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - cross_attn_layer_head_mask=cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None, - past_key_value=past_key_value, - ) - - if use_cache: - present_key_values += (present_key_value,) - - if output_attentions: - all_self_attns += (layer_self_attn,) - - if encoder_hidden_states is not None: - all_cross_attns += (layer_cross_attn,) - - hidden_states = self.layer_norm(hidden_states) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - if not return_dict: - return hidden_states, present_key_values, all_hidden_states, all_self_attns, all_cross_attns - else: - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=present_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFBlenderbotMainLayer(keras.layers.Layer): - config_class = BlenderbotConfig - - def __init__(self, config: BlenderbotConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.shared = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.d_model, - embeddings_initializer=keras.initializers.TruncatedNormal(stddev=self.config.init_std), - name="model.shared", - ) - # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) - self.shared.load_weight_prefix = "model.shared" - - self.encoder = TFBlenderbotEncoder(config, self.shared, name="encoder") - self.decoder = TFBlenderbotDecoder(config, self.shared, name="decoder") - - def get_input_embeddings(self): - return self.shared - - def set_input_embeddings(self, new_embeddings): - self.shared = new_embeddings - self.encoder.embed_tokens = self.shared - self.decoder.embed_tokens = self.shared - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - decoder_input_ids=None, - decoder_attention_mask=None, - decoder_position_ids=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values=None, - inputs_embeds=None, - decoder_inputs_embeds=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - **kwargs, - ): - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True - elif return_dict and not isinstance(encoder_outputs, TFBaseModelOutput): - encoder_outputs = TFBaseModelOutput( - last_hidden_state=encoder_outputs[0], - hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, - attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, - ) - # If the user passed a TFBaseModelOutput for encoder_outputs, we wrap it in a tuple when return_dict=False - elif not return_dict and not isinstance(encoder_outputs, tuple): - encoder_outputs = encoder_outputs.to_tuple() - - decoder_outputs = self.decoder( - decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return TFSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # The shared/tied weights expect to be in the model base namespace - # Adding "/" to the end (not the start!) of a tf.name_scope puts it in the root namespace rather than - # the current one. - with tf.name_scope(self.shared.load_weight_prefix + "/" + self.shared.name + "/"): - self.shared.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - "The bare BLENDERBOT Model outputting raw hidden-states without any specific head on top.", - BLENDERBOT_START_DOCSTRING, -) -class TFBlenderbotModel(TFBlenderbotPreTrainedModel): - def __init__(self, config: BlenderbotConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.model = TFBlenderbotMainLayer(config, name="model") - - def get_encoder(self): - return self.model.encoder - - def get_decoder(self): - return self.model.decoder - - @classmethod - def from_pretrained(cls, pretrained_model_name_or_path: str | os.PathLike | None, *model_args, **kwargs): - if pretrained_model_name_or_path == "facebook/blenderbot-90M": - from ..blenderbot_small import TFBlenderbotSmallModel - - warnings.warn( - "The checkpoint `facebook/blenderbot-90M` is deprecated. In the future, please use the identical" - " checkpoint `facebook/small_blenderbot-90M` with" - " `TFBlenderbotSmallForConditionalGeneration.from_pretrained('facebook/small_blenderbot-90M')`" - " instead.", - FutureWarning, - ) - return TFBlenderbotSmallModel.from_pretrained(pretrained_model_name_or_path) - - return super().from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs) - - @unpack_inputs - @add_start_docstrings_to_model_forward(BLENDERBOT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSeq2SeqModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: list[tf.Tensor] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ) -> tuple[tf.Tensor] | TFSeq2SeqModelOutput: - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - encoder_outputs=encoder_outputs, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartModel.serving_output - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqModelOutput( - last_hidden_state=output.last_hidden_state, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -# Copied from transformers.models.bart.modeling_tf_bart.BiasLayer -class BiasLayer(keras.layers.Layer): - """ - Bias as a layer. It is used for serialization purposes: `keras.Model.save_weights` stores on a per-layer basis, - so all weights have to be registered in a layer. - """ - - def __init__(self, shape, initializer, trainable, name, **kwargs): - super().__init__(name=name, **kwargs) - # Note: the name of this variable will NOT be scoped when serialized, i.e. it will not be in the format of - # "outer_layer/inner_layer/.../name:0". Instead, it will be "name:0". For further details, see: - # https://github.com/huggingface/transformers/pull/18833#issuecomment-1233090214 - self.bias = self.add_weight(name=name, shape=shape, initializer=initializer, trainable=trainable) - - def call(self, x): - return x + self.bias - - -@add_start_docstrings( - "The BLENDERBOT Model with a language modeling head. Can be used for summarization.", - BLENDERBOT_START_DOCSTRING, -) -class TFBlenderbotForConditionalGeneration(TFBlenderbotPreTrainedModel, TFCausalLanguageModelingLoss): - _keys_to_ignore_on_load_unexpected = [ - r"model.encoder.embed_tokens.weight", - r"model.decoder.embed_tokens.weight", - ] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.model = TFBlenderbotMainLayer(config, name="model") - self.use_cache = config.use_cache - # final_bias_logits is registered as a buffer in pytorch, so not trainable for the sake of consistency. - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, config.vocab_size], initializer="zeros", trainable=False - ) - - def get_decoder(self): - return self.model.decoder - - def get_encoder(self): - return self.model.encoder - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - def get_bias(self): - return {"final_logits_bias": self.bias_layer.bias} - - def set_bias(self, value): - # Replaces the existing layers containing bias for correct (de)serialization. - vocab_size = value["final_logits_bias"].shape[-1] - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, vocab_size], initializer="zeros", trainable=False - ) - self.bias_layer.bias.assign(value["final_logits_bias"]) - - @classmethod - def from_pretrained(cls, pretrained_model_name_or_path: str | os.PathLike | None, *model_args, **kwargs): - if pretrained_model_name_or_path == "facebook/blenderbot-90M": - from ..blenderbot_small import TFBlenderbotSmallForConditionalGeneration - - warnings.warn( - "The checkpoint `facebook/blenderbot-90M` is deprecated. In the future, please use the identical" - " checkpoint `facebook/small_blenderbot-90M` with" - " `TFBlenderbotSmallForConditionalGeneration.from_pretrained('facebook/small_blenderbot-90M')`" - " instead.", - FutureWarning, - ) - return TFBlenderbotSmallForConditionalGeneration.from_pretrained(pretrained_model_name_or_path) - - return super().from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs) - - @unpack_inputs - @add_start_docstrings_to_model_forward(BLENDERBOT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - @add_end_docstrings(BLENDERBOT_GENERATION_EXAMPLE) - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: list[tf.Tensor] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor] | TFSeq2SeqLMOutput: - r""" - labels (`tf.tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., - config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - - Returns: - - """ - if labels is not None: - labels = tf.where( - labels == self.config.pad_token_id, - tf.cast(tf.fill(shape_list(labels), -100), labels.dtype), - labels, - ) - use_cache = False - if decoder_input_ids is None and decoder_inputs_embeds is None: - decoder_input_ids = shift_tokens_right( - labels, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - outputs = self.model( - input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - encoder_outputs=encoder_outputs, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - lm_logits = tf.matmul(outputs[0], self.model.shared.weights, transpose_b=True) - lm_logits = self.bias_layer(lm_logits) - masked_lm_loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return TFSeq2SeqLMOutput( - loss=masked_lm_loss, - logits=lm_logits, - past_key_values=outputs.past_key_values, # index 1 of d outputs - decoder_hidden_states=outputs.decoder_hidden_states, # index 2 of d outputs - decoder_attentions=outputs.decoder_attentions, # index 3 of d outputs - cross_attentions=outputs.cross_attentions, # index 4 of d outputs - encoder_last_hidden_state=outputs.encoder_last_hidden_state, # index 0 of encoder outputs - encoder_hidden_states=outputs.encoder_hidden_states, # 1 of e out - encoder_attentions=outputs.encoder_attentions, # 2 of e out - ) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartForConditionalGeneration.serving_output - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartForConditionalGeneration.prepare_inputs_for_generation - def prepare_inputs_for_generation( - self, - decoder_input_ids, - past_key_values=None, - attention_mask=None, - decoder_attention_mask=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - use_cache=None, - encoder_outputs=None, - **kwargs, - ): - # cut decoder_input_ids if past_key_values is used - if past_key_values is not None: - decoder_input_ids = decoder_input_ids[:, -1:] - - if decoder_attention_mask is not None: # xla - decoder_position_ids = tf.math.cumsum(decoder_attention_mask, axis=-1, exclusive=True)[:, -1:] - elif past_key_values is not None: # no xla + past_key_values - decoder_position_ids = past_key_values[0][0].shape[2] - else: # no xla + no past_key_values - decoder_position_ids = tf.range(decoder_input_ids.shape[1]) - - return { - "input_ids": None, # encoder_outputs is defined. input_ids not needed - "encoder_outputs": encoder_outputs, - "past_key_values": past_key_values, - "decoder_input_ids": decoder_input_ids, - "attention_mask": attention_mask, - "decoder_attention_mask": decoder_attention_mask, - "decoder_position_ids": decoder_position_ids, - "head_mask": head_mask, - "decoder_head_mask": decoder_head_mask, - "cross_attn_head_mask": cross_attn_head_mask, - "use_cache": use_cache, # change this to avoid caching (presumably for debugging) - } - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "bias_layer", None) is not None: - with tf.name_scope(self.bias_layer.name): - self.bias_layer.build(None) - - -__all__ = ["TFBlenderbotForConditionalGeneration", "TFBlenderbotModel", "TFBlenderbotPreTrainedModel"] diff --git a/src/transformers/models/blenderbot_small/__init__.py b/src/transformers/models/blenderbot_small/__init__.py index 075d0070e4c4..7f08df82e757 100644 --- a/src/transformers/models/blenderbot_small/__init__.py +++ b/src/transformers/models/blenderbot_small/__init__.py @@ -20,8 +20,6 @@ if TYPE_CHECKING: from .configuration_blenderbot_small import * from .modeling_blenderbot_small import * - from .modeling_flax_blenderbot_small import * - from .modeling_tf_blenderbot_small import * from .tokenization_blenderbot_small import * from .tokenization_blenderbot_small_fast import * else: diff --git a/src/transformers/models/blenderbot_small/configuration_blenderbot_small.py b/src/transformers/models/blenderbot_small/configuration_blenderbot_small.py index 6d43b975e5ba..6cd7f7275c17 100644 --- a/src/transformers/models/blenderbot_small/configuration_blenderbot_small.py +++ b/src/transformers/models/blenderbot_small/configuration_blenderbot_small.py @@ -16,11 +16,11 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import Any, Optional +from typing import Any from ... import PreTrainedTokenizer from ...configuration_utils import PretrainedConfig -from ...file_utils import TensorType, is_torch_available +from ...file_utils import is_torch_available from ...onnx import OnnxConfig, OnnxConfigWithPast, OnnxSeq2SeqConfigWithPast from ...onnx.utils import compute_effective_axis_dimension from ...utils import logging @@ -164,7 +164,7 @@ def __init__( ) -# Copied from transformers.models.bart.configuration_bart.BartOnnxConfig +# Copied from transformers.models.bart.configuration_bart.BartOnnxConfig with Bart->BlenderbotSmall class BlenderbotSmallOnnxConfig(OnnxSeq2SeqConfigWithPast): @property def inputs(self) -> Mapping[str, Mapping[int, str]]: @@ -229,16 +229,15 @@ def _generate_dummy_inputs_for_default_and_seq2seq_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: encoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) # Generate decoder inputs decoder_seq_length = seq_length if not self.use_past else 1 decoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, decoder_seq_length, is_pair, framework + tokenizer, batch_size, decoder_seq_length, is_pair ) decoder_inputs = {f"decoder_{name}": tensor for name, tensor in decoder_inputs.items()} common_inputs = dict(**encoder_inputs, **decoder_inputs) @@ -297,10 +296,9 @@ def _generate_dummy_inputs_for_causal_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) if self.use_past: @@ -335,7 +333,6 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: # Copied from OnnxConfig.generate_dummy_inputs # Did not use super(OnnxConfigWithPast, self).generate_dummy_inputs for code clarity. @@ -352,7 +349,7 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( # Generate dummy inputs according to compute batch and sequence dummy_input = [" ".join([tokenizer.unk_token]) * seq_length] * batch_size - common_inputs = dict(tokenizer(dummy_input, return_tensors=framework)) + common_inputs = dict(tokenizer(dummy_input, return_tensors="pt")) return common_inputs def generate_dummy_inputs( @@ -361,20 +358,19 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: if self.task in ["default", "seq2seq-lm"]: common_inputs = self._generate_dummy_inputs_for_default_and_seq2seq_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) elif self.task == "causal-lm": common_inputs = self._generate_dummy_inputs_for_causal_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) else: common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) return common_inputs diff --git a/src/transformers/models/blenderbot_small/modeling_flax_blenderbot_small.py b/src/transformers/models/blenderbot_small/modeling_flax_blenderbot_small.py deleted file mode 100644 index ac30320bbdb4..000000000000 --- a/src/transformers/models/blenderbot_small/modeling_flax_blenderbot_small.py +++ /dev/null @@ -1,1528 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Facebook, Inc. and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax BlenderbotSmall model.""" - -import math -import random -from functools import partial -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxSeq2SeqLMOutput, - FlaxSeq2SeqModelOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, logging, replace_return_docstrings -from .configuration_blenderbot_small import BlenderbotSmallConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/blenderbot_small-90M" -_CONFIG_FOR_DOC = "BlenderbotSmallConfig" - -BLENDERBOT_SMALL_START_DOCSTRING = r""" - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`BlenderbotSmallConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -BLENDERBOT_SMALL_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -BLENDERBOT_SMALL_ENCODE_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -BLENDERBOT_SMALL_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.bart.modeling_flax_bart.shift_tokens_right -def shift_tokens_right(input_ids: jnp.ndarray, pad_token_id: int, decoder_start_token_id: int) -> jnp.ndarray: - """ - Shift input ids one token to the right. - """ - shifted_input_ids = jnp.zeros_like(input_ids) - shifted_input_ids = shifted_input_ids.at[:, 1:].set(input_ids[:, :-1]) - shifted_input_ids = shifted_input_ids.at[:, 0].set(decoder_start_token_id) - - shifted_input_ids = jnp.where(shifted_input_ids == -100, pad_token_id, shifted_input_ids) - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention with Bart->BlenderbotSmall -class FlaxBlenderbotSmallAttention(nn.Module): - config: BlenderbotSmallConfig - embed_dim: int - num_heads: int - dropout: float = 0.0 - causal: bool = False - bias: bool = True - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self) -> None: - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {self.num_heads})." - ) - - dense = partial( - nn.Dense, - self.embed_dim, - use_bias=self.bias, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() - self.out_proj = dense() - - self.dropout_layer = nn.Dropout(rate=self.dropout) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states: jnp.ndarray, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.q_proj(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.k_proj(key_value_states) - value_states = self.v_proj(key_value_states) - else: - # self_attention - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartEncoderLayer with Bart->BlenderbotSmall -class FlaxBlenderbotSmallEncoderLayer(nn.Module): - config: BlenderbotSmallConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxBlenderbotSmallAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.encoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - self.fc1 = nn.Dense( - self.config.encoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states, attn_weights = self.self_attn(hidden_states=hidden_states, attention_mask=attention_mask) - - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartEncoderLayerCollection with Bart->BlenderbotSmall -class FlaxBlenderbotSmallEncoderLayerCollection(nn.Module): - config: BlenderbotSmallConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxBlenderbotSmallEncoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.encoder_layers) - ] - self.layerdrop = self.config.encoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for encoder_layer in self.layers: - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): # skip the layer - layer_outputs = (None, None) - else: - layer_outputs = encoder_layer( - hidden_states, - attention_mask, - output_attentions, - deterministic, - ) - hidden_states = layer_outputs[0] - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderLayer with Bart->BlenderbotSmall -class FlaxBlenderbotSmallDecoderLayer(nn.Module): - config: BlenderbotSmallConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxBlenderbotSmallAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - causal=True, - dtype=self.dtype, - ) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.encoder_attn = FlaxBlenderbotSmallAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.fc1 = nn.Dense( - self.config.decoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - - # Self Attention - hidden_states, self_attn_weights = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Cross-Attention Block - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - hidden_states, cross_attn_weights = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # Fully Connected - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights, cross_attn_weights) - - return outputs - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderLayerCollection with Bart->BlenderbotSmall -class FlaxBlenderbotSmallDecoderLayerCollection(nn.Module): - config: BlenderbotSmallConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxBlenderbotSmallDecoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.decoder_layers) - ] - self.layerdrop = self.config.decoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - for decoder_layer in self.layers: - if output_hidden_states: - all_hidden_states += (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): - layer_outputs = (None, None, None) - else: - layer_outputs = decoder_layer( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - deterministic=deterministic, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attns += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = [hidden_states, all_hidden_states, all_self_attns, all_cross_attentions] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - -class FlaxBlenderbotSmallEncoder(nn.Module): - config: BlenderbotSmallConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_source_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(embed_dim) if self.config.scale_embedding else 1.0 - - self.embed_positions = nn.Embed( - self.config.max_position_embeddings, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.layers = FlaxBlenderbotSmallEncoderLayerCollection(self.config, self.dtype) - self.layernorm_embedding = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - embed_pos = self.embed_positions(position_ids) - - hidden_states = inputs_embeds + embed_pos - hidden_states = self.layernorm_embedding(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - if not return_dict: - return outputs - - return FlaxBaseModelOutput( - last_hidden_state=outputs.last_hidden_state, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -class FlaxBlenderbotSmallDecoder(nn.Module): - config: BlenderbotSmallConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_target_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(self.config.d_model) if self.config.scale_embedding else 1.0 - - self.embed_positions = nn.Embed( - self.config.max_position_embeddings, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.layers = FlaxBlenderbotSmallDecoderLayerCollection(self.config, self.dtype) - self.layernorm_embedding = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - # embed positions - positions = self.embed_positions(position_ids) - - # BlenderbotSmall applies layer norm on inputs_embeds in decoder - inputs_embeds = self.layernorm_embedding(inputs_embeds) - hidden_states = inputs_embeds + positions - - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - if not return_dict: - return outputs - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=outputs.last_hidden_state, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartModule with Bart->BlenderbotSmall -class FlaxBlenderbotSmallModule(nn.Module): - config: BlenderbotSmallConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - - self.encoder = FlaxBlenderbotSmallEncoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - self.decoder = FlaxBlenderbotSmallDecoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -class FlaxBlenderbotSmallPreTrainedModel(FlaxPreTrainedModel): - config_class = BlenderbotSmallConfig - base_model_prefix: str = "model" - module_class: nn.Module = None - - def __init__( - self, - config: BlenderbotSmallConfig, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - # make sure initialization pass will work for FlaxBlenderbotSmallForSequenceClassificationModule - input_ids = input_ids.at[(..., -1)].set(self.config.eos_token_id) - attention_mask = jnp.ones_like(input_ids) - decoder_input_ids = input_ids - decoder_attention_mask = jnp.ones_like(input_ids) - - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - decoder_position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape - ) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(BLENDERBOT_SMALL_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=BlenderbotSmallConfig) - def encode( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxBlenderbotSmallForConditionalGeneration - - >>> model = FlaxBlenderbotSmallForConditionalGeneration.from_pretrained("facebook/blenderbot_small-90M") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot_small-90M") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, input_ids, attention_mask, position_ids, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(input_ids, attention_mask, position_ids, **kwargs) - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - @add_start_docstrings(BLENDERBOT_SMALL_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings( - output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=BlenderbotSmallConfig - ) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoTokenizer, FlaxBlenderbotSmallForConditionalGeneration - - >>> model = FlaxBlenderbotSmallForConditionalGeneration.from_pretrained("facebook/blenderbot_small-90M") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot_small-90M") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> last_decoder_hidden_states = outputs.last_hidden_state - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxBlenderbotSmallAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_input_ids: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # prepare decoder inputs - if decoder_input_ids is None: - decoder_input_ids = shift_tokens_right( - input_ids, self.config.pad_token_id, decoder_start_token_id=self.config.decoder_start_token_id - ) - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - if decoder_position_ids is None: - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - -@add_start_docstrings( - "The bare BlenderbotSmall Model transformer outputting raw hidden-states without any specific head on top.", - BLENDERBOT_SMALL_START_DOCSTRING, -) -class FlaxBlenderbotSmallModel(FlaxBlenderbotSmallPreTrainedModel): - config: BlenderbotSmallConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - module_class = FlaxBlenderbotSmallModule - - -append_call_sample_docstring(FlaxBlenderbotSmallModel, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartForConditionalGenerationModule with Bart->BlenderbotSmall -class FlaxBlenderbotSmallForConditionalGenerationModule(nn.Module): - config: BlenderbotSmallConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., jnp.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.model = FlaxBlenderbotSmallModule(config=self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.model.shared.num_embeddings, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.final_logits_bias = self.param("final_logits_bias", self.bias_init, (1, self.model.shared.num_embeddings)) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - position_ids=position_ids, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = self.model.variables["params"]["shared"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - lm_logits += jax.lax.stop_gradient(self.final_logits_bias.astype(self.dtype)) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return output - - return FlaxSeq2SeqLMOutput( - logits=lm_logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings( - "The BLENDERBOT_SMALL Model with a language modeling head. Can be used for summarization.", - BLENDERBOT_SMALL_START_DOCSTRING, -) -class FlaxBlenderbotSmallForConditionalGeneration(FlaxBlenderbotSmallPreTrainedModel): - module_class = FlaxBlenderbotSmallForConditionalGenerationModule - dtype: jnp.dtype = jnp.float32 - - @add_start_docstrings(BLENDERBOT_SMALL_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=BlenderbotSmallConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - deterministic: bool = True, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoTokenizer, FlaxBlenderbotSmallForConditionalGeneration - - >>> model = FlaxBlenderbotSmallForConditionalGeneration.from_pretrained("facebook/blenderbot_small-90M") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot_small-90M") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxBlenderbotSmallAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - outputs = decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = module.model.variables["params"]["shared"]["embedding"] - lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = module.lm_head(hidden_states) - - lm_logits += module.final_logits_bias.astype(self.dtype) - return lm_logits, outputs - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - if past_key_values is None: - lm_logits, decoder_outputs = outputs - else: - (lm_logits, decoder_outputs), past = outputs - - if return_dict: - outputs = FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=decoder_outputs.hidden_states, - attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - ) - else: - outputs = (lm_logits,) + decoder_outputs[1:] - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - position_ids = decoder_attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - "decoder_position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 - return model_kwargs - - -FLAX_BLENDERBOT_SMALL_CONDITIONAL_GENERATION_DOCSTRING = """ - Returns: - - Summarization example: - - ```py - >>> from transformers import AutoTokenizer, FlaxBlenderbotSmallForConditionalGeneration - - >>> model = FlaxBlenderbotSmallForConditionalGeneration.from_pretrained("facebook/blenderbot_small-90M") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot_small-90M") - - >>> ARTICLE_TO_SUMMARIZE = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], max_length=1024, return_tensors="np") - - >>> # Generate Summary - >>> summary_ids = model.generate(inputs["input_ids"]).sequences - >>> print(tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)) - ``` - - Mask filling example: - - ```py - >>> from transformers import AutoTokenizer, FlaxBlenderbotSmallForConditionalGeneration - - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot_small-90M") - >>> TXT = "My friends are but they eat too many carbs." - - >>> model = FlaxBlenderbotSmallForConditionalGeneration.from_pretrained("facebook/blenderbot_small-90M") - >>> input_ids = tokenizer([TXT], return_tensors="np")["input_ids"] - >>> logits = model(input_ids).logits - - >>> masked_index = (input_ids[0] == tokenizer.mask_token_id).nonzero().item() - >>> probs = jax.nn.softmax(logits[0, masked_index], axis=0) - >>> values, predictions = jax.lax.top_k(probs) - - >>> tokenizer.decode(predictions).split() - ``` -""" - -overwrite_call_docstring( - FlaxBlenderbotSmallForConditionalGeneration, - BLENDERBOT_SMALL_INPUTS_DOCSTRING + FLAX_BLENDERBOT_SMALL_CONDITIONAL_GENERATION_DOCSTRING, -) -append_replace_return_docstrings( - FlaxBlenderbotSmallForConditionalGeneration, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC -) - - -__all__ = [ - "FlaxBlenderbotSmallForConditionalGeneration", - "FlaxBlenderbotSmallModel", - "FlaxBlenderbotSmallPreTrainedModel", -] diff --git a/src/transformers/models/blenderbot_small/modeling_tf_blenderbot_small.py b/src/transformers/models/blenderbot_small/modeling_tf_blenderbot_small.py deleted file mode 100644 index be7711801ed2..000000000000 --- a/src/transformers/models/blenderbot_small/modeling_tf_blenderbot_small.py +++ /dev/null @@ -1,1527 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Facebook, Inc and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 BlenderbotSmall model.""" - -from __future__ import annotations - -import random - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPastAndCrossAttentions, - TFSeq2SeqLMOutput, - TFSeq2SeqModelOutput, -) - -# Public API -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFPreTrainedModel, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_end_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_blenderbot_small import BlenderbotSmallConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/blenderbot_small-90M" -_CONFIG_FOR_DOC = "BlenderbotSmallConfig" - - -LARGE_NEGATIVE = -1e8 - - -# Copied from transformers.models.bart.modeling_tf_bart.shift_tokens_right -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): - pad_token_id = tf.cast(pad_token_id, input_ids.dtype) - decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) - start_tokens = tf.fill( - (shape_list(input_ids)[0], 1), tf.convert_to_tensor(decoder_start_token_id, input_ids.dtype) - ) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.fill(shape_list(shifted_input_ids), tf.convert_to_tensor(pad_token_id, input_ids.dtype)), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE - mask_cond = tf.range(shape_list(mask)[-1]) - - mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -# Copied from transformers.models.blenderbot.modeling_tf_blenderbot.TFBlenderbotLearnedPositionalEmbedding with Blenderbot->BlenderbotSmall -class TFBlenderbotSmallLearnedPositionalEmbedding(keras.layers.Embedding): - """ - This module learns positional embeddings up to a fixed maximum size. - """ - - def __init__(self, num_embeddings: int, embedding_dim: int, **kwargs): - super().__init__(num_embeddings, embedding_dim, **kwargs) - - def call( - self, input_shape: tf.TensorShape, past_key_values_length: int = 0, position_ids: tf.Tensor | None = None - ): - """Input is expected to be of size [bsz x seqlen].""" - if position_ids is None: - seq_len = input_shape[1] - position_ids = tf.range(seq_len, delta=1, name="range") - position_ids += past_key_values_length - - return super().call(tf.cast(position_ids, dtype=tf.int32)) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with Bart->BlenderbotSmall -class TFBlenderbotSmallAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartEncoderLayer with Bart->BlenderbotSmall -class TFBlenderbotSmallEncoderLayer(keras.layers.Layer): - def __init__(self, config: BlenderbotSmallConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFBlenderbotSmallAttention( - self.embed_dim, config.encoder_attention_heads, dropout=config.attention_dropout, name="self_attn" - ) - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - self.fc1 = keras.layers.Dense(config.encoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: np.ndarray | tf.Tensor | None, - layer_head_mask: tf.Tensor | None, - training: bool | None = False, - ) -> tf.Tensor: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - `(encoder_attention_heads,)` - """ - residual = hidden_states - hidden_states, self_attn_weights, _ = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, layer_head_mask=layer_head_mask - ) - - tf.debugging.assert_equal( - shape_list(hidden_states), - shape_list(residual), - message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", - ) - - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - return hidden_states, self_attn_weights - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.encoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartDecoderLayer with Bart->BlenderbotSmall -class TFBlenderbotSmallDecoderLayer(keras.layers.Layer): - def __init__(self, config: BlenderbotSmallConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFBlenderbotSmallAttention( - embed_dim=self.embed_dim, - num_heads=config.decoder_attention_heads, - dropout=config.attention_dropout, - name="self_attn", - is_decoder=True, - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.encoder_attn = TFBlenderbotSmallAttention( - self.embed_dim, - config.decoder_attention_heads, - dropout=config.attention_dropout, - name="encoder_attn", - is_decoder=True, - ) - self.encoder_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.decoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - cross_attn_layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - encoder_hidden_states (`tf.Tensor`): - cross attention input to the layer of shape `(batch, seq_len, embed_dim)` - encoder_attention_mask (`tf.Tensor`): encoder attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - `(decoder_attention_heads,)` - cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. - `(decoder_attention_heads,)` - past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states - """ - residual = hidden_states - - # Self Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Cross-Attention Block - cross_attn_present_key_value = None - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - layer_head_mask=cross_attn_layer_head_mask, - past_key_value=cross_attn_past_key_value, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # add cross-attn to positions 3,4 of present_key_value tuple - present_key_value = present_key_value + cross_attn_present_key_value - - # Fully Connected - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - return ( - hidden_states, - self_attn_weights, - cross_attn_weights, - present_key_value, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "encoder_attn", None) is not None: - with tf.name_scope(self.encoder_attn.name): - self.encoder_attn.build(None) - if getattr(self, "encoder_attn_layer_norm", None) is not None: - with tf.name_scope(self.encoder_attn_layer_norm.name): - self.encoder_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.decoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFBlenderbotSmallPreTrainedModel(TFPreTrainedModel): - config_class = BlenderbotSmallConfig - base_model_prefix = "model" - - -BLENDERBOT_SMALL_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`BlenderbotSmallConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -BLENDERBOT_SMALL_GENERATION_EXAMPLE = r""" - Conversation example:: - - ```py - >>> from transformers import AutoTokenizer, TFBlenderbotSmallForConditionalGeneration - - >>> mname = "facebook/blenderbot_small-90M" - >>> model = BlenderbotSmallForConditionalGeneration.from_pretrained(mname) - >>> tokenizer = AutoTokenizer.from_pretrained(mname) - - >>> UTTERANCE = "My friends are cool but they eat too many carbs." - >>> print("Human: ", UTTERANCE) - >>> inputs = tokenizer([UTTERANCE], return_tensors="tf") - - >>> reply_ids = model.generate(**inputs) - >>> print("Bot: ", tokenizer.batch_decode(reply_ids, skip_special_tokens=True)[0]) - what kind of carbs do they eat? i don't know much about carbs. - - >>> REPLY = "I'm not sure" - >>> print("Human: ", REPLY) - >>> NEXT_UTTERANCE = ( - ... "My friends are cool but they eat too many carbs. " - ... "what kind of carbs do they eat? i don't know much about carbs. " - ... "I'm not sure." - ... ) - - >>> inputs = tokenizer([NEXT_UTTERANCE], return_tensors="tf") - >>> inputs.pop("token_type_ids") - >>> next_reply_ids = model.generate(**inputs) - >>> print("Bot: ", tokenizer.batch_decode(next_reply_ids, skip_special_tokens=True)[0]) - ``` -""" - -BLENDERBOT_SMALL_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - BlenderbotSmall uses the `bos_token_id` as the starting token for `decoder_input_ids` generation. If - `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - will be made by default and ignore pad tokens. It is not recommended to set this for most use cases. - decoder_position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_outputs (`tf.FloatTensor`, *optional*): - hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - of shape `(batch_size, sequence_length, hidden_size)` is a sequence of - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@keras_serializable -class TFBlenderbotSmallEncoder(keras.layers.Layer): - config_class = BlenderbotSmallConfig - """ - Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a - [`TFBlenderbotSmallEncoderLayer`]. - - Args: - config: BlenderbotSmallConfig - """ - - def __init__(self, config: BlenderbotSmallConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.dropout = keras.layers.Dropout(config.dropout) - self.layerdrop = config.encoder_layerdrop - self.padding_idx = config.pad_token_id - self.max_source_positions = config.max_position_embeddings - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - - self.embed_tokens = embed_tokens - self.embed_positions = TFBlenderbotSmallLearnedPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.layers = [TFBlenderbotSmallEncoderLayer(config, name=f"layers.{i}") for i in range(config.encoder_layers)] - self.layernorm_embedding = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_embedding") - self.embed_dim = config.d_model - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids=None, - inputs_embeds=None, - attention_mask=None, - head_mask=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - """ - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. This argument can be used only in eager mode, in graph mode the value - in the config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. This argument can be used only in eager mode, in graph mode the value in the config - will be used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - embed_pos = self.embed_positions(input_shape) - hidden_states = inputs_embeds + embed_pos - hidden_states = self.layernorm_embedding(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - - # check attention mask and invert - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - attention_mask = _expand_mask(attention_mask) - else: - attention_mask = None - - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - # check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - tf.debugging.assert_equal( - shape_list(head_mask)[0], - len(self.layers), - message=( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(head_mask)[0]}." - ), - ) - - # encoder layers - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): # skip the layer - continue - - hidden_states, attn = encoder_layer( - hidden_states, - attention_mask, - head_mask[idx] if head_mask is not None else None, - ) - - if output_attentions: - all_attentions += (attn,) - - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layernorm_embedding", None) is not None: - with tf.name_scope(self.layernorm_embedding.name): - self.layernorm_embedding.build([None, None, self.embed_dim]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFBlenderbotSmallDecoder(keras.layers.Layer): - config_class = BlenderbotSmallConfig - """ - Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFBlenderbotSmallDecoderLayer`] - - Args: - config: BlenderbotSmallConfig - embed_tokens: output embedding - """ - - def __init__(self, config: BlenderbotSmallConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.padding_idx = config.pad_token_id - self.embed_tokens = embed_tokens - self.layerdrop = config.decoder_layerdrop - self.embed_positions = TFBlenderbotSmallLearnedPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - self.layers = [TFBlenderbotSmallDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] - self.layernorm_embedding = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_embedding") - - self.dropout = keras.layers.Dropout(config.dropout) - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids=None, - inputs_embeds=None, - attention_mask=None, - position_ids=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - head_mask=None, - cross_attn_head_mask=None, - past_key_values=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention - of the decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): - Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values - selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers` with each tuple having 2 tuples each of which has 2 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up - decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those - that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of - all `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. This argument can be used only in eager mode, in graph mode the value - in the config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. This argument can be used only in eager mode, in graph mode the value in the config - will be used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - past_key_values_length = shape_list(past_key_values[0][0])[2] if past_key_values is not None else 0 - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - if input_shape[-1] > 1: - combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length=past_key_values_length) - else: - combined_attention_mask = _expand_mask( - tf.ones((input_shape[0], input_shape[1] + past_key_values_length)), tgt_len=input_shape[-1] - ) - - if attention_mask is not None: - combined_attention_mask = combined_attention_mask + _expand_mask(attention_mask, tgt_len=input_shape[-1]) - - if encoder_hidden_states is not None and encoder_attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) - - # embed positions - if position_ids is None: - positions = self.embed_positions(input_shape, past_key_values_length) - else: - positions = self.embed_positions(input_shape, position_ids=position_ids) - - hidden_states = self.layernorm_embedding(inputs_embeds) + positions - hidden_states = self.dropout(hidden_states, training=training) - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attns = () if (output_attentions and encoder_hidden_states is not None) else None - present_key_values = () if use_cache else None - - # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired - for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: - if attn_mask is not None: - tf.debugging.assert_equal( - shape_list(attn_mask)[0], - len(self.layers), - message=( - f"The {attn_mask_name} should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(attn_mask)[0]}." - ), - ) - - for idx, decoder_layer in enumerate(self.layers): - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - if output_hidden_states: - all_hidden_states += (hidden_states,) - dropout_probability = random.uniform(0, 1) - - if training and (dropout_probability < self.layerdrop): - continue - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( - hidden_states, - attention_mask=combined_attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - cross_attn_layer_head_mask=cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None, - past_key_value=past_key_value, - ) - - if use_cache: - present_key_values += (present_key_value,) - - if output_attentions: - all_self_attns += (layer_self_attn,) - - if encoder_hidden_states is not None: - all_cross_attns += (layer_cross_attn,) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - if not return_dict: - return hidden_states, present_key_values, all_hidden_states, all_self_attns, all_cross_attns - else: - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=present_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layernorm_embedding", None) is not None: - with tf.name_scope(self.layernorm_embedding.name): - self.layernorm_embedding.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFBlenderbotSmallMainLayer(keras.layers.Layer): - config_class = BlenderbotSmallConfig - - def __init__(self, config: BlenderbotSmallConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.shared = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.d_model, - embeddings_initializer=keras.initializers.TruncatedNormal(stddev=self.config.init_std), - name="model.shared", - ) - # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) - self.shared.load_weight_prefix = "model.shared" - - self.encoder = TFBlenderbotSmallEncoder(config, self.shared, name="encoder") - self.decoder = TFBlenderbotSmallDecoder(config, self.shared, name="decoder") - - def get_input_embeddings(self): - return self.shared - - def set_input_embeddings(self, new_embeddings): - self.shared = new_embeddings - self.encoder.embed_tokens = self.shared - self.decoder.embed_tokens = self.shared - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - decoder_input_ids=None, - decoder_attention_mask=None, - decoder_position_ids=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values=None, - inputs_embeds=None, - decoder_inputs_embeds=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - **kwargs, - ): - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True - elif return_dict and not isinstance(encoder_outputs, TFBaseModelOutput): - encoder_outputs = TFBaseModelOutput( - last_hidden_state=encoder_outputs[0], - hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, - attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, - ) - # If the user passed a TFBaseModelOutput for encoder_outputs, we wrap it in a tuple when return_dict=False - elif not return_dict and not isinstance(encoder_outputs, tuple): - encoder_outputs = encoder_outputs.to_tuple() - - decoder_outputs = self.decoder( - decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return TFSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # The shared/tied weights expect to be in the model base namespace - # Adding "/" to the end (not the start!) of a tf.name_scope puts it in the root namespace rather than - # the current one. - with tf.name_scope(self.shared.load_weight_prefix + "/" + self.shared.name + "/"): - self.shared.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - "The bare BLENDERBOT_SMALL Model outputting raw hidden-states without any specific head on top.", - BLENDERBOT_SMALL_START_DOCSTRING, -) -class TFBlenderbotSmallModel(TFBlenderbotSmallPreTrainedModel): - def __init__(self, config: BlenderbotSmallConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.model = TFBlenderbotSmallMainLayer(config, name="model") - - def get_encoder(self): - return self.model.encoder - - def get_decoder(self): - return self.model.decoder - - @unpack_inputs - @add_start_docstrings_to_model_forward(BLENDERBOT_SMALL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSeq2SeqModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: list[tf.Tensor] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ) -> tuple[tf.Tensor] | TFSeq2SeqModelOutput: - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - encoder_outputs=encoder_outputs, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartModel.serving_output - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqModelOutput( - last_hidden_state=output.last_hidden_state, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -# Copied from transformers.models.bart.modeling_tf_bart.BiasLayer -class BiasLayer(keras.layers.Layer): - """ - Bias as a layer. It is used for serialization purposes: `keras.Model.save_weights` stores on a per-layer basis, - so all weights have to be registered in a layer. - """ - - def __init__(self, shape, initializer, trainable, name, **kwargs): - super().__init__(name=name, **kwargs) - # Note: the name of this variable will NOT be scoped when serialized, i.e. it will not be in the format of - # "outer_layer/inner_layer/.../name:0". Instead, it will be "name:0". For further details, see: - # https://github.com/huggingface/transformers/pull/18833#issuecomment-1233090214 - self.bias = self.add_weight(name=name, shape=shape, initializer=initializer, trainable=trainable) - - def call(self, x): - return x + self.bias - - -@add_start_docstrings( - "The BLENDERBOT_SMALL Model with a language modeling head. Can be used for summarization.", - BLENDERBOT_SMALL_START_DOCSTRING, -) -class TFBlenderbotSmallForConditionalGeneration(TFBlenderbotSmallPreTrainedModel, TFCausalLanguageModelingLoss): - _keys_to_ignore_on_load_unexpected = [ - r"model.encoder.embed_tokens.weight", - r"model.decoder.embed_tokens.weight", - ] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.model = TFBlenderbotSmallMainLayer(config, name="model") - self.use_cache = config.use_cache - # final_bias_logits is registered as a buffer in pytorch, so not trainable for the sake of consistency. - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, config.vocab_size], initializer="zeros", trainable=False - ) - - def get_decoder(self): - return self.model.decoder - - def get_encoder(self): - return self.model.encoder - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - def get_bias(self): - return {"final_logits_bias": self.bias_layer.bias} - - def set_bias(self, value): - # Replaces the existing layers containing bias for correct (de)serialization. - vocab_size = value["final_logits_bias"].shape[-1] - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, vocab_size], initializer="zeros", trainable=False - ) - self.bias_layer.bias.assign(value["final_logits_bias"]) - - @unpack_inputs - @add_start_docstrings_to_model_forward(BLENDERBOT_SMALL_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - @add_end_docstrings(BLENDERBOT_SMALL_GENERATION_EXAMPLE) - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: TFBaseModelOutput | None = None, - past_key_values: list[tf.Tensor] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor] | TFSeq2SeqLMOutput: - r""" - labels (`tf.tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., - config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - - Returns: - - """ - - if labels is not None: - labels = tf.where( - labels == self.config.pad_token_id, - tf.cast(tf.fill(shape_list(labels), -100), labels.dtype), - labels, - ) - use_cache = False - if decoder_input_ids is None and decoder_inputs_embeds is None: - decoder_input_ids = shift_tokens_right( - labels, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - outputs = self.model( - input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - encoder_outputs=encoder_outputs, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - lm_logits = tf.matmul(outputs[0], self.model.shared.weights, transpose_b=True) - lm_logits = self.bias_layer(lm_logits) - masked_lm_loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return TFSeq2SeqLMOutput( - loss=masked_lm_loss, - logits=lm_logits, - past_key_values=outputs.past_key_values, # index 1 of d outputs - decoder_hidden_states=outputs.decoder_hidden_states, # index 2 of d outputs - decoder_attentions=outputs.decoder_attentions, # index 3 of d outputs - cross_attentions=outputs.cross_attentions, # index 4 of d outputs - encoder_last_hidden_state=outputs.encoder_last_hidden_state, # index 0 of encoder outputs - encoder_hidden_states=outputs.encoder_hidden_states, # 1 of e out - encoder_attentions=outputs.encoder_attentions, # 2 of e out - ) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartForConditionalGeneration.serving_output - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartForConditionalGeneration.prepare_inputs_for_generation - def prepare_inputs_for_generation( - self, - decoder_input_ids, - past_key_values=None, - attention_mask=None, - decoder_attention_mask=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - use_cache=None, - encoder_outputs=None, - **kwargs, - ): - # cut decoder_input_ids if past_key_values is used - if past_key_values is not None: - decoder_input_ids = decoder_input_ids[:, -1:] - - if decoder_attention_mask is not None: # xla - decoder_position_ids = tf.math.cumsum(decoder_attention_mask, axis=-1, exclusive=True)[:, -1:] - elif past_key_values is not None: # no xla + past_key_values - decoder_position_ids = past_key_values[0][0].shape[2] - else: # no xla + no past_key_values - decoder_position_ids = tf.range(decoder_input_ids.shape[1]) - - return { - "input_ids": None, # encoder_outputs is defined. input_ids not needed - "encoder_outputs": encoder_outputs, - "past_key_values": past_key_values, - "decoder_input_ids": decoder_input_ids, - "attention_mask": attention_mask, - "decoder_attention_mask": decoder_attention_mask, - "decoder_position_ids": decoder_position_ids, - "head_mask": head_mask, - "decoder_head_mask": decoder_head_mask, - "cross_attn_head_mask": cross_attn_head_mask, - "use_cache": use_cache, # change this to avoid caching (presumably for debugging) - } - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "bias_layer", None) is not None: - with tf.name_scope(self.bias_layer.name): - self.bias_layer.build(None) - - -__all__ = ["TFBlenderbotSmallForConditionalGeneration", "TFBlenderbotSmallModel", "TFBlenderbotSmallPreTrainedModel"] diff --git a/src/transformers/models/blip/__init__.py b/src/transformers/models/blip/__init__.py index 952de2f855a7..c16593d7ce17 100644 --- a/src/transformers/models/blip/__init__.py +++ b/src/transformers/models/blip/__init__.py @@ -23,8 +23,6 @@ from .image_processing_blip_fast import * from .modeling_blip import * from .modeling_blip_text import * - from .modeling_tf_blip import * - from .modeling_tf_blip_text import * from .processing_blip import * else: import sys diff --git a/src/transformers/models/blip/image_processing_blip.py b/src/transformers/models/blip/image_processing_blip.py index 78a152374fd0..0efc3c5d1eb3 100644 --- a/src/transformers/models/blip/image_processing_blip.py +++ b/src/transformers/models/blip/image_processing_blip.py @@ -204,10 +204,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -235,10 +233,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/blip/modeling_blip_text.py b/src/transformers/models/blip/modeling_blip_text.py index 6f1f58c75334..99026a2b4fd0 100644 --- a/src/transformers/models/blip/modeling_blip_text.py +++ b/src/transformers/models/blip/modeling_blip_text.py @@ -49,8 +49,6 @@ def __init__(self, config): self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -581,8 +579,6 @@ class BlipTextPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Embedding)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) elif isinstance(module, nn.LayerNorm): module.bias.data.zero_() diff --git a/src/transformers/models/blip/modeling_tf_blip.py b/src/transformers/models/blip/modeling_tf_blip.py deleted file mode 100644 index a1a1f7928273..000000000000 --- a/src/transformers/models/blip/modeling_tf_blip.py +++ /dev/null @@ -1,1709 +0,0 @@ -# coding=utf-8 -# Copyright 2023 The Salesforce Team Authors and The HuggingFace Team. All rights reserved. -# -# 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. -"""TensorFlow BLIP model.""" - -from __future__ import annotations - -import warnings -from dataclasses import dataclass -from typing import Any - -import tensorflow as tf - -from ...modeling_tf_outputs import TFBaseModelOutput, TFBaseModelOutputWithPooling -from ...modeling_tf_utils import ( - TFPreTrainedModel, - get_initializer, - get_tf_activation, - keras, - keras_serializable, - shape_list, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, stable_softmax -from ...utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_blip import BlipConfig, BlipTextConfig, BlipVisionConfig -from .modeling_tf_blip_text import BLIP_TEXT_INPUTS_DOCSTRING, TFBlipTextLMHeadModel, TFBlipTextModel - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "Salesforce/blip-vqa-base" - - -# Copied from transformers.models.clip.modeling_tf_clip.contrastive_loss -def contrastive_loss(logits: tf.Tensor) -> tf.Tensor: - return tf.math.reduce_mean( - keras.metrics.sparse_categorical_crossentropy( - y_true=tf.range(shape_list(logits)[0]), y_pred=logits, from_logits=True - ) - ) - - -# Copied from transformers.models.clip.modeling_tf_clip.clip_loss with clip->blip -def blip_loss(similarity: tf.Tensor) -> tf.Tensor: - caption_loss = contrastive_loss(similarity) - image_loss = contrastive_loss(tf.transpose(similarity)) - return (caption_loss + image_loss) / 2.0 - - -@dataclass -class TFBlipForConditionalGenerationModelOutput(ModelOutput): - """ - Adapted from the base class for vision model's outputs that also contains image embeddings of the pooling of the - last hidden states. This class also adds the loss term from the text decoder. - - Args: - loss (`tf.Tensor`, *optional*, returned when `labels` is provided, `tf.Tensor` of shape `(1,)`): - Language modeling loss from the text decoder. - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`, *optional*): - Prediction scores of the language modeling head of the text decoder model. - image_embeds (`tf.Tensor` of shape `(batch_size, output_dim)`, *optional*): - The image embeddings obtained after applying the Vision Transformer model to the input image. - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads.` - """ - - loss: tuple[tf.Tensor] | None = None - logits: tuple[tf.Tensor] | None = None - image_embeds: tf.Tensor | None = None - last_hidden_state: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - @property - def decoder_logits(self): - warnings.warn( - "`decoder_logits` attribute is deprecated and will be removed in version 5 of Transformers." - " Please use the `logits` attribute to retrieve the final output instead.", - FutureWarning, - ) - return self.logits - - -@dataclass -class TFBlipTextVisionModelOutput(ModelOutput): - """ - Adapted from the base class for vision model's outputs that also contains image embeddings of the pooling of the - last hidden states. This class also adds the loss term from the text decoder. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Language modeling loss from the text decoder. - image_embeds (`tf.Tensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`): - The image embeddings obtained by applying the projection layer to the pooler_output. - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - image_embeds: tf.Tensor | None = None - last_hidden_state: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFBlipImageTextMatchingModelOutput(ModelOutput): - """ - Adapted from the base class for vision model's outputs that also contains image embeddings of the pooling of the - last hidden states. This class also adds the loss term from the text decoder as well as the image-text similarity - scores. - - Args: - itm_score (`tf.Tensor`): - The image-text similarity scores. - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Language modeling loss from the text decoder. - image_embeds (`tf.Tensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`): - The image embeddings obtained by applying the projection layer to the pooler_output. - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - vision_pooler_output (`tf.Tensor` of shape `(batch_size, hidden_size)`, *optional*): - Last layer hidden-state of the vision of the vision-only branch of the model. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - question_embeds (`tf.Tensor`): - The question embeddings obtained by the text projection layer. - """ - - itm_score: tf.Tensor | None = None - loss: tf.Tensor | None = None - image_embeds: tf.Tensor | None = None - last_hidden_state: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - vision_pooler_output: tf.Tensor | None = None - attentions: tuple[tf.Tensor, ...] | None = None - question_embeds: tuple[tf.Tensor] | None = None - - -@dataclass -class TFBlipOutput(ModelOutput): - """ - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `return_loss` is `True`): - Contrastive loss for image-text similarity. - logits_per_image:(`tf.Tensor` of shape `(image_batch_size, text_batch_size)`): - The scaled dot product scores between `image_embeds` and `text_embeds`. This represents the image-text - similarity scores. - logits_per_text:(`tf.Tensor` of shape `(text_batch_size, image_batch_size)`): - The scaled dot product scores between `text_embeds` and `image_embeds`. This represents the text-image - similarity scores. - text_embeds(`tf.Tensor` of shape `(batch_size, output_dim`): - The text embeddings obtained by applying the projection layer to the pooled output of [`BlipTextModel`]. - image_embeds(`tf.Tensor` of shape `(batch_size, output_dim`): - The image embeddings obtained by applying the projection layer to the pooled output of [`BlipVisionModel`]. - text_model_output(`BaseModelOutputWithPooling`): - The output of the [`BlipTextModel`]. - vision_model_output(`BaseModelOutputWithPooling`): - The output of the [`BlipVisionModel`]. - """ - - loss: tf.Tensor | None = None - logits_per_image: tf.Tensor | None = None - logits_per_text: tf.Tensor | None = None - text_embeds: tf.Tensor | None = None - image_embeds: tf.Tensor | None = None - text_model_output: TFBaseModelOutputWithPooling = None - vision_model_output: TFBaseModelOutputWithPooling = None - - def to_tuple(self) -> tuple[Any]: - return tuple( - self[k] if k not in ["text_model_output", "vision_model_output"] else getattr(self, k).to_tuple() - for k in self.keys() - ) - - -class TFBlipVisionEmbeddings(keras.layers.Layer): - def __init__(self, config: BlipVisionConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.embed_dim = config.hidden_size - self.image_size = config.image_size - self.patch_size = config.patch_size - - self.patch_embedding = keras.layers.Conv2D( - filters=self.embed_dim, - kernel_size=self.patch_size, - strides=self.patch_size, - kernel_initializer=get_initializer(self.config.initializer_range), - data_format="channels_last", - name="patch_embedding", - ) - - self.num_patches = (self.image_size // self.patch_size) ** 2 - self.num_positions = self.num_patches + 1 - - def build(self, input_shape=None): - self.class_embedding = self.add_weight( - shape=(1, 1, self.embed_dim), - initializer=get_initializer(self.config.initializer_range), - trainable=True, - name="class_embedding", - ) - - self.position_embedding = self.add_weight( - shape=(1, self.num_positions, self.embed_dim), - initializer=get_initializer(self.config.initializer_range), - trainable=True, - name="position_embedding", - ) - - if self.built: - return - self.built = True - if getattr(self, "patch_embedding", None) is not None: - with tf.name_scope(self.patch_embedding.name): - self.patch_embedding.build([None, None, None, 3]) - - def call(self, pixel_values: tf.Tensor) -> tf.Tensor: - # Input is channels-first, we transpose. PyTorch transposes after the conv because PyTorch - # likes channels-first convs. - batch_size = tf.shape(pixel_values)[0] - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - patch_embeds = self.patch_embedding(pixel_values) - patch_embeds = tf.reshape(patch_embeds, (batch_size, self.num_patches, -1)) - - class_embeds = tf.broadcast_to(self.class_embedding, (batch_size, 1, self.embed_dim)) - embeddings = tf.concat([class_embeds, patch_embeds], axis=1) - embeddings = embeddings + self.position_embedding[:, : tf.shape(embeddings)[1], :] - return embeddings - - -# Copied from transformers.models.clip.modeling_tf_clip.TFCLIPTextEmbeddings with CLIP->Blip -class TFBlipTextEmbeddings(keras.layers.Layer): - def __init__(self, config: BlipTextConfig, **kwargs): - super().__init__(**kwargs) - - self.embed_dim = config.hidden_size - - self.config = config - - def build(self, input_shape: tf.TensorShape = None): - with tf.name_scope("token_embedding"): - self.weight = self.add_weight( - shape=(self.config.vocab_size, self.embed_dim), - initializer=get_initializer(self.config.initializer_factor * self.config.initializer_range), - trainable=True, - name="weight", - ) - - with tf.name_scope("position_embedding"): - self.position_embedding = self.add_weight( - shape=(self.config.max_position_embeddings, self.embed_dim), - initializer=get_initializer(self.config.initializer_factor * self.config.initializer_range), - trainable=True, - name="embeddings", - ) - - super().build(input_shape) - - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - if input_ids is None and inputs_embeds is None: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) - - position_embeds = tf.gather(params=self.position_embedding, indices=position_ids) - position_embeds = tf.tile(input=position_embeds, multiples=(input_shape[0], 1, 1)) - final_embeddings = inputs_embeds + position_embeds - - return final_embeddings - - -class TFBlipAttention(keras.layers.Layer): - """Multi-headed attention from 'Attention Is All You Need' paper""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.embed_dim = config.hidden_size - self.num_heads = config.num_attention_heads - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" - f" {self.num_heads})." - ) - self.scale = self.head_dim**-0.5 - self.dropout = keras.layers.Dropout(config.attention_dropout, name="dropout") - - self.qkv = keras.layers.Dense( - 3 * self.embed_dim, kernel_initializer=get_initializer(config.initializer_range), name="qkv" - ) - - self.projection = keras.layers.Dense( - self.embed_dim, kernel_initializer=get_initializer(config.initializer_range), name="projection" - ) - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = False, - training: bool | None = None, - ) -> tuple[tf.Tensor, tf.Tensor | None, tuple[tf.Tensor] | None]: - """Input shape: Batch x Time x Channel""" - - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - mixed_qkv = self.qkv(hidden_states) - mixed_qkv = tf.reshape(mixed_qkv, (bsz, tgt_len, 3, self.num_heads, self.head_dim)) - mixed_qkv = tf.transpose(mixed_qkv, perm=(2, 0, 3, 1, 4)) - - query_states, key_states, value_states = mixed_qkv[0], mixed_qkv[1], mixed_qkv[2] - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = query_states @ tf.transpose(key_states, (0, 1, 3, 2)) - - attention_scores = attention_scores * self.scale - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - - context_layer = tf.transpose(attention_probs @ value_states, perm=(0, 2, 1, 3)) - - new_context_layer_shape = shape_list(context_layer)[:-2] + [self.embed_dim] - context_layer = tf.reshape(context_layer, new_context_layer_shape) - - output = self.projection(context_layer) - - outputs = (output, attention_probs) if output_attentions else (output, None) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "qkv", None) is not None: - with tf.name_scope(self.qkv.name): - self.qkv.build([None, None, self.embed_dim]) - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, self.embed_dim]) - - -class TFBlipMLP(keras.layers.Layer): - def __init__(self, config: BlipConfig, **kwargs): - super().__init__(**kwargs) - - self.activation_fn = get_tf_activation(config.hidden_act) - - in_proj_std = (config.hidden_size**-0.5) * ((2 * config.num_hidden_layers) ** -0.5) - fc_std = (2 * config.hidden_size) ** -0.5 - - self.fc1 = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(fc_std), name="fc1" - ) - self.fc2 = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(in_proj_std), name="fc2" - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.fc1(inputs=hidden_states) - hidden_states = self.activation_fn(hidden_states) - hidden_states = self.fc2(inputs=hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.config.hidden_size]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.intermediate_size]) - - -class TFBlipEncoderLayer(keras.layers.Layer): - def __init__(self, config: BlipConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.hidden_size - self.self_attn = TFBlipAttention(config, name="self_attn") - self.layer_norm1 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm1") - self.mlp = TFBlipMLP(config, name="mlp") - self.layer_norm2 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm2") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - output_attentions: bool | None = False, - training: bool | None = None, - ) -> tuple[tf.Tensor]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - `(config.encoder_attention_heads,)`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - """ - residual = hidden_states - - hidden_states = self.layer_norm1(hidden_states) - hidden_states, attn_weights = self.self_attn( - hidden_states=hidden_states, - head_mask=attention_mask, - output_attentions=output_attentions, - training=training, - ) - hidden_states = hidden_states + residual - residual = hidden_states - hidden_states = self.layer_norm2(hidden_states) - hidden_states = self.mlp(hidden_states) - - hidden_states = hidden_states + residual - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "layer_norm1", None) is not None: - with tf.name_scope(self.layer_norm1.name): - self.layer_norm1.build([None, None, self.embed_dim]) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "layer_norm2", None) is not None: - with tf.name_scope(self.layer_norm2.name): - self.layer_norm2.build([None, None, self.embed_dim]) - - -class TFBlipPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = BlipConfig - base_model_prefix = "blip" - _keys_to_ignore_on_load_missing = [r"position_ids"] - - -BLIP_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - Parameters: - config ([`BlipConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -BLIP_VISION_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using - [`BlipImageProcessor`]. See [`BlipImageProcessor.__call__`] for details. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -BLIP_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoProcessor`]. See [`BlipProcessor.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using - [`BlipImageProcessor`]. See [`BlipImageProcessor.__call__`] for details. - return_loss (`bool`, *optional*): - Whether or not to return the contrastive loss. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@keras_serializable -class TFBlipEncoder(keras.layers.Layer): - config_class = BlipConfig - """ - Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a - [`BlipEncoderLayer`]. - - Args: - config (`BlipConfig`): - The corresponding vision configuration for the `BlipEncoder`. - """ - - def __init__(self, config: BlipConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layers = [TFBlipEncoderLayer(config, name=f"layers_._{i}") for i in range(config.num_hidden_layers)] - - @unpack_inputs - def call( - self, - inputs_embeds, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = None, - ) -> tuple | TFBaseModelOutput: - r""" - Args: - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Embedded representation of the inputs. Should be float, not int tokens. - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - hidden_states = inputs_embeds - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - layer_outputs = encoder_layer( - hidden_states, - attention_mask, - output_attentions=output_attentions, - training=training, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFBlipVisionModel(TFBlipPreTrainedModel): - main_input_name = "pixel_values" - config_class = BlipVisionConfig - - def __init__(self, config: BlipVisionConfig, *args, **kwargs): - super().__init__(config, *args, **kwargs) - self.config = config - - self.embeddings = TFBlipVisionEmbeddings(config, name="embeddings") - self.encoder = TFBlipEncoder(config, name="encoder") - self.post_layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="post_layernorm") - self.embed_dim = config.hidden_size - - def serving_output(self, output: TFBaseModelOutputWithPooling) -> TFBaseModelOutputWithPooling: - hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None - attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None - - return TFBaseModelOutputWithPooling( - last_hidden_state=output.last_hidden_state, - pooler_output=output.pooler_output, - hidden_states=hs, - attentions=attns, - ) - - @unpack_inputs - @add_start_docstrings_to_model_forward(BLIP_VISION_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBaseModelOutputWithPooling, config_class=BlipVisionConfig) - def call( - self, - pixel_values: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = None, - ) -> tuple | TFBaseModelOutputWithPooling: - r""" - Returns: - - """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - hidden_states = self.embeddings(pixel_values) - - encoder_outputs = self.encoder( - inputs_embeds=hidden_states, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - last_hidden_state = encoder_outputs[0] - last_hidden_state = self.post_layernorm(last_hidden_state) - - pooled_output = last_hidden_state[:, 0, :] - # TF gets confused if we call the layer with inputs of different ranks, so insert a singleton dimension - pooled_output = self.post_layernorm(tf.expand_dims(pooled_output, 1)) - pooled_output = tf.squeeze(pooled_output, 1) - - if not return_dict: - return (last_hidden_state, pooled_output) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def get_input_embeddings(self): - return self.embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "post_layernorm", None) is not None: - with tf.name_scope(self.post_layernorm.name): - self.post_layernorm.build([None, None, self.embed_dim]) - - -class TFBlipMainLayer(keras.layers.Layer): - config_class = BlipConfig - - def __init__(self, config: BlipConfig, *args, **kwargs): - super().__init__(*args, **kwargs) - - if not isinstance(config.text_config, BlipTextConfig): - raise TypeError( - "config.text_config is expected to be of type BlipTextConfig but is of type" - f" {type(config.text_config)}." - ) - - if not isinstance(config.vision_config, BlipVisionConfig): - raise TypeError( - "config.vision_config is expected to be of type BlipVisionConfig but is of type" - f" {type(config.vision_config)}." - ) - - text_config = config.text_config - vision_config = config.vision_config - - self.projection_dim = config.projection_dim - self.text_embed_dim = text_config.hidden_size - self.vision_embed_dim = vision_config.hidden_size - - self.text_model = TFBlipTextModel(text_config, name="text_model") - self.vision_model = TFBlipVisionModel(vision_config, name="vision_model") - - self.visual_projection = keras.layers.Dense( - self.projection_dim, - use_bias=False, - kernel_initializer=get_initializer(config.initializer_range), - name="visual_projection", - ) - self.text_projection = keras.layers.Dense( - self.projection_dim, - use_bias=False, - kernel_initializer=get_initializer(config.initializer_range), - name="text_projection", - ) - - self.config = config - - def build(self, input_shape=None): - self.logit_scale = self.add_weight( - name="logit_scale", - shape=[], - initializer=keras.initializers.Constant(self.config.logit_scale_init_value), - trainable=True, - ) - - if self.built: - return - self.built = True - if getattr(self, "text_model", None) is not None: - with tf.name_scope(self.text_model.name): - self.text_model.build(None) - if getattr(self, "vision_model", None) is not None: - with tf.name_scope(self.vision_model.name): - self.vision_model.build(None) - if getattr(self, "visual_projection", None) is not None: - with tf.name_scope(self.visual_projection.name): - self.visual_projection.build([None, None, self.vision_embed_dim]) - if getattr(self, "text_projection", None) is not None: - with tf.name_scope(self.text_projection.name): - self.text_projection.build([None, None, self.text_embed_dim]) - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - pixel_values: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - return_loss: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = None, - ) -> tuple | TFBlipOutput: - # Use BLIP model's config for some fields (if specified) instead of those of vision & text components. - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - vision_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - text_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - image_embeds = vision_outputs[1] - image_embeds = self.visual_projection(image_embeds) - - text_embeds = text_outputs[1] - text_embeds = self.text_projection(text_embeds) - - # normalized features - image_embeds = image_embeds / tf.norm(image_embeds, ord=2, axis=-1, keepdims=True) - text_embeds = text_embeds / tf.norm(text_embeds, ord=2, axis=-1, keepdims=True) - - # cosine similarity as logits - logit_scale = tf.exp(self.logit_scale) - logits_per_text = tf.matmul(text_embeds, image_embeds, transpose_b=True) * logit_scale - logits_per_image = tf.transpose(logits_per_text) - - loss = None - if return_loss: - loss = blip_loss(logits_per_text) - loss = tf.reshape(loss, (1,)) - - if not return_dict: - output = (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs) - return ((loss,) + output) if loss is not None else output - - return TFBlipOutput( - loss=loss, - logits_per_image=logits_per_image, - logits_per_text=logits_per_text, - text_embeds=text_embeds, - image_embeds=image_embeds, - text_model_output=text_outputs, - vision_model_output=vision_outputs, - ) - - -class TFBlipModel(TFBlipPreTrainedModel): - config_class = BlipConfig - _keys_to_ignore_on_load_missing = [r"text_decoder.cls.predictions.decoder.bias"] - main_input_name = "input_ids" - - def __init__(self, config: BlipConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.blip = TFBlipMainLayer(config, name="blip") - - def serving_output(self, output: TFBlipOutput) -> TFBlipOutput: - return TFBlipOutput( - logits_per_image=output.logits_per_image, - logits_per_text=output.logits_per_text, - text_embeds=output.text_embeds, - image_embeds=output.image_embeds, - ) - - @unpack_inputs - @add_start_docstrings_to_model_forward(BLIP_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBlipOutput, config_class=BlipConfig) - def call( - self, - input_ids: tf.Tensor | None = None, - pixel_values: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - return_loss: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = None, - ) -> tuple | TFBlipOutput: - r""" - Returns: - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFBlipModel - - >>> model = TFBlipModel.from_pretrained("Salesforce/blip-image-captioning-base") - >>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor( - ... text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="tf", padding=True - ... ) - - >>> outputs = model(**inputs) - >>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score - >>> probs = tf.nn.softmax(logits_per_image, axis=1) # we can take the softmax to get the label probabilities - ```""" - outputs = self.blip( - input_ids=input_ids, - pixel_values=pixel_values, - attention_mask=attention_mask, - position_ids=position_ids, - return_loss=return_loss, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - @add_start_docstrings_to_model_forward(BLIP_TEXT_INPUTS_DOCSTRING) - def get_text_features( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - return_dict: bool | None = None, - ) -> tf.Tensor: - r""" - Returns: - text_features (`tf.Tensor` of shape `(batch_size, output_dim`): The text embeddings obtained by applying - the projection layer to the pooled output of [`TFBlipTextModel`]. - - Examples: - - ```python - >>> from transformers import AutoProcessor, TFBlipModel - - >>> model = TFBlipModel.from_pretrained("Salesforce/blip-image-captioning-base") - >>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base") - - >>> inputs = processor(text=["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="tf") - >>> text_features = model.get_text_features(**inputs) - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - text_outputs = self.blip.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - return_dict=return_dict, - ) - - pooled_output = text_outputs[1] - text_features = self.blip.text_projection(pooled_output) - - return text_features - - @add_start_docstrings_to_model_forward(BLIP_VISION_INPUTS_DOCSTRING) - def get_image_features( - self, - pixel_values: tf.Tensor | None = None, - return_dict: bool | None = None, - ) -> tf.Tensor: - r""" - Returns: - image_features (`tf.Tensor` of shape `(batch_size, output_dim`): The image embeddings obtained by applying - the projection layer to the pooled output of [`TFBlipVisionModel`]. - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFBlipModel - - >>> model = TFBlipModel.from_pretrained("Salesforce/blip-image-captioning-base") - >>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor(images=image, return_tensors="tf") - - >>> image_features = model.get_image_features(**inputs) - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - vision_outputs = self.blip.vision_model(pixel_values=pixel_values, return_dict=return_dict) - - pooled_output = vision_outputs[1] # pooled_output - image_features = self.blip.visual_projection(pooled_output) - - return image_features - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "blip", None) is not None: - with tf.name_scope(self.blip.name): - self.blip.build(None) - - -@add_start_docstrings( - """ - BLIP Model for image captioning. The model consists of a vision encoder and a text decoder. One can optionally pass - `input_ids` to the model, which serve as a text prompt, to make the text decoder continue the prompt. Otherwise, - the decoder starts generating text from the [BOS] (beginning-of-sequence) token. will start generating the caption - from the text input. If no text input is provided, the decoder will start with the [BOS] token only. - """, - BLIP_START_DOCSTRING, -) -class TFBlipForConditionalGeneration(TFBlipPreTrainedModel): - config_class = BlipConfig - _keys_to_ignore_on_load_missing = [r"text_decoder.cls.predictions.decoder.bias"] - main_input_name = "pixel_values" - - def __init__(self, config: BlipConfig, *args, **kwargs): - super().__init__(config, *args, **kwargs) - - self.vision_model = TFBlipVisionModel(config.vision_config, name="vision_model") - - self.text_decoder = TFBlipTextLMHeadModel(config.text_config, name="text_decoder") - - self.decoder_input_ids = config.text_config.bos_token_id - self.decoder_pad_token_id = config.text_config.pad_token_id - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.vision_model.embeddings.patch_embedding - - @unpack_inputs - @add_start_docstrings_to_model_forward(BLIP_VISION_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBlipForConditionalGenerationModelOutput, config_class=BlipConfig) - def call( - self, - pixel_values: tf.Tensor, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - labels: tf.Tensor | None = None, - return_dict: bool | None = None, - training: bool | None = None, - ) -> tuple | TFBlipForConditionalGenerationModelOutput: - r""" - Returns: - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFBlipForConditionalGeneration - - >>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base") - >>> model = TFBlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - >>> text = "A picture of" - - >>> inputs = processor(images=image, text=text, return_tensors="tf") - - >>> outputs = model(**inputs) - ```""" - - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - vision_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - image_embeds = vision_outputs[0] - - outputs = self.text_decoder( - input_ids=input_ids, - attention_mask=attention_mask, - encoder_hidden_states=image_embeds, - labels=labels, - return_dict=False, - training=training, - ) - - if not return_dict: - outputs = (outputs[0], outputs[1], image_embeds, vision_outputs[0]) + vision_outputs[2:] - return tuple(output for output in outputs if output is not None) - - if labels is not None: - loss = outputs[0] - logits = outputs[1] - else: - loss = None - logits = outputs[0] - - if loss is not None and loss.shape.rank == 0: - loss = tf.reshape(loss, (1,)) - - return TFBlipForConditionalGenerationModelOutput( - loss=loss, - logits=logits, - image_embeds=image_embeds, - last_hidden_state=vision_outputs.last_hidden_state, - hidden_states=vision_outputs.hidden_states, - attentions=vision_outputs.attentions, - ) - - def generate( - self, - pixel_values: tf.Tensor, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - **generate_kwargs, - ) -> tf.Tensor: - r""" - Overrides *generate* function to be able to use the model as a conditional generator - - Parameters: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, image_height, image_width)`: - Input image to be processed - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - The sequence used as a prompt for the generation. - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - Examples: - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFBlipForConditionalGeneration - - >>> model = TFBlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base") - >>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor(images=image, return_tensors="tf") - - >>> outputs = model.generate(**inputs) - >>> print(processor.decode(outputs[0], skip_special_tokens=True)) - two cats sleeping on a couch - ``` - """ - - batch_size = pixel_values.shape[0] - vision_outputs = self.vision_model(pixel_values=pixel_values) - - image_embeds = vision_outputs[0] - - image_attention_mask = tf.ones(shape_list(image_embeds)[:-1], dtype=tf.int32) - - if isinstance(input_ids, list): - input_ids = tf.convert_to_tensor(input_ids, dtype=tf.int32) - elif input_ids is None: - input_ids = tf.convert_to_tensor( - [[self.decoder_input_ids, self.config.text_config.eos_token_id]], dtype=tf.int32 - ) - - input_ids = tf.tile(input_ids, (batch_size, 1)) - - # PyTorch: input_ids[:, 0] = self.config.text_config.bos_token_id - input_ids = tf.concat( - [tf.ones((batch_size, 1), dtype=tf.int32) * self.config.text_config.bos_token_id, input_ids[:, 1:]], axis=1 - ) - attention_mask = attention_mask[:, :-1] if attention_mask is not None else None - - outputs = self.text_decoder.generate( - input_ids=input_ids[:, :-1], - eos_token_id=self.config.text_config.sep_token_id, - pad_token_id=self.config.text_config.pad_token_id, - attention_mask=attention_mask, - encoder_hidden_states=image_embeds, - encoder_attention_mask=image_attention_mask, - **generate_kwargs, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "vision_model", None) is not None: - with tf.name_scope(self.vision_model.name): - self.vision_model.build(None) - if getattr(self, "text_decoder", None) is not None: - with tf.name_scope(self.text_decoder.name): - self.text_decoder.build(None) - - -@add_start_docstrings( - """ - BLIP Model for visual question answering. The model consists of a vision encoder, a text encoder as well as a text - decoder. The vision encoder will encode the input image, the text encoder will encode the input question together - with the encoding of the image, and the text decoder will output the answer to the question. - """, - BLIP_START_DOCSTRING, -) -class TFBlipForQuestionAnswering(TFBlipPreTrainedModel): - config_class = BlipConfig - _keys_to_ignore_on_load_missing = [r"text_decoder.cls.predictions.decoder.bias"] - - def __init__(self, config: BlipConfig, *args, **kwargs): - super().__init__(config, *args, **kwargs) - - self.vision_model = TFBlipVisionModel(config.vision_config, name="vision_model") - - self.text_encoder = TFBlipTextModel(config.text_config, name="text_encoder", add_pooling_layer=False) - - self.text_decoder = TFBlipTextLMHeadModel(config.text_config, name="text_decoder") - - self.decoder_pad_token_id = config.text_config.pad_token_id - self.decoder_start_token_id = config.text_config.bos_token_id - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.vision_model.embeddings.patch_embedding - - # Adapted from transformers.models.t5.modeling_tf_t5.TFT5PreTrainedModel._shift_right - def _shift_right(self, input_ids): - decoder_start_token_id = self.decoder_start_token_id - pad_token_id = self.decoder_pad_token_id - - if decoder_start_token_id is None or pad_token_id is None: - raise ValueError("decoder_start_token_id and pad_token_id must be defined!") - - start_tokens = tf.fill((shape_list(input_ids)[0], 1), decoder_start_token_id) - start_tokens = tf.cast(start_tokens, input_ids.dtype) # Ensure compatible dtypes for concatenation - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.cast(tf.fill(shape_list(shifted_input_ids), pad_token_id), shifted_input_ids.dtype), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=shifted_input_ids.dtype)) - - return shifted_input_ids - - @unpack_inputs - @add_start_docstrings_to_model_forward(BLIP_VISION_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBlipTextVisionModelOutput, config_class=BlipVisionConfig) - def call( - self, - input_ids: tf.Tensor, - pixel_values: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - labels: tf.Tensor | None = None, - return_dict: bool | None = None, - training: bool | None = None, - ) -> tuple | TFBlipTextVisionModelOutput: - r""" - Returns: - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFBlipForQuestionAnswering - - >>> model = TFBlipForQuestionAnswering.from_pretrained("Salesforce/blip-vqa-base") - >>> processor = AutoProcessor.from_pretrained("Salesforce/blip-vqa-base") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> # training - >>> text = "How many cats are in the picture?" - >>> label = "2" - >>> inputs = processor(images=image, text=text, return_tensors="tf") - >>> labels = processor(text=label, return_tensors="tf").input_ids - - >>> inputs["labels"] = labels - >>> outputs = model(**inputs) - >>> loss = outputs.loss - - >>> # inference - >>> text = "How many cats are in the picture?" - >>> inputs = processor(images=image, text=text, return_tensors="tf") - >>> outputs = model.generate(**inputs) - >>> print(processor.decode(outputs[0], skip_special_tokens=True)) - 2 - ```""" - if labels is None and decoder_input_ids is None: - raise ValueError( - "Either `decoder_input_ids` or `labels` should be passed when calling" - " `TFBlipForQuestionAnswering`. if you are training the model make sure that `labels` is passed, if you" - " are using the model for inference make sure that `decoder_input_ids` is passed or call `generate`" - ) - - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - vision_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - image_embeds = vision_outputs[0] - image_attention_mask = tf.ones(shape_list(image_embeds)[:-1], dtype=tf.int64) - - question_embeds = self.text_encoder( - input_ids=input_ids, - attention_mask=attention_mask, - encoder_hidden_states=image_embeds, - encoder_attention_mask=image_attention_mask, - return_dict=return_dict, - training=training, - ) - - question_embeds = question_embeds[0] if not return_dict else question_embeds.last_hidden_state - - if labels is not None and decoder_input_ids is None: - # labels are already shifted right, see: https://github.com/huggingface/transformers/pull/23153 - decoder_input_ids = labels - - answer_output = self.text_decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - encoder_hidden_states=question_embeds, - encoder_attention_mask=attention_mask, - labels=labels, - return_dict=return_dict, - training=training, - ) - - if labels is not None: - decoder_loss = tf.reduce_mean(answer_output.loss) if return_dict else tf.reduce_mean(answer_output[0]) - else: - decoder_loss = None - - if not return_dict: - outputs = (decoder_loss, image_embeds, vision_outputs[0]) + vision_outputs[2:] - return tuple(output for output in outputs if output is not None) - - return TFBlipTextVisionModelOutput( - loss=decoder_loss, - image_embeds=image_embeds, - last_hidden_state=vision_outputs.last_hidden_state, - hidden_states=vision_outputs.hidden_states, - attentions=vision_outputs.attentions, - ) - - def generate( - self, - input_ids: tf.Tensor, - pixel_values: tf.Tensor, - attention_mask: tf.Tensor | None = None, - **generate_kwargs, - ) -> tf.Tensor: - r""" - Overrides *generate* function to be able to use the model as a conditional generator - - Parameters: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - The sequence used as a prompt for the generation. - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, image_height, image_width)`: - Input image to be processed - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`. `1` for - tokens that are NOT MASKED, `0` for MASKED tokens. - generate_kwargs (dict, *optional*): - Additional arguments passed to the `generate` function of the decoder - - - Examples: - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFBlipForQuestionAnswering - - >>> model = TFBlipForQuestionAnswering.from_pretrained("Salesforce/blip-vqa-base") - >>> processor = AutoProcessor.from_pretrained("Salesforce/blip-vqa-base") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - >>> text = "How many cats are in the picture?" - - >>> inputs = processor(images=image, text=text, return_tensors="tf") - - >>> outputs = model.generate(**inputs) - >>> print(processor.decode(outputs[0], skip_special_tokens=True)) - 2 - ``` - """ - vision_outputs = self.vision_model(pixel_values=pixel_values) - - image_embeds = vision_outputs[0] - - image_attention_mask = tf.ones(shape_list(image_embeds)[:-1], dtype=tf.int32) - - if isinstance(input_ids, list): - input_ids = tf.Tensor(input_ids) - - question_outputs = self.text_encoder( - input_ids=input_ids, - attention_mask=attention_mask, - encoder_hidden_states=image_embeds, - encoder_attention_mask=image_attention_mask, - return_dict=False, - ) - - question_embeds = question_outputs[0] - - question_attention_mask = tf.ones(shape_list(question_embeds)[:-1], dtype=tf.int32) - - bos_ids = tf.fill( - (tf.shape(question_embeds)[0], 1), value=tf.cast(self.decoder_start_token_id, input_ids.dtype) - ) - - outputs = self.text_decoder.generate( - input_ids=bos_ids, - eos_token_id=self.config.text_config.sep_token_id, - pad_token_id=self.config.text_config.pad_token_id, - encoder_hidden_states=question_embeds, - encoder_attention_mask=question_attention_mask, - **generate_kwargs, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "vision_model", None) is not None: - with tf.name_scope(self.vision_model.name): - self.vision_model.build(None) - if getattr(self, "text_encoder", None) is not None: - with tf.name_scope(self.text_encoder.name): - self.text_encoder.build(None) - if getattr(self, "text_decoder", None) is not None: - with tf.name_scope(self.text_decoder.name): - self.text_decoder.build(None) - - -@add_start_docstrings( - """ - BLIP Model with a vision and text projector, and a classification head on top. The model is used in the context of - image-text retrieval. Given an image and a text, the model returns the probability of the text being relevant to - the image. - """, - BLIP_START_DOCSTRING, -) -class TFBlipForImageTextRetrieval(TFBlipPreTrainedModel): - config_class = BlipConfig - - def __init__(self, config: BlipConfig, *args, **kwargs): - super().__init__(config, *args, **kwargs) - - self.vision_model = TFBlipVisionModel(config.vision_config, name="vision_model") - - self.text_encoder = TFBlipTextModel(config.text_config, name="text_encoder", add_pooling_layer=False) - - # vision projection layer - self.vision_proj = keras.layers.Dense( - config.image_text_hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="vision_proj", - ) - - # text projection layer - self.text_proj = keras.layers.Dense( - config.image_text_hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="text_proj", - ) - - # image text matching head - self.itm_head = keras.layers.Dense( - 2, kernel_initializer=get_initializer(config.initializer_range), name="itm_head" - ) - - self.decoder_pad_token_id = ( - config.text_config.pad_token_id - if not hasattr(config, "decoder_pad_token_id") - else config.decoder_pad_token_id - ) - self.decoder_start_token_id = ( - config.text_config.bos_token_id - if not hasattr(config, "decoder_start_token_id") - else config.decoder_start_token_id - ) - self.config = config - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.vision_model.embeddings.patch_embedding - - @unpack_inputs - @add_start_docstrings_to_model_forward(BLIP_VISION_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBlipImageTextMatchingModelOutput, config_class=BlipVisionConfig) - def call( - self, - input_ids: tf.Tensor, - pixel_values: tf.Tensor | None = None, - use_itm_head: bool | None = True, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = None, - ) -> tuple | TFBlipImageTextMatchingModelOutput: - r""" - Returns: - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFBlipForImageTextRetrieval - - >>> model = TFBlipForImageTextRetrieval.from_pretrained("Salesforce/blip-itm-base-coco") - >>> processor = AutoProcessor.from_pretrained("Salesforce/blip-itm-base-coco") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - >>> text = "an image of a cat" - - >>> inputs = processor(images=image, text=text, return_tensors="tf") - >>> outputs = model(**inputs) - ``` - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - vision_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - image_embeds = vision_outputs[0] - image_atts = tf.ones(shape_list(image_embeds)[:-1], dtype=tf.int64) - - # Matt: In PyTorch, only one path (itm/non-itm) is taken. However, in TensorFlow this can result in - # some layers not being built! To avoid this, we always call both paths, then use an if statement to select - # which output to pass to the final output. The unnecessary nodes will be pruned from the final graph, but - # not before the layers have all been built correctly. - itm_question_embeds = self.text_encoder( - input_ids=input_ids, - attention_mask=attention_mask, - encoder_hidden_states=image_embeds, - encoder_attention_mask=image_atts, - return_dict=return_dict, - training=training, - ) - itm_question_embeds = itm_question_embeds[0] if not return_dict else itm_question_embeds.last_hidden_state - - itm_output = self.itm_head(itm_question_embeds[:, 0, :]) - - no_itm_question_embeds = self.text_encoder( - input_ids=input_ids, - attention_mask=attention_mask, - return_dict=return_dict, - training=training, - ) - no_itm_question_embeds = ( - no_itm_question_embeds[0] if not return_dict else no_itm_question_embeds.last_hidden_state - ) - - image_feat, _ = tf.linalg.normalize(self.vision_proj(image_embeds[:, 0, :]), ord=2, axis=-1) - text_feat, _ = tf.linalg.normalize(self.text_proj(no_itm_question_embeds[:, 0, :]), ord=2, axis=-1) - - no_itm_output = tf.matmul(image_feat, text_feat, transpose_b=True) - - if use_itm_head: - output = itm_output - question_embeds = itm_question_embeds - else: - output = no_itm_output - question_embeds = no_itm_question_embeds - - if not return_dict: - outputs = (output, vision_outputs[0]) + vision_outputs[2:] + (question_embeds,) - return tuple(output for output in outputs if output is not None) - - return TFBlipImageTextMatchingModelOutput( - itm_score=output, - last_hidden_state=vision_outputs.last_hidden_state, - hidden_states=vision_outputs.hidden_states, - attentions=vision_outputs.attentions, - question_embeds=question_embeds, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "vision_model", None) is not None: - with tf.name_scope(self.vision_model.name): - self.vision_model.build(None) - if getattr(self, "text_encoder", None) is not None: - with tf.name_scope(self.text_encoder.name): - self.text_encoder.build(None) - if getattr(self, "vision_proj", None) is not None: - with tf.name_scope(self.vision_proj.name): - self.vision_proj.build([None, None, self.config.vision_config.hidden_size]) - if getattr(self, "text_proj", None) is not None: - with tf.name_scope(self.text_proj.name): - self.text_proj.build([None, None, self.config.text_config.hidden_size]) - if getattr(self, "itm_head", None) is not None: - with tf.name_scope(self.itm_head.name): - self.itm_head.build([None, None, self.config.text_config.hidden_size]) - - -__all__ = [ - "TFBlipModel", - "TFBlipPreTrainedModel", - "TFBlipForConditionalGeneration", - "TFBlipForQuestionAnswering", - "TFBlipVisionModel", - "TFBlipTextModel", - "TFBlipForImageTextRetrieval", -] diff --git a/src/transformers/models/blip/modeling_tf_blip_text.py b/src/transformers/models/blip/modeling_tf_blip_text.py deleted file mode 100644 index 7dae1126e03b..000000000000 --- a/src/transformers/models/blip/modeling_tf_blip_text.py +++ /dev/null @@ -1,1122 +0,0 @@ -# coding=utf-8 -# Copyright 2023 The Salesforce Team Authors and The HuggingFace Team. All rights reserved. -# -# Licensed under the BSD-3-clause license (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://opensource.org/licenses/BSD-3-Clause -# -# 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. - - -from __future__ import annotations - -import math - -import tensorflow as tf - -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFBaseModelOutputWithPoolingAndCrossAttentions, - TFCausalLMOutputWithCrossAttentions, -) -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - get_initializer, - get_tf_activation, - keras, - keras_serializable, - shape_list, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, invert_attention_mask, stable_softmax -from ...utils import add_start_docstrings_to_model_forward, logging -from .configuration_blip import BlipTextConfig - - -logger = logging.get_logger(__name__) - -BLIP_TEXT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoProcessor`]. See [`BlipProcessor.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#L52 -class TFBlipTextEmbeddings(keras.layers.Layer): - """Construct the embeddings from word and position embeddings.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.word_embeddings = keras.layers.Embedding( - config.vocab_size, - config.hidden_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="word_embeddings", - ) - self.position_embeddings = keras.layers.Embedding( - config.max_position_embeddings, - config.hidden_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="position_embeddings", - ) - - # self.LayerNorm is not snake-cased to stick with PyTorch model variable name and be able to load - # any TensorFlow checkpoint file - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob, name="dropout") - - self.position_ids = tf.expand_dims(tf.range(config.max_position_embeddings), 0) - self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") - - self.config = config - - def call(self, input_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0, training=None): - if input_ids is not None: - input_shape = tf.shape(input_ids) - else: - input_shape = tf.shape(inputs_embeds)[:-1] - - seq_length = input_shape[1] - - if position_ids is None: - position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length] - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = self.word_embeddings(input_ids) - - embeddings = inputs_embeds - - if self.position_embedding_type == "absolute": - position_embeddings = self.position_embeddings(position_ids) - embeddings += position_embeddings - embeddings = self.LayerNorm(embeddings) - embeddings = self.dropout(embeddings, training=training) - return embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "word_embeddings", None) is not None: - with tf.name_scope(self.word_embeddings.name): - self.word_embeddings.build(None) - if getattr(self, "position_embeddings", None) is not None: - with tf.name_scope(self.position_embeddings.name): - self.position_embeddings.build(None) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - -# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#L97 -class TFBlipTextSelfAttention(keras.layers.Layer): - def __init__(self, config, is_cross_attention, **kwargs): - super().__init__(**kwargs) - self.config = config - if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): - raise ValueError( - "The hidden size (%d) is not a multiple of the number of attention heads (%d)" - % (config.hidden_size, config.num_attention_heads) - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - - self.query = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - self.max_position_embeddings = config.max_position_embeddings - self.distance_embedding = keras.layers.Embedding( - 2 * config.max_position_embeddings - 1, self.attention_head_size - ) - self.is_cross_attention = is_cross_attention - - def transpose_for_scores(self, x): - new_x_shape = tf.concat( - [tf.shape(x)[:-1], tf.constant([self.num_attention_heads, self.attention_head_size], dtype=tf.int32)], - axis=0, - ) - x = tf.reshape(x, new_x_shape) - return tf.transpose(x, perm=(0, 2, 1, 3)) - - def call( - self, - hidden_states, - attention_mask=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=None, - output_attentions=False, - training=None, - ): - mixed_query_layer = self.query(hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention: - key_layer = self.transpose_for_scores(self.key(encoder_hidden_states)) - value_layer = self.transpose_for_scores(self.value(encoder_hidden_states)) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(hidden_states)) - value_layer = self.transpose_for_scores(self.value(hidden_states)) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(hidden_states)) - value_layer = self.transpose_for_scores(self.value(hidden_states)) - - query_layer = self.transpose_for_scores(mixed_query_layer) - - past_key_value = (key_layer, value_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - seq_length = shape_list(hidden_states)[1] - position_ids_l = tf.expand_dims(tf.range(seq_length, dtype=tf.int64, device=hidden_states.device), 1) - position_ids_r = tf.expand_dims(tf.range(seq_length, dtype=tf.int64, device=hidden_states.device), 0) - distance = position_ids_l - position_ids_r - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = tf.cast(positional_embedding, query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = tf.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = tf.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = tf.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in BlipTextModel forward() function) - attention_scores = attention_scores + tf.cast(attention_mask, attention_scores.dtype) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs_dropped = self.dropout(attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs_dropped = attention_probs_dropped * head_mask - - context_layer = attention_probs_dropped @ value_layer - - context_layer = tf.transpose(context_layer, perm=(0, 2, 1, 3)) - new_context_layer_shape = shape_list(context_layer)[:-2] + [self.all_head_size] - context_layer = tf.reshape(context_layer, new_context_layer_shape) - - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if self.is_cross_attention: - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.encoder_hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.encoder_hidden_size]) - else: - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -class TFBlipTextSelfOutput(keras.layers.Layer): - def __init__(self, config: BlipTextConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool | None = None) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#242 -class TFBlipTextAttention(keras.layers.Layer): - def __init__(self, config, is_cross_attention=False, **kwargs): - super().__init__(**kwargs) - self.self = TFBlipTextSelfAttention(config, is_cross_attention, name="self") - # "output" is a protected attribute on TF models - self.self_output = TFBlipTextSelfOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - output_attentions: bool | None = False, - training: bool | None = None, - ): - self_outputs = self.self( - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - past_key_value, - output_attentions, - training=training, - ) - attention_output = self.self_output(self_outputs[0], hidden_states, training=training) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self", None) is not None: - with tf.name_scope(self.self.name): - self.self.build(None) - if getattr(self, "self_output", None) is not None: - with tf.name_scope(self.self_output.name): - self.self_output.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->BlipText -class TFBlipTextIntermediate(keras.layers.Layer): - def __init__(self, config: BlipTextConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFBlipTextOutput(keras.layers.Layer): - def __init__(self, config: BlipTextConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFBlipTextLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.attention = TFBlipTextAttention(config, name="attention") - if self.config.is_decoder: - self.crossattention = TFBlipTextAttention( - config, is_cross_attention=self.config.is_decoder, name="crossattention" - ) - self.intermediate = TFBlipTextIntermediate(config, name="intermediate") - self.self_output = TFBlipTextOutput(config, name="output") - - def call( - self, - hidden_states, - attention_mask=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=None, - output_attentions=False, - training=None, - ): - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - hidden_states, - attention_mask, - head_mask, - output_attentions=output_attentions, - past_key_value=self_attn_past_key_value, - training=training, - ) - attention_output = self_attention_outputs[0] - - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - - if encoder_hidden_states is not None: - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - output_attentions=output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - intermediate_output = self.intermediate(attention_output) - layer_output = self.self_output(intermediate_output, attention_output, training=training) - outputs = (layer_output,) + outputs - - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "self_output", None) is not None: - with tf.name_scope(self.self_output.name): - self.self_output.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - - -# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#L386 -@keras_serializable -class TFBlipTextEncoder(keras.layers.Layer): - config_class = BlipTextConfig - - def __init__(self, config, name=None, **kwargs): - super().__init__(name=name, **kwargs) - self.config = config - self.layer = [TFBlipTextLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - @unpack_inputs - def call( - self, - hidden_states, - attention_mask=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_values=None, - use_cache=None, - output_attentions=False, - output_hidden_states=False, - return_dict=True, - training=None, - ): - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.is_decoder else None - - next_decoder_cache = () if use_cache else None - - for i in range(self.config.num_hidden_layers): - layer_module = self.layer[i] - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_head_mask = head_mask[i] if head_mask is not None else None - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states, - attention_mask, - layer_head_mask, - encoder_hidden_states, - encoder_attention_mask, - past_key_value, - output_attentions, - training=training, - ) - - hidden_states = layer_outputs[0] - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - next_decoder_cache, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->BlipText -class TFBlipTextPooler(keras.layers.Layer): - def __init__(self, config: BlipTextConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPredictionHeadTransform with Bert->BlipText -class TFBlipTextPredictionHeadTransform(keras.layers.Layer): - def __init__(self, config: BlipTextConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - - if isinstance(config.hidden_act, str): - self.transform_act_fn = get_tf_activation(config.hidden_act) - else: - self.transform_act_fn = config.hidden_act - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.transform_act_fn(hidden_states) - hidden_states = self.LayerNorm(inputs=hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFBlipTextLMPredictionHead(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.transform = TFBlipTextPredictionHeadTransform(config, name="transform") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.decoder = keras.layers.Dense( - config.vocab_size, - kernel_initializer=get_initializer(config.initializer_range), - name="decoder", - use_bias=False, - ) - self.config = config - - def build(self, input_shape=None): - self.bias = self.add_weight(name="bias", shape=(self.config.vocab_size,), initializer="zeros", trainable=True) - - if self.built: - return - self.built = True - if getattr(self, "transform", None) is not None: - with tf.name_scope(self.transform.name): - self.transform.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build([None, None, self.config.hidden_size]) - - def call(self, hidden_states): - hidden_states = self.transform(hidden_states) - hidden_states = self.decoder(hidden_states) + self.bias - return hidden_states - - -class TFBlipTextOnlyMLMHead(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.predictions = TFBlipTextLMPredictionHead(config, name="predictions") - - def call(self, sequence_output: tf.Tensor) -> tf.Tensor: - prediction_scores = self.predictions(sequence_output) - return prediction_scores - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#L548 -class TFBlipTextPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = BlipTextConfig - base_model_prefix = "bert" - _keys_to_ignore_on_load_missing = [r"position_ids"] - - -# Adapted from https://github.com/salesforce/BLIP/blob/3a29b7410476bf5f2ba0955827390eb6ea1f4f9d/models/med.py#L571 -class TFBlipTextModel(TFBlipTextPreTrainedModel): - """ - The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of - cross-attention is added between the self-attention layers, following the architecture described in [Attention is - all you need](https://huggingface.co/papers/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, - Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin. argument and `is_decoder` set to `True`; an - `encoder_hidden_states` is then expected as an input to the forward pass. - """ - - def __init__(self, config, add_pooling_layer=True, name=None, **kwargs): - super().__init__(config, name=name, **kwargs) - self.config = config - - self.embeddings = TFBlipTextEmbeddings(config, name="embeddings") - self.encoder = TFBlipTextEncoder(config, name="encoder") - self.pooler = TFBlipTextPooler(config, name="pooler") if add_pooling_layer else None - - def get_input_embeddings(self): - return self.embeddings.word_embeddings - - def set_input_embeddings(self, value): - self.embeddings.word_embeddings = value - - @tf.function - def get_extended_attention_mask( - self, attention_mask: tf.Tensor, input_shape: tuple[int], is_decoder: bool - ) -> tf.Tensor: - """ - Makes broadcastable attention and causal masks so that future and masked tokens are ignored. - - Arguments: - attention_mask (`tf.Tensor`): - Mask with ones indicating tokens to attend to, zeros for tokens to ignore. - input_shape (`tuple[int]`): - The shape of the input to the model. - is_decoder (`bool`): - Whether the model is used as a decoder. - - Returns: - `tf.Tensor` The extended attention mask, with the same dtype as `attention_mask.dtype`. - """ - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - if not isinstance(attention_mask, tf.Tensor): - attention_mask = tf.convert_to_tensor(attention_mask) # Catches NumPy inputs that haven't been cast yet - if attention_mask.shape.rank == 3: - extended_attention_mask = attention_mask[:, None, :, :] - elif attention_mask.shape.rank == 2: - # Provided a padding mask of dimensions [batch_size, seq_length] - # - if the model is a decoder, apply a causal mask in addition to the padding mask - # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, seq_length, seq_length] - if is_decoder: - batch_size, seq_length = input_shape - - seq_ids = tf.range(seq_length, dtype=attention_mask.dtype) - causal_mask = tf.broadcast_to(seq_ids, (batch_size, seq_length, seq_length)) <= seq_ids[None, :, None] - # in case past_key_values are used we need to add a prefix ones mask to the causal mask - - if shape_list(causal_mask)[1] < shape_list(attention_mask)[1]: - prefix_seq_len = tf.shape(attention_mask)[1] - tf.shape(causal_mask)[1] - causal_mask = tf.concat( - [ - tf.ones((batch_size, seq_length, prefix_seq_len), dtype=causal_mask.dtype), - causal_mask, - ], - axis=-1, - ) - extended_attention_mask = ( - tf.cast(causal_mask[:, None, :, :], attention_mask.dtype) * attention_mask[:, None, None, :] - ) - else: - extended_attention_mask = attention_mask[:, None, None, :] - else: - raise ValueError( - f"Wrong shape for input_ids (shape {input_shape}) or attention_mask (shape {attention_mask.shape})" - ) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, self.dtype) # fp16 compatibility - extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0 - return extended_attention_mask - - @add_start_docstrings_to_model_forward(BLIP_TEXT_INPUTS_DOCSTRING) - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - encoder_embeds: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - is_decoder: bool = False, - training: bool = False, - ) -> tuple[tf.Tensor] | TFBaseModelOutputWithPoolingAndCrossAttentions: - r""" - encoder_hidden_states (`tf.Tensor`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - past_key_values (`tuple(tuple(tf.Tensor))`, *optional*): - Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). - """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if is_decoder: - use_cache = use_cache if use_cache is not None else self.config.use_cache - else: - use_cache = False - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - batch_size, seq_length = input_shape - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - batch_size, seq_length = input_shape - elif encoder_embeds is not None: - input_shape = shape_list(encoder_embeds)[:-1] - batch_size, seq_length = input_shape - else: - raise ValueError("You have to specify either input_ids or inputs_embeds or encoder_embeds") - - # past_key_values_length - past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 - - if attention_mask is None: - attention_mask = tf.ones((batch_size, seq_length + past_key_values_length)) - - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask: tf.Tensor = self.get_extended_attention_mask(attention_mask, input_shape, is_decoder) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if encoder_hidden_states is not None: - if isinstance(encoder_hidden_states, list): - encoder_batch_size, encoder_sequence_length, _ = shape_list(encoder_hidden_states[0]) - else: - encoder_batch_size, encoder_sequence_length, _ = shape_list(encoder_hidden_states) - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - - if isinstance(encoder_attention_mask, list): - encoder_extended_attention_mask = [invert_attention_mask(mask) for mask in encoder_attention_mask] - elif encoder_attention_mask is None: - encoder_attention_mask = tf.ones(encoder_hidden_shape) - encoder_extended_attention_mask = invert_attention_mask(encoder_attention_mask) - else: - encoder_extended_attention_mask = invert_attention_mask(encoder_attention_mask) - else: - encoder_extended_attention_mask = None - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) - - if encoder_embeds is None: - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - ) - else: - embedding_output = encoder_embeds - - encoder_outputs = self.encoder( - embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] - - return TFBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#L811 -class TFBlipTextLMHeadModel(TFBlipTextPreTrainedModel): - _keys_to_ignore_on_load_unexpected = [r"pooler"] - _keys_to_ignore_on_load_missing = [r"position_ids", r"predictions.decoder.bias"] - - def __init__(self, config, **kwargs): - super().__init__(config, **kwargs) - - self.bert = TFBlipTextModel(config, add_pooling_layer=False, name="bert") - self.cls = TFBlipTextOnlyMLMHead(config, name="cls") - self.label_smoothing = config.label_smoothing - - def get_output_embeddings(self): - return self.cls.predictions.decoder - - def set_output_embeddings(self, new_embeddings): - self.cls.predictions.decoder = new_embeddings - - @add_start_docstrings_to_model_forward(BLIP_TEXT_INPUTS_DOCSTRING) - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - position_ids=None, - head_mask=None, - inputs_embeds=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - labels=None, - past_key_values=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - return_logits=False, - is_decoder=True, - training=None, - ): - r""" - encoder_hidden_states (`tf.Tensor`, *optional*): Sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention if the model is - configured as a decoder. - encoder_attention_mask (`tf.Tensor`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - labels (`tf.Tensor`, *optional*): - Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in - `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are - ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]` - past_key_values (`tuple(tuple(tf.Tensor))`, *optional*): - Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if labels is not None: - use_cache = False - - outputs = self.bert( - input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - is_decoder=is_decoder, - training=training, - ) - - sequence_output = outputs[0] - prediction_scores = self.cls(sequence_output) - - if return_logits: - return prediction_scores[:, :-1, :] - - lm_loss = None - if labels is not None: - # we are doing next-token prediction; shift prediction scores and input ids by one - shifted_prediction_scores = prediction_scores[:, :-1, :] - shifted_prediction_scores = tf.reshape(shifted_prediction_scores, (-1, self.config.vocab_size)) - labels = labels[:, 1:] - labels = tf.reshape(labels, (-1,)) - # Keras won't give us label smoothing for sparse CE, so we de-sparsify things here - # Use relu to clamp masked labels at 0 to avoid NaN (we will be zeroing those out later anyway) - one_hot_labels = tf.one_hot(tf.nn.relu(labels), depth=self.config.vocab_size, dtype=tf.float32) - loss_fct = keras.losses.CategoricalCrossentropy( - from_logits=True, label_smoothing=self.label_smoothing, reduction="none" - ) - masked_positions = tf.cast(tf.not_equal(labels, -100), dtype=tf.float32) - lm_loss = loss_fct(one_hot_labels, shifted_prediction_scores) - lm_loss *= masked_positions - lm_loss = tf.reduce_sum(lm_loss, axis=0) / tf.math.count_nonzero(masked_positions, dtype=tf.float32) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output - - return TFCausalLMOutputWithCrossAttentions( - loss=lm_loss, - logits=prediction_scores, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): - input_shape = input_ids.shape - # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly - if attention_mask is None: - attention_mask = input_ids.new_ones(input_shape) - - # cut decoder_input_ids if past_key_values is used - if past_key_values is not None: - input_ids = input_ids[:, -1:] - - return { - "input_ids": input_ids, - "attention_mask": attention_mask, - "past_key_values": past_key_values, - "encoder_hidden_states": model_kwargs.get("encoder_hidden_states"), - "encoder_attention_mask": model_kwargs.get("encoder_attention_mask"), - "is_decoder": True, - } - - def _reorder_cache(self, past_key_values, beam_idx): - reordered_past = () - for layer_past in past_key_values: - reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),) - return reordered_past - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert", None) is not None: - with tf.name_scope(self.bert.name): - self.bert.build(None) - if getattr(self, "cls", None) is not None: - with tf.name_scope(self.cls.name): - self.cls.build(None) - - -__all__ = ["TFBlipTextLMHeadModel", "TFBlipTextModel", "TFBlipTextPreTrainedModel"] diff --git a/src/transformers/models/blip/processing_blip.py b/src/transformers/models/blip/processing_blip.py index 5cc4334a974c..4ac741f84f46 100644 --- a/src/transformers/models/blip/processing_blip.py +++ b/src/transformers/models/blip/processing_blip.py @@ -86,10 +86,8 @@ def __call__( `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. """ if images is None and text is None: raise ValueError("You have to specify either images or text.") diff --git a/src/transformers/models/blip_2/processing_blip_2.py b/src/transformers/models/blip_2/processing_blip_2.py index a1c89f7f460a..71f79583c77e 100644 --- a/src/transformers/models/blip_2/processing_blip_2.py +++ b/src/transformers/models/blip_2/processing_blip_2.py @@ -100,10 +100,8 @@ def __call__( `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. """ if images is None and text is None: raise ValueError("You have to specify either images or text.") diff --git a/src/transformers/models/bloom/__init__.py b/src/transformers/models/bloom/__init__.py index 72d1d6e6ca47..4a938fd80b25 100644 --- a/src/transformers/models/bloom/__init__.py +++ b/src/transformers/models/bloom/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_bloom import * from .modeling_bloom import * - from .modeling_flax_bloom import * from .tokenization_bloom_fast import * else: import sys diff --git a/src/transformers/models/bloom/configuration_bloom.py b/src/transformers/models/bloom/configuration_bloom.py index 74748c113041..8d5fa7656a73 100644 --- a/src/transformers/models/bloom/configuration_bloom.py +++ b/src/transformers/models/bloom/configuration_bloom.py @@ -22,7 +22,7 @@ if TYPE_CHECKING: - from ... import PreTrainedTokenizer, TensorType + from ... import PreTrainedTokenizer from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfigWithPast, PatchingSpec @@ -187,10 +187,12 @@ def generate_dummy_inputs( 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 + tokenizer, + batch_size=batch_size, + seq_length=seq_length, + is_pair=is_pair, ) # We need to order the input in the way they appears in the forward() diff --git a/src/transformers/models/bloom/modeling_bloom.py b/src/transformers/models/bloom/modeling_bloom.py index 6fde63e03b4d..84e31fddfb2e 100644 --- a/src/transformers/models/bloom/modeling_bloom.py +++ b/src/transformers/models/bloom/modeling_bloom.py @@ -441,8 +441,6 @@ def __init__(self, *inputs, **kwargs): def _init_weights(self, module: nn.Module): """Initialize the weights.""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/bloom/modeling_flax_bloom.py b/src/transformers/models/bloom/modeling_flax_bloom.py deleted file mode 100644 index c7bb1cc9c9a5..000000000000 --- a/src/transformers/models/bloom/modeling_flax_bloom.py +++ /dev/null @@ -1,737 +0,0 @@ -# coding=utf-8 -# Copyright 2023 HuggingFace Inc. Team and Bigscience Workshop. All rights reserved. -# -# 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. -"""Flax BLOOM model.""" - -import math -from functools import partial -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, dot_product_attention_weights, make_causal_mask -from flax.linen.activation import tanh -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutput, -) -from ...modeling_flax_utils import FlaxPreTrainedModel, append_call_sample_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_bloom import BloomConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "bigscience/bloom" -_CONFIG_FOR_DOC = "BloomConfig" - - -BLOOM_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`BloomConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -BLOOM_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`): - `input_ids_length` = `sequence_length`. Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`BloomTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def build_alibi_tensor(attention_mask: jnp.ndarray, num_heads: int, dtype: Optional[jnp.dtype] = jnp.float32): - """ - Flax implementation of the BLOOM Alibi tensor. BLOOM Alibi tensor is not causal as the original paper mentions, it - relies on a translation invariance of softmax for quick implementation: with l being a tensor, and a fixed value - `softmax(l+a) = softmax(l)`. Based on - https://github.com/ofirpress/attention_with_linear_biases/blob/a35aaca144e0eb6b789dfcb46784c4b8e31b7983/fairseq/models/transformer.py#L742 - Link to paper: https://huggingface.co/papers/2108.12409 - - Args: - attention_mask (`jnp.ndarray`): - Token-wise attention mask, this should be of shape `(batch_size, max_seq_len)`. - num_heads (`int`): - Number of attention heads. - dtype (`jnp.dtype`, *optional*, defaults to `jnp.float32`): - The data type (dtype) of the output tensor. - - Returns: Alibi tensor of shape `(batch_size * num_heads, 1, max_seq_len)`. - """ - batch_size, seq_length = attention_mask.shape - closest_power_of_2 = 2 ** math.floor(math.log2(num_heads)) - base = jnp.array(2 ** (-(2 ** -(math.log2(closest_power_of_2) - 3))), dtype=jnp.float32) - powers = jnp.arange(1, 1 + closest_power_of_2, dtype=jnp.float32) - slopes = jax.lax.pow(base, powers) - - if closest_power_of_2 != num_heads: - extra_base = jnp.array(2 ** (-(2 ** -(math.log2(2 * closest_power_of_2) - 3))), dtype=jnp.float32) - num_remaining_heads = min(closest_power_of_2, num_heads - closest_power_of_2) - extra_powers = jnp.arange(1, 1 + 2 * num_remaining_heads, 2, dtype=jnp.float32) - slopes = jnp.cat([slopes, jax.lax.pow(extra_base, extra_powers)], axis=0) - - # Note: the Alibi tensor will added to the attention bias that will be applied to the query, key product of attention - # therefore, Alibi will have to be of shape (batch_size, num_heads, query_length, key_length) - # => here we set (batch_size=1, num_heads=num_heads, query_length=1, key_length=max_length) - # so that the query_length dimension will then be broadcast correctly. - # This is more or less identical to T5's relative position bias: - # https://github.com/huggingface/transformers/blob/f681437203baa7671de3174b0fa583c349d9d5e1/src/transformers/models/t5/modeling_t5.py#L527 - arange_tensor = ((attention_mask.cumsum(axis=-1) - 1) * attention_mask)[:, None, :] - alibi = slopes[..., None] * arange_tensor - alibi = jnp.expand_dims(alibi, axis=2) - return jnp.asarray(alibi, dtype) - - -class FlaxBloomAttention(nn.Module): - config: BloomConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.hidden_size = self.config.hidden_size - self.num_heads = self.config.n_head - self.head_dim = self.hidden_size // self.num_heads - self.attention_softmax_in_fp32 = self.dtype is not jnp.float32 - - if self.head_dim * self.num_heads != self.hidden_size: - raise ValueError( - f"`hidden_size` must be divisible by `num_heads` (got `hidden_size`: {self.hidden_size} and " - f"`num_heads`: {self.num_heads})." - ) - - dense = partial( - nn.Dense, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - self.query_key_value = dense(self.hidden_size * 3) - self.dense = dense(self.hidden_size) - self.resid_dropout = nn.Dropout(rate=self.config.hidden_dropout) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:-1] + (self.num_heads, self.head_dim * 3)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.hidden_size,)) - - @nn.compact - # Copied from transformers.models.gptj.modeling_flax_gptj.FlaxGPTJAttention._concatenate_to_cache - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key - # positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - residual, - alibi, - attention_mask=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - batch_size, seq_length = hidden_states.shape[:2] - - # proj q, k, v - fused_qkv = self.query_key_value(hidden_states) - fused_qkv = self._split_heads(fused_qkv) - query, key, value = jnp.split(fused_qkv, 3, axis=-1) - - causal_attention_mask = make_causal_mask(attention_mask, dtype="bool") - - # for fast decoding causal attention mask should be shifted - causal_attention_mask_shift = ( - self.variables["cache"]["cache_index"] if self.has_variable("cache", "cached_key") else 0 - ) - - # fast decoding for generate requires special attention_mask - if self.has_variable("cache", "cached_key"): - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_attention_mask = jax.lax.dynamic_slice( - causal_attention_mask, - (0, 0, causal_attention_mask_shift, 0), - (1, 1, seq_length, max_decoder_length), - ) - - # broadcast causal attention mask & attention mask to fit for merge - causal_attention_mask = jnp.broadcast_to( - causal_attention_mask, (batch_size,) + causal_attention_mask.shape[1:] - ) - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_attention_mask.shape) - attention_mask = combine_masks(attention_mask, causal_attention_mask) - - dropout_rng = None - if not deterministic and self.config.attention_dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.has_variable("cache", "cached_key") or init_cache: - key, value, attention_mask = self._concatenate_to_cache(key, value, query, attention_mask) - - # transform boolean mask into float mask - mask_value = jnp.finfo(self.dtype).min - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, mask_value).astype(self.dtype), - ) - - attention_bias = attention_bias + alibi - - # Cast in fp32 if the original dtype is different from fp32 - attention_dtype = jnp.float32 if self.attention_softmax_in_fp32 else self.dtype - - attn_weights = dot_product_attention_weights( - query, - key, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_dropout, - deterministic=deterministic, - dtype=attention_dtype, - ) - - # Cast back in the original dtype if the native dtype is not fp32 - if self.attention_softmax_in_fp32: - attn_weights = attn_weights.astype(self.dtype) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value) - attn_output = self._merge_heads(attn_output) - attn_output = self.dense(attn_output) - attn_output = self.resid_dropout(attn_output, deterministic=deterministic) - - attn_output = attn_output + residual - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class BloomGELU(nn.Module): - def setup(self): - self.dtype = jnp.float32 - - def __call__(self, x): - return x * 0.5 * (1.0 + tanh(0.79788456 * x * (1 + 0.044715 * x * x))) - - -class FlaxBloomMLP(nn.Module): - config: BloomConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - hidden_size = self.config.hidden_size - - kernel_init = jax.nn.initializers.normal(self.config.initializer_range) - - self.dense_h_to_4h = nn.Dense(4 * hidden_size, dtype=self.dtype, kernel_init=kernel_init) - self.dense_4h_to_h = nn.Dense(hidden_size, dtype=self.dtype, kernel_init=kernel_init) - self.hidden_dropout = nn.Dropout(self.config.hidden_dropout) - self.act = BloomGELU() - - def __call__(self, hidden_states, residual, deterministic: bool = True): - hidden_states = self.dense_h_to_4h(hidden_states) - hidden_states = self.act(hidden_states) - - intermediate_output = self.dense_4h_to_h(hidden_states) - - intermediate_output = intermediate_output + residual - hidden_states = self.hidden_dropout(intermediate_output, deterministic=deterministic) - - return hidden_states - - -class FlaxBloomBlock(nn.Module): - config: BloomConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.input_layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - - self.self_attention = FlaxBloomAttention(self.config, dtype=self.dtype) - self.post_attention_layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - - self.mlp = FlaxBloomMLP(self.config, dtype=self.dtype) - - self.apply_residual_connection_post_layernorm = self.config.apply_residual_connection_post_layernorm - self.hidden_dropout = self.config.hidden_dropout - - def __call__( - self, - hidden_states, - alibi, - attention_mask=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - layernorm_output = self.input_layernorm(hidden_states) - - # layer norm before saving residual if config calls for it - if self.apply_residual_connection_post_layernorm: - residual = layernorm_output - else: - residual = hidden_states - - # self-attention - attn_outputs = self.self_attention( - layernorm_output, - residual=residual, - alibi=alibi, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - - attention_output = attn_outputs[0] - - outputs = attn_outputs[1:] - - post_layernorm = self.post_attention_layernorm(attention_output) - - # set residual based on config - if self.apply_residual_connection_post_layernorm: - residual = post_layernorm - else: - residual = attention_output - - output = self.mlp(post_layernorm, residual, deterministic=deterministic) - - outputs = (output,) + outputs - - return outputs - - -class FlaxBloomPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = BloomConfig - base_model_prefix = "transformer" - module_class: nn.Module = None - - def __init__( - self, - config: BloomConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, input_ids, attention_mask, return_dict=False)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length), dtype="i4") - attention_mask = jnp.ones_like(input_ids) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(BLOOM_INPUTS_DOCSTRING) - def __call__( - self, - input_ids, - attention_mask=None, - past_key_values: Optional[dict] = None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - batch_size, sequence_length = input_ids.shape - - if attention_mask is None: - attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # If past_key_values are passed then cache is already initialized a private flag init_cache has to be passed - # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be - # changed by FlaxBloomAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - not train, - False, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - return outputs - - -class FlaxBloomBlockCollection(nn.Module): - config: BloomConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.layers = [ - FlaxBloomBlock(self.config, name=str(layer_number), dtype=self.dtype) - for layer_number in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - alibi, - attention_mask=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for layer_number in range(self.config.num_hidden_layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = self.layers[layer_number]( - hidden_states, - alibi=alibi, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - # this contains possible `None` values - `FlaxBloomModule` will filter them out - outputs = (hidden_states, all_hidden_states, all_attentions) - - return outputs - - -class FlaxBloomModule(nn.Module): - config: BloomConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.embed_dim = self.config.hidden_size - - # word embeddings (no positional embedding layer) - self.word_embeddings = nn.Embed( - self.config.vocab_size, - self.embed_dim, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - - # post-embedding layernorm - self.word_embeddings_layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - - # transformer layers - self.h = FlaxBloomBlockCollection(self.config, dtype=self.dtype) - - # final layernorm - self.ln_f = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - - def __call__( - self, - input_ids=None, - attention_mask=None, - deterministic=True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - inputs_embeds = self.word_embeddings(input_ids) - # do post-embedding layernorm - hidden_states = self.word_embeddings_layernorm(inputs_embeds) - - # build alibi depending on `attention_mask` - alibi = build_alibi_tensor(attention_mask, self.config.n_head, dtype=hidden_states.dtype) - - outputs = self.h( - hidden_states, - alibi=alibi, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_hidden_states=output_hidden_states, - output_attentions=output_attentions, - ) - - hidden_states = outputs[0] - hidden_states = self.ln_f(hidden_states) - - if output_hidden_states: - all_hidden_states = outputs[1] + (hidden_states,) - outputs = (hidden_states, all_hidden_states) + outputs[2:] - else: - outputs = (hidden_states,) + outputs[1:] - - if not return_dict: - return tuple(v for v in [outputs[0], outputs[-1]] if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=outputs[1], - attentions=outputs[-1], - ) - - -@add_start_docstrings( - "The bare Bloom Model transformer outputting raw hidden-states without any specific head on top.", - BLOOM_START_DOCSTRING, -) -# Copied from transformers.models.gpt_neo.modeling_flax_gpt_neo.FlaxGPTNeoModel with GPTNeo->Bloom -class FlaxBloomModel(FlaxBloomPreTrainedModel): - module_class = FlaxBloomModule - - -append_call_sample_docstring(FlaxBloomModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutput, _CONFIG_FOR_DOC) - - -class FlaxBloomForCausalLMModule(nn.Module): - config: BloomConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.transformer = FlaxBloomModule(self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - - def __call__( - self, - input_ids, - attention_mask, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - outputs = self.transformer( - input_ids, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_kernel = self.transformer.variables["params"]["word_embeddings"]["embedding"].T - lm_logits = self.lm_head.apply({"params": {"kernel": shared_kernel}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - return (lm_logits,) + outputs[1:] - - return FlaxCausalLMOutput(logits=lm_logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions) - - -@add_start_docstrings( - """ - The Bloom Model transformer with a language modeling head on top (linear layer with weights tied to the input - embeddings). - """, - BLOOM_START_DOCSTRING, -) -class FlaxBloomForCausalLM(FlaxBloomPreTrainedModel): - module_class = FlaxBloomForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for - # x > input_ids.shape[-1] and x < cache_length. But since Bloom uses a causal mask, - # those positions are masked anyway. Thus, we can create a single static attention_mask here, - # which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - return model_kwargs - - -append_call_sample_docstring(FlaxBloomForCausalLM, _CHECKPOINT_FOR_DOC, FlaxCausalLMOutput, _CONFIG_FOR_DOC) - - -__all__ = ["FlaxBloomForCausalLM", "FlaxBloomModel", "FlaxBloomPreTrainedModel"] diff --git a/src/transformers/models/bridgetower/image_processing_bridgetower.py b/src/transformers/models/bridgetower/image_processing_bridgetower.py index cb39ed097561..75b4e2b4238c 100644 --- a/src/transformers/models/bridgetower/image_processing_bridgetower.py +++ b/src/transformers/models/bridgetower/image_processing_bridgetower.py @@ -339,10 +339,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -431,10 +429,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -469,10 +465,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # Here, crop_size is used only if it is set, else size will be used. validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/bridgetower/modeling_bridgetower.py b/src/transformers/models/bridgetower/modeling_bridgetower.py index 59c5be00c316..97fcc469a4c6 100644 --- a/src/transformers/models/bridgetower/modeling_bridgetower.py +++ b/src/transformers/models/bridgetower/modeling_bridgetower.py @@ -838,8 +838,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized diff --git a/src/transformers/models/bros/modeling_bros.py b/src/transformers/models/bros/modeling_bros.py index d01a4c5a1c6d..5f5dd05ff82d 100755 --- a/src/transformers/models/bros/modeling_bros.py +++ b/src/transformers/models/bros/modeling_bros.py @@ -126,8 +126,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -578,8 +576,6 @@ def _init_weights(self, module: nn.Module): """Initialize the weights""" std = self.config.initializer_range if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/byt5/convert_byt5_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/byt5/convert_byt5_original_tf_checkpoint_to_pytorch.py index 9b1b15857cea..a53efce63544 100755 --- a/src/transformers/models/byt5/convert_byt5_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/byt5/convert_byt5_original_tf_checkpoint_to_pytorch.py @@ -15,14 +15,123 @@ """Convert T5 checkpoint.""" import argparse +import os -from transformers import T5Config, T5ForConditionalGeneration, load_tf_weights_in_t5 +import torch + +from transformers import T5Config, T5ForConditionalGeneration from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +def load_tf_weights_in_t5(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + tf_weights = {} + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + tf_weights[name] = array + + for txt_name in names: + name = txt_name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any( + n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + tf_weights.pop(txt_name, None) + continue + if "_slot_" in name[-1]: + logger.info(f"Skipping {'/'.join(name)}") + tf_weights.pop(txt_name, None) + continue + pointer = model + array = tf_weights[txt_name] + + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] in ["kernel", "scale", "embedding"]: + pointer = getattr(pointer, "weight") + elif scope_names[0] == "self_attention": + pointer = getattr(pointer, "layer") + pointer = pointer[0] + elif scope_names[0] == "enc_dec_attention": + pointer = getattr(pointer, "layer") + pointer = pointer[1] + elif scope_names[0] == "dense_relu_dense": + pointer = getattr(pointer, "layer") + pointer = pointer[2] + elif scope_names[0] == "rms_norm": + if hasattr(pointer, "layer_norm"): + pointer = getattr(pointer, "layer_norm") + elif hasattr(pointer, "final_layer_norm"): + pointer = getattr(pointer, "final_layer_norm") + elif scope_names[0] == "scale": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + elif scope_names[0] == "decoder" and name[1] == "logits": + continue + elif scope_names[0] == "logits": + pointer = getattr(pointer, "lm_head") + elif scope_names[0] == "wi" and len(scope_names) > 1 and scope_names[1].isdigit(): + pointer = getattr(pointer, f"wi_{scope_names[1]}") + continue + else: + try: + pointer = getattr(pointer, scope_names[0]) + except AttributeError: + logger.info(f"Skipping {'/'.join(name)}") + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if scope_names[0] not in ["kernel", "scale", "embedding"]: + pointer = getattr(pointer, "weight") + if scope_names[0] != "embedding": + logger.info(f"Transposing numpy weight of shape {array.shape} for {name}") + array = np.transpose(array) + try: + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array.astype(np.float32)) + tf_weights.pop(txt_name, None) + + logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}.") + return model + + def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, config_file, pytorch_dump_path): # Initialise PyTorch model config = T5Config.from_json_file(config_file) diff --git a/src/transformers/models/camembert/__init__.py b/src/transformers/models/camembert/__init__.py index 9d90f64de97f..a3a9c395eb5b 100644 --- a/src/transformers/models/camembert/__init__.py +++ b/src/transformers/models/camembert/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_camembert import * from .modeling_camembert import * - from .modeling_tf_camembert import * from .tokenization_camembert import * from .tokenization_camembert_fast import * else: diff --git a/src/transformers/models/camembert/modeling_camembert.py b/src/transformers/models/camembert/modeling_camembert.py index 3a07402f739a..aa86eb18d652 100644 --- a/src/transformers/models/camembert/modeling_camembert.py +++ b/src/transformers/models/camembert/modeling_camembert.py @@ -60,8 +60,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -672,8 +670,6 @@ class CamembertPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/camembert/modeling_tf_camembert.py b/src/transformers/models/camembert/modeling_tf_camembert.py deleted file mode 100644 index 0869902aa962..000000000000 --- a/src/transformers/models/camembert/modeling_tf_camembert.py +++ /dev/null @@ -1,1800 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 CamemBERT model.""" - -from __future__ import annotations - -import math -import warnings - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFBaseModelOutputWithPoolingAndCrossAttentions, - TFCausalLMOutputWithCrossAttentions, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_camembert import CamembertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "almanach/camembert-base" -_CONFIG_FOR_DOC = "CamembertConfig" - - -CAMEMBERT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`CamembertConfig`]): Model configuration class with all the parameters of the - model. Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -CAMEMBERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaEmbeddings -class TFCamembertEmbeddings(keras.layers.Layer): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.padding_idx = 1 - self.config = config - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - def create_position_ids_from_input_ids(self, input_ids, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding - symbols are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - input_ids: tf.Tensor - Returns: tf.Tensor - """ - mask = tf.cast(tf.math.not_equal(input_ids, self.padding_idx), dtype=input_ids.dtype) - incremental_indices = (tf.math.cumsum(mask, axis=1) + past_key_values_length) * mask - - return incremental_indices + self.padding_idx - - def call( - self, - input_ids=None, - position_ids=None, - token_type_ids=None, - inputs_embeds=None, - past_key_values_length=0, - training=False, - ): - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - if input_ids is not None: - # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = self.create_position_ids_from_input_ids( - input_ids=input_ids, past_key_values_length=past_key_values_length - ) - else: - position_ids = tf.expand_dims( - tf.range(start=self.padding_idx + 1, limit=input_shape[-1] + self.padding_idx + 1), axis=0 - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->Camembert -class TFCamembertPooler(keras.layers.Layer): - def __init__(self, config: CamembertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention with Bert->Camembert -class TFCamembertSelfAttention(keras.layers.Layer): - def __init__(self, config: CamembertConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - - self.is_decoder = config.is_decoder - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_layer = past_key_value[0] - value_layer = past_key_value[1] - attention_mask = encoder_attention_mask - elif is_cross_attention: - key_layer = self.transpose_for_scores(self.key(inputs=encoder_hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=encoder_hidden_states), batch_size) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_layer, value_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFCamembertModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - if self.is_decoder: - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfOutput with Bert->Camembert -class TFCamembertSelfOutput(keras.layers.Layer): - def __init__(self, config: CamembertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertAttention with Bert->Camembert -class TFCamembertAttention(keras.layers.Layer): - def __init__(self, config: CamembertConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFCamembertSelfAttention(config, name="self") - self.dense_output = TFCamembertSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - # add attentions (possibly with past_key_value) if we output them - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->Camembert -class TFCamembertIntermediate(keras.layers.Layer): - def __init__(self, config: CamembertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->Camembert -class TFCamembertOutput(keras.layers.Layer): - def __init__(self, config: CamembertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLayer with Bert->Camembert -class TFCamembertLayer(keras.layers.Layer): - def __init__(self, config: CamembertConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFCamembertAttention(config, name="attention") - self.is_decoder = config.is_decoder - self.add_cross_attention = config.add_cross_attention - if self.add_cross_attention: - if not self.is_decoder: - raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = TFCamembertAttention(config, name="crossattention") - self.intermediate = TFCamembertIntermediate(config, name="intermediate") - self.bert_output = TFCamembertOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_value: tuple[tf.Tensor] | None, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=self_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - cross_attn_present_key_value = None - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" - " by setting `config.add_cross_attention=True`" - ) - - # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - cross_attention_outputs = self.crossattention( - input_tensor=attention_output, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=cross_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - - # add cross-attn cache to positions 3,4 of present_key_value tuple - cross_attn_present_key_value = cross_attention_outputs[-1] - present_key_value = present_key_value + cross_attn_present_key_value - - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + outputs # add attentions if we output them - - # if decoder, return the attn key/values as the last output - if self.is_decoder: - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertEncoder with Bert->Camembert -class TFCamembertEncoder(keras.layers.Layer): - def __init__(self, config: CamembertConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layer = [TFCamembertLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_values: tuple[tuple[tf.Tensor]] | None, - use_cache: bool | None, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - next_decoder_cache = () if use_cache else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[i], - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - if self.config.add_cross_attention and encoder_hidden_states is not None: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v for v in [hidden_states, all_hidden_states, all_attentions, all_cross_attentions] if v is not None - ) - - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaMainLayer with Roberta->Camembert -class TFCamembertMainLayer(keras.layers.Layer): - config_class = CamembertConfig - - def __init__(self, config, add_pooling_layer=True, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.is_decoder = config.is_decoder - - self.num_hidden_layers = config.num_hidden_layers - self.initializer_range = config.initializer_range - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - self.encoder = TFCamembertEncoder(config, name="encoder") - self.pooler = TFCamembertPooler(config, name="pooler") if add_pooling_layer else None - # The embeddings must be the last declaration in order to follow the weights order - self.embeddings = TFCamembertEmbeddings(config, name="embeddings") - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.get_input_embeddings - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.set_input_embeddings - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer._prune_heads - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.call - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - if not self.config.is_decoder: - use_cache = False - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - - if past_key_values is None: - past_key_values_length = 0 - past_key_values = [None] * len(self.encoder.layer) - else: - past_key_values_length = shape_list(past_key_values[0][0])[-2] - - if attention_mask is None: - attention_mask = tf.fill(dims=(batch_size, seq_length + past_key_values_length), value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - - mask_seq_length = seq_length + past_key_values_length - # Copied from `modeling_tf_t5.py` - # Provided a padding mask of dimensions [batch_size, mask_seq_length] - # - if the model is a decoder, apply a causal mask in addition to the padding mask - # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - if self.is_decoder: - seq_ids = tf.range(mask_seq_length) - causal_mask = tf.less_equal( - tf.tile(seq_ids[None, None, :], (batch_size, mask_seq_length, 1)), - seq_ids[None, :, None], - ) - causal_mask = tf.cast(causal_mask, dtype=attention_mask.dtype) - extended_attention_mask = causal_mask * attention_mask[:, None, :] - attention_mask_shape = shape_list(extended_attention_mask) - extended_attention_mask = tf.reshape( - extended_attention_mask, (attention_mask_shape[0], 1, attention_mask_shape[1], attention_mask_shape[2]) - ) - if past_key_values[0] is not None: - # attention_mask needs to be sliced to the shape `[batch_size, 1, from_seq_length - cached_seq_length, to_seq_length] - extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :] - else: - extended_attention_mask = tf.reshape( - attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1]) - ) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Copied from `modeling_tf_t5.py` with -1e9 -> -10000 - if self.is_decoder and encoder_attention_mask is not None: - # If a 2D ou 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=extended_attention_mask.dtype) - num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) - if num_dims_encoder_attention_mask == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if num_dims_encoder_attention_mask == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, - # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) - - encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -10000.0 - else: - encoder_extended_attention_mask = None - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - - -class TFCamembertPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = CamembertConfig - base_model_prefix = "roberta" - - -@add_start_docstrings( - "The bare CamemBERT Model transformer outputting raw hidden-states without any specific head on top.", - CAMEMBERT_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaModel with Roberta->Camembert, ROBERTA->CAMEMBERT -class TFCamembertModel(TFCamembertPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.roberta = TFCamembertMainLayer(config, name="roberta") - - @unpack_inputs - @add_start_docstrings_to_model_forward(CAMEMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPoolingAndCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutputWithPoolingAndCrossAttentions: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - """ - outputs = self.roberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaLMHead with Roberta->Camembert -class TFCamembertLMHead(keras.layers.Layer): - """Camembert Head for masked language modeling.""" - - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.act = get_tf_activation("gelu") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.decoder = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - - def get_output_embeddings(self): - return self.decoder - - def set_output_embeddings(self, value): - self.decoder.weight = value - self.decoder.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.layer_norm(hidden_states) - - # project back to size of vocabulary with bias - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.decoder.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -@add_start_docstrings( - """CamemBERT Model with a `language modeling` head on top.""", - CAMEMBERT_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForMaskedLM with Roberta->Camembert, ROBERTA->CAMEMBERT -class TFCamembertForMaskedLM(TFCamembertPreTrainedModel, TFMaskedLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head.decoder.weight"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.roberta = TFCamembertMainLayer(config, add_pooling_layer=False, name="roberta") - self.lm_head = TFCamembertLMHead(config, self.roberta.embeddings, name="lm_head") - - def get_lm_head(self): - return self.lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(CAMEMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - mask="", - expected_output="' Paris'", - expected_loss=0.1, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - prediction_scores = self.lm_head(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaClassificationHead -class TFCamembertClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.out_proj = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="out_proj" - ) - self.config = config - - def call(self, features, training=False): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x, training=training) - x = self.dense(x) - x = self.dropout(x, training=training) - x = self.out_proj(x) - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - CamemBERT Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - CAMEMBERT_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForSequenceClassification with Roberta->Camembert, ROBERTA->CAMEMBERT -class TFCamembertForSequenceClassification(TFCamembertPreTrainedModel, TFSequenceClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta = TFCamembertMainLayer(config, add_pooling_layer=False, name="roberta") - self.classifier = TFCamembertClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(CAMEMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="cardiffnlp/twitter-roberta-base-emotion", - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="'optimism'", - expected_loss=0.08, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.classifier(sequence_output, training=training) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - CamemBERT Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. - for Named-Entity-Recognition (NER) tasks. - """, - CAMEMBERT_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForTokenClassification with Roberta->Camembert, ROBERTA->CAMEMBERT -class TFCamembertForTokenClassification(TFCamembertPreTrainedModel, TFTokenClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta = TFCamembertMainLayer(config, add_pooling_layer=False, name="roberta") - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(CAMEMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="ydshieh/roberta-large-ner-english", - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="['O', 'ORG', 'ORG', 'O', 'O', 'O', 'O', 'O', 'LOC', 'O', 'LOC', 'LOC']", - expected_loss=0.01, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - CamemBERT Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - CAMEMBERT_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForMultipleChoice with Roberta->Camembert, ROBERTA->CAMEMBERT -class TFCamembertForMultipleChoice(TFCamembertPreTrainedModel, TFMultipleChoiceLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"lm_head"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.roberta = TFCamembertMainLayer(config, name="roberta") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward( - CAMEMBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") - ) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - outputs = self.roberta( - flat_input_ids, - flat_attention_mask, - flat_token_type_ids, - flat_position_ids, - head_mask, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, training=training) - logits = self.classifier(pooled_output) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - CamemBERT Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - CAMEMBERT_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForQuestionAnswering with Roberta->Camembert, ROBERTA->CAMEMBERT -class TFCamembertForQuestionAnswering(TFCamembertPreTrainedModel, TFQuestionAnsweringLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta = TFCamembertMainLayer(config, add_pooling_layer=False, name="roberta") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(CAMEMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="ydshieh/roberta-base-squad2", - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="' puppet'", - expected_loss=0.86, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """CamemBERT Model with a `language modeling` head on top for CLM fine-tuning.""", CAMEMBERT_START_DOCSTRING -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForCausalLM with Roberta->Camembert, ROBERTA->CAMEMBERT -class TFCamembertForCausalLM(TFCamembertPreTrainedModel, TFCausalLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head.decoder.weight"] - - def __init__(self, config: CamembertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if not config.is_decoder: - logger.warning("If you want to use `TFCamembertLMHeadModel` as a standalone, add `is_decoder=True.`") - - self.roberta = TFCamembertMainLayer(config, add_pooling_layer=False, name="roberta") - self.lm_head = TFCamembertLMHead(config, input_embeddings=self.roberta.embeddings, name="lm_head") - - def get_lm_head(self): - return self.lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertLMHeadModel.prepare_inputs_for_generation - def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): - input_shape = input_ids.shape - # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly - if attention_mask is None: - attention_mask = tf.ones(input_shape) - - # cut decoder_input_ids if past is used - if past_key_values is not None: - input_ids = input_ids[:, -1:] - - return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} - - @unpack_inputs - @add_start_docstrings_to_model_forward(CAMEMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutputWithCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFCausalLMOutputWithCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - outputs = self.roberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - logits = self.lm_head(hidden_states=sequence_output, training=training) - loss = None - - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels=labels, logits=shifted_logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithCrossAttentions( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -__all__ = [ - "TFCamembertForCausalLM", - "TFCamembertForMaskedLM", - "TFCamembertForMultipleChoice", - "TFCamembertForQuestionAnswering", - "TFCamembertForSequenceClassification", - "TFCamembertForTokenClassification", - "TFCamembertModel", - "TFCamembertPreTrainedModel", -] diff --git a/src/transformers/models/canine/convert_canine_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/canine/convert_canine_original_tf_checkpoint_to_pytorch.py index 45dcdb290333..5c18f64dba1c 100644 --- a/src/transformers/models/canine/convert_canine_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/canine/convert_canine_original_tf_checkpoint_to_pytorch.py @@ -15,14 +15,115 @@ """Convert CANINE checkpoint.""" import argparse +import os -from transformers import CanineConfig, CanineModel, CanineTokenizer, load_tf_weights_in_canine +import torch + +from transformers import CanineConfig, CanineModel, CanineTokenizer from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +def load_tf_weights_in_canine(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array) + + for name, array in zip(names, arrays): + name = name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + # also discard the cls weights (which were used for the next sentence prediction pre-training task) + if any( + n + in [ + "adam_v", + "adam_m", + "AdamWeightDecayOptimizer", + "AdamWeightDecayOptimizer_1", + "global_step", + "cls", + "autoregressive_decoder", + "char_output_weights", + ] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + continue + # if first scope name starts with "bert", change it to "encoder" + if name[0] == "bert": + name[0] = "encoder" + # remove "embeddings" middle name of HashBucketCodepointEmbedders + elif name[1] == "embeddings": + name.remove(name[1]) + # rename segment_embeddings to token_type_embeddings + elif name[1] == "segment_embeddings": + name[1] = "token_type_embeddings" + # rename initial convolutional projection layer + elif name[1] == "initial_char_encoder": + name = ["chars_to_molecules"] + name[-2:] + # rename final convolutional projection layer + elif name[0] == "final_char_encoder" and name[1] in ["LayerNorm", "conv"]: + name = ["projection"] + name[1:] + pointer = model + for m_name in name: + if (re.fullmatch(r"[A-Za-z]+_\d+", m_name)) and "Embedder" not in m_name: + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "kernel" or scope_names[0] == "gamma": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights": + pointer = getattr(pointer, "weight") + else: + try: + pointer = getattr(pointer, scope_names[0]) + except AttributeError: + logger.info(f"Skipping {'/'.join(name)}") + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if m_name[-11:] == "_embeddings": + pointer = getattr(pointer, "weight") + elif m_name[-10:] in [f"Embedder_{i}" for i in range(8)]: + pointer = getattr(pointer, "weight") + elif m_name == "kernel": + array = np.transpose(array) + + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + return model + + def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, pytorch_dump_path): # Initialize PyTorch model config = CanineConfig() diff --git a/src/transformers/models/canine/modeling_canine.py b/src/transformers/models/canine/modeling_canine.py index 585961180f9e..545919dc7b77 100644 --- a/src/transformers/models/canine/modeling_canine.py +++ b/src/transformers/models/canine/modeling_canine.py @@ -16,7 +16,6 @@ import copy import math -import os from dataclasses import dataclass from typing import Optional, Union @@ -84,103 +83,6 @@ class CanineModelOutputWithPooling(ModelOutput): attentions: Optional[tuple[torch.FloatTensor]] = None -def load_tf_weights_in_canine(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - # also discard the cls weights (which were used for the next sentence prediction pre-training task) - if any( - n - in [ - "adam_v", - "adam_m", - "AdamWeightDecayOptimizer", - "AdamWeightDecayOptimizer_1", - "global_step", - "cls", - "autoregressive_decoder", - "char_output_weights", - ] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - # if first scope name starts with "bert", change it to "encoder" - if name[0] == "bert": - name[0] = "encoder" - # remove "embeddings" middle name of HashBucketCodepointEmbedders - elif name[1] == "embeddings": - name.remove(name[1]) - # rename segment_embeddings to token_type_embeddings - elif name[1] == "segment_embeddings": - name[1] = "token_type_embeddings" - # rename initial convolutional projection layer - elif name[1] == "initial_char_encoder": - name = ["chars_to_molecules"] + name[-2:] - # rename final convolutional projection layer - elif name[0] == "final_char_encoder" and name[1] in ["LayerNorm", "conv"]: - name = ["projection"] + name[1:] - pointer = model - for m_name in name: - if (re.fullmatch(r"[A-Za-z]+_\d+", m_name)) and "Embedder" not in m_name: - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name[-10:] in [f"Embedder_{i}" for i in range(8)]: - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class CanineEmbeddings(nn.Module): """Construct the character, position and token_type embeddings.""" @@ -197,8 +99,6 @@ def __init__(self, config): self.char_position_embeddings = nn.Embedding(config.num_hash_buckets, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -296,8 +196,6 @@ def __init__(self, config): ) self.activation = ACT2FN[config.hidden_act] - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) def forward(self, char_encoding: torch.Tensor) -> torch.Tensor: @@ -344,8 +242,6 @@ def __init__(self, config): stride=1, ) self.activation = ACT2FN[config.hidden_act] - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -873,15 +769,12 @@ def forward( @auto_docstring class CaninePreTrainedModel(PreTrainedModel): config: CanineConfig - load_tf_weights = load_tf_weights_in_canine base_model_prefix = "canine" supports_gradient_checkpointing = True def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv1d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1545,5 +1438,4 @@ def forward( "CanineLayer", "CanineModel", "CaninePreTrainedModel", - "load_tf_weights_in_canine", ] diff --git a/src/transformers/models/chameleon/image_processing_chameleon.py b/src/transformers/models/chameleon/image_processing_chameleon.py index 9cae9d7bdd34..484ce53e729c 100644 --- a/src/transformers/models/chameleon/image_processing_chameleon.py +++ b/src/transformers/models/chameleon/image_processing_chameleon.py @@ -218,10 +218,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -252,10 +250,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/chameleon/processing_chameleon.py b/src/transformers/models/chameleon/processing_chameleon.py index d481a62b6fc6..bf4441c00a2e 100644 --- a/src/transformers/models/chameleon/processing_chameleon.py +++ b/src/transformers/models/chameleon/processing_chameleon.py @@ -114,10 +114,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/chinese_clip/configuration_chinese_clip.py b/src/transformers/models/chinese_clip/configuration_chinese_clip.py index e7c98d0d2d9f..5b9c31965585 100644 --- a/src/transformers/models/chinese_clip/configuration_chinese_clip.py +++ b/src/transformers/models/chinese_clip/configuration_chinese_clip.py @@ -16,12 +16,11 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from ...processing_utils import ProcessorMixin - from ...utils import TensorType from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig @@ -405,13 +404,15 @@ def generate_dummy_inputs( processor: "ProcessorMixin", batch_size: int = -1, seq_length: int = -1, - framework: Optional["TensorType"] = None, ) -> Mapping[str, Any]: text_input_dict = super().generate_dummy_inputs( - processor.tokenizer, batch_size=batch_size, seq_length=seq_length, framework=framework + processor.tokenizer, + batch_size=batch_size, + seq_length=seq_length, ) image_input_dict = super().generate_dummy_inputs( - processor.image_processor, batch_size=batch_size, framework=framework + processor.image_processor, + batch_size=batch_size, ) return {**text_input_dict, **image_input_dict} diff --git a/src/transformers/models/chinese_clip/image_processing_chinese_clip.py b/src/transformers/models/chinese_clip/image_processing_chinese_clip.py index c55805f28913..1ada2c715669 100644 --- a/src/transformers/models/chinese_clip/image_processing_chinese_clip.py +++ b/src/transformers/models/chinese_clip/image_processing_chinese_clip.py @@ -219,10 +219,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -253,10 +251,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/chinese_clip/modeling_chinese_clip.py b/src/transformers/models/chinese_clip/modeling_chinese_clip.py index a0b461ab3ed3..a689886abc37 100644 --- a/src/transformers/models/chinese_clip/modeling_chinese_clip.py +++ b/src/transformers/models/chinese_clip/modeling_chinese_clip.py @@ -98,8 +98,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized diff --git a/src/transformers/models/clap/feature_extraction_clap.py b/src/transformers/models/clap/feature_extraction_clap.py index e333248c18ed..75c79c4e3834 100644 --- a/src/transformers/models/clap/feature_extraction_clap.py +++ b/src/transformers/models/clap/feature_extraction_clap.py @@ -290,7 +290,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.np.array` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/clap/modeling_clap.py b/src/transformers/models/clap/modeling_clap.py index 9d81a26581dd..b8983eecf035 100644 --- a/src/transformers/models/clap/modeling_clap.py +++ b/src/transformers/models/clap/modeling_clap.py @@ -1008,8 +1008,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized diff --git a/src/transformers/models/clip/__init__.py b/src/transformers/models/clip/__init__.py index 18a4db32e994..36fb3521a93e 100644 --- a/src/transformers/models/clip/__init__.py +++ b/src/transformers/models/clip/__init__.py @@ -23,8 +23,6 @@ from .image_processing_clip import * from .image_processing_clip_fast import * from .modeling_clip import * - from .modeling_flax_clip import * - from .modeling_tf_clip import * from .processing_clip import * from .tokenization_clip import * from .tokenization_clip_fast import * diff --git a/src/transformers/models/clip/configuration_clip.py b/src/transformers/models/clip/configuration_clip.py index 0b4fe6ba37f6..22c245485a0d 100644 --- a/src/transformers/models/clip/configuration_clip.py +++ b/src/transformers/models/clip/configuration_clip.py @@ -16,12 +16,11 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from ...processing_utils import ProcessorMixin - from ...utils import TensorType from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig @@ -393,13 +392,15 @@ def generate_dummy_inputs( processor: "ProcessorMixin", batch_size: int = -1, seq_length: int = -1, - framework: Optional["TensorType"] = None, ) -> Mapping[str, Any]: text_input_dict = super().generate_dummy_inputs( - processor.tokenizer, batch_size=batch_size, seq_length=seq_length, framework=framework + processor.tokenizer, + batch_size=batch_size, + seq_length=seq_length, ) image_input_dict = super().generate_dummy_inputs( - processor.image_processor, batch_size=batch_size, framework=framework + processor.image_processor, + batch_size=batch_size, ) return {**text_input_dict, **image_input_dict} diff --git a/src/transformers/models/clip/image_processing_clip.py b/src/transformers/models/clip/image_processing_clip.py index ea17e4a65ff4..ca5e00579f68 100644 --- a/src/transformers/models/clip/image_processing_clip.py +++ b/src/transformers/models/clip/image_processing_clip.py @@ -253,10 +253,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -289,10 +287,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/clip/modeling_flax_clip.py b/src/transformers/models/clip/modeling_flax_clip.py deleted file mode 100644 index 0394974d0647..000000000000 --- a/src/transformers/models/clip/modeling_flax_clip.py +++ /dev/null @@ -1,1306 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The OpenAI Team Authors, The Google Flax Team Authors and 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. - -from typing import Any, Optional, Union - -import flax -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxBaseModelOutputWithPooling -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import ModelOutput, add_start_docstrings, logging -from .configuration_clip import CLIPConfig, CLIPTextConfig, CLIPVisionConfig - - -logger = logging.get_logger(__name__) - -CLIP_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`CLIPConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -CLIP_TEXT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -CLIP_VISION_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`numpy.ndarray` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using - [`AutoImageProcessor`]. See [`CLIPImageProcessor.__call__`] for details. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -CLIP_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - pixel_values (`numpy.ndarray` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using - [`AutoImageProcessor`]. See [`CLIPImageProcessor.__call__`] for details. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@flax.struct.dataclass -class FlaxCLIPTextModelOutput(ModelOutput): - """ - Base class for text model's outputs that also contains a pooling of the last hidden states. - - Args: - text_embeds (`jnp.ndarray` of shape `(batch_size, output_dim`): - The text embeddings obtained by applying the projection layer to the pooled output of - [`FlaxCLIPTextModel`]. - last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - text_embeds: jnp.ndarray = None - last_hidden_state: jnp.ndarray = None - hidden_states: Optional[tuple[jnp.ndarray, ...]] = None - attentions: Optional[tuple[jnp.ndarray, ...]] = None - - -@flax.struct.dataclass -class FlaxCLIPOutput(ModelOutput): - """ - Args: - logits_per_image:(`jnp.ndarray` of shape `(image_batch_size, text_batch_size)`): - The scaled dot product scores between `image_embeds` and `text_embeds`. This represents the image-text - similarity scores. - logits_per_text:(`jnp.ndarray` of shape `(text_batch_size, image_batch_size)`): - The scaled dot product scores between `text_embeds` and `image_embeds`. This represents the text-image - similarity scores. - text_embeds(`jnp.ndarray` of shape `(batch_size, output_dim`): - The text embeddings obtained by applying the projection layer to the pooled output of - [`FlaxCLIPTextModel`]. - image_embeds(`jnp.ndarray` of shape `(batch_size, output_dim`): - The image embeddings obtained by applying the projection layer to the pooled output of - [`FlaxCLIPVisionModel`]. - text_model_output(`FlaxBaseModelOutputWithPooling`): - The output of the [`FlaxCLIPTextModel`]. - vision_model_output(`FlaxBaseModelOutputWithPooling`): - The output of the [`FlaxCLIPVisionModel`]. - """ - - logits_per_image: jnp.ndarray = None - logits_per_text: jnp.ndarray = None - text_embeds: jnp.ndarray = None - image_embeds: jnp.ndarray = None - text_model_output: FlaxBaseModelOutputWithPooling = None - vision_model_output: FlaxBaseModelOutputWithPooling = None - - def to_tuple(self) -> tuple[Any]: - return tuple( - self[k] if k not in ["text_model_output", "vision_model_output"] else getattr(self, k).to_tuple() - for k in self.keys() - ) - - -class FlaxCLIPVisionEmbeddings(nn.Module): - config: CLIPVisionConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - embed_dim = self.config.hidden_size - image_size = self.config.image_size - patch_size = self.config.patch_size - - self.class_embedding = self.param("class_embedding", jax.nn.initializers.normal(stddev=0.02), (embed_dim,)) - - self.patch_embedding = nn.Conv( - embed_dim, - kernel_size=(patch_size, patch_size), - strides=(patch_size, patch_size), - padding="VALID", - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(), - ) - - self.num_patches = (image_size // patch_size) ** 2 - num_positions = self.num_patches + 1 - self.position_embedding = nn.Embed(num_positions, embed_dim, embedding_init=jax.nn.initializers.normal()) - self.position_ids = jnp.expand_dims(jnp.arange(0, num_positions, dtype="i4"), axis=0) - - def __call__(self, pixel_values): - patch_embeds = self.patch_embedding(pixel_values) - batch_size, height, width, channels = patch_embeds.shape - patch_embeds = jnp.reshape(patch_embeds, (batch_size, height * width, channels)) - - class_embeds = jnp.expand_dims(self.class_embedding, axis=(0, 1)) - class_embeds = jnp.tile(class_embeds, (batch_size, 1, 1)) - embeddings = jnp.concatenate([class_embeds, patch_embeds], axis=1) - embeddings = embeddings + self.position_embedding(self.position_ids) - return embeddings - - -class FlaxCLIPTextEmbeddings(nn.Module): - config: CLIPTextConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - embed_dim = self.config.hidden_size - - self.token_embedding = nn.Embed(self.config.vocab_size, embed_dim, embedding_init=jax.nn.initializers.normal()) - self.position_embedding = nn.Embed( - self.config.max_position_embeddings, embed_dim, embedding_init=jax.nn.initializers.normal() - ) - self.position_ids = jnp.expand_dims( - jnp.arange(0, self.config.max_position_embeddings, dtype="i4"), axis=(0, 1) - ) - - def __call__(self, input_ids, position_ids): - input_embeds = self.token_embedding(input_ids.astype("i4")) - position_embeds = self.position_embedding(position_ids.astype("i4")) - - embeddings = input_embeds + position_embeds - return embeddings - - -class FlaxCLIPAttention(nn.Module): - config: Union[CLIPTextConfig, CLIPVisionConfig] - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.embed_dim = self.config.hidden_size - self.num_heads = self.config.num_attention_heads - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" - f" {self.num_heads})." - ) - self.scale = self.head_dim**-0.5 - self.dropout = self.config.attention_dropout - - self.k_proj = nn.Dense(self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(0.01)) - self.v_proj = nn.Dense(self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(0.01)) - self.q_proj = nn.Dense(self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(0.01)) - self.out_proj = nn.Dense(self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(0.01)) - - self.causal = isinstance(self.config, CLIPTextConfig) - if self.causal: - self.causal_mask = make_causal_mask(jnp.ones((1, self.config.max_position_embeddings), dtype="i4")) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - def __call__( - self, - hidden_states, - attention_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - ): - query = self.q_proj(hidden_states) - key = self.k_proj(hidden_states) - value = self.v_proj(hidden_states) - - query = self._split_heads(query) - key = self._split_heads(key) - value = self._split_heads(value) - - causal_attention_mask = None - if self.causal: - query_length, key_length = query.shape[1], key.shape[1] - causal_attention_mask = self.causal_mask[:, :, key_length - query_length : key_length, :key_length] - - if attention_mask is not None and causal_attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - attention_mask = combine_masks(attention_mask, causal_attention_mask, dtype="i4") - elif causal_attention_mask is not None: - attention_mask = causal_attention_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - if attention_mask is not None: - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query, - key, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxCLIPMLP(nn.Module): - config: Union[CLIPTextConfig, CLIPVisionConfig] - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.activation_fn = ACT2FN[self.config.hidden_act] - self.fc1 = nn.Dense( - self.config.intermediate_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(0.01), - ) - self.fc2 = nn.Dense(self.config.hidden_size, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(0.01)) - - def __call__(self, hidden_states): - hidden_states = self.fc1(hidden_states) - hidden_states = self.activation_fn(hidden_states) - hidden_states = self.fc2(hidden_states) - return hidden_states - - -class FlaxCLIPEncoderLayer(nn.Module): - config: Union[CLIPTextConfig, CLIPVisionConfig] - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.self_attn = FlaxCLIPAttention(self.config, dtype=self.dtype) - self.layer_norm1 = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.mlp = FlaxCLIPMLP(self.config, dtype=self.dtype) - self.layer_norm2 = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - ): - residual = hidden_states - - hidden_states = self.layer_norm1(hidden_states) - attn_outputs = self.self_attn( - hidden_states=hidden_states, - attention_mask=attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - ) - hidden_states = attn_outputs[0] - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.layer_norm2(hidden_states) - hidden_states = self.mlp(hidden_states) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += attn_outputs[1:] - - return outputs - - -class FlaxCLIPLayerCollection(nn.Module): - config: Union[CLIPTextConfig, CLIPVisionConfig] - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.layers = [ - FlaxCLIPEncoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for layer in self.layers: - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer( - hidden_states, attention_mask, deterministic=deterministic, output_attentions=output_attentions - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states,) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -class FlaxCLIPEncoder(nn.Module): - config: Union[CLIPTextConfig, CLIPVisionConfig] - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.layers = FlaxCLIPLayerCollection(self.config, dtype=self.dtype) - - def __call__( - self, - inputs_embeds, - attention_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.layers( - hidden_states=inputs_embeds, - attention_mask=attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -class FlaxCLIPTextTransformer(nn.Module): - config: CLIPTextConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.embeddings = FlaxCLIPTextEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxCLIPEncoder(self.config, dtype=self.dtype) - self.final_layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - # For `pooled_output` computation - self.eos_token_id = self.config.eos_token_id - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - hidden_states = self.embeddings(input_ids=input_ids, position_ids=position_ids) - - encoder_outputs = self.encoder( - inputs_embeds=hidden_states, - attention_mask=attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - last_hidden_state = encoder_outputs[0] - last_hidden_state = self.final_layer_norm(last_hidden_state) - - if self.eos_token_id == 2: - # The `eos_token_id` was incorrect before PR #24773: Let's keep what have been done here. - # A CLIP model with such `eos_token_id` in the config can't work correctly with extra new tokens added - # ------------------------------------------------------------ - # text_embeds.shape = [batch_size, sequence_length, transformer.width] - # take features from the EOS embedding (eos_token_id is the highest number in each sequence) - pooled_output = last_hidden_state[jnp.arange(last_hidden_state.shape[0]), input_ids.argmax(axis=-1)] - else: - # (no need to cast from bool to int after comparing to `eos_token_id`) - pooled_output = last_hidden_state[ - jnp.arange(last_hidden_state.shape[0]), (input_ids == self.eos_token_id).argmax(axis=-1) - ] - - if not return_dict: - return (last_hidden_state, pooled_output) + encoder_outputs[1:] - - return FlaxBaseModelOutputWithPooling( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - -class FlaxCLIPVisionTransformer(nn.Module): - config: CLIPVisionConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.embeddings = FlaxCLIPVisionEmbeddings(self.config, dtype=self.dtype) - self.pre_layrnorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.encoder = FlaxCLIPEncoder(self.config, dtype=self.dtype) - self.post_layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__( - self, - pixel_values=None, - deterministic: bool = True, - output_attentions=None, - output_hidden_states=None, - return_dict: bool = True, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - hidden_states = self.embeddings(pixel_values) - hidden_states = self.pre_layrnorm(hidden_states) - - encoder_outputs = self.encoder( - inputs_embeds=hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - last_hidden_state = encoder_outputs[0] - pooled_output = last_hidden_state[:, 0, :] - pooled_output = self.post_layernorm(pooled_output) - - if not return_dict: - return (last_hidden_state, pooled_output) + encoder_outputs[1:] - - return FlaxBaseModelOutputWithPooling( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - -class FlaxCLIPTextPreTrainedModel(FlaxPreTrainedModel): - config_class = CLIPTextConfig - module_class: nn.Module = None - - def __init__( - self, - config: CLIPTextConfig, - input_shape=(1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensor - input_ids = jnp.zeros(input_shape, dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - attention_mask = jnp.ones_like(input_ids) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, input_ids, attention_mask, position_ids)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - -class FlaxCLIPVisionPreTrainedModel(FlaxPreTrainedModel): - config_class = CLIPVisionConfig - main_input_name = "pixel_values" - module_class: nn.Module = None - - def __init__( - self, - config: CLIPVisionConfig, - input_shape: Optional[tuple] = None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - if input_shape is None: - input_shape = (1, config.image_size, config.image_size, 3) - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensor - pixel_values = jax.random.normal(rng, input_shape) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, pixel_values)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def __call__( - self, - pixel_values, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(pixel_values, dtype=jnp.float32), - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - -class FlaxCLIPPreTrainedModel(FlaxPreTrainedModel): - config_class = CLIPConfig - module_class: nn.Module = None - - def __init__( - self, - config: CLIPConfig, - input_shape: Optional[tuple] = None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - if input_shape is None: - input_shape = ((1, 1), (1, config.vision_config.image_size, config.vision_config.image_size, 3)) - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensor - input_ids = jnp.zeros(input_shape[0], dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape[0]) - attention_mask = jnp.ones_like(input_ids) - - pixel_values = jax.random.normal(rng, input_shape[1]) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, input_ids, pixel_values, attention_mask, position_ids)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def __call__( - self, - input_ids, - pixel_values, - attention_mask=None, - position_ids=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(input_ids, dtype="i4"), - jnp.array(pixel_values, dtype=jnp.float32), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - def get_text_features( - self, - input_ids, - attention_mask=None, - position_ids=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train=False, - ): - r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - - Returns: - text_features (`jnp.ndarray` of shape `(batch_size, output_dim`): The text embeddings obtained by applying - the projection layer to the pooled output of [`FlaxCLIPTextModel`]. - - Examples: - - ```python - >>> from transformers import AutoTokenizer, FlaxCLIPModel - - >>> model = FlaxCLIPModel.from_pretrained("openai/clip-vit-base-patch32") - >>> tokenizer = AutoTokenizer.from_pretrained("openai/clip-vit-base-patch32") - - >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="np") - >>> text_features = model.get_text_features(**inputs) - ```""" - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _get_features(module, input_ids, attention_mask, position_ids, deterministic): - text_outputs = module.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - ) - pooled_output = text_outputs[1] - text_features = module.text_projection(pooled_output) - return text_features - - return self.module.apply( - {"params": params or self.params}, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - not train, - method=_get_features, - rngs=rngs, - ) - - def get_image_features( - self, pixel_values, params: Optional[dict] = None, dropout_rng: jax.random.PRNGKey = None, train=False - ): - r""" - Args: - pixel_values (`numpy.ndarray` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained - using [`AutoImageProcessor`]. See [`CLIPImageProcessor.__call__`] for details. - - Returns: - image_features (`jnp.ndarray` of shape `(batch_size, output_dim`): The image embeddings obtained by - applying the projection layer to the pooled output of [`FlaxCLIPVisionModel`] - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, FlaxCLIPModel - - >>> model = FlaxCLIPModel.from_pretrained("openai/clip-vit-base-patch32") - >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor(images=image, return_tensors="np") - - >>> image_features = model.get_image_features(**inputs) - ```""" - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _get_features(module, pixel_values, deterministic): - vision_outputs = module.vision_model(pixel_values=pixel_values, deterministic=deterministic) - pooled_output = vision_outputs[1] # pooled_output - image_features = module.visual_projection(pooled_output) - return image_features - - return self.module.apply( - {"params": params or self.params}, - jnp.array(pixel_values, dtype=jnp.float32), - not train, - method=_get_features, - rngs=rngs, - ) - - -class FlaxCLIPTextModule(nn.Module): - config: CLIPTextConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.text_model = FlaxCLIPTextTransformer(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -class FlaxCLIPTextModel(FlaxCLIPTextPreTrainedModel): - module_class = FlaxCLIPTextModule - - -FLAX_CLIP_TEXT_MODEL_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxCLIPTextModel - - >>> model = FlaxCLIPTextModel.from_pretrained("openai/clip-vit-base-patch32") - >>> tokenizer = AutoTokenizer.from_pretrained("openai/clip-vit-base-patch32") - - >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="np") - - >>> outputs = model(**inputs) - >>> last_hidden_state = outputs.last_hidden_state - >>> pooler_output = outputs.pooler_output # pooled (EOS token) states - ``` -""" - -overwrite_call_docstring(FlaxCLIPTextModel, CLIP_TEXT_INPUTS_DOCSTRING + FLAX_CLIP_TEXT_MODEL_DOCSTRING) -append_replace_return_docstrings( - FlaxCLIPTextModel, output_type=FlaxBaseModelOutputWithPooling, config_class=CLIPTextConfig -) - - -class FlaxCLIPTextModelWithProjectionModule(nn.Module): - config: CLIPTextConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.text_model = FlaxCLIPTextTransformer(self.config, dtype=self.dtype) - self.text_projection = nn.Dense(self.config.projection_dim, use_bias=False, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - text_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = text_outputs[1] - text_embeds = self.text_projection(pooled_output) - - if not return_dict: - return (text_embeds, text_outputs[0]) + text_outputs[2:] - - return FlaxCLIPTextModelOutput( - text_embeds=text_embeds, - last_hidden_state=text_outputs.last_hidden_state, - hidden_states=text_outputs.hidden_states, - attentions=text_outputs.attentions, - ) - - -class FlaxCLIPTextModelWithProjection(FlaxCLIPTextPreTrainedModel): - module_class = FlaxCLIPTextModelWithProjectionModule - - -FLAX_CLIP_TEXT_MODEL_WITH_PROJECTION_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxCLIPTextModelWithProjection - - >>> model = FlaxCLIPTextModelWithProjection.from_pretrained("openai/clip-vit-base-patch32") - >>> tokenizer = AutoTokenizer.from_pretrained("openai/clip-vit-base-patch32") - - >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="np") - - >>> outputs = model(**inputs) - >>> text_embeds = outputs.text_embeds - ``` -""" - -overwrite_call_docstring( - FlaxCLIPTextModelWithProjection, CLIP_TEXT_INPUTS_DOCSTRING + FLAX_CLIP_TEXT_MODEL_WITH_PROJECTION_DOCSTRING -) -append_replace_return_docstrings( - FlaxCLIPTextModelWithProjection, output_type=FlaxCLIPTextModelOutput, config_class=CLIPTextConfig -) - - -class FlaxCLIPVisionModule(nn.Module): - config: CLIPVisionConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.vision_model = FlaxCLIPVisionTransformer(self.config, dtype=self.dtype) - - def __call__( - self, - pixel_values, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.vision_model( - pixel_values=pixel_values, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -class FlaxCLIPVisionModel(FlaxCLIPVisionPreTrainedModel): - module_class = FlaxCLIPVisionModule - - -FLAX_CLIP_VISION_MODEL_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, FlaxCLIPVisionModel - - >>> model = FlaxCLIPVisionModel.from_pretrained("openai/clip-vit-base-patch32") - >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor(images=image, return_tensors="np") - - >>> outputs = model(**inputs) - >>> last_hidden_state = outputs.last_hidden_state - >>> pooler_output = outputs.pooler_output # pooled CLS states - ``` -""" - -overwrite_call_docstring(FlaxCLIPVisionModel, CLIP_VISION_INPUTS_DOCSTRING + FLAX_CLIP_VISION_MODEL_DOCSTRING) -append_replace_return_docstrings( - FlaxCLIPVisionModel, output_type=FlaxBaseModelOutputWithPooling, config_class=CLIPVisionConfig -) - - -class FlaxCLIPModule(nn.Module): - config: CLIPConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - text_config = self.config.text_config - vision_config = self.config.vision_config - - self.projection_dim = self.config.projection_dim - self.text_embed_dim = text_config.hidden_size - self.vision_embed_dim = vision_config.hidden_size - - self.text_model = FlaxCLIPTextTransformer(text_config, dtype=self.dtype) - self.vision_model = FlaxCLIPVisionTransformer(vision_config, dtype=self.dtype) - - self.visual_projection = nn.Dense( - self.projection_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(0.02), - use_bias=False, - ) - self.text_projection = nn.Dense( - self.projection_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(0.02), - use_bias=False, - ) - - self.logit_scale = self.param( - "logit_scale", lambda _, shape: jnp.ones(shape) * self.config.logit_scale_init_value, [] - ) - - def __call__( - self, - input_ids=None, - pixel_values=None, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - ): - return_dict = return_dict if return_dict is not None else self.config.return_dict - - vision_outputs = self.vision_model( - pixel_values=pixel_values, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - text_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - image_embeds = vision_outputs[1] - image_embeds = self.visual_projection(image_embeds) - - text_embeds = text_outputs[1] - text_embeds = self.text_projection(text_embeds) - - # normalized features - image_embeds = image_embeds / jnp.linalg.norm(image_embeds, axis=-1, keepdims=True) - text_embeds = text_embeds / jnp.linalg.norm(text_embeds, axis=-1, keepdims=True) - - # cosine similarity as logits - logit_scale = jnp.exp(self.logit_scale) - logits_per_text = jnp.matmul(text_embeds, image_embeds.T) * logit_scale - logits_per_image = logits_per_text.T - - if not return_dict: - return (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs) - - return FlaxCLIPOutput( - logits_per_image=logits_per_image, - logits_per_text=logits_per_text, - text_embeds=text_embeds, - image_embeds=image_embeds, - text_model_output=text_outputs, - vision_model_output=vision_outputs, - ) - - -@add_start_docstrings(CLIP_START_DOCSTRING) -class FlaxCLIPModel(FlaxCLIPPreTrainedModel): - module_class = FlaxCLIPModule - - -FLAX_CLIP_MODEL_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> import jax - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, FlaxCLIPModel - - >>> model = FlaxCLIPModel.from_pretrained("openai/clip-vit-base-patch32") - >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor( - ... text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="np", padding=True - ... ) - - >>> outputs = model(**inputs) - >>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score - >>> probs = jax.nn.softmax(logits_per_image, axis=1) # we can take the softmax to get the label probabilities - ``` -""" - -overwrite_call_docstring(FlaxCLIPModel, CLIP_INPUTS_DOCSTRING + FLAX_CLIP_MODEL_DOCSTRING) -append_replace_return_docstrings(FlaxCLIPModel, output_type=FlaxCLIPOutput, config_class=CLIPConfig) - - -__all__ = [ - "FlaxCLIPModel", - "FlaxCLIPPreTrainedModel", - "FlaxCLIPTextModel", - "FlaxCLIPTextPreTrainedModel", - "FlaxCLIPTextModelWithProjection", - "FlaxCLIPVisionModel", - "FlaxCLIPVisionPreTrainedModel", -] diff --git a/src/transformers/models/clip/modeling_tf_clip.py b/src/transformers/models/clip/modeling_tf_clip.py deleted file mode 100644 index ab2e38827998..000000000000 --- a/src/transformers/models/clip/modeling_tf_clip.py +++ /dev/null @@ -1,1460 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The OpenAI Team Authors and The HuggingFace Team. All rights reserved. -# -# 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. -"""TF 2.0 CLIP model.""" - -from __future__ import annotations - -import math -from dataclasses import dataclass -from typing import Any - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import TFBaseModelOutput, TFBaseModelOutputWithPooling - -# Public API -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_clip import CLIPConfig, CLIPTextConfig, CLIPVisionConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "openai/clip-vit-base-patch32" - - -LARGE_NEGATIVE = -1e8 - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -# contrastive loss function, adapted from -# https://sachinruk.github.io/blog/pytorch/pytorch%20lightning/loss%20function/gpu/2021/03/07/CLIP.html -def contrastive_loss(logits: tf.Tensor) -> tf.Tensor: - return tf.math.reduce_mean( - keras.metrics.sparse_categorical_crossentropy( - y_true=tf.range(shape_list(logits)[0]), y_pred=logits, from_logits=True - ) - ) - - -def clip_loss(similarity: tf.Tensor) -> tf.Tensor: - caption_loss = contrastive_loss(similarity) - image_loss = contrastive_loss(tf.transpose(similarity)) - return (caption_loss + image_loss) / 2.0 - - -@dataclass -class TFCLIPOutput(ModelOutput): - """ - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `return_loss` is `True`): - Contrastive loss for image-text similarity. - logits_per_image:(`tf.Tensor` of shape `(image_batch_size, text_batch_size)`): - The scaled dot product scores between `image_embeds` and `text_embeds`. This represents the image-text - similarity scores. - logits_per_text:(`tf.Tensor` of shape `(text_batch_size, image_batch_size)`): - The scaled dot product scores between `text_embeds` and `image_embeds`. This represents the text-image - similarity scores. - text_embeds(`tf.Tensor` of shape `(batch_size, output_dim`): - The text embeddings obtained by applying the projection layer to the pooled output of [`TFCLIPTextModel`]. - image_embeds(`tf.Tensor` of shape `(batch_size, output_dim`): - The image embeddings obtained by applying the projection layer to the pooled output of - [`TFCLIPVisionModel`]. - text_model_output([`~modeling_tf_utils.TFBaseModelOutputWithPooling`]): - The output of the [`TFCLIPTextModel`]. - vision_model_output([`~modeling_tf_utils.TFBaseModelOutputWithPooling`]): - The output of the [`TFCLIPVisionModel`]. - """ - - loss: tf.Tensor | None = None - logits_per_image: tf.Tensor | None = None - logits_per_text: tf.Tensor | None = None - text_embeds: tf.Tensor | None = None - image_embeds: tf.Tensor | None = None - text_model_output: TFBaseModelOutputWithPooling = None - vision_model_output: TFBaseModelOutputWithPooling = None - - def to_tuple(self) -> tuple[Any]: - return tuple( - self[k] if k not in ["text_model_output", "vision_model_output"] else getattr(self, k).to_tuple() - for k in self.keys() - ) - - -class TFCLIPVisionEmbeddings(keras.layers.Layer): - def __init__(self, config: CLIPVisionConfig, **kwargs): - super().__init__(**kwargs) - - self.embed_dim = config.hidden_size - self.image_size = config.image_size - self.patch_size = config.patch_size - - self.num_patches = (self.image_size // self.patch_size) ** 2 - self.num_positions = self.num_patches + 1 - - self.config = config - - self.patch_embedding = keras.layers.Conv2D( - filters=self.embed_dim, - kernel_size=self.patch_size, - strides=self.patch_size, - padding="valid", - data_format="channels_last", - use_bias=False, - kernel_initializer=get_initializer(self.config.initializer_range * self.config.initializer_factor), - name="patch_embedding", - ) - - def build(self, input_shape: tf.TensorShape = None): - factor = self.config.initializer_factor - - self.class_embedding = self.add_weight( - shape=(self.embed_dim,), - initializer=get_initializer(self.embed_dim**-0.5 * factor), - trainable=True, - name="class_embedding", - ) - - with tf.name_scope("position_embedding"): - self.position_embedding = self.add_weight( - shape=(self.num_positions, self.embed_dim), - initializer=get_initializer(self.config.initializer_range * factor), - trainable=True, - name="embeddings", - ) - - if self.built: - return - self.built = True - if getattr(self, "patch_embedding", None) is not None: - with tf.name_scope(self.patch_embedding.name): - self.patch_embedding.build([None, None, None, self.config.num_channels]) - - def call(self, pixel_values: tf.Tensor) -> tf.Tensor: - """`pixel_values` is expected to be of NCHW format.""" - - batch_size, num_channels, height, width = shape_list(pixel_values) - - # When running on CPU, `tf.nn.conv2d` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - # shape = (batch_size, in_height, in_width, in_channels=num_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - - patch_embeds = self.patch_embedding(pixel_values) - - # Change the 2D spatial dimensions to a single temporal dimension. - # shape = (batch_size, num_patches, out_channels=embed_dim) - patch_embeds = tf.reshape(tensor=patch_embeds, shape=(batch_size, self.num_patches, -1)) - - # add the [CLS] token to the embedded patch tokens - class_embeds = tf.broadcast_to(self.class_embedding, shape=(batch_size, 1, self.embed_dim)) - embeddings = tf.concat((class_embeds, patch_embeds), axis=1) - - embeddings = embeddings + self.position_embedding - - return embeddings - - -class TFCLIPTextEmbeddings(keras.layers.Layer): - def __init__(self, config: CLIPTextConfig, **kwargs): - super().__init__(**kwargs) - - self.embed_dim = config.hidden_size - - self.config = config - - def build(self, input_shape: tf.TensorShape = None): - with tf.name_scope("token_embedding"): - self.weight = self.add_weight( - shape=(self.config.vocab_size, self.embed_dim), - initializer=get_initializer(self.config.initializer_factor * self.config.initializer_range), - trainable=True, - name="weight", - ) - - with tf.name_scope("position_embedding"): - self.position_embedding = self.add_weight( - shape=(self.config.max_position_embeddings, self.embed_dim), - initializer=get_initializer(self.config.initializer_factor * self.config.initializer_range), - trainable=True, - name="embeddings", - ) - - super().build(input_shape) - - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - if input_ids is None and inputs_embeds is None: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) - - position_embeds = tf.gather(params=self.position_embedding, indices=position_ids) - position_embeds = tf.tile(input=position_embeds, multiples=(input_shape[0], 1, 1)) - final_embeddings = inputs_embeds + position_embeds - - return final_embeddings - - -class TFCLIPAttention(keras.layers.Layer): - """Multi-headed attention from 'Attention Is All You Need' paper""" - - def __init__(self, config: CLIPConfig, **kwargs): - super().__init__(**kwargs) - - self.embed_dim = config.hidden_size - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = self.embed_dim // self.num_attention_heads - if self.attention_head_size * self.num_attention_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" - f" {self.num_attention_heads})." - ) - - factor = config.initializer_factor - in_proj_std = (self.embed_dim**-0.5) * ((2 * config.num_hidden_layers) ** -0.5) * factor - out_proj_std = (self.embed_dim**-0.5) * factor - - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.q_proj = keras.layers.Dense( - units=self.embed_dim, kernel_initializer=get_initializer(in_proj_std), name="q_proj" - ) - self.k_proj = keras.layers.Dense( - units=self.embed_dim, kernel_initializer=get_initializer(in_proj_std), name="k_proj" - ) - self.v_proj = keras.layers.Dense( - units=self.embed_dim, kernel_initializer=get_initializer(in_proj_std), name="v_proj" - ) - - self.dropout = keras.layers.Dropout(rate=config.attention_dropout) - - self.out_proj = keras.layers.Dense( - units=self.embed_dim, kernel_initializer=get_initializer(out_proj_std), name="out_proj" - ) - - # copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention.transpose_for_scores - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - causal_attention_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - """Input shape: Batch x Time x Channel""" - - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.q_proj(inputs=hidden_states) - mixed_key_layer = self.k_proj(inputs=hidden_states) - mixed_value_layer = self.v_proj(inputs=hidden_states) - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - # apply the causal_attention_mask first - if causal_attention_mask is not None: - # Apply the causal attention mask (precomputed for all layers in TFCLIPModel call() function) - attention_scores = tf.add(attention_scores, causal_attention_mask) - - if attention_mask is not None: - # Apply the attention mask (precomputed for all layers in TFCLIPModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - _attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=_attention_probs, training=training) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, embed_dim) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.embed_dim)) - - attention_output = self.out_proj(attention_output, training=training) - # In TFBert, attention weights are returned after dropout. - # However, in CLIP, they are returned before dropout. - outputs = (attention_output, _attention_probs) if output_attentions else (attention_output,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -class TFCLIPMLP(keras.layers.Layer): - def __init__(self, config: CLIPConfig, **kwargs): - super().__init__(**kwargs) - - self.activation_fn = get_tf_activation(config.hidden_act) - - factor = config.initializer_factor - in_proj_std = (config.hidden_size**-0.5) * ((2 * config.num_hidden_layers) ** -0.5) * factor - fc_std = (2 * config.hidden_size) ** -0.5 * factor - - self.fc1 = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(fc_std), name="fc1" - ) - self.fc2 = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(in_proj_std), name="fc2" - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.fc1(inputs=hidden_states) - hidden_states = self.activation_fn(hidden_states) - hidden_states = self.fc2(inputs=hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.config.hidden_size]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.intermediate_size]) - - -class TFCLIPEncoderLayer(keras.layers.Layer): - def __init__(self, config: CLIPConfig, **kwargs): - super().__init__(**kwargs) - - self.embed_dim = config.hidden_size - self.self_attn = TFCLIPAttention(config, name="self_attn") - self.layer_norm1 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm1") - self.mlp = TFCLIPMLP(config, name="mlp") - self.layer_norm2 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm2") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - causal_attention_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - causal_attention_mask (`tf.Tensor`): causal attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - output_attentions (`bool`): - Whether or not to return the attentions tensors of all attention layers. See `outputs` under returned - tensors for more detail. - """ - residual = hidden_states - - hidden_states = self.layer_norm1(inputs=hidden_states) - attention_outputs = self.self_attn( - hidden_states=hidden_states, - attention_mask=attention_mask, - causal_attention_mask=causal_attention_mask, - output_attentions=output_attentions, - training=training, - ) - hidden_states = attention_outputs[0] - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.layer_norm2(inputs=hidden_states) - hidden_states = self.mlp(hidden_states=hidden_states) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) + attention_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "layer_norm1", None) is not None: - with tf.name_scope(self.layer_norm1.name): - self.layer_norm1.build([None, None, self.embed_dim]) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "layer_norm2", None) is not None: - with tf.name_scope(self.layer_norm2.name): - self.layer_norm2.build([None, None, self.embed_dim]) - - -class TFCLIPEncoder(keras.layers.Layer): - """ - Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a - [`TFCLIPEncoderLayer`]. - - Args: - config: CLIPConfig - """ - - def __init__(self, config: CLIPConfig, **kwargs): - super().__init__(**kwargs) - - self.layers = [TFCLIPEncoderLayer(config, name=f"layers_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - causal_attention_mask: tf.Tensor, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - for i, layer_module in enumerate(self.layers): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - causal_attention_mask=causal_attention_mask, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFCLIPTextTransformer(keras.layers.Layer): - def __init__(self, config: CLIPTextConfig, **kwargs): - super().__init__(**kwargs) - - self.embeddings = TFCLIPTextEmbeddings(config, name="embeddings") - self.encoder = TFCLIPEncoder(config, name="encoder") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="final_layer_norm") - - # For `pooled_output` computation - self.eos_token_id = config.eos_token_id - self.embed_dim = config.hidden_size - - def call( - self, - input_ids: TFModelInputType, - attention_mask: tf.Tensor, - position_ids: tf.Tensor, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - input_shape = shape_list(input_ids) - - embedding_output = self.embeddings(input_ids=input_ids, position_ids=position_ids) - - batch_size, seq_length = input_shape - # CLIP's text model uses causal mask, prepare it here. - # https://github.com/openai/CLIP/blob/cfcffb90e69f37bf2ff1e988237a0fbe41f33c04/clip/model.py#L324 - causal_attention_mask = self._build_causal_attention_mask(batch_size, seq_length, dtype=embedding_output.dtype) - - # check attention mask and invert - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - attention_mask = _expand_mask(attention_mask) - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=attention_mask, - causal_attention_mask=causal_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - sequence_output = self.final_layer_norm(inputs=sequence_output) - - if self.eos_token_id == 2: - # The `eos_token_id` was incorrect before PR #24773: Let's keep what have been done here. - # A CLIP model with such `eos_token_id` in the config can't work correctly with extra new tokens added - # ------------------------------------------------------------ - # text_embeds.shape = [batch_size, n_ctx, transformer.width] - # take features from the eot embedding (eot_token is the highest number in each sequence) - pooled_output = tf.gather_nd( - params=sequence_output, - indices=tf.stack( - values=(tf.range(input_shape[0], dtype=tf.int64), tf.math.argmax(input_ids, axis=-1)), axis=1 - ), - ) - else: - # The config gets updated `eos_token_id` from PR #24773 (so the use of extra new tokens is possible) - pooled_output = tf.gather_nd( - params=sequence_output, - indices=tf.stack( - values=( - tf.range(input_shape[0], dtype=tf.int64), - tf.math.argmax(tf.cast(input_ids == self.eos_token_id, dtype=tf.int8), axis=-1), - ), - axis=1, - ), - ) - - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def _build_causal_attention_mask(self, batch_size, seq_length, dtype=tf.float32): - # It is possible with an unspecified sequence length for seq_length to be - # a runtime value, which is unsupported by tf.constant. Per the TensorFlow - # docs, tf.fill can handle runtime dynamic shapes: - # https://www.tensorflow.org/api_docs/python/tf/fill - diag = tf.cast(tf.fill((seq_length,), 0.0), dtype) - - # set an additive 2D attention mask with all places being masked - to_mask = tf.cast(tf.fill((seq_length, seq_length), -10000.0), dtype) - - # set diagonal & lower triangular parts to 0 (i.e. the places not to be masked) - # TIP: think the 2D matrix as the space of (query_seq, key_seq) - to_mask = tf.linalg.band_part(to_mask, 0, -1) - # to_mask = tf.linalg.band_part(to_mask, -1, 0) - to_mask = tf.linalg.set_diag(to_mask, diagonal=diag) - - return tf.broadcast_to(input=to_mask, shape=(batch_size, 1, seq_length, seq_length)) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -@keras_serializable -class TFCLIPTextMainLayer(keras.layers.Layer): - config_class = CLIPTextConfig - - def __init__(self, config: CLIPTextConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.text_model = TFCLIPTextTransformer(config, name="text_model") - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.text_model.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.text_model.embeddings.weight = value - self.text_model.embeddings.vocab_size = shape_list(value)[0] - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - if input_ids is None: - raise ValueError("You have to specify input_ids") - - input_shape = shape_list(input_ids) - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - text_model_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return text_model_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "text_model", None) is not None: - with tf.name_scope(self.text_model.name): - self.text_model.build(None) - - -class TFCLIPVisionTransformer(keras.layers.Layer): - def __init__(self, config: CLIPVisionConfig, **kwargs): - super().__init__(**kwargs) - - self.embeddings = TFCLIPVisionEmbeddings(config, name="embeddings") - self.pre_layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="pre_layrnorm") - self.encoder = TFCLIPEncoder(config, name="encoder") - self.post_layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="post_layernorm") - self.embed_dim = config.hidden_size - - def call( - self, - pixel_values: TFModelInputType, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - embedding_output = self.embeddings(pixel_values=pixel_values) - embedding_output = self.pre_layernorm(inputs=embedding_output) - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=None, - causal_attention_mask=None, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = sequence_output[:, 0, :] - pooled_output = self.post_layernorm(inputs=pooled_output) - - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "pre_layernorm", None) is not None: - with tf.name_scope(self.pre_layernorm.name): - self.pre_layernorm.build([None, None, self.embed_dim]) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "post_layernorm", None) is not None: - with tf.name_scope(self.post_layernorm.name): - self.post_layernorm.build([None, self.embed_dim]) - - -@keras_serializable -class TFCLIPVisionMainLayer(keras.layers.Layer): - config_class = CLIPVisionConfig - - def __init__(self, config: CLIPVisionConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.vision_model = TFCLIPVisionTransformer(config, name="vision_model") - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.vision_model.embeddings - - @unpack_inputs - def call( - self, - pixel_values: TFModelInputType | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - vision_model_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return vision_model_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "vision_model", None) is not None: - with tf.name_scope(self.vision_model.name): - self.vision_model.build(None) - - -@keras_serializable -class TFCLIPMainLayer(keras.layers.Layer): - config_class = CLIPConfig - - def __init__(self, config: CLIPConfig, **kwargs): - super().__init__(**kwargs) - - if not isinstance(config.text_config, CLIPTextConfig): - raise TypeError( - "config.text_config is expected to be of type CLIPTextConfig but is of type" - f" {type(config.text_config)}." - ) - - if not isinstance(config.vision_config, CLIPVisionConfig): - raise TypeError( - "config.vision_config is expected to be of type CLIPVisionConfig but is of type" - f" {type(config.vision_config)}." - ) - - self.config = config - - text_config = config.text_config - vision_config = config.vision_config - - self.projection_dim = config.projection_dim - - self.text_model = TFCLIPTextTransformer(text_config, name="text_model") - self.vision_model = TFCLIPVisionTransformer(vision_config, name="vision_model") - - self.visual_projection = keras.layers.Dense( - units=self.projection_dim, - kernel_initializer=get_initializer(vision_config.hidden_size**-0.5 * self.config.initializer_factor), - use_bias=False, - name="visual_projection", - ) - - self.text_projection = keras.layers.Dense( - units=self.projection_dim, - kernel_initializer=get_initializer(text_config.hidden_size**-0.5 * self.config.initializer_factor), - use_bias=False, - name="text_projection", - ) - self.text_embed_dim = text_config.hidden_size - self.vision_embed_dim = vision_config.hidden_size - - def build(self, input_shape: tf.TensorShape = None): - self.logit_scale = self.add_weight( - shape=(1,), - initializer=keras.initializers.Constant(self.config.logit_scale_init_value), - trainable=True, - name="logit_scale", - ) - - if self.built: - return - self.built = True - if getattr(self, "text_model", None) is not None: - with tf.name_scope(self.text_model.name): - self.text_model.build(None) - if getattr(self, "vision_model", None) is not None: - with tf.name_scope(self.vision_model.name): - self.vision_model.build(None) - if getattr(self, "visual_projection", None) is not None: - with tf.name_scope(self.visual_projection.name): - self.visual_projection.build([None, None, self.vision_embed_dim]) - if getattr(self, "text_projection", None) is not None: - with tf.name_scope(self.text_projection.name): - self.text_projection.build([None, None, self.text_embed_dim]) - - @unpack_inputs - def get_text_features( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tf.Tensor: - if input_ids is None: - raise ValueError("You have to specify either input_ids") - - input_shape = shape_list(input_ids) - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - text_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - pooled_output = text_outputs[1] - text_features = self.text_projection(inputs=pooled_output) - - return text_features - - @unpack_inputs - def get_image_features( - self, - pixel_values: TFModelInputType | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tf.Tensor: - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - vision_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - pooled_output = vision_outputs[1] # pooled_output - image_features = self.visual_projection(inputs=pooled_output) - - return image_features - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - pixel_values: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - return_loss: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFCLIPOutput | tuple[tf.Tensor]: - if input_ids is None: - raise ValueError("You have to specify either input_ids") - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - input_shape = shape_list(input_ids) - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - vision_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - text_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - image_embeds = vision_outputs[1] - image_embeds = self.visual_projection(inputs=image_embeds) - - text_embeds = text_outputs[1] - text_embeds = self.text_projection(inputs=text_embeds) - - # normalized features - image_embeds = image_embeds / tf.norm(tensor=image_embeds, ord="euclidean", axis=-1, keepdims=True) - text_embeds = text_embeds / tf.norm(tensor=text_embeds, ord="euclidean", axis=-1, keepdims=True) - - # cosine similarity as logits - logit_scale = tf.math.exp(self.logit_scale) - logits_per_text = tf.matmul(text_embeds, image_embeds, transpose_b=True) * logit_scale - logits_per_image = tf.transpose(logits_per_text) - - loss = None - if return_loss: - loss = clip_loss(logits_per_text) - loss = tf.reshape(loss, (1,)) - - if not return_dict: - output = (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs) - return (loss,) + output if loss is not None else output - - return TFCLIPOutput( - loss=loss, - logits_per_image=logits_per_image, - logits_per_text=logits_per_text, - text_embeds=text_embeds, - image_embeds=image_embeds, - text_model_output=text_outputs, - vision_model_output=vision_outputs, - ) - - -class TFCLIPPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = CLIPConfig - base_model_prefix = "clip" - _keys_to_ignore_on_load_missing = [r"position_ids"] - _keys_to_ignore_on_load_unexpected = [r"position_ids"] - - -CLIP_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`CLIPConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -CLIP_TEXT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - -CLIP_VISION_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`CLIPImageProcessor.__call__`] for details. output_attentions (`bool`, *optional*): Whether or not to - return the attentions tensors of all attention layers. See `attentions` under returned tensors for more - detail. This argument can be used only in eager mode, in graph mode the value in the config will be used - instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - -CLIP_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` `dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`CLIPImageProcessor.__call__`] for details. - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - return_loss (`bool`, *optional*): - Whether or not to return the contrastive loss. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -class TFCLIPTextModel(TFCLIPPreTrainedModel): - config_class = CLIPTextConfig - - def __init__(self, config: CLIPTextConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.clip = TFCLIPTextMainLayer(config, name="clip") - - @unpack_inputs - @add_start_docstrings_to_model_forward(CLIP_TEXT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFBaseModelOutputWithPooling, config_class=CLIPTextConfig) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFCLIPTextModel - - >>> model = TFCLIPTextModel.from_pretrained("openai/clip-vit-base-patch32") - >>> tokenizer = AutoTokenizer.from_pretrained("openai/clip-vit-base-patch32") - - >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="tf") - - >>> outputs = model(**inputs) - >>> last_hidden_state = outputs.last_hidden_state - >>> pooled_output = outputs.pooler_output # pooled (EOS token) states - ```""" - - outputs = self.clip( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "clip", None) is not None: - with tf.name_scope(self.clip.name): - self.clip.build(None) - - -class TFCLIPVisionModel(TFCLIPPreTrainedModel): - config_class = CLIPVisionConfig - main_input_name = "pixel_values" - - def __init__(self, config: CLIPVisionConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.clip = TFCLIPVisionMainLayer(config, name="clip") - - @unpack_inputs - @add_start_docstrings_to_model_forward(CLIP_VISION_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBaseModelOutputWithPooling, config_class=CLIPVisionConfig) - def call( - self, - pixel_values: TFModelInputType | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFCLIPVisionModel - - >>> model = TFCLIPVisionModel.from_pretrained("openai/clip-vit-base-patch32") - >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor(images=image, return_tensors="tf") - - >>> outputs = model(**inputs) - >>> last_hidden_state = outputs.last_hidden_state - >>> pooled_output = outputs.pooler_output # pooled CLS states - ```""" - - outputs = self.clip( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "clip", None) is not None: - with tf.name_scope(self.clip.name): - self.clip.build(None) - - -@add_start_docstrings(CLIP_START_DOCSTRING) -class TFCLIPModel(TFCLIPPreTrainedModel): - config_class = CLIPConfig - - def __init__(self, config: CLIPConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.clip = TFCLIPMainLayer(config, name="clip") - - @unpack_inputs - @add_start_docstrings_to_model_forward(CLIP_TEXT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def get_text_features( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tf.Tensor: - r""" - Returns: - text_features (`tf.Tensor` of shape `(batch_size, output_dim`): The text embeddings obtained by applying - the projection layer to the pooled output of [`TFCLIPTextModel`]. - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFCLIPModel - - >>> model = TFCLIPModel.from_pretrained("openai/clip-vit-base-patch32") - >>> tokenizer = AutoTokenizer.from_pretrained("openai/clip-vit-base-patch32") - - >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="tf") - >>> text_features = model.get_text_features(**inputs) - ```""" - - text_features = self.clip.get_text_features( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - return text_features - - @unpack_inputs - @add_start_docstrings_to_model_forward(CLIP_VISION_INPUTS_DOCSTRING) - def get_image_features( - self, - pixel_values: TFModelInputType | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tf.Tensor: - r""" - Returns: - image_features (`tf.Tensor` of shape `(batch_size, output_dim`): The image embeddings obtained by applying - the projection layer to the pooled output of [`TFCLIPVisionModel`]. - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFCLIPModel - - >>> model = TFCLIPModel.from_pretrained("openai/clip-vit-base-patch32") - >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor(images=image, return_tensors="tf") - - >>> image_features = model.get_image_features(**inputs) - ```""" - - image_features = self.clip.get_image_features( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - return image_features - - @unpack_inputs - @add_start_docstrings_to_model_forward(CLIP_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFCLIPOutput, config_class=CLIPConfig) - def call( - self, - input_ids: TFModelInputType | None = None, - pixel_values: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - return_loss: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFCLIPOutput | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> import tensorflow as tf - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFCLIPModel - - >>> model = TFCLIPModel.from_pretrained("openai/clip-vit-base-patch32") - >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor( - ... text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="tf", padding=True - ... ) - - >>> outputs = model(**inputs) - >>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score - >>> probs = tf.nn.softmax(logits_per_image, axis=1) # we can take the softmax to get the label probabilities - ```""" - - outputs = self.clip( - input_ids=input_ids, - pixel_values=pixel_values, - attention_mask=attention_mask, - position_ids=position_ids, - return_loss=return_loss, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - return outputs - - def serving_output(self, output: TFCLIPOutput) -> TFCLIPOutput: - # TODO: As is this currently fails with saved_model=True, because - # TensorFlow cannot trace through nested dataclasses. Reference: - # https://github.com/huggingface/transformers/pull/16886 - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "clip", None) is not None: - with tf.name_scope(self.clip.name): - self.clip.build(None) - - -__all__ = ["TFCLIPModel", "TFCLIPPreTrainedModel", "TFCLIPTextModel", "TFCLIPVisionModel"] diff --git a/src/transformers/models/clipseg/processing_clipseg.py b/src/transformers/models/clipseg/processing_clipseg.py index 0af4c8ee12fc..e8cd47b0aa54 100644 --- a/src/transformers/models/clipseg/processing_clipseg.py +++ b/src/transformers/models/clipseg/processing_clipseg.py @@ -78,10 +78,8 @@ def __call__(self, text=None, images=None, visual_prompt=None, return_tensors=No return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchEncoding`]: A [`BatchEncoding`] with the following fields: diff --git a/src/transformers/models/clvp/feature_extraction_clvp.py b/src/transformers/models/clvp/feature_extraction_clvp.py index 160666ef78c0..077e70af67b1 100644 --- a/src/transformers/models/clvp/feature_extraction_clvp.py +++ b/src/transformers/models/clvp/feature_extraction_clvp.py @@ -170,7 +170,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. padding_value (`float`, *optional*, defaults to 0.0): diff --git a/src/transformers/models/codegen/configuration_codegen.py b/src/transformers/models/codegen/configuration_codegen.py index 6a9ab842710c..658f3cfca1ac 100644 --- a/src/transformers/models/codegen/configuration_codegen.py +++ b/src/transformers/models/codegen/configuration_codegen.py @@ -18,7 +18,7 @@ from collections.abc import Mapping from typing import Any, Optional -from ... import PreTrainedTokenizer, TensorType, is_torch_available +from ... import PreTrainedTokenizer, is_torch_available from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfigWithPast, PatchingSpec from ...utils import logging @@ -146,7 +146,7 @@ def __init__( ) -# Copied from transformers.models.gpt2.configuration_gpt2.GPT2OnnxConfig +# Copied from transformers.models.gpt2.configuration_gpt2.GPT2OnnxConfig with GPT2->CodeGen class CodeGenOnnxConfig(OnnxConfigWithPast): def __init__( self, @@ -185,10 +185,9 @@ def generate_dummy_inputs( 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 + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) # We need to order the input in the way they appears in the forward() diff --git a/src/transformers/models/codegen/modeling_codegen.py b/src/transformers/models/codegen/modeling_codegen.py index 887b400b4799..aae404d1e7f3 100644 --- a/src/transformers/models/codegen/modeling_codegen.py +++ b/src/transformers/models/codegen/modeling_codegen.py @@ -294,8 +294,6 @@ def __init__(self, *inputs, **kwargs): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, (nn.Linear,)): - # Slightly different from Mesh Transformer JAX which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/codegen/tokenization_codegen.py b/src/transformers/models/codegen/tokenization_codegen.py index 152b1a84fc37..d8a5a2745ae7 100644 --- a/src/transformers/models/codegen/tokenization_codegen.py +++ b/src/transformers/models/codegen/tokenization_codegen.py @@ -22,14 +22,11 @@ import numpy as np import regex as re -from ...utils import is_tf_available, is_torch_available, logging, to_py_obj +from ...utils import logging, to_py_obj if TYPE_CHECKING: - if is_torch_available(): - import torch - if is_tf_available(): - import tensorflow as tf + import torch from ...tokenization_utils import AddedToken, PreTrainedTokenizer @@ -313,7 +310,7 @@ def prepare_for_tokenization(self, text, is_split_into_words=False, **kwargs): def decode( self, - token_ids: Union[int, list[int], "np.ndarray", "torch.Tensor", "tf.Tensor"], + token_ids: Union[int, list[int], "np.ndarray", "torch.Tensor"], skip_special_tokens: bool = False, clean_up_tokenization_spaces: Optional[bool] = None, truncate_before_pattern: Optional[list[str]] = None, @@ -326,7 +323,7 @@ def decode( Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. Args: - token_ids (`Union[int, List[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, List[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. diff --git a/src/transformers/models/codegen/tokenization_codegen_fast.py b/src/transformers/models/codegen/tokenization_codegen_fast.py index 7bac0db7de4e..4cbeff06ad89 100644 --- a/src/transformers/models/codegen/tokenization_codegen_fast.py +++ b/src/transformers/models/codegen/tokenization_codegen_fast.py @@ -19,14 +19,12 @@ import numpy as np -from ...utils import is_tf_available, is_torch_available, logging +from ...utils import is_torch_available, logging if TYPE_CHECKING: if is_torch_available(): import torch - if is_tf_available(): - import tensorflow as tf from ...tokenization_utils_base import BatchEncoding @@ -160,7 +158,7 @@ def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = def decode( self, - token_ids: Union[int, list[int], "np.ndarray", "torch.Tensor", "tf.Tensor"], + token_ids: Union[int, list[int], "np.ndarray", "torch.Tensor"], skip_special_tokens: bool = False, clean_up_tokenization_spaces: Optional[bool] = None, truncate_before_pattern: Optional[list[str]] = None, @@ -173,7 +171,7 @@ def decode( Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. Args: - token_ids (`Union[int, List[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, List[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. diff --git a/src/transformers/models/cohere/tokenization_cohere_fast.py b/src/transformers/models/cohere/tokenization_cohere_fast.py index fd240b978480..8072cbe7c17c 100644 --- a/src/transformers/models/cohere/tokenization_cohere_fast.py +++ b/src/transformers/models/cohere/tokenization_cohere_fast.py @@ -276,10 +276,8 @@ def apply_tool_use_template( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Has no effect if tokenize is `False`. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.Tensor` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. return_dict (`bool`, *optional*, defaults to `False`): Whether to return a dictionary with named outputs. Has no effect if tokenize is `False`. **tokenizer_kwargs: Additional kwargs to pass to the tokenizer. @@ -424,10 +422,8 @@ def apply_grounded_generation_template( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Has no effect if tokenize is `False`. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.Tensor` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. return_dict (`bool`, *optional*, defaults to `False`): Whether to return a dictionary with named outputs. Has no effect if tokenize is `False`. **tokenizer_kwargs: Additional kwargs to pass to the tokenizer. diff --git a/src/transformers/models/cohere2_vision/processing_cohere2_vision.py b/src/transformers/models/cohere2_vision/processing_cohere2_vision.py index b72e1512ead9..cde77af658bc 100644 --- a/src/transformers/models/cohere2_vision/processing_cohere2_vision.py +++ b/src/transformers/models/cohere2_vision/processing_cohere2_vision.py @@ -103,10 +103,8 @@ def __call__( `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/colpali/modular_colpali.py b/src/transformers/models/colpali/modular_colpali.py index cf28475f4b3c..0c932a732258 100644 --- a/src/transformers/models/colpali/modular_colpali.py +++ b/src/transformers/models/colpali/modular_colpali.py @@ -117,10 +117,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: @@ -224,10 +222,8 @@ def process_images( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: @@ -259,10 +255,8 @@ def process_queries( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/colpali/processing_colpali.py b/src/transformers/models/colpali/processing_colpali.py index b3f758a00006..5d77eced20d9 100644 --- a/src/transformers/models/colpali/processing_colpali.py +++ b/src/transformers/models/colpali/processing_colpali.py @@ -158,10 +158,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: @@ -292,10 +290,8 @@ def process_images( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: @@ -327,10 +323,8 @@ def process_queries( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/colqwen2/modular_colqwen2.py b/src/transformers/models/colqwen2/modular_colqwen2.py index f3ae79abf6fa..a9a1f8ce3e1e 100644 --- a/src/transformers/models/colqwen2/modular_colqwen2.py +++ b/src/transformers/models/colqwen2/modular_colqwen2.py @@ -120,10 +120,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/colqwen2/processing_colqwen2.py b/src/transformers/models/colqwen2/processing_colqwen2.py index 1609f6e182da..372ce542d580 100644 --- a/src/transformers/models/colqwen2/processing_colqwen2.py +++ b/src/transformers/models/colqwen2/processing_colqwen2.py @@ -121,10 +121,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: @@ -277,10 +275,8 @@ def process_images( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: @@ -312,10 +308,8 @@ def process_queries( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/conditional_detr/image_processing_conditional_detr.py b/src/transformers/models/conditional_detr/image_processing_conditional_detr.py index 9221c463fe85..cf506b834918 100644 --- a/src/transformers/models/conditional_detr/image_processing_conditional_detr.py +++ b/src/transformers/models/conditional_detr/image_processing_conditional_detr.py @@ -18,7 +18,7 @@ import pathlib from collections import defaultdict from collections.abc import Iterable -from typing import Any, Callable, Optional, Union +from typing import Any, Optional, Union import numpy as np @@ -55,11 +55,7 @@ ) from ...utils import ( TensorType, - is_flax_available, - is_jax_tensor, is_scipy_available, - is_tf_available, - is_tf_tensor, is_torch_available, is_torch_tensor, is_vision_available, @@ -193,31 +189,6 @@ def get_image_size_for_max_height_width( return new_height, new_width -# Copied from transformers.models.detr.image_processing_detr.get_numpy_to_framework_fn -def get_numpy_to_framework_fn(arr) -> Callable: - """ - Returns a function that converts a numpy array to the framework of the input array. - - Args: - arr (`np.ndarray`): The array to convert. - """ - if isinstance(arr, np.ndarray): - return np.array - if is_tf_available() and is_tf_tensor(arr): - import tensorflow as tf - - return tf.convert_to_tensor - if is_torch_available() and is_torch_tensor(arr): - import torch - - return torch.tensor - if is_flax_available() and is_jax_tensor(arr): - import jax.numpy as jnp - - return jnp.array - raise ValueError(f"Cannot convert arrays of type {type(arr)}") - - # Copied from transformers.models.detr.image_processing_detr.safe_squeeze def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: """ @@ -1205,10 +1176,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -1393,10 +1362,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor.") validate_kwargs(captured_kwargs=kwargs.keys(), valid_processor_keys=self._valid_processor_keys) # Here, the pad() method pads to the maximum of (width, height). It does not need to be validated. @@ -1527,11 +1493,9 @@ def preprocess( return encoded_inputs - # POSTPROCESSING METHODS - TODO: add support for other frameworks def post_process(self, outputs, target_sizes): """ Converts the output of [`ConditionalDetrForObjectDetection`] into the format expected by the Pascal VOC format (xmin, ymin, xmax, ymax). - Only supports PyTorch. Args: outputs ([`ConditionalDetrObjectDetectionOutput`]): diff --git a/src/transformers/models/conditional_detr/modeling_conditional_detr.py b/src/transformers/models/conditional_detr/modeling_conditional_detr.py index ada06d87f7cc..2ee35cc19a3f 100644 --- a/src/transformers/models/conditional_detr/modeling_conditional_detr.py +++ b/src/transformers/models/conditional_detr/modeling_conditional_detr.py @@ -982,8 +982,6 @@ def _init_weights(self, module): nn.init.uniform_(module.row_embeddings.weight) nn.init.uniform_(module.column_embeddings.weight) if isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/convbert/__init__.py b/src/transformers/models/convbert/__init__.py index 670a7d6f4764..20999ba510da 100644 --- a/src/transformers/models/convbert/__init__.py +++ b/src/transformers/models/convbert/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_convbert import * from .modeling_convbert import * - from .modeling_tf_convbert import * from .tokenization_convbert import * from .tokenization_convbert_fast import * else: diff --git a/src/transformers/models/convbert/convert_convbert_original_tf1_checkpoint_to_pytorch.py b/src/transformers/models/convbert/convert_convbert_original_tf1_checkpoint_to_pytorch.py new file mode 100644 index 000000000000..350e5a7f3f90 --- /dev/null +++ b/src/transformers/models/convbert/convert_convbert_original_tf1_checkpoint_to_pytorch.py @@ -0,0 +1,183 @@ +# coding=utf-8 +# Copyright 2020 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. +"""Convert ConvBERT checkpoint.""" + +import argparse +import os +from operator import attrgetter + +import torch + +from transformers import ConvBertConfig, ConvBertModel +from transformers.utils import logging + + +logger = logging.get_logger(__name__) +logging.set_verbosity_info() + + +def load_tf_weights_in_convbert(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + tf_data = {} + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + tf_data[name] = array + + param_mapping = { + "embeddings.word_embeddings.weight": "electra/embeddings/word_embeddings", + "embeddings.position_embeddings.weight": "electra/embeddings/position_embeddings", + "embeddings.token_type_embeddings.weight": "electra/embeddings/token_type_embeddings", + "embeddings.LayerNorm.weight": "electra/embeddings/LayerNorm/gamma", + "embeddings.LayerNorm.bias": "electra/embeddings/LayerNorm/beta", + "embeddings_project.weight": "electra/embeddings_project/kernel", + "embeddings_project.bias": "electra/embeddings_project/bias", + } + if config.num_groups > 1: + group_dense_name = "g_dense" + else: + group_dense_name = "dense" + + for j in range(config.num_hidden_layers): + param_mapping[f"encoder.layer.{j}.attention.self.query.weight"] = ( + f"electra/encoder/layer_{j}/attention/self/query/kernel" + ) + param_mapping[f"encoder.layer.{j}.attention.self.query.bias"] = ( + f"electra/encoder/layer_{j}/attention/self/query/bias" + ) + param_mapping[f"encoder.layer.{j}.attention.self.key.weight"] = ( + f"electra/encoder/layer_{j}/attention/self/key/kernel" + ) + param_mapping[f"encoder.layer.{j}.attention.self.key.bias"] = ( + f"electra/encoder/layer_{j}/attention/self/key/bias" + ) + param_mapping[f"encoder.layer.{j}.attention.self.value.weight"] = ( + f"electra/encoder/layer_{j}/attention/self/value/kernel" + ) + param_mapping[f"encoder.layer.{j}.attention.self.value.bias"] = ( + f"electra/encoder/layer_{j}/attention/self/value/bias" + ) + param_mapping[f"encoder.layer.{j}.attention.self.key_conv_attn_layer.depthwise.weight"] = ( + f"electra/encoder/layer_{j}/attention/self/conv_attn_key/depthwise_kernel" + ) + param_mapping[f"encoder.layer.{j}.attention.self.key_conv_attn_layer.pointwise.weight"] = ( + f"electra/encoder/layer_{j}/attention/self/conv_attn_key/pointwise_kernel" + ) + param_mapping[f"encoder.layer.{j}.attention.self.key_conv_attn_layer.bias"] = ( + f"electra/encoder/layer_{j}/attention/self/conv_attn_key/bias" + ) + param_mapping[f"encoder.layer.{j}.attention.self.conv_kernel_layer.weight"] = ( + f"electra/encoder/layer_{j}/attention/self/conv_attn_kernel/kernel" + ) + param_mapping[f"encoder.layer.{j}.attention.self.conv_kernel_layer.bias"] = ( + f"electra/encoder/layer_{j}/attention/self/conv_attn_kernel/bias" + ) + param_mapping[f"encoder.layer.{j}.attention.self.conv_out_layer.weight"] = ( + f"electra/encoder/layer_{j}/attention/self/conv_attn_point/kernel" + ) + param_mapping[f"encoder.layer.{j}.attention.self.conv_out_layer.bias"] = ( + f"electra/encoder/layer_{j}/attention/self/conv_attn_point/bias" + ) + param_mapping[f"encoder.layer.{j}.attention.output.dense.weight"] = ( + f"electra/encoder/layer_{j}/attention/output/dense/kernel" + ) + param_mapping[f"encoder.layer.{j}.attention.output.LayerNorm.weight"] = ( + f"electra/encoder/layer_{j}/attention/output/LayerNorm/gamma" + ) + param_mapping[f"encoder.layer.{j}.attention.output.dense.bias"] = ( + f"electra/encoder/layer_{j}/attention/output/dense/bias" + ) + param_mapping[f"encoder.layer.{j}.attention.output.LayerNorm.bias"] = ( + f"electra/encoder/layer_{j}/attention/output/LayerNorm/beta" + ) + param_mapping[f"encoder.layer.{j}.intermediate.dense.weight"] = ( + f"electra/encoder/layer_{j}/intermediate/{group_dense_name}/kernel" + ) + param_mapping[f"encoder.layer.{j}.intermediate.dense.bias"] = ( + f"electra/encoder/layer_{j}/intermediate/{group_dense_name}/bias" + ) + param_mapping[f"encoder.layer.{j}.output.dense.weight"] = ( + f"electra/encoder/layer_{j}/output/{group_dense_name}/kernel" + ) + param_mapping[f"encoder.layer.{j}.output.dense.bias"] = ( + f"electra/encoder/layer_{j}/output/{group_dense_name}/bias" + ) + param_mapping[f"encoder.layer.{j}.output.LayerNorm.weight"] = ( + f"electra/encoder/layer_{j}/output/LayerNorm/gamma" + ) + param_mapping[f"encoder.layer.{j}.output.LayerNorm.bias"] = f"electra/encoder/layer_{j}/output/LayerNorm/beta" + + for param in model.named_parameters(): + param_name = param[0] + retriever = attrgetter(param_name) + result = retriever(model) + tf_name = param_mapping[param_name] + value = torch.from_numpy(tf_data[tf_name]) + logger.info(f"TF: {tf_name}, PT: {param_name} ") + if tf_name.endswith("/kernel"): + if not tf_name.endswith("/intermediate/g_dense/kernel"): + if not tf_name.endswith("/output/g_dense/kernel"): + value = value.T + if tf_name.endswith("/depthwise_kernel"): + value = value.permute(1, 2, 0) # 2, 0, 1 + if tf_name.endswith("/pointwise_kernel"): + value = value.permute(2, 1, 0) # 2, 1, 0 + if tf_name.endswith("/conv_attn_key/bias"): + value = value.unsqueeze(-1) + result.data = value + return model + + +def convert_orig_tf1_checkpoint_to_pytorch(tf_checkpoint_path, convbert_config_file, pytorch_dump_path): + conf = ConvBertConfig.from_json_file(convbert_config_file) + model = ConvBertModel(conf) + + model = load_tf_weights_in_convbert(model, conf, tf_checkpoint_path) + model.save_pretrained(pytorch_dump_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--tf_checkpoint_path", default=None, type=str, required=True, help="Path to the TensorFlow checkpoint path." + ) + parser.add_argument( + "--convbert_config_file", + default=None, + type=str, + required=True, + help=( + "The config json file corresponding to the pre-trained ConvBERT model. \n" + "This specifies the model architecture." + ), + ) + parser.add_argument( + "--pytorch_dump_path", default=None, type=str, required=True, help="Path to the output PyTorch model." + ) + args = parser.parse_args() + convert_orig_tf1_checkpoint_to_pytorch(args.tf_checkpoint_path, args.convbert_config_file, args.pytorch_dump_path) diff --git a/src/transformers/models/convbert/convert_convbert_original_tf1_checkpoint_to_pytorch_and_tf2.py b/src/transformers/models/convbert/convert_convbert_original_tf1_checkpoint_to_pytorch_and_tf2.py deleted file mode 100644 index 3d4ff779874b..000000000000 --- a/src/transformers/models/convbert/convert_convbert_original_tf1_checkpoint_to_pytorch_and_tf2.py +++ /dev/null @@ -1,57 +0,0 @@ -# coding=utf-8 -# Copyright 2020 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. -"""Convert ConvBERT checkpoint.""" - -import argparse - -from transformers import ConvBertConfig, ConvBertModel, TFConvBertModel, load_tf_weights_in_convbert -from transformers.utils import logging - - -logging.set_verbosity_info() - - -def convert_orig_tf1_checkpoint_to_pytorch(tf_checkpoint_path, convbert_config_file, pytorch_dump_path): - conf = ConvBertConfig.from_json_file(convbert_config_file) - model = ConvBertModel(conf) - - model = load_tf_weights_in_convbert(model, conf, tf_checkpoint_path) - model.save_pretrained(pytorch_dump_path) - - tf_model = TFConvBertModel.from_pretrained(pytorch_dump_path, from_pt=True) - tf_model.save_pretrained(pytorch_dump_path) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - # Required parameters - parser.add_argument( - "--tf_checkpoint_path", default=None, type=str, required=True, help="Path to the TensorFlow checkpoint path." - ) - parser.add_argument( - "--convbert_config_file", - default=None, - type=str, - required=True, - help=( - "The config json file corresponding to the pre-trained ConvBERT model. \n" - "This specifies the model architecture." - ), - ) - parser.add_argument( - "--pytorch_dump_path", default=None, type=str, required=True, help="Path to the output PyTorch model." - ) - args = parser.parse_args() - convert_orig_tf1_checkpoint_to_pytorch(args.tf_checkpoint_path, args.convbert_config_file, args.pytorch_dump_path) diff --git a/src/transformers/models/convbert/modeling_convbert.py b/src/transformers/models/convbert/modeling_convbert.py index 080b93fa92a6..5f4dd419b4fc 100755 --- a/src/transformers/models/convbert/modeling_convbert.py +++ b/src/transformers/models/convbert/modeling_convbert.py @@ -15,8 +15,6 @@ """PyTorch ConvBERT model.""" import math -import os -from operator import attrgetter from typing import Callable, Optional, Union import torch @@ -45,130 +43,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_convbert(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - tf_data = {} - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - tf_data[name] = array - - param_mapping = { - "embeddings.word_embeddings.weight": "electra/embeddings/word_embeddings", - "embeddings.position_embeddings.weight": "electra/embeddings/position_embeddings", - "embeddings.token_type_embeddings.weight": "electra/embeddings/token_type_embeddings", - "embeddings.LayerNorm.weight": "electra/embeddings/LayerNorm/gamma", - "embeddings.LayerNorm.bias": "electra/embeddings/LayerNorm/beta", - "embeddings_project.weight": "electra/embeddings_project/kernel", - "embeddings_project.bias": "electra/embeddings_project/bias", - } - if config.num_groups > 1: - group_dense_name = "g_dense" - else: - group_dense_name = "dense" - - for j in range(config.num_hidden_layers): - param_mapping[f"encoder.layer.{j}.attention.self.query.weight"] = ( - f"electra/encoder/layer_{j}/attention/self/query/kernel" - ) - param_mapping[f"encoder.layer.{j}.attention.self.query.bias"] = ( - f"electra/encoder/layer_{j}/attention/self/query/bias" - ) - param_mapping[f"encoder.layer.{j}.attention.self.key.weight"] = ( - f"electra/encoder/layer_{j}/attention/self/key/kernel" - ) - param_mapping[f"encoder.layer.{j}.attention.self.key.bias"] = ( - f"electra/encoder/layer_{j}/attention/self/key/bias" - ) - param_mapping[f"encoder.layer.{j}.attention.self.value.weight"] = ( - f"electra/encoder/layer_{j}/attention/self/value/kernel" - ) - param_mapping[f"encoder.layer.{j}.attention.self.value.bias"] = ( - f"electra/encoder/layer_{j}/attention/self/value/bias" - ) - param_mapping[f"encoder.layer.{j}.attention.self.key_conv_attn_layer.depthwise.weight"] = ( - f"electra/encoder/layer_{j}/attention/self/conv_attn_key/depthwise_kernel" - ) - param_mapping[f"encoder.layer.{j}.attention.self.key_conv_attn_layer.pointwise.weight"] = ( - f"electra/encoder/layer_{j}/attention/self/conv_attn_key/pointwise_kernel" - ) - param_mapping[f"encoder.layer.{j}.attention.self.key_conv_attn_layer.bias"] = ( - f"electra/encoder/layer_{j}/attention/self/conv_attn_key/bias" - ) - param_mapping[f"encoder.layer.{j}.attention.self.conv_kernel_layer.weight"] = ( - f"electra/encoder/layer_{j}/attention/self/conv_attn_kernel/kernel" - ) - param_mapping[f"encoder.layer.{j}.attention.self.conv_kernel_layer.bias"] = ( - f"electra/encoder/layer_{j}/attention/self/conv_attn_kernel/bias" - ) - param_mapping[f"encoder.layer.{j}.attention.self.conv_out_layer.weight"] = ( - f"electra/encoder/layer_{j}/attention/self/conv_attn_point/kernel" - ) - param_mapping[f"encoder.layer.{j}.attention.self.conv_out_layer.bias"] = ( - f"electra/encoder/layer_{j}/attention/self/conv_attn_point/bias" - ) - param_mapping[f"encoder.layer.{j}.attention.output.dense.weight"] = ( - f"electra/encoder/layer_{j}/attention/output/dense/kernel" - ) - param_mapping[f"encoder.layer.{j}.attention.output.LayerNorm.weight"] = ( - f"electra/encoder/layer_{j}/attention/output/LayerNorm/gamma" - ) - param_mapping[f"encoder.layer.{j}.attention.output.dense.bias"] = ( - f"electra/encoder/layer_{j}/attention/output/dense/bias" - ) - param_mapping[f"encoder.layer.{j}.attention.output.LayerNorm.bias"] = ( - f"electra/encoder/layer_{j}/attention/output/LayerNorm/beta" - ) - param_mapping[f"encoder.layer.{j}.intermediate.dense.weight"] = ( - f"electra/encoder/layer_{j}/intermediate/{group_dense_name}/kernel" - ) - param_mapping[f"encoder.layer.{j}.intermediate.dense.bias"] = ( - f"electra/encoder/layer_{j}/intermediate/{group_dense_name}/bias" - ) - param_mapping[f"encoder.layer.{j}.output.dense.weight"] = ( - f"electra/encoder/layer_{j}/output/{group_dense_name}/kernel" - ) - param_mapping[f"encoder.layer.{j}.output.dense.bias"] = ( - f"electra/encoder/layer_{j}/output/{group_dense_name}/bias" - ) - param_mapping[f"encoder.layer.{j}.output.LayerNorm.weight"] = ( - f"electra/encoder/layer_{j}/output/LayerNorm/gamma" - ) - param_mapping[f"encoder.layer.{j}.output.LayerNorm.bias"] = f"electra/encoder/layer_{j}/output/LayerNorm/beta" - - for param in model.named_parameters(): - param_name = param[0] - retriever = attrgetter(param_name) - result = retriever(model) - tf_name = param_mapping[param_name] - value = torch.from_numpy(tf_data[tf_name]) - logger.info(f"TF: {tf_name}, PT: {param_name} ") - if tf_name.endswith("/kernel"): - if not tf_name.endswith("/intermediate/g_dense/kernel"): - if not tf_name.endswith("/output/g_dense/kernel"): - value = value.T - if tf_name.endswith("/depthwise_kernel"): - value = value.permute(1, 2, 0) # 2, 0, 1 - if tf_name.endswith("/pointwise_kernel"): - value = value.permute(2, 1, 0) # 2, 1, 0 - if tf_name.endswith("/conv_attn_key/bias"): - value = value.unsqueeze(-1) - result.data = value - return model - - class ConvBertEmbeddings(nn.Module): """Construct the embeddings from word, position and token_type embeddings.""" @@ -178,8 +52,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.embedding_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.embedding_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.embedding_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -232,15 +104,12 @@ def forward( @auto_docstring class ConvBertPreTrainedModel(PreTrainedModel): config: ConvBertConfig - load_tf_weights = load_tf_weights_in_convbert base_model_prefix = "convbert" supports_gradient_checkpointing = True def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv1d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1330,5 +1199,4 @@ def forward( "ConvBertLayer", "ConvBertModel", "ConvBertPreTrainedModel", - "load_tf_weights_in_convbert", ] diff --git a/src/transformers/models/convbert/modeling_tf_convbert.py b/src/transformers/models/convbert/modeling_tf_convbert.py deleted file mode 100644 index 47c720f5c12c..000000000000 --- a/src/transformers/models/convbert/modeling_tf_convbert.py +++ /dev/null @@ -1,1474 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 ConvBERT model.""" - -from __future__ import annotations - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFSequenceSummary, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_convbert import ConvBertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "YituTech/conv-bert-base" -_CONFIG_FOR_DOC = "ConvBertConfig" - - -# Copied from transformers.models.albert.modeling_tf_albert.TFAlbertEmbeddings with Albert->ConvBert -class TFConvBertEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config: ConvBertConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = config.embedding_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.embedding_size]) - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertEmbeddings.call - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - past_key_values_length=0, - training: bool = False, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - if input_ids is None and inputs_embeds is None: - raise ValueError("Need to provide either `input_ids` or `input_embeds`.") - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - position_ids = tf.expand_dims( - tf.range(start=past_key_values_length, limit=input_shape[1] + past_key_values_length), axis=0 - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -class TFConvBertSelfAttention(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " - f"heads ({config.num_attention_heads})" - ) - - new_num_attention_heads = int(config.num_attention_heads / config.head_ratio) - if new_num_attention_heads < 1: - self.head_ratio = config.num_attention_heads - num_attention_heads = 1 - else: - num_attention_heads = new_num_attention_heads - self.head_ratio = config.head_ratio - - self.num_attention_heads = num_attention_heads - self.conv_kernel_size = config.conv_kernel_size - - if config.hidden_size % self.num_attention_heads != 0: - raise ValueError("hidden_size should be divisible by num_attention_heads") - - self.attention_head_size = config.hidden_size // config.num_attention_heads - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.query = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - - self.key_conv_attn_layer = keras.layers.SeparableConv1D( - self.all_head_size, - self.conv_kernel_size, - padding="same", - activation=None, - depthwise_initializer=get_initializer(1 / self.conv_kernel_size), - pointwise_initializer=get_initializer(config.initializer_range), - name="key_conv_attn_layer", - ) - - self.conv_kernel_layer = keras.layers.Dense( - self.num_attention_heads * self.conv_kernel_size, - activation=None, - name="conv_kernel_layer", - kernel_initializer=get_initializer(config.initializer_range), - ) - - self.conv_out_layer = keras.layers.Dense( - self.all_head_size, - activation=None, - name="conv_out_layer", - kernel_initializer=get_initializer(config.initializer_range), - ) - - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.config = config - - def transpose_for_scores(self, x, batch_size): - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - x = tf.reshape(x, (batch_size, -1, self.num_attention_heads, self.attention_head_size)) - return tf.transpose(x, perm=[0, 2, 1, 3]) - - def call(self, hidden_states, attention_mask, head_mask, output_attentions, training=False): - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(hidden_states) - mixed_key_layer = self.key(hidden_states) - mixed_value_layer = self.value(hidden_states) - - mixed_key_conv_attn_layer = self.key_conv_attn_layer(hidden_states) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - conv_attn_layer = tf.multiply(mixed_key_conv_attn_layer, mixed_query_layer) - - conv_kernel_layer = self.conv_kernel_layer(conv_attn_layer) - conv_kernel_layer = tf.reshape(conv_kernel_layer, [-1, self.conv_kernel_size, 1]) - conv_kernel_layer = stable_softmax(conv_kernel_layer, axis=1) - - paddings = tf.constant( - [ - [ - 0, - 0, - ], - [int((self.conv_kernel_size - 1) / 2), int((self.conv_kernel_size - 1) / 2)], - [0, 0], - ] - ) - - conv_out_layer = self.conv_out_layer(hidden_states) - conv_out_layer = tf.reshape(conv_out_layer, [batch_size, -1, self.all_head_size]) - conv_out_layer = tf.pad(conv_out_layer, paddings, "CONSTANT") - - unfold_conv_out_layer = tf.stack( - [ - tf.slice(conv_out_layer, [0, i, 0], [batch_size, shape_list(mixed_query_layer)[1], self.all_head_size]) - for i in range(self.conv_kernel_size) - ], - axis=-1, - ) - - conv_out_layer = tf.reshape(unfold_conv_out_layer, [-1, self.attention_head_size, self.conv_kernel_size]) - - conv_out_layer = tf.matmul(conv_out_layer, conv_kernel_layer) - conv_out_layer = tf.reshape(conv_out_layer, [-1, self.all_head_size]) - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = tf.matmul( - query_layer, key_layer, transpose_b=True - ) # (batch size, num_heads, seq_len_q, seq_len_k) - dk = tf.cast(shape_list(key_layer)[-1], attention_scores.dtype) # scale attention_scores - attention_scores = attention_scores / tf.math.sqrt(dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFBertModel call() function) - attention_scores = attention_scores + attention_mask - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - - value_layer = tf.reshape( - mixed_value_layer, [batch_size, -1, self.num_attention_heads, self.attention_head_size] - ) - value_layer = tf.transpose(value_layer, [0, 2, 1, 3]) - - context_layer = tf.matmul(attention_probs, value_layer) - context_layer = tf.transpose(context_layer, perm=[0, 2, 1, 3]) - - conv_out = tf.reshape(conv_out_layer, [batch_size, -1, self.num_attention_heads, self.attention_head_size]) - context_layer = tf.concat([context_layer, conv_out], 2) - context_layer = tf.reshape( - context_layer, (batch_size, -1, self.head_ratio * self.all_head_size) - ) # (batch_size, seq_len_q, all_head_size) - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - if getattr(self, "key_conv_attn_layer", None) is not None: - with tf.name_scope(self.key_conv_attn_layer.name): - self.key_conv_attn_layer.build([None, None, self.config.hidden_size]) - if getattr(self, "conv_kernel_layer", None) is not None: - with tf.name_scope(self.conv_kernel_layer.name): - self.conv_kernel_layer.build([None, None, self.all_head_size]) - if getattr(self, "conv_out_layer", None) is not None: - with tf.name_scope(self.conv_out_layer.name): - self.conv_out_layer.build([None, None, self.config.hidden_size]) - - -class TFConvBertSelfOutput(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states, input_tensor, training=False): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFConvBertAttention(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFConvBertSelfAttention(config, name="self") - self.dense_output = TFConvBertSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call(self, input_tensor, attention_mask, head_mask, output_attentions, training=False): - self_outputs = self.self_attention( - input_tensor, attention_mask, head_mask, output_attentions, training=training - ) - attention_output = self.dense_output(self_outputs[0], input_tensor, training=training) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -class GroupedLinearLayer(keras.layers.Layer): - def __init__(self, input_size, output_size, num_groups, kernel_initializer, **kwargs): - super().__init__(**kwargs) - self.input_size = input_size - self.output_size = output_size - self.num_groups = num_groups - self.kernel_initializer = kernel_initializer - self.group_in_dim = self.input_size // self.num_groups - self.group_out_dim = self.output_size // self.num_groups - - def build(self, input_shape=None): - self.kernel = self.add_weight( - "kernel", - shape=[self.group_out_dim, self.group_in_dim, self.num_groups], - initializer=self.kernel_initializer, - trainable=True, - ) - - self.bias = self.add_weight( - "bias", shape=[self.output_size], initializer=self.kernel_initializer, dtype=self.dtype, trainable=True - ) - super().build(input_shape) - - def call(self, hidden_states): - batch_size = shape_list(hidden_states)[0] - x = tf.transpose(tf.reshape(hidden_states, [-1, self.num_groups, self.group_in_dim]), [1, 0, 2]) - x = tf.matmul(x, tf.transpose(self.kernel, [2, 1, 0])) - x = tf.transpose(x, [1, 0, 2]) - x = tf.reshape(x, [batch_size, -1, self.output_size]) - x = tf.nn.bias_add(value=x, bias=self.bias) - return x - - -class TFConvBertIntermediate(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - if config.num_groups == 1: - self.dense = keras.layers.Dense( - config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - else: - self.dense = GroupedLinearLayer( - config.hidden_size, - config.intermediate_size, - num_groups=config.num_groups, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFConvBertOutput(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - if config.num_groups == 1: - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - else: - self.dense = GroupedLinearLayer( - config.intermediate_size, - config.hidden_size, - num_groups=config.num_groups, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states, input_tensor, training=False): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - - -class TFConvBertLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.attention = TFConvBertAttention(config, name="attention") - self.intermediate = TFConvBertIntermediate(config, name="intermediate") - self.bert_output = TFConvBertOutput(config, name="output") - - def call(self, hidden_states, attention_mask, head_mask, output_attentions, training=False): - attention_outputs = self.attention( - hidden_states, attention_mask, head_mask, output_attentions, training=training - ) - attention_output = attention_outputs[0] - intermediate_output = self.intermediate(attention_output) - layer_output = self.bert_output(intermediate_output, attention_output, training=training) - outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - - -class TFConvBertEncoder(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.layer = [TFConvBertLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states, - attention_mask, - head_mask, - output_attentions, - output_hidden_states, - return_dict, - training=False, - ): - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states, attention_mask, head_mask[i], output_attentions, training=training - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFConvBertPredictionHeadTransform(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - config.embedding_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.transform_act_fn = get_tf_activation(config.hidden_act) - else: - self.transform_act_fn = config.hidden_act - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.transform_act_fn(hidden_states) - hidden_states = self.LayerNorm(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -@keras_serializable -class TFConvBertMainLayer(keras.layers.Layer): - config_class = ConvBertConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.embeddings = TFConvBertEmbeddings(config, name="embeddings") - - if config.embedding_size != config.hidden_size: - self.embeddings_project = keras.layers.Dense(config.hidden_size, name="embeddings_project") - - self.encoder = TFConvBertEncoder(config, name="encoder") - self.config = config - - def get_input_embeddings(self): - return self.embeddings - - def set_input_embeddings(self, value): - self.embeddings.weight = value - self.embeddings.vocab_size = value.shape[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - def get_extended_attention_mask(self, attention_mask, input_shape, dtype): - if attention_mask is None: - attention_mask = tf.fill(input_shape, 1) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - extended_attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype) - extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0 - - return extended_attention_mask - - def get_head_mask(self, head_mask): - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - return head_mask - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - inputs_embeds=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(input_shape, 1) - - if token_type_ids is None: - token_type_ids = tf.fill(input_shape, 0) - - hidden_states = self.embeddings(input_ids, position_ids, token_type_ids, inputs_embeds, training=training) - extended_attention_mask = self.get_extended_attention_mask(attention_mask, input_shape, hidden_states.dtype) - head_mask = self.get_head_mask(head_mask) - - if hasattr(self, "embeddings_project"): - hidden_states = self.embeddings_project(hidden_states, training=training) - - hidden_states = self.encoder( - hidden_states, - extended_attention_mask, - head_mask, - output_attentions, - output_hidden_states, - return_dict, - training=training, - ) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "embeddings_project", None) is not None: - with tf.name_scope(self.embeddings_project.name): - self.embeddings_project.build([None, None, self.config.embedding_size]) - - -class TFConvBertPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = ConvBertConfig - base_model_prefix = "convbert" - - -CONVBERT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`ConvBertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -CONVBERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare ConvBERT Model transformer outputting raw hidden-states without any specific head on top.", - CONVBERT_START_DOCSTRING, -) -class TFConvBertModel(TFConvBertPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.convbert = TFConvBertMainLayer(config, name="convbert") - - @unpack_inputs - @add_start_docstrings_to_model_forward(CONVBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.array | tf.Tensor | None = None, - token_type_ids: np.array | tf.Tensor | None = None, - position_ids: np.array | tf.Tensor | None = None, - head_mask: np.array | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - outputs = self.convbert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convbert", None) is not None: - with tf.name_scope(self.convbert.name): - self.convbert.build(None) - - -class TFConvBertMaskedLMHead(keras.layers.Layer): - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = config.embedding_size - self.input_embeddings = input_embeddings - - def build(self, input_shape): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - super().build(input_shape) - - def get_output_embeddings(self): - return self.input_embeddings - - def set_output_embeddings(self, value): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.embedding_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -class TFConvBertGeneratorPredictions(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dense = keras.layers.Dense(config.embedding_size, name="dense") - self.config = config - - def call(self, generator_hidden_states, training=False): - hidden_states = self.dense(generator_hidden_states) - hidden_states = get_tf_activation("gelu")(hidden_states) - hidden_states = self.LayerNorm(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.embedding_size]) - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings("""ConvBERT Model with a `language modeling` head on top.""", CONVBERT_START_DOCSTRING) -class TFConvBertForMaskedLM(TFConvBertPreTrainedModel, TFMaskedLanguageModelingLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, **kwargs) - - self.config = config - self.convbert = TFConvBertMainLayer(config, name="convbert") - self.generator_predictions = TFConvBertGeneratorPredictions(config, name="generator_predictions") - - if isinstance(config.hidden_act, str): - self.activation = get_tf_activation(config.hidden_act) - else: - self.activation = config.hidden_act - - self.generator_lm_head = TFConvBertMaskedLMHead(config, self.convbert.embeddings, name="generator_lm_head") - - def get_lm_head(self): - return self.generator_lm_head - - def get_prefix_bias_name(self): - return self.name + "/" + self.generator_lm_head.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(CONVBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFMaskedLMOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - generator_hidden_states = self.convbert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - generator_sequence_output = generator_hidden_states[0] - prediction_scores = self.generator_predictions(generator_sequence_output, training=training) - prediction_scores = self.generator_lm_head(prediction_scores, training=training) - loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) - - if not return_dict: - output = (prediction_scores,) + generator_hidden_states[1:] - - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=generator_hidden_states.hidden_states, - attentions=generator_hidden_states.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convbert", None) is not None: - with tf.name_scope(self.convbert.name): - self.convbert.build(None) - if getattr(self, "generator_predictions", None) is not None: - with tf.name_scope(self.generator_predictions.name): - self.generator_predictions.build(None) - if getattr(self, "generator_lm_head", None) is not None: - with tf.name_scope(self.generator_lm_head.name): - self.generator_lm_head.build(None) - - -class TFConvBertClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.out_proj = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="out_proj" - ) - - self.config = config - - def call(self, hidden_states, **kwargs): - x = hidden_states[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x) - x = self.dense(x) - x = get_tf_activation(self.config.hidden_act)(x) - x = self.dropout(x) - x = self.out_proj(x) - - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - ConvBERT Model transformer with a sequence classification/regression head on top e.g., for GLUE tasks. - """, - CONVBERT_START_DOCSTRING, -) -class TFConvBertForSequenceClassification(TFConvBertPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.convbert = TFConvBertMainLayer(config, name="convbert") - self.classifier = TFConvBertClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(CONVBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFSequenceClassifierOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.convbert( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - logits = self.classifier(outputs[0], training=training) - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convbert", None) is not None: - with tf.name_scope(self.convbert.name): - self.convbert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - ConvBERT Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - CONVBERT_START_DOCSTRING, -) -class TFConvBertForMultipleChoice(TFConvBertPreTrainedModel, TFMultipleChoiceLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.convbert = TFConvBertMainLayer(config, name="convbert") - self.sequence_summary = TFSequenceSummary( - config, initializer_range=config.initializer_range, name="sequence_summary" - ) - self.classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward( - CONVBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") - ) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFMultipleChoiceModelOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - flat_inputs_embeds = ( - tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - outputs = self.convbert( - flat_input_ids, - flat_attention_mask, - flat_token_type_ids, - flat_position_ids, - head_mask, - flat_inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - logits = self.sequence_summary(outputs[0], training=training) - logits = self.classifier(logits) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[1:] - - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convbert", None) is not None: - with tf.name_scope(self.convbert.name): - self.convbert.build(None) - if getattr(self, "sequence_summary", None) is not None: - with tf.name_scope(self.sequence_summary.name): - self.sequence_summary.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - ConvBERT Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - CONVBERT_START_DOCSTRING, -) -class TFConvBertForTokenClassification(TFConvBertPreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.convbert = TFConvBertMainLayer(config, name="convbert") - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(CONVBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFTokenClassifierOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.convbert( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convbert", None) is not None: - with tf.name_scope(self.convbert.name): - self.convbert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - ConvBERT Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layer on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - CONVBERT_START_DOCSTRING, -) -class TFConvBertForQuestionAnswering(TFConvBertPreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.convbert = TFConvBertMainLayer(config, name="convbert") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(CONVBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: tf.Tensor | None = None, - end_positions: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFQuestionAnsweringModelOutput: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.convbert( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convbert", None) is not None: - with tf.name_scope(self.convbert.name): - self.convbert.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFConvBertForMaskedLM", - "TFConvBertForMultipleChoice", - "TFConvBertForQuestionAnswering", - "TFConvBertForSequenceClassification", - "TFConvBertForTokenClassification", - "TFConvBertLayer", - "TFConvBertModel", - "TFConvBertPreTrainedModel", -] diff --git a/src/transformers/models/convnext/__init__.py b/src/transformers/models/convnext/__init__.py index e2d826745f5b..92f604100822 100644 --- a/src/transformers/models/convnext/__init__.py +++ b/src/transformers/models/convnext/__init__.py @@ -23,7 +23,6 @@ from .image_processing_convnext import * from .image_processing_convnext_fast import * from .modeling_convnext import * - from .modeling_tf_convnext import * else: import sys diff --git a/src/transformers/models/convnext/image_processing_convnext.py b/src/transformers/models/convnext/image_processing_convnext.py index af89274500dd..ae0be69a5621 100644 --- a/src/transformers/models/convnext/image_processing_convnext.py +++ b/src/transformers/models/convnext/image_processing_convnext.py @@ -234,10 +234,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -265,10 +263,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/convnext/modeling_convnext.py b/src/transformers/models/convnext/modeling_convnext.py index 3120c140d2ed..e3224c29405f 100755 --- a/src/transformers/models/convnext/modeling_convnext.py +++ b/src/transformers/models/convnext/modeling_convnext.py @@ -41,11 +41,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -247,8 +242,6 @@ class ConvNextPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/convnext/modeling_tf_convnext.py b/src/transformers/models/convnext/modeling_tf_convnext.py deleted file mode 100644 index 7306877466d9..000000000000 --- a/src/transformers/models/convnext/modeling_tf_convnext.py +++ /dev/null @@ -1,667 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Meta Platforms Inc. and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 ConvNext model.""" - -from __future__ import annotations - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import TFBaseModelOutput, TFBaseModelOutputWithPooling, TFSequenceClassifierOutput -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_convnext import ConvNextConfig - - -logger = logging.get_logger(__name__) - - -_CONFIG_FOR_DOC = "ConvNextConfig" -_CHECKPOINT_FOR_DOC = "facebook/convnext-tiny-224" - - -class TFConvNextDropPath(keras.layers.Layer): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - References: - (1) github.com:rwightman/pytorch-image-models - """ - - def __init__(self, drop_path: float, **kwargs): - super().__init__(**kwargs) - self.drop_path = drop_path - - def call(self, x: tf.Tensor, training=None): - if training: - keep_prob = 1 - self.drop_path - shape = (tf.shape(x)[0],) + (1,) * (len(tf.shape(x)) - 1) - random_tensor = keep_prob + tf.random.uniform(shape, 0, 1) - random_tensor = tf.floor(random_tensor) - return (x / keep_prob) * random_tensor - return x - - -class TFConvNextEmbeddings(keras.layers.Layer): - """This class is comparable to (and inspired by) the SwinEmbeddings class - found in src/transformers/models/swin/modeling_swin.py. - """ - - def __init__(self, config: ConvNextConfig, **kwargs): - super().__init__(**kwargs) - self.patch_embeddings = keras.layers.Conv2D( - filters=config.hidden_sizes[0], - kernel_size=config.patch_size, - strides=config.patch_size, - name="patch_embeddings", - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer=keras.initializers.Zeros(), - ) - self.layernorm = keras.layers.LayerNormalization(epsilon=1e-6, name="layernorm") - self.num_channels = config.num_channels - self.config = config - - def call(self, pixel_values): - if isinstance(pixel_values, dict): - pixel_values = pixel_values["pixel_values"] - - tf.debugging.assert_equal( - shape_list(pixel_values)[1], - self.num_channels, - message="Make sure that the channel dimension of the pixel values match with the one set in the configuration.", - ) - - # When running on CPU, `keras.layers.Conv2D` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - # shape = (batch_size, in_height, in_width, in_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - - embeddings = self.patch_embeddings(pixel_values) - embeddings = self.layernorm(embeddings) - return embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "patch_embeddings", None) is not None: - with tf.name_scope(self.patch_embeddings.name): - self.patch_embeddings.build([None, None, None, self.config.num_channels]) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, None, self.config.hidden_sizes[0]]) - - -class TFConvNextLayer(keras.layers.Layer): - """This corresponds to the `Block` class in the original implementation. - - There are two equivalent implementations: [DwConv, LayerNorm (channels_first), Conv, GELU,1x1 Conv]; all in (N, C, - H, W) (2) [DwConv, Permute to (N, H, W, C), LayerNorm (channels_last), Linear, GELU, Linear]; Permute back - - The authors used (2) as they find it slightly faster in PyTorch. Since we already permuted the inputs to follow - NHWC ordering, we can just apply the operations straight-away without the permutation. - - Args: - config ([`ConvNextConfig`]): Model configuration class. - dim (`int`): Number of input channels. - drop_path (`float`): Stochastic depth rate. Default: 0.0. - """ - - def __init__(self, config, dim, drop_path=0.0, **kwargs): - super().__init__(**kwargs) - self.dim = dim - self.config = config - self.dwconv = keras.layers.Conv2D( - filters=dim, - kernel_size=7, - padding="same", - groups=dim, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer="zeros", - name="dwconv", - ) # depthwise conv - self.layernorm = keras.layers.LayerNormalization( - epsilon=1e-6, - name="layernorm", - ) - self.pwconv1 = keras.layers.Dense( - units=4 * dim, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer="zeros", - name="pwconv1", - ) # pointwise/1x1 convs, implemented with linear layers - self.act = get_tf_activation(config.hidden_act) - self.pwconv2 = keras.layers.Dense( - units=dim, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer="zeros", - name="pwconv2", - ) - # Using `layers.Activation` instead of `tf.identity` to better control `training` - # behaviour. - self.drop_path = ( - TFConvNextDropPath(drop_path, name="drop_path") - if drop_path > 0.0 - else keras.layers.Activation("linear", name="drop_path") - ) - - def build(self, input_shape: tf.TensorShape = None): - # PT's `nn.Parameters` must be mapped to a TF layer weight to inherit the same name hierarchy (and vice-versa) - self.layer_scale_parameter = ( - self.add_weight( - shape=(self.dim,), - initializer=keras.initializers.Constant(value=self.config.layer_scale_init_value), - trainable=True, - name="layer_scale_parameter", - ) - if self.config.layer_scale_init_value > 0 - else None - ) - - if self.built: - return - self.built = True - if getattr(self, "dwconv", None) is not None: - with tf.name_scope(self.dwconv.name): - self.dwconv.build([None, None, None, self.dim]) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, None, self.dim]) - if getattr(self, "pwconv1", None) is not None: - with tf.name_scope(self.pwconv1.name): - self.pwconv1.build([None, None, self.dim]) - if getattr(self, "pwconv2", None) is not None: - with tf.name_scope(self.pwconv2.name): - self.pwconv2.build([None, None, 4 * self.dim]) - if getattr(self, "drop_path", None) is not None: - with tf.name_scope(self.drop_path.name): - self.drop_path.build(None) - - def call(self, hidden_states, training=False): - input = hidden_states - x = self.dwconv(hidden_states) - x = self.layernorm(x) - x = self.pwconv1(x) - x = self.act(x) - x = self.pwconv2(x) - - if self.layer_scale_parameter is not None: - x = self.layer_scale_parameter * x - - x = input + self.drop_path(x, training=training) - return x - - -class TFConvNextStage(keras.layers.Layer): - """ConvNext stage, consisting of an optional downsampling layer + multiple residual blocks. - - Args: - config (`ConvNextV2Config`): - Model configuration class. - in_channels (`int`): - Number of input channels. - out_channels (`int`): - Number of output channels. - depth (`int`): - Number of residual blocks. - drop_path_rates(`list[float]`): - Stochastic depth rates for each layer. - """ - - def __init__( - self, - config: ConvNextConfig, - in_channels: int, - out_channels: int, - kernel_size: int = 2, - stride: int = 2, - depth: int = 2, - drop_path_rates: list[float] | None = None, - **kwargs, - ): - super().__init__(**kwargs) - if in_channels != out_channels or stride > 1: - self.downsampling_layer = [ - keras.layers.LayerNormalization( - epsilon=1e-6, - name="downsampling_layer.0", - ), - # Inputs to this layer will follow NHWC format since we - # transposed the inputs from NCHW to NHWC in the `TFConvNextEmbeddings` - # layer. All the outputs throughout the model will be in NHWC - # from this point on until the output where we again change to - # NCHW. - keras.layers.Conv2D( - filters=out_channels, - kernel_size=kernel_size, - strides=stride, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer=keras.initializers.Zeros(), - name="downsampling_layer.1", - ), - ] - else: - self.downsampling_layer = [tf.identity] - - drop_path_rates = drop_path_rates or [0.0] * depth - self.layers = [ - TFConvNextLayer( - config, - dim=out_channels, - drop_path=drop_path_rates[j], - name=f"layers.{j}", - ) - for j in range(depth) - ] - self.in_channels = in_channels - self.out_channels = out_channels - self.stride = stride - - def call(self, hidden_states): - for layer in self.downsampling_layer: - hidden_states = layer(hidden_states) - for layer in self.layers: - hidden_states = layer(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - if self.in_channels != self.out_channels or self.stride > 1: - with tf.name_scope(self.downsampling_layer[0].name): - self.downsampling_layer[0].build([None, None, None, self.in_channels]) - with tf.name_scope(self.downsampling_layer[1].name): - self.downsampling_layer[1].build([None, None, None, self.in_channels]) - - -class TFConvNextEncoder(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.stages = [] - drop_path_rates = tf.linspace(0.0, config.drop_path_rate, sum(config.depths)) - drop_path_rates = tf.split(drop_path_rates, config.depths) - drop_path_rates = [x.numpy().tolist() for x in drop_path_rates] - prev_chs = config.hidden_sizes[0] - for i in range(config.num_stages): - out_chs = config.hidden_sizes[i] - stage = TFConvNextStage( - config, - in_channels=prev_chs, - out_channels=out_chs, - stride=2 if i > 0 else 1, - depth=config.depths[i], - drop_path_rates=drop_path_rates[i], - name=f"stages.{i}", - ) - self.stages.append(stage) - prev_chs = out_chs - - def call(self, hidden_states, output_hidden_states=False, return_dict=True): - all_hidden_states = () if output_hidden_states else None - - for i, layer_module in enumerate(self.stages): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - hidden_states = layer_module(hidden_states) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states] if v is not None) - - return TFBaseModelOutput(last_hidden_state=hidden_states, hidden_states=all_hidden_states) - - def build(self, input_shape=None): - for stage in self.stages: - with tf.name_scope(stage.name): - stage.build(None) - - -@keras_serializable -class TFConvNextMainLayer(keras.layers.Layer): - config_class = ConvNextConfig - - def __init__(self, config: ConvNextConfig, add_pooling_layer: bool = True, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embeddings = TFConvNextEmbeddings(config, name="embeddings") - self.encoder = TFConvNextEncoder(config, name="encoder") - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - # We are setting the `data_format` like so because from here on we will revert to the - # NCHW output format - self.pooler = keras.layers.GlobalAvgPool2D(data_format="channels_first") if add_pooling_layer else None - - @unpack_inputs - def call( - self, - pixel_values: TFModelInputType | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - embedding_output = self.embeddings(pixel_values, training=training) - - encoder_outputs = self.encoder( - embedding_output, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - last_hidden_state = encoder_outputs[0] - # Change to NCHW output format have uniformity in the modules - last_hidden_state = tf.transpose(last_hidden_state, perm=(0, 3, 1, 2)) - pooled_output = self.layernorm(self.pooler(last_hidden_state)) - - # Change the other hidden state outputs to NCHW as well - if output_hidden_states: - hidden_states = tuple(tf.transpose(h, perm=(0, 3, 1, 2)) for h in encoder_outputs[1]) - - if not return_dict: - hidden_states = hidden_states if output_hidden_states else () - return (last_hidden_state, pooled_output) + hidden_states - - return TFBaseModelOutputWithPooling( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=hidden_states if output_hidden_states else encoder_outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, self.config.hidden_sizes[-1]]) - - -class TFConvNextPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = ConvNextConfig - base_model_prefix = "convnext" - main_input_name = "pixel_values" - - -CONVNEXT_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `pixel_values` only and nothing else: `model(pixel_values)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([pixel_values, attention_mask])` or `model([pixel_values, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"pixel_values": pixel_values, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`ConvNextConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -CONVNEXT_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`ConvNextImageProcessor.__call__`] for details. - - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. -""" - - -@add_start_docstrings( - "The bare ConvNext model outputting raw features without any specific head on top.", - CONVNEXT_START_DOCSTRING, -) -class TFConvNextModel(TFConvNextPreTrainedModel): - def __init__(self, config, *inputs, add_pooling_layer=True, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.convnext = TFConvNextMainLayer(config, add_pooling_layer=add_pooling_layer, name="convnext") - - @unpack_inputs - @add_start_docstrings_to_model_forward(CONVNEXT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBaseModelOutputWithPooling, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: TFModelInputType | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, TFConvNextModel - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/convnext-tiny-224") - >>> model = TFConvNextModel.from_pretrained("facebook/convnext-tiny-224") - - >>> inputs = image_processor(images=image, return_tensors="tf") - >>> outputs = model(**inputs) - >>> last_hidden_states = outputs.last_hidden_state - ```""" - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - outputs = self.convnext( - pixel_values=pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return (outputs[0],) + outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=outputs.last_hidden_state, - pooler_output=outputs.pooler_output, - hidden_states=outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convnext", None) is not None: - with tf.name_scope(self.convnext.name): - self.convnext.build(None) - - -@add_start_docstrings( - """ - ConvNext Model with an image classification head on top (a linear layer on top of the pooled features), e.g. for - ImageNet. - """, - CONVNEXT_START_DOCSTRING, -) -class TFConvNextForImageClassification(TFConvNextPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: ConvNextConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.convnext = TFConvNextMainLayer(config, name="convnext") - - # Classifier head - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer="zeros", - name="classifier", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(CONVNEXT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSequenceClassifierOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: TFModelInputType | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, TFConvNextForImageClassification - >>> import tensorflow as tf - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/convnext-tiny-224") - >>> model = TFConvNextForImageClassification.from_pretrained("facebook/convnext-tiny-224") - - >>> inputs = image_processor(images=image, return_tensors="tf") - >>> outputs = model(**inputs) - >>> logits = outputs.logits - >>> # model predicts one of the 1000 ImageNet classes - >>> predicted_class_idx = tf.math.argmax(logits, axis=-1)[0] - >>> print("Predicted class:", model.config.id2label[int(predicted_class_idx)]) - ```""" - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - outputs = self.convnext( - pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - pooled_output = outputs.pooler_output if return_dict else outputs[1] - - logits = self.classifier(pooled_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convnext", None) is not None: - with tf.name_scope(self.convnext.name): - self.convnext.build(None) - if getattr(self, "classifier", None) is not None: - if hasattr(self.classifier, "name"): - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_sizes[-1]]) - - -__all__ = ["TFConvNextForImageClassification", "TFConvNextModel", "TFConvNextPreTrainedModel"] diff --git a/src/transformers/models/convnextv2/__init__.py b/src/transformers/models/convnextv2/__init__.py index 0fd1293963b2..9e02170eceae 100644 --- a/src/transformers/models/convnextv2/__init__.py +++ b/src/transformers/models/convnextv2/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_convnextv2 import * from .modeling_convnextv2 import * - from .modeling_tf_convnextv2 import * else: import sys diff --git a/src/transformers/models/convnextv2/modeling_convnextv2.py b/src/transformers/models/convnextv2/modeling_convnextv2.py index bfa5338f5e86..3bf6130824ed 100644 --- a/src/transformers/models/convnextv2/modeling_convnextv2.py +++ b/src/transformers/models/convnextv2/modeling_convnextv2.py @@ -41,11 +41,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -267,8 +262,6 @@ class ConvNextV2PreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/convnextv2/modeling_tf_convnextv2.py b/src/transformers/models/convnextv2/modeling_tf_convnextv2.py deleted file mode 100644 index d370c3008d47..000000000000 --- a/src/transformers/models/convnextv2/modeling_tf_convnextv2.py +++ /dev/null @@ -1,681 +0,0 @@ -# coding=utf-8 -# Copyright 2023 Meta Platforms Inc. and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 ConvNextV2 model.""" - -from __future__ import annotations - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithNoAttention, - TFBaseModelOutputWithPooling, - TFBaseModelOutputWithPoolingAndNoAttention, - TFImageClassifierOutputWithNoAttention, -) -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_convnextv2 import ConvNextV2Config - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "ConvNextV2Config" - -# Base docstring -_CHECKPOINT_FOR_DOC = "facebook/convnextv2-tiny-1k-224" -_EXPECTED_OUTPUT_SHAPE = [1, 768, 7, 7] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "facebook/convnextv2-tiny-1k-224" -_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" - - -# Copied from transformers.models.convnext.modeling_tf_convnext.TFConvNextDropPath with ConvNext->ConvNextV2 -class TFConvNextV2DropPath(keras.layers.Layer): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - References: - (1) github.com:rwightman/pytorch-image-models - """ - - def __init__(self, drop_path: float, **kwargs): - super().__init__(**kwargs) - self.drop_path = drop_path - - def call(self, x: tf.Tensor, training=None): - if training: - keep_prob = 1 - self.drop_path - shape = (tf.shape(x)[0],) + (1,) * (len(tf.shape(x)) - 1) - random_tensor = keep_prob + tf.random.uniform(shape, 0, 1) - random_tensor = tf.floor(random_tensor) - return (x / keep_prob) * random_tensor - return x - - -class TFConvNextV2GRN(keras.layers.Layer): - """GRN (Global Response Normalization) layer""" - - def __init__(self, config: ConvNextV2Config, dim: int, **kwargs): - super().__init__(**kwargs) - self.dim = dim - - def build(self, input_shape: tf.TensorShape = None): - # PT's `nn.Parameters` must be mapped to a TF layer weight to inherit the same name hierarchy (and vice-versa) - self.weight = self.add_weight( - name="weight", - shape=(1, 1, 1, self.dim), - initializer=keras.initializers.Zeros(), - ) - self.bias = self.add_weight( - name="bias", - shape=(1, 1, 1, self.dim), - initializer=keras.initializers.Zeros(), - ) - return super().build(input_shape) - - def call(self, hidden_states: tf.Tensor): - global_features = tf.norm(hidden_states, ord="euclidean", axis=(1, 2), keepdims=True) - norm_features = global_features / (tf.reduce_mean(global_features, axis=-1, keepdims=True) + 1e-6) - hidden_states = self.weight * (hidden_states * norm_features) + self.bias + hidden_states - return hidden_states - - -# Copied from transformers.models.convnext.modeling_tf_convnext.TFConvNextEmbeddings with ConvNext->ConvNextV2 -class TFConvNextV2Embeddings(keras.layers.Layer): - """This class is comparable to (and inspired by) the SwinEmbeddings class - found in src/transformers/models/swin/modeling_swin.py. - """ - - def __init__(self, config: ConvNextV2Config, **kwargs): - super().__init__(**kwargs) - self.patch_embeddings = keras.layers.Conv2D( - filters=config.hidden_sizes[0], - kernel_size=config.patch_size, - strides=config.patch_size, - name="patch_embeddings", - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer=keras.initializers.Zeros(), - ) - self.layernorm = keras.layers.LayerNormalization(epsilon=1e-6, name="layernorm") - self.num_channels = config.num_channels - self.config = config - - def call(self, pixel_values): - if isinstance(pixel_values, dict): - pixel_values = pixel_values["pixel_values"] - - tf.debugging.assert_equal( - shape_list(pixel_values)[1], - self.num_channels, - message="Make sure that the channel dimension of the pixel values match with the one set in the configuration.", - ) - - # When running on CPU, `keras.layers.Conv2D` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - # shape = (batch_size, in_height, in_width, in_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - - embeddings = self.patch_embeddings(pixel_values) - embeddings = self.layernorm(embeddings) - return embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "patch_embeddings", None) is not None: - with tf.name_scope(self.patch_embeddings.name): - self.patch_embeddings.build([None, None, None, self.config.num_channels]) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, None, self.config.hidden_sizes[0]]) - - -class TFConvNextV2Layer(keras.layers.Layer): - """This corresponds to the `Block` class in the original implementation. - - There are two equivalent implementations: [DwConv, LayerNorm (channels_first), Conv, GELU,1x1 Conv]; all in (N, C, - H, W) (2) [DwConv, Permute to (N, H, W, C), LayerNorm (channels_last), Linear, GELU, Linear]; Permute back - - The authors used (2) as they find it slightly faster in PyTorch. Since we already permuted the inputs to follow - NHWC ordering, we can just apply the operations straight-away without the permutation. - - Args: - config (`ConvNextV2Config`): - Model configuration class. - dim (`int`): - Number of input channels. - drop_path (`float`, *optional*, defaults to 0.0): - Stochastic depth rate. - """ - - def __init__(self, config: ConvNextV2Config, dim: int, drop_path: float = 0.0, **kwargs): - super().__init__(**kwargs) - self.dim = dim - self.config = config - self.dwconv = keras.layers.Conv2D( - filters=dim, - kernel_size=7, - padding="same", - groups=dim, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer=keras.initializers.Zeros(), - name="dwconv", - ) # depthwise conv - self.layernorm = keras.layers.LayerNormalization( - epsilon=1e-6, - name="layernorm", - ) - self.pwconv1 = keras.layers.Dense( - units=4 * dim, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer=keras.initializers.Zeros(), - name="pwconv1", - ) # pointwise/1x1 convs, implemented with linear layers - self.act = get_tf_activation(config.hidden_act) - self.grn = TFConvNextV2GRN(config, 4 * dim, dtype=tf.float32, name="grn") - self.pwconv2 = keras.layers.Dense( - units=dim, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer=keras.initializers.Zeros(), - name="pwconv2", - ) - # Using `layers.Activation` instead of `tf.identity` to better control `training` - # behaviour. - self.drop_path = ( - TFConvNextV2DropPath(drop_path, name="drop_path") - if drop_path > 0.0 - else keras.layers.Activation("linear", name="drop_path") - ) - - def call(self, hidden_states, training=False): - input = hidden_states - x = self.dwconv(hidden_states) - x = self.layernorm(x) - x = self.pwconv1(x) - x = self.act(x) - x = self.grn(x) - x = self.pwconv2(x) - x = self.drop_path(x, training=training) - x = input + x - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dwconv", None) is not None: - with tf.name_scope(self.dwconv.name): - self.dwconv.build([None, None, None, self.dim]) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, None, self.dim]) - if getattr(self, "pwconv1", None) is not None: - with tf.name_scope(self.pwconv1.name): - self.pwconv1.build([None, None, self.dim]) - if getattr(self, "grn", None) is not None: - with tf.name_scope(self.grn.name): - self.grn.build(None) - if getattr(self, "pwconv2", None) is not None: - with tf.name_scope(self.pwconv2.name): - self.pwconv2.build([None, None, 4 * self.dim]) - if getattr(self, "drop_path", None) is not None: - with tf.name_scope(self.drop_path.name): - self.drop_path.build(None) - - -# Copied from transformers.models.convnext.modeling_tf_convnext.TFConvNextStage with ConvNext->ConvNextV2 -class TFConvNextV2Stage(keras.layers.Layer): - """ConvNextV2 stage, consisting of an optional downsampling layer + multiple residual blocks. - - Args: - config (`ConvNextV2V2Config`): - Model configuration class. - in_channels (`int`): - Number of input channels. - out_channels (`int`): - Number of output channels. - depth (`int`): - Number of residual blocks. - drop_path_rates(`list[float]`): - Stochastic depth rates for each layer. - """ - - def __init__( - self, - config: ConvNextV2Config, - in_channels: int, - out_channels: int, - kernel_size: int = 2, - stride: int = 2, - depth: int = 2, - drop_path_rates: list[float] | None = None, - **kwargs, - ): - super().__init__(**kwargs) - if in_channels != out_channels or stride > 1: - self.downsampling_layer = [ - keras.layers.LayerNormalization( - epsilon=1e-6, - name="downsampling_layer.0", - ), - # Inputs to this layer will follow NHWC format since we - # transposed the inputs from NCHW to NHWC in the `TFConvNextV2Embeddings` - # layer. All the outputs throughout the model will be in NHWC - # from this point on until the output where we again change to - # NCHW. - keras.layers.Conv2D( - filters=out_channels, - kernel_size=kernel_size, - strides=stride, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer=keras.initializers.Zeros(), - name="downsampling_layer.1", - ), - ] - else: - self.downsampling_layer = [tf.identity] - - drop_path_rates = drop_path_rates or [0.0] * depth - self.layers = [ - TFConvNextV2Layer( - config, - dim=out_channels, - drop_path=drop_path_rates[j], - name=f"layers.{j}", - ) - for j in range(depth) - ] - self.in_channels = in_channels - self.out_channels = out_channels - self.stride = stride - - def call(self, hidden_states): - for layer in self.downsampling_layer: - hidden_states = layer(hidden_states) - for layer in self.layers: - hidden_states = layer(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - if self.in_channels != self.out_channels or self.stride > 1: - with tf.name_scope(self.downsampling_layer[0].name): - self.downsampling_layer[0].build([None, None, None, self.in_channels]) - with tf.name_scope(self.downsampling_layer[1].name): - self.downsampling_layer[1].build([None, None, None, self.in_channels]) - - -class TFConvNextV2Encoder(keras.layers.Layer): - def __init__(self, config: ConvNextV2Config, **kwargs): - super().__init__(**kwargs) - self.stages = [] - drop_path_rates = tf.linspace(0.0, config.drop_path_rate, sum(config.depths)) - drop_path_rates = tf.split(drop_path_rates, config.depths) - drop_path_rates = [x.numpy().tolist() for x in drop_path_rates] - prev_chs = config.hidden_sizes[0] - for i in range(config.num_stages): - out_chs = config.hidden_sizes[i] - stage = TFConvNextV2Stage( - config, - in_channels=prev_chs, - out_channels=out_chs, - stride=2 if i > 0 else 1, - depth=config.depths[i], - drop_path_rates=drop_path_rates[i], - name=f"stages.{i}", - ) - self.stages.append(stage) - prev_chs = out_chs - - def call( - self, - hidden_states: tf.Tensor, - output_hidden_states: bool | None = False, - return_dict: bool | None = True, - ) -> tuple | TFBaseModelOutputWithNoAttention: - all_hidden_states = () if output_hidden_states else None - - for i, layer_module in enumerate(self.stages): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - hidden_states = layer_module(hidden_states) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states] if v is not None) - - return TFBaseModelOutputWithNoAttention(last_hidden_state=hidden_states, hidden_states=all_hidden_states) - - def build(self, input_shape=None): - for stage in self.stages: - with tf.name_scope(stage.name): - stage.build(None) - - -@keras_serializable -class TFConvNextV2MainLayer(keras.layers.Layer): - config_class = ConvNextV2Config - - def __init__(self, config: ConvNextV2Config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embeddings = TFConvNextV2Embeddings(config, name="embeddings") - self.encoder = TFConvNextV2Encoder(config, name="encoder") - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - # We are setting the `data_format` like so because from here on we will revert to the - # NCHW output format - self.pooler = keras.layers.GlobalAvgPool2D(data_format="channels_last") - - @unpack_inputs - def call( - self, - pixel_values: TFModelInputType | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - embedding_output = self.embeddings(pixel_values, training=training) - - encoder_outputs = self.encoder( - embedding_output, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - last_hidden_state = encoder_outputs[0] - - # Change to NCHW output format have uniformity in the modules - pooled_output = self.pooler(last_hidden_state) - last_hidden_state = tf.transpose(last_hidden_state, perm=(0, 3, 1, 2)) - pooled_output = self.layernorm(pooled_output) - - # Change the other hidden state outputs to NCHW as well - if output_hidden_states: - hidden_states = tuple(tf.transpose(h, perm=(0, 3, 1, 2)) for h in encoder_outputs[1]) - - if not return_dict: - hidden_states = hidden_states if output_hidden_states else () - return (last_hidden_state, pooled_output) + hidden_states - - return TFBaseModelOutputWithPoolingAndNoAttention( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=hidden_states if output_hidden_states else encoder_outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, self.config.hidden_sizes[-1]]) - - -class TFConvNextV2PreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = ConvNextV2Config - base_model_prefix = "convnextv2" - main_input_name = "pixel_values" - - -CONVNEXTV2_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `pixel_values` only and nothing else: `model(pixel_values)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([pixel_values, attention_mask])` or `model([pixel_values, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"pixel_values": pixel_values, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`ConvNextV2Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -CONVNEXTV2_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]`, `dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`ConvNextImageProcessor.__call__`] for details. - - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to `True`. -""" - - -@add_start_docstrings( - "The bare ConvNextV2 model outputting raw features without any specific head on top.", - CONVNEXTV2_START_DOCSTRING, -) -class TFConvNextV2Model(TFConvNextV2PreTrainedModel): - def __init__(self, config: ConvNextV2Config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.convnextv2 = TFConvNextV2MainLayer(config, name="convnextv2") - - @unpack_inputs - @add_start_docstrings_to_model_forward(CONVNEXTV2_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPoolingAndNoAttention, - config_class=_CONFIG_FOR_DOC, - modality="vision", - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - def call( - self, - pixel_values: TFModelInputType | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPoolingAndNoAttention | tuple[tf.Tensor]: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - outputs = self.convnextv2( - pixel_values=pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return outputs[:] - - return TFBaseModelOutputWithPoolingAndNoAttention( - last_hidden_state=outputs.last_hidden_state, - pooler_output=outputs.pooler_output, - hidden_states=outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convnextv2", None) is not None: - with tf.name_scope(self.convnextv2.name): - self.convnextv2.build(None) - - -@add_start_docstrings( - """ - ConvNextV2 Model with an image classification head on top (a linear layer on top of the pooled features), e.g. for - ImageNet. - """, - CONVNEXTV2_START_DOCSTRING, -) -class TFConvNextV2ForImageClassification(TFConvNextV2PreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: ConvNextV2Config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.convnextv2 = TFConvNextV2MainLayer(config, name="convnextv2") - - # Classifier head - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer=keras.initializers.Zeros(), - name="classifier", - ) - - @unpack_inputs - @add_start_docstrings_to_model_forward(CONVNEXTV2_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFImageClassifierOutputWithNoAttention, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - def call( - self, - pixel_values: TFModelInputType | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFImageClassifierOutputWithNoAttention | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - outputs = self.convnextv2( - pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - pooled_output = outputs.pooler_output if return_dict else outputs[1] - - logits = self.classifier(pooled_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFImageClassifierOutputWithNoAttention( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convnextv2", None) is not None: - with tf.name_scope(self.convnextv2.name): - self.convnextv2.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_sizes[-1]]) - - -__all__ = ["TFConvNextV2ForImageClassification", "TFConvNextV2Model", "TFConvNextV2PreTrainedModel"] diff --git a/src/transformers/models/csm/processing_csm.py b/src/transformers/models/csm/processing_csm.py index 0f929f6a2a0c..7e16ecbb6001 100644 --- a/src/transformers/models/csm/processing_csm.py +++ b/src/transformers/models/csm/processing_csm.py @@ -226,10 +226,8 @@ def __call__( The ratio of audio frames to keep for the depth decoder labels. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/ctrl/__init__.py b/src/transformers/models/ctrl/__init__.py index ea62163babef..93f27ba0710e 100644 --- a/src/transformers/models/ctrl/__init__.py +++ b/src/transformers/models/ctrl/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_ctrl import * from .modeling_ctrl import * - from .modeling_tf_ctrl import * from .tokenization_ctrl import * else: import sys diff --git a/src/transformers/models/ctrl/modeling_ctrl.py b/src/transformers/models/ctrl/modeling_ctrl.py index 506bed039b17..03da5b51c907 100644 --- a/src/transformers/models/ctrl/modeling_ctrl.py +++ b/src/transformers/models/ctrl/modeling_ctrl.py @@ -216,8 +216,6 @@ class CTRLPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, (nn.Linear, Conv1D)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/ctrl/modeling_tf_ctrl.py b/src/transformers/models/ctrl/modeling_tf_ctrl.py deleted file mode 100644 index 1dce90147bd8..000000000000 --- a/src/transformers/models/ctrl/modeling_tf_ctrl.py +++ /dev/null @@ -1,920 +0,0 @@ -# coding=utf-8 -# Copyright 2018 Salesforce and HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 CTRL model.""" - -from __future__ import annotations - -import numpy as np -import tensorflow as tf - -from ...modeling_tf_outputs import TFBaseModelOutputWithPast, TFCausalLMOutputWithPast, TFSequenceClassifierOutput -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_ctrl import CTRLConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "Salesforce/ctrl" -_CONFIG_FOR_DOC = "CTRLConfig" - - -def angle_defn(pos, i, d_model_size): - angle_rates = 1 / np.power(10000, (2 * (i // 2)) / d_model_size) - return pos * angle_rates - - -def positional_encoding(position, d_model_size): - # create the sinusoidal pattern for the positional encoding - angle_rads = angle_defn(np.arange(position)[:, np.newaxis], np.arange(d_model_size)[np.newaxis, :], d_model_size) - - sines = np.sin(angle_rads[:, 0::2]) - cosines = np.cos(angle_rads[:, 1::2]) - pos_encoding = tf.convert_to_tensor(np.concatenate([sines, cosines], axis=-1)) - - return pos_encoding - - -def scaled_dot_product_attention(q, k, v, mask, attention_mask=None, head_mask=None): - # calculate attention - matmul_qk = tf.matmul(q, k, transpose_b=True) - - dk = tf.cast(shape_list(k)[-1], dtype=matmul_qk.dtype) - scaled_attention_logits = matmul_qk / tf.math.sqrt(dk) - - if mask is not None: - scaled_attention_logits += tf.cast(mask * -1e4, dtype=scaled_attention_logits.dtype) - - if attention_mask is not None: - # Apply the attention mask - attention_mask = tf.cast(attention_mask, dtype=scaled_attention_logits.dtype) - scaled_attention_logits = scaled_attention_logits + attention_mask - - attention_weights = stable_softmax(scaled_attention_logits, axis=-1) - - # Mask heads if we want to - if head_mask is not None: - attention_weights = attention_weights * head_mask - - output = tf.matmul(attention_weights, v) - - return output, attention_weights - - -class TFMultiHeadAttention(keras.layers.Layer): - def __init__(self, d_model_size, num_heads, output_attentions=False, **kwargs): - super().__init__(**kwargs) - self.num_heads = num_heads - self.d_model_size = d_model_size - self.output_attentions = output_attentions - - self.depth = int(d_model_size / self.num_heads) - - self.Wq = keras.layers.Dense(d_model_size, name="Wq") - self.Wk = keras.layers.Dense(d_model_size, name="Wk") - self.Wv = keras.layers.Dense(d_model_size, name="Wv") - - self.dense = keras.layers.Dense(d_model_size, name="dense") - - def split_into_heads(self, x, batch_size): - x = tf.reshape(x, (batch_size, -1, self.num_heads, self.depth)) - return tf.transpose(x, perm=[0, 2, 1, 3]) - - def call(self, v, k, q, mask, layer_past, attention_mask, head_mask, use_cache, output_attentions, training=False): - batch_size = shape_list(q)[0] - - q = self.Wq(q) - k = self.Wk(k) - v = self.Wv(v) - - q = self.split_into_heads(q, batch_size) - k = self.split_into_heads(k, batch_size) - v = self.split_into_heads(v, batch_size) - - if layer_past is not None: - past_key, past_value = tf.unstack(layer_past, axis=0) - k = tf.concat((past_key, k), axis=-2) - v = tf.concat((past_value, v), axis=-2) - - if use_cache: - present = tf.stack((k, v), axis=0) - else: - present = (None,) - - output = scaled_dot_product_attention(q, k, v, mask, attention_mask, head_mask) - scaled_attention = tf.transpose(output[0], perm=[0, 2, 1, 3]) - attn = output[1] - original_size_attention = tf.reshape(scaled_attention, (batch_size, -1, self.d_model_size)) - output = self.dense(original_size_attention) - outputs = (output, present) - - if output_attentions: - outputs = outputs + (attn,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "Wq", None) is not None: - with tf.name_scope(self.Wq.name): - self.Wq.build([None, None, self.d_model_size]) - if getattr(self, "Wk", None) is not None: - with tf.name_scope(self.Wk.name): - self.Wk.build([None, None, self.d_model_size]) - if getattr(self, "Wv", None) is not None: - with tf.name_scope(self.Wv.name): - self.Wv.build([None, None, self.d_model_size]) - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.d_model_size]) - - -class TFPointWiseFeedForwardLayer(keras.layers.Layer): - def __init__(self, d_model_size, dff, **kwargs): - super().__init__(**kwargs) - - self.dense_0 = keras.layers.Dense(dff, activation="relu", name="0") - self.dense_2 = keras.layers.Dense(d_model_size, name="2") - self.d_model_size = d_model_size - self.dff = dff - - def call(self, inputs, trainable=False): - dense_0_output = self.dense_0(inputs) - dense_2_output = self.dense_2(dense_0_output) - - return dense_2_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense_0", None) is not None: - with tf.name_scope(self.dense_0.name): - self.dense_0.build([None, None, self.d_model_size]) - if getattr(self, "dense_2", None) is not None: - with tf.name_scope(self.dense_2.name): - self.dense_2.build([None, None, self.dff]) - - -class TFEncoderLayer(keras.layers.Layer): - def __init__( - self, d_model_size, num_heads, dff, rate=0.1, layer_norm_epsilon=1e-6, output_attentions=False, **kwargs - ): - super().__init__(**kwargs) - - self.output_attentions = output_attentions - - self.multi_head_attention = TFMultiHeadAttention( - d_model_size, num_heads, output_attentions=self.output_attentions, name="multi_head_attention" - ) - self.ffn = TFPointWiseFeedForwardLayer(d_model_size, dff, name="ffn") - - self.layernorm1 = keras.layers.LayerNormalization(epsilon=layer_norm_epsilon, name="layernorm1") - self.layernorm2 = keras.layers.LayerNormalization(epsilon=layer_norm_epsilon, name="layernorm2") - - self.dropout1 = keras.layers.Dropout(rate) - self.dropout2 = keras.layers.Dropout(rate) - self.d_model_size = d_model_size - - def call(self, x, mask, layer_past, attention_mask, head_mask, use_cache, output_attentions, training=False): - normed = self.layernorm1(x) - attn_outputs = self.multi_head_attention( - normed, - normed, - normed, - mask, - layer_past, - attention_mask, - head_mask, - use_cache, - output_attentions, - training=training, - ) - attn_output = attn_outputs[0] - attn_output = self.dropout1(attn_output, training=training) - out1 = x + attn_output - - out2 = self.layernorm2(out1) - ffn_output = self.ffn(out2) - ffn_output = self.dropout2(ffn_output, training=training) - out2 = out1 + ffn_output - - outputs = (out2,) + attn_outputs[1:] - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "multi_head_attention", None) is not None: - with tf.name_scope(self.multi_head_attention.name): - self.multi_head_attention.build(None) - if getattr(self, "ffn", None) is not None: - with tf.name_scope(self.ffn.name): - self.ffn.build(None) - if getattr(self, "layernorm1", None) is not None: - with tf.name_scope(self.layernorm1.name): - self.layernorm1.build([None, None, self.d_model_size]) - if getattr(self, "layernorm2", None) is not None: - with tf.name_scope(self.layernorm2.name): - self.layernorm2.build([None, None, self.d_model_size]) - - -@keras_serializable -class TFCTRLMainLayer(keras.layers.Layer): - config_class = CTRLConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.output_hidden_states = config.output_hidden_states - self.output_attentions = config.output_attentions - self.use_cache = config.use_cache - self.return_dict = config.use_return_dict - - self.d_model_size = config.n_embd - self.num_layers = config.n_layer - - self.pos_encoding = positional_encoding(config.n_positions, self.d_model_size) - - self.w = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.n_embd, - embeddings_initializer=get_initializer(config.initializer_range), - name="w", - ) - - self.dropout = keras.layers.Dropout(config.embd_pdrop) - self.h = [ - TFEncoderLayer( - config.n_embd, - config.n_head, - config.dff, - config.resid_pdrop, - config.layer_norm_epsilon, - self.output_attentions, - name=f"h_._{i}", - ) - for i in range(config.n_layer) - ] - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_epsilon, name="layernorm") - - def get_input_embeddings(self): - return self.w - - def set_input_embeddings(self, new_embeddings): - self.w = new_embeddings - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutputWithPast: - # If using past key value states, only the last tokens - # should be given as an input - if past_key_values is not None: - if input_ids is not None: - input_ids = input_ids[:, -1:] - if inputs_embeds is not None: - inputs_embeds = inputs_embeds[:, -1:] - if token_type_ids is not None: - token_type_ids = token_type_ids[:, -1:] - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - input_ids = tf.reshape(input_ids, [-1, input_shape[-1]]) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if past_key_values is None: - past_length = 0 - past_key_values = [None] * len(self.h) - else: - past_length = shape_list(past_key_values[0][0])[-2] - if position_ids is None: - position_ids = tf.expand_dims(tf.range(past_length, input_shape[-1] + past_length, dtype=tf.int32), axis=0) - position_ids = tf.tile(position_ids, [input_shape[0], 1]) - - # Attention mask. - if attention_mask is not None: - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1] + past_length)) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - - one_cst = tf.constant(1.0) - ten_thousand_cst = tf.constant(-10000.0) - attention_mask = tf.cast(attention_mask, dtype=one_cst.dtype) - attention_mask = tf.multiply(tf.subtract(one_cst, attention_mask), ten_thousand_cst) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # head_mask has shape n_layer x batch x n_heads x N x N - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.num_layers - - if token_type_ids is not None: - token_type_ids = tf.reshape(token_type_ids, [-1, shape_list(token_type_ids)[-1]]) - token_type_embeds = self.w(token_type_ids) - token_type_embeds *= tf.math.sqrt(tf.cast(self.d_model_size, dtype=token_type_embeds.dtype)) - else: - token_type_embeds = tf.constant(0.0) - position_ids = tf.reshape(position_ids, [-1, shape_list(position_ids)[-1]]) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.w.input_dim) - inputs_embeds = self.w(input_ids) - seq_len = input_shape[-1] - mask = 1 - tf.linalg.band_part(tf.ones((seq_len, seq_len)), -1, 0) - - inputs_embeds *= tf.math.sqrt(tf.cast(self.d_model_size, inputs_embeds.dtype)) - - pos_embeds = tf.gather(self.pos_encoding, position_ids) - pos_embeds = tf.cast(pos_embeds, dtype=token_type_embeds.dtype) - hidden_states = inputs_embeds + pos_embeds + token_type_embeds - - hidden_states = self.dropout(hidden_states, training=training) - - output_shape = input_shape + [shape_list(hidden_states)[-1]] - presents = () if use_cache else None - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - for i, (h, layer_past) in enumerate(zip(self.h, past_key_values)): - if output_hidden_states: - all_hidden_states = all_hidden_states + (tf.reshape(hidden_states, output_shape),) - outputs = h( - hidden_states, - mask, - layer_past, - attention_mask, - head_mask[i], - use_cache, - output_attentions, - training=training, - ) - hidden_states, present = outputs[:2] - - if use_cache: - presents = presents + (present,) - - if output_attentions: - all_attentions = all_attentions + (outputs[2],) - - hidden_states = self.layernorm(hidden_states) - hidden_states = tf.reshape(hidden_states, output_shape) - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if output_attentions: - # let the number of heads free (-1) so we can extract attention even after head pruning - attention_output_shape = input_shape[:-1] + [-1] + shape_list(all_attentions[0])[-2:] - all_attentions = tuple(tf.reshape(t, attention_output_shape) for t in all_attentions) - - if not return_dict: - return tuple(v for v in [hidden_states, presents, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutputWithPast( - last_hidden_state=hidden_states, - past_key_values=presents, - hidden_states=all_hidden_states, - attentions=all_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "w", None) is not None: - with tf.name_scope(self.w.name): - self.w.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, self.config.n_embd]) - if getattr(self, "h", None) is not None: - for layer in self.h: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFCTRLPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = CTRLConfig - base_model_prefix = "transformer" - - -CTRL_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`CTRLConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -CTRL_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, input_ids_length)`): - `input_ids_length` = `sequence_length` if `past` is `None` else `past[0].shape[-2]` (`sequence_length` of - input past key value states). - - Indices of input sequence tokens in the vocabulary. - - If `past` is used, only input IDs that do not have their past calculated should be passed as `input_ids`. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - past (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states (key and values in the attention blocks) as computed by the model (see - `past` output below). Can be used to speed up sequential decoding. The token ids which have their past - given to this model should not be passed as input ids as they have already been computed. - attention_mask (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, input_ids_length)`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, input_ids_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` or `Numpy array` of shape `(batch_size, input_ids_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - use_cache (`bool`, *optional*): - If set to `True`, `past` key value states are returned and can be used to speed up decoding (see `past`). - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare CTRL Model transformer outputting raw hidden-states without any specific head on top.", - CTRL_START_DOCSTRING, -) -class TFCTRLModel(TFCTRLPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFCTRLMainLayer(config, name="transformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(CTRL_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPast, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutputWithPast: - outputs = self.transformer( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -class TFCTRLBiasLayer(keras.layers.Layer): - """ - Bias as a layer. It is used for serialization purposes: `keras.Model.save_weights` stores on a per-layer basis, - so all weights have to be registered in a layer. - """ - - def __init__(self, shape, initializer, trainable, name, **kwargs): - super().__init__(name=name, **kwargs) - self.shape = shape - self.initializer = initializer - self.trainable = trainable - - def build(self, input_shape): - self.bias = self.add_weight( - name="bias", shape=self.shape, initializer=self.initializer, trainable=self.trainable - ) - super().build(input_shape) - - def call(self, x): - return x + self.bias - - -@add_start_docstrings( - """ - The CTRL Model transformer with a language modeling head on top (linear layer with weights tied to the input - embeddings). - """, - CTRL_START_DOCSTRING, -) -class TFCTRLLMHeadModel(TFCTRLPreTrainedModel, TFCausalLanguageModelingLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFCTRLMainLayer(config, name="transformer") - self.bias_layer = TFCTRLBiasLayer( - name="lm_head", shape=[1, config.vocab_size], initializer="zeros", trainable=True - ) - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - def get_bias(self): - return {"lm_head.bias": self.bias_layer.bias} - - def set_bias(self, value): - # Replaces the existing layers containing bias for correct (de)serialization. - vocab_size = value["lm_head.bias"].shape[-1] - self.bias_layer = TFCTRLBiasLayer( - name="final_logits_bias", shape=[1, vocab_size], initializer="zeros", trainable=True - ) - self.bias_layer.build(None) - self.bias_layer.bias.assign(value["lm_head.bias"]) - - # Copied from transformers.models.gpt2.modeling_tf_gpt2.TFGPT2LMHeadModel.prepare_inputs_for_generation - def prepare_inputs_for_generation(self, inputs, past_key_values=None, use_cache=None, **kwargs): - token_type_ids = kwargs.get("token_type_ids") - # only last token for inputs_ids if past is defined in kwargs - if past_key_values: - inputs = tf.expand_dims(inputs[:, -1], -1) - if token_type_ids is not None: - token_type_ids = tf.expand_dims(token_type_ids[:, -1], -1) - - position_ids = kwargs.get("position_ids") - attention_mask = kwargs.get("attention_mask") - - if attention_mask is not None and position_ids is None: - position_ids = tf.math.cumsum(attention_mask, axis=-1, exclusive=True) - if past_key_values: - position_ids = tf.expand_dims(position_ids[:, -1], -1) - - return { - "input_ids": inputs, - "attention_mask": attention_mask, - "position_ids": position_ids, - "past_key_values": past_key_values, - "use_cache": use_cache, - "token_type_ids": token_type_ids, - } - - @unpack_inputs - @add_start_docstrings_to_model_forward(CTRL_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutputWithPast, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFCausalLMOutputWithPast: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = transformer_outputs[0] - logits = tf.matmul(hidden_states, self.transformer.w.weights, transpose_b=True) - logits = self.bias_layer(logits) - - loss = None - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels, shifted_logits) - - if not return_dict: - output = (logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithPast( - loss=loss, - logits=logits, - past_key_values=transformer_outputs.past_key_values, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "bias_layer", None) is not None: - with tf.name_scope(self.bias_layer.name): - self.bias_layer.build(None) - - -@add_start_docstrings( - """ - The CTRL Model transformer with a sequence classification head on top (linear layer). - - [`TFCTRLForSequenceClassification`] uses the last token in order to do the classification, as other causal models - (e.g. GPT-1, GPT-2) do. - - Since it does classification on the last token, it requires to know the position of the last token. If a - `pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If - no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the - padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in - each row of the batch). - """, - CTRL_START_DOCSTRING, -) -class TFCTRLForSequenceClassification(TFCTRLPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.classifier = keras.layers.Dense( - config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - use_bias=False, - ) - self.transformer = TFCTRLMainLayer(config, name="transformer") - self.config = config - - def get_output_embeddings(self): - # Remove after transformers v4.32. Fix this model's `test_model_common_attributes` test too. - logger.warning( - "Sequence classification models do not have output embeddings. `.get_output_embeddings` will be removed " - "in transformers v4.32." - ) - return self.transformer.w - - @unpack_inputs - @add_start_docstrings_to_model_forward(CTRL_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFSequenceClassifierOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - - transformer_outputs = self.transformer( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = transformer_outputs[0] - logits = self.classifier(hidden_states) - logits_shape = shape_list(logits) - batch_size = logits_shape[0] - - if self.config.pad_token_id is None: - last_non_pad_token = tf.fill((batch_size,), value=logits_shape[1] - 1) - else: - if input_ids is not None: - token_indices = tf.range(shape_list(input_ids)[-1]) - non_pad_mask = tf.cast(input_ids != self.config.pad_token_id, token_indices.dtype) - last_non_pad_token = tf.reduce_max(token_indices * non_pad_mask, axis=-1) - else: - last_non_pad_token = tf.fill((batch_size,), value=logits_shape[1] - 1) - logger.warning_once( - f"{self.__class__.__name__} will not detect padding tokens in `inputs_embeds`. Results may be " - "unexpected if using padding tokens in conjunction with `inputs_embeds.`" - ) - loss = None - - pooled_logits = tf.gather(logits, last_non_pad_token, batch_dims=1, axis=1) - - if labels is not None: - if self.config.pad_token_id is None and logits_shape[0] != 1: - raise ValueError("Cannot handle batch sizes > 1 if no padding token is defined.") - - loss = self.hf_compute_loss(tf.reshape(labels, [-1]), tf.reshape(pooled_logits, [-1, self.num_labels])) - - if not return_dict: - output = (pooled_logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=pooled_logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.n_embd]) - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -__all__ = ["TFCTRLForSequenceClassification", "TFCTRLLMHeadModel", "TFCTRLModel", "TFCTRLPreTrainedModel"] diff --git a/src/transformers/models/cvt/__init__.py b/src/transformers/models/cvt/__init__.py index 756aded9e6ad..08a67f82b411 100644 --- a/src/transformers/models/cvt/__init__.py +++ b/src/transformers/models/cvt/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_cvt import * from .modeling_cvt import * - from .modeling_tf_cvt import * else: import sys diff --git a/src/transformers/models/cvt/modeling_cvt.py b/src/transformers/models/cvt/modeling_cvt.py index 9d935ee84893..bd27b2db7f24 100644 --- a/src/transformers/models/cvt/modeling_cvt.py +++ b/src/transformers/models/cvt/modeling_cvt.py @@ -54,11 +54,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/cvt/modeling_tf_cvt.py b/src/transformers/models/cvt/modeling_tf_cvt.py deleted file mode 100644 index 9239e1918eec..000000000000 --- a/src/transformers/models/cvt/modeling_tf_cvt.py +++ /dev/null @@ -1,1095 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Microsoft Research and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 Cvt model.""" - -from __future__ import annotations - -import collections.abc -from dataclasses import dataclass - -import tensorflow as tf - -from ...modeling_tf_outputs import TFImageClassifierOutputWithNoAttention -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_cvt import CvtConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "CvtConfig" - - -@dataclass -class TFBaseModelOutputWithCLSToken(ModelOutput): - """ - Base class for model's outputs. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - cls_token_value (`tf.Tensor` of shape `(batch_size, 1, hidden_size)`): - Classification token at the output of the last layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus - the initial embedding outputs. - """ - - last_hidden_state: tf.Tensor | None = None - cls_token_value: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - - -class TFCvtDropPath(keras.layers.Layer): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - References: - (1) github.com:rwightman/pytorch-image-models - """ - - def __init__(self, drop_prob: float, **kwargs): - super().__init__(**kwargs) - self.drop_prob = drop_prob - - def call(self, x: tf.Tensor, training=None): - if self.drop_prob == 0.0 or not training: - return x - keep_prob = 1 - self.drop_prob - shape = (tf.shape(x)[0],) + (1,) * (len(tf.shape(x)) - 1) - random_tensor = keep_prob + tf.random.uniform(shape, 0, 1, dtype=self.compute_dtype) - random_tensor = tf.floor(random_tensor) - return (x / keep_prob) * random_tensor - - -class TFCvtEmbeddings(keras.layers.Layer): - """Construct the Convolutional Token Embeddings.""" - - def __init__( - self, - config: CvtConfig, - patch_size: int, - num_channels: int, - embed_dim: int, - stride: int, - padding: int, - dropout_rate: float, - **kwargs, - ): - super().__init__(**kwargs) - self.convolution_embeddings = TFCvtConvEmbeddings( - config, - patch_size=patch_size, - num_channels=num_channels, - embed_dim=embed_dim, - stride=stride, - padding=padding, - name="convolution_embeddings", - ) - self.dropout = keras.layers.Dropout(dropout_rate) - - def call(self, pixel_values: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_state = self.convolution_embeddings(pixel_values) - hidden_state = self.dropout(hidden_state, training=training) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convolution_embeddings", None) is not None: - with tf.name_scope(self.convolution_embeddings.name): - self.convolution_embeddings.build(None) - - -class TFCvtConvEmbeddings(keras.layers.Layer): - """Image to Convolution Embeddings. This convolutional operation aims to model local spatial contexts.""" - - def __init__( - self, - config: CvtConfig, - patch_size: int, - num_channels: int, - embed_dim: int, - stride: int, - padding: int, - **kwargs, - ): - super().__init__(**kwargs) - self.padding = keras.layers.ZeroPadding2D(padding=padding) - self.patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) - self.projection = keras.layers.Conv2D( - filters=embed_dim, - kernel_size=patch_size, - strides=stride, - padding="valid", - data_format="channels_last", - kernel_initializer=get_initializer(config.initializer_range), - name="projection", - ) - # Using the same default epsilon as PyTorch - self.normalization = keras.layers.LayerNormalization(epsilon=1e-5, name="normalization") - self.num_channels = num_channels - self.embed_dim = embed_dim - - def call(self, pixel_values: tf.Tensor) -> tf.Tensor: - if isinstance(pixel_values, dict): - pixel_values = pixel_values["pixel_values"] - - pixel_values = self.projection(self.padding(pixel_values)) - - # "batch_size, height, width, num_channels -> batch_size, (height*width), num_channels" - batch_size, height, width, num_channels = shape_list(pixel_values) - hidden_size = height * width - pixel_values = tf.reshape(pixel_values, shape=(batch_size, hidden_size, num_channels)) - pixel_values = self.normalization(pixel_values) - - # "batch_size, (height*width), num_channels -> batch_size, height, width, num_channels" - pixel_values = tf.reshape(pixel_values, shape=(batch_size, height, width, num_channels)) - return pixel_values - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, None, self.num_channels]) - if getattr(self, "normalization", None) is not None: - with tf.name_scope(self.normalization.name): - self.normalization.build([None, None, self.embed_dim]) - - -class TFCvtSelfAttentionConvProjection(keras.layers.Layer): - """Convolutional projection layer.""" - - def __init__(self, config: CvtConfig, embed_dim: int, kernel_size: int, stride: int, padding: int, **kwargs): - super().__init__(**kwargs) - self.padding = keras.layers.ZeroPadding2D(padding=padding) - self.convolution = keras.layers.Conv2D( - filters=embed_dim, - kernel_size=kernel_size, - kernel_initializer=get_initializer(config.initializer_range), - padding="valid", - strides=stride, - use_bias=False, - name="convolution", - groups=embed_dim, - ) - # Using the same default epsilon as PyTorch, TF uses (1 - pytorch momentum) - self.normalization = keras.layers.BatchNormalization(epsilon=1e-5, momentum=0.9, name="normalization") - self.embed_dim = embed_dim - - def call(self, hidden_state: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_state = self.convolution(self.padding(hidden_state)) - hidden_state = self.normalization(hidden_state, training=training) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convolution", None) is not None: - with tf.name_scope(self.convolution.name): - self.convolution.build([None, None, None, self.embed_dim]) - if getattr(self, "normalization", None) is not None: - with tf.name_scope(self.normalization.name): - self.normalization.build([None, None, None, self.embed_dim]) - - -class TFCvtSelfAttentionLinearProjection(keras.layers.Layer): - """Linear projection layer used to flatten tokens into 1D.""" - - def call(self, hidden_state: tf.Tensor) -> tf.Tensor: - # "batch_size, height, width, num_channels -> batch_size, (height*width), num_channels" - batch_size, height, width, num_channels = shape_list(hidden_state) - hidden_size = height * width - hidden_state = tf.reshape(hidden_state, shape=(batch_size, hidden_size, num_channels)) - return hidden_state - - -class TFCvtSelfAttentionProjection(keras.layers.Layer): - """Convolutional Projection for Attention.""" - - def __init__( - self, - config: CvtConfig, - embed_dim: int, - kernel_size: int, - stride: int, - padding: int, - projection_method: str = "dw_bn", - **kwargs, - ): - super().__init__(**kwargs) - if projection_method == "dw_bn": - self.convolution_projection = TFCvtSelfAttentionConvProjection( - config, embed_dim, kernel_size, stride, padding, name="convolution_projection" - ) - self.linear_projection = TFCvtSelfAttentionLinearProjection() - - def call(self, hidden_state: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_state = self.convolution_projection(hidden_state, training=training) - hidden_state = self.linear_projection(hidden_state) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convolution_projection", None) is not None: - with tf.name_scope(self.convolution_projection.name): - self.convolution_projection.build(None) - - -class TFCvtSelfAttention(keras.layers.Layer): - """ - Self-attention layer. A depth-wise separable convolution operation (Convolutional Projection), is applied for - query, key, and value embeddings. - """ - - def __init__( - self, - config: CvtConfig, - num_heads: int, - embed_dim: int, - kernel_size: int, - stride_q: int, - stride_kv: int, - padding_q: int, - padding_kv: int, - qkv_projection_method: str, - qkv_bias: bool, - attention_drop_rate: float, - with_cls_token: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.scale = embed_dim**-0.5 - self.with_cls_token = with_cls_token - self.embed_dim = embed_dim - self.num_heads = num_heads - - self.convolution_projection_query = TFCvtSelfAttentionProjection( - config, - embed_dim, - kernel_size, - stride_q, - padding_q, - projection_method="linear" if qkv_projection_method == "avg" else qkv_projection_method, - name="convolution_projection_query", - ) - self.convolution_projection_key = TFCvtSelfAttentionProjection( - config, - embed_dim, - kernel_size, - stride_kv, - padding_kv, - projection_method=qkv_projection_method, - name="convolution_projection_key", - ) - self.convolution_projection_value = TFCvtSelfAttentionProjection( - config, - embed_dim, - kernel_size, - stride_kv, - padding_kv, - projection_method=qkv_projection_method, - name="convolution_projection_value", - ) - - self.projection_query = keras.layers.Dense( - units=embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - use_bias=qkv_bias, - bias_initializer="zeros", - name="projection_query", - ) - self.projection_key = keras.layers.Dense( - units=embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - use_bias=qkv_bias, - bias_initializer="zeros", - name="projection_key", - ) - self.projection_value = keras.layers.Dense( - units=embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - use_bias=qkv_bias, - bias_initializer="zeros", - name="projection_value", - ) - self.dropout = keras.layers.Dropout(attention_drop_rate) - - def rearrange_for_multi_head_attention(self, hidden_state: tf.Tensor) -> tf.Tensor: - batch_size, hidden_size, _ = shape_list(hidden_state) - head_dim = self.embed_dim // self.num_heads - hidden_state = tf.reshape(hidden_state, shape=(batch_size, hidden_size, self.num_heads, head_dim)) - hidden_state = tf.transpose(hidden_state, perm=(0, 2, 1, 3)) - return hidden_state - - def call(self, hidden_state: tf.Tensor, height: int, width: int, training: bool = False) -> tf.Tensor: - if self.with_cls_token: - cls_token, hidden_state = tf.split(hidden_state, [1, height * width], 1) - - # "batch_size, (height*width), num_channels -> batch_size, height, width, num_channels" - batch_size, hidden_size, num_channels = shape_list(hidden_state) - hidden_state = tf.reshape(hidden_state, shape=(batch_size, height, width, num_channels)) - - key = self.convolution_projection_key(hidden_state, training=training) - query = self.convolution_projection_query(hidden_state, training=training) - value = self.convolution_projection_value(hidden_state, training=training) - - if self.with_cls_token: - query = tf.concat((cls_token, query), axis=1) - key = tf.concat((cls_token, key), axis=1) - value = tf.concat((cls_token, value), axis=1) - - head_dim = self.embed_dim // self.num_heads - - query = self.rearrange_for_multi_head_attention(self.projection_query(query)) - key = self.rearrange_for_multi_head_attention(self.projection_key(key)) - value = self.rearrange_for_multi_head_attention(self.projection_value(value)) - - attention_score = tf.matmul(query, key, transpose_b=True) * self.scale - attention_probs = stable_softmax(logits=attention_score, axis=-1) - attention_probs = self.dropout(attention_probs, training=training) - - context = tf.matmul(attention_probs, value) - # "batch_size, num_heads, hidden_size, head_dim -> batch_size, hidden_size, (num_heads*head_dim)" - _, _, hidden_size, _ = shape_list(context) - context = tf.transpose(context, perm=(0, 2, 1, 3)) - context = tf.reshape(context, (batch_size, hidden_size, self.num_heads * head_dim)) - return context - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convolution_projection_query", None) is not None: - with tf.name_scope(self.convolution_projection_query.name): - self.convolution_projection_query.build(None) - if getattr(self, "convolution_projection_key", None) is not None: - with tf.name_scope(self.convolution_projection_key.name): - self.convolution_projection_key.build(None) - if getattr(self, "convolution_projection_value", None) is not None: - with tf.name_scope(self.convolution_projection_value.name): - self.convolution_projection_value.build(None) - if getattr(self, "projection_query", None) is not None: - with tf.name_scope(self.projection_query.name): - self.projection_query.build([None, None, self.embed_dim]) - if getattr(self, "projection_key", None) is not None: - with tf.name_scope(self.projection_key.name): - self.projection_key.build([None, None, self.embed_dim]) - if getattr(self, "projection_value", None) is not None: - with tf.name_scope(self.projection_value.name): - self.projection_value.build([None, None, self.embed_dim]) - - -class TFCvtSelfOutput(keras.layers.Layer): - """Output of the Attention layer .""" - - def __init__(self, config: CvtConfig, embed_dim: int, drop_rate: float, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - units=embed_dim, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(drop_rate) - self.embed_dim = embed_dim - - def call(self, hidden_state: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_state = self.dense(inputs=hidden_state) - hidden_state = self.dropout(inputs=hidden_state, training=training) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.embed_dim]) - - -class TFCvtAttention(keras.layers.Layer): - """Attention layer. First chunk of the convolutional transformer block.""" - - def __init__( - self, - config: CvtConfig, - num_heads: int, - embed_dim: int, - kernel_size: int, - stride_q: int, - stride_kv: int, - padding_q: int, - padding_kv: int, - qkv_projection_method: str, - qkv_bias: bool, - attention_drop_rate: float, - drop_rate: float, - with_cls_token: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.attention = TFCvtSelfAttention( - config, - num_heads, - embed_dim, - kernel_size, - stride_q, - stride_kv, - padding_q, - padding_kv, - qkv_projection_method, - qkv_bias, - attention_drop_rate, - with_cls_token, - name="attention", - ) - self.dense_output = TFCvtSelfOutput(config, embed_dim, drop_rate, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call(self, hidden_state: tf.Tensor, height: int, width: int, training: bool = False): - self_output = self.attention(hidden_state, height, width, training=training) - attention_output = self.dense_output(self_output, training=training) - return attention_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -class TFCvtIntermediate(keras.layers.Layer): - """Intermediate dense layer. Second chunk of the convolutional transformer block.""" - - def __init__(self, config: CvtConfig, embed_dim: int, mlp_ratio: int, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - units=int(embed_dim * mlp_ratio), - kernel_initializer=get_initializer(config.initializer_range), - activation="gelu", - name="dense", - ) - self.embed_dim = embed_dim - - def call(self, hidden_state: tf.Tensor) -> tf.Tensor: - hidden_state = self.dense(hidden_state) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.embed_dim]) - - -class TFCvtOutput(keras.layers.Layer): - """ - Output of the Convolutional Transformer Block (last chunk). It consists of a MLP and a residual connection. - """ - - def __init__(self, config: CvtConfig, embed_dim: int, mlp_ratio: int, drop_rate: int, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - units=embed_dim, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(drop_rate) - self.embed_dim = embed_dim - self.mlp_ratio = mlp_ratio - - def call(self, hidden_state: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_state = self.dense(inputs=hidden_state) - hidden_state = self.dropout(inputs=hidden_state, training=training) - hidden_state = hidden_state + input_tensor - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, int(self.embed_dim * self.mlp_ratio)]) - - -class TFCvtLayer(keras.layers.Layer): - """ - Convolutional Transformer Block composed by attention layers, normalization and multi-layer perceptrons (mlps). It - consists of 3 chunks : an attention layer, an intermediate dense layer and an output layer. This corresponds to the - `Block` class in the original implementation. - """ - - def __init__( - self, - config: CvtConfig, - num_heads: int, - embed_dim: int, - kernel_size: int, - stride_q: int, - stride_kv: int, - padding_q: int, - padding_kv: int, - qkv_projection_method: str, - qkv_bias: bool, - attention_drop_rate: float, - drop_rate: float, - mlp_ratio: float, - drop_path_rate: float, - with_cls_token: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.attention = TFCvtAttention( - config, - num_heads, - embed_dim, - kernel_size, - stride_q, - stride_kv, - padding_q, - padding_kv, - qkv_projection_method, - qkv_bias, - attention_drop_rate, - drop_rate, - with_cls_token, - name="attention", - ) - self.intermediate = TFCvtIntermediate(config, embed_dim, mlp_ratio, name="intermediate") - self.dense_output = TFCvtOutput(config, embed_dim, mlp_ratio, drop_rate, name="output") - # Using `layers.Activation` instead of `tf.identity` to better control `training` behaviour. - self.drop_path = ( - TFCvtDropPath(drop_path_rate, name="drop_path") - if drop_path_rate > 0.0 - else keras.layers.Activation("linear", name="drop_path") - ) - # Using the same default epsilon as PyTorch - self.layernorm_before = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_before") - self.layernorm_after = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_after") - self.embed_dim = embed_dim - - def call(self, hidden_state: tf.Tensor, height: int, width: int, training: bool = False) -> tf.Tensor: - # in Cvt, layernorm is applied before self-attention - attention_output = self.attention(self.layernorm_before(hidden_state), height, width, training=training) - attention_output = self.drop_path(attention_output, training=training) - - # first residual connection - hidden_state = attention_output + hidden_state - - # in Cvt, layernorm is also applied after self-attention - layer_output = self.layernorm_after(hidden_state) - layer_output = self.intermediate(layer_output) - - # second residual connection is done here - layer_output = self.dense_output(layer_output, hidden_state) - layer_output = self.drop_path(layer_output, training=training) - return layer_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - if getattr(self, "drop_path", None) is not None: - with tf.name_scope(self.drop_path.name): - self.drop_path.build(None) - if getattr(self, "layernorm_before", None) is not None: - with tf.name_scope(self.layernorm_before.name): - self.layernorm_before.build([None, None, self.embed_dim]) - if getattr(self, "layernorm_after", None) is not None: - with tf.name_scope(self.layernorm_after.name): - self.layernorm_after.build([None, None, self.embed_dim]) - - -class TFCvtStage(keras.layers.Layer): - """ - Cvt stage (encoder block). Each stage has 2 parts : - - (1) A Convolutional Token Embedding layer - - (2) A Convolutional Transformer Block (layer). - The classification token is added only in the last stage. - - Args: - config ([`CvtConfig`]): Model configuration class. - stage (`int`): Stage number. - """ - - def __init__(self, config: CvtConfig, stage: int, **kwargs): - super().__init__(**kwargs) - self.config = config - self.stage = stage - if self.config.cls_token[self.stage]: - self.cls_token = self.add_weight( - shape=(1, 1, self.config.embed_dim[-1]), - initializer=get_initializer(self.config.initializer_range), - trainable=True, - name="cvt.encoder.stages.2.cls_token", - ) - - self.embedding = TFCvtEmbeddings( - self.config, - patch_size=config.patch_sizes[self.stage], - num_channels=config.num_channels if self.stage == 0 else config.embed_dim[self.stage - 1], - stride=config.patch_stride[self.stage], - embed_dim=config.embed_dim[self.stage], - padding=config.patch_padding[self.stage], - dropout_rate=config.drop_rate[self.stage], - name="embedding", - ) - - drop_path_rates = tf.linspace(0.0, config.drop_path_rate[self.stage], config.depth[stage]) - drop_path_rates = [x.numpy().item() for x in drop_path_rates] - self.layers = [ - TFCvtLayer( - config, - num_heads=config.num_heads[self.stage], - embed_dim=config.embed_dim[self.stage], - kernel_size=config.kernel_qkv[self.stage], - stride_q=config.stride_q[self.stage], - stride_kv=config.stride_kv[self.stage], - padding_q=config.padding_q[self.stage], - padding_kv=config.padding_kv[self.stage], - qkv_projection_method=config.qkv_projection_method[self.stage], - qkv_bias=config.qkv_bias[self.stage], - attention_drop_rate=config.attention_drop_rate[self.stage], - drop_rate=config.drop_rate[self.stage], - mlp_ratio=config.mlp_ratio[self.stage], - drop_path_rate=drop_path_rates[self.stage], - with_cls_token=config.cls_token[self.stage], - name=f"layers.{j}", - ) - for j in range(config.depth[self.stage]) - ] - - def call(self, hidden_state: tf.Tensor, training: bool = False): - cls_token = None - hidden_state = self.embedding(hidden_state, training) - - # "batch_size, height, width, num_channels -> batch_size, (height*width), num_channels" - batch_size, height, width, num_channels = shape_list(hidden_state) - hidden_size = height * width - hidden_state = tf.reshape(hidden_state, shape=(batch_size, hidden_size, num_channels)) - - if self.config.cls_token[self.stage]: - cls_token = tf.repeat(self.cls_token, repeats=batch_size, axis=0) - hidden_state = tf.concat((cls_token, hidden_state), axis=1) - - for layer in self.layers: - layer_outputs = layer(hidden_state, height, width, training=training) - hidden_state = layer_outputs - - if self.config.cls_token[self.stage]: - cls_token, hidden_state = tf.split(hidden_state, [1, height * width], 1) - - # "batch_size, (height*width), num_channels -> batch_size, height, width, num_channels" - hidden_state = tf.reshape(hidden_state, shape=(batch_size, height, width, num_channels)) - return hidden_state, cls_token - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embedding", None) is not None: - with tf.name_scope(self.embedding.name): - self.embedding.build(None) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFCvtEncoder(keras.layers.Layer): - """ - Convolutional Vision Transformer encoder. CVT has 3 stages of encoder blocks with their respective number of layers - (depth) being 1, 2 and 10. - - Args: - config ([`CvtConfig`]): Model configuration class. - """ - - config_class = CvtConfig - - def __init__(self, config: CvtConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.stages = [ - TFCvtStage(config, stage_idx, name=f"stages.{stage_idx}") for stage_idx in range(len(config.depth)) - ] - - def call( - self, - pixel_values: TFModelInputType, - output_hidden_states: bool | None = False, - return_dict: bool | None = True, - training: bool | None = False, - ) -> TFBaseModelOutputWithCLSToken | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - hidden_state = pixel_values - # When running on CPU, `keras.layers.Conv2D` doesn't support (batch_size, num_channels, height, width) - # as input format. So change the input format to (batch_size, height, width, num_channels). - hidden_state = tf.transpose(hidden_state, perm=(0, 2, 3, 1)) - - cls_token = None - for _, (stage_module) in enumerate(self.stages): - hidden_state, cls_token = stage_module(hidden_state, training=training) - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_state,) - - # Change back to (batch_size, num_channels, height, width) format to have uniformity in the modules - hidden_state = tf.transpose(hidden_state, perm=(0, 3, 1, 2)) - if output_hidden_states: - all_hidden_states = tuple(tf.transpose(hs, perm=(0, 3, 1, 2)) for hs in all_hidden_states) - - if not return_dict: - return tuple(v for v in [hidden_state, cls_token, all_hidden_states] if v is not None) - - return TFBaseModelOutputWithCLSToken( - last_hidden_state=hidden_state, - cls_token_value=cls_token, - hidden_states=all_hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "stages", None) is not None: - for layer in self.stages: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFCvtMainLayer(keras.layers.Layer): - """Construct the Cvt model.""" - - config_class = CvtConfig - - def __init__(self, config: CvtConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.encoder = TFCvtEncoder(config, name="encoder") - - @unpack_inputs - def call( - self, - pixel_values: TFModelInputType | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithCLSToken | tuple[tf.Tensor]: - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - encoder_outputs = self.encoder( - pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - - if not return_dict: - return (sequence_output,) + encoder_outputs[1:] - - return TFBaseModelOutputWithCLSToken( - last_hidden_state=sequence_output, - cls_token_value=encoder_outputs.cls_token_value, - hidden_states=encoder_outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - - -class TFCvtPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = CvtConfig - base_model_prefix = "cvt" - main_input_name = "pixel_values" - - -TFCVT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TF 2.0 models accepts two formats as inputs: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional arguments. - - This second option is useful when using [`keras.Model.fit`] method which currently requires having all the - tensors in the first argument of the model call function: `model(inputs)`. - - - - Args: - config ([`CvtConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -TFCVT_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`CvtImageProcessor.__call__`] - for details. - - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare Cvt Model transformer outputting raw hidden-states without any specific head on top.", - TFCVT_START_DOCSTRING, -) -class TFCvtModel(TFCvtPreTrainedModel): - def __init__(self, config: CvtConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.cvt = TFCvtMainLayer(config, name="cvt") - - @unpack_inputs - @add_start_docstrings_to_model_forward(TFCVT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBaseModelOutputWithCLSToken, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: tf.Tensor | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithCLSToken | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, TFCvtModel - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/cvt-13") - >>> model = TFCvtModel.from_pretrained("microsoft/cvt-13") - - >>> inputs = image_processor(images=image, return_tensors="tf") - >>> outputs = model(**inputs) - >>> last_hidden_states = outputs.last_hidden_state - ```""" - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - outputs = self.cvt( - pixel_values=pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return (outputs[0],) + outputs[1:] - - return TFBaseModelOutputWithCLSToken( - last_hidden_state=outputs.last_hidden_state, - cls_token_value=outputs.cls_token_value, - hidden_states=outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "cvt", None) is not None: - with tf.name_scope(self.cvt.name): - self.cvt.build(None) - - -@add_start_docstrings( - """ - Cvt Model transformer with an image classification head on top (a linear layer on top of the final hidden state of - the [CLS] token) e.g. for ImageNet. - """, - TFCVT_START_DOCSTRING, -) -class TFCvtForImageClassification(TFCvtPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: CvtConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.cvt = TFCvtMainLayer(config, name="cvt") - # Using same default epsilon as in the original implementation. - self.layernorm = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm") - - # Classifier head - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - use_bias=True, - bias_initializer="zeros", - name="classifier", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(TFCVT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFImageClassifierOutputWithNoAttention, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: tf.Tensor | None = None, - labels: tf.Tensor | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFImageClassifierOutputWithNoAttention | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, TFCvtForImageClassification - >>> import tensorflow as tf - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/cvt-13") - >>> model = TFCvtForImageClassification.from_pretrained("microsoft/cvt-13") - - >>> inputs = image_processor(images=image, return_tensors="tf") - >>> outputs = model(**inputs) - >>> logits = outputs.logits - >>> # model predicts one of the 1000 ImageNet classes - >>> predicted_class_idx = tf.math.argmax(logits, axis=-1)[0] - >>> print("Predicted class:", model.config.id2label[int(predicted_class_idx)]) - ```""" - - outputs = self.cvt( - pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - cls_token = outputs[1] - if self.config.cls_token[-1]: - sequence_output = self.layernorm(cls_token) - else: - # rearrange "batch_size, num_channels, height, width -> batch_size, (height*width), num_channels" - batch_size, num_channels, height, width = shape_list(sequence_output) - sequence_output = tf.reshape(sequence_output, shape=(batch_size, num_channels, height * width)) - sequence_output = tf.transpose(sequence_output, perm=(0, 2, 1)) - sequence_output = self.layernorm(sequence_output) - - sequence_output_mean = tf.reduce_mean(sequence_output, axis=1) - logits = self.classifier(sequence_output_mean) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFImageClassifierOutputWithNoAttention(loss=loss, logits=logits, hidden_states=outputs.hidden_states) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "cvt", None) is not None: - with tf.name_scope(self.cvt.name): - self.cvt.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, self.config.embed_dim[-1]]) - if getattr(self, "classifier", None) is not None: - if hasattr(self.classifier, "name"): - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.embed_dim[-1]]) - - -__all__ = ["TFCvtForImageClassification", "TFCvtModel", "TFCvtPreTrainedModel"] diff --git a/src/transformers/models/dab_detr/modeling_dab_detr.py b/src/transformers/models/dab_detr/modeling_dab_detr.py index 4b7a27e7663b..cbb7450c7f0b 100644 --- a/src/transformers/models/dab_detr/modeling_dab_detr.py +++ b/src/transformers/models/dab_detr/modeling_dab_detr.py @@ -824,8 +824,6 @@ def _init_weights(self, module): nn.init.xavier_uniform_(module.k_linear.weight, gain=xavier_std) nn.init.xavier_uniform_(module.q_linear.weight, gain=xavier_std) if isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/dac/feature_extraction_dac.py b/src/transformers/models/dac/feature_extraction_dac.py index e81a2466dd91..21af67e2233a 100644 --- a/src/transformers/models/dac/feature_extraction_dac.py +++ b/src/transformers/models/dac/feature_extraction_dac.py @@ -92,7 +92,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*, default to 'pt'): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/data2vec/__init__.py b/src/transformers/models/data2vec/__init__.py index 7000ac3d353b..4fcf78dd606f 100644 --- a/src/transformers/models/data2vec/__init__.py +++ b/src/transformers/models/data2vec/__init__.py @@ -24,7 +24,6 @@ from .modeling_data2vec_audio import * from .modeling_data2vec_text import * from .modeling_data2vec_vision import * - from .modeling_tf_data2vec_vision import * else: import sys diff --git a/src/transformers/models/data2vec/modeling_data2vec_text.py b/src/transformers/models/data2vec/modeling_data2vec_text.py index f866dd9144a6..1d901908f818 100644 --- a/src/transformers/models/data2vec/modeling_data2vec_text.py +++ b/src/transformers/models/data2vec/modeling_data2vec_text.py @@ -61,8 +61,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -568,8 +566,6 @@ class Data2VecTextPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/data2vec/modeling_data2vec_vision.py b/src/transformers/models/data2vec/modeling_data2vec_vision.py index f214f8eb6a0b..e59258625210 100644 --- a/src/transformers/models/data2vec/modeling_data2vec_vision.py +++ b/src/transformers/models/data2vec/modeling_data2vec_vision.py @@ -62,11 +62,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -746,8 +741,6 @@ class Data2VecVisionPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d, nn.ConvTranspose2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/data2vec/modeling_tf_data2vec_vision.py b/src/transformers/models/data2vec/modeling_tf_data2vec_vision.py deleted file mode 100644 index 0fa0fe1f811e..000000000000 --- a/src/transformers/models/data2vec/modeling_tf_data2vec_vision.py +++ /dev/null @@ -1,1723 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Meta Platforms and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 Data2Vec Vision model.""" - -from __future__ import annotations - -import collections.abc -import math -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPooling, - TFSemanticSegmenterOutput, - TFSequenceClassifierOutput, -) -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_data2vec_vision import Data2VecVisionConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "Data2VecVisionConfig" - -# Base docstring -_CHECKPOINT_FOR_DOC = "facebook/data2vec-vision-base" -_EXPECTED_OUTPUT_SHAPE = [1, 197, 768] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "facebook/data2vec-vision-base-ft1k" -_IMAGE_CLASS_EXPECTED_OUTPUT = "remote control, remote" - - -@dataclass -class TFData2VecVisionModelOutputWithPooling(TFBaseModelOutputWithPooling): - """ - Class for outputs of [`TFData2VecVisionModel`]. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - pooler_output (`tf.Tensor` of shape `(batch_size, hidden_size)`): - Average of the last layer hidden states of the patch tokens (excluding the *[CLS]* token) if - *config.use_mean_pooling* is set to True. If set to False, then the final hidden state of the *[CLS]* token - will be returned. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: tf.Tensor | None = None - pooler_output: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -class TFData2VecVisionDropPath(keras.layers.Layer): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - References: - (1) github.com:rwightman/pytorch-image-models - """ - - def __init__(self, drop_path, **kwargs): - super().__init__(**kwargs) - self.drop_path = drop_path - - def call(self, x, training=None): - if training: - keep_prob = 1 - self.drop_path - shape = (tf.shape(x)[0],) + (1,) * (len(tf.shape(x)) - 1) - random_tensor = keep_prob + tf.random.uniform(shape, 0, 1) - random_tensor = tf.floor(random_tensor) - return (x / keep_prob) * random_tensor - return x - - -class TFData2VecVisionEmbeddings(keras.layers.Layer): - """ - Construct the CLS token, position and patch embeddings. Optionally, also the mask token. - - """ - - def __init__(self, config: Data2VecVisionConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - - self.patch_embeddings = TFData2VecVisionPatchEmbeddings(config, name="patch_embeddings") - self.num_patches = self.patch_embeddings.num_patches - self.config = config - - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - - def build(self, input_shape=None): - self.cls_token = self.add_weight( - shape=(1, 1, self.config.hidden_size), - initializer=tf.random_normal_initializer(stddev=self.config.initializer_range), - trainable=True, - name="cls_token", - ) - if self.config.use_mask_token: - self.mask_token = self.add_weight( - shape=(1, 1, self.config.hidden_size), - initializer=tf.random_normal_initializer(stddev=self.config.initializer_range), - trainable=True, - name="mask_token", - ) - else: - self.mask_token = None - - if self.config.use_absolute_position_embeddings: - self.position_embeddings = self.add_weight( - shape=(1, self.num_patches + 1, self.config.hidden_size), - initializer=tf.random_normal_initializer(stddev=self.config.initializer_range), - trainable=True, - name="position_embeddings", - ) - else: - self.position_embeddings = None - - if self.built: - return - self.built = True - if getattr(self, "patch_embeddings", None) is not None: - with tf.name_scope(self.patch_embeddings.name): - self.patch_embeddings.build(None) - - def call(self, pixel_values: tf.Tensor, bool_masked_pos: tf.Tensor | None = None) -> tf.Tensor: - embeddings = self.patch_embeddings(pixel_values) - batch_size, seq_len, projection_dim = shape_list(embeddings) - - cls_tokens = tf.tile(self.cls_token, (batch_size, 1, 1)) - - if bool_masked_pos is not None: - mask_tokens = tf.broadcast_to(self.mask_token, (batch_size, seq_len, projection_dim)) - # replace the masked visual tokens by mask_tokens - w = bool_masked_pos[..., None] - w = tf.cast(w, mask_tokens.dtype) - # since TF doesn't support eager tensor assignment - embeddings = embeddings * (1 - w) + mask_tokens * w - - embeddings = tf.concat([cls_tokens, embeddings], axis=1) - if self.position_embeddings is not None: - embeddings = embeddings + self.position_embeddings - embeddings = self.dropout(embeddings) - - return embeddings - - -class TFData2VecVisionPatchEmbeddings(keras.layers.Layer): - """ - Image to Patch Embedding. - """ - - def __init__(self, config: Data2VecVisionConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - - image_size, patch_size = config.image_size, config.patch_size - num_channels, hidden_size = config.num_channels, config.hidden_size - - image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) - patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) - num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) - patch_shape = (image_size[0] // patch_size[0], image_size[1] // patch_size[1]) - self.image_size = image_size - self.patch_size = patch_size - self.num_patches = num_patches - self.patch_shape = patch_shape - self.num_channels = num_channels - - self.projection = keras.layers.Conv2D( - filters=hidden_size, - kernel_size=patch_size, - strides=patch_size, - padding="valid", - data_format="channels_last", - kernel_initializer="glorot_uniform", # following torch.nn.Linear - bias_initializer="zeros", - name="projection", - ) - - def call(self, pixel_values: tf.Tensor, training: bool = False) -> tf.Tensor: - batch_size, num_channels, height, width = shape_list(pixel_values) - if tf.executing_eagerly(): - if num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the" - " configuration." - ) - if height != self.image_size[0] or width != self.image_size[1]: - raise ValueError( - f"Input image size ({height}*{width}) doesn't match model" - f" ({self.image_size[0]}*{self.image_size[1]})." - ) - - # When running on CPU, `keras.layers.Conv2D` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - # shape = (batch_size, in_height, in_width, in_channels=num_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - - projection = self.projection(pixel_values) - - # Change the 2D spatial dimensions to a single temporal dimension. - # shape = (batch_size, num_patches, out_channels=embed_dim) - num_patches = (width // self.patch_size[1]) * (height // self.patch_size[0]) - - return tf.reshape(tensor=projection, shape=(batch_size, num_patches, -1)) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, None, self.num_channels]) - - -class TFData2VecVisionSelfAttention(keras.layers.Layer): - def __init__(self, config: Data2VecVisionConfig, window_size: tuple | None = None, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="key", - use_bias=False, - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - - if window_size: - self.relative_position_bias = TFData2VecVisionRelativePositionBias( - config, window_size=window_size, name="relative_position_bias" - ) - else: - self.relative_position_bias = None - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - relative_position_bias: TFData2VecVisionRelativePositionBias | None = None, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - mixed_key_layer = self.key(inputs=hidden_states) - mixed_value_layer = self.value(inputs=hidden_states) - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - attention_scores = attention_scores / self.sqrt_att_head_size - - # Add relative position bias if present. - if self.relative_position_bias is not None: - # Passing `0.0` to the `relative_position_bias()` layer because otherwise Keras - # might complain about `Layer.call()` not being invoked properly. In this case this input - # i.e., 0.0 is not going to be used in any calculations so we're safe. - attention_scores = attention_scores + self.relative_position_bias(0.0)[None, ...] - - # Add shared relative position bias if provided. - if relative_position_bias is not None: - attention_scores = attention_scores + relative_position_bias - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - if getattr(self, "relative_position_bias", None) is not None: - with tf.name_scope(self.relative_position_bias.name): - self.relative_position_bias.build(None) - - -class TFData2VecVisionSelfOutput(keras.layers.Layer): - """ - The residual connection is defined in TFData2VecVisionLayer instead of here (as is the case with other models), due - to the layernorm applied before each block. - """ - - def __init__(self, config: Data2VecVisionConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, gamma=None, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFData2VecVisionAttention(keras.layers.Layer): - def __init__(self, config: Data2VecVisionConfig, window_size: tuple | None = None, **kwargs): - super().__init__(**kwargs) - - self.attention = TFData2VecVisionSelfAttention(config, window_size=window_size, name="attention") - self.dense_output = TFData2VecVisionSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - relative_position_bias: TFData2VecVisionRelativePositionBias | None = None, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.attention( - hidden_states=input_tensor, - head_mask=head_mask, - output_attentions=output_attentions, - relative_position_bias=relative_position_bias, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTIntermediate with ViT->Data2VecVision -class TFData2VecVisionIntermediate(keras.layers.Layer): - def __init__(self, config: Data2VecVisionConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFData2VecVisionOutput(keras.layers.Layer): - def __init__(self, config: Data2VecVisionConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - - -class TFData2VecVisionLayer(keras.layers.Layer): - """This corresponds to the Block class in the timm implementation.""" - - def __init__( - self, config: Data2VecVisionConfig, window_size: tuple | None = None, drop_path_rate: float = 0.0, **kwargs - ): - super().__init__(**kwargs) - self.config = config - - self.attention = TFData2VecVisionAttention(config, window_size=window_size, name="attention") - self.intermediate = TFData2VecVisionIntermediate(config, name="intermediate") - self.data2vec_output = TFData2VecVisionOutput(config, name="output") - - self.layernorm_before = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_before") - self.layernorm_after = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_after") - # Using `layers.Activation` instead of `tf.identity` to better control `training` - # behaviour. - self.drop_path = ( - TFData2VecVisionDropPath(drop_path_rate, name="drop_path") - if drop_path_rate > 0.0 - else keras.layers.Activation("linear", name="drop_path") - ) - self.init_values = config.layer_scale_init_value - - def build(self, input_shape: tf.TensorShape = None): - if self.init_values > 0: - self.lambda_1 = self.add_weight( - shape=(self.config.hidden_size), - initializer="ones", - trainable=True, - name="lambda_1", - ) - self.lambda_2 = self.add_weight( - shape=(self.config.hidden_size), - initializer="ones", - trainable=True, - name="lambda_2", - ) - self.lambda_1.assign(self.init_values * tf.ones(self.config.hidden_size)) - self.lambda_2.assign(self.init_values * tf.ones(self.config.hidden_size)) - else: - self.lambda_1, self.lambda_2 = None, None - - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "data2vec_output", None) is not None: - with tf.name_scope(self.data2vec_output.name): - self.data2vec_output.build(None) - if getattr(self, "layernorm_before", None) is not None: - with tf.name_scope(self.layernorm_before.name): - self.layernorm_before.build([None, None, self.config.hidden_size]) - if getattr(self, "layernorm_after", None) is not None: - with tf.name_scope(self.layernorm_after.name): - self.layernorm_after.build([None, None, self.config.hidden_size]) - if getattr(self, "drop_path", None) is not None: - with tf.name_scope(self.drop_path.name): - self.drop_path.build(None) - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - relative_position_bias: TFData2VecVisionRelativePositionBias | None = None, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_attention_outputs = self.attention( - # in Data2VecVision, layernorm is applied before self-attention - input_tensor=self.layernorm_before(inputs=hidden_states), - head_mask=head_mask, - output_attentions=output_attentions, - relative_position_bias=relative_position_bias, - training=training, - ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - # apply lambda_1 if present - if self.lambda_1 is not None: - attention_output = self.lambda_1 * attention_output - - # first residual connection - hidden_states = self.drop_path(attention_output) + hidden_states - - # in Data2VecVision, layernorm is also applied after self-attention - layer_output = self.layernorm_after(hidden_states) - - layer_output = self.intermediate(layer_output) - layer_output = self.data2vec_output(layer_output) - - if self.lambda_2 is not None: - layer_output = self.lambda_2 * layer_output - - # second residual connection - layer_output = self.drop_path(layer_output) + hidden_states - - outputs = (layer_output,) + outputs - - return outputs - - -# Taken and modified from here: -# https://github.com/leondgarse/keras_cv_attention_models/blob/main/keras_cv_attention_models/beit/beit.py#L28 -class TFData2VecVisionRelativePositionBias(keras.layers.Layer): - def __init__(self, config: Data2VecVisionConfig, window_size: tuple, **kwargs) -> None: - super().__init__(**kwargs) - self.config = config - - self.window_size = window_size - # +3 for cls_token_pos_len - # window_size can be something like (14, 14) - self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3 - - self.relative_position_index = self.get_position_index() - - def build(self, input_shape): - self.relative_position_bias_table = self.add_weight( - shape=(self.num_relative_distance, self.config.num_attention_heads), - initializer="zeros", - trainable=True, - name="relative_position_bias_table", - ) # [2*Wh-1 * 2*Ww-1, nH] - # cls to token & token 2 cls & cls to cls - - super().build(input_shape) - - def get_position_index(self): - # get pair-wise relative position index for each token inside the window - xx, yy = tf.meshgrid(range(self.window_size[0]), range(self.window_size[1])) - coords = tf.stack([yy, xx], axis=0) # [2, Wh, Ww] - coords_flatten = tf.reshape(coords, [2, -1]) # [2, Wh*Ww] - - relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # [2, Wh*Ww, Wh*Ww] - relative_coords = tf.transpose(relative_coords, perm=[1, 2, 0]) # [Wh*Ww, Wh*Ww, 2] - - xx = (relative_coords[:, :, 0] + self.window_size[0] - 1) * (2 * self.window_size[1] - 1) - yy = relative_coords[:, :, 1] + self.window_size[1] - 1 - relative_coords = tf.stack([xx, yy], axis=-1) - - relative_position_index = tf.reduce_sum(relative_coords, axis=-1) # [Wh*Ww, Wh*Ww] - - top = tf.ones((1, relative_position_index.shape[1]), dtype=relative_position_index.dtype) * ( - self.num_relative_distance - 3 - ) - left = tf.ones((relative_position_index.shape[0], 1), dtype=relative_position_index.dtype) * ( - self.num_relative_distance - 2 - ) - corner = tf.ones((1, 1), dtype=relative_position_index.dtype) * (self.num_relative_distance - 1) - - left_corner = tf.concat([corner, left], axis=0) - relative_position_index = tf.concat([top, relative_position_index], axis=0) - relative_position_index = tf.concat([left_corner, relative_position_index], axis=1) # [Wh*Ww + 1, Wh*Ww + 1] - return relative_position_index - - def call(self, inputs=None) -> tf.Tensor: - relative_position_bias = tf.gather(self.relative_position_bias_table, self.relative_position_index, axis=0) - return tf.transpose(relative_position_bias, [2, 0, 1]) - - -class TFData2VecVisionEncoder(keras.layers.Layer): - def __init__(self, config: Data2VecVisionConfig, window_size: tuple | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - if config.use_shared_relative_position_bias: - self.relative_position_bias = TFData2VecVisionRelativePositionBias( - config, window_size=window_size, name="relative_position_bias" - ) - else: - self.relative_position_bias = None - - # stochastic depth decay rule - dpr = list(tf.linspace(0.0, config.drop_path_rate, config.num_hidden_layers)) - self.layer = [ - TFData2VecVisionLayer( - config, - window_size=window_size if config.use_relative_position_bias else None, - drop_path_rate=dpr[i], - name=f"layer_._{i}", - ) - for i in range(config.num_hidden_layers) - ] - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor | None = None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ) -> tuple | TFBaseModelOutput: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_head_mask = head_mask[i] if head_mask is not None else None - # Passing `0.0` to the `relative_position_bias()` layer because otherwise Keras - # might complain about `Layer.call()` not being invoked properly. In this case this input - # i.e., 0.0 is not going to be used in any calculations so we're safe. - relative_position_bias = ( - self.relative_position_bias(0.0) if self.relative_position_bias is not None else None - ) - layer_outputs = layer_module(hidden_states, layer_head_mask, output_attentions, relative_position_bias) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "relative_position_bias", None) is not None: - with tf.name_scope(self.relative_position_bias.name): - self.relative_position_bias.build(None) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFData2VecVisionMainLayer(keras.layers.Layer): - config_class = Data2VecVisionConfig - - def __init__(self, config: Data2VecVisionConfig, add_pooling_layer: bool = True, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.add_pooling_layer = add_pooling_layer - - self.embeddings = TFData2VecVisionEmbeddings(config, name="embeddings") - self.encoder = TFData2VecVisionEncoder( - config, window_size=self.embeddings.patch_embeddings.patch_shape, name="encoder" - ) - self.layernorm = ( - tf.identity - if config.use_mean_pooling - else keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - ) - - # We are setting the `data_format` like so because from here on we will revert to the - # NCHW output format - self.pooler = TFData2VecVisionPooler(config, name="pooler") if add_pooling_layer else None - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings.patch_embeddings - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor | None = None, - bool_masked_pos: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple | TFData2VecVisionModelOutputWithPooling: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - embedding_output = self.embeddings(pixel_values, bool_masked_pos, training=training) - - encoder_outputs = self.encoder( - embedding_output, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - sequence_output = self.layernorm(sequence_output) - pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - - if not return_dict: - head_outputs = (sequence_output, pooled_output) if pooled_output is not None else (sequence_output,) - return head_outputs + encoder_outputs[1:] - - return TFData2VecVisionModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "layernorm", None) is not None: - if hasattr(self.layernorm, "name"): - with tf.name_scope(self.layernorm.name): - self.layernorm.build((None, self.config.hidden_size)) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -class TFData2VecVisionPooler(keras.layers.Layer): - def __init__(self, config: Data2VecVisionConfig, **kwargs): - super().__init__(**kwargs) - self.layernorm = ( - keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - if config.use_mean_pooling - else None - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - if self.layernorm is not None: - # Mean pool the final hidden states of the patch tokens - patch_tokens = hidden_states[:, 1:, :] - pooled_output = self.layernorm(tf.reduce_mean(patch_tokens, axis=1)) - else: - # Pool by simply taking the final hidden state of the [CLS] token - pooled_output = hidden_states[:, 0] - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layernorm", None) is not None: - if hasattr(self.layernorm, "name"): - with tf.name_scope(self.layernorm.name): - self.layernorm.build((None, self.config.hidden_size)) - - -class TFData2VecVisionPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = Data2VecVisionConfig - base_model_prefix = "data2vec_vision" - main_input_name = "pixel_values" - _keys_to_ignore_on_load_unexpected = [r"relative_position_index"] - - -DATA2VEC_VISION_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.). - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `pixel_values` only and nothing else: `model(pixel_values)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([pixel_values, attention_mask])` or `model([pixel_values, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"pixel_values": pixel_values, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`Data2VecVisionConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -DATA2VEC_VISION_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` `dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`BeitImageProcessor.__call__`] for details. - - head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - - return_dict (`bool`, *optional*): - Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare Data2VecVision Model transformer outputting raw hidden-states without any specific head on top.", - DATA2VEC_VISION_START_DOCSTRING, -) -class TFData2VecVisionModel(TFData2VecVisionPreTrainedModel): - def __init__(self, config: Data2VecVisionConfig, add_pooling_layer: bool = False, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.config = config - - self.data2vec_vision = TFData2VecVisionMainLayer( - config, add_pooling_layer=add_pooling_layer, name="data2vec_vision" - ) - - def get_input_embeddings(self): - return self.data2vec_vision.get_input_embeddings() - - @unpack_inputs - @add_start_docstrings_to_model_forward(DATA2VEC_VISION_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFData2VecVisionModelOutputWithPooling, - config_class=_CONFIG_FOR_DOC, - modality="vision", - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - def call( - self, - pixel_values: TFModelInputType | None = None, - bool_masked_pos: tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple | TFData2VecVisionModelOutputWithPooling: - r""" - bool_masked_pos (`tf.Tensor` of shape `(batch_size, num_patches)`, *optional*): - Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). - """ - outputs = self.data2vec_vision( - pixel_values=pixel_values, - bool_masked_pos=bool_masked_pos, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "data2vec_vision", None) is not None: - with tf.name_scope(self.data2vec_vision.name): - self.data2vec_vision.build(None) - - -@add_start_docstrings( - """ - Data2VecVision Model transformer with an image classification head on top (a linear layer on top of the average of - the final hidden states of the patch tokens) e.g. for ImageNet. - """, - DATA2VEC_VISION_START_DOCSTRING, -) -class TFData2VecVisionForImageClassification(TFData2VecVisionPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: Data2VecVisionConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.data2vec_vision = TFData2VecVisionMainLayer(config, add_pooling_layer=True, name="data2vec_vision") - - # Classifier head - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(DATA2VEC_VISION_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - def call( - self, - pixel_values: TFModelInputType | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.data2vec_vision( - pixel_values=pixel_values, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - pooled_output = outputs.pooler_output if return_dict else outputs[1] - logits = self.classifier(pooled_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "data2vec_vision", None) is not None: - with tf.name_scope(self.data2vec_vision.name): - self.data2vec_vision.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -class TFData2VecVisionConvModule(keras.layers.Layer): - """ - A convolutional block that bundles conv/norm/activation layers. This block simplifies the usage of convolution - layers, which are commonly used with a norm layer (e.g., BatchNorm) and activation layer (e.g., ReLU). - - Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. - """ - - def __init__( - self, - in_channels: int, - out_channels: int, - kernel_size: int | tuple[int, int], - padding: str = "valid", - bias: bool = False, - dilation: int | tuple[int, int] = 1, - **kwargs, - ) -> None: - super().__init__(**kwargs) - self.conv = keras.layers.Conv2D( - filters=out_channels, - kernel_size=kernel_size, - padding=padding, - use_bias=bias, - dilation_rate=dilation, - name="conv", - ) - self.bn = keras.layers.BatchNormalization(name="bn", momentum=0.9, epsilon=1e-5) - self.activation = tf.nn.relu - self.in_channels = in_channels - self.out_channels = out_channels - - def call(self, input: tf.Tensor) -> tf.Tensor: - output = self.conv(input) - output = self.bn(output) - output = self.activation(output) - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build([None, None, None, self.in_channels]) - if getattr(self, "bn", None) is not None: - with tf.name_scope(self.bn.name): - self.bn.build((None, None, None, self.out_channels)) - - -class TFAdaptiveAvgPool2D(keras.layers.Layer): - def __init__(self, output_dims: tuple[int, int], input_ordering: str = "NHWC", **kwargs): - super().__init__(**kwargs) - self.output_dims = output_dims - self.input_ordering = input_ordering - if input_ordering not in ("NCHW", "NHWC"): - raise ValueError("Unrecognized input_ordering, should be 'NCHW' or 'NHWC'!") - self.h_axis = input_ordering.index("H") - self.w_axis = input_ordering.index("W") - - def pseudo_1d_pool(self, inputs: tf.Tensor, h_pooling: bool): - # Figure out which axis we're pooling on - if h_pooling: - axis = self.h_axis - output_dim = self.output_dims[0] - else: - axis = self.w_axis - output_dim = self.output_dims[1] - input_dim = inputs.shape[axis] - - # Figure out the potential pooling windows - # This is the key idea - the torch op always uses only two - # consecutive pooling window sizes, like 3 and 4. Therefore, - # if we pool with both possible sizes, we simply need to gather - # the 'correct' pool at each position to reimplement the torch op. - small_window = math.ceil(input_dim / output_dim) - big_window = small_window + 1 - if h_pooling: - output_dim = self.output_dims[0] - small_window_shape = (small_window, 1) - big_window_shape = (big_window, 1) - else: - output_dim = self.output_dims[1] - small_window_shape = (1, small_window) - big_window_shape = (1, big_window) - - # For resizes to 1, or integer resizes, we can take quick shortcuts - if output_dim == input_dim: - return inputs - elif output_dim == 1: - return tf.reduce_mean(inputs, axis=axis, keepdims=True) - elif input_dim % output_dim == 0: - return tf.nn.avg_pool2d( - inputs, - ksize=small_window_shape, - strides=small_window_shape, - padding="VALID", - data_format=self.input_ordering, - ) - # When upscaling by an integer factor we can also take a quick shortcut - elif output_dim > input_dim and output_dim % input_dim == 0: - return tf.repeat(inputs, repeats=output_dim // input_dim, axis=axis) - - # For non-integer resizes, we pool with both possible window sizes and concatenate them - if output_dim < input_dim: - small_pool = tf.nn.avg_pool2d( - inputs, ksize=small_window_shape, strides=1, padding="VALID", data_format=self.input_ordering - ) - big_pool = tf.nn.avg_pool2d( - inputs, ksize=big_window_shape, strides=1, padding="VALID", data_format=self.input_ordering - ) - both_pool = tf.concat([small_pool, big_pool], axis=axis) - else: - # When we're actually upscaling instead, then we build the pools a bit differently - small_pool = inputs - big_pool = tf.nn.avg_pool2d( - inputs, ksize=big_window_shape, strides=1, padding="VALID", data_format=self.input_ordering - ) - both_pool = tf.concat([small_pool, big_pool], axis=axis) - - # We compute vectors of the start and end positions for each pooling window - # Each (start, end) pair here corresponds to a single output position - window_starts = tf.math.floor((tf.range(output_dim, dtype=tf.float32) * input_dim) / output_dim) - window_starts = tf.cast(window_starts, tf.int64) - window_ends = tf.math.ceil((tf.range(1, output_dim + 1, dtype=tf.float32) * input_dim) / output_dim) - window_ends = tf.cast(window_ends, tf.int64) - - # pool_selector is a boolean array of shape (output_dim,) where 1 indicates that output position - # has a big receptive field and 0 indicates that that output position has a small receptive field - pool_selector = tf.cast(window_ends - window_starts - small_window, tf.bool) - - # Since we concatenated the small and big pools, we need to do a bit of - # pointer arithmetic to get the indices of the big pools - small_indices = window_starts - big_indices = window_starts + small_pool.shape[axis] - - # Finally, we use the pool_selector to generate a list of indices, one per output position - gather_indices = tf.where(pool_selector, big_indices, small_indices) - - # Gathering from those indices yields the final, correct pooling - return tf.gather(both_pool, gather_indices, axis=axis) - - def call(self, inputs: tf.Tensor): - if self.input_ordering == "NHWC": - input_shape = inputs.shape[1:3] - else: - input_shape = inputs.shape[2:] - - # We break the task down into each possible case - # Firstly, if we're resizing down to 1, it's just tf.reduce_mean - if self.output_dims[0] == self.output_dims[1] == 1: - if self.input_ordering == "NHWC": - reduce_dims = [1, 2] - else: - reduce_dims = [2, 3] - return tf.reduce_mean(inputs, axis=reduce_dims, keepdims=True) - # Secondly, if we're resizing by an integer factor on both dimensions, we can take a quick shortcut - elif input_shape[0] % self.output_dims[0] == 0 and input_shape[1] % self.output_dims[1] == 0: - h_resize = int(input_shape[0] // self.output_dims[0]) - w_resize = int(input_shape[1] // self.output_dims[1]) - return tf.nn.avg_pool2d( - inputs, - ksize=(h_resize, w_resize), - strides=(h_resize, w_resize), - padding="VALID", - data_format=self.input_ordering, - ) - else: - # Finally, if we can't take the shortcut, we do a 1D pool on each axis. pseudo_1d_pool will take a shortcut - # for dimensions where an integer resize is possible. It can also handle upscaling. - h_pooled = self.pseudo_1d_pool(inputs, h_pooling=True) - return self.pseudo_1d_pool(h_pooled, h_pooling=False) - - -class TFData2VecVisionPyramidPoolingModule(keras.layers.Layer): - """ - Pyramid Pooling Module (PPM) used in PSPNet. - - Args: - pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid - Module. - channels (int): Channels after modules, before conv_seg. - - Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. - """ - - def __init__(self, pool_scales: tuple[int, ...], in_channels: int, out_channels: int, **kwargs) -> None: - super().__init__(**kwargs) - self.pool_scales = pool_scales - self.in_channels = in_channels - self.out_channels = out_channels - - self.layer_list = [] - for idx, pool_scale in enumerate(pool_scales): - pool_scale = pool_scale if isinstance(pool_scale, collections.abc.Iterable) else (pool_scale, pool_scale) - self.layer_list.append( - [ - TFAdaptiveAvgPool2D(output_dims=pool_scale), - TFData2VecVisionConvModule( - in_channels=in_channels, out_channels=self.out_channels, kernel_size=1, name=f"{idx}.1" - ), - ] - ) - - def call(self, x: tf.Tensor) -> list[tf.Tensor]: - ppm_outs = [] - inputs = x - - for ppm in self.layer_list: - for layer_module in ppm: - ppm_out = layer_module(x) - x = ppm_out - - upsampled_ppm_out = tf.image.resize(ppm_out, size=shape_list(inputs)[1:-1], method="bilinear") - ppm_outs.append(upsampled_ppm_out) - return ppm_outs - - def build(self, input_shape=None): - for layer in self.layer_list: - for layer_module in layer: - with tf.name_scope(layer_module.name): - layer_module.build(None) - - -class TFData2VecVisionUperHead(keras.layers.Layer): - """ - Unified Perceptual Parsing for Scene Understanding. This head is the implementation of - [UPerNet](https://huggingface.co/papers/1807.10221). - - Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. - """ - - def __init__(self, config: Data2VecVisionConfig, **kwargs) -> None: - super().__init__(**kwargs) - - self.pool_scales = config.pool_scales # e.g. (1, 2, 3, 6) - self.in_channels = [config.hidden_size] * 4 # e.g. [768, 768, 768, 768] - self.channels = config.hidden_size - self.classifier = keras.layers.Conv2D(config.num_labels, kernel_size=1, name="classifier") - - # PSP Module - self.psp_modules = TFData2VecVisionPyramidPoolingModule( - self.pool_scales, self.in_channels[-1], self.channels, name="psp_modules" - ) - self.bottleneck = TFData2VecVisionConvModule( - self.in_channels[-1] + len(self.pool_scales) * self.channels, - self.channels, - kernel_size=3, - padding="same", - name="bottleneck", - ) - # FPN Module - self.lateral_convs = [] - self.fpn_convs = [] - for idx, in_channels in enumerate(self.in_channels[:-1]): # skip the top layer - l_conv = TFData2VecVisionConvModule( - in_channels, out_channels=self.channels, kernel_size=1, name=f"lateral_convs.{idx}" - ) - fpn_conv = TFData2VecVisionConvModule( - in_channels=self.channels, - out_channels=self.channels, - kernel_size=3, - padding="same", - name=f"fpn_convs.{idx}", - ) - self.lateral_convs.append(l_conv) - self.fpn_convs.append(fpn_conv) - - self.fpn_bottleneck = TFData2VecVisionConvModule( - in_channels=len(self.in_channels) * self.channels, - out_channels=self.channels, - kernel_size=3, - padding="same", - name="fpn_bottleneck", - ) - - def psp_forward(self, inputs): - x = inputs[-1] - psp_outs = [x] - psp_outs.extend(self.psp_modules(x)) - psp_outs = tf.concat(psp_outs, axis=-1) - output = self.bottleneck(psp_outs) - - return output - - def call(self, encoder_hidden_states: tf.Tensor) -> tf.Tensor: - # build laterals - laterals = [lateral_conv(encoder_hidden_states[i]) for i, lateral_conv in enumerate(self.lateral_convs)] - - laterals.append(self.psp_forward(encoder_hidden_states)) - - # build top-down path - used_backbone_levels = len(laterals) - for i in range(used_backbone_levels - 1, 0, -1): - prev_shape = shape_list(laterals[i - 1])[1:-1] - laterals[i - 1] = laterals[i - 1] + tf.image.resize(laterals[i], size=prev_shape, method="bilinear") - - # build outputs - fpn_outs = [self.fpn_convs[i](laterals[i]) for i in range(used_backbone_levels - 1)] - # append psp feature - fpn_outs.append(laterals[-1]) - - for i in range(used_backbone_levels - 1, 0, -1): - fpn_outs[i] = tf.image.resize(fpn_outs[i], size=shape_list(fpn_outs[0])[1:-1], method="bilinear") - fpn_outs = tf.concat(fpn_outs, axis=-1) - output = self.fpn_bottleneck(fpn_outs) - output = self.classifier(output) - - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, None, self.channels]) - if getattr(self, "psp_modules", None) is not None: - with tf.name_scope(self.psp_modules.name): - self.psp_modules.build(None) - if getattr(self, "bottleneck", None) is not None: - with tf.name_scope(self.bottleneck.name): - self.bottleneck.build(None) - if getattr(self, "fpn_bottleneck", None) is not None: - with tf.name_scope(self.fpn_bottleneck.name): - self.fpn_bottleneck.build(None) - for layer in self.lateral_convs: - with tf.name_scope(layer.name): - layer.build(None) - for layer in self.fpn_convs: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFData2VecVisionFCNHead(keras.layers.Layer): - """ - Fully Convolution Networks for Semantic Segmentation. This head is implemented from - [FCNNet](https://huggingface.co/papers/1411.4038). - - Args: - config (Data2VecVisionConfig): Configuration. - kernel_size (int): The kernel size for convs in the head. Default: 3. - dilation (int): The dilation rate for convs in the head. Default: 1. - - - Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. - """ - - def __init__( - self, - config: Data2VecVisionConfig, - in_index: int = 2, - kernel_size: int = 3, - dilation: int | tuple[int, int] = 1, - **kwargs, - ) -> None: - super().__init__(**kwargs) - self.in_channels = config.hidden_size - self.channels = config.auxiliary_channels - self.num_convs = config.auxiliary_num_convs - self.concat_input = config.auxiliary_concat_input - self.in_index = in_index - - convs = [] - convs.append( - TFData2VecVisionConvModule( - in_channels=self.in_channels, - out_channels=self.channels, - kernel_size=kernel_size, - padding="same", - dilation=dilation, - name="convs.0", - ) - ) - for i in range(self.num_convs - 1): - convs.append( - TFData2VecVisionConvModule( - in_channels=self.channels, - out_channels=self.channels, - kernel_size=kernel_size, - padding="same", - dilation=dilation, - name=f"conv_module_{i + 2}", - ) - ) - if self.num_convs == 0: - self.convs = [tf.identity] - else: - self.convs = convs - if self.concat_input: - self.conv_cat = TFData2VecVisionConvModule( - self.in_channels + self.channels, - out_channels=self.channels, - kernel_size=kernel_size, - padding="same", - name="conv_cat", - ) - - self.classifier = keras.layers.Conv2D(config.num_labels, kernel_size=1, name="classifier") - - def call(self, encoder_hidden_states: tf.Tensor) -> tf.Tensor: - # just take the relevant feature maps - hidden_states = encoder_hidden_states[self.in_index] - output = hidden_states - for layer_module in self.convs: - output = layer_module(output) - if self.concat_input: - output = self.conv_cat(tf.concat([hidden_states, output], axis=-1)) - output = self.classifier(output) - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, None, self.channels]) - if getattr(self, "conv_cat", None) is not None: - with tf.name_scope(self.conv_cat.name): - self.conv_cat.build(None) - - -@add_start_docstrings( - """ - Data2VecVision Model transformer with a semantic segmentation head on top e.g. for ADE20k, CityScapes. - """, - DATA2VEC_VISION_START_DOCSTRING, -) -class TFData2VecVisionForSemanticSegmentation(TFData2VecVisionPreTrainedModel): - def __init__(self, config: Data2VecVisionConfig, *inputs, **kwargs) -> None: - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.data2vec_vision = TFData2VecVisionMainLayer(config, add_pooling_layer=False, name="data2vec_vision") - - # FPNs - self.fpn1 = [ - keras.layers.Conv2DTranspose(config.hidden_size, kernel_size=2, strides=2, name="fpn1.0"), - keras.layers.BatchNormalization(name="fpn1.1", momentum=0.9, epsilon=1e-5), - keras.layers.Activation("gelu"), - keras.layers.Conv2DTranspose(config.hidden_size, kernel_size=2, strides=2, name="fpn1.3"), - ] - self.fpn2 = [keras.layers.Conv2DTranspose(config.hidden_size, kernel_size=2, strides=2, name="fpn2.0")] - - self.fpn3 = tf.identity - self.fpn4 = keras.layers.MaxPool2D(pool_size=2, strides=2) - - # Semantic segmentation head(s) - self.decode_head = TFData2VecVisionUperHead(config, name="decode_head") - self.auxiliary_head = ( - TFData2VecVisionFCNHead(config, name="auxiliary_head") if config.use_auxiliary_head else None - ) - - def compute_loss(self, logits, auxiliary_logits, labels): - # upsample logits to the images' original size - if len(shape_list(labels)) > 3: - label_interp_shape = shape_list(labels)[1:-1] - else: - label_interp_shape = shape_list(labels)[-2:] - - upsampled_logits = tf.image.resize(logits, size=label_interp_shape, method="bilinear") - if auxiliary_logits is not None: - upsampled_auxiliary_logits = tf.image.resize(auxiliary_logits, size=label_interp_shape, method="bilinear") - # compute weighted loss - loss_fct = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction="none") - - # Copied from https://www.tensorflow.org/text/tutorials/transformer#loss_and_metrics. - # Utility to mask the index to ignore during computing the loss. - def masked_loss(real, pred): - mask = tf.math.logical_not(tf.math.equal(real, self.config.semantic_loss_ignore_index)) - loss_ = loss_fct(real, pred) - mask = tf.cast(mask, dtype=loss_.dtype) - loss_ *= mask - reduced_masked_loss = tf.reduce_sum(loss_) / tf.reduce_sum(mask) - return tf.reshape(reduced_masked_loss, (1,)) - - main_loss = masked_loss(labels, upsampled_logits) - auxiliary_loss = masked_loss(labels, upsampled_auxiliary_logits) - loss = main_loss + self.config.auxiliary_loss_weight * auxiliary_loss - - return loss - - @unpack_inputs - @add_start_docstrings_to_model_forward(DATA2VEC_VISION_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSemanticSegmenterOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - labels: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - ) -> tuple | TFSemanticSegmenterOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, height, width)`, *optional*): - Ground truth semantic segmentation maps for computing the loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels > 1`, a classification loss is computed (Cross-Entropy). - - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, TFData2VecVisionForSemanticSegmentation - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/data2vec-vision-base") - >>> model = TFData2VecVisionForSemanticSegmentation.from_pretrained("facebook/data2vec-vision-base") - - >>> inputs = image_processor(images=image, return_tensors="pt") - >>> outputs = model(**inputs) - >>> # logits are of shape (batch_size, num_labels, height, width) - >>> logits = outputs.logits - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - - if labels is not None and self.config.num_labels == 1: - raise ValueError("The number of labels should be greater than one") - - outputs = self.data2vec_vision( - pixel_values, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=True, # we need the intermediate hidden states - return_dict=return_dict, - ) - encoder_hidden_states = outputs.hidden_states if return_dict else outputs[1] - - # only keep certain features, and reshape - # note that we do +1 as the encoder_hidden_states also includes the initial embeddings - features = [feature for idx, feature in enumerate(encoder_hidden_states) if idx + 1 in self.config.out_indices] - patch_resolution = self.config.image_size // self.config.patch_size - - def reshape_features(x): - # We do it this way so TF can always infer the non-batch dims at compile time - x = tf.reshape(x, (-1, patch_resolution, patch_resolution, self.config.hidden_size)) - return x - - features = [reshape_features(x[:, 1:, :]) for x in features] - - # apply FPNs - ops = [self.fpn1, self.fpn2, self.fpn3, self.fpn4] - for module in ops[0]: - features[0] = module(features[0]) - features[1] = ops[1][0](features[1]) - for i in range(len(features[2:])): - features[i + 2] = ops[i + 2](features[i + 2]) - - logits = self.decode_head(features) - # Transpose the logits to maintain consistency in the output formats. - transposed_logits = tf.transpose(logits, perm=[0, 3, 1, 2]) - - auxiliary_logits = None - if self.auxiliary_head is not None: - auxiliary_logits = self.auxiliary_head(features) - - loss = None - if labels is not None: - loss = self.compute_loss(logits, auxiliary_logits, labels) - - if not return_dict: - if output_hidden_states: - output = (logits,) + outputs[1:] - else: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSemanticSegmenterOutput( - loss=loss, - logits=transposed_logits, - hidden_states=outputs.hidden_states if output_hidden_states else None, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "data2vec_vision", None) is not None: - with tf.name_scope(self.data2vec_vision.name): - self.data2vec_vision.build(None) - if getattr(self, "decode_head", None) is not None: - with tf.name_scope(self.decode_head.name): - self.decode_head.build(None) - if getattr(self, "auxiliary_head", None) is not None: - with tf.name_scope(self.auxiliary_head.name): - self.auxiliary_head.build(None) - if getattr(self, "fpn1", None) is not None: - with tf.name_scope(self.fpn1[0].name): - self.fpn1[0].build([None, None, None, self.config.hidden_size]) - with tf.name_scope(self.fpn1[1].name): - self.fpn1[1].build((None, None, None, self.config.hidden_size)) - with tf.name_scope(self.fpn1[3].name): - self.fpn1[3].build([None, None, None, self.config.hidden_size]) - if getattr(self, "fpn2", None) is not None: - with tf.name_scope(self.fpn2[0].name): - self.fpn2[0].build([None, None, None, self.config.hidden_size]) - - -__all__ = [ - "TFData2VecVisionForImageClassification", - "TFData2VecVisionForSemanticSegmentation", - "TFData2VecVisionModel", - "TFData2VecVisionPreTrainedModel", -] diff --git a/src/transformers/models/deberta/__init__.py b/src/transformers/models/deberta/__init__.py index f70972237964..ac2dbc3af259 100644 --- a/src/transformers/models/deberta/__init__.py +++ b/src/transformers/models/deberta/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_deberta import * from .modeling_deberta import * - from .modeling_tf_deberta import * from .tokenization_deberta import * from .tokenization_deberta_fast import * else: diff --git a/src/transformers/models/deberta/configuration_deberta.py b/src/transformers/models/deberta/configuration_deberta.py index 3e23a73a8c38..49015eb7cc5b 100644 --- a/src/transformers/models/deberta/configuration_deberta.py +++ b/src/transformers/models/deberta/configuration_deberta.py @@ -16,7 +16,7 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Any, Union from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig @@ -24,7 +24,7 @@ if TYPE_CHECKING: - from ... import FeatureExtractionMixin, PreTrainedTokenizerBase, TensorType + from ... import FeatureExtractionMixin, PreTrainedTokenizerBase logger = logging.get_logger(__name__) @@ -185,13 +185,12 @@ def generate_dummy_inputs( seq_length: int = -1, num_choices: int = -1, is_pair: bool = False, - framework: Optional["TensorType"] = None, num_channels: int = 3, image_width: int = 40, image_height: int = 40, tokenizer: "PreTrainedTokenizerBase" = None, ) -> Mapping[str, Any]: - dummy_inputs = super().generate_dummy_inputs(preprocessor=preprocessor, framework=framework) + dummy_inputs = super().generate_dummy_inputs(preprocessor=preprocessor) if self._config.type_vocab_size == 0 and "token_type_ids" in dummy_inputs: del dummy_inputs["token_type_ids"] return dummy_inputs diff --git a/src/transformers/models/deberta/modeling_deberta.py b/src/transformers/models/deberta/modeling_deberta.py index 461572b47677..3074db6ca00a 100644 --- a/src/transformers/models/deberta/modeling_deberta.py +++ b/src/transformers/models/deberta/modeling_deberta.py @@ -38,7 +38,7 @@ class DebertaLayerNorm(nn.Module): - """LayerNorm module in the TF style (epsilon inside the square root).""" + """LayerNorm module (epsilon inside the square root).""" def __init__(self, size, eps=1e-12): super().__init__() @@ -617,8 +617,6 @@ class DebertaPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/deberta/modeling_tf_deberta.py b/src/transformers/models/deberta/modeling_tf_deberta.py deleted file mode 100644 index 40d23fc28b94..000000000000 --- a/src/transformers/models/deberta/modeling_tf_deberta.py +++ /dev/null @@ -1,1652 +0,0 @@ -# coding=utf-8 -# Copyright 2021 Microsoft and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 DeBERTa model.""" - -from __future__ import annotations - -import math -from collections.abc import Sequence - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFMaskedLMOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_deberta import DebertaConfig - - -logger = logging.get_logger(__name__) - - -_CONFIG_FOR_DOC = "DebertaConfig" -_CHECKPOINT_FOR_DOC = "kamalkraj/deberta-base" - - -class TFDebertaContextPooler(keras.layers.Layer): - def __init__(self, config: DebertaConfig, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense(config.pooler_hidden_size, name="dense") - self.dropout = TFDebertaStableDropout(config.pooler_dropout, name="dropout") - self.config = config - - def call(self, hidden_states, training: bool = False): - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - context_token = hidden_states[:, 0] - context_token = self.dropout(context_token, training=training) - pooled_output = self.dense(context_token) - pooled_output = get_tf_activation(self.config.pooler_hidden_act)(pooled_output) - return pooled_output - - @property - def output_dim(self) -> int: - return self.config.hidden_size - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.pooler_hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - -class TFDebertaXSoftmax(keras.layers.Layer): - """ - Masked Softmax which is optimized for saving memory - - Args: - input (`tf.Tensor`): The input tensor that will apply softmax. - mask (`tf.Tensor`): The mask matrix where 0 indicate that element will be ignored in the softmax calculation. - dim (int): The dimension that will apply softmax - """ - - def __init__(self, axis=-1, **kwargs): - super().__init__(**kwargs) - self.axis = axis - - def call(self, inputs: tf.Tensor, mask: tf.Tensor): - rmask = tf.logical_not(tf.cast(mask, tf.bool)) - output = tf.where(rmask, tf.cast(float("-inf"), dtype=self.compute_dtype), inputs) - output = stable_softmax(tf.cast(output, dtype=tf.float32), self.axis) - output = tf.where(rmask, 0.0, output) - return output - - -class TFDebertaStableDropout(keras.layers.Layer): - """ - Optimized dropout module for stabilizing the training - - Args: - drop_prob (float): the dropout probabilities - """ - - def __init__(self, drop_prob, **kwargs): - super().__init__(**kwargs) - self.drop_prob = drop_prob - - @tf.custom_gradient - def xdropout(self, inputs): - """ - Applies dropout to the inputs, as vanilla dropout, but also scales the remaining elements up by 1/drop_prob. - """ - mask = tf.cast( - 1 - - tf.compat.v1.distributions.Bernoulli(probs=1.0 - self.drop_prob).sample(sample_shape=shape_list(inputs)), - tf.bool, - ) - scale = tf.convert_to_tensor(1.0 / (1 - self.drop_prob), dtype=self.compute_dtype) - if self.drop_prob > 0: - inputs = tf.where(mask, tf.cast(0.0, dtype=self.compute_dtype), inputs) * scale - - def grad(upstream): - if self.drop_prob > 0: - return tf.where(mask, tf.cast(0.0, dtype=self.compute_dtype), upstream) * scale - else: - return upstream - - return inputs, grad - - def call(self, inputs: tf.Tensor, training: tf.Tensor = False): - if training: - return self.xdropout(inputs) - return inputs - - -class TFDebertaLayerNorm(keras.layers.Layer): - """LayerNorm module in the TF style (epsilon inside the square root).""" - - def __init__(self, size, eps=1e-12, **kwargs): - super().__init__(**kwargs) - self.size = size - self.eps = eps - - def build(self, input_shape): - self.gamma = self.add_weight(shape=[self.size], initializer=tf.ones_initializer(), name="weight") - self.beta = self.add_weight(shape=[self.size], initializer=tf.zeros_initializer(), name="bias") - return super().build(input_shape) - - def call(self, x: tf.Tensor) -> tf.Tensor: - mean = tf.reduce_mean(x, axis=[-1], keepdims=True) - variance = tf.reduce_mean(tf.square(x - mean), axis=[-1], keepdims=True) - std = tf.math.sqrt(variance + self.eps) - return self.gamma * (x - mean) / std + self.beta - - -class TFDebertaSelfOutput(keras.layers.Layer): - def __init__(self, config: DebertaConfig, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense(config.hidden_size, name="dense") - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = TFDebertaStableDropout(config.hidden_dropout_prob, name="dropout") - self.config = config - - def call(self, hidden_states, input_tensor, training: bool = False): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - -class TFDebertaAttention(keras.layers.Layer): - def __init__(self, config: DebertaConfig, **kwargs): - super().__init__(**kwargs) - self.self = TFDebertaDisentangledSelfAttention(config, name="self") - self.dense_output = TFDebertaSelfOutput(config, name="output") - self.config = config - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - query_states: tf.Tensor | None = None, - relative_pos: tf.Tensor | None = None, - rel_embeddings: tf.Tensor | None = None, - output_attentions: bool = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self( - hidden_states=input_tensor, - attention_mask=attention_mask, - query_states=query_states, - relative_pos=relative_pos, - rel_embeddings=rel_embeddings, - output_attentions=output_attentions, - training=training, - ) - if query_states is None: - query_states = input_tensor - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=query_states, training=training - ) - - output = (attention_output,) + self_outputs[1:] - - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self", None) is not None: - with tf.name_scope(self.self.name): - self.self.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -class TFDebertaIntermediate(keras.layers.Layer): - def __init__(self, config: DebertaConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFDebertaOutput(keras.layers.Layer): - def __init__(self, config: DebertaConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = TFDebertaStableDropout(config.hidden_dropout_prob, name="dropout") - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - -class TFDebertaLayer(keras.layers.Layer): - def __init__(self, config: DebertaConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFDebertaAttention(config, name="attention") - self.intermediate = TFDebertaIntermediate(config, name="intermediate") - self.bert_output = TFDebertaOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - query_states: tf.Tensor | None = None, - relative_pos: tf.Tensor | None = None, - rel_embeddings: tf.Tensor | None = None, - output_attentions: bool = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - query_states=query_states, - relative_pos=relative_pos, - rel_embeddings=rel_embeddings, - output_attentions=output_attentions, - training=training, - ) - attention_output = attention_outputs[0] - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - - -class TFDebertaEncoder(keras.layers.Layer): - def __init__(self, config: DebertaConfig, **kwargs): - super().__init__(**kwargs) - - self.layer = [TFDebertaLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - self.relative_attention = getattr(config, "relative_attention", False) - self.config = config - if self.relative_attention: - self.max_relative_positions = getattr(config, "max_relative_positions", -1) - if self.max_relative_positions < 1: - self.max_relative_positions = config.max_position_embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if self.relative_attention: - self.rel_embeddings = self.add_weight( - name="rel_embeddings.weight", - shape=[self.max_relative_positions * 2, self.config.hidden_size], - initializer=get_initializer(self.config.initializer_range), - ) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - def get_rel_embedding(self): - rel_embeddings = self.rel_embeddings if self.relative_attention else None - return rel_embeddings - - def get_attention_mask(self, attention_mask): - if len(shape_list(attention_mask)) <= 2: - extended_attention_mask = tf.expand_dims(tf.expand_dims(attention_mask, 1), 2) - attention_mask = extended_attention_mask * tf.expand_dims(tf.squeeze(extended_attention_mask, -2), -1) - attention_mask = tf.cast(attention_mask, tf.uint8) - elif len(shape_list(attention_mask)) == 3: - attention_mask = tf.expand_dims(attention_mask, 1) - - return attention_mask - - def get_rel_pos(self, hidden_states, query_states=None, relative_pos=None): - if self.relative_attention and relative_pos is None: - q = shape_list(query_states)[-2] if query_states is not None else shape_list(hidden_states)[-2] - relative_pos = build_relative_position(q, shape_list(hidden_states)[-2]) - return relative_pos - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - query_states: tf.Tensor | None = None, - relative_pos: tf.Tensor | None = None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - attention_mask = self.get_attention_mask(attention_mask) - relative_pos = self.get_rel_pos(hidden_states, query_states, relative_pos) - - if isinstance(hidden_states, Sequence): - next_kv = hidden_states[0] - else: - next_kv = hidden_states - - rel_embeddings = self.get_rel_embedding() - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states=next_kv, - attention_mask=attention_mask, - query_states=query_states, - relative_pos=relative_pos, - rel_embeddings=rel_embeddings, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if query_states is not None: - query_states = hidden_states - if isinstance(hidden_states, Sequence): - next_kv = hidden_states[i + 1] if i + 1 < len(self.layer) else None - else: - next_kv = hidden_states - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -def build_relative_position(query_size, key_size): - """ - Build relative position according to the query and key - - We assume the absolute position of query \\(P_q\\) is range from (0, query_size) and the absolute position of key - \\(P_k\\) is range from (0, key_size), The relative positions from query to key is \\(R_{q \\rightarrow k} = P_q - - P_k\\) - - Args: - query_size (int): the length of query - key_size (int): the length of key - - Return: - `tf.Tensor`: A tensor with shape [1, query_size, key_size] - - """ - q_ids = tf.range(query_size, dtype=tf.int32) - k_ids = tf.range(key_size, dtype=tf.int32) - rel_pos_ids = q_ids[:, None] - tf.tile(tf.reshape(k_ids, [1, -1]), [query_size, 1]) - rel_pos_ids = rel_pos_ids[:query_size, :] - rel_pos_ids = tf.expand_dims(rel_pos_ids, axis=0) - return tf.cast(rel_pos_ids, tf.int64) - - -def c2p_dynamic_expand(c2p_pos, query_layer, relative_pos): - shapes = [ - shape_list(query_layer)[0], - shape_list(query_layer)[1], - shape_list(query_layer)[2], - shape_list(relative_pos)[-1], - ] - return tf.broadcast_to(c2p_pos, shapes) - - -def p2c_dynamic_expand(c2p_pos, query_layer, key_layer): - shapes = [ - shape_list(query_layer)[0], - shape_list(query_layer)[1], - shape_list(key_layer)[-2], - shape_list(key_layer)[-2], - ] - return tf.broadcast_to(c2p_pos, shapes) - - -def pos_dynamic_expand(pos_index, p2c_att, key_layer): - shapes = shape_list(p2c_att)[:2] + [shape_list(pos_index)[-2], shape_list(key_layer)[-2]] - return tf.broadcast_to(pos_index, shapes) - - -def torch_gather(x, indices, gather_axis): - if gather_axis < 0: - gather_axis = tf.rank(x) + gather_axis - - if gather_axis != tf.rank(x) - 1: - pre_roll = tf.rank(x) - 1 - gather_axis - permutation = tf.roll(tf.range(tf.rank(x)), pre_roll, axis=0) - x = tf.transpose(x, perm=permutation) - indices = tf.transpose(indices, perm=permutation) - else: - pre_roll = 0 - - flat_x = tf.reshape(x, (-1, tf.shape(x)[-1])) - flat_indices = tf.reshape(indices, (-1, tf.shape(indices)[-1])) - gathered = tf.gather(flat_x, flat_indices, batch_dims=1) - gathered = tf.reshape(gathered, tf.shape(indices)) - - if pre_roll != 0: - permutation = tf.roll(tf.range(tf.rank(x)), -pre_roll, axis=0) - gathered = tf.transpose(gathered, perm=permutation) - - return gathered - - -class TFDebertaDisentangledSelfAttention(keras.layers.Layer): - """ - Disentangled self-attention module - - Parameters: - config (`str`): - A model config class instance with the configuration to build a new model. The schema is similar to - *BertConfig*, for more details, please refer [`DebertaConfig`] - - """ - - def __init__(self, config: DebertaConfig, **kwargs): - super().__init__(**kwargs) - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " - f"heads ({config.num_attention_heads})" - ) - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.in_proj = keras.layers.Dense( - self.all_head_size * 3, - kernel_initializer=get_initializer(config.initializer_range), - name="in_proj", - use_bias=False, - ) - self.pos_att_type = config.pos_att_type if config.pos_att_type is not None else [] - - self.relative_attention = getattr(config, "relative_attention", False) - self.talking_head = getattr(config, "talking_head", False) - - if self.talking_head: - self.head_logits_proj = keras.layers.Dense( - self.num_attention_heads, - kernel_initializer=get_initializer(config.initializer_range), - name="head_logits_proj", - use_bias=False, - ) - self.head_weights_proj = keras.layers.Dense( - self.num_attention_heads, - kernel_initializer=get_initializer(config.initializer_range), - name="head_weights_proj", - use_bias=False, - ) - - self.softmax = TFDebertaXSoftmax(axis=-1) - - if self.relative_attention: - self.max_relative_positions = getattr(config, "max_relative_positions", -1) - if self.max_relative_positions < 1: - self.max_relative_positions = config.max_position_embeddings - self.pos_dropout = TFDebertaStableDropout(config.hidden_dropout_prob, name="pos_dropout") - if "c2p" in self.pos_att_type: - self.pos_proj = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="pos_proj", - use_bias=False, - ) - if "p2c" in self.pos_att_type: - self.pos_q_proj = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="pos_q_proj" - ) - - self.dropout = TFDebertaStableDropout(config.attention_probs_dropout_prob, name="dropout") - self.config = config - - def build(self, input_shape=None): - if self.built: - return - self.built = True - self.q_bias = self.add_weight( - name="q_bias", shape=(self.all_head_size), initializer=keras.initializers.Zeros() - ) - self.v_bias = self.add_weight( - name="v_bias", shape=(self.all_head_size), initializer=keras.initializers.Zeros() - ) - if getattr(self, "in_proj", None) is not None: - with tf.name_scope(self.in_proj.name): - self.in_proj.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "head_logits_proj", None) is not None: - with tf.name_scope(self.head_logits_proj.name): - self.head_logits_proj.build(None) - if getattr(self, "head_weights_proj", None) is not None: - with tf.name_scope(self.head_weights_proj.name): - self.head_weights_proj.build(None) - if getattr(self, "pos_dropout", None) is not None: - with tf.name_scope(self.pos_dropout.name): - self.pos_dropout.build(None) - if getattr(self, "pos_proj", None) is not None: - with tf.name_scope(self.pos_proj.name): - self.pos_proj.build([self.config.hidden_size]) - if getattr(self, "pos_q_proj", None) is not None: - with tf.name_scope(self.pos_q_proj.name): - self.pos_q_proj.build([self.config.hidden_size]) - - def transpose_for_scores(self, tensor: tf.Tensor) -> tf.Tensor: - shape = shape_list(tensor)[:-1] + [self.num_attention_heads, -1] - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=shape) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - query_states: tf.Tensor | None = None, - relative_pos: tf.Tensor | None = None, - rel_embeddings: tf.Tensor | None = None, - output_attentions: bool = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - """ - Call the module - - Args: - hidden_states (`tf.Tensor`): - Input states to the module usually the output from previous layer, it will be the Q,K and V in - *Attention(Q,K,V)* - - attention_mask (`tf.Tensor`): - An attention mask matrix of shape [*B*, *N*, *N*] where *B* is the batch size, *N* is the maximum - sequence length in which element [i,j] = *1* means the *i* th token in the input can attend to the *j* - th token. - - return_att (`bool`, *optional*): - Whether return the attention matrix. - - query_states (`tf.Tensor`, *optional*): - The *Q* state in *Attention(Q,K,V)*. - - relative_pos (`tf.Tensor`): - The relative position encoding between the tokens in the sequence. It's of shape [*B*, *N*, *N*] with - values ranging in [*-max_relative_positions*, *max_relative_positions*]. - - rel_embeddings (`tf.Tensor`): - The embedding of relative distances. It's a tensor of shape [\\(2 \\times - \\text{max_relative_positions}\\), *hidden_size*]. - - - """ - if query_states is None: - qp = self.in_proj(hidden_states) # .split(self.all_head_size, dim=-1) - query_layer, key_layer, value_layer = tf.split( - self.transpose_for_scores(qp), num_or_size_splits=3, axis=-1 - ) - else: - - def linear(w, b, x): - out = tf.matmul(x, w, transpose_b=True) - if b is not None: - out += tf.transpose(b) - return out - - ws = tf.split( - tf.transpose(self.in_proj.weight[0]), num_or_size_splits=self.num_attention_heads * 3, axis=0 - ) - qkvw = tf.TensorArray(dtype=self.dtype, size=3) - for k in tf.range(3): - qkvw_inside = tf.TensorArray(dtype=self.dtype, size=self.num_attention_heads) - for i in tf.range(self.num_attention_heads): - qkvw_inside = qkvw_inside.write(i, ws[i * 3 + k]) - qkvw = qkvw.write(k, qkvw_inside.concat()) - qkvb = [None] * 3 - - q = linear(qkvw[0], qkvb[0], query_states) - k = linear(qkvw[1], qkvb[1], hidden_states) - v = linear(qkvw[2], qkvb[2], hidden_states) - query_layer = self.transpose_for_scores(q) - key_layer = self.transpose_for_scores(k) - value_layer = self.transpose_for_scores(v) - - query_layer = query_layer + self.transpose_for_scores(self.q_bias[None, None, :]) - value_layer = value_layer + self.transpose_for_scores(self.v_bias[None, None, :]) - - rel_att = None - # Take the dot product between "query" and "key" to get the raw attention scores. - scale_factor = 1 + len(self.pos_att_type) - scale = math.sqrt(shape_list(query_layer)[-1] * scale_factor) - query_layer = query_layer / scale - - attention_scores = tf.matmul(query_layer, tf.transpose(key_layer, [0, 1, 3, 2])) - if self.relative_attention: - rel_embeddings = self.pos_dropout(rel_embeddings, training=training) - rel_att = self.disentangled_att_bias(query_layer, key_layer, relative_pos, rel_embeddings, scale_factor) - - if rel_att is not None: - attention_scores = attention_scores + rel_att - - if self.talking_head: - attention_scores = tf.transpose( - self.head_logits_proj(tf.transpose(attention_scores, [0, 2, 3, 1])), [0, 3, 1, 2] - ) - - attention_probs = self.softmax(attention_scores, attention_mask) - attention_probs = self.dropout(attention_probs, training=training) - if self.talking_head: - attention_probs = tf.transpose( - self.head_weights_proj(tf.transpose(attention_probs, [0, 2, 3, 1])), [0, 3, 1, 2] - ) - - context_layer = tf.matmul(attention_probs, value_layer) - context_layer = tf.transpose(context_layer, [0, 2, 1, 3]) - context_layer_shape = shape_list(context_layer) - # Set the final dimension here explicitly. - # Calling tf.reshape(context_layer, (*context_layer_shape[:-2], -1)) raises an error when executing - # the model in graph mode as context_layer is reshaped to (None, 7, None) and Dense layer in TFDebertaV2SelfOutput - # requires final input dimension to be defined - new_context_layer_shape = context_layer_shape[:-2] + [context_layer_shape[-2] * context_layer_shape[-1]] - context_layer = tf.reshape(context_layer, new_context_layer_shape) - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - return outputs - - def disentangled_att_bias(self, query_layer, key_layer, relative_pos, rel_embeddings, scale_factor): - if relative_pos is None: - q = shape_list(query_layer)[-2] - relative_pos = build_relative_position(q, shape_list(key_layer)[-2]) - shape_list_pos = shape_list(relative_pos) - if len(shape_list_pos) == 2: - relative_pos = tf.expand_dims(tf.expand_dims(relative_pos, 0), 0) - elif len(shape_list_pos) == 3: - relative_pos = tf.expand_dims(relative_pos, 1) - # bxhxqxk - elif len(shape_list_pos) != 4: - raise ValueError(f"Relative position ids must be of dim 2 or 3 or 4. {len(shape_list_pos)}") - - att_span = tf.cast( - tf.minimum( - tf.maximum(shape_list(query_layer)[-2], shape_list(key_layer)[-2]), self.max_relative_positions - ), - tf.int64, - ) - rel_embeddings = tf.expand_dims( - rel_embeddings[self.max_relative_positions - att_span : self.max_relative_positions + att_span, :], 0 - ) - - score = 0 - - # content->position - if "c2p" in self.pos_att_type: - pos_key_layer = self.pos_proj(rel_embeddings) - pos_key_layer = self.transpose_for_scores(pos_key_layer) - c2p_att = tf.matmul(query_layer, tf.transpose(pos_key_layer, [0, 1, 3, 2])) - c2p_pos = tf.clip_by_value(relative_pos + att_span, 0, att_span * 2 - 1) - c2p_att = torch_gather(c2p_att, c2p_dynamic_expand(c2p_pos, query_layer, relative_pos), -1) - score += c2p_att - - # position->content - if "p2c" in self.pos_att_type: - pos_query_layer = self.pos_q_proj(rel_embeddings) - pos_query_layer = self.transpose_for_scores(pos_query_layer) - pos_query_layer /= tf.math.sqrt( - tf.cast(shape_list(pos_query_layer)[-1] * scale_factor, dtype=self.compute_dtype) - ) - if shape_list(query_layer)[-2] != shape_list(key_layer)[-2]: - r_pos = build_relative_position(shape_list(key_layer)[-2], shape_list(key_layer)[-2]) - else: - r_pos = relative_pos - p2c_pos = tf.clip_by_value(-r_pos + att_span, 0, att_span * 2 - 1) - p2c_att = tf.matmul(key_layer, tf.transpose(pos_query_layer, [0, 1, 3, 2])) - p2c_att = tf.transpose( - torch_gather(p2c_att, p2c_dynamic_expand(p2c_pos, query_layer, key_layer), -1), [0, 1, 3, 2] - ) - if shape_list(query_layer)[-2] != shape_list(key_layer)[-2]: - pos_index = tf.expand_dims(relative_pos[:, :, :, 0], -1) - p2c_att = torch_gather(p2c_att, pos_dynamic_expand(pos_index, p2c_att, key_layer), -2) - score += p2c_att - - return score - - -class TFDebertaEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = getattr(config, "embedding_size", config.hidden_size) - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.position_biased_input = getattr(config, "position_biased_input", True) - self.initializer_range = config.initializer_range - if self.embedding_size != config.hidden_size: - self.embed_proj = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="embed_proj", - use_bias=False, - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = TFDebertaStableDropout(config.hidden_dropout_prob, name="dropout") - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - if self.config.type_vocab_size > 0: - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - else: - self.token_type_embeddings = None - - with tf.name_scope("position_embeddings"): - if self.position_biased_input: - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - else: - self.position_embeddings = None - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "embed_proj", None) is not None: - with tf.name_scope(self.embed_proj.name): - self.embed_proj.build([None, None, self.embedding_size]) - - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - mask: tf.Tensor | None = None, - training: bool = False, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - if input_ids is None and inputs_embeds is None: - raise ValueError("Need to provide either `input_ids` or `input_embeds`.") - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) - - final_embeddings = inputs_embeds - if self.position_biased_input: - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - final_embeddings += position_embeds - if self.config.type_vocab_size > 0: - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings += token_type_embeds - - if self.embedding_size != self.hidden_size: - final_embeddings = self.embed_proj(final_embeddings) - - final_embeddings = self.LayerNorm(final_embeddings) - - if mask is not None: - if len(shape_list(mask)) != len(shape_list(final_embeddings)): - if len(shape_list(mask)) == 4: - mask = tf.squeeze(tf.squeeze(mask, axis=1), axis=1) - mask = tf.cast(tf.expand_dims(mask, axis=2), dtype=self.compute_dtype) - - final_embeddings = final_embeddings * mask - - final_embeddings = self.dropout(final_embeddings, training=training) - - return final_embeddings - - -class TFDebertaPredictionHeadTransform(keras.layers.Layer): - def __init__(self, config: DebertaConfig, **kwargs): - super().__init__(**kwargs) - - self.embedding_size = getattr(config, "embedding_size", config.hidden_size) - - self.dense = keras.layers.Dense( - units=self.embedding_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - - if isinstance(config.hidden_act, str): - self.transform_act_fn = get_tf_activation(config.hidden_act) - else: - self.transform_act_fn = config.hidden_act - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.transform_act_fn(hidden_states) - hidden_states = self.LayerNorm(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.embedding_size]) - - -class TFDebertaLMPredictionHead(keras.layers.Layer): - def __init__(self, config: DebertaConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = getattr(config, "embedding_size", config.hidden_size) - - self.transform = TFDebertaPredictionHeadTransform(config, name="transform") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.input_embeddings = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "transform", None) is not None: - with tf.name_scope(self.transform.name): - self.transform.build(None) - - def get_output_embeddings(self) -> keras.layers.Layer: - return self.input_embeddings - - def set_output_embeddings(self, value: tf.Variable): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self) -> dict[str, tf.Variable]: - return {"bias": self.bias} - - def set_bias(self, value: tf.Variable): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.transform(hidden_states=hidden_states) - seq_length = shape_list(hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.embedding_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -class TFDebertaOnlyMLMHead(keras.layers.Layer): - def __init__(self, config: DebertaConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - self.predictions = TFDebertaLMPredictionHead(config, input_embeddings, name="predictions") - - def call(self, sequence_output: tf.Tensor) -> tf.Tensor: - prediction_scores = self.predictions(hidden_states=sequence_output) - - return prediction_scores - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -# @keras_serializable -class TFDebertaMainLayer(keras.layers.Layer): - config_class = DebertaConfig - - def __init__(self, config: DebertaConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - - self.embeddings = TFDebertaEmbeddings(config, name="embeddings") - self.encoder = TFDebertaEncoder(config, name="encoder") - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - mask=attention_mask, - training=training, - ) - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - - if not return_dict: - return (sequence_output,) + encoder_outputs[1:] - - return TFBaseModelOutput( - last_hidden_state=sequence_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - - -class TFDebertaPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = DebertaConfig - base_model_prefix = "deberta" - - -DEBERTA_START_DOCSTRING = r""" - The DeBERTa model was proposed in [DeBERTa: Decoding-enhanced BERT with Disentangled - Attention](https://huggingface.co/papers/2006.03654) by Pengcheng He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen. It's build - on top of BERT/RoBERTa with two improvements, i.e. disentangled attention and enhanced mask decoder. With those two - improvements, it out perform BERT/RoBERTa on a majority of tasks with 80GB pretraining data. - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`DebertaConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -DEBERTA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert *input_ids* indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput``] instead of a plain tuple. -""" - - -@add_start_docstrings( - "The bare DeBERTa Model transformer outputting raw hidden-states without any specific head on top.", - DEBERTA_START_DOCSTRING, -) -class TFDebertaModel(TFDebertaPreTrainedModel): - def __init__(self, config: DebertaConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.deberta = TFDebertaMainLayer(config, name="deberta") - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - outputs = self.deberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - - -@add_start_docstrings("""DeBERTa Model with a `language modeling` head on top.""", DEBERTA_START_DOCSTRING) -class TFDebertaForMaskedLM(TFDebertaPreTrainedModel, TFMaskedLanguageModelingLoss): - def __init__(self, config: DebertaConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if config.is_decoder: - logger.warning( - "If you want to use `TFDebertaForMaskedLM` make sure `config.is_decoder=False` for " - "bi-directional self-attention." - ) - - self.deberta = TFDebertaMainLayer(config, name="deberta") - self.mlm = TFDebertaOnlyMLMHead(config, input_embeddings=self.deberta.embeddings, name="cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.mlm.predictions - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.deberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.mlm(sequence_output=sequence_output, training=training) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - if getattr(self, "mlm", None) is not None: - with tf.name_scope(self.mlm.name): - self.mlm.build(None) - - -@add_start_docstrings( - """ - DeBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - DEBERTA_START_DOCSTRING, -) -class TFDebertaForSequenceClassification(TFDebertaPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: DebertaConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.deberta = TFDebertaMainLayer(config, name="deberta") - self.pooler = TFDebertaContextPooler(config, name="pooler") - - drop_out = getattr(config, "cls_dropout", None) - drop_out = self.config.hidden_dropout_prob if drop_out is None else drop_out - self.dropout = TFDebertaStableDropout(drop_out, name="cls_dropout") - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - self.output_dim = self.pooler.output_dim - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.deberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - pooled_output = self.pooler(sequence_output, training=training) - pooled_output = self.dropout(pooled_output, training=training) - logits = self.classifier(pooled_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[1:] - - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.output_dim]) - - -@add_start_docstrings( - """ - DeBERTa Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - DEBERTA_START_DOCSTRING, -) -class TFDebertaForTokenClassification(TFDebertaPreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config: DebertaConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.deberta = TFDebertaMainLayer(config, name="deberta") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.deberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(inputs=sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - DeBERTa Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - DEBERTA_START_DOCSTRING, -) -class TFDebertaForQuestionAnswering(TFDebertaPreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config: DebertaConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.deberta = TFDebertaMainLayer(config, name="deberta") - self.qa_outputs = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.deberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.qa_outputs(inputs=sequence_output) - start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) - start_logits = tf.squeeze(input=start_logits, axis=-1) - end_logits = tf.squeeze(input=end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels=labels, logits=(start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFDebertaForMaskedLM", - "TFDebertaForQuestionAnswering", - "TFDebertaForSequenceClassification", - "TFDebertaForTokenClassification", - "TFDebertaModel", - "TFDebertaPreTrainedModel", -] diff --git a/src/transformers/models/deberta_v2/__init__.py b/src/transformers/models/deberta_v2/__init__.py index 7c42c9c50286..929b26e60ae0 100644 --- a/src/transformers/models/deberta_v2/__init__.py +++ b/src/transformers/models/deberta_v2/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_deberta_v2 import * from .modeling_deberta_v2 import * - from .modeling_tf_deberta_v2 import * from .tokenization_deberta_v2 import * from .tokenization_deberta_v2_fast import * else: diff --git a/src/transformers/models/deberta_v2/configuration_deberta_v2.py b/src/transformers/models/deberta_v2/configuration_deberta_v2.py index 5189cfd53ae7..43576e815d07 100644 --- a/src/transformers/models/deberta_v2/configuration_deberta_v2.py +++ b/src/transformers/models/deberta_v2/configuration_deberta_v2.py @@ -16,7 +16,7 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Any, Union from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig @@ -24,7 +24,7 @@ if TYPE_CHECKING: - from ... import FeatureExtractionMixin, PreTrainedTokenizerBase, TensorType + from ... import FeatureExtractionMixin, PreTrainedTokenizerBase logger = logging.get_logger(__name__) @@ -184,13 +184,12 @@ def generate_dummy_inputs( seq_length: int = -1, num_choices: int = -1, is_pair: bool = False, - framework: Optional["TensorType"] = None, num_channels: int = 3, image_width: int = 40, image_height: int = 40, tokenizer: "PreTrainedTokenizerBase" = None, ) -> Mapping[str, Any]: - dummy_inputs = super().generate_dummy_inputs(preprocessor=preprocessor, framework=framework) + dummy_inputs = super().generate_dummy_inputs(preprocessor=preprocessor) if self._config.type_vocab_size == 0 and "token_type_ids" in dummy_inputs: del dummy_inputs["token_type_ids"] return dummy_inputs diff --git a/src/transformers/models/deberta_v2/modeling_deberta_v2.py b/src/transformers/models/deberta_v2/modeling_deberta_v2.py index 9d06f00c0ce6..71bf04b95542 100644 --- a/src/transformers/models/deberta_v2/modeling_deberta_v2.py +++ b/src/transformers/models/deberta_v2/modeling_deberta_v2.py @@ -697,8 +697,6 @@ class DebertaV2PreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/deberta_v2/modeling_tf_deberta_v2.py b/src/transformers/models/deberta_v2/modeling_tf_deberta_v2.py deleted file mode 100644 index d71891ac19c0..000000000000 --- a/src/transformers/models/deberta_v2/modeling_tf_deberta_v2.py +++ /dev/null @@ -1,1879 +0,0 @@ -# coding=utf-8 -# Copyright 2021 Microsoft and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 DeBERTa-v2 model.""" - -from __future__ import annotations - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_deberta_v2 import DebertaV2Config - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "DebertaV2Config" -_CHECKPOINT_FOR_DOC = "kamalkraj/deberta-v2-xlarge" - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaContextPooler with Deberta->DebertaV2 -class TFDebertaV2ContextPooler(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense(config.pooler_hidden_size, name="dense") - self.dropout = TFDebertaV2StableDropout(config.pooler_dropout, name="dropout") - self.config = config - - def call(self, hidden_states, training: bool = False): - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - context_token = hidden_states[:, 0] - context_token = self.dropout(context_token, training=training) - pooled_output = self.dense(context_token) - pooled_output = get_tf_activation(self.config.pooler_hidden_act)(pooled_output) - return pooled_output - - @property - def output_dim(self) -> int: - return self.config.hidden_size - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.pooler_hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaXSoftmax with Deberta->DebertaV2 -class TFDebertaV2XSoftmax(keras.layers.Layer): - """ - Masked Softmax which is optimized for saving memory - - Args: - input (`tf.Tensor`): The input tensor that will apply softmax. - mask (`tf.Tensor`): The mask matrix where 0 indicate that element will be ignored in the softmax calculation. - dim (int): The dimension that will apply softmax - """ - - def __init__(self, axis=-1, **kwargs): - super().__init__(**kwargs) - self.axis = axis - - def call(self, inputs: tf.Tensor, mask: tf.Tensor): - rmask = tf.logical_not(tf.cast(mask, tf.bool)) - output = tf.where(rmask, tf.cast(float("-inf"), dtype=self.compute_dtype), inputs) - output = stable_softmax(tf.cast(output, dtype=tf.float32), self.axis) - output = tf.where(rmask, 0.0, output) - return output - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaStableDropout with Deberta->DebertaV2 -class TFDebertaV2StableDropout(keras.layers.Layer): - """ - Optimized dropout module for stabilizing the training - - Args: - drop_prob (float): the dropout probabilities - """ - - def __init__(self, drop_prob, **kwargs): - super().__init__(**kwargs) - self.drop_prob = drop_prob - - @tf.custom_gradient - def xdropout(self, inputs): - """ - Applies dropout to the inputs, as vanilla dropout, but also scales the remaining elements up by 1/drop_prob. - """ - mask = tf.cast( - 1 - - tf.compat.v1.distributions.Bernoulli(probs=1.0 - self.drop_prob).sample(sample_shape=shape_list(inputs)), - tf.bool, - ) - scale = tf.convert_to_tensor(1.0 / (1 - self.drop_prob), dtype=self.compute_dtype) - if self.drop_prob > 0: - inputs = tf.where(mask, tf.cast(0.0, dtype=self.compute_dtype), inputs) * scale - - def grad(upstream): - if self.drop_prob > 0: - return tf.where(mask, tf.cast(0.0, dtype=self.compute_dtype), upstream) * scale - else: - return upstream - - return inputs, grad - - def call(self, inputs: tf.Tensor, training: tf.Tensor = False): - if training: - return self.xdropout(inputs) - return inputs - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaSelfOutput with Deberta->DebertaV2 -class TFDebertaV2SelfOutput(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense(config.hidden_size, name="dense") - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = TFDebertaV2StableDropout(config.hidden_dropout_prob, name="dropout") - self.config = config - - def call(self, hidden_states, input_tensor, training: bool = False): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaAttention with Deberta->DebertaV2 -class TFDebertaV2Attention(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - self.self = TFDebertaV2DisentangledSelfAttention(config, name="self") - self.dense_output = TFDebertaV2SelfOutput(config, name="output") - self.config = config - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - query_states: tf.Tensor | None = None, - relative_pos: tf.Tensor | None = None, - rel_embeddings: tf.Tensor | None = None, - output_attentions: bool = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self( - hidden_states=input_tensor, - attention_mask=attention_mask, - query_states=query_states, - relative_pos=relative_pos, - rel_embeddings=rel_embeddings, - output_attentions=output_attentions, - training=training, - ) - if query_states is None: - query_states = input_tensor - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=query_states, training=training - ) - - output = (attention_output,) + self_outputs[1:] - - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self", None) is not None: - with tf.name_scope(self.self.name): - self.self.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaIntermediate with Deberta->DebertaV2 -class TFDebertaV2Intermediate(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaOutput with Deberta->DebertaV2 -class TFDebertaV2Output(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = TFDebertaV2StableDropout(config.hidden_dropout_prob, name="dropout") - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaLayer with Deberta->DebertaV2 -class TFDebertaV2Layer(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - - self.attention = TFDebertaV2Attention(config, name="attention") - self.intermediate = TFDebertaV2Intermediate(config, name="intermediate") - self.bert_output = TFDebertaV2Output(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - query_states: tf.Tensor | None = None, - relative_pos: tf.Tensor | None = None, - rel_embeddings: tf.Tensor | None = None, - output_attentions: bool = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - query_states=query_states, - relative_pos=relative_pos, - rel_embeddings=rel_embeddings, - output_attentions=output_attentions, - training=training, - ) - attention_output = attention_outputs[0] - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - - -class TFDebertaV2ConvLayer(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - - self.kernel_size = getattr(config, "conv_kernel_size", 3) - # groups = getattr(config, "conv_groups", 1) - self.conv_act = get_tf_activation(getattr(config, "conv_act", "tanh")) - self.padding = (self.kernel_size - 1) // 2 - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = TFDebertaV2StableDropout(config.hidden_dropout_prob, name="dropout") - self.config = config - - def build(self, input_shape=None): - if self.built: - return - self.built = True - with tf.name_scope("conv"): - self.conv_kernel = self.add_weight( - name="kernel", - shape=[self.kernel_size, self.config.hidden_size, self.config.hidden_size], - initializer=get_initializer(self.config.initializer_range), - ) - self.conv_bias = self.add_weight( - name="bias", shape=[self.config.hidden_size], initializer=tf.zeros_initializer() - ) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - def call( - self, hidden_states: tf.Tensor, residual_states: tf.Tensor, input_mask: tf.Tensor, training: bool = False - ) -> tf.Tensor: - out = tf.nn.conv2d( - tf.expand_dims(hidden_states, 1), - tf.expand_dims(self.conv_kernel, 0), - strides=1, - padding=[[0, 0], [0, 0], [self.padding, self.padding], [0, 0]], - ) - out = tf.squeeze(tf.nn.bias_add(out, self.conv_bias), 1) - rmask = tf.cast(1 - input_mask, tf.bool) - out = tf.where(tf.broadcast_to(tf.expand_dims(rmask, -1), shape_list(out)), 0.0, out) - out = self.dropout(out, training=training) - out = self.conv_act(out) - - layer_norm_input = residual_states + out - output = self.LayerNorm(layer_norm_input) - - if input_mask is None: - output_states = output - else: - if len(shape_list(input_mask)) != len(shape_list(layer_norm_input)): - if len(shape_list(input_mask)) == 4: - input_mask = tf.squeeze(tf.squeeze(input_mask, axis=1), axis=1) - input_mask = tf.cast(tf.expand_dims(input_mask, axis=2), dtype=self.compute_dtype) - - output_states = output * input_mask - - return output_states - - -class TFDebertaV2Encoder(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - - self.layer = [TFDebertaV2Layer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - self.relative_attention = getattr(config, "relative_attention", False) - self.config = config - if self.relative_attention: - self.max_relative_positions = getattr(config, "max_relative_positions", -1) - if self.max_relative_positions < 1: - self.max_relative_positions = config.max_position_embeddings - - self.position_buckets = getattr(config, "position_buckets", -1) - self.pos_ebd_size = self.max_relative_positions * 2 - - if self.position_buckets > 0: - self.pos_ebd_size = self.position_buckets * 2 - - self.norm_rel_ebd = [x.strip() for x in getattr(config, "norm_rel_ebd", "none").lower().split("|")] - - if "layer_norm" in self.norm_rel_ebd: - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - - self.conv = TFDebertaV2ConvLayer(config, name="conv") if getattr(config, "conv_kernel_size", 0) > 0 else None - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if self.relative_attention: - self.rel_embeddings = self.add_weight( - name="rel_embeddings.weight", - shape=[self.pos_ebd_size, self.config.hidden_size], - initializer=get_initializer(self.config.initializer_range), - ) - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build(None) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, self.config.hidden_size]) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - def get_rel_embedding(self): - rel_embeddings = self.rel_embeddings if self.relative_attention else None - if rel_embeddings is not None and ("layer_norm" in self.norm_rel_ebd): - rel_embeddings = self.LayerNorm(rel_embeddings) - return rel_embeddings - - def get_attention_mask(self, attention_mask): - if len(shape_list(attention_mask)) <= 2: - extended_attention_mask = tf.expand_dims(tf.expand_dims(attention_mask, 1), 2) - attention_mask = extended_attention_mask * tf.expand_dims(tf.squeeze(extended_attention_mask, -2), -1) - attention_mask = tf.cast(attention_mask, tf.uint8) - elif len(shape_list(attention_mask)) == 3: - attention_mask = tf.expand_dims(attention_mask, 1) - - return attention_mask - - def get_rel_pos(self, hidden_states, query_states=None, relative_pos=None): - if self.relative_attention and relative_pos is None: - q = shape_list(query_states)[-2] if query_states is not None else shape_list(hidden_states)[-2] - relative_pos = build_relative_position( - q, - shape_list(hidden_states)[-2], - bucket_size=self.position_buckets, - max_position=self.max_relative_positions, - ) - return relative_pos - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - query_states: tf.Tensor | None = None, - relative_pos: tf.Tensor | None = None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - if len(shape_list(attention_mask)) <= 2: - input_mask = attention_mask - else: - input_mask = tf.cast(tf.math.reduce_sum(attention_mask, axis=-2) > 0, dtype=tf.uint8) - - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - attention_mask = self.get_attention_mask(attention_mask) - relative_pos = self.get_rel_pos(hidden_states, query_states, relative_pos) - - next_kv = hidden_states - - rel_embeddings = self.get_rel_embedding() - output_states = next_kv - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (output_states,) - - layer_outputs = layer_module( - hidden_states=next_kv, - attention_mask=attention_mask, - query_states=query_states, - relative_pos=relative_pos, - rel_embeddings=rel_embeddings, - output_attentions=output_attentions, - training=training, - ) - output_states = layer_outputs[0] - - if i == 0 and self.conv is not None: - output_states = self.conv(hidden_states, output_states, input_mask) - - next_kv = output_states - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (output_states,) - - if not return_dict: - return tuple(v for v in [output_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=output_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -def make_log_bucket_position(relative_pos, bucket_size, max_position): - sign = tf.math.sign(relative_pos) - mid = bucket_size // 2 - abs_pos = tf.where((relative_pos < mid) & (relative_pos > -mid), mid - 1, tf.math.abs(relative_pos)) - log_pos = tf.math.ceil( - tf.cast(tf.math.log(abs_pos / mid), tf.float32) - / tf.cast(tf.math.log((max_position - 1) / mid), tf.float32) - * tf.cast(mid - 1, tf.float32) # in graph mode - ) + tf.cast(mid, tf.float32) - bucket_pos = tf.cast( - tf.where(abs_pos <= mid, tf.cast(relative_pos, tf.float32), log_pos * tf.cast(sign, tf.float32)), tf.int32 - ) - return bucket_pos - - -def build_relative_position(query_size, key_size, bucket_size=-1, max_position=-1): - """ - Build relative position according to the query and key - - We assume the absolute position of query \\(P_q\\) is range from (0, query_size) and the absolute position of key - \\(P_k\\) is range from (0, key_size), The relative positions from query to key is \\(R_{q \\rightarrow k} = P_q - - P_k\\) - - Args: - query_size (int): the length of query - key_size (int): the length of key - bucket_size (int): the size of position bucket - max_position (int): the maximum allowed absolute position - - Return: - `tf.Tensor`: A tensor with shape [1, query_size, key_size] - - """ - q_ids = tf.range(query_size, dtype=tf.int32) - k_ids = tf.range(key_size, dtype=tf.int32) - rel_pos_ids = q_ids[:, None] - tf.tile(tf.expand_dims(k_ids, axis=0), [shape_list(q_ids)[0], 1]) - if bucket_size > 0 and max_position > 0: - rel_pos_ids = make_log_bucket_position(rel_pos_ids, bucket_size, max_position) - rel_pos_ids = rel_pos_ids[:query_size, :] - rel_pos_ids = tf.expand_dims(rel_pos_ids, axis=0) - return tf.cast(rel_pos_ids, tf.int64) - - -def c2p_dynamic_expand(c2p_pos, query_layer, relative_pos): - shapes = [ - shape_list(query_layer)[0], - shape_list(query_layer)[1], - shape_list(query_layer)[2], - shape_list(relative_pos)[-1], - ] - return tf.broadcast_to(c2p_pos, shapes) - - -def p2c_dynamic_expand(c2p_pos, query_layer, key_layer): - shapes = [ - shape_list(query_layer)[0], - shape_list(query_layer)[1], - shape_list(key_layer)[-2], - shape_list(key_layer)[-2], - ] - return tf.broadcast_to(c2p_pos, shapes) - - -def pos_dynamic_expand(pos_index, p2c_att, key_layer): - shapes = shape_list(p2c_att)[:2] + [shape_list(pos_index)[-2], shape_list(key_layer)[-2]] - return tf.broadcast_to(pos_index, shapes) - - -def take_along_axis(x, indices): - # Only a valid port of np.take_along_axis when the gather axis is -1 - - # TPU + gathers and reshapes don't go along well -- see https://github.com/huggingface/transformers/issues/18239 - if isinstance(tf.distribute.get_strategy(), tf.distribute.TPUStrategy): - # [B, S, P] -> [B, S, P, D] - one_hot_indices = tf.one_hot(indices, depth=x.shape[-1], dtype=x.dtype) - - # if we ignore the first two dims, this is equivalent to multiplying a matrix (one hot) by a vector (x) - # grossly abusing notation: [B, S, P, D] . [B, S, D] = [B, S, P] - gathered = tf.einsum("ijkl,ijl->ijk", one_hot_indices, x) - - # GPUs, on the other hand, prefer gathers instead of large one-hot+matmuls - else: - gathered = tf.gather(x, indices, batch_dims=2) - - return gathered - - -class TFDebertaV2DisentangledSelfAttention(keras.layers.Layer): - """ - Disentangled self-attention module - - Parameters: - config (`DebertaV2Config`): - A model config class instance with the configuration to build a new model. The schema is similar to - *BertConfig*, for more details, please refer [`DebertaV2Config`] - - """ - - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " - f"heads ({config.num_attention_heads})" - ) - self.num_attention_heads = config.num_attention_heads - _attention_head_size = config.hidden_size // config.num_attention_heads - self.attention_head_size = getattr(config, "attention_head_size", _attention_head_size) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.query_proj = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="query_proj", - use_bias=True, - ) - self.key_proj = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="key_proj", - use_bias=True, - ) - self.value_proj = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="value_proj", - use_bias=True, - ) - - self.share_att_key = getattr(config, "share_att_key", False) - self.pos_att_type = config.pos_att_type if config.pos_att_type is not None else [] - self.relative_attention = getattr(config, "relative_attention", False) - - if self.relative_attention: - self.position_buckets = getattr(config, "position_buckets", -1) - self.max_relative_positions = getattr(config, "max_relative_positions", -1) - if self.max_relative_positions < 1: - self.max_relative_positions = config.max_position_embeddings - self.pos_ebd_size = self.max_relative_positions - if self.position_buckets > 0: - self.pos_ebd_size = self.position_buckets - - self.pos_dropout = TFDebertaV2StableDropout(config.hidden_dropout_prob, name="pos_dropout") - - if not self.share_att_key: - if "c2p" in self.pos_att_type: - self.pos_key_proj = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="pos_proj", - use_bias=True, - ) - if "p2c" in self.pos_att_type: - self.pos_query_proj = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="pos_q_proj", - ) - self.softmax = TFDebertaV2XSoftmax(axis=-1) - self.dropout = TFDebertaV2StableDropout(config.attention_probs_dropout_prob, name="dropout") - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, attention_heads: int) -> tf.Tensor: - tensor_shape = shape_list(tensor) - # In graph mode mode, we can't reshape with -1 as the final dimension if the first dimension (batch size) is None - shape = tensor_shape[:-1] + [attention_heads, tensor_shape[-1] // attention_heads] - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=shape) - tensor = tf.transpose(tensor, perm=[0, 2, 1, 3]) - x_shape = shape_list(tensor) - tensor = tf.reshape(tensor, shape=[-1, x_shape[-2], x_shape[-1]]) - return tensor - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - query_states: tf.Tensor | None = None, - relative_pos: tf.Tensor | None = None, - rel_embeddings: tf.Tensor | None = None, - output_attentions: bool = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - """ - Call the module - - Args: - hidden_states (`tf.Tensor`): - Input states to the module usually the output from previous layer, it will be the Q,K and V in - *Attention(Q,K,V)* - - attention_mask (`tf.Tensor`): - An attention mask matrix of shape [*B*, *N*, *N*] where *B* is the batch size, *N* is the maximum - sequence length in which element [i,j] = *1* means the *i* th token in the input can attend to the *j* - th token. - - return_att (`bool`, *optional*): - Whether return the attention matrix. - - query_states (`tf.Tensor`, *optional*): - The *Q* state in *Attention(Q,K,V)*. - - relative_pos (`tf.Tensor`): - The relative position encoding between the tokens in the sequence. It's of shape [*B*, *N*, *N*] with - values ranging in [*-max_relative_positions*, *max_relative_positions*]. - - rel_embeddings (`tf.Tensor`): - The embedding of relative distances. It's a tensor of shape [\\(2 \\times - \\text{max_relative_positions}\\), *hidden_size*]. - - - """ - if query_states is None: - query_states = hidden_states - query_layer = self.transpose_for_scores(self.query_proj(query_states), self.num_attention_heads) - key_layer = self.transpose_for_scores(self.key_proj(hidden_states), self.num_attention_heads) - value_layer = self.transpose_for_scores(self.value_proj(hidden_states), self.num_attention_heads) - - rel_att = None - # Take the dot product between "query" and "key" to get the raw attention scores. - scale_factor = 1 - if "c2p" in self.pos_att_type: - scale_factor += 1 - if "p2c" in self.pos_att_type: - scale_factor += 1 - scale = tf.math.sqrt(tf.cast(shape_list(query_layer)[-1] * scale_factor, dtype=self.compute_dtype)) - attention_scores = tf.matmul(query_layer, tf.transpose(key_layer, [0, 2, 1]) / scale) - if self.relative_attention: - rel_embeddings = self.pos_dropout(rel_embeddings) - rel_att = self.disentangled_att_bias(query_layer, key_layer, relative_pos, rel_embeddings, scale_factor) - - if rel_att is not None: - attention_scores = attention_scores + rel_att - attention_scores = tf.reshape( - attention_scores, - (-1, self.num_attention_heads, shape_list(attention_scores)[-2], shape_list(attention_scores)[-1]), - ) - - # bsz x height x length x dimension - attention_probs = self.softmax(attention_scores, attention_mask) - attention_probs = self.dropout(attention_probs, training=training) - context_layer = tf.matmul( - tf.reshape(attention_probs, [-1, shape_list(attention_probs)[-2], shape_list(attention_probs)[-1]]), - value_layer, - ) - context_layer = tf.transpose( - tf.reshape( - context_layer, - [-1, self.num_attention_heads, shape_list(context_layer)[-2], shape_list(context_layer)[-1]], - ), - [0, 2, 1, 3], - ) - # Set the final dimension here explicitly. - # Calling tf.reshape(context_layer, (*context_layer_shape[:-2], -1)) raises an error when executing - # the model in graph mode as context_layer is reshaped to (None, 7, None) and Dense layer in TFDebertaV2SelfOutput - # requires final input dimension to be defined - context_layer_shape = shape_list(context_layer) - new_context_layer_shape = context_layer_shape[:-2] + [context_layer_shape[-2] * context_layer_shape[-1]] - context_layer = tf.reshape(context_layer, new_context_layer_shape) - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - return outputs - - def disentangled_att_bias(self, query_layer, key_layer, relative_pos, rel_embeddings, scale_factor): - if relative_pos is None: - q = shape_list(query_layer)[-2] - relative_pos = build_relative_position( - q, - shape_list(key_layer)[-2], - bucket_size=self.position_buckets, - max_position=self.max_relative_positions, - ) - shape_list_pos = shape_list(relative_pos) - if len(shape_list_pos) == 2: - relative_pos = tf.expand_dims(tf.expand_dims(relative_pos, 0), 0) - elif len(shape_list_pos) == 3: - relative_pos = tf.expand_dims(relative_pos, 1) - # bsz x height x query x key - elif len(shape_list_pos) != 4: - raise ValueError(f"Relative position ids must be of dim 2 or 3 or 4. {len(shape_list_pos)}") - - att_span = self.pos_ebd_size - rel_embeddings = tf.expand_dims( - rel_embeddings[self.pos_ebd_size - att_span : self.pos_ebd_size + att_span, :], 0 - ) - if self.share_att_key: - pos_query_layer = tf.tile( - self.transpose_for_scores(self.query_proj(rel_embeddings), self.num_attention_heads), - [shape_list(query_layer)[0] // self.num_attention_heads, 1, 1], - ) - pos_key_layer = tf.tile( - self.transpose_for_scores(self.key_proj(rel_embeddings), self.num_attention_heads), - [shape_list(query_layer)[0] // self.num_attention_heads, 1, 1], - ) - else: - if "c2p" in self.pos_att_type: - pos_key_layer = tf.tile( - self.transpose_for_scores(self.pos_key_proj(rel_embeddings), self.num_attention_heads), - [shape_list(query_layer)[0] // self.num_attention_heads, 1, 1], - ) # .split(self.all_head_size, dim=-1) - if "p2c" in self.pos_att_type: - pos_query_layer = tf.tile( - self.transpose_for_scores(self.pos_query_proj(rel_embeddings), self.num_attention_heads), - [shape_list(query_layer)[0] // self.num_attention_heads, 1, 1], - ) # .split(self.all_head_size, dim=-1) - - score = 0 - # content->position - if "c2p" in self.pos_att_type: - scale = tf.math.sqrt(tf.cast(shape_list(pos_key_layer)[-1] * scale_factor, dtype=self.compute_dtype)) - c2p_att = tf.matmul(query_layer, tf.transpose(pos_key_layer, [0, 2, 1])) - c2p_pos = tf.clip_by_value(relative_pos + att_span, 0, att_span * 2 - 1) - c2p_att = take_along_axis( - c2p_att, - tf.broadcast_to( - tf.squeeze(c2p_pos, 0), - [shape_list(query_layer)[0], shape_list(query_layer)[1], shape_list(relative_pos)[-1]], - ), - ) - score += c2p_att / scale - - # position->content - if "p2c" in self.pos_att_type: - scale = tf.math.sqrt(tf.cast(shape_list(pos_query_layer)[-1] * scale_factor, dtype=self.compute_dtype)) - if shape_list(key_layer)[-2] != shape_list(query_layer)[-2]: - r_pos = build_relative_position( - shape_list(key_layer)[-2], - shape_list(key_layer)[-2], - bucket_size=self.position_buckets, - max_position=self.max_relative_positions, - ) - r_pos = tf.expand_dims(r_pos, 0) - else: - r_pos = relative_pos - - p2c_pos = tf.clip_by_value(-r_pos + att_span, 0, att_span * 2 - 1) - - p2c_att = tf.matmul(key_layer, tf.transpose(pos_query_layer, [0, 2, 1])) - p2c_att = tf.transpose( - take_along_axis( - p2c_att, - tf.broadcast_to( - tf.squeeze(p2c_pos, 0), - [shape_list(query_layer)[0], shape_list(key_layer)[-2], shape_list(key_layer)[-2]], - ), - ), - [0, 2, 1], - ) - score += p2c_att / scale - - return score - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query_proj", None) is not None: - with tf.name_scope(self.query_proj.name): - self.query_proj.build([None, None, self.config.hidden_size]) - if getattr(self, "key_proj", None) is not None: - with tf.name_scope(self.key_proj.name): - self.key_proj.build([None, None, self.config.hidden_size]) - if getattr(self, "value_proj", None) is not None: - with tf.name_scope(self.value_proj.name): - self.value_proj.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "pos_dropout", None) is not None: - with tf.name_scope(self.pos_dropout.name): - self.pos_dropout.build(None) - if getattr(self, "pos_key_proj", None) is not None: - with tf.name_scope(self.pos_key_proj.name): - self.pos_key_proj.build([None, None, self.config.hidden_size]) - if getattr(self, "pos_query_proj", None) is not None: - with tf.name_scope(self.pos_query_proj.name): - self.pos_query_proj.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaEmbeddings Deberta->DebertaV2 -class TFDebertaV2Embeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = getattr(config, "embedding_size", config.hidden_size) - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.position_biased_input = getattr(config, "position_biased_input", True) - self.initializer_range = config.initializer_range - if self.embedding_size != config.hidden_size: - self.embed_proj = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="embed_proj", - use_bias=False, - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = TFDebertaV2StableDropout(config.hidden_dropout_prob, name="dropout") - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - if self.config.type_vocab_size > 0: - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - else: - self.token_type_embeddings = None - - with tf.name_scope("position_embeddings"): - if self.position_biased_input: - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - else: - self.position_embeddings = None - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "embed_proj", None) is not None: - with tf.name_scope(self.embed_proj.name): - self.embed_proj.build([None, None, self.embedding_size]) - - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - mask: tf.Tensor | None = None, - training: bool = False, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - if input_ids is None and inputs_embeds is None: - raise ValueError("Need to provide either `input_ids` or `input_embeds`.") - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) - - final_embeddings = inputs_embeds - if self.position_biased_input: - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - final_embeddings += position_embeds - if self.config.type_vocab_size > 0: - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings += token_type_embeds - - if self.embedding_size != self.hidden_size: - final_embeddings = self.embed_proj(final_embeddings) - - final_embeddings = self.LayerNorm(final_embeddings) - - if mask is not None: - if len(shape_list(mask)) != len(shape_list(final_embeddings)): - if len(shape_list(mask)) == 4: - mask = tf.squeeze(tf.squeeze(mask, axis=1), axis=1) - mask = tf.cast(tf.expand_dims(mask, axis=2), dtype=self.compute_dtype) - - final_embeddings = final_embeddings * mask - - final_embeddings = self.dropout(final_embeddings, training=training) - - return final_embeddings - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaPredictionHeadTransform with Deberta->DebertaV2 -class TFDebertaV2PredictionHeadTransform(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - - self.embedding_size = getattr(config, "embedding_size", config.hidden_size) - - self.dense = keras.layers.Dense( - units=self.embedding_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - - if isinstance(config.hidden_act, str): - self.transform_act_fn = get_tf_activation(config.hidden_act) - else: - self.transform_act_fn = config.hidden_act - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.transform_act_fn(hidden_states) - hidden_states = self.LayerNorm(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.embedding_size]) - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaLMPredictionHead with Deberta->DebertaV2 -class TFDebertaV2LMPredictionHead(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = getattr(config, "embedding_size", config.hidden_size) - - self.transform = TFDebertaV2PredictionHeadTransform(config, name="transform") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.input_embeddings = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "transform", None) is not None: - with tf.name_scope(self.transform.name): - self.transform.build(None) - - def get_output_embeddings(self) -> keras.layers.Layer: - return self.input_embeddings - - def set_output_embeddings(self, value: tf.Variable): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self) -> dict[str, tf.Variable]: - return {"bias": self.bias} - - def set_bias(self, value: tf.Variable): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.transform(hidden_states=hidden_states) - seq_length = shape_list(hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.embedding_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaOnlyMLMHead with Deberta->DebertaV2 -class TFDebertaV2OnlyMLMHead(keras.layers.Layer): - def __init__(self, config: DebertaV2Config, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - self.predictions = TFDebertaV2LMPredictionHead(config, input_embeddings, name="predictions") - - def call(self, sequence_output: tf.Tensor) -> tf.Tensor: - prediction_scores = self.predictions(hidden_states=sequence_output) - - return prediction_scores - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaMainLayer with Deberta->DebertaV2 -class TFDebertaV2MainLayer(keras.layers.Layer): - config_class = DebertaV2Config - - def __init__(self, config: DebertaV2Config, **kwargs): - super().__init__(**kwargs) - - self.config = config - - self.embeddings = TFDebertaV2Embeddings(config, name="embeddings") - self.encoder = TFDebertaV2Encoder(config, name="encoder") - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - mask=attention_mask, - training=training, - ) - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - - if not return_dict: - return (sequence_output,) + encoder_outputs[1:] - - return TFBaseModelOutput( - last_hidden_state=sequence_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - - -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaPreTrainedModel with Deberta->DebertaV2 -class TFDebertaV2PreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = DebertaV2Config - base_model_prefix = "deberta" - - -DEBERTA_START_DOCSTRING = r""" - The DeBERTa model was proposed in [DeBERTa: Decoding-enhanced BERT with Disentangled - Attention](https://huggingface.co/papers/2006.03654) by Pengcheng He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen. It's build - on top of BERT/RoBERTa with two improvements, i.e. disentangled attention and enhanced mask decoder. With those two - improvements, it out perform BERT/RoBERTa on a majority of tasks with 80GB pretraining data. - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`DebertaV2Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -DEBERTA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert *input_ids* indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput``] instead of a plain tuple. -""" - - -@add_start_docstrings( - "The bare DeBERTa Model transformer outputting raw hidden-states without any specific head on top.", - DEBERTA_START_DOCSTRING, -) -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaModel with Deberta->DebertaV2 -class TFDebertaV2Model(TFDebertaV2PreTrainedModel): - def __init__(self, config: DebertaV2Config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.deberta = TFDebertaV2MainLayer(config, name="deberta") - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - outputs = self.deberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - - -@add_start_docstrings("""DeBERTa Model with a `language modeling` head on top.""", DEBERTA_START_DOCSTRING) -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaForMaskedLM with Deberta->DebertaV2 -class TFDebertaV2ForMaskedLM(TFDebertaV2PreTrainedModel, TFMaskedLanguageModelingLoss): - def __init__(self, config: DebertaV2Config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if config.is_decoder: - logger.warning( - "If you want to use `TFDebertaV2ForMaskedLM` make sure `config.is_decoder=False` for " - "bi-directional self-attention." - ) - - self.deberta = TFDebertaV2MainLayer(config, name="deberta") - self.mlm = TFDebertaV2OnlyMLMHead(config, input_embeddings=self.deberta.embeddings, name="cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.mlm.predictions - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.deberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.mlm(sequence_output=sequence_output, training=training) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - if getattr(self, "mlm", None) is not None: - with tf.name_scope(self.mlm.name): - self.mlm.build(None) - - -@add_start_docstrings( - """ - DeBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - DEBERTA_START_DOCSTRING, -) -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaForSequenceClassification with Deberta->DebertaV2 -class TFDebertaV2ForSequenceClassification(TFDebertaV2PreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: DebertaV2Config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.deberta = TFDebertaV2MainLayer(config, name="deberta") - self.pooler = TFDebertaV2ContextPooler(config, name="pooler") - - drop_out = getattr(config, "cls_dropout", None) - drop_out = self.config.hidden_dropout_prob if drop_out is None else drop_out - self.dropout = TFDebertaV2StableDropout(drop_out, name="cls_dropout") - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - self.output_dim = self.pooler.output_dim - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.deberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - pooled_output = self.pooler(sequence_output, training=training) - pooled_output = self.dropout(pooled_output, training=training) - logits = self.classifier(pooled_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[1:] - - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.output_dim]) - - -@add_start_docstrings( - """ - DeBERTa Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - DEBERTA_START_DOCSTRING, -) -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaForTokenClassification with Deberta->DebertaV2 -class TFDebertaV2ForTokenClassification(TFDebertaV2PreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config: DebertaV2Config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.deberta = TFDebertaV2MainLayer(config, name="deberta") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.deberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(inputs=sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - DeBERTa Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - DEBERTA_START_DOCSTRING, -) -# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaForQuestionAnswering with Deberta->DebertaV2 -class TFDebertaV2ForQuestionAnswering(TFDebertaV2PreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config: DebertaV2Config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.deberta = TFDebertaV2MainLayer(config, name="deberta") - self.qa_outputs = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.deberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.qa_outputs(inputs=sequence_output) - start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) - start_logits = tf.squeeze(input=start_logits, axis=-1) - end_logits = tf.squeeze(input=end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels=labels, logits=(start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - DeBERTa Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - DEBERTA_START_DOCSTRING, -) -class TFDebertaV2ForMultipleChoice(TFDebertaV2PreTrainedModel, TFMultipleChoiceLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - # _keys_to_ignore_on_load_unexpected = [r"mlm___cls", r"nsp___cls", r"cls.predictions", r"cls.seq_relationship"] - # _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config: DebertaV2Config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.deberta = TFDebertaV2MainLayer(config, name="deberta") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.pooler = TFDebertaV2ContextPooler(config, name="pooler") - self.classifier = keras.layers.Dense( - units=1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.output_dim = self.pooler.output_dim - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(tensor=input_ids, shape=(-1, seq_length)) if input_ids is not None else None - flat_attention_mask = ( - tf.reshape(tensor=attention_mask, shape=(-1, seq_length)) if attention_mask is not None else None - ) - flat_token_type_ids = ( - tf.reshape(tensor=token_type_ids, shape=(-1, seq_length)) if token_type_ids is not None else None - ) - flat_position_ids = ( - tf.reshape(tensor=position_ids, shape=(-1, seq_length)) if position_ids is not None else None - ) - flat_inputs_embeds = ( - tf.reshape(tensor=inputs_embeds, shape=(-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - outputs = self.deberta( - input_ids=flat_input_ids, - attention_mask=flat_attention_mask, - token_type_ids=flat_token_type_ids, - position_ids=flat_position_ids, - inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - pooled_output = self.pooler(sequence_output, training=training) - pooled_output = self.dropout(pooled_output, training=training) - logits = self.classifier(pooled_output) - reshaped_logits = tf.reshape(tensor=logits, shape=(-1, num_choices)) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deberta", None) is not None: - with tf.name_scope(self.deberta.name): - self.deberta.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.output_dim]) - - -__all__ = [ - "TFDebertaV2ForMaskedLM", - "TFDebertaV2ForQuestionAnswering", - "TFDebertaV2ForMultipleChoice", - "TFDebertaV2ForSequenceClassification", - "TFDebertaV2ForTokenClassification", - "TFDebertaV2Model", - "TFDebertaV2PreTrainedModel", -] diff --git a/src/transformers/models/decision_transformer/modeling_decision_transformer.py b/src/transformers/models/decision_transformer/modeling_decision_transformer.py index f9c68fcbdeae..a16c9ab71075 100755 --- a/src/transformers/models/decision_transformer/modeling_decision_transformer.py +++ b/src/transformers/models/decision_transformer/modeling_decision_transformer.py @@ -15,7 +15,6 @@ """PyTorch DecisionTransformer model.""" import math -import os from dataclasses import dataclass from typing import Callable, Optional, Union @@ -40,63 +39,6 @@ logger = logging.get_logger(__name__) -# Copied from transformers.models.gpt2.modeling_gpt2.load_tf_weights_in_gpt2 -def load_tf_weights_in_gpt2(model, config, gpt2_checkpoint_path): - """Load tf checkpoints in a pytorch model""" - try: - import re - - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(gpt2_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array.squeeze()) - - for name, array in zip(names, arrays): - name = name[6:] # skip "model/" - name = name.split("/") - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+\d+", m_name): - scope_names = re.split(r"(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "w" or scope_names[0] == "g": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "b": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "wpe" or scope_names[0] == "wte": - pointer = getattr(pointer, scope_names[0]) - pointer = getattr(pointer, "weight") - else: - pointer = getattr(pointer, scope_names[0]) - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except ValueError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - # Copied from transformers.models.gpt2.modeling_gpt2.eager_attention_forward def eager_attention_forward(module, query, key, value, attention_mask, head_mask=None, **kwargs): attn_weights = torch.matmul(query, key.transpose(-1, -2)) @@ -456,7 +398,6 @@ def forward( @auto_docstring class DecisionTransformerGPT2PreTrainedModel(PreTrainedModel): config: DecisionTransformerConfig - load_tf_weights = load_tf_weights_in_gpt2 base_model_prefix = "transformer" is_parallelizable = True supports_gradient_checkpointing = True @@ -469,8 +410,6 @@ def __init__(self, *inputs, **kwargs): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, (nn.Linear, Conv1D)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -741,8 +680,6 @@ class DecisionTransformerPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/deepseek_vl/image_processing_deepseek_vl.py b/src/transformers/models/deepseek_vl/image_processing_deepseek_vl.py index 7ab4e98012ac..9d3d9a408a00 100644 --- a/src/transformers/models/deepseek_vl/image_processing_deepseek_vl.py +++ b/src/transformers/models/deepseek_vl/image_processing_deepseek_vl.py @@ -250,10 +250,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -283,10 +281,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/deepseek_vl/modular_deepseek_vl.py b/src/transformers/models/deepseek_vl/modular_deepseek_vl.py index 5bfc0ae7d74c..ce2f9be16ae6 100644 --- a/src/transformers/models/deepseek_vl/modular_deepseek_vl.py +++ b/src/transformers/models/deepseek_vl/modular_deepseek_vl.py @@ -261,10 +261,8 @@ def __call__( tensor. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/deepseek_vl/processing_deepseek_vl.py b/src/transformers/models/deepseek_vl/processing_deepseek_vl.py index 26d59d85a295..ddeb4f799ee1 100644 --- a/src/transformers/models/deepseek_vl/processing_deepseek_vl.py +++ b/src/transformers/models/deepseek_vl/processing_deepseek_vl.py @@ -92,10 +92,8 @@ def __call__( tensor. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid.py b/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid.py index 7c7d6df82424..d3d5a7e3e542 100644 --- a/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid.py +++ b/src/transformers/models/deepseek_vl_hybrid/image_processing_deepseek_vl_hybrid.py @@ -288,10 +288,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -333,10 +331,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py b/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py index d97b00f7fbd2..e9808b02ce34 100644 --- a/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py +++ b/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py @@ -600,10 +600,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -645,10 +643,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, @@ -959,10 +954,8 @@ def __call__( tensor. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/deepseek_vl_hybrid/processing_deepseek_vl_hybrid.py b/src/transformers/models/deepseek_vl_hybrid/processing_deepseek_vl_hybrid.py index 538fea5a6b32..d20fa495f9b8 100644 --- a/src/transformers/models/deepseek_vl_hybrid/processing_deepseek_vl_hybrid.py +++ b/src/transformers/models/deepseek_vl_hybrid/processing_deepseek_vl_hybrid.py @@ -92,10 +92,8 @@ def __call__( tensor. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/deformable_detr/image_processing_deformable_detr.py b/src/transformers/models/deformable_detr/image_processing_deformable_detr.py index c6875eb9b8f8..ef028eda1ed1 100644 --- a/src/transformers/models/deformable_detr/image_processing_deformable_detr.py +++ b/src/transformers/models/deformable_detr/image_processing_deformable_detr.py @@ -18,7 +18,7 @@ import pathlib from collections import defaultdict from collections.abc import Iterable -from typing import Any, Callable, Optional, Union +from typing import Any, Optional, Union import numpy as np @@ -55,11 +55,7 @@ ) from ...utils import ( TensorType, - is_flax_available, - is_jax_tensor, is_scipy_available, - is_tf_available, - is_tf_tensor, is_torch_available, is_torch_tensor, is_vision_available, @@ -191,31 +187,6 @@ def get_image_size_for_max_height_width( return new_height, new_width -# Copied from transformers.models.detr.image_processing_detr.get_numpy_to_framework_fn -def get_numpy_to_framework_fn(arr) -> Callable: - """ - Returns a function that converts a numpy array to the framework of the input array. - - Args: - arr (`np.ndarray`): The array to convert. - """ - if isinstance(arr, np.ndarray): - return np.array - if is_tf_available() and is_tf_tensor(arr): - import tensorflow as tf - - return tf.convert_to_tensor - if is_torch_available() and is_torch_tensor(arr): - import torch - - return torch.tensor - if is_flax_available() and is_jax_tensor(arr): - import jax.numpy as jnp - - return jnp.array - raise ValueError(f"Cannot convert arrays of type {type(arr)}") - - # Copied from transformers.models.detr.image_processing_detr.safe_squeeze def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: """ @@ -1203,10 +1174,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -1391,10 +1360,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor.") validate_kwargs(captured_kwargs=kwargs.keys(), valid_processor_keys=self._valid_processor_keys) # Here, the pad() method pads to the maximum of (width, height). It does not need to be validated. @@ -1525,11 +1491,10 @@ def preprocess( return encoded_inputs - # POSTPROCESSING METHODS - TODO: add support for other frameworks def post_process(self, outputs, target_sizes): """ Converts the raw output of [`DeformableDetrForObjectDetection`] into final bounding boxes in (top_left_x, - top_left_y, bottom_right_x, bottom_right_y) format. Only supports PyTorch. + top_left_y, bottom_right_x, bottom_right_y) format. Args: outputs ([`DeformableDetrObjectDetectionOutput`]): diff --git a/src/transformers/models/deformable_detr/modeling_deformable_detr.py b/src/transformers/models/deformable_detr/modeling_deformable_detr.py index 34f5bce7a5c4..657e78be87ef 100755 --- a/src/transformers/models/deformable_detr/modeling_deformable_detr.py +++ b/src/transformers/models/deformable_detr/modeling_deformable_detr.py @@ -959,8 +959,6 @@ def _init_weights(self, module): nn.init.xavier_uniform_(module.output_proj.weight.data) nn.init.constant_(module.output_proj.bias.data, 0.0) elif isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/deit/__init__.py b/src/transformers/models/deit/__init__.py index 98236a86d7a1..ef3e5149fe55 100644 --- a/src/transformers/models/deit/__init__.py +++ b/src/transformers/models/deit/__init__.py @@ -23,7 +23,6 @@ from .image_processing_deit import * from .image_processing_deit_fast import * from .modeling_deit import * - from .modeling_tf_deit import * else: import sys diff --git a/src/transformers/models/deit/configuration_deit.py b/src/transformers/models/deit/configuration_deit.py index 7a321ebe293e..8909fe5aff66 100644 --- a/src/transformers/models/deit/configuration_deit.py +++ b/src/transformers/models/deit/configuration_deit.py @@ -72,9 +72,7 @@ class DeiTConfig(PretrainedConfig): pooler_output_size (`int`, *optional*): Dimensionality of the pooler layer. If None, defaults to `hidden_size`. pooler_act (`str`, *optional*, defaults to `"tanh"`): - The activation function to be used by the pooler. Keys of ACT2FN are supported for Flax and - Pytorch, and elements of https://www.tensorflow.org/api_docs/python/tf/keras/activations are - supported for Tensorflow. + The activation function to be used by the pooler. Example: diff --git a/src/transformers/models/deit/image_processing_deit.py b/src/transformers/models/deit/image_processing_deit.py index 1e2f6c3b5ae5..795c872c62e5 100644 --- a/src/transformers/models/deit/image_processing_deit.py +++ b/src/transformers/models/deit/image_processing_deit.py @@ -211,10 +211,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - `None`: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -243,10 +241,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/deit/modeling_tf_deit.py b/src/transformers/models/deit/modeling_tf_deit.py deleted file mode 100644 index 3c56eee87911..000000000000 --- a/src/transformers/models/deit/modeling_tf_deit.py +++ /dev/null @@ -1,1232 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Facebook AI Research (FAIR) and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow DeiT model.""" - -from __future__ import annotations - -import collections.abc -import math -from dataclasses import dataclass - -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPooling, - TFImageClassifierOutput, - TFMaskedImageModelingOutput, -) -from ...modeling_tf_utils import ( - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_deit import DeiTConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "DeiTConfig" - -# Base docstring -_CHECKPOINT_FOR_DOC = "facebook/deit-base-distilled-patch16-224" -_EXPECTED_OUTPUT_SHAPE = [1, 198, 768] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "facebook/deit-base-distilled-patch16-224" -_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" - - -@dataclass -class TFDeiTForImageClassificationWithTeacherOutput(ModelOutput): - """ - Output type of [`DeiTForImageClassificationWithTeacher`]. - - Args: - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Prediction scores as the average of the cls_logits and distillation logits. - cls_logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Prediction scores of the classification head (i.e. the linear layer on top of the final hidden state of the - class token). - distillation_logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Prediction scores of the distillation head (i.e. the linear layer on top of the final hidden state of the - distillation token). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus - the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - """ - - logits: tf.Tensor | None = None - cls_logits: tf.Tensor | None = None - distillation_logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -class TFDeiTEmbeddings(keras.layers.Layer): - """ - Construct the CLS token, distillation token, position and patch embeddings. Optionally, also the mask token. - """ - - def __init__(self, config: DeiTConfig, use_mask_token: bool = False, **kwargs) -> None: - super().__init__(**kwargs) - self.config = config - self.use_mask_token = use_mask_token - self.patch_embeddings = TFDeiTPatchEmbeddings(config=config, name="patch_embeddings") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob, name="dropout") - - def build(self, input_shape=None): - self.cls_token = self.add_weight( - shape=(1, 1, self.config.hidden_size), - initializer=keras.initializers.zeros(), - trainable=True, - name="cls_token", - ) - self.distillation_token = self.add_weight( - shape=(1, 1, self.config.hidden_size), - initializer=keras.initializers.zeros(), - trainable=True, - name="distillation_token", - ) - self.mask_token = None - if self.use_mask_token: - self.mask_token = self.add_weight( - shape=(1, 1, self.config.hidden_size), - initializer=keras.initializers.zeros(), - trainable=True, - name="mask_token", - ) - num_patches = self.patch_embeddings.num_patches - self.position_embeddings = self.add_weight( - shape=(1, num_patches + 2, self.config.hidden_size), - initializer=keras.initializers.zeros(), - trainable=True, - name="position_embeddings", - ) - - if self.built: - return - self.built = True - if getattr(self, "patch_embeddings", None) is not None: - with tf.name_scope(self.patch_embeddings.name): - self.patch_embeddings.build(None) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - def interpolate_pos_encoding(self, embeddings: tf.Tensor, height: int, width: int) -> tf.Tensor: - num_patches = embeddings.shape[1] - 2 - num_positions = self.position_embeddings.shape[1] - 2 - - if num_patches == num_positions and height == width: - return self.position_embeddings - - class_pos_embed = self.position_embeddings[:, 0, :] - dist_pos_embed = self.position_embeddings[:, 1, :] - patch_pos_embed = self.position_embeddings[:, 2:, :] - dim = embeddings.shape[-1] - h0 = height // self.config.patch_size - w0 = width // self.config.patch_size - # # we add a small number to avoid floating point error in the interpolation - # # see discussion at https://github.com/facebookresearch/dino/issues/8 - h0, w0 = h0 + 0.1, w0 + 0.1 - patch_pos_embed = tf.reshape( - patch_pos_embed, (1, int(math.sqrt(num_positions)), int(math.sqrt(num_positions)), dim) - ) - patch_pos_embed = tf.image.resize(patch_pos_embed, size=(int(h0), int(w0)), method="bicubic") - patch_pos_embed = tf.transpose(patch_pos_embed, perm=[0, 2, 3, 1]) - patch_pos_embed = tf.reshape(patch_pos_embed, (1, -1, dim)) - - return tf.concat( - [tf.expand_dims(class_pos_embed, axis=0), tf.expand_dims(dist_pos_embed, axis=0), patch_pos_embed], axis=1 - ) - - def call( - self, - pixel_values: tf.Tensor, - bool_masked_pos: tf.Tensor | None = None, - training: bool = False, - interpolate_pos_encoding: bool = False, - ) -> tf.Tensor: - _, height, width, _ = pixel_values.shape - - embeddings = self.patch_embeddings(pixel_values) - batch_size, seq_length, _ = shape_list(embeddings) - - if bool_masked_pos is not None: - mask_tokens = tf.tile(self.mask_token, [batch_size, seq_length, 1]) - # replace the masked visual tokens by mask_tokens - mask = tf.expand_dims(bool_masked_pos, axis=-1) - mask = tf.cast(mask, dtype=mask_tokens.dtype) - embeddings = embeddings * (1.0 - mask) + mask_tokens * mask - - cls_tokens = tf.repeat(self.cls_token, repeats=batch_size, axis=0) - distillation_tokens = tf.repeat(self.distillation_token, repeats=batch_size, axis=0) - embeddings = tf.concat((cls_tokens, distillation_tokens, embeddings), axis=1) - position_embedding = self.position_embeddings - if interpolate_pos_encoding: - position_embedding = self.interpolate_pos_encoding(embeddings, height, width) - - embeddings = embeddings + position_embedding - embeddings = self.dropout(embeddings, training=training) - return embeddings - - -class TFDeiTPatchEmbeddings(keras.layers.Layer): - """ - This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial - `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a - Transformer. - """ - - def __init__(self, config: DeiTConfig, **kwargs) -> None: - super().__init__(**kwargs) - image_size, patch_size = config.image_size, config.patch_size - num_channels, hidden_size = config.num_channels, config.hidden_size - - image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) - patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) - num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) - self.image_size = image_size - self.patch_size = patch_size - self.num_channels = num_channels - self.num_patches = num_patches - - self.projection = keras.layers.Conv2D( - hidden_size, kernel_size=patch_size, strides=patch_size, name="projection" - ) - - def call(self, pixel_values: tf.Tensor) -> tf.Tensor: - batch_size, height, width, num_channels = shape_list(pixel_values) - if tf.executing_eagerly() and num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - - x = self.projection(pixel_values) - batch_size, height, width, num_channels = shape_list(x) - x = tf.reshape(x, (batch_size, height * width, num_channels)) - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, None, self.num_channels]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTSelfAttention with ViT->DeiT -class TFDeiTSelfAttention(keras.layers.Layer): - def __init__(self, config: DeiTConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - mixed_key_layer = self.key(inputs=hidden_states) - mixed_value_layer = self.value(inputs=hidden_states) - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTSelfOutput with ViT->DeiT -class TFDeiTSelfOutput(keras.layers.Layer): - """ - The residual connection is defined in TFDeiTLayer instead of here (as is the case with other models), due to the - layernorm applied before each block. - """ - - def __init__(self, config: DeiTConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTAttention with ViT->DeiT -class TFDeiTAttention(keras.layers.Layer): - def __init__(self, config: DeiTConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFDeiTSelfAttention(config, name="attention") - self.dense_output = TFDeiTSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, head_mask=head_mask, output_attentions=output_attentions, training=training - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTIntermediate with ViT->DeiT -class TFDeiTIntermediate(keras.layers.Layer): - def __init__(self, config: DeiTConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTOutput with ViT->DeiT -class TFDeiTOutput(keras.layers.Layer): - def __init__(self, config: DeiTConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = hidden_states + input_tensor - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - - -class TFDeiTLayer(keras.layers.Layer): - """This corresponds to the Block class in the timm implementation.""" - - def __init__(self, config: DeiTConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFDeiTAttention(config, name="attention") - self.intermediate = TFDeiTIntermediate(config, name="intermediate") - self.deit_output = TFDeiTOutput(config, name="output") - - self.layernorm_before = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_before") - self.layernorm_after = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_after") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - attention_outputs = self.attention( - # in DeiT, layernorm is applied before self-attention - input_tensor=self.layernorm_before(inputs=hidden_states, training=training), - head_mask=head_mask, - output_attentions=output_attentions, - training=training, - ) - attention_output = attention_outputs[0] - - # first residual connection - hidden_states = attention_output + hidden_states - - # in DeiT, layernorm is also applied after self-attention - layer_output = self.layernorm_after(inputs=hidden_states, training=training) - - intermediate_output = self.intermediate(hidden_states=layer_output, training=training) - - # second residual connection is done here - layer_output = self.deit_output( - hidden_states=intermediate_output, input_tensor=hidden_states, training=training - ) - outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "deit_output", None) is not None: - with tf.name_scope(self.deit_output.name): - self.deit_output.build(None) - if getattr(self, "layernorm_before", None) is not None: - with tf.name_scope(self.layernorm_before.name): - self.layernorm_before.build([None, None, self.config.hidden_size]) - if getattr(self, "layernorm_after", None) is not None: - with tf.name_scope(self.layernorm_after.name): - self.layernorm_after.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTEncoder with ViT->DeiT -class TFDeiTEncoder(keras.layers.Layer): - def __init__(self, config: DeiTConfig, **kwargs): - super().__init__(**kwargs) - - self.layer = [TFDeiTLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states=hidden_states, - head_mask=head_mask[i], - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFDeiTMainLayer(keras.layers.Layer): - config_class = DeiTConfig - - def __init__( - self, config: DeiTConfig, add_pooling_layer: bool = True, use_mask_token: bool = False, **kwargs - ) -> None: - super().__init__(**kwargs) - self.config = config - - self.embeddings = TFDeiTEmbeddings(config, use_mask_token=use_mask_token, name="embeddings") - self.encoder = TFDeiTEncoder(config, name="encoder") - - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - self.pooler = TFDeiTPooler(config, name="pooler") if add_pooling_layer else None - - def get_input_embeddings(self) -> TFDeiTPatchEmbeddings: - return self.embeddings.patch_embeddings - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - def get_head_mask(self, head_mask): - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - return head_mask - - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor | None = None, - bool_masked_pos: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - interpolate_pos_encoding: bool = False, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor, ...]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - # TF 2.0 image layers can't use NCHW format when running on CPU. - # (batch_size, num_channels, height, width) -> (batch_size, height, width, num_channels) - pixel_values = tf.transpose(pixel_values, (0, 2, 3, 1)) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - head_mask = self.get_head_mask(head_mask) - - embedding_output = self.embeddings( - pixel_values, - bool_masked_pos=bool_masked_pos, - training=training, - interpolate_pos_encoding=interpolate_pos_encoding, - ) - - encoder_outputs = self.encoder( - embedding_output, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = encoder_outputs[0] - sequence_output = self.layernorm(sequence_output, training=training) - pooled_output = self.pooler(sequence_output, training=training) if self.pooler is not None else None - - if not return_dict: - head_outputs = (sequence_output, pooled_output) if pooled_output is not None else (sequence_output,) - return head_outputs + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, self.config.hidden_size]) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTPreTrainedModel with ViT->DeiT all-casing -class TFDeiTPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = DeiTConfig - base_model_prefix = "deit" - main_input_name = "pixel_values" - - -DEIT_START_DOCSTRING = r""" - This model is a TensorFlow - [keras.layers.Layer](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer). Use it as a regular - TensorFlow Module and refer to the TensorFlow documentation for all matter related to general usage and behavior. - - Parameters: - config ([`DeiTConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -DEIT_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`DeiTImageProcessor.__call__`] for details. - - head_mask (`tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - interpolate_pos_encoding (`bool`, *optional*, defaults to `False`): - Whether to interpolate the pre-trained position encodings. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@add_start_docstrings( - "The bare DeiT Model transformer outputting raw hidden-states without any specific head on top.", - DEIT_START_DOCSTRING, -) -class TFDeiTModel(TFDeiTPreTrainedModel): - def __init__( - self, config: DeiTConfig, add_pooling_layer: bool = True, use_mask_token: bool = False, **kwargs - ) -> None: - super().__init__(config, **kwargs) - - self.deit = TFDeiTMainLayer( - config, add_pooling_layer=add_pooling_layer, use_mask_token=use_mask_token, name="deit" - ) - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPooling, - config_class=_CONFIG_FOR_DOC, - modality="vision", - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - def call( - self, - pixel_values: tf.Tensor | None = None, - bool_masked_pos: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - interpolate_pos_encoding: bool = False, - training: bool = False, - ) -> tuple | TFBaseModelOutputWithPooling: - outputs = self.deit( - pixel_values=pixel_values, - bool_masked_pos=bool_masked_pos, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - interpolate_pos_encoding=interpolate_pos_encoding, - training=training, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deit", None) is not None: - with tf.name_scope(self.deit.name): - self.deit.build(None) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTPooler with ViT->DeiT -class TFDeiTPooler(keras.layers.Layer): - def __init__(self, config: DeiTConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.pooler_output_size, - kernel_initializer=get_initializer(config.initializer_range), - activation=config.pooler_act, - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFDeitPixelShuffle(keras.layers.Layer): - """TF layer implementation of torch.nn.PixelShuffle""" - - def __init__(self, upscale_factor: int, **kwargs) -> None: - super().__init__(**kwargs) - if not isinstance(upscale_factor, int) or upscale_factor < 2: - raise ValueError(f"upscale_factor must be an integer value >= 2 got {upscale_factor}") - self.upscale_factor = upscale_factor - - def call(self, x: tf.Tensor) -> tf.Tensor: - hidden_states = x - batch_size, _, _, num_input_channels = shape_list(hidden_states) - block_size_squared = self.upscale_factor**2 - output_depth = int(num_input_channels / block_size_squared) - # When the number of output channels >= 2, PyTorch's PixelShuffle and - # TF's depth_to_space differ in their output as the order of channels selected for combining - # is a permutation of the other c.f. - # https://stackoverflow.com/questions/68272502/tf-depth-to-space-not-same-as-torchs-pixelshuffle-when-output-channels-1 - permutation = tf.constant( - [[i + j * block_size_squared for i in range(block_size_squared) for j in range(output_depth)]] - ) - hidden_states = tf.gather(params=hidden_states, indices=tf.tile(permutation, [batch_size, 1]), batch_dims=-1) - hidden_states = tf.nn.depth_to_space(hidden_states, block_size=self.upscale_factor, data_format="NHWC") - return hidden_states - - -class TFDeitDecoder(keras.layers.Layer): - def __init__(self, config: DeiTConfig, **kwargs) -> None: - super().__init__(**kwargs) - self.conv2d = keras.layers.Conv2D( - filters=config.encoder_stride**2 * config.num_channels, kernel_size=1, name="0" - ) - self.pixel_shuffle = TFDeitPixelShuffle(config.encoder_stride, name="1") - self.config = config - - def call(self, inputs: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = inputs - hidden_states = self.conv2d(hidden_states) - hidden_states = self.pixel_shuffle(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv2d", None) is not None: - with tf.name_scope(self.conv2d.name): - self.conv2d.build([None, None, None, self.config.hidden_size]) - if getattr(self, "pixel_shuffle", None) is not None: - with tf.name_scope(self.pixel_shuffle.name): - self.pixel_shuffle.build(None) - - -@add_start_docstrings( - "DeiT Model with a decoder on top for masked image modeling, as proposed in" - " [SimMIM](https://huggingface.co/papers/2111.09886).", - DEIT_START_DOCSTRING, -) -class TFDeiTForMaskedImageModeling(TFDeiTPreTrainedModel): - def __init__(self, config: DeiTConfig) -> None: - super().__init__(config) - - self.deit = TFDeiTMainLayer(config, add_pooling_layer=False, use_mask_token=True, name="deit") - self.decoder = TFDeitDecoder(config, name="decoder") - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFMaskedImageModelingOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: tf.Tensor | None = None, - bool_masked_pos: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - interpolate_pos_encoding: bool = False, - training: bool = False, - ) -> tuple | TFMaskedImageModelingOutput: - r""" - bool_masked_pos (`tf.Tensor` of type bool and shape `(batch_size, num_patches)`): - Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). - - Returns: - - Examples: - ```python - >>> from transformers import AutoImageProcessor, TFDeiTForMaskedImageModeling - >>> import tensorflow as tf - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/deit-base-distilled-patch16-224") - >>> model = TFDeiTForMaskedImageModeling.from_pretrained("facebook/deit-base-distilled-patch16-224") - - >>> num_patches = (model.config.image_size // model.config.patch_size) ** 2 - >>> pixel_values = image_processor(images=image, return_tensors="tf").pixel_values - >>> # create random boolean mask of shape (batch_size, num_patches) - >>> bool_masked_pos = tf.cast(tf.random.uniform((1, num_patches), minval=0, maxval=2, dtype=tf.int32), tf.bool) - - >>> outputs = model(pixel_values, bool_masked_pos=bool_masked_pos) - >>> loss, reconstructed_pixel_values = outputs.loss, outputs.reconstruction - >>> list(reconstructed_pixel_values.shape) - [1, 3, 224, 224] - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.deit( - pixel_values, - bool_masked_pos=bool_masked_pos, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - interpolate_pos_encoding=interpolate_pos_encoding, - training=training, - ) - - sequence_output = outputs[0] - - # Reshape to (batch_size, num_channels, height, width) - sequence_output = sequence_output[:, 1:-1] - batch_size, sequence_length, num_channels = shape_list(sequence_output) - height = width = int(sequence_length**0.5) - sequence_output = tf.reshape(sequence_output, (batch_size, height, width, num_channels)) - - # Reconstruct pixel values - reconstructed_pixel_values = self.decoder(sequence_output, training=training) - # TF 2.0 image layers can't use NCHW format when running on CPU, so intermediate layers use NHWC, - # including the decoder. We transpose to compute the loss against the pixel values - # (batch_size, height, width, num_channels) -> (batch_size, num_channels, height, width) - reconstructed_pixel_values = tf.transpose(reconstructed_pixel_values, (0, 3, 1, 2)) - - masked_im_loss = None - if bool_masked_pos is not None: - size = self.config.image_size // self.config.patch_size - bool_masked_pos = tf.reshape(bool_masked_pos, (-1, size, size)) - mask = tf.repeat(bool_masked_pos, self.config.patch_size, 1) - mask = tf.repeat(mask, self.config.patch_size, 2) - mask = tf.expand_dims(mask, 1) - mask = tf.cast(mask, tf.float32) - - reconstruction_loss = keras.losses.mean_absolute_error( - # Swap axes as metric calculation reduces over the final dimension - tf.transpose(pixel_values, (1, 2, 3, 0)), - tf.transpose(reconstructed_pixel_values, (1, 2, 3, 0)), - ) - reconstruction_loss = tf.expand_dims(reconstruction_loss, 0) - total_loss = tf.reduce_sum(reconstruction_loss * mask) - num_masked_pixels = (tf.reduce_sum(mask) + 1e-5) * self.config.num_channels - masked_im_loss = total_loss / num_masked_pixels - masked_im_loss = tf.reshape(masked_im_loss, (1,)) - - if not return_dict: - output = (reconstructed_pixel_values,) + outputs[1:] - return ((masked_im_loss,) + output) if masked_im_loss is not None else output - - return TFMaskedImageModelingOutput( - loss=masked_im_loss, - reconstruction=reconstructed_pixel_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deit", None) is not None: - with tf.name_scope(self.deit.name): - self.deit.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - """ - DeiT Model transformer with an image classification head on top (a linear layer on top of the final hidden state of - the [CLS] token) e.g. for ImageNet. - """, - DEIT_START_DOCSTRING, -) -class TFDeiTForImageClassification(TFDeiTPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: DeiTConfig): - super().__init__(config) - - self.num_labels = config.num_labels - self.deit = TFDeiTMainLayer(config, add_pooling_layer=False, name="deit") - - # Classifier head - self.classifier = ( - keras.layers.Dense(config.num_labels, name="classifier") - if config.num_labels > 0 - else keras.layers.Activation("linear", name="classifier") - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFImageClassifierOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - labels: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - interpolate_pos_encoding: bool = False, - training: bool = False, - ) -> tf.Tensor | TFImageClassifierOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, TFDeiTForImageClassification - >>> import tensorflow as tf - >>> from PIL import Image - >>> import requests - - >>> keras.utils.set_random_seed(3) # doctest: +IGNORE_RESULT - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> # note: we are loading a TFDeiTForImageClassificationWithTeacher from the hub here, - >>> # so the head will be randomly initialized, hence the predictions will be random - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/deit-base-distilled-patch16-224") - >>> model = TFDeiTForImageClassification.from_pretrained("facebook/deit-base-distilled-patch16-224") - - >>> inputs = image_processor(images=image, return_tensors="tf") - >>> outputs = model(**inputs) - >>> logits = outputs.logits - >>> # model predicts one of the 1000 ImageNet classes - >>> predicted_class_idx = tf.math.argmax(logits, axis=-1)[0] - >>> print("Predicted class:", model.config.id2label[int(predicted_class_idx)]) - Predicted class: little blue heron, Egretta caerulea - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.deit( - pixel_values, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - interpolate_pos_encoding=interpolate_pos_encoding, - training=training, - ) - - sequence_output = outputs[0] - - logits = self.classifier(sequence_output[:, 0, :]) - # we don't use the distillation token - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFImageClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deit", None) is not None: - with tf.name_scope(self.deit.name): - self.deit.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - DeiT Model transformer with image classification heads on top (a linear layer on top of the final hidden state of - the [CLS] token and a linear layer on top of the final hidden state of the distillation token) e.g. for ImageNet. - - .. warning:: - - This model supports inference-only. Fine-tuning with distillation (i.e. with a teacher) is not yet - supported. - """, - DEIT_START_DOCSTRING, -) -class TFDeiTForImageClassificationWithTeacher(TFDeiTPreTrainedModel): - def __init__(self, config: DeiTConfig) -> None: - super().__init__(config) - - self.num_labels = config.num_labels - self.deit = TFDeiTMainLayer(config, add_pooling_layer=False, name="deit") - - # Classifier heads - self.cls_classifier = ( - keras.layers.Dense(config.num_labels, name="cls_classifier") - if config.num_labels > 0 - else keras.layers.Activation("linear", name="cls_classifier") - ) - self.distillation_classifier = ( - keras.layers.Dense(config.num_labels, name="distillation_classifier") - if config.num_labels > 0 - else keras.layers.Activation("linear", name="distillation_classifier") - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFDeiTForImageClassificationWithTeacherOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - def call( - self, - pixel_values: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - interpolate_pos_encoding: bool = False, - training: bool = False, - ) -> tuple | TFDeiTForImageClassificationWithTeacherOutput: - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.deit( - pixel_values, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - interpolate_pos_encoding=interpolate_pos_encoding, - training=training, - ) - - sequence_output = outputs[0] - - cls_logits = self.cls_classifier(sequence_output[:, 0, :]) - distillation_logits = self.distillation_classifier(sequence_output[:, 1, :]) - - # during inference, return the average of both classifier predictions - logits = (cls_logits + distillation_logits) / 2 - - if not return_dict: - output = (logits, cls_logits, distillation_logits) + outputs[1:] - return output - - return TFDeiTForImageClassificationWithTeacherOutput( - logits=logits, - cls_logits=cls_logits, - distillation_logits=distillation_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "deit", None) is not None: - with tf.name_scope(self.deit.name): - self.deit.build(None) - if getattr(self, "cls_classifier", None) is not None: - with tf.name_scope(self.cls_classifier.name): - self.cls_classifier.build([None, None, self.config.hidden_size]) - if getattr(self, "distillation_classifier", None) is not None: - with tf.name_scope(self.distillation_classifier.name): - self.distillation_classifier.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFDeiTForImageClassification", - "TFDeiTForImageClassificationWithTeacher", - "TFDeiTForMaskedImageModeling", - "TFDeiTModel", - "TFDeiTPreTrainedModel", -] diff --git a/src/transformers/models/deprecated/deta/image_processing_deta.py b/src/transformers/models/deprecated/deta/image_processing_deta.py index 434d25a1ab51..b54e07d240ea 100644 --- a/src/transformers/models/deprecated/deta/image_processing_deta.py +++ b/src/transformers/models/deprecated/deta/image_processing_deta.py @@ -16,7 +16,7 @@ import pathlib from collections.abc import Iterable -from typing import Any, Callable, Optional, Union +from typing import Any, Optional, Union import numpy as np @@ -50,12 +50,7 @@ validate_preprocess_arguments, ) from ....utils import ( - is_flax_available, - is_jax_tensor, - is_tf_available, - is_tf_tensor, is_torch_available, - is_torch_tensor, is_torchvision_available, is_vision_available, logging, @@ -181,30 +176,6 @@ def get_image_size_for_max_height_width( return new_height, new_width -def get_numpy_to_framework_fn(arr) -> Callable: - """ - Returns a function that converts a numpy array to the framework of the input array. - - Args: - arr (`np.ndarray`): The array to convert. - """ - if isinstance(arr, np.ndarray): - return np.array - if is_tf_available() and is_tf_tensor(arr): - import tensorflow as tf - - return tf.convert_to_tensor - if is_torch_available() and is_torch_tensor(arr): - import torch - - return torch.tensor - if is_flax_available() and is_jax_tensor(arr): - import jax.numpy as jnp - - return jnp.array - raise ValueError(f"Cannot convert arrays of type {type(arr)}") - - def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: """ Squeezes an array, but only if the axis specified has dim 1. @@ -829,10 +800,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -1024,10 +993,7 @@ def preprocess( annotations = [annotations] if annotations is not None else None if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor.") if annotations is not None and len(images) != len(annotations): raise ValueError( f"The number of images ({len(images)}) and annotations ({len(annotations)}) do not match." diff --git a/src/transformers/models/deprecated/deta/modeling_deta.py b/src/transformers/models/deprecated/deta/modeling_deta.py index c4f6f5c65ded..1e233608e3e4 100644 --- a/src/transformers/models/deprecated/deta/modeling_deta.py +++ b/src/transformers/models/deprecated/deta/modeling_deta.py @@ -1041,8 +1041,6 @@ def _init_weights(self, module): elif isinstance(module, DetaMultiscaleDeformableAttention): module._reset_parameters() elif isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/deprecated/efficientformer/__init__.py b/src/transformers/models/deprecated/efficientformer/__init__.py index db3d0a634051..e43cb0e61df1 100644 --- a/src/transformers/models/deprecated/efficientformer/__init__.py +++ b/src/transformers/models/deprecated/efficientformer/__init__.py @@ -21,7 +21,6 @@ from .configuration_efficientformer import * from .image_processing_efficientformer import * from .modeling_efficientformer import * - from .modeling_tf_efficientformer import * else: import sys diff --git a/src/transformers/models/deprecated/efficientformer/image_processing_efficientformer.py b/src/transformers/models/deprecated/efficientformer/image_processing_efficientformer.py index a2dd1281e920..a8dcedea620a 100644 --- a/src/transformers/models/deprecated/efficientformer/image_processing_efficientformer.py +++ b/src/transformers/models/deprecated/efficientformer/image_processing_efficientformer.py @@ -225,10 +225,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -261,10 +259,7 @@ def preprocess( images = [images] if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py b/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py index d35d3e82c007..2167df912d87 100644 --- a/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py +++ b/src/transformers/models/deprecated/efficientformer/modeling_efficientformer.py @@ -241,11 +241,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/deprecated/efficientformer/modeling_tf_efficientformer.py b/src/transformers/models/deprecated/efficientformer/modeling_tf_efficientformer.py deleted file mode 100644 index 643097e79c3e..000000000000 --- a/src/transformers/models/deprecated/efficientformer/modeling_tf_efficientformer.py +++ /dev/null @@ -1,1198 +0,0 @@ -# coding=utf-8 -# Copyright 2023 Snapchat Research and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow EfficientFormer model.""" - -import itertools -from dataclasses import dataclass -from typing import Optional, Union - -import tensorflow as tf - -from ....activations_tf import ACT2FN -from ....modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPooling, - TFImageClassifierOutput, -) -from ....modeling_tf_utils import ( - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ....tf_utils import shape_list, stable_softmax -from ....utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_efficientformer import EfficientFormerConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "EfficientFormerConfig" - -# Base docstring -_CHECKPOINT_FOR_DOC = "snap-research/efficientformer-l1-300" -_EXPECTED_OUTPUT_SHAPE = [1, 49, 448] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "snap-research/efficientformer-l1-300" -_IMAGE_CLASS_EXPECTED_OUTPUT = "LABEL_281" - - -class TFEfficientFormerPatchEmbeddings(keras.layers.Layer): - """ - This class performs downsampling between two stages. For the input tensor with the shape [batch_size, num_channels, - height, width] it produces output tensor with the shape [batch_size, num_channels, height/stride, width/stride] - """ - - def __init__( - self, config: EfficientFormerConfig, num_channels: int, embed_dim: int, apply_norm: bool = True, **kwargs - ) -> None: - super().__init__(**kwargs) - self.num_channels = num_channels - - self.padding = keras.layers.ZeroPadding2D(padding=config.downsample_pad) - self.projection = keras.layers.Conv2D( - filters=embed_dim, - kernel_size=config.downsample_patch_size, - strides=config.downsample_stride, - padding="valid", - name="projection", - ) - # Use same default momentum and epsilon as PyTorch equivalent for BatchNormalization - self.norm = ( - keras.layers.BatchNormalization(axis=-1, epsilon=config.batch_norm_eps, momentum=0.9, name="norm") - if apply_norm - else tf.identity - ) - self.embed_dim = embed_dim - - def call(self, pixel_values: tf.Tensor, training: bool = False) -> tf.Tensor: - tf.debugging.assert_shapes( - [(pixel_values, (..., None, None, self.num_channels))], - message="Make sure that the channel dimension of the pixel values match with the one set in the configuration.", - ) - embeddings = self.projection(self.padding(pixel_values)) - embeddings = self.norm(embeddings, training=training) - return embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, None, self.num_channels]) - if getattr(self, "norm", None) is not None: - if hasattr(self.norm, "name"): - with tf.name_scope(self.norm.name): - self.norm.build([None, None, None, self.embed_dim]) - - -class TFEfficientFormerSelfAttention(keras.layers.Layer): - def __init__( - self, - dim: int, - key_dim: int, - num_heads: int, - attention_ratio: int, - resolution: int, - config: EfficientFormerConfig, - **kwargs, - ): - super().__init__(**kwargs) - - self.num_heads = num_heads - self.key_dim = key_dim - self.attention_ratio = attention_ratio - self.scale = key_dim**-0.5 - self.total_key_dim = key_dim * num_heads - self.expanded_key_dim = int(attention_ratio * key_dim) - self.total_expanded_key_dim = int(self.expanded_key_dim * num_heads) - hidden_size = self.total_expanded_key_dim + self.total_key_dim * 2 - - self.qkv = keras.layers.Dense( - units=hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="qkv" - ) - self.projection = keras.layers.Dense( - units=dim, kernel_initializer=get_initializer(config.initializer_range), name="projection" - ) - self.resolution = resolution - self.dim = dim - - def build(self, input_shape: tf.TensorShape) -> None: - points = list(itertools.product(range(self.resolution), range(self.resolution))) - num_points = len(points) - attention_offsets = {} - - idxs = [] - - for point_1 in points: - for point_2 in points: - offset = (abs(point_1[0] - point_2[0]), abs(point_1[1] - point_2[1])) - if offset not in attention_offsets: - attention_offsets[offset] = len(attention_offsets) - idxs.append(attention_offsets[offset]) - - self.attention_biases = self.add_weight( - shape=(self.num_heads, len(attention_offsets)), - initializer=keras.initializers.zeros(), - trainable=True, - name="attention_biases", - ) - self.attention_bias_idxs = self.add_weight( - shape=(num_points, num_points), - trainable=False, - dtype=tf.int32, - name="attention_bias_idxs", - ) - - self.attention_bias_idxs.assign(tf.reshape(tf.cast(idxs, dtype=tf.int32), (num_points, num_points))) - - if self.built: - return - self.built = True - if getattr(self, "qkv", None) is not None: - with tf.name_scope(self.qkv.name): - self.qkv.build([None, None, self.dim]) - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, self.total_expanded_key_dim]) - - def call( - self, hidden_states: tf.Tensor, output_attentions: bool = False, training: bool = False - ) -> tuple[tf.Tensor]: - batch_size, sequence_length, *_ = shape_list(hidden_states) - qkv = self.qkv(inputs=hidden_states) - - query_layer, key_layer, value_layer = tf.split( - tf.reshape(tensor=qkv, shape=(batch_size, sequence_length, self.num_heads, -1)), - num_or_size_splits=[self.key_dim, self.key_dim, self.expanded_key_dim], - axis=3, - ) - - query_layer = tf.transpose(query_layer, perm=[0, 2, 1, 3]) - key_layer = tf.transpose(key_layer, perm=[0, 2, 1, 3]) - value_layer = tf.transpose(value_layer, perm=[0, 2, 1, 3]) - - attention_probs = tf.matmul(query_layer, tf.transpose(key_layer, perm=[0, 1, 3, 2])) - scale = tf.cast(self.scale, dtype=attention_probs.dtype) - attention_probs = tf.multiply(attention_probs, scale) - - attention_biases = tf.gather(params=self.attention_biases, indices=self.attention_bias_idxs, axis=1) - attention_probs = attention_probs + attention_biases - attention_probs = stable_softmax(logits=attention_probs, axis=-1) - - context_layer = tf.matmul(attention_probs, value_layer) - context_layer = tf.transpose(context_layer, perm=[0, 2, 1, 3]) - - context_layer = tf.reshape( - tensor=context_layer, shape=(batch_size, sequence_length, self.total_expanded_key_dim) - ) - context_layer = self.projection(context_layer) - - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - - return outputs - - -class TFEfficientFormerConvStem(keras.layers.Layer): - def __init__(self, config: EfficientFormerConfig, out_channels: int, **kwargs): - super().__init__(**kwargs) - - self.padding = keras.layers.ZeroPadding2D(padding=1) - self.convolution1 = keras.layers.Conv2D( - filters=out_channels // 2, kernel_size=3, strides=2, padding="valid", name="convolution1" - ) - # Use same default momentum and epsilon as PyTorch equivalent for BatchNormalization - self.batchnorm_before = keras.layers.BatchNormalization( - axis=-1, epsilon=config.batch_norm_eps, momentum=0.9, name="batchnorm_before" - ) - - self.convolution2 = keras.layers.Conv2D( - filters=out_channels, - kernel_size=3, - strides=2, - padding="valid", - name="convolution2", - ) - # Use same default momentum and epsilon as PyTorch equivalent for BatchNormalization - self.batchnorm_after = keras.layers.BatchNormalization( - axis=-1, epsilon=config.batch_norm_eps, momentum=0.9, name="batchnorm_after" - ) - - self.activation = keras.layers.Activation(activation=keras.activations.relu, name="activation") - self.out_channels = out_channels - self.config = config - - def call(self, pixel_values: tf.Tensor, training: bool = False) -> tf.Tensor: - features = self.batchnorm_before(self.convolution1(self.padding(pixel_values)), training=training) - features = self.activation(features) - features = self.batchnorm_after(self.convolution2(self.padding(features)), training=training) - features = self.activation(features) - return features - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convolution1", None) is not None: - with tf.name_scope(self.convolution1.name): - self.convolution1.build([None, None, None, self.config.num_channels]) - if getattr(self, "batchnorm_before", None) is not None: - with tf.name_scope(self.batchnorm_before.name): - self.batchnorm_before.build([None, None, None, self.out_channels // 2]) - if getattr(self, "convolution2", None) is not None: - with tf.name_scope(self.convolution2.name): - self.convolution2.build([None, None, None, self.out_channels // 2]) - if getattr(self, "batchnorm_after", None) is not None: - with tf.name_scope(self.batchnorm_after.name): - self.batchnorm_after.build([None, None, None, self.out_channels]) - if getattr(self, "activation", None) is not None: - with tf.name_scope(self.activation.name): - self.activation.build(None) - - -class TFEfficientFormerPooling(keras.layers.Layer): - def __init__(self, pool_size: int, **kwargs): - super().__init__(**kwargs) - self.pool = keras.layers.AveragePooling2D(pool_size=pool_size, strides=1, padding="same") - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - output = self.pool(hidden_states) - output = output - hidden_states - return output - - -class TFEfficientFormerDenseMlp(keras.layers.Layer): - def __init__( - self, - config: EfficientFormerConfig, - in_features: int, - hidden_features: Optional[int] = None, - out_features: Optional[int] = None, - **kwargs, - ): - super().__init__(**kwargs) - out_features = out_features or in_features - hidden_features = hidden_features or in_features - - self.linear_in = keras.layers.Dense( - units=hidden_features, kernel_initializer=get_initializer(config.initializer_range), name="linear_in" - ) - self.activation = ACT2FN[config.hidden_act] - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - self.linear_out = keras.layers.Dense( - units=out_features, kernel_initializer=get_initializer(config.initializer_range), name="linear_out" - ) - self.hidden_features = hidden_features - self.in_features = in_features - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.linear_in(inputs=hidden_states) - hidden_states = self.activation(hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.linear_out(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "linear_in", None) is not None: - with tf.name_scope(self.linear_in.name): - self.linear_in.build([None, None, self.in_features]) - if getattr(self, "linear_out", None) is not None: - with tf.name_scope(self.linear_out.name): - self.linear_out.build([None, None, self.hidden_features]) - - -class TFEfficientFormerConvMlp(keras.layers.Layer): - def __init__( - self, - config: EfficientFormerConfig, - in_features: int, - hidden_features: Optional[int] = None, - out_features: Optional[int] = None, - drop: float = 0.0, - **kwargs, - ): - super().__init__(**kwargs) - out_features = out_features or in_features - hidden_features = hidden_features or in_features - - self.convolution1 = keras.layers.Conv2D( - filters=hidden_features, - kernel_size=1, - name="convolution1", - padding="valid", - ) - - self.activation = ACT2FN[config.hidden_act] - - self.convolution2 = keras.layers.Conv2D( - filters=out_features, - kernel_size=1, - name="convolution2", - padding="valid", - ) - - self.dropout = keras.layers.Dropout(rate=drop) - - # Use same default momentum and epsilon as PyTorch equivalent for BatchNormalization - self.batchnorm_before = keras.layers.BatchNormalization( - axis=-1, epsilon=config.batch_norm_eps, momentum=0.9, name="batchnorm_before" - ) - # Use same default momentum and epsilon as PyTorch equivalent for BatchNormalization - self.batchnorm_after = keras.layers.BatchNormalization( - axis=-1, epsilon=config.batch_norm_eps, momentum=0.9, name="batchnorm_after" - ) - self.hidden_features = hidden_features - self.in_features = in_features - self.out_features = out_features - - def call(self, hidden_state: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_state = self.convolution1(hidden_state) - hidden_state = self.batchnorm_before(hidden_state, training=training) - hidden_state = self.activation(hidden_state) - hidden_state = self.dropout(hidden_state, training=training) - hidden_state = self.convolution2(hidden_state) - hidden_state = self.batchnorm_after(hidden_state, training=training) - hidden_state = self.dropout(hidden_state, training=training) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convolution1", None) is not None: - with tf.name_scope(self.convolution1.name): - self.convolution1.build([None, None, None, self.in_features]) - if getattr(self, "convolution2", None) is not None: - with tf.name_scope(self.convolution2.name): - self.convolution2.build([None, None, None, self.hidden_features]) - if getattr(self, "batchnorm_before", None) is not None: - with tf.name_scope(self.batchnorm_before.name): - self.batchnorm_before.build([None, None, None, self.hidden_features]) - if getattr(self, "batchnorm_after", None) is not None: - with tf.name_scope(self.batchnorm_after.name): - self.batchnorm_after.build([None, None, None, self.out_features]) - - -# Copied from transformers.models.convnext.modeling_tf_convnext.TFConvNextDropPath with ConvNext->EfficientFormer -class TFEfficientFormerDropPath(keras.layers.Layer): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - References: - (1) github.com:rwightman/pytorch-image-models - """ - - def __init__(self, drop_path: float, **kwargs): - super().__init__(**kwargs) - self.drop_path = drop_path - - def call(self, x: tf.Tensor, training=None): - if training: - keep_prob = 1 - self.drop_path - shape = (tf.shape(x)[0],) + (1,) * (len(tf.shape(x)) - 1) - random_tensor = keep_prob + tf.random.uniform(shape, 0, 1) - random_tensor = tf.floor(random_tensor) - return (x / keep_prob) * random_tensor - return x - - -class TFEfficientFormerFlat(keras.layers.Layer): - def __init__(self, **kwargs): - super().__init__(**kwargs) - - def call(self, hidden_states: tf.Tensor) -> tuple[tf.Tensor]: - batch_size, _, _, in_channels = shape_list(hidden_states) - hidden_states = tf.reshape(hidden_states, shape=[batch_size, -1, in_channels]) - return hidden_states - - -class TFEfficientFormerMeta3D(keras.layers.Layer): - def __init__(self, config: EfficientFormerConfig, dim: int, drop_path: float = 0.0, **kwargs): - super().__init__(**kwargs) - - self.token_mixer = TFEfficientFormerSelfAttention( - dim=config.dim, - key_dim=config.key_dim, - num_heads=config.num_attention_heads, - attention_ratio=config.attention_ratio, - resolution=config.resolution, - name="token_mixer", - config=config, - ) - self.dim = dim - self.config = config - - self.layernorm1 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm1") - self.layernorm2 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm2") - mlp_hidden_dim = int(dim * config.mlp_expansion_ratio) - self.mlp = TFEfficientFormerDenseMlp(config, in_features=dim, hidden_features=mlp_hidden_dim, name="mlp") - - # Using `layers.Activation` instead of `tf.identity` to better control `training' behavior. - self.drop_path = ( - TFEfficientFormerDropPath(drop_path) - if drop_path > 0.0 - else keras.layers.Activation("linear", name="drop_path") - ) - self.config = config - - def build(self, input_shape=None): - self.layer_scale_1 = None - self.layer_scale_2 = None - - if self.config.use_layer_scale: - self.layer_scale_1 = self.add_weight( - shape=(self.dim,), - initializer=keras.initializers.Constant(value=self.config.layer_scale_init_value), - trainable=True, - name="layer_scale_1", - ) - self.layer_scale_2 = self.add_weight( - shape=(self.dim,), - initializer=keras.initializers.Constant(value=self.config.layer_scale_init_value), - trainable=True, - name="layer_scale_2", - ) - - if self.built: - return - self.built = True - if getattr(self, "token_mixer", None) is not None: - with tf.name_scope(self.token_mixer.name): - self.token_mixer.build(None) - if getattr(self, "layernorm1", None) is not None: - with tf.name_scope(self.layernorm1.name): - self.layernorm1.build([None, None, self.dim]) - if getattr(self, "layernorm2", None) is not None: - with tf.name_scope(self.layernorm2.name): - self.layernorm2.build([None, None, self.dim]) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "drop_path", None) is not None: - with tf.name_scope(self.drop_path.name): - self.drop_path.build(None) - - def call( - self, hidden_states: tf.Tensor, output_attentions: bool = False, training: bool = False - ) -> tuple[tf.Tensor]: - self_attention_outputs = self.token_mixer( - hidden_states=self.layernorm1(hidden_states, training=training), - output_attentions=output_attentions, - training=training, - ) - - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - if self.config.use_layer_scale: - layer_output = hidden_states + self.drop_path( - tf.expand_dims(tf.expand_dims(self.layer_scale_1, 0), 0) * attention_output, - training=training, - ) - layer_output = layer_output + self.drop_path( - tf.expand_dims(tf.expand_dims(self.layer_scale_2, 0), 0) - * self.mlp(hidden_states=self.layernorm2(inputs=layer_output, training=training), training=training), - training=training, - ) - else: - layer_output = hidden_states + self.drop_path(attention_output, training=training) - layer_output = layer_output + self.drop_path( - self.mlp(hidden_states=self.layernorm2(inputs=layer_output, training=training), training=training), - training=training, - ) - - outputs = (layer_output,) + outputs - - return outputs - - -class TFEfficientFormerMeta3DLayers(keras.layers.Layer): - def __init__(self, config: EfficientFormerConfig, **kwargs): - super().__init__(**kwargs) - drop_paths = [ - config.drop_path_rate * (block_idx + sum(config.depths[:-1])) - for block_idx in range(config.num_meta3d_blocks) - ] - self.blocks = [ - TFEfficientFormerMeta3D(config, config.hidden_sizes[-1], drop_path=drop_path, name=f"blocks.{i}") - for i, drop_path in enumerate(drop_paths) - ] - - def call( - self, hidden_states: tf.Tensor, output_attentions: bool = False, training: bool = False - ) -> tuple[tf.Tensor]: - all_attention_outputs = () if output_attentions else None - - for i, layer_module in enumerate(self.blocks): - if isinstance(hidden_states, tuple): - hidden_states = hidden_states[0] - - hidden_states = layer_module( - hidden_states=hidden_states, output_attentions=output_attentions, training=training - ) - if output_attentions: - all_attention_outputs = all_attention_outputs + (hidden_states[1],) - - if output_attentions: - outputs = (hidden_states[0],) + all_attention_outputs - return outputs - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "blocks", None) is not None: - for layer in self.blocks: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFEfficientFormerMeta4D(keras.layers.Layer): - def __init__(self, config: EfficientFormerConfig, dim: int, drop_path: float = 0.0, **kwargs): - super().__init__(**kwargs) - pool_size = config.pool_size if config.pool_size is not None else 3 - self.token_mixer = TFEfficientFormerPooling(pool_size=pool_size, name="token_mixer") - self.dim = dim - mlp_hidden_dim = int(dim * config.mlp_expansion_ratio) - self.mlp = TFEfficientFormerConvMlp( - config=config, in_features=dim, hidden_features=mlp_hidden_dim, drop=config.hidden_dropout_prob, name="mlp" - ) - - self.drop_path = ( - TFEfficientFormerDropPath(drop_path, name="drop_path") - if drop_path > 0.0 - else keras.layers.Activation("linear", name="drop_path") - ) - self.config = config - - def build(self, input_shape=None): - self.layer_scale_1 = None - self.layer_scale_2 = None - - if self.config.use_layer_scale: - self.layer_scale_1 = self.add_weight( - shape=(self.dim), - initializer=keras.initializers.Constant(value=self.config.layer_scale_init_value), - trainable=True, - name="layer_scale_1", - ) - self.layer_scale_2 = self.add_weight( - shape=(self.dim), - initializer=keras.initializers.Constant(value=self.config.layer_scale_init_value), - trainable=True, - name="layer_scale_2", - ) - - if self.built: - return - self.built = True - if getattr(self, "token_mixer", None) is not None: - with tf.name_scope(self.token_mixer.name): - self.token_mixer.build(None) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "drop_path", None) is not None: - with tf.name_scope(self.drop_path.name): - self.drop_path.build(None) - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tuple[tf.Tensor]: - outputs = self.token_mixer(hidden_states) - - if self.config.use_layer_scale: - layer_output = hidden_states + self.drop_path( - tf.expand_dims(tf.expand_dims(self.layer_scale_1, 0), 0) * outputs, - training=training, - ) - - layer_output = layer_output + self.drop_path( - tf.expand_dims(tf.expand_dims(self.layer_scale_2, 0), 0) - * self.mlp(hidden_state=layer_output, training=training), - training=training, - ) - - else: - layer_output = hidden_states + self.drop_path(outputs, training=training) - layer_output = layer_output + self.drop_path( - self.mlp(hidden_state=layer_output, training=training), training=training - ) - - return layer_output - - -class TFEfficientFormerMeta4DLayers(keras.layers.Layer): - def __init__(self, config: EfficientFormerConfig, stage_idx: int, **kwargs): - super().__init__(**kwargs) - num_layers = ( - config.depths[stage_idx] if stage_idx != -1 else config.depths[stage_idx] - config.num_meta3d_blocks - ) - drop_paths = [ - config.drop_path_rate * (block_idx + sum(config.depths[:stage_idx])) for block_idx in range(num_layers) - ] - - self.blocks = [ - TFEfficientFormerMeta4D( - config=config, dim=config.hidden_sizes[stage_idx], drop_path=drop_paths[i], name=f"blocks.{i}" - ) - for i in range(len(drop_paths)) - ] - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tuple[tf.Tensor]: - for layer_module in self.blocks: - hidden_states = layer_module(hidden_states=hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "blocks", None) is not None: - for layer in self.blocks: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFEfficientFormerIntermediateStage(keras.layers.Layer): - def __init__(self, config: EfficientFormerConfig, index: int, **kwargs): - super().__init__(**kwargs) - self.meta4D_layers = TFEfficientFormerMeta4DLayers(config=config, stage_idx=index, name="meta4D_layers") - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tuple[tf.Tensor]: - hidden_states = self.meta4D_layers(hidden_states=hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "meta4D_layers", None) is not None: - with tf.name_scope(self.meta4D_layers.name): - self.meta4D_layers.build(None) - - -class TFEfficientFormerLastStage(keras.layers.Layer): - def __init__(self, config: EfficientFormerConfig, **kwargs): - super().__init__(**kwargs) - self.meta4D_layers = TFEfficientFormerMeta4DLayers(config=config, stage_idx=-1, name="meta4D_layers") - self.flat = TFEfficientFormerFlat(name="flat") - self.meta3D_layers = TFEfficientFormerMeta3DLayers(config, name="meta3D_layers") - - def call( - self, hidden_states: tf.Tensor, output_attentions: bool = False, training: bool = False - ) -> tuple[tf.Tensor]: - hidden_states = self.meta4D_layers(hidden_states=hidden_states, training=training) - hidden_states = self.flat(hidden_states=hidden_states) - hidden_states = self.meta3D_layers( - hidden_states=hidden_states, output_attentions=output_attentions, training=training - ) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "meta4D_layers", None) is not None: - with tf.name_scope(self.meta4D_layers.name): - self.meta4D_layers.build(None) - if getattr(self, "flat", None) is not None: - with tf.name_scope(self.flat.name): - self.flat.build(None) - if getattr(self, "meta3D_layers", None) is not None: - with tf.name_scope(self.meta3D_layers.name): - self.meta3D_layers.build(None) - - -class TFEfficientFormerEncoder(keras.layers.Layer): - def __init__(self, config: EfficientFormerConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - num_intermediate_stages = len(config.depths) - 1 - downsamples = [ - config.downsamples[i] or config.hidden_sizes[i] != config.hidden_sizes[i + 1] - for i in range(num_intermediate_stages) - ] - - intermediate_stages = [] - layer_count = -1 - for i in range(num_intermediate_stages): - layer_count += 1 - intermediate_stages.append( - TFEfficientFormerIntermediateStage(config, i, name=f"intermediate_stages.{layer_count}") - ) - if downsamples[i]: - layer_count += 1 - intermediate_stages.append( - TFEfficientFormerPatchEmbeddings( - config, - config.hidden_sizes[i], - config.hidden_sizes[i + 1], - name=f"intermediate_stages.{layer_count}", - ) - ) - self.intermediate_stages = intermediate_stages - self.last_stage = TFEfficientFormerLastStage(config, name="last_stage") - - def call( - self, - hidden_states: tf.Tensor, - output_hidden_states: bool, - output_attentions: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutput: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - for layer_module in self.intermediate_stages: - hidden_states = layer_module(hidden_states, training=training) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_output = self.last_stage(hidden_states, output_attentions=output_attentions, training=training) - - if output_attentions: - all_self_attentions = all_self_attentions + layer_output[1:] - - if output_hidden_states: - all_hidden_states = all_hidden_states + (layer_output[0],) - - if not return_dict: - return tuple(v for v in [layer_output[0], all_hidden_states, all_self_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=layer_output[0], - hidden_states=all_hidden_states, - attentions=all_self_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "last_stage", None) is not None: - with tf.name_scope(self.last_stage.name): - self.last_stage.build(None) - for layer in self.intermediate_stages: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFEfficientFormerMainLayer(keras.layers.Layer): - config_class = EfficientFormerConfig - - def __init__(self, config: EfficientFormerConfig, **kwargs) -> None: - super().__init__(**kwargs) - self.config = config - - self.patch_embed = TFEfficientFormerConvStem(config, config.hidden_sizes[0], name="patch_embed") - self.encoder = TFEfficientFormerEncoder(config, name="encoder") - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - - @unpack_inputs - def call( - self, - pixel_values: Optional[tf.Tensor] = None, - output_attentions: Optional[tf.Tensor] = None, - output_hidden_states: Optional[tf.Tensor] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[TFBaseModelOutput, tuple[tf.Tensor, ...]]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - # When running on CPU, keras.layers.Conv2D and keras.layers.AveragePool2D do not - # support channels first NCHW format. A number of blocks contain both. - # So change the input format from (batch_size, num_channels, height, width) to - # (batch_size, height, width, num_channels) here. - # shape = (batch_size, in_height, in_width, in_channels=num_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - embedding_output = self.patch_embed(pixel_values, training=training) - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - sequence_output = self.layernorm(sequence_output, training=training) - - # Change the hidden states from (batch_size, height, width, num_channels) to - # (batch_size, num_channels, height, width). - # The hidden states are in (batch_size, height, width, num_channels) - # shape after all stages except the MB3D blocks. - if output_hidden_states: - hidden_states = tuple(tf.transpose(h, perm=(0, 3, 1, 2)) for h in encoder_outputs[1][:-1]) + ( - encoder_outputs[1][-1], - ) - - if not return_dict: - head_outputs = (sequence_output,) - return head_outputs + encoder_outputs[1:] - - return TFBaseModelOutput( - last_hidden_state=sequence_output, - hidden_states=hidden_states if output_hidden_states else encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "patch_embed", None) is not None: - with tf.name_scope(self.patch_embed.name): - self.patch_embed.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, self.config.hidden_sizes[-1]]) - - -class TFEfficientFormerPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = EfficientFormerConfig - base_model_prefix = "efficientformer" - main_input_name = "pixel_values" - - -EFFICIENTFORMER_START_DOCSTRING = r""" - This model is a TensorFlow - [keras.layers.Layer](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer). Use it as a regular - TensorFlow Module and refer to the TensorFlow documentation for all matter related to general usage and behavior. - - - Parameters: - config ([`EfficientFormerConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -EFFICIENTFORMER_INPUTS_DOCSTRING = r""" - Args: - pixel_values ((`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`EfficientFormerImageProcessor.__call__`] for details. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@add_start_docstrings( - "The bare EfficientFormer Model transformer outputting raw hidden-states without any specific head on top.", - EFFICIENTFORMER_START_DOCSTRING, -) -class TFEfficientFormerModel(TFEfficientFormerPreTrainedModel): - def __init__(self, config: EfficientFormerConfig, **kwargs) -> None: - super().__init__(config, **kwargs) - - self.efficientformer = TFEfficientFormerMainLayer(config, name="efficientformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(EFFICIENTFORMER_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPooling, - config_class=_CONFIG_FOR_DOC, - modality="vision", - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - def call( - self, - pixel_values: Optional[tf.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[tuple, TFBaseModelOutput]: - outputs = self.efficientformer( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "efficientformer", None) is not None: - with tf.name_scope(self.efficientformer.name): - self.efficientformer.build(None) - - -@add_start_docstrings( - """ - EfficientFormer Model transformer with an image classification head on top of pooled last hidden state, e.g. for - ImageNet. - """, - EFFICIENTFORMER_START_DOCSTRING, -) -class TFEfficientFormerForImageClassification(TFEfficientFormerPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: EfficientFormerConfig): - super().__init__(config) - - self.num_labels = config.num_labels - self.efficientformer = TFEfficientFormerMainLayer(config, name="efficientformer") - - # Classifier head - self.classifier = ( - keras.layers.Dense(config.num_labels, name="classifier") - if config.num_labels > 0 - else keras.layers.Activation("linear", name="classifier") - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(EFFICIENTFORMER_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFImageClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - def call( - self, - pixel_values: Optional[tf.Tensor] = None, - labels: Optional[tf.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[tf.Tensor, TFImageClassifierOutput]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.efficientformer( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - - logits = self.classifier(tf.reduce_mean(sequence_output, axis=-2)) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFImageClassifierOutput( - loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "efficientformer", None) is not None: - with tf.name_scope(self.efficientformer.name): - self.efficientformer.build(None) - if getattr(self, "classifier", None) is not None: - if hasattr(self.classifier, "name"): - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_sizes[-1]]) - - -@dataclass -class TFEfficientFormerForImageClassificationWithTeacherOutput(ModelOutput): - """ - Args: - Output type of [`EfficientFormerForImageClassificationWithTeacher`]. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Prediction scores as the average of the cls_logits and distillation logits. - cls_logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Prediction scores of the classification head (i.e. the linear layer on top of the final hidden state of the - class token). - distillation_logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Prediction scores of the distillation head (i.e. the linear layer on top of the final hidden state of the - distillation token). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when - `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus - the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when - `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - """ - - logits: Optional[tf.Tensor] = None - cls_logits: Optional[tf.Tensor] = None - distillation_logits: Optional[tf.Tensor] = None - hidden_states: Optional[tuple[tf.Tensor]] = None - attentions: Optional[tuple[tf.Tensor]] = None - - -@add_start_docstrings( - """ - EfficientFormer Model transformer with image classification heads on top (a linear layer on top of the final hidden - state and a linear layer on top of the final hidden state of the distillation token) e.g. for ImageNet. - - .. warning:: - This model supports inference-only. Fine-tuning with distillation (i.e. with a teacher) is not yet - supported. - """, - EFFICIENTFORMER_START_DOCSTRING, -) -class TFEfficientFormerForImageClassificationWithTeacher(TFEfficientFormerPreTrainedModel): - def __init__(self, config: EfficientFormerConfig) -> None: - super().__init__(config) - - self.num_labels = config.num_labels - self.efficientformer = TFEfficientFormerMainLayer(config, name="efficientformer") - - # Classifier heads - self.classifier = ( - keras.layers.Dense(config.num_labels, name="classifier") - if config.num_labels > 0 - else keras.layers.Activation("linear", name="classifier") - ) - self.distillation_classifier = ( - keras.layers.Dense(config.num_labels, name="distillation_classifier") - if config.num_labels > 0 - else keras.layers.Activation("linear", name="distillation_classifier") - ) - - @unpack_inputs - @add_start_docstrings_to_model_forward(EFFICIENTFORMER_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFEfficientFormerForImageClassificationWithTeacherOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - def call( - self, - pixel_values: Optional[tf.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[tuple, TFEfficientFormerForImageClassificationWithTeacherOutput]: - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if training: - raise Exception( - "This model supports inference-only. Fine-tuning with distillation (i.e. with a teacher) is not yet supported." - ) - - outputs = self.efficientformer( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - - cls_logits = self.classifier(tf.reduce_mean(sequence_output, axis=-2)) - distillation_logits = self.distillation_classifier(tf.reduce_mean(sequence_output, axis=-2)) - logits = (cls_logits + distillation_logits) / 2 - - if not return_dict: - output = (logits, cls_logits, distillation_logits) + outputs[1:] - return output - - return TFEfficientFormerForImageClassificationWithTeacherOutput( - logits=logits, - cls_logits=cls_logits, - distillation_logits=distillation_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "efficientformer", None) is not None: - with tf.name_scope(self.efficientformer.name): - self.efficientformer.build(None) - if getattr(self, "classifier", None) is not None: - if hasattr(self.classifier, "name"): - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_sizes[-1]]) - if getattr(self, "distillation_classifier", None) is not None: - if hasattr(self.distillation_classifier, "name"): - with tf.name_scope(self.distillation_classifier.name): - self.distillation_classifier.build([None, None, self.config.hidden_sizes[-1]]) - - -__all__ = [ - "TFEfficientFormerForImageClassification", - "TFEfficientFormerForImageClassificationWithTeacher", - "TFEfficientFormerModel", - "TFEfficientFormerPreTrainedModel", -] diff --git a/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py b/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py index f0e97c132d09..4cecdf5728a3 100755 --- a/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py +++ b/src/transformers/models/deprecated/ernie_m/modeling_ernie_m.py @@ -409,8 +409,6 @@ class ErnieMPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/deprecated/gptsan_japanese/modeling_gptsan_japanese.py b/src/transformers/models/deprecated/gptsan_japanese/modeling_gptsan_japanese.py index 0e2d27f03bac..eb5b030bbf82 100644 --- a/src/transformers/models/deprecated/gptsan_japanese/modeling_gptsan_japanese.py +++ b/src/transformers/models/deprecated/gptsan_japanese/modeling_gptsan_japanese.py @@ -706,22 +706,15 @@ def _init_weights(self, module): elif isinstance(module, nn.Embedding): module.weight.data.normal_(mean=0.0, std=factor * 1.0) elif isinstance(module, GPTSanJapaneseModel): - # Mesh TensorFlow embeddings initialization - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L1624 module.embed_tokens.weight.data.normal_(mean=0.0, std=factor * 1.0) module.position_embeddings.weight.data.normal_(mean=0.0, std=factor * 1.0) if hasattr(module, "extra_position_embeddings") and module.extra_position_embeddings is not None: module.extra_position_embeddings.weight.data.normal_(mean=0.0, std=factor * 1.0) elif isinstance(module, (GPTSanJapaneseModel, GPTSanJapaneseForConditionalGeneration)): - # Mesh TensorFlow embeddings initialization - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L1624 module.final_logits_bias.data.normal_(mean=0.0, std=factor * 1.0) if hasattr(module, "lm_head") and not self.config.tie_word_embeddings: module.lm_head.weight.data.normal_(mean=0.0, std=factor * 1.0) elif isinstance(module, GPTSanJapaneseDenseActDense): - # Mesh TensorFlow FF initialization - # See https://github.com/tensorflow/mesh/blob/master/mesh_tensorflow/transformer/transformer_layers.py#L56 - # and https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L89 module.wi.weight.data.normal_(mean=0.0, std=factor * ((self.config.d_model) ** -0.5)) if hasattr(module.wi, "bias") and module.wi.bias is not None: module.wi.bias.data.zero_() @@ -738,8 +731,6 @@ def _init_weights(self, module): module.q_proj.weight.data.normal_(mean=0.0, std=factor * ((d_model * key_value_proj_dim) ** -0.5)) module.out_proj.weight.data.normal_(mean=0.0, std=factor * ((n_heads * key_value_proj_dim) ** -0.5)) elif isinstance(module, GPTSanJapaneseSparseMLP): - # Mesh TensorFlow attention initialization to avoid scaling before softmax - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/attention.py#L136 d_model = self.config.d_model key_value_proj_dim = self.config.d_model n_heads = self.config.num_heads diff --git a/src/transformers/models/deprecated/jukebox/modeling_jukebox.py b/src/transformers/models/deprecated/jukebox/modeling_jukebox.py index f928d49cf5f7..daaa4b2ee489 100755 --- a/src/transformers/models/deprecated/jukebox/modeling_jukebox.py +++ b/src/transformers/models/deprecated/jukebox/modeling_jukebox.py @@ -907,7 +907,7 @@ def _attn(self, query_states, key_states, value_states, sample): def merge_heads(self, hidden_states): hidden_states = hidden_states.permute(0, 2, 1, 3).contiguous() new_hidden_states_shape = (*hidden_states.size()[:-2], hidden_states.size(-2) * hidden_states.size(-1)) - return hidden_states.view(*new_hidden_states_shape) # in Tensorflow implem: fct merge_states + return hidden_states.view(*new_hidden_states_shape) def split_heads(self, hidden_states, is_key=False): new_hidden_states_shape = ( @@ -915,7 +915,7 @@ def split_heads(self, hidden_states, is_key=False): self.n_heads, hidden_states.size(-1) // self.n_heads, ) - hidden_states = hidden_states.view(*new_hidden_states_shape) # in Tensorflow implem: fct split_states + hidden_states = hidden_states.view(*new_hidden_states_shape) if is_key: return hidden_states.permute(0, 2, 3, 1) else: diff --git a/src/transformers/models/deprecated/jukebox/tokenization_jukebox.py b/src/transformers/models/deprecated/jukebox/tokenization_jukebox.py index ec2162db2cce..473d23d49565 100644 --- a/src/transformers/models/deprecated/jukebox/tokenization_jukebox.py +++ b/src/transformers/models/deprecated/jukebox/tokenization_jukebox.py @@ -26,8 +26,8 @@ from ....tokenization_utils import AddedToken, PreTrainedTokenizer from ....tokenization_utils_base import BatchEncoding -from ....utils import TensorType, is_flax_available, is_tf_available, is_torch_available, logging -from ....utils.generic import _is_jax, _is_numpy +from ....utils import TensorType, is_torch_available, logging +from ....utils.generic import _is_numpy logger = logging.get_logger(__name__) @@ -279,30 +279,13 @@ def convert_to_tensors( if not isinstance(tensor_type, TensorType): tensor_type = TensorType(tensor_type) - # Get a function reference for the correct framework - if tensor_type == TensorType.TENSORFLOW: - if not is_tf_available(): - raise ImportError( - "Unable to convert output to TensorFlow tensors format, TensorFlow is not installed." - ) - import tensorflow as tf - - as_tensor = tf.constant - is_tensor = tf.is_tensor - elif tensor_type == TensorType.PYTORCH: + if tensor_type == TensorType.PYTORCH: if not is_torch_available(): raise ImportError("Unable to convert output to PyTorch tensors format, PyTorch is not installed.") import torch as_tensor = torch.tensor is_tensor = torch.is_tensor - elif tensor_type == TensorType.JAX: - if not is_flax_available(): - raise ImportError("Unable to convert output to JAX tensors format, JAX is not installed.") - import jax.numpy as jnp # noqa: F811 - - as_tensor = jnp.array - is_tensor = _is_jax else: as_tensor = np.asarray is_tensor = _is_numpy diff --git a/src/transformers/models/deprecated/mctct/feature_extraction_mctct.py b/src/transformers/models/deprecated/mctct/feature_extraction_mctct.py index 966a160f91b0..0ce7c1da31a2 100644 --- a/src/transformers/models/deprecated/mctct/feature_extraction_mctct.py +++ b/src/transformers/models/deprecated/mctct/feature_extraction_mctct.py @@ -207,7 +207,6 @@ def __call__( return_tensors (`str` or [`~file_utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/deprecated/mctct/modeling_mctct.py b/src/transformers/models/deprecated/mctct/modeling_mctct.py index 253b09c1c43c..357b8b2c3681 100755 --- a/src/transformers/models/deprecated/mctct/modeling_mctct.py +++ b/src/transformers/models/deprecated/mctct/modeling_mctct.py @@ -118,8 +118,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file # self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.LayerNorm = MCTCTLayerNorm() self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -427,8 +425,6 @@ def _init_weights(self, module): """Initialize the weights""" std = self.config.initializer_range if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/deprecated/mega/modeling_mega.py b/src/transformers/models/deprecated/mega/modeling_mega.py index c237afee9a33..02e41e91b24c 100644 --- a/src/transformers/models/deprecated/mega/modeling_mega.py +++ b/src/transformers/models/deprecated/mega/modeling_mega.py @@ -154,8 +154,6 @@ def __init__(self, config: MegaConfig): self.sine, self.cosine = MegaRotaryRelativePositionalBias.get_sinusoid_embeddings( config.max_positions, self.embed_dim ) - # alpha and beta parameters for the rotary bias; beta renamed to b_param to avoid clashes with tf/flax weight handling - # in loading pretrained weights self.alpha = nn.Parameter(torch.Tensor(1, self.embed_dim)) self.b_param = nn.Parameter(torch.Tensor(1, self.embed_dim)) self.register_buffer("_float_tensor", torch.FloatTensor([0.0])) diff --git a/src/transformers/models/deprecated/nat/modeling_nat.py b/src/transformers/models/deprecated/nat/modeling_nat.py index a619cdb11225..1667c98297fa 100644 --- a/src/transformers/models/deprecated/nat/modeling_nat.py +++ b/src/transformers/models/deprecated/nat/modeling_nat.py @@ -258,11 +258,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -620,8 +615,6 @@ class NatPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/deprecated/nezha/modeling_nezha.py b/src/transformers/models/deprecated/nezha/modeling_nezha.py index ddfecac9f506..eaf1cedfed32 100644 --- a/src/transformers/models/deprecated/nezha/modeling_nezha.py +++ b/src/transformers/models/deprecated/nezha/modeling_nezha.py @@ -15,7 +15,6 @@ """PyTorch Nezha model.""" import math -import os import warnings from dataclasses import dataclass from typing import Optional, Union @@ -57,79 +56,6 @@ _CONFIG_FOR_DOC = "NezhaConfig" -def load_tf_weights_in_nezha(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class NezhaRelativePositionsEncoding(nn.Module): """Implement the Functional Relative Position Encoding""" @@ -170,8 +96,6 @@ def __init__(self, config): self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) self.register_buffer( @@ -703,15 +627,12 @@ class NezhaPreTrainedModel(PreTrainedModel): """ config: NezhaConfig - load_tf_weights = load_tf_weights_in_nezha base_model_prefix = "nezha" supports_gradient_checkpointing = True def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py b/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py index f92bc07a8bfb..f522a1d72154 100755 --- a/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py +++ b/src/transformers/models/deprecated/qdqbert/modeling_qdqbert.py @@ -16,7 +16,6 @@ """PyTorch QDQBERT model.""" import math -import os import warnings from typing import Optional, Union @@ -71,79 +70,6 @@ _CONFIG_FOR_DOC = "QDQBertConfig" -def load_tf_weights_in_qdqbert(model, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class QDQBertEmbeddings(nn.Module): """Construct the embeddings from word, position and token_type embeddings.""" @@ -153,8 +79,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -712,15 +636,12 @@ class QDQBertPreTrainedModel(PreTrainedModel): """ config: QDQBertConfig - load_tf_weights = load_tf_weights_in_qdqbert base_model_prefix = "bert" supports_gradient_checkpointing = True def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1732,5 +1653,4 @@ def forward( "QDQBertLMHeadModel", "QDQBertModel", "QDQBertPreTrainedModel", - "load_tf_weights_in_qdqbert", ] diff --git a/src/transformers/models/deprecated/realm/modeling_realm.py b/src/transformers/models/deprecated/realm/modeling_realm.py index 9e2de5c9c1c4..69bab60f6803 100644 --- a/src/transformers/models/deprecated/realm/modeling_realm.py +++ b/src/transformers/models/deprecated/realm/modeling_realm.py @@ -15,7 +15,6 @@ """PyTorch REALM model.""" import math -import os from dataclasses import dataclass from typing import Optional, Union @@ -46,113 +45,6 @@ _CONFIG_FOR_DOC = "RealmConfig" -def load_tf_weights_in_realm(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - if isinstance(model, RealmReader) and "reader" not in name: - logger.info(f"Skipping {name} as it is not {model.__class__.__name__}'s parameter") - continue - - # For pretrained openqa reader - if (name.startswith("bert") or name.startswith("cls")) and isinstance(model, RealmForOpenQA): - name = name.replace("bert/", "reader/realm/") - name = name.replace("cls/", "reader/cls/") - - # For pretrained encoder - if (name.startswith("bert") or name.startswith("cls")) and isinstance(model, RealmKnowledgeAugEncoder): - name = name.replace("bert/", "realm/") - - # For finetuned reader - if name.startswith("reader"): - reader_prefix = "" if isinstance(model, RealmReader) else "reader/" - name = name.replace("reader/module/bert/", f"{reader_prefix}realm/") - name = name.replace("reader/module/cls/", f"{reader_prefix}cls/") - name = name.replace("reader/dense/", f"{reader_prefix}qa_outputs/dense_intermediate/") - name = name.replace("reader/dense_1/", f"{reader_prefix}qa_outputs/dense_output/") - name = name.replace("reader/layer_normalization", f"{reader_prefix}qa_outputs/layer_normalization") - - # For embedder and scorer - if name.startswith("module/module/module/"): # finetuned - embedder_prefix = "" if isinstance(model, RealmEmbedder) else "embedder/" - name = name.replace("module/module/module/module/bert/", f"{embedder_prefix}realm/") - name = name.replace("module/module/module/LayerNorm/", f"{embedder_prefix}cls/LayerNorm/") - name = name.replace("module/module/module/dense/", f"{embedder_prefix}cls/dense/") - name = name.replace("module/module/module/module/cls/predictions/", f"{embedder_prefix}cls/predictions/") - name = name.replace("module/module/module/bert/", f"{embedder_prefix}realm/") - name = name.replace("module/module/module/cls/predictions/", f"{embedder_prefix}cls/predictions/") - elif name.startswith("module/module/"): # pretrained - embedder_prefix = "" if isinstance(model, RealmEmbedder) else "embedder/" - name = name.replace("module/module/LayerNorm/", f"{embedder_prefix}cls/LayerNorm/") - name = name.replace("module/module/dense/", f"{embedder_prefix}cls/dense/") - - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - assert pointer.shape == array.shape, ( - f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched" - ) - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class RealmEmbeddings(nn.Module): """Construct the embeddings from word, position and token_type embeddings.""" @@ -162,8 +54,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -945,14 +835,11 @@ class RealmPreTrainedModel(PreTrainedModel): """ config: RealmConfig - load_tf_weights = load_tf_weights_in_realm base_model_prefix = "realm" def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1851,5 +1738,4 @@ def forward( "RealmPreTrainedModel", "RealmReader", "RealmScorer", - "load_tf_weights_in_realm", ] diff --git a/src/transformers/models/deprecated/realm/retrieval_realm.py b/src/transformers/models/deprecated/realm/retrieval_realm.py index b5e47abb1179..354ca2aba63a 100644 --- a/src/transformers/models/deprecated/realm/retrieval_realm.py +++ b/src/transformers/models/deprecated/realm/retrieval_realm.py @@ -31,16 +31,6 @@ logger = logging.get_logger(__name__) -def convert_tfrecord_to_np(block_records_path: str, num_block_records: int) -> np.ndarray: - import tensorflow.compat.v1 as tf - - blocks_dataset = tf.data.TFRecordDataset(block_records_path, buffer_size=512 * 1024 * 1024) - blocks_dataset = blocks_dataset.batch(num_block_records, drop_remainder=True) - np_record = next(blocks_dataset.take(1).as_numpy_iterator()) - - return np_record - - class ScaNNSearcher: """Note that ScaNNSearcher cannot currently be used within the model. In future versions, it might however be included.""" diff --git a/src/transformers/models/deprecated/retribert/modeling_retribert.py b/src/transformers/models/deprecated/retribert/modeling_retribert.py index 06806e8e6d0b..926d7551e51b 100644 --- a/src/transformers/models/deprecated/retribert/modeling_retribert.py +++ b/src/transformers/models/deprecated/retribert/modeling_retribert.py @@ -40,7 +40,6 @@ class RetriBertPreTrainedModel(PreTrainedModel): """ config: RetriBertConfig - load_tf_weights = None base_model_prefix = "retribert" def _init_weights(self, module): diff --git a/src/transformers/models/deprecated/tapex/tokenization_tapex.py b/src/transformers/models/deprecated/tapex/tokenization_tapex.py index b32383ddd497..fa74d8aa3b55 100644 --- a/src/transformers/models/deprecated/tapex/tokenization_tapex.py +++ b/src/transformers/models/deprecated/tapex/tokenization_tapex.py @@ -93,7 +93,6 @@ class TapexTruncationStrategy(ExplicitEnum): return_tensors (`str` or [`~file_utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. """ diff --git a/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py b/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py index b6ae410c1474..1b4126f9ef20 100644 --- a/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py +++ b/src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py @@ -15,7 +15,6 @@ """PyTorch TrajectoryTransformer model.""" import math -import os from dataclasses import dataclass from typing import Optional, Union @@ -43,79 +42,6 @@ _CONFIG_FOR_DOC = "TrajectoryTransformerConfig" -def load_tf_weights_in_trajectory_transformer(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - @dataclass class TrajectoryTransformerOutput(ModelOutput): """ @@ -154,7 +80,6 @@ class TrajectoryTransformerPreTrainedModel(PreTrainedModel): """ config: TrajectoryTransformerConfig - load_tf_weights = load_tf_weights_in_trajectory_transformer base_model_prefix = "trajectory_transformer" main_input_name = "trajectories" supports_gradient_checkpointing = True @@ -598,5 +523,4 @@ def forward( __all__ = [ "TrajectoryTransformerModel", "TrajectoryTransformerPreTrainedModel", - "load_tf_weights_in_trajectory_transformer", ] diff --git a/src/transformers/models/deprecated/transfo_xl/__init__.py b/src/transformers/models/deprecated/transfo_xl/__init__.py index 0ac9a2cbf476..9bd3dd7b8838 100644 --- a/src/transformers/models/deprecated/transfo_xl/__init__.py +++ b/src/transformers/models/deprecated/transfo_xl/__init__.py @@ -19,7 +19,6 @@ if TYPE_CHECKING: from .configuration_transfo_xl import * - from .modeling_tf_transfo_xl import * from .modeling_transfo_xl import * from .tokenization_transfo_xl import * else: diff --git a/src/transformers/models/deprecated/transfo_xl/convert_transfo_xl_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/deprecated/transfo_xl/convert_transfo_xl_original_tf_checkpoint_to_pytorch.py index 2c7b687c4d98..989a70ef71bd 100644 --- a/src/transformers/models/deprecated/transfo_xl/convert_transfo_xl_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/deprecated/transfo_xl/convert_transfo_xl_original_tf_checkpoint_to_pytorch.py @@ -21,12 +21,13 @@ import torch -from transformers import TransfoXLConfig, TransfoXLLMHeadModel, load_tf_weights_in_transfo_xl +from transformers import TransfoXLConfig, TransfoXLLMHeadModel from transformers.models.deprecated.transfo_xl import tokenization_transfo_xl as data_utils from transformers.models.deprecated.transfo_xl.tokenization_transfo_xl import CORPUS_NAME, VOCAB_FILES_NAMES from transformers.utils import CONFIG_NAME, WEIGHTS_NAME, logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() # We do this to be able to load python 2 datasets pickles @@ -37,6 +38,133 @@ sys.modules["vocabulary"] = data_utils +def build_tf_to_pytorch_map(model, config): + """ + A map of modules from TF to PyTorch. This time I use a map to keep the PyTorch model as identical to the original + PyTorch model as possible. + """ + tf_to_pt_map = {} + + if hasattr(model, "transformer"): + # We are loading in a TransfoXLLMHeadModel => we will load also the Adaptive Softmax + tf_to_pt_map.update( + { + "transformer/adaptive_softmax/cutoff_0/cluster_W": model.crit.cluster_weight, + "transformer/adaptive_softmax/cutoff_0/cluster_b": model.crit.cluster_bias, + } + ) + for i, (out_l, proj_l, tie_proj) in enumerate( + zip(model.crit.out_layers, model.crit.out_projs, config.tie_projs) + ): + layer_str = f"transformer/adaptive_softmax/cutoff_{i}/" + if config.tie_word_embeddings: + tf_to_pt_map.update({layer_str + "b": out_l.bias}) + else: + raise NotImplementedError + # I don't think this is implemented in the TF code + tf_to_pt_map.update({layer_str + "lookup_table": out_l.weight, layer_str + "b": out_l.bias}) + if not tie_proj: + tf_to_pt_map.update({layer_str + "proj": proj_l}) + # Now load the rest of the transformer + model = model.transformer + + # Embeddings + for i, (embed_l, proj_l) in enumerate(zip(model.word_emb.emb_layers, model.word_emb.emb_projs)): + layer_str = f"transformer/adaptive_embed/cutoff_{i}/" + tf_to_pt_map.update({layer_str + "lookup_table": embed_l.weight, layer_str + "proj_W": proj_l}) + + # Transformer blocks + for i, b in enumerate(model.layers): + layer_str = f"transformer/layer_{i}/" + tf_to_pt_map.update( + { + layer_str + "rel_attn/LayerNorm/gamma": b.dec_attn.layer_norm.weight, + layer_str + "rel_attn/LayerNorm/beta": b.dec_attn.layer_norm.bias, + layer_str + "rel_attn/o/kernel": b.dec_attn.o_net.weight, + layer_str + "rel_attn/qkv/kernel": b.dec_attn.qkv_net.weight, + layer_str + "rel_attn/r/kernel": b.dec_attn.r_net.weight, + layer_str + "ff/LayerNorm/gamma": b.pos_ff.layer_norm.weight, + layer_str + "ff/LayerNorm/beta": b.pos_ff.layer_norm.bias, + layer_str + "ff/layer_1/kernel": b.pos_ff.CoreNet[0].weight, + layer_str + "ff/layer_1/bias": b.pos_ff.CoreNet[0].bias, + layer_str + "ff/layer_2/kernel": b.pos_ff.CoreNet[3].weight, + layer_str + "ff/layer_2/bias": b.pos_ff.CoreNet[3].bias, + } + ) + + # Relative positioning biases + if config.untie_r: + r_r_list = [] + r_w_list = [] + for b in model.layers: + r_r_list.append(b.dec_attn.r_r_bias) + r_w_list.append(b.dec_attn.r_w_bias) + else: + r_r_list = [model.r_r_bias] + r_w_list = [model.r_w_bias] + tf_to_pt_map.update({"transformer/r_r_bias": r_r_list, "transformer/r_w_bias": r_w_list}) + return tf_to_pt_map + + +def load_tf_weights_in_transfo_xl(model, config, tf_path): + """Load tf checkpoints in a pytorch model""" + try: + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + # Build TF to PyTorch weights loading map + tf_to_pt_map = build_tf_to_pytorch_map(model, config) + + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + tf_weights = {} + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + tf_weights[name] = array + + for name, pointer in tf_to_pt_map.items(): + assert name in tf_weights + array = tf_weights[name] + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if "kernel" in name or "proj" in name: + array = np.transpose(array) + if ("r_r_bias" in name or "r_w_bias" in name) and len(pointer) > 1: + # Here we will split the TF weights + assert len(pointer) == array.shape[0] + for i, p_i in enumerate(pointer): + arr_i = array[i, ...] + try: + assert p_i.shape == arr_i.shape + except AssertionError as e: + e.args += (p_i.shape, arr_i.shape) + raise + logger.info(f"Initialize PyTorch weight {name} for layer {i}") + p_i.data = torch.from_numpy(arr_i) + else: + try: + assert pointer.shape == array.shape, ( + f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched" + ) + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + tf_weights.pop(name, None) + tf_weights.pop(name + "/Adam", None) + tf_weights.pop(name + "/Adam_1", None) + + logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}") + return model + + def convert_transfo_xl_checkpoint_to_pytorch( tf_checkpoint_path, transfo_xl_config_file, pytorch_dump_folder_path, transfo_xl_dataset_file ): diff --git a/src/transformers/models/deprecated/transfo_xl/modeling_tf_transfo_xl.py b/src/transformers/models/deprecated/transfo_xl/modeling_tf_transfo_xl.py deleted file mode 100644 index 3c7830d63344..000000000000 --- a/src/transformers/models/deprecated/transfo_xl/modeling_tf_transfo_xl.py +++ /dev/null @@ -1,1128 +0,0 @@ -# coding=utf-8 -# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -""" -TF 2.0 Transformer XL model. -""" - -from __future__ import annotations - -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ....modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ....tf_utils import shape_list, stable_softmax -from ....utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_transfo_xl import TransfoXLConfig -from .modeling_tf_transfo_xl_utilities import TFAdaptiveSoftmaxMask - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "transfo-xl/transfo-xl-wt103" -_CONFIG_FOR_DOC = "TransfoXLConfig" - - -class TFPositionalEmbedding(keras.layers.Layer): - def __init__(self, demb, **kwargs): - super().__init__(**kwargs) - - self.inv_freq = 1 / (10000 ** (tf.range(0, demb, 2.0) / demb)) - - def call(self, pos_seq, bsz=None): - self.inv_freq = tf.cast(self.inv_freq, dtype=pos_seq.dtype) - sinusoid_inp = tf.einsum("i,j->ij", pos_seq, self.inv_freq) - pos_emb = tf.concat([tf.sin(sinusoid_inp), tf.cos(sinusoid_inp)], -1) - - if bsz is not None: - return tf.tile(pos_emb[:, None, :], [1, bsz, 1]) - else: - return pos_emb[:, None, :] - - -class TFPositionwiseFF(keras.layers.Layer): - def __init__(self, d_model, d_inner, dropout, pre_lnorm=False, layer_norm_epsilon=1e-5, init_std=0.02, **kwargs): - super().__init__(**kwargs) - - self.d_model = d_model - self.d_inner = d_inner - self.dropout = dropout - - self.layer_1 = keras.layers.Dense( - d_inner, kernel_initializer=get_initializer(init_std), activation=tf.nn.relu, name="CoreNet_._0" - ) - self.drop_1 = keras.layers.Dropout(dropout) - self.layer_2 = keras.layers.Dense(d_model, kernel_initializer=get_initializer(init_std), name="CoreNet_._3") - self.drop_2 = keras.layers.Dropout(dropout) - - self.layer_norm = keras.layers.LayerNormalization(epsilon=layer_norm_epsilon, name="layer_norm") - - self.pre_lnorm = pre_lnorm - - def call(self, inp, training=False): - if self.pre_lnorm: - # layer normalization + positionwise feed-forward - core_out = self.layer_norm(inp) - core_out = self.layer_1(core_out) - core_out = self.drop_1(core_out, training=training) - core_out = self.layer_2(core_out) - core_out = self.drop_2(core_out, training=training) - - # residual connection - output = core_out + inp - else: - # positionwise feed-forward - core_out = self.layer_1(inp) - core_out = self.drop_1(core_out, training=training) - core_out = self.layer_2(core_out) - core_out = self.drop_2(core_out, training=training) - - # residual connection + layer normalization - output = self.layer_norm(inp + core_out) - - return output - - -class TFRelPartialLearnableMultiHeadAttn(keras.layers.Layer): - def __init__( - self, - n_head, - d_model, - d_head, - dropout, - dropatt=0.0, - pre_lnorm=False, - r_r_bias=None, - r_w_bias=None, - layer_norm_epsilon=1e-5, - init_std=0.02, - output_attentions=False, - **kwargs, - ): - super().__init__(**kwargs) - - self.n_head = n_head - self.d_model = d_model - self.d_head = d_head - self.dropout = dropout - self.output_attentions = output_attentions - - self.qkv_net = keras.layers.Dense( - 3 * n_head * d_head, kernel_initializer=get_initializer(init_std), use_bias=False, name="qkv_net" - ) - - self.drop = keras.layers.Dropout(dropout) - self.dropatt = keras.layers.Dropout(dropatt) - self.o_net = keras.layers.Dense( - d_model, kernel_initializer=get_initializer(init_std), use_bias=False, name="o_net" - ) - - self.layer_norm = keras.layers.LayerNormalization(epsilon=layer_norm_epsilon, name="layer_norm") - - self.scale = 1 / (d_head**0.5) - - self.pre_lnorm = pre_lnorm - - if r_r_bias is not None and r_w_bias is not None: # Biases are shared - self.r_r_bias = r_r_bias - self.r_w_bias = r_w_bias - else: - self.r_r_bias = None - self.r_w_bias = None - - self.r_net = keras.layers.Dense( - self.n_head * self.d_head, kernel_initializer=get_initializer(init_std), use_bias=False, name="r_net" - ) - - def build(self, input_shape): - if self.r_r_bias is None or self.r_w_bias is None: # Biases are not shared - self.r_r_bias = self.add_weight( - shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_r_bias" - ) - self.r_w_bias = self.add_weight( - shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_w_bias" - ) - super().build(input_shape) - - def _rel_shift(self, x): - x_size = shape_list(x) - - x = tf.pad(x, [[0, 0], [1, 0], [0, 0], [0, 0]]) - x = tf.reshape(x, [x_size[1] + 1, x_size[0], x_size[2], x_size[3]]) - x = tf.slice(x, [1, 0, 0, 0], [-1, -1, -1, -1]) - x = tf.reshape(x, x_size) - - return x - - def call(self, w, r, attn_mask, mems, head_mask, output_attentions, training=False): - qlen, rlen, bsz = shape_list(w)[0], shape_list(r)[0], shape_list(w)[1] - - if mems is not None: - mems = tf.cast(mems, dtype=w.dtype) - cat = tf.concat([mems, w], 0) - if self.pre_lnorm: - w_heads = self.qkv_net(self.layer_norm(cat)) - else: - w_heads = self.qkv_net(cat) - r_head_k = self.r_net(r) - - w_head_q, w_head_k, w_head_v = tf.split(w_heads, 3, axis=-1) - w_head_q = w_head_q[-qlen:] - else: - if self.pre_lnorm: - w_heads = self.qkv_net(self.layer_norm(w)) - else: - w_heads = self.qkv_net(w) - r_head_k = self.r_net(r) - - w_head_q, w_head_k, w_head_v = tf.split(w_heads, 3, axis=-1) - - klen = shape_list(w_head_k)[0] - - w_head_q = tf.reshape(w_head_q, (qlen, bsz, self.n_head, self.d_head)) # qlen x bsz x n_head x d_head - w_head_k = tf.reshape(w_head_k, (klen, bsz, self.n_head, self.d_head)) # qlen x bsz x n_head x d_head - w_head_v = tf.reshape(w_head_v, (klen, bsz, self.n_head, self.d_head)) # qlen x bsz x n_head x d_head - - r_head_k = tf.reshape(r_head_k, (rlen, self.n_head, self.d_head)) # qlen x n_head x d_head - - # compute attention score - rw_head_q = w_head_q + self.r_w_bias # qlen x bsz x n_head x d_head - AC = tf.einsum("ibnd,jbnd->ijbn", rw_head_q, w_head_k) # qlen x klen x bsz x n_head - - rr_head_q = w_head_q + self.r_r_bias - BD = tf.einsum("ibnd,jnd->ijbn", rr_head_q, r_head_k) # qlen x klen x bsz x n_head - BD = self._rel_shift(BD) - - # [qlen x klen x bsz x n_head] - attn_score = AC + BD - attn_score = attn_score * self.scale - - # compute attention probability - if attn_mask is not None: - attn_mask_t = attn_mask[:, :, None, None] - attn_mask_t = tf.cast(attn_mask_t, dtype=attn_score.dtype) - attn_score = attn_score * (1.0 - attn_mask_t) - 1e30 * attn_mask_t - - # [qlen x klen x bsz x n_head] - attn_prob = stable_softmax(attn_score, axis=1) - attn_prob = self.dropatt(attn_prob, training=training) - - # Mask heads if we want to - if head_mask is not None: - attn_prob = attn_prob * head_mask - - # compute attention vector - attn_vec = tf.einsum("ijbn,jbnd->ibnd", attn_prob, w_head_v) - - # [qlen x bsz x n_head x d_head] - attn_vec_sizes = shape_list(attn_vec) - attn_vec = tf.reshape(attn_vec, (attn_vec_sizes[0], attn_vec_sizes[1], self.n_head * self.d_head)) - - # linear projection - attn_out = self.o_net(attn_vec) - attn_out = self.drop(attn_out, training=training) - - if self.pre_lnorm: - # residual connection - outputs = [w + attn_out] - else: - # residual connection + layer normalization - outputs = [self.layer_norm(w + attn_out)] - - if output_attentions: - outputs.append(attn_prob) - - return outputs - - -class TFRelPartialLearnableDecoderLayer(keras.layers.Layer): - def __init__( - self, - n_head, - d_model, - d_head, - d_inner, - dropout, - dropatt=0.0, - pre_lnorm=False, - r_w_bias=None, - r_r_bias=None, - layer_norm_epsilon=1e-5, - init_std=0.02, - output_attentions=False, - **kwargs, - ): - super().__init__(**kwargs) - - self.dec_attn = TFRelPartialLearnableMultiHeadAttn( - n_head, - d_model, - d_head, - dropout, - dropatt=dropatt, - pre_lnorm=pre_lnorm, - r_w_bias=r_w_bias, - r_r_bias=r_r_bias, - init_std=init_std, - layer_norm_epsilon=layer_norm_epsilon, - output_attentions=output_attentions, - name="dec_attn", - ) - self.pos_ff = TFPositionwiseFF( - d_model, - d_inner, - dropout, - pre_lnorm=pre_lnorm, - init_std=init_std, - layer_norm_epsilon=layer_norm_epsilon, - name="pos_ff", - ) - - def call(self, dec_inp, r, dec_attn_mask, mems, head_mask, output_attentions, training=False): - attn_outputs = self.dec_attn(dec_inp, r, dec_attn_mask, mems, head_mask, output_attentions, training=training) - ff_output = self.pos_ff(attn_outputs[0], training=training) - - outputs = [ff_output] + attn_outputs[1:] - - return outputs - - -class TFTransfoEmbeddings(keras.layers.Layer): - def __init__(self, vocab_size, emb_size, init_std, **kwargs): - super().__init__(**kwargs) - - self.vocab_size = vocab_size - self.emb_size = emb_size - self.init_std = init_std - - def build(self, input_shape): - self.weight = self.add_weight( - shape=(self.vocab_size, self.emb_size), - initializer=get_initializer(self.init_std), - name="embeddings", - ) - - super().build(input_shape) - - def call(self, inputs): - return tf.gather(self.weight, inputs) - - -class TFAdaptiveEmbedding(keras.layers.Layer): - def __init__(self, n_token, d_embed, d_proj, cutoffs, div_val=1, init_std=0.02, sample_softmax=False, **kwargs): - super().__init__(**kwargs) - - self.n_token = n_token - self.d_embed = d_embed - self.init_std = init_std - - self.cutoffs = cutoffs + [n_token] - self.div_val = div_val - self.d_proj = d_proj - - self.emb_scale = d_proj**0.5 - - self.cutoff_ends = [0] + self.cutoffs - - self.emb_layers = [] - self.emb_projs = [] - - if div_val == 1: - raise NotImplementedError # Removed these to avoid maintaining dead code - They are not used in our pretrained checkpoint - else: - for i in range(len(self.cutoffs)): - l_idx, r_idx = self.cutoff_ends[i], self.cutoff_ends[i + 1] - d_emb_i = d_embed // (div_val**i) - self.emb_layers.append( - TFTransfoEmbeddings( - r_idx - l_idx, - d_emb_i, - init_std, - name=f"emb_layers_._{i}", - ) - ) - - def build(self, input_shape): - for i in range(len(self.cutoffs)): - d_emb_i = self.d_embed // (self.div_val**i) - self.emb_projs.append( - self.add_weight( - shape=(d_emb_i, self.d_proj), - initializer=get_initializer(self.init_std), - trainable=True, - name=f"emb_projs_._{i}", - ) - ) - - super().build(input_shape) - - def call(self, inp): - if self.div_val == 1: - raise NotImplementedError # Removed these to avoid maintaining dead code - They are not used in our pretrained checkpoint - else: - inp_flat = tf.reshape(inp, (-1,)) - emb_flat = tf.zeros([shape_list(inp_flat)[0], self.d_proj]) - for i in range(len(self.cutoffs)): - l_idx, r_idx = self.cutoff_ends[i], self.cutoff_ends[i + 1] - - mask_i = (inp_flat >= l_idx) & (inp_flat < r_idx) - - inp_i = tf.boolean_mask(inp_flat, mask_i) - l_idx - emb_i = self.emb_layers[i](inp_i) - emb_i = tf.einsum("id,de->ie", emb_i, self.emb_projs[i]) - - mask_idx = tf.where(mask_i) - scatter = tf.scatter_nd(mask_idx, emb_i, shape_list(emb_flat)) - emb_flat = tf.cast(emb_flat, dtype=scatter.dtype) - emb_flat += scatter - - embed_shape = shape_list(inp) + [self.d_proj] - embed = tf.reshape(emb_flat, embed_shape) - - embed *= self.emb_scale - - return embed - - -@keras_serializable -class TFTransfoXLMainLayer(keras.layers.Layer): - config_class = TransfoXLConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.output_hidden_states = config.output_hidden_states - self.output_attentions = config.output_attentions - self.return_dict = config.use_return_dict - - self.n_token = config.vocab_size - - self.d_embed = config.d_embed - self.d_model = config.d_model - self.n_head = config.n_head - self.d_head = config.d_head - self.untie_r = config.untie_r - - self.word_emb = TFAdaptiveEmbedding( - config.vocab_size, - config.d_embed, - config.d_model, - config.cutoffs, - div_val=config.div_val, - init_std=config.init_std, - name="word_emb", - ) - - self.drop = keras.layers.Dropout(config.dropout) - - self.n_layer = config.n_layer - self.mem_len = config.mem_len - self.attn_type = config.attn_type - - self.layers = [] - if config.attn_type == 0: # the default attention - for i in range(config.n_layer): - self.layers.append( - TFRelPartialLearnableDecoderLayer( - config.n_head, - config.d_model, - config.d_head, - config.d_inner, - config.dropout, - dropatt=config.dropatt, - pre_lnorm=config.pre_lnorm, - r_w_bias=None if self.untie_r else self.r_w_bias, - r_r_bias=None if self.untie_r else self.r_r_bias, - layer_norm_epsilon=config.layer_norm_epsilon, - init_std=config.init_std, - output_attentions=self.output_attentions, - name=f"layers_._{i}", - ) - ) - else: # learnable embeddings and absolute embeddings - raise NotImplementedError # Removed these to avoid maintaining dead code - They are not used in our pretrained checkpoint - - self.same_length = config.same_length - self.clamp_len = config.clamp_len - - if self.attn_type == 0: # default attention - self.pos_emb = TFPositionalEmbedding(self.d_model, name="pos_emb") - else: # learnable embeddings and absolute embeddings - raise NotImplementedError # Removed these to avoid maintaining dead code - They are not used in our pretrained checkpoint - - def build(self, input_shape): - if not self.untie_r: - self.r_w_bias = self.add_weight( - shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_w_bias" - ) - self.r_r_bias = self.add_weight( - shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_r_bias" - ) - super().build(input_shape) - - def get_input_embeddings(self): - return self.word_emb - - def set_input_embeddings(self, value): - raise NotImplementedError - - def backward_compatible(self): - self.sample_softmax = -1 - - def reset_memory_length(self, mem_len): - self.mem_len = mem_len - - def _prune_heads(self, heads): - raise NotImplementedError - - def init_mems(self, bsz): - if self.mem_len > 0: - mems = [] - for i in range(self.n_layer): - empty = tf.zeros([self.mem_len, bsz, self.d_model]) - mems.append(empty) - - return mems - else: - return None - - def _update_mems(self, hids, mems, mlen, qlen): - # does not deal with None - if mems is None: - return None - - # mems is not None - assert len(hids) == len(mems), "len(hids) != len(mems)" - - # There are `mlen + qlen` steps that can be cached into mems - new_mems = [] - end_idx = mlen + tf.math.maximum(0, qlen) - beg_idx = tf.math.maximum(0, end_idx - tf.convert_to_tensor(self.mem_len)) - for i in range(len(hids)): - mems[i] = tf.cast(mems[i], dtype=hids[i].dtype) - cat = tf.concat([mems[i], hids[i]], axis=0) - tf.stop_gradient(cat) - new_mems.append(cat[beg_idx:end_idx]) - - return new_mems - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - mems: list[tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ): - # the original code for Transformer-XL used shapes [len, bsz] but we want a unified interface in the library - # so we transpose here from shape [bsz, len] to shape [len, bsz] - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_ids = tf.transpose(input_ids, perm=(1, 0)) - qlen, bsz = shape_list(input_ids) - elif inputs_embeds is not None: - inputs_embeds = tf.transpose(inputs_embeds, perm=(1, 0, 2)) - qlen, bsz = shape_list(inputs_embeds)[:2] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if mems is None: - mems = self.init_mems(bsz) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] (a head_mask for each layer) - # and head_mask is converted to shape [num_hidden_layers x qlen x klen x bsz x n_head] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.n_layer - - if inputs_embeds is not None: - word_emb = inputs_embeds - else: - word_emb = self.word_emb(input_ids) - - mlen = shape_list(mems[0])[0] if mems is not None else 0 - klen = mlen + qlen - - # Compute decoder attention mask - all_ones = tf.ones([qlen, klen], dtype=tf.int32) - upper_mask = 1 - tf.linalg.band_part(tf.ones([qlen, klen], dtype=tf.int32), -1, mlen) - if self.same_length: - mask_len = klen - self.mem_len - mask_shift_len = qlen - tf.nn.relu(mask_len) # Lazy clamping of negatives to zero - - # Use an indicator variable instead of a conditional to keep the compiler happy - lower_mask = tf.linalg.band_part(all_ones, -1, 0) - ( - tf.linalg.band_part(all_ones, mask_shift_len - 1, 0) * tf.cast(mask_shift_len != 0, tf.int32) - ) - dec_attn_mask = upper_mask + lower_mask - else: - dec_attn_mask = upper_mask - - hids = [] - attentions = [] if output_attentions else None - if self.attn_type == 0: # default - pos_seq = tf.range(klen - 1, -1, -1.0) - if self.clamp_len > 0: - pos_seq = tf.minimum(pos_seq, self.clamp_len) - pos_emb = self.pos_emb(pos_seq) - - core_out = self.drop(word_emb, training=training) - pos_emb = self.drop(pos_emb, training=training) - - for i, layer in enumerate(self.layers): - hids.append(core_out) - mems_i = None if mems is None else mems[i] - layer_outputs = layer( - core_out, - pos_emb, - dec_attn_mask, - mems_i, - head_mask[i], - output_attentions, - training=training, - ) - core_out = layer_outputs[0] - if output_attentions: - attentions.append(layer_outputs[1]) - else: # learnable embeddings and absolute embeddings - raise NotImplementedError # Removed these to avoid maintaining dead code - They are not used in our pretrained checkpoint - - core_out = self.drop(core_out, training=training) - - new_mems = self._update_mems(hids, mems, mlen, qlen) - - # We transpose back here to shape [bsz, len, hidden_dim] - core_out = tf.transpose(core_out, perm=(1, 0, 2)) - - if output_hidden_states: - # Transpose to library standard shape [bsz, len, hidden_dim] and add last layer - hids = tuple(tf.transpose(t, perm=(1, 0, 2)) for t in hids) - hids = hids + (core_out,) - else: - hids = None - if output_attentions: - # Transpose to library standard shape [bsz, n_heads, query_seq_len, key_seq_len] - attentions = tuple(tf.transpose(t, perm=(2, 3, 0, 1)) for t in attentions) - - if not return_dict: - return tuple(v for v in [core_out, new_mems, hids, attentions] if v is not None) - - return TFTransfoXLModelOutput( - last_hidden_state=core_out, - mems=new_mems, - hidden_states=hids, - attentions=attentions, - ) - - -class TFTransfoXLPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = TransfoXLConfig - base_model_prefix = "transformer" - - -@dataclass -class TFTransfoXLModelOutput(ModelOutput): - """ - Base class for model's outputs that may also contain a past key/values (to speed up sequential decoding). - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - mems (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states (key and values in the attention blocks). Can be used (see `mems` - input) to speed up sequential decoding. The token ids which have their past given to this model should not - be passed as input ids as they have already been computed. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: tf.Tensor | None = None - mems: list[tf.Tensor] = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFTransfoXLLMHeadModelOutput(ModelOutput): - """ - Base class for model's outputs that may also contain a past key/values (to speed up sequential decoding). - - Args: - losses (`tf.Tensor` of shape *(batch_size, sequence_length-1)*, *optional*, returned when `labels` is provided): - Language modeling losses (not reduced). - prediction_scores (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token after SoftMax). - mems (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states (key and values in the attention blocks). Can be used (see `mems` - input) to speed up sequential decoding. The token ids which have their past given to this model should not - be passed as input ids as they have already been computed. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - prediction_scores: tf.Tensor | None = None - mems: list[tf.Tensor] = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFTransfoXLSequenceClassifierOutputWithPast(ModelOutput): - """ - Base class for outputs of sentence classification models. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - mems (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states (key and values in the attention blocks). Can be used (see `mems` - input) to speed up sequential decoding. The token ids which have their past given to this model should not - be passed as input ids as they have already been computed. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - mems: list[tf.Tensor] = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -TRANSFO_XL_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`TransfoXLConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -TRANSFO_XL_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - mems (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states (key and values in the attention blocks) as computed by the model (see - `mems` output below). Can be used to speed up sequential decoding. The token ids which have their mems - given to this model should not be passed as `input_ids` as they have already been computed. - head_mask (`tf.Tensor` or `Numpy array` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - inputs_embeds (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare Bert Model transformer outputting raw hidden-states without any specific head on top.", - TRANSFO_XL_START_DOCSTRING, -) -class TFTransfoXLModel(TFTransfoXLPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFTransfoXLMainLayer(config, name="transformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(TRANSFO_XL_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTransfoXLModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - mems: list[tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFTransfoXLModelOutput | tuple[tf.Tensor]: - outputs = self.transformer( - input_ids=input_ids, - mems=mems, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - -@add_start_docstrings( - """ - The Transformer-XL Model with a language modeling head on top (adaptive softmax with weights tied to the adaptive - input embeddings) - """, - TRANSFO_XL_START_DOCSTRING, -) -class TFTransfoXLLMHeadModel(TFTransfoXLPreTrainedModel): - def __init__(self, config): - super().__init__(config) - self.transformer = TFTransfoXLMainLayer(config, name="transformer") - self.sample_softmax = config.sample_softmax - assert self.sample_softmax <= 0, ( - "Sampling from the softmax is not implemented yet. Please look at issue: #3310:" - " https://github.com/huggingface/transformers/issues/3310" - ) - - self.crit = TFAdaptiveSoftmaxMask( - config.vocab_size, config.d_embed, config.d_model, config.cutoffs, div_val=config.div_val, name="crit" - ) - - def _resize_token_embeddings(self, new_num_tokens): - raise NotImplementedError() - - def get_output_embeddings(self): - """Double-check if you are using adaptive softmax.""" - if len(self.crit.out_layers) > 0: - return self.crit.out_layers[-1] - return None - - def reset_memory_length(self, mem_len): - self.transformer.reset_memory_length(mem_len) - - def init_mems(self, bsz): - return self.transformer.init_mems(bsz) - - @unpack_inputs - @add_start_docstrings_to_model_forward(TRANSFO_XL_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTransfoXLLMHeadModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - mems: list[tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFTransfoXLLMHeadModelOutput | tuple[tf.Tensor]: - if input_ids is not None: - bsz, tgt_len = shape_list(input_ids)[:2] - else: - bsz, tgt_len = shape_list(inputs_embeds)[:2] - - transformer_outputs = self.transformer( - input_ids, - mems, - head_mask, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict, - training=training, - ) - - last_hidden = transformer_outputs[0] - pred_hid = last_hidden[:, -tgt_len:] - - softmax_output = self.crit(pred_hid, labels, training=training) - prediction_scores = softmax_output if labels is None else () - - if not return_dict: - return (prediction_scores,) + transformer_outputs[1:] - - return TFTransfoXLLMHeadModelOutput( - prediction_scores=prediction_scores, - mems=transformer_outputs.mems, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def prepare_inputs_for_generation(self, input_ids, past_key_values=None, **model_kwargs): - inputs = {} - - # if past is defined in model kwargs then use it for faster decoding - if past_key_values: - input_ids = tf.expand_dims(input_ids[:, -1], axis=-1) - else: - input_ids = input_ids - - return inputs - - # Adapted from the torch tie_weights function - def tf_to_pt_weight_rename(self, tf_weight): - if self.config.tie_word_embeddings and "crit.out_layers" in tf_weight: - return tf_weight, tf_weight.replace("crit.out_layers", "transformer.word_emb.emb_layers") - elif self.config.tie_projs and "crit.out_projs" in tf_weight: - for i, tie_proj in enumerate(self.config.tie_projs): - if tie_proj and self.config.div_val == 1 and self.config.d_model != self.config.d_embed: - # self.crit.out_projs[i] = self.transformer.word_emb.emb_projs[0] - return tf_weight, tf_weight.replace(f"crit.out_projs.{i}", "transformer.word_emb.emb_projs.0") - elif tie_proj and self.config.div_val != 1: - # self.crit.out_projs[i] = self.transformer.word_emb.emb_projs[i] - return tf_weight, tf_weight.replace("crit.out_projs", "transformer.word_emb.emb_projs") - else: - return (tf_weight,) - - -@add_start_docstrings( - """ - The Transfo XL Model transformer with a sequence classification head on top (linear layer). - - [`TFTransfoXLForSequenceClassification`] uses the last token in order to do the classification, as other causal - models (e.g. GPT-1,GPT-2) do. - - Since it does classification on the last token, it requires to know the position of the last token. If a - `pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If - no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the - padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in - each row of the batch). - """, - TRANSFO_XL_START_DOCSTRING, -) -class TFTransfoXLForSequenceClassification(TFTransfoXLPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.score = keras.layers.Dense( - config.num_labels, - kernel_initializer=get_initializer(config.init_range), - name="score", - use_bias=False, - ) - self.transformer = TFTransfoXLMainLayer(config, name="transformer") - - def get_output_embeddings(self): - # Remove after transformers v4.32. Fix this model's `test_model_common_attributes` test too. - logger.warning( - "Sequence classification models do not have output embeddings. `.get_output_embeddings` will be removed " - "in transformers v4.32." - ) - return self.transformer.word_emb - - @unpack_inputs - @add_start_docstrings_to_model_forward(TRANSFO_XL_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTransfoXLSequenceClassifierOutputWithPast, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - mems: list[tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFTransfoXLSequenceClassifierOutputWithPast: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - mems=mems, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - hidden_states = transformer_outputs[0] - logits = self.score(hidden_states) - in_logits = None - if self.config.pad_token_id is None: - sequence_lengths = -1 - else: - if input_ids is not None: - sequence_lengths = ( - tf.argmax(tf.cast(tf.math.equal(input_ids, self.config.pad_token_id), input_ids.dtype), axis=-1) - - 1 - ) - sequence_lengths = tf.where(sequence_lengths >= 0, sequence_lengths, input_ids.shape[-1] - 1) - in_logits = tf.gather(logits, sequence_lengths, batch_dims=1, axis=1) - else: - sequence_lengths = -1 - logger.warning_once( - f"{self.__class__.__name__} will not detect padding tokens in `inputs_embeds`. Results may be " - "unexpected if using padding tokens in conjunction with `inputs_embeds.`" - ) - loss = None - - if labels is not None: - if input_ids is not None: - batch_size, sequence_length = shape_list(input_ids)[:2] - else: - batch_size, sequence_length = shape_list(inputs_embeds)[:2] - assert self.config.pad_token_id is not None or batch_size == 1, ( - "Cannot handle batch sizes > 1 if no padding token is defined." - ) - - if not tf.is_tensor(sequence_lengths): - in_logits = logits[0:batch_size, sequence_lengths] - - loss = self.hf_compute_loss(tf.reshape(labels, [-1, 1]), tf.reshape(in_logits, [-1, self.num_labels])) - - pooled_logits = in_logits if in_logits is not None else logits - - if not return_dict: - output = (pooled_logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTransfoXLSequenceClassifierOutputWithPast( - loss=loss, - logits=pooled_logits, - mems=transformer_outputs.mems, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - -__all__ = [ - "TFAdaptiveEmbedding", - "TFTransfoXLForSequenceClassification", - "TFTransfoXLLMHeadModel", - "TFTransfoXLMainLayer", - "TFTransfoXLModel", - "TFTransfoXLPreTrainedModel", -] diff --git a/src/transformers/models/deprecated/transfo_xl/modeling_tf_transfo_xl_utilities.py b/src/transformers/models/deprecated/transfo_xl/modeling_tf_transfo_xl_utilities.py deleted file mode 100644 index 48205e06fb20..000000000000 --- a/src/transformers/models/deprecated/transfo_xl/modeling_tf_transfo_xl_utilities.py +++ /dev/null @@ -1,178 +0,0 @@ -# coding=utf-8 -# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -""" -A TF 2.0 Adaptive Softmax for Transformer XL model. -""" - -import tensorflow as tf - -from ....modeling_tf_utils import keras -from ....tf_utils import shape_list - - -class TFAdaptiveSoftmaxMask(keras.layers.Layer): - def __init__(self, vocab_size, d_embed, d_proj, cutoffs, div_val=1, keep_order=False, **kwargs): - super().__init__(**kwargs) - - self.vocab_size = vocab_size - self.d_embed = d_embed - self.d_proj = d_proj - - self.cutoffs = cutoffs + [vocab_size] - self.cutoff_ends = [0] + self.cutoffs - self.div_val = div_val - - self.shortlist_size = self.cutoffs[0] - self.n_clusters = len(self.cutoffs) - 1 - self.head_size = self.shortlist_size + self.n_clusters - self.keep_order = keep_order - - self.out_layers = [] - self.out_projs = [] - - def build(self, input_shape): - if self.n_clusters > 0: - self.cluster_weight = self.add_weight( - shape=(self.n_clusters, self.d_embed), initializer="zeros", trainable=True, name="cluster_weight" - ) - self.cluster_bias = self.add_weight( - shape=(self.n_clusters,), initializer="zeros", trainable=True, name="cluster_bias" - ) - - if self.div_val == 1: - for i in range(len(self.cutoffs)): - if self.d_proj != self.d_embed: - weight = self.add_weight( - shape=(self.d_embed, self.d_proj), - initializer="zeros", - trainable=True, - name=f"out_projs_._{i}", - ) - self.out_projs.append(weight) - else: - self.out_projs.append(None) - weight = self.add_weight( - shape=(self.vocab_size, self.d_embed), - initializer="zeros", - trainable=True, - name=f"out_layers_._{i}_._weight", - ) - bias = self.add_weight( - shape=(self.vocab_size,), - initializer="zeros", - trainable=True, - name=f"out_layers_._{i}_._bias", - ) - self.out_layers.append((weight, bias)) - else: - for i in range(len(self.cutoffs)): - l_idx, r_idx = self.cutoff_ends[i], self.cutoff_ends[i + 1] - d_emb_i = self.d_embed // (self.div_val**i) - - weight = self.add_weight( - shape=(d_emb_i, self.d_proj), initializer="zeros", trainable=True, name=f"out_projs_._{i}" - ) - self.out_projs.append(weight) - weight = self.add_weight( - shape=(r_idx - l_idx, d_emb_i), - initializer="zeros", - trainable=True, - name=f"out_layers_._{i}_._weight", - ) - bias = self.add_weight( - shape=(r_idx - l_idx,), - initializer="zeros", - trainable=True, - name=f"out_layers_._{i}_._bias", - ) - self.out_layers.append((weight, bias)) - super().build(input_shape) - - @staticmethod - def _logit(x, W, b, proj=None): - y = x - if proj is not None: - y = tf.einsum("ibd,ed->ibe", y, proj) - return tf.einsum("ibd,nd->ibn", y, W) + b - - @staticmethod - def _gather_logprob(logprob, target): - lp_size = shape_list(logprob) - r = tf.range(lp_size[0], dtype=target.dtype) - idx = tf.stack([r, target], 1) - return tf.gather_nd(logprob, idx) - - def call(self, hidden, target, return_mean=True, training=False): - head_logprob = 0 - if self.n_clusters == 0: - output = self._logit(hidden, self.out_layers[0][0], self.out_layers[0][1], self.out_projs[0]) - if target is not None: - loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=target, logits=output) - out = tf.nn.log_softmax(output, axis=-1) - else: - hidden_sizes = shape_list(hidden) - out = [] - loss = tf.zeros(hidden_sizes[:2]) - for i in range(len(self.cutoffs)): - l_idx, r_idx = self.cutoff_ends[i], self.cutoff_ends[i + 1] - if target is not None: - mask = (target >= l_idx) & (target < r_idx) - mask_idx = tf.where(mask) - cur_target = tf.boolean_mask(target, mask) - l_idx - - if self.div_val == 1: - cur_W = self.out_layers[0][0][l_idx:r_idx] - cur_b = self.out_layers[0][1][l_idx:r_idx] - else: - cur_W = self.out_layers[i][0] - cur_b = self.out_layers[i][1] - - if i == 0: - cur_W = tf.concat([cur_W, self.cluster_weight], 0) - cur_b = tf.concat([cur_b, self.cluster_bias], 0) - - head_logit = self._logit(hidden, cur_W, cur_b, self.out_projs[0]) - head_logprob = tf.nn.log_softmax(head_logit) - out.append(head_logprob[..., : self.cutoffs[0]]) - if target is not None: - cur_head_logprob = tf.boolean_mask(head_logprob, mask) - cur_logprob = self._gather_logprob(cur_head_logprob, cur_target) - else: - tail_logit = self._logit(hidden, cur_W, cur_b, self.out_projs[i]) - tail_logprob = tf.nn.log_softmax(tail_logit) - cluster_prob_idx = self.cutoffs[0] + i - 1 # No probability for the head cluster - logprob_i = head_logprob[..., cluster_prob_idx, None] + tail_logprob - out.append(logprob_i) - if target is not None: - cur_head_logprob = tf.boolean_mask(head_logprob, mask) - cur_tail_logprob = tf.boolean_mask(tail_logprob, mask) - cur_logprob = self._gather_logprob(cur_tail_logprob, cur_target) - cur_logprob += cur_head_logprob[:, self.cutoff_ends[1] + i - 1] - if target is not None: - loss += tf.scatter_nd(mask_idx, -cur_logprob, shape_list(loss)) - out = tf.concat(out, axis=-1) - - if target is not None: - if return_mean: - loss = tf.reduce_mean(loss) - # Add the training-time loss value to the layer using `self.add_loss()`. - self.add_loss(loss) - - # Log the loss as a metric (we could log arbitrary metrics, - # including different metrics for training and inference. - self.add_metric(loss, name=self.name, aggregation="mean" if return_mean else "") - - return out diff --git a/src/transformers/models/deprecated/transfo_xl/modeling_transfo_xl.py b/src/transformers/models/deprecated/transfo_xl/modeling_transfo_xl.py index 19c3fb0bd485..a7b4825e5fcd 100644 --- a/src/transformers/models/deprecated/transfo_xl/modeling_transfo_xl.py +++ b/src/transformers/models/deprecated/transfo_xl/modeling_transfo_xl.py @@ -44,133 +44,6 @@ _CONFIG_FOR_DOC = "TransfoXLConfig" -def build_tf_to_pytorch_map(model, config): - """ - A map of modules from TF to PyTorch. This time I use a map to keep the PyTorch model as identical to the original - PyTorch model as possible. - """ - tf_to_pt_map = {} - - if hasattr(model, "transformer"): - # We are loading in a TransfoXLLMHeadModel => we will load also the Adaptive Softmax - tf_to_pt_map.update( - { - "transformer/adaptive_softmax/cutoff_0/cluster_W": model.crit.cluster_weight, - "transformer/adaptive_softmax/cutoff_0/cluster_b": model.crit.cluster_bias, - } - ) - for i, (out_l, proj_l, tie_proj) in enumerate( - zip(model.crit.out_layers, model.crit.out_projs, config.tie_projs) - ): - layer_str = f"transformer/adaptive_softmax/cutoff_{i}/" - if config.tie_word_embeddings: - tf_to_pt_map.update({layer_str + "b": out_l.bias}) - else: - raise NotImplementedError - # I don't think this is implemented in the TF code - tf_to_pt_map.update({layer_str + "lookup_table": out_l.weight, layer_str + "b": out_l.bias}) - if not tie_proj: - tf_to_pt_map.update({layer_str + "proj": proj_l}) - # Now load the rest of the transformer - model = model.transformer - - # Embeddings - for i, (embed_l, proj_l) in enumerate(zip(model.word_emb.emb_layers, model.word_emb.emb_projs)): - layer_str = f"transformer/adaptive_embed/cutoff_{i}/" - tf_to_pt_map.update({layer_str + "lookup_table": embed_l.weight, layer_str + "proj_W": proj_l}) - - # Transformer blocks - for i, b in enumerate(model.layers): - layer_str = f"transformer/layer_{i}/" - tf_to_pt_map.update( - { - layer_str + "rel_attn/LayerNorm/gamma": b.dec_attn.layer_norm.weight, - layer_str + "rel_attn/LayerNorm/beta": b.dec_attn.layer_norm.bias, - layer_str + "rel_attn/o/kernel": b.dec_attn.o_net.weight, - layer_str + "rel_attn/qkv/kernel": b.dec_attn.qkv_net.weight, - layer_str + "rel_attn/r/kernel": b.dec_attn.r_net.weight, - layer_str + "ff/LayerNorm/gamma": b.pos_ff.layer_norm.weight, - layer_str + "ff/LayerNorm/beta": b.pos_ff.layer_norm.bias, - layer_str + "ff/layer_1/kernel": b.pos_ff.CoreNet[0].weight, - layer_str + "ff/layer_1/bias": b.pos_ff.CoreNet[0].bias, - layer_str + "ff/layer_2/kernel": b.pos_ff.CoreNet[3].weight, - layer_str + "ff/layer_2/bias": b.pos_ff.CoreNet[3].bias, - } - ) - - # Relative positioning biases - if config.untie_r: - r_r_list = [] - r_w_list = [] - for b in model.layers: - r_r_list.append(b.dec_attn.r_r_bias) - r_w_list.append(b.dec_attn.r_w_bias) - else: - r_r_list = [model.r_r_bias] - r_w_list = [model.r_w_bias] - tf_to_pt_map.update({"transformer/r_r_bias": r_r_list, "transformer/r_w_bias": r_w_list}) - return tf_to_pt_map - - -def load_tf_weights_in_transfo_xl(model, config, tf_path): - """Load tf checkpoints in a pytorch model""" - try: - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - # Build TF to PyTorch weights loading map - tf_to_pt_map = build_tf_to_pytorch_map(model, config) - - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - tf_weights = {} - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - tf_weights[name] = array - - for name, pointer in tf_to_pt_map.items(): - assert name in tf_weights - array = tf_weights[name] - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if "kernel" in name or "proj" in name: - array = np.transpose(array) - if ("r_r_bias" in name or "r_w_bias" in name) and len(pointer) > 1: - # Here we will split the TF weights - assert len(pointer) == array.shape[0] - for i, p_i in enumerate(pointer): - arr_i = array[i, ...] - try: - assert p_i.shape == arr_i.shape - except AssertionError as e: - e.args += (p_i.shape, arr_i.shape) - raise - logger.info(f"Initialize PyTorch weight {name} for layer {i}") - p_i.data = torch.from_numpy(arr_i) - else: - try: - assert pointer.shape == array.shape, ( - f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched" - ) - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - tf_weights.pop(name, None) - tf_weights.pop(name + "/Adam", None) - tf_weights.pop(name + "/Adam_1", None) - - logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}") - return model - - class PositionalEmbedding(nn.Module): def __init__(self, demb): super().__init__() @@ -459,7 +332,6 @@ class TransfoXLPreTrainedModel(PreTrainedModel): """ config: TransfoXLConfig - load_tf_weights = load_tf_weights_in_transfo_xl base_model_prefix = "transformer" def _init_weight(self, weight): @@ -1299,5 +1171,4 @@ def forward( "TransfoXLLMHeadModel", "TransfoXLModel", "TransfoXLPreTrainedModel", - "load_tf_weights_in_transfo_xl", ] diff --git a/src/transformers/models/deprecated/transfo_xl/tokenization_transfo_xl.py b/src/transformers/models/deprecated/transfo_xl/tokenization_transfo_xl.py index 70e2da018556..e7081cd46d42 100644 --- a/src/transformers/models/deprecated/transfo_xl/tokenization_transfo_xl.py +++ b/src/transformers/models/deprecated/transfo_xl/tokenization_transfo_xl.py @@ -201,7 +201,6 @@ def __init__( try: vocab_dict = None if pretrained_vocab_file is not None: - # Priority on pickle files (support PyTorch and TF) if not strtobool(os.environ.get("TRUST_REMOTE_CODE", "False")): raise ValueError( "This part uses `pickle.load` which is insecure and will execute arbitrary code that is " diff --git a/src/transformers/models/deprecated/tvlt/image_processing_tvlt.py b/src/transformers/models/deprecated/tvlt/image_processing_tvlt.py index c0e1a33f091b..19b5cddb246b 100644 --- a/src/transformers/models/deprecated/tvlt/image_processing_tvlt.py +++ b/src/transformers/models/deprecated/tvlt/image_processing_tvlt.py @@ -332,10 +332,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -382,8 +380,7 @@ def preprocess( if not valid_images(videos): raise ValueError( - "Invalid image or video type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." + "Invalid image or video type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor" ) videos = make_batched(videos) diff --git a/src/transformers/models/deprecated/tvlt/modeling_tvlt.py b/src/transformers/models/deprecated/tvlt/modeling_tvlt.py index 2b21df928ff3..82aa12ada9e9 100644 --- a/src/transformers/models/deprecated/tvlt/modeling_tvlt.py +++ b/src/transformers/models/deprecated/tvlt/modeling_tvlt.py @@ -579,8 +579,6 @@ class TvltPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/deprecated/van/modeling_van.py b/src/transformers/models/deprecated/van/modeling_van.py index c0fc0bc1a637..6ee0e881e558 100644 --- a/src/transformers/models/deprecated/van/modeling_van.py +++ b/src/transformers/models/deprecated/van/modeling_van.py @@ -50,11 +50,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/deprecated/vit_hybrid/image_processing_vit_hybrid.py b/src/transformers/models/deprecated/vit_hybrid/image_processing_vit_hybrid.py index 92d518363b2c..662382be43df 100644 --- a/src/transformers/models/deprecated/vit_hybrid/image_processing_vit_hybrid.py +++ b/src/transformers/models/deprecated/vit_hybrid/image_processing_vit_hybrid.py @@ -243,10 +243,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -278,10 +276,7 @@ def preprocess( validate_kwargs(captured_kwargs=kwargs.keys(), valid_processor_keys=self._valid_processor_keys) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/depth_anything/modeling_depth_anything.py b/src/transformers/models/depth_anything/modeling_depth_anything.py index bc7d74131204..5710016bd513 100644 --- a/src/transformers/models/depth_anything/modeling_depth_anything.py +++ b/src/transformers/models/depth_anything/modeling_depth_anything.py @@ -218,8 +218,6 @@ class DepthAnythingPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d, nn.ConvTranspose2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/depth_pro/image_processing_depth_pro.py b/src/transformers/models/depth_pro/image_processing_depth_pro.py index 47f224f248bd..5b76d8cbc8e6 100644 --- a/src/transformers/models/depth_pro/image_processing_depth_pro.py +++ b/src/transformers/models/depth_pro/image_processing_depth_pro.py @@ -232,10 +232,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -261,10 +259,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") self._validate_input_arguments( do_resize=do_resize, size=size, diff --git a/src/transformers/models/depth_pro/modeling_depth_pro.py b/src/transformers/models/depth_pro/modeling_depth_pro.py index 52de04d42df7..9fb4c35b23e5 100644 --- a/src/transformers/models/depth_pro/modeling_depth_pro.py +++ b/src/transformers/models/depth_pro/modeling_depth_pro.py @@ -618,8 +618,6 @@ class DepthProPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/detr/image_processing_detr.py b/src/transformers/models/detr/image_processing_detr.py index f29bd48a5934..7a2e67f83de6 100644 --- a/src/transformers/models/detr/image_processing_detr.py +++ b/src/transformers/models/detr/image_processing_detr.py @@ -18,7 +18,7 @@ import pathlib from collections import defaultdict from collections.abc import Iterable -from typing import Any, Callable, Optional, Union +from typing import Any, Optional, Union import numpy as np @@ -54,11 +54,7 @@ ) from ...utils import ( TensorType, - is_flax_available, - is_jax_tensor, is_scipy_available, - is_tf_available, - is_tf_tensor, is_torch_available, is_torch_tensor, is_vision_available, @@ -189,30 +185,6 @@ def get_resize_output_image_size( return get_size_with_aspect_ratio(image_size, size, max_size) -def get_numpy_to_framework_fn(arr) -> Callable: - """ - Returns a function that converts a numpy array to the framework of the input array. - - Args: - arr (`np.ndarray`): The array to convert. - """ - if isinstance(arr, np.ndarray): - return np.array - if is_tf_available() and is_tf_tensor(arr): - import tensorflow as tf - - return tf.convert_to_tensor - if is_torch_available() and is_torch_tensor(arr): - import torch - - return torch.tensor - if is_flax_available() and is_jax_tensor(arr): - import jax.numpy as jnp - - return jnp.array - raise ValueError(f"Cannot convert arrays of type {type(arr)}") - - def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: """ Squeezes an array, but only if the axis specified has dim 1. @@ -635,7 +607,6 @@ def resize_annotation( return new_annotation -# TODO - (Amy) make compatible with other frameworks def binary_mask_to_rle(mask): """ Converts given binary mask of shape `(height, width)` to the run-length encoding (RLE) format. @@ -658,7 +629,6 @@ def binary_mask_to_rle(mask): return list(runs) -# TODO - (Amy) make compatible with other frameworks def convert_segmentation_to_rle(segmentation): """ Converts given segmentation map of shape `(height, width)` to the run-length encoding (RLE) format. @@ -1179,10 +1149,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -1366,10 +1334,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor.") validate_kwargs(captured_kwargs=kwargs.keys(), valid_processor_keys=self._valid_processor_keys) # Here, the pad() method pads to the maximum of (width, height). It does not need to be validated. @@ -1500,12 +1465,11 @@ def preprocess( return encoded_inputs - # POSTPROCESSING METHODS - TODO: add support for other frameworks # inspired by https://github.com/facebookresearch/detr/blob/master/models/detr.py#L258 def post_process(self, outputs, target_sizes): """ Converts the raw output of [`DetrForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y, - bottom_right_x, bottom_right_y) format. Only supports PyTorch. + bottom_right_x, bottom_right_y) format. Args: outputs ([`DetrObjectDetectionOutput`]): diff --git a/src/transformers/models/detr/image_processing_detr_fast.py b/src/transformers/models/detr/image_processing_detr_fast.py index 96a89a98074c..f30ebfa41859 100644 --- a/src/transformers/models/detr/image_processing_detr_fast.py +++ b/src/transformers/models/detr/image_processing_detr_fast.py @@ -725,7 +725,7 @@ def _preprocess( def post_process(self, outputs, target_sizes): """ Converts the raw output of [`DetrForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y, - bottom_right_x, bottom_right_y) format. Only supports PyTorch. + bottom_right_x, bottom_right_y) format. Args: outputs ([`DetrObjectDetectionOutput`]): diff --git a/src/transformers/models/detr/modeling_detr.py b/src/transformers/models/detr/modeling_detr.py index 86835ca62cfc..89441a8b1246 100644 --- a/src/transformers/models/detr/modeling_detr.py +++ b/src/transformers/models/detr/modeling_detr.py @@ -739,8 +739,6 @@ def _init_weights(self, module): nn.init.uniform_(module.row_embeddings.weight) nn.init.uniform_(module.column_embeddings.weight) if isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/dia/feature_extraction_dia.py b/src/transformers/models/dia/feature_extraction_dia.py index b4376b773b27..dcb32d2be6f4 100644 --- a/src/transformers/models/dia/feature_extraction_dia.py +++ b/src/transformers/models/dia/feature_extraction_dia.py @@ -92,7 +92,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*, default to 'pt'): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/dinat/modeling_dinat.py b/src/transformers/models/dinat/modeling_dinat.py index 4b7ec37b0ea8..a65b4862c473 100644 --- a/src/transformers/models/dinat/modeling_dinat.py +++ b/src/transformers/models/dinat/modeling_dinat.py @@ -214,11 +214,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -588,8 +583,6 @@ class DinatPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/dinov2/__init__.py b/src/transformers/models/dinov2/__init__.py index 3cc316957eac..002634ed4b49 100644 --- a/src/transformers/models/dinov2/__init__.py +++ b/src/transformers/models/dinov2/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_dinov2 import * from .modeling_dinov2 import * - from .modeling_flax_dinov2 import * else: import sys diff --git a/src/transformers/models/dinov2/modeling_dinov2.py b/src/transformers/models/dinov2/modeling_dinov2.py index 0a9a2cba1da7..f84d442a3efc 100644 --- a/src/transformers/models/dinov2/modeling_dinov2.py +++ b/src/transformers/models/dinov2/modeling_dinov2.py @@ -297,11 +297,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/dinov2/modeling_flax_dinov2.py b/src/transformers/models/dinov2/modeling_flax_dinov2.py deleted file mode 100644 index b9ea2eaa3ebc..000000000000 --- a/src/transformers/models/dinov2/modeling_flax_dinov2.py +++ /dev/null @@ -1,801 +0,0 @@ -# coding=utf-8 -# Copyright 2023 Meta AI and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax DINOv2 model.""" - -import collections.abc -import math -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxBaseModelOutputWithPooling, FlaxSequenceClassifierOutput -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward -from .configuration_dinov2 import Dinov2Config - - -DINOV2_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`Dinov2Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -DINOV2_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`numpy.ndarray` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`Dinov2ImageProcessor.__call__`] - for details. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -class FlaxDinov2PatchEmbeddings(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - image_size = self.config.image_size - patch_size = self.config.patch_size - image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) - patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) - num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) - - self.num_patches = num_patches - self.num_channels = self.config.num_channels - self.projection = nn.Conv( - self.config.hidden_size, - kernel_size=patch_size, - strides=patch_size, - padding="VALID", - dtype=self.dtype, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - ) - - # Copied from transformers.models.vit.modeling_flax_vit.FlaxViTPatchEmbeddings.__call__ - def __call__(self, pixel_values): - num_channels = pixel_values.shape[-1] - if num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - embeddings = self.projection(pixel_values) - batch_size, _, _, channels = embeddings.shape - return jnp.reshape(embeddings, (batch_size, -1, channels)) - - -class FlaxDinov2Embeddings(nn.Module): - """Construct the CLS token, position and patch embeddings.""" - - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.cls_token = self.param( - "cls_token", - jax.nn.initializers.variance_scaling(self.config.initializer_range**2, "fan_in", "truncated_normal"), - (1, 1, self.config.hidden_size), - ) - if self.config.use_mask_token: - self.mask_token = self.param( - "mask_token", - jax.nn.initializers.variance_scaling(self.config.initializer_range**2, "fan_in", "truncated_normal"), - (1, self.config.hidden_size), - ) - self.patch_embeddings = FlaxDinov2PatchEmbeddings(self.config, dtype=self.dtype) - num_patches = self.patch_embeddings.num_patches - self.position_embeddings = self.param( - "position_embeddings", - jax.nn.initializers.variance_scaling(self.config.initializer_range**2, "fan_in", "truncated_normal"), - (1, num_patches + 1, self.config.hidden_size), - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def interpolate_pos_encoding(self, config, hidden_states, height, width, position_embeddings): - num_patches = hidden_states.shape[1] - 1 - num_positions = position_embeddings.shape[1] - 1 - if num_patches == num_positions and height == width: - return position_embeddings - class_pos_embed = position_embeddings[:, 0] - patch_pos_embed = position_embeddings[:, 1:] - dim = hidden_states.shape[-1] - - h = height // config.patch_size - w = width // config.patch_size - height, width = h + 0.1, w + 0.1 - - patch_pos_embed = patch_pos_embed.reshape( - (1, int(math.sqrt(num_positions)), int(math.sqrt(num_positions)), dim) - ) - patch_pos_embed = jnp.transpose(patch_pos_embed, (0, 3, 1, 2)) - target_dtype = patch_pos_embed.dtype - new_height_ratio = jnp.float32(height / math.sqrt(num_positions)) - new_width_ratio = jnp.float32(width / math.sqrt(num_positions)) - - scale = jnp.array([new_height_ratio, new_width_ratio], dtype=jnp.float32) - translation = jnp.array([0.0, 0.0], dtype=jnp.float32) - - patch_pos_embed = jax.image.scale_and_translate( - patch_pos_embed.astype(jnp.float32), - shape=(patch_pos_embed.shape[0], patch_pos_embed.shape[1], h, w), - spatial_dims=(2, 3), - scale=scale, - translation=translation, - method="bicubic", - antialias=False, - ) - patch_pos_embed = patch_pos_embed.astype(target_dtype) - patch_pos_embed = jnp.transpose(patch_pos_embed, (0, 2, 3, 1)).reshape((position_embeddings.shape[0], -1, dim)) - patch_pos_embed_expanded = jnp.tile(patch_pos_embed, (hidden_states.shape[0], 1, 1)) - class_pos_embed_expanded = jnp.tile(class_pos_embed, (hidden_states.shape[0], 1, 1)) - - return jnp.concatenate((class_pos_embed_expanded, patch_pos_embed_expanded), axis=1) - - def __call__(self, pixel_values, deterministic=True): - batch_size = pixel_values.shape[0] - target_dtype = self.patch_embeddings.projection.dtype - height, width = pixel_values.shape[1], pixel_values.shape[2] - - embeddings = self.patch_embeddings(pixel_values.astype(target_dtype)) - - cls_tokens = jnp.broadcast_to(self.cls_token, (batch_size, 1, self.config.hidden_size)) - embeddings = jnp.concatenate((cls_tokens, embeddings), axis=1) - - embeddings = embeddings + self.interpolate_pos_encoding( - self.config, embeddings, height, width, self.position_embeddings - ) - - embeddings = self.dropout(embeddings, deterministic=deterministic) - return embeddings - - -# Copied from transformers.models.vit.modeling_flax_vit.FlaxViTSelfAttention with ViT->Dinov2 -class FlaxDinov2SelfAttention(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - if self.config.hidden_size % self.config.num_attention_heads != 0: - raise ValueError( - "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads`:" - " {self.config.num_attention_heads}" - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, mode="fan_in", distribution="truncated_normal" - ), - use_bias=self.config.qkv_bias, - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, mode="fan_in", distribution="truncated_normal" - ), - use_bias=self.config.qkv_bias, - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, mode="fan_in", distribution="truncated_normal" - ), - use_bias=self.config.qkv_bias, - ) - - def __call__(self, hidden_states, deterministic: bool = True, output_attentions: bool = False): - head_dim = self.config.hidden_size // self.config.num_attention_heads - - query_states = self.query(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - value_states = self.value(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - key_states = self.key(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -# Copied from transformers.models.vit.modeling_flax_vit.FlaxViTSelfOutput with ViT->Dinov2 -class FlaxDinov2SelfOutput(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, input_tensor, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -# Copied from transformers.models.vit.modeling_flax_vit.FlaxViTAttention with ViT->Dinov2 -class FlaxDinov2Attention(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.attention = FlaxDinov2SelfAttention(self.config, dtype=self.dtype) - self.output = FlaxDinov2SelfOutput(self.config, dtype=self.dtype) - - def __call__(self, hidden_states, deterministic=True, output_attentions: bool = False): - attn_outputs = self.attention(hidden_states, deterministic=deterministic, output_attentions=output_attentions) - attn_output = attn_outputs[0] - hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_outputs[1],) - - return outputs - - -def ones_with_scale(key, shape, scale, dtype=jnp.float32): - return jnp.ones(shape, dtype) * scale - - -class FlaxDinov2LayerScale(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.lambda1 = self.config.layerscale_value * self.param( - "lambda1", - jax.nn.initializers.ones, - (self.config.hidden_size,), - ) - self.lambda1 = self.lambda1 * self.config.layerscale_value - - def __call__(self, hidden_states): - return self.lambda1 * hidden_states - - -# Copied from transformers.models.beit.modeling_flax_beit.FlaxBeitDropPath with Beit -> Dinov2 -class FlaxDinov2DropPath(nn.Module): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" - - rate: float - - @nn.module.compact - def __call__(self, inputs, deterministic: Optional[bool] = True): - if self.rate == 0.0: - return inputs - keep_prob = 1.0 - self.rate - if deterministic: - return inputs - else: - shape = (inputs.shape[0],) + (1,) * (inputs.ndim - 1) # work with diff dim tensors, not just 2D ConvNets - rng = self.make_rng("droppath") - random_tensor = keep_prob + jax.random.uniform(rng, shape=shape, dtype=inputs.dtype) - binary_tensor = jnp.floor(random_tensor) - output = inputs / keep_prob * binary_tensor - return output - - -class FlaxDinov2MLP(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.fc1 = nn.Dense( - self.config.hidden_size * self.config.mlp_ratio, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - dtype=self.dtype, - ) - self.fc2 = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - dtype=self.dtype, - ) - if isinstance(self.config.hidden_act, str): - self.act = ACT2FN[self.config.hidden_act] - else: - self.act = self.config.hidden_act - - def __call__(self, hidden_states): - hidden_states = self.fc1(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.fc2(hidden_states) - return hidden_states - - -class FlaxDinov2SwiGLUFFN(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - hidden_features = int(self.config.hidden_size * self.config.mlp_ratio) - hidden_features = (int(hidden_features * 2 / 3) + 7) // 8 * 8 - - self.weights_in = nn.Dense( - 2 * hidden_features, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - dtype=self.dtype, - ) - self.weights_out = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - dtype=self.dtype, - ) - - def __call__(self, hidden_states): - hidden_states = self.weights_in(hidden_states) - x1, x2 = jnp.split(hidden_states, 2, axis=-1) - hidden = nn.silu(x1) * x2 - return self.weights_out(hidden) - - -class FlaxDinov2Layer(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.norm1 = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.attention = FlaxDinov2Attention(self.config, dtype=self.dtype) - self.layer_scale1 = FlaxDinov2LayerScale(self.config, dtype=self.dtype) - self.drop_path = FlaxDinov2DropPath(self.config.drop_path_rate) - self.norm2 = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - if self.config.use_swiglu_ffn: - self.mlp = FlaxDinov2SwiGLUFFN(self.config, dtype=self.dtype) - else: - self.mlp = FlaxDinov2MLP(self.config, dtype=self.dtype) - - self.layer_scale2 = FlaxDinov2LayerScale(self.config, dtype=self.dtype) - - def __call__(self, hidden_states, deterministic: bool = True, output_attentions: bool = False): - self_attention_outputs = self.attention( - self.norm1(hidden_states), # in Dinov2, layernorm is applied before self-attention - deterministic=deterministic, - output_attentions=output_attentions, - ) - - attention_output = self_attention_outputs[0] - - attention_output = self.layer_scale1(attention_output) - - outputs = self_attention_outputs[1:] - - # first residual connection - hidden_states = self.drop_path(attention_output) + hidden_states - - # in Dinov2, layernorm is also applied after self-attention - layer_output = self.norm2(hidden_states) - layer_output = self.mlp(layer_output) - layer_output = self.layer_scale2(layer_output) - - # second residual connection - layer_output = self.drop_path(layer_output) + hidden_states - - outputs = (layer_output,) + outputs - - return outputs - - -# Copied from transformers.models.vit.modeling_flax_vit.FlaxViTLayerCollection with ViT->Dinov2 -class FlaxDinov2LayerCollection(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxDinov2Layer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer(hidden_states, deterministic=deterministic, output_attentions=output_attentions) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states,) - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -# Copied from transformers.models.vit.modeling_flax_vit.FlaxViTEncoder with ViT->Dinov2 -class FlaxDinov2Encoder(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layer = FlaxDinov2LayerCollection(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.layer( - hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -class FlaxDinov2PreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = Dinov2Config - base_model_prefix = "dinov2" - main_input_name = "pixel_values" - module_class: nn.Module = None - - def __init__( - self, - config: Dinov2Config, - input_shape=None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - if input_shape is None: - input_shape = (1, config.image_size, config.image_size, config.num_channels) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - pixel_values = jnp.zeros(input_shape, dtype=self.dtype) - - params_rng, dropout_rng = jax.random.split(rng) - dropout_rng, droppath_rng = jax.random.split(dropout_rng) - rngs = {"params": params_rng, "dropout": dropout_rng, "droppath": droppath_rng} - - random_params = self.module.init(rngs, pixel_values, return_dict=False)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(DINOV2_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - pixel_values, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - dropout_rng, droppath_rng = jax.random.split(dropout_rng) - rngs["dropout"] = dropout_rng - rngs["droppath"] = droppath_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(pixel_values, dtype=jnp.float32), - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - -class FlaxDinov2Module(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.embeddings = FlaxDinov2Embeddings(self.config, dtype=self.dtype) - self.encoder = FlaxDinov2Encoder(self.config, dtype=self.dtype) - self.layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__( - self, - pixel_values, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - hidden_states = self.embeddings(pixel_values, deterministic=deterministic) - - encoder_outputs = self.encoder( - hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - sequence_output = encoder_outputs[0] - sequence_output = self.layernorm(sequence_output) - pooled_output = sequence_output[:, 0, :] - - if not return_dict: - head_outputs = (sequence_output, pooled_output) - return head_outputs + encoder_outputs[1:] - - return FlaxBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - -@add_start_docstrings( - "The bare Dinov2 Model transformer outputting raw hidden-states without any specific head on top.", - DINOV2_START_DOCSTRING, -) -class FlaxDinov2Model(FlaxDinov2PreTrainedModel): - module_class = FlaxDinov2Module - - -FLAX_VISION_MODEL_DOCSTRING = """ - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, FlaxDinov2Model - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/dinov2-base") - >>> model = FlaxDinov2Model.from_pretrained("facebook/dinov2-base") - - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> last_hidden_states = outputs.last_hidden_state - ``` -""" - -overwrite_call_docstring(FlaxDinov2Model, FLAX_VISION_MODEL_DOCSTRING) -append_replace_return_docstrings( - FlaxDinov2Model, output_type=FlaxBaseModelOutputWithPooling, config_class=Dinov2Config -) - - -class FlaxDinov2ForImageClassificationModule(nn.Module): - config: Dinov2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dinov2 = FlaxDinov2Module(config=self.config, dtype=self.dtype) - self.classifier = nn.Dense( - self.config.num_labels, - dtype=self.dtype, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - ) - - def __call__( - self, - pixel_values=None, - deterministic: bool = True, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.dinov2( - pixel_values, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - cls_token = hidden_states[:, 0] - patch_tokens = hidden_states[:, 1:] - linear_input = jnp.concatenate([cls_token, patch_tokens.mean(axis=1)], axis=-1) - - logits = self.classifier(linear_input) - - if not return_dict: - output = (logits,) + outputs[2:] - return output - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Dinov2 Model transformer with an image classification head on top (a linear layer on top of the final hidden state of - the [CLS] token) e.g. for ImageNet. - """, - DINOV2_START_DOCSTRING, -) -class FlaxDinov2ForImageClassification(FlaxDinov2PreTrainedModel): - module_class = FlaxDinov2ForImageClassificationModule - - -FLAX_VISION_CLASSIFICATION_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoImageProcessor, FlaxDinov2ForImageClassification - >>> from PIL import Image - >>> import jax - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/dinov2-base-imagenet1k-1-layer") - >>> model = FlaxDinov2ForImageClassification.from_pretrained("facebook/dinov2-base-imagenet1k-1-layer", from_pt=True) - - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> logits = outputs.logits - - >>> # model predicts one of the 1000 ImageNet classes - >>> predicted_class_idx = jax.numpy.argmax(logits, axis=-1) - >>> print("Predicted class:", model.config.id2label[predicted_class_idx.item()]) - ``` -""" - -overwrite_call_docstring(FlaxDinov2ForImageClassification, FLAX_VISION_CLASSIFICATION_DOCSTRING) -append_replace_return_docstrings( - FlaxDinov2ForImageClassification, output_type=FlaxSequenceClassifierOutput, config_class=Dinov2Config -) - - -__all__ = ["FlaxDinov2ForImageClassification", "FlaxDinov2Model", "FlaxDinov2PreTrainedModel"] diff --git a/src/transformers/models/dinov2_with_registers/modeling_dinov2_with_registers.py b/src/transformers/models/dinov2_with_registers/modeling_dinov2_with_registers.py index a02ac4c58476..042c21babd19 100644 --- a/src/transformers/models/dinov2_with_registers/modeling_dinov2_with_registers.py +++ b/src/transformers/models/dinov2_with_registers/modeling_dinov2_with_registers.py @@ -313,11 +313,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/dinov3_convnext/modeling_dinov3_convnext.py b/src/transformers/models/dinov3_convnext/modeling_dinov3_convnext.py index df2ef491192c..8eef42c03d17 100644 --- a/src/transformers/models/dinov3_convnext/modeling_dinov3_convnext.py +++ b/src/transformers/models/dinov3_convnext/modeling_dinov3_convnext.py @@ -38,11 +38,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -199,8 +194,6 @@ class DINOv3ConvNextPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/dinov3_vit/modeling_dinov3_vit.py b/src/transformers/models/dinov3_vit/modeling_dinov3_vit.py index dbea73e6caf5..76e365903082 100644 --- a/src/transformers/models/dinov3_vit/modeling_dinov3_vit.py +++ b/src/transformers/models/dinov3_vit/modeling_dinov3_vit.py @@ -329,11 +329,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/distilbert/__init__.py b/src/transformers/models/distilbert/__init__.py index 4d6fae2e0236..094524ab267f 100644 --- a/src/transformers/models/distilbert/__init__.py +++ b/src/transformers/models/distilbert/__init__.py @@ -20,8 +20,6 @@ if TYPE_CHECKING: from .configuration_distilbert import * from .modeling_distilbert import * - from .modeling_flax_distilbert import * - from .modeling_tf_distilbert import * from .tokenization_distilbert import * from .tokenization_distilbert_fast import * else: diff --git a/src/transformers/models/distilbert/modeling_distilbert.py b/src/transformers/models/distilbert/modeling_distilbert.py index bc116b231af1..8f0cdcd76898 100755 --- a/src/transformers/models/distilbert/modeling_distilbert.py +++ b/src/transformers/models/distilbert/modeling_distilbert.py @@ -562,7 +562,6 @@ def forward( @auto_docstring class DistilBertPreTrainedModel(PreTrainedModel): config: DistilBertConfig - load_tf_weights = None base_model_prefix = "distilbert" supports_gradient_checkpointing = True _supports_flash_attn = True @@ -571,8 +570,6 @@ class DistilBertPreTrainedModel(PreTrainedModel): def _init_weights(self, module: nn.Module): """Initialize the weights.""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/distilbert/modeling_flax_distilbert.py b/src/transformers/models/distilbert/modeling_flax_distilbert.py deleted file mode 100644 index fba3dfd9d332..000000000000 --- a/src/transformers/models/distilbert/modeling_flax_distilbert.py +++ /dev/null @@ -1,906 +0,0 @@ -# coding=utf-8 -# Copyright 2019-present, the HuggingFace Inc. team, The Google AI Language Team and Facebook, Inc. -# -# 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. - -import math -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxMaskedLMOutput, - FlaxMultipleChoiceModelOutput, - FlaxQuestionAnsweringModelOutput, - FlaxSequenceClassifierOutput, - FlaxTokenClassifierOutput, -) -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring, overwrite_call_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_distilbert import DistilBertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "distilbert-base-uncased" -_CONFIG_FOR_DOC = "DistilBertConfig" - - -FLAX_DISTILBERT_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`DistilBertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -DISTILBERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def get_angles(pos, i, d_model): - angle_rates = 1 / np.power(10000, (2 * (i // 2)) / np.float32(d_model)) - return pos * angle_rates - - -def positional_encoding(position, d_model): - # create the sinusoidal pattern for the positional encoding - angle_rads = get_angles(np.arange(position)[:, np.newaxis], np.arange(d_model)[np.newaxis, :], d_model) - - # apply sin to even indices in the array; 2i - angle_rads[:, 0::2] = np.sin(angle_rads[:, 0::2]) - - # apply cos to odd indices in the array; 2i+1 - angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2]) - - pos_encoding = angle_rads[np.newaxis, ...] - - return jnp.array(pos_encoding) - - -class FlaxEmbeddings(nn.Module): - """Construct the embeddings from word, position and token_type embeddings.""" - - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.word_embeddings = nn.Embed( - self.config.vocab_size, - self.config.dim, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - if not self.config.sinusoidal_pos_embds: - self.position_embeddings = nn.Embed( - self.config.max_position_embeddings, - self.config.dim, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - else: - self.pos_encoding = positional_encoding(self.config.max_position_embeddings, self.config.dim) - self.LayerNorm = nn.LayerNorm(epsilon=1e-12, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.dropout) - - def __call__(self, input_ids, deterministic: bool = True): - # Embed - batch_size, seq_length = input_ids.shape - inputs_embeds = self.word_embeddings(input_ids.astype("i4")) - if not self.config.sinusoidal_pos_embds: - position_ids = jnp.arange(seq_length).astype("i4") - position_ids = jnp.broadcast_to(position_ids, shape=(batch_size, seq_length)) - position_embeds = self.position_embeddings(position_ids.astype("i4")) - else: - position_embeds = self.pos_encoding[:, :seq_length, :] - # explicitly cast the positions here, since self.embed_positions are not registered as parameters - position_embeds = position_embeds.astype(inputs_embeds.dtype) - - # Sum all embeddings - hidden_states = inputs_embeds + position_embeds - - # Layer Norm - hidden_states = self.LayerNorm(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxMultiHeadSelfAttention(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.n_heads = self.config.n_heads - self.dim = self.config.dim - self.dropout = nn.Dropout(rate=self.config.attention_dropout) - - if not (self.dim % self.n_heads == 0): - raise ValueError(f"Hidden size {self.dim} not dividable by number of heads {self.n_heads}") - - self.q_lin = nn.Dense( - self.dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.k_lin = nn.Dense( - self.dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.v_lin = nn.Dense( - self.dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.out_lin = nn.Dense( - self.dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - - def __call__( - self, - query, - key, - value, - mask, - deterministic: bool = True, - output_attentions: bool = False, - ): - bs, q_len, dim = query.shape - k_len = key.shape[1] - # assert dim == self.dim, f'Dimensions do not match: {dim} input vs {self.dim} configured' - # assert key.size() == value.size() - - dim_per_head = self.dim // self.n_heads - - mask_reshp = (bs, 1, 1, k_len) - - def shape(x): - """separate heads""" - return x.reshape(bs, -1, self.n_heads, dim_per_head).transpose(0, 2, 1, 3) - - def unshape(x): - """group heads""" - return x.transpose(0, 2, 1, 3).reshape(bs, -1, self.n_heads * dim_per_head) - - q = shape(self.q_lin(query)) # (bs, n_heads, q_len, dim_per_head) - k = shape(self.k_lin(key)) # (bs, n_heads, k_len, dim_per_head) - v = shape(self.v_lin(value)) # (bs, n_heads, k_len, dim_per_head) - - q = q / math.sqrt(dim_per_head) # (bs, n_heads, q_len, dim_per_head) - scores = jnp.matmul(q, k.transpose(0, 1, 3, 2)) # (bs, n_heads, q_len, k_len) - mask = jnp.reshape(mask, mask_reshp) - - mask = mask.astype(scores.dtype) - scores = scores - 1e30 * (1.0 - mask) - - weights = nn.softmax(scores, axis=-1) # (bs, n_heads, q_len, k_len) - weights = self.dropout(weights, deterministic=deterministic) - - context = jnp.matmul(weights, v) # (bs, n_heads, q_len, dim_per_head) - context = unshape(context) # (bs, q_len, dim) - context = self.out_lin(context) # (bs, q_len, dim) - - if output_attentions: - return (context, weights) - else: - return (context,) - - -class FlaxFFN(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout = nn.Dropout(rate=self.config.dropout) - self.chunk_size_feed_forward = self.config.chunk_size_feed_forward - self.seq_len_dim = 1 - self.lin1 = nn.Dense( - self.config.hidden_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.lin2 = nn.Dense( - self.config.dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - - self.activation = ACT2FN[self.config.activation] - - def __call__(self, hidden_states, deterministic: bool = True): - hidden_states = self.lin1(hidden_states) - hidden_states = self.activation(hidden_states) - hidden_states = self.lin2(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxTransformerBlock(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - assert self.config.dim % self.config.n_heads == 0, ( - f"Hidden size {self.config.dim} not dividable by number of heads {self.config.n_heads}" - ) - - self.attention = FlaxMultiHeadSelfAttention(self.config, dtype=self.dtype) - self.sa_layer_norm = nn.LayerNorm(epsilon=1e-12, dtype=self.dtype) - - self.ffn = FlaxFFN(self.config, dtype=self.dtype) - self.output_layer_norm = nn.LayerNorm(epsilon=1e-12, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attn_mask, - output_attentions: bool = False, - deterministic: bool = True, - ): - # Self-Attention - sa_output = self.attention( - query=hidden_states, - key=hidden_states, - value=hidden_states, - mask=attn_mask, - output_attentions=output_attentions, - deterministic=deterministic, - ) - if output_attentions: - sa_output, sa_weights = sa_output - else: - assert type(sa_output) is tuple - sa_output = sa_output[0] - sa_output = self.sa_layer_norm(sa_output + hidden_states) - - # Feed Forward Network - ffn_output = self.ffn(sa_output, deterministic=deterministic) - ffn_output = self.output_layer_norm(ffn_output + sa_output) - output = (ffn_output,) - if output_attentions: - output = (sa_weights,) + output - return output - - -class FlaxTransformer(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxTransformerBlock(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.n_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask, - output_attentions: bool = False, - output_hidden_states: bool = False, - deterministic: bool = True, - return_dict: bool = False, - ): - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - for layer_module in self.layers: - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states=hidden_states, - attn_mask=attention_mask, - output_attentions=output_attentions, - deterministic=deterministic, - ) - hidden_states = layer_outputs[-1] - - if output_attentions: - assert len(layer_outputs) == 2 - attentions = layer_outputs[0] - all_attentions = all_attentions + (attentions,) - else: - assert len(layer_outputs) == 1 - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_attentions, all_hidden_states] if v is not None) - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -class FlaxTransformerEncoder(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layer = FlaxTransformer(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - output_attentions: bool = False, - output_hidden_states: bool = False, - deterministic: bool = True, - return_dict: bool = False, - ): - return self.layer( - hidden_states=hidden_states, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - deterministic=deterministic, - return_dict=return_dict, - ) - - -class FlaxDistilBertLMDecoder(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) - - def __call__(self, inputs, kernel): - inputs = jnp.asarray(inputs, self.dtype) - kernel = jnp.asarray(kernel, self.dtype) - y = lax.dot_general(inputs, kernel, (((inputs.ndim - 1,), (0,)), ((), ()))) - bias = jnp.asarray(self.bias, self.dtype) - y = y + bias - return y - - -class FlaxDistilBertPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = DistilBertConfig - base_model_prefix = "distilbert" - module_class: nn.Module = None - - def __init__( - self, - config: DistilBertConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, input_ids, attention_mask, return_dict=False)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - input_ids, - attention_mask=None, - head_mask=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - -class FlaxDistilBertModule(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.embeddings = FlaxEmbeddings(self.config, dtype=self.dtype) - self.transformer = FlaxTransformerEncoder(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - input_embeds = self.embeddings(input_ids, deterministic=deterministic) - return self.transformer( - hidden_states=input_embeds, - attention_mask=attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -@add_start_docstrings( - "The bare DistilBert Model transformer outputting raw hidden-states without any specific head on top.", - FLAX_DISTILBERT_START_DOCSTRING, -) -class FlaxDistilBertModel(FlaxDistilBertPreTrainedModel): - module_class = FlaxDistilBertModule - - -append_call_sample_docstring(FlaxDistilBertModel, _CHECKPOINT_FOR_DOC, None, _CONFIG_FOR_DOC) - - -class FlaxDistilBertForMaskedLMModule(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.distilbert = FlaxDistilBertModule(self.config, dtype=self.dtype) - self.vocab_transform = nn.Dense( - self.config.dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.vocab_layer_norm = nn.LayerNorm(epsilon=1e-12, dtype=self.dtype) - if self.config.tie_word_embeddings: - self.vocab_projector = FlaxDistilBertLMDecoder( - self.config, - dtype=self.dtype, - ) - else: - self.vocab_projector = nn.Dense( - self.config.vocab_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - - def __call__( - self, - input_ids, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - dlbrt_output = self.distilbert( - input_ids=input_ids, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - deterministic=deterministic, - return_dict=return_dict, - ) - hidden_states = dlbrt_output[0] - prediction_logits = self.vocab_transform(hidden_states) - prediction_logits = ACT2FN[self.config.activation](prediction_logits) - prediction_logits = self.vocab_layer_norm(prediction_logits) - - if self.config.tie_word_embeddings: - shared_embedding = self.distilbert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - prediction_logits = self.vocab_projector(prediction_logits, shared_embedding.T) - else: - prediction_logits = self.vocab_projector(prediction_logits) - - if not return_dict: - output = (prediction_logits,) + dlbrt_output[1:] - return output - - return FlaxMaskedLMOutput( - logits=prediction_logits, - hidden_states=dlbrt_output.hidden_states, - attentions=dlbrt_output.attentions, - ) - - -@add_start_docstrings("""DistilBert Model with a `language modeling` head on top.""", FLAX_DISTILBERT_START_DOCSTRING) -class FlaxDistilBertForMaskedLM(FlaxDistilBertPreTrainedModel): - module_class = FlaxDistilBertForMaskedLMModule - - -append_call_sample_docstring(FlaxDistilBertForMaskedLM, _CHECKPOINT_FOR_DOC, FlaxMaskedLMOutput, _CONFIG_FOR_DOC) - - -class FlaxDistilBertForSequenceClassificationModule(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.distilbert = FlaxDistilBertModule(config=self.config, dtype=self.dtype) - self.pre_classifier = nn.Dense( - self.config.dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.dropout = nn.Dropout(rate=self.config.seq_classif_dropout) - self.classifier = nn.Dense( - self.config.num_labels, - dtype=self.dtype, - ) - - def __call__( - self, - input_ids, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - # Model - distilbert_output = self.distilbert( - input_ids, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_state = distilbert_output[0] # (bs, seq_len, dim) - pooled_output = hidden_state[:, 0] # (bs, dim) - pooled_output = self.pre_classifier(pooled_output) # (bs, dim) - pooled_output = ACT2FN["relu"](pooled_output) - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) # (bs, dim) - - if not return_dict: - return (logits,) + distilbert_output[1:] - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=distilbert_output.hidden_states, - attentions=distilbert_output.attentions, - ) - - -@add_start_docstrings( - """ - DistilBert Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - FLAX_DISTILBERT_START_DOCSTRING, -) -class FlaxDistilBertForSequenceClassification(FlaxDistilBertPreTrainedModel): - module_class = FlaxDistilBertForSequenceClassificationModule - - -append_call_sample_docstring( - FlaxDistilBertForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxDistilBertForMultipleChoiceModule(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.distilbert = FlaxDistilBertModule(config=self.config, dtype=self.dtype) - self.pre_classifier = nn.Dense( - self.config.dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.dropout = nn.Dropout(rate=self.config.seq_classif_dropout) - self.classifier = nn.Dense( - 1, - dtype=self.dtype, - ) - - def __call__( - self, - input_ids, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - num_choices = input_ids.shape[1] - input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None - attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None - - # Model - outputs = self.distilbert( - input_ids, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_state = outputs[0] - pooled_output = hidden_state[:, 0] - pooled_output = self.pre_classifier(pooled_output) - pooled_output = ACT2FN["relu"](pooled_output) - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) - - reshaped_logits = logits.reshape(-1, num_choices) - - if not return_dict: - return (reshaped_logits,) + outputs[2:] - - return FlaxMultipleChoiceModelOutput( - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - DistilBert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and - a softmax) e.g. for RocStories/SWAG tasks. - """, - FLAX_DISTILBERT_START_DOCSTRING, -) -class FlaxDistilBertForMultipleChoice(FlaxDistilBertPreTrainedModel): - module_class = FlaxDistilBertForMultipleChoiceModule - - -overwrite_call_docstring( - FlaxDistilBertForMultipleChoice, DISTILBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") -) -append_call_sample_docstring( - FlaxDistilBertForMultipleChoice, - _CHECKPOINT_FOR_DOC, - FlaxMultipleChoiceModelOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxDistilBertForTokenClassificationModule(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.distilbert = FlaxDistilBertModule(config=self.config, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.dropout) - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - # Model - outputs = self.distilbert( - input_ids, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - logits = self.classifier(hidden_states) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxTokenClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - DistilBert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. - for Named-Entity-Recognition (NER) tasks. - """, - FLAX_DISTILBERT_START_DOCSTRING, -) -class FlaxDistilBertForTokenClassification(FlaxDistilBertPreTrainedModel): - module_class = FlaxDistilBertForTokenClassificationModule - - -append_call_sample_docstring( - FlaxDistilBertForTokenClassification, - _CHECKPOINT_FOR_DOC, - FlaxTokenClassifierOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxDistilBertForQuestionAnsweringModule(nn.Module): - config: DistilBertConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.distilbert = FlaxDistilBertModule(config=self.config, dtype=self.dtype) - self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) - assert self.config.num_labels == 2 - self.dropout = nn.Dropout(rate=self.config.qa_dropout) - - def __call__( - self, - input_ids, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # Model - distilbert_output = self.distilbert( - input_ids, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = distilbert_output[0] - - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - logits = self.qa_outputs(hidden_states) - start_logits, end_logits = jnp.split(logits, self.config.num_labels, axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - return (start_logits, end_logits) + distilbert_output[1:] - - return FlaxQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - hidden_states=distilbert_output.hidden_states, - attentions=distilbert_output.attentions, - ) - - -@add_start_docstrings( - """ - DistilBert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a - linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - FLAX_DISTILBERT_START_DOCSTRING, -) -class FlaxDistilBertForQuestionAnswering(FlaxDistilBertPreTrainedModel): - module_class = FlaxDistilBertForQuestionAnsweringModule - - -append_call_sample_docstring( - FlaxDistilBertForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - - -__all__ = [ - "FlaxDistilBertForMaskedLM", - "FlaxDistilBertForMultipleChoice", - "FlaxDistilBertForQuestionAnswering", - "FlaxDistilBertForSequenceClassification", - "FlaxDistilBertForTokenClassification", - "FlaxDistilBertModel", - "FlaxDistilBertPreTrainedModel", -] diff --git a/src/transformers/models/distilbert/modeling_tf_distilbert.py b/src/transformers/models/distilbert/modeling_tf_distilbert.py deleted file mode 100644 index a2efa1105c1c..000000000000 --- a/src/transformers/models/distilbert/modeling_tf_distilbert.py +++ /dev/null @@ -1,1146 +0,0 @@ -# coding=utf-8 -# Copyright 2019-present, the HuggingFace Inc. team, The Google AI Language Team and Facebook, Inc. -# -# 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. -""" -TF 2.0 DistilBERT model -""" - -from __future__ import annotations - -import warnings - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_distilbert import DistilBertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "distilbert-base-uncased" -_CONFIG_FOR_DOC = "DistilBertConfig" - - -class TFEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.dim = config.dim - self.initializer_range = config.initializer_range - self.max_position_embeddings = config.max_position_embeddings - self.LayerNorm = keras.layers.LayerNormalization(epsilon=1e-12, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.dropout) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.dim], - initializer=get_initializer(initializer_range=self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.dim], - initializer=get_initializer(initializer_range=self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.dim]) - - def call(self, input_ids=None, position_ids=None, inputs_embeds=None, training=False): - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - final_embeddings = inputs_embeds + position_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -class TFMultiHeadSelfAttention(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.n_heads = config.n_heads - self.dim = config.dim - self.dropout = keras.layers.Dropout(config.attention_dropout) - self.output_attentions = config.output_attentions - - assert self.dim % self.n_heads == 0, f"Hidden size {self.dim} not dividable by number of heads {self.n_heads}" - - self.q_lin = keras.layers.Dense( - config.dim, kernel_initializer=get_initializer(config.initializer_range), name="q_lin" - ) - self.k_lin = keras.layers.Dense( - config.dim, kernel_initializer=get_initializer(config.initializer_range), name="k_lin" - ) - self.v_lin = keras.layers.Dense( - config.dim, kernel_initializer=get_initializer(config.initializer_range), name="v_lin" - ) - self.out_lin = keras.layers.Dense( - config.dim, kernel_initializer=get_initializer(config.initializer_range), name="out_lin" - ) - - self.pruned_heads = set() - self.config = config - - def prune_heads(self, heads): - raise NotImplementedError - - def call(self, query, key, value, mask, head_mask, output_attentions, training=False): - """ - Parameters: - query: tf.Tensor(bs, seq_length, dim) - key: tf.Tensor(bs, seq_length, dim) - value: tf.Tensor(bs, seq_length, dim) - mask: tf.Tensor(bs, seq_length) - - Returns: - weights: tf.Tensor(bs, n_heads, seq_length, seq_length) Attention weights context: tf.Tensor(bs, - seq_length, dim) Contextualized layer. Optional: only if `output_attentions=True` - """ - bs, q_length, dim = shape_list(query) - k_length = shape_list(key)[1] - # assert dim == self.dim, f'Dimensions do not match: {dim} input vs {self.dim} configured' - # assert key.size() == value.size() - dim_per_head = int(self.dim / self.n_heads) - dim_per_head = tf.cast(dim_per_head, dtype=tf.int32) - mask_reshape = [bs, 1, 1, k_length] - - def shape(x): - """separate heads""" - return tf.transpose(tf.reshape(x, (bs, -1, self.n_heads, dim_per_head)), perm=(0, 2, 1, 3)) - - def unshape(x): - """group heads""" - return tf.reshape(tf.transpose(x, perm=(0, 2, 1, 3)), (bs, -1, self.n_heads * dim_per_head)) - - q = shape(self.q_lin(query)) # (bs, n_heads, q_length, dim_per_head) - k = shape(self.k_lin(key)) # (bs, n_heads, k_length, dim_per_head) - v = shape(self.v_lin(value)) # (bs, n_heads, k_length, dim_per_head) - q = tf.cast(q, dtype=tf.float32) - q = tf.multiply(q, tf.math.rsqrt(tf.cast(dim_per_head, dtype=tf.float32))) - k = tf.cast(k, dtype=q.dtype) - scores = tf.matmul(q, k, transpose_b=True) # (bs, n_heads, q_length, k_length) - mask = tf.reshape(mask, mask_reshape) # (bs, n_heads, qlen, klen) - # scores.masked_fill_(mask, -float('inf')) # (bs, n_heads, q_length, k_length) - - mask = tf.cast(mask, dtype=scores.dtype) - scores = scores - 1e30 * (1.0 - mask) - weights = stable_softmax(scores, axis=-1) # (bs, n_heads, qlen, klen) - weights = self.dropout(weights, training=training) # (bs, n_heads, qlen, klen) - - # Mask heads if we want to - if head_mask is not None: - weights = weights * head_mask - - context = tf.matmul(weights, v) # (bs, n_heads, qlen, dim_per_head) - context = unshape(context) # (bs, q_length, dim) - context = self.out_lin(context) # (bs, q_length, dim) - - if output_attentions: - return (context, weights) - else: - return (context,) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "q_lin", None) is not None: - with tf.name_scope(self.q_lin.name): - self.q_lin.build([None, None, self.config.dim]) - if getattr(self, "k_lin", None) is not None: - with tf.name_scope(self.k_lin.name): - self.k_lin.build([None, None, self.config.dim]) - if getattr(self, "v_lin", None) is not None: - with tf.name_scope(self.v_lin.name): - self.v_lin.build([None, None, self.config.dim]) - if getattr(self, "out_lin", None) is not None: - with tf.name_scope(self.out_lin.name): - self.out_lin.build([None, None, self.config.dim]) - - -class TFFFN(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dropout = keras.layers.Dropout(config.dropout) - self.lin1 = keras.layers.Dense( - config.hidden_dim, kernel_initializer=get_initializer(config.initializer_range), name="lin1" - ) - self.lin2 = keras.layers.Dense( - config.dim, kernel_initializer=get_initializer(config.initializer_range), name="lin2" - ) - self.activation = get_tf_activation(config.activation) - self.config = config - - def call(self, input, training=False): - x = self.lin1(input) - x = self.activation(x) - x = self.lin2(x) - x = self.dropout(x, training=training) - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "lin1", None) is not None: - with tf.name_scope(self.lin1.name): - self.lin1.build([None, None, self.config.dim]) - if getattr(self, "lin2", None) is not None: - with tf.name_scope(self.lin2.name): - self.lin2.build([None, None, self.config.hidden_dim]) - - -class TFTransformerBlock(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.n_heads = config.n_heads - self.dim = config.dim - self.hidden_dim = config.hidden_dim - self.dropout = keras.layers.Dropout(config.dropout) - self.activation = config.activation - self.output_attentions = config.output_attentions - - assert config.dim % config.n_heads == 0, ( - f"Hidden size {config.dim} not dividable by number of heads {config.n_heads}" - ) - - self.attention = TFMultiHeadSelfAttention(config, name="attention") - self.sa_layer_norm = keras.layers.LayerNormalization(epsilon=1e-12, name="sa_layer_norm") - - self.ffn = TFFFN(config, name="ffn") - self.output_layer_norm = keras.layers.LayerNormalization(epsilon=1e-12, name="output_layer_norm") - self.config = config - - def call(self, x, attn_mask, head_mask, output_attentions, training=False): # removed: src_enc=None, src_len=None - """ - Parameters: - x: tf.Tensor(bs, seq_length, dim) - attn_mask: tf.Tensor(bs, seq_length) - - Outputs: sa_weights: tf.Tensor(bs, n_heads, seq_length, seq_length) The attention weights ffn_output: - tf.Tensor(bs, seq_length, dim) The output of the transformer block contextualization. - """ - # Self-Attention - sa_output = self.attention(x, x, x, attn_mask, head_mask, output_attentions, training=training) - if output_attentions: - sa_output, sa_weights = sa_output # (bs, seq_length, dim), (bs, n_heads, seq_length, seq_length) - else: # To handle these `output_attentions` or `output_hidden_states` cases returning tuples - # assert type(sa_output) == tuple - sa_output = sa_output[0] - sa_output = self.sa_layer_norm(sa_output + x) # (bs, seq_length, dim) - - # Feed Forward Network - ffn_output = self.ffn(sa_output, training=training) # (bs, seq_length, dim) - ffn_output = self.output_layer_norm(ffn_output + sa_output) # (bs, seq_length, dim) - - output = (ffn_output,) - if output_attentions: - output = (sa_weights,) + output - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "sa_layer_norm", None) is not None: - with tf.name_scope(self.sa_layer_norm.name): - self.sa_layer_norm.build([None, None, self.config.dim]) - if getattr(self, "ffn", None) is not None: - with tf.name_scope(self.ffn.name): - self.ffn.build(None) - if getattr(self, "output_layer_norm", None) is not None: - with tf.name_scope(self.output_layer_norm.name): - self.output_layer_norm.build([None, None, self.config.dim]) - - -class TFTransformer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.n_layers = config.n_layers - self.output_hidden_states = config.output_hidden_states - self.output_attentions = config.output_attentions - - self.layer = [TFTransformerBlock(config, name=f"layer_._{i}") for i in range(config.n_layers)] - - def call(self, x, attn_mask, head_mask, output_attentions, output_hidden_states, return_dict, training=False): - # docstyle-ignore - """ - Parameters: - x: tf.Tensor(bs, seq_length, dim) Input sequence embedded. - attn_mask: tf.Tensor(bs, seq_length) Attention mask on the sequence. - - Returns: - hidden_state: tf.Tensor(bs, seq_length, dim) - Sequence of hidden states in the last (top) layer - all_hidden_states: tuple[tf.Tensor(bs, seq_length, dim)] - Tuple of length n_layers with the hidden states from each layer. - Optional: only if output_hidden_states=True - all_attentions: tuple[tf.Tensor(bs, n_heads, seq_length, seq_length)] - Tuple of length n_layers with the attention weights from each layer - Optional: only if output_attentions=True - """ - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - hidden_state = x - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_state,) - - layer_outputs = layer_module(hidden_state, attn_mask, head_mask[i], output_attentions, training=training) - hidden_state = layer_outputs[-1] - - if output_attentions: - assert len(layer_outputs) == 2 - attentions = layer_outputs[0] - all_attentions = all_attentions + (attentions,) - else: - assert len(layer_outputs) == 1, f"Incorrect number of outputs {len(layer_outputs)} instead of 1" - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_state,) - - if not return_dict: - return tuple(v for v in [hidden_state, all_hidden_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_state, hidden_states=all_hidden_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFDistilBertMainLayer(keras.layers.Layer): - config_class = DistilBertConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.num_hidden_layers = config.num_hidden_layers - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - - self.embeddings = TFEmbeddings(config, name="embeddings") # Embeddings - self.transformer = TFTransformer(config, name="transformer") # Encoder - - def get_input_embeddings(self): - return self.embeddings - - def set_input_embeddings(self, value): - self.embeddings.weight = value - self.embeddings.vocab_size = value.shape[0] - - def _prune_heads(self, heads_to_prune): - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - head_mask=None, - inputs_embeds=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.ones(input_shape) # (bs, seq_length) - - attention_mask = tf.cast(attention_mask, dtype=tf.float32) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.num_hidden_layers - - embedding_output = self.embeddings(input_ids, inputs_embeds=inputs_embeds) # (bs, seq_length, dim) - tfmr_output = self.transformer( - embedding_output, - attention_mask, - head_mask, - output_attentions, - output_hidden_states, - return_dict, - training=training, - ) - - return tfmr_output # last-layer hidden-state, (all hidden_states), (all attentions) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -# INTERFACE FOR ENCODER AND TASK SPECIFIC MODEL # -class TFDistilBertPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = DistilBertConfig - base_model_prefix = "distilbert" - - -DISTILBERT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`DistilBertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -DISTILBERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare DistilBERT encoder/transformer outputting raw hidden-states without any specific head on top.", - DISTILBERT_START_DOCSTRING, -) -class TFDistilBertModel(TFDistilBertPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.distilbert = TFDistilBertMainLayer(config, name="distilbert") # Embeddings - - @unpack_inputs - @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - outputs = self.distilbert( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "distilbert", None) is not None: - with tf.name_scope(self.distilbert.name): - self.distilbert.build(None) - - -class TFDistilBertLMHead(keras.layers.Layer): - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.dim = config.dim - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.input_embeddings = input_embeddings - - def build(self, input_shape): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - super().build(input_shape) - - def get_output_embeddings(self): - return self.input_embeddings - - def set_output_embeddings(self, value): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.dim]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -@add_start_docstrings( - """DistilBert Model with a `masked language modeling` head on top.""", - DISTILBERT_START_DOCSTRING, -) -class TFDistilBertForMaskedLM(TFDistilBertPreTrainedModel, TFMaskedLanguageModelingLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.config = config - - self.distilbert = TFDistilBertMainLayer(config, name="distilbert") - self.vocab_transform = keras.layers.Dense( - config.dim, kernel_initializer=get_initializer(config.initializer_range), name="vocab_transform" - ) - self.act = get_tf_activation(config.activation) - self.vocab_layer_norm = keras.layers.LayerNormalization(epsilon=1e-12, name="vocab_layer_norm") - self.vocab_projector = TFDistilBertLMHead(config, self.distilbert.embeddings, name="vocab_projector") - - def get_lm_head(self): - return self.vocab_projector - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.vocab_projector.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - distilbert_output = self.distilbert( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = distilbert_output[0] # (bs, seq_length, dim) - prediction_logits = self.vocab_transform(hidden_states) # (bs, seq_length, dim) - prediction_logits = self.act(prediction_logits) # (bs, seq_length, dim) - prediction_logits = self.vocab_layer_norm(prediction_logits) # (bs, seq_length, dim) - prediction_logits = self.vocab_projector(prediction_logits) - - loss = None if labels is None else self.hf_compute_loss(labels, prediction_logits) - - if not return_dict: - output = (prediction_logits,) + distilbert_output[1:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_logits, - hidden_states=distilbert_output.hidden_states, - attentions=distilbert_output.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "distilbert", None) is not None: - with tf.name_scope(self.distilbert.name): - self.distilbert.build(None) - if getattr(self, "vocab_transform", None) is not None: - with tf.name_scope(self.vocab_transform.name): - self.vocab_transform.build([None, None, self.config.dim]) - if getattr(self, "vocab_layer_norm", None) is not None: - with tf.name_scope(self.vocab_layer_norm.name): - self.vocab_layer_norm.build([None, None, self.config.dim]) - if getattr(self, "vocab_projector", None) is not None: - with tf.name_scope(self.vocab_projector.name): - self.vocab_projector.build(None) - - -@add_start_docstrings( - """ - DistilBert Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - DISTILBERT_START_DOCSTRING, -) -class TFDistilBertForSequenceClassification(TFDistilBertPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.distilbert = TFDistilBertMainLayer(config, name="distilbert") - self.pre_classifier = keras.layers.Dense( - config.dim, - kernel_initializer=get_initializer(config.initializer_range), - activation="relu", - name="pre_classifier", - ) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.dropout = keras.layers.Dropout(config.seq_classif_dropout) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - distilbert_output = self.distilbert( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_state = distilbert_output[0] # (bs, seq_len, dim) - pooled_output = hidden_state[:, 0] # (bs, dim) - pooled_output = self.pre_classifier(pooled_output) # (bs, dim) - pooled_output = self.dropout(pooled_output, training=training) # (bs, dim) - logits = self.classifier(pooled_output) # (bs, dim) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + distilbert_output[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=distilbert_output.hidden_states, - attentions=distilbert_output.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "distilbert", None) is not None: - with tf.name_scope(self.distilbert.name): - self.distilbert.build(None) - if getattr(self, "pre_classifier", None) is not None: - with tf.name_scope(self.pre_classifier.name): - self.pre_classifier.build([None, None, self.config.dim]) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.dim]) - - -@add_start_docstrings( - """ - DistilBert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. - for Named-Entity-Recognition (NER) tasks. - """, - DISTILBERT_START_DOCSTRING, -) -class TFDistilBertForTokenClassification(TFDistilBertPreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.distilbert = TFDistilBertMainLayer(config, name="distilbert") - self.dropout = keras.layers.Dropout(config.dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.distilbert( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "distilbert", None) is not None: - with tf.name_scope(self.distilbert.name): - self.distilbert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - DistilBert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and - a softmax) e.g. for RocStories/SWAG tasks. - """, - DISTILBERT_START_DOCSTRING, -) -class TFDistilBertForMultipleChoice(TFDistilBertPreTrainedModel, TFMultipleChoiceLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.distilbert = TFDistilBertMainLayer(config, name="distilbert") - self.dropout = keras.layers.Dropout(config.seq_classif_dropout) - self.pre_classifier = keras.layers.Dense( - config.dim, - kernel_initializer=get_initializer(config.initializer_range), - activation="relu", - name="pre_classifier", - ) - self.classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward( - DISTILBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") - ) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_inputs_embeds = ( - tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - distilbert_output = self.distilbert( - flat_input_ids, - flat_attention_mask, - head_mask, - flat_inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_state = distilbert_output[0] # (bs, seq_len, dim) - pooled_output = hidden_state[:, 0] # (bs, dim) - pooled_output = self.pre_classifier(pooled_output) # (bs, dim) - pooled_output = self.dropout(pooled_output, training=training) # (bs, dim) - logits = self.classifier(pooled_output) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + distilbert_output[1:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=distilbert_output.hidden_states, - attentions=distilbert_output.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "distilbert", None) is not None: - with tf.name_scope(self.distilbert.name): - self.distilbert.build(None) - if getattr(self, "pre_classifier", None) is not None: - with tf.name_scope(self.pre_classifier.name): - self.pre_classifier.build([None, None, self.config.dim]) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.dim]) - - -@add_start_docstrings( - """ - DistilBert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a - linear layer on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - DISTILBERT_START_DOCSTRING, -) -class TFDistilBertForQuestionAnswering(TFDistilBertPreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.distilbert = TFDistilBertMainLayer(config, name="distilbert") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - assert config.num_labels == 2, f"Incorrect number of labels {config.num_labels} instead of 2" - self.dropout = keras.layers.Dropout(config.qa_dropout) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - distilbert_output = self.distilbert( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = distilbert_output[0] # (bs, max_query_len, dim) - hidden_states = self.dropout(hidden_states, training=training) # (bs, max_query_len, dim) - logits = self.qa_outputs(hidden_states) # (bs, max_query_len, 2) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + distilbert_output[1:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=distilbert_output.hidden_states, - attentions=distilbert_output.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "distilbert", None) is not None: - with tf.name_scope(self.distilbert.name): - self.distilbert.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.dim]) - - -__all__ = [ - "TFDistilBertForMaskedLM", - "TFDistilBertForMultipleChoice", - "TFDistilBertForQuestionAnswering", - "TFDistilBertForSequenceClassification", - "TFDistilBertForTokenClassification", - "TFDistilBertMainLayer", - "TFDistilBertModel", - "TFDistilBertPreTrainedModel", -] diff --git a/src/transformers/models/donut/image_processing_donut.py b/src/transformers/models/donut/image_processing_donut.py index 7dec96422c5d..f49cc964080d 100644 --- a/src/transformers/models/donut/image_processing_donut.py +++ b/src/transformers/models/donut/image_processing_donut.py @@ -363,10 +363,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -398,10 +396,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/donut/modeling_donut_swin.py b/src/transformers/models/donut/modeling_donut_swin.py index c5736b16183b..c541b960fd2e 100644 --- a/src/transformers/models/donut/modeling_donut_swin.py +++ b/src/transformers/models/donut/modeling_donut_swin.py @@ -334,11 +334,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -834,8 +829,6 @@ class DonutSwinPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/dpr/__init__.py b/src/transformers/models/dpr/__init__.py index 9aeadbeaf416..386b47bb2ecd 100644 --- a/src/transformers/models/dpr/__init__.py +++ b/src/transformers/models/dpr/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_dpr import * from .modeling_dpr import * - from .modeling_tf_dpr import * from .tokenization_dpr import * from .tokenization_dpr_fast import * else: diff --git a/src/transformers/models/dpr/modeling_dpr.py b/src/transformers/models/dpr/modeling_dpr.py index f1ae00a02e07..7ee4dcaf52e1 100644 --- a/src/transformers/models/dpr/modeling_dpr.py +++ b/src/transformers/models/dpr/modeling_dpr.py @@ -108,8 +108,6 @@ class DPRPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -247,7 +245,6 @@ class DPRPretrainedContextEncoder(DPRPreTrainedModel): """ config: DPRConfig - load_tf_weights = None base_model_prefix = "ctx_encoder" @@ -258,7 +255,6 @@ class DPRPretrainedQuestionEncoder(DPRPreTrainedModel): """ config: DPRConfig - load_tf_weights = None base_model_prefix = "question_encoder" @@ -269,7 +265,6 @@ class DPRPretrainedReader(DPRPreTrainedModel): """ config: DPRConfig - load_tf_weights = None base_model_prefix = "span_predictor" diff --git a/src/transformers/models/dpr/modeling_tf_dpr.py b/src/transformers/models/dpr/modeling_tf_dpr.py deleted file mode 100644 index aef83e6c55fb..000000000000 --- a/src/transformers/models/dpr/modeling_tf_dpr.py +++ /dev/null @@ -1,799 +0,0 @@ -# coding=utf-8 -# Copyright 2018 DPR Authors, The Hugging Face 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. - -"""TensorFlow DPR model for Open Domain Question Answering.""" - -from __future__ import annotations - -from dataclasses import dataclass - -import tensorflow as tf - -from ...modeling_tf_outputs import TFBaseModelOutputWithPooling -from ...modeling_tf_utils import TFModelInputType, TFPreTrainedModel, get_initializer, keras, shape_list, unpack_inputs -from ...utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from ..bert.modeling_tf_bert import TFBertMainLayer -from .configuration_dpr import DPRConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "DPRConfig" - - -########## -# Outputs -########## - - -@dataclass -class TFDPRContextEncoderOutput(ModelOutput): - r""" - Class for outputs of [`TFDPRContextEncoder`]. - - Args: - pooler_output (`tf.Tensor` of shape `(batch_size, embeddings_size)`): - The DPR encoder outputs the *pooler_output* that corresponds to the context representation. Last layer - hidden-state of the first token of the sequence (classification token) further processed by a Linear layer. - This output is to be used to embed contexts for nearest neighbors queries with questions embeddings. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - pooler_output: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFDPRQuestionEncoderOutput(ModelOutput): - """ - Class for outputs of [`TFDPRQuestionEncoder`]. - - Args: - pooler_output (`tf.Tensor` of shape `(batch_size, embeddings_size)`): - The DPR encoder outputs the *pooler_output* that corresponds to the question representation. Last layer - hidden-state of the first token of the sequence (classification token) further processed by a Linear layer. - This output is to be used to embed questions for nearest neighbors queries with context embeddings. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - pooler_output: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFDPRReaderOutput(ModelOutput): - """ - Class for outputs of [`TFDPRReaderEncoder`]. - - Args: - start_logits (`tf.Tensor` of shape `(n_passages, sequence_length)`): - Logits of the start index of the span for each passage. - end_logits (`tf.Tensor` of shape `(n_passages, sequence_length)`): - Logits of the end index of the span for each passage. - relevance_logits (`tf.Tensor` of shape `(n_passages, )`): - Outputs of the QA classifier of the DPRReader that corresponds to the scores of each passage to answer the - question, compared to all the other passages. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - start_logits: tf.Tensor | None = None - end_logits: tf.Tensor | None = None - relevance_logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -class TFDPREncoderLayer(keras.layers.Layer): - base_model_prefix = "bert_model" - - def __init__(self, config: DPRConfig, **kwargs): - super().__init__(**kwargs) - - # resolve name conflict with TFBertMainLayer instead of TFBertModel - self.bert_model = TFBertMainLayer(config, add_pooling_layer=False, name="bert_model") - self.config = config - - if self.config.hidden_size <= 0: - raise ValueError("Encoder hidden_size can't be zero") - self.projection_dim = config.projection_dim - if self.projection_dim > 0: - self.encode_proj = keras.layers.Dense( - config.projection_dim, kernel_initializer=get_initializer(config.initializer_range), name="encode_proj" - ) - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor, ...]: - outputs = self.bert_model( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - pooled_output = sequence_output[:, 0, :] - if self.projection_dim > 0: - pooled_output = self.encode_proj(pooled_output) - - if not return_dict: - return (sequence_output, pooled_output) + outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - @property - def embeddings_size(self) -> int: - if self.projection_dim > 0: - return self.projection_dim - return self.bert_model.config.hidden_size - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bert_model", None) is not None: - with tf.name_scope(self.bert_model.name): - self.bert_model.build(None) - if getattr(self, "encode_proj", None) is not None: - with tf.name_scope(self.encode_proj.name): - self.encode_proj.build(None) - - -class TFDPRSpanPredictorLayer(keras.layers.Layer): - base_model_prefix = "encoder" - - def __init__(self, config: DPRConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.encoder = TFDPREncoderLayer(config, name="encoder") - - self.qa_outputs = keras.layers.Dense( - 2, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.qa_classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="qa_classifier" - ) - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = False, - training: bool = False, - ) -> TFDPRReaderOutput | tuple[tf.Tensor, ...]: - # notations: N - number of questions in a batch, M - number of passages per questions, L - sequence length - n_passages, sequence_length = shape_list(input_ids) if input_ids is not None else shape_list(inputs_embeds)[:2] - # feed encoder - outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - # compute logits - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - relevance_logits = self.qa_classifier(sequence_output[:, 0, :]) - - # resize - start_logits = tf.reshape(start_logits, [n_passages, sequence_length]) - end_logits = tf.reshape(end_logits, [n_passages, sequence_length]) - relevance_logits = tf.reshape(relevance_logits, [n_passages]) - - if not return_dict: - return (start_logits, end_logits, relevance_logits) + outputs[2:] - - return TFDPRReaderOutput( - start_logits=start_logits, - end_logits=end_logits, - relevance_logits=relevance_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.encoder.embeddings_size]) - if getattr(self, "qa_classifier", None) is not None: - with tf.name_scope(self.qa_classifier.name): - self.qa_classifier.build([None, None, self.encoder.embeddings_size]) - - -class TFDPRSpanPredictor(TFPreTrainedModel): - base_model_prefix = "encoder" - - def __init__(self, config: DPRConfig, **kwargs): - super().__init__(config, **kwargs) - self.encoder = TFDPRSpanPredictorLayer(config) - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = False, - training: bool = False, - ) -> TFDPRReaderOutput | tuple[tf.Tensor, ...]: - outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - -class TFDPREncoder(TFPreTrainedModel): - base_model_prefix = "encoder" - - def __init__(self, config: DPRConfig, **kwargs): - super().__init__(config, **kwargs) - - self.encoder = TFDPREncoderLayer(config) - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = False, - training: bool = False, - ) -> TFDPRReaderOutput | tuple[tf.Tensor, ...]: - outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - -################## -# PreTrainedModel -################## - - -class TFDPRPretrainedContextEncoder(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = DPRConfig - base_model_prefix = "ctx_encoder" - - -class TFDPRPretrainedQuestionEncoder(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = DPRConfig - base_model_prefix = "question_encoder" - - -class TFDPRPretrainedReader(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = DPRConfig - base_model_prefix = "reader" - - -############### -# Actual Models -############### - - -TF_DPR_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Tensorflow [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) - subclass. Use it as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to - general usage and behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`DPRConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -TF_DPR_ENCODERS_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. To match pretraining, DPR input sequence should be - formatted with [CLS] and [SEP] tokens as follows: - - (a) For sequence pairs (for a pair title+text for example): - - ``` - tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP] - token_type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1 - ``` - - (b) For single sequences (for a question for example): - - ``` - tokens: [CLS] the dog is hairy . [SEP] - token_type_ids: 0 0 0 0 0 0 0 - ``` - - DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right - rather than the left. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - inputs_embeds (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - -TF_DPR_READER_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shapes `(n_passages, sequence_length)`): - Indices of input sequence tokens in the vocabulary. It has to be a sequence triplet with 1) the question - and 2) the passages titles and 3) the passages texts To match pretraining, DPR `input_ids` sequence should - be formatted with [CLS] and [SEP] with the format: - - `[CLS] [SEP] [SEP] ` - - DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right - rather than the left. - - Indices can be obtained using [`DPRReaderTokenizer`]. See this class documentation for more details. - attention_mask (`Numpy array` or `tf.Tensor` of shape `(n_passages, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - inputs_embeds (`Numpy array` or `tf.Tensor` of shape `(n_passages, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare DPRContextEncoder transformer outputting pooler outputs as context representations.", - TF_DPR_START_DOCSTRING, -) -class TFDPRContextEncoder(TFDPRPretrainedContextEncoder): - def __init__(self, config: DPRConfig, *args, **kwargs): - super().__init__(config, *args, **kwargs) - self.ctx_encoder = TFDPREncoderLayer(config, name="ctx_encoder") - - def get_input_embeddings(self): - try: - return self.ctx_encoder.bert_model.get_input_embeddings() - except AttributeError: - self.build() - return self.ctx_encoder.bert_model.get_input_embeddings() - - @unpack_inputs - @add_start_docstrings_to_model_forward(TF_DPR_ENCODERS_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFDPRContextEncoderOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFDPRContextEncoderOutput | tuple[tf.Tensor, ...]: - r""" - Return: - - Examples: - - ```python - >>> from transformers import TFDPRContextEncoder, DPRContextEncoderTokenizer - - >>> tokenizer = DPRContextEncoderTokenizer.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base") - >>> model = TFDPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base", from_pt=True) - >>> input_ids = tokenizer("Hello, is my dog cute ?", return_tensors="tf")["input_ids"] - >>> embeddings = model(input_ids).pooler_output - ``` - """ - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = ( - tf.ones(input_shape, dtype=tf.dtypes.int32) - if input_ids is None - else (input_ids != self.config.pad_token_id) - ) - if token_type_ids is None: - token_type_ids = tf.zeros(input_shape, dtype=tf.dtypes.int32) - - outputs = self.ctx_encoder( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return outputs[1:] - - return TFDPRContextEncoderOutput( - pooler_output=outputs.pooler_output, hidden_states=outputs.hidden_states, attentions=outputs.attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "ctx_encoder", None) is not None: - with tf.name_scope(self.ctx_encoder.name): - self.ctx_encoder.build(None) - - -@add_start_docstrings( - "The bare DPRQuestionEncoder transformer outputting pooler outputs as question representations.", - TF_DPR_START_DOCSTRING, -) -class TFDPRQuestionEncoder(TFDPRPretrainedQuestionEncoder): - def __init__(self, config: DPRConfig, *args, **kwargs): - super().__init__(config, *args, **kwargs) - self.question_encoder = TFDPREncoderLayer(config, name="question_encoder") - - def get_input_embeddings(self): - try: - return self.question_encoder.bert_model.get_input_embeddings() - except AttributeError: - self.build() - return self.question_encoder.bert_model.get_input_embeddings() - - @unpack_inputs - @add_start_docstrings_to_model_forward(TF_DPR_ENCODERS_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFDPRQuestionEncoderOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFDPRQuestionEncoderOutput | tuple[tf.Tensor, ...]: - r""" - Return: - - Examples: - - ```python - >>> from transformers import TFDPRQuestionEncoder, DPRQuestionEncoderTokenizer - - >>> tokenizer = DPRQuestionEncoderTokenizer.from_pretrained("facebook/dpr-question_encoder-single-nq-base") - >>> model = TFDPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base", from_pt=True) - >>> input_ids = tokenizer("Hello, is my dog cute ?", return_tensors="tf")["input_ids"] - >>> embeddings = model(input_ids).pooler_output - ``` - """ - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = ( - tf.ones(input_shape, dtype=tf.dtypes.int32) - if input_ids is None - else (input_ids != self.config.pad_token_id) - ) - if token_type_ids is None: - token_type_ids = tf.zeros(input_shape, dtype=tf.dtypes.int32) - - outputs = self.question_encoder( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return outputs[1:] - return TFDPRQuestionEncoderOutput( - pooler_output=outputs.pooler_output, hidden_states=outputs.hidden_states, attentions=outputs.attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "question_encoder", None) is not None: - with tf.name_scope(self.question_encoder.name): - self.question_encoder.build(None) - - -@add_start_docstrings( - "The bare DPRReader transformer outputting span predictions.", - TF_DPR_START_DOCSTRING, -) -class TFDPRReader(TFDPRPretrainedReader): - def __init__(self, config: DPRConfig, *args, **kwargs): - super().__init__(config, *args, **kwargs) - self.span_predictor = TFDPRSpanPredictorLayer(config, name="span_predictor") - - def get_input_embeddings(self): - try: - return self.span_predictor.encoder.bert_model.get_input_embeddings() - except AttributeError: - self.build() - return self.span_predictor.encoder.bert_model.get_input_embeddings() - - @unpack_inputs - @add_start_docstrings_to_model_forward(TF_DPR_READER_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFDPRReaderOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFDPRReaderOutput | tuple[tf.Tensor, ...]: - r""" - Return: - - Examples: - - ```python - >>> from transformers import TFDPRReader, DPRReaderTokenizer - - >>> tokenizer = DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base") - >>> model = TFDPRReader.from_pretrained("facebook/dpr-reader-single-nq-base", from_pt=True) - >>> encoded_inputs = tokenizer( - ... questions=["What is love ?"], - ... titles=["Haddaway"], - ... texts=["'What Is Love' is a song recorded by the artist Haddaway"], - ... return_tensors="tf", - ... ) - >>> outputs = model(encoded_inputs) - >>> start_logits = outputs.start_logits - >>> end_logits = outputs.end_logits - >>> relevance_logits = outputs.relevance_logits - ``` - """ - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.ones(input_shape, dtype=tf.dtypes.int32) - - return self.span_predictor( - input_ids=input_ids, - attention_mask=attention_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "span_predictor", None) is not None: - with tf.name_scope(self.span_predictor.name): - self.span_predictor.build(None) - - -__all__ = [ - "TFDPRContextEncoder", - "TFDPRPretrainedContextEncoder", - "TFDPRPretrainedQuestionEncoder", - "TFDPRPretrainedReader", - "TFDPRQuestionEncoder", - "TFDPRReader", -] diff --git a/src/transformers/models/dpr/tokenization_dpr.py b/src/transformers/models/dpr/tokenization_dpr.py index 020b235cb6bd..1a87ef9fd915 100644 --- a/src/transformers/models/dpr/tokenization_dpr.py +++ b/src/transformers/models/dpr/tokenization_dpr.py @@ -112,7 +112,6 @@ class DPRQuestionEncoderTokenizer(BertTokenizer): return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. return_attention_mask (`bool`, *optional*): diff --git a/src/transformers/models/dpr/tokenization_dpr_fast.py b/src/transformers/models/dpr/tokenization_dpr_fast.py index dbf745291745..5f501dbdd4f0 100644 --- a/src/transformers/models/dpr/tokenization_dpr_fast.py +++ b/src/transformers/models/dpr/tokenization_dpr_fast.py @@ -113,7 +113,6 @@ class DPRQuestionEncoderTokenizerFast(BertTokenizerFast): return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. return_attention_mask (`bool`, *optional*): diff --git a/src/transformers/models/dpt/configuration_dpt.py b/src/transformers/models/dpt/configuration_dpt.py index 70e46f232022..d0263630b075 100644 --- a/src/transformers/models/dpt/configuration_dpt.py +++ b/src/transformers/models/dpt/configuration_dpt.py @@ -122,9 +122,7 @@ class DPTConfig(PretrainedConfig): pooler_output_size (`int`, *optional*): Dimensionality of the pooler layer. If None, defaults to `hidden_size`. pooler_act (`str`, *optional*, defaults to `"tanh"`): - The activation function to be used by the pooler. Keys of ACT2FN are supported for Flax and - Pytorch, and elements of https://www.tensorflow.org/api_docs/python/tf/keras/activations are - supported for Tensorflow. + The activation function to be used by the pooler. Example: diff --git a/src/transformers/models/dpt/image_processing_dpt.py b/src/transformers/models/dpt/image_processing_dpt.py index 9b28950d2ded..0ec3eaed1c43 100644 --- a/src/transformers/models/dpt/image_processing_dpt.py +++ b/src/transformers/models/dpt/image_processing_dpt.py @@ -495,10 +495,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -531,10 +529,7 @@ def preprocess( segmentation_maps = make_flat_list_of_images(segmentation_maps, expected_ndims=2) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, @@ -591,7 +586,7 @@ def preprocess( # Copied from transformers.models.beit.image_processing_beit.BeitImageProcessor.post_process_semantic_segmentation with Beit->DPT def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[list[tuple]] = None): """ - Converts the output of [`DPTForSemanticSegmentation`] into semantic segmentation maps. Only supports PyTorch. + Converts the output of [`DPTForSemanticSegmentation`] into semantic segmentation maps. Args: outputs ([`DPTForSemanticSegmentation`]): @@ -605,7 +600,6 @@ def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[lis segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each `torch.Tensor` correspond to a semantic class id. """ - # TODO: add support for other frameworks logits = outputs.logits # Resize logits and compute semantic segmentation maps diff --git a/src/transformers/models/dpt/image_processing_dpt_fast.py b/src/transformers/models/dpt/image_processing_dpt_fast.py index d4848c50653c..3e80ad7943db 100644 --- a/src/transformers/models/dpt/image_processing_dpt_fast.py +++ b/src/transformers/models/dpt/image_processing_dpt_fast.py @@ -256,7 +256,7 @@ def _preprocess( def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[list[tuple]] = None): """ - Converts the output of [`DPTForSemanticSegmentation`] into semantic segmentation maps. Only supports PyTorch. + Converts the output of [`DPTForSemanticSegmentation`] into semantic segmentation maps. Args: outputs ([`DPTForSemanticSegmentation`]): @@ -270,7 +270,6 @@ def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[lis segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each `torch.Tensor` correspond to a semantic class id. """ - # TODO: add support for other frameworks logits = outputs.logits # Resize logits and compute semantic segmentation maps diff --git a/src/transformers/models/dpt/modeling_dpt.py b/src/transformers/models/dpt/modeling_dpt.py index 363fce92f897..7be71fd3ceb4 100755 --- a/src/transformers/models/dpt/modeling_dpt.py +++ b/src/transformers/models/dpt/modeling_dpt.py @@ -758,8 +758,6 @@ class DPTPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d, nn.ConvTranspose2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/efficientloftr/image_processing_efficientloftr.py b/src/transformers/models/efficientloftr/image_processing_efficientloftr.py index 58ce0e96f5b8..5b87278683ac 100644 --- a/src/transformers/models/efficientloftr/image_processing_efficientloftr.py +++ b/src/transformers/models/efficientloftr/image_processing_efficientloftr.py @@ -70,8 +70,7 @@ def convert_to_grayscale( input_data_format: Optional[Union[str, ChannelDimension]] = None, ) -> ImageInput: """ - Converts an image to grayscale format using the NTSC formula. Only support numpy and PIL Image. TODO support torch - and tensorflow grayscale conversion + Converts an image to grayscale format using the NTSC formula. Only support numpy and PIL Image. This function is supposed to return a 1-channel image, but it returns a 3-channel image with the same value in each channel, because of an issue that is discussed in : @@ -260,10 +259,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -290,10 +287,7 @@ def preprocess( images = validate_and_format_image_pairs(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_resize=do_resize, diff --git a/src/transformers/models/efficientnet/image_processing_efficientnet.py b/src/transformers/models/efficientnet/image_processing_efficientnet.py index ea822d75ca27..eaad420b31f8 100644 --- a/src/transformers/models/efficientnet/image_processing_efficientnet.py +++ b/src/transformers/models/efficientnet/image_processing_efficientnet.py @@ -264,10 +264,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - `None`: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -298,10 +296,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/efficientnet/modeling_efficientnet.py b/src/transformers/models/efficientnet/modeling_efficientnet.py index a263ff20760c..e368fefa0e79 100644 --- a/src/transformers/models/efficientnet/modeling_efficientnet.py +++ b/src/transformers/models/efficientnet/modeling_efficientnet.py @@ -438,8 +438,6 @@ class EfficientNetPreTrainedModel(PreTrainedModel): def _init_weights(self, module: nn.Module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/electra/__init__.py b/src/transformers/models/electra/__init__.py index a78ed5c42aea..506212b561e1 100644 --- a/src/transformers/models/electra/__init__.py +++ b/src/transformers/models/electra/__init__.py @@ -20,8 +20,6 @@ if TYPE_CHECKING: from .configuration_electra import * from .modeling_electra import * - from .modeling_flax_electra import * - from .modeling_tf_electra import * from .tokenization_electra import * from .tokenization_electra_fast import * else: diff --git a/src/transformers/models/electra/convert_electra_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/electra/convert_electra_original_tf_checkpoint_to_pytorch.py index b0abc30cd758..00d6fecc21b0 100644 --- a/src/transformers/models/electra/convert_electra_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/electra/convert_electra_original_tf_checkpoint_to_pytorch.py @@ -15,16 +15,100 @@ """Convert ELECTRA checkpoint.""" import argparse +import os import torch -from transformers import ElectraConfig, ElectraForMaskedLM, ElectraForPreTraining, load_tf_weights_in_electra +from transformers import ElectraConfig, ElectraForMaskedLM, ElectraForPreTraining from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +def load_tf_weights_in_electra(model, config, tf_checkpoint_path, discriminator_or_generator="discriminator"): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array) + for name, array in zip(names, arrays): + original_name: str = name + + try: + if isinstance(model, ElectraForMaskedLM): + name = name.replace("electra/embeddings/", "generator/embeddings/") + + if discriminator_or_generator == "generator": + name = name.replace("electra/", "discriminator/") + name = name.replace("generator/", "electra/") + + name = name.replace("dense_1", "dense_prediction") + name = name.replace("generator_predictions/output_bias", "generator_lm_head/bias") + + name = name.split("/") + # print(original_name, name) + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any(n in ["global_step", "temperature"] for n in name): + logger.info(f"Skipping {original_name}") + continue + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "kernel" or scope_names[0] == "gamma": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + else: + pointer = getattr(pointer, scope_names[0]) + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if m_name.endswith("_embeddings"): + pointer = getattr(pointer, "weight") + elif m_name == "kernel": + array = np.transpose(array) + try: + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + except ValueError as e: + e.args += (pointer.shape, array.shape) + raise + print(f"Initialize PyTorch weight {name}", original_name) + pointer.data = torch.from_numpy(array) + except AttributeError as e: + print(f"Skipping {original_name}", name, e) + continue + return model + + def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, config_file, pytorch_dump_path, discriminator_or_generator): # Initialise PyTorch model config = ElectraConfig.from_json_file(config_file) diff --git a/src/transformers/models/electra/modeling_electra.py b/src/transformers/models/electra/modeling_electra.py index a10b0b658337..d3b47ea55b79 100644 --- a/src/transformers/models/electra/modeling_electra.py +++ b/src/transformers/models/electra/modeling_electra.py @@ -15,7 +15,6 @@ """PyTorch ELECTRA model.""" import math -import os from dataclasses import dataclass from typing import Callable, Optional, Union @@ -47,88 +46,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_electra(model, config, tf_checkpoint_path, discriminator_or_generator="discriminator"): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - for name, array in zip(names, arrays): - original_name: str = name - - try: - if isinstance(model, ElectraForMaskedLM): - name = name.replace("electra/embeddings/", "generator/embeddings/") - - if discriminator_or_generator == "generator": - name = name.replace("electra/", "discriminator/") - name = name.replace("generator/", "electra/") - - name = name.replace("dense_1", "dense_prediction") - name = name.replace("generator_predictions/output_bias", "generator_lm_head/bias") - - name = name.split("/") - # print(original_name, name) - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any(n in ["global_step", "temperature"] for n in name): - logger.info(f"Skipping {original_name}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - pointer = getattr(pointer, scope_names[0]) - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name.endswith("_embeddings"): - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except ValueError as e: - e.args += (pointer.shape, array.shape) - raise - print(f"Initialize PyTorch weight {name}", original_name) - pointer.data = torch.from_numpy(array) - except AttributeError as e: - print(f"Skipping {original_name}", name, e) - continue - return model - - class ElectraEmbeddings(nn.Module): """Construct the embeddings from word, position and token_type embeddings.""" @@ -138,8 +55,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.embedding_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.embedding_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.embedding_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -637,15 +552,12 @@ def forward(self, generator_hidden_states): @auto_docstring class ElectraPreTrainedModel(PreTrainedModel): config: ElectraConfig - load_tf_weights = load_tf_weights_in_electra base_model_prefix = "electra" supports_gradient_checkpointing = True def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1582,5 +1494,4 @@ def forward( "ElectraForTokenClassification", "ElectraModel", "ElectraPreTrainedModel", - "load_tf_weights_in_electra", ] diff --git a/src/transformers/models/electra/modeling_flax_electra.py b/src/transformers/models/electra/modeling_flax_electra.py deleted file mode 100644 index 14d845476d62..000000000000 --- a/src/transformers/models/electra/modeling_flax_electra.py +++ /dev/null @@ -1,1614 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Google Flax Team Authors and 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. - -from typing import Callable, Optional - -import flax -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen import partitioning as nn_partitioning -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxMaskedLMOutput, - FlaxMultipleChoiceModelOutput, - FlaxQuestionAnsweringModelOutput, - FlaxSequenceClassifierOutput, - FlaxTokenClassifierOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import ModelOutput, add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_electra import ElectraConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "google/electra-small-discriminator" -_CONFIG_FOR_DOC = "ElectraConfig" - -remat = nn_partitioning.remat - - -@flax.struct.dataclass -class FlaxElectraForPreTrainingOutput(ModelOutput): - """ - Output type of [`ElectraForPreTraining`]. - - Args: - logits (`jnp.ndarray` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: jnp.ndarray = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -ELECTRA_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`ElectraConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -ELECTRA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - head_mask (`numpy.ndarray` of shape `({0})`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - -""" - - -class FlaxElectraEmbeddings(nn.Module): - """Construct the embeddings from word, position and token_type embeddings.""" - - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.word_embeddings = nn.Embed( - self.config.vocab_size, - self.config.embedding_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.position_embeddings = nn.Embed( - self.config.max_position_embeddings, - self.config.embedding_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.token_type_embeddings = nn.Embed( - self.config.type_vocab_size, - self.config.embedding_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEmbeddings.__call__ - def __call__(self, input_ids, token_type_ids, position_ids, attention_mask, deterministic: bool = True): - # Embed - inputs_embeds = self.word_embeddings(input_ids.astype("i4")) - position_embeds = self.position_embeddings(position_ids.astype("i4")) - token_type_embeddings = self.token_type_embeddings(token_type_ids.astype("i4")) - - # Sum all embeddings - hidden_states = inputs_embeds + token_type_embeddings + position_embeds - - # Layer Norm - hidden_states = self.LayerNorm(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfAttention with Bert->Electra -class FlaxElectraSelfAttention(nn.Module): - config: ElectraConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.head_dim = self.config.hidden_size // self.config.num_attention_heads - if self.config.hidden_size % self.config.num_attention_heads != 0: - raise ValueError( - "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads` " - " : {self.config.num_attention_heads}" - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.num_attention_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.hidden_size,)) - - @nn.compact - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention._concatenate_to_cache - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic=True, - output_attentions: bool = False, - ): - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.query(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.key(key_value_states) - value_states = self.value(key_value_states) - else: - # self_attention - key_states = self.key(hidden_states) - value_states = self.value(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - # Mask heads if we want to - if layer_head_mask is not None: - attn_weights = jnp.einsum("...hqk,h->...hqk", attn_weights, layer_head_mask) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfOutput with Bert->Electra -class FlaxElectraSelfOutput(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, input_tensor, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertAttention with Bert->Electra -class FlaxElectraAttention(nn.Module): - config: ElectraConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.self = FlaxElectraSelfAttention(self.config, causal=self.causal, dtype=self.dtype) - self.output = FlaxElectraSelfOutput(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states=None, - init_cache=False, - deterministic=True, - output_attentions: bool = False, - ): - # Attention mask comes in as attention_mask.shape == (*batch_sizes, kv_length) - # FLAX expects: attention_mask.shape == (*batch_sizes, 1, 1, kv_length) such that it is broadcastable - # with attn_weights.shape == (*batch_sizes, num_heads, q_length, kv_length) - attn_outputs = self.self( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=key_value_states, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attn_output = attn_outputs[0] - hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_outputs[1],) - - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertIntermediate with Bert->Electra -class FlaxElectraIntermediate(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertOutput with Bert->Electra -class FlaxElectraOutput(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states, attention_output, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + attention_output) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayer with Bert->Electra -class FlaxElectraLayer(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.attention = FlaxElectraAttention(self.config, causal=self.config.is_decoder, dtype=self.dtype) - self.intermediate = FlaxElectraIntermediate(self.config, dtype=self.dtype) - self.output = FlaxElectraOutput(self.config, dtype=self.dtype) - if self.config.add_cross_attention: - self.crossattention = FlaxElectraAttention(self.config, causal=False, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - ): - # Self Attention - attention_outputs = self.attention( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = attention_outputs[0] - - # Cross-Attention Block - if encoder_hidden_states is not None: - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=encoder_hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = cross_attention_outputs[0] - - hidden_states = self.intermediate(attention_output) - hidden_states = self.output(hidden_states, attention_output, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attention_outputs[1],) - if encoder_hidden_states is not None: - outputs += (cross_attention_outputs[1],) - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayerCollection with Bert->Electra -class FlaxElectraLayerCollection(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - if self.gradient_checkpointing: - FlaxElectraCheckpointLayer = remat(FlaxElectraLayer, static_argnums=(5, 6, 7)) - self.layers = [ - FlaxElectraCheckpointLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - else: - self.layers = [ - FlaxElectraLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - # Check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - if head_mask.shape[0] != (len(self.layers)): - raise ValueError( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for " - f" {head_mask.shape[0]}." - ) - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer( - hidden_states, - attention_mask, - head_mask[i] if head_mask is not None else None, - encoder_hidden_states, - encoder_attention_mask, - init_cache, - deterministic, - output_attentions, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions, all_cross_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEncoder with Bert->Electra -class FlaxElectraEncoder(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.layer = FlaxElectraLayerCollection( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.layer( - hidden_states, - attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -class FlaxElectraGeneratorPredictions(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dense = nn.Dense(self.config.embedding_size, dtype=self.dtype) - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = ACT2FN[self.config.hidden_act](hidden_states) - hidden_states = self.LayerNorm(hidden_states) - return hidden_states - - -class FlaxElectraDiscriminatorPredictions(nn.Module): - """Prediction module for the discriminator, made up of two dense layers.""" - - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense(self.config.hidden_size, dtype=self.dtype) - self.dense_prediction = nn.Dense(1, dtype=self.dtype) - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = ACT2FN[self.config.hidden_act](hidden_states) - hidden_states = self.dense_prediction(hidden_states).squeeze(-1) - return hidden_states - - -class FlaxElectraPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = ElectraConfig - base_model_prefix = "electra" - module_class: nn.Module = None - - def __init__( - self, - config: ElectraConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - gradient_checkpointing: bool = False, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, gradient_checkpointing=gradient_checkpointing, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPreTrainedModel.enable_gradient_checkpointing - def enable_gradient_checkpointing(self): - self._module = self.module_class( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=True, - ) - - # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPreTrainedModel.init_weights - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - token_type_ids = jnp.zeros_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - attention_mask = jnp.ones_like(input_ids) - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - if self.config.add_cross_attention: - encoder_hidden_states = jnp.zeros(input_shape + (self.config.hidden_size,)) - encoder_attention_mask = attention_mask - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - return_dict=False, - ) - else: - module_init_outputs = self.module.init( - rngs, input_ids, attention_mask, token_type_ids, position_ids, head_mask, return_dict=False - ) - - random_params = module_init_outputs["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderPreTrainedModel.init_cache - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length), dtype="i4") - attention_mask = jnp.ones_like(input_ids, dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - past_key_values: Optional[dict] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # init input tensors if not passed - if token_type_ids is None: - token_type_ids = jnp.ones_like(input_ids) - - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - if head_mask is None: - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - if self.config.add_cross_attention: - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed - # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be - # changed by FlaxElectraAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - else: - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - ) - - return outputs - - -class FlaxElectraModule(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.embeddings = FlaxElectraEmbeddings(self.config, dtype=self.dtype) - if self.config.embedding_size != self.config.hidden_size: - self.embeddings_project = nn.Dense(self.config.hidden_size, dtype=self.dtype) - self.encoder = FlaxElectraEncoder( - self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask: Optional[np.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - embeddings = self.embeddings( - input_ids, token_type_ids, position_ids, attention_mask, deterministic=deterministic - ) - if hasattr(self, "embeddings_project"): - embeddings = self.embeddings_project(embeddings) - - return self.encoder( - embeddings, - attention_mask, - head_mask=head_mask, - deterministic=deterministic, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -@add_start_docstrings( - "The bare Electra Model transformer outputting raw hidden-states without any specific head on top.", - ELECTRA_START_DOCSTRING, -) -class FlaxElectraModel(FlaxElectraPreTrainedModel): - module_class = FlaxElectraModule - - -append_call_sample_docstring(FlaxElectraModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutput, _CONFIG_FOR_DOC) - - -class FlaxElectraTiedDense(nn.Module): - embedding_size: int - dtype: jnp.dtype = jnp.float32 - precision = None - bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.bias = self.param("bias", self.bias_init, (self.embedding_size,)) - - def __call__(self, x, kernel): - x = jnp.asarray(x, self.dtype) - kernel = jnp.asarray(kernel, self.dtype) - y = lax.dot_general( - x, - kernel, - (((x.ndim - 1,), (0,)), ((), ())), - precision=self.precision, - ) - bias = jnp.asarray(self.bias, self.dtype) - return y + bias - - -class FlaxElectraForMaskedLMModule(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.electra = FlaxElectraModule( - config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.generator_predictions = FlaxElectraGeneratorPredictions(config=self.config, dtype=self.dtype) - if self.config.tie_word_embeddings: - self.generator_lm_head = FlaxElectraTiedDense(self.config.vocab_size, dtype=self.dtype) - else: - self.generator_lm_head = nn.Dense(self.config.vocab_size, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - outputs = self.electra( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - prediction_scores = self.generator_predictions(hidden_states) - - if self.config.tie_word_embeddings: - shared_embedding = self.electra.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - prediction_scores = self.generator_lm_head(prediction_scores, shared_embedding.T) - else: - prediction_scores = self.generator_lm_head(prediction_scores) - - if not return_dict: - return (prediction_scores,) + outputs[1:] - - return FlaxMaskedLMOutput( - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings("""Electra Model with a `language modeling` head on top.""", ELECTRA_START_DOCSTRING) -class FlaxElectraForMaskedLM(FlaxElectraPreTrainedModel): - module_class = FlaxElectraForMaskedLMModule - - -append_call_sample_docstring(FlaxElectraForMaskedLM, _CHECKPOINT_FOR_DOC, FlaxMaskedLMOutput, _CONFIG_FOR_DOC) - - -class FlaxElectraForPreTrainingModule(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.electra = FlaxElectraModule( - config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.discriminator_predictions = FlaxElectraDiscriminatorPredictions(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.electra( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - - logits = self.discriminator_predictions(hidden_states) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxElectraForPreTrainingOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Electra model with a binary classification head on top as used during pretraining for identifying generated tokens. - - It is recommended to load the discriminator checkpoint into that model. - """, - ELECTRA_START_DOCSTRING, -) -class FlaxElectraForPreTraining(FlaxElectraPreTrainedModel): - module_class = FlaxElectraForPreTrainingModule - - -FLAX_ELECTRA_FOR_PRETRAINING_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxElectraForPreTraining - - >>> tokenizer = AutoTokenizer.from_pretrained("google/electra-small-discriminator") - >>> model = FlaxElectraForPreTraining.from_pretrained("google/electra-small-discriminator") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="np") - >>> outputs = model(**inputs) - - >>> prediction_logits = outputs.logits - ``` -""" - -overwrite_call_docstring( - FlaxElectraForPreTraining, - ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length") + FLAX_ELECTRA_FOR_PRETRAINING_DOCSTRING, -) -append_replace_return_docstrings( - FlaxElectraForPreTraining, output_type=FlaxElectraForPreTrainingOutput, config_class=_CONFIG_FOR_DOC -) - - -class FlaxElectraForTokenClassificationModule(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.electra = FlaxElectraModule( - config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(classifier_dropout) - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.electra( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - logits = self.classifier(hidden_states) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxTokenClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Electra model with a token classification head on top. - - Both the discriminator and generator may be loaded into this model. - """, - ELECTRA_START_DOCSTRING, -) -class FlaxElectraForTokenClassification(FlaxElectraPreTrainedModel): - module_class = FlaxElectraForTokenClassificationModule - - -append_call_sample_docstring( - FlaxElectraForTokenClassification, - _CHECKPOINT_FOR_DOC, - FlaxTokenClassifierOutput, - _CONFIG_FOR_DOC, -) - - -def identity(x, **kwargs): - return x - - -class FlaxElectraSequenceSummary(nn.Module): - r""" - Compute a single vector summary of a sequence hidden states. - - Args: - config ([`PretrainedConfig`]): - The config used by the model. Relevant arguments in the config class of the model are (refer to the actual - config class of your model for the default values it uses): - - - **summary_use_proj** (`bool`) -- Add a projection after the vector extraction. - - **summary_proj_to_labels** (`bool`) -- If `True`, the projection outputs to `config.num_labels` classes - (otherwise to `config.hidden_size`). - - **summary_activation** (`Optional[str]`) -- Set to `"tanh"` to add a tanh activation to the output, - another string or `None` will add no activation. - - **summary_first_dropout** (`float`) -- Optional dropout probability before the projection and activation. - - **summary_last_dropout** (`float`)-- Optional dropout probability after the projection and activation. - """ - - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.summary = identity - if hasattr(self.config, "summary_use_proj") and self.config.summary_use_proj: - if ( - hasattr(self.config, "summary_proj_to_labels") - and self.config.summary_proj_to_labels - and self.config.num_labels > 0 - ): - num_classes = self.config.num_labels - else: - num_classes = self.config.hidden_size - self.summary = nn.Dense(num_classes, dtype=self.dtype) - - activation_string = getattr(self.config, "summary_activation", None) - self.activation = ACT2FN[activation_string] if activation_string else lambda x: x # noqa F407 - - self.first_dropout = identity - if hasattr(self.config, "summary_first_dropout") and self.config.summary_first_dropout > 0: - self.first_dropout = nn.Dropout(self.config.summary_first_dropout) - - self.last_dropout = identity - if hasattr(self.config, "summary_last_dropout") and self.config.summary_last_dropout > 0: - self.last_dropout = nn.Dropout(self.config.summary_last_dropout) - - def __call__(self, hidden_states, cls_index=None, deterministic: bool = True): - """ - Compute a single vector summary of a sequence hidden states. - - Args: - hidden_states (`jnp.ndarray` of shape `[batch_size, seq_len, hidden_size]`): - The hidden states of the last layer. - cls_index (`jnp.ndarray` of shape `[batch_size]` or `[batch_size, ...]` where ... are optional leading dimensions of `hidden_states`, *optional*): - Used if `summary_type == "cls_index"` and takes the last token of the sequence as classification token. - - Returns: - `jnp.ndarray`: The summary of the sequence hidden states. - """ - # NOTE: this does "first" type summary always - output = hidden_states[:, 0] - output = self.first_dropout(output, deterministic=deterministic) - output = self.summary(output) - output = self.activation(output) - output = self.last_dropout(output, deterministic=deterministic) - return output - - -class FlaxElectraForMultipleChoiceModule(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.electra = FlaxElectraModule( - config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.sequence_summary = FlaxElectraSequenceSummary(config=self.config, dtype=self.dtype) - self.classifier = nn.Dense(1, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - num_choices = input_ids.shape[1] - input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None - attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None - token_type_ids = token_type_ids.reshape(-1, token_type_ids.shape[-1]) if token_type_ids is not None else None - position_ids = position_ids.reshape(-1, position_ids.shape[-1]) if position_ids is not None else None - - # Model - outputs = self.electra( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - pooled_output = self.sequence_summary(hidden_states, deterministic=deterministic) - logits = self.classifier(pooled_output) - - reshaped_logits = logits.reshape(-1, num_choices) - - if not return_dict: - return (reshaped_logits,) + outputs[1:] - - return FlaxMultipleChoiceModelOutput( - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - ELECTRA Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - ELECTRA_START_DOCSTRING, -) -class FlaxElectraForMultipleChoice(FlaxElectraPreTrainedModel): - module_class = FlaxElectraForMultipleChoiceModule - - -# adapt docstring slightly for FlaxElectraForMultipleChoice -overwrite_call_docstring( - FlaxElectraForMultipleChoice, ELECTRA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") -) -append_call_sample_docstring( - FlaxElectraForMultipleChoice, - _CHECKPOINT_FOR_DOC, - FlaxMultipleChoiceModelOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxElectraForQuestionAnsweringModule(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.electra = FlaxElectraModule( - config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.electra( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - logits = self.qa_outputs(hidden_states) - start_logits, end_logits = jnp.split(logits, self.config.num_labels, axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - return (start_logits, end_logits) + outputs[1:] - - return FlaxQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - ELECTRA Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - ELECTRA_START_DOCSTRING, -) -class FlaxElectraForQuestionAnswering(FlaxElectraPreTrainedModel): - module_class = FlaxElectraForQuestionAnsweringModule - - -append_call_sample_docstring( - FlaxElectraForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxElectraClassificationHead(nn.Module): - """Head for sentence-level classification tasks.""" - - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense(self.config.hidden_size, dtype=self.dtype) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(classifier_dropout) - self.out_proj = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__(self, hidden_states, deterministic: bool = True): - x = hidden_states[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x, deterministic=deterministic) - x = self.dense(x) - x = ACT2FN["gelu"](x) # although BERT uses tanh here, it seems Electra authors used gelu - x = self.dropout(x, deterministic=deterministic) - x = self.out_proj(x) - return x - - -class FlaxElectraForSequenceClassificationModule(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.electra = FlaxElectraModule( - config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.classifier = FlaxElectraClassificationHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.electra( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - logits = self.classifier(hidden_states, deterministic=deterministic) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Electra Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - ELECTRA_START_DOCSTRING, -) -class FlaxElectraForSequenceClassification(FlaxElectraPreTrainedModel): - module_class = FlaxElectraForSequenceClassificationModule - - -append_call_sample_docstring( - FlaxElectraForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxElectraForCausalLMModule(nn.Module): - config: ElectraConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.electra = FlaxElectraModule( - config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.generator_predictions = FlaxElectraGeneratorPredictions(config=self.config, dtype=self.dtype) - if self.config.tie_word_embeddings: - self.generator_lm_head = FlaxElectraTiedDense(self.config.vocab_size, dtype=self.dtype) - else: - self.generator_lm_head = nn.Dense(self.config.vocab_size, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask: Optional[jnp.ndarray] = None, - token_type_ids: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - head_mask: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - outputs = self.electra( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - prediction_scores = self.generator_predictions(hidden_states) - - if self.config.tie_word_embeddings: - shared_embedding = self.electra.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - prediction_scores = self.generator_lm_head(prediction_scores, shared_embedding.T) - else: - prediction_scores = self.generator_lm_head(prediction_scores) - - if not return_dict: - return (prediction_scores,) + outputs[1:] - - return FlaxCausalLMOutputWithCrossAttentions( - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - """ - Electra Model with a language modeling head on top (a linear layer on top of the hidden-states output) e.g for - autoregressive tasks. - """, - ELECTRA_START_DOCSTRING, -) -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForCausalLM with Bert->Electra -class FlaxElectraForCausalLM(FlaxElectraPreTrainedModel): - module_class = FlaxElectraForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyway. - # Thus, we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxElectraForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutputWithCrossAttentions, - _CONFIG_FOR_DOC, -) - - -__all__ = [ - "FlaxElectraForCausalLM", - "FlaxElectraForMaskedLM", - "FlaxElectraForMultipleChoice", - "FlaxElectraForPreTraining", - "FlaxElectraForQuestionAnswering", - "FlaxElectraForSequenceClassification", - "FlaxElectraForTokenClassification", - "FlaxElectraModel", - "FlaxElectraPreTrainedModel", -] diff --git a/src/transformers/models/electra/modeling_tf_electra.py b/src/transformers/models/electra/modeling_tf_electra.py deleted file mode 100644 index 3a5c33e503d7..000000000000 --- a/src/transformers/models/electra/modeling_tf_electra.py +++ /dev/null @@ -1,1775 +0,0 @@ -# coding=utf-8 -# Copyright 2019 The Google AI Language Team Authors and 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. -"""TF Electra model.""" - -from __future__ import annotations - -import math -import warnings -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFSequenceSummary, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_electra import ElectraConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "google/electra-small-discriminator" -_CONFIG_FOR_DOC = "ElectraConfig" - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention with Bert->Electra -class TFElectraSelfAttention(keras.layers.Layer): - def __init__(self, config: ElectraConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - - self.is_decoder = config.is_decoder - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_layer = past_key_value[0] - value_layer = past_key_value[1] - attention_mask = encoder_attention_mask - elif is_cross_attention: - key_layer = self.transpose_for_scores(self.key(inputs=encoder_hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=encoder_hidden_states), batch_size) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_layer, value_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFElectraModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - if self.is_decoder: - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfOutput with Bert->Electra -class TFElectraSelfOutput(keras.layers.Layer): - def __init__(self, config: ElectraConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertAttention with Bert->Electra -class TFElectraAttention(keras.layers.Layer): - def __init__(self, config: ElectraConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFElectraSelfAttention(config, name="self") - self.dense_output = TFElectraSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - # add attentions (possibly with past_key_value) if we output them - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->Electra -class TFElectraIntermediate(keras.layers.Layer): - def __init__(self, config: ElectraConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->Electra -class TFElectraOutput(keras.layers.Layer): - def __init__(self, config: ElectraConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLayer with Bert->Electra -class TFElectraLayer(keras.layers.Layer): - def __init__(self, config: ElectraConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFElectraAttention(config, name="attention") - self.is_decoder = config.is_decoder - self.add_cross_attention = config.add_cross_attention - if self.add_cross_attention: - if not self.is_decoder: - raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = TFElectraAttention(config, name="crossattention") - self.intermediate = TFElectraIntermediate(config, name="intermediate") - self.bert_output = TFElectraOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_value: tuple[tf.Tensor] | None, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=self_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - cross_attn_present_key_value = None - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" - " by setting `config.add_cross_attention=True`" - ) - - # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - cross_attention_outputs = self.crossattention( - input_tensor=attention_output, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=cross_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - - # add cross-attn cache to positions 3,4 of present_key_value tuple - cross_attn_present_key_value = cross_attention_outputs[-1] - present_key_value = present_key_value + cross_attn_present_key_value - - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + outputs # add attentions if we output them - - # if decoder, return the attn key/values as the last output - if self.is_decoder: - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertEncoder with Bert->Electra -class TFElectraEncoder(keras.layers.Layer): - def __init__(self, config: ElectraConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layer = [TFElectraLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_values: tuple[tuple[tf.Tensor]] | None, - use_cache: bool | None, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - next_decoder_cache = () if use_cache else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[i], - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - if self.config.add_cross_attention and encoder_hidden_states is not None: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v for v in [hidden_states, all_hidden_states, all_attentions, all_cross_attentions] if v is not None - ) - - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->Electra -class TFElectraPooler(keras.layers.Layer): - def __init__(self, config: ElectraConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.albert.modeling_tf_albert.TFAlbertEmbeddings with Albert->Electra -class TFElectraEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config: ElectraConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = config.embedding_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.embedding_size]) - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertEmbeddings.call - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - past_key_values_length=0, - training: bool = False, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - if input_ids is None and inputs_embeds is None: - raise ValueError("Need to provide either `input_ids` or `input_embeds`.") - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - position_ids = tf.expand_dims( - tf.range(start=past_key_values_length, limit=input_shape[1] + past_key_values_length), axis=0 - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -class TFElectraDiscriminatorPredictions(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense(config.hidden_size, name="dense") - self.dense_prediction = keras.layers.Dense(1, name="dense_prediction") - self.config = config - - def call(self, discriminator_hidden_states, training=False): - hidden_states = self.dense(discriminator_hidden_states) - hidden_states = get_tf_activation(self.config.hidden_act)(hidden_states) - logits = tf.squeeze(self.dense_prediction(hidden_states), -1) - - return logits - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "dense_prediction", None) is not None: - with tf.name_scope(self.dense_prediction.name): - self.dense_prediction.build([None, None, self.config.hidden_size]) - - -class TFElectraGeneratorPredictions(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dense = keras.layers.Dense(config.embedding_size, name="dense") - self.config = config - - def call(self, generator_hidden_states, training=False): - hidden_states = self.dense(generator_hidden_states) - hidden_states = get_tf_activation("gelu")(hidden_states) - hidden_states = self.LayerNorm(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.embedding_size]) - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFElectraPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = ElectraConfig - base_model_prefix = "electra" - # When the model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"generator_lm_head.weight"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - -@keras_serializable -class TFElectraMainLayer(keras.layers.Layer): - config_class = ElectraConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.is_decoder = config.is_decoder - - self.embeddings = TFElectraEmbeddings(config, name="embeddings") - - if config.embedding_size != config.hidden_size: - self.embeddings_project = keras.layers.Dense(config.hidden_size, name="embeddings_project") - - self.encoder = TFElectraEncoder(config, name="encoder") - - def get_input_embeddings(self): - return self.embeddings - - def set_input_embeddings(self, value): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - def get_extended_attention_mask(self, attention_mask, input_shape, dtype, past_key_values_length=0): - batch_size, seq_length = input_shape - - if attention_mask is None: - attention_mask = tf.fill(dims=(batch_size, seq_length + past_key_values_length), value=1) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - - mask_seq_length = seq_length + past_key_values_length - # Copied from `modeling_tf_t5.py` - # Provided a padding mask of dimensions [batch_size, mask_seq_length] - # - if the model is a decoder, apply a causal mask in addition to the padding mask - # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - if self.is_decoder: - seq_ids = tf.range(mask_seq_length) - causal_mask = tf.less_equal( - tf.tile(seq_ids[None, None, :], (batch_size, mask_seq_length, 1)), - seq_ids[None, :, None], - ) - causal_mask = tf.cast(causal_mask, dtype=attention_mask.dtype) - extended_attention_mask = causal_mask * attention_mask[:, None, :] - attention_mask_shape = shape_list(extended_attention_mask) - extended_attention_mask = tf.reshape( - extended_attention_mask, (attention_mask_shape[0], 1, attention_mask_shape[1], attention_mask_shape[2]) - ) - if past_key_values_length > 0: - extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :] - else: - extended_attention_mask = tf.reshape( - attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1]) - ) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=dtype) - one_cst = tf.constant(1.0, dtype=dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - return extended_attention_mask - - def get_head_mask(self, head_mask): - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - return head_mask - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - if not self.config.is_decoder: - use_cache = False - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - - if past_key_values is None: - past_key_values_length = 0 - past_key_values = [None] * len(self.encoder.layer) - else: - past_key_values_length = shape_list(past_key_values[0][0])[-2] - - if attention_mask is None: - attention_mask = tf.fill(dims=(batch_size, seq_length + past_key_values_length), value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - hidden_states = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - training=training, - ) - extended_attention_mask = self.get_extended_attention_mask( - attention_mask, input_shape, hidden_states.dtype, past_key_values_length - ) - - # Copied from `modeling_tf_t5.py` with -1e9 -> -10000 - if self.is_decoder and encoder_attention_mask is not None: - # If a 2D ou 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=extended_attention_mask.dtype) - num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) - if num_dims_encoder_attention_mask == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if num_dims_encoder_attention_mask == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, - # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) - - encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -10000.0 - else: - encoder_extended_attention_mask = None - - head_mask = self.get_head_mask(head_mask) - - if hasattr(self, "embeddings_project"): - hidden_states = self.embeddings_project(hidden_states, training=training) - - hidden_states = self.encoder( - hidden_states=hidden_states, - attention_mask=extended_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "embeddings_project", None) is not None: - with tf.name_scope(self.embeddings_project.name): - self.embeddings_project.build([None, None, self.config.embedding_size]) - - -@dataclass -class TFElectraForPreTrainingOutput(ModelOutput): - """ - Output type of [`TFElectraForPreTraining`]. - - Args: - loss (*optional*, returned when `labels` is provided, `tf.Tensor` of shape `(1,)`): - Total loss of the ELECTRA objective. - logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Prediction scores of the head (scores for each token before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -ELECTRA_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`ElectraConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -ELECTRA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare Electra Model transformer outputting raw hidden-states without any specific head on top. Identical to " - "the BERT model except that it uses an additional linear layer between the embedding layer and the encoder if the " - "hidden size and embedding size are different. " - "" - "Both the generator and discriminator checkpoints may be loaded into this model.", - ELECTRA_START_DOCSTRING, -) -class TFElectraModel(TFElectraPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.electra = TFElectraMainLayer(config, name="electra") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPastAndCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - """ - outputs = self.electra( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "electra", None) is not None: - with tf.name_scope(self.electra.name): - self.electra.build(None) - - -@add_start_docstrings( - """ - Electra model with a binary classification head on top as used during pretraining for identifying generated tokens. - - Even though both the discriminator and generator may be loaded into this model, the discriminator is the only model - of the two to have the correct classification head to be used for this model. - """, - ELECTRA_START_DOCSTRING, -) -class TFElectraForPreTraining(TFElectraPreTrainedModel): - def __init__(self, config, **kwargs): - super().__init__(config, **kwargs) - - self.electra = TFElectraMainLayer(config, name="electra") - self.discriminator_predictions = TFElectraDiscriminatorPredictions(config, name="discriminator_predictions") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFElectraForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFElectraForPreTrainingOutput | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFElectraForPreTraining - - >>> tokenizer = AutoTokenizer.from_pretrained("google/electra-small-discriminator") - >>> model = TFElectraForPreTraining.from_pretrained("google/electra-small-discriminator") - >>> input_ids = tf.constant(tokenizer.encode("Hello, my dog is cute"))[None, :] # Batch size 1 - >>> outputs = model(input_ids) - >>> scores = outputs[0] - ```""" - discriminator_hidden_states = self.electra( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - discriminator_sequence_output = discriminator_hidden_states[0] - logits = self.discriminator_predictions(discriminator_sequence_output) - - if not return_dict: - return (logits,) + discriminator_hidden_states[1:] - - return TFElectraForPreTrainingOutput( - logits=logits, - hidden_states=discriminator_hidden_states.hidden_states, - attentions=discriminator_hidden_states.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "electra", None) is not None: - with tf.name_scope(self.electra.name): - self.electra.build(None) - if getattr(self, "discriminator_predictions", None) is not None: - with tf.name_scope(self.discriminator_predictions.name): - self.discriminator_predictions.build(None) - - -class TFElectraMaskedLMHead(keras.layers.Layer): - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = config.embedding_size - self.input_embeddings = input_embeddings - - def build(self, input_shape): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - super().build(input_shape) - - def get_output_embeddings(self): - return self.input_embeddings - - def set_output_embeddings(self, value): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.embedding_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -@add_start_docstrings( - """ - Electra model with a language modeling head on top. - - Even though both the discriminator and generator may be loaded into this model, the generator is the only model of - the two to have been trained for the masked language modeling task. - """, - ELECTRA_START_DOCSTRING, -) -class TFElectraForMaskedLM(TFElectraPreTrainedModel, TFMaskedLanguageModelingLoss): - def __init__(self, config, **kwargs): - super().__init__(config, **kwargs) - - self.config = config - self.electra = TFElectraMainLayer(config, name="electra") - self.generator_predictions = TFElectraGeneratorPredictions(config, name="generator_predictions") - - if isinstance(config.hidden_act, str): - self.activation = get_tf_activation(config.hidden_act) - else: - self.activation = config.hidden_act - - self.generator_lm_head = TFElectraMaskedLMHead(config, self.electra.embeddings, name="generator_lm_head") - - def get_lm_head(self): - return self.generator_lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.generator_lm_head.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="google/electra-small-generator", - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - mask="[MASK]", - expected_output="'paris'", - expected_loss=1.22, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - generator_hidden_states = self.electra( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - generator_sequence_output = generator_hidden_states[0] - prediction_scores = self.generator_predictions(generator_sequence_output, training=training) - prediction_scores = self.generator_lm_head(prediction_scores, training=training) - loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) - - if not return_dict: - output = (prediction_scores,) + generator_hidden_states[1:] - - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=generator_hidden_states.hidden_states, - attentions=generator_hidden_states.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "electra", None) is not None: - with tf.name_scope(self.electra.name): - self.electra.build(None) - if getattr(self, "generator_predictions", None) is not None: - with tf.name_scope(self.generator_predictions.name): - self.generator_predictions.build(None) - if getattr(self, "generator_lm_head", None) is not None: - with tf.name_scope(self.generator_lm_head.name): - self.generator_lm_head.build(None) - - -class TFElectraClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - classifier_dropout = ( - config.classifhidden_dropout_probier_dropout - if config.classifier_dropout is not None - else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.out_proj = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="out_proj" - ) - self.config = config - - def call(self, inputs, **kwargs): - x = inputs[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x) - x = self.dense(x) - x = get_tf_activation("gelu")(x) # although BERT uses tanh here, it seems Electra authors used gelu here - x = self.dropout(x) - x = self.out_proj(x) - - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - ELECTRA Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - ELECTRA_START_DOCSTRING, -) -class TFElectraForSequenceClassification(TFElectraPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.electra = TFElectraMainLayer(config, name="electra") - self.classifier = TFElectraClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="bhadresh-savani/electra-base-emotion", - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="'joy'", - expected_loss=0.06, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.electra( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - logits = self.classifier(outputs[0]) - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "electra", None) is not None: - with tf.name_scope(self.electra.name): - self.electra.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - ELECTRA Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - ELECTRA_START_DOCSTRING, -) -class TFElectraForMultipleChoice(TFElectraPreTrainedModel, TFMultipleChoiceLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.electra = TFElectraMainLayer(config, name="electra") - self.sequence_summary = TFSequenceSummary( - config, initializer_range=config.initializer_range, name="sequence_summary" - ) - self.classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - flat_inputs_embeds = ( - tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - outputs = self.electra( - input_ids=flat_input_ids, - attention_mask=flat_attention_mask, - token_type_ids=flat_token_type_ids, - position_ids=flat_position_ids, - head_mask=head_mask, - inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - logits = self.sequence_summary(outputs[0]) - logits = self.classifier(logits) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[1:] - - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "electra", None) is not None: - with tf.name_scope(self.electra.name): - self.electra.build(None) - if getattr(self, "sequence_summary", None) is not None: - with tf.name_scope(self.sequence_summary.name): - self.sequence_summary.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Electra model with a token classification head on top. - - Both the discriminator and generator may be loaded into this model. - """, - ELECTRA_START_DOCSTRING, -) -class TFElectraForTokenClassification(TFElectraPreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config, **kwargs): - super().__init__(config, **kwargs) - - self.electra = TFElectraMainLayer(config, name="electra") - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="bhadresh-savani/electra-base-discriminator-finetuned-conll03-english", - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="['B-LOC', 'B-ORG', 'O', 'O', 'O', 'O', 'O', 'B-LOC', 'O', 'B-LOC', 'I-LOC']", - expected_loss=0.11, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - discriminator_hidden_states = self.electra( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - discriminator_sequence_output = discriminator_hidden_states[0] - discriminator_sequence_output = self.dropout(discriminator_sequence_output) - logits = self.classifier(discriminator_sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + discriminator_hidden_states[1:] - - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=discriminator_hidden_states.hidden_states, - attentions=discriminator_hidden_states.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "electra", None) is not None: - with tf.name_scope(self.electra.name): - self.electra.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Electra Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - ELECTRA_START_DOCSTRING, -) -class TFElectraForQuestionAnswering(TFElectraPreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.electra = TFElectraMainLayer(config, name="electra") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="bhadresh-savani/electra-base-squad2", - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - qa_target_start_index=11, - qa_target_end_index=12, - expected_output="'a nice puppet'", - expected_loss=2.64, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - discriminator_hidden_states = self.electra( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - discriminator_sequence_output = discriminator_hidden_states[0] - logits = self.qa_outputs(discriminator_sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = ( - start_logits, - end_logits, - ) + discriminator_hidden_states[1:] - - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=discriminator_hidden_states.hidden_states, - attentions=discriminator_hidden_states.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "electra", None) is not None: - with tf.name_scope(self.electra.name): - self.electra.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFElectraForMaskedLM", - "TFElectraForMultipleChoice", - "TFElectraForPreTraining", - "TFElectraForQuestionAnswering", - "TFElectraForSequenceClassification", - "TFElectraForTokenClassification", - "TFElectraModel", - "TFElectraPreTrainedModel", -] diff --git a/src/transformers/models/emu3/image_processing_emu3.py b/src/transformers/models/emu3/image_processing_emu3.py index aaf3afa41733..c46dce41f529 100644 --- a/src/transformers/models/emu3/image_processing_emu3.py +++ b/src/transformers/models/emu3/image_processing_emu3.py @@ -329,10 +329,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -362,10 +360,7 @@ def preprocess( images = make_nested_list_of_images(images) if images is not None and not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( rescale_factor=rescale_factor, diff --git a/src/transformers/models/emu3/processing_emu3.py b/src/transformers/models/emu3/processing_emu3.py index 67ccab795733..ef2681d2385b 100644 --- a/src/transformers/models/emu3/processing_emu3.py +++ b/src/transformers/models/emu3/processing_emu3.py @@ -117,10 +117,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/encodec/feature_extraction_encodec.py b/src/transformers/models/encodec/feature_extraction_encodec.py index 3cc8d523f7f0..1086bdfb228e 100644 --- a/src/transformers/models/encodec/feature_extraction_encodec.py +++ b/src/transformers/models/encodec/feature_extraction_encodec.py @@ -116,7 +116,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/encoder_decoder/__init__.py b/src/transformers/models/encoder_decoder/__init__.py index c786feb9213f..b1cde1442a13 100644 --- a/src/transformers/models/encoder_decoder/__init__.py +++ b/src/transformers/models/encoder_decoder/__init__.py @@ -20,8 +20,6 @@ if TYPE_CHECKING: from .configuration_encoder_decoder import * from .modeling_encoder_decoder import * - from .modeling_flax_encoder_decoder import * - from .modeling_tf_encoder_decoder import * else: import sys diff --git a/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py b/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py index 30e2370b2240..55a736fd9034 100644 --- a/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py +++ b/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py @@ -14,10 +14,7 @@ # limitations under the License. """Classes to support Encoder-Decoder architectures""" -import gc import inspect -import os -import tempfile import warnings from typing import Optional, Union @@ -204,99 +201,6 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): return self.decoder.set_output_embeddings(new_embeddings) - @classmethod - def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs): - r""" - Example: - - ```python - >>> from transformers import EncoderDecoderModel - - >>> model = EncoderDecoderModel.from_pretrained("patrickvonplaten/bert2bert-cnn_dailymail-fp16") - ```""" - - from_tf = kwargs.pop("from_tf", False) - if from_tf: - from transformers import TFEncoderDecoderModel - - # a workaround to load from tensorflow checkpoint - # Using `_tf_model` won't work, because the weight names in the encoder/decoder of `_tf_model` get - # extended before saving those components. For example, The name of `_tf_model.encoder.vit` is - # `[top model name]/encoder/vit`, but the name of `tf_model.encoder.vit` is `[top model name]/vit`. The - # [top model name] is handled (stripped) by the conversion method, and the former case gets extra `encoder`, - # which should not occur when we want to save the components alone. - # There was a (very) ugly potential fix, which wasn't integrated to `transformers`: see - # https://github.com/huggingface/transformers/pull/13222/commits/dbb3c9de76eee235791d2064094654637c99f36d#r697304245 - # (the change in `src/transformers/modeling_tf_utils.py`) - _tf_model = TFEncoderDecoderModel.from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs) - config = _tf_model.config - - # Using `tf_model` instead - encoder = _tf_model.encoder.__class__(_tf_model.config.encoder) - decoder = _tf_model.decoder.__class__(_tf_model.config.decoder) - # Make sure models are built - encoder(encoder.dummy_inputs) - decoder(decoder.dummy_inputs) - - # Get the variable correspondence between `_tf_model` and `encoder` and `decoder` - encoder_variables = {} - for v in encoder.trainable_variables + encoder.non_trainable_variables: - encoder_variables["/".join(v.name.split("/")[1:])] = v - decoder_variables = {} - for v in decoder.trainable_variables + decoder.non_trainable_variables: - decoder_variables["/".join(v.name.split("/")[1:])] = v - - _encoder_variables = {} - for v in _tf_model.encoder.trainable_variables + _tf_model.encoder.non_trainable_variables: - _encoder_variables["/".join(v.name.split("/")[2:])] = v - _decoder_variables = {} - for v in _tf_model.decoder.trainable_variables + _tf_model.decoder.non_trainable_variables: - _decoder_variables["/".join(v.name.split("/")[2:])] = v - - # assign weight values to `encoder` and `decoder` from `_tf_model` - for name, v in encoder_variables.items(): - v.assign(_encoder_variables[name]) - for name, v in decoder_variables.items(): - v.assign(_decoder_variables[name]) - - tf_model = TFEncoderDecoderModel(encoder=encoder, decoder=decoder) - - # Deal with `enc_to_dec_proj` - if hasattr(_tf_model, "enc_to_dec_proj"): - tf_model(tf_model.dummy_inputs) - tf_model.enc_to_dec_proj.kernel.assign(_tf_model.enc_to_dec_proj.kernel) - tf_model.enc_to_dec_proj.bias.assign(_tf_model.enc_to_dec_proj.bias) - - with tempfile.TemporaryDirectory() as tmpdirname: - encoder_dir = os.path.join(tmpdirname, "encoder") - decoder_dir = os.path.join(tmpdirname, "decoder") - tf_model.encoder.save_pretrained(encoder_dir) - tf_model.decoder.save_pretrained(decoder_dir) - - if hasattr(tf_model, "enc_to_dec_proj"): - enc_to_dec_proj_weight = torch.transpose( - torch.from_numpy(tf_model.enc_to_dec_proj.kernel.numpy()), 1, 0 - ) - enc_to_dec_proj_bias = torch.from_numpy(tf_model.enc_to_dec_proj.bias.numpy()) - - del _tf_model - del tf_model - gc.collect() - - model = EncoderDecoderModel.from_encoder_decoder_pretrained( - encoder_dir, decoder_dir, encoder_from_tf=True, decoder_from_tf=True - ) - # This is only for copying some specific attributes of this particular model. - model.config = config - - if hasattr(model, "enc_to_dec_proj"): - model.enc_to_dec_proj.weight.data = enc_to_dec_proj_weight.contiguous() - model.enc_to_dec_proj.bias.data = enc_to_dec_proj_bias.contiguous() - - return model - - return super().from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs) - @classmethod def from_encoder_decoder_pretrained( cls, @@ -320,10 +224,6 @@ def from_encoder_decoder_pretrained( - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In - this case, `from_tf` should be set to `True` and a configuration object should be provided as - `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a - PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. decoder_pretrained_model_name_or_path (`str`, *optional*, defaults to `None`): Information necessary to initiate the decoder. Can be either: @@ -331,10 +231,6 @@ def from_encoder_decoder_pretrained( - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In - this case, `from_tf` should be set to `True` and a configuration object should be provided as - `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a - PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. model_args (remaining positional arguments, *optional*): All remaining positional arguments will be passed to the underlying model's `__init__` method. diff --git a/src/transformers/models/encoder_decoder/modeling_flax_encoder_decoder.py b/src/transformers/models/encoder_decoder/modeling_flax_encoder_decoder.py deleted file mode 100644 index 4a27c23c3c69..000000000000 --- a/src/transformers/models/encoder_decoder/modeling_flax_encoder_decoder.py +++ /dev/null @@ -1,901 +0,0 @@ -# coding=utf-8 -# Copyright 2021 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. -"""Classes to support Flax Encoder-Decoder architectures""" - -import os -from typing import Optional, Union - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxCausalLMOutputWithCrossAttentions, FlaxSeq2SeqLMOutput -from ...modeling_flax_utils import FlaxPreTrainedModel -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from ..auto.configuration_auto import AutoConfig -from ..auto.modeling_flax_auto import FlaxAutoModel, FlaxAutoModelForCausalLM -from .configuration_encoder_decoder import EncoderDecoderConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "EncoderDecoderConfig" - -ENCODER_DECODER_START_DOCSTRING = r""" - This class can be used to initialize a sequence-to-sequence model with any pretrained autoencoding model as the - encoder and any pretrained autoregressive model as the decoder. The encoder is loaded via - [`~AutoModel.from_pretrained`] function and the decoder is loaded via [`~AutoModelForCausalLM.from_pretrained`] - function. Cross-attention layers are automatically added to the decoder and should be fine-tuned on a downstream - generative task, like summarization. - - The effectiveness of initializing sequence-to-sequence models with pretrained checkpoints for sequence generation - tasks was shown in [Leveraging Pre-trained Checkpoints for Sequence Generation - Tasks](https://huggingface.co/papers/1907.12461) by Sascha Rothe, Shashi Narayan, Aliaksei Severyn. Michael Matena, Yanqi - Zhou, Wei Li, Peter J. Liu. - - After such an Encoder Decoder model has been trained/fine-tuned, it can be saved/loaded just like any other models - (see the examples for more information). - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Parameters: - config ([`EncoderDecoderConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -ENCODER_DECODER_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For sequence to sequence training, `decoder_input_ids` should be provided. `decoder_input_ids` should be - created outside of the model by shifting the `labels` to the right, replacing -100 by the `pad_token_id` - and prepending them with the `decoder_start_token_id`. - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.encoder.max_position_embeddings - 1]`. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.decoder.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.FlaxSeq2SeqLMOutput`] instead of a plain tuple. -""" - -ENCODER_DECODER_ENCODE_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.encoder.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.FlaxBaseModelOutput`] instead of a plain tuple. -""" - -ENCODER_DECODER_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - For sequence to sequence training, `decoder_input_ids` should be provided. `decoder_input_ids` should be - created outside of the model by shifting the `labels` to the right, replacing -100 by the `pad_token_id` - and prepending them with the `decoder_start_token_id`. - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.decoder.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.FlaxCausalLMOutputWithCrossAttentions`] instead of a - plain tuple. -""" - - -class FlaxEncoderDecoderModule(nn.Module): - config: EncoderDecoderConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - encoder_config = self.config.encoder - decoder_config = self.config.decoder - - # Copied from `modeling_hybrid_clip.py` with modifications. - from ...models.auto.modeling_flax_auto import FLAX_MODEL_FOR_CAUSAL_LM_MAPPING, FLAX_MODEL_MAPPING - - encoder_module = FLAX_MODEL_MAPPING[encoder_config.__class__].module_class - decoder_module = FLAX_MODEL_FOR_CAUSAL_LM_MAPPING[decoder_config.__class__].module_class - - self.encoder = encoder_module(encoder_config, dtype=self.dtype) - self.decoder = decoder_module(decoder_config, dtype=self.dtype) - - # encoder outputs might need to be projected to different dimension for decoder - if ( - self.encoder.config.hidden_size != self.decoder.config.hidden_size - and self.decoder.config.cross_attention_hidden_size is None - ): - self.enc_to_dec_proj = nn.Dense( - self.decoder.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.decoder.config.initializer_range), - dtype=self.dtype, - ) - else: - self.enc_to_dec_proj = None - - def _get_encoder_module(self): - return self.encoder - - def _get_projection_module(self): - return self.enc_to_dec_proj - - def _get_decoder_module(self): - return self.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - encoder_hidden_states = encoder_outputs[0] - - # optionally project encoder_hidden_states - if self.enc_to_dec_proj is not None: - encoder_hidden_states = self.enc_to_dec_proj(encoder_hidden_states) - - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqLMOutput( - logits=decoder_outputs.logits, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -@add_start_docstrings(ENCODER_DECODER_START_DOCSTRING) -class FlaxEncoderDecoderModel(FlaxPreTrainedModel): - r""" - [`FlaxEncoderDecoderModel`] is a generic model class that will be instantiated as a transformer architecture with - the module (flax.nn.Module) of one of the base model classes of the library as encoder module and another one as - decoder module when created with the :meth*~transformers.FlaxAutoModel.from_pretrained* class method for the - encoder and :meth*~transformers.FlaxAutoModelForCausalLM.from_pretrained* class method for the decoder. - """ - - config_class = EncoderDecoderConfig - base_model_prefix = "encoder_decoder" - module_class = FlaxEncoderDecoderModule - - def __init__( - self, - config: EncoderDecoderConfig, - input_shape: Optional[tuple] = None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - if input_shape is None: - input_shape = ((1, 1), (1, 1)) - - if not _do_init: - raise ValueError( - "`FlaxEncoderDecoderModel` cannot be created without initializing, `_do_init` must be `True`." - ) - - if config.decoder.cross_attention_hidden_size is not None: - if config.decoder.cross_attention_hidden_size != config.encoder.hidden_size: - raise ValueError( - "If `cross_attention_hidden_size` is specified in the decoder's configuration, it has to be equal" - f" to the encoder's `hidden_size`. Got {config.decoder.cross_attention_hidden_size} for" - f" `config.decoder.cross_attention_hidden_size` and {config.encoder.hidden_size} for" - " `config.encoder.hidden_size`." - ) - - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - encoder_input_shape, decoder_input_shape = input_shape - - # init input tensors - input_ids = jnp.zeros(encoder_input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - decoder_input_ids = jnp.zeros(decoder_input_shape, dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - decoder_batch_size, decoder_sequence_length = decoder_input_ids.shape - if not decoder_batch_size == batch_size: - raise ValueError( - f"The inputs of encoder and decoder should have the same batch size, but got {batch_size} for encoder" - f" and {decoder_batch_size} for decoder." - ) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(decoder_sequence_length)[None, :], (decoder_batch_size, decoder_sequence_length) - ) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape - ) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(ENCODER_DECODER_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=_CONFIG_FOR_DOC) - def encode( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import FlaxEncoderDecoderModel, BertTokenizer - - >>> # initialize a bert2gpt2 from pretrained BERT and GPT2 models. Note that the cross-attention layers will be randomly initialized - >>> model = FlaxEncoderDecoderModel.from_encoder_decoder_pretrained("google-bert/bert-base-cased", "openai-community/gpt2") - - >>> tokenizer = BertTokenizer.from_pretrained("google-bert/bert-base-cased") - - >>> text = "My friends are cool but they eat too many carbs." - >>> input_ids = tokenizer.encode(text, return_tensors="np") - >>> encoder_outputs = model.encode(input_ids) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, input_ids, attention_mask, position_ids, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(input_ids, attention_mask, position_ids, **kwargs) - - outputs = self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - if return_dict: - outputs = FlaxBaseModelOutput( - last_hidden_state=outputs.last_hidden_state, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - return outputs - - @add_start_docstrings(ENCODER_DECODER_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=_CONFIG_FOR_DOC) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import FlaxEncoderDecoderModel, BertTokenizer - >>> import jax.numpy as jnp - - >>> # initialize a bert2gpt2 from pretrained BERT and GPT2 models. Note that the cross-attention layers will be randomly initialized - >>> model = FlaxEncoderDecoderModel.from_encoder_decoder_pretrained("google-bert/bert-base-cased", "openai-community/gpt2") - - >>> tokenizer = BertTokenizer.from_pretrained("google-bert/bert-base-cased") - - >>> text = "My friends are cool but they eat too many carbs." - >>> input_ids = tokenizer.encode(text, max_length=1024, return_tensors="np") - >>> encoder_outputs = model.encode(input_ids) - - >>> decoder_start_token_id = model.config.decoder.bos_token_id - >>> decoder_input_ids = jnp.ones((input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxBartAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward( - module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, encoder_hidden_states, **kwargs - ): - projection_module = module._get_projection_module() - decoder_module = module._get_decoder_module() - - # optionally project encoder_hidden_states - if projection_module is not None: - encoder_hidden_states = projection_module(encoder_hidden_states) - - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - encoder_hidden_states=encoder_hidden_states, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - @add_start_docstrings_to_model_forward(ENCODER_DECODER_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_input_ids: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Examples: - - ```python - >>> from transformers import FlaxEncoderDecoderModel, BertTokenizer, GPT2Tokenizer - - >>> # load a fine-tuned bert2gpt2 model - >>> model = FlaxEncoderDecoderModel.from_pretrained("patrickvonplaten/bert2gpt2-cnn_dailymail-fp16") - >>> # load input & output tokenizer - >>> tokenizer_input = BertTokenizer.from_pretrained("google-bert/bert-base-cased") - >>> tokenizer_output = GPT2Tokenizer.from_pretrained("openai-community/gpt2") - - >>> article = '''Sigma Alpha Epsilon is under fire for a video showing party-bound fraternity members - >>> singing a racist chant. SAE's national chapter suspended the students, - >>> but University of Oklahoma President David Boren took it a step further, - >>> saying the university's affiliation with the fraternity is permanently done.''' - - >>> input_ids = tokenizer_input(article, add_special_tokens=True, return_tensors="np").input_ids - - >>> # use GPT2's eos_token as the pad as well as eos token - >>> model.config.eos_token_id = model.config.decoder.eos_token_id - >>> model.config.pad_token_id = model.config.eos_token_id - - >>> sequences = model.generate(input_ids, num_beams=4, max_length=12).sequences - - >>> summary = tokenizer_output.batch_decode(sequences, skip_special_tokens=True)[0] - >>> assert summary == "SAS Alpha Epsilon suspended Sigma Alpha Epsilon members" - ``` - """ - - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # prepare decoder inputs - if decoder_input_ids is None: - raise ValueError( - "`decoder_input_ids` cannot be `None`. For sequence to sequence training, `decoder_position_ids` must" - " be specified as an input argument." - ) - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - if decoder_position_ids is None: - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - decoder_position_ids = decoder_attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) - else: - decoder_position_ids = jnp.broadcast_to( - jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length) - ) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - "decoder_position_ids": decoder_position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 - return model_kwargs - - @classmethod - def from_encoder_decoder_pretrained( - cls, - encoder_pretrained_model_name_or_path: Optional[Union[str, os.PathLike]] = None, - decoder_pretrained_model_name_or_path: Optional[Union[str, os.PathLike]] = None, - *model_args, - **kwargs, - ) -> FlaxPreTrainedModel: - r""" - Instantiate an encoder and a decoder from one or two base classes of the library from pretrained model - checkpoints. - - Params: - encoder_pretrained_model_name_or_path (`Union[str, os.PathLike]`, *optional*): - Information necessary to initiate the encoder. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~FlaxPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - decoder_pretrained_model_name_or_path (`Union[str, os.PathLike]`, *optional*, defaults to `None`): - Information necessary to initiate the decoder. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~FlaxPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - model_args (remaining positional arguments, *optional*): - All remaining positional arguments will be passed to the underlying model's `__init__` method. - - kwargs (remaining dictionary of keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). - - - To update the encoder configuration, use the prefix *encoder_* for each configuration parameter. - - To update the decoder configuration, use the prefix *decoder_* for each configuration parameter. - - To update the parent model configuration, do not use a prefix for each configuration parameter. - - Behaves differently depending on whether a `config` is provided or automatically loaded. - - Example: - - ```python - >>> from transformers import FlaxEncoderDecoderModel - - >>> # initialize a bert2gpt2 from pretrained BERT and GPT2 models. Note that the cross-attention layers will be randomly initialized - >>> model = FlaxEncoderDecoderModel.from_encoder_decoder_pretrained("google-bert/bert-base-cased", "openai-community/gpt2") - >>> # saving model after fine-tuning - >>> model.save_pretrained("./bert2gpt2") - >>> # load fine-tuned model - >>> model = FlaxEncoderDecoderModel.from_pretrained("./bert2gpt2") - ```""" - - kwargs_encoder = { - argument[len("encoder_") :]: value for argument, value in kwargs.items() if argument.startswith("encoder_") - } - - kwargs_decoder = { - argument[len("decoder_") :]: value for argument, value in kwargs.items() if argument.startswith("decoder_") - } - - # remove encoder, decoder kwargs from kwargs - for key in kwargs_encoder: - del kwargs["encoder_" + key] - for key in kwargs_decoder: - del kwargs["decoder_" + key] - - # Load and initialize the encoder and decoder - # The distinction between encoder and decoder at the model level is made - # by the value of the flag `is_decoder` that we need to set correctly. - encoder = kwargs_encoder.pop("model", None) - if encoder is None: - if encoder_pretrained_model_name_or_path is None: - raise ValueError( - "If `encoder_model` is not defined as an argument, a `encoder_pretrained_model_name_or_path` has " - "to be defined." - ) - - if "config" not in kwargs_encoder: - encoder_config, kwargs_encoder = AutoConfig.from_pretrained( - encoder_pretrained_model_name_or_path, **kwargs_encoder, return_unused_kwargs=True - ) - if encoder_config.is_decoder is True or encoder_config.add_cross_attention is True: - logger.info( - f"Initializing {encoder_pretrained_model_name_or_path} as a encoder model " - "from a decoder model. Cross-attention and causal mask are disabled." - ) - encoder_config.is_decoder = False - encoder_config.add_cross_attention = False - - kwargs_encoder["config"] = encoder_config - - encoder = FlaxAutoModel.from_pretrained( - encoder_pretrained_model_name_or_path, *model_args, **kwargs_encoder - ) - - decoder = kwargs_decoder.pop("model", None) - if decoder is None: - if decoder_pretrained_model_name_or_path is None: - raise ValueError( - "If `decoder_model` is not defined as an argument, a `decoder_pretrained_model_name_or_path` has " - "to be defined." - ) - - if "config" not in kwargs_decoder: - decoder_config, kwargs_decoder = AutoConfig.from_pretrained( - decoder_pretrained_model_name_or_path, **kwargs_decoder, return_unused_kwargs=True - ) - if decoder_config.is_decoder is False or decoder_config.add_cross_attention is False: - logger.info( - f"Initializing {decoder_pretrained_model_name_or_path} as a decoder model. Cross attention" - f" layers are added to {decoder_pretrained_model_name_or_path} and randomly initialized if" - f" {decoder_pretrained_model_name_or_path}'s architecture allows for cross attention layers." - ) - decoder_config.is_decoder = True - decoder_config.add_cross_attention = True - - kwargs_decoder["config"] = decoder_config - - if kwargs_decoder["config"].is_decoder is False or kwargs_decoder["config"].add_cross_attention is False: - logger.warning( - f"Decoder model {decoder_pretrained_model_name_or_path} is not initialized as a decoder. " - f"In order to initialize {decoder_pretrained_model_name_or_path} as a decoder, " - "make sure that the attributes `is_decoder` and `add_cross_attention` of `decoder_config` " - "passed to `.from_encoder_decoder_pretrained(...)` are set to `True` or do not pass a " - "`decoder_config` to `.from_encoder_decoder_pretrained(...)`" - ) - - decoder = FlaxAutoModelForCausalLM.from_pretrained(decoder_pretrained_model_name_or_path, **kwargs_decoder) - - # instantiate config with corresponding kwargs - dtype = kwargs.pop("dtype", jnp.float32) - config = EncoderDecoderConfig.from_encoder_decoder_configs(encoder.config, decoder.config, **kwargs) - - # init model - model = cls(config, dtype=dtype) - model.params["encoder"] = encoder.params - model.params["decoder"] = decoder.params - - return model - - -__all__ = ["FlaxEncoderDecoderModel"] diff --git a/src/transformers/models/encoder_decoder/modeling_tf_encoder_decoder.py b/src/transformers/models/encoder_decoder/modeling_tf_encoder_decoder.py deleted file mode 100644 index 7e5343d20049..000000000000 --- a/src/transformers/models/encoder_decoder/modeling_tf_encoder_decoder.py +++ /dev/null @@ -1,661 +0,0 @@ -# coding=utf-8 -# Copyright 2021 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. -"""Classes to support TF Encoder-Decoder architectures""" - -from __future__ import annotations - -import inspect -import re -import warnings - -import numpy as np -import tensorflow as tf - -from ...configuration_utils import PretrainedConfig -from ...modeling_tf_outputs import TFBaseModelOutput, TFSeq2SeqLMOutput -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - get_initializer, - keras, - unpack_inputs, -) -from ...tf_utils import shape_list -from ...utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from ..auto.configuration_auto import AutoConfig -from ..auto.modeling_tf_auto import TFAutoModel, TFAutoModelForCausalLM -from .configuration_encoder_decoder import EncoderDecoderConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "EncoderDecoderConfig" - -DEPRECATION_WARNING = ( - "Version v4.17.0 introduces a better way to train encoder-decoder models by computing the loss inside the" - " encoder-decoder framework rather than in the decoder itself. You may observe training discrepancies if" - " fine-tuning a model trained with versions anterior to 4.17.0. The decoder_input_ids are now created based on the" - " labels, no need to pass them yourself anymore." -) - -ENCODER_DECODER_START_DOCSTRING = r""" - This class can be used to initialize a sequence-to-sequence model with any pretrained autoencoding model as the - encoder and any pretrained autoregressive model as the decoder. The encoder is loaded via - [`~TFAutoModel.from_pretrained`] function and the decoder is loaded via [`~TFAutoModelForCausalLM.from_pretrained`] - function. Cross-attention layers are automatically added to the decoder and should be fine-tuned on a downstream - generative task, like summarization. - - The effectiveness of initializing sequence-to-sequence models with pretrained checkpoints for sequence generation - tasks was shown in [Leveraging Pre-trained Checkpoints for Sequence Generation - Tasks](https://huggingface.co/papers/1907.12461) by Sascha Rothe, Shashi Narayan, Aliaksei Severyn. Michael Matena, Yanqi - Zhou, Wei Li, Peter J. Liu. - - After such an Encoder Decoder model has been trained/fine-tuned, it can be saved/loaded just like any other models - (see the examples for more information). - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - Parameters: - config ([`EncoderDecoderConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -ENCODER_DECODER_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`np.ndarray` or `tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - Provide for sequence to sequence training to the decoder. Indices can be obtained using - [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and [`PreTrainedTokenizer.__call__`] for - details. - decoder_attention_mask (`np.ndarray` or `tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - encoder_outputs (`tuple(tuple(tf.Tensor)`, *optional*): - This tuple must consist of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` (`tf.Tensor` of shape `({0}, hidden_size)`) is a tensor of hidden-states at the output - of the last layer of the encoder. Used in the cross-attention of the decoder. - past_key_values (`tuple(tuple(tf.Tensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `({0})`. - inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - decoder_inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `(batch_size, target_sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `decoder_input_ids` you can choose to directly pass an embedded - representation. This is useful if you want more control over how to convert `decoder_input_ids` indices - into associated vectors than the model's internal embedding lookup matrix. - labels (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Labels for computing the masked language modeling loss for the decoder. Indices should be in `[-100, 0, - ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.Seq2SeqLMOutput`] instead of a plain tuple. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - kwargs (*optional*): Remaining dictionary of keyword arguments. Keyword arguments come in two flavors: - - - Without a prefix which will be input as `**encoder_kwargs` for the encoder forward function. - - With a *decoder_* prefix which will be input as `**decoder_kwargs`` for the decoder forward function. -""" - - -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): - if pad_token_id is None: - raise ValueError("Make sure to set the pad_token_id attribute of the model's configuration.") - pad_token_id = tf.cast(pad_token_id, input_ids.dtype) - - if decoder_start_token_id is None: - raise ValueError("Make sure to set the decoder_start_token_id attribute of the model's configuration.") - decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) - - start_tokens = tf.fill((shape_list(input_ids)[0], 1), decoder_start_token_id) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, tf.fill(shape_list(shifted_input_ids), pad_token_id), shifted_input_ids - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -@add_start_docstrings(ENCODER_DECODER_START_DOCSTRING) -class TFEncoderDecoderModel(TFPreTrainedModel, TFCausalLanguageModelingLoss): - r""" - [`TFEncoderDecoderModel`] is a generic model class that will be instantiated as a transformer architecture with one - of the base model classes of the library as encoder and another one as decoder when created with the - [`~TFAutoModel.from_pretrained`] class method for the encoder and [`~TFAutoModelForCausalLM.from_pretrained`] class - method for the decoder. - """ - - config_class = EncoderDecoderConfig - base_model_prefix = "encoder_decoder" - load_weight_prefix = "tf_encoder_decoder_model" - - def __init__( - self, - config: PretrainedConfig | None = None, - encoder: TFPreTrainedModel | None = None, - decoder: TFPreTrainedModel | None = None, - ): - if config is None and (encoder is None or decoder is None): - raise ValueError("Either a configuration or an encoder and a decoder has to be provided.") - if config is None: - config = EncoderDecoderConfig.from_encoder_decoder_configs(encoder.config, decoder.config) - else: - if not isinstance(config, self.config_class): - raise ValueError(f"config: {config} has to be of type {self.config_class}") - - if config.decoder.cross_attention_hidden_size is not None: - if config.decoder.cross_attention_hidden_size != config.encoder.hidden_size: - raise ValueError( - "If `cross_attention_hidden_size` is specified in the decoder's configuration, it has to be equal" - f" to the encoder's `hidden_size`. Got {config.decoder.cross_attention_hidden_size} for" - f" `config.decoder.cross_attention_hidden_size` and {config.encoder.hidden_size} for" - " `config.encoder.hidden_size`." - ) - - # initialize with config - super().__init__(config) - - if encoder is None: - encoder = TFAutoModel.from_config(config.encoder, name="encoder") - - if decoder is None: - decoder = TFAutoModelForCausalLM.from_config(config.decoder, name="decoder") - - self.encoder = encoder - self.decoder = decoder - - if self.encoder.config.to_dict() != self.config.encoder.to_dict(): - logger.warning( - f"Config of the encoder: {self.encoder.__class__} is overwritten by shared encoder config:" - f" {self.config.encoder}" - ) - if self.decoder.config.to_dict() != self.config.decoder.to_dict(): - logger.warning( - f"Config of the decoder: {self.decoder.__class__} is overwritten by shared decoder config:" - f" {self.config.decoder}" - ) - - # make sure that the individual model's config refers to the shared config - # so that the updates to the config will be synced - self.encoder.config = self.config.encoder - self.decoder.config = self.config.decoder - - # encoder outputs might need to be projected to different dimension for decoder - if ( - self.encoder.config.hidden_size != self.decoder.config.hidden_size - and self.decoder.config.cross_attention_hidden_size is None - ): - self.enc_to_dec_proj = keras.layers.Dense( - units=self.decoder.config.hidden_size, - kernel_initializer=get_initializer(config.encoder.initializer_range), - name="enc_to_dec_proj", - ) - - if self.encoder.get_output_embeddings() is not None: - raise ValueError( - f"The encoder {self.encoder} should not have a LM Head. Please use a model without LM Head" - ) - - decoder_signature = set(inspect.signature(self.decoder.call).parameters.keys()) - if "encoder_hidden_states" not in decoder_signature: - raise ValueError( - "The selected decoder is not prepared for the encoder hidden states to be passed. Please see the " - "following discussion on GitHub: https://github.com/huggingface/transformers/issues/23350" - ) - - def get_encoder(self): - return self.encoder - - def get_input_embeddings(self): - return self.encoder.get_input_embeddings() - - def get_output_embeddings(self): - return self.decoder.get_output_embeddings() - - def set_output_embeddings(self, new_embeddings): - return self.decoder.set_output_embeddings(new_embeddings) - - def tf_to_pt_weight_rename(self, tf_weight): - # Matt: The TF and PT weights don't align because our TF base classes have an extra layer compared to PT models - # (the main model stem is in the MainLayer class). If we remove that layer, then weight names sync up as normal. - # However, the name of that extra layer is the name of the MainLayer in the base model. We make the assumption - # here that the config model_type is the same as the name of the MainLayer. I don't know of anywhere that's - # not the case, and I wasn't sure how else to go from the config to the correct MainLayer name! - - # This override is only needed in the case where we're crossloading weights from PT. However, since weights are - # often safetensors now, we don't know if we're going to be crossloading until we sniff the weights file. - # Therefore, we specify tf_to_pt_weight_rename anyway, and let the super method figure out if it needs it - # or not. - encoder_model_type = self.config.encoder.model_type - if "encoder" in tf_weight and "decoder" not in tf_weight: - return (re.sub(rf"encoder\.{encoder_model_type}\.", "encoder.", tf_weight),) - else: - return (tf_weight,) - - @classmethod - def from_encoder_decoder_pretrained( - cls, - encoder_pretrained_model_name_or_path: str | None = None, - decoder_pretrained_model_name_or_path: str | None = None, - *model_args, - **kwargs, - ) -> TFPreTrainedModel: - r""" - Instantiate an encoder and a decoder from one or two base classes of the library from pretrained model - checkpoints. - - - Params: - encoder_pretrained_model_name_or_path (`str`, *optional*): - Information necessary to initiate the encoder. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~TFPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *pytorch index checkpoint file* (e.g, `./pt_model/`). In this case, - `encoder_from_pt` should be set to `True`. - - decoder_pretrained_model_name_or_path (`str`, *optional*, defaults to `None`): - Information necessary to initiate the decoder. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~TFPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *pytorch checkpoint file* (e.g, `./pt_model/`). In this case, - `decoder_from_pt` should be set to `True`. - - model_args (remaining positional arguments, *optional*): - All remaining positional arguments will be passed to the underlying model's `__init__` method. - - kwargs (remaining dictionary of keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). - - - To update the encoder configuration, use the prefix *encoder_* for each configuration parameter. - - To update the decoder configuration, use the prefix *decoder_* for each configuration parameter. - - To update the parent model configuration, do not use a prefix for each configuration parameter. - - Behaves differently depending on whether a `config` is provided or automatically loaded. - - Example: - - ```python - >>> from transformers import TFEncoderDecoderModel - - >>> # initialize a bert2gpt2 from two pretrained BERT models. Note that the cross-attention layers will be randomly initialized - >>> model = TFEncoderDecoderModel.from_encoder_decoder_pretrained("google-bert/bert-base-uncased", "openai-community/gpt2") - >>> # saving model after fine-tuning - >>> model.save_pretrained("./bert2gpt2") - >>> # load fine-tuned model - >>> model = TFEncoderDecoderModel.from_pretrained("./bert2gpt2") - ```""" - - kwargs_encoder = { - argument[len("encoder_") :]: value for argument, value in kwargs.items() if argument.startswith("encoder_") - } - - kwargs_decoder = { - argument[len("decoder_") :]: value for argument, value in kwargs.items() if argument.startswith("decoder_") - } - - # remove encoder, decoder kwargs from kwargs - for key in kwargs_encoder: - del kwargs["encoder_" + key] - for key in kwargs_decoder: - del kwargs["decoder_" + key] - - # Load and initialize the encoder and decoder - # The distinction between encoder and decoder at the model level is made - # by the value of the flag `is_decoder` that we need to set correctly. - encoder = kwargs_encoder.pop("model", None) - if encoder is None: - if encoder_pretrained_model_name_or_path is None: - raise ValueError( - "If `encoder_model` is not defined as an argument, a `encoder_pretrained_model_name_or_path` has " - "to be defined." - ) - - if "config" not in kwargs_encoder: - encoder_config = AutoConfig.from_pretrained(encoder_pretrained_model_name_or_path) - if encoder_config.is_decoder is True or encoder_config.add_cross_attention is True: - logger.info( - f"Initializing {encoder_pretrained_model_name_or_path} as a encoder model " - "from a decoder model. Cross-attention and causal mask are disabled." - ) - encoder_config.is_decoder = False - encoder_config.add_cross_attention = False - - kwargs_encoder["config"] = encoder_config - - kwargs_encoder["name"] = "encoder" - kwargs_encoder["load_weight_prefix"] = cls.load_weight_prefix - encoder = TFAutoModel.from_pretrained(encoder_pretrained_model_name_or_path, *model_args, **kwargs_encoder) - - decoder = kwargs_decoder.pop("model", None) - if decoder is None: - if decoder_pretrained_model_name_or_path is None: - raise ValueError( - "If `decoder_model` is not defined as an argument, a `decoder_pretrained_model_name_or_path` has " - "to be defined." - ) - - if "config" not in kwargs_decoder: - decoder_config = AutoConfig.from_pretrained(decoder_pretrained_model_name_or_path) - if decoder_config.is_decoder is False or decoder_config.add_cross_attention is False: - logger.info( - f"Initializing {decoder_pretrained_model_name_or_path} as a decoder model. Cross attention" - f" layers are added to {decoder_pretrained_model_name_or_path} and randomly initialized if" - f" {decoder_pretrained_model_name_or_path}'s architecture allows for cross attention layers." - ) - decoder_config.is_decoder = True - decoder_config.add_cross_attention = True - - kwargs_decoder["config"] = decoder_config - - if kwargs_decoder["config"].is_decoder is False or kwargs_decoder["config"].add_cross_attention is False: - logger.warning( - f"Decoder model {decoder_pretrained_model_name_or_path} is not initialized as a decoder. " - f"In order to initialize {decoder_pretrained_model_name_or_path} as a decoder, " - "make sure that the attributes `is_decoder` and `add_cross_attention` of `decoder_config` " - "passed to `.from_encoder_decoder_pretrained(...)` are set to `True` or do not pass a " - "`decoder_config` to `.from_encoder_decoder_pretrained(...)`" - ) - - kwargs_decoder["name"] = "decoder" - kwargs_decoder["load_weight_prefix"] = cls.load_weight_prefix - decoder = TFAutoModelForCausalLM.from_pretrained(decoder_pretrained_model_name_or_path, **kwargs_decoder) - - # Make sure these 2 `keras.Model` have fixed names so `from_pretrained` could load model weights correctly. - if encoder.name != "encoder": - raise ValueError("encoder model must be created with the name `encoder`.") - if decoder.name != "decoder": - raise ValueError("decoder model must be created with the name `decoder`.") - - # instantiate config with corresponding kwargs - config = EncoderDecoderConfig.from_encoder_decoder_configs(encoder.config, decoder.config, **kwargs) - return cls(encoder=encoder, decoder=decoder, config=config) - - @unpack_inputs - @add_start_docstrings_to_model_forward(ENCODER_DECODER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ) -> TFSeq2SeqLMOutput | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import TFEncoderDecoderModel, BertTokenizer - - >>> # initialize a bert2gpt2 from a pretrained BERT and GPT2 models. Note that the cross-attention layers will be randomly initialized - >>> model = TFEncoderDecoderModel.from_encoder_decoder_pretrained("google-bert/bert-base-cased", "openai-community/gpt2") - - >>> tokenizer = BertTokenizer.from_pretrained("google-bert/bert-base-cased") - - >>> # forward - >>> input_ids = tokenizer.encode( - ... "Hello, my dog is cute", add_special_tokens=True, return_tensors="tf" - ... ) # Batch size 1 - >>> outputs = model(input_ids=input_ids, decoder_input_ids=input_ids) - - >>> # training - >>> outputs = model(input_ids=input_ids, decoder_input_ids=input_ids, labels=input_ids) - >>> loss, logits = outputs.loss, outputs.logits - - >>> # save and load from pretrained - >>> model.save_pretrained("bert2gpt2") - >>> model = TFEncoderDecoderModel.from_pretrained("bert2gpt2") - - >>> # generation - >>> generated = model.generate(input_ids, decoder_start_token_id=model.config.decoder.bos_token_id) - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - kwargs_encoder = {argument: value for argument, value in kwargs.items() if not argument.startswith("decoder_")} - - kwargs_decoder = { - argument[len("decoder_") :]: value for argument, value in kwargs.items() if argument.startswith("decoder_") - } - - # Let the user be responsible for the expected format. - if encoder_outputs is not None: - if return_dict and not isinstance(encoder_outputs, ModelOutput): - raise ValueError( - "If `return_dict=True` and `encoder_outputs` is provided, it should be an instance of " - f"`ModelOutput`. Got an instance {type(encoder_outputs)} for `encoder_outputs`." - ) - - if encoder_outputs is None: - encoder_inputs = { - "input_ids": input_ids, - "attention_mask": attention_mask, - "inputs_embeds": inputs_embeds, - "output_attentions": output_attentions, - "output_hidden_states": output_hidden_states, - "return_dict": return_dict, - "training": training, - } - - # Add arguments to encoder from `kwargs_encoder` - encoder_inputs.update(kwargs_encoder) - - # Handle the case where the inputs are passed as a single dict which contains `labels`. - # The `labels` shouldn't be passed to `self.encoder` below, because it is a based model without this - # parameter (otherwise, an error occurs when `input_processing` is called inside `self.encoder.call()`). - if "labels" in encoder_inputs: - labels = encoder_inputs.pop("labels") - - # handle the init case where `dummy_inputs` returns a dict containing `decoder_input_ids`. - if "decoder_input_ids" in encoder_inputs: - decoder_input_ids = encoder_inputs.pop("decoder_input_ids") - # handle the init case where `dummy_inputs` returns a dict containing `decoder_input_ids`. - if "decoder_attention_mask" in encoder_inputs: - decoder_attention_mask = encoder_inputs.pop("decoder_attention_mask") - - encoder_outputs = self.encoder(**encoder_inputs) - - encoder_hidden_states = encoder_outputs[0] - - # optionally project encoder_hidden_states - if ( - self.encoder.config.hidden_size != self.decoder.config.hidden_size - and self.decoder.config.cross_attention_hidden_size is None - ): - encoder_hidden_states = self.enc_to_dec_proj(encoder_hidden_states) - - if (labels is not None) and (decoder_input_ids is None and decoder_inputs_embeds is None): - decoder_input_ids = shift_tokens_right( - labels, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - decoder_inputs = { - "input_ids": decoder_input_ids, - "attention_mask": decoder_attention_mask, - "encoder_hidden_states": encoder_hidden_states, - "encoder_attention_mask": attention_mask, - "inputs_embeds": decoder_inputs_embeds, - "output_attentions": output_attentions, - "output_hidden_states": output_hidden_states, - "use_cache": use_cache, - "past_key_values": past_key_values, - "return_dict": return_dict, - "training": training, - } - - # Add arguments to decoder from `kwargs_decoder` - decoder_inputs.update(kwargs_decoder) - - decoder_outputs = self.decoder(**decoder_inputs) - - logits = decoder_outputs[0] - - # Compute loss independent from decoder (as some shift the logits inside them) - loss = None - if labels is not None: - warnings.warn(DEPRECATION_WARNING, FutureWarning) - loss = self.hf_compute_loss(labels, logits) - - if not return_dict: - past_key_values = None - if use_cache: - past_key_values = decoder_outputs[1] - # The starting index of the remaining elements in `decoder_outputs` - start_index = sum([1 if x is not None else 0 for x in (loss, logits, past_key_values)]) - - if not isinstance(encoder_outputs, tuple): - encoder_outputs = encoder_outputs.to_tuple() - output = (loss, logits, past_key_values) + decoder_outputs[start_index:] + encoder_outputs - output = tuple(x for x in output if x is not None) - return output - - return TFSeq2SeqLMOutput( - loss=loss, - logits=decoder_outputs.logits, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def prepare_inputs_for_generation( - self, input_ids, past_key_values=None, attention_mask=None, use_cache=None, encoder_outputs=None, **kwargs - ): - decoder_inputs = self.decoder.prepare_inputs_for_generation(input_ids, past_key_values=past_key_values) - decoder_attention_mask = decoder_inputs.get("attention_mask", None) - past_key_values = decoder_inputs.get("past_key_values") - if past_key_values is None: - past_key_values = decoder_inputs.get("past") # e.g. on TF GPT2 - input_dict = { - "input_ids": None, # needs to be passed to make Keras.layer.__call__ happy - "attention_mask": attention_mask, - "decoder_attention_mask": decoder_attention_mask, - "decoder_input_ids": decoder_inputs["input_ids"], - # TODO (joao): the `TFBaseModelOutput` wrapper should not be needed after the generate refactor is complete - "encoder_outputs": TFBaseModelOutput(last_hidden_state=encoder_outputs[0]), - "past_key_values": past_key_values, - "use_cache": use_cache, - } - return input_dict - - def prepare_decoder_input_ids_from_labels(self, labels: tf.Tensor): - return shift_tokens_right(labels, self.config.pad_token_id, self.config.decoder_start_token_id) - - def resize_token_embeddings(self, *args, **kwargs): - raise NotImplementedError( - "Resizing the embedding layers via the TFEncoderDecoderModel directly is not supported.Please use the" - " respective methods of the wrapped objects (model.encoder.resize_token_embeddings(...) or" - " model.decoder.resize_token_embeddings(...))" - ) - - def _reorder_cache(self, past, beam_idx): - # apply decoder cache reordering here - return self.decoder._reorder_cache(past, beam_idx) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "enc_to_dec_proj", None) is not None: - with tf.name_scope(self.enc_to_dec_proj.name): - self.enc_to_dec_proj.build([None, None, self.encoder.config.hidden_size]) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -__all__ = ["TFEncoderDecoderModel"] diff --git a/src/transformers/models/eomt/image_processing_eomt.py b/src/transformers/models/eomt/image_processing_eomt.py index 93a440693dee..4fbd308da336 100644 --- a/src/transformers/models/eomt/image_processing_eomt.py +++ b/src/transformers/models/eomt/image_processing_eomt.py @@ -557,7 +557,7 @@ def preprocess( Label to be assigned to background pixels in segmentation maps. If provided, segmentation map pixels denoted with 0 (background) will be replaced with `ignore_index`. return_tensors (`str` or `TensorType`, *optional*): - The type of tensors to return. Can be `"pt"`, `"tf"`, `"np"`, or `"jax"`. + The type of tensors to return. Can be `"pt"` or `"np"`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): Channel format of the output image. Either `"channels_first"` or `"channels_last"`. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -581,10 +581,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/eomt/modeling_eomt.py b/src/transformers/models/eomt/modeling_eomt.py index 3e979040388d..e7e1624c1406 100644 --- a/src/transformers/models/eomt/modeling_eomt.py +++ b/src/transformers/models/eomt/modeling_eomt.py @@ -808,11 +808,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/ernie/modeling_ernie.py b/src/transformers/models/ernie/modeling_ernie.py index 7cbce6b2d20b..4c7c33fd7e43 100644 --- a/src/transformers/models/ernie/modeling_ernie.py +++ b/src/transformers/models/ernie/modeling_ernie.py @@ -60,8 +60,6 @@ def __init__(self, config): if config.use_task_id: self.task_type_embeddings = nn.Embedding(config.task_type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -628,8 +626,6 @@ class ErniePreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/esm/__init__.py b/src/transformers/models/esm/__init__.py index 8eac54d6ddcb..e308c53e9a3d 100644 --- a/src/transformers/models/esm/__init__.py +++ b/src/transformers/models/esm/__init__.py @@ -21,7 +21,6 @@ from .configuration_esm import * from .modeling_esm import * from .modeling_esmfold import * - from .modeling_tf_esm import * from .tokenization_esm import * else: import sys diff --git a/src/transformers/models/esm/modeling_esm.py b/src/transformers/models/esm/modeling_esm.py index ddcf460f01ee..21015e50bb2f 100755 --- a/src/transformers/models/esm/modeling_esm.py +++ b/src/transformers/models/esm/modeling_esm.py @@ -609,8 +609,6 @@ class EsmPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/esm/modeling_tf_esm.py b/src/transformers/models/esm/modeling_tf_esm.py deleted file mode 100644 index 3fd066868f0e..000000000000 --- a/src/transformers/models/esm/modeling_tf_esm.py +++ /dev/null @@ -1,1574 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Meta and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""PyTorch ESM model.""" - -from __future__ import annotations - -import os - -import numpy as np -import tensorflow as tf - -from ...file_utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFBaseModelOutputWithPoolingAndCrossAttentions, - TFMaskedLMOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - shape_list, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, stable_softmax -from ...utils import logging -from .configuration_esm import EsmConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/esm2_t6_8M_UR50D" -_CONFIG_FOR_DOC = "EsmConfig" - - -def rotate_half(x): - x1, x2 = tf.split(x, 2, axis=-1) - return tf.concat((-x2, x1), axis=-1) - - -def apply_rotary_pos_emb(x, cos, sin): - cos = cos[:, :, : tf.shape(x)[-2], :] - sin = sin[:, :, : tf.shape(x)[-2], :] - - return (x * cos) + (rotate_half(x) * sin) - - -def symmetrize(x): - "Make layer symmetric in final two dimensions, used for contact prediction." - return x + tf.linalg.matrix_transpose(x) # Transposes last two dimensions only - - -def average_product_correct(x): - "Perform average product correct, used for contact prediction." - a1 = tf.reduce_sum(x, -1, keepdims=True) - a2 = tf.reduce_sum(x, -2, keepdims=True) - a12 = tf.reduce_sum(x, (-1, -2), keepdims=True) - - avg = a1 * a2 - avg = avg / a12 - normalized = x - avg - return normalized - - -class TFRotaryEmbedding(keras.layers.Layer): - """ - Rotary position embeddings based on those in - [RoFormer](https://huggingface.co/docs/transformers/model_doc/roformer). Query and keys are transformed by rotation - matrices which depend on their relative positions. - """ - - def __init__(self, dim: int, name=None): - super().__init__(name=name) - # Matt: The PyTorch version of this layer does a lot of work to cache values, but we just rely on TF compilation - # and/or XLA to sort out constants like that. It actually may not seem like this layer needs to be stateful at - # all when we benefit from TF compilation, but it does. The reason is that self.inv_freq is a buffer in the - # original implementation, but all the shared ESM checkpoints were trained with fp16 params. This means that - # the inv_freq tensor was stored as a float16, and we need to replicate those lower-precision values or our - # models give different outputs from the original. - self.dim = dim - - def build(self, input_shape): - super().build(input_shape) - self.inv_freq = self.add_weight( - "inv_freq", shape=(self.dim // 2,), dtype=tf.float32, initializer=get_initializer(1.0), trainable=False - ) - self.inv_freq.assign( - 1.0 / (10000 ** (tf.range(start=0, limit=self.dim, delta=2, dtype=tf.float32) / self.dim)) - ) - - def _compute_cos_sin(self, x, seq_dimension=2): - seq_len = tf.shape(x)[seq_dimension] - - t = tf.range(seq_len, dtype=self.inv_freq.dtype) - freqs = tf.einsum("i, j -> ij", t, self.inv_freq) # Outer multiplication - emb = tf.concat((freqs, freqs), axis=-1)[None, None, :, :] - - return tf.cos(emb), tf.sin(emb) - - def call(self, q: tf.Tensor, k: tf.Tensor) -> tuple[tf.Tensor, tf.Tensor]: - cos_emb, sin_emb = self._compute_cos_sin(k, seq_dimension=-2) - - return ( - apply_rotary_pos_emb(q, cos_emb, sin_emb), - apply_rotary_pos_emb(k, cos_emb, sin_emb), - ) - - -class TFEsmContactPredictionHead(keras.layers.Layer): - """Performs symmetrization, apc, and computes a logistic regression on the output features""" - - def __init__( - self, - in_features: int, - bias=True, - eos_idx: int = 2, - name=None, - ): - super().__init__(name=name) - self.eos_idx = eos_idx - self.in_features = in_features - self.regression = keras.layers.Dense(1, use_bias=bias, activation="sigmoid", name="regression") - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "regression", None) is not None: - with tf.name_scope(self.regression.name): - self.regression.build((None, self.in_features)) - - def call(self, tokens, attentions): - # remove eos token attentions - eos_mask = tf.cast(tokens != self.eos_idx, attentions.dtype) - eos_mask = tf.expand_dims(eos_mask, 1) * tf.expand_dims(eos_mask, 2) - attentions = attentions * eos_mask[:, None, None, :, :] - attentions = attentions[..., :-1, :-1] - # remove cls token attentions - attentions = attentions[..., 1:, 1:] - batch_size, layers, heads, seqlen, _ = shape_list(attentions) - attentions = tf.reshape(attentions, (batch_size, layers * heads, seqlen, seqlen)) - - # features: batch x channels x tokens x tokens (symmetric) - attentions = average_product_correct(symmetrize(attentions)) - attentions = tf.transpose(attentions, perm=(0, 2, 3, 1)) - return tf.squeeze(self.regression(attentions), 3) - - -class TFEsmEmbeddings(keras.layers.Layer): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ - - def __init__(self, config, name=None): - super().__init__(name=name) - self.word_embeddings = keras.layers.Embedding( - config.vocab_size, - config.hidden_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="word_embeddings", - ) - self.position_embeddings = keras.layers.Embedding( - config.max_position_embeddings, - config.hidden_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="position_embeddings", - ) - - if config.emb_layer_norm_before: - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - else: - self.layer_norm = None - # Matt: I think this line was copied incorrectly from BERT, disabling for now - # self.dropout = Dropout(config.hidden_dropout_prob) - self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") - - self.position_ids = tf.range(config.max_position_embeddings)[None, :] - - self.padding_idx = config.pad_token_id - self.token_dropout = config.token_dropout - self.mask_token_id = config.mask_token_id - self.config = config - - def call( - self, input_ids=None, attention_mask=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): - if position_ids is None: - if input_ids is not None: - # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) - else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = self.word_embeddings(input_ids) - - # Note that if we want to support ESM-1 (not 1b!) in future then we need to support an - # embedding_scale factor here. - embeddings = inputs_embeds - - # Matt: ESM has the option to handle masking in MLM in a slightly unusual way. If the token_dropout - # flag is False then it is handled in the same was as BERT/RoBERTa. If it is set to True, however, - # masked tokens are treated as if they were selected for input dropout and zeroed out. - # This "mask-dropout" is compensated for when masked tokens are not present, by scaling embeddings by - # a factor of (fraction of unmasked tokens during training) / (fraction of unmasked tokens in sample). - # This is analogous to the way that dropout layers scale down outputs during evaluation when not - # actually dropping out values (or, equivalently, scale up their un-dropped outputs in training). - if self.token_dropout: - embeddings = tf.where((input_ids == self.mask_token_id)[:, :, None], 0.0, embeddings) - mask_ratio_train = 0.15 * 0.8 # Hardcoded as the ratio used in all ESM model training runs - src_lengths = tf.cast(tf.reduce_sum(attention_mask, axis=-1), tf.float32) - masked_tokens = input_ids == self.mask_token_id - mask_ratio_observed = tf.math.count_nonzero(masked_tokens, dtype=tf.float32, axis=-1) / src_lengths - embeddings = embeddings * (1 - mask_ratio_train) / (1 - mask_ratio_observed)[:, None, None] - - if self.position_embedding_type == "absolute": - position_embeddings = self.position_embeddings(position_ids) - embeddings += position_embeddings - - if self.layer_norm is not None: - embeddings = self.layer_norm(embeddings) - if attention_mask is not None: - embeddings = embeddings * tf.cast(tf.expand_dims(attention_mask, -1), embeddings.dtype) - # Matt: I think this line was copied incorrectly from BERT, disabling it for now. - # embeddings = self.dropout(embeddings) - return embeddings - - def create_position_ids_from_inputs_embeds(self, inputs_embeds): - """ - We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. - - Args: - inputs_embeds: tf.Tensor - - Returns: tf.Tensor - """ - input_shape = shape_list(inputs_embeds)[:-1] - sequence_length = input_shape[1] - - position_ids = tf.range( - start=self.padding_idx + 1, limit=sequence_length + self.padding_idx + 1, dtype=tf.int64 - ) - return tf.broadcast_to(tf.expand_dims(position_ids, 0), input_shape) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "word_embeddings", None) is not None: - with tf.name_scope(self.word_embeddings.name): - self.word_embeddings.build(None) - if getattr(self, "position_embeddings", None) is not None: - with tf.name_scope(self.position_embeddings.name): - self.position_embeddings.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - - -class TFEsmSelfAttention(keras.layers.Layer): - def __init__(self, config, position_embedding_type=None, name=None): - super().__init__(name=name) - if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " - f"heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - - self.query = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.position_embedding_type = position_embedding_type or getattr( - config, "position_embedding_type", "absolute" - ) - self.rotary_embeddings = None - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - self.max_position_embeddings = config.max_position_embeddings - self.distance_embedding = keras.layers.Embedding( - 2 * config.max_position_embeddings - 1, - self.attention_head_size, - embeddings_initializer=get_initializer(config.initializer_range), - ) - elif self.position_embedding_type == "rotary": - self.rotary_embeddings = TFRotaryEmbedding(dim=self.attention_head_size, name="rotary_embeddings") - - self.is_decoder = config.is_decoder - self.config = config - - def transpose_for_scores(self, x: tf.Tensor) -> tf.Tensor: - new_x_shape = shape_list(x)[:-1] + [self.num_attention_heads, self.attention_head_size] - x = tf.reshape(x, new_x_shape) - return tf.transpose(x, perm=(0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - output_attentions: bool | None = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - mixed_query_layer = self.query(hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_layer = past_key_value[0] - value_layer = past_key_value[1] - attention_mask = encoder_attention_mask - elif is_cross_attention: - key_layer = self.transpose_for_scores(self.key(encoder_hidden_states)) - value_layer = self.transpose_for_scores(self.value(encoder_hidden_states)) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(hidden_states)) - value_layer = self.transpose_for_scores(self.value(hidden_states)) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(hidden_states)) - value_layer = self.transpose_for_scores(self.value(hidden_states)) - - query_layer = self.transpose_for_scores(mixed_query_layer) - - # Matt: Our BERT model (which this code was derived from) scales attention logits down by sqrt(head_dim). - # ESM scales the query down by the same factor instead. Modulo numerical stability these are equivalent, - # but not when rotary embeddings get involved. Therefore, we scale the query here to match the original - # ESM code and fix rotary embeddings. - query_layer = query_layer * self.attention_head_size**-0.5 - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_layer, value_layer) - - if self.position_embedding_type == "rotary": - query_layer, key_layer = self.rotary_embeddings(query_layer, key_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - seq_length = shape_list(hidden_states)[1] - position_ids_l = tf.expand_dims(tf.range(seq_length, dtype=tf.int64), -1) - position_ids_r = tf.expand_dims(tf.range(seq_length, dtype=tf.int64), 0) - distance = position_ids_l - position_ids_r - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = tf.cast(positional_embedding, query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = tf.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = tf.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = tf.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in EsmModel forward() function) - attention_scores = attention_scores + attention_mask - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - - context_layer = attention_probs @ value_layer - - context_layer = tf.transpose(context_layer, perm=(0, 2, 1, 3)) - new_context_layer_shape = shape_list(context_layer)[:-2] + [self.all_head_size] - context_layer = tf.reshape(context_layer, new_context_layer_shape) - - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - - if self.is_decoder: - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - if getattr(self, "rotary_embeddings", None) is not None: - with tf.name_scope(self.rotary_embeddings.name): - self.rotary_embeddings.build(None) - - -class TFEsmSelfOutput(keras.layers.Layer): - def __init__(self, config, name=None): - super().__init__(name=name) - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states, input_tensor, training=False): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states += input_tensor - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFEsmAttention(keras.layers.Layer): - def __init__(self, config, name=None): - super().__init__(name=name) - self.self = TFEsmSelfAttention(config, name="self") - self.output_layer = TFEsmSelfOutput(config, name="output") - self.pruned_heads = set() - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - hidden_states, - attention_mask=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=None, - output_attentions=False, - training=False, - ): - hidden_states_ln = self.LayerNorm(hidden_states) - self_outputs = self.self( - hidden_states_ln, - attention_mask, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - past_key_value, - output_attentions, - training, - ) - attention_output = self.output_layer(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self", None) is not None: - with tf.name_scope(self.self.name): - self.self.build(None) - if getattr(self, "output_layer", None) is not None: - with tf.name_scope(self.output_layer.name): - self.output_layer.build(None) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFEsmIntermediate(keras.layers.Layer): - def __init__(self, config: EsmConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = tf.nn.gelu(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFEsmOutput(keras.layers.Layer): - def __init__(self, config, name=None): - super().__init__(name=name) - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states, input_tensor, training=False): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states += input_tensor - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - - -class TFEsmLayer(keras.layers.Layer): - def __init__(self, config, name=None): - super().__init__(name=name) - self.chunk_size_feed_forward = config.chunk_size_feed_forward - self.seq_len_dim = 1 - self.attention = TFEsmAttention(config, name="attention") - self.is_decoder = config.is_decoder - self.add_cross_attention = config.add_cross_attention - if self.add_cross_attention: - if not self.is_decoder: - raise RuntimeError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = TFEsmAttention(config) - self.intermediate = TFEsmIntermediate(config, name="intermediate") - self.output_layer = TFEsmOutput(config, name="output") - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call( - self, - hidden_states, - attention_mask=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=None, - output_attentions=False, - training=False, - ): - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - hidden_states, - attention_mask, - head_mask, - output_attentions=output_attentions, - past_key_value=self_attn_past_key_value, - training=training, - ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - cross_attn_present_key_value = None - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise AttributeError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated" - " with cross-attention layers by setting `config.add_cross_attention=True`" - ) - - # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - cross_attn_past_key_value, - output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - - # add cross-attn cache to positions 3,4 of present_key_value tuple - cross_attn_present_key_value = cross_attention_outputs[-1] - present_key_value = present_key_value + cross_attn_present_key_value - - layernorm_output = self.LayerNorm(attention_output) - intermediate_output = self.intermediate(hidden_states=layernorm_output) - layer_output = self.output_layer( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + outputs # add attentions if we output them - - # if decoder, return the attn key/values as the last output - if self.is_decoder: - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "output_layer", None) is not None: - with tf.name_scope(self.output_layer.name): - self.output_layer.build(None) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFEsmEncoder(keras.layers.Layer): - def __init__(self, config, name=None): - super().__init__(name=name) - self.config = config - self.layer = [TFEsmLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - self.emb_layer_norm_after = keras.layers.LayerNormalization( - epsilon=config.layer_norm_eps, name="emb_layer_norm_after" - ) - - def call( - self, - hidden_states, - attention_mask=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_values=None, - use_cache=None, - output_attentions=False, - output_hidden_states=False, - return_dict=True, - training=False, - ): - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - next_decoder_cache = () if use_cache else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_head_mask = head_mask[i] if head_mask is not None else None - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states, - attention_mask, - layer_head_mask, - encoder_hidden_states, - encoder_attention_mask, - past_key_value, - output_attentions, - training, - ) - - hidden_states = layer_outputs[0] - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if self.emb_layer_norm_after: - hidden_states = self.emb_layer_norm_after(hidden_states) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - next_decoder_cache, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "emb_layer_norm_after", None) is not None: - with tf.name_scope(self.emb_layer_norm_after.name): - self.emb_layer_norm_after.build([None, None, self.config.hidden_size]) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->Esm -class TFEsmPooler(keras.layers.Layer): - def __init__(self, config: EsmConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFEsmPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = EsmConfig - base_model_prefix = "esm" - - -ESM_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Keras [Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it as a - regular Keras model and refer to the TF/Keras documentation for all matters related to general usage and behavior. - - Parameters: - config ([`EsmConfig`]): Model configuration class with all the parameters of the - model. Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -ESM_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. -""" - - -@add_start_docstrings( - "The bare ESM Model transformer outputting raw hidden-states without any specific head on top.", - ESM_START_DOCSTRING, -) -class TFEsmMainLayer(keras.layers.Layer): - """ - - The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of - cross-attention is added between the self-attention layers, following the architecture described in [Attention is - all you need](https://huggingface.co/papers/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, - Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin. - - To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set - to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and - `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. - """ - - _keys_to_ignore_on_load_missing = [r"position_ids"] - - def __init__(self, config, add_pooling_layer=True, name=None, **kwargs): - super().__init__(name=name, **kwargs) - - self.config = config - self.is_decoder = config.is_decoder - - self.embeddings = TFEsmEmbeddings(config, name="embeddings") - self.encoder = TFEsmEncoder(config, name="encoder") - self.pooler = TFEsmPooler(config, name="pooler") if add_pooling_layer else None - - self.contact_head = TFEsmContactPredictionHead( - in_features=self.config.num_hidden_layers * self.config.num_attention_heads, bias=True, name="contact_head" - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - if getattr(self, "contact_head", None) is not None: - with tf.name_scope(self.contact_head.name): - self.contact_head.build(None) - - def get_input_embeddings(self): - return self.embeddings.word_embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.word_embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - raise NotImplementedError - - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - if not self.config.is_decoder: - use_cache = False - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - - if past_key_values is None: - past_key_values_length = 0 - past_key_values = [None] * len(self.encoder.layer) - else: - past_key_values_length = shape_list(past_key_values[0][0])[-2] - - if attention_mask is None: - attention_mask = tf.fill(dims=(batch_size, seq_length + past_key_values_length), value=1) - - embedding_output = self.embeddings( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - - mask_seq_length = seq_length + past_key_values_length - # Copied from `modeling_tf_t5.py` - # Provided a padding mask of dimensions [batch_size, mask_seq_length] - # - if the model is a decoder, apply a causal mask in addition to the padding mask - # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - if self.is_decoder: - seq_ids = tf.range(mask_seq_length) - causal_mask = tf.less_equal( - tf.tile(seq_ids[None, None, :], (batch_size, mask_seq_length, 1)), - seq_ids[None, :, None], - ) - causal_mask = tf.cast(causal_mask, dtype=attention_mask.dtype) - extended_attention_mask = causal_mask * attention_mask[:, None, :] - attention_mask_shape = shape_list(extended_attention_mask) - extended_attention_mask = tf.reshape( - extended_attention_mask, (attention_mask_shape[0], 1, attention_mask_shape[1], attention_mask_shape[2]) - ) - if past_key_values[0] is not None: - # attention_mask needs to be sliced to the shape `[batch_size, 1, from_seq_length - cached_seq_length, to_seq_length] - extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :] - else: - extended_attention_mask = tf.reshape( - attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1]) - ) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Copied from `modeling_tf_t5.py` with -1e9 -> -10000 - if self.is_decoder and encoder_attention_mask is not None: - # If a 2D ou 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=extended_attention_mask.dtype) - num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) - if num_dims_encoder_attention_mask == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if num_dims_encoder_attention_mask == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, - # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) - - encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -10000.0 - else: - encoder_extended_attention_mask = None - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, - ) - - def predict_contacts(self, tokens, attention_mask): - attns = self(tokens, attention_mask=attention_mask, return_dict=True, output_attentions=True).attentions - attns = tf.stack(attns, axis=1) # Matches the original model layout - # In the original model, attentions for padding tokens are completely zeroed out. - # This makes no difference most of the time because the other tokens won't attend to them, - # but it does for the contact prediction task, which takes attentions as input, - # so we have to mimic that here. - attention_mask = tf.cast(attention_mask, attns.dtype) - attns *= attention_mask[:, None, None, None] - attns *= attention_mask[:, None, None, :, None] - return self.contact_head(tokens, attns) - - -@add_start_docstrings( - "The bare ESM Model transformer outputting raw hidden-states without any specific head on top.", - ESM_START_DOCSTRING, -) -class TFEsmModel(TFEsmPreTrainedModel): - def __init__(self, config: EsmConfig, add_pooling_layer=True, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.esm = TFEsmMainLayer(config, add_pooling_layer=add_pooling_layer, name="esm") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ESM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPoolingAndCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - """ - outputs = self.esm( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - def predict_contacts(self, tokens, attention_mask): - return self.esm.predict_contacts(tokens, attention_mask) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "esm", None) is not None: - with tf.name_scope(self.esm.name): - self.esm.build(None) - - -@add_start_docstrings("""ESM Model with a `language modeling` head on top.""", ESM_START_DOCSTRING) -class TFEsmForMaskedLM(TFEsmPreTrainedModel, TFMaskedLanguageModelingLoss): - _keys_to_ignore_on_load_missing = [r"position_ids"] - _keys_to_ignore_on_load_unexpected = [r"pooler"] - - def __init__(self, config): - super().__init__(config) - - if config.is_decoder: - logger.warning( - "If you want to use `EsmForMaskedLM` make sure `config.is_decoder=False` for " - "bi-directional self-attention." - ) - - self.esm = TFEsmMainLayer(config, add_pooling_layer=False, name="esm") - self.lm_head = TFEsmLMHead(config, name="lm_head") - if config.tie_word_embeddings: - # Ensure word embeddings are built so that we actually have something to tie - with tf.name_scope(os.path.join(self._name_scope(), "esm", "embeddings", "word_embeddings")): - self.esm.embeddings.word_embeddings.build((None, None)) - self.lm_head.decoder = self.esm.embeddings.word_embeddings.weights[0] - - def get_output_embeddings(self): - return self.lm_head.decoder - - def set_output_embeddings(self, new_embeddings): - self.lm_head.decoder = new_embeddings - - def get_lm_head(self): - return self.lm_head - - @unpack_inputs - @add_start_docstrings_to_model_forward(ESM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - mask="", - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - kwargs (`dict[str, any]`, *optional*, defaults to `{}`): - Used to hide legacy arguments that have been deprecated. - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.esm( - input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.lm_head(sequence_output) - - masked_lm_loss = None - if labels is not None: - masked_lm_loss = self.hf_compute_loss(labels=labels, logits=prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - - return TFMaskedLMOutput( - loss=masked_lm_loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def predict_contacts(self, tokens, attention_mask): - return self.esm.predict_contacts(tokens, attention_mask) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "esm", None) is not None: - with tf.name_scope(self.esm.name): - self.esm.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -class TFEsmLMHead(keras.layers.Layer): - """ESM Head for masked language modeling.""" - - def __init__(self, config, name=None): - super().__init__(name=name) - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - if config.tie_word_embeddings: - self.decoder = None - else: - self.decoder = keras.layers.Dense( - config.vocab_size, - kernel_initializer=get_initializer(config.initializer_range), - name="decoder", - use_bias=False, - ) - self.config = config - - def build(self, input_shape=None): - # Separate bias to match the PT model and allow weight cross-loading to work - # Put it in the build so it gets the right name when adding it as a weight - if self.built: - return - self.built = True - self.bias = self.add_weight("bias", shape=(self.config.vocab_size,), initializer="zeros", trainable=True) - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "decoder", None) is not None and not self.config.tie_word_embeddings: - with tf.name_scope(self.decoder.name): - self.decoder.build([None, None, self.config.hidden_size]) - - def get_bias(self): - return {"bias": self.bias} - - def call(self, features): - x = self.dense(features) - x = tf.nn.gelu(x) - x = self.layer_norm(x) - - # project back to size of vocabulary with bias - if self.config.tie_word_embeddings: - x = tf.matmul(x, self.decoder, transpose_b=True) + self.bias - else: - x = self.decoder(x) + self.bias - return x - - -@add_start_docstrings( - """ - ESM Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled - output) e.g. for GLUE tasks. - """, - ESM_START_DOCSTRING, -) -class TFEsmForSequenceClassification(TFEsmPreTrainedModel, TFSequenceClassificationLoss): - _keys_to_ignore_on_load_missing = [r"position_ids"] - - def __init__(self, config): - super().__init__(config) - self.num_labels = config.num_labels - self.config = config - - self.esm = TFEsmMainLayer(config, add_pooling_layer=False, name="esm") - self.classifier = TFEsmClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ESM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.esm( - input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "esm", None) is not None: - with tf.name_scope(self.esm.name): - self.esm.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - ESM Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - ESM_START_DOCSTRING, -) -class TFEsmForTokenClassification(TFEsmPreTrainedModel, TFTokenClassificationLoss): - _keys_to_ignore_on_load_unexpected = [r"pooler"] - _keys_to_ignore_on_load_missing = [r"position_ids"] - - def __init__(self, config): - super().__init__(config) - self.num_labels = config.num_labels - - self.esm = TFEsmMainLayer(config, add_pooling_layer=False, name="esm") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.classifier = keras.layers.Dense(config.num_labels, name="classifier") - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ESM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.esm( - input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "esm", None) is not None: - with tf.name_scope(self.esm.name): - self.esm.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -class TFEsmClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, config, name=None): - super().__init__(name=name) - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.out_proj = keras.layers.Dense( - config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - activation="linear", - name="out_proj", - ) - self.config = config - - def call(self, features, training=False): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x, training=training) - x = self.dense(x) - x = self.dropout(x, training=training) - x = self.out_proj(x) - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: tf.Tensor x: - - Returns: tf.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = tf.cast(input_ids != padding_idx, tf.int64) - incremental_indices = (tf.cumsum(mask, axis=1) + past_key_values_length) * mask - return incremental_indices + padding_idx - - -__all__ = [ - "TFEsmForMaskedLM", - "TFEsmForSequenceClassification", - "TFEsmForTokenClassification", - "TFEsmModel", - "TFEsmPreTrainedModel", -] diff --git a/src/transformers/models/esm/openfold_utils/tensor_utils.py b/src/transformers/models/esm/openfold_utils/tensor_utils.py index 449c810aed3f..c776f89659b6 100644 --- a/src/transformers/models/esm/openfold_utils/tensor_utils.py +++ b/src/transformers/models/esm/openfold_utils/tensor_utils.py @@ -93,7 +93,6 @@ def batched_gather(data: torch.Tensor, inds: torch.Tensor, dim: int = 0, no_batc T = TypeVar("T") -# With tree_map, a poor man's JAX tree_map def dict_map( fn: Callable[[T], Any], dic: dict[Any, Union[dict, list, tuple, T]], leaf_type: type[T] ) -> dict[Any, Union[dict, list, tuple, Any]]: diff --git a/src/transformers/models/falcon/modeling_falcon.py b/src/transformers/models/falcon/modeling_falcon.py index 26dc56e41480..dac4dc658b19 100644 --- a/src/transformers/models/falcon/modeling_falcon.py +++ b/src/transformers/models/falcon/modeling_falcon.py @@ -655,8 +655,6 @@ def __init__(self, *inputs, **kwargs): def _init_weights(self, module: nn.Module): """Initialize the weights.""" if isinstance(module, (nn.Linear, FalconLinear)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/flaubert/__init__.py b/src/transformers/models/flaubert/__init__.py index e981d9cbcb1e..e418a0f74381 100644 --- a/src/transformers/models/flaubert/__init__.py +++ b/src/transformers/models/flaubert/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_flaubert import * from .modeling_flaubert import * - from .modeling_tf_flaubert import * from .tokenization_flaubert import * else: import sys diff --git a/src/transformers/models/flaubert/modeling_flaubert.py b/src/transformers/models/flaubert/modeling_flaubert.py index 1dadc6f5377b..91c6990b77b9 100644 --- a/src/transformers/models/flaubert/modeling_flaubert.py +++ b/src/transformers/models/flaubert/modeling_flaubert.py @@ -676,7 +676,6 @@ def forward( # Copied from transformers.models.xlm.modeling_xlm.XLMPreTrainedModel with XLM->Flaubert class FlaubertPreTrainedModel(PreTrainedModel): config: FlaubertConfig - load_tf_weights = None base_model_prefix = "transformer" def __init__(self, *inputs, **kwargs): diff --git a/src/transformers/models/flaubert/modeling_tf_flaubert.py b/src/transformers/models/flaubert/modeling_tf_flaubert.py deleted file mode 100644 index 88b7ae9f0c9d..000000000000 --- a/src/transformers/models/flaubert/modeling_tf_flaubert.py +++ /dev/null @@ -1,1343 +0,0 @@ -# coding=utf-8 -# Copyright 2019-present, Facebook, Inc and 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. -""" -TF 2.0 Flaubert model. -""" - -from __future__ import annotations - -import itertools -import random -import warnings -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFSequenceSummary, - TFSharedEmbeddings, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - MULTIPLE_CHOICE_DUMMY_INPUTS, - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_flaubert import FlaubertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "flaubert/flaubert_base_cased" -_CONFIG_FOR_DOC = "FlaubertConfig" - - -FLAUBERT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`FlaubertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -FLAUBERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - `1` for tokens that are **not masked**, - - `0` for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - langs (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): - A parallel sequence of tokens to be used to indicate the language of each token in the input. Indices are - languages ids which can be obtained from the language names by using two conversion mappings provided in - the configuration of the model (only provided for multilingual models). More precisely, the *language name - to language id* mapping is in `model.config.lang2id` (which is a dictionary string to int) and the - *language id to language name* mapping is in `model.config.id2lang` (dictionary int to string). - - See usage examples detailed in the [multilingual documentation](../multilingual). - token_type_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - `0` corresponds to a *sentence A* token, - - `1` corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - lengths (`tf.Tensor` or `Numpy array` of shape `(batch_size,)`, *optional*): - Length of each sentence that can be used to avoid performing attention on padding token indices. You can - also use *attention_mask* for the same result (see above), kept here for compatibility Indices selected in - `[0, ..., input_ids.size(-1)]`: - cache (`dict[str, tf.Tensor]`, *optional*): - Dictionary string to `tf.FloatTensor` that contains precomputed hidden states (key and values in the - attention blocks) as computed by the model (see `cache` output below). Can be used to speed up sequential - decoding. - - The dictionary object will be modified in-place during the forward pass to add newly computed - hidden-states. - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - `1` indicates the head is **not masked**, - - `0` indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -def get_masks(slen, lengths, causal, padding_mask=None): - """ - Generate hidden states mask, and optionally an attention mask. - """ - bs = shape_list(lengths)[0] - if padding_mask is not None: - mask = padding_mask - else: - # assert lengths.max().item() <= slen - alen = tf.range(slen, dtype=lengths.dtype) - mask = alen < tf.expand_dims(lengths, axis=1) - - # attention mask is the same as mask, or triangular inferior attention (causal) - if causal: - attn_mask = tf.less_equal( - tf.tile(tf.reshape(alen, (1, 1, slen)), (bs, slen, 1)), tf.reshape(alen, (1, slen, 1)) - ) - else: - attn_mask = mask - - # sanity check - # assert shape_list(mask) == [bs, slen] - tf.debugging.assert_equal(shape_list(mask), [bs, slen]) - if causal: - tf.debugging.assert_equal(shape_list(attn_mask), [bs, slen, slen]) - - return mask, attn_mask - - -class TFFlaubertPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = FlaubertConfig - base_model_prefix = "transformer" - - @property - def dummy_inputs(self): - # Sometimes Flaubert has language embeddings so don't forget to build them as well if needed - inputs_list = tf.constant([[7, 6, 0, 0, 1], [1, 2, 3, 0, 0], [0, 0, 0, 4, 5]], dtype=tf.int32) - attns_list = tf.constant([[1, 1, 0, 0, 1], [1, 1, 1, 0, 0], [1, 0, 0, 1, 1]], dtype=tf.int32) - if self.config.use_lang_emb and self.config.n_langs > 1: - return { - "input_ids": inputs_list, - "attention_mask": attns_list, - "langs": tf.constant([[1, 1, 0, 0, 1], [1, 1, 1, 0, 0], [1, 0, 0, 1, 1]], dtype=tf.int32), - } - else: - return {"input_ids": inputs_list, "attention_mask": attns_list} - - -@add_start_docstrings( - "The bare Flaubert Model transformer outputting raw hidden-states without any specific head on top.", - FLAUBERT_START_DOCSTRING, -) -class TFFlaubertModel(TFFlaubertPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFFlaubertMainLayer(config, name="transformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(FLAUBERT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutput: - outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - langs=langs, - token_type_ids=token_type_ids, - position_ids=position_ids, - lengths=lengths, - cache=cache, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -# Copied from transformers.models.xlm.modeling_tf_xlm.TFXLMMultiHeadAttention with XLM->Flaubert -class TFFlaubertMultiHeadAttention(keras.layers.Layer): - NEW_ID = itertools.count() - - def __init__(self, n_heads, dim, config, **kwargs): - super().__init__(**kwargs) - self.layer_id = next(TFFlaubertMultiHeadAttention.NEW_ID) - self.dim = dim - self.n_heads = n_heads - self.output_attentions = config.output_attentions - assert self.dim % self.n_heads == 0 - - self.q_lin = keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="q_lin") - self.k_lin = keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="k_lin") - self.v_lin = keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="v_lin") - self.out_lin = keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="out_lin") - self.dropout = keras.layers.Dropout(config.attention_dropout) - self.pruned_heads = set() - self.dim = dim - - def prune_heads(self, heads): - raise NotImplementedError - - def call(self, input, mask, kv, cache, head_mask, output_attentions, training=False): - """ - Self-attention (if kv is None) or attention over source sentence (provided by kv). - """ - # Input is (bs, qlen, dim) - # Mask is (bs, klen) (non-causal) or (bs, klen, klen) - bs, qlen, dim = shape_list(input) - - if kv is None: - klen = qlen if cache is None else cache["slen"] + qlen - else: - klen = shape_list(kv)[1] - - # assert dim == self.dim, f'Dimensions do not match: {dim} input vs {self.dim} configured' - dim_per_head = self.dim // self.n_heads - mask_reshape = (bs, 1, qlen, klen) if len(shape_list(mask)) == 3 else (bs, 1, 1, klen) - - def shape(x): - """projection""" - return tf.transpose(tf.reshape(x, (bs, -1, self.n_heads, dim_per_head)), perm=(0, 2, 1, 3)) - - def unshape(x): - """compute context""" - return tf.reshape(tf.transpose(x, perm=(0, 2, 1, 3)), (bs, -1, self.n_heads * dim_per_head)) - - q = shape(self.q_lin(input)) # (bs, n_heads, qlen, dim_per_head) - - if kv is None: - k = shape(self.k_lin(input)) # (bs, n_heads, qlen, dim_per_head) - v = shape(self.v_lin(input)) # (bs, n_heads, qlen, dim_per_head) - elif cache is None or self.layer_id not in cache: - k = v = kv - k = shape(self.k_lin(k)) # (bs, n_heads, qlen, dim_per_head) - v = shape(self.v_lin(v)) # (bs, n_heads, qlen, dim_per_head) - - if cache is not None: - if self.layer_id in cache: - if kv is None: - k_, v_ = cache[self.layer_id] - k = tf.concat([k_, k], axis=2) # (bs, n_heads, klen, dim_per_head) - v = tf.concat([v_, v], axis=2) # (bs, n_heads, klen, dim_per_head) - else: - k, v = cache[self.layer_id] - - cache[self.layer_id] = (k, v) - - f_dim_per_head = tf.cast(dim_per_head, dtype=q.dtype) - q = tf.multiply(q, tf.math.rsqrt(f_dim_per_head)) # (bs, n_heads, qlen, dim_per_head) - k = tf.cast(k, dtype=q.dtype) - scores = tf.matmul(q, k, transpose_b=True) # (bs, n_heads, qlen, klen) - mask = tf.reshape(mask, mask_reshape) # (bs, n_heads, qlen, klen) - # scores.masked_fill_(mask, -float('inf')) # (bs, n_heads, qlen, klen) - mask = tf.cast(mask, dtype=scores.dtype) - scores = scores - 1e30 * (1.0 - mask) - weights = stable_softmax(scores, axis=-1) # (bs, n_heads, qlen, klen) - weights = self.dropout(weights, training=training) # (bs, n_heads, qlen, klen) - - # Mask heads if we want to - if head_mask is not None: - weights = weights * head_mask - - context = tf.matmul(weights, v) # (bs, n_heads, qlen, dim_per_head) - context = unshape(context) # (bs, qlen, dim) - outputs = (self.out_lin(context),) - - if output_attentions: - outputs = outputs + (weights,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "q_lin", None) is not None: - with tf.name_scope(self.q_lin.name): - self.q_lin.build([None, None, self.dim]) - if getattr(self, "k_lin", None) is not None: - with tf.name_scope(self.k_lin.name): - self.k_lin.build([None, None, self.dim]) - if getattr(self, "v_lin", None) is not None: - with tf.name_scope(self.v_lin.name): - self.v_lin.build([None, None, self.dim]) - if getattr(self, "out_lin", None) is not None: - with tf.name_scope(self.out_lin.name): - self.out_lin.build([None, None, self.dim]) - - -# Copied from transformers.models.xlm.modeling_tf_xlm.TFXLMTransformerFFN -class TFFlaubertTransformerFFN(keras.layers.Layer): - def __init__(self, in_dim, dim_hidden, out_dim, config, **kwargs): - super().__init__(**kwargs) - - self.lin1 = keras.layers.Dense(dim_hidden, kernel_initializer=get_initializer(config.init_std), name="lin1") - self.lin2 = keras.layers.Dense(out_dim, kernel_initializer=get_initializer(config.init_std), name="lin2") - self.act = get_tf_activation("gelu") if config.gelu_activation else get_tf_activation("relu") - self.dropout = keras.layers.Dropout(config.dropout) - self.in_dim = in_dim - self.dim_hidden = dim_hidden - - def call(self, input, training=False): - x = self.lin1(input) - x = self.act(x) - x = self.lin2(x) - x = self.dropout(x, training=training) - - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "lin1", None) is not None: - with tf.name_scope(self.lin1.name): - self.lin1.build([None, None, self.in_dim]) - if getattr(self, "lin2", None) is not None: - with tf.name_scope(self.lin2.name): - self.lin2.build([None, None, self.dim_hidden]) - - -@keras_serializable -class TFFlaubertMainLayer(keras.layers.Layer): - config_class = FlaubertConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.n_heads = config.n_heads - self.n_langs = config.n_langs - self.dim = config.emb_dim - self.hidden_dim = self.dim * 4 - self.n_words = config.n_words - self.pad_index = config.pad_index - self.causal = config.causal - self.n_layers = config.n_layers - self.use_lang_emb = config.use_lang_emb - self.layerdrop = getattr(config, "layerdrop", 0.0) - self.pre_norm = getattr(config, "pre_norm", False) - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - self.max_position_embeddings = config.max_position_embeddings - self.embed_init_std = config.embed_init_std - self.dropout = keras.layers.Dropout(config.dropout) - self.embeddings = TFSharedEmbeddings( - self.n_words, self.dim, initializer_range=config.embed_init_std, name="embeddings" - ) - self.layer_norm_emb = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm_emb") - self.attentions = [] - self.layer_norm1 = [] - self.ffns = [] - self.layer_norm2 = [] - - for i in range(self.n_layers): - self.attentions.append( - TFFlaubertMultiHeadAttention(self.n_heads, self.dim, config=config, name=f"attentions_._{i}") - ) - self.layer_norm1.append( - keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name=f"layer_norm1_._{i}") - ) - # if self.is_decoder: - # self.layer_norm15.append(nn.LayerNorm(self.dim, eps=config.layer_norm_eps)) - # self.encoder_attn.append(MultiHeadAttention(self.n_heads, self.dim, dropout=self.attention_dropout)) - self.ffns.append( - TFFlaubertTransformerFFN(self.dim, self.hidden_dim, self.dim, config=config, name=f"ffns_._{i}") - ) - self.layer_norm2.append( - keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name=f"layer_norm2_._{i}") - ) - - def build(self, input_shape=None): - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.dim], - initializer=get_initializer(self.embed_init_std), - ) - - if self.n_langs > 1 and self.use_lang_emb: - with tf.name_scope("lang_embeddings"): - self.lang_embeddings = self.add_weight( - name="embeddings", - shape=[self.n_langs, self.dim], - initializer=get_initializer(self.embed_init_std), - ) - - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "layer_norm_emb", None) is not None: - with tf.name_scope(self.layer_norm_emb.name): - self.layer_norm_emb.build([None, None, self.dim]) - for layer in self.attentions: - with tf.name_scope(layer.name): - layer.build(None) - for layer in self.layer_norm1: - with tf.name_scope(layer.name): - layer.build([None, None, self.dim]) - for layer in self.ffns: - with tf.name_scope(layer.name): - layer.build(None) - for layer in self.layer_norm2: - with tf.name_scope(layer.name): - layer.build([None, None, self.dim]) - - def get_input_embeddings(self): - return self.embeddings - - def set_input_embeddings(self, value): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - @unpack_inputs - def call( - self, - input_ids: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutput: - # removed: src_enc=None, src_len=None - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - bs, slen = shape_list(input_ids) - elif inputs_embeds is not None: - bs, slen = shape_list(inputs_embeds)[:2] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if lengths is None: - if input_ids is not None: - lengths = tf.reduce_sum( - tf.cast(tf.not_equal(input_ids, self.pad_index), dtype=input_ids.dtype), axis=1 - ) - else: - lengths = tf.convert_to_tensor([slen] * bs) - # mask = input_ids != self.pad_index - - # check inputs - # assert shape_list(lengths)[0] == bs - ( - tf.debugging.assert_equal(shape_list(lengths)[0], bs), - f"Expected batch size {shape_list(lengths)[0]} and received batch size {bs} mismatched", - ) - # assert lengths.max().item() <= slen - # input_ids = input_ids.transpose(0, 1) # batch size as dimension 0 - # assert (src_enc is None) == (src_len is None) - # if src_enc is not None: - # assert self.is_decoder - # assert src_enc.size(0) == bs - - # generate masks - mask, attn_mask = get_masks(slen, lengths, self.causal, padding_mask=attention_mask) - # if self.is_decoder and src_enc is not None: - # src_mask = torch.arange(src_len.max(), dtype=torch.long, device=lengths.device) < src_len[:, None] - - # position_ids - if position_ids is None: - position_ids = tf.expand_dims(tf.range(slen), axis=0) - position_ids = tf.tile(position_ids, (bs, 1)) - - # assert shape_list(position_ids) == [bs, slen] # (slen, bs) - ( - tf.debugging.assert_equal(shape_list(position_ids), [bs, slen]), - f"Position id shape {shape_list(position_ids)} and input shape {[bs, slen]} mismatched", - ) - # position_ids = position_ids.transpose(0, 1) - - # langs - if langs is not None: - # assert shape_list(langs) == [bs, slen] # (slen, bs) - ( - tf.debugging.assert_equal(shape_list(langs), [bs, slen]), - f"Lang shape {shape_list(langs)} and input shape {[bs, slen]} mismatched", - ) - # langs = langs.transpose(0, 1) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x qlen x klen] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.n_layers - - # do not recompute cached elements - if cache is not None and input_ids is not None: - _slen = slen - cache["slen"] - input_ids = input_ids[:, -_slen:] - position_ids = position_ids[:, -_slen:] - if langs is not None: - langs = langs[:, -_slen:] - mask = mask[:, -_slen:] - attn_mask = attn_mask[:, -_slen:] - - # embeddings - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embeddings.vocab_size) - inputs_embeds = self.embeddings(input_ids) - - tensor = inputs_embeds + tf.gather(self.position_embeddings, position_ids) - - if langs is not None and self.use_lang_emb: - tensor = tensor + tf.gather(self.lang_embeddings, langs) - if token_type_ids is not None: - tensor = tensor + self.embeddings(token_type_ids) - - tensor = self.layer_norm_emb(tensor) - tensor = self.dropout(tensor, training=training) - mask = tf.cast(mask, dtype=tensor.dtype) - tensor = tensor * tf.expand_dims(mask, axis=-1) - - # hidden_states and attentions cannot be None in graph mode. - hidden_states = () if output_hidden_states else None - attentions = () if output_attentions else None - - # transformer layers - for i in range(self.n_layers): - # LayerDrop - dropout_probability = random.uniform(0, 1) - - if training and (dropout_probability < self.layerdrop): - continue - - if output_hidden_states: - hidden_states = hidden_states + (tensor,) - - # self attention - if not self.pre_norm: - attn_outputs = self.attentions[i]( - tensor, - attn_mask, - None, - cache, - head_mask[i], - output_attentions, - training=training, - ) - attn = attn_outputs[0] - - if output_attentions: - attentions = attentions + (attn_outputs[1],) - - attn = self.dropout(attn, training=training) - tensor = tensor + attn - tensor = self.layer_norm1[i](tensor) - else: - tensor_normalized = self.layer_norm1[i](tensor) - attn_outputs = self.attentions[i]( - tensor_normalized, - attn_mask, - None, - cache, - head_mask[i], - output_attentions, - training=training, - ) - attn = attn_outputs[0] - - if output_attentions: - attentions = attentions + (attn_outputs[1],) - - attn = self.dropout(attn, training=training) - tensor = tensor + attn - - # encoder attention (for decoder only) - # if self.is_decoder and src_enc is not None: - # attn = self.encoder_attn[i](tensor, src_mask, kv=src_enc, cache=cache) - # attn = nn.functional.dropout(attn, p=self.dropout, training=self.training) - # tensor = tensor + attn - # tensor = self.layer_norm15[i](tensor) - - # FFN - if not self.pre_norm: - tensor = tensor + self.ffns[i](tensor) - tensor = self.layer_norm2[i](tensor) - else: - tensor_normalized = self.layer_norm2[i](tensor) - tensor = tensor + self.ffns[i](tensor_normalized) - - tensor = tensor * tf.expand_dims(mask, axis=-1) - - # Add last hidden state - if output_hidden_states: - hidden_states = hidden_states + (tensor,) - - # update cache length - if cache is not None: - cache["slen"] += tensor.size(1) - - # move back sequence length to dimension 0 - # tensor = tensor.transpose(0, 1) - - if not return_dict: - return tuple(v for v in [tensor, hidden_states, attentions] if v is not None) - - return TFBaseModelOutput(last_hidden_state=tensor, hidden_states=hidden_states, attentions=attentions) - - -# Copied from transformers.models.xlm.modeling_tf_xlm.TFXLMPredLayer -class TFFlaubertPredLayer(keras.layers.Layer): - """ - Prediction layer (cross_entropy or adaptive_softmax). - """ - - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.asm = config.asm - self.n_words = config.n_words - self.pad_index = config.pad_index - - if config.asm is False: - self.input_embeddings = input_embeddings - else: - raise NotImplementedError - # self.proj = nn.AdaptiveLogSoftmaxWithLoss( - # in_features=dim, - # n_classes=config.n_words, - # cutoffs=config.asm_cutoffs, - # div_value=config.asm_div_value, - # head_bias=True, # default is False - # ) - - def build(self, input_shape): - # The output weights are the same as the input embeddings, but there is an output-only bias for each token. - self.bias = self.add_weight(shape=(self.n_words,), initializer="zeros", trainable=True, name="bias") - - super().build(input_shape) - - def get_output_embeddings(self): - return self.input_embeddings - - def set_output_embeddings(self, value): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - hidden_states = self.input_embeddings(hidden_states, mode="linear") - hidden_states = hidden_states + self.bias - - return hidden_states - - -@dataclass -class TFFlaubertWithLMHeadModelOutput(ModelOutput): - """ - Base class for [`TFFlaubertWithLMHeadModel`] outputs. - - Args: - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@add_start_docstrings( - """ - The Flaubert Model transformer with a language modeling head on top (linear layer with weights tied to the input - embeddings). - """, - FLAUBERT_START_DOCSTRING, -) -class TFFlaubertWithLMHeadModel(TFFlaubertPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFFlaubertMainLayer(config, name="transformer") - self.pred_layer = TFFlaubertPredLayer(config, self.transformer.embeddings, name="pred_layer_._proj") - # Flaubert does not have past caching features - self.supports_xla_generation = False - - def get_lm_head(self): - return self.pred_layer - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.pred_layer.name - - def prepare_inputs_for_generation(self, inputs, **kwargs): - mask_token_id = self.config.mask_token_id - lang_id = self.config.lang_id - - effective_batch_size = inputs.shape[0] - mask_token = tf.fill((effective_batch_size, 1), 1) * mask_token_id - inputs = tf.concat([inputs, mask_token], axis=1) - - if lang_id is not None: - langs = tf.ones_like(inputs) * lang_id - else: - langs = None - return {"input_ids": inputs, "langs": langs} - - @unpack_inputs - @add_start_docstrings_to_model_forward(FLAUBERT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFFlaubertWithLMHeadModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFFlaubertWithLMHeadModelOutput: - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - langs=langs, - token_type_ids=token_type_ids, - position_ids=position_ids, - lengths=lengths, - cache=cache, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - output = transformer_outputs[0] - outputs = self.pred_layer(output) - - if not return_dict: - return (outputs,) + transformer_outputs[1:] - - return TFFlaubertWithLMHeadModelOutput( - logits=outputs, hidden_states=transformer_outputs.hidden_states, attentions=transformer_outputs.attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "pred_layer", None) is not None: - with tf.name_scope(self.pred_layer.name): - self.pred_layer.build(None) - - -@add_start_docstrings( - """ - Flaubert Model with a sequence classification/regression head on top (a linear layer on top of the pooled output) - e.g. for GLUE tasks. - """, - FLAUBERT_START_DOCSTRING, -) -# Copied from transformers.models.xlm.modeling_tf_xlm.TFXLMForSequenceClassification with XLM_INPUTS->FLAUBERT_INPUTS,XLM->Flaubert -class TFFlaubertForSequenceClassification(TFFlaubertPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.transformer = TFFlaubertMainLayer(config, name="transformer") - self.sequence_summary = TFSequenceSummary(config, initializer_range=config.init_std, name="sequence_summary") - - @unpack_inputs - @add_start_docstrings_to_model_forward(FLAUBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - langs=langs, - token_type_ids=token_type_ids, - position_ids=position_ids, - lengths=lengths, - cache=cache, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - output = transformer_outputs[0] - - logits = self.sequence_summary(output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "sequence_summary", None) is not None: - with tf.name_scope(self.sequence_summary.name): - self.sequence_summary.build(None) - - -@add_start_docstrings( - """ - Flaubert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layer on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - FLAUBERT_START_DOCSTRING, -) -# Copied from transformers.models.xlm.modeling_tf_xlm.TFXLMForQuestionAnsweringSimple with XLM_INPUTS->FLAUBERT_INPUTS,XLM->Flaubert -class TFFlaubertForQuestionAnsweringSimple(TFFlaubertPreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFFlaubertMainLayer(config, name="transformer") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.init_std), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(FLAUBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - langs=langs, - token_type_ids=token_type_ids, - position_ids=position_ids, - lengths=lengths, - cache=cache, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = transformer_outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Flaubert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - FLAUBERT_START_DOCSTRING, -) -# Copied from transformers.models.xlm.modeling_tf_xlm.TFXLMForTokenClassification with XLM_INPUTS->FLAUBERT_INPUTS,XLM->Flaubert -class TFFlaubertForTokenClassification(TFFlaubertPreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.transformer = TFFlaubertMainLayer(config, name="transformer") - self.dropout = keras.layers.Dropout(config.dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.init_std), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(FLAUBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - langs=langs, - token_type_ids=token_type_ids, - position_ids=position_ids, - lengths=lengths, - cache=cache, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = transformer_outputs[0] - - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Flaubert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - FLAUBERT_START_DOCSTRING, -) -# Copied from transformers.models.xlm.modeling_tf_xlm.TFXLMForMultipleChoice with XLM_INPUTS->FLAUBERT_INPUTS,XLM->Flaubert -class TFFlaubertForMultipleChoice(TFFlaubertPreTrainedModel, TFMultipleChoiceLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.transformer = TFFlaubertMainLayer(config, name="transformer") - self.sequence_summary = TFSequenceSummary(config, initializer_range=config.init_std, name="sequence_summary") - self.logits_proj = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="logits_proj" - ) - self.config = config - - @property - def dummy_inputs(self): - """ - Dummy inputs to build the network. - - Returns: - tf.Tensor with dummy inputs - """ - # Sometimes Flaubert has language embeddings so don't forget to build them as well if needed - if self.config.use_lang_emb and self.config.n_langs > 1: - return { - "input_ids": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32), - "langs": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32), - } - else: - return { - "input_ids": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32), - } - - @unpack_inputs - @add_start_docstrings_to_model_forward( - FLAUBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") - ) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - flat_langs = tf.reshape(langs, (-1, seq_length)) if langs is not None else None - flat_inputs_embeds = ( - tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - - if lengths is not None: - logger.warning( - "The `lengths` parameter cannot be used with the Flaubert multiple choice models. Please use the " - "attention mask instead.", - ) - lengths = None - - transformer_outputs = self.transformer( - flat_input_ids, - flat_attention_mask, - flat_langs, - flat_token_type_ids, - flat_position_ids, - lengths, - cache, - head_mask, - flat_inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - output = transformer_outputs[0] - logits = self.sequence_summary(output) - logits = self.logits_proj(logits) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "sequence_summary", None) is not None: - with tf.name_scope(self.sequence_summary.name): - self.sequence_summary.build(None) - if getattr(self, "logits_proj", None) is not None: - with tf.name_scope(self.logits_proj.name): - self.logits_proj.build([None, None, self.config.num_labels]) - - -__all__ = [ - "TFFlaubertForMultipleChoice", - "TFFlaubertForQuestionAnsweringSimple", - "TFFlaubertForSequenceClassification", - "TFFlaubertForTokenClassification", - "TFFlaubertModel", - "TFFlaubertPreTrainedModel", - "TFFlaubertWithLMHeadModel", -] diff --git a/src/transformers/models/flava/image_processing_flava.py b/src/transformers/models/flava/image_processing_flava.py index 7b4db246a8fa..9d67ac841124 100644 --- a/src/transformers/models/flava/image_processing_flava.py +++ b/src/transformers/models/flava/image_processing_flava.py @@ -564,10 +564,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -640,10 +638,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") processed_images = [ self._preprocess_image( diff --git a/src/transformers/models/flava/modeling_flava.py b/src/transformers/models/flava/modeling_flava.py index 266c3e96af5a..c48f2ca1279f 100644 --- a/src/transformers/models/flava/modeling_flava.py +++ b/src/transformers/models/flava/modeling_flava.py @@ -375,8 +375,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -701,8 +699,6 @@ class FlavaPreTrainedModel(PreTrainedModel): def _init_weights(self, module: Union[nn.Linear, nn.Conv2d, nn.LayerNorm]) -> None: """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/florence2/modeling_florence2.py b/src/transformers/models/florence2/modeling_florence2.py index 763756faf73f..64947dea1285 100644 --- a/src/transformers/models/florence2/modeling_florence2.py +++ b/src/transformers/models/florence2/modeling_florence2.py @@ -53,11 +53,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/florence2/modular_florence2.py b/src/transformers/models/florence2/modular_florence2.py index f8732257f102..102cff29d800 100644 --- a/src/transformers/models/florence2/modular_florence2.py +++ b/src/transformers/models/florence2/modular_florence2.py @@ -363,10 +363,8 @@ def __call__( `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/florence2/processing_florence2.py b/src/transformers/models/florence2/processing_florence2.py index 91b63e9da7db..5ae0f4828bc1 100644 --- a/src/transformers/models/florence2/processing_florence2.py +++ b/src/transformers/models/florence2/processing_florence2.py @@ -171,10 +171,8 @@ def __call__( `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/fnet/modeling_fnet.py b/src/transformers/models/fnet/modeling_fnet.py index 2ad09a3b268b..b8cdd1f2ea58 100755 --- a/src/transformers/models/fnet/modeling_fnet.py +++ b/src/transformers/models/fnet/modeling_fnet.py @@ -91,8 +91,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) # NOTE: This is the project layer and will be needed. The original code allows for different embedding and different model dimensions. self.projection = nn.Linear(config.hidden_size, config.hidden_size) @@ -392,8 +390,6 @@ class FNetPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) # NOTE: Original code uses same initialization as weights for biases as well. if module.bias is not None: diff --git a/src/transformers/models/focalnet/modeling_focalnet.py b/src/transformers/models/focalnet/modeling_focalnet.py index ed31b5deb527..9b5d4daed70c 100644 --- a/src/transformers/models/focalnet/modeling_focalnet.py +++ b/src/transformers/models/focalnet/modeling_focalnet.py @@ -247,11 +247,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -589,8 +584,6 @@ class FocalNetPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/funnel/__init__.py b/src/transformers/models/funnel/__init__.py index e4e0587ce32f..1a75ee7e2e61 100644 --- a/src/transformers/models/funnel/__init__.py +++ b/src/transformers/models/funnel/__init__.py @@ -21,7 +21,6 @@ from .configuration_funnel import * from .convert_funnel_original_tf_checkpoint_to_pytorch import * from .modeling_funnel import * - from .modeling_tf_funnel import * from .tokenization_funnel import * from .tokenization_funnel_fast import * else: diff --git a/src/transformers/models/funnel/convert_funnel_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/funnel/convert_funnel_original_tf_checkpoint_to_pytorch.py index 4eab188f2ab7..25f7483732da 100755 --- a/src/transformers/models/funnel/convert_funnel_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/funnel/convert_funnel_original_tf_checkpoint_to_pytorch.py @@ -15,16 +15,109 @@ """Convert Funnel checkpoint.""" import argparse +import os import torch -from transformers import FunnelBaseModel, FunnelConfig, FunnelModel, load_tf_weights_in_funnel +from transformers import FunnelBaseModel, FunnelConfig, FunnelModel +from transformers.models.funnel.modeling_funnel import FunnelPositionwiseFFN, FunnelRelMultiheadAttention from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +def load_tf_weights_in_funnel(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array) + + _layer_map = { + "k": "k_head", + "q": "q_head", + "v": "v_head", + "o": "post_proj", + "layer_1": "linear_1", + "layer_2": "linear_2", + "rel_attn": "attention", + "ff": "ffn", + "kernel": "weight", + "gamma": "weight", + "beta": "bias", + "lookup_table": "weight", + "word_embedding": "word_embeddings", + "input": "embeddings", + } + + for name, array in zip(names, arrays): + name = name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any( + n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + continue + if name[0] == "generator": + continue + pointer = model + skipped = False + for m_name in name[1:]: + if not isinstance(pointer, FunnelPositionwiseFFN) and re.fullmatch(r"layer_\d+", m_name): + layer_index = int(re.search(r"layer_(\d+)", m_name).groups()[0]) + if layer_index < config.num_hidden_layers: + block_idx = 0 + while layer_index >= config.block_sizes[block_idx]: + layer_index -= config.block_sizes[block_idx] + block_idx += 1 + pointer = pointer.blocks[block_idx][layer_index] + else: + layer_index -= config.num_hidden_layers + pointer = pointer.layers[layer_index] + elif m_name == "r" and isinstance(pointer, FunnelRelMultiheadAttention): + pointer = pointer.r_kernel + break + elif m_name in _layer_map: + pointer = getattr(pointer, _layer_map[m_name]) + else: + try: + pointer = getattr(pointer, m_name) + except AttributeError: + print(f"Skipping {'/'.join(name)}", array.shape) + skipped = True + break + if not skipped: + if len(pointer.shape) != len(array.shape): + array = array.reshape(pointer.shape) + if m_name == "kernel": + array = np.transpose(array) + pointer.data = torch.from_numpy(array) + + return model + + def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, config_file, pytorch_dump_path, base_model): # Initialise PyTorch model config = FunnelConfig.from_json_file(config_file) diff --git a/src/transformers/models/funnel/modeling_funnel.py b/src/transformers/models/funnel/modeling_funnel.py index 4370344cccfb..d782be0856c8 100644 --- a/src/transformers/models/funnel/modeling_funnel.py +++ b/src/transformers/models/funnel/modeling_funnel.py @@ -14,7 +14,6 @@ # limitations under the License. """PyTorch Funnel Transformer model.""" -import os from dataclasses import dataclass from typing import Optional, Union @@ -43,96 +42,6 @@ INF = 1e6 -def load_tf_weights_in_funnel(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - _layer_map = { - "k": "k_head", - "q": "q_head", - "v": "v_head", - "o": "post_proj", - "layer_1": "linear_1", - "layer_2": "linear_2", - "rel_attn": "attention", - "ff": "ffn", - "kernel": "weight", - "gamma": "weight", - "beta": "bias", - "lookup_table": "weight", - "word_embedding": "word_embeddings", - "input": "embeddings", - } - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - if name[0] == "generator": - continue - pointer = model - skipped = False - for m_name in name[1:]: - if not isinstance(pointer, FunnelPositionwiseFFN) and re.fullmatch(r"layer_\d+", m_name): - layer_index = int(re.search(r"layer_(\d+)", m_name).groups()[0]) - if layer_index < config.num_hidden_layers: - block_idx = 0 - while layer_index >= config.block_sizes[block_idx]: - layer_index -= config.block_sizes[block_idx] - block_idx += 1 - pointer = pointer.blocks[block_idx][layer_index] - else: - layer_index -= config.num_hidden_layers - pointer = pointer.layers[layer_index] - elif m_name == "r" and isinstance(pointer, FunnelRelMultiheadAttention): - pointer = pointer.r_kernel - break - elif m_name in _layer_map: - pointer = getattr(pointer, _layer_map[m_name]) - else: - try: - pointer = getattr(pointer, m_name) - except AttributeError: - print(f"Skipping {'/'.join(name)}", array.shape) - skipped = True - break - if not skipped: - if len(pointer.shape) != len(array.shape): - array = array.reshape(pointer.shape) - if m_name == "kernel": - array = np.transpose(array) - pointer.data = torch.from_numpy(array) - - return model - - class FunnelEmbeddings(nn.Module): def __init__(self, config: FunnelConfig) -> None: super().__init__() @@ -761,7 +670,6 @@ def forward(self, discriminator_hidden_states: torch.Tensor) -> torch.Tensor: @auto_docstring class FunnelPreTrainedModel(PreTrainedModel): config: FunnelConfig - load_tf_weights = load_tf_weights_in_funnel base_model_prefix = "funnel" def _init_weights(self, module): @@ -1448,5 +1356,4 @@ def forward( "FunnelForTokenClassification", "FunnelModel", "FunnelPreTrainedModel", - "load_tf_weights_in_funnel", ] diff --git a/src/transformers/models/funnel/modeling_tf_funnel.py b/src/transformers/models/funnel/modeling_tf_funnel.py deleted file mode 100644 index 3d57fa99eaa1..000000000000 --- a/src/transformers/models/funnel/modeling_tf_funnel.py +++ /dev/null @@ -1,1883 +0,0 @@ -# coding=utf-8 -# Copyright 2020-present Google Brain and Carnegie Mellon University Authors and 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. -"""TF 2.0 Funnel model.""" - -from __future__ import annotations - -import warnings -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_funnel import FunnelConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "FunnelConfig" - - -INF = 1e6 - - -class TFFunnelEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - self.initializer_std = 1.0 if config.initializer_std is None else config.initializer_std - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(initializer_range=self.initializer_std), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.d_model]) - - def call(self, input_ids=None, inputs_embeds=None, training=False): - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - assert not (input_ids is not None and inputs_embeds is not None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(self.weight, input_ids) - - final_embeddings = self.LayerNorm(inputs=inputs_embeds) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -class TFFunnelAttentionStructure: - """ - Contains helpers for `TFFunnelRelMultiheadAttention `. - """ - - cls_token_type_id: int = 2 - - def __init__(self, config): - self.d_model = config.d_model - self.attention_type = config.attention_type - self.num_blocks = config.num_blocks - self.separate_cls = config.separate_cls - self.truncate_seq = config.truncate_seq - self.pool_q_only = config.pool_q_only - self.pooling_type = config.pooling_type - - self.sin_dropout = keras.layers.Dropout(config.hidden_dropout) - self.cos_dropout = keras.layers.Dropout(config.hidden_dropout) - # Track where we are at in terms of pooling from the original input, e.g., by how much the sequence length was - # divided. - self.pooling_mult = None - - def init_attention_inputs(self, inputs_embeds, attention_mask=None, token_type_ids=None, training=False): - """Returns the attention inputs associated to the inputs of the model.""" - # inputs_embeds has shape batch_size x seq_len x d_model - # attention_mask and token_type_ids have shape batch_size x seq_len - self.pooling_mult = 1 - self.seq_len = seq_len = shape_list(inputs_embeds)[1] - position_embeds = self.get_position_embeds(seq_len, training=training) - token_type_mat = self.token_type_ids_to_mat(token_type_ids) if token_type_ids is not None else None - cls_mask = ( - tf.pad(tf.ones([seq_len - 1, seq_len - 1], dtype=inputs_embeds.dtype), [[1, 0], [1, 0]]) - if self.separate_cls - else None - ) - return (position_embeds, token_type_mat, attention_mask, cls_mask) - - def token_type_ids_to_mat(self, token_type_ids): - """Convert `token_type_ids` to `token_type_mat`.""" - token_type_mat = tf.equal(tf.expand_dims(token_type_ids, -1), tf.expand_dims(token_type_ids, -2)) - # Treat as in the same segment as both A & B - cls_ids = tf.equal(token_type_ids, tf.constant([self.cls_token_type_id], dtype=token_type_ids.dtype)) - cls_mat = tf.logical_or(tf.expand_dims(cls_ids, -1), tf.expand_dims(cls_ids, -2)) - return tf.logical_or(cls_mat, token_type_mat) - - def get_position_embeds(self, seq_len, training=False): - """ - Create and cache inputs related to relative position encoding. Those are very different depending on whether we - are using the factorized or the relative shift attention: - - For the factorized attention, it returns the matrices (phi, pi, psi, omega) used in the paper, appendix A.2.2, - final formula. - - For the relative shift attention, it returns all possible vectors R used in the paper, appendix A.2.1, final - formula. - - Paper link: https://huggingface.co/papers/2006.03236 - """ - if self.attention_type == "factorized": - # Notations from the paper, appending A.2.2, final formula. - # We need to create and return the matrices phi, psi, pi and omega. - pos_seq = tf.range(0, seq_len, 1.0) - freq_seq = tf.range(0, self.d_model // 2, 1.0) - inv_freq = 1 / (10000 ** (freq_seq / (self.d_model // 2))) - sinusoid = tf.einsum("i,d->id", pos_seq, inv_freq) - - sin_embed = tf.sin(sinusoid) - sin_embed_d = self.sin_dropout(sin_embed, training=training) - cos_embed = tf.cos(sinusoid) - cos_embed_d = self.cos_dropout(cos_embed, training=training) - # This is different from the formula on the paper... - phi = tf.concat([sin_embed_d, sin_embed_d], axis=-1) - psi = tf.concat([cos_embed, sin_embed], axis=-1) - pi = tf.concat([cos_embed_d, cos_embed_d], axis=-1) - omega = tf.concat([-sin_embed, cos_embed], axis=-1) - return (phi, pi, psi, omega) - else: - # Notations from the paper, appending A.2.1, final formula. - # We need to create and return all the possible vectors R for all blocks and shifts. - freq_seq = tf.range(0, self.d_model // 2, 1.0) - inv_freq = 1 / (10000 ** (freq_seq / (self.d_model // 2))) - # Maximum relative positions for the first input - rel_pos_id = tf.range(-seq_len * 2, seq_len * 2, 1.0) - zero_offset = seq_len * tf.constant(2) - sinusoid = tf.einsum("i,d->id", rel_pos_id, inv_freq) - sin_embed = self.sin_dropout(tf.sin(sinusoid), training=training) - cos_embed = self.cos_dropout(tf.cos(sinusoid), training=training) - pos_embed = tf.concat([sin_embed, cos_embed], axis=-1) - - pos = tf.range(0, seq_len) - pooled_pos = pos - position_embeds_list = [] - for block_index in range(0, self.num_blocks): - # For each block with block_index > 0, we need two types position embeddings: - # - Attention(pooled-q, unpooled-kv) - # - Attention(pooled-q, pooled-kv) - # For block_index = 0 we only need the second one and leave the first one as None. - - # First type - position_embeds_pooling = tf.fill([1], value=-1.0) - - if block_index != 0: - pooled_pos = self.stride_pool_pos(pos, block_index) - - # construct rel_pos_id - stride = 2 ** (block_index - 1) - rel_pos = self.relative_pos(pos, stride, pooled_pos, shift=2) - # rel_pos = tf.expand_dims(rel_pos,1) + zero_offset - # rel_pos = tf.broadcast_to(rel_pos, (rel_pos.shape[0], self.d_model)) - rel_pos = tf.cast(rel_pos, dtype=zero_offset.dtype) - rel_pos = rel_pos + zero_offset - position_embeds_pooling = tf.gather(pos_embed, rel_pos, axis=0) - - # Second type - pos = pooled_pos - stride = 2**block_index - rel_pos = self.relative_pos(pos, stride) - - # rel_pos = tf.expand_dims(rel_pos,1) + zero_offset - # rel_pos = tf.broadcast_to(rel_pos, (rel_pos.shape[0], self.d_model)) - rel_pos = tf.cast(rel_pos, dtype=zero_offset.dtype) - rel_pos = rel_pos + zero_offset - tf.debugging.assert_less(rel_pos, tf.shape(pos_embed)[0]) - position_embeds_no_pooling = tf.gather(pos_embed, rel_pos, axis=0) - - position_embeds_list.append([position_embeds_no_pooling, position_embeds_pooling]) - return position_embeds_list - - def stride_pool_pos(self, pos_id, block_index): - """ - Pool `pos_id` while keeping the cls token separate (if `self.separate_cls=True`). - """ - if self.separate_cls: - # Under separate , we treat the as the first token in - # the previous block of the 1st real block. Since the 1st real - # block always has position 1, the position of the previous block - # will be at `1 - 2 ** block_index`. - cls_pos = tf.constant([-(2**block_index) + 1], dtype=pos_id.dtype) - pooled_pos_id = pos_id[1:-1] if self.truncate_seq else pos_id[1:] - return tf.concat([cls_pos, pooled_pos_id[::2]], 0) - else: - return pos_id[::2] - - def relative_pos(self, pos, stride, pooled_pos=None, shift=1): - """ - Build the relative positional vector between `pos` and `pooled_pos`. - """ - if pooled_pos is None: - pooled_pos = pos - - ref_point = pooled_pos[0] - pos[0] - num_remove = shift * shape_list(pooled_pos)[0] - max_dist = ref_point + num_remove * stride - min_dist = pooled_pos[0] - pos[-1] - - return tf.range(max_dist, min_dist - 1, -stride) - - def stride_pool(self, tensor, axis): - """ - Perform pooling by stride slicing the tensor along the given axis. - """ - if tensor is None: - return None - - # Do the stride pool recursively if axis is a list or a tuple of ints. - if isinstance(axis, (list, tuple)): - for ax in axis: - tensor = self.stride_pool(tensor, ax) - return tensor - - # Do the stride pool recursively if tensor is a list or tuple of tensors. - if isinstance(tensor, (tuple, list)): - return type(tensor)(self.stride_pool(x, axis) for x in tensor) - - # Deal with negative axis - axis %= len(shape_list(tensor)) - - axis_slice = slice(None, -1, 2) if self.separate_cls and self.truncate_seq else slice(None, None, 2) - enc_slice = [slice(None)] * axis + [axis_slice] - if self.separate_cls: - cls_slice = [slice(None)] * axis + [slice(None, 1)] - tensor = tf.concat([tensor[cls_slice], tensor], axis) - return tensor[enc_slice] - - def pool_tensor(self, tensor, mode="mean", stride=2): - """Apply 1D pooling to a tensor of size [B x T (x H)].""" - if tensor is None: - return None - - # Do the pool recursively if tensor is a list or tuple of tensors. - if isinstance(tensor, (tuple, list)): - return type(tensor)(self.pool_tensor(tensor, mode=mode, stride=stride) for x in tensor) - - if self.separate_cls: - suffix = tensor[:, :-1] if self.truncate_seq else tensor - tensor = tf.concat([tensor[:, :1], suffix], axis=1) - - ndim = len(shape_list(tensor)) - if ndim == 2: - tensor = tensor[:, :, None] - - if mode == "mean": - tensor = tf.nn.avg_pool1d(tensor, stride, strides=stride, data_format="NWC", padding="SAME") - elif mode == "max": - tensor = tf.nn.max_pool1d(tensor, stride, strides=stride, data_format="NWC", padding="SAME") - elif mode == "min": - tensor = -tf.nn.max_pool1d(-tensor, stride, strides=stride, data_format="NWC", padding="SAME") - else: - raise NotImplementedError("The supported modes are 'mean', 'max' and 'min'.") - - return tf.squeeze(tensor, 2) if ndim == 2 else tensor - - def pre_attention_pooling(self, output, attention_inputs): - """Pool `output` and the proper parts of `attention_inputs` before the attention layer.""" - position_embeds, token_type_mat, attention_mask, cls_mask = attention_inputs - if self.pool_q_only: - if self.attention_type == "factorized": - position_embeds = self.stride_pool(position_embeds[:2], 0) + position_embeds[2:] - token_type_mat = self.stride_pool(token_type_mat, 1) - cls_mask = self.stride_pool(cls_mask, 0) - output = self.pool_tensor(output, mode=self.pooling_type) - else: - self.pooling_mult *= 2 - if self.attention_type == "factorized": - position_embeds = self.stride_pool(position_embeds, 0) - token_type_mat = self.stride_pool(token_type_mat, [1, 2]) - cls_mask = self.stride_pool(cls_mask, [1, 2]) - attention_mask = self.pool_tensor(attention_mask, mode="min") - output = self.pool_tensor(output, mode=self.pooling_type) - attention_inputs = (position_embeds, token_type_mat, attention_mask, cls_mask) - return output, attention_inputs - - def post_attention_pooling(self, attention_inputs): - """Pool the proper parts of `attention_inputs` after the attention layer.""" - position_embeds, token_type_mat, attention_mask, cls_mask = attention_inputs - if self.pool_q_only: - self.pooling_mult *= 2 - if self.attention_type == "factorized": - position_embeds = position_embeds[:2] + self.stride_pool(position_embeds[2:], 0) - token_type_mat = self.stride_pool(token_type_mat, 2) - cls_mask = self.stride_pool(cls_mask, 1) - attention_mask = self.pool_tensor(attention_mask, mode="min") - attention_inputs = (position_embeds, token_type_mat, attention_mask, cls_mask) - return attention_inputs - - -def _relative_shift_gather(positional_attn, context_len, shift): - batch_size, n_head, seq_len, max_rel_len = shape_list(positional_attn) - # max_rel_len = 2 * context_len + shift -1 is the numbers of possible relative positions i-j - - # What's next is the same as doing the following gather in PyTorch, which might be clearer code but less efficient. - # idxs = context_len + torch.arange(0, context_len).unsqueeze(0) - torch.arange(0, seq_len).unsqueeze(1) - # # matrix of context_len + i-j - # return positional_attn.gather(3, idxs.expand([batch_size, n_head, context_len, context_len])) - - positional_attn = tf.reshape(positional_attn, [batch_size, n_head, max_rel_len, seq_len]) - positional_attn = positional_attn[:, :, shift:, :] - positional_attn = tf.reshape(positional_attn, [batch_size, n_head, seq_len, max_rel_len - shift]) - positional_attn = positional_attn[..., :context_len] - return positional_attn - - -class TFFunnelRelMultiheadAttention(keras.layers.Layer): - def __init__(self, config, block_index, **kwargs): - super().__init__(**kwargs) - self.attention_type = config.attention_type - self.n_head = n_head = config.n_head - self.d_head = d_head = config.d_head - self.d_model = d_model = config.d_model - self.initializer_range = config.initializer_range - self.block_index = block_index - - self.hidden_dropout = keras.layers.Dropout(config.hidden_dropout) - self.attention_dropout = keras.layers.Dropout(config.attention_dropout) - - initializer = get_initializer(config.initializer_range) - - self.q_head = keras.layers.Dense( - n_head * d_head, use_bias=False, kernel_initializer=initializer, name="q_head" - ) - self.k_head = keras.layers.Dense(n_head * d_head, kernel_initializer=initializer, name="k_head") - self.v_head = keras.layers.Dense(n_head * d_head, kernel_initializer=initializer, name="v_head") - - self.post_proj = keras.layers.Dense(d_model, kernel_initializer=initializer, name="post_proj") - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.scale = 1.0 / (d_head**0.5) - - def build(self, input_shape=None): - n_head, d_head, d_model = self.n_head, self.d_head, self.d_model - initializer = get_initializer(self.initializer_range) - - self.r_w_bias = self.add_weight( - shape=(n_head, d_head), initializer=initializer, trainable=True, name="r_w_bias" - ) - self.r_r_bias = self.add_weight( - shape=(n_head, d_head), initializer=initializer, trainable=True, name="r_r_bias" - ) - self.r_kernel = self.add_weight( - shape=(d_model, n_head, d_head), initializer=initializer, trainable=True, name="r_kernel" - ) - self.r_s_bias = self.add_weight( - shape=(n_head, d_head), initializer=initializer, trainable=True, name="r_s_bias" - ) - self.seg_embed = self.add_weight( - shape=(2, n_head, d_head), initializer=initializer, trainable=True, name="seg_embed" - ) - - if self.built: - return - self.built = True - if getattr(self, "q_head", None) is not None: - with tf.name_scope(self.q_head.name): - self.q_head.build([None, None, d_model]) - if getattr(self, "k_head", None) is not None: - with tf.name_scope(self.k_head.name): - self.k_head.build([None, None, d_model]) - if getattr(self, "v_head", None) is not None: - with tf.name_scope(self.v_head.name): - self.v_head.build([None, None, d_model]) - if getattr(self, "post_proj", None) is not None: - with tf.name_scope(self.post_proj.name): - self.post_proj.build([None, None, n_head * d_head]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, d_model]) - - def relative_positional_attention(self, position_embeds, q_head, context_len, cls_mask=None): - """Relative attention score for the positional encodings""" - # q_head has shape batch_size x sea_len x n_head x d_head - if self.attention_type == "factorized": - # Notations from the paper, appending A.2.2, final formula (https://huggingface.co/papers/2006.03236) - # phi and pi have shape seq_len x d_model, psi and omega have shape context_len x d_model - phi, pi, psi, omega = position_embeds - # Shape n_head x d_head - u = self.r_r_bias * self.scale - # Shape d_model x n_head x d_head - w_r = self.r_kernel - - # Shape batch_size x sea_len x n_head x d_model - q_r_attention = tf.einsum("binh,dnh->bind", q_head + u, w_r) - q_r_attention_1 = q_r_attention * phi[:, None] - q_r_attention_2 = q_r_attention * pi[:, None] - - # Shape batch_size x n_head x seq_len x context_len - positional_attn = tf.einsum("bind,jd->bnij", q_r_attention_1, psi) + tf.einsum( - "bind,jd->bnij", q_r_attention_2, omega - ) - else: - # Notations from the paper, appending A.2.1, final formula (https://huggingface.co/papers/2006.03236) - # Grab the proper positional encoding, shape max_rel_len x d_model - if shape_list(q_head)[1] != context_len: - shift = 2 - r = position_embeds[self.block_index][1] - else: - shift = 1 - r = position_embeds[self.block_index][0] - # Shape n_head x d_head - v = self.r_r_bias * self.scale - # Shape d_model x n_head x d_head - w_r = self.r_kernel - - # Shape max_rel_len x n_head x d_model - r_head = tf.einsum("td,dnh->tnh", r, w_r) - # Shape batch_size x n_head x seq_len x max_rel_len - positional_attn = tf.einsum("binh,tnh->bnit", q_head + v, r_head) - # Shape batch_size x n_head x seq_len x context_len - positional_attn = _relative_shift_gather(positional_attn, context_len, shift) - - if cls_mask is not None: - positional_attn *= cls_mask - return positional_attn - - def relative_token_type_attention(self, token_type_mat, q_head, cls_mask=None): - """Relative attention score for the token_type_ids""" - if token_type_mat is None: - return 0 - batch_size, seq_len, context_len = shape_list(token_type_mat) - # q_head has shape batch_size x seq_len x n_head x d_head - # Shape n_head x d_head - r_s_bias = self.r_s_bias * self.scale - - # Shape batch_size x n_head x seq_len x 2 - token_type_bias = tf.einsum("bind,snd->bnis", q_head + r_s_bias, self.seg_embed) - # Shape batch_size x n_head x seq_len x context_len - token_type_mat = tf.tile(token_type_mat[:, None], [1, shape_list(q_head)[2], 1, 1]) - # token_type_mat = tf.broadcast_to(token_type_mat[:, None], new_shape) - # Shapes batch_size x n_head x seq_len - diff_token_type, same_token_type = tf.split(token_type_bias, 2, axis=-1) - # Shape batch_size x n_head x seq_len x context_len - token_type_attn = tf.where( - token_type_mat, - tf.tile(same_token_type, [1, 1, 1, context_len]), - tf.tile(diff_token_type, [1, 1, 1, context_len]), - ) - - if cls_mask is not None: - token_type_attn *= cls_mask - return token_type_attn - - def call(self, query, key, value, attention_inputs, output_attentions=False, training=False): - # query has shape batch_size x seq_len x d_model - # key and value have shapes batch_size x context_len x d_model - position_embeds, token_type_mat, attention_mask, cls_mask = attention_inputs - - batch_size, seq_len, _ = shape_list(query) - context_len = shape_list(key)[1] - n_head, d_head = self.n_head, self.d_head - - # Shape batch_size x seq_len x n_head x d_head - q_head = tf.reshape(self.q_head(query), [batch_size, seq_len, n_head, d_head]) - # Shapes batch_size x context_len x n_head x d_head - k_head = tf.reshape(self.k_head(key), [batch_size, context_len, n_head, d_head]) - v_head = tf.reshape(self.v_head(value), [batch_size, context_len, n_head, d_head]) - - q_head = q_head * self.scale - # Shape n_head x d_head - r_w_bias = self.r_w_bias * self.scale - # Shapes batch_size x n_head x seq_len x context_len - content_score = tf.einsum("bind,bjnd->bnij", q_head + r_w_bias, k_head) - positional_attn = self.relative_positional_attention(position_embeds, q_head, context_len, cls_mask) - token_type_attn = self.relative_token_type_attention(token_type_mat, q_head, cls_mask) - - # merge attention scores - attn_score = content_score + positional_attn + token_type_attn - - # perform masking - if attention_mask is not None: - attention_mask = tf.cast(attention_mask, dtype=attn_score.dtype) - attn_score = attn_score - (INF * (1 - attention_mask[:, None, None])) - - # attention probability - attn_prob = stable_softmax(attn_score, axis=-1) - attn_prob = self.attention_dropout(attn_prob, training=training) - - # attention output, shape batch_size x seq_len x n_head x d_head - attn_vec = tf.einsum("bnij,bjnd->bind", attn_prob, v_head) - - # Shape shape batch_size x seq_len x d_model - attn_out = self.post_proj(tf.reshape(attn_vec, [batch_size, seq_len, n_head * d_head])) - attn_out = self.hidden_dropout(attn_out, training=training) - - output = self.layer_norm(query + attn_out) - return (output, attn_prob) if output_attentions else (output,) - - -class TFFunnelPositionwiseFFN(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - initializer = get_initializer(config.initializer_range) - self.linear_1 = keras.layers.Dense(config.d_inner, kernel_initializer=initializer, name="linear_1") - self.activation_function = get_tf_activation(config.hidden_act) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - self.linear_2 = keras.layers.Dense(config.d_model, kernel_initializer=initializer, name="linear_2") - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.config = config - - def call(self, hidden, training=False): - h = self.linear_1(hidden) - h = self.activation_function(h) - h = self.activation_dropout(h, training=training) - h = self.linear_2(h) - h = self.dropout(h, training=training) - return self.layer_norm(hidden + h) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "linear_1", None) is not None: - with tf.name_scope(self.linear_1.name): - self.linear_1.build([None, None, self.config.d_model]) - if getattr(self, "linear_2", None) is not None: - with tf.name_scope(self.linear_2.name): - self.linear_2.build([None, None, self.config.d_inner]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - - -class TFFunnelLayer(keras.layers.Layer): - def __init__(self, config, block_index, **kwargs): - super().__init__(**kwargs) - self.attention = TFFunnelRelMultiheadAttention(config, block_index, name="attention") - self.ffn = TFFunnelPositionwiseFFN(config, name="ffn") - - def call(self, query, key, value, attention_inputs, output_attentions=False, training=False): - attn = self.attention( - query, key, value, attention_inputs, output_attentions=output_attentions, training=training - ) - output = self.ffn(attn[0], training=training) - return (output, attn[1]) if output_attentions else (output,) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "ffn", None) is not None: - with tf.name_scope(self.ffn.name): - self.ffn.build(None) - - -class TFFunnelEncoder(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.separate_cls = config.separate_cls - self.pool_q_only = config.pool_q_only - self.block_repeats = config.block_repeats - self.attention_structure = TFFunnelAttentionStructure(config) - self.blocks = [ - [TFFunnelLayer(config, block_index, name=f"blocks_._{block_index}_._{i}") for i in range(block_size)] - for block_index, block_size in enumerate(config.block_sizes) - ] - - def call( - self, - inputs_embeds, - attention_mask=None, - token_type_ids=None, - output_attentions=False, - output_hidden_states=False, - return_dict=True, - training=False, - ): - # The pooling is not implemented on long tensors, so we convert this mask. - # attention_mask = tf.cast(attention_mask, inputs_embeds.dtype) - attention_inputs = self.attention_structure.init_attention_inputs( - inputs_embeds, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - training=training, - ) - hidden = inputs_embeds - - all_hidden_states = (inputs_embeds,) if output_hidden_states else None - all_attentions = () if output_attentions else None - - for block_index, block in enumerate(self.blocks): - pooling_flag = shape_list(hidden)[1] > (2 if self.separate_cls else 1) - pooling_flag = pooling_flag and block_index > 0 - pooled_hidden = tf.zeros(shape_list(hidden)) - - if pooling_flag: - pooled_hidden, attention_inputs = self.attention_structure.pre_attention_pooling( - hidden, attention_inputs - ) - - for layer_index, layer in enumerate(block): - for repeat_index in range(self.block_repeats[block_index]): - do_pooling = (repeat_index == 0) and (layer_index == 0) and pooling_flag - if do_pooling: - query = pooled_hidden - key = value = hidden if self.pool_q_only else pooled_hidden - else: - query = key = value = hidden - layer_output = layer( - query, key, value, attention_inputs, output_attentions=output_attentions, training=training - ) - hidden = layer_output[0] - if do_pooling: - attention_inputs = self.attention_structure.post_attention_pooling(attention_inputs) - - if output_attentions: - all_attentions = all_attentions + layer_output[1:] - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden,) - - if not return_dict: - return tuple(v for v in [hidden, all_hidden_states, all_attentions] if v is not None) - return TFBaseModelOutput(last_hidden_state=hidden, hidden_states=all_hidden_states, attentions=all_attentions) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - for block in self.blocks: - for layer in block: - with tf.name_scope(layer.name): - layer.build(None) - - -def upsample(x, stride, target_len, separate_cls=True, truncate_seq=False): - """ - Upsample tensor `x` to match `target_len` by repeating the tokens `stride` time on the sequence length dimension. - """ - if stride == 1: - return x - if separate_cls: - cls = x[:, :1] - x = x[:, 1:] - output = tf.repeat(x, repeats=stride, axis=1) - if separate_cls: - if truncate_seq: - output = tf.pad(output, [[0, 0], [0, stride - 1], [0, 0]]) - output = output[:, : target_len - 1] - output = tf.concat([cls, output], axis=1) - else: - output = output[:, :target_len] - return output - - -class TFFunnelDecoder(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.separate_cls = config.separate_cls - self.truncate_seq = config.truncate_seq - self.stride = 2 ** (len(config.block_sizes) - 1) - self.attention_structure = TFFunnelAttentionStructure(config) - self.layers = [TFFunnelLayer(config, 0, name=f"layers_._{i}") for i in range(config.num_decoder_layers)] - - def call( - self, - final_hidden, - first_block_hidden, - attention_mask=None, - token_type_ids=None, - output_attentions=False, - output_hidden_states=False, - return_dict=True, - training=False, - ): - upsampled_hidden = upsample( - final_hidden, - stride=self.stride, - target_len=shape_list(first_block_hidden)[1], - separate_cls=self.separate_cls, - truncate_seq=self.truncate_seq, - ) - - hidden = upsampled_hidden + first_block_hidden - all_hidden_states = (hidden,) if output_hidden_states else None - all_attentions = () if output_attentions else None - - attention_inputs = self.attention_structure.init_attention_inputs( - hidden, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - training=training, - ) - - for layer in self.layers: - layer_output = layer( - hidden, hidden, hidden, attention_inputs, output_attentions=output_attentions, training=training - ) - hidden = layer_output[0] - - if output_attentions: - all_attentions = all_attentions + layer_output[1:] - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden,) - - if not return_dict: - return tuple(v for v in [hidden, all_hidden_states, all_attentions] if v is not None) - return TFBaseModelOutput(last_hidden_state=hidden, hidden_states=all_hidden_states, attentions=all_attentions) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFFunnelBaseLayer(keras.layers.Layer): - """Base model without decoder""" - - config_class = FunnelConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - - self.embeddings = TFFunnelEmbeddings(config, name="embeddings") - self.encoder = TFFunnelEncoder(config, name="encoder") - - def get_input_embeddings(self): - return self.embeddings - - def set_input_embeddings(self, value): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - raise NotImplementedError # Not implemented yet in the library fr TF 2.0 models - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - token_type_ids=None, - inputs_embeds=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(input_shape, 1) - - if token_type_ids is None: - token_type_ids = tf.fill(input_shape, 0) - - if inputs_embeds is None: - inputs_embeds = self.embeddings(input_ids, training=training) - - encoder_outputs = self.encoder( - inputs_embeds, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return encoder_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - - -@keras_serializable -class TFFunnelMainLayer(keras.layers.Layer): - """Base model with decoder""" - - config_class = FunnelConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.block_sizes = config.block_sizes - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - - self.embeddings = TFFunnelEmbeddings(config, name="embeddings") - self.encoder = TFFunnelEncoder(config, name="encoder") - self.decoder = TFFunnelDecoder(config, name="decoder") - - def get_input_embeddings(self): - return self.embeddings - - def set_input_embeddings(self, value): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - raise NotImplementedError # Not implemented yet in the library fr TF 2.0 models - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - token_type_ids=None, - inputs_embeds=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(input_shape, 1) - - if token_type_ids is None: - token_type_ids = tf.fill(input_shape, 0) - - if inputs_embeds is None: - inputs_embeds = self.embeddings(input_ids, training=training) - - encoder_outputs = self.encoder( - inputs_embeds, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - output_attentions=output_attentions, - output_hidden_states=True, - return_dict=return_dict, - training=training, - ) - - decoder_outputs = self.decoder( - final_hidden=encoder_outputs[0], - first_block_hidden=encoder_outputs[1][self.block_sizes[0]], - attention_mask=attention_mask, - token_type_ids=token_type_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - idx = 0 - outputs = (decoder_outputs[0],) - if output_hidden_states: - idx += 1 - outputs = outputs + (encoder_outputs[1] + decoder_outputs[idx],) - if output_attentions: - idx += 1 - outputs = outputs + (encoder_outputs[2] + decoder_outputs[idx],) - return outputs - - return TFBaseModelOutput( - last_hidden_state=decoder_outputs[0], - hidden_states=(encoder_outputs.hidden_states + decoder_outputs.hidden_states) - if output_hidden_states - else None, - attentions=(encoder_outputs.attentions + decoder_outputs.attentions) if output_attentions else None, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -class TFFunnelDiscriminatorPredictions(keras.layers.Layer): - """Prediction module for the discriminator, made up of two dense layers.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - initializer = get_initializer(config.initializer_range) - self.dense = keras.layers.Dense(config.d_model, kernel_initializer=initializer, name="dense") - self.activation_function = get_tf_activation(config.hidden_act) - self.dense_prediction = keras.layers.Dense(1, kernel_initializer=initializer, name="dense_prediction") - self.config = config - - def call(self, discriminator_hidden_states): - hidden_states = self.dense(discriminator_hidden_states) - hidden_states = self.activation_function(hidden_states) - logits = tf.squeeze(self.dense_prediction(hidden_states)) - return logits - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.d_model]) - if getattr(self, "dense_prediction", None) is not None: - with tf.name_scope(self.dense_prediction.name): - self.dense_prediction.build([None, None, self.config.d_model]) - - -class TFFunnelMaskedLMHead(keras.layers.Layer): - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - self.config = config - self.hidden_size = config.hidden_size - self.input_embeddings = input_embeddings - - def build(self, input_shape): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - super().build(input_shape) - - def get_output_embeddings(self): - return self.input_embeddings - - def set_output_embeddings(self, value): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states, training=False): - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -class TFFunnelClassificationHead(keras.layers.Layer): - def __init__(self, config, n_labels, **kwargs): - super().__init__(**kwargs) - initializer = get_initializer(config.initializer_range) - self.linear_hidden = keras.layers.Dense(config.d_model, kernel_initializer=initializer, name="linear_hidden") - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.linear_out = keras.layers.Dense(n_labels, kernel_initializer=initializer, name="linear_out") - self.config = config - - def call(self, hidden, training=False): - hidden = self.linear_hidden(hidden) - hidden = keras.activations.tanh(hidden) - hidden = self.dropout(hidden, training=training) - return self.linear_out(hidden) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "linear_hidden", None) is not None: - with tf.name_scope(self.linear_hidden.name): - self.linear_hidden.build([None, None, self.config.d_model]) - if getattr(self, "linear_out", None) is not None: - with tf.name_scope(self.linear_out.name): - self.linear_out.build([None, None, self.config.d_model]) - - -class TFFunnelPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = FunnelConfig - base_model_prefix = "funnel" - - @property - def dummy_inputs(self): - # Funnel misbehaves with very small inputs, so we override and make them a bit bigger - return {"input_ids": tf.ones((1, 3), dtype=tf.int32)} - - -@dataclass -class TFFunnelForPreTrainingOutput(ModelOutput): - """ - Output type of [`FunnelForPreTraining`]. - - Args: - logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Prediction scores of the head (scores for each token before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -FUNNEL_START_DOCSTRING = r""" - - The Funnel Transformer model was proposed in [Funnel-Transformer: Filtering out Sequential Redundancy for Efficient - Language Processing](https://huggingface.co/papers/2006.03236) by Zihang Dai, Guokun Lai, Yiming Yang, Quoc V. Le. - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`XxxConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -FUNNEL_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - """ - The base Funnel Transformer Model transformer outputting raw hidden-states without upsampling head (also called - decoder) or any task-specific head on top. - """, - FUNNEL_START_DOCSTRING, -) -class TFFunnelBaseModel(TFFunnelPreTrainedModel): - def __init__(self, config: FunnelConfig, *inputs, **kwargs) -> None: - super().__init__(config, *inputs, **kwargs) - self.funnel = TFFunnelBaseLayer(config, name="funnel") - - @add_start_docstrings_to_model_forward(FUNNEL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="funnel-transformer/small-base", - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFBaseModelOutput: - return self.funnel( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - def serving_output(self, output): - # hidden_states and attentions not converted to Tensor with tf.convert_to_tensor as they are all of - # different dimensions - return TFBaseModelOutput( - last_hidden_state=output.last_hidden_state, - hidden_states=output.hidden_states, - attentions=output.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "funnel", None) is not None: - with tf.name_scope(self.funnel.name): - self.funnel.build(None) - - -@add_start_docstrings( - "The bare Funnel Transformer Model transformer outputting raw hidden-states without any specific head on top.", - FUNNEL_START_DOCSTRING, -) -class TFFunnelModel(TFFunnelPreTrainedModel): - def __init__(self, config: FunnelConfig, *inputs, **kwargs) -> None: - super().__init__(config, *inputs, **kwargs) - self.funnel = TFFunnelMainLayer(config, name="funnel") - - @unpack_inputs - @add_start_docstrings_to_model_forward(FUNNEL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="funnel-transformer/small", - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFBaseModelOutput: - return self.funnel( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - def serving_output(self, output): - # hidden_states and attentions not converted to Tensor with tf.convert_to_tensor as they are all of - # different dimensions - return TFBaseModelOutput( - last_hidden_state=output.last_hidden_state, - hidden_states=output.hidden_states, - attentions=output.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "funnel", None) is not None: - with tf.name_scope(self.funnel.name): - self.funnel.build(None) - - -@add_start_docstrings( - """ - Funnel model with a binary classification head on top as used during pretraining for identifying generated tokens. - """, - FUNNEL_START_DOCSTRING, -) -class TFFunnelForPreTraining(TFFunnelPreTrainedModel): - def __init__(self, config: FunnelConfig, **kwargs) -> None: - super().__init__(config, **kwargs) - - self.funnel = TFFunnelMainLayer(config, name="funnel") - self.discriminator_predictions = TFFunnelDiscriminatorPredictions(config, name="discriminator_predictions") - - @unpack_inputs - @add_start_docstrings_to_model_forward(FUNNEL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFFunnelForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ) -> tuple[tf.Tensor] | TFFunnelForPreTrainingOutput: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFFunnelForPreTraining - >>> import torch - from ...utils.deprecation import deprecate_kwarg - from ...utils.deprecation import deprecate_kwarg - from ...utils.deprecation import deprecate_kwarg - from ...utils.deprecation import deprecate_kwarg - - >>> tokenizer = AutoTokenizer.from_pretrained("funnel-transformer/small") - >>> model = TFFunnelForPreTraining.from_pretrained("funnel-transformer/small") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="tf") - >>> logits = model(inputs).logits - ```""" - discriminator_hidden_states = self.funnel( - input_ids, - attention_mask, - token_type_ids, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - discriminator_sequence_output = discriminator_hidden_states[0] - logits = self.discriminator_predictions(discriminator_sequence_output) - - if not return_dict: - return (logits,) + discriminator_hidden_states[1:] - - return TFFunnelForPreTrainingOutput( - logits=logits, - hidden_states=discriminator_hidden_states.hidden_states, - attentions=discriminator_hidden_states.attentions, - ) - - def serving_output(self, output): - # hidden_states and attentions not converted to Tensor with tf.convert_to_tensor as they are all of - # different dimensions - return TFFunnelForPreTrainingOutput( - logits=output.logits, hidden_states=output.hidden_states, attentions=output.attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "funnel", None) is not None: - with tf.name_scope(self.funnel.name): - self.funnel.build(None) - if getattr(self, "discriminator_predictions", None) is not None: - with tf.name_scope(self.discriminator_predictions.name): - self.discriminator_predictions.build(None) - - -@add_start_docstrings("""Funnel Model with a `language modeling` head on top.""", FUNNEL_START_DOCSTRING) -class TFFunnelForMaskedLM(TFFunnelPreTrainedModel, TFMaskedLanguageModelingLoss): - def __init__(self, config: FunnelConfig, *inputs, **kwargs) -> None: - super().__init__(config, *inputs, **kwargs) - - self.funnel = TFFunnelMainLayer(config, name="funnel") - self.lm_head = TFFunnelMaskedLMHead(config, self.funnel.embeddings, name="lm_head") - - def get_lm_head(self) -> TFFunnelMaskedLMHead: - return self.lm_head - - def get_prefix_bias_name(self) -> str: - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(FUNNEL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="funnel-transformer/small", - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFMaskedLMOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.funnel( - input_ids, - attention_mask, - token_type_ids, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.lm_head(sequence_output, training=training) - - loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def serving_output(self, output: TFMaskedLMOutput) -> TFMaskedLMOutput: - # hidden_states and attentions not converted to Tensor with tf.convert_to_tensor as they are all of - # different dimensions - return TFMaskedLMOutput(logits=output.logits, hidden_states=output.hidden_states, attentions=output.attentions) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "funnel", None) is not None: - with tf.name_scope(self.funnel.name): - self.funnel.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -@add_start_docstrings( - """ - Funnel Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled - output) e.g. for GLUE tasks. - """, - FUNNEL_START_DOCSTRING, -) -class TFFunnelForSequenceClassification(TFFunnelPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: FunnelConfig, *inputs, **kwargs) -> None: - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.funnel = TFFunnelBaseLayer(config, name="funnel") - self.classifier = TFFunnelClassificationHead(config, config.num_labels, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(FUNNEL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="funnel-transformer/small-base", - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFSequenceClassifierOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.funnel( - input_ids, - attention_mask, - token_type_ids, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - last_hidden_state = outputs[0] - pooled_output = last_hidden_state[:, 0] - logits = self.classifier(pooled_output, training=training) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def serving_output(self, output: TFSequenceClassifierOutput) -> TFSequenceClassifierOutput: - # hidden_states and attentions not converted to Tensor with tf.convert_to_tensor as they are all of - # different dimensions - return TFSequenceClassifierOutput( - logits=output.logits, hidden_states=output.hidden_states, attentions=output.attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "funnel", None) is not None: - with tf.name_scope(self.funnel.name): - self.funnel.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - Funnel Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - FUNNEL_START_DOCSTRING, -) -class TFFunnelForMultipleChoice(TFFunnelPreTrainedModel, TFMultipleChoiceLoss): - def __init__(self, config: FunnelConfig, *inputs, **kwargs) -> None: - super().__init__(config, *inputs, **kwargs) - - self.funnel = TFFunnelBaseLayer(config, name="funnel") - self.classifier = TFFunnelClassificationHead(config, 1, name="classifier") - - @property - def dummy_inputs(self): - return {"input_ids": tf.ones((3, 3, 4), dtype=tf.int32)} - - @unpack_inputs - @add_start_docstrings_to_model_forward(FUNNEL_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @add_code_sample_docstrings( - checkpoint="funnel-transformer/small-base", - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFMultipleChoiceModelOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_inputs_embeds = ( - tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - - outputs = self.funnel( - flat_input_ids, - attention_mask=flat_attention_mask, - token_type_ids=flat_token_type_ids, - inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - last_hidden_state = outputs[0] - pooled_output = last_hidden_state[:, 0] - logits = self.classifier(pooled_output, training=training) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def serving_output(self, output: TFMultipleChoiceModelOutput) -> TFMultipleChoiceModelOutput: - # hidden_states and attentions not converted to Tensor with tf.convert_to_tensor as they are all of - # different dimensions - return TFMultipleChoiceModelOutput( - logits=output.logits, hidden_states=output.hidden_states, attentions=output.attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "funnel", None) is not None: - with tf.name_scope(self.funnel.name): - self.funnel.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - Funnel Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - FUNNEL_START_DOCSTRING, -) -class TFFunnelForTokenClassification(TFFunnelPreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config: FunnelConfig, *inputs, **kwargs) -> None: - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.funnel = TFFunnelMainLayer(config, name="funnel") - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(FUNNEL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="funnel-transformer/small", - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFTokenClassifierOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.funnel( - input_ids, - attention_mask, - token_type_ids, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def serving_output(self, output: TFTokenClassifierOutput) -> TFTokenClassifierOutput: - # hidden_states and attentions not converted to Tensor with tf.convert_to_tensor as they are all of - # different dimensions - return TFTokenClassifierOutput( - logits=output.logits, hidden_states=output.hidden_states, attentions=output.attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "funnel", None) is not None: - with tf.name_scope(self.funnel.name): - self.funnel.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Funnel Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - FUNNEL_START_DOCSTRING, -) -class TFFunnelForQuestionAnswering(TFFunnelPreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config: FunnelConfig, *inputs, **kwargs) -> None: - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.funnel = TFFunnelMainLayer(config, name="funnel") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(FUNNEL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="funnel-transformer/small", - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFQuestionAnsweringModelOutput: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - - outputs = self.funnel( - input_ids, - attention_mask, - token_type_ids, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions, "end_position": end_positions} - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def serving_output(self, output: TFQuestionAnsweringModelOutput) -> TFQuestionAnsweringModelOutput: - # hidden_states and attentions not converted to Tensor with tf.convert_to_tensor as they are all of - # different dimensions - return TFQuestionAnsweringModelOutput( - start_logits=output.start_logits, - end_logits=output.end_logits, - hidden_states=output.hidden_states, - attentions=output.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "funnel", None) is not None: - with tf.name_scope(self.funnel.name): - self.funnel.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFFunnelBaseModel", - "TFFunnelForMaskedLM", - "TFFunnelForMultipleChoice", - "TFFunnelForPreTraining", - "TFFunnelForQuestionAnswering", - "TFFunnelForSequenceClassification", - "TFFunnelForTokenClassification", - "TFFunnelModel", - "TFFunnelPreTrainedModel", -] diff --git a/src/transformers/models/fuyu/image_processing_fuyu.py b/src/transformers/models/fuyu/image_processing_fuyu.py index e52d9dc8ee91..a1aa184a3b3c 100644 --- a/src/transformers/models/fuyu/image_processing_fuyu.py +++ b/src/transformers/models/fuyu/image_processing_fuyu.py @@ -414,10 +414,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format of the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. diff --git a/src/transformers/models/gemma/__init__.py b/src/transformers/models/gemma/__init__.py index 65fb1ca5edef..80c8d30760c4 100644 --- a/src/transformers/models/gemma/__init__.py +++ b/src/transformers/models/gemma/__init__.py @@ -19,7 +19,6 @@ if TYPE_CHECKING: from .configuration_gemma import * - from .modeling_flax_gemma import * from .modeling_gemma import * from .tokenization_gemma import * from .tokenization_gemma_fast import * diff --git a/src/transformers/models/gemma/configuration_gemma.py b/src/transformers/models/gemma/configuration_gemma.py index 363af5c3ffc4..58d6c3d08537 100644 --- a/src/transformers/models/gemma/configuration_gemma.py +++ b/src/transformers/models/gemma/configuration_gemma.py @@ -54,9 +54,6 @@ class GemmaConfig(PretrainedConfig): The attention head dimension. hidden_act (`str` or `function`, *optional*, defaults to `"gelu_pytorch_tanh"`): The legacy activation function. It is overwritten by the `hidden_activation`. - hidden_activation (`str` or `function`, *optional*): - The non-linear activation function (function or string) in the decoder. Will default to `"gelu_pytorch_tanh"` - if not specified. `"gelu_pytorch_tanh"` uses an approximation of the `"gelu"` activation function. max_position_embeddings (`int`, *optional*, defaults to 8192): The maximum sequence length that this model might ever be used with. initializer_range (`float`, *optional*, defaults to 0.02): @@ -117,7 +114,6 @@ def __init__( num_key_value_heads=16, head_dim=256, hidden_act="gelu_pytorch_tanh", - hidden_activation=None, max_position_embeddings=8192, initializer_range=0.02, rms_norm_eps=1e-6, @@ -140,7 +136,6 @@ def __init__( self.head_dim = head_dim self.num_key_value_heads = num_key_value_heads self.hidden_act = hidden_act - self.hidden_activation = hidden_activation self.initializer_range = initializer_range self.rms_norm_eps = rms_norm_eps self.use_cache = use_cache diff --git a/src/transformers/models/gemma/modeling_flax_gemma.py b/src/transformers/models/gemma/modeling_flax_gemma.py deleted file mode 100644 index 0addcd7dde7a..000000000000 --- a/src/transformers/models/gemma/modeling_flax_gemma.py +++ /dev/null @@ -1,777 +0,0 @@ -# coding=utf-8 -# Copyright 2024 Google Inc., and the HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax Gemma model.""" - -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxCausalLMOutput -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_gemma import GemmaConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "GemmaConfig" -_CHECKPOINT_FOR_DOC = "google/gemma-2b" -_REAL_CHECKPOINT_FOR_DOC = "openlm-research/open_llama_3b_v2" - -GEMMA_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`GemmaConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16`, or - `jax.numpy.bfloat16`. - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -GEMMA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - If you want to change padding behavior, you should read [`modeling_opt._prepare_decoder_attention_mask`] - and modify to your needs. See diagram 1 in [the paper](https://huggingface.co/papers/1910.13461) for more - information on the default strategy. - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - position_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.n_positions - 1]`. - - [What are position IDs?](../glossary#position-ids) - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def create_sinusoidal_positions(num_pos, dim): - inv_freq = 1.0 / (10000 ** (np.arange(0, dim, 2)[: (dim // 2)] / dim)) - freqs = np.einsum("i , j -> i j", np.arange(num_pos), inv_freq).astype("float32") - - emb = np.concatenate((freqs, freqs), axis=-1) - out = np.concatenate((np.sin(emb)[:, None, :], np.cos(emb)[:, None, :]), axis=-1) - return jnp.array(out[:, :, :num_pos]) - - -# Copied from transformers.models.llama.modeling_flax_llama.rotate_half -def rotate_half(tensor): - """Rotates half the hidden dims of the input.""" - rotate_half_tensor = jnp.concatenate( - (-tensor[..., tensor.shape[-1] // 2 :], tensor[..., : tensor.shape[-1] // 2]), axis=-1 - ) - return rotate_half_tensor - - -# Copied from transformers.models.llama.modeling_flax_llama.apply_rotary_pos_emb -def apply_rotary_pos_emb(tensor, sin_pos, cos_pos): - return (tensor * cos_pos) + (rotate_half(tensor) * sin_pos) - - -class FlaxGemmaRMSNorm(nn.Module): - config: GemmaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.epsilon = self.config.rms_norm_eps - self.weight = self.param("weight", lambda _, shape: jnp.ones(shape), self.config.hidden_size) - - def __call__(self, hidden_states): - variance = jnp.asarray(hidden_states, dtype=jnp.float32) - variance = jnp.power(variance, 2) - variance = variance.mean(-1, keepdims=True) - # use `jax.numpy.sqrt` as `jax.lax.rsqrt` does not match `torch.rsqrt` - hidden_states = hidden_states / jnp.sqrt(variance + self.epsilon) - - return (1 + self.weight) * jnp.asarray(hidden_states, dtype=self.dtype) - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaRotaryEmbedding with Llama->Gemma -class FlaxGemmaRotaryEmbedding(nn.Module): - config: GemmaConfig - dtype: jnp.dtype = jnp.float32 - - # Ignore copy - def setup(self): - head_dim = self.config.head_dim - self.sincos = create_sinusoidal_positions(self.config.max_position_embeddings, head_dim) - - def __call__(self, key, query, position_ids): - sincos = self.sincos[position_ids] - sin_pos, cos_pos = jnp.split(sincos, 2, axis=-1) - - key = apply_rotary_pos_emb(key, sin_pos, cos_pos) - query = apply_rotary_pos_emb(query, sin_pos, cos_pos) - - key = jnp.asarray(key, dtype=self.dtype) - query = jnp.asarray(query, dtype=self.dtype) - - return key, query - - -class FlaxGemmaAttention(nn.Module): - config: GemmaConfig - dtype: jnp.dtype = jnp.float32 - causal: bool = True - is_cross_attention: bool = False - - def setup(self): - config = self.config - self.embed_dim = config.hidden_size - self.num_heads = config.num_attention_heads - self.head_dim = config.head_dim - self.attention_softmax_in_fp32 = self.dtype is not jnp.float32 - - self.num_key_value_heads = config.num_key_value_heads - self.num_key_value_groups = self.num_heads // self.num_key_value_heads - - kernel = jax.nn.initializers.normal(self.config.initializer_range) - self.q_proj = nn.Dense( - self.num_heads * self.head_dim, use_bias=config.attention_bias, dtype=self.dtype, kernel_init=kernel - ) - self.k_proj = nn.Dense( - self.num_key_value_heads * self.head_dim, - use_bias=config.attention_bias, - dtype=self.dtype, - kernel_init=kernel, - ) - self.v_proj = nn.Dense( - self.num_key_value_heads * self.head_dim, - use_bias=config.attention_bias, - dtype=self.dtype, - kernel_init=kernel, - ) - self.o_proj = nn.Dense(self.embed_dim, use_bias=config.attention_bias, dtype=self.dtype, kernel_init=kernel) - - self.causal_mask = make_causal_mask(jnp.ones((1, config.max_position_embeddings), dtype="bool"), dtype="bool") - self.rotary_emb = FlaxGemmaRotaryEmbedding(config, dtype=self.dtype) - - def _split_heads(self, hidden_states, num_heads): - return hidden_states.reshape(hidden_states.shape[:2] + (num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads * self.head_dim,)) - - @nn.compact - # Copied from transformers.models.gpt_neo.modeling_flax_gpt_neo.FlaxGPTNeoSelfAttention._concatenate_to_cache - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - attention_mask, - position_ids, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - query = self.q_proj(hidden_states) - key = self.k_proj(hidden_states) - value = self.v_proj(hidden_states) - - query = self._split_heads(query, self.num_heads) - key = self._split_heads(key, self.num_key_value_heads) - value = self._split_heads(value, self.num_key_value_heads) - - key, query = self.rotary_emb(key, query, position_ids) - - query_length, key_length = query.shape[1], key.shape[1] - - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - - batch_size = hidden_states.shape[0] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - - dropout_rng = None - if not deterministic and self.config.attention_dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.has_variable("cache", "cached_key") or init_cache: - key, value, attention_mask = self._concatenate_to_cache(key, value, query, attention_mask) - - # transform boolean mask into float mask - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - - key = jnp.repeat(key, repeats=self.num_key_value_groups, axis=2) - value = jnp.repeat(value, repeats=self.num_key_value_groups, axis=2) - - # usual dot product attention - attention_dtype = jnp.float32 if self.attention_softmax_in_fp32 else self.dtype - attn_weights = dot_product_attention_weights( - query, - key, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_dropout, - deterministic=deterministic, - dtype=attention_dtype, - ) - - if self.attention_softmax_in_fp32: - attn_weights = attn_weights.astype(self.dtype) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value) - attn_output = self._merge_heads(attn_output) - attn_output = self.o_proj(attn_output) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxGemmaMLP(nn.Module): - config: GemmaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - embed_dim = self.config.hidden_size - inner_dim = self.config.intermediate_size if self.config.intermediate_size is not None else 4 * embed_dim - - kernel_init = jax.nn.initializers.normal(self.config.initializer_range) - if self.config.hidden_activation is None: - logger.warning_once( - "Gemma's activation function should be approximate GeLU and not exact GeLU. " - "Changing the activation function to `gelu_pytorch_tanh`." - f"if you want to use the legacy `{self.config.hidden_act}`, " - f"edit the `model.config` to set `hidden_activation={self.config.hidden_act}` " - " instead of `hidden_act`. See https://github.com/huggingface/transformers/pull/29402 for more details." - ) - hidden_activation = "gelu_pytorch_tanh" - else: - hidden_activation = self.config.hidden_activation - self.act = ACT2FN[hidden_activation] - - self.gate_proj = nn.Dense(inner_dim, use_bias=False, dtype=self.dtype, kernel_init=kernel_init) - self.down_proj = nn.Dense(embed_dim, use_bias=False, dtype=self.dtype, kernel_init=kernel_init) - self.up_proj = nn.Dense(inner_dim, use_bias=False, dtype=self.dtype, kernel_init=kernel_init) - - def __call__(self, hidden_states): - up_proj_states = self.up_proj(hidden_states) - gate_states = self.act(self.gate_proj(hidden_states)) - - hidden_states = self.down_proj(up_proj_states * gate_states) - return hidden_states - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaDecoderLayer with Llama->Gemma -class FlaxGemmaDecoderLayer(nn.Module): - config: GemmaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.input_layernorm = FlaxGemmaRMSNorm(self.config, dtype=self.dtype) - self.self_attn = FlaxGemmaAttention(self.config, dtype=self.dtype) - self.post_attention_layernorm = FlaxGemmaRMSNorm(self.config, dtype=self.dtype) - self.mlp = FlaxGemmaMLP(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - residual = hidden_states - hidden_states = self.input_layernorm(hidden_states) - outputs = self.self_attn( - hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - # residual connection - attn_output = outputs[0] - hidden_states = residual + attn_output - - residual = hidden_states - hidden_states = self.post_attention_layernorm(hidden_states) - hidden_states = self.mlp(hidden_states) - # residual connection - hidden_states = residual + hidden_states - - return (hidden_states,) + outputs[1:] - - -# Copied from transformers.models.gpt_neo.modeling_flax_gpt_neo.FlaxGPTNeoPreTrainedModel with GPTNeo->Gemma, GPT_NEO->GEMMA, transformer->model -class FlaxGemmaPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = GemmaConfig - base_model_prefix = "model" - module_class: nn.Module = None - - def __init__( - self, - config: GemmaConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, input_ids, attention_mask, position_ids, return_dict=False)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length)) - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(GEMMA_INPUTS_DOCSTRING) - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - params: Optional[dict] = None, - past_key_values: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - batch_size, sequence_length = input_ids.shape - - if position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `position_ids` when passing `past_key_values`.") - - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - if attention_mask is None: - attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be changed by FlaxGemmaAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - not train, - False, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - return outputs - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaLayerCollection with Llama->Gemma -class FlaxGemmaLayerCollection(nn.Module): - config: GemmaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.blocks = [ - FlaxGemmaDecoderLayer(self.config, dtype=self.dtype, name=str(i)) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = False, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for block in self.blocks: - if output_hidden_states: - all_hidden_states += (hidden_states,) - layer_outputs = block( - hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - # this contains possible `None` values - `FlaxGemmaModule` will filter them out - outputs = (hidden_states, all_hidden_states, all_attentions) - - return outputs - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaModule with Llama->Gemma -class FlaxGemmaModule(nn.Module): - config: GemmaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.hidden_size = self.config.hidden_size - embedding_init = jax.nn.initializers.normal(stddev=self.config.initializer_range) - self.embed_tokens = nn.Embed( - self.config.vocab_size, - self.hidden_size, - embedding_init=embedding_init, - dtype=self.dtype, - ) - self.layers = FlaxGemmaLayerCollection(self.config, dtype=self.dtype) - self.norm = FlaxGemmaRMSNorm(self.config, dtype=self.dtype) - - # Ignore copy - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - deterministic=True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - input_embeds = self.embed_tokens(input_ids.astype("i4")) - - input_embeds = input_embeds * (self.config.hidden_size**0.5) - - outputs = self.layers( - input_embeds, - position_ids=position_ids, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.norm(hidden_states) - - if output_hidden_states: - all_hidden_states = outputs[1] + (hidden_states,) - outputs = (hidden_states, all_hidden_states) + outputs[2:] - else: - outputs = (hidden_states,) + outputs[1:] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=outputs[1], - attentions=outputs[-1], - ) - - -@add_start_docstrings( - "The bare Gemma Model transformer outputting raw hidden-states without any specific head on top.", - GEMMA_START_DOCSTRING, -) -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaModel with Llama->Gemma -class FlaxGemmaModel(FlaxGemmaPreTrainedModel): - module_class = FlaxGemmaModule - - -append_call_sample_docstring( - FlaxGemmaModel, - _CHECKPOINT_FOR_DOC, - FlaxBaseModelOutput, - _CONFIG_FOR_DOC, - real_checkpoint=_REAL_CHECKPOINT_FOR_DOC, -) - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaForCausalLMModule with Llama->Gemma -class FlaxGemmaForCausalLMModule(nn.Module): - config: GemmaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.model = FlaxGemmaModule(self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - - # Ignore copy - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - outputs = self.model( - input_ids, - position_ids=position_ids, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_kernel = self.model.variables["params"]["embed_tokens"]["embedding"].T - lm_logits = self.lm_head.apply({"params": {"kernel": shared_kernel}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - return (lm_logits,) + outputs[1:] - - return FlaxCausalLMOutput(logits=lm_logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions) - - -@add_start_docstrings( - """ - The Gemma Model transformer with a language modeling head (linear layer) on top. - """, - GEMMA_START_DOCSTRING, -) -# Copied from transformers.models.gptj.modeling_flax_gptj.FlaxGPTJForCausalLM with GPTJ->Gemma -class FlaxGemmaForCausalLM(FlaxGemmaPreTrainedModel): - module_class = FlaxGemmaForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since Gemma uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxGemmaForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutput, - _CONFIG_FOR_DOC, - real_checkpoint=_REAL_CHECKPOINT_FOR_DOC, -) - - -__all__ = ["FlaxGemmaForCausalLM", "FlaxGemmaModel", "FlaxGemmaPreTrainedModel"] diff --git a/src/transformers/models/gemma/modular_gemma.py b/src/transformers/models/gemma/modular_gemma.py index 281fcd54fb7d..00dfb9edbcf7 100644 --- a/src/transformers/models/gemma/modular_gemma.py +++ b/src/transformers/models/gemma/modular_gemma.py @@ -79,9 +79,6 @@ class GemmaConfig(PretrainedConfig): The attention head dimension. hidden_act (`str` or `function`, *optional*, defaults to `"gelu_pytorch_tanh"`): The legacy activation function. It is overwritten by the `hidden_activation`. - hidden_activation (`str` or `function`, *optional*): - The non-linear activation function (function or string) in the decoder. Will default to `"gelu_pytorch_tanh"` - if not specified. `"gelu_pytorch_tanh"` uses an approximation of the `"gelu"` activation function. max_position_embeddings (`int`, *optional*, defaults to 8192): The maximum sequence length that this model might ever be used with. initializer_range (`float`, *optional*, defaults to 0.02): @@ -142,7 +139,6 @@ def __init__( num_key_value_heads=16, head_dim=256, hidden_act="gelu_pytorch_tanh", - hidden_activation=None, max_position_embeddings=8192, initializer_range=0.02, rms_norm_eps=1e-6, @@ -165,7 +161,6 @@ def __init__( self.head_dim = head_dim self.num_key_value_heads = num_key_value_heads self.hidden_act = hidden_act - self.hidden_activation = hidden_activation self.initializer_range = initializer_range self.rms_norm_eps = rms_norm_eps self.use_cache = use_cache diff --git a/src/transformers/models/gemma3/image_processing_gemma3.py b/src/transformers/models/gemma3/image_processing_gemma3.py index 8addbbfd378c..efa65a6d2bf2 100644 --- a/src/transformers/models/gemma3/image_processing_gemma3.py +++ b/src/transformers/models/gemma3/image_processing_gemma3.py @@ -285,10 +285,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -338,10 +336,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/gemma3n/feature_extraction_gemma3n.py b/src/transformers/models/gemma3n/feature_extraction_gemma3n.py index 62e3fb3878f7..7dcc4e2c5ca8 100644 --- a/src/transformers/models/gemma3n/feature_extraction_gemma3n.py +++ b/src/transformers/models/gemma3n/feature_extraction_gemma3n.py @@ -296,7 +296,7 @@ def __call__( pad_to_multiple_of (`int`, *optional*, defaults to 128): When padding, pad to a multiple of this value. The default value is defined for optimal TPU support. return_tensors (`Union[str, TensorType]`, *optional*, defaults to `None`): - The type of tensors to return (e.g., NumPy, Torch, JAX, TensorFlow). + The type of tensors to return (e.g., NumPy, or Torch). return_attention_mask (`bool`, *optional*, defaults to `True`): Whether to return the attention mask for the generated MEL spectrograms. """ diff --git a/src/transformers/models/git/modeling_git.py b/src/transformers/models/git/modeling_git.py index 4122b7a0df79..b98d2b1c231c 100644 --- a/src/transformers/models/git/modeling_git.py +++ b/src/transformers/models/git/modeling_git.py @@ -76,8 +76,6 @@ def __init__(self, config): self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -463,8 +461,6 @@ def _init_weights(self, module): nn.init.normal_(module.patch_embedding.weight, std=self.config.initializer_range) nn.init.normal_(module.position_embedding.weight, std=self.config.initializer_range) if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/glm4v/image_processing_glm4v.py b/src/transformers/models/glm4v/image_processing_glm4v.py index 8293545deee2..e35699005116 100644 --- a/src/transformers/models/glm4v/image_processing_glm4v.py +++ b/src/transformers/models/glm4v/image_processing_glm4v.py @@ -352,10 +352,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -393,10 +391,7 @@ def preprocess( images = make_flat_list_of_images(images) if images is not None and not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( rescale_factor=rescale_factor, diff --git a/src/transformers/models/glm4v/modular_glm4v.py b/src/transformers/models/glm4v/modular_glm4v.py index 7c400edc51c3..526abd1138b1 100644 --- a/src/transformers/models/glm4v/modular_glm4v.py +++ b/src/transformers/models/glm4v/modular_glm4v.py @@ -1562,10 +1562,8 @@ def __call__( tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/glm4v/processing_glm4v.py b/src/transformers/models/glm4v/processing_glm4v.py index 817da3630d52..511869bbcafd 100644 --- a/src/transformers/models/glm4v/processing_glm4v.py +++ b/src/transformers/models/glm4v/processing_glm4v.py @@ -117,10 +117,8 @@ def __call__( tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/glpn/image_processing_glpn.py b/src/transformers/models/glpn/image_processing_glpn.py index e3e0255e2b47..35306eabc8d5 100644 --- a/src/transformers/models/glpn/image_processing_glpn.py +++ b/src/transformers/models/glpn/image_processing_glpn.py @@ -166,10 +166,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - `None`: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -189,10 +187,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # Here, the rescale() method uses a constant rescale_factor. It does not need to be validated # with a rescale_factor. diff --git a/src/transformers/models/glpn/modeling_glpn.py b/src/transformers/models/glpn/modeling_glpn.py index e326750743a1..abdbcbf10e79 100755 --- a/src/transformers/models/glpn/modeling_glpn.py +++ b/src/transformers/models/glpn/modeling_glpn.py @@ -36,11 +36,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -417,8 +412,6 @@ class GLPNPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/got_ocr2/image_processing_got_ocr2.py b/src/transformers/models/got_ocr2/image_processing_got_ocr2.py index 209ac88ea2fb..43bf8b520ffa 100644 --- a/src/transformers/models/got_ocr2/image_processing_got_ocr2.py +++ b/src/transformers/models/got_ocr2/image_processing_got_ocr2.py @@ -309,10 +309,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -344,10 +342,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/got_ocr2/processing_got_ocr2.py b/src/transformers/models/got_ocr2/processing_got_ocr2.py index 16c062ec63ad..35df3b5a3f05 100644 --- a/src/transformers/models/got_ocr2/processing_got_ocr2.py +++ b/src/transformers/models/got_ocr2/processing_got_ocr2.py @@ -177,10 +177,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/gpt2/__init__.py b/src/transformers/models/gpt2/__init__.py index f01899e668e3..58c4f4e012f5 100644 --- a/src/transformers/models/gpt2/__init__.py +++ b/src/transformers/models/gpt2/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_gpt2 import * - from .modeling_flax_gpt2 import * from .modeling_gpt2 import * - from .modeling_tf_gpt2 import * from .tokenization_gpt2 import * from .tokenization_gpt2_fast import * from .tokenization_gpt2_tf import * diff --git a/src/transformers/models/gpt2/configuration_gpt2.py b/src/transformers/models/gpt2/configuration_gpt2.py index db5151a2ba15..0fa19ada1c90 100644 --- a/src/transformers/models/gpt2/configuration_gpt2.py +++ b/src/transformers/models/gpt2/configuration_gpt2.py @@ -19,7 +19,7 @@ from collections.abc import Mapping from typing import Any, Optional -from ... import PreTrainedTokenizer, TensorType, is_torch_available +from ... import PreTrainedTokenizer, is_torch_available from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfigWithPast, PatchingSpec from ...utils import logging @@ -228,10 +228,9 @@ def generate_dummy_inputs( 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 + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) # We need to order the input in the way they appears in the forward() diff --git a/src/transformers/models/gpt2/convert_gpt2_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/gpt2/convert_gpt2_original_tf_checkpoint_to_pytorch.py index 33f9dabed07f..8fba497c49a8 100755 --- a/src/transformers/models/gpt2/convert_gpt2_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/gpt2/convert_gpt2_original_tf_checkpoint_to_pytorch.py @@ -15,14 +15,72 @@ """Convert OpenAI GPT checkpoint.""" import argparse +import os import torch -from transformers import GPT2Config, GPT2Model, load_tf_weights_in_gpt2 +from transformers import GPT2Config, GPT2Model from transformers.utils import CONFIG_NAME, WEIGHTS_NAME, logging logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def load_tf_weights_in_gpt2(model, config, gpt2_checkpoint_path): + """Load tf checkpoints in a pytorch model""" + try: + import re + + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(gpt2_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array.squeeze()) + + for name, array in zip(names, arrays): + name = name[6:] # skip "model/" + name = name.split("/") + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+\d+", m_name): + scope_names = re.split(r"(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "w" or scope_names[0] == "g": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "b": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "wpe" or scope_names[0] == "wte": + pointer = getattr(pointer, scope_names[0]) + pointer = getattr(pointer, "weight") + else: + pointer = getattr(pointer, scope_names[0]) + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + try: + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + except ValueError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + return model def convert_gpt2_checkpoint_to_pytorch(gpt2_checkpoint_path, gpt2_config_file, pytorch_dump_folder_path): diff --git a/src/transformers/models/gpt2/modeling_flax_gpt2.py b/src/transformers/models/gpt2/modeling_flax_gpt2.py deleted file mode 100644 index 8e419217c5a3..000000000000 --- a/src/transformers/models/gpt2/modeling_flax_gpt2.py +++ /dev/null @@ -1,782 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Google Flax Team Authors and 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. - -from typing import Any, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, -) -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_gpt2 import GPT2Config - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "openai-community/gpt2" -_CONFIG_FOR_DOC = "GPT2Config" - - -GPT2_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`GPT2Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -GPT2_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`): - `input_ids_length` = `sequence_length`. Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -class FlaxConv1D(nn.Module): - features: int - use_bias: bool = True - dtype: Any = jnp.float32 - precision: Any = None - - @nn.compact - def __call__(self, inputs): - inputs = jnp.asarray(inputs, self.dtype) - kernel = self.param("kernel", jax.nn.initializers.normal(stddev=0.02), (self.features, inputs.shape[-1])) - kernel = jnp.asarray(kernel.transpose(), self.dtype) - y = lax.dot_general(inputs, kernel, (((inputs.ndim - 1,), (0,)), ((), ())), precision=self.precision) - if self.use_bias: - bias = self.param("bias", jax.nn.initializers.zeros, (self.features,)) - bias = jnp.asarray(bias, self.dtype) - y = y + bias - return y - - -class FlaxGPT2Attention(nn.Module): - config: GPT2Config - dtype: jnp.dtype = jnp.float32 - causal: bool = True - is_cross_attention: bool = False - - def setup(self): - config = self.config - self.embed_dim = config.hidden_size - self.num_heads = config.num_attention_heads - self.head_dim = self.embed_dim // self.num_heads - - if self.is_cross_attention: - self.c_attn = FlaxConv1D(2 * self.embed_dim, dtype=self.dtype) - self.q_attn = FlaxConv1D(self.embed_dim, dtype=self.dtype) - else: - self.c_attn = FlaxConv1D(3 * self.embed_dim, dtype=self.dtype) - self.c_proj = FlaxConv1D(self.embed_dim, dtype=self.dtype) - - self.resid_dropout = nn.Dropout(rate=config.resid_pdrop) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - if not is_cross_attention: - qkv_out = self.c_attn(hidden_states) - query, key, value = jnp.split(qkv_out, 3, axis=2) - else: - q_out = self.q_attn(hidden_states) - (query,) = jnp.split(q_out, 1, axis=2) - kv_out = self.c_attn(key_value_states) - key, value = jnp.split(kv_out, 2, axis=2) - - query = self._split_heads(query) - key = self._split_heads(key) - value = self._split_heads(value) - - query_length, key_length = query.shape[1], key.shape[1] - - if self.causal: - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - dropout_rng = None - if not deterministic and self.config.attn_pdrop > 0.0: - dropout_rng = self.make_rng("dropout") - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key, value, attention_mask = self._concatenate_to_cache(key, value, query, attention_mask) - - # transform boolean mask into float mask - if attention_mask is not None: - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - # usual dot product attention - attn_weights = dot_product_attention_weights( - query, - key, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attn_pdrop, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value) - attn_output = self._merge_heads(attn_output) - attn_output = self.c_proj(attn_output) - attn_output = self.resid_dropout(attn_output, deterministic=deterministic) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxGPT2MLP(nn.Module): - config: GPT2Config - intermediate_size: int - dtype: jnp.dtype = jnp.float32 - - def setup(self): - embed_dim = self.config.hidden_size - self.c_fc = FlaxConv1D(self.intermediate_size, dtype=self.dtype) - self.c_proj = FlaxConv1D(embed_dim, dtype=self.dtype) - self.act = ACT2FN[self.config.activation_function] - self.dropout = nn.Dropout(rate=self.config.resid_pdrop) - - def __call__(self, hidden_states, deterministic: bool = True): - hidden_states = self.c_fc(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.c_proj(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxGPT2Block(nn.Module): - config: GPT2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - hidden_size = self.config.hidden_size - inner_dim = self.config.n_inner if self.config.n_inner is not None else 4 * hidden_size - - self.ln_1 = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - self.attn = FlaxGPT2Attention(self.config, dtype=self.dtype) - self.ln_2 = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - - if self.config.add_cross_attention: - self.crossattention = FlaxGPT2Attention( - config=self.config, dtype=self.dtype, causal=False, is_cross_attention=True - ) - self.ln_cross_attn = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - - self.mlp = FlaxGPT2MLP(self.config, inner_dim, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask=None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - residual = hidden_states - hidden_states = self.ln_1(hidden_states) - attn_outputs = self.attn( - hidden_states, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - # residual connection - attn_output = attn_outputs[0] # output_attn: a, (attentions) - outputs = attn_outputs[1:] - # residual connection - hidden_states = attn_output + residual - - # Cross-Attention Block - if encoder_hidden_states is not None: - # add one self-attention block for cross-attention - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with " - "cross-attention layers by setting `config.add_cross_attention=True`" - ) - residual = hidden_states - hidden_states = self.ln_cross_attn(hidden_states) - cross_attn_outputs = self.crossattention( - hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attn_output = cross_attn_outputs[0] - # residual connection - hidden_states = residual + attn_output - outputs = outputs + cross_attn_outputs[1:] # add cross attentions if we output attention weights - - residual = hidden_states - hidden_states = self.ln_2(hidden_states) - feed_forward_hidden_states = self.mlp(hidden_states, deterministic=deterministic) - # residual connection - hidden_states = residual + feed_forward_hidden_states - - outputs = (hidden_states,) + outputs - - return outputs - - -class FlaxGPT2PreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = GPT2Config - base_model_prefix = "transformer" - module_class: nn.Module = None - - def __init__( - self, - config: GPT2Config, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - if self.config.add_cross_attention: - encoder_hidden_states = jnp.zeros(input_shape + (self.config.n_embd,)) - encoder_attention_mask = attention_mask - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states, - encoder_attention_mask, - return_dict=False, - ) - else: - module_init_outputs = self.module.init(rngs, input_ids, attention_mask, position_ids, return_dict=False) - - random_params = module_init_outputs["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length)) - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(GPT2_INPUTS_DOCSTRING) - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - params: Optional[dict] = None, - past_key_values: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if encoder_hidden_states is not None and encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = input_ids.shape - - if position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `position_ids` when passing `past_key_values`.") - - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - if attention_mask is None: - attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be changed by FlaxGPT2Attention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - encoder_hidden_states, - encoder_attention_mask, - not train, - False, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - return outputs - - -class FlaxGPT2BlockCollection(nn.Module): - config: GPT2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.blocks = [ - FlaxGPT2Block(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask=None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - for block in self.blocks: - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = block( - hidden_states, - attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - # this contains possible `None` values - `FlaxGPT2Module` will filter them out - outputs = (hidden_states, all_hidden_states, all_attentions, all_cross_attentions) - - return outputs - - -class FlaxGPT2Module(nn.Module): - config: GPT2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.embed_dim = self.config.hidden_size - - self.wte = nn.Embed( - self.config.vocab_size, - self.embed_dim, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.wpe = nn.Embed( - self.config.max_position_embeddings, - self.embed_dim, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.embd_pdrop) - self.h = FlaxGPT2BlockCollection(self.config, dtype=self.dtype) - self.ln_f = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic=True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - input_embeds = self.wte(input_ids.astype("i4")) - position_embeds = self.wpe(position_ids.astype("i4")) - - hidden_states = input_embeds + position_embeds - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - - outputs = self.h( - hidden_states, - attention_mask, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.ln_f(hidden_states) - - if output_hidden_states: - all_hidden_states = outputs[1] + (hidden_states,) - outputs = (hidden_states, all_hidden_states) + outputs[2:] - else: - outputs = (hidden_states,) + outputs[1:] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=outputs[1], - attentions=outputs[2], - cross_attentions=outputs[3], - ) - - -@add_start_docstrings( - "The bare GPT2 Model transformer outputting raw hidden-states without any specific head on top.", - GPT2_START_DOCSTRING, -) -class FlaxGPT2Model(FlaxGPT2PreTrainedModel): - module_class = FlaxGPT2Module - - -append_call_sample_docstring( - FlaxGPT2Model, - _CHECKPOINT_FOR_DOC, - FlaxBaseModelOutputWithPastAndCrossAttentions, - _CONFIG_FOR_DOC, -) - - -class FlaxGPT2LMHeadModule(nn.Module): - config: GPT2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.transformer = FlaxGPT2Module(self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - outputs = self.transformer( - input_ids, - attention_mask, - position_ids, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_kernel = self.transformer.variables["params"]["wte"]["embedding"].T - lm_logits = self.lm_head.apply({"params": {"kernel": shared_kernel}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - return (lm_logits,) + outputs[1:] - - return FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - """ - The GPT2 Model transformer with a language modeling head on top (linear layer with weights tied to the input - embeddings). - """, - GPT2_START_DOCSTRING, -) -class FlaxGPT2LMHeadModel(FlaxGPT2PreTrainedModel): - module_class = FlaxGPT2LMHeadModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since GPT2 uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice( - extended_attention_mask, attention_mask.astype("i4"), (0, 0) - ) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxGPT2LMHeadModel, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutputWithCrossAttentions, - _CONFIG_FOR_DOC, -) - - -__all__ = ["FlaxGPT2LMHeadModel", "FlaxGPT2Model", "FlaxGPT2PreTrainedModel"] diff --git a/src/transformers/models/gpt2/modeling_gpt2.py b/src/transformers/models/gpt2/modeling_gpt2.py index ae0786179464..1cbea3f50da8 100644 --- a/src/transformers/models/gpt2/modeling_gpt2.py +++ b/src/transformers/models/gpt2/modeling_gpt2.py @@ -16,7 +16,6 @@ """PyTorch OpenAI GPT-2 model.""" import math -import os import warnings from dataclasses import dataclass from typing import Callable, Optional, Union @@ -54,62 +53,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_gpt2(model, config, gpt2_checkpoint_path): - """Load tf checkpoints in a pytorch model""" - try: - import re - - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(gpt2_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array.squeeze()) - - for name, array in zip(names, arrays): - name = name[6:] # skip "model/" - name = name.split("/") - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+\d+", m_name): - scope_names = re.split(r"(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "w" or scope_names[0] == "g": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "b": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "wpe" or scope_names[0] == "wte": - pointer = getattr(pointer, scope_names[0]) - pointer = getattr(pointer, "weight") - else: - pointer = getattr(pointer, scope_names[0]) - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except ValueError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - def eager_attention_forward(module, query, key, value, attention_mask, head_mask=None, **kwargs): attn_weights = torch.matmul(query, key.transpose(-1, -2)) @@ -562,7 +505,6 @@ def forward( @auto_docstring class GPT2PreTrainedModel(PreTrainedModel): config: GPT2Config - load_tf_weights = load_tf_weights_in_gpt2 base_model_prefix = "transformer" is_parallelizable = True supports_gradient_checkpointing = True @@ -580,8 +522,6 @@ def __init__(self, *inputs, **kwargs): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, (nn.Linear, Conv1D)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1634,5 +1574,4 @@ def forward( "GPT2LMHeadModel", "GPT2Model", "GPT2PreTrainedModel", - "load_tf_weights_in_gpt2", ] diff --git a/src/transformers/models/gpt2/modeling_tf_gpt2.py b/src/transformers/models/gpt2/modeling_tf_gpt2.py deleted file mode 100644 index 42e23fc29015..000000000000 --- a/src/transformers/models/gpt2/modeling_tf_gpt2.py +++ /dev/null @@ -1,1238 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The OpenAI Team Authors and HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 OpenAI GPT-2 model.""" - -from __future__ import annotations - -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFCausalLMOutputWithCrossAttentions, - TFSequenceClassifierOutputWithPast, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFConv1D, - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - TFSequenceSummary, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_gpt2 import GPT2Config - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "openai-community/gpt2" -_CONFIG_FOR_DOC = "GPT2Config" - - -class TFAttention(keras.layers.Layer): - def __init__(self, nx, config, scale=False, is_cross_attention=False, **kwargs): - super().__init__(**kwargs) - - n_state = nx # in Attention: n_state=768 (nx=n_embd) - # [switch nx => n_state from Block to Attention to keep identical to TF implementation] - assert n_state % config.n_head == 0 - self.n_head = config.n_head - self.split_size = n_state - self.scale = scale - self.output_attentions = config.output_attentions - - self.is_cross_attention = is_cross_attention - - if self.is_cross_attention: - self.c_attn = TFConv1D(n_state * 2, nx, initializer_range=config.initializer_range, name="c_attn") - self.q_attn = TFConv1D(n_state, nx, initializer_range=config.initializer_range, name="q_attn") - else: - self.c_attn = TFConv1D(n_state * 3, nx, initializer_range=config.initializer_range, name="c_attn") - - self.c_proj = TFConv1D(n_state, nx, initializer_range=config.initializer_range, name="c_proj") - self.attn_dropout = keras.layers.Dropout(config.attn_pdrop) - self.resid_dropout = keras.layers.Dropout(config.resid_pdrop) - self.pruned_heads = set() - self.embed_dim = n_state - - def prune_heads(self, heads): - pass - - @staticmethod - def causal_attention_mask(nd, ns, dtype): - """ - 1's in the lower triangle, counting from the lower right corner. Same as tf.matrix_band_part(tf.ones([nd, ns]), - -1, ns-nd), but doesn't produce garbage on TPUs. - """ - i = tf.range(nd)[:, None] - j = tf.range(ns) - m = i >= j - ns + nd - return tf.cast(m, dtype) - - def _attn(self, q, k, v, attention_mask, head_mask, output_attentions, training=False): - # q, k, v have shape [batch, heads, sequence, features] - w = tf.matmul(q, k, transpose_b=True) - if self.scale: - dk = tf.cast(shape_list(k)[-1], dtype=w.dtype) # scale attention_scores - w = w / tf.math.sqrt(dk) - - if not self.is_cross_attention: - # if only "normal" attention layer implements causal mask - - # w has shape [batch, heads, dst_sequence, src_sequence], where information flows from src to dst. - _, _, nd, ns = shape_list(w) - b = self.causal_attention_mask(nd, ns, dtype=w.dtype) - b = tf.reshape(b, [1, 1, nd, ns]) - w = w * b - 1e4 * (1 - b) - - if attention_mask is not None: - # Apply the attention mask - attention_mask = tf.cast(attention_mask, dtype=w.dtype) - w = w + attention_mask - - w = stable_softmax(w, axis=-1) - w = self.attn_dropout(w, training=training) - - # Mask heads if we want to - if head_mask is not None: - w = w * head_mask - - outputs = [tf.matmul(w, v)] - if output_attentions: - outputs.append(w) - return outputs - - def merge_heads(self, x): - x = tf.transpose(x, [0, 2, 1, 3]) - x_shape = shape_list(x) - new_x_shape = x_shape[:-2] + [x_shape[-2] * x_shape[-1]] - return tf.reshape(x, new_x_shape) - - def split_heads(self, x): - x_shape = shape_list(x) - new_x_shape = x_shape[:-1] + [self.n_head, x_shape[-1] // self.n_head] - x = tf.reshape(x, new_x_shape) - return tf.transpose(x, (0, 2, 1, 3)) # (batch, head, seq_length, head_features) - - def call( - self, - x, - layer_past, - attention_mask, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - use_cache, - output_attentions, - training=False, - ): - if encoder_hidden_states is not None: - if not hasattr(self, "q_attn"): - raise ValueError( - "If class is used as cross attention, the weights `q_attn` have to be defined. " - "Please make sure to instantiate class with `GPT2Attention(..., is_cross_attention=True)`." - ) - - query = self.q_attn(x) - kv_out = self.c_attn(encoder_hidden_states) - key, value = tf.split(kv_out, 2, axis=2) - attention_mask = encoder_attention_mask - else: - x = self.c_attn(x) - query, key, value = tf.split(x, 3, axis=2) - - query = self.split_heads(query) - key = self.split_heads(key) - value = self.split_heads(value) - if layer_past is not None: - past_key, past_value = tf.unstack(layer_past, axis=0, num=2) - key = tf.concat([past_key, key], axis=-2) - value = tf.concat([past_value, value], axis=-2) - - # to cope with keras serialization - if use_cache: - present = tf.stack([key, value], axis=0) - else: - present = (None,) - - attn_outputs = self._attn(query, key, value, attention_mask, head_mask, output_attentions, training=training) - a = attn_outputs[0] - - a = self.merge_heads(a) - a = self.c_proj(a) - a = self.resid_dropout(a, training=training) - - outputs = [a, present] + attn_outputs[1:] - return outputs # a, present, (attentions) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if self.is_cross_attention: - c_attn_shape = 2 * self.embed_dim - else: - c_attn_shape = 3 * self.embed_dim - if getattr(self, "c_proj", None) is not None: - with tf.name_scope(self.c_proj.name): - self.c_proj.build([None, None, self.embed_dim]) - if getattr(self, "c_attn", None) is not None: - with tf.name_scope(self.c_attn.name): - self.c_attn.build([None, None, c_attn_shape]) - if getattr(self, "q_attn", None) is not None: - with tf.name_scope(self.q_attn.name): - self.q_attn.build([None, None, self.embed_dim]) - - -class TFMLP(keras.layers.Layer): - def __init__(self, n_state, config, **kwargs): - super().__init__(**kwargs) - nx = config.n_embd - self.c_fc = TFConv1D(n_state, nx, initializer_range=config.initializer_range, name="c_fc") - self.c_proj = TFConv1D(nx, n_state, initializer_range=config.initializer_range, name="c_proj") - self.act = get_tf_activation(config.activation_function) - self.dropout = keras.layers.Dropout(config.resid_pdrop) - self.intermediate_size = n_state - self.embed_dim = nx - - def call(self, x, training=False): - h = self.act(self.c_fc(x)) - h2 = self.c_proj(h) - h2 = self.dropout(h2, training=training) - return h2 - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "c_fc", None) is not None: - with tf.name_scope(self.c_fc.name): - self.c_fc.build([None, None, self.intermediate_size]) - if getattr(self, "c_proj", None) is not None: - with tf.name_scope(self.c_proj.name): - self.c_proj.build([None, None, self.embed_dim]) - - -class TFBlock(keras.layers.Layer): - def __init__(self, config, scale=False, **kwargs): - super().__init__(**kwargs) - nx = config.n_embd - inner_dim = config.n_inner if config.n_inner is not None else 4 * nx - self.ln_1 = keras.layers.LayerNormalization(epsilon=config.layer_norm_epsilon, name="ln_1") - self.attn = TFAttention(nx, config, scale, name="attn") - self.ln_2 = keras.layers.LayerNormalization(epsilon=config.layer_norm_epsilon, name="ln_2") - - if config.add_cross_attention: - self.crossattention = TFAttention(nx, config, scale, name="crossattention", is_cross_attention=True) - self.ln_cross_attn = keras.layers.LayerNormalization( - epsilon=config.layer_norm_epsilon, name="ln_cross_attn" - ) - - self.mlp = TFMLP(inner_dim, config, name="mlp") - self.hidden_size = config.hidden_size - - def call( - self, - x, - layer_past, - attention_mask, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - use_cache, - output_attentions, - training=False, - ): - a = self.ln_1(x) - output_attn = self.attn( - a, - layer_past=layer_past, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - use_cache=use_cache, - output_attentions=output_attentions, - training=training, - ) - a = output_attn[0] # output_attn: a, present, (attentions) - outputs = output_attn[1:] - x = x + a - - # Cross-Attention Block - if encoder_hidden_states is not None: - # add one self-attention block for cross-attention - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with " - "cross-attention layers by setting `config.add_cross_attention=True`" - ) - - ca = self.ln_cross_attn(x) - output_cross_attn = self.crossattention( - ca, - layer_past=None, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - use_cache=False, - output_attentions=output_attentions, - training=training, - ) - ca = output_cross_attn[0] # output_attn: a, present, (cross_attentions) - x = x + ca - outputs = outputs + output_cross_attn[2:] # add cross attentions if we output attention weights - - m = self.ln_2(x) - m = self.mlp(m, training=training) - x = x + m - - outputs = [x] + outputs - return outputs # x, present, (attentions, cross_attentions) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "ln_1", None) is not None: - with tf.name_scope(self.ln_1.name): - self.ln_1.build([None, None, self.hidden_size]) - if getattr(self, "attn", None) is not None: - with tf.name_scope(self.attn.name): - self.attn.build(None) - if getattr(self, "ln_2", None) is not None: - with tf.name_scope(self.ln_2.name): - self.ln_2.build([None, None, self.hidden_size]) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - if getattr(self, "ln_cross_attn", None) is not None: - with tf.name_scope(self.ln_cross_attn.name): - self.ln_cross_attn.build([None, None, self.hidden_size]) - - -@keras_serializable -class TFGPT2MainLayer(keras.layers.Layer): - config_class = GPT2Config - - def __init__(self, config, *inputs, **kwargs): - super().__init__(*inputs, **kwargs) - - self.config = config - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.use_cache = config.use_cache - self.return_dict = config.use_return_dict - - self.num_hidden_layers = config.n_layer - self.n_embd = config.n_embd - self.n_positions = config.n_positions - self.initializer_range = config.initializer_range - - self.wte = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.hidden_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="wte", - ) - self.wpe = keras.layers.Embedding( - input_dim=config.n_positions, - output_dim=config.n_embd, - embeddings_initializer=get_initializer(config.initializer_range), - name="wpe", - ) - self.drop = keras.layers.Dropout(config.embd_pdrop) - self.h = [TFBlock(config, scale=True, name=f"h_._{i}") for i in range(config.n_layer)] - self.ln_f = keras.layers.LayerNormalization(epsilon=config.layer_norm_epsilon, name="ln_f") - self.embed_dim = config.hidden_size - - def get_input_embeddings(self): - return self.wte - - def set_input_embeddings(self, new_embeddings): - self.wte = new_embeddings - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - input_ids = tf.reshape(input_ids, [-1, input_shape[-1]]) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if past_key_values is None: - past_length = 0 - past_key_values = [None] * len(self.h) - else: - past_length = shape_list(past_key_values[0][0])[-2] - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(past_length, input_shape[-1] + past_length), axis=0) - - if attention_mask is not None: - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - attention_mask = tf.reshape(attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - one_cst = tf.constant(1.0) - attention_mask = tf.cast(attention_mask, dtype=one_cst.dtype) - attention_mask = tf.multiply(tf.subtract(one_cst, attention_mask), tf.constant(-10000.0)) - - # Copied from `modeling_tf_t5.py` with -1e9 -> -10000 - if self.config.add_cross_attention and encoder_attention_mask is not None: - # If a 2D ou 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=encoder_hidden_states.dtype) - num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) - if num_dims_encoder_attention_mask == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if num_dims_encoder_attention_mask == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, - # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) - - encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -10000.0 - else: - encoder_extended_attention_mask = None - - encoder_attention_mask = encoder_extended_attention_mask - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.num_hidden_layers - # head_mask = tf.constant([0] * self.num_hidden_layers) - - position_ids = tf.reshape(position_ids, [-1, shape_list(position_ids)[-1]]) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = self.wte(input_ids) - - position_embeds = self.wpe(position_ids) - - if token_type_ids is not None: - token_type_ids = tf.reshape(token_type_ids, [-1, shape_list(token_type_ids)[-1]]) - token_type_embeds = self.wte(token_type_ids) - else: - token_type_embeds = tf.constant(0.0) - - position_embeds = tf.cast(position_embeds, dtype=inputs_embeds.dtype) - token_type_embeds = tf.cast(token_type_embeds, dtype=inputs_embeds.dtype) - hidden_states = inputs_embeds + position_embeds + token_type_embeds - hidden_states = self.drop(hidden_states, training=training) - - output_shape = input_shape + [shape_list(hidden_states)[-1]] - - presents = () if use_cache else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - all_hidden_states = () if output_hidden_states else None - for i, (block, layer_past) in enumerate(zip(self.h, past_key_values)): - if output_hidden_states: - all_hidden_states = all_hidden_states + (tf.reshape(hidden_states, output_shape),) - - outputs = block( - hidden_states, - layer_past, - attention_mask, - head_mask[i], - encoder_hidden_states, - encoder_attention_mask, - use_cache, - output_attentions, - training=training, - ) - - hidden_states, present = outputs[:2] - if use_cache: - presents = presents + (present,) - - if output_attentions: - all_attentions = all_attentions + (outputs[2],) - if self.config.add_cross_attention and encoder_hidden_states is not None: - all_cross_attentions = all_cross_attentions + (outputs[3],) - - hidden_states = self.ln_f(hidden_states) - - hidden_states = tf.reshape(hidden_states, output_shape) - # Add last hidden state - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if output_attentions: - # let the number of heads free (-1) so we can extract attention even after head pruning - attention_output_shape = input_shape[:-1] + [-1] + shape_list(all_attentions[0])[-2:] - all_attentions = tuple(tf.reshape(t, attention_output_shape) for t in all_attentions) - - if not return_dict: - return tuple( - v - for v in [hidden_states, presents, all_hidden_states, all_attentions, all_cross_attentions] - if v is not None - ) - - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=presents, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "wte", None) is not None: - with tf.name_scope(self.wte.name): - self.wte.build(None) - if getattr(self, "wpe", None) is not None: - with tf.name_scope(self.wpe.name): - self.wpe.build(None) - if getattr(self, "ln_f", None) is not None: - with tf.name_scope(self.ln_f.name): - self.ln_f.build([None, None, self.embed_dim]) - if getattr(self, "h", None) is not None: - for layer in self.h: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFGPT2PreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = GPT2Config - base_model_prefix = "transformer" - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"h.\d+.attn.bias", r"h.\d+.crossattention.bias"] - - @property - def input_signature(self): - # Although GPT-2 supports token_type_ids in theory, in practice they are rarely used, and the implementation - # means that passing token_type_ids=0 yields different outputs from token_type_ids=None. - # Therefore, we remove the token_type_ids argument by default, even though it would usually be included. - return { - "input_ids": tf.TensorSpec((None, None), tf.int32, name="input_ids"), - "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), - } - - -@dataclass -class TFGPT2DoubleHeadsModelOutput(ModelOutput): - """ - Base class for outputs of models predicting if two sentences are consecutive or not. - - Args: - logits (`tf.Tensor` of shape `(batch_size, num_choices, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - mc_logits (`tf.Tensor` of shape `(batch_size, num_choices)`): - Prediction scores of the multiple choice classification head (scores for each choice before SoftMax). - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: tf.Tensor | None = None - mc_logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -GPT2_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`GPT2Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -GPT2_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, input_ids_length)`): - `input_ids_length` = `sequence_length` if `past_key_values` is `None` else `past_key_values[0].shape[-2]` - (`sequence_length` of input past key value states). Indices of input sequence tokens in the vocabulary. - - If `past_key_values` is used, only input IDs that do not have their past calculated should be passed as - `input_ids`. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - past_key_values (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states (key and values in the attention blocks) as computed by the model (see - `past_key_values` output below). Can be used to speed up sequential decoding. The token ids which have - their past given to this model should not be passed as input ids as they have already been computed. - attention_mask (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - If `past_key_values` is used, `attention_mask` needs to contain the masking strategy that was used for - `past_key_values`. In other words, the `attention_mask` always has to have the length: - `len(past_key_values) + len(input_ids)` - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, input_ids_length)`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, input_ids_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, input_ids_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare GPT2 Model transformer outputting raw hidden-states without any specific head on top.", - GPT2_START_DOCSTRING, -) -class TFGPT2Model(TFGPT2PreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFGPT2MainLayer(config, name="transformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(GPT2_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPastAndCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past` are used, the user can optionally input only the last `decoder_input_ids` (those that don't have - their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past`). Set to `False` during training, `True` during generation - """ - - outputs = self.transformer( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -@add_start_docstrings( - """ - The GPT2 Model transformer with a language modeling head on top (linear layer with weights tied to the input - embeddings). - """, - GPT2_START_DOCSTRING, -) -class TFGPT2LMHeadModel(TFGPT2PreTrainedModel, TFCausalLanguageModelingLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFGPT2MainLayer(config, name="transformer") - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - def prepare_inputs_for_generation(self, inputs, past_key_values=None, use_cache=None, **kwargs): - token_type_ids = kwargs.get("token_type_ids") - # only last token for inputs_ids if past is defined in kwargs - if past_key_values: - inputs = tf.expand_dims(inputs[:, -1], -1) - if token_type_ids is not None: - token_type_ids = tf.expand_dims(token_type_ids[:, -1], -1) - - position_ids = kwargs.get("position_ids") - attention_mask = kwargs.get("attention_mask") - - if attention_mask is not None and position_ids is None: - position_ids = tf.math.cumsum(attention_mask, axis=-1, exclusive=True) - if past_key_values: - position_ids = tf.expand_dims(position_ids[:, -1], -1) - - return { - "input_ids": inputs, - "attention_mask": attention_mask, - "position_ids": position_ids, - "past_key_values": past_key_values, - "use_cache": use_cache, - "token_type_ids": token_type_ids, - } - - @unpack_inputs - @add_start_docstrings_to_model_forward(GPT2_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutputWithCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFCausalLMOutputWithCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past` are used, the user can optionally input only the last `decoder_input_ids` (those that don't have - their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past`). Set to `False` during training, `True` during generation - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - - transformer_outputs = self.transformer( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = transformer_outputs[0] - logits = tf.matmul(hidden_states, self.transformer.wte.weights, transpose_b=True) - - loss = None - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels, shifted_logits) - - if not return_dict: - output = (logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithCrossAttentions( - loss=loss, - logits=logits, - past_key_values=transformer_outputs.past_key_values, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - cross_attentions=transformer_outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -@add_start_docstrings( - """ - The GPT2 Model transformer with a language modeling and a multiple-choice classification head on top e.g. for - RocStories/SWAG tasks. The two heads are two linear layers. The language modeling head has its weights tied to the - input embeddings, the classification head takes as input the input of a specified classification token index in the - input sequence). - """, - GPT2_START_DOCSTRING, -) -class TFGPT2DoubleHeadsModel(TFGPT2PreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - config.num_labels = 1 - self.transformer = TFGPT2MainLayer(config, name="transformer") - self.multiple_choice_head = TFSequenceSummary( - config, initializer_range=config.initializer_range, name="multiple_choice_head" - ) - - @unpack_inputs - @add_start_docstrings_to_model_forward(GPT2_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFGPT2DoubleHeadsModelOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - mc_token_ids: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFGPT2DoubleHeadsModelOutput | tuple[tf.Tensor]: - r""" - mc_token_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, num_choices)`, *optional*, default to index of the last token of the input): - Index of the classification token in each input sequence. Selected in the range `[0, input_ids.size(-1) - - 1]`. - - Return: - - Examples: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFGPT2DoubleHeadsModel - - >>> tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2") - >>> model = TFGPT2DoubleHeadsModel.from_pretrained("openai-community/gpt2") - - >>> # Add a [CLS] to the vocabulary (we should train it also!) - >>> num_added_tokens = tokenizer.add_special_tokens({"cls_token": "[CLS]"}) - - >>> embedding_layer = model.resize_token_embeddings( - ... len(tokenizer) - ... ) # Update the model embeddings with the new vocabulary size - - >>> choices = ["Hello, my dog is cute [CLS]", "Hello, my cat is cute [CLS]"] - >>> encoded_choices = [tokenizer.encode(s) for s in choices] - >>> cls_token_location = [tokens.index(tokenizer.cls_token_id) for tokens in encoded_choices] - - >>> input_ids = tf.constant(encoded_choices)[None, :] # Batch size: 1, number of choices: 2 - >>> mc_token_ids = tf.constant([cls_token_location]) # Batch size: 1 - - >>> outputs = model(input_ids, mc_token_ids=mc_token_ids) - >>> lm_prediction_scores, mc_prediction_scores = outputs[:2] - ```""" - - if input_ids is not None: - input_shapes = shape_list(input_ids) - else: - input_shapes = shape_list(inputs_embeds)[:-1] - - seq_length = input_shapes[-1] - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - transformer_outputs = self.transformer( - input_ids=flat_input_ids, - past_key_values=past_key_values, - attention_mask=flat_attention_mask, - token_type_ids=flat_token_type_ids, - position_ids=flat_position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=None, - encoder_attention_mask=None, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = transformer_outputs[0] - hidden_states = tf.reshape(hidden_states, input_shapes + shape_list(hidden_states)[-1:]) - if return_dict and output_hidden_states: - # We do this to match the slightly odd PT behaviour - the final hidden state is reshaped to rank 4 when the - # input is rank 3, but all other hidden states remain at rank-3 (with the first 2 dims merged) - all_hidden_states = transformer_outputs.hidden_states[:-1] + (hidden_states,) - else: - all_hidden_states = None - lm_logits = tf.matmul(hidden_states, self.transformer.wte.weights, transpose_b=True) - mc_logits = self.multiple_choice_head(hidden_states, mc_token_ids, training=training) - mc_logits = tf.squeeze(mc_logits, axis=-1) - - if not return_dict: - return (lm_logits, mc_logits) + transformer_outputs[1:] - - return TFGPT2DoubleHeadsModelOutput( - logits=lm_logits, - mc_logits=mc_logits, - past_key_values=transformer_outputs.past_key_values, - hidden_states=all_hidden_states, - attentions=transformer_outputs.attentions, - ) - - @property - def input_signature(self): - return { - "input_ids": tf.TensorSpec((None, None, None), tf.int32, name="input_ids"), - "attention_mask": tf.TensorSpec((None, None, None), tf.int32, name="attention_mask"), - "mc_token_ids": tf.TensorSpec((None, None), tf.int32, name="mc_token_ids"), - } - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "multiple_choice_head", None) is not None: - with tf.name_scope(self.multiple_choice_head.name): - self.multiple_choice_head.build(None) - - -@add_start_docstrings( - """ - The GPT2 Model transformer with a sequence classification head on top (linear layer). - - [`TFGPT2ForSequenceClassification`] uses the last token in order to do the classification, as other causal models - (e.g. GPT-1) do. - - Since it does classification on the last token, it requires to know the position of the last token. If a - `pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If - no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the - padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in - each row of the batch). - """, - GPT2_START_DOCSTRING, -) -class TFGPT2ForSequenceClassification(TFGPT2PreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.score = keras.layers.Dense( - config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="score", - use_bias=False, - ) - self.transformer = TFGPT2MainLayer(config, name="transformer") - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(GPT2_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint="microsoft/DialogRPT-updown", - output_type=TFSequenceClassifierOutputWithPast, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutputWithPast | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = transformer_outputs[0] - logits = self.score(hidden_states) - logits_shape = shape_list(logits) - batch_size = logits_shape[0] - - if self.config.pad_token_id is None: - last_non_pad_token = tf.fill((batch_size,), value=logits_shape[1] - 1) - else: - if input_ids is not None: - token_indices = tf.range(shape_list(input_ids)[-1]) - non_pad_mask = tf.cast(input_ids != self.config.pad_token_id, token_indices.dtype) - last_non_pad_token = tf.reduce_max(token_indices * non_pad_mask, axis=-1) - else: - last_non_pad_token = tf.fill((batch_size,), value=logits_shape[1] - 1) - logger.warning_once( - f"{self.__class__.__name__} will not detect padding tokens in `inputs_embeds`. Results may be " - "unexpected if using padding tokens in conjunction with `inputs_embeds.`" - ) - loss = None - - pooled_logits = tf.gather(logits, last_non_pad_token, batch_dims=1, axis=1) - - if labels is not None: - if self.config.pad_token_id is None and logits_shape[0] != 1: - raise ValueError("Cannot handle batch sizes > 1 if no padding token is defined.") - - loss = self.hf_compute_loss(tf.reshape(labels, [-1]), tf.reshape(pooled_logits, [-1, self.num_labels])) - - if not return_dict: - output = (pooled_logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutputWithPast( - loss=loss, - logits=pooled_logits, - past_key_values=transformer_outputs.past_key_values, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "score", None) is not None: - with tf.name_scope(self.score.name): - self.score.build([None, None, self.config.n_embd]) - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -__all__ = [ - "TFGPT2DoubleHeadsModel", - "TFGPT2ForSequenceClassification", - "TFGPT2LMHeadModel", - "TFGPT2MainLayer", - "TFGPT2Model", - "TFGPT2PreTrainedModel", -] diff --git a/src/transformers/models/gpt2/tokenization_gpt2_tf.py b/src/transformers/models/gpt2/tokenization_gpt2_tf.py deleted file mode 100644 index 145a45da0db6..000000000000 --- a/src/transformers/models/gpt2/tokenization_gpt2_tf.py +++ /dev/null @@ -1,119 +0,0 @@ -import os -from typing import Optional, Union - -import tensorflow as tf -from tensorflow_text import pad_model_inputs - -from ...modeling_tf_utils import keras -from ...utils.import_utils import is_keras_nlp_available, requires -from .tokenization_gpt2 import GPT2Tokenizer - - -if is_keras_nlp_available(): - from keras_nlp.tokenizers import BytePairTokenizer - - -@requires(backends=("keras_nlp",)) -class TFGPT2Tokenizer(keras.layers.Layer): - """ - This is an in-graph tokenizer for GPT2. It should be initialized similarly to other tokenizers, using the - `from_pretrained()` method. It can also be initialized with the `from_tokenizer()` method, which imports settings - from an existing standard tokenizer object. - - In-graph tokenizers, unlike other Hugging Face tokenizers, are actually Keras layers and are designed to be run - when the model is called, rather than during preprocessing. As a result, they have somewhat more limited options - than standard tokenizer classes. They are most useful when you want to create an end-to-end model that goes - straight from `tf.string` inputs to outputs. - - Args: - vocab (dict[str, int]): Vocabulary dict for Byte Pair Tokenizer - merges (list[str]): Merges list for Byte Pair Tokenizer - """ - - def __init__( - self, - vocab: dict[str, int], - merges: list[str], - max_length: Optional[int] = None, - pad_token_id: Optional[int] = None, - ): - super().__init__() - self.pad_token_id = pad_token_id - self.max_length = max_length - self.vocab = vocab - self.merges = merges - - self.tf_tokenizer = BytePairTokenizer(vocab, merges, sequence_length=max_length) - - @classmethod - def from_tokenizer(cls, tokenizer: GPT2Tokenizer, *args, **kwargs): - """Creates TFGPT2Tokenizer from GPT2Tokenizer - - Args: - tokenizer (GPT2Tokenizer) - - Examples: - - ```python - from transformers import AutoTokenizer, TFGPT2Tokenizer - - tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2") - tf_tokenizer = TFGPT2Tokenizer.from_tokenizer(tokenizer) - ``` - """ - merges = [" ".join(m) for m in tokenizer.bpe_ranks] - vocab = tokenizer.get_vocab() - return cls(vocab, merges, *args, **kwargs) - - @classmethod - def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], *init_inputs, **kwargs): - """Creates TFGPT2Tokenizer from pretrained GPT2Tokenizer - - Args: - pretrained_model_name_or_path (Union[str, os.PathLike]): Path to pretrained model - - Examples: - - ```python - from transformers import TFGPT2Tokenizer - - tf_tokenizer = TFGPT2Tokenizer.from_pretrained("openai-community/gpt2") - ``` - """ - tokenizer = GPT2Tokenizer.from_pretrained(pretrained_model_name_or_path, *init_inputs, **kwargs) - return cls.from_tokenizer(tokenizer, *init_inputs, **kwargs) - - @classmethod - def from_config(cls, config): - """Creates TFGPT2Tokenizer from configurations - - Args: - config (Dict): Dictionary with keys such as stated in `get_config`. - """ - return cls(**config) - - def get_config(self): - return { - "vocab": self.vocab, - "merges": self.merges, - "max_length": self.max_length, - "pad_token_id": self.pad_token_id, - } - - def call(self, x, max_length: Optional[int] = None): - input_ids = self.tf_tokenizer(x) - attention_mask = tf.ones_like(input_ids) - - if self.pad_token_id is not None: - # pad the tokens up to max length - max_length = max_length if max_length is not None else self.max_length - - if max_length is not None: - input_ids, attention_mask = pad_model_inputs( - input_ids, max_seq_length=max_length, pad_value=self.pad_token_id - ) - - return {"attention_mask": attention_mask, "input_ids": input_ids} - - -__all__ = ["TFGPT2Tokenizer"] diff --git a/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py b/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py index 6992dc642a4f..63b2ec4039f6 100644 --- a/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py +++ b/src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py @@ -383,8 +383,6 @@ def _init_weights(self, module): ) module.c_proj._is_hf_initialized = True elif isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/gpt_neo/__init__.py b/src/transformers/models/gpt_neo/__init__.py index 578577f22882..242a20d00d6d 100644 --- a/src/transformers/models/gpt_neo/__init__.py +++ b/src/transformers/models/gpt_neo/__init__.py @@ -19,7 +19,6 @@ if TYPE_CHECKING: from .configuration_gpt_neo import * - from .modeling_flax_gpt_neo import * from .modeling_gpt_neo import * else: import sys diff --git a/src/transformers/models/gpt_neo/configuration_gpt_neo.py b/src/transformers/models/gpt_neo/configuration_gpt_neo.py index 875a170277d2..a9bbfcd33ef8 100644 --- a/src/transformers/models/gpt_neo/configuration_gpt_neo.py +++ b/src/transformers/models/gpt_neo/configuration_gpt_neo.py @@ -16,9 +16,9 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import Any, Optional +from typing import Any -from ... import PreTrainedTokenizer, TensorType, is_torch_available +from ... import PreTrainedTokenizer, is_torch_available from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfigWithPast from ...utils import logging @@ -227,10 +227,12 @@ def generate_dummy_inputs( 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 + tokenizer, + batch_size=batch_size, + seq_length=seq_length, + is_pair=is_pair, ) # We need to order the input in the way they appears in the forward() diff --git a/src/transformers/models/gpt_neo/convert_gpt_neo_mesh_tf_to_pytorch.py b/src/transformers/models/gpt_neo/convert_gpt_neo_mesh_tf_to_pytorch.py index 3db22857293c..6c52a515b6c4 100644 --- a/src/transformers/models/gpt_neo/convert_gpt_neo_mesh_tf_to_pytorch.py +++ b/src/transformers/models/gpt_neo/convert_gpt_neo_mesh_tf_to_pytorch.py @@ -16,12 +16,97 @@ import argparse import json +import os -from transformers import GPTNeoConfig, GPTNeoForCausalLM, load_tf_weights_in_gpt_neo +import torch +import torch.nn as nn + +from transformers import GPTNeoConfig, GPTNeoForCausalLM from transformers.utils import logging logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def load_tf_weights_in_gpt_neo(model, config, gpt_neo_checkpoint_path): + """Load tf checkpoints in a pytorch model""" + try: + import re + + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(gpt_neo_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + if "global_step" not in name and "adam" not in name: + array = tf.train.load_variable(tf_path, name) + array = tf.dtypes.cast(array.squeeze(), tf.float32).numpy() + name = name.replace("attn/q", "attn/attention/q_proj/w") + name = name.replace("attn/k", "attn/attention/k_proj/w") + name = name.replace("attn/v", "attn/attention/v_proj/w") + name = name.replace("attn/o", "attn/attention/out_proj/w") + name = name.replace("norm_1", "ln_1") + name = name.replace("norm_2", "ln_2") + name = name.replace("attn/compute_output_bias/o_b", "attn/attention/out_proj/b") + name = name.replace("conv1d_main/c_fc/kernel", "c_fc/w") + name = name.replace("conv1d_main/c_fc/bias", "c_fc/b") + name = name.replace("conv1d_main/c_proj/kernel", "c_proj/w") + name = name.replace("conv1d_main/c_proj/bias", "c_proj/b") + + names.append(name) + arrays.append(array) + + for name, array in zip(names, arrays): + name = name[5:] # skip "gpt2/" + name = name.split("/") + pointer = model.transformer + for m_name in name: + if re.fullmatch(r"[A-Za-z]+\d+", m_name): + scope_names = re.split(r"(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "w" or scope_names[0] == "g": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "b": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "wpe" or scope_names[0] == "wte": + pointer = getattr(pointer, scope_names[0]) + pointer = getattr(pointer, "weight") + else: + pointer = getattr(pointer, scope_names[0]) + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + + if name[-1] == "w" and name[-2] in ["out_proj", "k_proj", "q_proj", "v_proj", "c_proj", "c_fc"]: + array = array.transpose() + + if name == ["wte"]: + # if vocab is padded, then trim off the padding embeddings + array = array[: config.vocab_size] + + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched {name}") + + print(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + + # init the final linear layer using word embeddings + embs = model.transformer.wte.weight + lin = nn.Linear(embs.size()[1], embs.size()[0], bias=False) + lin.weight = embs + model.set_output_embeddings(lin) + return model def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, config_file, pytorch_dump_path): diff --git a/src/transformers/models/gpt_neo/modeling_flax_gpt_neo.py b/src/transformers/models/gpt_neo/modeling_flax_gpt_neo.py deleted file mode 100644 index a6cdc50b359b..000000000000 --- a/src/transformers/models/gpt_neo/modeling_flax_gpt_neo.py +++ /dev/null @@ -1,687 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Eleuther AI and The Google Flax Team Authors and 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. - -from functools import partial -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxCausalLMOutput -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_gpt_neo import GPTNeoConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "GPTNeoConfig" -_CHECKPOINT_FOR_DOC = "EleutherAI/gpt-neo-1.3B" - - -GPT_NEO_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`GPTNeoConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -GPT_NEO_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`): - `input_ids_length` = `sequence_length`. Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -class FlaxGPTNeoSelfAttention(nn.Module): - config: GPTNeoConfig - attention_type: str - dtype: jnp.dtype = jnp.float32 - - def setup(self): - config = self.config - self.embed_dim = config.hidden_size - self.num_heads = config.num_attention_heads - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and " - f"`num_heads`: {self.num_heads})." - ) - - self.attn_dropout = nn.Dropout(config.attention_dropout) - self.resid_dropout = nn.Dropout(config.resid_dropout) - - dense = partial( - nn.Dense, - self.embed_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(use_bias=False), dense(use_bias=False), dense(use_bias=False) - self.out_proj = dense() - - self.causal_mask = make_causal_mask(jnp.ones((1, config.max_position_embeddings), dtype="bool"), dtype="bool") - if self.attention_type == "local": - self.causal_mask = self.causal_mask ^ jnp.tril(self.causal_mask, -config.window_size) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - attention_mask=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - query = self.q_proj(hidden_states) * jnp.sqrt(self.head_dim).astype(self.dtype) - key = self.k_proj(hidden_states) - value = self.v_proj(hidden_states) - - query = self._split_heads(query) - key = self._split_heads(key) - value = self._split_heads(value) - - query_length, key_length = query.shape[1], key.shape[1] - - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - - batch_size = hidden_states.shape[0] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - - dropout_rng = None - if not deterministic and self.config.attention_dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.has_variable("cache", "cached_key") or init_cache: - key, value, attention_mask = self._concatenate_to_cache(key, value, query, attention_mask) - - # transform boolean mask into float mask - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - - # usual dot product attention - attn_weights = dot_product_attention_weights( - query, - key, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_dropout, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - attn_output = self.resid_dropout(attn_output, deterministic=deterministic) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxGPTNeoAttention(nn.Module): - config: GPTNeoConfig - layer_id: int = 0 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - attention_type = self.config.attention_layers[self.layer_id] - self.attention = FlaxGPTNeoSelfAttention(self.config, attention_type, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - return self.attention( - hidden_states, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - - -class FlaxGPTNeoMLP(nn.Module): - config: GPTNeoConfig - intermediate_size: int - dtype: jnp.dtype = jnp.float32 - - def setup(self): - embed_dim = self.config.hidden_size - kernel_init = jax.nn.initializers.normal(self.config.initializer_range) - self.c_fc = nn.Dense(self.intermediate_size, dtype=self.dtype, kernel_init=kernel_init) - self.c_proj = nn.Dense(embed_dim, dtype=self.dtype, kernel_init=kernel_init) - self.act = ACT2FN[self.config.activation_function] - self.dropout = nn.Dropout(rate=self.config.resid_dropout) - - def __call__(self, hidden_states, deterministic: bool = True): - hidden_states = self.c_fc(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.c_proj(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxGPTNeoBlock(nn.Module): - config: GPTNeoConfig - layer_id: int = 0 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - hidden_size = self.config.hidden_size - inner_dim = self.config.intermediate_size if self.config.intermediate_size is not None else 4 * hidden_size - - self.ln_1 = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - self.attn = FlaxGPTNeoAttention(self.config, layer_id=self.layer_id, dtype=self.dtype) - self.ln_2 = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - self.mlp = FlaxGPTNeoMLP(self.config, inner_dim, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - residual = hidden_states - hidden_states = self.ln_1(hidden_states) - outputs = self.attn( - hidden_states, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - # residual connection - attn_output = outputs[0] - hidden_states = attn_output + residual - - residual = hidden_states - hidden_states = self.ln_2(hidden_states) - feed_forward_hidden_states = self.mlp(hidden_states, deterministic=deterministic) - # residual connection - hidden_states = residual + feed_forward_hidden_states - - return (hidden_states,) + outputs[1:] - - -class FlaxGPTNeoPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = GPTNeoConfig - base_model_prefix = "transformer" - module_class: nn.Module = None - - def __init__( - self, - config: GPTNeoConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, input_ids, attention_mask, position_ids, return_dict=False)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length)) - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(GPT_NEO_INPUTS_DOCSTRING) - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - params: Optional[dict] = None, - past_key_values: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - batch_size, sequence_length = input_ids.shape - - if position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `position_ids` when passing `past_key_values`.") - - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - if attention_mask is None: - attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be changed by FlaxGPTNeoAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - not train, - False, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - return outputs - - -class FlaxGPTNeoBlockCollection(nn.Module): - config: GPTNeoConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.blocks = [ - FlaxGPTNeoBlock(self.config, layer_id=i, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for block in self.blocks: - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = block( - hidden_states, - attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - # this contains possible `None` values - `FlaxGPTNeoModule` will filter them out - outputs = (hidden_states, all_hidden_states, all_attentions) - - return outputs - - -class FlaxGPTNeoModule(nn.Module): - config: GPTNeoConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.embed_dim = self.config.hidden_size - embedding_init = jax.nn.initializers.normal(stddev=self.config.initializer_range) - self.wte = nn.Embed( - self.config.vocab_size, - self.embed_dim, - embedding_init=embedding_init, - ) - self.wpe = nn.Embed( - self.config.max_position_embeddings, - self.embed_dim, - embedding_init=embedding_init, - ) - self.dropout = nn.Dropout(rate=self.config.embed_dropout) - self.h = FlaxGPTNeoBlockCollection(self.config, dtype=self.dtype) - self.ln_f = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - deterministic=True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - input_embeds = self.wte(input_ids.astype("i4")) - position_embeds = self.wpe(position_ids.astype("i4")) - - hidden_states = input_embeds + position_embeds - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - - outputs = self.h( - hidden_states, - attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.ln_f(hidden_states) - - hidden_states = outputs[0] - hidden_states = self.ln_f(hidden_states) - - if output_hidden_states: - all_hidden_states = outputs[1] + (hidden_states,) - outputs = (hidden_states, all_hidden_states) + outputs[2:] - else: - outputs = (hidden_states,) + outputs[1:] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=outputs[1], - attentions=outputs[-1], - ) - - -@add_start_docstrings( - "The bare GPTNeo Model transformer outputting raw hidden-states without any specific head on top.", - GPT_NEO_START_DOCSTRING, -) -class FlaxGPTNeoModel(FlaxGPTNeoPreTrainedModel): - module_class = FlaxGPTNeoModule - - -append_call_sample_docstring(FlaxGPTNeoModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutput, _CONFIG_FOR_DOC) - - -class FlaxGPTNeoForCausalLMModule(nn.Module): - config: GPTNeoConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.transformer = FlaxGPTNeoModule(self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - outputs = self.transformer( - input_ids, - attention_mask, - position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_kernel = self.transformer.variables["params"]["wte"]["embedding"].T - lm_logits = self.lm_head.apply({"params": {"kernel": shared_kernel}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - return (lm_logits,) + outputs[1:] - - return FlaxCausalLMOutput(logits=lm_logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions) - - -@add_start_docstrings( - """ - The GPTNeo Model transformer with a language modeling head on top (linear layer with weights tied to the input - embeddings). - """, - GPT_NEO_START_DOCSTRING, -) -class FlaxGPTNeoForCausalLM(FlaxGPTNeoPreTrainedModel): - module_class = FlaxGPTNeoForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since GPTNeo uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring(FlaxGPTNeoForCausalLM, _CHECKPOINT_FOR_DOC, FlaxCausalLMOutput, _CONFIG_FOR_DOC) - - -__all__ = ["FlaxGPTNeoForCausalLM", "FlaxGPTNeoModel", "FlaxGPTNeoPreTrainedModel"] diff --git a/src/transformers/models/gpt_neo/modeling_gpt_neo.py b/src/transformers/models/gpt_neo/modeling_gpt_neo.py index 69d74565745a..5d1d1beb0405 100755 --- a/src/transformers/models/gpt_neo/modeling_gpt_neo.py +++ b/src/transformers/models/gpt_neo/modeling_gpt_neo.py @@ -14,7 +14,6 @@ # limitations under the License. """PyTorch GPT Neo model.""" -import os from typing import Optional, Union import torch @@ -63,86 +62,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_gpt_neo(model, config, gpt_neo_checkpoint_path): - """Load tf checkpoints in a pytorch model""" - try: - import re - - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(gpt_neo_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - if "global_step" not in name and "adam" not in name: - array = tf.train.load_variable(tf_path, name) - array = tf.dtypes.cast(array.squeeze(), tf.float32).numpy() - name = name.replace("attn/q", "attn/attention/q_proj/w") - name = name.replace("attn/k", "attn/attention/k_proj/w") - name = name.replace("attn/v", "attn/attention/v_proj/w") - name = name.replace("attn/o", "attn/attention/out_proj/w") - name = name.replace("norm_1", "ln_1") - name = name.replace("norm_2", "ln_2") - name = name.replace("attn/compute_output_bias/o_b", "attn/attention/out_proj/b") - name = name.replace("conv1d_main/c_fc/kernel", "c_fc/w") - name = name.replace("conv1d_main/c_fc/bias", "c_fc/b") - name = name.replace("conv1d_main/c_proj/kernel", "c_proj/w") - name = name.replace("conv1d_main/c_proj/bias", "c_proj/b") - - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name[5:] # skip "gpt2/" - name = name.split("/") - pointer = model.transformer - for m_name in name: - if re.fullmatch(r"[A-Za-z]+\d+", m_name): - scope_names = re.split(r"(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "w" or scope_names[0] == "g": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "b": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "wpe" or scope_names[0] == "wte": - pointer = getattr(pointer, scope_names[0]) - pointer = getattr(pointer, "weight") - else: - pointer = getattr(pointer, scope_names[0]) - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - - if name[-1] == "w" and name[-2] in ["out_proj", "k_proj", "q_proj", "v_proj", "c_proj", "c_fc"]: - array = array.transpose() - - if name == ["wte"]: - # if vocab is padded, then trim off the padding embeddings - array = array[: config.vocab_size] - - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched {name}") - - print(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - - # init the final linear layer using word embeddings - embs = model.transformer.wte.weight - lin = nn.Linear(embs.size()[1], embs.size()[0], bias=False) - lin.weight = embs - model.set_output_embeddings(lin) - return model - - class GPTNeoSelfAttention(nn.Module): def __init__(self, config, attention_type, layer_id=None): super().__init__() @@ -470,7 +389,6 @@ def forward( @auto_docstring class GPTNeoPreTrainedModel(PreTrainedModel): config: GPTNeoConfig - load_tf_weights = load_tf_weights_in_gpt_neo base_model_prefix = "transformer" supports_gradient_checkpointing = True _no_split_modules = ["GPTNeoBlock"] @@ -484,8 +402,6 @@ def __init__(self, *inputs, **kwargs): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, (nn.Linear,)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -843,8 +759,6 @@ def forward( if labels is not None: # move labels to correct device to enable model parallelism labels = labels.to(lm_logits.device) - # Compute loss in fp32 to match with mesh-tf version - # https://github.com/EleutherAI/gpt-neo/blob/89ce74164da2fb16179106f54e2269b5da8db333/models/gpt2/gpt2.py#L179 lm_logits = lm_logits.to(torch.float32) # Flatten the tokens @@ -1188,5 +1102,4 @@ def forward( "GPTNeoForTokenClassification", "GPTNeoModel", "GPTNeoPreTrainedModel", - "load_tf_weights_in_gpt_neo", ] diff --git a/src/transformers/models/gptj/__init__.py b/src/transformers/models/gptj/__init__.py index 84d99fda2e69..a814910a8885 100644 --- a/src/transformers/models/gptj/__init__.py +++ b/src/transformers/models/gptj/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_gptj import * - from .modeling_flax_gptj import * from .modeling_gptj import * - from .modeling_tf_gptj import * else: import sys diff --git a/src/transformers/models/gptj/configuration_gptj.py b/src/transformers/models/gptj/configuration_gptj.py index 68c690996880..278bfbf0be96 100644 --- a/src/transformers/models/gptj/configuration_gptj.py +++ b/src/transformers/models/gptj/configuration_gptj.py @@ -18,7 +18,7 @@ from collections.abc import Mapping from typing import Any, Optional -from ... import PreTrainedTokenizer, TensorType, is_torch_available +from ... import PreTrainedTokenizer, is_torch_available from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfigWithPast, PatchingSpec from ...utils import logging @@ -174,10 +174,9 @@ def generate_dummy_inputs( 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 + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) # We need to order the input in the way they appears in the forward() diff --git a/src/transformers/models/gptj/modeling_flax_gptj.py b/src/transformers/models/gptj/modeling_flax_gptj.py deleted file mode 100644 index 12ea7a4fffb4..000000000000 --- a/src/transformers/models/gptj/modeling_flax_gptj.py +++ /dev/null @@ -1,721 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The EleutherAI and 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. - -from functools import partial -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxCausalLMOutput -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_gptj import GPTJConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "gptj" -_CONFIG_FOR_DOC = "GPTJConfig" - - -GPTJ_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`GPTJConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -GPTJ_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`): - `input_ids_length` = `sequence_length`. Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def create_sinusoidal_positions(num_pos, dim): - inv_freq = 1.0 / (10000 ** (np.arange(0, dim, 2) / dim)) - sinusoid_inp = np.einsum("i , j -> i j", np.arange(num_pos), inv_freq).astype("float32") - sin, cos = np.sin(sinusoid_inp), np.cos(sinusoid_inp) - - sentinel = dim // 2 + dim % 2 - out = np.zeros((num_pos, dim)) - out[:, 0:sentinel] = sin - out[:, sentinel:] = cos - - return jnp.array(out) - - -def rotate_every_two(tensor): - rotate_half_tensor = jnp.stack((-tensor[:, :, :, 1::2], tensor[:, :, :, ::2]), axis=-1) - rotate_half_tensor = rotate_half_tensor.reshape(rotate_half_tensor.shape[:-2] + (-1,)) - return rotate_half_tensor - - -def apply_rotary_pos_emb(tensor, sincos): - sin_pos, cos_pos = sincos - sin_pos = sin_pos[:, :, None, :].repeat(2, 3) - cos_pos = cos_pos[:, :, None, :].repeat(2, 3) - return (tensor * cos_pos) + (rotate_every_two(tensor) * sin_pos) - - -class FlaxGPTJAttention(nn.Module): - config: GPTJConfig - dtype: jnp.dtype = jnp.float32 - causal: bool = True - is_cross_attention: bool = False - - def setup(self): - config = self.config - self.embed_dim = config.hidden_size - self.num_heads = config.num_attention_heads - self.head_dim = self.embed_dim // self.num_heads - - self.rotary_dim = config.rotary_dim - - dense = partial( - nn.Dense, - self.embed_dim, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() - self.out_proj = dense() - - self.resid_dropout = nn.Dropout(rate=config.resid_pdrop) - - self.causal_mask = make_causal_mask(jnp.ones((1, config.max_position_embeddings), dtype="bool"), dtype="bool") - - pos_embd_dim = self.rotary_dim or self.embed_dim - self.embed_positions = create_sinusoidal_positions(config.max_position_embeddings, pos_embd_dim) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key - # positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - attention_mask, - position_ids, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - query = self.q_proj(hidden_states) - key = self.k_proj(hidden_states) - value = self.v_proj(hidden_states) - - query = self._split_heads(query) - key = self._split_heads(key) - value = self._split_heads(value) - - sincos = jnp.take(self.embed_positions, position_ids, axis=0) - sincos = jnp.split(sincos, 2, axis=-1) - if self.rotary_dim is not None: - k_rot = key[:, :, :, : self.rotary_dim] - k_pass = key[:, :, :, self.rotary_dim :] - - q_rot = query[:, :, :, : self.rotary_dim] - q_pass = query[:, :, :, self.rotary_dim :] - - k_rot = apply_rotary_pos_emb(k_rot, sincos) - q_rot = apply_rotary_pos_emb(q_rot, sincos) - - key = jnp.concatenate([k_rot, k_pass], axis=-1) - query = jnp.concatenate([q_rot, q_pass], axis=-1) - else: - key = apply_rotary_pos_emb(key, sincos) - query = apply_rotary_pos_emb(query, sincos) - - query_length, key_length = query.shape[1], key.shape[1] - - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - - batch_size = hidden_states.shape[0] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - - dropout_rng = None - if not deterministic and self.config.attn_pdrop > 0.0: - dropout_rng = self.make_rng("dropout") - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.has_variable("cache", "cached_key") or init_cache: - key, value, attention_mask = self._concatenate_to_cache(key, value, query, attention_mask) - - # transform boolean mask into float mask - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - - # usual dot product attention - attn_weights = dot_product_attention_weights( - query, - key, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attn_pdrop, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - attn_output = self.resid_dropout(attn_output, deterministic=deterministic) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxGPTJMLP(nn.Module): - config: GPTJConfig - intermediate_size: int - dtype: jnp.dtype = jnp.float32 - - def setup(self): - embed_dim = self.config.hidden_size - kernel_init = jax.nn.initializers.normal(self.config.initializer_range) - - self.fc_in = nn.Dense(self.intermediate_size, dtype=self.dtype, kernel_init=kernel_init) - self.fc_out = nn.Dense(embed_dim, dtype=self.dtype, kernel_init=kernel_init) - - self.act = ACT2FN[self.config.activation_function] - self.dropout = nn.Dropout(rate=self.config.resid_pdrop) - - def __call__(self, hidden_states, deterministic: bool = True): - hidden_states = self.fc_in(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.fc_out(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxGPTJBlock(nn.Module): - config: GPTJConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - hidden_size = self.config.hidden_size - inner_dim = self.config.n_inner if self.config.n_inner is not None else 4 * hidden_size - - self.ln_1 = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - self.attn = FlaxGPTJAttention(self.config, dtype=self.dtype) - - self.mlp = FlaxGPTJMLP(self.config, inner_dim, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - residual = hidden_states - hidden_states = self.ln_1(hidden_states) - attn_outputs = self.attn( - hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - attn_output = attn_outputs[0] - - feed_forward_hidden_states = self.mlp(hidden_states, deterministic=deterministic) - # residual connection - hidden_states = attn_output + feed_forward_hidden_states + residual - - return (hidden_states,) + attn_outputs[1:] - - -class FlaxGPTJPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = GPTJConfig - base_model_prefix = "transformer" - module_class: nn.Module = None - - def __init__( - self, - config: GPTJConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - if self.config.add_cross_attention: - encoder_hidden_states = jnp.zeros(input_shape + (self.config.n_embd,)) - encoder_attention_mask = attention_mask - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states, - encoder_attention_mask, - return_dict=False, - ) - else: - module_init_outputs = self.module.init(rngs, input_ids, attention_mask, position_ids, return_dict=False) - - random_params = module_init_outputs["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length)) - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return init_variables["cache"] - - @add_start_docstrings_to_model_forward(GPTJ_INPUTS_DOCSTRING) - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - params: Optional[dict] = None, - past_key_values: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - batch_size, sequence_length = input_ids.shape - - if position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `position_ids` when passing `past_key_values`.") - - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - if attention_mask is None: - attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be changed by FlaxGPTJAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - not train, - False, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - return outputs - - -class FlaxGPTJBlockCollection(nn.Module): - config: GPTJConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.blocks = [ - FlaxGPTJBlock(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for block in self.blocks: - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = block( - hidden_states, - attention_mask, - position_ids=position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - # this contains possible `None` values - `FlaxGPTJModule` will filter them out - outputs = (hidden_states, all_hidden_states, all_attentions) - - return outputs - - -class FlaxGPTJModule(nn.Module): - config: GPTJConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.embed_dim = self.config.hidden_size - - self.wte = nn.Embed( - self.config.vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.dropout = nn.Dropout(rate=self.config.embd_pdrop) - self.h = FlaxGPTJBlockCollection(self.config, dtype=self.dtype) - self.ln_f = nn.LayerNorm(epsilon=self.config.layer_norm_epsilon, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - deterministic=True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - input_embeds = self.wte(input_ids.astype("i4")) - - hidden_states = self.dropout(input_embeds, deterministic=deterministic) - - outputs = self.h( - hidden_states, - attention_mask, - position_ids=position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.ln_f(hidden_states) - - if output_hidden_states: - all_hidden_states = outputs[1] + (hidden_states,) - outputs = (hidden_states, all_hidden_states) + outputs[2:] - else: - outputs = (hidden_states,) + outputs[1:] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=outputs[1], - attentions=outputs[-1], - ) - - -@add_start_docstrings( - "The bare GPTJ Model transformer outputting raw hidden-states without any specific head on top.", - GPTJ_START_DOCSTRING, -) -class FlaxGPTJModel(FlaxGPTJPreTrainedModel): - module_class = FlaxGPTJModule - - -append_call_sample_docstring( - FlaxGPTJModel, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxGPTJForCausalLMModule(nn.Module): - config: GPTJConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.transformer = FlaxGPTJModule(self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - outputs = self.transformer( - input_ids, - attention_mask, - position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_kernel = self.transformer.variables["params"]["wte"]["embedding"].T - lm_logits = self.lm_head.apply({"params": {"kernel": shared_kernel}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - return (lm_logits,) + outputs[1:] - - return FlaxCausalLMOutput(logits=lm_logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions) - - -@add_start_docstrings( - """ - The GPTJ Model transformer with a language modeling head on top. - """, - GPTJ_START_DOCSTRING, -) -class FlaxGPTJForCausalLM(FlaxGPTJPreTrainedModel): - module_class = FlaxGPTJForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since GPTJ uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxGPTJForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutput, - _CONFIG_FOR_DOC, -) - - -__all__ = ["FlaxGPTJForCausalLM", "FlaxGPTJModel", "FlaxGPTJPreTrainedModel"] diff --git a/src/transformers/models/gptj/modeling_gptj.py b/src/transformers/models/gptj/modeling_gptj.py index cb6a4f579c52..cf63907dc6bf 100644 --- a/src/transformers/models/gptj/modeling_gptj.py +++ b/src/transformers/models/gptj/modeling_gptj.py @@ -480,8 +480,6 @@ def __init__(self, *inputs, **kwargs): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, (nn.Linear,)): - # Slightly different from Mesh Transformer JAX which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/gptj/modeling_tf_gptj.py b/src/transformers/models/gptj/modeling_tf_gptj.py deleted file mode 100644 index 0ec32258223c..000000000000 --- a/src/transformers/models/gptj/modeling_tf_gptj.py +++ /dev/null @@ -1,1094 +0,0 @@ -# coding=utf-8 -# Copyright 2022 The EleutherAI and HuggingFace Teams. All rights reserved. -# -# 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. -"""TF 2.0 GPT-J model.""" - -from __future__ import annotations - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...file_utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, -) -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPast, - TFCausalLMOutputWithPast, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutputWithPast, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFSharedEmbeddings, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import logging -from .configuration_gptj import GPTJConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "EleutherAI/gpt-j-6B" -_CONFIG_FOR_DOC = "GPTJConfig" - - -def create_sinusoidal_positions(num_pos: int, dim: int) -> tf.Tensor: - inv_freq = tf.cast(1.0 / (10000 ** (tf.range(0, dim, 2) / dim)), tf.float32) - sinusoid_inp = tf.cast(tf.einsum("i , j -> i j", tf.range(num_pos, dtype=tf.float32), inv_freq), tf.float32) - sin, cos = tf.sin(sinusoid_inp), tf.cos(sinusoid_inp) - out = tf.concat((sin, cos), axis=1) - return out - - -def rotate_every_two(x: tf.Tensor) -> tf.Tensor: - rotate_half_tensor = tf.stack((-x[:, :, :, 1::2], x[:, :, :, ::2]), axis=-1) - new_shape = shape_list(rotate_half_tensor)[:-2] + [tf.math.reduce_prod(shape_list(rotate_half_tensor)[-2:])] - rotate_half_tensor = tf.reshape(rotate_half_tensor, new_shape) - return rotate_half_tensor - - -def apply_rotary_pos_emb(tensor: tf.Tensor, sincos: tf.Tensor) -> tf.Tensor: - sin_pos, cos_pos = sincos - sin_pos = tf.repeat(sin_pos[:, :, None, :], 2, 3) - cos_pos = tf.repeat(cos_pos[:, :, None, :], 2, 3) - return (tensor * cos_pos) + (rotate_every_two(tensor) * sin_pos) - - -class TFGPTJAttention(keras.layers.Layer): - def __init__(self, config: GPTJConfig, **kwargs): - super().__init__(**kwargs) - - self.embed_dim = config.hidden_size - self.num_attention_heads = config.num_attention_heads - self.head_dim = self.embed_dim // self.num_attention_heads - if self.head_dim * self.num_attention_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_attention_heads (got `embed_dim`: {self.embed_dim} and" - f" `num_attention_heads`: {self.num_attention_heads})." - ) - self.scale_attn = self.head_dim**0.5 - self.rotary_dim = config.rotary_dim - - self.attn_dropout = keras.layers.Dropout(config.attn_pdrop) - self.resid_dropout = keras.layers.Dropout(config.resid_pdrop) - - self.q_proj = keras.layers.Dense( - self.embed_dim, - use_bias=False, - kernel_initializer=get_initializer(config.initializer_range), - name="q_proj", - ) - self.k_proj = keras.layers.Dense( - self.embed_dim, - use_bias=False, - kernel_initializer=get_initializer(config.initializer_range), - name="k_proj", - ) - self.v_proj = keras.layers.Dense( - self.embed_dim, - use_bias=False, - kernel_initializer=get_initializer(config.initializer_range), - name="v_proj", - ) - self.out_proj = keras.layers.Dense( - self.embed_dim, - use_bias=False, - kernel_initializer=get_initializer(config.initializer_range), - name="out_proj", - ) - - self.max_positions = config.max_position_embeddings - self.lower_triangle_mask = tf.reshape( - tf.cast(tf.experimental.numpy.tril(tf.ones((self.max_positions, self.max_positions))), tf.int8), - (1, 1, self.max_positions, self.max_positions), - ) - pos_embd_dim = self.rotary_dim or self.embed_dim - self.embed_positions = create_sinusoidal_positions(self.max_positions, pos_embd_dim) - - def get_causal_mask(self, key_length, query_length) -> tf.Tensor: - return tf.cast(self.lower_triangle_mask[:, :, key_length - query_length : key_length, :key_length], tf.bool) - - @staticmethod - def get_masked_bias(dtype: tf.DType) -> tf.Tensor: - return tf.cast(tf.constant(-1e9), dtype) - - def _split_heads(self, hidden_states: tf.Tensor, rotary: bool) -> tf.Tensor: - """ - Splits hidden dim into attn_head_size and num_attention_heads - """ - new_shape = shape_list(hidden_states)[:-1] + [self.num_attention_heads, self.head_dim] - hidden_states = tf.reshape(hidden_states, new_shape) - if rotary: - return hidden_states - if len(shape_list(hidden_states)) == 4: - return tf.transpose(hidden_states, (0, 2, 1, 3)) # (batch, head, seq_length, head_features) - if len(shape_list(hidden_states)) == 5: - return tf.transpose(hidden_states, (0, 1, 3, 2, 4)) # (batch, blocks, head, block_length, head_features) - raise ValueError(f"Input tensor rank should be one of [4, 5], but is: {len(shape_list(hidden_states))}") - - def _merge_heads(self, hidden_states: tf.Tensor) -> tf.Tensor: - """ - Merges attn_head_size dim and num_attn_heads dim into hidden dim - """ - if len(shape_list(hidden_states)) == 4: - hidden_states = tf.transpose(hidden_states, (0, 2, 1, 3)) - elif len(shape_list(hidden_states)) == 5: - hidden_states = tf.transpose(hidden_states, (0, 1, 3, 2, 4)) - else: - raise ValueError(f"Input tensor rank should be one of [4, 5], but is: {len(shape_list(hidden_states))}") - new_shape = shape_list(hidden_states)[:-2] + [self.num_attention_heads * self.head_dim] - return tf.reshape(hidden_states, new_shape) - - def _attn( - self, - query: tf.Tensor, - key: tf.Tensor, - value: tf.Tensor, - attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - ) -> tuple[tf.Tensor, tf.Tensor]: - # compute causal mask from causal mask buffer - query_length, key_length = shape_list(query)[-2], shape_list(key)[-2] - causal_mask = self.get_causal_mask(key_length, query_length) - - # Keep the attention weights computation in fp32 to avoid overflow issues - query = tf.cast(query, tf.float32) - key = tf.cast(key, tf.float32) - - attn_weights = tf.matmul(query, key, transpose_b=True) - attn_weights = tf.where(causal_mask, attn_weights, self.get_masked_bias(attn_weights.dtype)) - - attn_weights = attn_weights / self.scale_attn - - if attention_mask is not None: - # Apply the attention mask - attn_weights = attn_weights + attention_mask - - attn_weights = stable_softmax(attn_weights, axis=-1) - attn_weights = tf.cast(attn_weights, value.dtype) - attn_weights = self.attn_dropout(attn_weights) - - # Mask heads if we want to - if head_mask is not None: - attn_weights = attn_weights * head_mask - - attn_output = tf.matmul(attn_weights, value) - - return attn_output, attn_weights - - def call( - self, - hidden_states: tf.Tensor, - layer_past: tuple[tf.Tensor, tf.Tensor] | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - use_cache: bool = False, - output_attentions: bool = False, - ): - query = self.q_proj(hidden_states) - key = self.k_proj(hidden_states) - value = self.v_proj(hidden_states) - - query = self._split_heads(query, True) - key = self._split_heads(key, True) - value = self._split_heads(value, False) - - sincos = tf.cast(tf.gather(self.embed_positions, position_ids, axis=0), hidden_states.dtype) - sincos = tf.split(sincos, 2, axis=-1) - if self.rotary_dim is not None: - k_rot = key[:, :, :, : self.rotary_dim] - k_pass = key[:, :, :, self.rotary_dim :] - - q_rot = query[:, :, :, : self.rotary_dim] - q_pass = query[:, :, :, self.rotary_dim :] - - k_rot = apply_rotary_pos_emb(k_rot, sincos) - q_rot = apply_rotary_pos_emb(q_rot, sincos) - - key = tf.concat((k_rot, k_pass), axis=-1) - query = tf.concat((q_rot, q_pass), axis=-1) - else: - key = apply_rotary_pos_emb(key, sincos) - query = apply_rotary_pos_emb(query, sincos) - - key = tf.transpose(key, (0, 2, 1, 3)) - query = tf.transpose(query, (0, 2, 1, 3)) - - if layer_past is not None: - past_key = layer_past[0] - past_value = layer_past[1] - key = tf.concat((past_key, key), axis=-2) - value = tf.concat((past_value, value), axis=-2) - - if use_cache is True: - present = (key, value) - else: - present = None - - # compute self-attention: V x Softmax(QK^T) - attn_output, attn_weights = self._attn(query, key, value, attention_mask, head_mask) - - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - attn_output = self.resid_dropout(attn_output) - - outputs = (attn_output, present) - if output_attentions: - outputs += (attn_weights,) - - return outputs # a, present, (attentions) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -class TFGPTJMLP(keras.layers.Layer): - def __init__(self, intermediate_size: int, config: GPTJConfig, **kwargs): - super().__init__(**kwargs) - embed_dim = config.n_embd - - self.fc_in = keras.layers.Dense( - intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="fc_in" - ) - self.fc_out = keras.layers.Dense( - embed_dim, kernel_initializer=get_initializer(config.initializer_range), name="fc_out" - ) - - self.act = get_tf_activation(config.activation_function) - self.dropout = keras.layers.Dropout(config.embd_pdrop) - self.embed_dim = config.n_embd - self.intermediate_size = intermediate_size - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.fc_in(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.fc_out(hidden_states) - hidden_states = self.dropout(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "fc_in", None) is not None: - with tf.name_scope(self.fc_in.name): - self.fc_in.build([None, None, self.embed_dim]) - if getattr(self, "fc_out", None) is not None: - with tf.name_scope(self.fc_out.name): - self.fc_out.build([None, None, self.intermediate_size]) - - -class TFGPTJBlock(keras.layers.Layer): - def __init__(self, config: GPTJConfig, **kwargs): - super().__init__(**kwargs) - inner_dim = config.n_inner if config.n_inner is not None else 4 * config.n_embd - self.ln_1 = keras.layers.LayerNormalization(epsilon=config.layer_norm_epsilon, name="ln_1") - self.attn = TFGPTJAttention(config, name="attn") - self.mlp = TFGPTJMLP(inner_dim, config, name="mlp") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - layer_past: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - use_cache: bool = False, - output_attentions: bool = False, - ): - residual = hidden_states - hidden_states = self.ln_1(hidden_states) - attn_outputs = self.attn( - hidden_states=hidden_states, - layer_past=layer_past, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - use_cache=use_cache, - output_attentions=output_attentions, - ) # attn_outputs: attn_output, present, (attentions) - attn_output = attn_outputs[0] - outputs = attn_outputs[1:] - - feed_forward_hidden_states = self.mlp(hidden_states) - hidden_states = attn_output + feed_forward_hidden_states + residual - - if use_cache: - outputs = (hidden_states,) + outputs - else: - outputs = (hidden_states,) + outputs[1:] - return outputs # hidden_states, present, (attentions) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "ln_1", None) is not None: - with tf.name_scope(self.ln_1.name): - self.ln_1.build([None, None, self.config.n_embd]) - if getattr(self, "attn", None) is not None: - with tf.name_scope(self.attn.name): - self.attn.build(None) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - - -@keras_serializable -class TFGPTJMainLayer(keras.layers.Layer): - config_class = GPTJConfig - - def __init__(self, config: GPTJConfig, *inputs, **kwargs): - super().__init__(*inputs, **kwargs) - - self.config = config - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.use_cache = config.use_cache - self.return_dict = config.use_return_dict - - self.num_hidden_layers = config.n_layer - self.n_embd = config.n_embd - self.n_positions = config.n_positions - self.initializer_range = config.initializer_range - - self.wte = TFSharedEmbeddings( - config.vocab_size, config.hidden_size, initializer_range=config.initializer_range, name="wte" - ) - self.drop = keras.layers.Dropout(config.embd_pdrop) - self.h = [TFGPTJBlock(config, name=f"h_._{i}") for i in range(config.n_layer)] - self.ln_f = keras.layers.LayerNormalization(epsilon=config.layer_norm_epsilon, name="ln_f") - self.embed_dim = config.n_embd - - def get_input_embeddings(self): - return self.wte - - def set_input_embeddings(self, value: tf.Tensor): - self.wte.weight = value - self.wte.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids=None, - past_key_values=None, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - inputs_embeds=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ) -> TFBaseModelOutputWithPast | tuple[tf.Tensor]: - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - input_ids = tf.reshape(input_ids, [-1, input_shape[-1]]) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if past_key_values is None: - past_length = 0 - past_key_values = [None] * len(self.h) - else: - past_length = shape_list(past_key_values[0][0])[-2] - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(past_length, input_shape[-1] + past_length), axis=0) - - if attention_mask is not None: - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - attention_mask = tf.reshape(attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - one_cst = tf.constant(1.0) - attention_mask = tf.cast(attention_mask, dtype=one_cst.dtype) - attention_mask = tf.multiply(tf.subtract(one_cst, attention_mask), tf.constant(-10000.0)) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.num_hidden_layers - # head_mask = tf.constant([0] * self.num_hidden_layers) - - position_ids = tf.reshape(position_ids, [-1, shape_list(position_ids)[-1]]) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.wte.vocab_size) - inputs_embeds = self.wte(input_ids, mode="embedding") - - if token_type_ids is not None: - token_type_ids = tf.reshape(token_type_ids, [-1, shape_list(token_type_ids)[-1]]) - token_type_embeds = self.wte(token_type_ids, mode="embedding") - else: - token_type_embeds = tf.constant(0.0) - - token_type_embeds = tf.cast(token_type_embeds, dtype=inputs_embeds.dtype) - hidden_states = inputs_embeds + token_type_embeds - hidden_states = self.drop(hidden_states, training=training) - - output_shape = input_shape + [shape_list(hidden_states)[-1]] - - presents = () if use_cache else None - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - for i, (block, layer_past) in enumerate(zip(self.h, past_key_values)): - if output_hidden_states: - all_hidden_states = all_hidden_states + (tf.reshape(hidden_states, output_shape),) - - outputs = block( - hidden_states=hidden_states, - layer_past=layer_past, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask[i], - use_cache=use_cache, - output_attentions=output_attentions, - training=training, - ) - - hidden_states = outputs[0] - if use_cache: - presents = presents + (outputs[1],) - - if output_attentions: - all_attentions = all_attentions + (outputs[2 if use_cache else 1],) - - hidden_states = self.ln_f(hidden_states) - - hidden_states = tf.reshape(hidden_states, output_shape) - # Add last hidden state - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if output_attentions: - # let the number of heads free (-1) so we can extract attention even after head pruning - attention_output_shape = input_shape[:-1] + [-1] + shape_list(all_attentions[0])[-2:] - all_attentions = tuple(tf.reshape(t, attention_output_shape) for t in all_attentions) - - if not return_dict: - return tuple(v for v in [hidden_states, presents, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutputWithPast( - last_hidden_state=hidden_states, - past_key_values=presents, - hidden_states=all_hidden_states, - attentions=all_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "wte", None) is not None: - with tf.name_scope(self.wte.name): - self.wte.build(None) - if getattr(self, "ln_f", None) is not None: - with tf.name_scope(self.ln_f.name): - self.ln_f.build([None, None, self.embed_dim]) - if getattr(self, "h", None) is not None: - for layer in self.h: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFGPTJPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = GPTJConfig - base_model_prefix = "transformer" - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"h.\d+.attn.bias"] - - -GPTJ_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`GPTJConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -GPTJ_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, input_ids_length)`): - `input_ids_length` = `sequence_length` if `past` is `None` else `past[0].shape[-2]` (`sequence_length` of - input past key value states). Indices of input sequence tokens in the vocabulary. - - If `past` is used, only input IDs that do not have their past calculated should be passed as `input_ids`. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - past_key_values (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states (key and values in the attention blocks) as computed by the model (see - `past` output below). Can be used to speed up sequential decoding. The token ids which have their past - given to this model should not be passed as input ids as they have already been computed. - attention_mask (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, input_ids_length)`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, input_ids_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, input_ids_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare GPT-J Model transformer outputting raw hidden-states without any specific head on top.", - GPTJ_START_DOCSTRING, -) -class TFGPTJModel(TFGPTJPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFGPTJMainLayer(config, name="transformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(GPTJ_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPast, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPast | tuple[tf.Tensor]: - r""" - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past`). Set to `False` during training, `True` during generation - """ - - outputs = self.transformer( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -@add_start_docstrings( - """ - The GPT-J Model transformer with a language modeling head on top. - """, - GPTJ_START_DOCSTRING, -) -class TFGPTJForCausalLM(TFGPTJPreTrainedModel, TFCausalLanguageModelingLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFGPTJMainLayer(config, name="transformer") - self.lm_head = keras.layers.Dense( - config.vocab_size, kernel_initializer=get_initializer(config.initializer_range), name="lm_head" - ) - self.config = config - - def prepare_inputs_for_generation(self, inputs, past_key_values=None, use_cache=None, **kwargs): - token_type_ids = kwargs.get("token_type_ids") - # only last token for inputs_ids if past is defined in kwargs - if past_key_values: - inputs = tf.expand_dims(inputs[:, -1], -1) - if token_type_ids is not None: - token_type_ids = tf.expand_dims(token_type_ids[:, -1], -1) - - position_ids = kwargs.get("position_ids") - attention_mask = kwargs.get("attention_mask") - - if attention_mask is not None and position_ids is None: - position_ids = tf.math.cumsum(attention_mask, axis=-1, exclusive=True) - if past_key_values: - position_ids = tf.expand_dims(position_ids[:, -1], -1) - - return { - "input_ids": inputs, - "attention_mask": attention_mask, - "position_ids": position_ids, - "past_key_values": past_key_values, - "use_cache": use_cache, - "token_type_ids": token_type_ids, - } - - @unpack_inputs - @add_start_docstrings_to_model_forward(GPTJ_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutputWithPast, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFCausalLMOutputWithPast | tuple[tf.Tensor]: - r""" - labels (`np.ndarray` or `tf.Tensor` of shape `(batch_size, input_ids_length)`, *optional*): - Labels for language modeling. Note that the labels **are shifted** inside the model, i.e. you can set - `labels = input_ids` Indices are selected in `[-100, 0, ..., config.vocab_size]` All labels set to `-100` - are ignored (masked), the loss is only computed for labels in `[0, ..., config.vocab_size]` - """ - - transformer_outputs = self.transformer( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = transformer_outputs[0] - lm_logits = self.lm_head(hidden_states) - - loss = None - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = lm_logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels, shifted_logits) - - if not return_dict: - output = (lm_logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithPast( - loss=loss, - logits=lm_logits, - past_key_values=transformer_outputs.past_key_values, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build([None, None, self.config.n_embd]) - - -@add_start_docstrings( - """ - The GPT-J Model transformer with a sequence classification head on top (linear layer). - - [`GPTJForSequenceClassification`] uses the last token in order to do the classification, as other causal models - (e.g. GPT, GPT-2, GPT-Neo) do. - - Since it does classification on the last token, it requires to know the position of the last token. If a - `pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If - no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the - padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in - each row of the batch). - """, - GPTJ_START_DOCSTRING, -) -class TFGPTJForSequenceClassification(TFGPTJPreTrainedModel, TFSequenceClassificationLoss): - _keys_to_ignore_on_load_missing = [r"h.\d+.attn.masked_bias", r"h.\d+.attn.bias", r"lm_head.weight"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.transformer = TFGPTJMainLayer(config, name="transformer") - self.score = keras.layers.Dense( - self.num_labels, - use_bias=False, - kernel_initializer=get_initializer(config.initializer_range), - name="score", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(GPTJ_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutputWithPast, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutputWithPast | tuple[tf.Tensor]: - r""" - labels (`np.ndarray` or `tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - if labels is not None and self.config.pad_token_id is None and input_ids.shape[0] != 1: - raise ValueError("Cannot handle batch sizes > 1 if no padding token is defined.") - - transformer_outputs = self.transformer( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = transformer_outputs[0] - logits = self.score(hidden_states) - logits_shape = shape_list(logits) - batch_size = logits_shape[0] - - if self.config.pad_token_id is None: - last_non_pad_token = tf.fill((batch_size,), value=logits_shape[1] - 1) - else: - if input_ids is not None: - token_indices = tf.range(shape_list(input_ids)[-1]) - non_pad_mask = tf.cast(input_ids != self.config.pad_token_id, token_indices.dtype) - last_non_pad_token = tf.reduce_max(token_indices * non_pad_mask, axis=-1) - else: - last_non_pad_token = tf.fill((batch_size,), value=logits_shape[1] - 1) - logger.warning_once( - f"{self.__class__.__name__} will not detect padding tokens in `inputs_embeds`. Results may be " - "unexpected if using padding tokens in conjunction with `inputs_embeds.`" - ) - loss = None - - pooled_logits = tf.gather(logits, last_non_pad_token, batch_dims=1, axis=1) - - if labels is not None: - if self.config.pad_token_id is None and logits_shape[0] != 1: - raise ValueError("Cannot handle batch sizes > 1 if no padding token is defined.") - - loss = self.hf_compute_loss(tf.reshape(labels, [-1]), tf.reshape(pooled_logits, [-1, self.num_labels])) - - if not return_dict: - output = (pooled_logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutputWithPast( - loss=loss, - logits=pooled_logits, - past_key_values=transformer_outputs.past_key_values, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "score", None) is not None: - with tf.name_scope(self.score.name): - self.score.build([None, None, self.config.n_embd]) - - -@add_start_docstrings( - """ - The GPT-J Model transformer with a span classification head on top for extractive question-answering tasks like - SQuAD (a linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - GPTJ_START_DOCSTRING, -) -class TFGPTJForQuestionAnswering(TFGPTJPreTrainedModel, TFQuestionAnsweringLoss): - _keys_to_ignore_on_load_missing = [r"h.\d+.attn.masked_bias", r"h.\d+.attn.bias", r"lm_head.weight"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.transformer = TFGPTJMainLayer(config, name="transformer") - self.qa_outputs = keras.layers.Dense( - self.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(GPTJ_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`np.ndarray` or `tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`np.ndarray` or `tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - - transformer_outputs = self.transformer( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = transformer_outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + transformer_outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFGPTJForCausalLM", - "TFGPTJForQuestionAnswering", - "TFGPTJForSequenceClassification", - "TFGPTJModel", - "TFGPTJPreTrainedModel", -] diff --git a/src/transformers/models/grounding_dino/image_processing_grounding_dino.py b/src/transformers/models/grounding_dino/image_processing_grounding_dino.py index 24e3c8b3f987..737cf2e670ee 100644 --- a/src/transformers/models/grounding_dino/image_processing_grounding_dino.py +++ b/src/transformers/models/grounding_dino/image_processing_grounding_dino.py @@ -18,7 +18,7 @@ import pathlib from collections import defaultdict from collections.abc import Iterable -from typing import TYPE_CHECKING, Any, Callable, Optional, Union +from typing import TYPE_CHECKING, Any, Optional, Union import numpy as np @@ -54,11 +54,7 @@ from ...utils import ( ExplicitEnum, TensorType, - is_flax_available, - is_jax_tensor, is_scipy_available, - is_tf_available, - is_tf_tensor, is_torch_available, is_torch_tensor, is_vision_available, @@ -200,31 +196,6 @@ def get_image_size_for_max_height_width( return new_height, new_width -# Copied from transformers.models.detr.image_processing_detr.get_numpy_to_framework_fn -def get_numpy_to_framework_fn(arr) -> Callable: - """ - Returns a function that converts a numpy array to the framework of the input array. - - Args: - arr (`np.ndarray`): The array to convert. - """ - if isinstance(arr, np.ndarray): - return np.array - if is_tf_available() and is_tf_tensor(arr): - import tensorflow as tf - - return tf.convert_to_tensor - if is_torch_available() and is_torch_tensor(arr): - import torch - - return torch.tensor - if is_flax_available() and is_jax_tensor(arr): - import jax.numpy as jnp - - return jnp.array - raise ValueError(f"Cannot convert arrays of type {type(arr)}") - - # Copied from transformers.models.detr.image_processing_detr.safe_squeeze def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: """ @@ -1241,10 +1212,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -1429,10 +1398,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor.") validate_kwargs(captured_kwargs=kwargs.keys(), valid_processor_keys=self._valid_processor_keys) # Here, the pad() method pads to the maximum of (width, height). It does not need to be validated. diff --git a/src/transformers/models/grounding_dino/modeling_grounding_dino.py b/src/transformers/models/grounding_dino/modeling_grounding_dino.py index 5d674caca6fa..594524c8dd1c 100644 --- a/src/transformers/models/grounding_dino/modeling_grounding_dino.py +++ b/src/transformers/models/grounding_dino/modeling_grounding_dino.py @@ -861,11 +861,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -1418,8 +1413,6 @@ def _init_weights(self, module): module.vision_param.data.fill_(1e-4) module.text_param.data.fill_(1e-4) elif isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/groupvit/__init__.py b/src/transformers/models/groupvit/__init__.py index ab7fa27d09d1..10c315e28015 100644 --- a/src/transformers/models/groupvit/__init__.py +++ b/src/transformers/models/groupvit/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_groupvit import * from .modeling_groupvit import * - from .modeling_tf_groupvit import * else: import sys diff --git a/src/transformers/models/groupvit/configuration_groupvit.py b/src/transformers/models/groupvit/configuration_groupvit.py index d17288ede723..cd9fb2d0469e 100644 --- a/src/transformers/models/groupvit/configuration_groupvit.py +++ b/src/transformers/models/groupvit/configuration_groupvit.py @@ -16,7 +16,7 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig @@ -25,7 +25,6 @@ if TYPE_CHECKING: from ...processing_utils import ProcessorMixin - from ...utils import TensorType logger = logging.get_logger(__name__) @@ -389,13 +388,15 @@ def generate_dummy_inputs( processor: "ProcessorMixin", batch_size: int = -1, seq_length: int = -1, - framework: Optional["TensorType"] = None, ) -> Mapping[str, Any]: text_input_dict = super().generate_dummy_inputs( - processor.tokenizer, batch_size=batch_size, seq_length=seq_length, framework=framework + processor.tokenizer, + batch_size=batch_size, + seq_length=seq_length, ) image_input_dict = super().generate_dummy_inputs( - processor.image_processor, batch_size=batch_size, framework=framework + processor.image_processor, + batch_size=batch_size, ) return {**text_input_dict, **image_input_dict} diff --git a/src/transformers/models/groupvit/modeling_groupvit.py b/src/transformers/models/groupvit/modeling_groupvit.py index 775ebd286f0a..65fdaaa784d3 100644 --- a/src/transformers/models/groupvit/modeling_groupvit.py +++ b/src/transformers/models/groupvit/modeling_groupvit.py @@ -752,8 +752,6 @@ def _init_weights(self, module): init_range = self.config.initializer_range if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=init_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/groupvit/modeling_tf_groupvit.py b/src/transformers/models/groupvit/modeling_tf_groupvit.py deleted file mode 100644 index 1c999dca5f48..000000000000 --- a/src/transformers/models/groupvit/modeling_tf_groupvit.py +++ /dev/null @@ -1,2141 +0,0 @@ -# coding=utf-8 -# Copyright 2022 NVIDIA and The HuggingFace Team. All rights reserved. -# -# 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. -"""TF 2.0 GroupViT model.""" - -from __future__ import annotations - -import collections.abc -import math -from dataclasses import dataclass -from typing import Any - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import TFBaseModelOutput, TFBaseModelOutputWithPooling -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - is_tensorflow_probability_available, - logging, - replace_return_docstrings, -) -from .configuration_groupvit import GroupViTConfig, GroupViTTextConfig, GroupViTVisionConfig - - -logger = logging.get_logger(__name__) - -# soft dependency -if is_tensorflow_probability_available(): - try: - import tensorflow_probability as tfp - - # On the first call, check whether a compatible version of TensorFlow is installed - # TensorFlow Probability depends on a recent stable release of TensorFlow - _ = tfp.distributions.Normal(loc=0.0, scale=1.0) - except ImportError: - logger.error( - "GroupViT models are not usable since `tensorflow_probability` can't be loaded. " - "It seems you have `tensorflow_probability` installed with the wrong tensorflow version." - "Please try to reinstall it following the instructions here: https://github.com/tensorflow/probability." - ) -else: - try: - import tensorflow_probability as tfp - - # On the first call, check whether a compatible version of TensorFlow is installed - # TensorFlow Probability depends on a recent stable release of TensorFlow - _ = tfp.distributions.Normal(loc=0.0, scale=1.0) - except ImportError: - pass - -_CHECKPOINT_FOR_DOC = "nvidia/groupvit-gcc-yfcc" - - -LARGE_NEGATIVE = -1e8 - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -# contrastive loss function, adapted from -# https://sachinruk.github.io/blog/pytorch/pytorch%20lightning/loss%20function/gpu/2021/03/07/CLIP.html -def contrastive_loss(logits: tf.Tensor) -> tf.Tensor: - return tf.math.reduce_mean( - keras.metrics.sparse_categorical_crossentropy( - y_true=tf.range(shape_list(logits)[0]), y_pred=logits, from_logits=True - ) - ) - - -# Copied from transformers.models.clip.modeling_tf_clip.clip_loss with clip->groupvit -def groupvit_loss(similarity: tf.Tensor) -> tf.Tensor: - caption_loss = contrastive_loss(similarity) - image_loss = contrastive_loss(tf.transpose(similarity)) - return (caption_loss + image_loss) / 2.0 - - -def hard_softmax(logits: tf.Tensor, dim: int) -> tf.Tensor: - y_soft = stable_softmax(logits, dim) - # Straight through. - index = tf.argmax(y_soft, dim) - y_hard = tf.one_hot( - index, - depth=shape_list(logits)[dim], - # TensorFlow expects axis to be -1 or between [0, 3). But received: -2 - # This is why the following code snippet is used. - axis=range(len(shape_list(logits)))[dim], - dtype=y_soft.dtype, - ) - ret = y_hard - tf.stop_gradient(y_soft) + y_soft - - return ret - - -def gumbel_softmax(logits: tf.Tensor, tau: float = 1, hard: bool = False, dim: int = -1) -> tf.Tensor: - gumbel_dist = tfp.distributions.Gumbel(0.0, 1.0) - gumbels = gumbel_dist.sample(tf.shape(logits), dtype=logits.dtype) - - gumbels = (logits + gumbels) / tau # ~Gumbel(logits,tau) - y_soft = stable_softmax(gumbels, dim) - - if hard: - # Straight through. - index = tf.argmax(y_soft, dim) - y_hard = tf.one_hot( - index, - depth=shape_list(logits)[dim], - # TensorFlow expects axis to be -1 or between [0, 3). But received: -2 - # This is why the following code snippet is used. - axis=range(len(shape_list(logits)))[dim], - dtype=y_soft.dtype, - ) - ret = y_hard - tf.stop_gradient(y_soft) + y_soft - else: - # Reparametrization trick. - ret = y_soft - return ret - - -def resize_attention_map(attentions: tf.Tensor, height: int, width: int, align_corners: bool = False) -> tf.Tensor: - """ - Args: - attentions (`tf.Tensor`): attention map of shape [batch_size, groups, feat_height*feat_width] - height (`int`): height of the output attention map - width (`int`): width of the output attention map - align_corners (`bool`, *optional*): the `align_corner` argument for `nn.functional.interpolate`. - - Returns: - `tf.Tensor`: resized attention map of shape [batch_size, groups, height, width] - """ - - scale = (height * width // attentions.shape[2]) ** 0.5 - if height > width: - feat_width = int(np.round(width / scale)) - feat_height = shape_list(attentions)[2] // feat_width - else: - feat_height = int(np.round(height / scale)) - feat_width = shape_list(attentions)[2] // feat_height - - batch_size = shape_list(attentions)[0] - groups = shape_list(attentions)[1] # number of group token - # [batch_size, groups, height x width, groups] -> [batch_size, groups, height, width] - attentions = tf.reshape(attentions, (batch_size, groups, feat_height, feat_width)) - attentions = tf.transpose(attentions, perm=(0, 2, 3, 1)) - if align_corners: - attentions = tf.compat.v1.image.resize( - attentions, - size=(height, width), - method="bilinear", - align_corners=align_corners, - ) - else: - attentions = tf.image.resize(attentions, size=(height, width), method="bilinear") - attentions = tf.transpose(attentions, perm=(0, 3, 1, 2)) - return attentions - - -def get_grouping_from_attentions(attentions: tuple[tf.Tensor], hw_shape: tuple[int]) -> tf.Tensor: - """ - Args: - attentions (`tuple(tf.Tensor)`: tuple of attention maps returned by `TFGroupViTVisionTransformer` - hw_shape (`tuple(int)`): height and width of the output attention map - Returns: - `tf.Tensor`: the attention map of shape [batch_size, groups, height, width] - """ - - attn_maps = [] - prev_attn_masks = None - for attn_masks in attentions: - # [batch_size, num_groups, height x width] -> [batch_size, height x width, num_groups] - attn_masks = tf.transpose(attn_masks, perm=(0, 2, 1)) - if prev_attn_masks is None: - prev_attn_masks = attn_masks - else: - prev_attn_masks = tf.matmul(prev_attn_masks, attn_masks) - # [batch_size, height x width, num_groups] -> [batch_size, num_groups, height x width] -> [batch_size, num_groups, height, width] - cur_attn_map = resize_attention_map(tf.transpose(prev_attn_masks, perm=(0, 2, 1)), *hw_shape) - attn_maps.append(cur_attn_map) - - # [batch_size, num_groups, height, width] - final_grouping = attn_maps[-1] - - return tf.stop_gradient(final_grouping) - - -@dataclass -class TFGroupViTModelOutput(ModelOutput): - """ - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `return_loss` is `True`): - Contrastive loss for image-text similarity. - logits_per_image (`tf.Tensor` of shape `(image_batch_size, text_batch_size)`): - The scaled dot product scores between `image_embeds` and `text_embeds`. This represents the image-text - similarity scores. - logits_per_text (`tf.Tensor` of shape `(text_batch_size, image_batch_size)`): - The scaled dot product scores between `text_embeds` and `image_embeds`. This represents the text-image - similarity scores. - segmentation_logits (`tf.Tensor` of shape `(batch_size, config.num_labels, logits_height, logits_width)`): - Classification scores for each pixel. - - - - The logits returned do not necessarily have the same size as the `pixel_values` passed as inputs. This is - to avoid doing two interpolations and lose some quality when a user needs to resize the logits to the - original image size as post-processing. You should always check your logits shape and resize as needed. - - - - text_embeds (`tf.Tensor` of shape `(batch_size, output_dim`): - The text embeddings obtained by applying the projection layer to the pooled output of - [`TFGroupViTTextModel`]. - image_embeds (`tf.Tensor` of shape `(batch_size, output_dim`): - The image embeddings obtained by applying the projection layer to the pooled output of - [`TFGroupViTVisionModel`]. - text_model_output (`TFBaseModelOutputWithPooling`): - The output of the [`TFGroupViTTextModel`]. - vision_model_output (`TFBaseModelOutputWithPooling`): - The output of the [`TFGroupViTVisionModel`]. - """ - - loss: tf.Tensor | None = None - logits_per_image: tf.Tensor | None = None - logits_per_text: tf.Tensor | None = None - segmentation_logits: tf.Tensor | None = None - text_embeds: tf.Tensor | None = None - image_embeds: tf.Tensor | None = None - text_model_output: TFBaseModelOutputWithPooling = None - vision_model_output: TFBaseModelOutputWithPooling = None - - def to_tuple(self) -> tuple[Any]: - return tuple( - self[k] if k not in ["text_model_output", "vision_model_output"] else getattr(self, k).to_tuple() - for k in self.keys() - ) - - -class TFGroupViTCrossAttentionLayer(keras.layers.Layer): - def __init__(self, config: GroupViTVisionConfig, **kwargs): - super().__init__(**kwargs) - self.attn = TFGroupViTAttention(config, name="attn") - self.norm2 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="norm2") - self.mlp = TFGroupViTMLP(config, name="mlp") - self.norm_post = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="norm_post") - self.config = config - - def call(self, query: tf.Tensor, key: tf.Tensor, training: bool = False) -> tf.Tensor: - x = query - x = x + self.attn(query, encoder_hidden_states=key)[0] - x = x + self.mlp(self.norm2(x)) - x = self.norm_post(x) - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attn", None) is not None: - with tf.name_scope(self.attn.name): - self.attn.build(None) - if getattr(self, "norm2", None) is not None: - with tf.name_scope(self.norm2.name): - self.norm2.build([None, None, self.config.hidden_size]) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "norm_post", None) is not None: - with tf.name_scope(self.norm_post.name): - self.norm_post.build([None, None, self.config.hidden_size]) - - -class TFGroupViTAssignAttention(keras.layers.Layer): - def __init__(self, config: GroupViTVisionConfig, **kwargs): - super().__init__(**kwargs) - self.scale = config.hidden_size**-0.5 - - self.q_proj = keras.layers.Dense(config.hidden_size, name="q_proj") - self.k_proj = keras.layers.Dense(config.hidden_size, name="k_proj") - self.v_proj = keras.layers.Dense(config.hidden_size, name="v_proj") - self.proj = keras.layers.Dense(config.hidden_size, name="proj") - self.assign_eps = config.assign_eps - self.config = config - - def get_attn(self, attn: tf.Tensor, gumbel: bool = True, hard: bool = True, training: bool = False) -> tf.Tensor: - if gumbel and training: - attn = gumbel_softmax(attn, dim=-2, hard=hard) - else: - if hard: - attn = hard_softmax(attn, dim=-2) - else: - attn = stable_softmax(attn, axis=-2) - - return attn - - def call(self, query: tf.Tensor, key: tf.Tensor, training: bool = False): - value = key - # [batch_size, query_length, channels] - query = self.q_proj(query) - - # [batch_size, key_length, channels] - key = self.k_proj(key) - - # [batch_size, key_length, channels] - value = self.v_proj(value) - - # [batch_size, query_length, key_length] - raw_attn = tf.matmul(query, key, transpose_b=True) * self.scale - - attn = self.get_attn(raw_attn, training=training) - soft_attn = self.get_attn(raw_attn, training=training, gumbel=False, hard=False) - - attn = attn / (tf.math.reduce_sum(attn, axis=-1, keepdims=True) + self.assign_eps) - - out = tf.matmul(attn, value) - - out = self.proj(out) - - return out, soft_attn - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.config.hidden_size]) - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.config.hidden_size]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.config.hidden_size]) - if getattr(self, "proj", None) is not None: - with tf.name_scope(self.proj.name): - self.proj.build([None, None, self.config.hidden_size]) - - -class TFGroupViTTokenAssign(keras.layers.Layer): - def __init__(self, config: GroupViTVisionConfig, num_group_token: int, num_output_group: int, **kwargs): - super().__init__(**kwargs) - self.num_output_group = num_output_group - # norm on group_tokens - self.norm_tokens = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="norm_tokens") - assign_mlp_ratio = ( - config.assign_mlp_ratio - if isinstance(config.assign_mlp_ratio, collections.abc.Iterable) - else (config.assign_mlp_ratio, config.assign_mlp_ratio) - ) - tokens_dim, channels_dim = [int(x * config.hidden_size) for x in assign_mlp_ratio] - self.mlp_inter = TFGroupViTMixerMLP(config, num_group_token, tokens_dim, num_output_group, name="mlp_inter") - self.norm_post_tokens = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="norm_post_tokens") - # norm on x - self.norm_x = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="norm_x") - self.pre_assign_attn = TFGroupViTCrossAttentionLayer(config, name="pre_assign_attn") - - self.assign = TFGroupViTAssignAttention(config, name="assign") - self.norm_new_x = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="norm_new_x") - self.mlp_channels = TFGroupViTMLP( - config, config.hidden_size, channels_dim, config.hidden_size, name="mlp_channels" - ) - self.config = config - - def project_group_token(self, group_tokens: tf.Tensor) -> tf.Tensor: - """ - Args: - group_tokens (tf.Tensor): group tokens, [batch_size, num_group_tokens, channels] - - Returns: - projected_group_tokens (tf.Tensor): [batch_size, num_output_groups, channels] - """ - # [B, num_output_groups, C] <- [B, num_group_tokens, C] - projected_group_tokens = self.mlp_inter(group_tokens) - projected_group_tokens = self.norm_post_tokens(projected_group_tokens) - return projected_group_tokens - - def call(self, image_tokens: tf.Tensor, group_tokens: tf.Tensor, training: bool = False): - """ - Args: - image_tokens (`tf.Tensor`): image tokens, of shape [batch_size, input_length, channels] - group_tokens (`tf.Tensor`): group tokens, [batch_size, num_group_tokens, channels] - """ - - group_tokens = self.norm_tokens(group_tokens) - image_tokens = self.norm_x(image_tokens) - # [batch_size, num_output_groups, channels] - projected_group_tokens = self.project_group_token(group_tokens) - projected_group_tokens = self.pre_assign_attn(projected_group_tokens, image_tokens) - new_image_tokens, attention = self.assign(projected_group_tokens, image_tokens) - new_image_tokens += projected_group_tokens - - new_image_tokens = new_image_tokens + self.mlp_channels(self.norm_new_x(new_image_tokens)) - - return new_image_tokens, attention - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "norm_tokens", None) is not None: - with tf.name_scope(self.norm_tokens.name): - self.norm_tokens.build([None, None, self.config.hidden_size]) - if getattr(self, "mlp_inter", None) is not None: - with tf.name_scope(self.mlp_inter.name): - self.mlp_inter.build(None) - if getattr(self, "norm_post_tokens", None) is not None: - with tf.name_scope(self.norm_post_tokens.name): - self.norm_post_tokens.build([None, None, self.config.hidden_size]) - if getattr(self, "norm_x", None) is not None: - with tf.name_scope(self.norm_x.name): - self.norm_x.build([None, None, self.config.hidden_size]) - if getattr(self, "pre_assign_attn", None) is not None: - with tf.name_scope(self.pre_assign_attn.name): - self.pre_assign_attn.build(None) - if getattr(self, "assign", None) is not None: - with tf.name_scope(self.assign.name): - self.assign.build(None) - if getattr(self, "norm_new_x", None) is not None: - with tf.name_scope(self.norm_new_x.name): - self.norm_new_x.build([None, None, self.config.hidden_size]) - if getattr(self, "mlp_channels", None) is not None: - with tf.name_scope(self.mlp_channels.name): - self.mlp_channels.build(None) - - -# Adapted from transformers.models.vit.modeling_tf_vit.TFViTPatchEmbeddings with ViT->GroupViT -class TFGroupViTPatchEmbeddings(keras.layers.Layer): - """ - This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial - `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a - Transformer. - """ - - def __init__(self, config: GroupViTConfig, **kwargs): - super().__init__(**kwargs) - image_size, patch_size = config.image_size, config.patch_size - num_channels = config.num_channels - # hidden_size is a member as it will be required in the call method - self.hidden_size = config.hidden_size - - image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) - patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) - num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) - self.image_size = image_size - self.patch_size = patch_size - self.num_patches = num_patches - self.num_channels = num_channels - self.config = config - - self.projection = keras.layers.Conv2D( - filters=self.hidden_size, - kernel_size=patch_size, - strides=patch_size, - padding="valid", - data_format="channels_last", - use_bias=True, - kernel_initializer=get_initializer(self.config.initializer_range), - bias_initializer="zeros", - name="projection", - ) - - def call( - self, pixel_values: tf.Tensor, interpolate_pos_encoding: bool = False, training: bool = False - ) -> tf.Tensor: - batch_size, num_channels, height, width = shape_list(pixel_values) - if tf.executing_eagerly() and num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - if ( - not interpolate_pos_encoding - and tf.executing_eagerly() - and (height != self.image_size[0] or width != self.image_size[1]) - ): - raise ValueError( - f"Input image size ({height}*{width}) doesn't match model ({self.image_size[0]}*{self.image_size[1]})." - ) - - # When running on CPU, `keras.layers.Conv2D` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - # shape = (batch_size, in_height, in_width, in_channels=num_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - - projection = self.projection(pixel_values) - - # Change the 2D spatial dimensions to a single temporal dimension. - # shape = (batch_size, num_patches, out_channels=embed_dim) - num_patches = (width // self.patch_size[1]) * (height // self.patch_size[0]) - # In the TFGroupViTVisionEmbeddings the embeddings from this layer will be layer normalized - # LayerNormalization layer needs to have static last dimension (otherwise the test_keras_save_load fails with symbolic tensors) - # This is why we have used the hidden_size in the reshape method - embeddings = tf.reshape(tensor=projection, shape=(batch_size, num_patches, self.hidden_size)) - - return embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, None, self.num_channels]) - - -# Adapted from transformers.vit.modeling_tf_vit.TFViTEmbeddings -class TFGroupViTVisionEmbeddings(keras.layers.Layer): - """ - Construct the position and patch embeddings. - - """ - - def __init__(self, config: GroupViTVisionConfig, **kwargs): - super().__init__(**kwargs) - - self.patch_embeddings = TFGroupViTPatchEmbeddings(config, name="patch_embeddings") - self.dropout = keras.layers.Dropout(rate=config.dropout, name="dropout") - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - self.config = config - - def build(self, input_shape=None): - num_patches = self.patch_embeddings.num_patches - self.position_embeddings = self.add_weight( - shape=(1, num_patches, self.config.hidden_size), - initializer="zeros", - trainable=True, - name="position_embeddings", - ) - - if self.built: - return - self.built = True - if getattr(self, "patch_embeddings", None) is not None: - with tf.name_scope(self.patch_embeddings.name): - self.patch_embeddings.build(None) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, self.config.hidden_size]) - - def interpolate_pos_encoding(self, embeddings, height, width) -> tf.Tensor: - """ - This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher - resolution images. - - Source: - https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174 - """ - - batch_size, num_patches, dim = shape_list(embeddings) - num_positions = shape_list(self.position_embeddings)[1] - - if num_patches == num_positions and height == width: - return self.position_embeddings - patch_pos_embed = self.position_embeddings - h0 = height // self.config.patch_size - w0 = width // self.config.patch_size - patch_pos_embed = tf.image.resize( - images=tf.reshape( - patch_pos_embed, shape=(1, int(math.sqrt(num_positions)), int(math.sqrt(num_positions)), dim) - ), - size=(h0, w0), - method="bicubic", - ) - patch_pos_embed = tf.reshape(tensor=patch_pos_embed, shape=(1, -1, dim)) - return patch_pos_embed - - def call( - self, pixel_values: tf.Tensor, interpolate_pos_encoding: bool = False, training: bool = False - ) -> tf.Tensor: - _, _, height, width = shape_list(pixel_values) - embeddings = self.patch_embeddings(pixel_values, interpolate_pos_encoding=interpolate_pos_encoding) - embeddings = self.layernorm(embeddings) - - # add positional encoding to each token - if interpolate_pos_encoding: - embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width) - else: - embeddings = embeddings + self.position_embeddings - - embeddings = self.dropout(embeddings) - - return embeddings - - -# Copied from transformers.models.clip.modeling_tf_clip.TFCLIPTextEmbeddings with CLIP->GroupViT -class TFGroupViTTextEmbeddings(keras.layers.Layer): - def __init__(self, config: GroupViTTextConfig, **kwargs): - super().__init__(**kwargs) - - self.embed_dim = config.hidden_size - - self.config = config - - def build(self, input_shape: tf.TensorShape = None): - with tf.name_scope("token_embedding"): - self.weight = self.add_weight( - shape=(self.config.vocab_size, self.embed_dim), - initializer=get_initializer(self.config.initializer_factor * self.config.initializer_range), - trainable=True, - name="weight", - ) - - with tf.name_scope("position_embedding"): - self.position_embedding = self.add_weight( - shape=(self.config.max_position_embeddings, self.embed_dim), - initializer=get_initializer(self.config.initializer_factor * self.config.initializer_range), - trainable=True, - name="embeddings", - ) - - super().build(input_shape) - - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - if input_ids is None and inputs_embeds is None: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) - - position_embeds = tf.gather(params=self.position_embedding, indices=position_ids) - position_embeds = tf.tile(input=position_embeds, multiples=(input_shape[0], 1, 1)) - final_embeddings = inputs_embeds + position_embeds - - return final_embeddings - - -class TFGroupViTStage(keras.layers.Layer): - """This corresponds to the `GroupingLayer` class in the GroupViT implementation.""" - - def __init__( - self, - config: GroupViTVisionConfig, - depth: int, - num_prev_group_token: int, - num_group_token: int, - num_output_group: int, - **kwargs, - ): - super().__init__(**kwargs) - self.config = config - self.depth = depth - self.num_group_token = num_group_token - self.layers = [TFGroupViTEncoderLayer(config, name=f"layers_._{i}") for i in range(depth)] - - if num_group_token > 0: - self.downsample = TFGroupViTTokenAssign( - config=config, - num_group_token=num_group_token, - num_output_group=num_output_group, - name="downsample", - ) - else: - self.downsample = None - - if num_prev_group_token > 0 and num_group_token > 0: - self.group_projector = [ - keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="group_projector.0"), - TFGroupViTMixerMLP( - config, num_prev_group_token, config.hidden_size // 2, num_group_token, name="group_projector.1" - ), - ] - else: - self.group_projector = None - - def build(self, input_shape=None): - if self.num_group_token > 0: - self.group_token = self.add_weight( - shape=(1, self.num_group_token, self.config.hidden_size), - initializer="zeros", - trainable=True, - name="group_token", - ) - else: - self.group_token = None - - if self.built: - return - self.built = True - if getattr(self, "downsample", None) is not None: - with tf.name_scope(self.downsample.name): - self.downsample.build(None) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - if getattr(self, "group_projector", None) is not None: - with tf.name_scope(self.group_projector[0].name): - self.group_projector[0].build([None, None, self.config.hidden_size]) - with tf.name_scope(self.group_projector[1].name): - self.group_projector[1].build(None) - - @property - def with_group_token(self): - return self.group_token is not None - - def split_x(self, x: tf.Tensor) -> tf.Tensor: - if self.with_group_token: - return x[:, : -self.num_group_token], x[:, -self.num_group_token :] - else: - return x, None - - def concat_x(self, x: tf.Tensor, group_token: tf.Tensor | None = None) -> tf.Tensor: - if group_token is None: - return x - return tf.concat([x, group_token], axis=1) - - def call( - self, - hidden_states: tf.Tensor, - prev_group_token: tf.Tensor | None = None, - output_attentions: bool = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - `(config.encoder_attention_heads,)`. - output_attentions (`bool`, *optional*): - Whether or not to return the grouping tensors of Grouping block. - """ - if self.with_group_token: - group_token = tf.tile(self.group_token, multiples=(shape_list(hidden_states)[0], 1, 1)) - if self.group_projector is not None: - for layer in self.group_projector: - prev_group_token = layer(prev_group_token) - group_token = group_token + prev_group_token - else: - group_token = None - - x = hidden_states - - cat_x = self.concat_x(x, group_token) - for layer in self.layers: - layer_out = layer( - cat_x, - attention_mask=None, - causal_attention_mask=None, - output_attentions=None, - ) - cat_x = layer_out[0] - - x, group_token = self.split_x(cat_x) - - attention = None - if self.downsample is not None: - x, attention = self.downsample(x, group_token) - - outputs = (x, group_token) - if output_attentions: - outputs = outputs + (attention,) - - return outputs - - -class TFGroupViTMLP(keras.layers.Layer): - def __init__( - self, - config: GroupViTVisionConfig, - hidden_size: int | None = None, - intermediate_size: int | None = None, - output_size: int | None = None, - **kwargs, - ): - super().__init__(**kwargs) - self.config = config - self.activation_fn = get_tf_activation(config.hidden_act) - hidden_size = hidden_size if hidden_size is not None else config.hidden_size - intermediate_size = intermediate_size if intermediate_size is not None else config.intermediate_size - output_size = output_size if output_size is not None else hidden_size - self.fc1 = keras.layers.Dense(intermediate_size, name="fc1") - self.fc2 = keras.layers.Dense(output_size, name="fc2") - self.intermediate_size = intermediate_size - self.hidden_size = hidden_size - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.fc1(hidden_states) - hidden_states = self.activation_fn(hidden_states) - hidden_states = self.fc2(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.hidden_size]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.intermediate_size]) - - -class TFGroupViTMixerMLP(TFGroupViTMLP): - def call(self, x, training: bool = False): - x = super().call(hidden_states=tf.transpose(x, perm=(0, 2, 1))) - return tf.transpose(x, perm=(0, 2, 1)) - - -# Adapted from transformers.models.clip.modeling_tf_clip.TFCLIPAttention -class TFGroupViTAttention(keras.layers.Layer): - """Multi-headed attention from 'Attention Is All You Need' paper""" - - def __init__(self, config: GroupViTConfig, **kwargs): - super().__init__(**kwargs) - - self.embed_dim = config.hidden_size - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = self.embed_dim // self.num_attention_heads - if self.attention_head_size * self.num_attention_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" - f" {self.num_attention_heads})." - ) - - factor = config.initializer_factor - in_proj_std = (self.embed_dim**-0.5) * ((2 * config.num_hidden_layers) ** -0.5) * factor - out_proj_std = (self.embed_dim**-0.5) * factor - - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.q_proj = keras.layers.Dense( - units=self.embed_dim, kernel_initializer=get_initializer(in_proj_std), name="q_proj" - ) - self.k_proj = keras.layers.Dense( - units=self.embed_dim, kernel_initializer=get_initializer(in_proj_std), name="k_proj" - ) - self.v_proj = keras.layers.Dense( - units=self.embed_dim, kernel_initializer=get_initializer(in_proj_std), name="v_proj" - ) - - self.dropout = keras.layers.Dropout(rate=config.attention_dropout) - - self.out_proj = keras.layers.Dense( - units=self.embed_dim, kernel_initializer=get_initializer(out_proj_std), name="out_proj" - ) - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention.transpose_for_scores - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - causal_attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - encoder_hidden_states: tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor]: - """Input shape: Batch x Time x Channel""" - - batch_size = shape_list(hidden_states)[0] - is_cross_attention = encoder_hidden_states is not None - - mixed_query_layer = self.q_proj(inputs=hidden_states) - if is_cross_attention: - mixed_key_layer = self.k_proj(inputs=encoder_hidden_states) - mixed_value_layer = self.v_proj(inputs=encoder_hidden_states) - else: - mixed_key_layer = self.k_proj(inputs=hidden_states) - mixed_value_layer = self.v_proj(inputs=hidden_states) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - # apply the causal_attention_mask first - if causal_attention_mask is not None: - # Apply the causal attention mask (precomputed for all layers in TFCLIPModel call() function) - attention_scores = tf.add(attention_scores, causal_attention_mask) - - if attention_mask is not None: - # Apply the attention mask (precomputed for all layers in TFCLIPModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - _attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=_attention_probs) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, embed_dim) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.embed_dim)) - - attention_output = self.out_proj(attention_output) - # In TFBert, attention weights are returned after dropout. - # However, in CLIP, they are returned before dropout. - outputs = (attention_output, _attention_probs) if output_attentions else (attention_output,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.clip.modeling_tf_clip.TFCLIPEncoderLayer with CLIP->GroupViT -class TFGroupViTEncoderLayer(keras.layers.Layer): - def __init__(self, config: GroupViTConfig, **kwargs): - super().__init__(**kwargs) - - self.embed_dim = config.hidden_size - self.self_attn = TFGroupViTAttention(config, name="self_attn") - self.layer_norm1 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm1") - self.mlp = TFGroupViTMLP(config, name="mlp") - self.layer_norm2 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm2") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - causal_attention_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - causal_attention_mask (`tf.Tensor`): causal attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - output_attentions (`bool`): - Whether or not to return the attentions tensors of all attention layers. See `outputs` under returned - tensors for more detail. - """ - residual = hidden_states - - hidden_states = self.layer_norm1(inputs=hidden_states) - attention_outputs = self.self_attn( - hidden_states=hidden_states, - attention_mask=attention_mask, - causal_attention_mask=causal_attention_mask, - output_attentions=output_attentions, - training=training, - ) - hidden_states = attention_outputs[0] - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.layer_norm2(inputs=hidden_states) - hidden_states = self.mlp(hidden_states=hidden_states) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) + attention_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "layer_norm1", None) is not None: - with tf.name_scope(self.layer_norm1.name): - self.layer_norm1.build([None, None, self.embed_dim]) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "layer_norm2", None) is not None: - with tf.name_scope(self.layer_norm2.name): - self.layer_norm2.build([None, None, self.embed_dim]) - - -# Adapted from transformers.models.clip.modeling_tf_clip.TFGroupViTTextEncoder -class TFGroupViTTextEncoder(keras.layers.Layer): - def __init__(self, config: GroupViTTextConfig, **kwargs): - super().__init__(**kwargs) - - self.layers = [TFGroupViTEncoderLayer(config, name=f"layers_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states, - attention_mask: tf.Tensor, - causal_attention_mask: tf.Tensor, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> tuple | TFBaseModelOutput: - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - layer_outputs = encoder_layer( - hidden_states, - attention_mask, - causal_attention_mask, - output_attentions=output_attentions, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFGroupViTVisionEncoder(keras.layers.Layer): - def __init__(self, config: GroupViTVisionConfig, **kwargs) -> None: - super().__init__(**kwargs) - - self.stages = [ - TFGroupViTStage( - config=config, - depth=config.depths[i], - num_group_token=config.num_group_tokens[i], - num_output_group=config.num_output_groups[i], - num_prev_group_token=config.num_output_groups[i - 1] if i > 0 else 0, - name=f"stages_._{i}", - ) - for i in range(len(config.depths)) - ] - - def call( - self, - hidden_states: tf.Tensor, - output_hidden_states: bool, - output_attentions: bool, - return_dict: bool, - training: bool = False, - ) -> tuple | TFBaseModelOutput: - all_hidden_states = () if output_hidden_states else None - all_groupings = () if output_attentions else None - - group_tokens = None - - for stage in self.stages: - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = stage(hidden_states, group_tokens, output_attentions) - - hidden_states = layer_outputs[0] - group_tokens = layer_outputs[1] - - if output_attentions and layer_outputs[2] is not None: - all_groupings = all_groupings + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_groupings] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_groupings - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "stages", None) is not None: - for layer in self.stages: - with tf.name_scope(layer.name): - layer.build(None) - - -# Copied from transformers.models.clip.modeling_tf_clip.TFCLIPTextTransformer with CLIPText->GroupViTText, CLIPEncoder->GroupViTTextEncoder -class TFGroupViTTextTransformer(keras.layers.Layer): - def __init__(self, config: GroupViTTextConfig, **kwargs): - super().__init__(**kwargs) - - self.embeddings = TFGroupViTTextEmbeddings(config, name="embeddings") - self.encoder = TFGroupViTTextEncoder(config, name="encoder") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="final_layer_norm") - - # For `pooled_output` computation - self.eos_token_id = config.eos_token_id - self.embed_dim = config.hidden_size - - def call( - self, - input_ids: TFModelInputType, - attention_mask: tf.Tensor, - position_ids: tf.Tensor, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - input_shape = shape_list(input_ids) - - embedding_output = self.embeddings(input_ids=input_ids, position_ids=position_ids) - - batch_size, seq_length = input_shape - # CLIP's text model uses causal mask, prepare it here. - # https://github.com/openai/CLIP/blob/cfcffb90e69f37bf2ff1e988237a0fbe41f33c04/clip/model.py#L324 - causal_attention_mask = self._build_causal_attention_mask(batch_size, seq_length, dtype=embedding_output.dtype) - - # check attention mask and invert - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - attention_mask = _expand_mask(attention_mask) - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=attention_mask, - causal_attention_mask=causal_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - sequence_output = self.final_layer_norm(inputs=sequence_output) - - if self.eos_token_id == 2: - # The `eos_token_id` was incorrect before PR #24773: Let's keep what have been done here. - # A CLIP model with such `eos_token_id` in the config can't work correctly with extra new tokens added - # ------------------------------------------------------------ - # text_embeds.shape = [batch_size, n_ctx, transformer.width] - # take features from the eot embedding (eot_token is the highest number in each sequence) - pooled_output = tf.gather_nd( - params=sequence_output, - indices=tf.stack( - values=(tf.range(input_shape[0], dtype=tf.int64), tf.math.argmax(input_ids, axis=-1)), axis=1 - ), - ) - else: - # The config gets updated `eos_token_id` from PR #24773 (so the use of extra new tokens is possible) - pooled_output = tf.gather_nd( - params=sequence_output, - indices=tf.stack( - values=( - tf.range(input_shape[0], dtype=tf.int64), - tf.math.argmax(tf.cast(input_ids == self.eos_token_id, dtype=tf.int8), axis=-1), - ), - axis=1, - ), - ) - - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def _build_causal_attention_mask(self, batch_size, seq_length, dtype=tf.float32): - # It is possible with an unspecified sequence length for seq_length to be - # a runtime value, which is unsupported by tf.constant. Per the TensorFlow - # docs, tf.fill can handle runtime dynamic shapes: - # https://www.tensorflow.org/api_docs/python/tf/fill - diag = tf.cast(tf.fill((seq_length,), 0.0), dtype) - - # set an additive 2D attention mask with all places being masked - to_mask = tf.cast(tf.fill((seq_length, seq_length), -10000.0), dtype) - - # set diagonal & lower triangular parts to 0 (i.e. the places not to be masked) - # TIP: think the 2D matrix as the space of (query_seq, key_seq) - to_mask = tf.linalg.band_part(to_mask, 0, -1) - # to_mask = tf.linalg.band_part(to_mask, -1, 0) - to_mask = tf.linalg.set_diag(to_mask, diagonal=diag) - - return tf.broadcast_to(input=to_mask, shape=(batch_size, 1, seq_length, seq_length)) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -# Adapted from transformers.models.clip.modeling_tf_clip.TFCLIPVisionTransformer -class TFGroupViTVisionTransformer(keras.layers.Layer): - def __init__(self, config: GroupViTVisionConfig, **kwargs): - super().__init__(**kwargs) - - self.embeddings = TFGroupViTVisionEmbeddings(config, name="embeddings") - self.encoder = TFGroupViTVisionEncoder(config, name="encoder") - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - self.embed_dim = config.hidden_size - - def call( - self, - pixel_values: TFModelInputType, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> tuple | TFBaseModelOutputWithPooling: - embedding_output = self.embeddings(pixel_values) - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - output_hidden_states=output_hidden_states, - output_attentions=output_attentions, - return_dict=return_dict, - ) - - last_hidden_state = encoder_outputs[0] - - # normalize the last hidden state - last_hidden_state = self.layernorm(last_hidden_state) - pooled_output = tf.math.reduce_mean(last_hidden_state, axis=1) - - if not return_dict: - return (last_hidden_state, pooled_output) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, self.embed_dim]) - - -@keras_serializable -# Copied from transformers.models.clip.modeling_tf_clip.TFCLIPTextMainLayer with CLIP->GroupViT -class TFGroupViTTextMainLayer(keras.layers.Layer): - config_class = GroupViTTextConfig - - def __init__(self, config: GroupViTTextConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.text_model = TFGroupViTTextTransformer(config, name="text_model") - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.text_model.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.text_model.embeddings.weight = value - self.text_model.embeddings.vocab_size = shape_list(value)[0] - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - if input_ids is None: - raise ValueError("You have to specify input_ids") - - input_shape = shape_list(input_ids) - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - text_model_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return text_model_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "text_model", None) is not None: - with tf.name_scope(self.text_model.name): - self.text_model.build(None) - - -@keras_serializable -# Copied from transformers.models.clip.modeling_tf_clip.TFCLIPVisionMainLayer with CLIP->GroupViT -class TFGroupViTVisionMainLayer(keras.layers.Layer): - config_class = GroupViTVisionConfig - - def __init__(self, config: GroupViTVisionConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.vision_model = TFGroupViTVisionTransformer(config, name="vision_model") - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.vision_model.embeddings - - @unpack_inputs - def call( - self, - pixel_values: TFModelInputType | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - vision_model_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return vision_model_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "vision_model", None) is not None: - with tf.name_scope(self.vision_model.name): - self.vision_model.build(None) - - -@keras_serializable -# Adapted from transformers.models.clip.modeling_tf_clip.TFCLIPMainLayer -class TFGroupViTMainLayer(keras.layers.Layer): - config_class = GroupViTConfig - - def __init__(self, config: GroupViTConfig, **kwargs): - super().__init__(**kwargs) - - if not isinstance(config.text_config, GroupViTTextConfig): - raise TypeError( - "config.text_config is expected to be of type GroupViTTextConfig but is of type" - f" {type(config.text_config)}." - ) - - if not isinstance(config.vision_config, GroupViTVisionConfig): - raise TypeError( - "config.vision_config is expected to be of type GroupViTVisionConfig but is of type" - f" {type(config.vision_config)}." - ) - - self.config = config - - text_config = config.text_config - vision_config = config.vision_config - - self.projection_dim = config.projection_dim - self.projection_intermediate_dim = config.projection_intermediate_dim - self.text_embed_dim = text_config.hidden_size - self.vision_embed_dim = vision_config.hidden_size - - self.text_model = TFGroupViTTextTransformer(text_config, name="text_model") - self.vision_model = TFGroupViTVisionTransformer(vision_config, name="vision_model") - - self.visual_projection = [ - keras.layers.Dense(self.projection_intermediate_dim, name="visual_projection.0"), - keras.layers.BatchNormalization(name="visual_projection.1", momentum=0.9, epsilon=1e-5), - keras.layers.ReLU(name="visual_projection.2"), - keras.layers.Dense(self.projection_dim, name="visual_projection.3"), - ] - self.text_projection = [ - keras.layers.Dense(self.projection_intermediate_dim, name="text_projection.0"), - keras.layers.BatchNormalization(name="text_projection.1", momentum=0.9, epsilon=1e-5), - keras.layers.ReLU(name="text_projection.2"), - keras.layers.Dense(self.projection_dim, name="text_projection.3"), - ] - - def build(self, input_shape=None): - self.logit_scale = self.add_weight( - shape=(1,), - initializer=keras.initializers.Constant(self.config.logit_scale_init_value), - trainable=True, - name="logit_scale", - ) - - if self.built: - return - self.built = True - if getattr(self, "text_model", None) is not None: - with tf.name_scope(self.text_model.name): - self.text_model.build(None) - if getattr(self, "vision_model", None) is not None: - with tf.name_scope(self.vision_model.name): - self.vision_model.build(None) - if getattr(self, "visual_projection", None) is not None: - with tf.name_scope(self.visual_projection[0].name): - self.visual_projection[0].build([None, None, None, self.vision_embed_dim]) - with tf.name_scope(self.visual_projection[1].name): - self.visual_projection[1].build((None, self.projection_intermediate_dim)) - with tf.name_scope(self.visual_projection[3].name): - self.visual_projection[3].build([None, None, None, self.projection_intermediate_dim]) - if getattr(self, "text_projection", None) is not None: - with tf.name_scope(self.text_projection[0].name): - self.text_projection[0].build([None, None, None, self.text_embed_dim]) - with tf.name_scope(self.text_projection[1].name): - self.text_projection[1].build((None, self.projection_intermediate_dim)) - with tf.name_scope(self.text_projection[3].name): - self.text_projection[3].build([None, None, None, self.projection_intermediate_dim]) - - @unpack_inputs - def get_text_features( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tf.Tensor: - if input_ids is None: - raise ValueError("You have to specify either input_ids") - - input_shape = shape_list(input_ids) - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - text_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - pooled_output = text_outputs[1] - for layer in self.text_projection: - pooled_output = layer(pooled_output) - - text_features = pooled_output - return text_features - - @unpack_inputs - def get_image_features( - self, - pixel_values: TFModelInputType | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tf.Tensor: - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - vision_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - pooled_output = vision_outputs[1] - for layer in self.visual_projection: - pooled_output = layer(pooled_output) - - image_features = pooled_output - return image_features - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - pixel_values: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - return_loss: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - output_segmentation: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFGroupViTModelOutput | tuple[tf.Tensor]: - if input_ids is None: - raise ValueError("You have to specify either input_ids") - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - input_shape = shape_list(input_ids) - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - if output_segmentation: - output_attentions = True - vision_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - text_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - image_embeds = vision_outputs[1] - for layer in self.visual_projection: - image_embeds = layer(image_embeds) - - text_embeds = text_outputs[1] - for layer in self.text_projection: - text_embeds = layer(text_embeds) - - # normalized features - image_embeds = image_embeds / tf.norm(image_embeds, axis=-1, keepdims=True) - text_embeds = text_embeds / tf.norm(text_embeds, axis=-1, keepdims=True) - - # cosine similarity as logits - logit_scale = tf.math.exp(self.logit_scale) - logits_per_text = tf.matmul(text_embeds, image_embeds, transpose_b=True) * logit_scale - logits_per_image = tf.transpose(logits_per_text) - - seg_logits = None - if output_segmentation: - # grouped features - # [batch_size_image, num_group, hidden_size] - image_group_embeds = vision_outputs[0] - # [batch_size_image*num_group, hidden_size] - image_group_embeds = tf.reshape(image_group_embeds, shape=(-1, shape_list(image_group_embeds)[-1])) - for layer in self.visual_projection: - image_group_embeds = layer(image_group_embeds) - if output_hidden_states: - attentions = vision_outputs[3] - else: - attentions = vision_outputs[2] - # [batch_size_image, num_group, height, width] - grouping = get_grouping_from_attentions(attentions, pixel_values.shape[2:]) - - # normalized features - image_group_embeds = image_group_embeds / tf.norm( - tensor=image_group_embeds, ord="euclidean", axis=-1, keepdims=True - ) - # [batch_size_image x num_group, batch_size_text] - logits_per_image_group = tf.matmul(image_group_embeds, text_embeds, transpose_b=True) * logit_scale - # [batch_size_image, batch_size_text, num_group] - logits_per_image_group = tf.reshape( - logits_per_image_group, shape=(image_embeds.shape[0], -1, text_embeds.shape[0]) - ) - logits_per_image_group = tf.transpose(logits_per_image_group, perm=(0, 2, 1)) - - # [batch_size_image, batch_size_text, height x width] - flatten_grouping = tf.reshape(grouping, shape=(shape_list(grouping)[0], shape_list(grouping)[1], -1)) - - # [batch_size_image, batch_size_text, height, width] - seg_logits = tf.matmul(logits_per_image_group, flatten_grouping) * logit_scale - seg_logits = tf.reshape( - seg_logits, shape=(seg_logits.shape[0], seg_logits.shape[1], grouping.shape[2], grouping.shape[3]) - ) - - loss = None - if return_loss: - loss = groupvit_loss(logits_per_text)[None, ...] - - if not return_dict: - if seg_logits is not None: - output = ( - logits_per_image, - logits_per_text, - seg_logits, - text_embeds, - image_embeds, - text_outputs, - vision_outputs, - ) - else: - output = (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs) - return ((loss,) + output) if loss is not None else output - - return TFGroupViTModelOutput( - loss=loss, - logits_per_image=logits_per_image, - logits_per_text=logits_per_text, - segmentation_logits=seg_logits, - text_embeds=text_embeds, - image_embeds=image_embeds, - text_model_output=text_outputs, - vision_model_output=vision_outputs, - ) - - -class TFGroupViTPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = GroupViTConfig - base_model_prefix = "groupvit" - - -GROUPVIT_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TF 2.0 models accepts two formats as inputs: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional arguments. - - This second option is useful when using [`keras.Model.fit`] method which currently requires having all the - tensors in the first argument of the model call function: `model(inputs)`. - - If you choose this second option, there are three possibilities you can use to gather all the input Tensors in the - first positional argument : - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - - - Args: - config ([`GroupViTConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -GROUPVIT_TEXT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - -GROUPVIT_VISION_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]`, `dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`CLIPImageProcessor.__call__`] for details. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - -GROUPVIT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` `dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`CLIPImageProcessor.__call__`] for details. - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - return_loss (`bool`, *optional*): - Whether or not to return the contrastive loss. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -class TFGroupViTTextModel(TFGroupViTPreTrainedModel): - config_class = GroupViTTextConfig - main_input_name = "input_ids" - - def __init__(self, config: GroupViTTextConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.groupvit = TFGroupViTTextMainLayer(config, name="groupvit") - - @unpack_inputs - @add_start_docstrings_to_model_forward(GROUPVIT_TEXT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFBaseModelOutputWithPooling, config_class=GroupViTTextConfig) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import CLIPTokenizer, TFGroupViTTextModel - - >>> tokenizer = CLIPTokenizer.from_pretrained("nvidia/groupvit-gcc-yfcc") - >>> model = TFGroupViTTextModel.from_pretrained("nvidia/groupvit-gcc-yfcc") - - >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="tf") - - >>> outputs = model(**inputs) - >>> last_hidden_state = outputs.last_hidden_state - >>> pooled_output = outputs.pooler_output # pooled (EOS token) states - ```""" - - outputs = self.groupvit( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "groupvit", None) is not None: - with tf.name_scope(self.groupvit.name): - self.groupvit.build(None) - - -class TFGroupViTVisionModel(TFGroupViTPreTrainedModel): - config_class = GroupViTVisionConfig - main_input_name = "pixel_values" - - def __init__(self, config: GroupViTVisionConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.groupvit = TFGroupViTVisionMainLayer(config, name="groupvit") - - @unpack_inputs - @add_start_docstrings_to_model_forward(GROUPVIT_VISION_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBaseModelOutputWithPooling, config_class=GroupViTVisionConfig) - def call( - self, - pixel_values: TFModelInputType | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFGroupViTVisionModel - - >>> processor = AutoProcessor.from_pretrained("nvidia/groupvit-gcc-yfcc") - >>> model = TFGroupViTVisionModel.from_pretrained("nvidia/groupvit-gcc-yfcc") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor(images=image, return_tensors="tf") - - >>> outputs = model(**inputs) - >>> last_hidden_state = outputs.last_hidden_state - >>> pooled_output = outputs.pooler_output # pooled CLS states - ```""" - - outputs = self.groupvit( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "groupvit", None) is not None: - with tf.name_scope(self.groupvit.name): - self.groupvit.build(None) - - -@add_start_docstrings(GROUPVIT_START_DOCSTRING) -class TFGroupViTModel(TFGroupViTPreTrainedModel): - config_class = GroupViTConfig - - def __init__(self, config: GroupViTConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.groupvit = TFGroupViTMainLayer(config, name="groupvit") - - @unpack_inputs - @add_start_docstrings_to_model_forward(GROUPVIT_TEXT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def get_text_features( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tf.Tensor: - r""" - Returns: - text_features (`tf.Tensor` of shape `(batch_size, output_dim`): The text embeddings obtained by applying - the projection layer to the pooled output of [`TFGroupViTTextModel`]. - - Examples: - - ```python - >>> from transformers import CLIPTokenizer, TFGroupViTModel - - >>> model = TFGroupViTModel.from_pretrained("nvidia/groupvit-gcc-yfcc") - >>> tokenizer = CLIPTokenizer.from_pretrained("nvidia/groupvit-gcc-yfcc") - - >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="tf") - >>> text_features = model.get_text_features(**inputs) - ```""" - - text_features = self.groupvit.get_text_features( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return text_features - - @unpack_inputs - @add_start_docstrings_to_model_forward(GROUPVIT_VISION_INPUTS_DOCSTRING) - def get_image_features( - self, - pixel_values: TFModelInputType | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tf.Tensor: - r""" - Returns: - image_features (`tf.Tensor` of shape `(batch_size, output_dim`): The image embeddings obtained by applying - the projection layer to the pooled output of [`TFGroupViTVisionModel`]. - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFGroupViTModel - - >>> model = TFGroupViTModel.from_pretrained("nvidia/groupvit-gcc-yfcc") - >>> processor = AutoProcessor.from_pretrained("nvidia/groupvit-gcc-yfcc") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor(images=image, return_tensors="tf") - - >>> image_features = model.get_image_features(**inputs) - ```""" - - image_features = self.groupvit.get_image_features( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return image_features - - @unpack_inputs - @add_start_docstrings_to_model_forward(GROUPVIT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFGroupViTModelOutput, config_class=GroupViTConfig) - def call( - self, - input_ids: TFModelInputType | None = None, - pixel_values: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - return_loss: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - output_segmentation: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFGroupViTModelOutput | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import AutoProcessor, TFGroupViTModel - >>> import tensorflow as tf - - >>> model = TFGroupViTModel.from_pretrained("nvidia/groupvit-gcc-yfcc") - >>> processor = AutoProcessor.from_pretrained("nvidia/groupvit-gcc-yfcc") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = processor( - ... text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="tf", padding=True - ... ) - - >>> outputs = model(**inputs) - >>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score - >>> probs = tf.math.softmax(logits_per_image, axis=1) # we can take the softmax to get the label probabilities - ```""" - - outputs = self.groupvit( - input_ids=input_ids, - pixel_values=pixel_values, - attention_mask=attention_mask, - position_ids=position_ids, - return_loss=return_loss, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - output_segmentation=output_segmentation, - return_dict=return_dict, - training=training, - ) - - return outputs - - def serving_output(self, output: TFGroupViTModelOutput) -> TFGroupViTModelOutput: - # TODO: As is this currently fails with saved_model=True, because - # TensorFlow cannot trace through nested dataclasses. Reference: - # https://github.com/huggingface/transformers/pull/16886 - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "groupvit", None) is not None: - with tf.name_scope(self.groupvit.name): - self.groupvit.build(None) - - -__all__ = ["TFGroupViTModel", "TFGroupViTPreTrainedModel", "TFGroupViTTextModel", "TFGroupViTVisionModel"] diff --git a/src/transformers/models/hiera/modeling_hiera.py b/src/transformers/models/hiera/modeling_hiera.py index 0c084f0f836e..7ae70f6cbe8b 100644 --- a/src/transformers/models/hiera/modeling_hiera.py +++ b/src/transformers/models/hiera/modeling_hiera.py @@ -404,11 +404,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/hubert/__init__.py b/src/transformers/models/hubert/__init__.py index d975dabc689a..25d366620f0b 100644 --- a/src/transformers/models/hubert/__init__.py +++ b/src/transformers/models/hubert/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_hubert import * from .modeling_hubert import * - from .modeling_tf_hubert import * else: import sys diff --git a/src/transformers/models/hubert/modeling_hubert.py b/src/transformers/models/hubert/modeling_hubert.py index 060b715e8d49..dfa53a2cf193 100755 --- a/src/transformers/models/hubert/modeling_hubert.py +++ b/src/transformers/models/hubert/modeling_hubert.py @@ -688,8 +688,6 @@ class HubertPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/hubert/modeling_tf_hubert.py b/src/transformers/models/hubert/modeling_tf_hubert.py deleted file mode 100644 index 45c05ff30737..000000000000 --- a/src/transformers/models/hubert/modeling_tf_hubert.py +++ /dev/null @@ -1,1671 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Fairseq Authors and the HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow Hubert model.""" - -from __future__ import annotations - -import warnings -from typing import Any - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import TFBaseModelOutput, TFCausalLMOutput -from ...modeling_tf_utils import ( - TFPreTrainedModel, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list, stable_softmax -from ...utils import ( - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_hubert import HubertConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "HubertConfig" - - -LARGE_NEGATIVE = -1e8 - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2._sample_without_replacement -def _sample_without_replacement(distribution, num_samples): - """ - Categorical sampling without replacement is currently not implemented. The gumbel-max trick will do for now - see - https://github.com/tensorflow/tensorflow/issues/9260 for more info - """ - z = -tf.math.log(tf.random.uniform(shape_list(distribution), 0, 1)) - _, indices = tf.nn.top_k(distribution + z, num_samples) - return indices - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2._scatter_values_on_batch_indices -def _scatter_values_on_batch_indices(values, batch_indices, output_shape): - """ - Scatter function as in PyTorch with indices in format (batch_dim, indices) - """ - indices_shape = shape_list(batch_indices) - # broadcast batch dim to indices_shape - broad_casted_batch_dims = tf.reshape( - tf.broadcast_to(tf.expand_dims(tf.range(indices_shape[0]), axis=-1), indices_shape), [1, -1] - ) - # transform batch_indices to pair_indices - pair_indices = tf.transpose(tf.concat([broad_casted_batch_dims, tf.reshape(batch_indices, [1, -1])], 0)) - # scatter values to pair indices - return tf.scatter_nd(pair_indices, tf.reshape(values, [-1]), output_shape) - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2._compute_mask_indices -def _compute_mask_indices( - shape: tuple[int, int], - mask_prob: float, - mask_length: int, - min_masks: int = 0, -) -> tf.Tensor: - """ - Computes random mask spans for a given shape - - Args: - shape: the shape for which to compute masks. - should be of size 2 where first element is batch size and 2nd is timesteps - attention_mask: optional padding mask of the same size as shape, which will prevent masking padded elements - mask_prob: - probability for each token to be chosen as start of the span to be masked. this will be multiplied by - number of timesteps divided by length of mask span to mask approximately this percentage of all elements. - however due to overlaps, the actual number will be smaller (unless no_overlap is True) - mask_length: size of the mask - min_masks: minimum number of masked spans - - Adapted from [fairseq's - data_utils.py](https://github.com/pytorch/fairseq/blob/e0788f7007a8473a76db573985031f3c94201e79/fairseq/data/data_utils.py#L376). - """ - batch_size, sequence_length = shape - - if mask_length < 1: - raise ValueError("`mask_length` has to be bigger than 0.") - - tf.debugging.assert_less( - mask_length, - sequence_length, - message=( - f"`mask_length` has to be smaller than `sequence_length`, but got `mask_length`: {mask_length} and" - f" `sequence_length`: {sequence_length}`" - ), - ) - - # compute number of masked spans in batch - num_masked_spans = mask_prob * tf.cast(sequence_length, tf.float32) / mask_length + tf.random.uniform((1,)) - num_masked_spans = tf.maximum(num_masked_spans, min_masks) - num_masked_spans = tf.cast(num_masked_spans, tf.int32) - - # make sure num masked indices <= sequence_length - num_masked_spans = tf.math.minimum(sequence_length // mask_length, num_masked_spans) - num_masked_spans = tf.squeeze(num_masked_spans) - - # SpecAugment mask to fill - spec_aug_mask = tf.zeros((batch_size, sequence_length), dtype=tf.int32) - - # uniform distribution to sample from, make sure that offset samples are < sequence_length - uniform_dist = tf.ones((batch_size, sequence_length - (mask_length - 1))) - - # get random indices to mask - spec_aug_mask_idxs = _sample_without_replacement(uniform_dist, num_masked_spans) - - # expand masked indices to masked spans - spec_aug_mask_idxs = tf.expand_dims(spec_aug_mask_idxs, -1) - spec_aug_mask_idxs = tf.tile(spec_aug_mask_idxs, (1, 1, mask_length)) - spec_aug_mask_idxs = tf.reshape(spec_aug_mask_idxs, (batch_size, num_masked_spans * mask_length)) - - offsets = tf.range(mask_length)[tf.newaxis, tf.newaxis, :] - offsets = tf.tile(offsets, (batch_size, num_masked_spans, 1)) - offsets = tf.reshape(offsets, (batch_size, num_masked_spans * mask_length)) - - spec_aug_mask_idxs = spec_aug_mask_idxs + offsets - - # scatter indices to mask - spec_aug_mask = _scatter_values_on_batch_indices( - tf.ones_like(spec_aug_mask_idxs), spec_aug_mask_idxs, tf.shape(spec_aug_mask) - ) - - return spec_aug_mask - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2GroupNorm with Wav2Vec2->Hubert -class TFHubertGroupNorm(keras.layers.Layer): - """ - From tensorflow-addons https://www.tensorflow.org/addons/api_docs/python/tfa/layers/GroupNormalization - """ - - def __init__( - self, - groups: int = 32, - axis: int = -1, - epsilon: float = 1e-3, - center: bool = True, - scale: bool = True, - beta_initializer: keras.initializers.Initializer = "zeros", - gamma_initializer: keras.initializers.Initializer = "ones", - beta_regularizer: keras.regularizers.Regularizer = None, - gamma_regularizer: keras.regularizers.Regularizer = None, - beta_constraint: keras.constraints.Constraint = None, - gamma_constraint: keras.constraints.Constraint = None, - **kwargs, - ): - super().__init__(**kwargs) - self.supports_masking = True - self.groups = groups - self.axis = axis - self.epsilon = epsilon - self.center = center - self.scale = scale - self.beta_initializer = keras.initializers.get(beta_initializer) - self.gamma_initializer = keras.initializers.get(gamma_initializer) - self.beta_regularizer = keras.regularizers.get(beta_regularizer) - self.gamma_regularizer = keras.regularizers.get(gamma_regularizer) - self.beta_constraint = keras.constraints.get(beta_constraint) - self.gamma_constraint = keras.constraints.get(gamma_constraint) - self._check_axis() - - def build(self, input_shape): - self._check_if_input_shape_is_none(input_shape) - self._set_number_of_groups_for_instance_norm(input_shape) - self._check_size_of_dimensions(input_shape) - self._create_input_spec(input_shape) - - self._add_gamma_weight(input_shape) - self._add_beta_weight(input_shape) - self.built = True - super().build(input_shape) - - def call(self, inputs): - input_shape = keras.backend.int_shape(inputs) - tensor_input_shape = tf.shape(inputs) - - reshaped_inputs, group_shape = self._reshape_into_groups(inputs, input_shape, tensor_input_shape) - - normalized_inputs = self._apply_normalization(reshaped_inputs, input_shape) - - is_instance_norm = (input_shape[self.axis] // self.groups) == 1 - if not is_instance_norm: - outputs = tf.reshape(normalized_inputs, tensor_input_shape) - else: - outputs = normalized_inputs - - return outputs - - def get_config(self): - config = { - "groups": self.groups, - "axis": self.axis, - "epsilon": self.epsilon, - "center": self.center, - "scale": self.scale, - "beta_initializer": keras.initializers.serialize(self.beta_initializer), - "gamma_initializer": keras.initializers.serialize(self.gamma_initializer), - "beta_regularizer": keras.regularizers.serialize(self.beta_regularizer), - "gamma_regularizer": keras.regularizers.serialize(self.gamma_regularizer), - "beta_constraint": keras.constraints.serialize(self.beta_constraint), - "gamma_constraint": keras.constraints.serialize(self.gamma_constraint), - } - base_config = super().get_config() - return {**base_config, **config} - - def compute_output_shape(self, input_shape): - return input_shape - - def _reshape_into_groups(self, inputs, input_shape, tensor_input_shape): - group_shape = [tensor_input_shape[i] for i in range(len(input_shape))] - is_instance_norm = (input_shape[self.axis] // self.groups) == 1 - if not is_instance_norm: - group_shape[self.axis] = input_shape[self.axis] // self.groups - group_shape.insert(self.axis, self.groups) - group_shape = tf.stack(group_shape) - reshaped_inputs = tf.reshape(inputs, group_shape) - return reshaped_inputs, group_shape - else: - return inputs, group_shape - - def _apply_normalization(self, reshaped_inputs, input_shape): - group_shape = keras.backend.int_shape(reshaped_inputs) - group_reduction_axes = list(range(1, len(group_shape))) - is_instance_norm = (input_shape[self.axis] // self.groups) == 1 - if not is_instance_norm: - axis = -2 if self.axis == -1 else self.axis - 1 - else: - axis = -1 if self.axis == -1 else self.axis - 1 - group_reduction_axes.pop(axis) - - mean, variance = tf.nn.moments(reshaped_inputs, group_reduction_axes, keepdims=True) - - gamma, beta = self._get_reshaped_weights(input_shape) - normalized_inputs = tf.nn.batch_normalization( - reshaped_inputs, - mean=mean, - variance=variance, - scale=gamma, - offset=beta, - variance_epsilon=self.epsilon, - ) - return normalized_inputs - - def _get_reshaped_weights(self, input_shape): - broadcast_shape = self._create_broadcast_shape(input_shape) - gamma = None - beta = None - if self.scale: - gamma = tf.reshape(self.gamma, broadcast_shape) - - if self.center: - beta = tf.reshape(self.beta, broadcast_shape) - return gamma, beta - - def _check_if_input_shape_is_none(self, input_shape): - dim = input_shape[self.axis] - if dim is None: - raise ValueError( - "Axis " - + str(self.axis) - + " of input tensor should have a defined dimension but the layer received an input with shape " - + str(input_shape) - + "." - ) - - def _set_number_of_groups_for_instance_norm(self, input_shape): - dim = input_shape[self.axis] - - if self.groups == -1: - self.groups = dim - - def _check_size_of_dimensions(self, input_shape): - dim = input_shape[self.axis] - if dim < self.groups: - raise ValueError( - "Number of groups (" - + str(self.groups) - + ") cannot be more than the number of channels (" - + str(dim) - + ")." - ) - - if dim % self.groups != 0: - raise ValueError( - "Number of groups (" - + str(self.groups) - + ") must be a multiple of the number of channels (" - + str(dim) - + ")." - ) - - def _check_axis(self): - if self.axis == 0: - raise ValueError( - "You are trying to normalize your batch axis. Do you want to use tf.layer.batch_normalization instead" - ) - - def _create_input_spec(self, input_shape): - dim = input_shape[self.axis] - self.input_spec = keras.layers.InputSpec(ndim=len(input_shape), axes={self.axis: dim}) - - def _add_gamma_weight(self, input_shape): - dim = input_shape[self.axis] - shape = (dim,) - - if self.scale: - self.gamma = self.add_weight( - shape=shape, - name="gamma", - initializer=self.gamma_initializer, - regularizer=self.gamma_regularizer, - constraint=self.gamma_constraint, - ) - else: - self.gamma = None - - def _add_beta_weight(self, input_shape): - dim = input_shape[self.axis] - shape = (dim,) - - if self.center: - self.beta = self.add_weight( - shape=shape, - name="beta", - initializer=self.beta_initializer, - regularizer=self.beta_regularizer, - constraint=self.beta_constraint, - ) - else: - self.beta = None - - def _create_broadcast_shape(self, input_shape): - broadcast_shape = [1] * len(input_shape) - is_instance_norm = (input_shape[self.axis] // self.groups) == 1 - if not is_instance_norm: - broadcast_shape[self.axis] = input_shape[self.axis] // self.groups - broadcast_shape.insert(self.axis, self.groups) - else: - broadcast_shape[self.axis] = self.groups - return broadcast_shape - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2WeightNormConv1D with Wav2Vec2->Hubert -class TFHubertWeightNormConv1D(keras.layers.Conv1D): - """Adapted from https://www.tensorflow.org/probability/api_docs/python/tfp/layers/weight_norm/WeightNorm""" - - def __init__(self, filters, kernel_size, groups, explicit_padding, **kwargs): - super().__init__( - filters=filters, - kernel_size=kernel_size, - groups=groups, - padding="valid", - use_bias=True, - bias_initializer="he_normal", - **kwargs, - ) - self.explicit_padding = explicit_padding - self.filter_axis = 2 - self.kernel_norm_axes = tf.constant([0, 1]) - - def _init_norm(self): - """Set the norm of the weight vector.""" - kernel_norm = tf.sqrt(tf.reduce_sum(tf.square(self.weight_v), axis=self.kernel_norm_axes)) - self.weight_g.assign(kernel_norm[:, tf.newaxis, tf.newaxis]) - - def _normalize_kernel(self): - """Generate normalized weights.""" - kernel = tf.nn.l2_normalize(self.weight_v, axis=self.kernel_norm_axes) * tf.transpose(self.weight_g) - self.kernel = tf.transpose(kernel) - - def build(self, input_shape): - if not self.built: - super().build(input_shape) - - self.kernel = tf.Variable(tf.transpose(self.kernel), name="weight_v", trainable=True) - self.weight_v = self.kernel - - self.weight_g = self.add_weight( - name="weight_g", - shape=(int(self.weight_v.shape[self.filter_axis]), 1, 1), - initializer="ones", - dtype=self.weight_v.dtype, - trainable=True, - ) - self._init_norm() - self.bias = self.add_weight(name="bias", shape=(self.filters,), initializer="zeros", trainable=True) - - def call(self, inputs): - # TODO Matt: Assigning to attributes in call() is deeply sinful in TensorFlow, as it should be idempotent. - # This whole layer should be replaced by a layer that doesn't inherit from Conv1D, but instead calls - # a functional 1d convolution with normalized weights that it generates (but does not store!) - self._normalize_kernel() - - padded_inputs = tf.pad(inputs, ((0, 0), (self.explicit_padding, self.explicit_padding), (0, 0))) - output = super().call(padded_inputs) - - return output - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2NoLayerNormConvLayer with Wav2Vec2->Hubert -class TFHubertNoLayerNormConvLayer(keras.layers.Layer): - def __init__(self, config: HubertConfig, layer_id: int = 0, **kwargs: Any) -> None: - super().__init__(**kwargs) - self.in_conv_dim = config.conv_dim[layer_id] if layer_id > 0 else 1 - self.out_conv_dim = config.conv_dim[layer_id] - - self.conv = keras.layers.Conv1D( - filters=self.out_conv_dim, - kernel_size=config.conv_kernel[layer_id], - strides=config.conv_stride[layer_id], - use_bias=config.conv_bias, - name="conv", - ) - self.activation = get_tf_activation(config.feat_extract_activation) - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.conv(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build([None, None, self.in_conv_dim]) - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2LayerNormConvLayer with Wav2Vec2->Hubert -class TFHubertLayerNormConvLayer(keras.layers.Layer): - def __init__(self, config: HubertConfig, layer_id: int = 0, **kwargs: Any) -> None: - super().__init__(**kwargs) - self.in_conv_dim = config.conv_dim[layer_id] if layer_id > 0 else 1 - self.out_conv_dim = config.conv_dim[layer_id] - - self.conv = keras.layers.Conv1D( - filters=self.out_conv_dim, - kernel_size=config.conv_kernel[layer_id], - strides=config.conv_stride[layer_id], - use_bias=config.conv_bias, - name="conv", - ) - self.layer_norm = keras.layers.LayerNormalization(name="layer_norm", epsilon=config.layer_norm_eps) - self.activation = get_tf_activation(config.feat_extract_activation) - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.conv(hidden_states) - hidden_states = self.layer_norm(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build([None, None, self.in_conv_dim]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.out_conv_dim]) - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2GroupNormConvLayer with Wav2Vec2->Hubert -class TFHubertGroupNormConvLayer(keras.layers.Layer): - def __init__(self, config: HubertConfig, layer_id: int = 0, **kwargs: Any) -> None: - super().__init__(**kwargs) - self.in_conv_dim = config.conv_dim[layer_id] if layer_id > 0 else 1 - self.out_conv_dim = config.conv_dim[layer_id] - - self.conv = keras.layers.Conv1D( - filters=self.out_conv_dim, - kernel_size=config.conv_kernel[layer_id], - strides=config.conv_stride[layer_id], - use_bias=config.conv_bias, - name="conv", - ) - self.activation = get_tf_activation(config.feat_extract_activation) - self.layer_norm = TFHubertGroupNorm(groups=self.out_conv_dim, epsilon=config.layer_norm_eps, name="layer_norm") - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.conv(hidden_states) - hidden_states = self.layer_norm(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build([None, None, self.in_conv_dim]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.out_conv_dim]) - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2PositionalConvEmbedding with Wav2Vec2->Hubert -class TFHubertPositionalConvEmbedding(keras.layers.Layer): - def __init__(self, config: HubertConfig, **kwargs: Any) -> None: - super().__init__(**kwargs) - self.conv = TFHubertWeightNormConv1D( - filters=config.hidden_size, - kernel_size=config.num_conv_pos_embeddings, - groups=config.num_conv_pos_embedding_groups, - explicit_padding=config.num_conv_pos_embeddings // 2, - name="conv", - ) - self.padding = TFHubertSamePadLayer(config.num_conv_pos_embeddings) - self.activation = get_tf_activation(config.feat_extract_activation) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.conv(hidden_states) - hidden_states = self.padding(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2SamePadLayer with Wav2Vec2->Hubert -class TFHubertSamePadLayer(keras.layers.Layer): - def __init__(self, num_conv_pos_embeddings, **kwargs): - super().__init__(**kwargs) - self.num_pad_remove = 1 if num_conv_pos_embeddings % 2 == 0 else 0 - - def call(self, hidden_states): - if self.num_pad_remove > 0: - hidden_states = hidden_states[:, : -self.num_pad_remove, :] - return hidden_states - - -class TFHubertFeatureEncoder(keras.layers.Layer): - def __init__(self, config: HubertConfig, **kwargs: Any) -> None: - super().__init__(**kwargs) - - if config.feat_extract_norm == "group": - conv_layers = [TFHubertGroupNormConvLayer(config, layer_id=0, name=f"conv_layers.{0}")] + [ - TFHubertNoLayerNormConvLayer(config, layer_id=i + 1, name=f"conv_layers.{i + 1}") - for i in range(config.num_feat_extract_layers - 1) - ] - elif config.feat_extract_norm == "layer": - conv_layers = [ - TFHubertLayerNormConvLayer(config, layer_id=i, name=f"conv_layers.{i}") - for i in range(config.num_feat_extract_layers) - ] - else: - raise ValueError( - f"`config.feat_extract_norm` is {config.feat_extract_norm}, but has to be one of ['group', 'layer']" - ) - self.conv_layers = conv_layers - - def call(self, input_values): - hidden_states = tf.expand_dims(input_values, -1) - for conv_layer in self.conv_layers: - hidden_states = conv_layer(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - for conv_layer in self.conv_layers: - with tf.name_scope(conv_layer.name): - conv_layer.build(None) - - -class TFHubertFeatureExtractor(TFHubertFeatureEncoder): - def __init__(self, config, **kwargs): - super().__init__(config, **kwargs) - warnings.warn( - f"The class `{self.__class__.__name__}` has been depreciated " - "and will be removed in Transformers v5. " - f"Use `{self.__class__.__bases__[0].__name__}` instead.", - FutureWarning, - ) - - -class TFHubertFeatureProjection(keras.layers.Layer): - def __init__(self, config: HubertConfig, **kwargs): - super().__init__(**kwargs) - - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.projection = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer="zeros", - name="projection", - ) - self.dropout = keras.layers.Dropout(rate=config.feat_proj_dropout) - self.config = config - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.layer_norm(hidden_states) - hidden_states = self.projection(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.conv_dim[-1]]) - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, self.config.conv_dim[-1]]) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with TFBart->TFHubert -class TFHubertAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2FeedForward with Wav2Vec2->Hubert -class TFHubertFeedForward(keras.layers.Layer): - def __init__(self, config: HubertConfig, **kwargs): - super().__init__(**kwargs) - - self.intermediate_dropout = keras.layers.Dropout(config.activation_dropout) - - self.intermediate_dense = keras.layers.Dense( - units=config.intermediate_size, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer="zeros", - name="intermediate_dense", - ) - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - - self.output_dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer="zeros", - name="output_dense", - ) - self.output_dropout = keras.layers.Dropout(config.hidden_dropout) - self.config = config - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.intermediate_dense(hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - hidden_states = self.intermediate_dropout(hidden_states, training=training) - - hidden_states = self.output_dense(hidden_states) - hidden_states = self.output_dropout(hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "intermediate_dense", None) is not None: - with tf.name_scope(self.intermediate_dense.name): - self.intermediate_dense.build([None, None, self.config.hidden_size]) - if getattr(self, "output_dense", None) is not None: - with tf.name_scope(self.output_dense.name): - self.output_dense.build([None, None, self.config.intermediate_size]) - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2EncoderLayer with Wav2Vec2->Hubert -class TFHubertEncoderLayer(keras.layers.Layer): - def __init__(self, config: HubertConfig, **kwargs): - super().__init__(**kwargs) - self.attention = TFHubertAttention( - embed_dim=config.hidden_size, - num_heads=config.num_attention_heads, - dropout=config.attention_dropout, - is_decoder=False, - name="attention", - ) - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.feed_forward = TFHubertFeedForward(config, name="feed_forward") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - attn_residual = hidden_states - hidden_states, attn_weights, _ = self.attention( - hidden_states, attention_mask=attention_mask, training=training - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = attn_residual + hidden_states - - hidden_states = self.layer_norm(hidden_states) - hidden_states = hidden_states + self.feed_forward(hidden_states) - hidden_states = self.final_layer_norm(hidden_states) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "feed_forward", None) is not None: - with tf.name_scope(self.feed_forward.name): - self.feed_forward.build(None) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2EncoderLayerStableLayerNorm with Wav2Vec2->Hubert -class TFHubertEncoderLayerStableLayerNorm(keras.layers.Layer): - def __init__(self, config: HubertConfig, **kwargs): - super().__init__(**kwargs) - self.attention = TFHubertAttention( - embed_dim=config.hidden_size, - num_heads=config.num_attention_heads, - dropout=config.attention_dropout, - is_decoder=False, - name="attention", - ) - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.feed_forward = TFHubertFeedForward(config, name="feed_forward") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - attn_residual = hidden_states - hidden_states = self.layer_norm(hidden_states) - hidden_states, attn_weights, _ = self.attention( - hidden_states, attention_mask=attention_mask, training=training - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = attn_residual + hidden_states - hidden_states = hidden_states + self.feed_forward(self.final_layer_norm(hidden_states)) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "feed_forward", None) is not None: - with tf.name_scope(self.feed_forward.name): - self.feed_forward.build(None) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2Encoder with Wav2Vec2->Hubert -class TFHubertEncoder(keras.layers.Layer): - def __init__(self, config: HubertConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.pos_conv_embed = TFHubertPositionalConvEmbedding(config, name="pos_conv_embed") - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.layer = [TFHubertEncoderLayer(config, name=f"layers.{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = False, - output_hidden_states: bool | None = False, - return_dict: bool | None = True, - training: bool | None = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - - if attention_mask is not None: - hidden_states = hidden_states * tf.expand_dims(attention_mask, -1) - attention_mask = _expand_mask(attention_mask) - else: - attention_mask = None - - position_embeddings = self.pos_conv_embed(hidden_states) - hidden_states = hidden_states + position_embeddings - hidden_states = self.layer_norm(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = np.random.uniform(0, 1) - if training and (dropout_probability < self.config.layerdrop): # skip the layer - continue - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "pos_conv_embed", None) is not None: - with tf.name_scope(self.pos_conv_embed.name): - self.pos_conv_embed.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -# Copied from transformers.models.wav2vec2.modeling_tf_wav2vec2.TFWav2Vec2EncoderStableLayerNorm with Wav2Vec2->Hubert -class TFHubertEncoderStableLayerNorm(keras.layers.Layer): - def __init__(self, config: HubertConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.pos_conv_embed = TFHubertPositionalConvEmbedding(config, name="pos_conv_embed") - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.layer = [ - TFHubertEncoderLayerStableLayerNorm(config, name=f"layers.{i}") for i in range(config.num_hidden_layers) - ] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = False, - output_hidden_states: bool | None = False, - return_dict: bool | None = True, - training: bool | None = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - - if attention_mask is not None: - hidden_states = hidden_states * tf.expand_dims(attention_mask, -1) - attention_mask = _expand_mask(attention_mask) - else: - attention_mask = None - - position_embeddings = self.pos_conv_embed(hidden_states) - hidden_states = hidden_states + position_embeddings - hidden_states = self.dropout(hidden_states, training=training) - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = np.random.uniform(0, 1) - if training and (dropout_probability < self.config.layerdrop): # skip the layer - continue - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - - hidden_states = self.layer_norm(hidden_states) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "pos_conv_embed", None) is not None: - with tf.name_scope(self.pos_conv_embed.name): - self.pos_conv_embed.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFHubertMainLayer(keras.layers.Layer): - config_class = HubertConfig - - def __init__(self, config: HubertConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.feature_extractor = TFHubertFeatureEncoder(config, name="feature_extractor") - self.feature_projection = TFHubertFeatureProjection(config, name="feature_projection") - - if config.do_stable_layer_norm: - self.encoder = TFHubertEncoderStableLayerNorm(config, name="encoder") - else: - self.encoder = TFHubertEncoder(config, name="encoder") - - def build(self, input_shape=None): - self.masked_spec_embed = self.add_weight( - shape=(self.config.hidden_size,), initializer="uniform", trainable=True, name="masked_spec_embed" - ) - - if self.built: - return - self.built = True - if getattr(self, "feature_extractor", None) is not None: - with tf.name_scope(self.feature_extractor.name): - self.feature_extractor.build(None) - if getattr(self, "feature_projection", None) is not None: - with tf.name_scope(self.feature_projection.name): - self.feature_projection.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - - def _get_feat_extract_output_lengths(self, input_lengths: tf.Tensor): - """ - Computes the output length of the convolutional layers - """ - - def _conv_out_length(input_length, kernel_size, stride): - # 1D convolutional layer output length formula taken - # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html - return (input_length - kernel_size) // stride + 1 - - for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): - input_lengths = _conv_out_length(input_lengths, kernel_size, stride) - - return input_lengths - - def _mask_hidden_states(self, hidden_states: tf.Tensor, mask_time_indices: tf.Tensor | None = None): - """ - Masks extracted features along time axis and/or along feature axis according to - [SpecAugment](https://huggingface.co/papers/1904.08779). - """ - batch_size, sequence_length, hidden_size = shape_list(hidden_states) - - # `config.apply_spec_augment` can set masking to False - if not getattr(self.config, "apply_spec_augment", True): - return hidden_states - - if mask_time_indices is not None: - # apply SpecAugment along time axis with given mask_time_indices - hidden_states = tf.where( - tf.cast(mask_time_indices[:, :, tf.newaxis], tf.bool), - self.masked_spec_embed[tf.newaxis, tf.newaxis, :], - hidden_states, - ) - - elif self.config.mask_time_prob > 0: - # generate indices & apply SpecAugment along time axis - mask_time_indices = _compute_mask_indices( - (batch_size, sequence_length), - mask_prob=self.config.mask_time_prob, - mask_length=self.config.mask_time_length, - min_masks=2, - ) - hidden_states = tf.where( - tf.cast(mask_time_indices[:, :, tf.newaxis], tf.bool), - self.masked_spec_embed[tf.newaxis, tf.newaxis, :], - hidden_states, - ) - - # apply SpecAugment along feature axis - if self.config.mask_feature_prob > 0: - mask_feature_indices = _compute_mask_indices( - (batch_size, hidden_size), - mask_prob=self.config.mask_feature_prob, - mask_length=self.config.mask_feature_length, - ) - hidden_states = tf.where(mask_feature_indices[:, tf.newaxis, :], hidden_states, 0) - - return hidden_states - - @unpack_inputs - def call( - self, - input_values: tf.Tensor, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: tf.Tensor | None = None, - output_hidden_states: tf.Tensor | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs: Any, - ): - hidden_states = self.feature_extractor(tf.cast(input_values, tf.float32), training=training) - - if attention_mask is not None: - # compute real output lengths according to convolution formula - output_lengths = self._get_feat_extract_output_lengths(tf.reduce_sum(attention_mask, -1)) - - attention_mask = tf.sequence_mask( - output_lengths, maxlen=shape_list(hidden_states)[1], dtype=hidden_states.dtype - ) - - hidden_states = self.feature_projection(hidden_states, training=training) - - mask_time_indices = kwargs.get("mask_time_indices") - if training: - hidden_states = self._mask_hidden_states(hidden_states, mask_time_indices=mask_time_indices) - - encoder_outputs = self.encoder( - hidden_states, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = encoder_outputs[0] - - if not return_dict: - return (hidden_states,) + encoder_outputs[1:] - - return TFBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - -class TFHubertPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = HubertConfig - base_model_prefix = "hubert" - main_input_name = "input_values" - - @property - def input_signature(self): - return { - "input_values": tf.TensorSpec((None, 16000), tf.float32, name="input_values"), - "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), - "token_type_ids": tf.TensorSpec((None, None), tf.int32, name="token_type_ids"), - } - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - logger.warning( - f"\n{self.__class__.__name__} has backpropagation operations that are NOT supported on CPU. If you wish " - "to train/fine-tune this model, you need a GPU or a TPU" - ) - - -HUBERT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_values` only and nothing else: `model(input_values)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_values, attention_mask])` or `model([input_values, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_values": input_values, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`HubertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -HUBERT_INPUTS_DOCSTRING = r""" - Args: - input_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` `dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_values` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_values` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare TFHubert Model transformer outputting raw hidden-states without any specific head on top.", - HUBERT_START_DOCSTRING, -) -class TFHubertModel(TFHubertPreTrainedModel): - def __init__(self, config: HubertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.config = config - self.hubert = TFHubertMainLayer(config, name="hubert") - - @add_start_docstrings_to_model_forward(HUBERT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBaseModelOutput, config_class=_CONFIG_FOR_DOC) - @unpack_inputs - def call( - self, - input_values: tf.Tensor, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - """ - - Returns: - - Example: - - ```python - >>> from transformers import AutoProcessor, TFHubertModel - >>> from datasets import load_dataset - - >>> processor = AutoProcessor.from_pretrained("facebook/hubert-large-ls960-ft") - >>> model = TFHubertModel.from_pretrained("facebook/hubert-large-ls960-ft") - - - >>> def map_to_array(example): - ... example["speech"] = example["audio"]["array"] - ... return example - - - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> ds = ds.map(map_to_array) - - >>> input_values = processor(ds["speech"][0], return_tensors="tf").input_values # Batch size 1 - >>> hidden_states = model(input_values).last_hidden_state - ```""" - - output_hidden_states = output_hidden_states if output_hidden_states else self.config.output_hidden_states - output_attentions = output_attentions if output_attentions else self.config.output_attentions - return_dict = return_dict if return_dict else self.config.return_dict - - outputs = self.hubert( - input_values=input_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "hubert", None) is not None: - with tf.name_scope(self.hubert.name): - self.hubert.build(None) - - -@add_start_docstrings( - """TFHubert Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).""", - HUBERT_START_DOCSTRING, -) -class TFHubertForCTC(TFHubertPreTrainedModel): - def __init__(self, config: HubertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.hubert = TFHubertMainLayer(config, name="hubert") - self.dropout = keras.layers.Dropout(config.final_dropout) - self.lm_head = keras.layers.Dense(config.vocab_size, name="lm_head") - self.output_hidden_size = ( - config.output_hidden_size if hasattr(config, "add_adapter") and config.add_adapter else config.hidden_size - ) - - def freeze_feature_extractor(self): - """ - Calling this function will disable the gradient computation for the feature encoder so that its parameters will - not be updated during training. - """ - warnings.warn( - "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5. " - "Please use the equivalent `freeze_feature_encoder` method instead.", - FutureWarning, - ) - self.freeze_feature_encoder() - - def freeze_feature_encoder(self): - """ - Calling this function will disable the gradient computation for the feature encoder so that its parameter will - not be updated during training. - """ - self.hubert.feature_extractor.trainable = False - - @add_start_docstrings_to_model_forward(HUBERT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFCausalLMOutput, config_class=_CONFIG_FOR_DOC) - @unpack_inputs - def call( - self, - input_values: tf.Tensor, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - labels: tf.Tensor | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFCausalLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_values` docstring) Tokens with indices set to `-100` are ignored (masked), - the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - - Returns: - - Example: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoProcessor, TFHubertForCTC - >>> from datasets import load_dataset - - >>> processor = AutoProcessor.from_pretrained("facebook/hubert-large-ls960-ft") - >>> model = TFHubertForCTC.from_pretrained("facebook/hubert-large-ls960-ft") - - - >>> def map_to_array(example): - ... example["speech"] = example["audio"]["array"] - ... return example - - - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> ds = ds.map(map_to_array) - - >>> input_values = processor(ds["speech"][0], return_tensors="tf").input_values # Batch size 1 - >>> logits = model(input_values).logits - >>> predicted_ids = tf.argmax(logits, axis=-1) - - >>> transcription = processor.decode(predicted_ids[0]) - - >>> # compute loss - >>> target_transcription = "A MAN SAID TO THE UNIVERSE SIR I EXIST" - - >>> # Pass the transcription as text to encode labels - >>> labels = processor(text=transcription, return_tensors="tf").input_values - - >>> loss = model(input_values, labels=labels).loss - ```""" - if labels is not None and tf.reduce_max(labels) >= self.config.vocab_size: - raise ValueError(f"Label values must be <= vocab_size: {self.config.vocab_size}") - - outputs = self.hubert( - input_values=input_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, training=training) - - logits = self.lm_head(hidden_states) - - if labels is not None: - attention_mask = ( - attention_mask if attention_mask is not None else tf.ones_like(input_values, dtype=tf.float32) - ) - input_lengths = self.hubert._get_feat_extract_output_lengths(tf.reduce_sum(attention_mask, axis=-1)) - - # assuming that padded tokens are filled with -100 - # when not being attended to - labels_mask = tf.cast(labels >= 0, tf.int32) - target_lengths = tf.reduce_sum(labels_mask, axis=-1) - - loss = tf.nn.ctc_loss( - logits=logits, - labels=labels, - logit_length=input_lengths, - label_length=target_lengths, - blank_index=self.config.pad_token_id, - logits_time_major=False, - ) - - if self.config.ctc_loss_reduction == "sum": - loss = tf.reduce_sum(loss) - loss = tf.reshape(loss, (1,)) - if self.config.ctc_loss_reduction == "mean": - loss = tf.reduce_mean(loss) - loss = tf.reshape(loss, (1,)) - else: - loss = None - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "hubert", None) is not None: - with tf.name_scope(self.hubert.name): - self.hubert.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build([None, None, self.output_hidden_size]) - - -__all__ = ["TFHubertForCTC", "TFHubertModel", "TFHubertPreTrainedModel"] diff --git a/src/transformers/models/hubert/modular_hubert.py b/src/transformers/models/hubert/modular_hubert.py index facebcf445e6..d7169a85d30b 100644 --- a/src/transformers/models/hubert/modular_hubert.py +++ b/src/transformers/models/hubert/modular_hubert.py @@ -136,8 +136,6 @@ class HubertPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/ibert/modeling_ibert.py b/src/transformers/models/ibert/modeling_ibert.py index 57b3df2f570b..e1b3c7fb966c 100644 --- a/src/transformers/models/ibert/modeling_ibert.py +++ b/src/transformers/models/ibert/modeling_ibert.py @@ -89,8 +89,6 @@ def __init__(self, config): self.embeddings_act1 = QuantAct(self.embedding_act_bit, quant_mode=self.quant_mode) self.embeddings_act2 = QuantAct(self.embedding_act_bit, quant_mode=self.quant_mode) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = IntLayerNorm( config.hidden_size, eps=config.layer_norm_eps, @@ -628,8 +626,6 @@ class IBertPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (QuantLinear, nn.Linear)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/idefics/__init__.py b/src/transformers/models/idefics/__init__.py index 4adb66825445..fedac647008b 100644 --- a/src/transformers/models/idefics/__init__.py +++ b/src/transformers/models/idefics/__init__.py @@ -21,7 +21,6 @@ from .configuration_idefics import * from .image_processing_idefics import * from .modeling_idefics import * - from .modeling_tf_idefics import * from .processing_idefics import * else: import sys diff --git a/src/transformers/models/idefics/image_processing_idefics.py b/src/transformers/models/idefics/image_processing_idefics.py index fe9085331cde..6ef5b39afeeb 100644 --- a/src/transformers/models/idefics/image_processing_idefics.py +++ b/src/transformers/models/idefics/image_processing_idefics.py @@ -155,10 +155,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # For training a user needs to pass their own set of transforms as a Callable. # For reference this is what was used in the original IDEFICS training: diff --git a/src/transformers/models/idefics/modeling_tf_idefics.py b/src/transformers/models/idefics/modeling_tf_idefics.py deleted file mode 100644 index 0e8e75be28f8..000000000000 --- a/src/transformers/models/idefics/modeling_tf_idefics.py +++ /dev/null @@ -1,1778 +0,0 @@ -# coding=utf-8 -# Copyright 2022 EleutherAI and the HuggingFace Inc. team. All rights reserved. -# -# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX -# and OPT implementations in this library. It has been modified from its -# original forms to accommodate minor architectural differences compared -# to GPT-NeoX and OPT used by the Meta AI team that trained the model. -# -# 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. -"""TF 2.0 Idefics model.""" - -from __future__ import annotations - -from dataclasses import dataclass - -import tensorflow as tf - -from ... import TFPreTrainedModel -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ModelOutput -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - keras_serializable, - shape_list, - unpack_inputs, -) -from ...tf_utils import invert_attention_mask, scaled_dot_product_attention -from ...utils import ( - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_idefics import IdeficsConfig -from .perceiver_tf import TFIdeficsPerceiverResampler -from .vision_tf import TFIdeficsVisionTransformer - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "IdeficsConfig" - - -@dataclass -class TFIdeficsBaseModelOutputWithPast(ModelOutput): - """ - Base class for Idefics model's outputs that may also contain a past key/values (to speed up sequential decoding). - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - - If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, - hidden_size)` is output. - past_key_values (`tuple(tuple(tf.Tensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(tf.Tensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and optionally if - `config.is_encoder_decoder=True` 2 additional tensors of shape `(batch_size, num_heads, - encoder_sequence_length, embed_size_per_head)`. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if - `config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values` - input) to speed up sequential decoding. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + - one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - image_hidden_states (`tuple(tf.Tensor)`, *optional*): - Tuple of `tf.Tensor` (one for the output of the image embeddings, `(batch_size, num_images, - sequence_length, hidden_size)`. - - image_hidden_states of the model produced by the vision encoder, and optionally by the perceiver - """ - - last_hidden_state: tf.Tensor | None = None - past_key_values: tuple[tuple[tf.Tensor]] | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - image_hidden_states: tuple[tf.Tensor] | None = None - - -@dataclass -class TFIdeficsCausalLMOutputWithPast(ModelOutput): - """ - Base class for Idefics causal language model (or autoregressive) outputs. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Language modeling loss (for next-token prediction). - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`tuple(tuple(tf.Tensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(tf.Tensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) - - Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see - `past_key_values` input) to speed up sequential decoding. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + - one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - image_hidden_states (`tuple(tf.Tensor)`, *optional*): - Tuple of `tf.Tensor` (one for the output of the image embeddings, `(batch_size, num_images, - sequence_length, hidden_size)`. - - image_hidden_states of the model produced by the vision encoder, and optionally by the perceiver - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - image_hidden_states: tuple[tf.Tensor] | None = None - - -def expand_inputs_for_generation( - input_ids, - expand_size=1, - is_encoder_decoder=False, - attention_mask=None, - encoder_outputs=None, - **model_kwargs, -): - expanded_return_idx = tf.reshape(tf.repeat(tf.range(tf.shape(input_ids)[0]), expand_size), [-1]) - input_ids = tf.gather(input_ids, expanded_return_idx) - model_kwargs["pixel_values"] = model_kwargs.get("pixel_values") - model_kwargs["image_encoder_embeddings"] = model_kwargs.get("image_encoder_embeddings") - model_kwargs["perceiver_embeddings"] = model_kwargs.get("perceiver_embeddings") - model_kwargs["image_attention_mask"] = model_kwargs.get("image_attention_mask") - - if "token_type_ids" in model_kwargs: - token_type_ids = model_kwargs["token_type_ids"] - model_kwargs["token_type_ids"] = tf.gather(token_type_ids, expanded_return_idx) - - if attention_mask is not None: - model_kwargs["attention_mask"] = tf.gather(attention_mask, expanded_return_idx) - - if model_kwargs["image_attention_mask"] is not None: - model_kwargs["image_attention_mask"] = tf.gather(model_kwargs["image_attention_mask"], expanded_return_idx) - - if model_kwargs["pixel_values"] is not None: - model_kwargs["pixel_values"] = tf.gather(model_kwargs["pixel_values"], expanded_return_idx) - - elif model_kwargs["image_encoder_embeddings"] is not None: - model_kwargs["image_encoder_embeddings"] = tf.gather( - model_kwargs["image_encoder_embeddings"], expanded_return_idx - ) - - elif model_kwargs["perceiver_embeddings"] is not None: - model_kwargs["perceiver_embeddings"] = tf.gather(model_kwargs["perceiver_embeddings"], expanded_return_idx) - - return input_ids, model_kwargs - - -def update_model_kwargs_for_generation(outputs, model_kwargs): - # must have this key set to at least None - if "past_key_values" in outputs: - model_kwargs["past_key_values"] = outputs.past_key_values - else: - model_kwargs["past_key_values"] = None - - # update token_type_ids with last value - if "token_type_ids" in model_kwargs: - token_type_ids = model_kwargs["token_type_ids"] - model_kwargs["token_type_ids"] = tf.concat([token_type_ids, token_type_ids[:, -1:, ...]], axis=-1) - - # update attention masks - if "attention_mask" in model_kwargs: - attention_mask = model_kwargs["attention_mask"] - model_kwargs["attention_mask"] = tf.concat( - [attention_mask, tf.ones_like(attention_mask[:, -1:, ...])], axis=-1 - ) - if "image_attention_mask" in model_kwargs: - image_attention_mask = model_kwargs["image_attention_mask"] - last_mask = image_attention_mask[:, -1:, ...] - model_kwargs["image_attention_mask"] = last_mask - - # Get the precomputed image_hidden_states - model_kwargs["image_hidden_states"] = outputs.image_hidden_states - - return model_kwargs - - -def prepare_inputs_for_generation(input_ids, past_key_values=None, **kwargs): - token_type_ids = kwargs.get("token_type_ids") - # only last token for inputs_ids if past is defined in kwargs - if past_key_values is not None: - input_ids = input_ids[:, -1:] - if token_type_ids is not None: - token_type_ids = token_type_ids[:, -1:] - - attention_mask = kwargs.get("attention_mask") - position_ids = kwargs.get("position_ids") - - if attention_mask is not None and position_ids is None: - # create position_ids on the fly for batch generation - position_ids = tf.math.cumsum(tf.cast(attention_mask, dtype=tf.int64), axis=-1) - 1 - position_ids = tf.where(attention_mask == 0, 1, position_ids) - if past_key_values is not None: - position_ids = position_ids[:, -1:] - - pixel_values = kwargs.get("pixel_values") - image_encoder_embeddings = kwargs.get("image_encoder_embeddings") - perceiver_embeddings = kwargs.get("perceiver_embeddings") - image_attention_mask = kwargs.get("image_attention_mask") - interpolate_pos_encoding = kwargs.get("interpolate_pos_encoding", False) - - return { - "input_ids": input_ids, - "past_key_values": past_key_values, - "use_cache": kwargs.get("use_cache"), - "position_ids": position_ids, - "attention_mask": attention_mask, - "token_type_ids": token_type_ids, - "pixel_values": pixel_values, - "image_encoder_embeddings": image_encoder_embeddings, - "perceiver_embeddings": perceiver_embeddings, - "image_attention_mask": image_attention_mask, - "interpolate_pos_encoding": interpolate_pos_encoding, - } - - -def freeze_model(model, module_exceptions=[]): - mapping = { - "LayerNorm": tf.keras.layers.LayerNormalization, - "Dense": tf.keras.layers.Dense, - "Embedding": tf.keras.layers.Embedding, - } - module_exceptions_mapped = [mapping[m] for m in module_exceptions] - if not hasattr(model, "layers"): - model.trainable = False # It is just a layer - return model - for layer in model.layers: - if module_exceptions and any(isinstance(layer, t) for t in module_exceptions_mapped): - layer.trainable = True # Explicitly setting it to true to avoid any mistakes - else: - layer.trainable = False - return model - - -class TFIdeficsDecoupledEmbedding(tf.keras.layers.Embedding): - """ - Implements a decoupling of parameters to allow freezing (or not) a subset of the embeddings. In practise, the - regular `weight` can be trained or frozen (i.e. `partially_freeze=True`), and if `num_additional_embeddings` > 0, - then it will create `num_additional_embeddings` additional parameters that are always trained. If - `num_additional_embeddings=0`, then the module defaults back to the regular behavior of `tf.keras.layers.Embedding`. - """ - - def __init__( - self, - num_embeddings, - num_additional_embeddings, - embedding_dim, - partially_freeze: bool | None = False, - dtype=None, - **kwargs, - ) -> None: - """ - Args: - num_embeddings (`int`): - Size of the dictionary of embeddings - num_additional_embeddings (`int`): - Number of additional embeddings. Only useful when you `partially_freeze=True`. - embedding_dim (`int`): - The size of each embedding vector - partially_freeze: (`bool`, *optional*, defaults to `False`): - If `True`, the regular `weight` will be frozen. `additional_weight` is never frozen. - - Note: there are a lot of other parameters to initialize a standard `tf.keras.layers.Embedding` such as `mask_zero`, - `input_length` or `embeddings_initializer`. We are not supporting these. - """ - super().__init__( - input_dim=num_embeddings, - output_dim=embedding_dim, - dtype=dtype, - **kwargs, - ) - self.num_embeddings = num_embeddings - self.num_additional_embeddings = num_additional_embeddings - self.partially_freeze = partially_freeze - - if partially_freeze: - self.trainable = False - - if self.num_additional_embeddings > 0: - self.additional_embedding = tf.keras.layers.Embedding( - input_dim=self.num_additional_embeddings, - output_dim=embedding_dim, - dtype=dtype, - name="additional_embedding", - ) - - def call(self, input_ids): - """ - we have 2 embeddings, with different indices - one pretrained self.weight and another - self.additional_embedding.weight that is being trained. - - in order to make a lookup of the input ids, we: - 1. find out the indices of the entries belonging to the 2nd embedding - 2. extract those values while subtracting the size of the first embedding (num_embeddings), since the 2nd - embedding starts from 0 and not num_embeddings - 3. perform the 2nd embedding lookup - 4. now we handle the 1st embedding, we overwrite indices belonging to the 2nd embedding with a padding index - 5. perform the 1st embedding lookup - 6. now we overwrite the values in the 1st embedding lookup with the values of the 2nd embedding lookup - - note: for the 1st embedding lookup we could have looked up only the low indices and not do the padding, but - then we have to create a new tensor and populate it with 2 tensors that are spread out across various indices - - i.e. not a simple concat - I haven't benchmarked the complex case if it's any faster, given that seqlens are - usually relatively short it's probably not faster or if faster not by much - but might be a good idea to - measure. - - """ - if self.num_additional_embeddings == 0: - return super().call(input_ids) - - # Clone so that we don't modify the original input_ids later on - input_ids = tf.identity(input_ids) - additional_vocab_indices = tf.where(input_ids >= self.num_embeddings) - input_ids_additional_vocab = tf.gather_nd(input_ids, additional_vocab_indices) - additional_embeddings = self.additional_embedding(input_ids_additional_vocab - self.num_embeddings) - - # for successful lookup replace input_ids with 0, the results of these will be discarded anyway - input_ids = tf.tensor_scatter_nd_update( - input_ids, - additional_vocab_indices, - # tensor filled with 0, having the same length as additional_vocab_indices - tf.zeros(tf.shape(additional_vocab_indices)[0], dtype=input_ids.dtype), - ) - full_vector = super().call(input_ids) - - # overwrite the records with high indices - full_vector = tf.tensor_scatter_nd_update(full_vector, additional_vocab_indices, additional_embeddings) - - return full_vector - - def extra_repr(self) -> str: - return f"num_embeddings={self.num_embeddings}, num_additional_embeddings={self.num_additional_embeddings}, embedding_dim={self.output_dim}, partially_freeze={self.partially_freeze}" - - -class TFIdeficsDecoupledLinear(tf.keras.layers.Layer): - """ - Implements a decoupling of parameters to allow freezing (or not) a subset of the parameters. In practise, the - regular `weight` can be trained or frozen (i.e. `partially_freeze=True`), and if `out_additional_features` > 0, - then it will create `out_additional_features * in_features` additional parameters that are always trained. If - `out_additional_features=0`, then the module defaults back to the regular behavior of `tf.keras.layers.Dense`. - """ - - def __init__( - self, - in_features: int, - out_features: int, - out_additional_features: int = 0, - bias: bool = True, - partially_freeze: bool = True, - **kwargs, - ) -> None: - """ - out_additional_features: int. Number of additional trainable dimensions. Only makes sense when - `partially_freeze=True`. partially_freeze: bool. If True, the regular `weight` will be frozen and extra - parameters (if any) will be trainable. If False, default to the regular behavior of tf.keras.layers.Dense. - """ - super().__init__(**kwargs) - self.out_additional_features = out_additional_features - self.partially_freeze = partially_freeze - - self.in_features = in_features - self.out_features = out_features - self.use_bias = bias - - if out_additional_features > 0: - self.additional_fc = tf.keras.layers.Dense( - units=out_additional_features, use_bias=bias, name="additional_fc" - ) - - def call(self, inputs: tf.Tensor) -> tf.Tensor: - output = tf.linalg.matmul(a=inputs, b=self.weight, transpose_b=True) - if self.bias is not None: - output = tf.nn.bias_add(output, self.bias) - - if self.out_additional_features > 0: - additional_features = self.additional_fc(inputs) - output = tf.concat([output, additional_features], axis=-1) - - return output - - def get_config(self): - config = super().get_config() - config.update( - { - "in_features": self.in_features, - "out_features": self.out_features, - "out_additional_features": self.out_additional_features, - "bias": self.bias is not None, - "partially_freeze": self.partially_freeze, - } - ) - return config - - def extra_repr(self) -> str: - """Overwriting `nn.Linear.extra_repr` to include new parameters.""" - return f"in_features={self.in_features}, out_features={self.out_features}, out_additional_features={self.out_additional_features}, bias={self.bias is not None}, partially_freeze={self.partially_freeze}" - - @classmethod - def from_config(cls, config): - return cls(**config) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - self.weight = self.add_weight( - shape=(self.out_features, self.in_features), trainable=not self.partially_freeze, name="weight" - ) - if self.use_bias: - self.bias = self.add_weight(shape=(self.out_features,), trainable=not self.partially_freeze, name="bias") - else: - self.bias = None - if getattr(self, "additional_fc", None) is not None: - with tf.name_scope(self.additional_fc.name): - self.additional_fc.build(self.in_features) - - -def _make_causal_mask(input_ids_shape, dtype, past_key_values_length=0): - """ - Make causal mask used for bi-directional self-attention, supporting both static and dynamic shapes. - """ - bsz, tgt_len = input_ids_shape - - # Create a matrix where only the lower triangle and diagonal are filled with zeros (causal mask) - mask = tf.fill((tgt_len, tgt_len), tf.dtypes.as_dtype(dtype).min) - mask_cond = tf.range(tgt_len) - mask = tf.where(mask_cond[:, None] >= mask_cond[None, :], 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length), dtype=dtype), mask], axis=-1) - - if bsz is None: - # When batch size is dynamic, expand and tile - # so we can compile a functional model - mask = tf.expand_dims(mask, 0) - mask = tf.expand_dims(mask, 0) # shape: (1, 1, tgt_len, tgt_len + past_key_values_length) - mask = tf.tile(mask, [bsz, 1, 1, 1]) - else: - # When batch size is static, directly use broadcast_to - mask = tf.broadcast_to(mask[None, None, :, :], (bsz, 1, tgt_len, tgt_len + past_key_values_length)) - - return mask - - -def _expand_mask(mask, dtype, tgt_len=None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - bsz, src_len = shape_list(mask) - tgt_len = tgt_len if tgt_len is not None else src_len - - expanded_mask = tf.expand_dims(tf.expand_dims(mask, 1), 1) - expanded_mask = tf.broadcast_to(expanded_mask, [bsz, 1, tgt_len, src_len]) - - inverted_mask = 1.0 - tf.cast(expanded_mask, dtype) - - return tf.where( - tf.cast(inverted_mask, bool), tf.fill(dims=shape_list(inverted_mask), value=tf.float32.min), inverted_mask - ) - - -class TFIdeficsRMSNorm(tf.keras.layers.Layer): - def __init__(self, hidden_size, eps=1e-6, **kwargs): - """ - TFIdeficsRMSNorm is equivalent to T5LayerNorm - """ - super().__init__(**kwargs) - self.hidden_size = hidden_size - self.variance_epsilon = eps - - def build(self, input_shape): - if self.built: - return - self.built = True - self.weight = self.add_weight(name="weight", shape=[self.hidden_size], initializer="ones") - - super().build(input_shape) - - def call(self, hidden_states): - variance = tf.math.reduce_mean(tf.math.square(tf.cast(hidden_states, tf.float32)), axis=-1, keepdims=True) - hidden_states = hidden_states * tf.math.rsqrt(variance + self.variance_epsilon) - - # convert into half-precision if necessary - if self.weight.dtype in [tf.float16, tf.bfloat16]: - hidden_states = tf.cast(hidden_states, self.weight.dtype) - - return self.weight * hidden_states - - -class TFIdeficsEmbedding(tf.keras.layers.Layer): - def __init__(self, dim, max_position_embeddings=2048, base=10000, **kwargs): - super().__init__(**kwargs) - - self.dim = dim - self.max_position_embeddings = max_position_embeddings - self.base = base - self.inv_freq = tf.constant( - 1.0 / (self.base ** (tf.range(start=0, limit=self.dim, delta=2, dtype=tf.float32) / self.dim)) - ) - - def _compute_cos_sin(self, seq_len): - t = tf.range(seq_len, dtype=self.inv_freq.dtype) - freqs = tf.einsum("i, j -> ij", t, self.inv_freq) # Outer multiplication - emb = tf.concat((freqs, freqs), axis=-1) - - return tf.cos(emb), tf.sin(emb) - - def call(self, x, seq_len=None): - # x: [bs, num_attention_heads, seq_len, head_size] - if seq_len is None: - seq_len = shape_list(x)[2] - return self._compute_cos_sin(seq_len=seq_len) - - -def rotate_half(x): - """Rotates half the hidden dims of the input.""" - x1 = x[..., : x.shape[-1] // 2] - x2 = x[..., x.shape[-1] // 2 :] - return tf.concat((-x2, x1), axis=-1) - - -def apply_rotary_pos_emb(q, k, cos, sin, position_ids): - cos = tf.gather(cos, position_ids) # [seq_len, dim] -> [batch_size, 1, seq_len, head_dim] - sin = tf.gather(sin, position_ids) - cos = tf.expand_dims(cos, 1) - sin = tf.expand_dims(sin, 1) - q_embed = (q * cos) + (rotate_half(q) * sin) - k_embed = (k * cos) + (rotate_half(k) * sin) - return q_embed, k_embed - - -class TFIdeficsMLP(tf.keras.layers.Layer): - def __init__( - self, - hidden_size: int, - intermediate_size: int, - hidden_act: str, - **kwargs, - ): - super().__init__(**kwargs) - self.gate_proj = tf.keras.layers.Dense(intermediate_size, use_bias=False, name="gate_proj") - self.down_proj = tf.keras.layers.Dense(hidden_size, use_bias=False, name="down_proj") - self.up_proj = tf.keras.layers.Dense(intermediate_size, use_bias=False, name="up_proj") - self.act_fn = get_tf_activation(hidden_act) - self.intermediate_size = intermediate_size - self.hidden_size = hidden_size - - def call(self, x): - return self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "gate_proj", None) is not None: - with tf.name_scope(self.gate_proj.name): - self.gate_proj.build(self.hidden_size) - if getattr(self, "down_proj", None) is not None: - with tf.name_scope(self.down_proj.name): - self.down_proj.build(self.intermediate_size) - if getattr(self, "up_proj", None) is not None: - with tf.name_scope(self.up_proj.name): - self.up_proj.build(self.hidden_size) - - -class TFIdeficsAttention(tf.keras.layers.Layer): - """Multi-headed attention from 'Attention Is All You Need' paper""" - - def __init__( - self, - hidden_size: int, - num_heads: int, - dropout: float = 0.0, - is_cross_attention: bool = False, - config: IdeficsConfig = None, - qk_layer_norms: bool = False, - **kwargs, - ): - super().__init__(**kwargs) - self.hidden_size = hidden_size - self.num_heads = num_heads - self.head_dim = hidden_size // num_heads - self.dropout = dropout - self.config = config - self.is_causal = True - - if (self.head_dim * num_heads) != self.hidden_size: - raise ValueError( - f"hidden_size must be divisible by num_heads (got `hidden_size`: {self.hidden_size}" - f" and `num_heads`: {num_heads})." - ) - - self.is_cross_attention = is_cross_attention - - self.q_proj = tf.keras.layers.Dense( - num_heads * self.head_dim, - use_bias=False, - name="q_proj", - ) - self.k_proj = tf.keras.layers.Dense( - num_heads * self.head_dim, - use_bias=False, - name="k_proj", - ) - self.v_proj = tf.keras.layers.Dense( - num_heads * self.head_dim, - use_bias=False, - name="v_proj", - ) - self.o_proj = tf.keras.layers.Dense( - hidden_size, - use_bias=False, - name="o_proj", - ) - self.rotary_emb = TFIdeficsEmbedding(self.head_dim, name="rotary_emb") - - self.qk_layer_norms = qk_layer_norms - if self.qk_layer_norms: - self.q_layer_norm = TFIdeficsRMSNorm(self.head_dim, eps=config.rms_norm_eps, name="q_layer_norm") - self.k_layer_norm = TFIdeficsRMSNorm(self.head_dim, eps=config.rms_norm_eps, name="k_layer_norm") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - past_key_value: tuple[tf.Tensor] | None = None, - output_attentions: bool = False, - use_cache: bool = False, - ) -> tuple[tf.Tensor, tf.Tensor | None, tuple[tf.Tensor] | None]: - # if key_value_states are provided this layer is used as a cross-attention layer - is_cross_attention = self.is_cross_attention or key_value_states is not None - - bsz, q_len, _ = shape_list(hidden_states) - - query_states = self._shape(self.q_proj(hidden_states), q_len, bsz) - if not is_cross_attention: - key_states = self._shape(self.k_proj(hidden_states), q_len, bsz) - value_states = self._shape(self.v_proj(hidden_states), q_len, bsz) - else: - _, kv_len, _ = shape_list(key_value_states) # Note that, in this case, `kv_len` == `kv_seq_len` - key_states = self._shape(self.k_proj(key_value_states), kv_len, bsz) - value_states = self._shape(self.v_proj(key_value_states), kv_len, bsz) - - kv_seq_len = shape_list(key_states)[-2] - if past_key_value is not None: - kv_seq_len += shape_list(past_key_value[0])[-2] - if not is_cross_attention: - # Below is to allow symbolic tensors compilation - if tf.is_tensor(kv_seq_len): - seq_len = tf.reduce_max(kv_seq_len, q_len) - else: - seq_len = max(kv_seq_len, q_len) - cos, sin = self.rotary_emb(value_states, seq_len) - query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin, position_ids) - # [bsz, nh, t, hd] - - if past_key_value is not None: - # reuse k, v, self_attention - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - - past_key_value = (key_states, value_states) if use_cache else None - - if self.qk_layer_norms: - query_states = self.q_layer_norm(query_states) - key_states = self.k_layer_norm(key_states) - - tf.debugging.assert_equal( - tf.shape(attention_mask), - [bsz, 1, q_len, kv_seq_len], - message=f"Attention weights should be of size {[bsz, 1, q_len, kv_seq_len]}, but is {tf.shape(attention_mask)}", - ) - - attn_output = scaled_dot_product_attention( - query_states, - key_states, - value_states, - attn_mask=attention_mask, - # The q_len > 1 is necessary to match with AttentionMaskConverter.to_causal_4d that does not create a causal mask in case q_len == 1. - is_causal=self.is_causal and attention_mask is None and q_len > 1, - ) - - tf.debugging.assert_equal( - tf.shape(attn_output), - [bsz, self.num_heads, q_len, self.head_dim], - message=f"Attention weights should be of size {[bsz, self.num_heads, q_len, self.head_dim]}, but is {tf.shape(attn_output)}", - ) - - attn_output = tf.reshape(tf.transpose(attn_output, perm=[0, 2, 1, 3]), (bsz, q_len, self.hidden_size)) - - attn_output = self.o_proj(attn_output) - - attn_weights = None - if output_attentions: - logger.warning_once( - "attn_weights are not extracted in scaled_dot_product_attention. The model returns None instead" - ) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if self.is_cross_attention: - kv_input_dim = ( - self.hidden_size - if not hasattr(self.config.vision_config, "embed_dim") - else self.config.vision_config.embed_dim - ) - else: - kv_input_dim = self.hidden_size - if getattr(self, "o_proj", None) is not None: - with tf.name_scope(self.o_proj.name): - self.o_proj.build(self.num_heads * self.head_dim) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build(self.hidden_size) - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build(kv_input_dim) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build(kv_input_dim) - if getattr(self, "rotary_emb", None) is not None: - with tf.name_scope(self.rotary_emb.name): - self.rotary_emb.build(None) - - -class TFIdeficsDecoderLayer(tf.keras.layers.Layer): - def __init__(self, config: IdeficsConfig, **kwargs): - super().__init__(**kwargs) - self.hidden_size = config.hidden_size - self.self_attn = TFIdeficsAttention( - hidden_size=self.hidden_size, - num_heads=config.num_attention_heads, - dropout=config.dropout, - config=config, - name="self_attn", - ) - self.mlp = TFIdeficsMLP( - hidden_size=self.hidden_size, - intermediate_size=config.intermediate_size, - hidden_act=config.hidden_act, - name="mlp", - ) - self.input_layernorm = TFIdeficsRMSNorm(config.hidden_size, eps=config.rms_norm_eps, name="input_layernorm") - self.post_attention_layernorm = TFIdeficsRMSNorm( - config.hidden_size, eps=config.rms_norm_eps, name="post_attention_layernorm" - ) - self.dropout = config.dropout - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - past_key_value: tuple[tf.Tensor] | None = None, - output_attentions: bool | None = False, - use_cache: bool | None = False, - training=False, - ) -> tuple[tf.Tensor, tuple[tf.Tensor, tf.Tensor] | None]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`, *optional*): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding - (see `past_key_values`). - past_key_value (`Tuple(tf.Tensor)`, *optional*): cached past key and value projection states - """ - - residual = hidden_states - - hidden_states = self.input_layernorm(hidden_states) - - # Self Attention - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - past_key_value=past_key_value, - output_attentions=output_attentions, - use_cache=use_cache, - ) - hidden_states = tf.nn.dropout(hidden_states, rate=self.dropout) - hidden_states = residual + hidden_states - - # Fully Connected - residual = hidden_states - hidden_states = self.post_attention_layernorm(hidden_states) - hidden_states = self.mlp(hidden_states) - hidden_states = tf.nn.dropout(hidden_states, rate=self.dropout) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights,) - - if use_cache: - outputs += (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "input_layernorm", None) is not None: - with tf.name_scope(self.input_layernorm.name): - self.input_layernorm.build(None) - if getattr(self, "post_attention_layernorm", None) is not None: - with tf.name_scope(self.post_attention_layernorm.name): - self.post_attention_layernorm.build(None) - - -class TFIdeficsGatedCrossAttentionLayer(tf.keras.layers.Layer): - def __init__(self, config: IdeficsConfig, **kwargs): - super().__init__(**kwargs) - self.hidden_size = config.hidden_size - self.cross_attn = TFIdeficsAttention( - hidden_size=self.hidden_size, - num_heads=config.num_attention_heads, - is_cross_attention=True, - dropout=config.dropout, - config=config, - qk_layer_norms=config.qk_layer_norms, - name="cross_attn", - ) - self.mlp = TFIdeficsMLP( - hidden_size=self.hidden_size, - intermediate_size=config.intermediate_size, - hidden_act=config.hidden_act, - name="mlp", - ) - self.input_layernorm = TFIdeficsRMSNorm(config.hidden_size, eps=config.rms_norm_eps, name="input_layernorm") - self.post_attention_layernorm = TFIdeficsRMSNorm( - config.hidden_size, eps=config.rms_norm_eps, name="post_attention_layernorm" - ) - self.config = config.dropout - - self.act_cross_attn = tf.keras.activations.tanh - self.act_dense = tf.keras.activations.tanh - - self.alpha_initializer = config.alpha_initializer - self.alpha_type = config.alpha_type - self.alphas_initializer_range = config.alphas_initializer_range - - def build(self, input_shape): - if self.built: - return - self.built = True - if self.alpha_initializer == "zeros": - if self.alpha_type == "vector": - self.alpha_cross_attn = self.add_weight( - shape=(1, 1, self.hidden_size), initializer="zeros", trainable=True, name="alpha_cross_attn" - ) - self.alpha_dense = self.add_weight( - shape=(1, 1, self.hidden_size), initializer="zeros", trainable=True, name="alpha_dense" - ) - elif self.alpha_type == "float": - self.alpha_cross_attn = self.add_weight( - shape=(1,), initializer="zeros", trainable=True, name="alpha_cross_attn" - ) - self.alpha_dense = self.add_weight(shape=(1,), initializer="zeros", trainable=True, name="alpha_dense") - else: - raise ValueError(f"Unknown value for `alpha_type` ({self.alpha_type})") - - elif self.alpha_initializer == "ones": - if self.alpha_type == "vector": - self.alpha_cross_attn = self.add_weight( - shape=(1, 1, self.hidden_size), initializer="ones", trainable=True, name="alpha_cross_attn" - ) - self.alpha_dense = self.add_weight( - shape=(1, 1, self.hidden_size), initializer="ones", trainable=True, name="alpha_dense" - ) - elif self.alpha_type == "float": - self.alpha_cross_attn = self.add_weight( - shape=(1,), initializer="ones", trainable=True, name="alpha_cross_attn" - ) - self.alpha_dense = self.add_weight(shape=(1,), initializer="ones", trainable=True, name="alpha_dense") - else: - raise ValueError(f"Unknown value for `alpha_type` ({self.alpha_type})") - - elif self.alpha_initializer in {"normal", "gaussian", "random"}: - if self.alpha_type == "vector": - self.alpha_cross_attn = self.add_weight( - shape=(1, 1, self.hidden_size), - initializer=tf.keras.initializers.RandomNormal(mean=0.0, stddev=self.alphas_initializer_range), - trainable=True, - name="alpha_cross_attn", - ) - self.alpha_dense = self.add_weight( - shape=(1, 1, self.hidden_size), - initializer=tf.keras.initializers.RandomNormal(mean=0.0, stddev=self.alphas_initializer_range), - trainable=True, - name="alpha_dense", - ) - elif self.alpha_type == "float": - self.alpha_cross_attn = self.add_weight( - shape=(1,), - initializer=tf.keras.initializers.RandomNormal(mean=0.0, stddev=self.alphas_initializer_range), - trainable=True, - name="alpha_type", - ) - self.alpha_dense = self.add_weight( - shape=(1,), - initializer=tf.keras.initializers.RandomNormal(mean=0.0, stddev=self.alphas_initializer_range), - trainable=True, - name="alpha_dense", - ) - else: - raise ValueError(f"Unknown value for `alpha_type` ({self.alpha_type})") - - else: - raise NotImplementedError(f"Alpha initialization scheme {self.alpha_initializer} not yet implemented!") - - if not (hasattr(self, "alpha_cross_attn") and hasattr(self, "alpha_dense")): - raise ValueError("Alpha parameters not initialized correctly!") - with tf.name_scope(self.cross_attn.name): - self.cross_attn.build(None) - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - with tf.name_scope(self.input_layernorm.name): - self.input_layernorm.build(None) - with tf.name_scope(self.post_attention_layernorm.name): - self.post_attention_layernorm.build(None) - super().build(input_shape) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - image_hidden_states: tf.Tensor | None = None, - image_attention_mask: tf.Tensor | None = None, - cross_attention_gate: tf.Tensor | None = None, - output_attentions: bool | None = False, - use_cache: bool | None = False, - past_key_value: tuple[tf.Tensor] | None = None, - ) -> tuple[tf.Tensor, tuple[tf.Tensor, tf.Tensor] | None]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`, *optional*): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding - (see `past_key_values`). - past_key_value (`Tuple(tf.Tensor)`, *optional*): cached past key and value projection states - no_images (`bool`, *optional*, defaults to `False`): If `True` the vision part is ignored - """ - if image_hidden_states is None: - raise ValueError( - "`image_hidden_states` is required for Idefics cross attention module which are visual features to be" - " conditioned on." - ) - - if cross_attention_gate is None: - raise ValueError( - "`cross_attention_gate` is required for Idefics cross attention module to zero-out the cross-attention hidden_states attending to no images." - ) - - if past_key_value is not None: - raise NotImplementedError("Past key value states are not implemented for Idefics cross attention module.") - - residual = hidden_states - - hidden_states = self.input_layernorm(hidden_states) - - # Self Attention - hidden_states, self_attn_weights, present_key_value = self.cross_attn( - hidden_states=hidden_states, - key_value_states=image_hidden_states, - attention_mask=image_attention_mask, - output_attentions=output_attentions, - ) - hidden_states = tf.nn.dropout(hidden_states, rate=self.config) - mask = tf.cast(cross_attention_gate == 0, dtype=hidden_states.dtype) - # Expand dimensions of mask to match hidden_states - mask = tf.expand_dims(mask, -1) - hidden_states = tf.where( - tf.broadcast_to(mask, tf.shape(hidden_states)) == 1, tf.zeros_like(hidden_states), hidden_states - ) - # when there are no images the model is used in pure language mode - # gate = 0 if no_images else 1 - hidden_states = residual + self.act_cross_attn(self.alpha_cross_attn) * hidden_states - # Fully Connected - residual = hidden_states - hidden_states = self.post_attention_layernorm(hidden_states) - hidden_states = self.mlp(hidden_states) - hidden_states = tf.nn.dropout(hidden_states, rate=self.config) - hidden_states = residual + self.act_dense(self.alpha_dense) * hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights,) - - if use_cache: - outputs += (present_key_value,) - - return outputs - - -LLAMA_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a TensorFlow [tf.keras.layers.Layer](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer) subclass. - Use it as a regular TensorFlow Layer and refer to the TensorFlow documentation for all matter related to general usage - and behavior. - - Parameters: - config ([`IdeficsConfig`]): - Model configuration class with all the parameters of the model. Initializing with a config file does not - load the weights associated with the model, only the configuration. Check out the - [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - - -@add_start_docstrings( - "The bare LLaMA Model outputting raw hidden-states without any specific head on top.", - LLAMA_START_DOCSTRING, -) -class TFIdeficsPreTrainedModel(TFPreTrainedModel): - config_class = IdeficsConfig - base_model_prefix = "model" - supports_gradient_checkpointing = True - _no_split_modules = ["TFIdeficsDecoderLayer", "TFIdeficsGatedCrossAttentionLayer"] - - -LLAMA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - If you want to change padding behavior, you should read [`modeling_opt._prepare_decoder_attention_mask`] - and modify to your needs. See diagram 1 in [the paper](https://huggingface.co/papers/1910.13461) for more - information on the default strategy. - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.n_positions - 1]`. [What are position IDs?](../glossary#position-ids) - past_key_values (`tuple(tuple(tf.Tensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(tf.Tensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape - `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention - blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@add_start_docstrings( - "The bare LLaMA Model outputting raw hidden-states without any specific head on top.", - LLAMA_START_DOCSTRING, -) -@keras_serializable -class TFIdeficsMainLayer(tf.keras.layers.Layer): - """ - Transformer decoder consisting of `config.num_hidden_layers` layers. Each layer is a [`IdeficsDecoderLayer`] - - Args: - config: IdeficsConfig - """ - - config_class = IdeficsConfig - - def __init__(self, config: IdeficsConfig, add_pooling_year: bool = True, **kwargs): - super().__init__(**kwargs) - self.config = config - self.padding_idx = config.pad_token_id - self.vocab_size = config.vocab_size - - self.embed_tokens = TFIdeficsDecoupledEmbedding( - num_embeddings=config.vocab_size, - num_additional_embeddings=config.additional_vocab_size, - embedding_dim=config.hidden_size, - partially_freeze=config.freeze_text_layers, - name="embed_tokens", - ) - - self.image_size = config.vision_config.image_size - self.vision_config = config.vision_config - self.vision_model = TFIdeficsVisionTransformer(config.vision_config, name="vision_model") - - # Perceiver Resampler - if config.use_resampler: - perceiver_config = config.perceiver_config - self.perceiver_resampler = TFIdeficsPerceiverResampler( - config, - config.vision_config.embed_dim, - perceiver_config.resampler_depth, - perceiver_config.resampler_n_heads, - perceiver_config.resampler_head_dim, - perceiver_config.resampler_n_latents, - name="perceiver_resampler", - ) - - self.decoder_layers = [ - TFIdeficsDecoderLayer(config, name=f"layers.{i}") for i in range(config.num_hidden_layers) - ] - - self.cross_layer_interval = config.cross_layer_interval - num_cross_layers = config.num_hidden_layers // self.cross_layer_interval - self.gated_cross_attn_layers = [ - TFIdeficsGatedCrossAttentionLayer(config, name=f"gated_cross_attn_layers.{i}") - for i in range(num_cross_layers) - ] - self.gradient_checkpointing = False - - self.norm = TFIdeficsRMSNorm(config.hidden_size, eps=config.rms_norm_eps, name="norm") - - self.gradient_checkpointing = False - self.freeze_relevant_params(config) - - def freeze_relevant_params(self, config=None): - if config is None: - config = self.config - - if config.freeze_text_layers: - self.freeze_text_layers(config.freeze_text_module_exceptions) - - if config.freeze_vision_layers: - freeze_model(self.vision_model, module_exceptions=config.freeze_vision_module_exceptions) - - def freeze_text_layers(self, module_exceptions=[]): - for module in [self.decoder_layers, self.norm]: - freeze_model(module, module_exceptions=module_exceptions) - - def freeze_vision_layers(self, module_exceptions=[]): - freeze_model(self.vision_model, module_exceptions=module_exceptions) - - def _prepare_decoder_attention_mask(self, attention_mask, input_shape, inputs_embeds, past_key_values_length): - # create causal mask - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - combined_attention_mask = None - # if input_shape[-1] > 1: - combined_attention_mask = _make_causal_mask( - input_shape, - inputs_embeds.dtype, - past_key_values_length=past_key_values_length, - ) - - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - expanded_attn_mask = _expand_mask(attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1]) - combined_attention_mask = ( - expanded_attn_mask if combined_attention_mask is None else expanded_attn_mask + combined_attention_mask - ) - - return combined_attention_mask - - @unpack_inputs - @add_start_docstrings_to_model_forward(LLAMA_INPUTS_DOCSTRING) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - past_key_values: list[tf.Tensor] | None = None, - inputs_embeds: tf.Tensor | None = None, - pixel_values: tf.Tensor | None = None, - image_encoder_embeddings: tf.Tensor | None = None, - perceiver_embeddings: tf.Tensor | None = None, - image_attention_mask: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - interpolate_pos_encoding: bool | None = False, - return_dict: bool | None = None, - training: bool | None = None, - ) -> TFIdeficsBaseModelOutputWithPast | tuple[tf.Tensor]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - use_cache = use_cache if use_cache is not None else self.config.use_cache - - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # retrieve input_ids and inputs_embeds - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - batch_size, seq_length = shape_list(input_ids) - elif inputs_embeds is not None: - batch_size, seq_length, _ = shape_list(inputs_embeds) - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - seq_length_with_past = seq_length - past_key_values_length = 0 - - if past_key_values is not None: - past_key_values_length = shape_list(past_key_values[0][0])[2] - seq_length_with_past = seq_length_with_past + past_key_values_length - - if attention_mask is not None and position_ids is None: - # create position_ids on the fly for batch generation - position_ids = tf.math.cumsum(tf.cast(attention_mask, dtype=tf.int32), axis=-1) - 1 - position_ids = tf.where(attention_mask == 0, 1, position_ids) - elif position_ids is None: - position_ids = tf.range(past_key_values_length, seq_length + past_key_values_length, dtype=tf.int32) - position_ids = tf.expand_dims(position_ids, 0) - - no_images = False - if ( - sum((int(pixel_values is None), int(image_encoder_embeddings is None), int(perceiver_embeddings is None))) - != 2 - ): - raise ValueError( - "Exactly 1 of pixel_values, image_encoder_embeddings or perceiver_embeddings has to be not-None." - ) - - elif pixel_values is not None: - no_images = tf.reduce_sum(tf.cast(pixel_values, dtype=tf.int32)) == 0 - pixel_values = tf.cast(pixel_values, dtype=self.dtype) # fp16 compatibility - # Below hack is because when cross-loading pytorch weights, there is an - # initial forward pass with dummy input and code below is here to handle that - if len(pixel_values.shape) == 4: - batch_size = shape_list(pixel_values)[0] - num_images = shape_list(pixel_values)[0] - # pixel_values = tf.reshape(pixel_values, [batch_size * num_images, *pixel_values.shape[1:]]) - elif len(pixel_values.shape) == 5: - batch_size, num_images = shape_list(pixel_values)[:2] - pixel_values = tf.reshape(pixel_values, [batch_size * num_images, *pixel_values.shape[2:]]) - - # Get sequence from the vision encoder - image_hidden_states = self.vision_model( - pixel_values=pixel_values, interpolate_pos_encoding=interpolate_pos_encoding - ).last_hidden_state - - elif image_encoder_embeddings is not None: - batch_size, num_images, image_seq_len, image_hidden_size = shape_list(image_encoder_embeddings) - image_hidden_states = tf.cast(image_encoder_embeddings, dtype=self.dtype) - image_hidden_states = tf.reshape( - image_hidden_states, (batch_size * num_images, image_seq_len, image_hidden_size) - ) - - if self.config.use_resampler: - if perceiver_embeddings is None: - perceiver_embeddings = self.perceiver_resampler(image_hidden_states) - image_seq_len, image_hidden_size = shape_list(perceiver_embeddings)[1:3] - else: - batch_size, num_images, image_seq_len, image_hidden_size = shape_list(perceiver_embeddings) - image_hidden_states = perceiver_embeddings - elif perceiver_embeddings is None: - image_seq_len, image_hidden_size = shape_list(image_hidden_states)[1:3] - else: - raise ValueError("If `perceiver_embeddings` are passed, use_resampler should be True") - - image_hidden_states = tf.reshape( - image_hidden_states, (batch_size, num_images * image_seq_len, image_hidden_size) - ) - # # Hack to use the model in full language modeling mode - # image_attention_mask = tf.zeros((batch_size, seq_length, 1), dtype=tf.int32) - - # this is to account for the dummy inputs - if pixel_values is not None and len(pixel_values.shape) == 4 and image_attention_mask is None: - image_attention_mask = tf.zeros((batch_size, seq_length, 1), dtype=tf.int32) - - text_seq_len = shape_list(image_attention_mask)[1] - image_attention_mask = tf.expand_dims(image_attention_mask, -1) - image_attention_mask = tf.repeat(image_attention_mask, repeats=image_seq_len) - image_attention_mask = tf.reshape(image_attention_mask, (batch_size, text_seq_len, num_images * image_seq_len)) - - if image_hidden_states is not None: - image_batch_size, image_sequence_length, _ = shape_list(image_hidden_states) - image_hidden_shape = (image_batch_size, image_sequence_length) - if image_attention_mask is None: - image_attention_mask = tf.ones(image_hidden_shape, dtype=tf.int32) - image_attention_mask = invert_attention_mask(image_attention_mask) - else: - image_attention_mask = None - - cross_attention_gate = tf.squeeze( - tf.cast(tf.reduce_any(image_attention_mask == 0, axis=-1), dtype=self.dtype), axis=1 - ) - if inputs_embeds is None: - inputs_embeds = self.embed_tokens(input_ids) - # embed positions - if attention_mask is None: - attention_mask = tf.ones((batch_size, seq_length_with_past), dtype=tf.bool) - attention_mask = self._prepare_decoder_attention_mask( - attention_mask, (batch_size, seq_length), inputs_embeds, past_key_values_length - ) - - hidden_states = inputs_embeds - - if self.gradient_checkpointing and training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - next_decoder_cache = () if use_cache else None - - for idx, decoder_layer in enumerate(self.decoder_layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - def vblock( - main_block, - hidden_states, - attention_mask, - position_ids, - past_key_value, - image_hidden_states, - image_attention_mask, - cross_attention_gate, - output_attentions, - use_cache, - layer_idx, - cross_layer_interval, - gated_cross_attn_layers, - ): - # TODO(ls): Add cross attention values to respective lists - if layer_idx % cross_layer_interval == 0: - xblock = gated_cross_attn_layers[layer_idx // cross_layer_interval] - outputs = xblock( - hidden_states, - attention_mask=attention_mask, - image_hidden_states=image_hidden_states, - image_attention_mask=image_attention_mask, - cross_attention_gate=cross_attention_gate, - output_attentions=output_attentions, - use_cache=use_cache, - past_key_value=None, # not implemented - ) - hidden_states = outputs[0] - - layer_outputs = main_block( - hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - past_key_value=past_key_value, - output_attentions=output_attentions, - use_cache=use_cache, - ) - - return layer_outputs - - if self.gradient_checkpointing and training: - past_key_value = None - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - layer_outputs = tf.recompute_grad( - vblock, - decoder_layer, - hidden_states, - attention_mask, - position_ids, - past_key_value, - image_hidden_states, - image_attention_mask, - output_attentions, - use_cache, - no_images, - idx, - self.cross_layer_interval, - self.gated_cross_attn_layers, - ) - else: - layer_outputs = vblock( - decoder_layer, - hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - past_key_value=past_key_value, - image_hidden_states=image_hidden_states, - image_attention_mask=image_attention_mask, - cross_attention_gate=cross_attention_gate, - output_attentions=output_attentions, - use_cache=use_cache, - layer_idx=idx, - cross_layer_interval=self.cross_layer_interval, - gated_cross_attn_layers=self.gated_cross_attn_layers, - ) - - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[2 if output_attentions else 1],) - - if output_attentions: - all_self_attns += (layer_outputs[1],) - - hidden_states = self.norm(hidden_states) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - next_cache = next_decoder_cache if use_cache else None - image_hidden_states = tf.reshape( - image_hidden_states, (batch_size, num_images, image_seq_len, image_hidden_size) - ) - if not return_dict: - return tuple( - v - for v in [hidden_states, next_cache, all_hidden_states, all_self_attns, image_hidden_states] - if v is not None - ) - return TFIdeficsBaseModelOutputWithPast( - last_hidden_state=hidden_states, - past_key_values=next_cache, - hidden_states=all_hidden_states, - attentions=all_self_attns, - image_hidden_states=image_hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_tokens", None) is not None: - with tf.name_scope(self.embed_tokens.name): - self.embed_tokens.build(None) - if getattr(self, "vision_model", None) is not None: - with tf.name_scope(self.vision_model.name): - self.vision_model.build(None) - if getattr(self, "norm", None) is not None: - with tf.name_scope(self.norm.name): - self.norm.build(None) - if getattr(self, "perceiver_resampler", None) is not None: - with tf.name_scope(self.perceiver_resampler.name): - self.perceiver_resampler.build(None) - if getattr(self, "decoder_layers", None) is not None: - for layer in self.decoder_layers: - with tf.name_scope(layer.name): - layer.build(None) - if getattr(self, "gated_cross_attn_layers", None) is not None: - for layer in self.gated_cross_attn_layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFIdeficsModel(TFIdeficsPreTrainedModel): - def __init__(self, config: IdeficsConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.model = TFIdeficsMainLayer(config, name="model") - - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - past_key_values: list[tf.Tensor] | None = None, - inputs_embeds: tf.Tensor | None = None, - pixel_values: tf.Tensor | None = None, - image_encoder_embeddings: tf.Tensor | None = None, - perceiver_embeddings: tf.Tensor | None = None, - image_attention_mask: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - interpolate_pos_encoding: bool | None = False, - return_dict: bool | None = None, - training: bool | None = None, - ) -> TFIdeficsBaseModelOutputWithPast | tuple[tf.Tensor]: - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - pixel_values=pixel_values, - image_encoder_embeddings=image_encoder_embeddings, - perceiver_embeddings=perceiver_embeddings, - image_attention_mask=image_attention_mask, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - interpolate_pos_encoding=interpolate_pos_encoding, - return_dict=return_dict, - training=training, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -class TFIdeficsForVisionText2Text(TFPreTrainedModel, TFCausalLanguageModelingLoss): - _keys_to_ignore_on_load_missing = [r"lm_head.weight"] - _tied_weights_keys = ["model.embed_tokens.weight", "lm_head.weight"] - config_class = IdeficsConfig - - def __init__(self, config, vision_model=None, **kwargs): - super().__init__(config, **kwargs) - self.model = TFIdeficsMainLayer(config, name="model") - self.lm_head = TFIdeficsDecoupledLinear( - config.hidden_size, - config.vocab_size, - config.additional_vocab_size, - bias=False, - partially_freeze=config.freeze_lm_head, - name="lm_head", - ) - - def tie_weights(self): - """ - Overwrite `transformers.modeling_utils.PreTrainedModel.tie_weights` to handle the case of - IdeficsDecoupledLinear and IdeficsDecoupledEmbedding. - """ - output_embeddings = self.get_output_embeddings() - input_embeddings = self.get_input_embeddings() - - if getattr(self.config, "tie_word_embeddings", True): - output_embeddings.weight = input_embeddings.weight - if input_embeddings.num_additional_embeddings > 0: - assert output_embeddings.out_additional_features == input_embeddings.num_additional_embeddings - output_embeddings.additional_fc.weight = input_embeddings.additional_embedding.weight - - if hasattr(output_embeddings, "out_features") and hasattr(input_embeddings, "num_embeddings"): - output_embeddings.out_features = input_embeddings.num_embeddings - if hasattr(output_embeddings, "out_additional_features") and hasattr( - input_embeddings, "num_additional_embeddings" - ): - output_embeddings.out_additional_features = input_embeddings.num_additional_embeddings - - @unpack_inputs - @add_start_docstrings_to_model_forward(LLAMA_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFIdeficsCausalLMOutputWithPast, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - past_key_values: list[tf.Tensor] | None = None, - inputs_embeds: tf.Tensor | None = None, - pixel_values: tf.Tensor | None = None, - image_encoder_embeddings: tf.Tensor | None = None, - perceiver_embeddings: tf.Tensor | None = None, - image_attention_mask: tf.Tensor | None = None, - labels: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - interpolate_pos_encoding: bool | None = False, - return_dict: bool | None = None, - training=False, - ) -> TFIdeficsCausalLMOutputWithPast | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., - config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - - Returns: - - Example: - - ```python - >> from transformers import AutoTokenizer, TFIdeficsForVisionText2Text - - >> model = TFIdeficsForVisionText2Text.from_pretrained("HuggingFaceM4/idefics-9b") - >> tokenizer = AutoTokenizer.from_pretrained("HuggingFaceM4/idefics-9b") - - >> prompt = "Hey, are you consciours? Can you talk to me?" - >> inputs = tokenizer(prompt, return_tensors="tf") - - >> # Generate - >> generate_ids = model.generate(inputs.input_ids, max_length=30) - >> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] - "Hey, are you consciours? Can you talk to me?\nI'm not consciours, but I can talk to you." - ```""" - - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn) - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - pixel_values=pixel_values, - image_encoder_embeddings=image_encoder_embeddings, - perceiver_embeddings=perceiver_embeddings, - image_attention_mask=image_attention_mask, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - interpolate_pos_encoding=interpolate_pos_encoding, - return_dict=return_dict, - training=training, - ) - - hidden_states = outputs[0] - logits = self.lm_head(hidden_states) - - loss = None - if labels is not None: - # Shift so that tokens < n predict n - if attention_mask is not None: - shift_attention_mask = attention_mask[..., 1:] - shift_logits = logits[..., :-1, :][shift_attention_mask != 0] - shift_labels = labels[..., 1:][shift_attention_mask != 0] - else: - shift_logits = logits[..., :-1, :] - shift_labels = labels[..., 1:] - # Flatten the tokens - loss = self.hf_compute_loss( - labels=tf.reshape(shift_labels, [-1]), logits=tf.reshape(shift_logits, [-1, shift_logits.shape[-1]]) - ) - - if not return_dict: - output = (logits,) + outputs[1:] - return (loss,) + output if loss is not None else output - - return TFIdeficsCausalLMOutputWithPast( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - image_hidden_states=outputs.image_hidden_states, - ) - - def prepare_inputs_for_generation(self, input_ids, past=None, **kwargs): - image_hidden_states = kwargs.pop("image_hidden_states", None) - if image_hidden_states is not None: - if self.config.use_resampler: - kwargs["perceiver_embeddings"] = image_hidden_states - else: - kwargs["image_encoder_embeddings"] = image_hidden_states - kwargs["pixel_values"] = None - inputs = prepare_inputs_for_generation(input_ids, past=past, **kwargs) - unwanted_kwargs = ["token_type_ids"] - for kwarg in unwanted_kwargs: - inputs.pop(kwarg, None) - return inputs - - @staticmethod - def _expand_inputs_for_generation( - *args, - **model_kwargs, - ): - return expand_inputs_for_generation(*args, **model_kwargs) - - @staticmethod - def _update_model_kwargs_for_generation(outputs, model_kwargs, is_encoder_decoder): - return update_model_kwargs_for_generation(outputs, model_kwargs) - - @staticmethod - def _reorder_cache(past, beam_idx): - reordered_past = () - for layer_past in past: - reordered_past += (tuple(tf.gather(past_state, beam_idx) for past_state in layer_past),) - return reordered_past - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -__all__ = ["TFIdeficsForVisionText2Text", "TFIdeficsModel", "TFIdeficsPreTrainedModel"] diff --git a/src/transformers/models/idefics/perceiver_tf.py b/src/transformers/models/idefics/perceiver_tf.py deleted file mode 100644 index a4de96b68e78..000000000000 --- a/src/transformers/models/idefics/perceiver_tf.py +++ /dev/null @@ -1,195 +0,0 @@ -# This code was adapted from https://github.com/lucidrains/flamingo-pytorch licensed under the MIT License. -# -# MIT License -# -# Copyright (c) 2020 The Google AI Language Team Authors, The HuggingFace Inc. team and github/lonePatient -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - - -""" - -Generic interface to various configurations of the Perceiver Resampler, that simply takes in a series of (potentially -time-indexed) contextual embeddings, and "resamples" (compresses) them down to a pre-specified number of latents! Note -that the Perceiver in general resamples based solely off the *long-range* context; there's a nice opportunity here to -prime the Perceiver Resampler with say a single layer's worth of language embeddings (the target domain), and use that -to softly "retrieve & compress" what we need --> this would be a novel contribution we should explore. - -References: - - DeepMind's Flamingo: https://www.deepmind.com/blog/tackling-multiple-tasks-with-a-single-visual-language-model - - Code borrowed w/ love from: https://github.com/lucidrains/flamingo-pytorch - -""" - -from typing import Optional - -import tensorflow as tf - -from ...modeling_tf_utils import shape_list -from .configuration_idefics import IdeficsConfig - - -class TFIdeficsPerceiverResampler(tf.keras.layers.Layer): - def __init__( - self, config: IdeficsConfig, embed_dim: int, depth: int, n_heads: int, head_dim: int, n_latents: int, **kwargs - ) -> None: - """ - Instantiates a Perceiver Resampler that operates over a sequence of embeddings (say from a ResNet or ViT or - MAE) of a given dimension, performs `depth` blocks of cross-attention with a fixed `n_latents` inputs, then - returns a Tensor of shape [bsz, n_latents, embed_dim]. :param embed_dim: Dimensionality of embeddings being fed - to the Perceiver Resampler (also dimensionality of latent embeddings *returned* by the Perceiver Resampler. - Could be e.g., VIT embed_dim, ResNet pool dim, and so on. - - Args: - config (`IdeficsConfig`): config object - embed_dim (`int`): The size of each embedding vector - depth (`int`): Depth of the Perceiver Resampler (Transformer w/ cross attention). Should be shallow (< 3). - n_heads (`int`): Number of heads in each Transformer block (for multi-headed self-attention). - head_dim (`int`): Dimensionality of each head projection in the Transformer block. - n_latents (`int`): - Number of latent embeddings to resample ("compress") the input sequence to (usually < 128). - - """ - super().__init__(**kwargs) - self.embed_dim, self.n_heads, self.head_dim, self.n_latents = embed_dim, n_heads, head_dim, n_latents - self.qk_layer_norms = config.perceiver_config.qk_layer_norms_perceiver - - self.intermediate_dim = ( - self.embed_dim * 4 - if not hasattr(config.vision_config, "embed_dim") - else config.vision_config.embed_dim * 4 - ) - # Create Transformer Blocks - self.blocks = [] - for i in range(depth): - self.blocks.append( - [ - TFIdeficsPerceiverAttention( - self.embed_dim, self.n_heads, self.head_dim, self.qk_layer_norms, name=f"blocks.{i}.0" - ), - TFIdeficsMLP(self.intermediate_dim, config, name=f"blocks.{i}.1"), - ] - ) - - self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - def build(self, input_shape): - # Create Latents for Perceiver - self.latents = self.add_weight( - shape=(self.n_latents, self.embed_dim), initializer="random_normal", trainable=True, name="latents" - ) - super().build(input_shape) - - def call(self, context: tf.Tensor) -> tf.Tensor: - """Resample arbitrary length context & *compress* down to self.n_latents latent embeddings""" - # tf.repeat(self.latents, "seq embed -> bsz seq embed", bsz=context.shape[0]) - latents = tf.expand_dims(self.latents, axis=0) - latents = tf.tile(latents, [tf.shape(context)[0], 1, 1]) - # Feed through Perceiver Attention blocks... - for attn, ff in self.blocks: - latents = attn(context, latents) + latents - latents = ff(latents) + latents - return self.layer_norm(latents) - - -class TFIdeficsPerceiverAttention(tf.keras.layers.Layer): - def __init__(self, embed_dim: int, n_heads: int, head_dim: int, qk_layer_norms: bool, **kwargs) -> None: - """Perceiver Cross-Attention Module --> let long-form inputs be `context`, resampled embeddings be `latents`""" - super().__init__(**kwargs) - self.embed_dim, self.n_heads, self.head_dim = embed_dim, n_heads, head_dim - self.qk_layer_norms = qk_layer_norms - # Normalization & Scaling - self.context_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="context_layer_norm") - self.latents_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="latents_layer_norm") - if self.qk_layer_norms: - self.q_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="q_layer_norm") - self.k_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="k_layer_norm") - - self.qk_scale = self.head_dim**-0.5 - - # Q, K, V Projection (no bias -- detail from Perceiver/Flamingo Papers). - self.q_proj = tf.keras.layers.Dense(self.n_heads * self.head_dim, use_bias=False, name="q_proj") - self.k_proj = tf.keras.layers.Dense(self.n_heads * self.head_dim, use_bias=False, name="k_proj") - self.v_proj = tf.keras.layers.Dense(self.n_heads * self.head_dim, use_bias=False, name="v_proj") - - self.output_proj = tf.keras.layers.Dense(embed_dim, use_bias=False, name="output_proj") - - def call(self, context: tf.Tensor, latents: tf.Tensor) -> tf.Tensor: - """ - Runs Perceiver Self-Attention, with special (context, latents) appended along the `seq` dimension! - - Args: - context (`tf.Tensor`): - Tensor of shape `[bsz, seq, embed_dim]` representing long-form context to resample. - latents (`tf.Tensor`): - Tensor of shape `[bsz, n_latents, embed_dim]` representing fixed length latents to compress to. - - Returns: - `tf.Tensor`: Tensor of shape `[bsz, n_latents, embed_dim]` representing attention over latents w/ cross - from context. - """ - context = self.context_layer_norm(context) - latents = self.latents_layer_norm(latents) - batch_size, seq_length, embed_dim = shape_list(context) - - # Query, Key, Value Projections --> Note that in Flamingo, latents are *concatenated* with context prior to attn! - # Note: This results in queries w/ `seq = n_latents`, and keys, values with `seq = len(context) + n_latents` - q = self.q_proj(latents) - k = self.k_proj(tf.concat([context, latents], axis=-2)) - v = self.v_proj(tf.concat([context, latents], axis=-2)) - - # Multiheaded Self-Attention w/ stable softmax (subtract per-row max -- `amax` -- before softmax call) - # =>> `attn` should be a 2D matrix of shape [n_latents x (context + n_latents)] - q, k, v = [ - tf.transpose(tf.reshape(x, (batch_size, x.shape[1], self.n_heads, self.head_dim)), perm=[0, 2, 1, 3]) - for x in (q, k, v) - ] - - if self.qk_layer_norms: - q = self.q_layer_norm(q) - k = self.k_layer_norm(k) - - scores = tf.einsum("... i d, ... j d -> ... i j", q * self.qk_scale, k) - stabilized_scores = scores - tf.reduce_max(scores, axis=-1, keepdims=True) - attn = tf.nn.softmax(stabilized_scores, axis=-1) - - # Attend & project back to output... - resampled = tf.einsum("... i j, ... j d -> ... i d", attn, v) - return self.output_proj( - tf.reshape(tf.transpose(resampled, perm=[0, 2, 1, 3]), (batch_size, -1, self.n_heads * self.head_dim)) - ) - - -class TFIdeficsMLP(tf.keras.layers.Layer): - def __init__(self, intermediate_size, config: IdeficsConfig, **kwargs): - """Simple MLP block with intermediate_size and embedding size""" - super().__init__(**kwargs) - self.embed_dim = config.vision_config.embed_dim - self.ln = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="ln") - self.fc = tf.keras.layers.Dense(intermediate_size, use_bias=False, name="fc") - self.act = tf.keras.layers.ReLU(name="act") - self.c_proj = tf.keras.layers.Dense(self.embed_dim, use_bias=False, name="c_proj") - - def call(self, hidden_states: Optional[tuple[tf.Tensor]]) -> tf.Tensor: - hidden_states = self.ln(hidden_states) - hidden_states = self.fc(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.c_proj(hidden_states) - - return hidden_states diff --git a/src/transformers/models/idefics/processing_idefics.py b/src/transformers/models/idefics/processing_idefics.py index 59c8078ad84a..5ab7e480c8ea 100644 --- a/src/transformers/models/idefics/processing_idefics.py +++ b/src/transformers/models/idefics/processing_idefics.py @@ -29,15 +29,13 @@ Unpack, ) from ...tokenization_utils_base import PreTokenizedInput, TextInput -from ...utils import is_tf_available, is_torch_available +from ...utils import is_torch_available from ...utils.deprecation import deprecate_kwarg if is_torch_available(): import torch -if is_tf_available(): - import tensorflow as tf IMAGE_TOKEN = "" @@ -74,8 +72,6 @@ def incremental_to_binary_attention_mask(incremental_mask, return_tensors, num_c if num_classes != -1: if return_tensors == "pt": incremental_mask[incremental_mask >= num_classes] = -1 - elif return_tensors == "tf": - incremental_mask = tf.where(incremental_mask >= num_classes, -1, incremental_mask) # Create mask for negative values if return_tensors == "pt": @@ -83,13 +79,6 @@ def incremental_to_binary_attention_mask(incremental_mask, return_tensors, num_c incremental_mask[negatives] = 0 attn_mask = torch.nn.functional.one_hot(incremental_mask, num_classes=num_classes) attn_mask[negatives, :] = 0 - elif return_tensors == "tf": - negatives = tf.equal(incremental_mask, -1) - incremental_mask = tf.where(negatives, 0, incremental_mask) - attn_mask = tf.one_hot(incremental_mask, depth=num_classes) - # Reshape 'negatives' to add an extra dimension, making it [batch_size, seq_length, 1] - negatives_expanded = tf.expand_dims(negatives, -1) - attn_mask = tf.where(negatives_expanded, tf.zeros_like(attn_mask), attn_mask) return attn_mask @@ -98,8 +87,6 @@ def incremental_to_binary_attention_mask(incremental_mask, return_tensors, num_c def image_attention_mask_for_packed_input_ids(input_ids, tokenizer, return_tensors): if return_tensors == "pt": return image_attention_mask_for_packed_input_ids_pt(input_ids, tokenizer) - elif return_tensors == "tf": - return image_attention_mask_for_packed_input_ids_tf(input_ids, tokenizer) def image_attention_mask_for_packed_input_ids_pt(input_ids, tokenizer): @@ -149,39 +136,6 @@ def image_attention_mask_for_packed_input_ids_pt(input_ids, tokenizer): return image_attention_mask, next_image_attention_mask -def image_attention_mask_for_packed_input_ids_tf(input_ids, tokenizer): - image_token_id = tokenizer.convert_tokens_to_ids(IMAGE_TOKEN) - eod_token_id = tokenizer.eos_token_id - batch_size = tf.shape(input_ids)[0] - image_attention_mask = tf.fill(tf.shape(input_ids), -1) - next_image_attention_mask = tf.fill(tf.shape(input_ids), -1) - - for batch_idx in range(batch_size): - count = -1 - seen_eod = False - seq_length = tf.shape(input_ids)[1] - - for idx in range(seq_length - 1, -1, -1): - token_id = input_ids[batch_idx, idx].numpy() - if token_id == image_token_id: - count += 1 - indices = [[batch_idx, idx]] - updates = [count] - image_attention_mask = tf.tensor_scatter_nd_update(image_attention_mask, indices, updates) - next_image_attention_mask = tf.tensor_scatter_nd_update(next_image_attention_mask, indices, updates) - elif token_id == eod_token_id and not seen_eod: - seen_eod = True - count = 0 - indices = [[batch_idx, idx]] - updates = [count] - next_image_attention_mask = tf.tensor_scatter_nd_update(next_image_attention_mask, indices, updates) - if seen_eod and token_id != eod_token_id: - indices = [[batch_idx, idx]] - updates = [-1] - next_image_attention_mask = tf.tensor_scatter_nd_update(next_image_attention_mask, indices, updates) - return image_attention_mask, next_image_attention_mask - - def is_url(string): """Checks if the passed string contains a valid url and nothing else. e.g. if space is included it's immediately invalidated the url""" @@ -451,42 +405,19 @@ def image_tokens(last_was_image): if return_tensors == "pt": padded_image_tensor = torch.zeros(max_num_images, *current_images.size()[1:]) padded_image_tensor[: current_images.size(0)] = current_images - elif return_tensors == "tf": - # Assuming current_images is a TensorFlow tensor - # Get the shape of current_images, excluding the first dimension - image_shape = tf.shape(current_images)[1:] - # Create a shape for the padded_image_tensor - padded_shape = tf.concat([[max_num_images], image_shape], axis=0) - # Create the padded_image_tensor of zeros - padded_image_tensor = tf.zeros(padded_shape, dtype=current_images.dtype) - # Get the number of images (assuming current_images has shape [num_images, height, width, channels]) - num_images = tf.shape(current_images)[0] - # Update the padded_image_tensor with the values from current_images - indices = tf.reshape(tf.range(num_images), (-1, 1)) - updates = current_images - padded_image_tensor = tf.tensor_scatter_nd_update(padded_image_tensor, indices, updates) else: if return_tensors == "pt": padded_image_tensor = torch.zeros(max_num_images, *self.default_image_dims) - elif return_tensors == "tf": - padded_image_tensor = tf.zeros((max_num_images, *self.default_image_dims)) output_images.append(padded_image_tensor) if return_tensors == "pt": output_input_ids.append(torch.tensor(padded_input_ids)) output_attention_masks.append(torch.tensor(attention_mask)) - elif return_tensors == "tf": - output_input_ids.append(tf.convert_to_tensor(padded_input_ids, dtype=tf.int32)) - output_attention_masks.append(attention_mask) if return_tensors == "pt": output_input_ids = torch.stack(output_input_ids) output_images = torch.stack(output_images) output_attention_masks = torch.stack(output_attention_masks) - elif return_tensors == "tf": - output_input_ids = tf.stack(output_input_ids) - output_images = tf.stack(output_images) - output_attention_masks = tf.stack(output_attention_masks) if at_least_one_image: image_attention_mask, _ = image_attention_mask_for_packed_input_ids( @@ -501,10 +432,6 @@ def image_tokens(last_was_image): image_attention_mask = torch.zeros( output_input_ids.shape[0], output_input_ids.shape[1], 1, dtype=torch.bool ) - elif return_tensors == "tf": - image_attention_mask = tf.zeros( - (output_input_ids.shape[0], output_input_ids.shape[1], 1), dtype=tf.bool - ) return BatchFeature( data={ "input_ids": output_input_ids, diff --git a/src/transformers/models/idefics/vision_tf.py b/src/transformers/models/idefics/vision_tf.py deleted file mode 100644 index 1d8cf9402218..000000000000 --- a/src/transformers/models/idefics/vision_tf.py +++ /dev/null @@ -1,572 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The OpenAI Team Authors and The HuggingFace Team. All rights reserved. -# -# 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. -"""TF IdeficsVision model: a copy of CLIPVisionModel using a simpler config object""" - -import math -from dataclasses import dataclass -from typing import Optional, Union - -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import TFBaseModelOutput, TFBaseModelOutputWithPooling -from ...modeling_tf_utils import TFPreTrainedModel, shape_list -from ...tf_utils import flatten -from ...utils import ModelOutput, logging -from .configuration_idefics import IdeficsVisionConfig - - -logger = logging.get_logger(__name__) - - -@dataclass -class TFIdeficsVisionModelOutput(ModelOutput): - """ - Base class for vision model's outputs that also contains image embeddings of the pooling of the last hidden states. - - Args: - image_embeds (`tf.Tensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`): - The image embeddings obtained by applying the projection layer to the pooler_output. - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + - one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - image_embeds: Optional[tf.Tensor] = None - last_hidden_state: Optional[tf.Tensor] = None - hidden_states: Optional[tuple[tf.Tensor]] = None - attentions: Optional[tuple[tf.Tensor]] = None - - -class TFIdeficsVisionEmbeddings(tf.keras.layers.Layer): - def __init__(self, config: IdeficsVisionConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.embed_dim = config.hidden_size - self.image_size = config.image_size - self.patch_size = config.patch_size - - self.patch_embedding = tf.keras.layers.Conv2D( - filters=self.embed_dim, - kernel_size=self.patch_size, - strides=self.patch_size, - use_bias=False, - padding="valid", - data_format="channels_last", - name="patch_embedding", - ) - - self.num_patches = (self.image_size // self.patch_size) ** 2 - self.num_positions = self.num_patches + 1 - self.position_embedding = tf.keras.layers.Embedding( - self.num_positions, self.embed_dim, name="position_embedding" - ) - # self.position_ids = tf.range(self.num_positions)[tf.newaxis, :] - - def interpolate_pos_encoding(self, embeddings: tf.Tensor, height: int, width: int) -> tf.Tensor: - num_patches = shape_list(embeddings)[1] - 1 - pos_embed = self.position_embedding(self.position_ids) - num_positions = shape_list(pos_embed)[1] - 1 - if num_patches == num_positions and height == width: - return pos_embed - class_pos_embed = pos_embed[:, 0] - patch_pos_embed = pos_embed[:, 1:] - - embed_dim = shape_list(embeddings)[-1] - num_h_patches = height // self.config.patch_size - num_w_patches = width // self.config.patch_size - num_h_patches, num_w_patches = num_h_patches + 0.1, num_w_patches + 0.1 - sqrt_num_positions = math.sqrt(float(num_positions)) - patch_pos_embed = tf.reshape(patch_pos_embed, (1, int(sqrt_num_positions), int(sqrt_num_positions), embed_dim)) - - scale_height = num_h_patches / sqrt_num_positions - scale_width = num_w_patches / sqrt_num_positions - original_height = tf.cast(tf.shape(patch_pos_embed)[1], tf.float32) - original_width = tf.cast(tf.shape(patch_pos_embed)[2], tf.float32) - # Apply scaling - new_height = tf.cast(original_height * scale_height, tf.int32) - new_width = tf.cast(original_width * scale_width, tf.int32) - - patch_pos_embed = tf.image.resize( - patch_pos_embed, size=[new_height, new_width], method=tf.image.ResizeMethod.BICUBIC - ) - - if ( - int(num_h_patches) != shape_list(patch_pos_embed)[-3] - or int(num_w_patches) != shape_list(patch_pos_embed)[-2] - ): - raise ValueError( - f"Number of patches for images ({int(num_h_patches), int(num_w_patches)}) don't match the " - f"shape of position embedding ({shape_list(patch_pos_embed)[-2], shape_list(patch_pos_embed)[-1]})" - ) - patch_pos_embed = tf.reshape(patch_pos_embed, (1, -1, embed_dim)) - return tf.concat((class_pos_embed[tf.newaxis, :], patch_pos_embed), axis=1) - - def call(self, pixel_values: tf.Tensor, interpolate_pos_encoding: bool = False) -> tf.Tensor: - # Input `pixel_values` is NCHW format which doesn't run on CPU so first thing we do is - # transpose it to change it to NHWC. We don't care to transpose it back because - # the Conv2D layer is only hit once for each query - - if isinstance(pixel_values, dict): - pixel_values = pixel_values["pixel_values"] - - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - batch_size, height, width, num_channels = shape_list(pixel_values) - if not interpolate_pos_encoding: - if height != self.image_size or width != self.image_size: - raise ValueError( - f"Input image size ({height}*{width}) doesn't match model" - f" ({self.image_size}*{self.image_size}). You should try to set `interpolate_pos_encoding=True`" - ) - - patch_embeds = self.patch_embedding(pixel_values) # shape = [*, width, grid, grid] - # Change the 2D spatial dimensions to a single temporal dimension. - # shape = (batch_size, num_patches, out_channels=embed_dim) - patch_embeds = flatten(patch_embeds, 1, 2) - - class_embeds = tf.broadcast_to( - self.class_embedding[tf.newaxis, tf.newaxis, :], [batch_size, 1, self.embed_dim] - ) - embeddings = tf.concat([class_embeds, patch_embeds], axis=1) - - # add positional encoding to each token - if interpolate_pos_encoding: - embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width) - else: - embeddings = embeddings + self.position_embedding(self.position_ids) - - return embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - self.position_ids = tf.range(self.num_positions, name="self.position_ids")[tf.newaxis, :] - self.class_embedding = self.add_weight(shape=(self.embed_dim,), name="class_embedding") - if getattr(self, "patch_embedding", None) is not None: - with tf.name_scope(self.patch_embedding.name): - self.patch_embedding.build([None, None, None, self.config.num_channels]) - if getattr(self, "position_embedding", None) is not None: - with tf.name_scope(self.position_embedding.name): - self.position_embedding.build(None) - - -class TFIdeficsVisionAttention(tf.keras.layers.Layer): - """Multi-headed attention from 'Attention Is All You Need' paper""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.embed_dim = config.hidden_size - self.num_heads = config.num_attention_heads - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" - f" {self.num_heads})." - ) - self.scale = self.head_dim**-0.5 - self.dropout = config.attention_dropout - - self.k_proj = tf.keras.layers.Dense(self.embed_dim, name="k_proj") - self.v_proj = tf.keras.layers.Dense(self.embed_dim, name="v_proj") - self.q_proj = tf.keras.layers.Dense(self.embed_dim, name="q_proj") - self.out_proj = tf.keras.layers.Dense(self.embed_dim, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: Optional[tf.Tensor] = None, - causal_attention_mask: Optional[tf.Tensor] = None, - output_attentions: Optional[bool] = False, - ) -> tuple[tf.Tensor, Optional[tf.Tensor], Optional[tuple[tf.Tensor]]]: - """Input shape: Batch x Time x Channel""" - - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scale - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.linalg.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - tf.shape(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=f"Attention weights should be of size {[bsz * self.num_heads, tgt_len, src_len]}, but is {tf.shape(attn_weights)}", - ) - - # apply the causal_attention_mask first - if causal_attention_mask is not None: - if shape_list(causal_attention_mask) != [bsz, 1, tgt_len, src_len]: - raise ValueError( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(causal_attention_mask)}" - ) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + causal_attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - if attention_mask is not None: - if shape_list(attention_mask) != [bsz, 1, tgt_len, src_len]: - raise ValueError( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is {shape_list(attention_mask)}" - ) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = tf.nn.softmax(attn_weights, axis=-1) - - if output_attentions: - # this operation is a bit awkward, but it's required to - # make sure that attn_weights keeps its gradient. - # In order to do so, attn_weights have to reshaped - # twice and have to be reused in the following - attn_weights_reshaped = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - attn_weights = tf.reshape(attn_weights_reshaped, (bsz * self.num_heads, tgt_len, src_len)) - else: - attn_weights_reshaped = None - - attn_probs = tf.nn.dropout(attn_weights, rate=self.dropout) - - attn_output = tf.linalg.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - tf.shape(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=f"Attention weights should be of size {[bsz * self.num_heads, tgt_len, self.head_dim]}, but is {tf.shape(attn_output)}", - ) - - attn_output = tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)) - attn_output = tf.transpose(attn_output, perm=[0, 2, 1, 3]) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights_reshaped - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build((self.embed_dim, self.embed_dim)) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build((self.embed_dim, self.embed_dim)) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build((self.embed_dim, self.embed_dim)) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build((self.embed_dim, self.embed_dim)) - - -class TFIdeficsVisionMLP(tf.keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.activation_fn = get_tf_activation(config.hidden_act) - self.fc1 = tf.keras.layers.Dense(config.intermediate_size, name="fc1") - self.fc2 = tf.keras.layers.Dense(config.hidden_size, name="fc2") - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.fc1(hidden_states) - hidden_states = self.activation_fn(hidden_states) - hidden_states = self.fc2(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build(self.config.hidden_size) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build(self.config.intermediate_size) - - -class TFIdeficsVisionEncoderLayer(tf.keras.layers.Layer): - def __init__(self, config: IdeficsVisionConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.hidden_size - self.self_attn = TFIdeficsVisionAttention(config, name="self_attn") - self.layer_norm1 = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm1") - self.mlp = TFIdeficsVisionMLP(config, name="mlp") - self.layer_norm2 = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm2") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - causal_attention_mask: tf.Tensor, - output_attentions: Optional[bool] = False, - ) -> tuple[tf.Tensor]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - `(config.encoder_attention_heads,)`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - """ - residual = hidden_states - - hidden_states = self.layer_norm1(hidden_states) - hidden_states, attn_weights = self.self_attn( - hidden_states=hidden_states, - attention_mask=attention_mask, - causal_attention_mask=causal_attention_mask, - output_attentions=output_attentions, - ) - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.layer_norm2(hidden_states) - hidden_states = self.mlp(hidden_states) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer_norm1", None) is not None: - with tf.name_scope(self.layer_norm1.name): - self.layer_norm1.build([None, None, self.embed_dim]) - if getattr(self, "layer_norm2", None) is not None: - with tf.name_scope(self.layer_norm2.name): - self.layer_norm2.build([None, None, self.embed_dim]) - - -class TFIdeficsVisionEncoder(tf.keras.layers.Layer): - """ - Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a - [`TFIdeficsVisionEncoderLayer`]. - - Args: - config: IdeficsVisionConfig - """ - - def __init__(self, config: IdeficsVisionConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layers = [ - TFIdeficsVisionEncoderLayer(config, name=f"layers.{i}") for i in range(config.num_hidden_layers) - ] - self.gradient_checkpointing = False - - def call( - self, - inputs_embeds, - attention_mask: Optional[tf.Tensor] = None, - causal_attention_mask: Optional[tf.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: Optional[bool] = None, - ) -> Union[tuple, TFBaseModelOutput]: - r""" - Args: - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - causal_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Causal mask for the text model. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - hidden_states = inputs_embeds - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - if self.gradient_checkpointing and training: - - def create_custom_forward(module): - def custom_forward(*inputs): - return module(*inputs, output_attentions) - - return custom_forward - - layer_outputs = tf.recompute_grad( - create_custom_forward(encoder_layer), - hidden_states, - attention_mask, - causal_attention_mask, - ) - else: - layer_outputs = encoder_layer( - hidden_states, - attention_mask, - causal_attention_mask, - output_attentions=output_attentions, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFIdeficsVisionTransformer(TFPreTrainedModel): - def __init__(self, config: IdeficsVisionConfig, **kwargs): - super().__init__(config, **kwargs) - self.config = config - self.embed_dim = config.hidden_size - - self.embeddings = TFIdeficsVisionEmbeddings(config, name="embeddings") - self.pre_layrnorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="pre_layrnorm") - self.encoder = TFIdeficsVisionEncoder(config, name="encoder") - self.post_layernorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="post_layernorm") - - # Adapted from transformers.models.clip.modeling_clip.CLIPVisionTransformer.forward - def call( - self, - pixel_values: Optional[tf.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - interpolate_pos_encoding: Optional[bool] = False, - return_dict: Optional[bool] = None, - training: Optional[bool] = False, - ) -> Union[tuple, TFBaseModelOutputWithPooling]: - r""" - Returns: - - """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - hidden_states = self.embeddings(pixel_values, interpolate_pos_encoding=interpolate_pos_encoding) - hidden_states = self.pre_layrnorm(hidden_states) - encoder_outputs = self.encoder( - inputs_embeds=hidden_states, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - last_hidden_state = encoder_outputs[0] - pooled_output = last_hidden_state[:, 0, :] - pooled_output = self.post_layernorm(pooled_output) - - if not return_dict: - return (last_hidden_state, pooled_output) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "pre_layrnorm", None) is not None: - with tf.name_scope(self.pre_layrnorm.name): - self.pre_layrnorm.build([None, None, self.embed_dim]) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "post_layernorm", None) is not None: - with tf.name_scope(self.post_layernorm.name): - self.post_layernorm.build([None, self.embed_dim]) diff --git a/src/transformers/models/idefics2/image_processing_idefics2.py b/src/transformers/models/idefics2/image_processing_idefics2.py index 3f0db7644563..15a04a887e87 100644 --- a/src/transformers/models/idefics2/image_processing_idefics2.py +++ b/src/transformers/models/idefics2/image_processing_idefics2.py @@ -303,10 +303,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -444,10 +442,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -476,10 +472,7 @@ def preprocess( images_list = make_nested_list_of_images(images) if not valid_images(images_list[0]): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/idefics3/image_processing_idefics3.py b/src/transformers/models/idefics3/image_processing_idefics3.py index e460a041965a..c7526f30993a 100644 --- a/src/transformers/models/idefics3/image_processing_idefics3.py +++ b/src/transformers/models/idefics3/image_processing_idefics3.py @@ -546,10 +546,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -657,10 +655,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. return_row_col_info (`bool`, *optional*, default to `False`): Whether to return the number of rows and columns of the split images. This is used for the `Idefics3Processor` to generate prompt strings based on the number of rows and columns. @@ -693,10 +689,7 @@ def preprocess( images_list = make_nested_list_of_images(images) if not valid_images(images_list[0]): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/ijepa/configuration_ijepa.py b/src/transformers/models/ijepa/configuration_ijepa.py index 5f528adad0d5..084a7d8f3d94 100644 --- a/src/transformers/models/ijepa/configuration_ijepa.py +++ b/src/transformers/models/ijepa/configuration_ijepa.py @@ -59,9 +59,7 @@ class IJepaConfig(PretrainedConfig): pooler_output_size (`int`, *optional*): Dimensionality of the pooler layer. If None, defaults to `hidden_size`. pooler_act (`str`, *optional*, defaults to `"tanh"`): - The activation function to be used by the pooler. Keys of ACT2FN are supported for Flax and - Pytorch, and elements of https://www.tensorflow.org/api_docs/python/tf/keras/activations are - supported for Tensorflow. + The activation function to be used by the pooler. Example: diff --git a/src/transformers/models/imagegpt/configuration_imagegpt.py b/src/transformers/models/imagegpt/configuration_imagegpt.py index 8cfa8d5e4782..435324721d86 100644 --- a/src/transformers/models/imagegpt/configuration_imagegpt.py +++ b/src/transformers/models/imagegpt/configuration_imagegpt.py @@ -16,7 +16,7 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig @@ -24,7 +24,7 @@ if TYPE_CHECKING: - from ... import FeatureExtractionMixin, TensorType + from ... import FeatureExtractionMixin logger = logging.get_logger(__name__) @@ -159,13 +159,12 @@ def generate_dummy_inputs( batch_size: int = 1, seq_length: int = -1, is_pair: bool = False, - framework: Optional["TensorType"] = None, num_channels: int = 3, image_width: int = 32, image_height: int = 32, ) -> Mapping[str, Any]: """ - Generate inputs to provide to the ONNX exporter for the specific framework + Generate inputs to provide to the ONNX exporter. Args: preprocessor ([`PreTrainedTokenizerBase`] or [`FeatureExtractionMixin`]): @@ -178,8 +177,6 @@ def generate_dummy_inputs( The sequence length to export the model for (-1 means dynamic axis). is_pair (`bool`, *optional*, defaults to `False`): Indicate if the input is a pair (sentence 1, sentence 2) - framework (`TensorType`, *optional*, defaults to `None`): - The framework (PyTorch or TensorFlow) that the tokenizer will generate tensors for. num_channels (`int`, *optional*, defaults to 3): The number of channels of the generated images. image_width (`int`, *optional*, defaults to 40): @@ -192,7 +189,7 @@ def generate_dummy_inputs( """ input_image = self._generate_dummy_images(batch_size, num_channels, image_height, image_width) - inputs = dict(preprocessor(images=input_image, return_tensors=framework)) + inputs = dict(preprocessor(images=input_image, return_tensors="pt")) return inputs diff --git a/src/transformers/models/imagegpt/convert_imagegpt_original_tf2_to_pytorch.py b/src/transformers/models/imagegpt/convert_imagegpt_original_tf2_to_pytorch.py index 182d66b9af28..a1bb2efee2e1 100644 --- a/src/transformers/models/imagegpt/convert_imagegpt_original_tf2_to_pytorch.py +++ b/src/transformers/models/imagegpt/convert_imagegpt_original_tf2_to_pytorch.py @@ -15,14 +15,124 @@ """Convert OpenAI Image GPT checkpoints.""" import argparse +import os import torch -from transformers import ImageGPTConfig, ImageGPTForCausalLM, load_tf_weights_in_imagegpt +from transformers import ImageGPTConfig, ImageGPTForCausalLM from transformers.utils import CONFIG_NAME, WEIGHTS_NAME, logging logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def load_tf_weights_in_imagegpt(model, config, imagegpt_checkpoint_path): + """ + Load tf checkpoints in a pytorch model + """ + try: + import re + + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(imagegpt_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array.squeeze()) + + for name, array in zip(names, arrays): + name = name[6:] # skip "model/" + name = name.split("/") + + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any( + n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] + for n in name + ) or name[-1] in ["_step"]: + logger.info("Skipping {}".format("/".join(name))) + continue + + pointer = model + if name[-1] not in ["wtet"]: + pointer = getattr(pointer, "transformer") + + for m_name in name: + if re.fullmatch(r"[A-Za-z]+\d+", m_name): + scope_names = re.split(r"(\d+)", m_name) + else: + scope_names = [m_name] + + if scope_names[0] == "w" or scope_names[0] == "g": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "b": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "wpe" or scope_names[0] == "wte": + pointer = getattr(pointer, scope_names[0]) + pointer = getattr(pointer, "weight") + elif scope_names[0] in ["q_proj", "k_proj", "v_proj"]: + pointer = getattr(pointer, "c_attn") + pointer = getattr(pointer, "weight") + elif len(name) == 3 and name[1] == "attn" and scope_names[0] == "c_proj": + pointer = getattr(pointer, scope_names[0]) + pointer = getattr(pointer, "weight") + elif scope_names[0] == "wtet": + pointer = getattr(pointer, "lm_head") + pointer = getattr(pointer, "weight") + elif scope_names[0] == "sos": + pointer = getattr(pointer, "wte") + pointer = getattr(pointer, "weight") + else: + pointer = getattr(pointer, scope_names[0]) + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + + if len(name) > 1 and name[1] == "attn" or name[-1] == "wtet" or name[-1] == "sos" or name[-1] == "wte": + pass # array is used to initialize only part of the pointer so sizes won't match + else: + try: + assert pointer.shape == array.shape + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + + logger.info(f"Initialize PyTorch weight {name}") + + if name[-1] == "q_proj": + pointer.data[:, : config.n_embd] = torch.from_numpy(array.reshape(config.n_embd, config.n_embd)).T + elif name[-1] == "k_proj": + pointer.data[:, config.n_embd : 2 * config.n_embd] = torch.from_numpy( + array.reshape(config.n_embd, config.n_embd) + ).T + elif name[-1] == "v_proj": + pointer.data[:, 2 * config.n_embd :] = torch.from_numpy(array.reshape(config.n_embd, config.n_embd)).T + elif len(name) == 3 and name[1] == "attn" and name[2] == "c_proj": + pointer.data = torch.from_numpy(array.reshape(config.n_embd, config.n_embd)) + elif name[-1] == "wtet": + pointer.data = torch.from_numpy(array) + elif name[-1] == "wte": + pointer.data[: config.vocab_size - 1, :] = torch.from_numpy(array) + elif name[-1] == "sos": + pointer.data[-1] = torch.from_numpy(array) + else: + pointer.data = torch.from_numpy(array) + + return model def convert_imagegpt_checkpoint_to_pytorch(imagegpt_checkpoint_path, model_size, pytorch_dump_folder_path): diff --git a/src/transformers/models/imagegpt/image_processing_imagegpt.py b/src/transformers/models/imagegpt/image_processing_imagegpt.py index 9168ecaceff2..97086ed45e07 100644 --- a/src/transformers/models/imagegpt/image_processing_imagegpt.py +++ b/src/transformers/models/imagegpt/image_processing_imagegpt.py @@ -213,10 +213,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -241,10 +239,7 @@ def preprocess( images = make_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # Here, normalize() is using a constant factor to divide pixel values. # hence, the method does not need iamge_mean and image_std. diff --git a/src/transformers/models/imagegpt/modeling_imagegpt.py b/src/transformers/models/imagegpt/modeling_imagegpt.py index a962141e4479..cd527d28e5d1 100755 --- a/src/transformers/models/imagegpt/modeling_imagegpt.py +++ b/src/transformers/models/imagegpt/modeling_imagegpt.py @@ -15,7 +15,6 @@ """PyTorch OpenAI ImageGPT model.""" import math -import os from typing import Any, Optional, Union import torch @@ -44,114 +43,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_imagegpt(model, config, imagegpt_checkpoint_path): - """ - Load tf checkpoints in a pytorch model - """ - try: - import re - - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(imagegpt_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array.squeeze()) - - for name, array in zip(names, arrays): - name = name[6:] # skip "model/" - name = name.split("/") - - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ) or name[-1] in ["_step"]: - logger.info("Skipping {}".format("/".join(name))) - continue - - pointer = model - if name[-1] not in ["wtet"]: - pointer = getattr(pointer, "transformer") - - for m_name in name: - if re.fullmatch(r"[A-Za-z]+\d+", m_name): - scope_names = re.split(r"(\d+)", m_name) - else: - scope_names = [m_name] - - if scope_names[0] == "w" or scope_names[0] == "g": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "b": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "wpe" or scope_names[0] == "wte": - pointer = getattr(pointer, scope_names[0]) - pointer = getattr(pointer, "weight") - elif scope_names[0] in ["q_proj", "k_proj", "v_proj"]: - pointer = getattr(pointer, "c_attn") - pointer = getattr(pointer, "weight") - elif len(name) == 3 and name[1] == "attn" and scope_names[0] == "c_proj": - pointer = getattr(pointer, scope_names[0]) - pointer = getattr(pointer, "weight") - elif scope_names[0] == "wtet": - pointer = getattr(pointer, "lm_head") - pointer = getattr(pointer, "weight") - elif scope_names[0] == "sos": - pointer = getattr(pointer, "wte") - pointer = getattr(pointer, "weight") - else: - pointer = getattr(pointer, scope_names[0]) - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - - if len(name) > 1 and name[1] == "attn" or name[-1] == "wtet" or name[-1] == "sos" or name[-1] == "wte": - pass # array is used to initialize only part of the pointer so sizes won't match - else: - try: - assert pointer.shape == array.shape - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - - logger.info(f"Initialize PyTorch weight {name}") - - if name[-1] == "q_proj": - pointer.data[:, : config.n_embd] = torch.from_numpy(array.reshape(config.n_embd, config.n_embd)).T - elif name[-1] == "k_proj": - pointer.data[:, config.n_embd : 2 * config.n_embd] = torch.from_numpy( - array.reshape(config.n_embd, config.n_embd) - ).T - elif name[-1] == "v_proj": - pointer.data[:, 2 * config.n_embd :] = torch.from_numpy(array.reshape(config.n_embd, config.n_embd)).T - elif len(name) == 3 and name[1] == "attn" and name[2] == "c_proj": - pointer.data = torch.from_numpy(array.reshape(config.n_embd, config.n_embd)) - elif name[-1] == "wtet": - pointer.data = torch.from_numpy(array) - elif name[-1] == "wte": - pointer.data[: config.vocab_size - 1, :] = torch.from_numpy(array) - elif name[-1] == "sos": - pointer.data[-1] = torch.from_numpy(array) - else: - pointer.data = torch.from_numpy(array) - - return model - - class ImageGPTLayerNorm(nn.Module): def __init__(self, hidden_size: tuple[int], eps: float = 1e-5): super().__init__() @@ -498,7 +389,6 @@ def forward( @auto_docstring class ImageGPTPreTrainedModel(PreTrainedModel): config: ImageGPTConfig - load_tf_weights = load_tf_weights_in_imagegpt base_model_prefix = "transformer" main_input_name = "input_ids" supports_gradient_checkpointing = True @@ -510,8 +400,6 @@ def __init__(self, *inputs, **kwargs): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, (nn.Linear, Conv1D)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1020,5 +908,4 @@ def forward( "ImageGPTForImageClassification", "ImageGPTModel", "ImageGPTPreTrainedModel", - "load_tf_weights_in_imagegpt", ] diff --git a/src/transformers/models/instructblipvideo/image_processing_instructblipvideo.py b/src/transformers/models/instructblipvideo/image_processing_instructblipvideo.py index 56391b59dbdd..ccd0d701738c 100644 --- a/src/transformers/models/instructblipvideo/image_processing_instructblipvideo.py +++ b/src/transformers/models/instructblipvideo/image_processing_instructblipvideo.py @@ -207,10 +207,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -253,10 +251,7 @@ def preprocess( ) if not valid_images(videos): - raise ValueError( - "Invalid input type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid input type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") pixel_values = [ [ diff --git a/src/transformers/models/internvl/processing_internvl.py b/src/transformers/models/internvl/processing_internvl.py index a13457886baf..12e6a6163ba8 100644 --- a/src/transformers/models/internvl/processing_internvl.py +++ b/src/transformers/models/internvl/processing_internvl.py @@ -180,10 +180,8 @@ def __call__( The image or batch of videos to be prepared. Each video can be a 4D NumPy array or PyTorch return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/janus/image_processing_janus.py b/src/transformers/models/janus/image_processing_janus.py index 16659bd85354..c1f34efde71e 100644 --- a/src/transformers/models/janus/image_processing_janus.py +++ b/src/transformers/models/janus/image_processing_janus.py @@ -247,10 +247,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -280,10 +278,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/janus/modular_janus.py b/src/transformers/models/janus/modular_janus.py index dcd5c1e1e730..ef99aaf45680 100644 --- a/src/transformers/models/janus/modular_janus.py +++ b/src/transformers/models/janus/modular_janus.py @@ -1546,10 +1546,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -1579,10 +1577,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/janus/processing_janus.py b/src/transformers/models/janus/processing_janus.py index 2de97400043f..c2413e705756 100644 --- a/src/transformers/models/janus/processing_janus.py +++ b/src/transformers/models/janus/processing_janus.py @@ -102,10 +102,8 @@ def __call__( tensor. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/jetmoe/modeling_jetmoe.py b/src/transformers/models/jetmoe/modeling_jetmoe.py index 0ca0a9a43669..06388d96f1e7 100644 --- a/src/transformers/models/jetmoe/modeling_jetmoe.py +++ b/src/transformers/models/jetmoe/modeling_jetmoe.py @@ -843,8 +843,6 @@ class JetMoePreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, (nn.Linear,)): - # Slightly different from Mesh Transformer JAX which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/kosmos2_5/image_processing_kosmos2_5.py b/src/transformers/models/kosmos2_5/image_processing_kosmos2_5.py index d603575ef32d..b768205da2a4 100644 --- a/src/transformers/models/kosmos2_5/image_processing_kosmos2_5.py +++ b/src/transformers/models/kosmos2_5/image_processing_kosmos2_5.py @@ -209,9 +209,6 @@ def normalize( """ Normalize an image. image = (image - image_mean) / image_std. - The image std is to mimic the tensorflow implementation of the `per_image_standardization`: - https://www.tensorflow.org/api_docs/python/tf/image/per_image_standardization - Args: image (`np.ndarray`): Image to normalize. @@ -253,9 +250,7 @@ def preprocess( """ Preprocess an image or batch of images. The processor first computes the maximum possible number of aspect-ratio preserving patches of size `patch_size` that can be extracted from the image. It then pads the - image with zeros to make the image respect the constraint of `max_patches`. Before extracting the patches the - images are standardized following the tensorflow implementation of `per_image_standardization` - (https://www.tensorflow.org/api_docs/python/tf/image/per_image_standardization). + image with zeros to make the image respect the constraint of `max_patches`. Args: @@ -272,10 +267,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -299,10 +292,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # PIL RGBA images are converted to RGB if do_convert_rgb: diff --git a/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py b/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py index c6d8b1b1edf5..c539288d9913 100644 --- a/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py +++ b/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py @@ -105,9 +105,6 @@ def normalize( """ Normalize an image. image = (image - image_mean) / image_std. - The image std is to mimic the tensorflow implementation of the `per_image_standardization`: - https://www.tensorflow.org/api_docs/python/tf/image/per_image_standardization - Args: image (`torch.Tensor`): Image to normalize. diff --git a/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py b/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py index 8f9fbd706b32..ad4910dcb8c1 100644 --- a/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py +++ b/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py @@ -484,7 +484,6 @@ def __init__(self, config): self.is_causal = False self.scaling = self.head_dim**-0.5 - # Mesh TensorFlow initialization to avoid scaling before softmax self.query = nn.Linear(self.hidden_size, self.inner_dim, bias=False) self.key = nn.Linear(self.hidden_size, self.inner_dim, bias=False) self.value = nn.Linear(self.hidden_size, self.inner_dim, bias=False) diff --git a/src/transformers/models/kyutai_speech_to_text/feature_extraction_kyutai_speech_to_text.py b/src/transformers/models/kyutai_speech_to_text/feature_extraction_kyutai_speech_to_text.py index bde1736f9da8..fa0ce5e11ded 100644 --- a/src/transformers/models/kyutai_speech_to_text/feature_extraction_kyutai_speech_to_text.py +++ b/src/transformers/models/kyutai_speech_to_text/feature_extraction_kyutai_speech_to_text.py @@ -126,7 +126,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py b/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py index 8541a911e947..16e8f6cd6dcb 100644 --- a/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py +++ b/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py @@ -105,7 +105,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/layoutlm/__init__.py b/src/transformers/models/layoutlm/__init__.py index 0f079c33c715..5db595015b49 100644 --- a/src/transformers/models/layoutlm/__init__.py +++ b/src/transformers/models/layoutlm/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_layoutlm import * from .modeling_layoutlm import * - from .modeling_tf_layoutlm import * from .tokenization_layoutlm import * from .tokenization_layoutlm_fast import * else: diff --git a/src/transformers/models/layoutlm/configuration_layoutlm.py b/src/transformers/models/layoutlm/configuration_layoutlm.py index 18bfacb75592..f777cd862408 100644 --- a/src/transformers/models/layoutlm/configuration_layoutlm.py +++ b/src/transformers/models/layoutlm/configuration_layoutlm.py @@ -20,7 +20,7 @@ from ... import PretrainedConfig, PreTrainedTokenizer from ...onnx import OnnxConfig, PatchingSpec -from ...utils import TensorType, is_torch_available, logging +from ...utils import is_torch_available, logging logger = logging.get_logger(__name__) @@ -154,32 +154,30 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: """ - Generate inputs to provide to the ONNX exporter for the specific framework + Generate inputs to provide to the ONNX exporter Args: tokenizer: The tokenizer associated with this model configuration batch_size: The batch size (int) to export the model for (-1 means dynamic axis) seq_length: The sequence length (int) to export the model for (-1 means dynamic axis) is_pair: Indicate if the input is a pair (sentence 1, sentence 2) - framework: The framework (optional) the tokenizer will generate tensor for Returns: Mapping[str, Tensor] holding the kwargs to provide to the model's forward function """ input_dict = super().generate_dummy_inputs( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, + batch_size=batch_size, + seq_length=seq_length, + is_pair=is_pair, ) # Generate a dummy bbox box = [48, 84, 73, 128] - if not framework == TensorType.PYTORCH: - raise NotImplementedError("Exporting LayoutLM to ONNX is currently only supported for PyTorch.") - if not is_torch_available(): raise ValueError("Cannot generate dummy inputs without PyTorch installed.") import torch diff --git a/src/transformers/models/layoutlm/modeling_layoutlm.py b/src/transformers/models/layoutlm/modeling_layoutlm.py index 9e71eb7d8fb9..11b7fac2b78c 100644 --- a/src/transformers/models/layoutlm/modeling_layoutlm.py +++ b/src/transformers/models/layoutlm/modeling_layoutlm.py @@ -466,8 +466,6 @@ class LayoutLMPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/layoutlm/modeling_tf_layoutlm.py b/src/transformers/models/layoutlm/modeling_tf_layoutlm.py deleted file mode 100644 index f6738693843b..000000000000 --- a/src/transformers/models/layoutlm/modeling_tf_layoutlm.py +++ /dev/null @@ -1,1691 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The Microsoft Research Asia LayoutLM Team Authors and 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. -"""TF 2.0 LayoutLM model.""" - -from __future__ import annotations - -import math -import warnings - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFBaseModelOutputWithPoolingAndCrossAttentions, - TFMaskedLMOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_layoutlm import LayoutLMConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "LayoutLMConfig" - - -class TFLayoutLMEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config: LayoutLMConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.max_2d_position_embeddings = config.max_2d_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("x_position_embeddings"): - self.x_position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_2d_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("y_position_embeddings"): - self.y_position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_2d_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("h_position_embeddings"): - self.h_position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_2d_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("w_position_embeddings"): - self.w_position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_2d_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - def call( - self, - input_ids: tf.Tensor | None = None, - bbox: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - training: bool = False, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) - - if bbox is None: - bbox = tf.fill(input_shape + [4], value=0) - try: - left_position_embeddings = tf.gather(self.x_position_embeddings, bbox[:, :, 0]) - upper_position_embeddings = tf.gather(self.y_position_embeddings, bbox[:, :, 1]) - right_position_embeddings = tf.gather(self.x_position_embeddings, bbox[:, :, 2]) - lower_position_embeddings = tf.gather(self.y_position_embeddings, bbox[:, :, 3]) - except IndexError as e: - raise IndexError("The `bbox`coordinate values should be within 0-1000 range.") from e - h_position_embeddings = tf.gather(self.h_position_embeddings, bbox[:, :, 3] - bbox[:, :, 1]) - w_position_embeddings = tf.gather(self.w_position_embeddings, bbox[:, :, 2] - bbox[:, :, 0]) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = ( - inputs_embeds - + position_embeds - + token_type_embeds - + left_position_embeddings - + upper_position_embeddings - + right_position_embeddings - + lower_position_embeddings - + h_position_embeddings - + w_position_embeddings - ) - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention with Bert->LayoutLM -class TFLayoutLMSelfAttention(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - - self.is_decoder = config.is_decoder - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_layer = past_key_value[0] - value_layer = past_key_value[1] - attention_mask = encoder_attention_mask - elif is_cross_attention: - key_layer = self.transpose_for_scores(self.key(inputs=encoder_hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=encoder_hidden_states), batch_size) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_layer, value_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFLayoutLMModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - if self.is_decoder: - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfOutput with Bert->LayoutLM -class TFLayoutLMSelfOutput(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertAttention with Bert->LayoutLM -class TFLayoutLMAttention(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFLayoutLMSelfAttention(config, name="self") - self.dense_output = TFLayoutLMSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - # add attentions (possibly with past_key_value) if we output them - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->LayoutLM -class TFLayoutLMIntermediate(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->LayoutLM -class TFLayoutLMOutput(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLayer with Bert->LayoutLM -class TFLayoutLMLayer(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFLayoutLMAttention(config, name="attention") - self.is_decoder = config.is_decoder - self.add_cross_attention = config.add_cross_attention - if self.add_cross_attention: - if not self.is_decoder: - raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = TFLayoutLMAttention(config, name="crossattention") - self.intermediate = TFLayoutLMIntermediate(config, name="intermediate") - self.bert_output = TFLayoutLMOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_value: tuple[tf.Tensor] | None, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=self_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - cross_attn_present_key_value = None - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" - " by setting `config.add_cross_attention=True`" - ) - - # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - cross_attention_outputs = self.crossattention( - input_tensor=attention_output, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=cross_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - - # add cross-attn cache to positions 3,4 of present_key_value tuple - cross_attn_present_key_value = cross_attention_outputs[-1] - present_key_value = present_key_value + cross_attn_present_key_value - - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + outputs # add attentions if we output them - - # if decoder, return the attn key/values as the last output - if self.is_decoder: - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertEncoder with Bert->LayoutLM -class TFLayoutLMEncoder(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layer = [TFLayoutLMLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_values: tuple[tuple[tf.Tensor]] | None, - use_cache: bool | None, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - next_decoder_cache = () if use_cache else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[i], - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - if self.config.add_cross_attention and encoder_hidden_states is not None: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v for v in [hidden_states, all_hidden_states, all_attentions, all_cross_attentions] if v is not None - ) - - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->LayoutLM -class TFLayoutLMPooler(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPredictionHeadTransform with Bert->LayoutLM -class TFLayoutLMPredictionHeadTransform(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - - if isinstance(config.hidden_act, str): - self.transform_act_fn = get_tf_activation(config.hidden_act) - else: - self.transform_act_fn = config.hidden_act - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.transform_act_fn(hidden_states) - hidden_states = self.LayerNorm(inputs=hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLMPredictionHead with Bert->LayoutLM -class TFLayoutLMLMPredictionHead(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - - self.transform = TFLayoutLMPredictionHeadTransform(config, name="transform") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.input_embeddings = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "transform", None) is not None: - with tf.name_scope(self.transform.name): - self.transform.build(None) - - def get_output_embeddings(self) -> keras.layers.Layer: - return self.input_embeddings - - def set_output_embeddings(self, value: tf.Variable): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self) -> dict[str, tf.Variable]: - return {"bias": self.bias} - - def set_bias(self, value: tf.Variable): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.transform(hidden_states=hidden_states) - seq_length = shape_list(hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertMLMHead with Bert->LayoutLM -class TFLayoutLMMLMHead(keras.layers.Layer): - def __init__(self, config: LayoutLMConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.predictions = TFLayoutLMLMPredictionHead(config, input_embeddings, name="predictions") - - def call(self, sequence_output: tf.Tensor) -> tf.Tensor: - prediction_scores = self.predictions(hidden_states=sequence_output) - - return prediction_scores - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -@keras_serializable -class TFLayoutLMMainLayer(keras.layers.Layer): - config_class = LayoutLMConfig - - def __init__(self, config: LayoutLMConfig, add_pooling_layer: bool = True, **kwargs): - super().__init__(**kwargs) - - self.config = config - - self.embeddings = TFLayoutLMEmbeddings(config, name="embeddings") - self.encoder = TFLayoutLMEncoder(config, name="encoder") - self.pooler = TFLayoutLMPooler(config, name="pooler") if add_pooling_layer else None - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - bbox: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - if bbox is None: - bbox = tf.fill(dims=input_shape + [4], value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - bbox=bbox, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - extended_attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - # Need to pass these required positional arguments to `Encoder` - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=None, - past_key_values=None, - use_cache=False, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -class TFLayoutLMPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = LayoutLMConfig - base_model_prefix = "layoutlm" - - @property - def input_signature(self): - signature = super().input_signature - signature["bbox"] = tf.TensorSpec(shape=(None, None, 4), dtype=tf.int32, name="bbox") - return signature - - -LAYOUTLM_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`LayoutLMConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -LAYOUTLM_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - bbox (`Numpy array` or `tf.Tensor` of shape `({0}, 4)`, *optional*): - Bounding Boxes of each input sequence tokens. Selected in the range `[0, config.max_2d_position_embeddings- - 1]`. - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare LayoutLM Model transformer outputting raw hidden-states without any specific head on top.", - LAYOUTLM_START_DOCSTRING, -) -class TFLayoutLMModel(TFLayoutLMPreTrainedModel): - def __init__(self, config: LayoutLMConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.layoutlm = TFLayoutLMMainLayer(config, name="layoutlm") - - @unpack_inputs - @add_start_docstrings_to_model_forward(LAYOUTLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings( - output_type=TFBaseModelOutputWithPoolingAndCrossAttentions, config_class=_CONFIG_FOR_DOC - ) - def call( - self, - input_ids: TFModelInputType | None = None, - bbox: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFLayoutLMModel - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("microsoft/layoutlm-base-uncased") - >>> model = TFLayoutLMModel.from_pretrained("microsoft/layoutlm-base-uncased") - - >>> words = ["Hello", "world"] - >>> normalized_word_boxes = [637, 773, 693, 782], [698, 773, 733, 782] - - >>> token_boxes = [] - >>> for word, box in zip(words, normalized_word_boxes): - ... word_tokens = tokenizer.tokenize(word) - ... token_boxes.extend([box] * len(word_tokens)) - >>> # add bounding boxes of cls + sep tokens - >>> token_boxes = [[0, 0, 0, 0]] + token_boxes + [[1000, 1000, 1000, 1000]] - - >>> encoding = tokenizer(" ".join(words), return_tensors="tf") - >>> input_ids = encoding["input_ids"] - >>> attention_mask = encoding["attention_mask"] - >>> token_type_ids = encoding["token_type_ids"] - >>> bbox = tf.convert_to_tensor([token_boxes]) - - >>> outputs = model( - ... input_ids=input_ids, bbox=bbox, attention_mask=attention_mask, token_type_ids=token_type_ids - ... ) - - >>> last_hidden_states = outputs.last_hidden_state - ```""" - outputs = self.layoutlm( - input_ids=input_ids, - bbox=bbox, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layoutlm", None) is not None: - with tf.name_scope(self.layoutlm.name): - self.layoutlm.build(None) - - -@add_start_docstrings("""LayoutLM Model with a `language modeling` head on top.""", LAYOUTLM_START_DOCSTRING) -class TFLayoutLMForMaskedLM(TFLayoutLMPreTrainedModel, TFMaskedLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"pooler", - r"cls.seq_relationship", - r"cls.predictions.decoder.weight", - r"nsp___cls", - ] - - def __init__(self, config: LayoutLMConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if config.is_decoder: - logger.warning( - "If you want to use `TFLayoutLMForMaskedLM` make sure `config.is_decoder=False` for " - "bi-directional self-attention." - ) - - self.layoutlm = TFLayoutLMMainLayer(config, add_pooling_layer=True, name="layoutlm") - self.mlm = TFLayoutLMMLMHead(config, input_embeddings=self.layoutlm.embeddings, name="mlm___cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.mlm.predictions - - def get_prefix_bias_name(self) -> str: - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.mlm.name + "/" + self.mlm.predictions.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(LAYOUTLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFMaskedLMOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - bbox: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFLayoutLMForMaskedLM - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("microsoft/layoutlm-base-uncased") - >>> model = TFLayoutLMForMaskedLM.from_pretrained("microsoft/layoutlm-base-uncased") - - >>> words = ["Hello", "[MASK]"] - >>> normalized_word_boxes = [637, 773, 693, 782], [698, 773, 733, 782] - - >>> token_boxes = [] - >>> for word, box in zip(words, normalized_word_boxes): - ... word_tokens = tokenizer.tokenize(word) - ... token_boxes.extend([box] * len(word_tokens)) - >>> # add bounding boxes of cls + sep tokens - >>> token_boxes = [[0, 0, 0, 0]] + token_boxes + [[1000, 1000, 1000, 1000]] - - >>> encoding = tokenizer(" ".join(words), return_tensors="tf") - >>> input_ids = encoding["input_ids"] - >>> attention_mask = encoding["attention_mask"] - >>> token_type_ids = encoding["token_type_ids"] - >>> bbox = tf.convert_to_tensor([token_boxes]) - - >>> labels = tokenizer("Hello world", return_tensors="tf")["input_ids"] - - >>> outputs = model( - ... input_ids=input_ids, - ... bbox=bbox, - ... attention_mask=attention_mask, - ... token_type_ids=token_type_ids, - ... labels=labels, - ... ) - - >>> loss = outputs.loss - ```""" - outputs = self.layoutlm( - input_ids=input_ids, - bbox=bbox, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.mlm(sequence_output=sequence_output, training=training) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layoutlm", None) is not None: - with tf.name_scope(self.layoutlm.name): - self.layoutlm.build(None) - if getattr(self, "mlm", None) is not None: - with tf.name_scope(self.mlm.name): - self.mlm.build(None) - - -@add_start_docstrings( - """ - LayoutLM Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - LAYOUTLM_START_DOCSTRING, -) -class TFLayoutLMForSequenceClassification(TFLayoutLMPreTrainedModel, TFSequenceClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"mlm___cls", r"nsp___cls", r"cls.predictions", r"cls.seq_relationship"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config: LayoutLMConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.layoutlm = TFLayoutLMMainLayer(config, name="layoutlm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(LAYOUTLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFSequenceClassifierOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - bbox: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFLayoutLMForSequenceClassification - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("microsoft/layoutlm-base-uncased") - >>> model = TFLayoutLMForSequenceClassification.from_pretrained("microsoft/layoutlm-base-uncased") - - >>> words = ["Hello", "world"] - >>> normalized_word_boxes = [637, 773, 693, 782], [698, 773, 733, 782] - - >>> token_boxes = [] - >>> for word, box in zip(words, normalized_word_boxes): - ... word_tokens = tokenizer.tokenize(word) - ... token_boxes.extend([box] * len(word_tokens)) - >>> # add bounding boxes of cls + sep tokens - >>> token_boxes = [[0, 0, 0, 0]] + token_boxes + [[1000, 1000, 1000, 1000]] - - >>> encoding = tokenizer(" ".join(words), return_tensors="tf") - >>> input_ids = encoding["input_ids"] - >>> attention_mask = encoding["attention_mask"] - >>> token_type_ids = encoding["token_type_ids"] - >>> bbox = tf.convert_to_tensor([token_boxes]) - >>> sequence_label = tf.convert_to_tensor([1]) - - >>> outputs = model( - ... input_ids=input_ids, - ... bbox=bbox, - ... attention_mask=attention_mask, - ... token_type_ids=token_type_ids, - ... labels=sequence_label, - ... ) - - >>> loss = outputs.loss - >>> logits = outputs.logits - ```""" - outputs = self.layoutlm( - input_ids=input_ids, - bbox=bbox, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(inputs=pooled_output, training=training) - logits = self.classifier(inputs=pooled_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layoutlm", None) is not None: - with tf.name_scope(self.layoutlm.name): - self.layoutlm.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - LayoutLM Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - LAYOUTLM_START_DOCSTRING, -) -class TFLayoutLMForTokenClassification(TFLayoutLMPreTrainedModel, TFTokenClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"pooler", - r"mlm___cls", - r"nsp___cls", - r"cls.predictions", - r"cls.seq_relationship", - ] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config: LayoutLMConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.layoutlm = TFLayoutLMMainLayer(config, add_pooling_layer=True, name="layoutlm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(LAYOUTLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFTokenClassifierOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - bbox: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - - Returns: - - Examples: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFLayoutLMForTokenClassification - - >>> tokenizer = AutoTokenizer.from_pretrained("microsoft/layoutlm-base-uncased") - >>> model = TFLayoutLMForTokenClassification.from_pretrained("microsoft/layoutlm-base-uncased") - - >>> words = ["Hello", "world"] - >>> normalized_word_boxes = [637, 773, 693, 782], [698, 773, 733, 782] - - >>> token_boxes = [] - >>> for word, box in zip(words, normalized_word_boxes): - ... word_tokens = tokenizer.tokenize(word) - ... token_boxes.extend([box] * len(word_tokens)) - >>> # add bounding boxes of cls + sep tokens - >>> token_boxes = [[0, 0, 0, 0]] + token_boxes + [[1000, 1000, 1000, 1000]] - - >>> encoding = tokenizer(" ".join(words), return_tensors="tf") - >>> input_ids = encoding["input_ids"] - >>> attention_mask = encoding["attention_mask"] - >>> token_type_ids = encoding["token_type_ids"] - >>> bbox = tf.convert_to_tensor([token_boxes]) - >>> token_labels = tf.convert_to_tensor([1, 1, 0, 0]) - - >>> outputs = model( - ... input_ids=input_ids, - ... bbox=bbox, - ... attention_mask=attention_mask, - ... token_type_ids=token_type_ids, - ... labels=token_labels, - ... ) - - >>> loss = outputs.loss - >>> logits = outputs.logits - ```""" - outputs = self.layoutlm( - input_ids=input_ids, - bbox=bbox, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - sequence_output = self.dropout(inputs=sequence_output, training=training) - logits = self.classifier(inputs=sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layoutlm", None) is not None: - with tf.name_scope(self.layoutlm.name): - self.layoutlm.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - LayoutLM Model with a span classification head on top for extractive question-answering tasks such as - [DocVQA](https://rrc.cvc.uab.es/?ch=17) (a linear layer on top of the final hidden-states output to compute `span - start logits` and `span end logits`). - """, - LAYOUTLM_START_DOCSTRING, -) -class TFLayoutLMForQuestionAnswering(TFLayoutLMPreTrainedModel, TFQuestionAnsweringLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"pooler", - r"mlm___cls", - r"nsp___cls", - r"cls.predictions", - r"cls.seq_relationship", - ] - - def __init__(self, config: LayoutLMConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.layoutlm = TFLayoutLMMainLayer(config, add_pooling_layer=True, name="layoutlm") - self.qa_outputs = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="qa_outputs", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(LAYOUTLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFQuestionAnsweringModelOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - bbox: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - - Returns: - - Examples: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFLayoutLMForQuestionAnswering - >>> from datasets import load_dataset - - >>> tokenizer = AutoTokenizer.from_pretrained("impira/layoutlm-document-qa", add_prefix_space=True) - >>> model = TFLayoutLMForQuestionAnswering.from_pretrained("impira/layoutlm-document-qa", revision="1e3ebac") - - >>> dataset = load_dataset("nielsr/funsd", split="train") - >>> example = dataset[0] - >>> question = "what's his name?" - >>> words = example["words"] - >>> boxes = example["bboxes"] - - >>> encoding = tokenizer( - ... question.split(), words, is_split_into_words=True, return_token_type_ids=True, return_tensors="tf" - ... ) - >>> bbox = [] - >>> for i, s, w in zip(encoding.input_ids[0], encoding.sequence_ids(0), encoding.word_ids(0)): - ... if s == 1: - ... bbox.append(boxes[w]) - ... elif i == tokenizer.sep_token_id: - ... bbox.append([1000] * 4) - ... else: - ... bbox.append([0] * 4) - >>> encoding["bbox"] = tf.convert_to_tensor([bbox]) - - >>> word_ids = encoding.word_ids(0) - >>> outputs = model(**encoding) - >>> loss = outputs.loss - >>> start_scores = outputs.start_logits - >>> end_scores = outputs.end_logits - >>> start, end = word_ids[tf.math.argmax(start_scores, -1)[0]], word_ids[tf.math.argmax(end_scores, -1)[0]] - >>> print(" ".join(words[start : end + 1])) - M. Hamann P. Harper, P. Martinez - ```""" - - outputs = self.layoutlm( - input_ids=input_ids, - bbox=bbox, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - - logits = self.qa_outputs(inputs=sequence_output) - start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) - start_logits = tf.squeeze(input=start_logits, axis=-1) - end_logits = tf.squeeze(input=end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels=labels, logits=(start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layoutlm", None) is not None: - with tf.name_scope(self.layoutlm.name): - self.layoutlm.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFLayoutLMForMaskedLM", - "TFLayoutLMForSequenceClassification", - "TFLayoutLMForTokenClassification", - "TFLayoutLMForQuestionAnswering", - "TFLayoutLMMainLayer", - "TFLayoutLMModel", - "TFLayoutLMPreTrainedModel", -] diff --git a/src/transformers/models/layoutlmv2/image_processing_layoutlmv2.py b/src/transformers/models/layoutlmv2/image_processing_layoutlmv2.py index de2e7361a6d3..76fc752bbeea 100644 --- a/src/transformers/models/layoutlmv2/image_processing_layoutlmv2.py +++ b/src/transformers/models/layoutlmv2/image_processing_layoutlmv2.py @@ -234,10 +234,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -254,10 +252,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_resize=do_resize, size=size, diff --git a/src/transformers/models/layoutlmv2/modeling_layoutlmv2.py b/src/transformers/models/layoutlmv2/modeling_layoutlmv2.py index 3f444fbb6b28..f3b856518133 100755 --- a/src/transformers/models/layoutlmv2/modeling_layoutlmv2.py +++ b/src/transformers/models/layoutlmv2/modeling_layoutlmv2.py @@ -473,8 +473,6 @@ class LayoutLMv2PreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/layoutlmv2/tokenization_layoutlmv2.py b/src/transformers/models/layoutlmv2/tokenization_layoutlmv2.py index 7d82b5cf4104..a4c04598d855 100644 --- a/src/transformers/models/layoutlmv2/tokenization_layoutlmv2.py +++ b/src/transformers/models/layoutlmv2/tokenization_layoutlmv2.py @@ -81,7 +81,6 @@ return_tensors (`str` or [`~file_utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. """ diff --git a/src/transformers/models/layoutlmv3/__init__.py b/src/transformers/models/layoutlmv3/__init__.py index c776b676f603..c87afd9c58e7 100644 --- a/src/transformers/models/layoutlmv3/__init__.py +++ b/src/transformers/models/layoutlmv3/__init__.py @@ -23,7 +23,6 @@ from .image_processing_layoutlmv3 import * from .image_processing_layoutlmv3_fast import * from .modeling_layoutlmv3 import * - from .modeling_tf_layoutlmv3 import * from .processing_layoutlmv3 import * from .tokenization_layoutlmv3 import * from .tokenization_layoutlmv3_fast import * diff --git a/src/transformers/models/layoutlmv3/configuration_layoutlmv3.py b/src/transformers/models/layoutlmv3/configuration_layoutlmv3.py index c845bb43b346..b78760743832 100644 --- a/src/transformers/models/layoutlmv3/configuration_layoutlmv3.py +++ b/src/transformers/models/layoutlmv3/configuration_layoutlmv3.py @@ -16,7 +16,7 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any from packaging import version @@ -28,7 +28,6 @@ if TYPE_CHECKING: from ...processing_utils import ProcessorMixin - from ...utils import TensorType logger = logging.get_logger(__name__) @@ -227,13 +226,12 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional["TensorType"] = None, num_channels: int = 3, image_width: int = 40, image_height: int = 40, ) -> Mapping[str, Any]: """ - Generate inputs to provide to the ONNX exporter for the specific framework + Generate inputs to provide to the ONNX exporter Args: processor ([`ProcessorMixin`]): @@ -244,8 +242,6 @@ def generate_dummy_inputs( The sequence length to export the model for (-1 means dynamic axis). is_pair (`bool`, *optional*, defaults to `False`): Indicate if the input is a pair (sentence 1, sentence 2). - framework (`TensorType`, *optional*, defaults to `None`): - The framework (PyTorch or TensorFlow) that the processor will generate tensors for. num_channels (`int`, *optional*, defaults to 3): The number of channels of the generated images. image_width (`int`, *optional*, defaults to 40): @@ -284,7 +280,7 @@ def generate_dummy_inputs( dummy_image, text=dummy_text, boxes=dummy_bboxes, - return_tensors=framework, + return_tensors="pt", ) ) diff --git a/src/transformers/models/layoutlmv3/image_processing_layoutlmv3.py b/src/transformers/models/layoutlmv3/image_processing_layoutlmv3.py index 8189abf67311..0ce7f5ce6968 100644 --- a/src/transformers/models/layoutlmv3/image_processing_layoutlmv3.py +++ b/src/transformers/models/layoutlmv3/image_processing_layoutlmv3.py @@ -279,10 +279,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -309,10 +307,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/layoutlmv3/modeling_layoutlmv3.py b/src/transformers/models/layoutlmv3/modeling_layoutlmv3.py index 73bf26b0dfbe..63631e12eab5 100644 --- a/src/transformers/models/layoutlmv3/modeling_layoutlmv3.py +++ b/src/transformers/models/layoutlmv3/modeling_layoutlmv3.py @@ -205,8 +205,6 @@ class LayoutLMv3PreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/layoutlmv3/modeling_tf_layoutlmv3.py b/src/transformers/models/layoutlmv3/modeling_tf_layoutlmv3.py deleted file mode 100644 index c0586d58835e..000000000000 --- a/src/transformers/models/layoutlmv3/modeling_tf_layoutlmv3.py +++ /dev/null @@ -1,1767 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Microsoft Research and 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. -"""TF 2.0 LayoutLMv3 model.""" - -from __future__ import annotations - -import collections -import math - -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, replace_return_docstrings -from .configuration_layoutlmv3 import LayoutLMv3Config - - -_CONFIG_FOR_DOC = "LayoutLMv3Config" - -_DUMMY_INPUT_IDS = [ - [7, 6, 1], - [1, 2, 0], -] - -_DUMMY_BBOX = [ - [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], - [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]], -] - - -LARGE_NEGATIVE = -1e8 - - -class TFLayoutLMv3PatchEmbeddings(keras.layers.Layer): - """LayoutLMv3 image (patch) embeddings.""" - - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - patch_sizes = ( - config.patch_size - if isinstance(config.patch_size, collections.abc.Iterable) - else (config.patch_size, config.patch_size) - ) - self.proj = keras.layers.Conv2D( - filters=config.hidden_size, - kernel_size=patch_sizes, - strides=patch_sizes, - padding="valid", - data_format="channels_last", - use_bias=True, - kernel_initializer=get_initializer(config.initializer_range), - name="proj", - ) - self.hidden_size = config.hidden_size - self.num_patches = (config.input_size**2) // (patch_sizes[0] * patch_sizes[1]) - self.config = config - - def call(self, pixel_values: tf.Tensor) -> tf.Tensor: - # When running on CPU, `keras.layers.Conv2D` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - pixel_values = tf.transpose(pixel_values, perm=[0, 2, 3, 1]) - - embeddings = self.proj(pixel_values) - embeddings = tf.reshape(embeddings, (-1, self.num_patches, self.hidden_size)) - return embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "proj", None) is not None: - with tf.name_scope(self.proj.name): - self.proj.build([None, None, None, self.config.num_channels]) - - -class TFLayoutLMv3TextEmbeddings(keras.layers.Layer): - """ - LayoutLMv3 text embeddings. Same as `RobertaEmbeddings` but with added spatial (layout) embeddings. - """ - - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - self.word_embeddings = keras.layers.Embedding( - config.vocab_size, - config.hidden_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="word_embeddings", - ) - self.token_type_embeddings = keras.layers.Embedding( - config.type_vocab_size, - config.hidden_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="token_type_embeddings", - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.padding_token_index = config.pad_token_id - self.position_embeddings = keras.layers.Embedding( - config.max_position_embeddings, - config.hidden_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="position_embeddings", - ) - self.x_position_embeddings = keras.layers.Embedding( - config.max_2d_position_embeddings, - config.coordinate_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="x_position_embeddings", - ) - self.y_position_embeddings = keras.layers.Embedding( - config.max_2d_position_embeddings, - config.coordinate_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="y_position_embeddings", - ) - self.h_position_embeddings = keras.layers.Embedding( - config.max_2d_position_embeddings, - config.shape_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="h_position_embeddings", - ) - self.w_position_embeddings = keras.layers.Embedding( - config.max_2d_position_embeddings, - config.shape_size, - embeddings_initializer=get_initializer(config.initializer_range), - name="w_position_embeddings", - ) - self.max_2d_positions = config.max_2d_position_embeddings - self.config = config - - def calculate_spatial_position_embeddings(self, bbox: tf.Tensor) -> tf.Tensor: - try: - left_position_ids = bbox[:, :, 0] - upper_position_ids = bbox[:, :, 1] - right_position_ids = bbox[:, :, 2] - lower_position_ids = bbox[:, :, 3] - except IndexError as exception: - raise IndexError("Bounding box is not of shape (batch_size, seq_length, 4).") from exception - - try: - left_position_embeddings = self.x_position_embeddings(left_position_ids) - upper_position_embeddings = self.y_position_embeddings(upper_position_ids) - right_position_embeddings = self.x_position_embeddings(right_position_ids) - lower_position_embeddings = self.y_position_embeddings(lower_position_ids) - except IndexError as exception: - raise IndexError( - f"The `bbox` coordinate values should be within 0-{self.max_2d_positions} range." - ) from exception - - max_position_id = self.max_2d_positions - 1 - h_position_embeddings = self.h_position_embeddings( - tf.clip_by_value(bbox[:, :, 3] - bbox[:, :, 1], 0, max_position_id) - ) - w_position_embeddings = self.w_position_embeddings( - tf.clip_by_value(bbox[:, :, 2] - bbox[:, :, 0], 0, max_position_id) - ) - - # LayoutLMv1 sums the spatial embeddings, but LayoutLMv3 concatenates them. - spatial_position_embeddings = tf.concat( - [ - left_position_embeddings, - upper_position_embeddings, - right_position_embeddings, - lower_position_embeddings, - h_position_embeddings, - w_position_embeddings, - ], - axis=-1, - ) - return spatial_position_embeddings - - def create_position_ids_from_inputs_embeds(self, inputs_embds: tf.Tensor) -> tf.Tensor: - """ - We are provided embeddings directly. We cannot infer which are padded, so just generate sequential position - ids. - """ - input_shape = tf.shape(inputs_embds) - sequence_length = input_shape[1] - start_index = self.padding_token_index + 1 - end_index = self.padding_token_index + sequence_length + 1 - position_ids = tf.range(start_index, end_index, dtype=tf.int32) - batch_size = input_shape[0] - position_ids = tf.reshape(position_ids, (1, sequence_length)) - position_ids = tf.tile(position_ids, (batch_size, 1)) - return position_ids - - def create_position_ids_from_input_ids(self, input_ids: tf.Tensor) -> tf.Tensor: - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_token_index + 1. - """ - mask = tf.cast(tf.not_equal(input_ids, self.padding_token_index), input_ids.dtype) - position_ids = tf.cumsum(mask, axis=1) * mask - position_ids = position_ids + self.padding_token_index - return position_ids - - def create_position_ids(self, input_ids: tf.Tensor, inputs_embeds: tf.Tensor) -> tf.Tensor: - if input_ids is None: - return self.create_position_ids_from_inputs_embeds(inputs_embeds) - else: - return self.create_position_ids_from_input_ids(input_ids) - - def call( - self, - input_ids: tf.Tensor | None = None, - bbox: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - training: bool = False, - ) -> tf.Tensor: - if position_ids is None: - position_ids = self.create_position_ids(input_ids, inputs_embeds) - - if input_ids is not None: - input_shape = tf.shape(input_ids) - else: - input_shape = tf.shape(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.zeros(input_shape, dtype=position_ids.dtype) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.word_embeddings.input_dim) - inputs_embeds = self.word_embeddings(input_ids) - token_type_embeddings = self.token_type_embeddings(token_type_ids) - - embeddings = inputs_embeds + token_type_embeddings - position_embeddings = self.position_embeddings(position_ids) - embeddings += position_embeddings - - spatial_position_embeddings = self.calculate_spatial_position_embeddings(bbox) - - embeddings += spatial_position_embeddings - - embeddings = self.LayerNorm(embeddings) - embeddings = self.dropout(embeddings, training=training) - return embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "word_embeddings", None) is not None: - with tf.name_scope(self.word_embeddings.name): - self.word_embeddings.build(None) - if getattr(self, "token_type_embeddings", None) is not None: - with tf.name_scope(self.token_type_embeddings.name): - self.token_type_embeddings.build(None) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "position_embeddings", None) is not None: - with tf.name_scope(self.position_embeddings.name): - self.position_embeddings.build(None) - if getattr(self, "x_position_embeddings", None) is not None: - with tf.name_scope(self.x_position_embeddings.name): - self.x_position_embeddings.build(None) - if getattr(self, "y_position_embeddings", None) is not None: - with tf.name_scope(self.y_position_embeddings.name): - self.y_position_embeddings.build(None) - if getattr(self, "h_position_embeddings", None) is not None: - with tf.name_scope(self.h_position_embeddings.name): - self.h_position_embeddings.build(None) - if getattr(self, "w_position_embeddings", None) is not None: - with tf.name_scope(self.w_position_embeddings.name): - self.w_position_embeddings.build(None) - - -class TFLayoutLMv3SelfAttention(keras.layers.Layer): - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " - f"heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.attention_score_normaliser = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="query", - ) - self.key = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="key", - ) - self.value = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="value", - ) - - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.has_relative_attention_bias = config.has_relative_attention_bias - self.has_spatial_attention_bias = config.has_spatial_attention_bias - self.config = config - - def transpose_for_scores(self, x: tf.Tensor): - shape = tf.shape(x) - new_shape = ( - shape[0], # batch_size - shape[1], # seq_length - self.num_attention_heads, - self.attention_head_size, - ) - x = tf.reshape(x, new_shape) - return tf.transpose(x, perm=[0, 2, 1, 3]) # batch_size, num_heads, seq_length, attention_head_size - - def cogview_attention(self, attention_scores: tf.Tensor, alpha: float | int = 32): - """ - https://huggingface.co/papers/2105.13290 Section 2.4 Stabilization of training: Precision Bottleneck Relaxation - (PB-Relax). A replacement of the original keras.layers.Softmax(axis=-1)(attention_scores). Seems the new - attention_probs will result in a slower speed and a little bias. Can use - tf.debugging.assert_near(standard_attention_probs, cogview_attention_probs, atol=1e-08) for comparison. The - smaller atol (e.g., 1e-08), the better. - """ - scaled_attention_scores = attention_scores / alpha - max_value = tf.expand_dims(tf.reduce_max(scaled_attention_scores, axis=-1), axis=-1) - new_attention_scores = (scaled_attention_scores - max_value) * alpha - return tf.math.softmax(new_attention_scores, axis=-1) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None, - head_mask: tf.Tensor | None, - output_attentions: bool, - rel_pos: tf.Tensor | None = None, - rel_2d_pos: tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | tuple[tf.Tensor, tf.Tensor]: - key_layer = self.transpose_for_scores(self.key(hidden_states)) - value_layer = self.transpose_for_scores(self.value(hidden_states)) - query_layer = self.transpose_for_scores(self.query(hidden_states)) - - # Take the dot product between "query" and "key" to get the raw attention scores. - normalised_query_layer = query_layer / self.attention_score_normaliser - transposed_key_layer = tf.transpose( - key_layer, perm=[0, 1, 3, 2] - ) # batch_size, num_heads, attention_head_size, seq_length - attention_scores = tf.matmul(normalised_query_layer, transposed_key_layer) - - if self.has_relative_attention_bias and self.has_spatial_attention_bias: - attention_scores += (rel_pos + rel_2d_pos) / self.attention_score_normaliser - elif self.has_relative_attention_bias: - attention_scores += rel_pos / self.attention_score_normaliser - - if attention_mask is not None: - # Apply the attention mask (is precomputed for all layers in TFLayoutLMv3Model call() function) - attention_scores += attention_mask - - # Normalize the attention scores to probabilities. - # Use the trick of CogView paper to stabilize training. - attention_probs = self.cogview_attention(attention_scores) - - attention_probs = self.dropout(attention_probs, training=training) - - # Mask heads if we want to. - if head_mask is not None: - attention_probs = attention_probs * head_mask - - context_layer = tf.matmul(attention_probs, value_layer) - context_layer = tf.transpose( - context_layer, perm=[0, 2, 1, 3] - ) # batch_size, seq_length, num_heads, attention_head_size - shape = tf.shape(context_layer) - context_layer = tf.reshape( - context_layer, (shape[0], shape[1], self.all_head_size) - ) # batch_size, seq_length, num_heads * attention_head_size - - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from models.roberta.modeling_tf_roberta.TFRobertaSelfOutput -class TFLayoutLMv3SelfOutput(keras.layers.Layer): - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFLayoutLMv3Attention(keras.layers.Layer): - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - self.self_attention = TFLayoutLMv3SelfAttention(config, name="self") - self.self_output = TFLayoutLMv3SelfOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None, - head_mask: tf.Tensor | None, - output_attentions: bool, - rel_pos: tf.Tensor | None = None, - rel_2d_pos: tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | tuple[tf.Tensor, tf.Tensor]: - self_outputs = self.self_attention( - hidden_states, - attention_mask, - head_mask, - output_attentions, - rel_pos, - rel_2d_pos, - training=training, - ) - attention_output = self.self_output(self_outputs[0], hidden_states, training=training) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "self_output", None) is not None: - with tf.name_scope(self.self_output.name): - self.self_output.build(None) - - -# Copied from models.roberta.modeling_tf_bert.TFRobertaIntermediate -class TFLayoutLMv3Intermediate(keras.layers.Layer): - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from models.roberta.modeling_tf_bert.TFRobertaOutput -class TFLayoutLMv3Output(keras.layers.Layer): - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFLayoutLMv3Layer(keras.layers.Layer): - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - self.attention = TFLayoutLMv3Attention(config, name="attention") - self.intermediate = TFLayoutLMv3Intermediate(config, name="intermediate") - self.bert_output = TFLayoutLMv3Output(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None, - head_mask: tf.Tensor | None, - output_attentions: bool, - rel_pos: tf.Tensor | None = None, - rel_2d_pos: tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | tuple[tf.Tensor, tf.Tensor]: - self_attention_outputs = self.attention( - hidden_states, - attention_mask, - head_mask, - output_attentions=output_attentions, - rel_pos=rel_pos, - rel_2d_pos=rel_2d_pos, - training=training, - ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - intermediate_output = self.intermediate(attention_output) - layer_output = self.bert_output(intermediate_output, attention_output, training=training) - outputs = (layer_output,) + outputs - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - - -class TFLayoutLMv3Encoder(keras.layers.Layer): - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layer = [TFLayoutLMv3Layer(config, name=f"layer.{i}") for i in range(config.num_hidden_layers)] - - self.has_relative_attention_bias = config.has_relative_attention_bias - self.has_spatial_attention_bias = config.has_spatial_attention_bias - - if self.has_relative_attention_bias: - self.rel_pos_bins = config.rel_pos_bins - self.max_rel_pos = config.max_rel_pos - self.rel_pos_bias = keras.layers.Dense( - units=config.num_attention_heads, - kernel_initializer=get_initializer(config.initializer_range), - use_bias=False, - name="rel_pos_bias", - ) - - if self.has_spatial_attention_bias: - self.max_rel_2d_pos = config.max_rel_2d_pos - self.rel_2d_pos_bins = config.rel_2d_pos_bins - self.rel_pos_x_bias = keras.layers.Dense( - units=config.num_attention_heads, - kernel_initializer=get_initializer(config.initializer_range), - use_bias=False, - name="rel_pos_x_bias", - ) - self.rel_pos_y_bias = keras.layers.Dense( - units=config.num_attention_heads, - kernel_initializer=get_initializer(config.initializer_range), - use_bias=False, - name="rel_pos_y_bias", - ) - - def relative_position_bucket(self, relative_positions: tf.Tensor, num_buckets: int, max_distance: int): - # the negative relative positions are assigned to the interval [0, num_buckets / 2] - # we deal with this by assigning absolute relative positions to the interval [0, num_buckets / 2] - # and then offsetting the positive relative positions by num_buckets / 2 at the end - num_buckets = num_buckets // 2 - buckets = tf.abs(relative_positions) - - # half of the buckets are for exact increments in positions - max_exact_buckets = num_buckets // 2 - is_small = buckets < max_exact_buckets - - # the other half of the buckets are for logarithmically bigger bins in positions up to max_distance - buckets_log_ratio = tf.math.log(tf.cast(buckets, tf.float32) / max_exact_buckets) - distance_log_ratio = math.log(max_distance / max_exact_buckets) - buckets_big_offset = ( - buckets_log_ratio / distance_log_ratio * (num_buckets - max_exact_buckets) - ) # scale is [0, num_buckets - max_exact_buckets] - buckets_big = max_exact_buckets + buckets_big_offset # scale is [max_exact_buckets, num_buckets] - buckets_big = tf.cast(buckets_big, buckets.dtype) - buckets_big = tf.minimum(buckets_big, num_buckets - 1) - - return (tf.cast(relative_positions > 0, buckets.dtype) * num_buckets) + tf.where( - is_small, buckets, buckets_big - ) - - def _cal_pos_emb( - self, - dense_layer: keras.layers.Dense, - position_ids: tf.Tensor, - num_buckets: int, - max_distance: int, - ): - rel_pos_matrix = tf.expand_dims(position_ids, axis=-2) - tf.expand_dims(position_ids, axis=-1) - rel_pos = self.relative_position_bucket(rel_pos_matrix, num_buckets, max_distance) - rel_pos_one_hot = tf.one_hot(rel_pos, depth=num_buckets, dtype=self.compute_dtype) - embedding = dense_layer(rel_pos_one_hot) - # batch_size, seq_length, seq_length, num_heads --> batch_size, num_heads, seq_length, seq_length - embedding = tf.transpose(embedding, [0, 3, 1, 2]) - embedding = tf.cast(embedding, dtype=self.compute_dtype) - return embedding - - def _cal_1d_pos_emb(self, position_ids: tf.Tensor): - return self._cal_pos_emb(self.rel_pos_bias, position_ids, self.rel_pos_bins, self.max_rel_pos) - - def _cal_2d_pos_emb(self, bbox: tf.Tensor): - position_coord_x = bbox[:, :, 0] # left - position_coord_y = bbox[:, :, 3] # bottom - rel_pos_x = self._cal_pos_emb( - self.rel_pos_x_bias, - position_coord_x, - self.rel_2d_pos_bins, - self.max_rel_2d_pos, - ) - rel_pos_y = self._cal_pos_emb( - self.rel_pos_y_bias, - position_coord_y, - self.rel_2d_pos_bins, - self.max_rel_2d_pos, - ) - rel_2d_pos = rel_pos_x + rel_pos_y - return rel_2d_pos - - def call( - self, - hidden_states: tf.Tensor, - bbox: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - position_ids: tf.Tensor | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor] | tuple[tf.Tensor, tf.Tensor] | tuple[tf.Tensor, tf.Tensor, tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - - rel_pos = self._cal_1d_pos_emb(position_ids) if self.has_relative_attention_bias else None - rel_2d_pos = self._cal_2d_pos_emb(bbox) if self.has_spatial_attention_bias else None - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_head_mask = head_mask[i] if head_mask is not None else None - - layer_outputs = layer_module( - hidden_states, - attention_mask, - layer_head_mask, - output_attentions, - rel_pos=rel_pos, - rel_2d_pos=rel_2d_pos, - training=training, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if return_dict: - return TFBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - ) - else: - return tuple( - value for value in [hidden_states, all_hidden_states, all_self_attentions] if value is not None - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rel_pos_bias", None) is not None: - with tf.name_scope(self.rel_pos_bias.name): - self.rel_pos_bias.build([None, None, self.rel_pos_bins]) - if getattr(self, "rel_pos_x_bias", None) is not None: - with tf.name_scope(self.rel_pos_x_bias.name): - self.rel_pos_x_bias.build([None, None, self.rel_2d_pos_bins]) - if getattr(self, "rel_pos_y_bias", None) is not None: - with tf.name_scope(self.rel_pos_y_bias.name): - self.rel_pos_y_bias.build([None, None, self.rel_2d_pos_bins]) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFLayoutLMv3MainLayer(keras.layers.Layer): - config_class = LayoutLMv3Config - - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - - self.config = config - - if config.text_embed: - self.embeddings = TFLayoutLMv3TextEmbeddings(config, name="embeddings") - - if config.visual_embed: - self.patch_embed = TFLayoutLMv3PatchEmbeddings(config, name="patch_embed") - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob, name="dropout") - - if config.has_relative_attention_bias or config.has_spatial_attention_bias: - image_size = config.input_size // config.patch_size - self.init_visual_bbox(image_size=(image_size, image_size)) - - self.norm = keras.layers.LayerNormalization(epsilon=1e-6, name="norm") - - self.encoder = TFLayoutLMv3Encoder(config, name="encoder") - - def build(self, input_shape=None): - if self.config.visual_embed: - image_size = self.config.input_size // self.config.patch_size - self.cls_token = self.add_weight( - shape=(1, 1, self.config.hidden_size), - initializer="zeros", - trainable=True, - dtype=tf.float32, - name="cls_token", - ) - self.pos_embed = self.add_weight( - shape=(1, image_size * image_size + 1, self.config.hidden_size), - initializer="zeros", - trainable=True, - dtype=tf.float32, - name="pos_embed", - ) - - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "patch_embed", None) is not None: - with tf.name_scope(self.patch_embed.name): - self.patch_embed.build(None) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "norm", None) is not None: - with tf.name_scope(self.norm.name): - self.norm.build([None, None, self.config.hidden_size]) - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings.word_embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.word_embeddings.weight = value - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer._prune_heads - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - def init_visual_bbox(self, image_size: tuple[int, int], max_len: int = 1000): - # We should not hardcode max_len to 1000, but it is done by the reference implementation, - # so we keep it for compatibility with the pretrained weights. The more correct approach - # would have been to pass on max_len=config.max_2d_position_embeddings - 1. - height, width = image_size - - visual_bbox_x = tf.range(0, max_len * (width + 1), max_len) // width - visual_bbox_x = tf.expand_dims(visual_bbox_x, axis=0) - visual_bbox_x = tf.tile(visual_bbox_x, [width, 1]) # (width, width + 1) - - visual_bbox_y = tf.range(0, max_len * (height + 1), max_len) // height - visual_bbox_y = tf.expand_dims(visual_bbox_y, axis=1) - visual_bbox_y = tf.tile(visual_bbox_y, [1, height]) # (height + 1, height) - - visual_bbox = tf.stack( - [visual_bbox_x[:, :-1], visual_bbox_y[:-1], visual_bbox_x[:, 1:], visual_bbox_y[1:]], - axis=-1, - ) - visual_bbox = tf.reshape(visual_bbox, [-1, 4]) - - cls_token_box = tf.constant([[1, 1, max_len - 1, max_len - 1]], dtype=tf.int32) - self.visual_bbox = tf.concat([cls_token_box, visual_bbox], axis=0) - - def calculate_visual_bbox(self, batch_size: int, dtype: tf.DType): - visual_bbox = tf.expand_dims(self.visual_bbox, axis=0) - visual_bbox = tf.tile(visual_bbox, [batch_size, 1, 1]) - visual_bbox = tf.cast(visual_bbox, dtype=dtype) - return visual_bbox - - def embed_image(self, pixel_values: tf.Tensor) -> tf.Tensor: - embeddings = self.patch_embed(pixel_values) - - # add [CLS] token - batch_size = tf.shape(embeddings)[0] - cls_tokens = tf.tile(self.cls_token, [batch_size, 1, 1]) - embeddings = tf.concat([cls_tokens, embeddings], axis=1) - - # add position embeddings - if getattr(self, "pos_embed", None) is not None: - embeddings += self.pos_embed - - embeddings = self.norm(embeddings) - return embeddings - - def get_extended_attention_mask(self, attention_mask: tf.Tensor) -> tf.Tensor: - # Adapted from transformers.modelling_utils.ModuleUtilsMixin.get_extended_attention_mask - - n_dims = len(attention_mask.shape) - - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - if n_dims == 3: - extended_attention_mask = tf.expand_dims(attention_mask, axis=1) - elif n_dims == 2: - # Provided a padding mask of dimensions [batch_size, seq_length]. - # Make the mask broadcastable to [batch_size, num_heads, seq_length, seq_length]. - extended_attention_mask = tf.expand_dims(attention_mask, axis=1) # (batch_size, 1, seq_length) - extended_attention_mask = tf.expand_dims(extended_attention_mask, axis=1) # (batch_size, 1, 1, seq_length) - else: - raise ValueError(f"Wrong shape for attention_mask (shape {attention_mask.shape}).") - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, self.compute_dtype) - extended_attention_mask = (1.0 - extended_attention_mask) * LARGE_NEGATIVE - - return extended_attention_mask - - def get_head_mask(self, head_mask: tf.Tensor | None) -> tf.Tensor | list[tf.Tensor | None]: - if head_mask is None: - return [None] * self.config.num_hidden_layers - - n_dims = tf.rank(head_mask) - if n_dims == 1: - # Gets a tensor with masks for each head (H). - head_mask = tf.expand_dims(head_mask, axis=0) # 1, num_heads - head_mask = tf.expand_dims(head_mask, axis=0) # 1, 1, num_heads - head_mask = tf.expand_dims(head_mask, axis=-1) # 1, 1, num_heads, 1 - head_mask = tf.expand_dims(head_mask, axis=-1) # 1, 1, num_heads, 1, 1 - head_mask = tf.tile( - head_mask, [self.config.num_hidden_layers, 1, 1, 1, 1] - ) # seq_length, 1, num_heads, 1, 1 - elif n_dims == 2: - # Gets a tensor with masks for each layer (L) and head (H). - head_mask = tf.expand_dims(head_mask, axis=1) # seq_length, 1, num_heads - head_mask = tf.expand_dims(head_mask, axis=-1) # seq_length, 1, num_heads, 1 - head_mask = tf.expand_dims(head_mask, axis=-1) # seq_length, 1, num_heads, 1, 1 - elif n_dims != 5: - raise ValueError(f"Wrong shape for head_mask (shape {head_mask.shape}).") - assert tf.rank(head_mask) == 5, f"Got head_mask rank of {tf.rank(head_mask)}, but require 5." - head_mask = tf.cast(head_mask, self.compute_dtype) - return head_mask - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - bbox: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - pixel_values: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor] | tuple[tf.Tensor, tf.Tensor] | tuple[tf.Tensor, tf.Tensor, tf.Tensor]: - # This method can be called with a variety of modalities: - # 1. text + layout - # 2. text + layout + image - # 3. image - # The complexity of this method is mostly just due to handling of these different modalities. - - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if input_ids is not None: - input_shape = tf.shape(input_ids) - batch_size = input_shape[0] - seq_length = input_shape[1] - elif inputs_embeds is not None: - input_shape = tf.shape(inputs_embeds) - batch_size = input_shape[0] - seq_length = input_shape[1] - elif pixel_values is not None: - batch_size = tf.shape(pixel_values)[0] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds or pixel_values") - - # Determine which integer dtype to use. - if input_ids is not None: - int_dtype = input_ids.dtype - elif bbox is not None: - int_dtype = bbox.dtype - elif attention_mask is not None: - int_dtype = attention_mask.dtype - elif token_type_ids is not None: - int_dtype = token_type_ids.dtype - else: - int_dtype = tf.int32 - - if input_ids is not None or inputs_embeds is not None: - if attention_mask is None: - attention_mask = tf.ones((batch_size, seq_length), dtype=int_dtype) - if token_type_ids is None: - token_type_ids = tf.zeros((batch_size, seq_length), dtype=int_dtype) - if bbox is None: - bbox = tf.zeros((batch_size, seq_length, 4), dtype=int_dtype) - - embedding_output = self.embeddings( - input_ids=input_ids, - bbox=bbox, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - training=training, - ) - - final_bbox = None - final_position_ids = None - if pixel_values is not None: - # embed image - visual_embeddings = self.embed_image(pixel_values) - - # calculate attention mask - visual_attention_mask = tf.ones((batch_size, tf.shape(visual_embeddings)[1]), dtype=int_dtype) - if attention_mask is None: - attention_mask = visual_attention_mask - else: - attention_mask = tf.concat([attention_mask, visual_attention_mask], axis=1) - - # calculate bounding boxes - if self.config.has_spatial_attention_bias: - visual_bbox = self.calculate_visual_bbox(batch_size, int_dtype) - if bbox is None: - final_bbox = visual_bbox - else: - final_bbox = tf.concat([bbox, visual_bbox], axis=1) - - # calculate position IDs - if self.config.has_relative_attention_bias or self.config.has_spatial_attention_bias: - visual_position_ids = tf.range(0, tf.shape(visual_embeddings)[1], dtype=int_dtype) - visual_position_ids = tf.expand_dims(visual_position_ids, axis=0) - visual_position_ids = tf.tile(visual_position_ids, [batch_size, 1]) - - if input_ids is not None or inputs_embeds is not None: - position_ids = tf.expand_dims(tf.range(0, seq_length, dtype=int_dtype), axis=0) - position_ids = tf.tile(position_ids, [batch_size, 1]) - final_position_ids = tf.concat([position_ids, visual_position_ids], axis=1) - else: - final_position_ids = visual_position_ids - - # calculate embeddings - if input_ids is None and inputs_embeds is None: - embedding_output = visual_embeddings - else: - embedding_output = tf.concat([embedding_output, visual_embeddings], axis=1) - embedding_output = self.LayerNorm(embedding_output) - embedding_output = self.dropout(embedding_output, training=training) - - elif self.config.has_relative_attention_bias or self.config.has_spatial_attention_bias: - if self.config.has_relative_attention_bias: - position_ids = tf.expand_dims(tf.range(0, seq_length, dtype=int_dtype), axis=0) - position_ids = tf.tile(position_ids, [batch_size, 1]) - final_position_ids = position_ids - - if self.config.has_spatial_attention_bias: - final_bbox = bbox - - extended_attention_mask = self.get_extended_attention_mask(attention_mask) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape batch_size x num_heads x seq_length x seq_length - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - head_mask = self.get_head_mask(head_mask) - - encoder_outputs = self.encoder( - embedding_output, - bbox=final_bbox, - position_ids=final_position_ids, - attention_mask=extended_attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - sequence_output = encoder_outputs[0] - - if not return_dict: - return (sequence_output,) + encoder_outputs[1:] - - return TFBaseModelOutput( - last_hidden_state=sequence_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - return TFBaseModelOutput( - last_hidden_state=sequence_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - -class TFLayoutLMv3PreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = LayoutLMv3Config - base_model_prefix = "layoutlmv3" - - @property - def input_signature(self): - sig = super().input_signature - sig["bbox"] = tf.TensorSpec((None, None, 4), tf.int32, name="bbox") - return sig - - -LAYOUTLMV3_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`LayoutLMv3Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -LAYOUTLMV3_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. - - Note that `sequence_length = token_sequence_length + patch_sequence_length + 1` where `1` is for [CLS] - token. See `pixel_values` for `patch_sequence_length`. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - - bbox (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length, 4)`, *optional*): - Bounding boxes of each input sequence tokens. Selected in the range `[0, - config.max_2d_position_embeddings-1]`. Each bounding box should be a normalized version in (x0, y0, x1, y1) - format, where (x0, y0) corresponds to the position of the upper left corner in the bounding box, and (x1, - y1) represents the position of the lower right corner. - - Note that `sequence_length = token_sequence_length + patch_sequence_length + 1` where `1` is for [CLS] - token. See `pixel_values` for `patch_sequence_length`. - - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Batch of document images. Each image is divided into patches of shape `(num_channels, config.patch_size, - config.patch_size)` and the total number of patches (=`patch_sequence_length`) equals to `((height / - config.patch_size) * (width / config.patch_size))`. - - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - Note that `sequence_length = token_sequence_length + patch_sequence_length + 1` where `1` is for [CLS] - token. See `pixel_values` for `patch_sequence_length`. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - Note that `sequence_length = token_sequence_length + patch_sequence_length + 1` where `1` is for [CLS] - token. See `pixel_values` for `patch_sequence_length`. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - Note that `sequence_length = token_sequence_length + patch_sequence_length + 1` where `1` is for [CLS] - token. See `pixel_values` for `patch_sequence_length`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert *input_ids* indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@add_start_docstrings( - "The bare LayoutLMv3 Model transformer outputting raw hidden-states without any specific head on top.", - LAYOUTLMV3_START_DOCSTRING, -) -class TFLayoutLMv3Model(TFLayoutLMv3PreTrainedModel): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"position_ids"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.layoutlmv3 = TFLayoutLMv3MainLayer(config, name="layoutlmv3") - - @unpack_inputs - @add_start_docstrings_to_model_forward(LAYOUTLMV3_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBaseModelOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: tf.Tensor | None = None, - bbox: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - pixel_values: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor] | tuple[tf.Tensor, tf.Tensor] | tuple[tf.Tensor, tf.Tensor, tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoProcessor, TFAutoModel - >>> from datasets import load_dataset - - >>> processor = AutoProcessor.from_pretrained("microsoft/layoutlmv3-base", apply_ocr=False) - >>> model = TFAutoModel.from_pretrained("microsoft/layoutlmv3-base") - - >>> dataset = load_dataset("nielsr/funsd-layoutlmv3", split="train") - >>> example = dataset[0] - >>> image = example["image"] - >>> words = example["tokens"] - >>> boxes = example["bboxes"] - - >>> encoding = processor(image, words, boxes=boxes, return_tensors="tf") - - >>> outputs = model(**encoding) - >>> last_hidden_states = outputs.last_hidden_state - ```""" - - outputs = self.layoutlmv3( - input_ids=input_ids, - bbox=bbox, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layoutlmv3", None) is not None: - with tf.name_scope(self.layoutlmv3.name): - self.layoutlmv3.build(None) - - -class TFLayoutLMv3ClassificationHead(keras.layers.Layer): - """ - Head for sentence-level classification tasks. Reference: RobertaClassificationHead - """ - - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, - activation="tanh", - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout( - classifier_dropout, - name="dropout", - ) - self.out_proj = keras.layers.Dense( - config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="out_proj", - ) - self.config = config - - def call(self, inputs: tf.Tensor, training: bool = False) -> tf.Tensor: - outputs = self.dropout(inputs, training=training) - outputs = self.dense(outputs) - outputs = self.dropout(outputs, training=training) - outputs = self.out_proj(outputs) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - LayoutLMv3 Model with a sequence classification head on top (a linear layer on top of the final hidden state of the - [CLS] token) e.g. for document image classification tasks such as the - [RVL-CDIP](https://www.cs.cmu.edu/~aharley/rvl-cdip/) dataset. - """, - LAYOUTLMV3_START_DOCSTRING, -) -class TFLayoutLMv3ForSequenceClassification(TFLayoutLMv3PreTrainedModel, TFSequenceClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"position_ids"] - - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(config, **kwargs) - self.config = config - self.layoutlmv3 = TFLayoutLMv3MainLayer(config, name="layoutlmv3") - self.classifier = TFLayoutLMv3ClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(LAYOUTLMV3_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSequenceClassifierOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - labels: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - bbox: tf.Tensor | None = None, - pixel_values: tf.Tensor | None = None, - training: bool | None = False, - ) -> ( - TFSequenceClassifierOutput - | tuple[tf.Tensor] - | tuple[tf.Tensor, tf.Tensor] - | tuple[tf.Tensor, tf.Tensor, tf.Tensor] - | tuple[tf.Tensor, tf.Tensor, tf.Tensor, tf.Tensor] - ): - """ - Returns: - - Examples: - - ```python - >>> from transformers import AutoProcessor, TFAutoModelForSequenceClassification - >>> from datasets import load_dataset - >>> import tensorflow as tf - - >>> processor = AutoProcessor.from_pretrained("microsoft/layoutlmv3-base", apply_ocr=False) - >>> model = TFAutoModelForSequenceClassification.from_pretrained("microsoft/layoutlmv3-base") - - >>> dataset = load_dataset("nielsr/funsd-layoutlmv3", split="train") - >>> example = dataset[0] - >>> image = example["image"] - >>> words = example["tokens"] - >>> boxes = example["bboxes"] - - >>> encoding = processor(image, words, boxes=boxes, return_tensors="tf") - >>> sequence_label = tf.convert_to_tensor([1]) - - >>> outputs = model(**encoding, labels=sequence_label) - >>> loss = outputs.loss - >>> logits = outputs.logits - ```""" - - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.layoutlmv3( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - bbox=bbox, - pixel_values=pixel_values, - training=training, - ) - sequence_output = outputs[0][:, 0, :] - logits = self.classifier(sequence_output, training=training) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layoutlmv3", None) is not None: - with tf.name_scope(self.layoutlmv3.name): - self.layoutlmv3.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - LayoutLMv3 Model with a token classification head on top (a linear layer on top of the final hidden states) e.g. - for sequence labeling (information extraction) tasks such as [FUNSD](https://guillaumejaume.github.io/FUNSD/), - [SROIE](https://rrc.cvc.uab.es/?ch=13), [CORD](https://github.com/clovaai/cord) and - [Kleister-NDA](https://github.com/applicaai/kleister-nda). - """, - LAYOUTLMV3_START_DOCSTRING, -) -class TFLayoutLMv3ForTokenClassification(TFLayoutLMv3PreTrainedModel, TFTokenClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"position_ids"] - - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(config, **kwargs) - self.num_labels = config.num_labels - - self.layoutlmv3 = TFLayoutLMv3MainLayer(config, name="layoutlmv3") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob, name="dropout") - if config.num_labels < 10: - self.classifier = keras.layers.Dense( - config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - else: - self.classifier = TFLayoutLMv3ClassificationHead(config, name="classifier") - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(LAYOUTLMV3_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFTokenClassifierOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: tf.Tensor | None = None, - bbox: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - labels: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - pixel_values: tf.Tensor | None = None, - training: bool | None = False, - ) -> ( - TFTokenClassifierOutput - | tuple[tf.Tensor] - | tuple[tf.Tensor, tf.Tensor] - | tuple[tf.Tensor, tf.Tensor, tf.Tensor] - | tuple[tf.Tensor, tf.Tensor, tf.Tensor, tf.Tensor] - ): - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - - Returns: - - Examples: - - ```python - >>> from transformers import AutoProcessor, TFAutoModelForTokenClassification - >>> from datasets import load_dataset - - >>> processor = AutoProcessor.from_pretrained("microsoft/layoutlmv3-base", apply_ocr=False) - >>> model = TFAutoModelForTokenClassification.from_pretrained("microsoft/layoutlmv3-base", num_labels=7) - - >>> dataset = load_dataset("nielsr/funsd-layoutlmv3", split="train") - >>> example = dataset[0] - >>> image = example["image"] - >>> words = example["tokens"] - >>> boxes = example["bboxes"] - >>> word_labels = example["ner_tags"] - - >>> encoding = processor(image, words, boxes=boxes, word_labels=word_labels, return_tensors="tf") - - >>> outputs = model(**encoding) - >>> loss = outputs.loss - >>> logits = outputs.logits - ```""" - - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.layoutlmv3( - input_ids, - bbox=bbox, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - pixel_values=pixel_values, - training=training, - ) - if input_ids is not None: - input_shape = tf.shape(input_ids) - else: - input_shape = tf.shape(inputs_embeds)[:-1] - - seq_length = input_shape[1] - # only take the text part of the output representations - sequence_output = outputs[0][:, :seq_length] - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layoutlmv3", None) is not None: - with tf.name_scope(self.layoutlmv3.name): - self.layoutlmv3.build(None) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - LayoutLMv3 Model with a span classification head on top for extractive question-answering tasks such as - [DocVQA](https://rrc.cvc.uab.es/?ch=17) (a linear layer on top of the text part of the hidden-states output to - compute `span start logits` and `span end logits`). - """, - LAYOUTLMV3_START_DOCSTRING, -) -class TFLayoutLMv3ForQuestionAnswering(TFLayoutLMv3PreTrainedModel, TFQuestionAnsweringLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"position_ids"] - - def __init__(self, config: LayoutLMv3Config, **kwargs): - super().__init__(config, **kwargs) - - self.num_labels = config.num_labels - - self.layoutlmv3 = TFLayoutLMv3MainLayer(config, name="layoutlmv3") - self.qa_outputs = TFLayoutLMv3ClassificationHead(config, name="qa_outputs") - - @unpack_inputs - @add_start_docstrings_to_model_forward(LAYOUTLMV3_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFQuestionAnsweringModelOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - start_positions: tf.Tensor | None = None, - end_positions: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - bbox: tf.Tensor | None = None, - pixel_values: tf.Tensor | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> ( - TFQuestionAnsweringModelOutput - | tuple[tf.Tensor] - | tuple[tf.Tensor, tf.Tensor] - | tuple[tf.Tensor, tf.Tensor, tf.Tensor] - | tuple[tf.Tensor, tf.Tensor, tf.Tensor, tf.Tensor] - ): - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - - Returns: - - Examples: - - ```python - >>> from transformers import AutoProcessor, TFAutoModelForQuestionAnswering - >>> from datasets import load_dataset - >>> import tensorflow as tf - - >>> processor = AutoProcessor.from_pretrained("microsoft/layoutlmv3-base", apply_ocr=False) - >>> model = TFAutoModelForQuestionAnswering.from_pretrained("microsoft/layoutlmv3-base") - - >>> dataset = load_dataset("nielsr/funsd-layoutlmv3", split="train") - >>> example = dataset[0] - >>> image = example["image"] - >>> question = "what's his name?" - >>> words = example["tokens"] - >>> boxes = example["bboxes"] - - >>> encoding = processor(image, question, words, boxes=boxes, return_tensors="tf") - >>> start_positions = tf.convert_to_tensor([1]) - >>> end_positions = tf.convert_to_tensor([3]) - - >>> outputs = model(**encoding, start_positions=start_positions, end_positions=end_positions) - >>> loss = outputs.loss - >>> start_scores = outputs.start_logits - >>> end_scores = outputs.end_logits - ```""" - - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.layoutlmv3( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - bbox=bbox, - pixel_values=pixel_values, - training=training, - ) - - sequence_output = outputs[0] - - logits = self.qa_outputs(sequence_output, training=training) - start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) - start_logits = tf.squeeze(input=start_logits, axis=-1) - end_logits = tf.squeeze(input=end_logits, axis=-1) - - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions, "end_position": end_positions} - loss = self.hf_compute_loss(labels, logits=(start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layoutlmv3", None) is not None: - with tf.name_scope(self.layoutlmv3.name): - self.layoutlmv3.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build(None) - - -__all__ = [ - "TFLayoutLMv3ForQuestionAnswering", - "TFLayoutLMv3ForSequenceClassification", - "TFLayoutLMv3ForTokenClassification", - "TFLayoutLMv3Model", - "TFLayoutLMv3PreTrainedModel", -] diff --git a/src/transformers/models/layoutlmv3/tokenization_layoutlmv3.py b/src/transformers/models/layoutlmv3/tokenization_layoutlmv3.py index b69fc57b1743..fdf95a34d58d 100644 --- a/src/transformers/models/layoutlmv3/tokenization_layoutlmv3.py +++ b/src/transformers/models/layoutlmv3/tokenization_layoutlmv3.py @@ -85,7 +85,6 @@ return_tensors (`str` or [`~file_utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. """ @@ -134,7 +133,6 @@ return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. """ diff --git a/src/transformers/models/layoutxlm/tokenization_layoutxlm.py b/src/transformers/models/layoutxlm/tokenization_layoutxlm.py index 3dbe3c21a636..9c1d5c05a9f9 100644 --- a/src/transformers/models/layoutxlm/tokenization_layoutxlm.py +++ b/src/transformers/models/layoutxlm/tokenization_layoutxlm.py @@ -84,7 +84,6 @@ return_tensors (`str` or [`~file_utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. return_token_type_ids (`bool`, *optional*): diff --git a/src/transformers/models/layoutxlm/tokenization_layoutxlm_fast.py b/src/transformers/models/layoutxlm/tokenization_layoutxlm_fast.py index 6710c6c8cb66..7b08a3aa5f0e 100644 --- a/src/transformers/models/layoutxlm/tokenization_layoutxlm_fast.py +++ b/src/transformers/models/layoutxlm/tokenization_layoutxlm_fast.py @@ -86,7 +86,6 @@ return_tensors (`str` or [`~file_utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. return_token_type_ids (`bool`, *optional*): diff --git a/src/transformers/models/led/__init__.py b/src/transformers/models/led/__init__.py index 786ebd36d7b8..678b3af02aaf 100644 --- a/src/transformers/models/led/__init__.py +++ b/src/transformers/models/led/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_led import * from .modeling_led import * - from .modeling_tf_led import * from .tokenization_led import * from .tokenization_led_fast import * else: diff --git a/src/transformers/models/led/modeling_tf_led.py b/src/transformers/models/led/modeling_tf_led.py deleted file mode 100644 index f499ffac30c9..000000000000 --- a/src/transformers/models/led/modeling_tf_led.py +++ /dev/null @@ -1,2663 +0,0 @@ -# coding=utf-8 -# Copyright 2021 Iz Beltagy, Matthew E. Peters, Arman Cohan and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 LED model.""" - -from __future__ import annotations - -import random -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import TFBaseModelOutputWithPastAndCrossAttentions - -# Public API -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_led import LEDConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "allenai/led-base-16384" -_CONFIG_FOR_DOC = "LEDConfig" - - -LARGE_NEGATIVE = -1e8 - - -# Copied from transformers.models.bart.modeling_tf_bart.shift_tokens_right -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): - pad_token_id = tf.cast(pad_token_id, input_ids.dtype) - decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) - start_tokens = tf.fill( - (shape_list(input_ids)[0], 1), tf.convert_to_tensor(decoder_start_token_id, input_ids.dtype) - ) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.fill(shape_list(shifted_input_ids), tf.convert_to_tensor(pad_token_id, input_ids.dtype)), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE - mask_cond = tf.range(shape_list(mask)[-1]) - - mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -class TFLEDLearnedPositionalEmbedding(keras.layers.Embedding): - """ - This module learns positional embeddings up to a fixed maximum size. - """ - - def __init__(self, num_embeddings: int, embedding_dim: int, **kwargs): - super().__init__(num_embeddings, embedding_dim, **kwargs) - - def call(self, input_shape: tf.TensorShape, past_key_values_length: int = 0): - """Input is expected to be of size [bsz x seqlen].""" - seq_len = input_shape[1] - position_ids = tf.range(seq_len, delta=1, name="range") - position_ids += past_key_values_length - - return super().call(tf.cast(position_ids, dtype=tf.int32)) - - -# Copied from transformers.models.longformer.modeling_tf_longformer.TFLongformerSelfAttention with TFLongformer->TFLEDEncoder -class TFLEDEncoderSelfAttention(keras.layers.Layer): - def __init__(self, config, layer_id, **kwargs): - super().__init__(**kwargs) - self.config = config - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " - f"heads ({config.num_attention_heads}" - ) - - self.num_heads = config.num_attention_heads - self.head_dim = int(config.hidden_size / config.num_attention_heads) - self.embed_dim = config.hidden_size - self.query = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="query", - ) - self.key = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="key", - ) - self.value = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="value", - ) - - # separate projection layers for tokens with global attention - self.query_global = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="query_global", - ) - self.key_global = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="key_global", - ) - self.value_global = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="value_global", - ) - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.global_dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.layer_id = layer_id - attention_window = config.attention_window[self.layer_id] - - assert attention_window % 2 == 0, ( - f"`attention_window` for layer {self.layer_id} has to be an even value. Given {attention_window}" - ) - assert attention_window > 0, ( - f"`attention_window` for layer {self.layer_id} has to be positive. Given {attention_window}" - ) - - self.one_sided_attn_window_size = attention_window // 2 - - def build(self, input_shape=None): - if not self.built: - with tf.name_scope("query_global"): - self.query_global.build((self.config.hidden_size,)) - with tf.name_scope("key_global"): - self.key_global.build((self.config.hidden_size,)) - with tf.name_scope("value_global"): - self.value_global.build((self.config.hidden_size,)) - - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - if getattr(self, "query_global", None) is not None: - with tf.name_scope(self.query_global.name): - self.query_global.build([None, None, self.config.hidden_size]) - if getattr(self, "key_global", None) is not None: - with tf.name_scope(self.key_global.name): - self.key_global.build([None, None, self.config.hidden_size]) - if getattr(self, "value_global", None) is not None: - with tf.name_scope(self.value_global.name): - self.value_global.build([None, None, self.config.hidden_size]) - - def call( - self, - inputs, - training=False, - ): - """ - LongformerSelfAttention expects *len(hidden_states)* to be multiple of *attention_window*. Padding to - *attention_window* happens in LongformerModel.forward to avoid redoing the padding on each layer. - - The *attention_mask* is changed in [`LongformerModel.forward`] from 0, 1, 2 to: - - - -10000: no attention - - 0: local attention - - +10000: global attention - """ - # retrieve input args - ( - hidden_states, - attention_mask, - layer_head_mask, - is_index_masked, - is_index_global_attn, - is_global_attn, - ) = inputs - - # project hidden states - query_vectors = self.query(hidden_states) - key_vectors = self.key(hidden_states) - value_vectors = self.value(hidden_states) - batch_size, seq_len, embed_dim = shape_list(hidden_states) - - tf.debugging.assert_equal( - embed_dim, - self.embed_dim, - message=f"hidden_states should have embed_dim = {self.embed_dim}, but has {embed_dim}", - ) - - # normalize query - query_vectors /= tf.math.sqrt(tf.cast(self.head_dim, dtype=query_vectors.dtype)) - query_vectors = tf.reshape(query_vectors, (batch_size, seq_len, self.num_heads, self.head_dim)) - key_vectors = tf.reshape(key_vectors, (batch_size, seq_len, self.num_heads, self.head_dim)) - - # attn_probs = (batch_size, seq_len, num_heads, window*2+1) - attn_scores = self._sliding_chunks_query_key_matmul( - query_vectors, key_vectors, self.one_sided_attn_window_size - ) - - # values to pad for attention probs - remove_from_windowed_attention_mask = attention_mask != 0 - # cast to fp32/fp16 then replace 1's with -inf - float_mask = tf.cast(remove_from_windowed_attention_mask, dtype=query_vectors.dtype) * LARGE_NEGATIVE - - # diagonal mask with zeros everywhere and -inf inplace of padding - diagonal_mask = self._sliding_chunks_query_key_matmul( - tf.ones(shape_list(attention_mask)), - float_mask, - self.one_sided_attn_window_size, - ) - - # pad local attention probs - attn_scores += diagonal_mask - - tf.debugging.assert_equal( - shape_list(attn_scores), - [batch_size, seq_len, self.num_heads, self.one_sided_attn_window_size * 2 + 1], - message=( - f"attn_probs should be of size ({batch_size}, {seq_len}, {self.num_heads}," - f" {self.one_sided_attn_window_size * 2 + 1}), but is of size {shape_list(attn_scores)}" - ), - ) - - # compute global attn indices required through out forward fn - ( - max_num_global_attn_indices, - is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero, - ) = self._get_global_attn_indices(is_index_global_attn) - - # this function is only relevant for global attention - if is_global_attn: - attn_scores = self._concat_with_global_key_attn_probs( - attn_scores=attn_scores, - query_vectors=query_vectors, - key_vectors=key_vectors, - max_num_global_attn_indices=max_num_global_attn_indices, - is_index_global_attn_nonzero=is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero=is_local_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero=is_local_index_no_global_attn_nonzero, - ) - - attn_probs = stable_softmax(attn_scores, axis=-1) - - # softmax sometimes inserts NaN if all positions are masked, replace them with 0 - # Make sure to create a mask with the proper shape: - # if is_global_attn==True => [batch_size, seq_len, self.num_heads, self.one_sided_attn_window_size * 2 + max_num_global_attn_indices + 1] - # if is_global_attn==False => [batch_size, seq_len, self.num_heads, self.one_sided_attn_window_size * 2 + 1] - if is_global_attn: - masked_index = tf.tile( - is_index_masked[:, :, None, None], - (1, 1, self.num_heads, self.one_sided_attn_window_size * 2 + max_num_global_attn_indices + 1), - ) - else: - masked_index = tf.tile( - is_index_masked[:, :, None, None], - (1, 1, self.num_heads, self.one_sided_attn_window_size * 2 + 1), - ) - attn_probs = tf.where( - masked_index, - tf.zeros(shape_list(masked_index), dtype=attn_probs.dtype), - attn_probs, - ) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_probs = tf.reshape(layer_head_mask, (1, 1, -1, 1)) * attn_probs - - # apply dropout - attn_probs = self.dropout(attn_probs, training=training) - value_vectors = tf.reshape(value_vectors, (batch_size, seq_len, self.num_heads, self.head_dim)) - - # if global attention, compute sum of global and local attn - - if is_global_attn: - attn_output = self._compute_attn_output_with_global_indices( - value_vectors=value_vectors, - attn_probs=attn_probs, - max_num_global_attn_indices=max_num_global_attn_indices, - is_index_global_attn_nonzero=is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero=is_local_index_global_attn_nonzero, - ) - else: - attn_output = self._sliding_chunks_matmul_attn_probs_value( - attn_probs, value_vectors, self.one_sided_attn_window_size - ) - - tf.debugging.assert_equal( - shape_list(attn_output), [batch_size, seq_len, self.num_heads, self.head_dim], message="Unexpected size" - ) - - attn_output = tf.reshape(attn_output, (batch_size, seq_len, embed_dim)) - - # compute value for global attention and overwrite to attention output - if is_global_attn: - attn_output, global_attn_probs = self._compute_global_attn_output_from_hidden( - attn_output=attn_output, - hidden_states=hidden_states, - max_num_global_attn_indices=max_num_global_attn_indices, - layer_head_mask=layer_head_mask, - is_local_index_global_attn_nonzero=is_local_index_global_attn_nonzero, - is_index_global_attn_nonzero=is_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero=is_local_index_no_global_attn_nonzero, - is_index_masked=is_index_masked, - training=training, - ) - else: - # Leave attn_output unchanged - global_attn_probs = tf.zeros((batch_size, self.num_heads, max_num_global_attn_indices, seq_len)) - - # make sure that local attention probabilities are set to 0 for indices of global attn - # Make sure to create a mask with the proper shape: - # if is_global_attn==True => [batch_size, seq_len, self.num_heads, self.one_sided_attn_window_size * 2 + max_num_global_attn_indices + 1] - # if is_global_attn==False => [batch_size, seq_len, self.num_heads, self.one_sided_attn_window_size * 2 + 1] - if is_global_attn: - masked_global_attn_index = tf.tile( - is_index_global_attn[:, :, None, None], - (1, 1, self.num_heads, self.one_sided_attn_window_size * 2 + max_num_global_attn_indices + 1), - ) - else: - masked_global_attn_index = tf.tile( - is_index_global_attn[:, :, None, None], - (1, 1, self.num_heads, self.one_sided_attn_window_size * 2 + 1), - ) - attn_probs = tf.where( - masked_global_attn_index, - tf.zeros(shape_list(masked_global_attn_index), dtype=attn_probs.dtype), - attn_probs, - ) - - outputs = (attn_output, attn_probs, global_attn_probs) - - return outputs - - def _sliding_chunks_query_key_matmul(self, query, key, window_overlap): - """ - Matrix multiplication of query and key tensors using with a sliding window attention pattern. This - implementation splits the input into overlapping chunks of size 2w (e.g. 512 for pretrained Longformer) with an - overlap of size window_overlap - """ - batch_size, seq_len, num_heads, head_dim = shape_list(query) - - tf.debugging.assert_equal( - seq_len % (window_overlap * 2), - 0, - message=f"Sequence length should be multiple of {window_overlap * 2}. Given {seq_len}", - ) - tf.debugging.assert_equal( - shape_list(query), - shape_list(key), - message=( - f"Shape of query and key should be equal, but got query: {shape_list(query)} and key:" - f" {shape_list(key)}" - ), - ) - - chunks_count = seq_len // window_overlap - 1 - - # group batch_size and num_heads dimensions into one, then chunk seq_len into chunks of size window_overlap * 2 - query = tf.reshape( - tf.transpose(query, (0, 2, 1, 3)), - (batch_size * num_heads, seq_len, head_dim), - ) - key = tf.reshape(tf.transpose(key, (0, 2, 1, 3)), (batch_size * num_heads, seq_len, head_dim)) - chunked_query = self._chunk(query, window_overlap) - chunked_key = self._chunk(key, window_overlap) - - # matrix multiplication - # bcxd: batch_size * num_heads x chunks x 2window_overlap x head_dim - # bcyd: batch_size * num_heads x chunks x 2window_overlap x head_dim - # bcxy: batch_size * num_heads x chunks x 2window_overlap x 2window_overlap - chunked_query = tf.cast(chunked_query, dtype=chunked_key.dtype) - chunked_attention_scores = tf.einsum("bcxd,bcyd->bcxy", chunked_query, chunked_key) # multiply - - # convert diagonals into columns - paddings = tf.convert_to_tensor([[0, 0], [0, 0], [0, 1], [0, 0]]) - diagonal_chunked_attention_scores = self._pad_and_transpose_last_two_dims(chunked_attention_scores, paddings) - - # allocate space for the overall attention matrix where the chunks are combined. The last dimension - # has (window_overlap * 2 + 1) columns. The first (window_overlap) columns are the window_overlap lower triangles (attention from a word to - # window_overlap previous words). The following column is attention score from each word to itself, then - # followed by window_overlap columns for the upper triangle. - - # copy parts from diagonal_chunked_attention_scores into the combined matrix of attentions - # - copying the main diagonal and the upper triangle - # TODO: This code is most likely not very efficient and should be improved - diagonal_attn_scores_up_triang = tf.concat( - [ - diagonal_chunked_attention_scores[:, :, :window_overlap, : window_overlap + 1], - diagonal_chunked_attention_scores[:, -1:, window_overlap:, : window_overlap + 1], - ], - axis=1, - ) - - # - copying the lower triangle - diagonal_attn_scores_low_triang = tf.concat( - [ - tf.zeros( - (batch_size * num_heads, 1, window_overlap, window_overlap), - dtype=diagonal_chunked_attention_scores.dtype, - ), - diagonal_chunked_attention_scores[:, :, -(window_overlap + 1) : -1, window_overlap + 1 :], - ], - axis=1, - ) - diagonal_attn_scores_first_chunk = tf.concat( - [ - tf.roll( - diagonal_chunked_attention_scores, - shift=[1, window_overlap], - axis=[2, 3], - )[:, :, :window_overlap, :window_overlap], - tf.zeros( - (batch_size * num_heads, 1, window_overlap, window_overlap), - dtype=diagonal_chunked_attention_scores.dtype, - ), - ], - axis=1, - ) - first_chunk_mask = ( - tf.tile( - tf.range(chunks_count + 1, dtype=tf.int64)[None, :, None, None], - (batch_size * num_heads, 1, window_overlap, window_overlap), - ) - < 1 - ) - diagonal_attn_scores_low_triang = tf.where( - first_chunk_mask, - diagonal_attn_scores_first_chunk, - diagonal_attn_scores_low_triang, - ) - - # merging upper and lower triangle - diagonal_attention_scores = tf.concat( - [diagonal_attn_scores_low_triang, diagonal_attn_scores_up_triang], axis=-1 - ) - - # separate batch_size and num_heads dimensions again - diagonal_attention_scores = tf.transpose( - tf.reshape( - diagonal_attention_scores, - (batch_size, num_heads, seq_len, 2 * window_overlap + 1), - ), - (0, 2, 1, 3), - ) - - diagonal_attention_scores = self._mask_invalid_locations(diagonal_attention_scores, window_overlap) - - return diagonal_attention_scores - - @staticmethod - def _mask_invalid_locations(input_tensor, window_overlap): - # create correct upper triangle bool mask - mask_2d_upper = tf.reverse( - tf.linalg.band_part(tf.ones(shape=(window_overlap, window_overlap + 1)), -1, 0), - axis=[0], - ) - - # pad to full matrix - padding = tf.convert_to_tensor( - [[0, shape_list(input_tensor)[1] - window_overlap], [0, shape_list(input_tensor)[3] - window_overlap - 1]] - ) - - # create lower mask - mask_2d = tf.pad(mask_2d_upper, padding) - - # combine with upper mask - mask_2d = mask_2d + tf.reverse(mask_2d, axis=[0, 1]) - - # broadcast to full matrix - mask_4d = tf.tile(mask_2d[None, :, None, :], (shape_list(input_tensor)[0], 1, 1, 1)) - - # inf tensor used for masking - inf_tensor = -float("inf") * tf.ones_like(input_tensor) - - # mask - input_tensor = tf.where(tf.math.greater(mask_4d, 0), inf_tensor, input_tensor) - - return input_tensor - - def _sliding_chunks_matmul_attn_probs_value(self, attn_probs, value, window_overlap): - """ - Same as _sliding_chunks_query_key_matmul but for attn_probs and value tensors. Returned tensor will be of the - same shape as `attn_probs` - """ - - batch_size, seq_len, num_heads, head_dim = shape_list(value) - - tf.debugging.assert_equal( - seq_len % (window_overlap * 2), 0, message="Seq_len has to be multiple of 2 * window_overlap" - ) - tf.debugging.assert_equal( - shape_list(attn_probs)[:3], - shape_list(value)[:3], - message="value and attn_probs must have same dims (except head_dim)", - ) - tf.debugging.assert_equal( - shape_list(attn_probs)[3], - 2 * window_overlap + 1, - message="attn_probs last dim has to be 2 * window_overlap + 1", - ) - - chunks_count = seq_len // window_overlap - 1 - - # group batch_size and num_heads dimensions into one, then chunk seq_len into chunks of size 2 window overlap - chunked_attn_probs = tf.reshape( - tf.transpose(attn_probs, (0, 2, 1, 3)), - ( - batch_size * num_heads, - seq_len // window_overlap, - window_overlap, - 2 * window_overlap + 1, - ), - ) - - # group batch_size and num_heads dimensions into one - value = tf.reshape( - tf.transpose(value, (0, 2, 1, 3)), - (batch_size * num_heads, seq_len, head_dim), - ) - - # pad seq_len with w at the beginning of the sequence and another window overlap at the end - paddings = tf.convert_to_tensor([[0, 0], [window_overlap, window_overlap], [0, 0]]) - padded_value = tf.pad(value, paddings, constant_values=-1) - - # chunk padded_value into chunks of size 3 window overlap and an overlap of size window overlap - frame_size = 3 * window_overlap * head_dim - frame_hop_size = (shape_list(padded_value)[1] * head_dim - frame_size) // chunks_count - chunked_value = tf.signal.frame( - tf.reshape(padded_value, (batch_size * num_heads, -1)), - frame_size, - frame_hop_size, - ) - chunked_value = tf.reshape( - chunked_value, - (batch_size * num_heads, chunks_count + 1, 3 * window_overlap, head_dim), - ) - - tf.debugging.assert_equal( - shape_list(chunked_value), - [batch_size * num_heads, chunks_count + 1, 3 * window_overlap, head_dim], - message="Chunked value has the wrong shape", - ) - - chunked_attn_probs = self._pad_and_diagonalize(chunked_attn_probs) - context = tf.einsum("bcwd,bcdh->bcwh", chunked_attn_probs, chunked_value) - context = tf.transpose( - tf.reshape(context, (batch_size, num_heads, seq_len, head_dim)), - (0, 2, 1, 3), - ) - - return context - - @staticmethod - def _pad_and_transpose_last_two_dims(hidden_states_padded, paddings): - """pads rows and then flips rows and columns""" - hidden_states_padded = tf.pad( - hidden_states_padded, paddings - ) # padding value is not important because it will be overwritten - batch_size, chunk_size, seq_length, hidden_dim = shape_list(hidden_states_padded) - hidden_states_padded = tf.reshape(hidden_states_padded, (batch_size, chunk_size, hidden_dim, seq_length)) - - return hidden_states_padded - - @staticmethod - def _pad_and_diagonalize(chunked_hidden_states): - """ - shift every row 1 step right, converting columns into diagonals. - - Example: - - ```python - chunked_hidden_states: [ - 0.4983, - 2.6918, - -0.0071, - 1.0492, - -1.8348, - 0.7672, - 0.2986, - 0.0285, - -0.7584, - 0.4206, - -0.0405, - 0.1599, - 2.0514, - -1.1600, - 0.5372, - 0.2629, - ] - window_overlap = num_rows = 4 - ``` - - (pad & diagonalize) => [ 0.4983, 2.6918, -0.0071, 1.0492, 0.0000, 0.0000, 0.0000 - 0.0000, -1.8348, 0.7672, 0.2986, 0.0285, 0.0000, 0.0000 0.0000, 0.0000, -0.7584, 0.4206, - -0.0405, 0.1599, 0.0000 0.0000, 0.0000, 0.0000, 2.0514, -1.1600, 0.5372, 0.2629 ] - """ - total_num_heads, num_chunks, window_overlap, hidden_dim = shape_list(chunked_hidden_states) - paddings = tf.convert_to_tensor([[0, 0], [0, 0], [0, 0], [0, window_overlap + 1]]) - chunked_hidden_states = tf.pad( - chunked_hidden_states, paddings - ) # total_num_heads x num_chunks x window_overlap x (hidden_dim+window_overlap+1). Padding value is not important because it'll be overwritten - chunked_hidden_states = tf.reshape( - chunked_hidden_states, (total_num_heads, num_chunks, -1) - ) # total_num_heads x num_chunks x window_overlapL+window_overlapwindow_overlap+window_overlap - chunked_hidden_states = chunked_hidden_states[ - :, :, :-window_overlap - ] # total_num_heads x num_chunks x window_overlapL+window_overlapwindow_overlap - chunked_hidden_states = tf.reshape( - chunked_hidden_states, - (total_num_heads, num_chunks, window_overlap, window_overlap + hidden_dim), - ) # total_num_heads x num_chunks, window_overlap x hidden_dim+window_overlap - chunked_hidden_states = chunked_hidden_states[:, :, :, :-1] - - return chunked_hidden_states - - @staticmethod - def _chunk(hidden_states, window_overlap): - """convert into overlapping chunks. Chunk size = 2w, overlap size = w""" - batch_size, seq_length, hidden_dim = shape_list(hidden_states) - num_output_chunks = 2 * (seq_length // (2 * window_overlap)) - 1 - - # define frame size and frame stride (similar to convolution) - frame_hop_size = window_overlap * hidden_dim - frame_size = 2 * frame_hop_size - hidden_states = tf.reshape(hidden_states, (batch_size, seq_length * hidden_dim)) - - # chunk with overlap - chunked_hidden_states = tf.signal.frame(hidden_states, frame_size, frame_hop_size) - - tf.debugging.assert_equal( - shape_list(chunked_hidden_states), - [batch_size, num_output_chunks, frame_size], - message=( - "Make sure chunking is correctly applied. `Chunked hidden states should have output dimension" - f" {[batch_size, frame_size, num_output_chunks]}, but got {shape_list(chunked_hidden_states)}." - ), - ) - - chunked_hidden_states = tf.reshape( - chunked_hidden_states, - (batch_size, num_output_chunks, 2 * window_overlap, hidden_dim), - ) - - return chunked_hidden_states - - @staticmethod - def _get_global_attn_indices(is_index_global_attn): - """compute global attn indices required throughout forward pass""" - # helper variable - num_global_attn_indices = tf.math.count_nonzero(is_index_global_attn, axis=1) - num_global_attn_indices = tf.cast(num_global_attn_indices, dtype=tf.constant(1).dtype) - - # max number of global attn indices in batch - max_num_global_attn_indices = tf.reduce_max(num_global_attn_indices) - - # indices of global attn - is_index_global_attn_nonzero = tf.where(is_index_global_attn) - - # helper variable - is_local_index_global_attn = tf.range(max_num_global_attn_indices) < tf.expand_dims( - num_global_attn_indices, axis=-1 - ) - - # location of the non-padding values within global attention indices - is_local_index_global_attn_nonzero = tf.where(is_local_index_global_attn) - - # location of the padding values within global attention indices - is_local_index_no_global_attn_nonzero = tf.where(tf.math.logical_not(is_local_index_global_attn)) - - return ( - max_num_global_attn_indices, - is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero, - ) - - def _concat_with_global_key_attn_probs( - self, - attn_scores, - key_vectors, - query_vectors, - max_num_global_attn_indices, - is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero, - ): - batch_size = shape_list(key_vectors)[0] - - # select global key vectors - global_key_vectors = tf.gather_nd(key_vectors, is_index_global_attn_nonzero) - - # create only global key vectors - key_vectors_only_global = tf.scatter_nd( - is_local_index_global_attn_nonzero, - global_key_vectors, - shape=( - batch_size, - max_num_global_attn_indices, - self.num_heads, - self.head_dim, - ), - ) - - # (batch_size, seq_len, num_heads, max_num_global_attn_indices) - attn_probs_from_global_key = tf.einsum("blhd,bshd->blhs", query_vectors, key_vectors_only_global) - - # (batch_size, max_num_global_attn_indices, seq_len, num_heads) - attn_probs_from_global_key_trans = tf.transpose(attn_probs_from_global_key, (0, 3, 1, 2)) - mask_shape = (shape_list(is_local_index_no_global_attn_nonzero)[0],) + tuple( - shape_list(attn_probs_from_global_key_trans)[-2:] - ) - mask = tf.ones(mask_shape) * -10000.0 - mask = tf.cast(mask, dtype=attn_probs_from_global_key_trans.dtype) - - # scatter mask - attn_probs_from_global_key_trans = tf.tensor_scatter_nd_update( - attn_probs_from_global_key_trans, - is_local_index_no_global_attn_nonzero, - mask, - ) - - # (batch_size, seq_len, num_heads, max_num_global_attn_indices) - attn_probs_from_global_key = tf.transpose(attn_probs_from_global_key_trans, (0, 2, 3, 1)) - - # concat to attn_probs - # (batch_size, seq_len, num_heads, extra attention count + 2*window+1) - attn_scores = tf.concat((attn_probs_from_global_key, attn_scores), axis=-1) - - return attn_scores - - def _compute_attn_output_with_global_indices( - self, - value_vectors, - attn_probs, - max_num_global_attn_indices, - is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero, - ): - batch_size = shape_list(attn_probs)[0] - - # cut local attn probs to global only - attn_probs_only_global = attn_probs[:, :, :, :max_num_global_attn_indices] - - # select global value vectors - global_value_vectors = tf.gather_nd(value_vectors, is_index_global_attn_nonzero) - - # create only global value vectors - value_vectors_only_global = tf.scatter_nd( - is_local_index_global_attn_nonzero, - global_value_vectors, - shape=( - batch_size, - max_num_global_attn_indices, - self.num_heads, - self.head_dim, - ), - ) - - # compute attn output only global - attn_output_only_global = tf.einsum("blhs,bshd->blhd", attn_probs_only_global, value_vectors_only_global) - - # reshape attn probs - attn_probs_without_global = attn_probs[:, :, :, max_num_global_attn_indices:] - - # compute attn output with global - attn_output_without_global = self._sliding_chunks_matmul_attn_probs_value( - attn_probs_without_global, value_vectors, self.one_sided_attn_window_size - ) - - return attn_output_only_global + attn_output_without_global - - def _compute_global_attn_output_from_hidden( - self, - attn_output, - hidden_states, - max_num_global_attn_indices, - layer_head_mask, - is_local_index_global_attn_nonzero, - is_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero, - is_index_masked, - training, - ): - batch_size, seq_len = shape_list(hidden_states)[:2] - - # prepare global hidden states - global_attn_hidden_states = tf.gather_nd(hidden_states, is_index_global_attn_nonzero) - global_attn_hidden_states = tf.scatter_nd( - is_local_index_global_attn_nonzero, - global_attn_hidden_states, - shape=(batch_size, max_num_global_attn_indices, self.embed_dim), - ) - - # global key, query, value - global_query_vectors_only_global = self.query_global(global_attn_hidden_states) - global_key_vectors = self.key_global(hidden_states) - global_value_vectors = self.value_global(hidden_states) - - # normalize - global_query_vectors_only_global /= tf.math.sqrt( - tf.cast(self.head_dim, dtype=global_query_vectors_only_global.dtype) - ) - global_query_vectors_only_global = self.reshape_and_transpose(global_query_vectors_only_global, batch_size) - global_key_vectors = self.reshape_and_transpose(global_key_vectors, batch_size) - global_value_vectors = self.reshape_and_transpose(global_value_vectors, batch_size) - - # compute attn scores - global_attn_scores = tf.matmul(global_query_vectors_only_global, global_key_vectors, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(global_attn_scores), - [batch_size * self.num_heads, max_num_global_attn_indices, seq_len], - message=( - "global_attn_scores have the wrong size. Size should be" - f" {(batch_size * self.num_heads, max_num_global_attn_indices, seq_len)}, but is" - f" {shape_list(global_attn_scores)}." - ), - ) - - global_attn_scores = tf.reshape( - global_attn_scores, - (batch_size, self.num_heads, max_num_global_attn_indices, seq_len), - ) - global_attn_scores_trans = tf.transpose(global_attn_scores, (0, 2, 1, 3)) - mask_shape = (shape_list(is_local_index_no_global_attn_nonzero)[0],) + tuple( - shape_list(global_attn_scores_trans)[-2:] - ) - global_attn_mask = tf.ones(mask_shape) * -10000.0 - global_attn_mask = tf.cast(global_attn_mask, dtype=global_attn_scores_trans.dtype) - - # scatter mask - global_attn_scores_trans = tf.tensor_scatter_nd_update( - global_attn_scores_trans, - is_local_index_no_global_attn_nonzero, - global_attn_mask, - ) - global_attn_scores = tf.transpose(global_attn_scores_trans, (0, 2, 1, 3)) - - # mask global attn scores - attn_mask = tf.tile(is_index_masked[:, None, None, :], (1, shape_list(global_attn_scores)[1], 1, 1)) - global_attn_scores = tf.where(attn_mask, -10000.0, global_attn_scores) - global_attn_scores = tf.reshape( - global_attn_scores, - (batch_size * self.num_heads, max_num_global_attn_indices, seq_len), - ) - - # compute global attn probs - global_attn_probs_float = stable_softmax(global_attn_scores, axis=-1) - - # apply layer head masking - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - global_attn_probs_float = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - global_attn_probs_float, (batch_size, self.num_heads, max_num_global_attn_indices, seq_len) - ) - global_attn_probs_float = tf.reshape( - global_attn_probs_float, (batch_size * self.num_heads, max_num_global_attn_indices, seq_len) - ) - - # dropout - global_attn_probs = self.global_dropout(global_attn_probs_float, training=training) - - # global attn output - global_attn_output = tf.matmul(global_attn_probs, global_value_vectors) - - tf.debugging.assert_equal( - shape_list(global_attn_output), - [batch_size * self.num_heads, max_num_global_attn_indices, self.head_dim], - message=( - "global_attn_output tensor has the wrong size. Size should be" - f" {(batch_size * self.num_heads, max_num_global_attn_indices, self.head_dim)}, but is" - f" {shape_list(global_attn_output)}." - ), - ) - - global_attn_output = tf.reshape( - global_attn_output, - (batch_size, self.num_heads, max_num_global_attn_indices, self.head_dim), - ) - - # get only non zero global attn output - nonzero_global_attn_output = tf.gather_nd( - tf.transpose(global_attn_output, (0, 2, 1, 3)), - is_local_index_global_attn_nonzero, - ) - nonzero_global_attn_output = tf.reshape( - nonzero_global_attn_output, - (shape_list(is_local_index_global_attn_nonzero)[0], -1), - ) - - # overwrite values with global attention - attn_output = tf.tensor_scatter_nd_update( - attn_output, is_index_global_attn_nonzero, nonzero_global_attn_output - ) - - global_attn_probs = tf.reshape( - global_attn_probs, (batch_size, self.num_heads, max_num_global_attn_indices, seq_len) - ) - - return attn_output, global_attn_probs - - def reshape_and_transpose(self, vector, batch_size): - return tf.reshape( - tf.transpose( - tf.reshape(vector, (batch_size, -1, self.num_heads, self.head_dim)), - (0, 2, 1, 3), - ), - (batch_size * self.num_heads, -1, self.head_dim), - ) - - -class TFLEDEncoderAttention(keras.layers.Layer): - def __init__(self, config, layer_id, **kwargs): - super().__init__(**kwargs) - self.longformer_self_attn = TFLEDEncoderSelfAttention(config, layer_id=layer_id, name="longformer_self_attn") - self.output_dense = keras.layers.Dense(config.d_model, use_bias=True, name="output") - self.config = config - - def call(self, inputs, training=False): - ( - hidden_states, - attention_mask, - layer_head_mask, - is_index_masked, - is_index_global_attn, - is_global_attn, - ) = inputs - - self_outputs = self.longformer_self_attn( - [hidden_states, attention_mask, layer_head_mask, is_index_masked, is_index_global_attn, is_global_attn], - training=training, - ) - - attention_output = self.output_dense(self_outputs[0], training=training) - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "longformer_self_attn", None) is not None: - with tf.name_scope(self.longformer_self_attn.name): - self.longformer_self_attn.build(None) - if getattr(self, "output_dense", None) is not None: - with tf.name_scope(self.output_dense.name): - self.output_dense.build([None, None, self.config.d_model]) - - -class TFLEDDecoderAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - assert self.head_dim * num_heads == self.embed_dim, "embed_dim must be divisible by num_heads" - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training=False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + tf.cast( - attention_mask, dtype=attn_weights.dtype - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -class TFLEDEncoderLayer(keras.layers.Layer): - def __init__(self, config: LEDConfig, layer_id: int, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFLEDEncoderAttention(config, layer_id, name="self_attn") - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - self.fc1 = keras.layers.Dense(config.encoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - layer_head_mask: tf.Tensor, - is_index_masked: tf.Tensor, - is_index_global_attn: tf.Tensor, - is_global_attn: bool, - training=False, - ): - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape *(batch, seq_len, embed_dim)* - attention_mask (`tf.Tensor`): attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - *(config.encoder_attention_heads,)*. - """ - residual = hidden_states - layer_outputs = self.self_attn( - [hidden_states, attention_mask, layer_head_mask, is_index_masked, is_index_global_attn, is_global_attn], - training=training, - ) - - hidden_states = layer_outputs[0] - - tf.debugging.assert_equal( - shape_list(hidden_states), - shape_list(residual), - message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", - ) - - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - return (hidden_states,) + layer_outputs[1:] - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.encoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFLEDDecoderLayer(keras.layers.Layer): - def __init__(self, config: LEDConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFLEDDecoderAttention( - embed_dim=self.embed_dim, - num_heads=config.decoder_attention_heads, - dropout=config.attention_dropout, - name="self_attn", - is_decoder=True, - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.encoder_attn = TFLEDDecoderAttention( - self.embed_dim, - config.decoder_attention_heads, - dropout=config.attention_dropout, - name="encoder_attn", - is_decoder=True, - ) - self.encoder_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.decoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states, - attention_mask: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - encoder_layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tf.Tensor] | None = None, - training=False, - ) -> tuple[tf.Tensor, tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape *(batch, seq_len, embed_dim)* - attention_mask (`tf.Tensor`): attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - encoder_hidden_states (`tf.Tensor`): - cross attention input to the layer of shape *(batch, seq_len, embed_dim)* - encoder_attention_mask (`tf.Tensor`): encoder attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - *(config.encoder_attention_heads,)*. - encoder_layer_head_mask (`tf.Tensor`): mask for encoder attention heads in a given layer of - size *(config.encoder_attention_heads,)*. - past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states - """ - residual = hidden_states - - # Self-Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Cross-Attention Block - cross_attn_present_key_value = None - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - layer_head_mask=encoder_layer_head_mask, - past_key_value=cross_attn_past_key_value, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # add cross-attn to positions 3,4 of present_key_value tuple - present_key_value = present_key_value + cross_attn_present_key_value - - # Fully Connected - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - return ( - hidden_states, - self_attn_weights, - cross_attn_weights, - present_key_value, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "encoder_attn", None) is not None: - with tf.name_scope(self.encoder_attn.name): - self.encoder_attn.build(None) - if getattr(self, "encoder_attn_layer_norm", None) is not None: - with tf.name_scope(self.encoder_attn_layer_norm.name): - self.encoder_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.decoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFLEDPreTrainedModel(TFPreTrainedModel): - config_class = LEDConfig - base_model_prefix = "led" - - @property - def input_signature(self): - sig = super().input_signature - sig["global_attention_mask"] = tf.TensorSpec((None, None), tf.int32, name="global_attention_mask") - return sig - - -@dataclass -# Copied from transformers.models.longformer.modeling_tf_longformer.TFLongformerBaseModelOutput with TFLongformer->TFLEDEncoder -class TFLEDEncoderBaseModelOutput(ModelOutput): - """ - Base class for Longformer's outputs, with potential hidden states, local and global attentions. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x + - attention_window + 1)`, where `x` is the number of tokens with global attention mask. - - Local attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token in the sequence to every token with - global attention (first `x` values) and to every token in the attention window (remaining `attention_window - + 1` values). Note that the first `x` values refer to tokens with fixed positions in the text, but the - remaining `attention_window + 1` values refer to tokens with relative positions: the attention weight of a - token to itself is located at index `x + attention_window / 2` and the `attention_window / 2` preceding - (succeeding) values are the attention weights to the `attention_window / 2` preceding (succeeding) tokens. - If the attention window contains a token with global attention, the attention weight at the corresponding - index is set to 0; the value should be accessed from the first `x` attention weights. If a token has global - attention, the attention weights to all other tokens in `attentions` is set to 0, the values should be - accessed from `global_attentions`. - global_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x)`, where `x` - is the number of tokens with global attention mask. - - Global attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token with global attention to every token - in the sequence. - """ - - last_hidden_state: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - global_attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFLEDSeq2SeqModelOutput(ModelOutput): - """ - Base class for model encoder's outputs that also contains : pre-computed hidden states that can speed up sequential - decoding. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the decoder of the model. - - If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, - hidden_size)` is output. - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be - used (see `past_key_values` input) to speed up sequential decoding. - decoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the decoder at the output of each layer plus the initial embedding outputs. - decoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - cross_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - encoder_last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder of the model. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - encoder_global_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x)`, where `x` - is the number of tokens with global attention mask. - - Global attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token with global attention to every token - in the sequence. - """ - - last_hidden_state: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - decoder_hidden_states: tuple[tf.Tensor, ...] | None = None - decoder_attentions: tuple[tf.Tensor, ...] | None = None - cross_attentions: tuple[tf.Tensor, ...] | None = None - encoder_last_hidden_state: tf.Tensor | None = None - encoder_hidden_states: tuple[tf.Tensor, ...] | None = None - encoder_attentions: tuple[tf.Tensor, ...] | None = None - encoder_global_attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFLEDSeq2SeqLMOutput(ModelOutput): - """ - Base class for sequence-to-sequence language models outputs. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Language modeling loss. - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be - used (see `past_key_values` input) to speed up sequential decoding. - decoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the decoder at the output of each layer plus the initial embedding outputs. - decoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - cross_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the - weighted average in the cross-attention heads. - encoder_last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder of the model. - encoder_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. - encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the - self-attention heads. - encoder_global_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x)`, where `x` - is the number of tokens with global attention mask. - - Global attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token with global attention to every token - in the sequence. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - decoder_hidden_states: tuple[tf.Tensor, ...] | None = None - decoder_attentions: tuple[tf.Tensor, ...] | None = None - cross_attentions: tuple[tf.Tensor, ...] | None = None - encoder_last_hidden_state: tf.Tensor | None = None - encoder_hidden_states: tuple[tf.Tensor, ...] | None = None - encoder_attentions: tuple[tf.Tensor, ...] | None = None - encoder_global_attentions: tuple[tf.Tensor, ...] | None = None - - -LED_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`LEDConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -LED_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`LedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - - LED uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If `past_key_values` - is used, optionally only the last `decoder_input_ids` have to be input (see `past_key_values`). - decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - will be made by default and ignore pad tokens. It is not recommended to set this for most use cases. - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_outputs (`tf.Tensor`, *optional*): - hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - of shape `(batch_size, sequence_length, hidden_size)` is a sequence of - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@keras_serializable -class TFLEDEncoder(keras.layers.Layer): - config_class = LEDConfig - """ - Transformer encoder consisting of *config.encoder_layers* self-attention layers. Each layer is a - [`TFLEDEncoderLayer`]. - - Args: - config: LEDConfig - """ - - def __init__(self, config: LEDConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.dropout = keras.layers.Dropout(config.dropout) - if config.encoder_layerdrop > 0: - logger.warning("Layerdrop is currently disabled in TFLED models.") - self.layerdrop = 0.0 - self.padding_idx = config.pad_token_id - - if isinstance(config.attention_window, int): - assert config.attention_window % 2 == 0, "`config.attention_window` has to be an even value" - assert config.attention_window > 0, "`config.attention_window` has to be positive" - config.attention_window = [config.attention_window] * config.num_hidden_layers # one value per layer - else: - assert len(config.attention_window) == config.num_hidden_layers, ( - "`len(config.attention_window)` should equal `config.num_hidden_layers`. " - f"Expected {config.num_hidden_layers}, given {len(config.attention_window)}" - ) - - self.attention_window = config.attention_window - self.embed_tokens = embed_tokens - self.embed_positions = TFLEDLearnedPositionalEmbedding( - config.max_encoder_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.layers = [TFLEDEncoderLayer(config, i, name=f"layers.{i}") for i in range(config.encoder_layers)] - self.layernorm_embedding = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_embedding") - self.embed_dim = config.d_model - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids=None, - inputs_embeds=None, - attention_mask=None, - global_attention_mask=None, - head_mask=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - """ - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(input_shape, 1) - - # merge `global_attention_mask` and `attention_mask` - if global_attention_mask is not None: - attention_mask = attention_mask * tf.cast((global_attention_mask + 1), dtype=attention_mask.dtype) - - padding_len, input_ids, attention_mask, inputs_embeds = self._pad_to_window_size( - input_ids=input_ids, - attention_mask=attention_mask, - inputs_embeds=inputs_embeds, - pad_token_id=self.padding_idx, - ) - - input_shape = shape_list(attention_mask) - # is index masked or global attention - is_index_masked = tf.math.less(tf.cast(attention_mask, tf.int8), 1) - is_index_global_attn = tf.math.greater(tf.cast(attention_mask, tf.int8), 1) - is_global_attn = tf.math.reduce_any(is_index_global_attn) - - embed_pos = self.embed_positions(input_shape) - hidden_states = inputs_embeds + embed_pos - hidden_states = self.layernorm_embedding(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - - # check attention mask and invert - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - attention_mask = _expand_mask(attention_mask)[:, 0, 0, :] - attention_mask = attention_mask[:, :, None, None] - - encoder_states = () if output_hidden_states else None - all_attentions = all_global_attentions = () if output_attentions else None - - # check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - tf.debugging.assert_equal( - shape_list(head_mask)[0], - len(self.layers), - message=( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(head_mask)[0]}." - ), - ) - - # encoder layers - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - hidden_states_to_add = self.compute_hidden_states(hidden_states, padding_len) - encoder_states = encoder_states + (hidden_states_to_add,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): # skip the layer - continue - - layer_outputs = encoder_layer( - hidden_states=hidden_states, - attention_mask=attention_mask, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - is_index_masked=is_index_masked, - is_index_global_attn=is_index_global_attn, - is_global_attn=is_global_attn, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - # bzs x seq_len x num_attn_heads x (num_global_attn + attention_window_len + 1) => bzs x num_attn_heads x seq_len x (num_global_attn + attention_window_len + 1) - all_attentions = all_attentions + (tf.transpose(layer_outputs[1], (0, 2, 1, 3)),) - - # bzs x num_attn_heads x num_global_attn x seq_len => bzs x num_attn_heads x seq_len x num_global_attn - all_global_attentions = all_global_attentions + (tf.transpose(layer_outputs[2], (0, 1, 3, 2)),) - - # undo padding - # unpad `hidden_states` because the calling function is expecting a length == input_ids.size(1) - hidden_states = self.compute_hidden_states(hidden_states, padding_len) - - # undo padding - if output_attentions: - all_attentions = ( - tuple(state[:, :, :-padding_len, :] for state in all_attentions) if padding_len > 0 else all_attentions - ) - - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFLEDEncoderBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=encoder_states, - attentions=all_attentions, - global_attentions=all_global_attentions, - ) - - @tf.function - def compute_hidden_states(self, hidden_states, padding_len): - return hidden_states[:, :-padding_len] if padding_len > 0 else hidden_states - - def _pad_to_window_size( - self, - input_ids, - attention_mask, - inputs_embeds, - pad_token_id, - ): - """A helper function to pad tokens and mask to work with implementation of Longformer selfattention.""" - # padding - attention_window = ( - self.attention_window if isinstance(self.attention_window, int) else max(self.attention_window) - ) - - assert attention_window % 2 == 0, f"`attention_window` should be an even value. Given {attention_window}" - - input_shape = shape_list(input_ids) if input_ids is not None else shape_list(inputs_embeds) - batch_size, seq_len = input_shape[:2] - padding_len = (attention_window - seq_len % attention_window) % attention_window - - if padding_len > 0: - logger.warning_once( - f"Input ids are automatically padded from {seq_len} to {seq_len + padding_len} to be a multiple of " - f"`config.attention_window`: {attention_window}" - ) - - paddings = tf.convert_to_tensor([[0, 0], [0, padding_len]]) - - if input_ids is not None: - input_ids = tf.pad(input_ids, paddings, constant_values=pad_token_id) - - if inputs_embeds is not None: - if padding_len > 0: - input_ids_padding = tf.fill((batch_size, padding_len), pad_token_id) - inputs_embeds_padding = self.embed_tokens(input_ids_padding) - inputs_embeds = tf.concat([inputs_embeds, inputs_embeds_padding], axis=-2) - - attention_mask = tf.pad(attention_mask, paddings, constant_values=False) # no attention on the padding tokens - - return ( - padding_len, - input_ids, - attention_mask, - inputs_embeds, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layernorm_embedding", None) is not None: - with tf.name_scope(self.layernorm_embedding.name): - self.layernorm_embedding.build([None, None, self.embed_dim]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFLEDDecoder(keras.layers.Layer): - config_class = LEDConfig - """ - Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFLEDDecoderLayer`] - - Args: - config: LEDConfig - embed_tokens: output embedding - """ - - def __init__(self, config: LEDConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.padding_idx = config.pad_token_id - self.embed_tokens = embed_tokens - if config.decoder_layerdrop > 0: - logger.warning("Layerdrop is currently disabled in TFLED models.") - self.layerdrop = 0.0 - self.embed_positions = TFLEDLearnedPositionalEmbedding( - config.max_decoder_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.layers = [TFLEDDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] - self.layernorm_embedding = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_embedding") - - self.dropout = keras.layers.Dropout(config.dropout) - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids=None, - inputs_embeds=None, - attention_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - head_mask=None, - encoder_head_mask=None, - past_key_values=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - [What are attention masks?](../glossary#attention-mask) - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention - of the decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): - Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values - selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in encoder to avoid performing cross-attention - on hidden heads. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers` with each tuple having 2 tuples each of which has 2 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up - decoding. If `past_key_values` are used, the user can optionally input only the last - `decoder_input_ids` (those that don't have their past key value states given to this model) of shape - `(batch_size, 1)` instead of all `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - past_key_values_length = shape_list(past_key_values[0][0])[2] if past_key_values is not None else 0 - - # embed positions - positions = self.embed_positions(input_shape, past_key_values_length) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) - - hidden_states = inputs_embeds - - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - if input_shape[-1] > 1: - combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length=past_key_values_length) - else: - combined_attention_mask = _expand_mask( - tf.ones((input_shape[0], input_shape[1] + past_key_values_length)), tgt_len=input_shape[-1] - ) - - if attention_mask is not None and input_shape[-1] > 1: - combined_attention_mask = combined_attention_mask + _expand_mask(attention_mask, tgt_len=input_shape[-1]) - - if encoder_hidden_states is not None and encoder_attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) - - hidden_states = self.layernorm_embedding(hidden_states + positions) - hidden_states = self.dropout(hidden_states, training=training) - - # decoder layers - all_hidden_states = () - all_self_attns = () - all_cross_attentions = () - present_key_values = () - - # check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - tf.debugging.assert_equal( - shape_list(head_mask)[0], - len(self.layers), - message=( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(head_mask)[0]}." - ), - ) - - for idx, decoder_layer in enumerate(self.layers): - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - if output_hidden_states: - all_hidden_states += (hidden_states,) - dropout_probability = random.uniform(0, 1) - - if training and (dropout_probability < self.layerdrop): - continue - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( - hidden_states, - attention_mask=combined_attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - encoder_layer_head_mask=encoder_head_mask[idx] if encoder_head_mask is not None else None, - past_key_value=past_key_value, - ) - - if use_cache: - present_key_values += (present_key_value,) - - if output_attentions: - all_self_attns += (layer_self_attn,) - all_cross_attentions += (layer_cross_attn,) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - else: - all_hidden_states = None - - all_self_attns = all_self_attns if output_attentions else None - all_cross_attentions = all_cross_attentions if output_attentions else None - - present_key_values = present_key_values if use_cache else None - - if not return_dict: - return tuple( - v - for v in [hidden_states, present_key_values, all_hidden_states, all_self_attns, all_cross_attentions] - if v is not None - ) - else: - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=present_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layernorm_embedding", None) is not None: - with tf.name_scope(self.layernorm_embedding.name): - self.layernorm_embedding.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFLEDMainLayer(keras.layers.Layer): - config_class = LEDConfig - - def __init__(self, config: LEDConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.shared = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.d_model, - embeddings_initializer=keras.initializers.TruncatedNormal(stddev=self.config.init_std), - name="led.shared", - ) - # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) - self.shared.load_weight_prefix = "led.shared" - - self.encoder = TFLEDEncoder(config, self.shared, name="encoder") - self.decoder = TFLEDDecoder(config, self.shared, name="decoder") - - def get_input_embeddings(self): - return self.shared - - def set_input_embeddings(self, new_embeddings): - self.shared = new_embeddings - self.encoder.embed_tokens = self.shared - self.decoder.embed_tokens = self.shared - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - decoder_input_ids=None, - decoder_attention_mask=None, - head_mask=None, - decoder_head_mask=None, - encoder_outputs: tuple | TFLEDEncoderBaseModelOutput | None = None, - global_attention_mask=None, - past_key_values=None, - inputs_embeds=None, - decoder_inputs_embeds=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - **kwargs, - ): - if decoder_input_ids is None and decoder_inputs_embeds is None: - use_cache = False - - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - global_attention_mask=global_attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - # If the user passed a tuple for encoder_outputs, we wrap it in a TFLEDEncoderBaseModelOutput when return_dict=True - elif return_dict and not isinstance(encoder_outputs, TFLEDEncoderBaseModelOutput): - encoder_outputs = TFLEDEncoderBaseModelOutput( - last_hidden_state=encoder_outputs[0], - hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, - attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, - ) - # If the user passed a TFLEDEncoderBaseModelOutput for encoder_outputs, we wrap it in a tuple when return_dict=False - elif not return_dict and not isinstance(encoder_outputs, tuple): - encoder_outputs = encoder_outputs.to_tuple() - - decoder_outputs = self.decoder( - decoder_input_ids, - attention_mask=decoder_attention_mask, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - head_mask=decoder_head_mask, - encoder_head_mask=head_mask, - past_key_values=past_key_values, - inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return TFLEDSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - encoder_global_attentions=encoder_outputs.global_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # The shared/tied weights expect to be in the model base namespace - # Adding "/" to the end (not the start!) of a tf.name_scope puts it in the root namespace rather than - # the current one. - with tf.name_scope(self.shared.load_weight_prefix + "/" + self.shared.name + "/"): - self.shared.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - "The bare LED Model outputting raw hidden-states without any specific head on top.", - LED_START_DOCSTRING, -) -class TFLEDModel(TFLEDPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.led = TFLEDMainLayer(config, name="led") - - def get_encoder(self): - return self.led.encoder - - def get_decoder(self): - return self.led.decoder - - @unpack_inputs - @add_start_docstrings_to_model_forward(LED_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFLEDSeq2SeqModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - encoder_outputs: tf.Tensor | None = None, - global_attention_mask: tf.Tensor | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ) -> tuple[tf.Tensor] | TFLEDSeq2SeqModelOutput: - outputs = self.led( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - encoder_outputs=encoder_outputs, - global_attention_mask=global_attention_mask, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - enc_g_attns = tf.convert_to_tensor(output.encoder_global_attentions) if self.config.output_attentions else None - - return TFLEDSeq2SeqModelOutput( - last_hidden_state=output.last_hidden_state, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - encoder_global_attentions=enc_g_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "led", None) is not None: - with tf.name_scope(self.led.name): - self.led.build(None) - - -# Copied from transformers.models.bart.modeling_tf_bart.BiasLayer -class BiasLayer(keras.layers.Layer): - """ - Bias as a layer. It is used for serialization purposes: `keras.Model.save_weights` stores on a per-layer basis, - so all weights have to be registered in a layer. - """ - - def __init__(self, shape, initializer, trainable, name, **kwargs): - super().__init__(name=name, **kwargs) - # Note: the name of this variable will NOT be scoped when serialized, i.e. it will not be in the format of - # "outer_layer/inner_layer/.../name:0". Instead, it will be "name:0". For further details, see: - # https://github.com/huggingface/transformers/pull/18833#issuecomment-1233090214 - self.bias = self.add_weight(name=name, shape=shape, initializer=initializer, trainable=trainable) - - def call(self, x): - return x + self.bias - - -@add_start_docstrings( - "The LED Model with a language modeling head. Can be used for summarization.", - LED_START_DOCSTRING, -) -class TFLEDForConditionalGeneration(TFLEDPreTrainedModel): - _keys_to_ignore_on_load_unexpected = [ - r"led.encoder.embed_tokens.weight", - r"led.decoder.embed_tokens.weight", - ] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.led = TFLEDMainLayer(config, name="led") - self.use_cache = config.use_cache - # final_bias_logits is registered as a buffer in pytorch, so not trainable for the sake of consistency. - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, config.vocab_size], initializer="zeros", trainable=False - ) - - # TODO (Joao): investigate why LED has numerical issues in XLA generate - self.supports_xla_generation = False - - def get_decoder(self): - return self.led.decoder - - def get_encoder(self): - return self.led.encoder - - def get_bias(self): - return {"final_logits_bias": self.bias_layer.bias} - - def set_bias(self, value): - # Replaces the existing layers containing bias for correct (de)serialization. - vocab_size = value["final_logits_bias"].shape[-1] - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, vocab_size], initializer="zeros", trainable=False - ) - self.bias_layer.bias.assign(value["final_logits_bias"]) - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - @unpack_inputs - @add_start_docstrings_to_model_forward(LED_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFLEDSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: TFLEDEncoderBaseModelOutput | None = None, - global_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFLEDSeq2SeqLMOutput: - """ - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFLEDForConditionalGeneration - >>> import tensorflow as tf - - >>> mname = "allenai/led-base-16384" - >>> tokenizer = AutoTokenizer.from_pretrained(mname) - >>> TXT = "My friends are but they eat too many carbs." - >>> model = TFLEDForConditionalGeneration.from_pretrained(mname) - >>> batch = tokenizer([TXT], return_tensors="tf") - >>> logits = model(inputs=batch.input_ids).logits - >>> probs = tf.nn.softmax(logits[0]) - >>> # probs[5] is associated with the mask token - ```""" - - if labels is not None: - use_cache = False - if decoder_input_ids is None and decoder_inputs_embeds is None: - decoder_input_ids = shift_tokens_right( - labels, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - outputs = self.led( - input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - encoder_outputs=encoder_outputs, - global_attention_mask=global_attention_mask, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - lm_logits = tf.matmul(outputs[0], self.led.shared.weights, transpose_b=True) - lm_logits = self.bias_layer(lm_logits) - masked_lm_loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return TFLEDSeq2SeqLMOutput( - loss=masked_lm_loss, - logits=lm_logits, - past_key_values=outputs.past_key_values, # index 1 of d outputs - decoder_hidden_states=outputs.decoder_hidden_states, # index 2 of d outputs - decoder_attentions=outputs.decoder_attentions, # index 3 of d outputs - cross_attentions=outputs.cross_attentions, # index 4 of d outputs - encoder_last_hidden_state=outputs.encoder_last_hidden_state, # index 0 of encoder outputs - encoder_hidden_states=outputs.encoder_hidden_states, # 1 of e out - encoder_attentions=outputs.encoder_attentions, # 2 of e out - encoder_global_attentions=outputs.encoder_global_attentions, - ) - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - enc_g_attns = tf.convert_to_tensor(output.encoder_global_attentions) if self.config.output_attentions else None - - return TFLEDSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - encoder_global_attentions=enc_g_attns, - ) - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - past_key_values=None, - attention_mask=None, - head_mask=None, - decoder_head_mask=None, - use_cache=None, - encoder_outputs=None, - **kwargs, - ): - # cut decoder_input_ids if past is used - if past_key_values is not None: - decoder_input_ids = decoder_input_ids[:, -1:] - - return { - "input_ids": None, # encoder_outputs is defined. input_ids not needed - "encoder_outputs": encoder_outputs, - "past_key_values": past_key_values, - "decoder_input_ids": decoder_input_ids, - "attention_mask": attention_mask, - "head_mask": head_mask, - "decoder_head_mask": decoder_head_mask, - "use_cache": use_cache, # change this to avoid caching (presumably for debugging) - } - - def prepare_decoder_input_ids_from_labels(self, labels: tf.Tensor): - return shift_tokens_right(labels, self.config.pad_token_id, self.config.decoder_start_token_id) - - def hf_compute_loss(self, labels, logits): - """CrossEntropyLoss that ignores pad tokens""" - loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=keras.losses.Reduction.NONE) - if self.config.tf_legacy_loss: - melted_labels = tf.reshape(labels, (-1,)) - active_loss = tf.not_equal(melted_labels, self.config.pad_token_id) - reduced_logits = tf.boolean_mask(tf.reshape(logits, (-1, shape_list(logits)[2])), active_loss) - labels = tf.boolean_mask(melted_labels, active_loss) - return loss_fn(labels, reduced_logits) - - # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway - unmasked_loss = loss_fn(tf.nn.relu(labels), logits) - # make sure only non-padding labels affect the loss - loss_mask = tf.cast(labels != self.config.pad_token_id, dtype=unmasked_loss.dtype) - masked_loss = unmasked_loss * loss_mask - reduced_masked_loss = tf.reduce_sum(masked_loss) / tf.reduce_sum(loss_mask) - return tf.reshape(reduced_masked_loss, (1,)) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "led", None) is not None: - with tf.name_scope(self.led.name): - self.led.build(None) - if getattr(self, "bias_layer", None) is not None: - with tf.name_scope(self.bias_layer.name): - self.bias_layer.build(None) - - -__all__ = ["TFLEDForConditionalGeneration", "TFLEDModel", "TFLEDPreTrainedModel"] diff --git a/src/transformers/models/levit/image_processing_levit.py b/src/transformers/models/levit/image_processing_levit.py index 5bf03b39e4b9..021c6f4aa652 100644 --- a/src/transformers/models/levit/image_processing_levit.py +++ b/src/transformers/models/levit/image_processing_levit.py @@ -226,10 +226,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. If unset, the channel dimension format of the input image is used. Can be one of: @@ -258,10 +256,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/levit/modeling_levit.py b/src/transformers/models/levit/modeling_levit.py index 3deca07e2400..bec62dec56e0 100644 --- a/src/transformers/models/levit/modeling_levit.py +++ b/src/transformers/models/levit/modeling_levit.py @@ -474,8 +474,6 @@ class LevitPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/lightglue/image_processing_lightglue.py b/src/transformers/models/lightglue/image_processing_lightglue.py index 400475b76c77..855fbb12d641 100644 --- a/src/transformers/models/lightglue/image_processing_lightglue.py +++ b/src/transformers/models/lightglue/image_processing_lightglue.py @@ -73,8 +73,7 @@ def convert_to_grayscale( input_data_format: Optional[Union[str, ChannelDimension]] = None, ) -> ImageInput: """ - Converts an image to grayscale format using the NTSC formula. Only support numpy and PIL Image. TODO support torch - and tensorflow grayscale conversion + Converts an image to grayscale format using the NTSC formula. Only support numpy and PIL Image. This function is supposed to return a 1-channel image, but it returns a 3-channel image with the same value in each channel, because of an issue that is discussed in : @@ -261,10 +260,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -291,10 +288,7 @@ def preprocess( images = validate_and_format_image_pairs(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_resize=do_resize, diff --git a/src/transformers/models/lilt/modeling_lilt.py b/src/transformers/models/lilt/modeling_lilt.py index bb00d16c3965..c486a494b48a 100644 --- a/src/transformers/models/lilt/modeling_lilt.py +++ b/src/transformers/models/lilt/modeling_lilt.py @@ -46,8 +46,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -567,8 +565,6 @@ class LiltPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/llama/__init__.py b/src/transformers/models/llama/__init__.py index 0677bb91435c..3166111744a1 100644 --- a/src/transformers/models/llama/__init__.py +++ b/src/transformers/models/llama/__init__.py @@ -19,7 +19,6 @@ if TYPE_CHECKING: from .configuration_llama import * - from .modeling_flax_llama import * from .modeling_llama import * from .tokenization_llama import * from .tokenization_llama_fast import * diff --git a/src/transformers/models/llama/modeling_flax_llama.py b/src/transformers/models/llama/modeling_flax_llama.py deleted file mode 100644 index 63e34e996ade..000000000000 --- a/src/transformers/models/llama/modeling_flax_llama.py +++ /dev/null @@ -1,747 +0,0 @@ -# coding=utf-8 -# Copyright 2023 Meta AI, EleutherAI and the HuggingFace Inc. team. All rights reserved. -# -# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX -# and OPT implementations in this library. It has been modified from its -# original forms to accommodate minor architectural differences compared -# to GPT-NeoX and OPT used by the Meta AI team that trained the model. -# -# 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. -"""Flax LLaMA model.""" - -from functools import partial -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxCausalLMOutput -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_llama import LlamaConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "LlamaConfig" -_CHECKPOINT_FOR_DOC = "afmck/testing-llama-tiny" -_REAL_CHECKPOINT_FOR_DOC = "openlm-research/open_llama_3b_v2" - -LLAMA_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`LlamaConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16`, or - `jax.numpy.bfloat16`. - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -LLAMA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - If you want to change padding behavior, you should read [`modeling_opt._prepare_decoder_attention_mask`] - and modify to your needs. See diagram 1 in [the paper](https://huggingface.co/papers/1910.13461) for more - information on the default strategy. - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - position_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.n_positions - 1]`. - - [What are position IDs?](../glossary#position-ids) - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def create_sinusoidal_positions(num_pos, dim): - inv_freq = 1.0 / (10000 ** (np.arange(0, dim, 2) / dim)) - freqs = np.einsum("i , j -> i j", np.arange(num_pos), inv_freq).astype("float32") - - emb = np.concatenate((freqs, freqs), axis=-1) - out = np.concatenate((np.sin(emb)[:, None, :], np.cos(emb)[:, None, :]), axis=-1) - return jnp.array(out[:, :, :num_pos]) - - -def rotate_half(tensor): - """Rotates half the hidden dims of the input.""" - rotate_half_tensor = jnp.concatenate( - (-tensor[..., tensor.shape[-1] // 2 :], tensor[..., : tensor.shape[-1] // 2]), axis=-1 - ) - return rotate_half_tensor - - -def apply_rotary_pos_emb(tensor, sin_pos, cos_pos): - return (tensor * cos_pos) + (rotate_half(tensor) * sin_pos) - - -class FlaxLlamaRMSNorm(nn.Module): - config: LlamaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.epsilon = self.config.rms_norm_eps - self.weight = self.param("weight", lambda _, shape: jnp.ones(shape), self.config.hidden_size) - - def __call__(self, hidden_states): - variance = jnp.asarray(hidden_states, dtype=jnp.float32) - variance = jnp.power(variance, 2) - variance = variance.mean(-1, keepdims=True) - # use `jax.numpy.sqrt` as `jax.lax.rsqrt` does not match `torch.rsqrt` - hidden_states = hidden_states / jnp.sqrt(variance + self.epsilon) - - return self.weight * jnp.asarray(hidden_states, dtype=self.dtype) - - -class FlaxLlamaRotaryEmbedding(nn.Module): - config: LlamaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - head_dim = self.config.hidden_size // self.config.num_attention_heads - self.sincos = create_sinusoidal_positions(self.config.max_position_embeddings, head_dim) - - def __call__(self, key, query, position_ids): - sincos = self.sincos[position_ids] - sin_pos, cos_pos = jnp.split(sincos, 2, axis=-1) - - key = apply_rotary_pos_emb(key, sin_pos, cos_pos) - query = apply_rotary_pos_emb(query, sin_pos, cos_pos) - - key = jnp.asarray(key, dtype=self.dtype) - query = jnp.asarray(query, dtype=self.dtype) - - return key, query - - -class FlaxLlamaAttention(nn.Module): - config: LlamaConfig - dtype: jnp.dtype = jnp.float32 - causal: bool = True - is_cross_attention: bool = False - - def setup(self): - config = self.config - self.embed_dim = config.hidden_size - self.num_heads = config.num_attention_heads - self.head_dim = self.embed_dim // self.num_heads - self.num_key_value_heads = config.num_key_value_heads - self.num_key_value_groups = self.num_heads // self.num_key_value_heads - self.attention_softmax_in_fp32 = self.dtype is not jnp.float32 - - dense = partial( - nn.Dense, - use_bias=config.attention_bias, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - self.q_proj = dense(self.num_heads * self.head_dim) - self.k_proj = dense(self.num_key_value_heads * self.head_dim) - self.v_proj = dense(self.num_key_value_heads * self.head_dim) - self.o_proj = dense(self.embed_dim) - self.causal_mask = make_causal_mask(jnp.ones((1, config.max_position_embeddings), dtype="bool"), dtype="bool") - self.rotary_emb = FlaxLlamaRotaryEmbedding(config, dtype=self.dtype) - - def _split_heads(self, hidden_states, num_heads): - return hidden_states.reshape(hidden_states.shape[:2] + (num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - # Copied from transformers.models.gpt_neo.modeling_flax_gpt_neo.FlaxGPTNeoSelfAttention._concatenate_to_cache - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - attention_mask, - position_ids, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - query = self.q_proj(hidden_states) - key = self.k_proj(hidden_states) - value = self.v_proj(hidden_states) - - query = self._split_heads(query, self.num_heads) - key = self._split_heads(key, self.num_key_value_heads) - value = self._split_heads(value, self.num_key_value_heads) - - key, query = self.rotary_emb(key, query, position_ids) - - query_length, key_length = query.shape[1], key.shape[1] - - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - - batch_size = hidden_states.shape[0] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - - dropout_rng = None - if not deterministic and self.config.attention_dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.has_variable("cache", "cached_key") or init_cache: - key, value, attention_mask = self._concatenate_to_cache(key, value, query, attention_mask) - - key = jnp.repeat(key, self.num_key_value_groups, axis=2) - value = jnp.repeat(value, self.num_key_value_groups, axis=2) - - # transform boolean mask into float mask - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - - # usual dot product attention - attention_dtype = jnp.float32 if self.attention_softmax_in_fp32 else self.dtype - attn_weights = dot_product_attention_weights( - query, - key, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_dropout, - deterministic=deterministic, - dtype=attention_dtype, - ) - - if self.attention_softmax_in_fp32: - attn_weights = attn_weights.astype(self.dtype) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value) - attn_output = self._merge_heads(attn_output) - attn_output = self.o_proj(attn_output) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxLlamaMLP(nn.Module): - config: LlamaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - embed_dim = self.config.hidden_size - inner_dim = self.config.intermediate_size if self.config.intermediate_size is not None else 4 * embed_dim - - kernel_init = jax.nn.initializers.normal(self.config.initializer_range) - self.act = ACT2FN[self.config.hidden_act] - - self.gate_proj = nn.Dense(inner_dim, use_bias=False, dtype=self.dtype, kernel_init=kernel_init) - self.down_proj = nn.Dense(embed_dim, use_bias=False, dtype=self.dtype, kernel_init=kernel_init) - self.up_proj = nn.Dense(inner_dim, use_bias=False, dtype=self.dtype, kernel_init=kernel_init) - - def __call__(self, hidden_states): - up_proj_states = self.up_proj(hidden_states) - gate_states = self.act(self.gate_proj(hidden_states)) - - hidden_states = self.down_proj(up_proj_states * gate_states) - return hidden_states - - -class FlaxLlamaDecoderLayer(nn.Module): - config: LlamaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.input_layernorm = FlaxLlamaRMSNorm(self.config, dtype=self.dtype) - self.self_attn = FlaxLlamaAttention(self.config, dtype=self.dtype) - self.post_attention_layernorm = FlaxLlamaRMSNorm(self.config, dtype=self.dtype) - self.mlp = FlaxLlamaMLP(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - residual = hidden_states - hidden_states = self.input_layernorm(hidden_states) - outputs = self.self_attn( - hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - # residual connection - attn_output = outputs[0] - hidden_states = residual + attn_output - - residual = hidden_states - hidden_states = self.post_attention_layernorm(hidden_states) - hidden_states = self.mlp(hidden_states) - # residual connection - hidden_states = residual + hidden_states - - return (hidden_states,) + outputs[1:] - - -# Copied from transformers.models.gpt_neo.modeling_flax_gpt_neo.FlaxGPTNeoPreTrainedModel with GPTNeo->Llama, GPT_NEO->LLAMA, transformer->model -class FlaxLlamaPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = LlamaConfig - base_model_prefix = "model" - module_class: nn.Module = None - - def __init__( - self, - config: LlamaConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, input_ids, attention_mask, position_ids, return_dict=False)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length)) - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(LLAMA_INPUTS_DOCSTRING) - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - params: Optional[dict] = None, - past_key_values: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - batch_size, sequence_length = input_ids.shape - - if position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `position_ids` when passing `past_key_values`.") - - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - if attention_mask is None: - attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be changed by FlaxLlamaAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - not train, - False, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - return outputs - - -class FlaxLlamaLayerCollection(nn.Module): - config: LlamaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.blocks = [ - FlaxLlamaDecoderLayer(self.config, dtype=self.dtype, name=str(i)) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = False, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for block in self.blocks: - if output_hidden_states: - all_hidden_states += (hidden_states,) - layer_outputs = block( - hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - # this contains possible `None` values - `FlaxLlamaModule` will filter them out - outputs = (hidden_states, all_hidden_states, all_attentions) - - return outputs - - -class FlaxLlamaModule(nn.Module): - config: LlamaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.hidden_size = self.config.hidden_size - embedding_init = jax.nn.initializers.normal(stddev=self.config.initializer_range) - self.embed_tokens = nn.Embed( - self.config.vocab_size, - self.hidden_size, - embedding_init=embedding_init, - dtype=self.dtype, - ) - self.layers = FlaxLlamaLayerCollection(self.config, dtype=self.dtype) - self.norm = FlaxLlamaRMSNorm(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - deterministic=True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - input_embeds = self.embed_tokens(input_ids.astype("i4")) - - outputs = self.layers( - input_embeds, - position_ids=position_ids, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.norm(hidden_states) - - if output_hidden_states: - all_hidden_states = outputs[1] + (hidden_states,) - outputs = (hidden_states, all_hidden_states) + outputs[2:] - else: - outputs = (hidden_states,) + outputs[1:] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=outputs[1], - attentions=outputs[-1], - ) - - -@add_start_docstrings( - "The bare Llama Model transformer outputting raw hidden-states without any specific head on top.", - LLAMA_START_DOCSTRING, -) -class FlaxLlamaModel(FlaxLlamaPreTrainedModel): - module_class = FlaxLlamaModule - - -append_call_sample_docstring( - FlaxLlamaModel, - _CHECKPOINT_FOR_DOC, - FlaxBaseModelOutput, - _CONFIG_FOR_DOC, - real_checkpoint=_REAL_CHECKPOINT_FOR_DOC, -) - - -class FlaxLlamaForCausalLMModule(nn.Module): - config: LlamaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.model = FlaxLlamaModule(self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - outputs = self.model( - input_ids, - position_ids=position_ids, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - return (lm_logits,) + outputs[1:] - - return FlaxCausalLMOutput(logits=lm_logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions) - - -@add_start_docstrings( - """ - The Llama Model transformer with a language modeling head (linear layer) on top. - """, - LLAMA_START_DOCSTRING, -) -# Copied from transformers.models.gptj.modeling_flax_gptj.FlaxGPTJForCausalLM with GPTJ->Llama -class FlaxLlamaForCausalLM(FlaxLlamaPreTrainedModel): - module_class = FlaxLlamaForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since Llama uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxLlamaForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutput, - _CONFIG_FOR_DOC, - real_checkpoint=_REAL_CHECKPOINT_FOR_DOC, -) - - -__all__ = ["FlaxLlamaForCausalLM", "FlaxLlamaModel", "FlaxLlamaPreTrainedModel"] diff --git a/src/transformers/models/llama4/processing_llama4.py b/src/transformers/models/llama4/processing_llama4.py index ce590bc6f40b..47a0b4cd99fb 100644 --- a/src/transformers/models/llama4/processing_llama4.py +++ b/src/transformers/models/llama4/processing_llama4.py @@ -159,10 +159,8 @@ def __call__( `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/llava/image_processing_llava.py b/src/transformers/models/llava/image_processing_llava.py index d3aa81303bb8..543b22dc431f 100644 --- a/src/transformers/models/llava/image_processing_llava.py +++ b/src/transformers/models/llava/image_processing_llava.py @@ -334,10 +334,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -371,10 +369,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # we don't pass `do_pad` here since LLaVa uses a custom padding to a square validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/llava/processing_llava.py b/src/transformers/models/llava/processing_llava.py index 63c07c20cbb9..398bd9d8d065 100644 --- a/src/transformers/models/llava/processing_llava.py +++ b/src/transformers/models/llava/processing_llava.py @@ -115,10 +115,8 @@ def __call__( `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/llava_next/image_processing_llava_next.py b/src/transformers/models/llava_next/image_processing_llava_next.py index 3887c9c7ad4b..07d8a934db21 100644 --- a/src/transformers/models/llava_next/image_processing_llava_next.py +++ b/src/transformers/models/llava_next/image_processing_llava_next.py @@ -606,10 +606,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -643,10 +641,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/llava_next_video/image_processing_llava_next_video.py b/src/transformers/models/llava_next_video/image_processing_llava_next_video.py index ba1cd30a1133..8468c20afa4e 100644 --- a/src/transformers/models/llava_next_video/image_processing_llava_next_video.py +++ b/src/transformers/models/llava_next_video/image_processing_llava_next_video.py @@ -326,10 +326,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. diff --git a/src/transformers/models/llava_next_video/processing_llava_next_video.py b/src/transformers/models/llava_next_video/processing_llava_next_video.py index b9dbc6650b63..e858a1784254 100644 --- a/src/transformers/models/llava_next_video/processing_llava_next_video.py +++ b/src/transformers/models/llava_next_video/processing_llava_next_video.py @@ -143,10 +143,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/llava_onevision/image_processing_llava_onevision.py b/src/transformers/models/llava_onevision/image_processing_llava_onevision.py index 837eda460802..d7593a5355bd 100644 --- a/src/transformers/models/llava_onevision/image_processing_llava_onevision.py +++ b/src/transformers/models/llava_onevision/image_processing_llava_onevision.py @@ -650,10 +650,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -696,10 +694,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/longformer/__init__.py b/src/transformers/models/longformer/__init__.py index 87f53105424b..a0ee62087e76 100644 --- a/src/transformers/models/longformer/__init__.py +++ b/src/transformers/models/longformer/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_longformer import * from .modeling_longformer import * - from .modeling_tf_longformer import * from .tokenization_longformer import * from .tokenization_longformer_fast import * else: diff --git a/src/transformers/models/longformer/configuration_longformer.py b/src/transformers/models/longformer/configuration_longformer.py index 207cc1839479..111ede4d0dd6 100644 --- a/src/transformers/models/longformer/configuration_longformer.py +++ b/src/transformers/models/longformer/configuration_longformer.py @@ -20,7 +20,7 @@ from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig -from ...utils import TensorType, logging +from ...utils import logging if TYPE_CHECKING: @@ -188,10 +188,12 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: inputs = super().generate_dummy_inputs( - preprocessor=tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + preprocessor=tokenizer, + batch_size=batch_size, + seq_length=seq_length, + is_pair=is_pair, ) import torch diff --git a/src/transformers/models/longformer/modeling_longformer.py b/src/transformers/models/longformer/modeling_longformer.py index cdc708924967..fc466a38ecc2 100755 --- a/src/transformers/models/longformer/modeling_longformer.py +++ b/src/transformers/models/longformer/modeling_longformer.py @@ -392,8 +392,6 @@ def __init__(self, config): self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -1357,8 +1355,6 @@ class LongformerPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/longformer/modeling_tf_longformer.py b/src/transformers/models/longformer/modeling_tf_longformer.py deleted file mode 100644 index 891f5d76c95c..000000000000 --- a/src/transformers/models/longformer/modeling_tf_longformer.py +++ /dev/null @@ -1,2783 +0,0 @@ -# coding=utf-8 -# Copyright 2020 The Allen Institute for AI team and 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. -"""Tensorflow Longformer model.""" - -from __future__ import annotations - -import warnings -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_longformer import LongformerConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "allenai/longformer-base-4096" -_CONFIG_FOR_DOC = "LongformerConfig" - -LARGE_NEGATIVE = -1e8 - - -@dataclass -class TFLongformerBaseModelOutput(ModelOutput): - """ - Base class for Longformer's outputs, with potential hidden states, local and global attentions. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x + - attention_window + 1)`, where `x` is the number of tokens with global attention mask. - - Local attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token in the sequence to every token with - global attention (first `x` values) and to every token in the attention window (remaining `attention_window - + 1` values). Note that the first `x` values refer to tokens with fixed positions in the text, but the - remaining `attention_window + 1` values refer to tokens with relative positions: the attention weight of a - token to itself is located at index `x + attention_window / 2` and the `attention_window / 2` preceding - (succeeding) values are the attention weights to the `attention_window / 2` preceding (succeeding) tokens. - If the attention window contains a token with global attention, the attention weight at the corresponding - index is set to 0; the value should be accessed from the first `x` attention weights. If a token has global - attention, the attention weights to all other tokens in `attentions` is set to 0, the values should be - accessed from `global_attentions`. - global_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x)`, where `x` - is the number of tokens with global attention mask. - - Global attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token with global attention to every token - in the sequence. - """ - - last_hidden_state: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - global_attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFLongformerBaseModelOutputWithPooling(ModelOutput): - """ - Base class for Longformer's outputs that also contains a pooling of the last hidden states. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - pooler_output (`tf.Tensor` of shape `(batch_size, hidden_size)`): - Last layer hidden-state of the first token of the sequence (classification token) further processed by a - Linear layer and a Tanh activation function. The Linear layer weights are trained from the next sentence - prediction (classification) objective during pretraining. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x + - attention_window + 1)`, where `x` is the number of tokens with global attention mask. - - Local attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token in the sequence to every token with - global attention (first `x` values) and to every token in the attention window (remaining `attention_window - + 1` values). Note that the first `x` values refer to tokens with fixed positions in the text, but the - remaining `attention_window + 1` values refer to tokens with relative positions: the attention weight of a - token to itself is located at index `x + attention_window / 2` and the `attention_window / 2` preceding - (succeeding) values are the attention weights to the `attention_window / 2` preceding (succeeding) tokens. - If the attention window contains a token with global attention, the attention weight at the corresponding - index is set to 0; the value should be accessed from the first `x` attention weights. If a token has global - attention, the attention weights to all other tokens in `attentions` is set to 0, the values should be - accessed from `global_attentions`. - global_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x)`, where `x` - is the number of tokens with global attention mask. - - Global attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token with global attention to every token - in the sequence. - """ - - last_hidden_state: tf.Tensor | None = None - pooler_output: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - global_attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFLongformerMaskedLMOutput(ModelOutput): - """ - Base class for masked language models outputs. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Masked language modeling (MLM) loss. - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x + - attention_window + 1)`, where `x` is the number of tokens with global attention mask. - - Local attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token in the sequence to every token with - global attention (first `x` values) and to every token in the attention window (remaining `attention_window - + 1` values). Note that the first `x` values refer to tokens with fixed positions in the text, but the - remaining `attention_window + 1` values refer to tokens with relative positions: the attention weight of a - token to itself is located at index `x + attention_window / 2` and the `attention_window / 2` preceding - (succeeding) values are the attention weights to the `attention_window / 2` preceding (succeeding) tokens. - If the attention window contains a token with global attention, the attention weight at the corresponding - index is set to 0; the value should be accessed from the first `x` attention weights. If a token has global - attention, the attention weights to all other tokens in `attentions` is set to 0, the values should be - accessed from `global_attentions`. - global_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x)`, where `x` - is the number of tokens with global attention mask. - - Global attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token with global attention to every token - in the sequence. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - global_attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFLongformerQuestionAnsweringModelOutput(ModelOutput): - """ - Base class for outputs of question answering Longformer models. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Total span extraction loss is the sum of a Cross-Entropy for the start and end positions. - start_logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Span-start scores (before SoftMax). - end_logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Span-end scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x + - attention_window + 1)`, where `x` is the number of tokens with global attention mask. - - Local attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token in the sequence to every token with - global attention (first `x` values) and to every token in the attention window (remaining `attention_window - + 1` values). Note that the first `x` values refer to tokens with fixed positions in the text, but the - remaining `attention_window + 1` values refer to tokens with relative positions: the attention weight of a - token to itself is located at index `x + attention_window / 2` and the `attention_window / 2` preceding - (succeeding) values are the attention weights to the `attention_window / 2` preceding (succeeding) tokens. - If the attention window contains a token with global attention, the attention weight at the corresponding - index is set to 0; the value should be accessed from the first `x` attention weights. If a token has global - attention, the attention weights to all other tokens in `attentions` is set to 0, the values should be - accessed from `global_attentions`. - global_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x)`, where `x` - is the number of tokens with global attention mask. - - Global attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token with global attention to every token - in the sequence. - """ - - loss: tf.Tensor | None = None - start_logits: tf.Tensor | None = None - end_logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - global_attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFLongformerSequenceClassifierOutput(ModelOutput): - """ - Base class for outputs of sentence classification models. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x + - attention_window + 1)`, where `x` is the number of tokens with global attention mask. - - Local attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token in the sequence to every token with - global attention (first `x` values) and to every token in the attention window (remaining `attention_window - + 1` values). Note that the first `x` values refer to tokens with fixed positions in the text, but the - remaining `attention_window + 1` values refer to tokens with relative positions: the attention weight of a - token to itself is located at index `x + attention_window / 2` and the `attention_window / 2` preceding - (succeeding) values are the attention weights to the `attention_window / 2` preceding (succeeding) tokens. - If the attention window contains a token with global attention, the attention weight at the corresponding - index is set to 0; the value should be accessed from the first `x` attention weights. If a token has global - attention, the attention weights to all other tokens in `attentions` is set to 0, the values should be - accessed from `global_attentions`. - global_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x)`, where `x` - is the number of tokens with global attention mask. - - Global attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token with global attention to every token - in the sequence. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - global_attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFLongformerMultipleChoiceModelOutput(ModelOutput): - """ - Base class for outputs of multiple choice models. - - Args: - loss (`tf.Tensor` of shape *(1,)*, *optional*, returned when `labels` is provided): - Classification loss. - logits (`tf.Tensor` of shape `(batch_size, num_choices)`): - *num_choices* is the second dimension of the input tensors. (see *input_ids* above). - - Classification scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x + - attention_window + 1)`, where `x` is the number of tokens with global attention mask. - - Local attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token in the sequence to every token with - global attention (first `x` values) and to every token in the attention window (remaining `attention_window - + 1` values). Note that the first `x` values refer to tokens with fixed positions in the text, but the - remaining `attention_window + 1` values refer to tokens with relative positions: the attention weight of a - token to itself is located at index `x + attention_window / 2` and the `attention_window / 2` preceding - (succeeding) values are the attention weights to the `attention_window / 2` preceding (succeeding) tokens. - If the attention window contains a token with global attention, the attention weight at the corresponding - index is set to 0; the value should be accessed from the first `x` attention weights. If a token has global - attention, the attention weights to all other tokens in `attentions` is set to 0, the values should be - accessed from `global_attentions`. - global_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x)`, where `x` - is the number of tokens with global attention mask. - - Global attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token with global attention to every token - in the sequence. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - global_attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFLongformerTokenClassifierOutput(ModelOutput): - """ - Base class for outputs of token classification models. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided) : - Classification loss. - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.num_labels)`): - Classification scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x + - attention_window + 1)`, where `x` is the number of tokens with global attention mask. - - Local attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token in the sequence to every token with - global attention (first `x` values) and to every token in the attention window (remaining `attention_window - + 1` values). Note that the first `x` values refer to tokens with fixed positions in the text, but the - remaining `attention_window + 1` values refer to tokens with relative positions: the attention weight of a - token to itself is located at index `x + attention_window / 2` and the `attention_window / 2` preceding - (succeeding) values are the attention weights to the `attention_window / 2` preceding (succeeding) tokens. - If the attention window contains a token with global attention, the attention weight at the corresponding - index is set to 0; the value should be accessed from the first `x` attention weights. If a token has global - attention, the attention weights to all other tokens in `attentions` is set to 0, the values should be - accessed from `global_attentions`. - global_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, x)`, where `x` - is the number of tokens with global attention mask. - - Global attentions weights after the attention softmax, used to compute the weighted average in the - self-attention heads. Those are the attention weights from every token with global attention to every token - in the sequence. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - global_attentions: tuple[tf.Tensor, ...] | None = None - - -def _compute_global_attention_mask(input_ids_shape, sep_token_indices, before_sep_token=True): - """ - Computes global attention mask by putting attention on all tokens before `sep_token_id` if `before_sep_token is - True` else after `sep_token_id`. - """ - assert shape_list(sep_token_indices)[1] == 2, "`input_ids` should have two dimensions" - question_end_index = tf.reshape(sep_token_indices, (input_ids_shape[0], 3, 2))[:, 0, 1][:, None] - # bool attention mask with True in locations of global attention - attention_mask = tf.expand_dims(tf.range(input_ids_shape[1], dtype=tf.int64), axis=0) - attention_mask = tf.tile(attention_mask, (input_ids_shape[0], 1)) - if before_sep_token is True: - question_end_index = tf.tile(question_end_index, (1, input_ids_shape[1])) - attention_mask = tf.cast(attention_mask < question_end_index, dtype=question_end_index.dtype) - else: - # last token is separation token and should not be counted and in the middle are two separation tokens - question_end_index = tf.tile(question_end_index + 1, (1, input_ids_shape[1])) - attention_mask = tf.cast( - attention_mask > question_end_index, - dtype=question_end_index.dtype, - ) * tf.cast(attention_mask < input_ids_shape[-1], dtype=question_end_index.dtype) - - return attention_mask - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaLMHead with Roberta->Longformer -class TFLongformerLMHead(keras.layers.Layer): - """Longformer Head for masked language modeling.""" - - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.act = get_tf_activation("gelu") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.decoder = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - - def get_output_embeddings(self): - return self.decoder - - def set_output_embeddings(self, value): - self.decoder.weight = value - self.decoder.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.layer_norm(hidden_states) - - # project back to size of vocabulary with bias - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.decoder.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -class TFLongformerEmbeddings(keras.layers.Layer): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing and some extra casting. - """ - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.padding_idx = 1 - self.config = config - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - def create_position_ids_from_input_ids(self, input_ids, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding - symbols are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - input_ids: tf.Tensor - Returns: tf.Tensor - """ - mask = tf.cast(tf.math.not_equal(input_ids, self.padding_idx), dtype=input_ids.dtype) - incremental_indices = (tf.math.cumsum(mask, axis=1) + past_key_values_length) * mask - - return incremental_indices + self.padding_idx - - def call( - self, - input_ids=None, - position_ids=None, - token_type_ids=None, - inputs_embeds=None, - past_key_values_length=0, - training=False, - ): - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.cast(tf.fill(dims=input_shape, value=0), tf.int64) - - if position_ids is None: - if input_ids is not None: - # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = self.create_position_ids_from_input_ids( - input_ids=input_ids, past_key_values_length=past_key_values_length - ) - else: - position_ids = tf.expand_dims( - tf.range(start=self.padding_idx + 1, limit=input_shape[-1] + self.padding_idx + 1, dtype=tf.int64), - axis=0, - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->Longformer -class TFLongformerIntermediate(keras.layers.Layer): - def __init__(self, config: LongformerConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->Longformer -class TFLongformerOutput(keras.layers.Layer): - def __init__(self, config: LongformerConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->Longformer -class TFLongformerPooler(keras.layers.Layer): - def __init__(self, config: LongformerConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfOutput with Bert->Longformer -class TFLongformerSelfOutput(keras.layers.Layer): - def __init__(self, config: LongformerConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFLongformerSelfAttention(keras.layers.Layer): - def __init__(self, config, layer_id, **kwargs): - super().__init__(**kwargs) - self.config = config - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " - f"heads ({config.num_attention_heads}" - ) - - self.num_heads = config.num_attention_heads - self.head_dim = int(config.hidden_size / config.num_attention_heads) - self.embed_dim = config.hidden_size - self.query = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="query", - ) - self.key = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="key", - ) - self.value = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="value", - ) - - # separate projection layers for tokens with global attention - self.query_global = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="query_global", - ) - self.key_global = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="key_global", - ) - self.value_global = keras.layers.Dense( - self.embed_dim, - kernel_initializer=get_initializer(config.initializer_range), - name="value_global", - ) - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.global_dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.layer_id = layer_id - attention_window = config.attention_window[self.layer_id] - - assert attention_window % 2 == 0, ( - f"`attention_window` for layer {self.layer_id} has to be an even value. Given {attention_window}" - ) - assert attention_window > 0, ( - f"`attention_window` for layer {self.layer_id} has to be positive. Given {attention_window}" - ) - - self.one_sided_attn_window_size = attention_window // 2 - - def build(self, input_shape=None): - if not self.built: - with tf.name_scope("query_global"): - self.query_global.build((self.config.hidden_size,)) - with tf.name_scope("key_global"): - self.key_global.build((self.config.hidden_size,)) - with tf.name_scope("value_global"): - self.value_global.build((self.config.hidden_size,)) - - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - if getattr(self, "query_global", None) is not None: - with tf.name_scope(self.query_global.name): - self.query_global.build([None, None, self.config.hidden_size]) - if getattr(self, "key_global", None) is not None: - with tf.name_scope(self.key_global.name): - self.key_global.build([None, None, self.config.hidden_size]) - if getattr(self, "value_global", None) is not None: - with tf.name_scope(self.value_global.name): - self.value_global.build([None, None, self.config.hidden_size]) - - def call( - self, - inputs, - training=False, - ): - """ - LongformerSelfAttention expects *len(hidden_states)* to be multiple of *attention_window*. Padding to - *attention_window* happens in LongformerModel.forward to avoid redoing the padding on each layer. - - The *attention_mask* is changed in [`LongformerModel.forward`] from 0, 1, 2 to: - - - -10000: no attention - - 0: local attention - - +10000: global attention - """ - # retrieve input args - ( - hidden_states, - attention_mask, - layer_head_mask, - is_index_masked, - is_index_global_attn, - is_global_attn, - ) = inputs - - # project hidden states - query_vectors = self.query(hidden_states) - key_vectors = self.key(hidden_states) - value_vectors = self.value(hidden_states) - batch_size, seq_len, embed_dim = shape_list(hidden_states) - - tf.debugging.assert_equal( - embed_dim, - self.embed_dim, - message=f"hidden_states should have embed_dim = {self.embed_dim}, but has {embed_dim}", - ) - - # normalize query - query_vectors /= tf.math.sqrt(tf.cast(self.head_dim, dtype=query_vectors.dtype)) - query_vectors = tf.reshape(query_vectors, (batch_size, seq_len, self.num_heads, self.head_dim)) - key_vectors = tf.reshape(key_vectors, (batch_size, seq_len, self.num_heads, self.head_dim)) - - # attn_probs = (batch_size, seq_len, num_heads, window*2+1) - attn_scores = self._sliding_chunks_query_key_matmul( - query_vectors, key_vectors, self.one_sided_attn_window_size - ) - - # values to pad for attention probs - remove_from_windowed_attention_mask = attention_mask != 0 - # cast to fp32/fp16 then replace 1's with -inf - float_mask = tf.cast(remove_from_windowed_attention_mask, dtype=query_vectors.dtype) * LARGE_NEGATIVE - - # diagonal mask with zeros everywhere and -inf inplace of padding - diagonal_mask = self._sliding_chunks_query_key_matmul( - tf.ones(shape_list(attention_mask)), - float_mask, - self.one_sided_attn_window_size, - ) - - # pad local attention probs - attn_scores += diagonal_mask - - tf.debugging.assert_equal( - shape_list(attn_scores), - [batch_size, seq_len, self.num_heads, self.one_sided_attn_window_size * 2 + 1], - message=( - f"attn_probs should be of size ({batch_size}, {seq_len}, {self.num_heads}," - f" {self.one_sided_attn_window_size * 2 + 1}), but is of size {shape_list(attn_scores)}" - ), - ) - - # compute global attn indices required through out forward fn - ( - max_num_global_attn_indices, - is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero, - ) = self._get_global_attn_indices(is_index_global_attn) - - # this function is only relevant for global attention - if is_global_attn: - attn_scores = self._concat_with_global_key_attn_probs( - attn_scores=attn_scores, - query_vectors=query_vectors, - key_vectors=key_vectors, - max_num_global_attn_indices=max_num_global_attn_indices, - is_index_global_attn_nonzero=is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero=is_local_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero=is_local_index_no_global_attn_nonzero, - ) - - attn_probs = stable_softmax(attn_scores, axis=-1) - - # softmax sometimes inserts NaN if all positions are masked, replace them with 0 - # Make sure to create a mask with the proper shape: - # if is_global_attn==True => [batch_size, seq_len, self.num_heads, self.one_sided_attn_window_size * 2 + max_num_global_attn_indices + 1] - # if is_global_attn==False => [batch_size, seq_len, self.num_heads, self.one_sided_attn_window_size * 2 + 1] - if is_global_attn: - masked_index = tf.tile( - is_index_masked[:, :, None, None], - (1, 1, self.num_heads, self.one_sided_attn_window_size * 2 + max_num_global_attn_indices + 1), - ) - else: - masked_index = tf.tile( - is_index_masked[:, :, None, None], - (1, 1, self.num_heads, self.one_sided_attn_window_size * 2 + 1), - ) - attn_probs = tf.where( - masked_index, - tf.zeros(shape_list(masked_index), dtype=attn_probs.dtype), - attn_probs, - ) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_probs = tf.reshape(layer_head_mask, (1, 1, -1, 1)) * attn_probs - - # apply dropout - attn_probs = self.dropout(attn_probs, training=training) - value_vectors = tf.reshape(value_vectors, (batch_size, seq_len, self.num_heads, self.head_dim)) - - # if global attention, compute sum of global and local attn - - if is_global_attn: - attn_output = self._compute_attn_output_with_global_indices( - value_vectors=value_vectors, - attn_probs=attn_probs, - max_num_global_attn_indices=max_num_global_attn_indices, - is_index_global_attn_nonzero=is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero=is_local_index_global_attn_nonzero, - ) - else: - attn_output = self._sliding_chunks_matmul_attn_probs_value( - attn_probs, value_vectors, self.one_sided_attn_window_size - ) - - tf.debugging.assert_equal( - shape_list(attn_output), [batch_size, seq_len, self.num_heads, self.head_dim], message="Unexpected size" - ) - - attn_output = tf.reshape(attn_output, (batch_size, seq_len, embed_dim)) - - # compute value for global attention and overwrite to attention output - if is_global_attn: - attn_output, global_attn_probs = self._compute_global_attn_output_from_hidden( - attn_output=attn_output, - hidden_states=hidden_states, - max_num_global_attn_indices=max_num_global_attn_indices, - layer_head_mask=layer_head_mask, - is_local_index_global_attn_nonzero=is_local_index_global_attn_nonzero, - is_index_global_attn_nonzero=is_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero=is_local_index_no_global_attn_nonzero, - is_index_masked=is_index_masked, - training=training, - ) - else: - # Leave attn_output unchanged - global_attn_probs = tf.zeros((batch_size, self.num_heads, max_num_global_attn_indices, seq_len)) - - # make sure that local attention probabilities are set to 0 for indices of global attn - # Make sure to create a mask with the proper shape: - # if is_global_attn==True => [batch_size, seq_len, self.num_heads, self.one_sided_attn_window_size * 2 + max_num_global_attn_indices + 1] - # if is_global_attn==False => [batch_size, seq_len, self.num_heads, self.one_sided_attn_window_size * 2 + 1] - if is_global_attn: - masked_global_attn_index = tf.tile( - is_index_global_attn[:, :, None, None], - (1, 1, self.num_heads, self.one_sided_attn_window_size * 2 + max_num_global_attn_indices + 1), - ) - else: - masked_global_attn_index = tf.tile( - is_index_global_attn[:, :, None, None], - (1, 1, self.num_heads, self.one_sided_attn_window_size * 2 + 1), - ) - attn_probs = tf.where( - masked_global_attn_index, - tf.zeros(shape_list(masked_global_attn_index), dtype=attn_probs.dtype), - attn_probs, - ) - - outputs = (attn_output, attn_probs, global_attn_probs) - - return outputs - - def _sliding_chunks_query_key_matmul(self, query, key, window_overlap): - """ - Matrix multiplication of query and key tensors using with a sliding window attention pattern. This - implementation splits the input into overlapping chunks of size 2w (e.g. 512 for pretrained Longformer) with an - overlap of size window_overlap - """ - batch_size, seq_len, num_heads, head_dim = shape_list(query) - - tf.debugging.assert_equal( - seq_len % (window_overlap * 2), - 0, - message=f"Sequence length should be multiple of {window_overlap * 2}. Given {seq_len}", - ) - tf.debugging.assert_equal( - shape_list(query), - shape_list(key), - message=( - f"Shape of query and key should be equal, but got query: {shape_list(query)} and key:" - f" {shape_list(key)}" - ), - ) - - chunks_count = seq_len // window_overlap - 1 - - # group batch_size and num_heads dimensions into one, then chunk seq_len into chunks of size window_overlap * 2 - query = tf.reshape( - tf.transpose(query, (0, 2, 1, 3)), - (batch_size * num_heads, seq_len, head_dim), - ) - key = tf.reshape(tf.transpose(key, (0, 2, 1, 3)), (batch_size * num_heads, seq_len, head_dim)) - chunked_query = self._chunk(query, window_overlap) - chunked_key = self._chunk(key, window_overlap) - - # matrix multiplication - # bcxd: batch_size * num_heads x chunks x 2window_overlap x head_dim - # bcyd: batch_size * num_heads x chunks x 2window_overlap x head_dim - # bcxy: batch_size * num_heads x chunks x 2window_overlap x 2window_overlap - chunked_query = tf.cast(chunked_query, dtype=chunked_key.dtype) - chunked_attention_scores = tf.einsum("bcxd,bcyd->bcxy", chunked_query, chunked_key) # multiply - - # convert diagonals into columns - paddings = tf.convert_to_tensor([[0, 0], [0, 0], [0, 1], [0, 0]]) - diagonal_chunked_attention_scores = self._pad_and_transpose_last_two_dims(chunked_attention_scores, paddings) - - # allocate space for the overall attention matrix where the chunks are combined. The last dimension - # has (window_overlap * 2 + 1) columns. The first (window_overlap) columns are the window_overlap lower triangles (attention from a word to - # window_overlap previous words). The following column is attention score from each word to itself, then - # followed by window_overlap columns for the upper triangle. - - # copy parts from diagonal_chunked_attention_scores into the combined matrix of attentions - # - copying the main diagonal and the upper triangle - # TODO: This code is most likely not very efficient and should be improved - diagonal_attn_scores_up_triang = tf.concat( - [ - diagonal_chunked_attention_scores[:, :, :window_overlap, : window_overlap + 1], - diagonal_chunked_attention_scores[:, -1:, window_overlap:, : window_overlap + 1], - ], - axis=1, - ) - - # - copying the lower triangle - diagonal_attn_scores_low_triang = tf.concat( - [ - tf.zeros( - (batch_size * num_heads, 1, window_overlap, window_overlap), - dtype=diagonal_chunked_attention_scores.dtype, - ), - diagonal_chunked_attention_scores[:, :, -(window_overlap + 1) : -1, window_overlap + 1 :], - ], - axis=1, - ) - diagonal_attn_scores_first_chunk = tf.concat( - [ - tf.roll( - diagonal_chunked_attention_scores, - shift=[1, window_overlap], - axis=[2, 3], - )[:, :, :window_overlap, :window_overlap], - tf.zeros( - (batch_size * num_heads, 1, window_overlap, window_overlap), - dtype=diagonal_chunked_attention_scores.dtype, - ), - ], - axis=1, - ) - first_chunk_mask = ( - tf.tile( - tf.range(chunks_count + 1, dtype=tf.int64)[None, :, None, None], - (batch_size * num_heads, 1, window_overlap, window_overlap), - ) - < 1 - ) - diagonal_attn_scores_low_triang = tf.where( - first_chunk_mask, - diagonal_attn_scores_first_chunk, - diagonal_attn_scores_low_triang, - ) - - # merging upper and lower triangle - diagonal_attention_scores = tf.concat( - [diagonal_attn_scores_low_triang, diagonal_attn_scores_up_triang], axis=-1 - ) - - # separate batch_size and num_heads dimensions again - diagonal_attention_scores = tf.transpose( - tf.reshape( - diagonal_attention_scores, - (batch_size, num_heads, seq_len, 2 * window_overlap + 1), - ), - (0, 2, 1, 3), - ) - - diagonal_attention_scores = self._mask_invalid_locations(diagonal_attention_scores, window_overlap) - - return diagonal_attention_scores - - @staticmethod - def _mask_invalid_locations(input_tensor, window_overlap): - # create correct upper triangle bool mask - mask_2d_upper = tf.reverse( - tf.linalg.band_part(tf.ones(shape=(window_overlap, window_overlap + 1)), -1, 0), - axis=[0], - ) - - # pad to full matrix - padding = tf.convert_to_tensor( - [[0, shape_list(input_tensor)[1] - window_overlap], [0, shape_list(input_tensor)[3] - window_overlap - 1]] - ) - - # create lower mask - mask_2d = tf.pad(mask_2d_upper, padding) - - # combine with upper mask - mask_2d = mask_2d + tf.reverse(mask_2d, axis=[0, 1]) - - # broadcast to full matrix - mask_4d = tf.tile(mask_2d[None, :, None, :], (shape_list(input_tensor)[0], 1, 1, 1)) - - # inf tensor used for masking - inf_tensor = -float("inf") * tf.ones_like(input_tensor) - - # mask - input_tensor = tf.where(tf.math.greater(mask_4d, 0), inf_tensor, input_tensor) - - return input_tensor - - def _sliding_chunks_matmul_attn_probs_value(self, attn_probs, value, window_overlap): - """ - Same as _sliding_chunks_query_key_matmul but for attn_probs and value tensors. Returned tensor will be of the - same shape as `attn_probs` - """ - - batch_size, seq_len, num_heads, head_dim = shape_list(value) - - tf.debugging.assert_equal( - seq_len % (window_overlap * 2), 0, message="Seq_len has to be multiple of 2 * window_overlap" - ) - tf.debugging.assert_equal( - shape_list(attn_probs)[:3], - shape_list(value)[:3], - message="value and attn_probs must have same dims (except head_dim)", - ) - tf.debugging.assert_equal( - shape_list(attn_probs)[3], - 2 * window_overlap + 1, - message="attn_probs last dim has to be 2 * window_overlap + 1", - ) - - chunks_count = seq_len // window_overlap - 1 - - # group batch_size and num_heads dimensions into one, then chunk seq_len into chunks of size 2 window overlap - chunked_attn_probs = tf.reshape( - tf.transpose(attn_probs, (0, 2, 1, 3)), - ( - batch_size * num_heads, - seq_len // window_overlap, - window_overlap, - 2 * window_overlap + 1, - ), - ) - - # group batch_size and num_heads dimensions into one - value = tf.reshape( - tf.transpose(value, (0, 2, 1, 3)), - (batch_size * num_heads, seq_len, head_dim), - ) - - # pad seq_len with w at the beginning of the sequence and another window overlap at the end - paddings = tf.convert_to_tensor([[0, 0], [window_overlap, window_overlap], [0, 0]]) - padded_value = tf.pad(value, paddings, constant_values=-1) - - # chunk padded_value into chunks of size 3 window overlap and an overlap of size window overlap - frame_size = 3 * window_overlap * head_dim - frame_hop_size = (shape_list(padded_value)[1] * head_dim - frame_size) // chunks_count - chunked_value = tf.signal.frame( - tf.reshape(padded_value, (batch_size * num_heads, -1)), - frame_size, - frame_hop_size, - ) - chunked_value = tf.reshape( - chunked_value, - (batch_size * num_heads, chunks_count + 1, 3 * window_overlap, head_dim), - ) - - tf.debugging.assert_equal( - shape_list(chunked_value), - [batch_size * num_heads, chunks_count + 1, 3 * window_overlap, head_dim], - message="Chunked value has the wrong shape", - ) - - chunked_attn_probs = self._pad_and_diagonalize(chunked_attn_probs) - context = tf.einsum("bcwd,bcdh->bcwh", chunked_attn_probs, chunked_value) - context = tf.transpose( - tf.reshape(context, (batch_size, num_heads, seq_len, head_dim)), - (0, 2, 1, 3), - ) - - return context - - @staticmethod - def _pad_and_transpose_last_two_dims(hidden_states_padded, paddings): - """pads rows and then flips rows and columns""" - hidden_states_padded = tf.pad( - hidden_states_padded, paddings - ) # padding value is not important because it will be overwritten - batch_size, chunk_size, seq_length, hidden_dim = shape_list(hidden_states_padded) - hidden_states_padded = tf.reshape(hidden_states_padded, (batch_size, chunk_size, hidden_dim, seq_length)) - - return hidden_states_padded - - @staticmethod - def _pad_and_diagonalize(chunked_hidden_states): - """ - shift every row 1 step right, converting columns into diagonals. - - Example: - - ```python - chunked_hidden_states: [ - 0.4983, - 2.6918, - -0.0071, - 1.0492, - -1.8348, - 0.7672, - 0.2986, - 0.0285, - -0.7584, - 0.4206, - -0.0405, - 0.1599, - 2.0514, - -1.1600, - 0.5372, - 0.2629, - ] - window_overlap = num_rows = 4 - ``` - - (pad & diagonalize) => [ 0.4983, 2.6918, -0.0071, 1.0492, 0.0000, 0.0000, 0.0000 - 0.0000, -1.8348, 0.7672, 0.2986, 0.0285, 0.0000, 0.0000 0.0000, 0.0000, -0.7584, 0.4206, - -0.0405, 0.1599, 0.0000 0.0000, 0.0000, 0.0000, 2.0514, -1.1600, 0.5372, 0.2629 ] - """ - total_num_heads, num_chunks, window_overlap, hidden_dim = shape_list(chunked_hidden_states) - paddings = tf.convert_to_tensor([[0, 0], [0, 0], [0, 0], [0, window_overlap + 1]]) - chunked_hidden_states = tf.pad( - chunked_hidden_states, paddings - ) # total_num_heads x num_chunks x window_overlap x (hidden_dim+window_overlap+1). Padding value is not important because it'll be overwritten - chunked_hidden_states = tf.reshape( - chunked_hidden_states, (total_num_heads, num_chunks, -1) - ) # total_num_heads x num_chunks x window_overlapL+window_overlapwindow_overlap+window_overlap - chunked_hidden_states = chunked_hidden_states[ - :, :, :-window_overlap - ] # total_num_heads x num_chunks x window_overlapL+window_overlapwindow_overlap - chunked_hidden_states = tf.reshape( - chunked_hidden_states, - (total_num_heads, num_chunks, window_overlap, window_overlap + hidden_dim), - ) # total_num_heads x num_chunks, window_overlap x hidden_dim+window_overlap - chunked_hidden_states = chunked_hidden_states[:, :, :, :-1] - - return chunked_hidden_states - - @staticmethod - def _chunk(hidden_states, window_overlap): - """convert into overlapping chunks. Chunk size = 2w, overlap size = w""" - batch_size, seq_length, hidden_dim = shape_list(hidden_states) - num_output_chunks = 2 * (seq_length // (2 * window_overlap)) - 1 - - # define frame size and frame stride (similar to convolution) - frame_hop_size = window_overlap * hidden_dim - frame_size = 2 * frame_hop_size - hidden_states = tf.reshape(hidden_states, (batch_size, seq_length * hidden_dim)) - - # chunk with overlap - chunked_hidden_states = tf.signal.frame(hidden_states, frame_size, frame_hop_size) - - tf.debugging.assert_equal( - shape_list(chunked_hidden_states), - [batch_size, num_output_chunks, frame_size], - message=( - "Make sure chunking is correctly applied. `Chunked hidden states should have output dimension" - f" {[batch_size, frame_size, num_output_chunks]}, but got {shape_list(chunked_hidden_states)}." - ), - ) - - chunked_hidden_states = tf.reshape( - chunked_hidden_states, - (batch_size, num_output_chunks, 2 * window_overlap, hidden_dim), - ) - - return chunked_hidden_states - - @staticmethod - def _get_global_attn_indices(is_index_global_attn): - """compute global attn indices required throughout forward pass""" - # helper variable - num_global_attn_indices = tf.math.count_nonzero(is_index_global_attn, axis=1) - num_global_attn_indices = tf.cast(num_global_attn_indices, dtype=tf.constant(1).dtype) - - # max number of global attn indices in batch - max_num_global_attn_indices = tf.reduce_max(num_global_attn_indices) - - # indices of global attn - is_index_global_attn_nonzero = tf.where(is_index_global_attn) - - # helper variable - is_local_index_global_attn = tf.range(max_num_global_attn_indices) < tf.expand_dims( - num_global_attn_indices, axis=-1 - ) - - # location of the non-padding values within global attention indices - is_local_index_global_attn_nonzero = tf.where(is_local_index_global_attn) - - # location of the padding values within global attention indices - is_local_index_no_global_attn_nonzero = tf.where(tf.math.logical_not(is_local_index_global_attn)) - - return ( - max_num_global_attn_indices, - is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero, - ) - - def _concat_with_global_key_attn_probs( - self, - attn_scores, - key_vectors, - query_vectors, - max_num_global_attn_indices, - is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero, - ): - batch_size = shape_list(key_vectors)[0] - - # select global key vectors - global_key_vectors = tf.gather_nd(key_vectors, is_index_global_attn_nonzero) - - # create only global key vectors - key_vectors_only_global = tf.scatter_nd( - is_local_index_global_attn_nonzero, - global_key_vectors, - shape=( - batch_size, - max_num_global_attn_indices, - self.num_heads, - self.head_dim, - ), - ) - - # (batch_size, seq_len, num_heads, max_num_global_attn_indices) - attn_probs_from_global_key = tf.einsum("blhd,bshd->blhs", query_vectors, key_vectors_only_global) - - # (batch_size, max_num_global_attn_indices, seq_len, num_heads) - attn_probs_from_global_key_trans = tf.transpose(attn_probs_from_global_key, (0, 3, 1, 2)) - mask_shape = (shape_list(is_local_index_no_global_attn_nonzero)[0],) + tuple( - shape_list(attn_probs_from_global_key_trans)[-2:] - ) - mask = tf.ones(mask_shape) * -10000.0 - mask = tf.cast(mask, dtype=attn_probs_from_global_key_trans.dtype) - - # scatter mask - attn_probs_from_global_key_trans = tf.tensor_scatter_nd_update( - attn_probs_from_global_key_trans, - is_local_index_no_global_attn_nonzero, - mask, - ) - - # (batch_size, seq_len, num_heads, max_num_global_attn_indices) - attn_probs_from_global_key = tf.transpose(attn_probs_from_global_key_trans, (0, 2, 3, 1)) - - # concat to attn_probs - # (batch_size, seq_len, num_heads, extra attention count + 2*window+1) - attn_scores = tf.concat((attn_probs_from_global_key, attn_scores), axis=-1) - - return attn_scores - - def _compute_attn_output_with_global_indices( - self, - value_vectors, - attn_probs, - max_num_global_attn_indices, - is_index_global_attn_nonzero, - is_local_index_global_attn_nonzero, - ): - batch_size = shape_list(attn_probs)[0] - - # cut local attn probs to global only - attn_probs_only_global = attn_probs[:, :, :, :max_num_global_attn_indices] - - # select global value vectors - global_value_vectors = tf.gather_nd(value_vectors, is_index_global_attn_nonzero) - - # create only global value vectors - value_vectors_only_global = tf.scatter_nd( - is_local_index_global_attn_nonzero, - global_value_vectors, - shape=( - batch_size, - max_num_global_attn_indices, - self.num_heads, - self.head_dim, - ), - ) - - # compute attn output only global - attn_output_only_global = tf.einsum("blhs,bshd->blhd", attn_probs_only_global, value_vectors_only_global) - - # reshape attn probs - attn_probs_without_global = attn_probs[:, :, :, max_num_global_attn_indices:] - - # compute attn output with global - attn_output_without_global = self._sliding_chunks_matmul_attn_probs_value( - attn_probs_without_global, value_vectors, self.one_sided_attn_window_size - ) - - return attn_output_only_global + attn_output_without_global - - def _compute_global_attn_output_from_hidden( - self, - attn_output, - hidden_states, - max_num_global_attn_indices, - layer_head_mask, - is_local_index_global_attn_nonzero, - is_index_global_attn_nonzero, - is_local_index_no_global_attn_nonzero, - is_index_masked, - training, - ): - batch_size, seq_len = shape_list(hidden_states)[:2] - - # prepare global hidden states - global_attn_hidden_states = tf.gather_nd(hidden_states, is_index_global_attn_nonzero) - global_attn_hidden_states = tf.scatter_nd( - is_local_index_global_attn_nonzero, - global_attn_hidden_states, - shape=(batch_size, max_num_global_attn_indices, self.embed_dim), - ) - - # global key, query, value - global_query_vectors_only_global = self.query_global(global_attn_hidden_states) - global_key_vectors = self.key_global(hidden_states) - global_value_vectors = self.value_global(hidden_states) - - # normalize - global_query_vectors_only_global /= tf.math.sqrt( - tf.cast(self.head_dim, dtype=global_query_vectors_only_global.dtype) - ) - global_query_vectors_only_global = self.reshape_and_transpose(global_query_vectors_only_global, batch_size) - global_key_vectors = self.reshape_and_transpose(global_key_vectors, batch_size) - global_value_vectors = self.reshape_and_transpose(global_value_vectors, batch_size) - - # compute attn scores - global_attn_scores = tf.matmul(global_query_vectors_only_global, global_key_vectors, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(global_attn_scores), - [batch_size * self.num_heads, max_num_global_attn_indices, seq_len], - message=( - "global_attn_scores have the wrong size. Size should be" - f" {(batch_size * self.num_heads, max_num_global_attn_indices, seq_len)}, but is" - f" {shape_list(global_attn_scores)}." - ), - ) - - global_attn_scores = tf.reshape( - global_attn_scores, - (batch_size, self.num_heads, max_num_global_attn_indices, seq_len), - ) - global_attn_scores_trans = tf.transpose(global_attn_scores, (0, 2, 1, 3)) - mask_shape = (shape_list(is_local_index_no_global_attn_nonzero)[0],) + tuple( - shape_list(global_attn_scores_trans)[-2:] - ) - global_attn_mask = tf.ones(mask_shape) * -10000.0 - global_attn_mask = tf.cast(global_attn_mask, dtype=global_attn_scores_trans.dtype) - - # scatter mask - global_attn_scores_trans = tf.tensor_scatter_nd_update( - global_attn_scores_trans, - is_local_index_no_global_attn_nonzero, - global_attn_mask, - ) - global_attn_scores = tf.transpose(global_attn_scores_trans, (0, 2, 1, 3)) - - # mask global attn scores - attn_mask = tf.tile(is_index_masked[:, None, None, :], (1, shape_list(global_attn_scores)[1], 1, 1)) - global_attn_scores = tf.where(attn_mask, -10000.0, global_attn_scores) - global_attn_scores = tf.reshape( - global_attn_scores, - (batch_size * self.num_heads, max_num_global_attn_indices, seq_len), - ) - - # compute global attn probs - global_attn_probs_float = stable_softmax(global_attn_scores, axis=-1) - - # apply layer head masking - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - global_attn_probs_float = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - global_attn_probs_float, (batch_size, self.num_heads, max_num_global_attn_indices, seq_len) - ) - global_attn_probs_float = tf.reshape( - global_attn_probs_float, (batch_size * self.num_heads, max_num_global_attn_indices, seq_len) - ) - - # dropout - global_attn_probs = self.global_dropout(global_attn_probs_float, training=training) - - # global attn output - global_attn_output = tf.matmul(global_attn_probs, global_value_vectors) - - tf.debugging.assert_equal( - shape_list(global_attn_output), - [batch_size * self.num_heads, max_num_global_attn_indices, self.head_dim], - message=( - "global_attn_output tensor has the wrong size. Size should be" - f" {(batch_size * self.num_heads, max_num_global_attn_indices, self.head_dim)}, but is" - f" {shape_list(global_attn_output)}." - ), - ) - - global_attn_output = tf.reshape( - global_attn_output, - (batch_size, self.num_heads, max_num_global_attn_indices, self.head_dim), - ) - - # get only non zero global attn output - nonzero_global_attn_output = tf.gather_nd( - tf.transpose(global_attn_output, (0, 2, 1, 3)), - is_local_index_global_attn_nonzero, - ) - nonzero_global_attn_output = tf.reshape( - nonzero_global_attn_output, - (shape_list(is_local_index_global_attn_nonzero)[0], -1), - ) - - # overwrite values with global attention - attn_output = tf.tensor_scatter_nd_update( - attn_output, is_index_global_attn_nonzero, nonzero_global_attn_output - ) - - global_attn_probs = tf.reshape( - global_attn_probs, (batch_size, self.num_heads, max_num_global_attn_indices, seq_len) - ) - - return attn_output, global_attn_probs - - def reshape_and_transpose(self, vector, batch_size): - return tf.reshape( - tf.transpose( - tf.reshape(vector, (batch_size, -1, self.num_heads, self.head_dim)), - (0, 2, 1, 3), - ), - (batch_size * self.num_heads, -1, self.head_dim), - ) - - -class TFLongformerAttention(keras.layers.Layer): - def __init__(self, config, layer_id=0, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFLongformerSelfAttention(config, layer_id, name="self") - self.dense_output = TFLongformerSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call(self, inputs, training=False): - ( - hidden_states, - attention_mask, - layer_head_mask, - is_index_masked, - is_index_global_attn, - is_global_attn, - ) = inputs - - self_outputs = self.self_attention( - [hidden_states, attention_mask, layer_head_mask, is_index_masked, is_index_global_attn, is_global_attn], - training=training, - ) - attention_output = self.dense_output(self_outputs[0], hidden_states, training=training) - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -class TFLongformerLayer(keras.layers.Layer): - def __init__(self, config, layer_id=0, **kwargs): - super().__init__(**kwargs) - - self.attention = TFLongformerAttention(config, layer_id, name="attention") - self.intermediate = TFLongformerIntermediate(config, name="intermediate") - self.longformer_output = TFLongformerOutput(config, name="output") - - def call(self, inputs, training=False): - ( - hidden_states, - attention_mask, - layer_head_mask, - is_index_masked, - is_index_global_attn, - is_global_attn, - ) = inputs - - attention_outputs = self.attention( - [hidden_states, attention_mask, layer_head_mask, is_index_masked, is_index_global_attn, is_global_attn], - training=training, - ) - attention_output = attention_outputs[0] - intermediate_output = self.intermediate(attention_output) - layer_output = self.longformer_output(intermediate_output, attention_output, training=training) - outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "longformer_output", None) is not None: - with tf.name_scope(self.longformer_output.name): - self.longformer_output.build(None) - - -class TFLongformerEncoder(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.output_hidden_states = config.output_hidden_states - self.output_attentions = config.output_attentions - self.layer = [TFLongformerLayer(config, i, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states, - attention_mask=None, - head_mask=None, - padding_len=0, - is_index_masked=None, - is_index_global_attn=None, - is_global_attn=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - all_hidden_states = () if output_hidden_states else None - all_attentions = all_global_attentions = () if output_attentions else None - - for idx, layer_module in enumerate(self.layer): - if output_hidden_states: - hidden_states_to_add = hidden_states[:, :-padding_len] if padding_len > 0 else hidden_states - all_hidden_states = all_hidden_states + (hidden_states_to_add,) - - layer_outputs = layer_module( - [ - hidden_states, - attention_mask, - head_mask[idx] if head_mask is not None else None, - is_index_masked, - is_index_global_attn, - is_global_attn, - ], - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - # bzs x seq_len x num_attn_heads x (num_global_attn + attention_window_len + 1) => bzs x num_attn_heads x seq_len x (num_global_attn + attention_window_len + 1) - all_attentions = all_attentions + (tf.transpose(layer_outputs[1], (0, 2, 1, 3)),) - - # bzs x num_attn_heads x num_global_attn x seq_len => bzs x num_attn_heads x seq_len x num_global_attn - all_global_attentions = all_global_attentions + (tf.transpose(layer_outputs[2], (0, 1, 3, 2)),) - - # Add last layer - if output_hidden_states: - hidden_states_to_add = hidden_states[:, :-padding_len] if padding_len > 0 else hidden_states - all_hidden_states = all_hidden_states + (hidden_states_to_add,) - - # undo padding - # unpad `hidden_states` because the calling function is expecting a length == input_ids.size(1) - hidden_states = hidden_states[:, :-padding_len] if padding_len > 0 else hidden_states - if output_attentions: - all_attentions = ( - tuple(state[:, :, :-padding_len, :] for state in all_attentions) if padding_len > 0 else all_attentions - ) - - if not return_dict: - return tuple( - v for v in [hidden_states, all_hidden_states, all_attentions, all_global_attentions] if v is not None - ) - - return TFLongformerBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - global_attentions=all_global_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFLongformerMainLayer(keras.layers.Layer): - config_class = LongformerConfig - - def __init__(self, config, add_pooling_layer=True, **kwargs): - super().__init__(**kwargs) - - if isinstance(config.attention_window, int): - assert config.attention_window % 2 == 0, "`config.attention_window` has to be an even value" - assert config.attention_window > 0, "`config.attention_window` has to be positive" - config.attention_window = [config.attention_window] * config.num_hidden_layers # one value per layer - else: - assert len(config.attention_window) == config.num_hidden_layers, ( - "`len(config.attention_window)` should equal `config.num_hidden_layers`. " - f"Expected {config.num_hidden_layers}, given {len(config.attention_window)}" - ) - - self.config = config - self.num_hidden_layers = config.num_hidden_layers - self.initializer_range = config.initializer_range - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - self.pad_token_id = config.pad_token_id - self.attention_window = config.attention_window - self.embeddings = TFLongformerEmbeddings(config, name="embeddings") - self.encoder = TFLongformerEncoder(config, name="encoder") - self.pooler = TFLongformerPooler(config, name="pooler") if add_pooling_layer else None - - def get_input_embeddings(self): - return self.embeddings - - def set_input_embeddings(self, value): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - head_mask=None, - global_attention_mask=None, - token_type_ids=None, - position_ids=None, - inputs_embeds=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - if input_ids is not None and not isinstance(input_ids, tf.Tensor): - input_ids = tf.convert_to_tensor(input_ids, dtype=tf.int64) - elif input_ids is not None: - input_ids = tf.cast(input_ids, tf.int64) - - if attention_mask is not None and not isinstance(attention_mask, tf.Tensor): - attention_mask = tf.convert_to_tensor(attention_mask, dtype=tf.int64) - elif attention_mask is not None: - attention_mask = tf.cast(attention_mask, tf.int64) - - if global_attention_mask is not None and not isinstance(global_attention_mask, tf.Tensor): - global_attention_mask = tf.convert_to_tensor(global_attention_mask, dtype=tf.int64) - elif global_attention_mask is not None: - global_attention_mask = tf.cast(global_attention_mask, tf.int64) - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.cast(tf.fill(input_shape, 1), tf.int64) - - if token_type_ids is None: - token_type_ids = tf.cast(tf.fill(input_shape, 0), tf.int64) - - # merge `global_attention_mask` and `attention_mask` - if global_attention_mask is not None: - attention_mask = self._merge_to_attention_mask(attention_mask, global_attention_mask) - - ( - padding_len, - input_ids, - attention_mask, - token_type_ids, - position_ids, - inputs_embeds, - ) = self._pad_to_window_size( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - pad_token_id=self.pad_token_id, - ) - - # is index masked or global attention - is_index_masked = tf.math.less(attention_mask, 1) - is_index_global_attn = tf.math.greater(attention_mask, 1) - is_global_attn = tf.math.reduce_any(is_index_global_attn) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, to_seq_length, 1, 1] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - extended_attention_mask = tf.reshape(attention_mask, (attention_mask_shape[0], attention_mask_shape[1], 1, 1)) - - # Since attention_mask is 1.0 for positions we want to attend locally and 0.0 for - # masked and global attn positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(tf.math.abs(1 - extended_attention_mask), tf.dtypes.float32) * -10000.0 - embedding_output = self.embeddings( - input_ids, - position_ids, - token_type_ids, - inputs_embeds, - training=training, - ) - encoder_outputs = self.encoder( - embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - padding_len=padding_len, - is_index_masked=is_index_masked, - is_index_global_attn=is_index_global_attn, - is_global_attn=is_global_attn, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFLongformerBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - global_attentions=encoder_outputs.global_attentions, - ) - - def _pad_to_window_size( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - inputs_embeds, - pad_token_id, - ): - """A helper function to pad tokens and mask to work with implementation of Longformer selfattention.""" - # padding - attention_window = ( - self.attention_window if isinstance(self.attention_window, int) else max(self.attention_window) - ) - - assert attention_window % 2 == 0, f"`attention_window` should be an even value. Given {attention_window}" - - input_shape = shape_list(input_ids) if input_ids is not None else shape_list(inputs_embeds) - batch_size, seq_len = input_shape[:2] - padding_len = (attention_window - seq_len % attention_window) % attention_window - - paddings = tf.convert_to_tensor([[0, 0], [0, padding_len]]) - - if input_ids is not None: - input_ids = tf.pad(input_ids, paddings, constant_values=pad_token_id) - - if position_ids is not None: - # pad with position_id = pad_token_id as in modeling_roberta.RobertaEmbeddings - position_ids = tf.pad(position_ids, paddings, constant_values=pad_token_id) - - if inputs_embeds is not None: - if padding_len > 0: - input_ids_padding = tf.cast(tf.fill((batch_size, padding_len), self.pad_token_id), tf.int64) - inputs_embeds_padding = self.embeddings(input_ids_padding) - inputs_embeds = tf.concat([inputs_embeds, inputs_embeds_padding], axis=-2) - - attention_mask = tf.pad(attention_mask, paddings, constant_values=False) # no attention on the padding tokens - token_type_ids = tf.pad(token_type_ids, paddings, constant_values=0) # pad with token_type_id = 0 - - return ( - padding_len, - input_ids, - attention_mask, - token_type_ids, - position_ids, - inputs_embeds, - ) - - @staticmethod - def _merge_to_attention_mask(attention_mask: tf.Tensor, global_attention_mask: tf.Tensor): - # longformer self attention expects attention mask to have 0 (no attn), 1 (local attn), 2 (global attn) - # (global_attention_mask + 1) => 1 for local attention, 2 for global attention - # => final attention_mask => 0 for no attention, 1 for local attention 2 for global attention - if attention_mask is not None: - attention_mask = attention_mask * (global_attention_mask + 1) - else: - # simply use `global_attention_mask` as `attention_mask` - # if no `attention_mask` is given - attention_mask = global_attention_mask + 1 - - return attention_mask - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -class TFLongformerPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = LongformerConfig - base_model_prefix = "longformer" - - @property - def input_signature(self): - sig = super().input_signature - sig["global_attention_mask"] = tf.TensorSpec((None, None), tf.int32, name="global_attention_mask") - return sig - - -LONGFORMER_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`LongformerConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - - -LONGFORMER_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`np.ndarray` or `tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - global_attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to decide the attention given on each token, local attention or global attention. Tokens with global - attention attends to all other tokens, and all other tokens attend to them. This is important for - task-specific finetuning because it makes the model more flexible at representing the task. For example, - for classification, the token should be given global attention. For QA, all question tokens should also - have global attention. Please refer to the [Longformer paper](https://huggingface.co/papers/2004.05150) for more - details. Mask values selected in `[0, 1]`: - - - 0 for local attention (a sliding window attention), - - 1 for global attention (tokens that attend to all other tokens, and all other tokens attend to them). - - token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare Longformer Model outputting raw hidden-states without any specific head on top.", - LONGFORMER_START_DOCSTRING, -) -class TFLongformerModel(TFLongformerPreTrainedModel): - """ - - This class copies code from [`TFRobertaModel`] and overwrites standard self-attention with longformer - self-attention to provide the ability to process long sequences following the self-attention approach described in - [Longformer: the Long-Document Transformer](https://huggingface.co/papers/2004.05150) by Iz Beltagy, Matthew E. Peters, and - Arman Cohan. Longformer self-attention combines a local (sliding window) and global attention to extend to long - documents without the O(n^2) increase in memory and compute. - - The self-attention module `TFLongformerSelfAttention` implemented here supports the combination of local and global - attention but it lacks support for autoregressive attention and dilated attention. Autoregressive and dilated - attention are more relevant for autoregressive language modeling than finetuning on downstream tasks. Future - release will add support for autoregressive attention, but the support for dilated attention requires a custom CUDA - kernel to be memory and compute efficient. - - """ - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.longformer = TFLongformerMainLayer(config, name="longformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(LONGFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - global_attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFLongformerBaseModelOutputWithPooling | tuple[tf.Tensor]: - outputs = self.longformer( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - global_attention_mask=global_attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "longformer", None) is not None: - with tf.name_scope(self.longformer.name): - self.longformer.build(None) - - -@add_start_docstrings( - """Longformer Model with a `language modeling` head on top.""", - LONGFORMER_START_DOCSTRING, -) -class TFLongformerForMaskedLM(TFLongformerPreTrainedModel, TFMaskedLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.longformer = TFLongformerMainLayer(config, add_pooling_layer=False, name="longformer") - self.lm_head = TFLongformerLMHead(config, self.longformer.embeddings, name="lm_head") - - def get_lm_head(self): - return self.lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(LONGFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="allenai/longformer-base-4096", - output_type=TFLongformerMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - mask="", - expected_output="' Paris'", - expected_loss=0.44, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - global_attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFLongformerMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - - outputs = self.longformer( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - global_attention_mask=global_attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.lm_head(sequence_output, training=training) - loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - - return ((loss,) + output) if loss is not None else output - - return TFLongformerMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - global_attentions=outputs.global_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "longformer", None) is not None: - with tf.name_scope(self.longformer.name): - self.longformer.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -@add_start_docstrings( - """ - Longformer Model with a span classification head on top for extractive question-answering tasks like SQuAD / - TriviaQA (a linear layer on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - LONGFORMER_START_DOCSTRING, -) -class TFLongformerForQuestionAnswering(TFLongformerPreTrainedModel, TFQuestionAnsweringLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.longformer = TFLongformerMainLayer(config, add_pooling_layer=False, name="longformer") - self.qa_outputs = keras.layers.Dense( - config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="qa_outputs", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(LONGFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="allenai/longformer-large-4096-finetuned-triviaqa", - output_type=TFLongformerQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="' puppet'", - expected_loss=0.96, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - global_attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFLongformerQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (*sequence_length*). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (*sequence_length*). Position outside of the sequence - are not taken into account for computing the loss. - """ - - if input_ids is not None and not isinstance(input_ids, tf.Tensor): - input_ids = tf.convert_to_tensor(input_ids, dtype=tf.int64) - elif input_ids is not None: - input_ids = tf.cast(input_ids, tf.int64) - - if attention_mask is not None and not isinstance(attention_mask, tf.Tensor): - attention_mask = tf.convert_to_tensor(attention_mask, dtype=tf.int64) - elif attention_mask is not None: - attention_mask = tf.cast(attention_mask, tf.int64) - - if global_attention_mask is not None and not isinstance(global_attention_mask, tf.Tensor): - global_attention_mask = tf.convert_to_tensor(global_attention_mask, dtype=tf.int64) - elif global_attention_mask is not None: - global_attention_mask = tf.cast(global_attention_mask, tf.int64) - - # set global attention on question tokens - if global_attention_mask is None and input_ids is not None: - if shape_list(tf.where(input_ids == self.config.sep_token_id))[0] != 3 * shape_list(input_ids)[0]: - logger.warning( - f"There should be exactly three separator tokens: {self.config.sep_token_id} in every sample for" - " questions answering. You might also consider to set `global_attention_mask` manually in the" - " forward function to avoid this. This is most likely an error. The global attention is disabled" - " for this forward pass." - ) - global_attention_mask = tf.cast(tf.fill(shape_list(input_ids), value=0), tf.int64) - else: - logger.warning_once("Initializing global attention on question tokens...") - # put global attention on all tokens until `config.sep_token_id` is reached - sep_token_indices = tf.where(input_ids == self.config.sep_token_id) - sep_token_indices = tf.cast(sep_token_indices, dtype=tf.int64) - global_attention_mask = _compute_global_attention_mask(shape_list(input_ids), sep_token_indices) - - outputs = self.longformer( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - global_attention_mask=global_attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - - return ((loss,) + output) if loss is not None else output - - return TFLongformerQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - global_attentions=outputs.global_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "longformer", None) is not None: - with tf.name_scope(self.longformer.name): - self.longformer.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -class TFLongformerClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.out_proj = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="out_proj" - ) - self.config = config - - def call(self, hidden_states, training=False): - hidden_states = hidden_states[:, 0, :] # take token (equiv. to [CLS]) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - output = self.out_proj(hidden_states) - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Longformer Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - LONGFORMER_START_DOCSTRING, -) -class TFLongformerForSequenceClassification(TFLongformerPreTrainedModel, TFSequenceClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.longformer = TFLongformerMainLayer(config, add_pooling_layer=False, name="longformer") - self.classifier = TFLongformerClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(LONGFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFLongformerSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - global_attention_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFLongformerSequenceClassifierOutput | tuple[tf.Tensor]: - if input_ids is not None and not isinstance(input_ids, tf.Tensor): - input_ids = tf.convert_to_tensor(input_ids, dtype=tf.int64) - elif input_ids is not None: - input_ids = tf.cast(input_ids, tf.int64) - - if attention_mask is not None and not isinstance(attention_mask, tf.Tensor): - attention_mask = tf.convert_to_tensor(attention_mask, dtype=tf.int64) - elif attention_mask is not None: - attention_mask = tf.cast(attention_mask, tf.int64) - - if global_attention_mask is not None and not isinstance(global_attention_mask, tf.Tensor): - global_attention_mask = tf.convert_to_tensor(global_attention_mask, dtype=tf.int64) - elif global_attention_mask is not None: - global_attention_mask = tf.cast(global_attention_mask, tf.int64) - - if global_attention_mask is None and input_ids is not None: - logger.warning_once("Initializing global attention on CLS token...") - # global attention on cls token - global_attention_mask = tf.zeros_like(input_ids) - updates = tf.ones(shape_list(input_ids)[0], dtype=tf.int64) - indices = tf.pad( - tensor=tf.expand_dims(tf.range(shape_list(input_ids)[0], dtype=tf.int64), axis=1), - paddings=[[0, 0], [0, 1]], - constant_values=0, - ) - global_attention_mask = tf.tensor_scatter_nd_update( - global_attention_mask, - indices, - updates, - ) - - outputs = self.longformer( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - global_attention_mask=global_attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFLongformerSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - global_attentions=outputs.global_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "longformer", None) is not None: - with tf.name_scope(self.longformer.name): - self.longformer.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - Longformer Model with a multiple choice classification head on top (a linear layer on top of the pooled output and - a softmax) e.g. for RocStories/SWAG tasks. - """, - LONGFORMER_START_DOCSTRING, -) -class TFLongformerForMultipleChoice(TFLongformerPreTrainedModel, TFMultipleChoiceLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.longformer = TFLongformerMainLayer(config, name="longformer") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @property - def input_signature(self): - return { - "input_ids": tf.TensorSpec((None, None, None), tf.int32, name="input_ids"), - "attention_mask": tf.TensorSpec((None, None, None), tf.int32, name="attention_mask"), - "global_attention_mask": tf.TensorSpec((None, None, None), tf.int32, name="global_attention_mask"), - } - - @unpack_inputs - @add_start_docstrings_to_model_forward( - LONGFORMER_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") - ) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFLongformerMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - global_attention_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFLongformerMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - flat_global_attention_mask = ( - tf.reshape(global_attention_mask, (-1, shape_list(global_attention_mask)[-1])) - if global_attention_mask is not None - else None - ) - flat_inputs_embeds = ( - tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - - outputs = self.longformer( - flat_input_ids, - position_ids=flat_position_ids, - token_type_ids=flat_token_type_ids, - attention_mask=flat_attention_mask, - head_mask=head_mask, - global_attention_mask=flat_global_attention_mask, - inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - - pooled_output = self.dropout(pooled_output) - logits = self.classifier(pooled_output) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFLongformerMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - global_attentions=outputs.global_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "longformer", None) is not None: - with tf.name_scope(self.longformer.name): - self.longformer.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Longformer Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. - for Named-Entity-Recognition (NER) tasks. - """, - LONGFORMER_START_DOCSTRING, -) -class TFLongformerForTokenClassification(TFLongformerPreTrainedModel, TFTokenClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.longformer = TFLongformerMainLayer(config=config, add_pooling_layer=False, name="longformer") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(LONGFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFLongformerTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - global_attention_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.array | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFLongformerTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - - outputs = self.longformer( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - global_attention_mask=global_attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - sequence_output = self.dropout(sequence_output) - logits = self.classifier(sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFLongformerTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - global_attentions=outputs.global_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "longformer", None) is not None: - with tf.name_scope(self.longformer.name): - self.longformer.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFLongformerForMaskedLM", - "TFLongformerForMultipleChoice", - "TFLongformerForQuestionAnswering", - "TFLongformerForSequenceClassification", - "TFLongformerForTokenClassification", - "TFLongformerModel", - "TFLongformerPreTrainedModel", - "TFLongformerSelfAttention", -] diff --git a/src/transformers/models/longt5/__init__.py b/src/transformers/models/longt5/__init__.py index 2716e62cd7b2..9821ef87bc36 100644 --- a/src/transformers/models/longt5/__init__.py +++ b/src/transformers/models/longt5/__init__.py @@ -19,7 +19,6 @@ if TYPE_CHECKING: from .configuration_longt5 import * - from .modeling_flax_longt5 import * from .modeling_longt5 import * else: import sys diff --git a/src/transformers/models/longt5/configuration_longt5.py b/src/transformers/models/longt5/configuration_longt5.py index 245e9948a1ae..b4833f4394e7 100644 --- a/src/transformers/models/longt5/configuration_longt5.py +++ b/src/transformers/models/longt5/configuration_longt5.py @@ -26,7 +26,7 @@ class LongT5Config(PretrainedConfig): r""" - This is the configuration class to store the configuration of a [`LongT5Model`] or a [`FlaxLongT5Model`]. It is + This is the configuration class to store the configuration of a [`LongT5Model`]. It is used to instantiate a LongT5 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 LongT5 [google/long-t5-local-base](https://huggingface.co/google/long-t5-local-base) architecture. diff --git a/src/transformers/models/longt5/convert_longt5x_checkpoint_to_flax.py b/src/transformers/models/longt5/convert_longt5x_checkpoint_to_flax.py deleted file mode 100644 index d99797107363..000000000000 --- a/src/transformers/models/longt5/convert_longt5x_checkpoint_to_flax.py +++ /dev/null @@ -1,215 +0,0 @@ -# coding=utf-8 -# Copyright 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. - -"""Convert T5/LongT5X checkpoints from the original repository to JAX/FLAX model. This script is an extension of -'src/transformers/models/t5/convert_t5x_checkpoint_to_flax. -""" - -import argparse - -from t5x import checkpoints - -from transformers import AutoConfig, FlaxAutoModelForSeq2SeqLM - - -def convert_t5x_checkpoint_to_flax(t5x_checkpoint_path, config_name, flax_dump_folder_path): - config = AutoConfig.from_pretrained(config_name) - flax_model = FlaxAutoModelForSeq2SeqLM.from_config(config=config) - t5x_model = checkpoints.load_t5x_checkpoint(t5x_checkpoint_path) - - split_mlp_wi = "wi_0" in t5x_model["target"]["encoder"]["layers_0"]["mlp"] - - if config.model_type == "t5": - encoder_attn_name = "SelfAttention" - if config.model_type == "longt5" and config.encoder_attention_type == "local": - encoder_attn_name = "LocalSelfAttention" - elif config.model_type == "longt5" and config.encoder_attention_type == "transient-global": - encoder_attn_name = "TransientGlobalSelfAttention" - else: - raise ValueError( - "Given config is expected to have `model_type='t5'`, or `model_type='longt5` with `encoder_attention_type`" - " attribute with a value from ['local', 'transient-global]." - ) - - # Encoder - for layer_index in range(config.num_layers): - layer_name = f"layers_{str(layer_index)}" - - # Self-Attention - t5x_attention_key = t5x_model["target"]["encoder"][layer_name]["attention"]["key"]["kernel"] - t5x_attention_out = t5x_model["target"]["encoder"][layer_name]["attention"]["out"]["kernel"] - t5x_attention_query = t5x_model["target"]["encoder"][layer_name]["attention"]["query"]["kernel"] - t5x_attention_value = t5x_model["target"]["encoder"][layer_name]["attention"]["value"]["kernel"] - - # Global input layer norm - if config.model_type == "longt5" and config.encoder_attention_type == "transient-global": - t5x_global_layer_norm = t5x_model["target"]["encoder"][layer_name]["attention"]["T5LayerNorm_0"]["scale"] - - # Layer Normalization - t5x_attention_layer_norm = t5x_model["target"]["encoder"][layer_name]["pre_attention_layer_norm"]["scale"] - - if split_mlp_wi: - t5x_mlp_wi_0 = t5x_model["target"]["encoder"][layer_name]["mlp"]["wi_0"]["kernel"] - t5x_mlp_wi_1 = t5x_model["target"]["encoder"][layer_name]["mlp"]["wi_1"]["kernel"] - else: - t5x_mlp_wi = t5x_model["target"]["encoder"][layer_name]["mlp"]["wi"]["kernel"] - - t5x_mlp_wo = t5x_model["target"]["encoder"][layer_name]["mlp"]["wo"]["kernel"] - - # Layer Normalization - t5x_mlp_layer_norm = t5x_model["target"]["encoder"][layer_name]["pre_mlp_layer_norm"]["scale"] - - # Assigning - flax_model_encoder_layer_block = flax_model.params["encoder"]["block"][str(layer_index)]["layer"] - flax_model_encoder_layer_block["0"][encoder_attn_name]["k"]["kernel"] = t5x_attention_key - flax_model_encoder_layer_block["0"][encoder_attn_name]["o"]["kernel"] = t5x_attention_out - flax_model_encoder_layer_block["0"][encoder_attn_name]["q"]["kernel"] = t5x_attention_query - flax_model_encoder_layer_block["0"][encoder_attn_name]["v"]["kernel"] = t5x_attention_value - - flax_model_encoder_layer_block["0"]["layer_norm"]["weight"] = t5x_attention_layer_norm - - # Global input layer norm - if config.model_type == "longt5" and config.encoder_attention_type == "transient-global": - flax_model_encoder_layer_block["0"][encoder_attn_name]["global_input_layer_norm"]["weight"] = ( - t5x_global_layer_norm - ) - - if split_mlp_wi: - flax_model_encoder_layer_block["1"]["DenseReluDense"]["wi_0"]["kernel"] = t5x_mlp_wi_0 - flax_model_encoder_layer_block["1"]["DenseReluDense"]["wi_1"]["kernel"] = t5x_mlp_wi_1 - else: - flax_model_encoder_layer_block["1"]["DenseReluDense"]["wi"]["kernel"] = t5x_mlp_wi - - flax_model_encoder_layer_block["1"]["DenseReluDense"]["wo"]["kernel"] = t5x_mlp_wo - flax_model_encoder_layer_block["1"]["layer_norm"]["weight"] = t5x_mlp_layer_norm - - flax_model.params["encoder"]["block"][str(layer_index)]["layer"] = flax_model_encoder_layer_block - - # Only for layer 0: - t5x_encoder_rel_embedding = t5x_model["target"]["encoder"]["relpos_bias"]["rel_embedding"].T - flax_model.params["encoder"]["block"]["0"]["layer"]["0"][encoder_attn_name]["relative_attention_bias"][ - "embedding" - ] = t5x_encoder_rel_embedding - - # Side/global relative position_bias + layer norm - if config.model_type == "longt5" and config.encoder_attention_type == "transient-global": - t5x_encoder_global_rel_embedding = t5x_model["target"]["encoder"]["side_relpos_bias"]["rel_embedding"].T - flax_model.params["encoder"]["block"]["0"]["layer"]["0"][encoder_attn_name]["global_relative_attention_bias"][ - "embedding" - ] = t5x_encoder_global_rel_embedding - - # Assigning - t5x_encoder_norm = t5x_model["target"]["encoder"]["encoder_norm"]["scale"] - flax_model.params["encoder"]["final_layer_norm"]["weight"] = t5x_encoder_norm - - # Decoder - for layer_index in range(config.num_layers): - layer_name = f"layers_{str(layer_index)}" - - # Self-Attention - t5x_attention_key = t5x_model["target"]["decoder"][layer_name]["self_attention"]["key"]["kernel"] - t5x_attention_out = t5x_model["target"]["decoder"][layer_name]["self_attention"]["out"]["kernel"] - t5x_attention_query = t5x_model["target"]["decoder"][layer_name]["self_attention"]["query"]["kernel"] - t5x_attention_value = t5x_model["target"]["decoder"][layer_name]["self_attention"]["value"]["kernel"] - - # Layer Normalization - t5x_pre_attention_layer_norm = t5x_model["target"]["decoder"][layer_name]["pre_self_attention_layer_norm"][ - "scale" - ] - - # Encoder-Decoder-Attention - t5x_enc_dec_attention_module = t5x_model["target"]["decoder"][layer_name]["encoder_decoder_attention"] - t5x_enc_dec_attention_key = t5x_enc_dec_attention_module["key"]["kernel"] - t5x_enc_dec_attention_out = t5x_enc_dec_attention_module["out"]["kernel"] - t5x_enc_dec_attention_query = t5x_enc_dec_attention_module["query"]["kernel"] - t5x_enc_dec_attention_value = t5x_enc_dec_attention_module["value"]["kernel"] - - # Layer Normalization - t5x_cross_layer_norm = t5x_model["target"]["decoder"][layer_name]["pre_cross_attention_layer_norm"]["scale"] - - # MLP - if split_mlp_wi: - t5x_mlp_wi_0 = t5x_model["target"]["decoder"][layer_name]["mlp"]["wi_0"]["kernel"] - t5x_mlp_wi_1 = t5x_model["target"]["decoder"][layer_name]["mlp"]["wi_1"]["kernel"] - else: - t5x_mlp_wi = t5x_model["target"]["decoder"][layer_name]["mlp"]["wi"]["kernel"] - - t5x_mlp_wo = t5x_model["target"]["decoder"][layer_name]["mlp"]["wo"]["kernel"] - - # Layer Normalization - tx5_mlp_layer_norm = t5x_model["target"]["decoder"][layer_name]["pre_mlp_layer_norm"]["scale"] - - # Assigning - flax_model_decoder_layer_block = flax_model.params["decoder"]["block"][str(layer_index)]["layer"] - flax_model_decoder_layer_block["0"]["SelfAttention"]["k"]["kernel"] = t5x_attention_key - flax_model_decoder_layer_block["0"]["SelfAttention"]["o"]["kernel"] = t5x_attention_out - flax_model_decoder_layer_block["0"]["SelfAttention"]["q"]["kernel"] = t5x_attention_query - flax_model_decoder_layer_block["0"]["SelfAttention"]["v"]["kernel"] = t5x_attention_value - - flax_model_decoder_layer_block["0"]["layer_norm"]["weight"] = t5x_pre_attention_layer_norm - - flax_model_decoder_layer_block["1"]["EncDecAttention"]["k"]["kernel"] = t5x_enc_dec_attention_key - flax_model_decoder_layer_block["1"]["EncDecAttention"]["o"]["kernel"] = t5x_enc_dec_attention_out - flax_model_decoder_layer_block["1"]["EncDecAttention"]["q"]["kernel"] = t5x_enc_dec_attention_query - flax_model_decoder_layer_block["1"]["EncDecAttention"]["v"]["kernel"] = t5x_enc_dec_attention_value - - flax_model_decoder_layer_block["1"]["layer_norm"]["weight"] = t5x_cross_layer_norm - - if split_mlp_wi: - flax_model_decoder_layer_block["2"]["DenseReluDense"]["wi_0"]["kernel"] = t5x_mlp_wi_0 - flax_model_decoder_layer_block["2"]["DenseReluDense"]["wi_1"]["kernel"] = t5x_mlp_wi_1 - else: - flax_model_decoder_layer_block["2"]["DenseReluDense"]["wi"]["kernel"] = t5x_mlp_wi - - flax_model_decoder_layer_block["2"]["DenseReluDense"]["wo"]["kernel"] = t5x_mlp_wo - - flax_model_decoder_layer_block["2"]["layer_norm"]["weight"] = tx5_mlp_layer_norm - - flax_model.params["decoder"]["block"][str(layer_index)]["layer"] = flax_model_decoder_layer_block - - # Decoder Normalization - tx5_decoder_norm = t5x_model["target"]["decoder"]["decoder_norm"]["scale"] - flax_model.params["decoder"]["final_layer_norm"]["weight"] = tx5_decoder_norm - - # Only for layer 0: - t5x_decoder_rel_embedding = t5x_model["target"]["decoder"]["relpos_bias"]["rel_embedding"].T - flax_model.params["decoder"]["block"]["0"]["layer"]["0"]["SelfAttention"]["relative_attention_bias"][ - "embedding" - ] = t5x_decoder_rel_embedding - - # Token Embeddings - tx5_token_embeddings = t5x_model["target"]["token_embedder"]["embedding"] - flax_model.params["shared"]["embedding"] = tx5_token_embeddings - - # LM Head (only in v1.1 and LongT5 checkpoints) - if "logits_dense" in t5x_model["target"]["decoder"]: - flax_model.params["lm_head"]["kernel"] = t5x_model["target"]["decoder"]["logits_dense"]["kernel"] - - flax_model.save_pretrained(flax_dump_folder_path) - print("T5X Model was successfully converted!") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - # Required parameters - parser.add_argument( - "--t5x_checkpoint_path", default=None, type=str, required=True, help="Path the T5X checkpoint." - ) - parser.add_argument("--config_name", default=None, type=str, required=True, help="Config name of LongT5/T5 model.") - parser.add_argument( - "--flax_dump_folder_path", default=None, type=str, required=True, help="Path to the output FLAX model." - ) - args = parser.parse_args() - convert_t5x_checkpoint_to_flax(args.t5x_checkpoint_path, args.config_name, args.flax_dump_folder_path) diff --git a/src/transformers/models/longt5/modeling_flax_longt5.py b/src/transformers/models/longt5/modeling_flax_longt5.py deleted file mode 100644 index dee4afeadf72..000000000000 --- a/src/transformers/models/longt5/modeling_flax_longt5.py +++ /dev/null @@ -1,2449 +0,0 @@ -# coding=utf-8 -# Copyright 2022 LongT5 Authors and 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. -"""Flax LongT5 model.""" - -import copy -from typing import Any, Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen import partitioning as nn_partitioning -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax.random import PRNGKey - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxSeq2SeqLMOutput, - FlaxSeq2SeqModelOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_longt5 import LongT5Config - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "google/long-t5-local-base" -_CONFIG_FOR_DOC = "LongT5Config" - -remat = nn_partitioning.remat - - -# Copied from transformers.models.bart.modeling_flax_bart.shift_tokens_right -def shift_tokens_right(input_ids: jnp.ndarray, pad_token_id: int, decoder_start_token_id: int) -> jnp.ndarray: - """ - Shift input ids one token to the right. - """ - shifted_input_ids = jnp.zeros_like(input_ids) - shifted_input_ids = shifted_input_ids.at[:, 1:].set(input_ids[:, :-1]) - shifted_input_ids = shifted_input_ids.at[:, 0].set(decoder_start_token_id) - - shifted_input_ids = jnp.where(shifted_input_ids == -100, pad_token_id, shifted_input_ids) - return shifted_input_ids - - -def _pad_to_multiple(x: jnp.ndarray, block_len: int, axis: int, pad_value: int = 0) -> jnp.ndarray: - """Pad an array so that a sequence length will be a multiple of `block_len`""" - pad_len = -x.shape[axis] % block_len - pad = [(0, 0)] * x.ndim - pad[axis] = (0, pad_len) - x = jnp.pad(x, pad_width=pad, mode="constant", constant_values=pad_value) - return x - - -def _split_into_blocks(x: jnp.ndarray, block_len: int, axis: int) -> jnp.ndarray: - """Split an input array into blocks of a given `block_len` along the given `axis`. If the dimension length - is not a multiple of `block_len`, it will be padded first with selected `pad_value`. - """ - # pad tensor to multiple of block_len - if x.shape[axis] % block_len != 0: - x = _pad_to_multiple(x, block_len, axis, pad_value=0) - num_blocks = x.shape[axis] // block_len - output_shape = x.shape[:axis] + (num_blocks, block_len) + x.shape[(axis + 1) :] - return x.reshape(output_shape) - - -def _concatenate_3_blocks(x: jnp.ndarray, block_axis: int, sequence_axis: int, pad_value: int = 0) -> jnp.ndarray: - """Concatenate three consecutive blocks for each input block for local attentiont. - For more information, see: https://huggingface.co/papers/2112.07916. - """ - num_blocks = x.shape[block_axis] - - pad = [(0, 0)] * x.ndim - pad[block_axis] = (1, 1) - # [batch_size, num_blocks, block_len] -> [batch_size, num_blocks + 2, block_len] - x = jnp.pad(x, pad_width=pad, mode="constant", constant_values=pad_value) - - blocks_list: list[np.array] = [] - for i in range(3): - # We use indexing approach here: - # https://numpy.org/doc/stable/user/basics.indexing.html#dealing-with-variable-numbers-of-indices-within-programs - indices = [slice(0, None)] * x.ndim - indices[block_axis] = slice(i, i + num_blocks) - indices = tuple(indices) - blocks_list.append(x[indices]) - return jnp.concatenate(blocks_list, axis=sequence_axis) # [batch_size, num_blocks, 3 * block_len, ...] - - -def _make_3block_relative_position_ids(block_len: int) -> jnp.ndarray: - """Makes 3-blocked relative position ids for local attention.""" - position_ids = jnp.arange(3 * block_len, dtype=jnp.int32) - center_position_ids = position_ids[block_len:-block_len] - relative_position_ids = position_ids[None, :] - center_position_ids[:, None] # [block_len, 3 * block_len] - return relative_position_ids - - -def _mask_local_attention_mask(local_attention_mask: np.ndarray, block_len: int) -> jnp.ndarray: - """Mask local attention mask to enforce that tokens are not allowed to attend tokens farther than ``local_radius.""" - relative_position_ids = _make_3block_relative_position_ids(block_len) - locality_mask = jnp.abs(relative_position_ids) < block_len - locality_mask = locality_mask[None, None, :, :] - return jnp.logical_and(local_attention_mask, locality_mask) - - -def _get_local_attention_mask(attention_mask: np.ndarray, block_len: int) -> jnp.ndarray: - """Prepare attention mask to be applied for a local attention.""" - # [batch_size, num_blocks, block_len] - _blocked_attention_mask = _split_into_blocks(attention_mask, block_len, axis=1) - # [batch_size, num_block, 3 * block_len] - _3blocked_attention_mask = _concatenate_3_blocks(_blocked_attention_mask, block_axis=1, sequence_axis=2) - - _blocked_attention_mask = _blocked_attention_mask[..., None] - _3blocked_attention_mask = _3blocked_attention_mask[..., None, :] - # [batch_size, num_block, block_len, 3 * block_len] - local_attention_mask = jnp.logical_and(_blocked_attention_mask, _3blocked_attention_mask) - local_attention_mask = _mask_local_attention_mask(local_attention_mask, block_len) - # [batch_size, 1, num_block, block_len, 3 * block_len] - return local_attention_mask[:, None, ...] - - -def _make_global_fixed_block_ids(attention_mask: np.ndarray, global_block_size: int) -> tuple[jnp.ndarray, np.ndarray]: - """Obtain the "fixed block" global id corresponding to each input token. - - This implementation is a simplified version of the original Flaxformr implementation adopted from: - https://github.com/google/flaxformer/blob/main/flaxformer/architectures/longt5/long_attention.py. - - In our scenario, as we use this strategy only for a decoder, orphan tokens, i.e. those tokens which do not make for - the whole fixed block, are assigned to the preceding block. - - Padding tokens from the original sequence are represented by -1. - """ - batch_size, seq_len = attention_mask.shape[:2] - - def handle_orphan_tokens(block_ids: np.ndarray) -> jnp.ndarray: - block_ends = (jnp.arange(seq_len) % global_block_size) == global_block_size - 1 - true_block_ends = jnp.logical_and(block_ends, block_ids >= 0) - full_blocks = true_block_ends.sum(-1)[..., None] - block_ids = jnp.minimum(block_ids, full_blocks - 1) - return block_ids - - fixed_block_mask = jnp.ones_like(attention_mask) / global_block_size - fixed_block_mask = jnp.cumsum(fixed_block_mask, axis=1) - fixed_block_mask - mask = jnp.where(attention_mask != 0.0, 1.0, -1000.0) - global_block_ids = jnp.maximum( - jnp.floor(mask + fixed_block_mask - 1.0), jnp.array(-1.0, dtype=attention_mask.dtype) - ) - # set padding tokens to -1 - global_block_ids = (global_block_ids * attention_mask) + (attention_mask - 1) - # [batch_size, seq_len] - global_block_ids = handle_orphan_tokens(global_block_ids) - num_globals = seq_len // global_block_size - - # [batch_size, seq_len // global_block_size] - if num_globals > 0: - _sequence_block_ids_max = jnp.repeat(global_block_ids.max(axis=-1)[:, None], repeats=num_globals, axis=1) - else: - _sequence_block_ids_max = jnp.zeros((batch_size, 0), dtype=global_block_ids.dtype) - global_segment_ids = jnp.cumsum(jnp.ones((batch_size, num_globals)), axis=-1) - 1 - global_segment_ids = jnp.where(global_segment_ids <= _sequence_block_ids_max, 1, 0) - return global_block_ids, global_segment_ids - - -def _make_side_relative_position_ids(attention_mask: np.ndarray, global_block_size: int) -> np.ndarray: - """Create the relative position tensor for local -> global attention.""" - block_ids, global_segment_ids = _make_global_fixed_block_ids(attention_mask, global_block_size) - global_seq_len = global_segment_ids.shape[-1] - global_positions = jnp.arange(global_seq_len) - side_relative_position = global_positions - block_ids[..., None] - return side_relative_position - - -def _create_global_aggregates(hidden_states: np.ndarray, block_ids: np.ndarray, global_seq_len: int) -> np.ndarray: - """Compute individual block aggregates by summing over individual blocks.""" - # (batch..., seq_len, global_seq_len)) - one_hot_block_ids = jax.nn.one_hot(block_ids, global_seq_len) - return jnp.einsum("...nd,...ng->...gd", hidden_states, one_hot_block_ids) - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5LayerNorm with T5->LongT5 -class FlaxLongT5LayerNorm(nn.Module): - hidden_size: int - dtype: jnp.dtype = jnp.float32 - eps: float = 1e-6 - weight_init: Callable[..., np.ndarray] = jax.nn.initializers.ones - - def setup(self): - self.weight = self.param("weight", self.weight_init, (self.hidden_size,)) - - def __call__(self, hidden_states): - """ - Construct a layernorm module in the LongT5 style; No bias and no subtraction of mean. - """ - # layer norm should always be calculated in float32 - variance = jnp.power(hidden_states.astype("f4"), 2).mean(axis=-1, keepdims=True) - hidden_states = hidden_states / jnp.sqrt(variance + self.eps) - - return self.weight * hidden_states - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5DenseActDense with T5->LongT5 -class FlaxLongT5DenseActDense(nn.Module): - config: LongT5Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - wi_init_std = self.config.initializer_factor * (self.config.d_model**-0.5) - wo_init_std = self.config.initializer_factor * (self.config.d_ff**-0.5) - - self.wi = nn.Dense( - self.config.d_ff, - use_bias=False, - kernel_init=jax.nn.initializers.normal(wi_init_std), - dtype=self.dtype, - ) - self.wo = nn.Dense( - self.config.d_model, - use_bias=False, - kernel_init=jax.nn.initializers.normal(wo_init_std), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - self.act = ACT2FN[self.config.dense_act_fn] - - def __call__(self, hidden_states, deterministic=True): - hidden_states = self.wi(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.wo(hidden_states) - return hidden_states - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5DenseGatedActDense with T5->LongT5 -class FlaxLongT5DenseGatedActDense(nn.Module): - config: LongT5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - wi_init_std = self.config.initializer_factor * (self.config.d_model**-0.5) - wo_init_std = self.config.initializer_factor * (self.config.d_ff**-0.5) - - self.wi_0 = nn.Dense( - self.config.d_ff, - use_bias=False, - kernel_init=jax.nn.initializers.normal(wi_init_std), - dtype=self.dtype, - ) - self.wi_1 = nn.Dense( - self.config.d_ff, - use_bias=False, - kernel_init=jax.nn.initializers.normal(wi_init_std), - dtype=self.dtype, - ) - self.wo = nn.Dense( - self.config.d_model, - use_bias=False, - kernel_init=jax.nn.initializers.normal(wo_init_std), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - self.act = ACT2FN[self.config.dense_act_fn] - - def __call__(self, hidden_states, deterministic): - hidden_gelu = self.act(self.wi_0(hidden_states)) - hidden_linear = self.wi_1(hidden_states) - hidden_states = hidden_gelu * hidden_linear - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.wo(hidden_states) - return hidden_states - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5LayerFF with T5->LongT5 -class FlaxLongT5LayerFF(nn.Module): - config: LongT5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - if self.config.is_gated_act: - self.DenseReluDense = FlaxLongT5DenseGatedActDense(self.config, dtype=self.dtype) - else: - self.DenseReluDense = FlaxLongT5DenseActDense(self.config, dtype=self.dtype) - - self.layer_norm = FlaxLongT5LayerNorm( - self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - - def __call__(self, hidden_states, deterministic=True): - forwarded_states = self.layer_norm(hidden_states) - forwarded_states = self.DenseReluDense(forwarded_states, deterministic=deterministic) - hidden_states = hidden_states + self.dropout(forwarded_states, deterministic=deterministic) - return hidden_states - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5Attention with T5->LongT5 -class FlaxLongT5Attention(nn.Module): - config: LongT5Config - has_relative_attention_bias: bool = False - causal: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.relative_attention_num_buckets = self.config.relative_attention_num_buckets - self.relative_attention_max_distance = self.config.relative_attention_max_distance - self.d_model = self.config.d_model - self.key_value_proj_dim = self.config.d_kv - self.n_heads = self.config.num_heads - self.dropout = self.config.dropout_rate - self.inner_dim = self.n_heads * self.key_value_proj_dim - - q_init_std = self.config.initializer_factor * ((self.inner_dim * self.key_value_proj_dim) ** -0.5) - kv_init_std = self.config.initializer_factor * (self.inner_dim**-0.5) - o_init_std = self.config.initializer_factor * (self.inner_dim**-0.5) - - self.q = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(q_init_std), - dtype=self.dtype, - ) - self.k = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(kv_init_std), - dtype=self.dtype, - ) - self.v = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(kv_init_std), - dtype=self.dtype, - ) - self.o = nn.Dense( - self.d_model, - use_bias=False, - kernel_init=jax.nn.initializers.normal(o_init_std), - dtype=self.dtype, - ) - - if self.has_relative_attention_bias: - self.relative_attention_bias = nn.Embed( - self.relative_attention_num_buckets, - self.n_heads, - embedding_init=jax.nn.initializers.normal(kv_init_std), - dtype=self.dtype, - ) - - @staticmethod - def _relative_position_bucket(relative_position, bidirectional=True, num_buckets=32, max_distance=128): - """ - Adapted from Mesh Tensorflow: - https://github.com/tensorflow/mesh/blob/0cb87fe07da627bf0b7e60475d59f95ed6b5be3d/mesh_tensorflow/transformer/transformer_layers.py#L593 - - Translate relative position to a bucket number for relative attention. The relative position is defined as - memory_position - query_position, i.e. the distance in tokens from the attending position to the attended-to - position. If bidirectional=False, then positive relative positions are invalid. We use smaller buckets for - small absolute relative_position and larger buckets for larger absolute relative_positions. All relative - positions >=max_distance map to the same bucket. All relative positions <=-max_distance map to the same bucket. - This should allow for more graceful generalization to longer sequences than the model has been trained on - """ - relative_buckets = 0 - if bidirectional: - num_buckets //= 2 - relative_buckets += (relative_position > 0) * num_buckets - relative_position = jnp.abs(relative_position) - else: - relative_position = -jnp.clip(relative_position, a_max=0) - # now relative_position is in the range [0, inf) - - # half of the buckets are for exact increments in positions - max_exact = num_buckets // 2 - is_small = relative_position < max_exact - - # The other half of the buckets are for logarithmically bigger bins in positions up to max_distance - relative_position_if_large = max_exact + ( - jnp.log(relative_position / max_exact) / jnp.log(max_distance / max_exact) * (num_buckets - max_exact) - ) - relative_position_if_large = jnp.clip(relative_position_if_large, a_max=num_buckets - 1) - - relative_buckets += jnp.where(is_small, relative_position, relative_position_if_large) - - return relative_buckets.astype("i4") - - def compute_bias(self, query_length, key_length): - """Compute binned relative position bias""" - context_position = jnp.arange(query_length, dtype="i4")[:, None] - memory_position = jnp.arange(key_length, dtype="i4")[None, :] - - relative_position = memory_position - context_position - relative_position_bucket = self._relative_position_bucket( - relative_position, - bidirectional=(not self.causal), - num_buckets=self.relative_attention_num_buckets, - max_distance=self.relative_attention_max_distance, - ) - - values = self.relative_attention_bias(relative_position_bucket) - values = values.transpose((2, 0, 1))[None, :, :, :] - return values - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.n_heads, self.key_value_proj_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.inner_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = jax.lax.dynamic_update_slice(cached_key.value, key, indices) - value = jax.lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions - # that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def _create_position_bias( - self, key_states, query_states, attention_mask, init_cache, seq_length, causal_attention_mask_shift - ): - cache_is_filled = self.causal and self.has_variable("cache", "cached_key") and (not init_cache) - key_length = key_states.shape[1] - query_length = key_length if cache_is_filled else query_states.shape[1] - - if self.has_relative_attention_bias: - position_bias = self.compute_bias(query_length, key_length) - elif attention_mask is not None: - position_bias = jnp.zeros_like(attention_mask) - else: - position_bias = jnp.zeros((1, self.n_heads, query_length, key_length), dtype=self.dtype) - - # if key and values are already calculated, only the last query position bias should be taken - if cache_is_filled: - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - position_bias = jax.lax.dynamic_slice( - position_bias, - (0, 0, causal_attention_mask_shift, 0), - (1, self.n_heads, seq_length, max_decoder_length), - ) - return position_bias - - def __call__( - self, - hidden_states, - attention_mask=None, - key_value_states=None, - position_bias=None, - use_cache=False, - output_attentions=False, - deterministic=True, - init_cache=False, - ): - """ - Self-attention (if key_value_states is None) or attention over source sentence (provided by key_value_states). - """ - batch_size, seq_length = hidden_states.shape[:2] - - # q, k, v projections - query_states = self.q(hidden_states) # (batch_size, n_heads, seq_length, dim_per_head) - key_states = self.k(hidden_states) if key_value_states is None else self.k(key_value_states) - value_states = self.v(hidden_states) if key_value_states is None else self.v(key_value_states) - - # reshape to (batch_size, seq_length, n_heads, head_dim) - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # counter-act scaling in dot_product_attention_weights function - query_states *= jnp.sqrt(query_states.shape[-1]) - - # for fast decoding causal attention mask should be shifted - causal_attention_mask_shift = ( - self.variables["cache"]["cache_index"] if (self.has_variable("cache", "cached_key") and self.causal) else 0 - ) - # create causal attention_mask; attention_mask has to be defined when model is causal - if self.causal: - causal_attention_mask = make_causal_mask(attention_mask, dtype="bool") - - # fast decoding for generate requires special attention_mask - if self.has_variable("cache", "cached_key"): - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_attention_mask = jax.lax.dynamic_slice( - causal_attention_mask, - (0, 0, causal_attention_mask_shift, 0), - (1, 1, seq_length, max_decoder_length), - ) - - # broadcast causal attention mask & attention mask to fit for merge - causal_attention_mask = jnp.broadcast_to( - causal_attention_mask, (batch_size,) + causal_attention_mask.shape[1:] - ) - attention_mask = jnp.broadcast_to( - jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_attention_mask.shape - ) - attention_mask = combine_masks(attention_mask, causal_attention_mask) - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # replace masked positions with -10_000 - if attention_mask is not None: - mask_value = jnp.finfo(self.dtype).min - attention_mask = jax.lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, mask_value).astype(self.dtype), - ) - - if position_bias is None: - # compute position bias (only for first layer) - position_bias = self._create_position_bias( - key_states, query_states, attention_mask, init_cache, seq_length, causal_attention_mask_shift - ) - - if attention_mask is not None: - position_bias = position_bias + attention_mask - - # create dropout rng - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - # Softmax(QK^T) - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=position_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - ) - - # multiply with value states - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - - # bring back to (batch_size, seq_length, d_model) - attn_output = self._merge_heads(attn_output) - - # apply output matrix - attn_output = self.o(attn_output) - - outputs = (attn_output, position_bias) - - if output_attentions: - outputs = outputs + (attn_weights,) - - return outputs - - -class FlaxLongT5LocalAttention(nn.Module): - config: LongT5Config - has_relative_attention_bias: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.relative_attention_num_buckets = self.config.relative_attention_num_buckets - self.relative_attention_max_distance = self.config.relative_attention_max_distance - self.d_model = self.config.d_model - self.key_value_proj_dim = self.config.d_kv - self.n_heads = self.config.num_heads - self.local_radius = self.config.local_radius - self.block_len = self.local_radius + 1 - self.dropout = self.config.dropout_rate - self.inner_dim = self.n_heads * self.key_value_proj_dim - - q_init_std = self.config.initializer_factor * ((self.inner_dim * self.key_value_proj_dim) ** -0.5) - kv_init_std = self.config.initializer_factor * (self.inner_dim**-0.5) - o_init_std = self.config.initializer_factor * (self.inner_dim**-0.5) - - self.q = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(q_init_std), - dtype=self.dtype, - ) - self.k = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(kv_init_std), - dtype=self.dtype, - ) - self.v = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(kv_init_std), - dtype=self.dtype, - ) - self.o = nn.Dense( - self.d_model, - use_bias=False, - kernel_init=jax.nn.initializers.normal(o_init_std), - dtype=self.dtype, - ) - - if self.has_relative_attention_bias: - self.relative_attention_bias = nn.Embed( - self.relative_attention_num_buckets, - self.n_heads, - embedding_init=jax.nn.initializers.normal(kv_init_std), - ) - - @staticmethod - # Copied from transformers.models.t5.modeling_flax_t5.FlaxT5Attention._relative_position_bucket - def _relative_position_bucket(relative_position, bidirectional=True, num_buckets=32, max_distance=128): - """ - Adapted from Mesh Tensorflow: - https://github.com/tensorflow/mesh/blob/0cb87fe07da627bf0b7e60475d59f95ed6b5be3d/mesh_tensorflow/transformer/transformer_layers.py#L593 - - Translate relative position to a bucket number for relative attention. The relative position is defined as - memory_position - query_position, i.e. the distance in tokens from the attending position to the attended-to - position. If bidirectional=False, then positive relative positions are invalid. We use smaller buckets for - small absolute relative_position and larger buckets for larger absolute relative_positions. All relative - positions >=max_distance map to the same bucket. All relative positions <=-max_distance map to the same bucket. - This should allow for more graceful generalization to longer sequences than the model has been trained on - """ - relative_buckets = 0 - if bidirectional: - num_buckets //= 2 - relative_buckets += (relative_position > 0) * num_buckets - relative_position = jnp.abs(relative_position) - else: - relative_position = -jnp.clip(relative_position, a_max=0) - # now relative_position is in the range [0, inf) - - # half of the buckets are for exact increments in positions - max_exact = num_buckets // 2 - is_small = relative_position < max_exact - - # The other half of the buckets are for logarithmically bigger bins in positions up to max_distance - relative_position_if_large = max_exact + ( - jnp.log(relative_position / max_exact) / jnp.log(max_distance / max_exact) * (num_buckets - max_exact) - ) - relative_position_if_large = jnp.clip(relative_position_if_large, a_max=num_buckets - 1) - - relative_buckets += jnp.where(is_small, relative_position, relative_position_if_large) - - return relative_buckets.astype("i4") - - def compute_bias(self, block_length: int): - """Compute binned relative position bias""" - memory_position = jnp.arange(3 * block_length, dtype="i4") - context_position = memory_position[block_length:-block_length] - - relative_position = memory_position[None, :] - context_position[:, None] - relative_position_bucket = self._relative_position_bucket( - relative_position, - bidirectional=True, - num_buckets=self.relative_attention_num_buckets, - max_distance=self.relative_attention_max_distance, - ) - - values = self.relative_attention_bias(relative_position_bucket) - values = values.transpose((2, 0, 1))[None, None, :, :, :] - return values - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.n_heads, self.key_value_proj_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[0], -1, self.inner_dim) - - def _create_position_bias(self, block_len: int, attention_mask: Optional[np.ndarray]) -> np.ndarray: - # position_bias shape: # (1, 1, n_heads, block_len, 3 * block_len) - if self.has_relative_attention_bias: - position_bias = self.compute_bias(block_len) - elif attention_mask is not None: - position_bias = jnp.zeros_like(attention_mask) - else: - position_bias = jnp.zeros((1, 1, self.n_heads, block_len, 3 * block_len), dtype=self.dtype) - - return position_bias - - def __call__( - self, - hidden_states, - attention_mask=None, - key_value_states=None, - position_bias=None, - output_attentions=False, - deterministic=True, - ): - """ - Self-attention (if key_value_states is None) or attention over source sentence (provided by key_value_states). - """ - batch_size, seq_length = hidden_states.shape[:2] - - # q, k, v projections - query_states = self.q(hidden_states) # (batch_size, n_heads, seq_length, dim_per_head) - key_states = self.k(hidden_states) if key_value_states is None else self.k(key_value_states) - value_states = self.v(hidden_states) if key_value_states is None else self.v(key_value_states) - - # reshape to (batch_size, seq_length, n_heads, head_dim) - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # Split into blocks -> (batch_size, num_blocks, block_len, n_heads, head_dim) - query_states = _split_into_blocks(query_states, self.block_len, axis=1) - key_states = _split_into_blocks(key_states, self.block_len, axis=1) - value_states = _split_into_blocks(value_states, self.block_len, axis=1) - - # Concatenate 3 blocks for keys and values -> (batch_size, num_blocks, 3 * block_len, n_heads, dim_per_head) - key_states = _concatenate_3_blocks(key_states, block_axis=1, sequence_axis=2) - value_states = _concatenate_3_blocks(value_states, block_axis=1, sequence_axis=2) - - # counter-act scaling in dot_product_attention_weights function - query_states *= jnp.sqrt(query_states.shape[-1]) - - if attention_mask is not None: - attention_mask = _get_local_attention_mask(attention_mask, self.block_len) - - # replace masked positions with -10_000 - attention_mask = jax.lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, -1e10).astype(self.dtype), - ) - - if position_bias is None: - # compute position bias (only for first layer) - position_bias = self._create_position_bias(self.block_len, attention_mask) - - if attention_mask is not None: - position_bias = position_bias + attention_mask.swapaxes(1, 2) - - # create dropout rng - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - # Softmax(QK^T) - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=position_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - ) - - # multiply with value states - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - - # bring back to (batch_size, seq_length, d_model) - attn_output = self._merge_heads(attn_output) - attn_output = attn_output[:, :seq_length, :] - - # apply output matrix - attn_output = self.o(attn_output) - - outputs = (attn_output, position_bias) - - if output_attentions: - outputs = outputs + (attn_weights,) - - return outputs - - -class FlaxLongT5TransientGlobalAttention(nn.Module): - config: LongT5Config - has_relative_attention_bias: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.relative_attention_num_buckets = self.config.relative_attention_num_buckets - self.relative_attention_max_distance = self.config.relative_attention_max_distance - self.d_model = self.config.d_model - self.key_value_proj_dim = self.config.d_kv - self.n_heads = self.config.num_heads - self.local_radius = self.config.local_radius - self.block_len = self.local_radius + 1 - self.global_block_size = self.config.global_block_size - self.dropout = self.config.dropout_rate - self.inner_dim = self.n_heads * self.key_value_proj_dim - - q_init_std = self.config.initializer_factor * ((self.inner_dim * self.key_value_proj_dim) ** -0.5) - kv_init_std = self.config.initializer_factor * (self.inner_dim**-0.5) - o_init_std = self.config.initializer_factor * (self.inner_dim**-0.5) - - self.q = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(q_init_std), - dtype=self.dtype, - ) - self.k = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(kv_init_std), - dtype=self.dtype, - ) - self.v = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(kv_init_std), - dtype=self.dtype, - ) - self.o = nn.Dense( - self.d_model, - use_bias=False, - kernel_init=jax.nn.initializers.normal(o_init_std), - dtype=self.dtype, - ) - - if self.has_relative_attention_bias: - self.relative_attention_bias = nn.Embed( - self.relative_attention_num_buckets, - self.n_heads, - embedding_init=jax.nn.initializers.normal(kv_init_std), - ) - - # Relativen attention bias & Layer norm for global attention - if self.has_relative_attention_bias: - self.global_relative_attention_bias = nn.Embed( - self.relative_attention_num_buckets, - self.n_heads, - embedding_init=jax.nn.initializers.normal(kv_init_std), - ) - self.global_input_layer_norm = FlaxLongT5LayerNorm( - self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype - ) - - @staticmethod - # Copied from transformers.models.t5.modeling_flax_t5.FlaxT5Attention._relative_position_bucket - def _relative_position_bucket(relative_position, bidirectional=True, num_buckets=32, max_distance=128): - """ - Adapted from Mesh Tensorflow: - https://github.com/tensorflow/mesh/blob/0cb87fe07da627bf0b7e60475d59f95ed6b5be3d/mesh_tensorflow/transformer/transformer_layers.py#L593 - - Translate relative position to a bucket number for relative attention. The relative position is defined as - memory_position - query_position, i.e. the distance in tokens from the attending position to the attended-to - position. If bidirectional=False, then positive relative positions are invalid. We use smaller buckets for - small absolute relative_position and larger buckets for larger absolute relative_positions. All relative - positions >=max_distance map to the same bucket. All relative positions <=-max_distance map to the same bucket. - This should allow for more graceful generalization to longer sequences than the model has been trained on - """ - relative_buckets = 0 - if bidirectional: - num_buckets //= 2 - relative_buckets += (relative_position > 0) * num_buckets - relative_position = jnp.abs(relative_position) - else: - relative_position = -jnp.clip(relative_position, a_max=0) - # now relative_position is in the range [0, inf) - - # half of the buckets are for exact increments in positions - max_exact = num_buckets // 2 - is_small = relative_position < max_exact - - # The other half of the buckets are for logarithmically bigger bins in positions up to max_distance - relative_position_if_large = max_exact + ( - jnp.log(relative_position / max_exact) / jnp.log(max_distance / max_exact) * (num_buckets - max_exact) - ) - relative_position_if_large = jnp.clip(relative_position_if_large, a_max=num_buckets - 1) - - relative_buckets += jnp.where(is_small, relative_position, relative_position_if_large) - - return relative_buckets.astype("i4") - - def compute_bias(self, block_length: int): - """Compute binned relative position bias""" - memory_position = jnp.arange(3 * block_length, dtype="i4") - context_position = memory_position[block_length:-block_length] - - relative_position = memory_position[None, :] - context_position[:, None] - relative_position_bucket = self._relative_position_bucket( - relative_position, - bidirectional=True, - num_buckets=self.relative_attention_num_buckets, - max_distance=self.relative_attention_max_distance, - ) - - values = self.relative_attention_bias(relative_position_bucket) - values = values.transpose((2, 0, 1))[None, None, :, :, :] - return values - - def compute_side_bias(self, attention_mask: np.ndarray, global_segment_ids: np.ndarray) -> np.ndarray: - # (batch_size, 1, 1, seq_len, global_seq_len) - side_attention_mask = jnp.equal(attention_mask[..., None], global_segment_ids[:, None, :])[:, None, ...] - attention_side_bias = jax.lax.select( - side_attention_mask > 0, - jnp.full(side_attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(side_attention_mask.shape, -1e10).astype(self.dtype), - ) - # (batch_size, seq_len, global_seq_len) - side_relative_position = _make_side_relative_position_ids(attention_mask, self.global_block_size) - side_relative_position_bucket = self._relative_position_bucket( - side_relative_position, - bidirectional=True, - num_buckets=self.relative_attention_num_buckets, - max_distance=self.relative_attention_max_distance, - ) - # (batch_size, seq_len, global_seq_len, num_heads) - side_bias = self.global_relative_attention_bias(side_relative_position_bucket) - - # (batch_size, 1, num_heads, seq_len, global_seq_len) - side_bias = jnp.transpose(side_bias, (0, 3, 1, 2)) - # (batch_size, num_heads, seq_len, global_seq_len) - attention_side_bias = attention_side_bias + side_bias - return attention_side_bias - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.n_heads, self.key_value_proj_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[0], -1, self.inner_dim) - - def _create_position_bias(self, block_len: int, attention_mask: Optional[np.ndarray]) -> np.ndarray: - # position_bias shape: # (1, 1, n_heads, block_len, 3 * block_len) - if self.has_relative_attention_bias: - position_bias = self.compute_bias(block_len) - elif attention_mask is not None: - position_bias = jnp.zeros_like(attention_mask) - else: - position_bias = jnp.zeros((1, 1, self.n_heads, block_len, 3 * block_len), dtype=self.dtype) - - return position_bias - - def __call__( - self, - hidden_states, - attention_mask=None, - key_value_states=None, - position_bias=None, - output_attentions=False, - deterministic=True, - ): - """ - Self-attention (if key_value_states is None) or attention over source sentence (provided by key_value_states). - """ - batch_size, seq_length = hidden_states.shape[:2] - - # Prepare components for transient-global attention - # Obtain block_ids and global_segment_ids - # global_seq_len := seq_len // self.global_block_size - # shapes: (batch_size, seq_len) & (batch_size, global_seq_len) - block_ids, global_segment_ids = _make_global_fixed_block_ids( - attention_mask if attention_mask is not None else jnp.ones((batch_size, seq_length)), - self.global_block_size, - ) - # Create global inputs - _global_seq_len = global_segment_ids.shape[-1] - global_inputs = _create_global_aggregates(hidden_states, block_ids, _global_seq_len) - global_inputs = self.global_input_layer_norm(global_inputs) - - # q, k, v projections - query_states = self.q(hidden_states) # (batch_size, n_heads, seq_length, dim_per_head) - key_states = self.k(hidden_states) if key_value_states is None else self.k(key_value_states) - value_states = self.v(hidden_states) if key_value_states is None else self.v(key_value_states) - - # reshape to (batch_size, seq_length, n_heads, head_dim) - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # Get global/side key/value_states - side_key_states = self.k(global_inputs) - side_value_states = self.v(global_inputs) - - # reshape to (batch_size, global_seq_len, n_heads, head_dim) - side_key_states = self._split_heads(side_key_states) - side_value_states = self._split_heads(side_value_states) - - # Split into blocks -> (batch_size, num_blocks, block_len, n_heads, head_dim) - query_states = _split_into_blocks(query_states, self.block_len, axis=1) - key_states = _split_into_blocks(key_states, self.block_len, axis=1) - value_states = _split_into_blocks(value_states, self.block_len, axis=1) - - # Concatenate 3 blocks for keys and values -> (batch_size, num_blocks, 3 * block_len, n_heads, dim_per_head) - key_states = _concatenate_3_blocks(key_states, block_axis=1, sequence_axis=2) - value_states = _concatenate_3_blocks(value_states, block_axis=1, sequence_axis=2) - - # Tile side inputs across local key/value blocks - # New shape: (batch_size, num_blocks, global_seq_len, n_heads, dim_per_head) - reps = [1] * (side_key_states.ndim + 1) - reps[1] = key_states.shape[1] - side_key_states = jnp.tile(side_key_states[:, None, ...], reps) - side_value_states = jnp.tile(side_value_states[:, None, ...], reps) - - # Concatenate "local" and "side"/"global" key/value states to allow each token to attend global aggregated ones - # New shape: (batch_size, num_blocks, 3 * block_len + global_seq_len, n_heads, dim_per_head) - key_states = jnp.concatenate((key_states, side_key_states), axis=2) - value_states = jnp.concatenate((value_states, side_value_states), axis=2) - - # counter-act scaling in dot_product_attention_weights function - query_states *= jnp.sqrt(query_states.shape[-1]) - - if attention_mask is not None: - local_attention_mask = _get_local_attention_mask(attention_mask, self.block_len) - local_attention_mask = jax.lax.select( - local_attention_mask > 0, - jnp.full(local_attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(local_attention_mask.shape, -1e10).astype(self.dtype), - ) - else: - local_attention_mask = None - - if position_bias is None: - # compute position bias (only for first layer) - position_bias = self._create_position_bias(self.block_len, attention_mask) - if local_attention_mask is not None: - position_bias = position_bias + local_attention_mask.swapaxes(1, 2) - - # Calculate global/side bias - shape: # (batch_size, num_heads, seq_len, global_seq_len) - if attention_mask is None: - attention_mask = jnp.ones((batch_size, seq_length)) - side_position_bias = self.compute_side_bias(attention_mask, global_segment_ids) - side_position_bias = _split_into_blocks(side_position_bias, self.block_len, axis=-2) - side_position_bias = jnp.swapaxes(side_position_bias, 1, 2) - position_bias = jnp.concatenate((position_bias, side_position_bias), axis=-1) - - # create dropout rng - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - # Softmax(QK^T) - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=position_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - ) - - # multiply with value states - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - - # bring back to (batch_size, seq_length, d_model) - attn_output = self._merge_heads(attn_output) - attn_output = attn_output[:, :seq_length, :] - - # apply output matrix - attn_output = self.o(attn_output) - - outputs = (attn_output, position_bias) - - if output_attentions: - outputs = outputs + (attn_weights,) - - return outputs - - -class FlaxLongT5LayerLocalSelfAttention(nn.Module): - """Local self attention used in encoder""" - - config: LongT5Config - has_relative_attention_bias: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.LocalSelfAttention = FlaxLongT5LocalAttention( - self.config, has_relative_attention_bias=self.has_relative_attention_bias, dtype=self.dtype - ) - self.layer_norm = FlaxLongT5LayerNorm( - self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_bias=None, - output_attentions=False, - deterministic=True, - **kwargs: Any, # to accept init_cache kwargs - ): - normed_hidden_states = self.layer_norm(hidden_states) - attention_output = self.LocalSelfAttention( - normed_hidden_states, - attention_mask=attention_mask, - position_bias=position_bias, - output_attentions=output_attentions, - deterministic=deterministic, - ) - hidden_states = hidden_states + self.dropout(attention_output[0], deterministic=deterministic) - outputs = (hidden_states,) + attention_output[1:] # add attentions if we output them - return outputs - - -class FlaxLongT5LayerTransientGlobalSelfAttention(nn.Module): - """Transient-Global self attention used in encoder""" - - config: LongT5Config - has_relative_attention_bias: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.TransientGlobalSelfAttention = FlaxLongT5TransientGlobalAttention( - self.config, has_relative_attention_bias=self.has_relative_attention_bias, dtype=self.dtype - ) - self.layer_norm = FlaxLongT5LayerNorm( - self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_bias=None, - output_attentions=False, - deterministic=True, - **kwargs: Any, # to accept init_cache kwargs - ): - normed_hidden_states = self.layer_norm(hidden_states) - attention_output = self.TransientGlobalSelfAttention( - normed_hidden_states, - attention_mask=attention_mask, - position_bias=position_bias, - output_attentions=output_attentions, - deterministic=deterministic, - ) - hidden_states = hidden_states + self.dropout(attention_output[0], deterministic=deterministic) - outputs = (hidden_states,) + attention_output[1:] # add attentions if we output them - return outputs - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5LayerSelfAttention with T5->LongT5 -class FlaxLongT5LayerSelfAttention(nn.Module): - config: LongT5Config - has_relative_attention_bias: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.SelfAttention = FlaxLongT5Attention( - self.config, - has_relative_attention_bias=self.has_relative_attention_bias, - causal=self.config.causal, - dtype=self.dtype, - ) - self.layer_norm = FlaxLongT5LayerNorm( - self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_bias=None, - output_attentions=False, - deterministic=True, - init_cache=False, - ): - normed_hidden_states = self.layer_norm(hidden_states) - attention_output = self.SelfAttention( - normed_hidden_states, - attention_mask=attention_mask, - position_bias=position_bias, - output_attentions=output_attentions, - deterministic=deterministic, - init_cache=init_cache, - ) - hidden_states = hidden_states + self.dropout(attention_output[0], deterministic=deterministic) - outputs = (hidden_states,) + attention_output[1:] # add attentions if we output them - return outputs - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5LayerCrossAttention with T5->LongT5 -class FlaxLongT5LayerCrossAttention(nn.Module): - config: LongT5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.EncDecAttention = FlaxLongT5Attention( - self.config, has_relative_attention_bias=False, causal=False, dtype=self.dtype - ) - self.layer_norm = FlaxLongT5LayerNorm( - self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - - def __call__( - self, - hidden_states, - key_value_states, - attention_mask=None, - position_bias=None, - output_attentions=False, - deterministic=True, - ): - normed_hidden_states = self.layer_norm(hidden_states) - attention_output = self.EncDecAttention( - normed_hidden_states, - attention_mask=attention_mask, - key_value_states=key_value_states, - position_bias=position_bias, - output_attentions=output_attentions, - ) - hidden_states = hidden_states + self.dropout(attention_output[0], deterministic=deterministic) - outputs = (hidden_states,) + attention_output[1:] # add attentions if we output them - return outputs - - -class FlaxLongT5Block(nn.Module): - config: LongT5Config - has_relative_attention_bias: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.causal = self.config.causal - if self.causal: - attention_layer = FlaxLongT5LayerSelfAttention - elif self.config.encoder_attention_type == "local": - attention_layer = FlaxLongT5LayerLocalSelfAttention - elif self.config.encoder_attention_type == "transient-global": - attention_layer = FlaxLongT5LayerTransientGlobalSelfAttention - else: - raise ValueError( - "For encoder attention mechanism, either `local` or `transient-global` attention type is expected, " - f"but got {self.config.encoder_attention_type}." - ) - self.layer = ( - attention_layer( - self.config, - has_relative_attention_bias=self.has_relative_attention_bias, - name=str(0), - dtype=self.dtype, - ), - ) - feed_forward_index = 1 - if self.causal: - self.layer += (FlaxLongT5LayerCrossAttention(self.config, name=str(1), dtype=self.dtype),) - feed_forward_index += 1 - - self.layer += (FlaxLongT5LayerFF(self.config, name=str(feed_forward_index), dtype=self.dtype),) - - # Copied from transformers.models.t5.modeling_flax_t5.FlaxT5Block.__call__ with T5->LongT5 - def __call__( - self, - hidden_states, - attention_mask=None, - position_bias=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - encoder_decoder_position_bias=None, - output_attentions=False, - return_dict=True, - deterministic=True, - init_cache=False, - ): - self_attention_outputs = self.layer[0]( - hidden_states, - attention_mask=attention_mask, - position_bias=position_bias, - output_attentions=output_attentions, - deterministic=deterministic, - init_cache=init_cache, - ) - hidden_states = self_attention_outputs[0] - attention_outputs = self_attention_outputs[1:] # Keep self-attention outputs and relative position weights - - do_cross_attention = self.causal and encoder_hidden_states is not None - if do_cross_attention: - cross_attention_outputs = self.layer[1]( - hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - position_bias=encoder_decoder_position_bias, - output_attentions=output_attentions, - deterministic=deterministic, - ) - hidden_states = cross_attention_outputs[0] - - # Keep cross-attention outputs and relative position weights - attention_outputs = attention_outputs + cross_attention_outputs[1:] - - # Apply Feed Forward layer - hidden_states = self.layer[-1](hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - outputs = outputs + attention_outputs - - # returns hidden-states, present_key_value_states, (self-attention position bias), (self-attention weights), - # (cross-attention position bias), (cross-attention weights) - return outputs - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5LayerCollection with T5->LongT5 -class FlaxLongT5LayerCollection(nn.Module): - config: LongT5Config - has_relative_attention_bias: bool - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layer = FlaxLongT5Block( - self.config, has_relative_attention_bias=self.has_relative_attention_bias, dtype=self.dtype - ) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_bias=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - encoder_decoder_position_bias=None, - output_attentions=False, - deterministic=True, - init_cache=False, - ): - return self.layer( - hidden_states, - attention_mask=attention_mask, - position_bias=position_bias, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - encoder_decoder_position_bias=encoder_decoder_position_bias, - output_attentions=output_attentions, - deterministic=deterministic, - init_cache=init_cache, - ) - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5BlockCollection with T5->LongT5 -class FlaxLongT5BlockCollection(nn.Module): - config: LongT5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.causal = self.config.causal - if self.gradient_checkpointing: - FlaxLongT5CheckpointLayer = remat(FlaxLongT5LayerCollection, static_argnums=(6, 7, 8)) - self.blocks = [ - FlaxLongT5CheckpointLayer( - self.config, - has_relative_attention_bias=(i == 0), - dtype=self.dtype, - name=str(i), - ) - for i in range(self.config.num_layers) - ] - else: - self.blocks = [ - FlaxLongT5LayerCollection( - self.config, - has_relative_attention_bias=(i == 0), - dtype=self.dtype, - name=str(i), - ) - for i in range(self.config.num_layers) - ] - - def __call__( - self, - hidden_states=None, - attention_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - output_attentions: bool = False, - output_hidden_states: bool = False, - deterministic: bool = True, - init_cache: bool = False, - ): - # Prepare head mask if needed - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if (output_attentions and self.causal) else None - position_bias = None - encoder_decoder_position_bias = None - - for i, layer_module in enumerate(self.blocks): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states, - attention_mask, - position_bias, - encoder_hidden_states, - encoder_attention_mask, - encoder_decoder_position_bias, - output_attentions, - deterministic, - init_cache, - ) - - hidden_states = layer_outputs[0] - - # We share the position biases between the layers - the first layer store them - # layer_outputs = hidden-states, key-value-states (self-attention position bias), (self-attention weights), - # (cross-attention position bias), (cross-attention weights) - position_bias = layer_outputs[1] - - if self.causal and encoder_hidden_states is not None: - encoder_decoder_position_bias = layer_outputs[3 if output_attentions else 2] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[2],) - if self.causal: - all_cross_attentions = all_cross_attentions + (layer_outputs[4],) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5Stack with T5->LongT5 -class FlaxLongT5Stack(nn.Module): - config: LongT5Config - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.causal = self.config.causal - - self.block = FlaxLongT5BlockCollection( - self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.final_layer_norm = FlaxLongT5LayerNorm( - self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - - def __call__( - self, - input_ids=None, - attention_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - init_cache: bool = False, - ): - hidden_states = self.embed_tokens(input_ids) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - - outputs = self.block( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - deterministic=deterministic, - init_cache=init_cache, - ) - - hidden_states = outputs[0] - - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - - # Add last layer - all_hidden_states = None - - if output_hidden_states: - all_hidden_states = outputs.hidden_states - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - if output_hidden_states: - return ( - hidden_states, - all_hidden_states, - ) + outputs[2:] - return (hidden_states,) + outputs[1:] - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -LONGT5_ENCODE_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. LongT5 is a model with relative position embeddings so - you should be able to pad the inputs on both the right and the left. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for detail. - - To know more on how to prepare `input_ids` for pretraining take a look a [LONGT5 - Training](./longt5#training). - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -LONGT5_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For training, `decoder_input_ids` should be provided. - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - past_key_values (`Dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -LONGT5_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. LongT5 is a model with relative position embeddings so - you should be able to pad the inputs on both the right and the left. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for detail. - - [What are input IDs?](../glossary#input-ids) - - To know more on how to prepare `input_ids` for pretraining take a look a [LONGT5 - Training](./longt5#training). - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - LONGT5 uses the `pad_token_id` as the starting token for `decoder_input_ids` generation. If - `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - To know more on how to prepare `decoder_input_ids` for pretraining take a look at [LONGT5 - Training](./longt5#training). - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - encoder_outputs (`tuple(tuple(jnp.ndarray)`, *optional*): - Tuple consists of (`last_hidden_state`, `optional`: *hidden_states*, `optional`: *attentions*) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)` is a sequence of hidden states at - the output of the last layer of the encoder. Used in the cross-attention of the decoder. - past_key_values (`tuple(tuple(jnp.ndarray))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -class FlaxLongT5PreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = LongT5Config - base_model_prefix = "transformer" - module_class: nn.Module = None - - def __init__( - self, - config: LongT5Config, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def enable_gradient_checkpointing(self): - self._module = self.module_class( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=True, - ) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - - attention_mask = jnp.ones_like(input_ids) - decoder_input_ids = jnp.ones_like(input_ids) - decoder_attention_mask = jnp.ones_like(input_ids) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(LONGT5_INPUTS_DOCSTRING) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_input_ids: jnp.ndarray = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if decoder_input_ids is None: - raise ValueError( - "Make sure to provide both `input_ids` and `decoder_input_ids`. `decoder_input_ids` is not passed" - " here." - ) - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # prepare decoder inputs - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(LONGT5_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=LongT5Config) - def encode( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxLongT5ForConditionalGeneration - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-base") - >>> model = FlaxLongT5ForConditionalGeneration.from_pretrained("google/long-t5-local-base") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, input_ids, attention_mask, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(input_ids, attention_mask, **kwargs) - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - @add_start_docstrings(LONGT5_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=LongT5Config) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxLongT5ForConditionalGeneration - >>> import jax.numpy as jnp - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-base") - >>> model = FlaxLongT5ForConditionalGeneration.from_pretrained("google/long-t5-local-base") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxLongT5Attention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - -LONGT5_START_DOCSTRING = r""" - The LongT5 model was proposed in [LongT5: Efficient Text-To-Text Transformer for Long - Sequences](https://huggingface.co/papers/2112.07916) by Mandy Guo, Joshua Ainslie, David Uthus, Santiago Ontanon, Jianmo - Ni, Yun-Hsuan Sung and Yinfei Yang. It's an encoder-decoder transformer pre-trained in a text-to-text denoising - generative setting. LongT5 model is an extension of T5 model, and it enables using one of the two different - efficient attention mechanisms - (1) Local attention, or (2) Transient-Global attention. - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`LongT5Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - - -@add_start_docstrings( - "The bare LONGT5 Model transformer outputting raw hidden-stateswithout any specific head on top.", - LONGT5_START_DOCSTRING, -) -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5Module with T5->LongT5 -class FlaxLongT5Module(nn.Module): - config: LongT5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - def setup(self): - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.initializer_factor * 1.0), - dtype=self.dtype, - ) - - encoder_config = copy.deepcopy(self.config) - encoder_config.causal = False - self.encoder = FlaxLongT5Stack( - encoder_config, - embed_tokens=self.shared, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - decoder_config = copy.deepcopy(self.config) - decoder_config.causal = True - decoder_config.num_layers = self.config.num_decoder_layers - self.decoder = FlaxLongT5Stack( - decoder_config, - embed_tokens=self.shared, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - def __call__( - self, - input_ids=None, - attention_mask=None, - decoder_input_ids=None, - decoder_attention_mask=None, - encoder_outputs=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - deterministic: bool = True, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # Encode if needed (training, first prediction pass) - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - # Decode - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5Model with T5->LongT5 -class FlaxLongT5Model(FlaxLongT5PreTrainedModel): - module_class = FlaxLongT5Module - - -append_call_sample_docstring(FlaxLongT5Model, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) - -FLAX_LONGT5_MODEL_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxLongT5Model - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-base") - >>> model = FlaxLongT5Model.from_pretrained("google/long-t5-local-base") - - >>> input_ids = tokenizer( - ... "Studies have been shown that owning a dog is good for you", return_tensors="np" - ... ).input_ids - >>> decoder_input_ids = tokenizer("Studies show that", return_tensors="np").input_ids - - >>> # forward pass - >>> outputs = model(input_ids=input_ids, decoder_input_ids=decoder_input_ids) - >>> last_hidden_states = outputs.last_hidden_state - ``` -""" - - -overwrite_call_docstring(FlaxLongT5Model, LONGT5_INPUTS_DOCSTRING + FLAX_LONGT5_MODEL_DOCSTRING) -append_replace_return_docstrings(FlaxLongT5Model, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - - -@add_start_docstrings("""LONGT5 Model with a `language modeling` head on top.""", LONGT5_START_DOCSTRING) -# Copied from transformers.models.t5.modeling_flax_t5.FlaxT5ForConditionalGenerationModule with T5->LongT5 -class FlaxLongT5ForConditionalGenerationModule(nn.Module): - config: LongT5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - def setup(self): - self.model_dim = self.config.d_model - - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.initializer_factor), - dtype=self.dtype, - ) - - encoder_config = copy.deepcopy(self.config) - encoder_config.causal = False - encoder_config.use_cache = False - encoder_config.is_encoder_decoder = False - self.encoder = FlaxLongT5Stack( - encoder_config, self.shared, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - - decoder_config = copy.deepcopy(self.config) - decoder_config.causal = True - decoder_config.is_encoder_decoder = False - decoder_config.num_layers = self.config.num_decoder_layers - self.decoder = FlaxLongT5Stack( - decoder_config, self.shared, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - kernel_init=jax.nn.initializers.normal(self.config.initializer_factor), - dtype=self.dtype, - ) - - def __call__( - self, - input_ids=None, - attention_mask=None, - decoder_input_ids=None, - decoder_attention_mask=None, - encoder_outputs=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - deterministic: bool = True, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # Encode - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = encoder_outputs[0] - - # Decode - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - encoder_hidden_states=hidden_states, - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - sequence_output = decoder_outputs[0] - - if self.config.tie_word_embeddings: - # Rescale output before projecting on vocab - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586 - sequence_output = sequence_output * (self.model_dim**-0.5) - - if self.config.tie_word_embeddings: - shared_embedding = self.shared.variables["params"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, sequence_output) - else: - lm_logits = self.lm_head(sequence_output) - - if not return_dict: - return (lm_logits,) + decoder_outputs[1:] + encoder_outputs - - return FlaxSeq2SeqLMOutput( - logits=lm_logits, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -class FlaxLongT5ForConditionalGeneration(FlaxLongT5PreTrainedModel): - module_class = FlaxLongT5ForConditionalGenerationModule - - @add_start_docstrings(LONGT5_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=LongT5Config) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxLongT5ForConditionalGeneration - >>> import jax.numpy as jnp - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-base") - >>> model = FlaxLongT5ForConditionalGeneration.from_pretrained("google/long-t5-local-base") - - >>> text = "summarize: My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxLongT5Attention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, **kwargs): - decoder_module = module._get_decoder_module() - decoder_outputs = decoder_module( - decoder_input_ids, - decoder_attention_mask, - **kwargs, - ) - - sequence_output = decoder_outputs[0] - - if self.config.tie_word_embeddings: - # Rescale output before projecting on vocab - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586 - sequence_output = sequence_output * (self.config.d_model**-0.5) - - if self.config.tie_word_embeddings: - shared_embedding = module.shared.variables["params"]["embedding"] - lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, sequence_output) - else: - lm_logits = module.lm_head(sequence_output) - - return lm_logits, decoder_outputs - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - if past_key_values is None: - lm_logits, decoder_outputs = outputs - else: - (lm_logits, decoder_outputs), past = outputs - - if return_dict: - outputs = FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=decoder_outputs.hidden_states, - attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - ) - else: - outputs = (lm_logits,) + decoder_outputs[1:] - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - extended_attention_mask = jax.lax.dynamic_update_slice( - extended_attention_mask, decoder_attention_mask, (0, 0) - ) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - return model_kwargs - - -FLAX_LONGT5_CONDITIONAL_GENERATION_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxLongT5ForConditionalGeneration - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-base") - >>> model = FlaxLongT5ForConditionalGeneration.from_pretrained("google/long-t5-local-base") - - >>> ARTICLE_TO_SUMMARIZE = "summarize: My friends are cool but they eat too many carbs." - >>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], return_tensors="np") - - >>> # Generate Summary - >>> summary_ids = model.generate(inputs["input_ids"]).sequences - >>> print(tokenizer.decode(summary_ids[0], skip_special_tokens=True, clean_up_tokenization_spaces=False)) - ``` -""" - - -overwrite_call_docstring( - FlaxLongT5ForConditionalGeneration, LONGT5_INPUTS_DOCSTRING + FLAX_LONGT5_CONDITIONAL_GENERATION_DOCSTRING -) -append_replace_return_docstrings( - FlaxLongT5ForConditionalGeneration, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC -) - - -__all__ = ["FlaxLongT5ForConditionalGeneration", "FlaxLongT5Model", "FlaxLongT5PreTrainedModel"] diff --git a/src/transformers/models/longt5/modeling_longt5.py b/src/transformers/models/longt5/modeling_longt5.py index 4e84a1550349..a3499fb2a0ba 100644 --- a/src/transformers/models/longt5/modeling_longt5.py +++ b/src/transformers/models/longt5/modeling_longt5.py @@ -347,7 +347,6 @@ def __init__( "when creating this class." ) - # Mesh TensorFlow initialization to avoid scaling before softmax self.q = nn.Linear(self.d_model, self.inner_dim, bias=False) self.k = nn.Linear(self.d_model, self.inner_dim, bias=False) self.v = nn.Linear(self.d_model, self.inner_dim, bias=False) @@ -570,7 +569,6 @@ def __init__(self, config: LongT5Config, has_relative_attention_bias: bool = Fal self.dropout = config.dropout_rate self.inner_dim = self.n_heads * self.key_value_proj_dim - # Mesh TensorFlow initialization to avoid scaling before softmax self.q = nn.Linear(self.d_model, self.inner_dim, bias=False) self.k = nn.Linear(self.d_model, self.inner_dim, bias=False) self.v = nn.Linear(self.d_model, self.inner_dim, bias=False) @@ -765,7 +763,6 @@ def __init__(self, config: LongT5Config, has_relative_attention_bias: bool = Fal self.dropout = config.dropout_rate self.inner_dim = self.n_heads * self.key_value_proj_dim - # Mesh TensorFlow initialization to avoid scaling before softmax self.q = nn.Linear(self.d_model, self.inner_dim, bias=False) self.k = nn.Linear(self.d_model, self.inner_dim, bias=False) self.v = nn.Linear(self.d_model, self.inner_dim, bias=False) @@ -1276,15 +1273,10 @@ def _init_weights(self, module): if isinstance(module, LongT5LayerNorm): module.weight.data.fill_(factor * 1.0) elif isinstance(module, (LongT5Model, LongT5ForConditionalGeneration, LongT5EncoderModel)): - # Mesh TensorFlow embeddings initialization - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L1624 module.shared.weight.data.normal_(mean=0.0, std=factor * 1.0) if hasattr(module, "lm_head") and not self.config.tie_word_embeddings: module.lm_head.weight.data.normal_(mean=0.0, std=factor * 1.0) elif isinstance(module, LongT5DenseActDense): - # Mesh TensorFlow FF initialization - # See https://github.com/tensorflow/mesh/blob/master/mesh_tensorflow/transformer/transformer_layers.py#L56 - # and https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L89 module.wi.weight.data.normal_(mean=0.0, std=factor * ((self.config.d_model) ** -0.5)) if hasattr(module.wi, "bias") and module.wi.bias is not None: module.wi.bias.data.zero_() @@ -1302,8 +1294,6 @@ def _init_weights(self, module): if hasattr(module.wo, "bias") and module.wo.bias is not None: module.wo.bias.data.zero_() elif isinstance(module, (LongT5Attention, LongT5LocalAttention, LongT5TransientGlobalAttention)): - # Mesh TensorFlow attention initialization to avoid scaling before softmax - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/attention.py#L136 d_model = self.config.d_model key_value_proj_dim = self.config.d_kv n_heads = self.config.num_heads @@ -2072,8 +2062,6 @@ def forward( sequence_output = decoder_outputs[0] if self.config.tie_word_embeddings: - # Rescale output before projecting on vocab - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586 sequence_output = sequence_output * (self.model_dim**-0.5) lm_logits = self.lm_head(sequence_output) @@ -2084,7 +2072,6 @@ def forward( labels = labels.to(lm_logits.device) loss = loss_fct(lm_logits.view(-1, lm_logits.size(-1)), labels.view(-1)) - # TODO(thom): Add z_loss https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L666 if not return_dict: output = (lm_logits,) + decoder_outputs[1:] + encoder_outputs diff --git a/src/transformers/models/luke/modeling_luke.py b/src/transformers/models/luke/modeling_luke.py index e78197beeb57..95e71e8e4a1c 100644 --- a/src/transformers/models/luke/modeling_luke.py +++ b/src/transformers/models/luke/modeling_luke.py @@ -298,8 +298,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) diff --git a/src/transformers/models/luke/tokenization_luke.py b/src/transformers/models/luke/tokenization_luke.py index efbc757e8630..4bb19bb5ee73 100644 --- a/src/transformers/models/luke/tokenization_luke.py +++ b/src/transformers/models/luke/tokenization_luke.py @@ -37,7 +37,7 @@ TruncationStrategy, to_py_obj, ) -from ...utils import add_end_docstrings, is_tf_tensor, is_torch_tensor, logging +from ...utils import add_end_docstrings, is_torch_tensor, logging logger = logging.get_logger(__name__) @@ -1403,7 +1403,7 @@ def pad( Pad a single encoded input or a batch of encoded inputs up to predefined length or to the max sequence length in the batch. Padding side (left/right) padding token ids are defined at the tokenizer level (with `self.padding_side`, `self.pad_token_id` and `self.pad_token_type_id`) .. note:: If the `encoded_inputs` passed - are dictionary of numpy arrays, PyTorch tensors or TensorFlow tensors, the result will use the same type unless + are dictionary of numpy arrays or PyTorch tensors the result will use the same type unless you provide a different tensor type with `return_tensors`. In the case of PyTorch tensors, you will lose the specific device of your tensors however. @@ -1412,8 +1412,8 @@ def pad( Tokenized inputs. Can represent one input ([`BatchEncoding`] or `dict[str, list[int]]`) or a batch of tokenized inputs (list of [`BatchEncoding`], *dict[str, list[list[int]]]* or *list[dict[str, list[int]]]*) so you can use this method during preprocessing as well as in a PyTorch Dataloader - collate function. Instead of `list[int]` you can have tensors (numpy arrays, PyTorch tensors or - TensorFlow tensors), see the note above for the return type. + collate function. Instead of `list[int]` you can have tensors (numpy arrays, or PyTorch tensors), + see the note above for the return type. padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `True`): Select a strategy to pad the returned sequences (according to the model's padding side and padding index) among: @@ -1441,7 +1441,6 @@ def pad( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. verbose (`bool`, *optional*, defaults to `True`): @@ -1466,7 +1465,7 @@ def pad( encoded_inputs["attention_mask"] = [] return encoded_inputs - # If we have PyTorch/TF/NumPy tensors/arrays as inputs, we cast them as python objects + # If we have PyTorch/NumPy tensors/arrays as inputs, we cast them as python objects # and rebuild them afterwards if no return_tensors is specified # Note that we lose the specific device the tensor may be on for PyTorch @@ -1480,16 +1479,14 @@ def pad( first_element = required_input[index][0] # At this state, if `first_element` is still a list/tuple, it's an empty one so there is nothing to do. if not isinstance(first_element, (int, list, tuple)): - if is_tf_tensor(first_element): - return_tensors = "tf" if return_tensors is None else return_tensors - elif is_torch_tensor(first_element): + if is_torch_tensor(first_element): return_tensors = "pt" if return_tensors is None else return_tensors elif isinstance(first_element, np.ndarray): return_tensors = "np" if return_tensors is None else return_tensors else: raise ValueError( f"type of {first_element} unknown: {type(first_element)}. " - "Should be one of a python, numpy, pytorch or tensorflow object." + "Should be one of a python, numpy, or pytorch object." ) for key, value in encoded_inputs.items(): diff --git a/src/transformers/models/lxmert/__init__.py b/src/transformers/models/lxmert/__init__.py index 3ad507465039..8cde45820316 100644 --- a/src/transformers/models/lxmert/__init__.py +++ b/src/transformers/models/lxmert/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_lxmert import * from .modeling_lxmert import * - from .modeling_tf_lxmert import * from .tokenization_lxmert import * from .tokenization_lxmert_fast import * else: diff --git a/src/transformers/models/lxmert/configuration_lxmert.py b/src/transformers/models/lxmert/configuration_lxmert.py index 18d3d2e60d7b..cba273e0f19a 100644 --- a/src/transformers/models/lxmert/configuration_lxmert.py +++ b/src/transformers/models/lxmert/configuration_lxmert.py @@ -66,8 +66,6 @@ class LxmertConfig(PretrainedConfig): The vocabulary size of the *token_type_ids* passed into [`BertModel`]. initializer_range (`float`, *optional*, defaults to 0.02): The standard deviation of the truncated_normal_initializer for initializing all weight matrices. - layer_norm_eps (`float`, *optional*, defaults to 1e-12): - The epsilon used by the layer normalization layers. l_layers (`int`, *optional*, defaults to 9): Number of hidden layers in the Transformer language encoder. x_layers (`int`, *optional*, defaults to 5): @@ -119,7 +117,6 @@ def __init__( max_position_embeddings=512, type_vocab_size=2, initializer_range=0.02, - layer_norm_eps=1e-12, l_layers=9, x_layers=5, r_layers=5, @@ -145,7 +142,6 @@ def __init__( self.max_position_embeddings = max_position_embeddings self.type_vocab_size = type_vocab_size self.initializer_range = initializer_range - self.layer_norm_eps = layer_norm_eps self.num_qa_labels = num_qa_labels self.num_object_labels = num_object_labels self.num_attr_labels = num_attr_labels diff --git a/src/transformers/models/lxmert/convert_lxmert_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/lxmert/convert_lxmert_original_tf_checkpoint_to_pytorch.py index 1dd77bc36f80..bf93a1cad190 100755 --- a/src/transformers/models/lxmert/convert_lxmert_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/lxmert/convert_lxmert_original_tf_checkpoint_to_pytorch.py @@ -15,16 +15,97 @@ """Convert LXMERT checkpoint.""" import argparse +import os import torch -from transformers import LxmertConfig, LxmertForPreTraining, load_tf_weights_in_lxmert +from transformers import LxmertConfig, LxmertForPreTraining from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +def load_tf_weights_in_lxmert(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array) + + for name, array in zip(names, arrays): + name = name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any( + n + in [ + "adam_v", + "adam_m", + "AdamWeightDecayOptimizer", + "AdamWeightDecayOptimizer_1", + "global_step", + ] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + continue + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "kernel" or scope_names[0] == "gamma": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + else: + try: + pointer = getattr(pointer, scope_names[0]) + except AttributeError: + logger.info(f"Skipping {'/'.join(name)}") + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if m_name[-11:] == "_embeddings": + pointer = getattr(pointer, "weight") + elif m_name == "kernel": + array = np.transpose(array) + try: + assert pointer.shape == array.shape + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + return model + + def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, config_file, pytorch_dump_path): # Initialise PyTorch model config = LxmertConfig.from_json_file(config_file) diff --git a/src/transformers/models/lxmert/modeling_lxmert.py b/src/transformers/models/lxmert/modeling_lxmert.py index 00243ce12329..c2183b6f41c8 100644 --- a/src/transformers/models/lxmert/modeling_lxmert.py +++ b/src/transformers/models/lxmert/modeling_lxmert.py @@ -15,7 +15,6 @@ """PyTorch LXMERT model.""" import math -import os import warnings from dataclasses import dataclass from typing import Optional, Union @@ -179,85 +178,6 @@ class LxmertForPreTrainingOutput(ModelOutput): cross_encoder_attentions: Optional[tuple[torch.FloatTensor]] = None -def load_tf_weights_in_lxmert(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n - in [ - "adam_v", - "adam_m", - "AdamWeightDecayOptimizer", - "AdamWeightDecayOptimizer_1", - "global_step", - ] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - assert pointer.shape == array.shape - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class LxmertEmbeddings(nn.Module): """Construct the embeddings from word, position and token_type embeddings.""" @@ -267,8 +187,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size, padding_idx=0) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size, padding_idx=0) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=1e-12) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -760,15 +678,12 @@ def forward(self, sequence_output, pooled_output): @auto_docstring class LxmertPreTrainedModel(PreTrainedModel): config: LxmertConfig - load_tf_weights = load_tf_weights_in_lxmert base_model_prefix = "lxmert" _supports_param_buffer_assignment = False def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/lxmert/modeling_tf_lxmert.py b/src/transformers/models/lxmert/modeling_tf_lxmert.py deleted file mode 100644 index aee9fb785796..000000000000 --- a/src/transformers/models/lxmert/modeling_tf_lxmert.py +++ /dev/null @@ -1,1660 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The Google AI Language Team Authors, The HuggingFace Inc. team, and the -# Lxmert Authors. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 LXMERT model.""" - -from __future__ import annotations - -import warnings -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - get_initializer, - keras, - keras_serializable, - shape_list, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_lxmert import LxmertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "unc-nlp/lxmert-base-uncased" -_CONFIG_FOR_DOC = "LxmertConfig" - - -@dataclass -class TFLxmertModelOutput(ModelOutput): - """ - Lxmert's outputs that contain the last hidden states, pooled outputs, and attention probabilities for the language, - visual, and, cross-modality encoders. (note: the visual encoder in Lxmert is referred to as the "relation-ship" - encoder") - - - Args: - language_output (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the language encoder. - vision_output (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the visual encoder. - pooled_output (`tf.Tensor` of shape `(batch_size, hidden_size)`): - Last layer hidden-state of the first token of the sequence (classification, CLS, token) further processed - by a Linear layer and a Tanh activation function. The Linear - language_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for input features + one for the output of each cross-modality layer) of shape - `(batch_size, sequence_length, hidden_size)`. - vision_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for input features + one for the output of each cross-modality layer) of shape - `(batch_size, sequence_length, hidden_size)`. - language_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - vision_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - cross_encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - """ - - language_output: tf.Tensor | None = None - vision_output: tf.Tensor | None = None - pooled_output: tf.Tensor | None = None - language_hidden_states: tuple[tf.Tensor] | None = None - vision_hidden_states: tuple[tf.Tensor] | None = None - language_attentions: tuple[tf.Tensor] | None = None - vision_attentions: tuple[tf.Tensor] | None = None - cross_encoder_attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFLxmertForPreTrainingOutput(ModelOutput): - """ - Output type of [`LxmertForPreTraining`]. - - Args: - loss (*optional*, returned when `labels` is provided, `tf.Tensor` of shape `(1,)`): - Total loss as the sum of the masked language modeling loss and the next sequence prediction - (classification) loss. - prediction_logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - cross_relationship_score (`tf.Tensor` of shape `(batch_size, 2)`): - Prediction scores of the textual matching objective (classification) head (scores of True/False - continuation before SoftMax). - question_answering_score (`tf.Tensor` of shape `(batch_size, n_qa_answers)`): - Prediction scores of question answering objective (classification). - language_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for input features + one for the output of each cross-modality layer) of shape - `(batch_size, sequence_length, hidden_size)`. - vision_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for input features + one for the output of each cross-modality layer) of shape - `(batch_size, sequence_length, hidden_size)`. - language_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - vision_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - cross_encoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - - """ - - loss: tf.Tensor | None = None - prediction_logits: tf.Tensor | None = None - cross_relationship_score: tf.Tensor | None = None - question_answering_score: tf.Tensor | None = None - language_hidden_states: tuple[tf.Tensor] | None = None - vision_hidden_states: tuple[tf.Tensor] | None = None - language_attentions: tuple[tf.Tensor] | None = None - vision_attentions: tuple[tf.Tensor] | None = None - cross_encoder_attentions: tuple[tf.Tensor] | None = None - - -class TFLxmertVisualFeatureEncoder(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - # Object feature encoding - self.visn_fc = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="visn_fc", - ) - self.visn_layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="visn_layer_norm") - - # Box position encoding - self.box_fc = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="box_fc", - ) - self.box_layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="box_layer_norm") - - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.feat_dim = config.visual_feat_dim - self.pos_dim = config.visual_pos_dim - self.config = config - - def call(self, visn_input, training=False): - feats, boxes = visn_input - - x = self.visn_fc(feats) - x = self.visn_layer_norm(x) - y = self.box_fc(boxes) - y = self.box_layer_norm(y) - output = (x + y) / 2 - - output = self.dropout(output, training=training) - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "visn_fc", None) is not None: - with tf.name_scope(self.visn_fc.name): - self.visn_fc.build([None, None, self.feat_dim]) - if getattr(self, "visn_layer_norm", None) is not None: - with tf.name_scope(self.visn_layer_norm.name): - self.visn_layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "box_fc", None) is not None: - with tf.name_scope(self.box_fc.name): - self.box_fc.build([None, None, self.pos_dim]) - if getattr(self, "box_layer_norm", None) is not None: - with tf.name_scope(self.box_layer_norm.name): - self.box_layer_norm.build([None, None, self.config.hidden_size]) - - -class TFLxmertEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(initializer_range=self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.hidden_size], - initializer=get_initializer(initializer_range=self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(initializer_range=self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - def call(self, input_ids=None, token_type_ids=None, inputs_embeds=None, training=False): - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -class TFLxmertAttention(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " - f"heads ({config.num_attention_heads}" - ) - - self.num_attention_heads = config.num_attention_heads - assert config.hidden_size % config.num_attention_heads == 0 - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - - self.query = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="query", - ) - self.key = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="key", - ) - self.value = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - name="value", - ) - - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.ctx_dim = config.hidden_size - self.config = config - - def transpose_for_scores(self, x, batch_size): - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - x = tf.reshape(x, (batch_size, -1, self.num_attention_heads, self.attention_head_size)) - return tf.transpose(x, perm=[0, 2, 1, 3]) - - def call(self, hidden_states, context, attention_mask, output_attentions, training=False): - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(hidden_states) - mixed_key_layer = self.key(context) - mixed_value_layer = self.value(context) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = tf.matmul( - query_layer, key_layer, transpose_b=True - ) # (batch size, num_heads, seq_len_q, seq_len_k) - dk = tf.cast(shape_list(key_layer)[-1], dtype=attention_scores.dtype) # scale attention_scores - attention_scores = attention_scores / tf.math.sqrt(dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFLxmertModel call() function) - attention_mask = tf.cast(attention_mask, dtype=attention_scores.dtype) - attention_scores = attention_scores + attention_mask - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs, training=training) - context_layer = tf.matmul(attention_probs, value_layer) - - context_layer = tf.transpose(context_layer, perm=[0, 2, 1, 3]) - context_layer = tf.reshape( - context_layer, (batch_size, -1, self.all_head_size) - ) # (batch_size, seq_len_q, all_head_size) - - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.ctx_dim]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.ctx_dim]) - - -class TFLxmertIntermediate(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.intermediate_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFLxmertOutput(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states, input_tensor, training=False): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFLxmertAttentionOutput(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states, input_tensor, training=False): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFLxmertSelfAttentionLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.self = TFLxmertAttention(config, name="self") - self.attention_output = TFLxmertAttentionOutput(config, name="output") - - def call(self, input_tensor, attention_mask, output_attentions, training=False): - # Self attention attends to itself, thus keys and queries are the same (input_tensor). - self_output = self.self(input_tensor, input_tensor, attention_mask, output_attentions) - if output_attentions: - attention_probs = self_output[1] - attention_output = self.attention_output(self_output[0], input_tensor) - return (attention_output, attention_probs) if output_attentions else (attention_output,) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self", None) is not None: - with tf.name_scope(self.self.name): - self.self.build(None) - if getattr(self, "attention_output", None) is not None: - with tf.name_scope(self.attention_output.name): - self.attention_output.build(None) - - -class TFLxmertCrossAttentionLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.att = TFLxmertAttention(config, name="att") - self.attention_output = TFLxmertAttentionOutput(config, name="output") - - def call( - self, - input_tensor, - ctx_tensor, - ctx_att_mask, - output_attentions=False, - training=False, - ): - output = self.att(input_tensor, ctx_tensor, ctx_att_mask, output_attentions, training=training) - if output_attentions: - attention_probs = output[1] - attention_output = self.attention_output(output[0], input_tensor, training=training) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "att", None) is not None: - with tf.name_scope(self.att.name): - self.att.build(None) - if getattr(self, "attention_output", None) is not None: - with tf.name_scope(self.attention_output.name): - self.attention_output.build(None) - - -class TFLxmertLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.attention = TFLxmertSelfAttentionLayer(config, name="attention") - self.intermediate = TFLxmertIntermediate(config, name="intermediate") - self.transformer_output = TFLxmertOutput(config, name="output") - - def call(self, hidden_states, attention_mask, output_attentions, training=False): - attention_outputs = self.attention(hidden_states, attention_mask, output_attentions, training=training) - attention_output = attention_outputs[0] - intermediate_output = self.intermediate(attention_output) - layer_output = self.transformer_output(intermediate_output, attention_output, training=training) - outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "transformer_output", None) is not None: - with tf.name_scope(self.transformer_output.name): - self.transformer_output.build(None) - - -class TFLxmertXLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.visual_attention = TFLxmertCrossAttentionLayer(config, name="visual_attention") - - # Self-attention Layers - self.lang_self_att = TFLxmertSelfAttentionLayer(config, name="lang_self_att") - self.visn_self_att = TFLxmertSelfAttentionLayer(config, name="visn_self_att") - - # Intermediate and Output Layers (FFNs) - self.lang_inter = TFLxmertIntermediate(config, name="lang_inter") - self.lang_output = TFLxmertOutput(config, name="lang_output") - self.visn_inter = TFLxmertIntermediate(config, name="visn_inter") - self.visn_output = TFLxmertOutput(config, name="visn_output") - - def cross_att( - self, - lang_input, - lang_attention_mask, - visn_input, - visn_attention_mask, - output_attentions, - training=False, - ): - # Cross Attention - - # Keras saving and loading model *does not work* with the same inputs for two layers. - lang_attention_lang_input = tf.identity(lang_input) - visn_attention_lang_input = tf.identity(lang_input) - lang_attention_visn_input = tf.identity(visn_input) - visn_attention_visn_input = tf.identity(visn_input) - - lang_att_output = self.visual_attention( - lang_attention_lang_input, - lang_attention_visn_input, - visn_attention_mask, - output_attentions=output_attentions, - training=training, - ) - visn_att_output = self.visual_attention( - visn_attention_visn_input, - visn_attention_lang_input, - lang_attention_mask, - output_attentions=output_attentions, - training=training, - ) - return lang_att_output, visn_att_output - - def self_att( - self, - lang_input, - lang_attention_mask, - visn_input, - visn_attention_mask, - training=False, - ): - # Self Attention - output_attentions = False - lang_att_output = self.lang_self_att(lang_input, lang_attention_mask, output_attentions, training=training) - visn_att_output = self.visn_self_att(visn_input, visn_attention_mask, output_attentions, training=training) - return lang_att_output[0], visn_att_output[0] - - def output_fc(self, lang_input, visn_input, training=False): - # FC layers - lang_inter_output = self.lang_inter(lang_input) - visn_inter_output = self.visn_inter(visn_input) - - # Layer output - lang_output = self.lang_output(lang_inter_output, lang_input, training) - visn_output = self.visn_output(visn_inter_output, visn_input, training) - return lang_output, visn_output - - def call( - self, - lang_feats, - lang_attention_mask, - visn_feats, - visn_attention_mask, - output_attentions, - training=False, - ): - lang_att_output = lang_feats - visn_att_output = visn_feats - - lang_att_output, visn_att_output = self.cross_att( - lang_att_output, - lang_attention_mask, - visn_att_output, - visn_attention_mask, - output_attentions, - training=training, - ) - attention_probs = lang_att_output[1:] - lang_att_output, visn_att_output = self.self_att( - lang_att_output[0], - lang_attention_mask, - visn_att_output[0], - visn_attention_mask, - training=training, - ) - lang_output, visn_output = self.output_fc(lang_att_output, visn_att_output, training=training) - - return (lang_output, visn_output, attention_probs[0]) if output_attentions else (lang_output, visn_output) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "visual_attention", None) is not None: - with tf.name_scope(self.visual_attention.name): - self.visual_attention.build(None) - if getattr(self, "lang_self_att", None) is not None: - with tf.name_scope(self.lang_self_att.name): - self.lang_self_att.build(None) - if getattr(self, "visn_self_att", None) is not None: - with tf.name_scope(self.visn_self_att.name): - self.visn_self_att.build(None) - if getattr(self, "lang_inter", None) is not None: - with tf.name_scope(self.lang_inter.name): - self.lang_inter.build(None) - if getattr(self, "lang_output", None) is not None: - with tf.name_scope(self.lang_output.name): - self.lang_output.build(None) - if getattr(self, "visn_inter", None) is not None: - with tf.name_scope(self.visn_inter.name): - self.visn_inter.build(None) - if getattr(self, "visn_output", None) is not None: - with tf.name_scope(self.visn_output.name): - self.visn_output.build(None) - - -class TFLxmertEncoder(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.visn_fc = TFLxmertVisualFeatureEncoder(config, name="visn_fc") - - # Number of layers - self.num_l_layers = config.l_layers - self.num_x_layers = config.x_layers - self.num_r_layers = config.r_layers - - # Layers - # Using self.layer instead of self.l_layer to support loading BERT weights. - self.layer = [TFLxmertLayer(config, name=f"layer_._{i}") for i in range(self.num_l_layers)] - self.x_layers = [TFLxmertXLayer(config, name=f"x_layers_._{i}") for i in range(self.num_x_layers)] - self.r_layers = [TFLxmertLayer(config, name=f"r_layers_._{i}") for i in range(self.num_r_layers)] - self.config = config - - def call( - self, - lang_feats=None, - lang_attention_mask=None, - visual_feats=None, - visual_pos=None, - visual_attention_mask=None, - output_attentions=None, - training=False, - ): - vision_hidden_states = () - language_hidden_states = () - vision_attentions = () if output_attentions or self.config.output_attentions else None - language_attentions = () if output_attentions or self.config.output_attentions else None - cross_encoder_attentions = () if output_attentions or self.config.output_attentions else None - - visual_feats = self.visn_fc([visual_feats, visual_pos], training=training) - - # Run language layers - for layer_module in self.layer: - l_outputs = layer_module(lang_feats, lang_attention_mask, output_attentions, training=training) - lang_feats = l_outputs[0] - language_hidden_states = language_hidden_states + (lang_feats,) - if language_attentions is not None: - language_attentions = language_attentions + (l_outputs[1],) - - # Run relational layers - for layer_module in self.r_layers: - v_outputs = layer_module( - visual_feats, - visual_attention_mask, - output_attentions, - training=training, - ) - visual_feats = v_outputs[0] - vision_hidden_states = vision_hidden_states + (visual_feats,) - if vision_attentions is not None: - vision_attentions = vision_attentions + (v_outputs[1],) - - # Run cross-modality layers - for layer_module in self.x_layers: - x_outputs = layer_module( - lang_feats, - lang_attention_mask, - visual_feats, - visual_attention_mask, - output_attentions, - training=training, - ) - lang_feats, visual_feats = x_outputs[:2] - vision_hidden_states = vision_hidden_states + (visual_feats,) - language_hidden_states = language_hidden_states + (lang_feats,) - if cross_encoder_attentions is not None: - cross_encoder_attentions = cross_encoder_attentions + (x_outputs[2],) - - visual_encoder_outputs = ( - vision_hidden_states, - vision_attentions if output_attentions else None, - ) - lang_encoder_outputs = ( - language_hidden_states, - language_attentions if output_attentions else None, - ) - - return ( - visual_encoder_outputs, - lang_encoder_outputs, - cross_encoder_attentions if output_attentions else None, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "visn_fc", None) is not None: - with tf.name_scope(self.visn_fc.name): - self.visn_fc.build(None) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - if getattr(self, "x_layers", None) is not None: - for layer in self.x_layers: - with tf.name_scope(layer.name): - layer.build(None) - if getattr(self, "r_layers", None) is not None: - for layer in self.r_layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFLxmertMainLayer(keras.layers.Layer): - config_class = LxmertConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.num_l_layers = config.l_layers - self.num_x_layers = config.x_layers - self.num_r_layers = config.r_layers - self.initializer_range = config.initializer_range - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - self.embeddings = TFLxmertEmbeddings(config, name="embeddings") - self.encoder = TFLxmertEncoder(config, name="encoder") - self.pooler = TFLxmertPooler(config, name="pooler") - self.config = config - - def get_input_embeddings(self): - return self.embeddings - - def set_input_embeddings(self, value): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids=None, - visual_feats=None, - visual_pos=None, - attention_mask=None, - visual_attention_mask=None, - token_type_ids=None, - inputs_embeds=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - if visual_pos is None or visual_feats is None: - raise ValueError("visual_feats and visual_pos cannot be `None` in LXMERT's `call` method.") - - if attention_mask is None: - attention_mask = tf.fill(input_shape, 1) - - if token_type_ids is None: - token_type_ids = tf.fill(input_shape, 0) - - # Positional Word Embeddings - embedding_output = self.embeddings(input_ids, token_type_ids, inputs_embeds, training) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - extended_attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - if visual_attention_mask is not None: - extended_visual_attention_mask = tf.reshape(visual_attention_mask, (input_shape[0], 1, 1, input_shape[1])) - extended_visual_attention_mask = tf.expand_dims(tf.expand_dims(visual_attention_mask, axis=1), axis=1) - - extended_visual_attention_mask = tf.cast(extended_visual_attention_mask, dtype=embedding_output.dtype) - extended_visual_attention_mask = tf.multiply( - tf.subtract(one_cst, extended_visual_attention_mask), ten_thousand_cst - ) - else: - extended_visual_attention_mask = None - - # Run Lxmert encoder - encoder_outputs = self.encoder( - embedding_output, - extended_attention_mask, - visual_feats, - visual_pos, - extended_visual_attention_mask, - output_attentions, - training, - ) - visual_encoder_outputs, lang_encoder_outputs = encoder_outputs[:2] - vision_hidden_states = visual_encoder_outputs[0] - language_hidden_states = lang_encoder_outputs[0] - - all_attentions = () - if output_attentions: - language_attentions = lang_encoder_outputs[1] - vision_attentions = visual_encoder_outputs[1] - cross_encoder_attentions = encoder_outputs[2] - all_attentions = ( - language_attentions, - vision_attentions, - cross_encoder_attentions, - ) - - hidden_states = (language_hidden_states, vision_hidden_states) if output_hidden_states else () - - visual_output = vision_hidden_states[-1] - lang_output = language_hidden_states[-1] - pooled_output = self.pooler(lang_output) - - if not return_dict: - return (lang_output, visual_output, pooled_output) + hidden_states + all_attentions - - return TFLxmertModelOutput( - pooled_output=pooled_output, - language_output=lang_output, - vision_output=visual_output, - language_hidden_states=language_hidden_states if output_hidden_states else None, - vision_hidden_states=vision_hidden_states if output_hidden_states else None, - language_attentions=language_attentions if output_attentions else None, - vision_attentions=vision_attentions if output_attentions else None, - cross_encoder_attentions=cross_encoder_attentions if output_attentions else None, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -class TFLxmertPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = LxmertConfig - base_model_prefix = "lxmert" - - @property - def dummy_inputs(self): - """ - Dummy inputs to build the network. - - Returns: - tf.Tensor with dummy inputs - """ - batch_size = 2 - num_visual_features = 10 - input_ids = tf.constant([[3, 5, 6], [2, 3, 4]], dtype=tf.int32) - visual_feats = tf.random.uniform((batch_size, num_visual_features, self.config.visual_feat_dim)) - visual_pos = tf.random.uniform((batch_size, num_visual_features, 4)) - - return { - "input_ids": input_ids, - "visual_feats": visual_feats, - "visual_pos": visual_pos, - } - - @property - def input_signature(self): - return { - "input_ids": tf.TensorSpec((None, None), tf.int32, name="input_ids"), - "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), - "visual_feats": tf.TensorSpec((None, None, self.config.visual_feat_dim), tf.float32, name="visual_feats"), - "visual_pos": tf.TensorSpec((None, None, 4), tf.float32, name="visual_pos"), - "visual_attention_mask": tf.TensorSpec((None, None), tf.int32, name="visual_attention_mask"), - "token_type_ids": tf.TensorSpec((None, None), tf.int32, name="token_type_ids"), - } - - -LXMERT_START_DOCSTRING = r""" - - The LXMERT model was proposed in [LXMERT: Learning Cross-Modality Encoder Representations from - Transformers](https://huggingface.co/papers/1908.07490) by Hao Tan and Mohit Bansal. It's a vision and language transformer - model, pre-trained on a variety of multi-modal datasets comprising of GQA, VQAv2.0, MCSCOCO captions, and Visual - genome, using a combination of masked language modeling, region of interest feature regression, cross entropy loss - for question answering attribute prediction, and object tag prediction. - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`LxmertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -LXMERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray` or `tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - visual_feats (`tf.Tensor` of shape `(batch_size, num_visual_features, visual_feat_dim)`): - This input represents visual features. They ROI pooled object features from bounding boxes using a - faster-RCNN model) - - These are currently not provided by the transformers library. - visual_pos (`tf.Tensor` of shape `(batch_size, num_visual_features, visual_feat_dim)`): - This input represents spatial features corresponding to their relative (via index) visual features. The - pre-trained LXMERT model expects these spatial features to be normalized bounding boxes on a scale of 0 to - 1. - - These are currently not provided by the transformers library. - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - visual_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - MMask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare Lxmert Model transformer outputting raw hidden-states without any specific head on top.", - LXMERT_START_DOCSTRING, -) -class TFLxmertModel(TFLxmertPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.lxmert = TFLxmertMainLayer(config, name="lxmert") - - @unpack_inputs - @add_start_docstrings_to_model_forward(LXMERT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFLxmertModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - visual_feats: tf.Tensor | None = None, - visual_pos: tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - visual_attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple | TFLxmertModelOutput: - outputs = self.lxmert( - input_ids, - visual_feats, - visual_pos, - attention_mask, - visual_attention_mask, - token_type_ids, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict, - training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "lxmert", None) is not None: - with tf.name_scope(self.lxmert.name): - self.lxmert.build(None) - - -class TFLxmertPooler(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states): - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(first_token_tensor) - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPredictionHeadTransform with Bert->Lxmert -class TFLxmertPredictionHeadTransform(keras.layers.Layer): - def __init__(self, config: LxmertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - - if isinstance(config.hidden_act, str): - self.transform_act_fn = get_tf_activation(config.hidden_act) - else: - self.transform_act_fn = config.hidden_act - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.transform_act_fn(hidden_states) - hidden_states = self.LayerNorm(inputs=hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLMPredictionHead with Bert->Lxmert -class TFLxmertLMPredictionHead(keras.layers.Layer): - def __init__(self, config: LxmertConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - - self.transform = TFLxmertPredictionHeadTransform(config, name="transform") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.input_embeddings = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "transform", None) is not None: - with tf.name_scope(self.transform.name): - self.transform.build(None) - - def get_output_embeddings(self) -> keras.layers.Layer: - return self.input_embeddings - - def set_output_embeddings(self, value: tf.Variable): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self) -> dict[str, tf.Variable]: - return {"bias": self.bias} - - def set_bias(self, value: tf.Variable): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.transform(hidden_states=hidden_states) - seq_length = shape_list(hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertMLMHead with Bert->Lxmert -class TFLxmertMLMHead(keras.layers.Layer): - def __init__(self, config: LxmertConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.predictions = TFLxmertLMPredictionHead(config, input_embeddings, name="predictions") - - def call(self, sequence_output: tf.Tensor) -> tf.Tensor: - prediction_scores = self.predictions(hidden_states=sequence_output) - - return prediction_scores - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -class TFLxmertPreTrainingHeads(keras.layers.Layer): - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - self.predictions = TFLxmertLMPredictionHead(config, input_embeddings, name="predictions") - - self.seq_relationship = keras.layers.Dense( - 2, - kernel_initializer=get_initializer(config.initializer_range), - name="seq_relationship", - ) - self.config = config - - def call(self, sequence_output, pooled_output): - prediction_scores = self.predictions(sequence_output) - seq_relationship_score = self.seq_relationship(pooled_output) - return prediction_scores, seq_relationship_score - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - if getattr(self, "seq_relationship", None) is not None: - with tf.name_scope(self.seq_relationship.name): - self.seq_relationship.build([None, None, self.config.hidden_size]) - - -class TFLxmertVisualAnswerHead(keras.layers.Layer): - def __init__(self, config, num_labels, **kwargs): - super().__init__(**kwargs) - hid_dim = config.hidden_size - self.dense = keras.layers.Dense( - hid_dim * 2, - kernel_initializer=get_initializer(config.initializer_range), - name="logit_fc_._0", - ) - self.activation = get_tf_activation("gelu") - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="logit_fc_._2") - self.dense_1 = keras.layers.Dense( - num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="logit_fc_._3", - ) - self.hid_dim = hid_dim - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - hidden_states = self.layer_norm(hidden_states) - hidden_states = self.dense_1(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.hid_dim]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, self.hid_dim * 2]) - if getattr(self, "dense_1", None) is not None: - with tf.name_scope(self.dense_1.name): - self.dense_1.build([None, None, self.hid_dim * 2]) - - -class TFLxmertVisualObjHead(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.transform = TFLxmertPredictionHeadTransform(config, name="transform") - - # Decide the use of visual losses - visual_losses = {} - if config.visual_obj_loss: - visual_losses["obj"] = {"shape": (-1,), "num": config.num_object_labels} - if config.visual_attr_loss: - visual_losses["attr"] = {"shape": (-1,), "num": config.num_attr_labels} - if config.visual_feat_loss: - visual_losses["feat"] = {"shape": (-1, 2048), "num": config.visual_feat_dim} - self.visual_losses = visual_losses - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.decoder_dict = { - key: keras.layers.Dense( - self.visual_losses[key]["num"], - kernel_initializer=get_initializer(config.initializer_range), - name=f"decoder_dict.{key}", - ) - for key in self.visual_losses - } - self.config = config - - def call(self, hidden_states): - hidden_states = self.transform(hidden_states) - output = {} - for key in self.visual_losses: - output[key] = self.decoder_dict[key](hidden_states) - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transform", None) is not None: - with tf.name_scope(self.transform.name): - self.transform.build(None) - if getattr(self, "decoder_dict", None) is not None: - for layer in self.decoder_dict.values(): - with tf.name_scope(layer.name): - layer.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings("""Lxmert Model with a `language modeling` head on top.""", LXMERT_START_DOCSTRING) -class TFLxmertForPreTraining(TFLxmertPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.config = config - self.num_qa_labels = config.num_qa_labels - self.visual_loss_normalizer = config.visual_loss_normalizer - - # Use of pretraining tasks - self.task_mask_lm = config.task_mask_lm - self.task_obj_predict = config.task_obj_predict - self.task_matched = config.task_matched - self.task_qa = config.task_qa - - # Lxmert backbone - self.lxmert = TFLxmertMainLayer(config, name="lxmert") - - # Pre-training heads - self.cls = TFLxmertPreTrainingHeads(config, self.lxmert.embeddings, name="cls") - if self.task_obj_predict: - self.obj_predict_head = TFLxmertVisualObjHead(config, name="obj_predict_head") - if self.task_qa: - self.answer_head = TFLxmertVisualAnswerHead(config, self.num_qa_labels, name="answer_head") - - # Loss functions - self.loss_fcts = { - "l2": keras.losses.Huber(delta=1.0, name="huber_loss"), - "visn_ce": keras.losses.SparseCategoricalCrossentropy(from_logits=True), - "ce": keras.losses.SparseCategoricalCrossentropy(from_logits=True), - } - - visual_losses = {} - if config.visual_obj_loss: - visual_losses["obj"] = { - "shape": (-1,), - "num": config.num_object_labels, - "loss": "visn_ce", - } - if config.visual_attr_loss: - visual_losses["attr"] = { - "shape": (-1,), - "num": config.num_attr_labels, - "loss": "visn_ce", - } - if config.visual_feat_loss: - visual_losses["feat"] = { - "shape": (-1, config.visual_feat_dim), - "num": config.visual_feat_dim, - "loss": "l2", - } - self.visual_losses = visual_losses - - @property - def dummy_inputs(self): - """ - Dummy inputs to build the network. - - Returns: - tf.Tensor with dummy inputs - """ - batch_size = 2 - num_visual_features = 10 - input_ids = tf.constant([[3, 5, 6], [2, 3, 4]], dtype=tf.int32) - visual_feats = tf.random.uniform((batch_size, num_visual_features, self.config.visual_feat_dim)) - visual_pos = tf.random.uniform((batch_size, num_visual_features, 4)) - - if self.config.task_obj_predict: - obj_labels = {} - if self.config.visual_attr_loss and self.config.task_obj_predict: - obj_labels["attr"] = ( - tf.ones([batch_size, num_visual_features]), - tf.ones([batch_size, num_visual_features]), - ) - if self.config.visual_feat_loss and self.config.task_obj_predict: - obj_labels["feat"] = ( - tf.ones([batch_size, num_visual_features, self.config.visual_feat_dim]), - tf.ones([batch_size, num_visual_features]), - ) - if self.config.visual_obj_loss and self.config.task_obj_predict: - obj_labels["obj"] = ( - tf.ones([batch_size, num_visual_features]), - tf.ones([batch_size, num_visual_features]), - ) - - return { - **{ - "input_ids": input_ids, - "visual_feats": visual_feats, - "visual_pos": visual_pos, - }, - **({"obj_labels": obj_labels} if self.config.task_obj_predict else {}), - } - - def get_lm_head(self): - return self.cls.predictions - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.cls.name + "/" + self.cls.predictions.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(LXMERT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFLxmertForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - visual_feats: tf.Tensor | None = None, - visual_pos: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - visual_attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - masked_lm_labels: tf.Tensor | None = None, - obj_labels: dict[str, tuple[tf.Tensor, tf.Tensor]] | None = None, - matched_label: tf.Tensor | None = None, - ans: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFLxmertForPreTrainingOutput: - r""" - masked_lm_labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - obj_labels (`dict[Str: tuple[tf.Tensor, tf.Tensor]]`, *optional*, defaults to `None`): - each key is named after each one of the visual losses and each element of the tuple is of the shape - `(batch_size, num_features)` and `(batch_size, num_features, visual_feature_dim)` for each the label id and - the label score respectively - matched_label (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the whether or not the text input matches the image (classification) loss. Input - should be a sequence pair (see `input_ids` docstring) Indices should be in `[0, 1]`: - - - 0 indicates that the sentence does not match the image, - - 1 indicates that the sentence does match the image. - ans (`tf.Tensor` of shape `(batch_size)`, *optional*, defaults to `None`): - a one hot representation hof the correct answer *optional* - - Returns: - """ - - lxmert_output = self.lxmert( - input_ids, - visual_feats, - visual_pos, - attention_mask, - visual_attention_mask, - token_type_ids, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict, - training, - ) - - lang_output, visual_output, pooled_output = ( - lxmert_output[0], - lxmert_output[1], - lxmert_output[2], - ) - lang_prediction_scores, cross_relationship_score = self.cls(lang_output, pooled_output) - if self.task_qa: - answer_score = self.answer_head(pooled_output) - else: - answer_score = pooled_output[0][0] - - total_loss = ( - None - if (masked_lm_labels is None and matched_label is None and obj_labels is None and ans is None) - else tf.constant(0.0) - ) - losses = () - if masked_lm_labels is not None and self.task_mask_lm: - masked_lm_loss = self.loss_fcts["ce"]( - tf.reshape(masked_lm_labels, [-1]), - tf.reshape(lang_prediction_scores, [-1, self.config.vocab_size]), - ) - total_loss += masked_lm_loss - losses += (masked_lm_loss,) - if matched_label is not None and self.task_matched: - matched_loss = self.loss_fcts["ce"]( - tf.reshape(matched_label, [-1]), - tf.reshape(cross_relationship_score, [-1, 2]), - ) - total_loss += matched_loss - losses += (matched_loss,) - if obj_labels is not None and self.task_obj_predict: - total_visn_loss = 0.0 - visn_prediction_scores_dict = self.obj_predict_head(visual_output) - for key, key_info in self.visual_losses.items(): - label, mask_conf = obj_labels[key] - output_dim = key_info["num"] - loss_fct_name = key_info["loss"] - label_shape = key_info["shape"] - weight = self.visual_loss_normalizer - visn_loss_fct = self.loss_fcts[loss_fct_name] - visn_prediction_scores = visn_prediction_scores_dict[key] - visn_loss = visn_loss_fct( - tf.reshape(label, label_shape), - tf.reshape(visn_prediction_scores, [-1, output_dim]), - ) - - if visn_loss.ndim > 1: # Regression Losses - visn_loss = tf.reduce_mean(visn_loss) - visn_loss = tf.reduce_mean(visn_loss * tf.cast(tf.reshape(mask_conf, [-1]), visn_loss.dtype)) * weight - total_visn_loss += visn_loss - losses += (visn_loss,) - total_loss += total_visn_loss - if ans is not None and self.task_qa: - answer_loss = self.loss_fcts["ce"]( - tf.reshape(ans, [-1]), tf.reshape(answer_score, [-1, self.num_qa_labels]) - ) - # exclude "*2" here to match the effect of QA losses. - # Previous: (loss *0) for 6 epochs, (loss *2) for 6 epochs. (Used 10 instead of 6 in EMNLP paper) - # Now : (loss *1) for 12 epochs - # - # * 2 # Multiply by 2 because > half of the data will not have label - total_loss += answer_loss - losses += (answer_loss,) - # return total_loss, tf.stack(losses)[tf.new_axis, ...], answer_score.detach() - - if not return_dict: - output = ( - lang_prediction_scores, - cross_relationship_score, - answer_score, - ) + lxmert_output[3:] - return ((total_loss,) + output) if total_loss is not None else output - - return TFLxmertForPreTrainingOutput( - loss=total_loss, - prediction_logits=lang_prediction_scores, - cross_relationship_score=cross_relationship_score, - question_answering_score=answer_score, - language_hidden_states=lxmert_output.language_hidden_states, - vision_hidden_states=lxmert_output.vision_hidden_states, - language_attentions=lxmert_output.language_attentions, - vision_attentions=lxmert_output.vision_attentions, - cross_encoder_attentions=lxmert_output.cross_encoder_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "lxmert", None) is not None: - with tf.name_scope(self.lxmert.name): - self.lxmert.build(None) - if getattr(self, "cls", None) is not None: - with tf.name_scope(self.cls.name): - self.cls.build(None) - if getattr(self, "obj_predict_head", None) is not None: - with tf.name_scope(self.obj_predict_head.name): - self.obj_predict_head.build(None) - if getattr(self, "answer_head", None) is not None: - with tf.name_scope(self.answer_head.name): - self.answer_head.build(None) - - -__all__ = [ - "TFLxmertForPreTraining", - "TFLxmertMainLayer", - "TFLxmertModel", - "TFLxmertPreTrainedModel", - "TFLxmertVisualFeatureEncoder", -] diff --git a/src/transformers/models/m2m_100/configuration_m2m_100.py b/src/transformers/models/m2m_100/configuration_m2m_100.py index 620641f1cf4e..ff4f6f0d1af8 100644 --- a/src/transformers/models/m2m_100/configuration_m2m_100.py +++ b/src/transformers/models/m2m_100/configuration_m2m_100.py @@ -16,13 +16,13 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import Any, Optional +from typing import Any from ... import PreTrainedTokenizer from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig, OnnxSeq2SeqConfigWithPast from ...onnx.utils import compute_effective_axis_dimension -from ...utils import TensorType, is_torch_available, logging +from ...utils import is_torch_available, logging logger = logging.get_logger(__name__) @@ -189,7 +189,6 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: # Copied from OnnxConfig.generate_dummy_inputs # Did not use super(OnnxConfigWithPast, self).generate_dummy_inputs for code clarity. @@ -206,7 +205,7 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( # Generate dummy inputs according to compute batch and sequence dummy_input = [" ".join([tokenizer.unk_token]) * seq_length] * batch_size - common_inputs = dict(tokenizer(dummy_input, return_tensors=framework)) + common_inputs = dict(tokenizer(dummy_input, return_tensors="pt")) return common_inputs # Copied from transformers.models.bart.configuration_bart.BartOnnxConfig._generate_dummy_inputs_for_default_and_seq2seq_lm @@ -216,16 +215,15 @@ def _generate_dummy_inputs_for_default_and_seq2seq_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: encoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) # Generate decoder inputs decoder_seq_length = seq_length if not self.use_past else 1 decoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, decoder_seq_length, is_pair, framework + tokenizer, batch_size, decoder_seq_length, is_pair ) decoder_inputs = {f"decoder_{name}": tensor for name, tensor in decoder_inputs.items()} common_inputs = dict(**encoder_inputs, **decoder_inputs) diff --git a/src/transformers/models/marian/__init__.py b/src/transformers/models/marian/__init__.py index 6cfabc1590f2..84afe5b372bb 100644 --- a/src/transformers/models/marian/__init__.py +++ b/src/transformers/models/marian/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_marian import * - from .modeling_flax_marian import * from .modeling_marian import * - from .modeling_tf_marian import * from .tokenization_marian import * else: import sys diff --git a/src/transformers/models/marian/configuration_marian.py b/src/transformers/models/marian/configuration_marian.py index 0e0468c50b5f..fd68286b9bed 100644 --- a/src/transformers/models/marian/configuration_marian.py +++ b/src/transformers/models/marian/configuration_marian.py @@ -16,13 +16,13 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import Any, Optional +from typing import Any from ... import PreTrainedTokenizer from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig, OnnxConfigWithPast, OnnxSeq2SeqConfigWithPast from ...onnx.utils import compute_effective_axis_dimension -from ...utils import TensorType, is_torch_available, logging +from ...utils import is_torch_available, logging logger = logging.get_logger(__name__) @@ -230,16 +230,21 @@ def _generate_dummy_inputs_for_default_and_seq2seq_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: encoder_inputs = self._generate_dummy_inputs_for_encoder_and_decoder( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, + batch_size, + seq_length, + is_pair, ) # Generate decoder inputs decoder_seq_length = seq_length if not self.use_past else 1 decoder_inputs = self._generate_dummy_inputs_for_encoder_and_decoder( - tokenizer, batch_size, decoder_seq_length, is_pair, framework + tokenizer, + batch_size, + decoder_seq_length, + is_pair, ) decoder_inputs = {f"decoder_{name}": tensor for name, tensor in decoder_inputs.items()} common_inputs = dict(**encoder_inputs, **decoder_inputs) @@ -298,10 +303,12 @@ def _generate_dummy_inputs_for_causal_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: common_inputs = self._generate_dummy_inputs_for_encoder_and_decoder( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, + batch_size, + seq_length, + is_pair, ) if self.use_past: @@ -338,7 +345,6 @@ def _generate_dummy_inputs_for_encoder_and_decoder( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: # Copied from OnnxConfig.generate_dummy_inputs # Did not use super(OnnxConfigWithPast, self).generate_dummy_inputs for code clarity. @@ -355,7 +361,7 @@ def _generate_dummy_inputs_for_encoder_and_decoder( # Generate dummy inputs according to compute batch and sequence dummy_input = [" ".join([tokenizer.unk_token]) * seq_length] * batch_size - common_inputs = dict(tokenizer(dummy_input, return_tensors=framework)) + common_inputs = dict(tokenizer(dummy_input, return_tensors="pt")) return common_inputs def generate_dummy_inputs( @@ -364,16 +370,21 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: if self.task in ["default", "seq2seq-lm"]: common_inputs = self._generate_dummy_inputs_for_default_and_seq2seq_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, + batch_size=batch_size, + seq_length=seq_length, + is_pair=is_pair, ) else: common_inputs = self._generate_dummy_inputs_for_causal_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, + batch_size=batch_size, + seq_length=seq_length, + is_pair=is_pair, ) return common_inputs diff --git a/src/transformers/models/marian/modeling_flax_marian.py b/src/transformers/models/marian/modeling_flax_marian.py deleted file mode 100644 index e1d9bea4fcdb..000000000000 --- a/src/transformers/models/marian/modeling_flax_marian.py +++ /dev/null @@ -1,1500 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Marian Team Authors and The Google Flax Team Authors And The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax Marian model.""" - -import math -import random -from functools import partial -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxSeq2SeqLMOutput, - FlaxSeq2SeqModelOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_marian import MarianConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "Helsinki-NLP/opus-mt-en-de" -_CONFIG_FOR_DOC = "MarianConfig" - - -MARIAN_START_DOCSTRING = r""" - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`MarianConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -MARIAN_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -MARIAN_ENCODE_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -MARIAN_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def create_sinusoidal_positions(n_pos, dim): - position_enc = np.array([[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)]) - sentinel = dim // 2 + dim % 2 - out = np.zeros_like(position_enc) - out[:, 0:sentinel] = np.sin(position_enc[:, 0::2]) - out[:, sentinel:] = np.cos(position_enc[:, 1::2]) - - return jnp.array(out) - - -# Copied from transformers.models.bart.modeling_flax_bart.shift_tokens_right -def shift_tokens_right(input_ids: jnp.ndarray, pad_token_id: int, decoder_start_token_id: int) -> jnp.ndarray: - """ - Shift input ids one token to the right. - """ - shifted_input_ids = jnp.zeros_like(input_ids) - shifted_input_ids = shifted_input_ids.at[:, 1:].set(input_ids[:, :-1]) - shifted_input_ids = shifted_input_ids.at[:, 0].set(decoder_start_token_id) - - shifted_input_ids = jnp.where(shifted_input_ids == -100, pad_token_id, shifted_input_ids) - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention with Bart->Marian -class FlaxMarianAttention(nn.Module): - config: MarianConfig - embed_dim: int - num_heads: int - dropout: float = 0.0 - causal: bool = False - bias: bool = True - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self) -> None: - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {self.num_heads})." - ) - - dense = partial( - nn.Dense, - self.embed_dim, - use_bias=self.bias, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() - self.out_proj = dense() - - self.dropout_layer = nn.Dropout(rate=self.dropout) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states: jnp.ndarray, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.q_proj(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.k_proj(key_value_states) - value_states = self.v_proj(key_value_states) - else: - # self_attention - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartEncoderLayer with Bart->Marian -class FlaxMarianEncoderLayer(nn.Module): - config: MarianConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxMarianAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.encoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - self.fc1 = nn.Dense( - self.config.encoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states, attn_weights = self.self_attn(hidden_states=hidden_states, attention_mask=attention_mask) - - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartEncoderLayerCollection with Bart->Marian -class FlaxMarianEncoderLayerCollection(nn.Module): - config: MarianConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxMarianEncoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.encoder_layers) - ] - self.layerdrop = self.config.encoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for encoder_layer in self.layers: - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): # skip the layer - layer_outputs = (None, None) - else: - layer_outputs = encoder_layer( - hidden_states, - attention_mask, - output_attentions, - deterministic, - ) - hidden_states = layer_outputs[0] - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderLayer with Bart->Marian -class FlaxMarianDecoderLayer(nn.Module): - config: MarianConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxMarianAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - causal=True, - dtype=self.dtype, - ) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.encoder_attn = FlaxMarianAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.fc1 = nn.Dense( - self.config.decoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - - # Self Attention - hidden_states, self_attn_weights = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Cross-Attention Block - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - hidden_states, cross_attn_weights = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # Fully Connected - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights, cross_attn_weights) - - return outputs - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderLayerCollection with Bart->Marian -class FlaxMarianDecoderLayerCollection(nn.Module): - config: MarianConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxMarianDecoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.decoder_layers) - ] - self.layerdrop = self.config.decoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - for decoder_layer in self.layers: - if output_hidden_states: - all_hidden_states += (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): - layer_outputs = (None, None, None) - else: - layer_outputs = decoder_layer( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - deterministic=deterministic, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attns += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = [hidden_states, all_hidden_states, all_self_attns, all_cross_attentions] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - -class FlaxMarianEncoder(nn.Module): - config: MarianConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.max_source_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(embed_dim) if self.config.scale_embedding else 1.0 - - self.embed_positions = create_sinusoidal_positions(self.config.max_position_embeddings, embed_dim) - self.layers = FlaxMarianEncoderLayerCollection(self.config, self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - positions = jnp.take(self.embed_positions, position_ids, axis=0) - # explicitly cast the positions here, since self.embed_positions are not registered as parameters - positions = positions.astype(inputs_embeds.dtype) - - hidden_states = inputs_embeds + positions - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - if not return_dict: - return outputs - - return FlaxBaseModelOutput( - last_hidden_state=outputs.last_hidden_state, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -class FlaxMarianDecoder(nn.Module): - config: MarianConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.max_target_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(self.config.d_model) if self.config.scale_embedding else 1.0 - - self.embed_positions = create_sinusoidal_positions(self.config.max_position_embeddings, embed_dim) - self.layers = FlaxMarianDecoderLayerCollection(self.config, self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - # embed positions - positions = jnp.take(self.embed_positions, position_ids, axis=0) - # explicitly cast the positions here, since self.embed_positions are not registered as parameters - positions = positions.astype(inputs_embeds.dtype) - - hidden_states = inputs_embeds + positions - - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - if not return_dict: - return outputs - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=outputs.last_hidden_state, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -class FlaxMarianModule(nn.Module): - config: MarianConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.encoder = FlaxMarianEncoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - self.decoder = FlaxMarianDecoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -class FlaxMarianPreTrainedModel(FlaxPreTrainedModel): - config_class = MarianConfig - base_model_prefix: str = "model" - module_class: nn.Module = None - - def __init__( - self, - config: MarianConfig, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - # make sure initialization pass will work for FlaxMarianForSequenceClassificationModule - input_ids = input_ids.at[(..., -1)].set(self.config.eos_token_id) - attention_mask = jnp.ones_like(input_ids) - decoder_input_ids = input_ids - decoder_attention_mask = jnp.ones_like(input_ids) - - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - decoder_position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape - ) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module(decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(MARIAN_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=MarianConfig) - def encode( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxMarianMTModel - - >>> tokenizer = AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-en-de") - >>> model = FlaxMarianMTModel.from_pretrained("Helsinki-NLP/opus-mt-en-de") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=64, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - ```""" - - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, input_ids, attention_mask, position_ids, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(input_ids, attention_mask, position_ids, **kwargs) - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - @add_start_docstrings(MARIAN_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=MarianConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoTokenizer, FlaxMarianMTModel - - >>> tokenizer = AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-en-de") - >>> model = FlaxMarianMTModel.from_pretrained("Helsinki-NLP/opus-mt-en-de") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=64, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> last_decoder_hidden_states = outputs.last_hidden_state - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxMarianAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - @add_start_docstrings_to_model_forward(MARIAN_INPUTS_DOCSTRING) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_input_ids: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # prepare decoder inputs - if decoder_input_ids is None: - decoder_input_ids = shift_tokens_right( - input_ids, self.config.pad_token_id, decoder_start_token_id=self.config.decoder_start_token_id - ) - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - if decoder_position_ids is None: - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - -@add_start_docstrings( - "The bare Marian Model transformer outputting raw hidden-states without any specific head on top.", - MARIAN_START_DOCSTRING, -) -class FlaxMarianModel(FlaxMarianPreTrainedModel): - config: MarianConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - module_class = FlaxMarianModule - - -append_call_sample_docstring(FlaxMarianModel, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) - - -class FlaxMarianMTModule(nn.Module): - config: MarianConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., jnp.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.model = FlaxMarianModule(config=self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.model.shared.num_embeddings, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.final_logits_bias = self.param("final_logits_bias", self.bias_init, (1, self.model.shared.num_embeddings)) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - position_ids=position_ids, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = self.model.variables["params"]["shared"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - lm_logits += self.final_logits_bias.astype(self.dtype) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return output - - return FlaxSeq2SeqLMOutput( - logits=lm_logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings( - "The MARIAN Model with a language modeling head. Can be used for translation.", MARIAN_START_DOCSTRING -) -class FlaxMarianMTModel(FlaxMarianPreTrainedModel): - module_class = FlaxMarianMTModule - dtype: jnp.dtype = jnp.float32 - - @add_start_docstrings(MARIAN_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=MarianConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoTokenizer, FlaxMarianMTModel - - >>> model = FlaxMarianMTModel.from_pretrained("Helsinki-NLP/opus-mt-en-de") - >>> tokenizer = AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-en-de") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=64, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxMarianAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - outputs = decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = module.model.variables["params"]["shared"]["embedding"] - lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = module.lm_head(hidden_states) - lm_logits += module.final_logits_bias.astype(self.dtype) - - return lm_logits, outputs - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - if past_key_values is None: - lm_logits, decoder_outputs = outputs - else: - (lm_logits, decoder_outputs), past = outputs - - if return_dict: - outputs = FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=decoder_outputs.hidden_states, - attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - ) - else: - outputs = (lm_logits,) + decoder_outputs[1:] - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - def _adapt_logits_for_beam_search(self, logits): - """This function enforces the padding token never to be generated.""" - logits = logits.at[:, :, self.config.pad_token_id].set(float("-inf")) - return logits - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - position_ids = decoder_attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - "decoder_position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 - return model_kwargs - - -FLAX_MARIAN_MT_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxMarianMTModel - - >>> model = FlaxMarianMTModel.from_pretrained("Helsinki-NLP/opus-mt-en-de") - >>> tokenizer = AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-en-de") - - >>> text = "My friends are cool but they eat too many carbs." - >>> input_ids = tokenizer(text, max_length=64, return_tensors="jax").input_ids - - >>> sequences = model.generate(input_ids, max_length=64, num_beams=2).sequences - - >>> outputs = tokenizer.batch_decode(sequences, skip_special_tokens=True) - >>> # should give *Meine Freunde sind cool, aber sie essen zu viele Kohlenhydrate.* - ``` -""" - -overwrite_call_docstring( - FlaxMarianMTModel, - MARIAN_INPUTS_DOCSTRING + FLAX_MARIAN_MT_DOCSTRING, -) -append_replace_return_docstrings(FlaxMarianMTModel, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - - -__all__ = ["FlaxMarianModel", "FlaxMarianMTModel", "FlaxMarianPreTrainedModel"] diff --git a/src/transformers/models/marian/modeling_tf_marian.py b/src/transformers/models/marian/modeling_tf_marian.py deleted file mode 100644 index c989cfa15f5a..000000000000 --- a/src/transformers/models/marian/modeling_tf_marian.py +++ /dev/null @@ -1,1558 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Marian Team Authors and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 Marian model.""" - -from __future__ import annotations - -import random - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPastAndCrossAttentions, - TFSeq2SeqLMOutput, - TFSeq2SeqModelOutput, -) - -# Public API -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFPreTrainedModel, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_end_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_marian import MarianConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "Helsinki-NLP/opus-mt-en-de" -_CONFIG_FOR_DOC = "MarianConfig" - - -LARGE_NEGATIVE = -1e8 - - -# Copied from transformers.models.bart.modeling_tf_bart.shift_tokens_right -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): - pad_token_id = tf.cast(pad_token_id, input_ids.dtype) - decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) - start_tokens = tf.fill( - (shape_list(input_ids)[0], 1), tf.convert_to_tensor(decoder_start_token_id, input_ids.dtype) - ) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.fill(shape_list(shifted_input_ids), tf.convert_to_tensor(pad_token_id, input_ids.dtype)), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE - mask_cond = tf.range(shape_list(mask)[-1]) - - mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -class TFMarianSinusoidalPositionalEmbedding(keras.layers.Layer): - """This module produces sinusoidal positional embeddings of any length.""" - - def __init__(self, num_positions: int, embedding_dim: int, **kwargs): - super().__init__(**kwargs) - - if embedding_dim % 2 != 0: - raise NotImplementedError(f"odd embedding_dim {embedding_dim} not supported") - - self.embedding_dim = embedding_dim - self.num_positions = num_positions - - def build(self, input_shape: tf.TensorShape): - """ - Build shared token embedding layer Shared weights logic adapted from - https://github.com/tensorflow/models/blob/a009f4fb9d2fc4949e32192a944688925ef78659/official/transformer/v2/embedding_layer.py#L24 - """ - - weight = self._init_weight(self.num_positions, self.embedding_dim) - - self.weight = self.add_weight( - name="embeddings", - shape=[self.num_positions, self.embedding_dim], - ) - weight = tf.cast(weight, dtype=self.weight.dtype) - - self.weight.assign(weight) - - super().build(input_shape) - - @staticmethod - def _init_weight(n_pos: int, dim: int): - """ - Identical to the XLM create_sinusoidal_embeddings except features are not interleaved. The cos features are in - the 2nd half of the vector. [dim // 2:] - """ - position_enc = np.array( - [[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)] - ) - table = np.zeros_like(position_enc) - # index 0 is all zero - table[:, 0 : dim // 2] = np.sin(position_enc[:, 0::2]) - table[:, dim // 2 :] = np.cos(position_enc[:, 1::2]) - # convert to tensor - table = tf.convert_to_tensor(table) - tf.stop_gradient(table) - return table - - def call( - self, input_shape: tf.TensorShape, past_key_values_length: int = 0, position_ids: tf.Tensor | None = None - ): - """Input is expected to be of size [bsz x seqlen].""" - if position_ids is None: - seq_len = input_shape[1] - position_ids = tf.range(past_key_values_length, seq_len + past_key_values_length, delta=1, name="range") - return tf.gather(self.weight, position_ids) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with Bart->Marian -class TFMarianAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartEncoderLayer with Bart->Marian -class TFMarianEncoderLayer(keras.layers.Layer): - def __init__(self, config: MarianConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFMarianAttention( - self.embed_dim, config.encoder_attention_heads, dropout=config.attention_dropout, name="self_attn" - ) - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - self.fc1 = keras.layers.Dense(config.encoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: np.ndarray | tf.Tensor | None, - layer_head_mask: tf.Tensor | None, - training: bool | None = False, - ) -> tf.Tensor: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - `(encoder_attention_heads,)` - """ - residual = hidden_states - hidden_states, self_attn_weights, _ = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, layer_head_mask=layer_head_mask - ) - - tf.debugging.assert_equal( - shape_list(hidden_states), - shape_list(residual), - message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", - ) - - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - return hidden_states, self_attn_weights - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.encoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartDecoderLayer with Bart->Marian -class TFMarianDecoderLayer(keras.layers.Layer): - def __init__(self, config: MarianConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFMarianAttention( - embed_dim=self.embed_dim, - num_heads=config.decoder_attention_heads, - dropout=config.attention_dropout, - name="self_attn", - is_decoder=True, - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.encoder_attn = TFMarianAttention( - self.embed_dim, - config.decoder_attention_heads, - dropout=config.attention_dropout, - name="encoder_attn", - is_decoder=True, - ) - self.encoder_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.decoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - cross_attn_layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - encoder_hidden_states (`tf.Tensor`): - cross attention input to the layer of shape `(batch, seq_len, embed_dim)` - encoder_attention_mask (`tf.Tensor`): encoder attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - `(decoder_attention_heads,)` - cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. - `(decoder_attention_heads,)` - past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states - """ - residual = hidden_states - - # Self Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Cross-Attention Block - cross_attn_present_key_value = None - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - layer_head_mask=cross_attn_layer_head_mask, - past_key_value=cross_attn_past_key_value, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # add cross-attn to positions 3,4 of present_key_value tuple - present_key_value = present_key_value + cross_attn_present_key_value - - # Fully Connected - residual = hidden_states - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - hidden_states = self.final_layer_norm(hidden_states) - - return ( - hidden_states, - self_attn_weights, - cross_attn_weights, - present_key_value, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "encoder_attn", None) is not None: - with tf.name_scope(self.encoder_attn.name): - self.encoder_attn.build(None) - if getattr(self, "encoder_attn_layer_norm", None) is not None: - with tf.name_scope(self.encoder_attn_layer_norm.name): - self.encoder_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.decoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFMarianPreTrainedModel(TFPreTrainedModel): - config_class = MarianConfig - base_model_prefix = "model" - - -MARIAN_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`MarianConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -MARIAN_GENERATION_EXAMPLE = r""" - TF version of marian-nmt's transformer.h (c++). Designed for the OPUS-NMT translation checkpoints. Available - models are listed [here](https://huggingface.co/models?search=Helsinki-NLP). - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFMarianMTModel - >>> from typing import List - - >>> src = "fr" # source language - >>> trg = "en" # target language - >>> sample_text = "où est l'arrêt de bus ?" - >>> model_name = f"Helsinki-NLP/opus-mt-{src}-{trg}" - - >>> model = TFMarianMTModel.from_pretrained(model_name) - >>> tokenizer = AutoTokenizer.from_pretrained(model_name) - >>> batch = tokenizer([sample_text], return_tensors="tf") - >>> gen = model.generate(**batch) - >>> tokenizer.batch_decode(gen, skip_special_tokens=True) - "Where is the bus stop ?" - ``` -""" - -MARIAN_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - Marian uses the `pad_token_id` as the starting token for `decoder_input_ids` generation. If - `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - will be made by default and ignore pad tokens. It is not recommended to set this for most use cases. - decoder_position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_outputs (`tf.FloatTensor`, *optional*): - hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - of shape `(batch_size, sequence_length, hidden_size)` is a sequence of - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@keras_serializable -class TFMarianEncoder(keras.layers.Layer): - config_class = MarianConfig - """ - Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a - [`TFMarianEncoderLayer`]. - - Args: - config: MarianConfig - """ - - def __init__(self, config: MarianConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.dropout = keras.layers.Dropout(config.dropout) - self.layerdrop = config.encoder_layerdrop - self.padding_idx = config.pad_token_id - self.max_source_positions = config.max_position_embeddings - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - - self.embed_tokens = embed_tokens - self.embed_positions = TFMarianSinusoidalPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.layers = [TFMarianEncoderLayer(config, name=f"layers.{i}") for i in range(config.encoder_layers)] - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ): - """ - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. This argument can be used only in eager mode, in graph mode the value - in the config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. This argument can be used only in eager mode, in graph mode the value in the config - will be used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - embed_pos = self.embed_positions(input_shape) - hidden_states = inputs_embeds + embed_pos - hidden_states = self.dropout(hidden_states, training=training) - - # check attention mask and invert - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - attention_mask = _expand_mask(attention_mask) - else: - attention_mask = None - - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - # check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - tf.debugging.assert_equal( - shape_list(head_mask)[0], - len(self.layers), - message=( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(head_mask)[0]}." - ), - ) - - # encoder layers - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): # skip the layer - continue - - hidden_states, attn = encoder_layer( - hidden_states, - attention_mask, - head_mask[idx] if head_mask is not None else None, - ) - - if output_attentions: - all_attentions += (attn,) - - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFMarianDecoder(keras.layers.Layer): - config_class = MarianConfig - """ - Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFMarianDecoderLayer`] - - Args: - config: MarianConfig - embed_tokens: output embedding - """ - - def __init__(self, config: MarianConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.padding_idx = config.pad_token_id - self.embed_tokens = embed_tokens - self.layerdrop = config.decoder_layerdrop - self.embed_positions = TFMarianSinusoidalPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - self.layers = [TFMarianDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] - - self.dropout = keras.layers.Dropout(config.dropout) - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ): - r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention - of the decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): - Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values - selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers` with each tuple having 2 tuples each of which has 2 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up - decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those - that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of - all `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. This argument can be used only in eager mode, in graph mode the value - in the config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. This argument can be used only in eager mode, in graph mode the value in the config - will be used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - past_key_values_length = shape_list(past_key_values[0][0])[2] if past_key_values is not None else 0 - - # embed positions - if position_ids is None: - positions = self.embed_positions(input_shape, past_key_values_length) - else: - positions = self.embed_positions(input_shape, position_ids=position_ids) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - hidden_states = inputs_embeds - - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - if input_shape[-1] > 1: - combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length=past_key_values_length) - else: - combined_attention_mask = _expand_mask( - tf.ones((input_shape[0], input_shape[1] + past_key_values_length)), tgt_len=input_shape[-1] - ) - - if attention_mask is not None: - combined_attention_mask = combined_attention_mask + _expand_mask(attention_mask, tgt_len=input_shape[-1]) - - if encoder_hidden_states is not None and encoder_attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) - - hidden_states = self.dropout(hidden_states + positions, training=training) - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attns = () if (output_attentions and encoder_hidden_states is not None) else None - present_key_values = () if use_cache else None - - # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired - for attn_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: - if attn_mask is not None: - tf.debugging.assert_equal( - shape_list(attn_mask)[0], - len(self.layers), - message=( - f"The {attn_name} should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(attn_mask)[0]}." - ), - ) - - for idx, decoder_layer in enumerate(self.layers): - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - if output_hidden_states: - all_hidden_states += (hidden_states,) - dropout_probability = random.uniform(0, 1) - - if training and (dropout_probability < self.layerdrop): - continue - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( - hidden_states, - attention_mask=combined_attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - cross_attn_layer_head_mask=cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None, - past_key_value=past_key_value, - ) - - if use_cache: - present_key_values += (present_key_value,) - - if output_attentions: - all_self_attns += (layer_self_attn,) - - if encoder_hidden_states is not None: - all_cross_attns += (layer_cross_attn,) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - if not return_dict: - return hidden_states, present_key_values, all_hidden_states, all_self_attns, all_cross_attns - else: - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=present_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFMarianMainLayer(keras.layers.Layer): - config_class = MarianConfig - - def __init__(self, config: MarianConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.shared = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.d_model, - embeddings_initializer=keras.initializers.TruncatedNormal(stddev=self.config.init_std), - name="model.shared", - ) - # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) - self.shared.load_weight_prefix = "model.shared" - - self.encoder = TFMarianEncoder(config, self.shared, name="encoder") - self.decoder = TFMarianDecoder(config, self.shared, name="decoder") - - def get_input_embeddings(self): - return self.shared - - def set_input_embeddings(self, new_embeddings): - self.shared = new_embeddings - self.encoder.embed_tokens = self.shared - self.decoder.embed_tokens = self.shared - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ): - if decoder_input_ids is None and decoder_inputs_embeds is None: - use_cache = False - - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True - elif return_dict and not isinstance(encoder_outputs, TFBaseModelOutput): - encoder_outputs = TFBaseModelOutput( - last_hidden_state=encoder_outputs[0], - hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, - attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, - ) - # If the user passed a TFBaseModelOutput for encoder_outputs, we wrap it in a tuple when return_dict=False - elif not return_dict and not isinstance(encoder_outputs, tuple): - encoder_outputs = encoder_outputs.to_tuple() - - decoder_outputs = self.decoder( - decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return TFSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # The shared/tied weights expect to be in the model base namespace - # Adding "/" to the end (not the start!) of a tf.name_scope puts it in the root namespace rather than - # the current one. - with tf.name_scope(self.shared.load_weight_prefix + "/" + self.shared.name + "/"): - self.shared.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - "The bare MARIAN Model outputting raw hidden-states without any specific head on top.", - MARIAN_START_DOCSTRING, -) -class TFMarianModel(TFMarianPreTrainedModel): - def __init__(self, config: MarianConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.model = TFMarianMainLayer(config, name="model") - - def get_encoder(self): - return self.model.encoder - - def get_decoder(self): - return self.model.decoder - - @unpack_inputs - @add_start_docstrings_to_model_forward(MARIAN_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSeq2SeqModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: tf.Tensor | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ) -> tuple[tf.Tensor] | TFSeq2SeqModelOutput: - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - encoder_outputs=encoder_outputs, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartModel.serving_output - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqModelOutput( - last_hidden_state=output.last_hidden_state, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -# Copied from transformers.models.bart.modeling_tf_bart.BiasLayer -class BiasLayer(keras.layers.Layer): - """ - Bias as a layer. It is used for serialization purposes: `keras.Model.save_weights` stores on a per-layer basis, - so all weights have to be registered in a layer. - """ - - def __init__(self, shape, initializer, trainable, name, **kwargs): - super().__init__(name=name, **kwargs) - # Note: the name of this variable will NOT be scoped when serialized, i.e. it will not be in the format of - # "outer_layer/inner_layer/.../name:0". Instead, it will be "name:0". For further details, see: - # https://github.com/huggingface/transformers/pull/18833#issuecomment-1233090214 - self.bias = self.add_weight(name=name, shape=shape, initializer=initializer, trainable=trainable) - - def call(self, x): - return x + self.bias - - -@add_start_docstrings( - "The MARIAN Model with a language modeling head. Can be used for summarization.", - MARIAN_START_DOCSTRING, -) -class TFMarianMTModel(TFMarianPreTrainedModel, TFCausalLanguageModelingLoss): - _keys_to_ignore_on_load_unexpected = [ - r"model.encoder.embed_tokens.weight", - r"model.decoder.embed_tokens.weight", - ] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.model = TFMarianMainLayer(config, name="model") - self.use_cache = config.use_cache - # final_bias_logits is registered as a buffer in pytorch, so not trainable for the sake of consistency. - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, config.vocab_size], initializer="zeros", trainable=False - ) - - def get_decoder(self): - return self.model.decoder - - def get_encoder(self): - return self.model.encoder - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - def get_bias(self): - return {"final_logits_bias": self.bias_layer.bias} - - def set_bias(self, value): - # Replaces the existing layers containing bias for correct (de)serialization. - vocab_size = value["final_logits_bias"].shape[-1] - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, vocab_size], initializer="zeros", trainable=False - ) - self.bias_layer.bias.assign(value["final_logits_bias"]) - - @unpack_inputs - @add_start_docstrings_to_model_forward(MARIAN_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - @add_end_docstrings(MARIAN_GENERATION_EXAMPLE) - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFSeq2SeqLMOutput: - r""" - labels (`tf.tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., - config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - - Returns: - - """ - - if labels is not None: - labels = tf.where( - labels == self.config.pad_token_id, - tf.fill(shape_list(labels), tf.cast(-100, labels.dtype)), - labels, - ) - use_cache = False - if decoder_input_ids is None and decoder_inputs_embeds is None: - decoder_input_ids = shift_tokens_right( - labels, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - outputs = self.model( - input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - encoder_outputs=encoder_outputs, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - lm_logits = tf.matmul(outputs[0], self.model.shared.weights, transpose_b=True) - lm_logits = self.bias_layer(lm_logits) - masked_lm_loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return TFSeq2SeqLMOutput( - loss=masked_lm_loss, - logits=lm_logits, - past_key_values=outputs.past_key_values, # index 1 of d outputs - decoder_hidden_states=outputs.decoder_hidden_states, # index 2 of d outputs - decoder_attentions=outputs.decoder_attentions, # index 3 of d outputs - cross_attentions=outputs.cross_attentions, # index 4 of d outputs - encoder_last_hidden_state=outputs.encoder_last_hidden_state, # index 0 of encoder outputs - encoder_hidden_states=outputs.encoder_hidden_states, # 1 of e out - encoder_attentions=outputs.encoder_attentions, # 2 of e out - ) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartForConditionalGeneration.serving_output - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartForConditionalGeneration.prepare_inputs_for_generation - def prepare_inputs_for_generation( - self, - decoder_input_ids, - past_key_values=None, - attention_mask=None, - decoder_attention_mask=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - use_cache=None, - encoder_outputs=None, - **kwargs, - ): - # cut decoder_input_ids if past_key_values is used - if past_key_values is not None: - decoder_input_ids = decoder_input_ids[:, -1:] - - if decoder_attention_mask is not None: # xla - decoder_position_ids = tf.math.cumsum(decoder_attention_mask, axis=-1, exclusive=True)[:, -1:] - elif past_key_values is not None: # no xla + past_key_values - decoder_position_ids = past_key_values[0][0].shape[2] - else: # no xla + no past_key_values - decoder_position_ids = tf.range(decoder_input_ids.shape[1]) - - return { - "input_ids": None, # encoder_outputs is defined. input_ids not needed - "encoder_outputs": encoder_outputs, - "past_key_values": past_key_values, - "decoder_input_ids": decoder_input_ids, - "attention_mask": attention_mask, - "decoder_attention_mask": decoder_attention_mask, - "decoder_position_ids": decoder_position_ids, - "head_mask": head_mask, - "decoder_head_mask": decoder_head_mask, - "cross_attn_head_mask": cross_attn_head_mask, - "use_cache": use_cache, # change this to avoid caching (presumably for debugging) - } - - def prepare_decoder_input_ids_from_labels(self, labels: tf.Tensor): - return shift_tokens_right(labels, self.config.pad_token_id, self.config.decoder_start_token_id) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "bias_layer", None) is not None: - with tf.name_scope(self.bias_layer.name): - self.bias_layer.build(None) - - -__all__ = ["TFMarianModel", "TFMarianMTModel", "TFMarianPreTrainedModel"] diff --git a/src/transformers/models/marian/tokenization_marian.py b/src/transformers/models/marian/tokenization_marian.py index ef8e1537b99d..66a3630ffd56 100644 --- a/src/transformers/models/marian/tokenization_marian.py +++ b/src/transformers/models/marian/tokenization_marian.py @@ -204,7 +204,7 @@ def batch_decode(self, sequences, **kwargs): Convert a list of lists of token ids into a list of strings by calling decode. Args: - sequences (`Union[list[int], list[list[int]], np.ndarray, torch.Tensor, tf.Tensor]`): + sequences (`Union[list[int], list[list[int]], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. @@ -230,7 +230,7 @@ def decode(self, token_ids, **kwargs): Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. Args: - token_ids (`Union[int, list[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. diff --git a/src/transformers/models/markuplm/modeling_markuplm.py b/src/transformers/models/markuplm/modeling_markuplm.py index 78fbf8f215aa..61acac83b0f2 100755 --- a/src/transformers/models/markuplm/modeling_markuplm.py +++ b/src/transformers/models/markuplm/modeling_markuplm.py @@ -553,8 +553,6 @@ class MarkupLMPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/markuplm/tokenization_markuplm.py b/src/transformers/models/markuplm/tokenization_markuplm.py index a090e11ec36d..0a6f7c3bd6a0 100644 --- a/src/transformers/models/markuplm/tokenization_markuplm.py +++ b/src/transformers/models/markuplm/tokenization_markuplm.py @@ -83,7 +83,6 @@ return_tensors (`str` or [`~file_utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. """ diff --git a/src/transformers/models/mask2former/image_processing_mask2former.py b/src/transformers/models/mask2former/image_processing_mask2former.py index a0c369722b54..14f75a8c414f 100644 --- a/src/transformers/models/mask2former/image_processing_mask2former.py +++ b/src/transformers/models/mask2former/image_processing_mask2former.py @@ -739,10 +739,7 @@ def preprocess( pad_size = self.pad_size if pad_size is None else pad_size if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, @@ -757,8 +754,7 @@ def preprocess( if segmentation_maps is not None and not valid_images(segmentation_maps): raise ValueError( - "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." + "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor" ) images = make_flat_list_of_images(images) @@ -858,10 +854,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): diff --git a/src/transformers/models/maskformer/image_processing_maskformer.py b/src/transformers/models/maskformer/image_processing_maskformer.py index 9ce33846170e..f537adad22bd 100644 --- a/src/transformers/models/maskformer/image_processing_maskformer.py +++ b/src/transformers/models/maskformer/image_processing_maskformer.py @@ -742,10 +742,7 @@ def preprocess( pad_size = self.pad_size if pad_size is None else pad_size if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, @@ -760,8 +757,7 @@ def preprocess( if segmentation_maps is not None and not valid_images(segmentation_maps): raise ValueError( - "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." + "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor" ) images = make_flat_list_of_images(images) @@ -860,10 +856,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): diff --git a/src/transformers/models/maskformer/modeling_maskformer.py b/src/transformers/models/maskformer/modeling_maskformer.py index 9e1c0072425b..02deeb4af638 100644 --- a/src/transformers/models/maskformer/modeling_maskformer.py +++ b/src/transformers/models/maskformer/modeling_maskformer.py @@ -1464,8 +1464,6 @@ def _init_weights(self, module: nn.Module): module.weight.data.fill_(1.0) # copied from DETR if isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/maskformer/modeling_maskformer_swin.py b/src/transformers/models/maskformer/modeling_maskformer_swin.py index 3a3e076a5a4c..2de478440414 100644 --- a/src/transformers/models/maskformer/modeling_maskformer_swin.py +++ b/src/transformers/models/maskformer/modeling_maskformer_swin.py @@ -107,11 +107,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -743,8 +738,6 @@ class MaskFormerSwinPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/mbart/__init__.py b/src/transformers/models/mbart/__init__.py index f3c5ef5767a4..0b90185d2cbe 100644 --- a/src/transformers/models/mbart/__init__.py +++ b/src/transformers/models/mbart/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_mbart import * - from .modeling_flax_mbart import * from .modeling_mbart import * - from .modeling_tf_mbart import * from .tokenization_mbart import * from .tokenization_mbart_fast import * else: diff --git a/src/transformers/models/mbart/configuration_mbart.py b/src/transformers/models/mbart/configuration_mbart.py index 104e7e00d9e5..ba0dd16553cb 100644 --- a/src/transformers/models/mbart/configuration_mbart.py +++ b/src/transformers/models/mbart/configuration_mbart.py @@ -16,13 +16,13 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import Any, Optional +from typing import Any from ... import PreTrainedTokenizer from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig, OnnxConfigWithPast, OnnxSeq2SeqConfigWithPast from ...onnx.utils import compute_effective_axis_dimension -from ...utils import TensorType, is_torch_available, logging +from ...utils import is_torch_available, logging logger = logging.get_logger(__name__) @@ -229,16 +229,15 @@ def _generate_dummy_inputs_for_default_and_seq2seq_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: encoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) # Generate decoder inputs decoder_seq_length = seq_length if not self.use_past else 1 decoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, decoder_seq_length, is_pair, framework + tokenizer, batch_size, decoder_seq_length, is_pair ) decoder_inputs = {f"decoder_{name}": tensor for name, tensor in decoder_inputs.items()} common_inputs = dict(**encoder_inputs, **decoder_inputs) @@ -297,10 +296,9 @@ def _generate_dummy_inputs_for_causal_lm( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size, seq_length, is_pair, framework + tokenizer, batch_size, seq_length, is_pair ) if self.use_past: @@ -335,7 +333,6 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: # Copied from OnnxConfig.generate_dummy_inputs # Did not use super(OnnxConfigWithPast, self).generate_dummy_inputs for code clarity. @@ -352,7 +349,7 @@ def _generate_dummy_inputs_for_sequence_classification_and_question_answering( # Generate dummy inputs according to compute batch and sequence dummy_input = [" ".join([tokenizer.unk_token]) * seq_length] * batch_size - common_inputs = dict(tokenizer(dummy_input, return_tensors=framework)) + common_inputs = dict(tokenizer(dummy_input, return_tensors="pt")) return common_inputs def generate_dummy_inputs( @@ -361,20 +358,19 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: if self.task in ["default", "seq2seq-lm"]: common_inputs = self._generate_dummy_inputs_for_default_and_seq2seq_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) elif self.task == "causal-lm": common_inputs = self._generate_dummy_inputs_for_causal_lm( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) else: common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair ) return common_inputs diff --git a/src/transformers/models/mbart/modeling_flax_mbart.py b/src/transformers/models/mbart/modeling_flax_mbart.py deleted file mode 100644 index ad269860a959..000000000000 --- a/src/transformers/models/mbart/modeling_flax_mbart.py +++ /dev/null @@ -1,1780 +0,0 @@ -# coding=utf-8 -# Copyright 2021, The Facebook AI Research Team and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax MBart model.""" - -import math -import random -from functools import partial -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxSeq2SeqLMOutput, - FlaxSeq2SeqModelOutput, - FlaxSeq2SeqQuestionAnsweringModelOutput, - FlaxSeq2SeqSequenceClassifierOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_mbart import MBartConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/mbart-large-cc25" -_CONFIG_FOR_DOC = "MBartConfig" - - -MBART_START_DOCSTRING = r""" - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`MBartConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -MBART_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -MBART_ENCODE_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -MBART_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def shift_tokens_right(input_ids: jnp.ndarray, pad_token_id: int) -> jnp.ndarray: - """ - Shift input ids one token to the right, and wrap the last non pad token (the token) Note that MBart does not - have a single `decoder_start_token_id` in contrast to other Bart-like models. - """ - prev_output_tokens = jnp.array(input_ids).copy() - - if pad_token_id is None: - raise ValueError("self.model.config.pad_token_id has to be defined.") - - # replace possible -100 values in labels by `pad_token_id` - prev_output_tokens = jnp.where(prev_output_tokens == -100, pad_token_id, input_ids) - index_of_eos = (jnp.where(prev_output_tokens != pad_token_id, 1, 0).sum(axis=-1) - 1).reshape(-1, 1) - decoder_start_tokens = jnp.array( - [prev_output_tokens[i, eos_idx] for i, eos_idx in enumerate(index_of_eos)], dtype=jnp.int32 - ).squeeze() - - prev_output_tokens = prev_output_tokens.at[:, 1:].set(prev_output_tokens[:, :-1]) - prev_output_tokens = prev_output_tokens.at[:, 0].set(decoder_start_tokens) - - return prev_output_tokens - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention with Bart->MBart -class FlaxMBartAttention(nn.Module): - config: MBartConfig - embed_dim: int - num_heads: int - dropout: float = 0.0 - causal: bool = False - bias: bool = True - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self) -> None: - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {self.num_heads})." - ) - - dense = partial( - nn.Dense, - self.embed_dim, - use_bias=self.bias, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() - self.out_proj = dense() - - self.dropout_layer = nn.Dropout(rate=self.dropout) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states: jnp.ndarray, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.q_proj(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.k_proj(key_value_states) - value_states = self.v_proj(key_value_states) - else: - # self_attention - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights - - -class FlaxMBartEncoderLayer(nn.Module): - config: MBartConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxMBartAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.encoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - self.fc1 = nn.Dense( - self.config.encoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - hidden_states, attn_weights = self.self_attn(hidden_states=hidden_states, attention_mask=attention_mask) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartEncoderLayerCollection with Bart->MBart -class FlaxMBartEncoderLayerCollection(nn.Module): - config: MBartConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxMBartEncoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.encoder_layers) - ] - self.layerdrop = self.config.encoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for encoder_layer in self.layers: - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): # skip the layer - layer_outputs = (None, None) - else: - layer_outputs = encoder_layer( - hidden_states, - attention_mask, - output_attentions, - deterministic, - ) - hidden_states = layer_outputs[0] - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -class FlaxMBartDecoderLayer(nn.Module): - config: MBartConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxMBartAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - causal=True, - dtype=self.dtype, - ) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.encoder_attn = FlaxMBartAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.fc1 = nn.Dense( - self.config.decoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - hidden_states, self_attn_weights = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - hidden_states = self.encoder_attn_layer_norm(hidden_states) - hidden_states, cross_attn_weights = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights, cross_attn_weights) - - return outputs - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderLayerCollection with Bart->MBart -class FlaxMBartDecoderLayerCollection(nn.Module): - config: MBartConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxMBartDecoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.decoder_layers) - ] - self.layerdrop = self.config.decoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - for decoder_layer in self.layers: - if output_hidden_states: - all_hidden_states += (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): - layer_outputs = (None, None, None) - else: - layer_outputs = decoder_layer( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - deterministic=deterministic, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attns += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = [hidden_states, all_hidden_states, all_self_attns, all_cross_attentions] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartClassificationHead with Bart->MBart -class FlaxMBartClassificationHead(nn.Module): - """Head for sentence-level classification tasks.""" - - config: MBartConfig - inner_dim: int - num_classes: int - pooler_dropout: float - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense( - self.inner_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.dropout = nn.Dropout(rate=self.pooler_dropout) - self.out_proj = nn.Dense( - self.num_classes, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - def __call__(self, hidden_states: jnp.ndarray, deterministic: bool): - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.dense(hidden_states) - hidden_states = jnp.tanh(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.out_proj(hidden_states) - return hidden_states - - -class FlaxMBartEncoder(nn.Module): - config: MBartConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_source_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(embed_dim) if self.config.scale_embedding else 1.0 - - # MBart is set up so that if padding_idx is specified then offset the embedding ids by 2 - # and adjust num_embeddings appropriately. Other models don't have this hack - self.offset = 2 - self.embed_positions = nn.Embed( - self.config.max_position_embeddings + self.offset, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.layers = FlaxMBartEncoderLayerCollection(self.config, self.dtype) - self.layernorm_embedding = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - embed_pos = self.embed_positions(position_ids + self.offset) - - hidden_states = inputs_embeds + embed_pos - hidden_states = self.layernorm_embedding(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - last_hidden_states = outputs[0] - last_hidden_states = self.layer_norm(last_hidden_states) - - # update the last element in `hidden_states` after applying `layernorm` above - hidden_states = None - if output_hidden_states: - hidden_states = outputs[1] - hidden_states = hidden_states[:-1] + (last_hidden_states,) - - if not return_dict: - outputs = (last_hidden_states, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=last_hidden_states, - hidden_states=hidden_states, - attentions=outputs.attentions, - ) - - -class FlaxMBartDecoder(nn.Module): - config: MBartConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_target_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(self.config.d_model) if self.config.scale_embedding else 1.0 - - # MBart is set up so that if padding_idx is specified then offset the embedding ids by 2 - # and adjust num_embeddings appropriately. Other models don't have this hack - self.offset = 2 - self.embed_positions = nn.Embed( - self.config.max_position_embeddings + self.offset, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.layers = FlaxMBartDecoderLayerCollection(self.config, self.dtype) - self.layernorm_embedding = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - # embed positions - positions = self.embed_positions(position_ids + self.offset) - - hidden_states = inputs_embeds + positions - hidden_states = self.layernorm_embedding(hidden_states) - - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - last_hidden_states = outputs[0] - last_hidden_states = self.layer_norm(last_hidden_states) - - # update the last element in `hidden_states` after applying `layernorm` above - hidden_states = None - if output_hidden_states: - hidden_states = outputs[1] - hidden_states = hidden_states[:-1] + (last_hidden_states,) - - if not return_dict: - outputs = (last_hidden_states, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=last_hidden_states, - hidden_states=hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartModule with Bart->MBart -class FlaxMBartModule(nn.Module): - config: MBartConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - - self.encoder = FlaxMBartEncoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - self.decoder = FlaxMBartDecoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -class FlaxMBartPreTrainedModel(FlaxPreTrainedModel): - config_class = MBartConfig - base_model_prefix: str = "model" - module_class: nn.Module = None - - def __init__( - self, - config: MBartConfig, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - # make sure initialization pass will work for FlaxMBartForSequenceClassificationModule - input_ids = input_ids.at[(..., -1)].set(self.config.eos_token_id) - attention_mask = jnp.ones_like(input_ids) - decoder_input_ids = input_ids - decoder_attention_mask = jnp.ones_like(input_ids) - - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - decoder_position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartPreTrainedModel.init_cache with Bart->MBart - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape - ) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(MBART_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=MBartConfig) - def encode( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxMBartForConditionalGeneration - - >>> model = FlaxMBartForConditionalGeneration.from_pretrained("facebook/mbart-large-cc25") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/mbart-large-cc25") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, input_ids, attention_mask, position_ids, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(input_ids, attention_mask, position_ids, **kwargs) - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - @add_start_docstrings(MBART_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=MBartConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxMBartForConditionalGeneration - - >>> model = FlaxMBartForConditionalGeneration.from_pretrained("facebook/mbart-large-cc25") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/mbart-large-cc25") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> last_decoder_hidden_states = outputs.last_hidden_state - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxMBartAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - @add_start_docstrings_to_model_forward(MBART_INPUTS_DOCSTRING) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_input_ids: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # prepare decoder inputs - if decoder_input_ids is None: - decoder_input_ids = shift_tokens_right(input_ids, self.config.pad_token_id) - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - if decoder_position_ids is None: - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - -@add_start_docstrings( - "The bare MBart Model transformer outputting raw hidden-states without any specific head on top.", - MBART_START_DOCSTRING, -) -class FlaxMBartModel(FlaxMBartPreTrainedModel): - config: MBartConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - module_class = FlaxMBartModule - - -append_call_sample_docstring(FlaxMBartModel, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartForConditionalGenerationModule with Bart->MBart -class FlaxMBartForConditionalGenerationModule(nn.Module): - config: MBartConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., jnp.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.model = FlaxMBartModule(config=self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.model.shared.num_embeddings, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.final_logits_bias = self.param("final_logits_bias", self.bias_init, (1, self.model.shared.num_embeddings)) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - position_ids=position_ids, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = self.model.variables["params"]["shared"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - lm_logits += jax.lax.stop_gradient(self.final_logits_bias.astype(self.dtype)) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return output - - return FlaxSeq2SeqLMOutput( - logits=lm_logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings( - "The MMBart Model with a language modeling head. Can be used for summarization.", MBART_START_DOCSTRING -) -class FlaxMBartForConditionalGeneration(FlaxMBartPreTrainedModel): - module_class = FlaxMBartForConditionalGenerationModule - dtype: jnp.dtype = jnp.float32 - - @add_start_docstrings(MBART_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=MBartConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxMBartForConditionalGeneration - - >>> model = FlaxMBartForConditionalGeneration.from_pretrained("facebook/mbart-large-cc25") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/mbart-large-cc25") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxMBartAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - outputs = decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = module.model.variables["params"]["shared"]["embedding"] - lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = module.lm_head(hidden_states) - - lm_logits += module.final_logits_bias.astype(self.dtype) - return lm_logits, outputs - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - if past_key_values is None: - lm_logits, decoder_outputs = outputs - else: - (lm_logits, decoder_outputs), past = outputs - - if return_dict: - outputs = FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=decoder_outputs.hidden_states, - attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - ) - else: - outputs = (lm_logits,) + decoder_outputs[1:] - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - position_ids = decoder_attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - "decoder_position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 - return model_kwargs - - -FLAX_MBART_CONDITIONAL_GENERATION_DOCSTRING = r""" - Returns: - - Summarization example: - - ```python - >>> from transformers import AutoTokenizer, FlaxMBartForConditionalGeneration, MBartConfig - - >>> model = FlaxMBartForConditionalGeneration.from_pretrained("facebook/mbart-large-cc25") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/mbart-large-cc25") - - >>> ARTICLE_TO_SUMMARIZE = "Meine Freunde sind cool, aber sie essen zu viel Kuchen." - >>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], max_length=1024, return_tensors="np") - - >>> # Generate Summary - >>> summary_ids = model.generate(inputs["input_ids"], num_beams=4, max_length=5).sequences - >>> print(tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)) - ``` - - Mask filling example: - - ```python - >>> from transformers import AutoTokenizer, FlaxMBartForConditionalGeneration - - >>> model = FlaxMBartForConditionalGeneration.from_pretrained("facebook/mbart-large-cc25") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/mbart-large-cc25") - - >>> # de_DE is the language symbol id for German - >>> TXT = " Meine Freunde sind nett aber sie essen zu viel Kuchen. de_DE" - >>> input_ids = tokenizer([TXT], add_special_tokens=False, return_tensors="np")["input_ids"] - - >>> logits = model(input_ids).logits - >>> masked_index = (input_ids[0] == tokenizer.mask_token_id).nonzero()[0].item() - >>> probs = logits[0, masked_index].softmax(dim=0) - >>> values, predictions = probs.topk(5) - - >>> tokenizer.decode(predictions).split() - ``` -""" - -overwrite_call_docstring( - FlaxMBartForConditionalGeneration, MBART_INPUTS_DOCSTRING + FLAX_MBART_CONDITIONAL_GENERATION_DOCSTRING -) -append_replace_return_docstrings( - FlaxMBartForConditionalGeneration, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC -) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartForSequenceClassificationModule with Bart->MBart -class FlaxMBartForSequenceClassificationModule(nn.Module): - config: MBartConfig - dtype: jnp.dtype = jnp.float32 - num_labels: Optional[int] = None - - def setup(self): - self.model = FlaxMBartModule(config=self.config, dtype=self.dtype) - self.classification_head = FlaxMBartClassificationHead( - config=self.config, - inner_dim=self.config.d_model, - num_classes=self.num_labels if self.num_labels is not None else self.config.num_labels, - pooler_dropout=self.config.classifier_dropout, - ) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - position_ids=position_ids, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = outputs[0] # last hidden state - - eos_mask = jnp.where(input_ids == self.config.eos_token_id, 1, 0) - - # The first condition is necessary to overcome jax._src.errors.ConcretizationTypeError during JIT compilation - if not isinstance(eos_mask, jax.interpreters.partial_eval.DynamicJaxprTracer): - if len(jnp.unique(eos_mask.sum(1))) > 1: - raise ValueError("All examples must have the same number of tokens.") - - if any(eos_mask.sum(1) == 0): - raise ValueError("There are missing tokens in input_ids") - - # Ensure to keep 1 only for the last token for each example - eos_mask_noised = eos_mask + jnp.arange(eos_mask.shape[1]) * 1e-6 - eos_mask = jnp.where(eos_mask_noised == eos_mask_noised.max(1).reshape(-1, 1), 1, 0) - - sentence_representation = jnp.einsum("ijk, ij -> ijk", hidden_states, eos_mask).sum(1) - logits = self.classification_head(sentence_representation, deterministic=deterministic) - - if not return_dict: - output = (logits,) + outputs[1:] - return output - - return FlaxSeq2SeqSequenceClassifierOutput( - logits=logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings( - """ - MBart model with a sequence classification/head on top (a linear layer on top of the pooled output) e.g. for GLUE - tasks. - """, - MBART_START_DOCSTRING, -) -class FlaxMBartForSequenceClassification(FlaxMBartPreTrainedModel): - module_class = FlaxMBartForSequenceClassificationModule - dtype = jnp.float32 - - -append_call_sample_docstring( - FlaxMBartForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSeq2SeqSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartForQuestionAnsweringModule with Bart->MBart -class FlaxMBartForQuestionAnsweringModule(nn.Module): - config: MBartConfig - dtype: jnp.dtype = jnp.float32 - num_labels = 2 - - def setup(self): - self.model = FlaxMBartModule(config=self.config, dtype=self.dtype) - self.qa_outputs = nn.Dense( - self.num_labels, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - position_ids=position_ids, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - sequence_output = outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = jnp.split(logits, logits.shape[-1], axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - output = (start_logits, end_logits) + outputs[1:] - return output - - return FlaxSeq2SeqQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings( - """ - MBart Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layer on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - MBART_START_DOCSTRING, -) -class FlaxMBartForQuestionAnswering(FlaxMBartPreTrainedModel): - module_class = FlaxMBartForQuestionAnsweringModule - dtype = jnp.float32 - - -append_call_sample_docstring( - FlaxMBartForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxSeq2SeqQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - - -__all__ = [ - "FlaxMBartForConditionalGeneration", - "FlaxMBartForQuestionAnswering", - "FlaxMBartForSequenceClassification", - "FlaxMBartModel", - "FlaxMBartPreTrainedModel", -] diff --git a/src/transformers/models/mbart/modeling_tf_mbart.py b/src/transformers/models/mbart/modeling_tf_mbart.py deleted file mode 100644 index ac29bfeac76f..000000000000 --- a/src/transformers/models/mbart/modeling_tf_mbart.py +++ /dev/null @@ -1,1572 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 MBart model.""" - -from __future__ import annotations - -import random - -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPastAndCrossAttentions, - TFSeq2SeqLMOutput, - TFSeq2SeqModelOutput, -) - -# Public API -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_end_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_mbart import MBartConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/mbart-large-cc25" -_CONFIG_FOR_DOC = "MBartConfig" - - -LARGE_NEGATIVE = -1e8 - - -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int): - """ - Shift input ids one token to the right, and wrap the last non pad token (the token) Note that MBart does not - have a single `decoder_start_token_id` in contrast to other Bart-like models. - """ - if pad_token_id is None: - raise ValueError("self.model.config.pad_token_id has to be defined.") - # replace possible -100 values in labels by `pad_token_id` - input_ids = tf.where( - input_ids == -100, tf.fill(shape_list(input_ids), tf.cast(pad_token_id, input_ids.dtype)), input_ids - ) - language_id_index = ( - tf.reduce_sum(tf.cast(tf.math.not_equal(input_ids, pad_token_id), dtype=input_ids.dtype), axis=-1) - 1 - ) - language_id_index = tf.stack( - [tf.range(shape_list(input_ids)[0], dtype=input_ids.dtype), language_id_index], axis=-1 - ) - languages_ids = tf.gather_nd(input_ids, language_id_index) - - shifted_input_ids = tf.concat([tf.expand_dims(languages_ids, axis=-1), input_ids[:, :-1]], axis=-1) - - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE - mask_cond = tf.range(shape_list(mask)[-1]) - - mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartLearnedPositionalEmbedding with Bart->MBart -class TFMBartLearnedPositionalEmbedding(keras.layers.Embedding): - """ - This module learns positional embeddings up to a fixed maximum size. - """ - - def __init__(self, num_embeddings: int, embedding_dim: int, **kwargs): - # MBart is set up so that if padding_idx is specified then offset the embedding ids by 2 - # and adjust num_embeddings appropriately. Other models don't have this hack - self.offset = 2 - super().__init__(num_embeddings + self.offset, embedding_dim, **kwargs) - - def call( - self, - input_shape: tf.TensorShape | None = None, - past_key_values_length: int = 0, - position_ids: tf.Tensor | None = None, - ): - """Input is expected to be of size [bsz x seqlen].""" - if position_ids is None: - seq_len = input_shape[1] - position_ids = tf.range(seq_len, delta=1, name="range") - position_ids += past_key_values_length - - offset_dtype = position_ids.dtype if isinstance(position_ids, tf.Tensor) else tf.int32 - return super().call(position_ids + tf.constant(self.offset, dtype=offset_dtype)) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with Bart->MBart -class TFMBartAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -class TFMBartEncoderLayer(keras.layers.Layer): - def __init__(self, config: MBartConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFMBartAttention( - self.embed_dim, config.encoder_attention_heads, dropout=config.attention_dropout, name="self_attn" - ) - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - self.fc1 = keras.layers.Dense(config.encoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - layer_head_mask: tf.Tensor, - training: bool | None = False, - ): - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape *(batch, seq_len, embed_dim)* - attention_mask (`tf.Tensor`): attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - *(encoder_attention_heads,)* - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - hidden_states, self_attn_weights, _ = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, layer_head_mask=layer_head_mask - ) - - tf.debugging.assert_equal( - shape_list(hidden_states), - shape_list(residual), - message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", - ) - - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return hidden_states, self_attn_weights - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.encoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFMBartDecoderLayer(keras.layers.Layer): - def __init__(self, config: MBartConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFMBartAttention( - embed_dim=self.embed_dim, - num_heads=config.decoder_attention_heads, - dropout=config.attention_dropout, - name="self_attn", - is_decoder=True, - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.encoder_attn = TFMBartAttention( - self.embed_dim, - config.decoder_attention_heads, - dropout=config.attention_dropout, - name="encoder_attn", - is_decoder=True, - ) - self.encoder_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.decoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - cross_attn_layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tf.Tensor] | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape *(batch, seq_len, embed_dim)* - attention_mask (`tf.Tensor`): attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - encoder_hidden_states (`tf.Tensor`): - cross attention input to the layer of shape *(batch, seq_len, embed_dim)* - encoder_attention_mask (`tf.Tensor`): encoder attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - *(decoder_attention_heads,)* - cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. - *(decoder_attention_heads,)* - past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_present_key_value = None - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - layer_head_mask=cross_attn_layer_head_mask, - past_key_value=cross_attn_past_key_value, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # add cross-attn to positions 3,4 of present_key_value tuple - present_key_value = present_key_value + cross_attn_present_key_value - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return ( - hidden_states, - self_attn_weights, - cross_attn_weights, - present_key_value, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "encoder_attn", None) is not None: - with tf.name_scope(self.encoder_attn.name): - self.encoder_attn.build(None) - if getattr(self, "encoder_attn_layer_norm", None) is not None: - with tf.name_scope(self.encoder_attn_layer_norm.name): - self.encoder_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.decoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFMBartPreTrainedModel(TFPreTrainedModel): - config_class = MBartConfig - base_model_prefix = "model" - - -MBART_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`MBartConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -MBART_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - MBart uses a specific language id token as the starting token for `decoder_input_ids` generation that - varies according to source and target language, *e.g.* 25004 for *en_XX*, and 25003 for *de_DE*. If - `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - will be made by default and ignore pad tokens. It is not recommended to set this for most use cases. - decoder_position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_outputs (`tf.FloatTensor`, *optional*): - hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - of shape `(batch_size, sequence_length, hidden_size)` is a sequence of - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - -MBART_GENERATION_EXAMPLE = r""" - Translation example: - - ```python - >>> from transformers import AutoTokenizer, TFMBartForConditionalGeneration - - >>> model = TFMBartForConditionalGeneration.from_pretrained("facebook/mbart-large-en-ro") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/mbart-large-en-ro") - - >>> example_english_phrase = "42 is the answer" - >>> inputs = tokenizer(example_english_phrase, return_tensors="tf") - - >>> # Translate - >>> generated_ids = model.generate(**inputs, num_beams=4, max_length=5) - >>> tokenizer.batch_decode(generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] - '42 este răspuns' - ``` - - Mask filling example: - - ```python - >>> from transformers import AutoTokenizer, TFMBartForConditionalGeneration - >>> import tensorflow as tf - - >>> model = TFMBartForConditionalGeneration.from_pretrained("facebook/mbart-large-cc25") - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/mbart-large-cc25") - - >>> # de_DE is the language symbol id for German - >>> TXT = " Meine Freunde sind nett aber sie essen zu viel Kuchen. de_DE" - - >>> input_ids = tokenizer([TXT], add_special_tokens=False, return_tensors="tf")["input_ids"] - >>> logits = model(input_ids).logits - - >>> masked_index = tf.where(input_ids[0] == tokenizer.mask_token_id)[0, 0] - >>> probs = tf.nn.softmax(logits[0, masked_index], axis=0) - >>> values, predictions = tf.math.top_k(probs, 5) - - >>> tokenizer.decode(predictions).split() - ['nett', 'sehr', 'ganz', 'nicht', 'so'] - ``` -""" - - -@keras_serializable -class TFMBartEncoder(keras.layers.Layer): - config_class = MBartConfig - """ - Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a - [`TFMBartEncoderLayer`]. - - Args: - config: MBartConfig - """ - - def __init__(self, config: MBartConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.dropout = keras.layers.Dropout(config.dropout) - self.layerdrop = config.encoder_layerdrop - self.padding_idx = config.pad_token_id - self.max_source_positions = config.max_position_embeddings - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - - self.embed_tokens = embed_tokens - self.embed_positions = TFMBartLearnedPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.layers = [TFMBartEncoderLayer(config, name=f"layers.{i}") for i in range(config.encoder_layers)] - self.layernorm_embedding = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_embedding") - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - self.embed_dim = config.d_model - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - inputs_embeds: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - """ - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. This argument can be used only in eager mode, in graph mode the value - in the config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. This argument can be used only in eager mode, in graph mode the value in the config - will be used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - embed_pos = self.embed_positions(input_shape) - hidden_states = inputs_embeds + embed_pos - hidden_states = self.layernorm_embedding(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - - # check attention mask and invert - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - attention_mask = _expand_mask(attention_mask) - else: - attention_mask = None - - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - # check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - tf.debugging.assert_equal( - shape_list(head_mask)[0], - len(self.layers), - message=( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(head_mask)[0]}." - ), - ) - - # encoder layers - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): # skip the layer - continue - - hidden_states, attn = encoder_layer( - hidden_states, - attention_mask, - head_mask[idx] if head_mask is not None else None, - ) - - if output_attentions: - all_attentions += (attn,) - - hidden_states = self.layer_norm(hidden_states) - - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layernorm_embedding", None) is not None: - with tf.name_scope(self.layernorm_embedding.name): - self.layernorm_embedding.build([None, None, self.embed_dim]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFMBartDecoder(keras.layers.Layer): - config_class = MBartConfig - """ - Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFMBartDecoderLayer`] - - Args: - config: MBartConfig - embed_tokens: output embedding - """ - - def __init__(self, config: MBartConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.padding_idx = config.pad_token_id - self.embed_tokens = embed_tokens - self.layerdrop = config.decoder_layerdrop - self.embed_positions = TFMBartLearnedPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - self.layers = [TFMBartDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] - self.layernorm_embedding = keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_embedding") - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - self.dropout = keras.layers.Dropout(config.dropout) - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType = None, - inputs_embeds: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor, tf.Tensor, tf.Tensor, tf.Tensor, tf.Tensor]: - r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention - of the decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): - Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values - selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers` with each tuple having 2 tuples each of which has 2 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up - decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those - that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of - all `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. This argument can be used only in eager mode, in graph mode the value - in the config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. This argument can be used only in eager mode, in graph mode the value in the config - will be used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - past_key_values_length = shape_list(past_key_values[0][0])[2] if past_key_values is not None else 0 - - # embed positions - if position_ids is None: - positions = self.embed_positions(input_shape, past_key_values_length) - else: - positions = self.embed_positions(input_shape, position_ids=position_ids) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - hidden_states = inputs_embeds - - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - if input_shape[-1] > 1: - combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length=past_key_values_length) - else: - combined_attention_mask = _expand_mask( - tf.ones((input_shape[0], input_shape[1] + past_key_values_length)), tgt_len=input_shape[-1] - ) - - if attention_mask is not None: - combined_attention_mask = combined_attention_mask + _expand_mask(attention_mask, tgt_len=input_shape[-1]) - - if encoder_hidden_states is not None and encoder_attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) - - hidden_states = self.layernorm_embedding(hidden_states + positions) - hidden_states = self.dropout(hidden_states, training=training) - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attns = () if (output_attentions and encoder_hidden_states is not None) else None - present_key_values = () if use_cache else None - - # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired - for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: - if attn_mask is not None: - tf.debugging.assert_equal( - shape_list(attn_mask)[0], - len(self.layers), - message=( - f"The {attn_mask_name} should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(attn_mask)[0]}." - ), - ) - - for idx, decoder_layer in enumerate(self.layers): - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - if output_hidden_states: - all_hidden_states += (hidden_states,) - dropout_probability = random.uniform(0, 1) - - if training and (dropout_probability < self.layerdrop): - continue - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( - hidden_states, - attention_mask=combined_attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - cross_attn_layer_head_mask=cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None, - past_key_value=past_key_value, - ) - - if use_cache: - present_key_values += (present_key_value,) - - if output_attentions: - all_self_attns += (layer_self_attn,) - - if encoder_hidden_states is not None: - all_cross_attns += (layer_cross_attn,) - - hidden_states = self.layer_norm(hidden_states) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - if not return_dict: - return hidden_states, present_key_values, all_hidden_states, all_self_attns, all_cross_attns - else: - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=present_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layernorm_embedding", None) is not None: - with tf.name_scope(self.layernorm_embedding.name): - self.layernorm_embedding.build([None, None, self.config.d_model]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFMBartMainLayer(keras.layers.Layer): - config_class = MBartConfig - - def __init__(self, config: MBartConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.shared = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.d_model, - embeddings_initializer=keras.initializers.TruncatedNormal(stddev=self.config.init_std), - name="model.shared", - ) - # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) - self.shared.load_weight_prefix = "model.shared" - - self.encoder = TFMBartEncoder(config, self.shared, name="encoder") - self.decoder = TFMBartDecoder(config, self.shared, name="decoder") - - def get_input_embeddings(self): - return self.shared - - def set_input_embeddings(self, new_embeddings): - self.shared = new_embeddings - self.encoder.embed_tokens = self.shared - self.decoder.embed_tokens = self.shared - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ) -> TFSeq2SeqModelOutput | tf.Tensor: - if decoder_input_ids is None and decoder_inputs_embeds is None: - use_cache = False - - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - - if decoder_input_ids is None and input_ids is not None: - decoder_input_ids = shift_tokens_right(input_ids, self.config.pad_token_id) - - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True - elif return_dict and not isinstance(encoder_outputs, TFBaseModelOutput): - encoder_outputs = TFBaseModelOutput( - last_hidden_state=encoder_outputs[0], - hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, - attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, - ) - # If the user passed a TFBaseModelOutput for encoder_outputs, we wrap it in a tuple when return_dict=False - elif not return_dict and not isinstance(encoder_outputs, tuple): - encoder_outputs = encoder_outputs.to_tuple() - - decoder_outputs = self.decoder( - decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return TFSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # The shared/tied weights expect to be in the model base namespace - # Adding "/" to the end (not the start!) of a tf.name_scope puts it in the root namespace rather than - # the current one. - with tf.name_scope(self.shared.load_weight_prefix + "/" + self.shared.name + "/"): - self.shared.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - "The bare MBART Model outputting raw hidden-states without any specific head on top.", - MBART_START_DOCSTRING, -) -class TFMBartModel(TFMBartPreTrainedModel): - def __init__(self, config: MBartConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.model = TFMBartMainLayer(config, name="model") - - def get_encoder(self): - return self.model.encoder - - def get_decoder(self): - return self.model.decoder - - @unpack_inputs - @add_start_docstrings_to_model_forward(MBART_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSeq2SeqModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ) -> TFSeq2SeqModelOutput | tuple[tf.Tensor]: - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - encoder_outputs=encoder_outputs, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartModel.serving_output - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqModelOutput( - last_hidden_state=output.last_hidden_state, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -# Copied from transformers.models.bart.modeling_tf_bart.BiasLayer -class BiasLayer(keras.layers.Layer): - """ - Bias as a layer. It is used for serialization purposes: `keras.Model.save_weights` stores on a per-layer basis, - so all weights have to be registered in a layer. - """ - - def __init__(self, shape, initializer, trainable, name, **kwargs): - super().__init__(name=name, **kwargs) - # Note: the name of this variable will NOT be scoped when serialized, i.e. it will not be in the format of - # "outer_layer/inner_layer/.../name:0". Instead, it will be "name:0". For further details, see: - # https://github.com/huggingface/transformers/pull/18833#issuecomment-1233090214 - self.bias = self.add_weight(name=name, shape=shape, initializer=initializer, trainable=trainable) - - def call(self, x): - return x + self.bias - - -@add_start_docstrings( - "The MBART Model with a language modeling head. Can be used for summarization, after fine-tuning the pretrained models.", - MBART_START_DOCSTRING, -) -class TFMBartForConditionalGeneration(TFMBartPreTrainedModel, TFCausalLanguageModelingLoss): - _keys_to_ignore_on_load_unexpected = [ - r"model.encoder.embed_tokens.weight", - r"model.decoder.embed_tokens.weight", - ] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.model = TFMBartMainLayer(config, name="model") - self.use_cache = config.use_cache - # final_bias_logits is registered as a buffer in pytorch, so not trainable for the sake of consistency. - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, config.vocab_size], initializer="zeros", trainable=False - ) - - def get_decoder(self): - return self.model.decoder - - def get_encoder(self): - return self.model.encoder - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - def get_bias(self): - return {"final_logits_bias": self.bias_layer.bias} - - def set_bias(self, value): - # Replaces the existing layers containing bias for correct (de)serialization. - vocab_size = value["final_logits_bias"].shape[-1] - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, vocab_size], initializer="zeros", trainable=False - ) - self.bias_layer.bias.assign(value["final_logits_bias"]) - - @unpack_inputs - @add_start_docstrings_to_model_forward(MBART_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - @add_end_docstrings(MBART_GENERATION_EXAMPLE) - def call( - self, - input_ids: TFModelInputType = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSeq2SeqLMOutput | tuple[tf.Tensor]: - """ - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., - config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - - Returns: - - """ - - if labels is not None: - labels = tf.where( - labels == self.config.pad_token_id, - tf.cast(tf.fill(shape_list(labels), -100), labels.dtype), - labels, - ) - use_cache = False - if decoder_input_ids is None and decoder_inputs_embeds is None: - decoder_input_ids = shift_tokens_right(labels, self.config.pad_token_id) - - outputs = self.model( - input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - encoder_outputs=encoder_outputs, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - lm_logits = tf.matmul(outputs[0], self.model.shared.weights, transpose_b=True) - lm_logits = self.bias_layer(lm_logits) - masked_lm_loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return TFSeq2SeqLMOutput( - loss=masked_lm_loss, - logits=lm_logits, - past_key_values=outputs.past_key_values, # index 1 of d outputs - decoder_hidden_states=outputs.decoder_hidden_states, # index 2 of d outputs - decoder_attentions=outputs.decoder_attentions, # index 3 of d outputs - cross_attentions=outputs.cross_attentions, # index 4 of d outputs - encoder_last_hidden_state=outputs.encoder_last_hidden_state, # index 0 of encoder outputs - encoder_hidden_states=outputs.encoder_hidden_states, # 1 of e out - encoder_attentions=outputs.encoder_attentions, # 2 of e out - ) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartForConditionalGeneration.serving_output - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartForConditionalGeneration.prepare_inputs_for_generation - def prepare_inputs_for_generation( - self, - decoder_input_ids, - past_key_values=None, - attention_mask=None, - decoder_attention_mask=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - use_cache=None, - encoder_outputs=None, - **kwargs, - ): - # cut decoder_input_ids if past_key_values is used - if past_key_values is not None: - decoder_input_ids = decoder_input_ids[:, -1:] - - if decoder_attention_mask is not None: # xla - decoder_position_ids = tf.math.cumsum(decoder_attention_mask, axis=-1, exclusive=True)[:, -1:] - elif past_key_values is not None: # no xla + past_key_values - decoder_position_ids = past_key_values[0][0].shape[2] - else: # no xla + no past_key_values - decoder_position_ids = tf.range(decoder_input_ids.shape[1]) - - return { - "input_ids": None, # encoder_outputs is defined. input_ids not needed - "encoder_outputs": encoder_outputs, - "past_key_values": past_key_values, - "decoder_input_ids": decoder_input_ids, - "attention_mask": attention_mask, - "decoder_attention_mask": decoder_attention_mask, - "decoder_position_ids": decoder_position_ids, - "head_mask": head_mask, - "decoder_head_mask": decoder_head_mask, - "cross_attn_head_mask": cross_attn_head_mask, - "use_cache": use_cache, # change this to avoid caching (presumably for debugging) - } - - def prepare_decoder_input_ids_from_labels(self, labels: tf.Tensor): - return shift_tokens_right(labels, self.config.pad_token_id) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "bias_layer", None) is not None: - with tf.name_scope(self.bias_layer.name): - self.bias_layer.build(None) - - -__all__ = ["TFMBartForConditionalGeneration", "TFMBartModel", "TFMBartPreTrainedModel"] diff --git a/src/transformers/models/megatron_bert/modeling_megatron_bert.py b/src/transformers/models/megatron_bert/modeling_megatron_bert.py index a75c0f575aca..8b8f842c2a2a 100755 --- a/src/transformers/models/megatron_bert/modeling_megatron_bert.py +++ b/src/transformers/models/megatron_bert/modeling_megatron_bert.py @@ -16,7 +16,6 @@ """PyTorch MegatronBERT model.""" import math -import os import warnings from dataclasses import dataclass from typing import Optional, Union @@ -50,75 +49,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_megatron_bert(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class MegatronBertEmbeddings(nn.Module): """Construct the embeddings from word, position and token_type embeddings.""" @@ -128,9 +58,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file - # In Megatron, layer-norm is applied after the 1st dropout. # self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -672,15 +599,12 @@ def forward(self, sequence_output, pooled_output): @auto_docstring class MegatronBertPreTrainedModel(PreTrainedModel): config: MegatronBertConfig - load_tf_weights = load_tf_weights_in_megatron_bert base_model_prefix = "bert" supports_gradient_checkpointing = True def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Embedding)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if hasattr(module, "bias") and module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/mgp_str/modeling_mgp_str.py b/src/transformers/models/mgp_str/modeling_mgp_str.py index be7cf08b14ab..73a963130a90 100644 --- a/src/transformers/models/mgp_str/modeling_mgp_str.py +++ b/src/transformers/models/mgp_str/modeling_mgp_str.py @@ -36,11 +36,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/mistral/__init__.py b/src/transformers/models/mistral/__init__.py index 18a5657cd2ec..ea17b3d67bc4 100644 --- a/src/transformers/models/mistral/__init__.py +++ b/src/transformers/models/mistral/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_mistral import * - from .modeling_flax_mistral import * from .modeling_mistral import * - from .modeling_tf_mistral import * else: import sys diff --git a/src/transformers/models/mistral/modeling_flax_mistral.py b/src/transformers/models/mistral/modeling_flax_mistral.py deleted file mode 100644 index 2c084ee114d7..000000000000 --- a/src/transformers/models/mistral/modeling_flax_mistral.py +++ /dev/null @@ -1,744 +0,0 @@ -# coding=utf-8 -# Copyright 2024 Mistral AI and the HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax Mistral model.""" - -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPast, - FlaxCausalLMOutput, - FlaxCausalLMOutputWithCrossAttentions, -) -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring, logging -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward -from .configuration_mistral import MistralConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "MistralConfig" -_REAL_CHECKPOINT_FOR_DOC = "mistralai/Mistral-7B-v0.1" -_CHECKPOINT_FOR_DOC = "ksmcg/Mistral-tiny" - -MISTRAL_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`MistralConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16`, or - `jax.numpy.bfloat16`. - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -MISTRAL_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - If you want to change padding behavior, you should read [`modeling_opt._prepare_decoder_attention_mask`] - and modify to your needs. See diagram 1 in [the paper](https://huggingface.co/papers/1910.13461) for more - information on the default strategy. - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - position_ids (`numpy.ndarray` of shape `(batch_size, input_ids_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.n_positions - 1]`. - - [What are position IDs?](../glossary#position-ids) - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaRMSNorm with Llama->Mistral -class FlaxMistralRMSNorm(nn.Module): - config: MistralConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.epsilon = self.config.rms_norm_eps - self.weight = self.param("weight", lambda _, shape: jnp.ones(shape), self.config.hidden_size) - - def __call__(self, hidden_states): - variance = jnp.asarray(hidden_states, dtype=jnp.float32) - variance = jnp.power(variance, 2) - variance = variance.mean(-1, keepdims=True) - # use `jax.numpy.sqrt` as `jax.lax.rsqrt` does not match `torch.rsqrt` - hidden_states = hidden_states / jnp.sqrt(variance + self.epsilon) - - return self.weight * jnp.asarray(hidden_states, dtype=self.dtype) - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaRotaryEmbedding with Llama->Mistral -class FlaxMistralRotaryEmbedding(nn.Module): - config: MistralConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - head_dim = self.config.hidden_size // self.config.num_attention_heads - self.sincos = create_sinusoidal_positions(self.config.max_position_embeddings, head_dim) - - def __call__(self, key, query, position_ids): - sincos = self.sincos[position_ids] - sin_pos, cos_pos = jnp.split(sincos, 2, axis=-1) - - key = apply_rotary_pos_emb(key, sin_pos, cos_pos) - query = apply_rotary_pos_emb(query, sin_pos, cos_pos) - - key = jnp.asarray(key, dtype=self.dtype) - query = jnp.asarray(query, dtype=self.dtype) - - return key, query - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaMLP with Llama->Mistral -class FlaxMistralMLP(nn.Module): - config: MistralConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - embed_dim = self.config.hidden_size - inner_dim = self.config.intermediate_size if self.config.intermediate_size is not None else 4 * embed_dim - - kernel_init = jax.nn.initializers.normal(self.config.initializer_range) - self.act = ACT2FN[self.config.hidden_act] - - self.gate_proj = nn.Dense(inner_dim, use_bias=False, dtype=self.dtype, kernel_init=kernel_init) - self.down_proj = nn.Dense(embed_dim, use_bias=False, dtype=self.dtype, kernel_init=kernel_init) - self.up_proj = nn.Dense(inner_dim, use_bias=False, dtype=self.dtype, kernel_init=kernel_init) - - def __call__(self, hidden_states): - up_proj_states = self.up_proj(hidden_states) - gate_states = self.act(self.gate_proj(hidden_states)) - - hidden_states = self.down_proj(up_proj_states * gate_states) - return hidden_states - - -# Copied from transformers.models.llama.modeling_flax_llama.apply_rotary_pos_emb -def apply_rotary_pos_emb(tensor, sin_pos, cos_pos): - return (tensor * cos_pos) + (rotate_half(tensor) * sin_pos) - - -# Copied from transformers.models.llama.modeling_flax_llama.create_sinusoidal_positions -def create_sinusoidal_positions(num_pos, dim): - inv_freq = 1.0 / (10000 ** (np.arange(0, dim, 2) / dim)) - freqs = np.einsum("i , j -> i j", np.arange(num_pos), inv_freq).astype("float32") - - emb = np.concatenate((freqs, freqs), axis=-1) - out = np.concatenate((np.sin(emb)[:, None, :], np.cos(emb)[:, None, :]), axis=-1) - return jnp.array(out[:, :, :num_pos]) - - -# Copied from transformers.models.llama.modeling_flax_llama.rotate_half -def rotate_half(tensor): - """Rotates half the hidden dims of the input.""" - rotate_half_tensor = jnp.concatenate( - (-tensor[..., tensor.shape[-1] // 2 :], tensor[..., : tensor.shape[-1] // 2]), axis=-1 - ) - return rotate_half_tensor - - -class FlaxMistralAttention(nn.Module): - config: MistralConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - config = self.config - self.hidden_size = config.hidden_size - self.num_heads = config.num_attention_heads - self.head_dim = self.hidden_size // self.num_heads - self.num_key_value_heads = config.num_key_value_heads - self.num_key_value_groups = self.num_heads // self.num_key_value_heads - self.max_position_embeddings = config.max_position_embeddings - self.attention_softmax_in_fp32 = self.dtype is not jnp.float32 - self.rope_theta = config.rope_theta - if (self.head_dim * self.num_heads) != self.hidden_size: - raise ValueError( - f"hidden_size must be divisible by num_heads (got `hidden_size`: {self.hidden_size}" - f" and `num_heads`: {self.num_heads})." - ) - self.q_proj = nn.Dense(self.num_heads * self.head_dim, use_bias=False, dtype=self.dtype) - self.k_proj = nn.Dense(self.num_key_value_heads * self.head_dim, use_bias=False, dtype=self.dtype) - self.v_proj = nn.Dense(self.num_key_value_heads * self.head_dim, use_bias=False, dtype=self.dtype) - self.o_proj = nn.Dense(self.hidden_size, use_bias=False, dtype=self.dtype) - causal_mask = make_causal_mask(jnp.ones((1, config.max_position_embeddings), dtype="bool"), dtype="bool") - self.causal_mask = jnp.triu(causal_mask, k=-(config.sliding_window or 0)) - self.rotary_emb = FlaxMistralRotaryEmbedding(self.config, dtype=self.dtype) - - def _split_heads(self, hidden_states, num_heads): - return hidden_states.reshape(hidden_states.shape[:2] + (num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.hidden_size,)) - - @nn.compact - # Copied from transformers.models.gpt_neo.modeling_flax_gpt_neo.FlaxGPTNeoSelfAttention._concatenate_to_cache - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - deterministic: bool = True, - output_attentions: bool = False, - init_cache: bool = False, - ) -> tuple[jnp.ndarray, jnp.ndarray]: - query_states = self.q_proj(hidden_states) - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states, self.num_heads) - key_states = self._split_heads(key_states, self.num_key_value_heads) - value_states = self._split_heads(value_states, self.num_key_value_heads) - - key_states, query_states = self.rotary_emb(key_states, query_states, position_ids) - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - - batch_size = hidden_states.shape[0] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - - if self.has_variable("cache", "cached_key") or init_cache: - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - key_states = jnp.repeat(key_states, self.num_key_value_groups, axis=2) - value_states = jnp.repeat(value_states, self.num_key_value_groups, axis=2) - - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - - # usual dot product attention - attention_dtype = jnp.float32 if self.attention_softmax_in_fp32 else self.dtype - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - deterministic=deterministic, - dropout_rate=self.config.attention_dropout, - dtype=attention_dtype, - ) - - if self.attention_softmax_in_fp32: - attn_weights = attn_weights.astype(self.dtype) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.o_proj(attn_output) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaDecoderLayer with Llama->Mistral -class FlaxMistralDecoderLayer(nn.Module): - config: MistralConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.input_layernorm = FlaxMistralRMSNorm(self.config, dtype=self.dtype) - self.self_attn = FlaxMistralAttention(self.config, dtype=self.dtype) - self.post_attention_layernorm = FlaxMistralRMSNorm(self.config, dtype=self.dtype) - self.mlp = FlaxMistralMLP(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - ): - residual = hidden_states - hidden_states = self.input_layernorm(hidden_states) - outputs = self.self_attn( - hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - # residual connection - attn_output = outputs[0] - hidden_states = residual + attn_output - - residual = hidden_states - hidden_states = self.post_attention_layernorm(hidden_states) - hidden_states = self.mlp(hidden_states) - # residual connection - hidden_states = residual + hidden_states - - return (hidden_states,) + outputs[1:] - - -# Copied from transformers.models.gpt_neo.modeling_flax_gpt_neo.FlaxGPTNeoPreTrainedModel with GPTNeo->Mistral, GPT_NEO->MISTRAL, transformer->model -class FlaxMistralPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = MistralConfig - base_model_prefix = "model" - module_class: nn.Module = None - - def __init__( - self, - config: MistralConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, input_ids, attention_mask, position_ids, return_dict=False)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length)) - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(MISTRAL_INPUTS_DOCSTRING) - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - params: Optional[dict] = None, - past_key_values: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - batch_size, sequence_length = input_ids.shape - - if position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `position_ids` when passing `past_key_values`.") - - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - if attention_mask is None: - attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be changed by FlaxMistralAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - not train, - False, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - return outputs - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaLayerCollection with Llama->Mistral -class FlaxMistralLayerCollection(nn.Module): - config: MistralConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.blocks = [ - FlaxMistralDecoderLayer(self.config, dtype=self.dtype, name=str(i)) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = False, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for block in self.blocks: - if output_hidden_states: - all_hidden_states += (hidden_states,) - layer_outputs = block( - hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - # this contains possible `None` values - `FlaxMistralModule` will filter them out - outputs = (hidden_states, all_hidden_states, all_attentions) - - return outputs - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaModule with Llama->Mistral -class FlaxMistralModule(nn.Module): - config: MistralConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.hidden_size = self.config.hidden_size - embedding_init = jax.nn.initializers.normal(stddev=self.config.initializer_range) - self.embed_tokens = nn.Embed( - self.config.vocab_size, - self.hidden_size, - embedding_init=embedding_init, - dtype=self.dtype, - ) - self.layers = FlaxMistralLayerCollection(self.config, dtype=self.dtype) - self.norm = FlaxMistralRMSNorm(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - deterministic=True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - input_embeds = self.embed_tokens(input_ids.astype("i4")) - - outputs = self.layers( - input_embeds, - position_ids=position_ids, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.norm(hidden_states) - - if output_hidden_states: - all_hidden_states = outputs[1] + (hidden_states,) - outputs = (hidden_states, all_hidden_states) + outputs[2:] - else: - outputs = (hidden_states,) + outputs[1:] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=outputs[1], - attentions=outputs[-1], - ) - - -@add_start_docstrings( - "The bare Mistral Model transformer outputting raw hidden-states without any specific head on top.", - MISTRAL_START_DOCSTRING, -) -class FlaxMistralModel(FlaxMistralPreTrainedModel): - module_class = FlaxMistralModule - - -append_call_sample_docstring( - FlaxMistralModel, - _CHECKPOINT_FOR_DOC, - FlaxBaseModelOutputWithPast, - _CONFIG_FOR_DOC, - real_checkpoint=_REAL_CHECKPOINT_FOR_DOC, -) - - -# Copied from transformers.models.llama.modeling_flax_llama.FlaxLlamaForCausalLMModule with Llama->Mistral -class FlaxMistralForCausalLMModule(nn.Module): - config: MistralConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.model = FlaxMistralModule(self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - - def __call__( - self, - input_ids, - attention_mask=None, - position_ids=None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - outputs = self.model( - input_ids, - position_ids=position_ids, - attention_mask=attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - return (lm_logits,) + outputs[1:] - - return FlaxCausalLMOutput(logits=lm_logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions) - - -@add_start_docstrings( - """ - The Mistral Model transformer with a language modeling head (linear layer) on top. - """, - MISTRAL_START_DOCSTRING, -) - -# Copied from transformers.models.gptj.modeling_flax_gptj.FlaxGPTJForCausalLM with GPTJ->Mistral -class FlaxMistralForCausalLM(FlaxMistralPreTrainedModel): - module_class = FlaxMistralForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since Mistral uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxMistralForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutputWithCrossAttentions, - _CONFIG_FOR_DOC, - real_checkpoint=_REAL_CHECKPOINT_FOR_DOC, -) - -__all__ = ["FlaxMistralForCausalLM", "FlaxMistralModel", "FlaxMistralPreTrainedModel"] diff --git a/src/transformers/models/mistral/modeling_tf_mistral.py b/src/transformers/models/mistral/modeling_tf_mistral.py deleted file mode 100644 index d3ca7d13b6a8..000000000000 --- a/src/transformers/models/mistral/modeling_tf_mistral.py +++ /dev/null @@ -1,1016 +0,0 @@ -# coding=utf-8 -# Copyright 2024 Mistral AI and the HuggingFace Inc. team. All rights reserved. -# -# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX -# and OPT implementations in this library. It has been modified from its -# original forms to accommodate minor architectural differences compared -# to GPT-NeoX and OPT used by the Meta AI team that trained the model. -# -# 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. -"""TF 2.0 Mistral model.""" - -import math -import warnings -from typing import Optional, Union - -import tensorflow as tf - -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPast, - TFCausalLMOutputWithPast, - TFSequenceClassifierOutputWithPast, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - get_tf_activation, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_mistral import MistralConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "MistralConfig" - - -def _make_causal_mask(input_ids_shape, dtype, past_key_values_length=0): - """ - Make causal mask used for bi-directional self-attention, supporting both static and dynamic shapes. - """ - bsz, tgt_len = input_ids_shape - - # Create a matrix where only the lower triangle and diagonal are filled with zeros (causal mask) - mask = tf.fill((tgt_len, tgt_len), tf.dtypes.as_dtype(dtype).min) - mask_cond = tf.range(tgt_len) - mask = tf.where(mask_cond[:, None] >= mask_cond[None, :], 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length), dtype=dtype), mask], axis=-1) - - if bsz is None: - # When batch size is dynamic, expand and tile - # so we can compile a functional model - mask = tf.expand_dims(mask, 0) - mask = tf.expand_dims(mask, 0) # shape: (1, 1, tgt_len, tgt_len + past_key_values_length) - mask = tf.tile(mask, [bsz, 1, 1, 1]) - else: - # When batch size is static, directly use broadcast_to - mask = tf.broadcast_to(mask[None, None, :, :], (bsz, 1, tgt_len, tgt_len + past_key_values_length)) - - return mask - - -def _expand_mask(mask, dtype, tgt_len=None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - bsz, src_len = shape_list(mask) - tgt_len = tgt_len if tgt_len is not None else src_len - - expanded_mask = tf.expand_dims(tf.expand_dims(mask, 1), 1) - expanded_mask = tf.broadcast_to(expanded_mask, [bsz, 1, tgt_len, src_len]) - - inverted_mask = 1.0 - tf.cast(expanded_mask, dtype) - - return tf.where( - tf.cast(inverted_mask, bool), tf.fill(dims=shape_list(inverted_mask), value=tf.float32.min), inverted_mask - ) - - -class TFMistralRMSNorm(keras.layers.Layer): - def __init__(self, hidden_size, eps=1e-6, **kwargs): - """ - TFMistralRMSNorm is equivalent to T5LayerNorm - """ - super().__init__(**kwargs) - self.hidden_size = hidden_size - self.variance_epsilon = eps - - def build(self, input_shape=None): - self.weight = self.add_weight( - name="weight", - shape=self.hidden_size, - initializer="ones", - ) - if self.built: - return - self.built = True - - def call(self, hidden_states): - input_dtype = hidden_states.dtype - hidden_states = tf.cast(hidden_states, tf.float32) - variance = tf.reduce_mean(tf.square(hidden_states), axis=-1, keepdims=True) - hidden_states = tf.divide(hidden_states, tf.sqrt(variance + self.variance_epsilon)) - return self.weight * tf.cast(hidden_states, input_dtype) - - -# Verification: https://colab.research.google.com/gist/ariG23498/f8d8131b795a131b93d99e70ee93c192/scratchpad.ipynb -class TFMistralRotaryEmbedding(keras.layers.Layer): - def __init__(self, dim, max_position_embeddings=2048, base=10000, **kwargs): - super().__init__(**kwargs) - self.dim = dim - self.max_position_embeddings = max_position_embeddings - self.base = base - self.inv_freq = 1.0 / (self.base ** (tf.range(start=0, limit=self.dim, delta=2, dtype=tf.float32) / self.dim)) - - def call(self, x, seq_len=None): - # x: [bs, num_attention_heads, seq_len, head_size] - t = tf.cast(tf.range(seq_len, dtype=tf.int64), self.inv_freq.dtype) - freqs = tf.einsum("i,j->ij", t, self.inv_freq) - emb = tf.concat([freqs, freqs], axis=-1) - cos_values = tf.cast(tf.cos(emb), x.dtype) - sin_values = tf.cast(tf.sin(emb), x.dtype) - - cos_values = cos_values[:seq_len] - cos_values = tf.cast(cos_values, dtype=x.dtype) - sin_values = sin_values[:seq_len] - sin_values = tf.cast(sin_values, dtype=x.dtype) - return (cos_values, sin_values) - - -def rotate_half(x): - """Rotates half the hidden dims of the input.""" - mid_length = shape_list(x)[-1] // 2 - x1 = x[..., :mid_length] - x2 = x[..., mid_length:] - return tf.concat([-x2, x1], axis=-1) - - -# Verification: https://colab.research.google.com/gist/ariG23498/bb8474baeb33f4ae6ed7d77da5f7e7a4/scratchpad.ipynb -def apply_rotary_pos_emb(q, k, cos, sin, position_ids, unsqueeze_dim=1): - """Applies Rotary Position Embedding to the query and key tensors. - - Args: - q (`tf.Tensor`): The query tensor. - k (`tf.Tensor`): The key tensor. - cos (`tf.Tensor`): The cosine part of the rotary embedding. - sin (`tf.Tensor`): The sine part of the rotary embedding. - position_ids (`tf.Tensor`): - The position indices of the tokens corresponding to the query and key tensors. For example, this can be - used to pass offsetted position ids when working with a KV-cache. - unsqueeze_dim (`int`, *optional*, defaults to 1): - The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and - sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note - that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and - k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes - cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have - the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. - Returns: - `tuple(tf.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. - """ - cos = tf.expand_dims(tf.gather(cos, position_ids), unsqueeze_dim) - sin = tf.expand_dims(tf.gather(sin, position_ids), unsqueeze_dim) - q_embed = (q * cos) + (rotate_half(q) * sin) - k_embed = (k * cos) + (rotate_half(k) * sin) - return q_embed, k_embed - - -class TFMistralMLP(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.hidden_size = config.hidden_size - self.intermediate_size = config.intermediate_size - self.gate_proj = keras.layers.Dense(self.intermediate_size, use_bias=False, name="gate_proj") - self.up_proj = keras.layers.Dense(self.intermediate_size, use_bias=False, name="up_proj") - self.down_proj = keras.layers.Dense(self.hidden_size, use_bias=False, name="down_proj") - self.act_fn = get_tf_activation(config.hidden_act) - - def call(self, x): - return self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "gate_proj", None) is not None: - with tf.name_scope(self.gate_proj.name): - self.gate_proj.build((self.hidden_size,)) - if getattr(self, "up_proj", None) is not None: - with tf.name_scope(self.up_proj.name): - self.up_proj.build((self.hidden_size,)) - if getattr(self, "down_proj", None) is not None: - with tf.name_scope(self.down_proj.name): - self.down_proj.build((self.intermediate_size,)) - - -# Verification: https://colab.research.google.com/gist/ariG23498/556d443d491966763ce2e7eee336efed/scratchpad.ipynb -def repeat_kv(hidden_states: tf.Tensor, n_rep: int) -> tf.Tensor: - """ - This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, - num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim) - """ - batch, num_key_value_heads, slen, head_dim = shape_list(hidden_states) - if n_rep == 1: - return hidden_states - hidden_states = tf.expand_dims(hidden_states, 2) - hidden_states = tf.repeat(hidden_states, repeats=n_rep, axis=2) - return tf.reshape(hidden_states, (batch, num_key_value_heads * n_rep, slen, head_dim)) - - -class TFMistralAttention(keras.layers.Layer): - """ - Multi-headed attention from 'Attention Is All You Need' paper. Modified to use sliding window attention: Longformer - and "Generating Long Sequences with Sparse Transformers". - """ - - def __init__(self, config: MistralConfig, layer_idx: Optional[int] = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layer_idx = layer_idx - if layer_idx is None: - logger.warning_once( - f"Instantiating {self.__class__.__name__} without passing a `layer_idx` is not recommended and will " - "lead to errors during the forward call if caching is used. Please make sure to provide a `layer_idx` " - "when creating this class." - ) - - self.hidden_size = config.hidden_size - self.num_heads = config.num_attention_heads - self.head_dim = self.hidden_size // self.num_heads - self.num_key_value_heads = config.num_key_value_heads - self.num_key_value_groups = self.num_heads // self.num_key_value_heads - self.max_position_embeddings = config.max_position_embeddings - self.rope_theta = config.rope_theta - self.is_causal = True - self.attention_dropout = config.attention_dropout - - if (self.head_dim * self.num_heads) != self.hidden_size: - raise ValueError( - f"hidden_size must be divisible by num_heads (got `hidden_size`: {self.hidden_size}" - f" and `num_heads`: {self.num_heads})." - ) - self.q_proj = keras.layers.Dense(self.num_heads * self.head_dim, use_bias=False, name="q_proj") - self.k_proj = keras.layers.Dense(self.num_key_value_heads * self.head_dim, use_bias=False, name="k_proj") - self.v_proj = keras.layers.Dense(self.num_key_value_heads * self.head_dim, use_bias=False, name="v_proj") - self.o_proj = keras.layers.Dense(self.hidden_size, use_bias=False, name="o_proj") - - self.rotary_emb = TFMistralRotaryEmbedding( - self.head_dim, - max_position_embeddings=self.max_position_embeddings, - base=self.rope_theta, - name="rotary_emb", - ) - self.dropout = keras.layers.Dropout(rate=self.attention_dropout) - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - tensor = tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)) - tensor = tf.transpose(tensor, perm=(0, 2, 1, 3)) - return tensor - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: Optional[tf.Tensor] = None, - position_ids: Optional[tf.Tensor] = None, - past_key_value: Optional[tuple[tf.Tensor]] = None, - output_attentions: Optional[bool] = False, - use_cache: Optional[bool] = False, - training=None, - **kwargs, - ) -> tuple[tf.Tensor, Optional[tf.Tensor], Optional[tuple[tf.Tensor]]]: - if "padding_mask" in kwargs: - warnings.warn( - "Passing `padding_mask` is deprecated and will be removed in v4.37. Please make sure use `attention_mask` instead.`" - ) - bsz, q_len, _ = shape_list(hidden_states) - - query_states = self.q_proj(hidden_states) - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = tf.transpose( - tf.reshape(query_states, (bsz, q_len, self.num_heads, self.head_dim)), perm=(0, 2, 1, 3) - ) - key_states = tf.transpose( - tf.reshape(key_states, (bsz, q_len, self.num_key_value_heads, self.head_dim)), perm=(0, 2, 1, 3) - ) - value_states = tf.transpose( - tf.reshape(value_states, (bsz, q_len, self.num_key_value_heads, self.head_dim)), perm=(0, 2, 1, 3) - ) - - kv_seq_len = shape_list(key_states)[-2] - if past_key_value is not None: - kv_seq_len += past_key_value[0].shape[-2] - cos, sin = self.rotary_emb( - x=value_states, - seq_len=kv_seq_len, - ) - query_states, key_states = apply_rotary_pos_emb( - q=query_states, - k=key_states, - cos=cos, - sin=sin, - position_ids=position_ids, - ) - - if past_key_value is not None: - # reuse k, v, self_attention - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - - past_key_value = (key_states, value_states) if use_cache else None - - # repeat k/v heads if n_kv_heads < n_heads - key_states = repeat_kv(key_states, self.num_key_value_groups) - value_states = repeat_kv(value_states, self.num_key_value_groups) - - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) / math.sqrt(self.head_dim) - - if attention_mask is not None: - attn_weights = attn_weights + attention_mask - - # upcast attention to fp32 - attn_weights = stable_softmax(attn_weights, axis=-1) - attn_weights = tf.cast(attn_weights, query_states.dtype) - attn_weights = self.dropout( - attn_weights, - training=training, - ) - attn_output = tf.matmul(attn_weights, value_states) - - attn_output = tf.transpose(attn_output, perm=(0, 2, 1, 3)) - attn_output = tf.reshape(attn_output, (bsz, q_len, self.hidden_size)) - - attn_output = self.o_proj(attn_output) - - if not output_attentions: - attn_weights = None - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build((self.hidden_size,)) - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build((self.hidden_size,)) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build((self.hidden_size,)) - if getattr(self, "o_proj", None) is not None: - with tf.name_scope(self.o_proj.name): - self.o_proj.build((self.num_heads * self.head_dim,)) - - -class TFMistralDecoderLayer(keras.layers.Layer): - def __init__(self, config: MistralConfig, layer_idx: int, **kwargs): - super().__init__(**kwargs) - self.hidden_size = config.hidden_size - - self.self_attn = TFMistralAttention(config, layer_idx, name="self_attn") - - self.mlp = TFMistralMLP(config, name="mlp") - self.input_layernorm = TFMistralRMSNorm(config.hidden_size, eps=config.rms_norm_eps, name="input_layernorm") - self.post_attention_layernorm = TFMistralRMSNorm( - config.hidden_size, eps=config.rms_norm_eps, name="post_attention_layernorm" - ) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: Optional[tf.Tensor] = None, - position_ids: Optional[tf.Tensor] = None, - past_key_value: Optional[tuple[tf.Tensor]] = None, - output_attentions: Optional[bool] = False, - use_cache: Optional[bool] = False, - **kwargs, - ) -> tuple[tf.Tensor, Optional[tuple[tf.Tensor, tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`, *optional*): attention mask of size - `(batch, sequence_length)` where padding elements are indicated by 0. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding - (see `past_key_values`). - past_key_value (`Tuple(tf.Tensor)`, *optional*): cached past key and value projection states - """ - if "padding_mask" in kwargs: - warnings.warn( - "Passing `padding_mask` is deprecated and will be removed in v4.37. Please make sure use `attention_mask` instead.`" - ) - - residual = hidden_states - - hidden_states = self.input_layernorm(hidden_states) - - # Self Attention - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - past_key_value=past_key_value, - output_attentions=output_attentions, - use_cache=use_cache, - ) - hidden_states = residual + hidden_states - - # Fully Connected - residual = hidden_states - hidden_states = self.post_attention_layernorm(hidden_states) - hidden_states = self.mlp(hidden_states) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights,) - - if use_cache: - outputs += (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "input_layernorm", None) is not None: - with tf.name_scope(self.input_layernorm.name): - self.input_layernorm.build(None) - if getattr(self, "post_attention_layernorm", None) is not None: - with tf.name_scope(self.post_attention_layernorm.name): - self.post_attention_layernorm.build(None) - - -@keras_serializable -class TFMistralMainLayer(keras.layers.Layer): - """ - Transformer decoder consisting of *config.num_hidden_layers* layers. Each layer is a [`MistralDecoderLayer`] - - Args: - config: MistralConfig - """ - - config_class = MistralConfig - - def __init__(self, config: MistralConfig, **kwargs): - super().__init__(**kwargs) - self.padding_idx = config.pad_token_id - self.vocab_size = config.vocab_size - self.hidden_size = config.hidden_size - - # TF and PT Embedding check: https://colab.research.google.com/gist/ariG23498/2b9826818875c9c4968c79cb19f55f2c/scratchpad.ipynb - self.embed_tokens = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.hidden_size, - name="embed_tokens", - ) - self.layers = [ - TFMistralDecoderLayer(config, layer_idx, name=f"layers.{layer_idx}") - for layer_idx in range(config.num_hidden_layers) - ] - self._attn_implementation = config._attn_implementation - self.norm = TFMistralRMSNorm(config.hidden_size, eps=config.rms_norm_eps, name="norm") - self.config = config - - def _prepare_decoder_attention_mask(self, attention_mask, input_shape, inputs_embeds, past_key_values_length): - # create causal mask - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - combined_attention_mask = None - # if input_shape[-1] > 1: - combined_attention_mask = _make_causal_mask( - input_shape, - inputs_embeds.dtype, - past_key_values_length=past_key_values_length, - ) - - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - expanded_attn_mask = _expand_mask(attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1]) - combined_attention_mask = ( - expanded_attn_mask if combined_attention_mask is None else expanded_attn_mask + combined_attention_mask - ) - - return combined_attention_mask - - @unpack_inputs - def call( - self, - input_ids: Optional[tf.Tensor] = None, - attention_mask: Optional[tf.Tensor] = None, - position_ids: Optional[tf.Tensor] = None, - past_key_values: Optional[list[tf.Tensor]] = None, - inputs_embeds: Optional[tf.Tensor] = None, - use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ) -> Union[tuple, TFBaseModelOutputWithPast]: - # retrieve input_ids and inputs_embeds - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - batch_size, seq_length = shape_list(input_ids) - elif inputs_embeds is not None: - batch_size, seq_length, _ = shape_list(inputs_embeds) - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - seq_length_with_past = seq_length - past_key_values_length = 0 - - if past_key_values is not None: - past_key_values_length = shape_list(past_key_values[0][0])[2] - seq_length_with_past = seq_length_with_past + past_key_values_length - - if position_ids is None: - position_ids = tf.range( - start=past_key_values_length, limit=seq_length + past_key_values_length, dtype=tf.int64 - ) - position_ids = tf.reshape(tf.expand_dims(position_ids, 0), (-1, seq_length)) - - else: - position_ids = tf.cast(tf.reshape(position_ids, (-1, seq_length)), tf.int64) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = self.embed_tokens(input_ids) - - if attention_mask is None: - attention_mask = tf.ones((batch_size, seq_length_with_past), dtype=tf.bool) - attention_mask = self._prepare_decoder_attention_mask( - attention_mask, (batch_size, seq_length), inputs_embeds, past_key_values_length - ) - - hidden_states = inputs_embeds - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - next_decoder_cache = () if use_cache else None - - for idx, decoder_layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - layer_outputs = decoder_layer( - hidden_states, - attention_mask=attention_mask, - position_ids=position_ids, - past_key_value=past_key_value, - output_attentions=output_attentions, - use_cache=use_cache, - ) - - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[2 if output_attentions else 1],) - - if output_attentions: - all_self_attns += (layer_outputs[1],) - - hidden_states = self.norm(hidden_states) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - next_cache = next_decoder_cache if use_cache else None - if not return_dict: - return tuple(v for v in [hidden_states, next_cache, all_hidden_states, all_self_attns] if v is not None) - return TFBaseModelOutputWithPast( - last_hidden_state=hidden_states, - past_key_values=next_cache, - hidden_states=all_hidden_states, - attentions=all_self_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_tokens", None) is not None: - with tf.name_scope(self.embed_tokens.name): - self.embed_tokens.build(None) - if getattr(self, "norm", None) is not None: - with tf.name_scope(self.norm.name): - self.norm.build(None) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -MISTRAL_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `model` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`MistralConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - - -@add_start_docstrings( - "The bare Mistral Model outputting raw hidden-states without any specific head on top.", - MISTRAL_START_DOCSTRING, -) -class TFMistralPreTrainedModel(TFPreTrainedModel): - config_class = MistralConfig - base_model_prefix = "model" - - -MISTRAL_INPUTS_DOCSTRING = r""" - Args: - input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - If you want to change padding behavior, you should read [`modeling_opt._prepare_decoder_attention_mask`] - and modify to your needs. See diagram 1 in [the paper](https://huggingface.co/papers/1910.13461) for more - information on the default strategy. - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.n_positions - 1]`. - - [What are position IDs?](../glossary#position-ids) - past_key_values (`Cache` or `tuple(tuple(tf.Tensor))`, *optional*): - Pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention - blocks) that can be used to speed up sequential decoding. This typically consists in the `past_key_values` - returned by the model at a previous stage of decoding, when `use_cache=True` or `config.use_cache=True`. - - One formats is allowed: - - Tuple of `tuple(tf.Tensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`). This is also known as the legacy - cache format. - - The model will output the same cache format that is fed as input. If no `past_key_values` are passed, the - legacy cache format will be returned. - - If `past_key_values` are used, the user can optionally input only the last `input_ids` (those that don't - have their past key value states given to this model) of shape `(batch_size, 1)` instead of all `input_ids` - of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@add_start_docstrings( - "The bare Mistral Model outputting raw hidden-states without any specific head on top.", - MISTRAL_START_DOCSTRING, -) -class TFMistralModel(TFMistralPreTrainedModel): - def __init__(self, config: MistralConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.model = TFMistralMainLayer(config, name="model") - - @unpack_inputs - @add_start_docstrings_to_model_forward(MISTRAL_INPUTS_DOCSTRING) - def call( - self, - input_ids: Optional[tf.Tensor] = None, - attention_mask: Optional[tf.Tensor] = None, - position_ids: Optional[tf.Tensor] = None, - past_key_values: Optional[list[tf.Tensor]] = None, - inputs_embeds: Optional[tf.Tensor] = None, - use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ) -> Union[tuple, TFBaseModelOutputWithPast]: - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -class TFMistralForCausalLM(TFMistralPreTrainedModel, TFCausalLanguageModelingLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.model = TFMistralMainLayer(config, name="model") - self.vocab_size = config.vocab_size - self.lm_head = keras.layers.Dense( - config.vocab_size, - use_bias=False, - kernel_initializer=get_initializer(config.initializer_range), - name="lm_head", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(MISTRAL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def call( - self, - input_ids: Optional[tf.Tensor] = None, - attention_mask: Optional[tf.Tensor] = None, - position_ids: Optional[tf.Tensor] = None, - past_key_values: Optional[list[tf.Tensor]] = None, - inputs_embeds: Optional[tf.Tensor] = None, - labels: Optional[tf.Tensor] = None, - use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ) -> Union[tuple, TFCausalLMOutputWithPast]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., config.vocab_size]` - or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - """ - - # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn) - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - logits = self.lm_head(hidden_states) - logits = tf.cast(logits, tf.float32) - - loss = None - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels, shifted_logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithPast( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def prepare_inputs_for_generation( - self, input_ids, past_key_values=None, attention_mask=None, inputs_embeds=None, **kwargs - ): - # Omit tokens covered by past_key_values - if past_key_values: - input_ids = tf.expand_dims(input_ids[:, -1], -1) - - position_ids = kwargs.get("position_ids") - if attention_mask is not None and position_ids is None: - position_ids = tf.math.cumsum(attention_mask, axis=-1, exclusive=True) - if past_key_values: - position_ids = tf.expand_dims(position_ids[:, -1], -1) - - return { - "input_ids": input_ids, - "attention_mask": attention_mask, - "position_ids": position_ids, - "past_key_values": past_key_values, - "use_cache": kwargs.get("use_cache"), - } - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build((self.config.hidden_size,)) - - -@add_start_docstrings( - """ - The Mistral Model transformer with a sequence classification head on top (linear layer). - - [`MistralForSequenceClassification`] uses the last token in order to do the classification, as other causal models - (e.g. GPT-2) do. - - Since it does classification on the last token, it requires to know the position of the last token. If a - `pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If - no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the - padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in - each row of the batch). - """, - MISTRAL_START_DOCSTRING, -) -class TFMistralForSequenceClassification(TFMistralPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.model = TFMistralMainLayer(config, name="model") - self.score = keras.layers.Dense( - self.num_labels, - use_bias=False, - kernel_initializer=get_initializer(config.initializer_range), - name="score", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(MISTRAL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def call( - self, - input_ids: Optional[tf.Tensor] = None, - attention_mask: Optional[tf.Tensor] = None, - position_ids: Optional[tf.Tensor] = None, - past_key_values: Optional[list[tf.Tensor]] = None, - inputs_embeds: Optional[tf.Tensor] = None, - labels: Optional[tf.Tensor] = None, - use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ) -> Union[tuple, TFSequenceClassifierOutputWithPast]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., - config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - """ - - transformer_outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = transformer_outputs[0] - logits = self.score(hidden_states) - logits_shape = shape_list(logits) - batch_size = logits_shape[0] - - if self.config.pad_token_id is None: - last_non_pad_token = tf.fill((batch_size,), value=logits_shape[1] - 1) - else: - if input_ids is not None: - token_indices = tf.range(shape_list(input_ids)[-1]) - non_pad_mask = tf.cast(input_ids != self.config.pad_token_id, token_indices.dtype) - last_non_pad_token = tf.reduce_max(token_indices * non_pad_mask, axis=-1) - else: - last_non_pad_token = tf.fill((batch_size,), value=logits_shape[1] - 1) - logger.warning_once( - f"{self.__class__.__name__} will not detect padding tokens in `inputs_embeds`. Results may be " - "unexpected if using padding tokens in conjunction with `inputs_embeds.`" - ) - loss = None - - pooled_logits = tf.gather(logits, last_non_pad_token, batch_dims=1, axis=1) - - if labels is not None: - if self.config.pad_token_id is None and logits_shape[0] != 1: - raise ValueError("Cannot handle batch sizes > 1 if no padding token is defined.") - - loss = self.hf_compute_loss(tf.reshape(labels, [-1]), tf.reshape(pooled_logits, [-1, self.num_labels])) - - if not return_dict: - output = (pooled_logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutputWithPast( - loss=loss, - logits=pooled_logits, - past_key_values=transformer_outputs.past_key_values, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "score", None) is not None: - with tf.name_scope(self.score.name): - self.score.build((self.config.hidden_size,)) - - -__all__ = ["TFMistralModel", "TFMistralForCausalLM", "TFMistralForSequenceClassification", "TFMistralPreTrainedModel"] diff --git a/src/transformers/models/mllama/image_processing_mllama.py b/src/transformers/models/mllama/image_processing_mllama.py index ba1a596aa459..a331e6d5319d 100644 --- a/src/transformers/models/mllama/image_processing_mllama.py +++ b/src/transformers/models/mllama/image_processing_mllama.py @@ -655,10 +655,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. Returns: `BatchFeature` of the following structure: diff --git a/src/transformers/models/mllama/processing_mllama.py b/src/transformers/models/mllama/processing_mllama.py index 0dae7c834303..a5a0ae8739b3 100644 --- a/src/transformers/models/mllama/processing_mllama.py +++ b/src/transformers/models/mllama/processing_mllama.py @@ -246,10 +246,8 @@ def __call__( `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/mluke/tokenization_mluke.py b/src/transformers/models/mluke/tokenization_mluke.py index 15f4db53287a..d63129c7b7e4 100644 --- a/src/transformers/models/mluke/tokenization_mluke.py +++ b/src/transformers/models/mluke/tokenization_mluke.py @@ -37,7 +37,7 @@ TruncationStrategy, to_py_obj, ) -from ...utils import add_end_docstrings, is_tf_tensor, is_torch_tensor, logging +from ...utils import add_end_docstrings, is_torch_tensor, logging from ...utils.import_utils import requires @@ -1241,7 +1241,7 @@ def pad( Pad a single encoded input or a batch of encoded inputs up to predefined length or to the max sequence length in the batch. Padding side (left/right) padding token ids are defined at the tokenizer level (with `self.padding_side`, `self.pad_token_id` and `self.pad_token_type_id`) .. note:: If the `encoded_inputs` passed - are dictionary of numpy arrays, PyTorch tensors or TensorFlow tensors, the result will use the same type unless + are dictionary of numpy arrays or PyTorch tensors the result will use the same type unless you provide a different tensor type with `return_tensors`. In the case of PyTorch tensors, you will lose the specific device of your tensors however. @@ -1250,8 +1250,8 @@ def pad( Tokenized inputs. Can represent one input ([`BatchEncoding`] or `dict[str, list[int]]`) or a batch of tokenized inputs (list of [`BatchEncoding`], *dict[str, list[list[int]]]* or *list[dict[str, list[int]]]*) so you can use this method during preprocessing as well as in a PyTorch Dataloader - collate function. Instead of `list[int]` you can have tensors (numpy arrays, PyTorch tensors or - TensorFlow tensors), see the note above for the return type. + collate function. Instead of `list[int]` you can have tensors (numpy arrays, or PyTorch tensors), + see the note above for the return type. padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `True`): Select a strategy to pad the returned sequences (according to the model's padding side and padding index) among: @@ -1279,7 +1279,6 @@ def pad( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. verbose (`bool`, *optional*, defaults to `True`): @@ -1304,7 +1303,7 @@ def pad( encoded_inputs["attention_mask"] = [] return encoded_inputs - # If we have PyTorch/TF/NumPy tensors/arrays as inputs, we cast them as python objects + # If we have PyTorch/NumPy tensors/arrays as inputs, we cast them as python objects # and rebuild them afterwards if no return_tensors is specified # Note that we lose the specific device the tensor may be on for PyTorch @@ -1318,16 +1317,14 @@ def pad( first_element = required_input[index][0] # At this state, if `first_element` is still a list/tuple, it's an empty one so there is nothing to do. if not isinstance(first_element, (int, list, tuple)): - if is_tf_tensor(first_element): - return_tensors = "tf" if return_tensors is None else return_tensors - elif is_torch_tensor(first_element): + if is_torch_tensor(first_element): return_tensors = "pt" if return_tensors is None else return_tensors elif isinstance(first_element, np.ndarray): return_tensors = "np" if return_tensors is None else return_tensors else: raise ValueError( f"type of {first_element} unknown: {type(first_element)}. " - "Should be one of a python, numpy, pytorch or tensorflow object." + "Should be one of a python, numpy, or pytorch object." ) for key, value in encoded_inputs.items(): diff --git a/src/transformers/models/mm_grounding_dino/modeling_mm_grounding_dino.py b/src/transformers/models/mm_grounding_dino/modeling_mm_grounding_dino.py index c3d498323de4..b27d6ac42a3a 100644 --- a/src/transformers/models/mm_grounding_dino/modeling_mm_grounding_dino.py +++ b/src/transformers/models/mm_grounding_dino/modeling_mm_grounding_dino.py @@ -411,11 +411,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -555,8 +550,6 @@ def _init_weights(self, module): module.vision_param.data.fill_(1e-4) module.text_param.data.fill_(1e-4) elif isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/mobilebert/__init__.py b/src/transformers/models/mobilebert/__init__.py index 4ea599122ddc..0066f7f2b382 100644 --- a/src/transformers/models/mobilebert/__init__.py +++ b/src/transformers/models/mobilebert/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_mobilebert import * from .modeling_mobilebert import * - from .modeling_tf_mobilebert import * from .tokenization_mobilebert import * from .tokenization_mobilebert_fast import * else: diff --git a/src/transformers/models/mobilebert/convert_mobilebert_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/mobilebert/convert_mobilebert_original_tf_checkpoint_to_pytorch.py index 022a9d036cdb..53288953d81e 100644 --- a/src/transformers/models/mobilebert/convert_mobilebert_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/mobilebert/convert_mobilebert_original_tf_checkpoint_to_pytorch.py @@ -13,14 +13,94 @@ # limitations under the License. import argparse +import os import torch -from transformers import MobileBertConfig, MobileBertForPreTraining, load_tf_weights_in_mobilebert +from transformers import MobileBertConfig, MobileBertForPreTraining from transformers.utils import logging logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def load_tf_weights_in_mobilebert(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array) + + for name, array in zip(names, arrays): + name = name.replace("ffn_layer", "ffn") + name = name.replace("FakeLayerNorm", "LayerNorm") + name = name.replace("extra_output_weights", "dense/kernel") + name = name.replace("bert", "mobilebert") + name = name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any( + n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + continue + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "kernel" or scope_names[0] == "gamma": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + else: + try: + pointer = getattr(pointer, scope_names[0]) + except AttributeError: + logger.info(f"Skipping {'/'.join(name)}") + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if m_name[-11:] == "_embeddings": + pointer = getattr(pointer, "weight") + elif m_name == "kernel": + array = np.transpose(array) + try: + assert pointer.shape == array.shape, ( + f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched" + ) + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + return model def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, mobilebert_config_file, pytorch_dump_path): diff --git a/src/transformers/models/mobilebert/modeling_mobilebert.py b/src/transformers/models/mobilebert/modeling_mobilebert.py index 99768685002a..1d6c5f7c46f4 100644 --- a/src/transformers/models/mobilebert/modeling_mobilebert.py +++ b/src/transformers/models/mobilebert/modeling_mobilebert.py @@ -21,7 +21,6 @@ # SOFTWARE. import math -import os import warnings from dataclasses import dataclass from typing import Optional, Union @@ -50,84 +49,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_mobilebert(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.replace("ffn_layer", "ffn") - name = name.replace("FakeLayerNorm", "LayerNorm") - name = name.replace("extra_output_weights", "dense/kernel") - name = name.replace("bert", "mobilebert") - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - assert pointer.shape == array.shape, ( - f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched" - ) - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class NoNorm(nn.Module): def __init__(self, feat_size, eps=None): super().__init__() @@ -659,14 +580,11 @@ def forward(self, sequence_output: torch.Tensor, pooled_output: torch.Tensor) -> @auto_docstring class MobileBertPreTrainedModel(PreTrainedModel): config: MobileBertConfig - load_tf_weights = load_tf_weights_in_mobilebert base_model_prefix = "mobilebert" def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1478,5 +1396,4 @@ def forward( "MobileBertLayer", "MobileBertModel", "MobileBertPreTrainedModel", - "load_tf_weights_in_mobilebert", ] diff --git a/src/transformers/models/mobilebert/modeling_tf_mobilebert.py b/src/transformers/models/mobilebert/modeling_tf_mobilebert.py deleted file mode 100644 index e4d148aa76c5..000000000000 --- a/src/transformers/models/mobilebert/modeling_tf_mobilebert.py +++ /dev/null @@ -1,1979 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 MobileBERT model.""" - -from __future__ import annotations - -import warnings -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPooling, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFNextSentencePredictorOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFNextSentencePredictionLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_mobilebert import MobileBertConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "google/mobilebert-uncased" -_CONFIG_FOR_DOC = "MobileBertConfig" - -# TokenClassification docstring -_CHECKPOINT_FOR_TOKEN_CLASSIFICATION = "vumichien/mobilebert-finetuned-ner" -_TOKEN_CLASS_EXPECTED_OUTPUT = "['I-ORG', 'I-ORG', 'O', 'O', 'O', 'O', 'O', 'I-LOC', 'O', 'I-LOC', 'I-LOC']" -_TOKEN_CLASS_EXPECTED_LOSS = 0.03 - -# QuestionAnswering docstring -_CHECKPOINT_FOR_QA = "vumichien/mobilebert-uncased-squad-v2" -_QA_EXPECTED_OUTPUT = "'a nice puppet'" -_QA_EXPECTED_LOSS = 3.98 -_QA_TARGET_START_INDEX = 12 -_QA_TARGET_END_INDEX = 13 - -# SequenceClassification docstring -_CHECKPOINT_FOR_SEQUENCE_CLASSIFICATION = "vumichien/emo-mobilebert" -_SEQ_CLASS_EXPECTED_OUTPUT = "'others'" -_SEQ_CLASS_EXPECTED_LOSS = "4.72" - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPreTrainingLoss -class TFMobileBertPreTrainingLoss: - """ - Loss function suitable for BERT-like pretraining, that is, the task of pretraining a language model by combining - NSP + MLM. .. note:: Any label of -100 will be ignored (along with the corresponding logits) in the loss - computation. - """ - - def hf_compute_loss(self, labels: tf.Tensor, logits: tf.Tensor) -> tf.Tensor: - loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=keras.losses.Reduction.NONE) - - # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway - unmasked_lm_losses = loss_fn(y_true=tf.nn.relu(labels["labels"]), y_pred=logits[0]) - # make sure only labels that are not equal to -100 - # are taken into account for the loss computation - lm_loss_mask = tf.cast(labels["labels"] != -100, dtype=unmasked_lm_losses.dtype) - masked_lm_losses = unmasked_lm_losses * lm_loss_mask - reduced_masked_lm_loss = tf.reduce_sum(masked_lm_losses) / tf.reduce_sum(lm_loss_mask) - - # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway - unmasked_ns_loss = loss_fn(y_true=tf.nn.relu(labels["next_sentence_label"]), y_pred=logits[1]) - ns_loss_mask = tf.cast(labels["next_sentence_label"] != -100, dtype=unmasked_ns_loss.dtype) - masked_ns_loss = unmasked_ns_loss * ns_loss_mask - - reduced_masked_ns_loss = tf.reduce_sum(masked_ns_loss) / tf.reduce_sum(ns_loss_mask) - - return tf.reshape(reduced_masked_lm_loss + reduced_masked_ns_loss, (1,)) - - -class TFMobileBertIntermediate(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense(config.intermediate_size, name="dense") - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.true_hidden_size]) - - -class TFLayerNorm(keras.layers.LayerNormalization): - def __init__(self, feat_size, *args, **kwargs): - self.feat_size = feat_size - super().__init__(*args, **kwargs) - - def build(self, input_shape=None): - super().build([None, None, self.feat_size]) - - -class TFNoNorm(keras.layers.Layer): - def __init__(self, feat_size, epsilon=None, **kwargs): - super().__init__(**kwargs) - self.feat_size = feat_size - - def build(self, input_shape): - self.bias = self.add_weight("bias", shape=[self.feat_size], initializer="zeros") - self.weight = self.add_weight("weight", shape=[self.feat_size], initializer="ones") - super().build(input_shape) - - def call(self, inputs: tf.Tensor): - return inputs * self.weight + self.bias - - -NORM2FN = {"layer_norm": TFLayerNorm, "no_norm": TFNoNorm} - - -class TFMobileBertEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.trigram_input = config.trigram_input - self.embedding_size = config.embedding_size - self.config = config - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.embedding_transformation = keras.layers.Dense(config.hidden_size, name="embedding_transformation") - - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file - self.LayerNorm = NORM2FN[config.normalization_type]( - config.hidden_size, epsilon=config.layer_norm_eps, name="LayerNorm" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.embedded_input_size = self.embedding_size * (3 if self.trigram_input else 1) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.embedding_size], - initializer=get_initializer(initializer_range=self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.hidden_size], - initializer=get_initializer(initializer_range=self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(initializer_range=self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "embedding_transformation", None) is not None: - with tf.name_scope(self.embedding_transformation.name): - self.embedding_transformation.build([None, None, self.embedded_input_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build(None) - - def call(self, input_ids=None, position_ids=None, token_type_ids=None, inputs_embeds=None, training=False): - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if self.trigram_input: - # From the paper MobileBERT: a Compact Task-Agnostic BERT for Resource-Limited - # Devices (https://huggingface.co/papers/2004.02984) - # - # The embedding table in BERT models accounts for a substantial proportion of model size. To compress - # the embedding layer, we reduce the embedding dimension to 128 in MobileBERT. - # Then, we apply a 1D convolution with kernel size 3 on the raw token embedding to produce a 512 - # dimensional output. - inputs_embeds = tf.concat( - [ - tf.pad(inputs_embeds[:, 1:], ((0, 0), (0, 1), (0, 0))), - inputs_embeds, - tf.pad(inputs_embeds[:, :-1], ((0, 0), (1, 0), (0, 0))), - ], - axis=2, - ) - - if self.trigram_input or self.embedding_size != self.hidden_size: - inputs_embeds = self.embedding_transformation(inputs_embeds) - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -class TFMobileBertSelfAttention(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " - f"heads ({config.num_attention_heads}" - ) - - self.num_attention_heads = config.num_attention_heads - self.output_attentions = config.output_attentions - assert config.hidden_size % config.num_attention_heads == 0 - self.attention_head_size = int(config.true_hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - - self.query = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.config = config - - def transpose_for_scores(self, x, batch_size): - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - x = tf.reshape(x, (batch_size, -1, self.num_attention_heads, self.attention_head_size)) - return tf.transpose(x, perm=[0, 2, 1, 3]) - - def call( - self, query_tensor, key_tensor, value_tensor, attention_mask, head_mask, output_attentions, training=False - ): - batch_size = shape_list(attention_mask)[0] - mixed_query_layer = self.query(query_tensor) - mixed_key_layer = self.key(key_tensor) - mixed_value_layer = self.value(value_tensor) - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = tf.matmul( - query_layer, key_layer, transpose_b=True - ) # (batch size, num_heads, seq_len_q, seq_len_k) - dk = tf.cast(shape_list(key_layer)[-1], dtype=attention_scores.dtype) # scale attention_scores - attention_scores = attention_scores / tf.math.sqrt(dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFMobileBertModel call() function) - attention_mask = tf.cast(attention_mask, dtype=attention_scores.dtype) - attention_scores = attention_scores + attention_mask - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - - context_layer = tf.matmul(attention_probs, value_layer) - - context_layer = tf.transpose(context_layer, perm=[0, 2, 1, 3]) - context_layer = tf.reshape( - context_layer, (batch_size, -1, self.all_head_size) - ) # (batch_size, seq_len_q, all_head_size) - - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.true_hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.true_hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build( - [ - None, - None, - self.config.true_hidden_size - if self.config.use_bottleneck_attention - else self.config.hidden_size, - ] - ) - - -class TFMobileBertSelfOutput(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.use_bottleneck = config.use_bottleneck - self.dense = keras.layers.Dense( - config.true_hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = NORM2FN[config.normalization_type]( - config.true_hidden_size, epsilon=config.layer_norm_eps, name="LayerNorm" - ) - if not self.use_bottleneck: - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states, residual_tensor, training=False): - hidden_states = self.dense(hidden_states) - if not self.use_bottleneck: - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.LayerNorm(hidden_states + residual_tensor) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.true_hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build(None) - - -class TFMobileBertAttention(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.self = TFMobileBertSelfAttention(config, name="self") - self.mobilebert_output = TFMobileBertSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - query_tensor, - key_tensor, - value_tensor, - layer_input, - attention_mask, - head_mask, - output_attentions, - training=False, - ): - self_outputs = self.self( - query_tensor, key_tensor, value_tensor, attention_mask, head_mask, output_attentions, training=training - ) - - attention_output = self.mobilebert_output(self_outputs[0], layer_input, training=training) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self", None) is not None: - with tf.name_scope(self.self.name): - self.self.build(None) - if getattr(self, "mobilebert_output", None) is not None: - with tf.name_scope(self.mobilebert_output.name): - self.mobilebert_output.build(None) - - -class TFOutputBottleneck(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense(config.hidden_size, name="dense") - self.LayerNorm = NORM2FN[config.normalization_type]( - config.hidden_size, epsilon=config.layer_norm_eps, name="LayerNorm" - ) - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states, residual_tensor, training=False): - layer_outputs = self.dense(hidden_states) - layer_outputs = self.dropout(layer_outputs, training=training) - layer_outputs = self.LayerNorm(layer_outputs + residual_tensor) - return layer_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.true_hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build(None) - - -class TFMobileBertOutput(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.use_bottleneck = config.use_bottleneck - self.dense = keras.layers.Dense( - config.true_hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = NORM2FN[config.normalization_type]( - config.true_hidden_size, epsilon=config.layer_norm_eps, name="LayerNorm" - ) - if not self.use_bottleneck: - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - else: - self.bottleneck = TFOutputBottleneck(config, name="bottleneck") - self.config = config - - def call(self, hidden_states, residual_tensor_1, residual_tensor_2, training=False): - hidden_states = self.dense(hidden_states) - if not self.use_bottleneck: - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.LayerNorm(hidden_states + residual_tensor_1) - else: - hidden_states = self.LayerNorm(hidden_states + residual_tensor_1) - hidden_states = self.bottleneck(hidden_states, residual_tensor_2) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build(None) - if getattr(self, "bottleneck", None) is not None: - with tf.name_scope(self.bottleneck.name): - self.bottleneck.build(None) - - -class TFBottleneckLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense(config.intra_bottleneck_size, name="dense") - self.LayerNorm = NORM2FN[config.normalization_type]( - config.intra_bottleneck_size, epsilon=config.layer_norm_eps, name="LayerNorm" - ) - self.config = config - - def call(self, inputs): - hidden_states = self.dense(inputs) - hidden_states = self.LayerNorm(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build(None) - - -class TFBottleneck(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.key_query_shared_bottleneck = config.key_query_shared_bottleneck - self.use_bottleneck_attention = config.use_bottleneck_attention - self.bottleneck_input = TFBottleneckLayer(config, name="input") - if self.key_query_shared_bottleneck: - self.attention = TFBottleneckLayer(config, name="attention") - - def call(self, hidden_states): - # This method can return three different tuples of values. These different values make use of bottlenecks, - # which are linear layers used to project the hidden states to a lower-dimensional vector, reducing memory - # usage. These linear layer have weights that are learned during training. - # - # If `config.use_bottleneck_attention`, it will return the result of the bottleneck layer four times for the - # key, query, value, and "layer input" to be used by the attention layer. - # This bottleneck is used to project the hidden. This last layer input will be used as a residual tensor - # in the attention self output, after the attention scores have been computed. - # - # If not `config.use_bottleneck_attention` and `config.key_query_shared_bottleneck`, this will return - # four values, three of which have been passed through a bottleneck: the query and key, passed through the same - # bottleneck, and the residual layer to be applied in the attention self output, through another bottleneck. - # - # Finally, in the last case, the values for the query, key and values are the hidden states without bottleneck, - # and the residual layer will be this value passed through a bottleneck. - - bottlenecked_hidden_states = self.bottleneck_input(hidden_states) - if self.use_bottleneck_attention: - return (bottlenecked_hidden_states,) * 4 - elif self.key_query_shared_bottleneck: - shared_attention_input = self.attention(hidden_states) - return (shared_attention_input, shared_attention_input, hidden_states, bottlenecked_hidden_states) - else: - return (hidden_states, hidden_states, hidden_states, bottlenecked_hidden_states) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "bottleneck_input", None) is not None: - with tf.name_scope(self.bottleneck_input.name): - self.bottleneck_input.build(None) - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - - -class TFFFNOutput(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense(config.true_hidden_size, name="dense") - self.LayerNorm = NORM2FN[config.normalization_type]( - config.true_hidden_size, epsilon=config.layer_norm_eps, name="LayerNorm" - ) - self.config = config - - def call(self, hidden_states, residual_tensor): - hidden_states = self.dense(hidden_states) - hidden_states = self.LayerNorm(hidden_states + residual_tensor) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build(None) - - -class TFFFNLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.intermediate = TFMobileBertIntermediate(config, name="intermediate") - self.mobilebert_output = TFFFNOutput(config, name="output") - - def call(self, hidden_states): - intermediate_output = self.intermediate(hidden_states) - layer_outputs = self.mobilebert_output(intermediate_output, hidden_states) - return layer_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "mobilebert_output", None) is not None: - with tf.name_scope(self.mobilebert_output.name): - self.mobilebert_output.build(None) - - -class TFMobileBertLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.use_bottleneck = config.use_bottleneck - self.num_feedforward_networks = config.num_feedforward_networks - self.attention = TFMobileBertAttention(config, name="attention") - self.intermediate = TFMobileBertIntermediate(config, name="intermediate") - self.mobilebert_output = TFMobileBertOutput(config, name="output") - - if self.use_bottleneck: - self.bottleneck = TFBottleneck(config, name="bottleneck") - if config.num_feedforward_networks > 1: - self.ffn = [TFFFNLayer(config, name=f"ffn.{i}") for i in range(config.num_feedforward_networks - 1)] - - def call(self, hidden_states, attention_mask, head_mask, output_attentions, training=False): - if self.use_bottleneck: - query_tensor, key_tensor, value_tensor, layer_input = self.bottleneck(hidden_states) - else: - query_tensor, key_tensor, value_tensor, layer_input = [hidden_states] * 4 - - attention_outputs = self.attention( - query_tensor, - key_tensor, - value_tensor, - layer_input, - attention_mask, - head_mask, - output_attentions, - training=training, - ) - - attention_output = attention_outputs[0] - s = (attention_output,) - - if self.num_feedforward_networks != 1: - for i, ffn_module in enumerate(self.ffn): - attention_output = ffn_module(attention_output) - s += (attention_output,) - - intermediate_output = self.intermediate(attention_output) - layer_output = self.mobilebert_output(intermediate_output, attention_output, hidden_states, training=training) - - outputs = ( - (layer_output,) - + attention_outputs[1:] - + ( - tf.constant(0), - query_tensor, - key_tensor, - value_tensor, - layer_input, - attention_output, - intermediate_output, - ) - + s - ) # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "mobilebert_output", None) is not None: - with tf.name_scope(self.mobilebert_output.name): - self.mobilebert_output.build(None) - if getattr(self, "bottleneck", None) is not None: - with tf.name_scope(self.bottleneck.name): - self.bottleneck.build(None) - if getattr(self, "ffn", None) is not None: - for layer in self.ffn: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFMobileBertEncoder(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.layer = [TFMobileBertLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states, - attention_mask, - head_mask, - output_attentions, - output_hidden_states, - return_dict, - training=False, - ): - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states, attention_mask, head_mask[i], output_attentions, training=training - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFMobileBertPooler(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.do_activate = config.classifier_activation - if self.do_activate: - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states): - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - if not self.do_activate: - return first_token_tensor - else: - pooled_output = self.dense(first_token_tensor) - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFMobileBertPredictionHeadTransform(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - if isinstance(config.hidden_act, str): - self.transform_act_fn = get_tf_activation(config.hidden_act) - else: - self.transform_act_fn = config.hidden_act - self.LayerNorm = NORM2FN["layer_norm"](config.hidden_size, epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.transform_act_fn(hidden_states) - hidden_states = self.LayerNorm(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build(None) - - -class TFMobileBertLMPredictionHead(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.transform = TFMobileBertPredictionHeadTransform(config, name="transform") - self.config = config - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - self.dense = self.add_weight( - shape=(self.config.hidden_size - self.config.embedding_size, self.config.vocab_size), - initializer="zeros", - trainable=True, - name="dense/weight", - ) - self.decoder = self.add_weight( - shape=(self.config.vocab_size, self.config.embedding_size), - initializer="zeros", - trainable=True, - name="decoder/weight", - ) - - if self.built: - return - self.built = True - if getattr(self, "transform", None) is not None: - with tf.name_scope(self.transform.name): - self.transform.build(None) - - def get_output_embeddings(self): - return self - - def set_output_embeddings(self, value): - self.decoder = value - self.config.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - hidden_states = self.transform(hidden_states) - hidden_states = tf.matmul(hidden_states, tf.concat([tf.transpose(self.decoder), self.dense], axis=0)) - hidden_states = hidden_states + self.bias - return hidden_states - - -class TFMobileBertMLMHead(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.predictions = TFMobileBertLMPredictionHead(config, name="predictions") - - def call(self, sequence_output): - prediction_scores = self.predictions(sequence_output) - return prediction_scores - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -@keras_serializable -class TFMobileBertMainLayer(keras.layers.Layer): - config_class = MobileBertConfig - - def __init__(self, config, add_pooling_layer=True, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.num_hidden_layers = config.num_hidden_layers - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - - self.embeddings = TFMobileBertEmbeddings(config, name="embeddings") - self.encoder = TFMobileBertEncoder(config, name="encoder") - self.pooler = TFMobileBertPooler(config, name="pooler") if add_pooling_layer else None - - def get_input_embeddings(self): - return self.embeddings - - def set_input_embeddings(self, value): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - inputs_embeds=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(input_shape, 1) - - if token_type_ids is None: - token_type_ids = tf.fill(input_shape, 0) - - embedding_output = self.embeddings(input_ids, position_ids, token_type_ids, inputs_embeds, training=training) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - extended_attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.num_hidden_layers - - encoder_outputs = self.encoder( - embedding_output, - extended_attention_mask, - head_mask, - output_attentions, - output_hidden_states, - return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -class TFMobileBertPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = MobileBertConfig - base_model_prefix = "mobilebert" - - -@dataclass -class TFMobileBertForPreTrainingOutput(ModelOutput): - """ - Output type of [`TFMobileBertForPreTraining`]. - - Args: - prediction_logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - seq_relationship_logits (`tf.Tensor` of shape `(batch_size, 2)`): - Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation - before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - prediction_logits: tf.Tensor | None = None - seq_relationship_logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -MOBILEBERT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`MobileBertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -MOBILEBERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare MobileBert Model transformer outputting raw hidden-states without any specific head on top.", - MOBILEBERT_START_DOCSTRING, -) -class TFMobileBertModel(TFMobileBertPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.mobilebert = TFMobileBertMainLayer(config, name="mobilebert") - - @unpack_inputs - @add_start_docstrings_to_model_forward(MOBILEBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPooling, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutputWithPooling: - outputs = self.mobilebert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilebert", None) is not None: - with tf.name_scope(self.mobilebert.name): - self.mobilebert.build(None) - - -@add_start_docstrings( - """ - MobileBert Model with two heads on top as done during the pretraining: a `masked language modeling` head and a - `next sentence prediction (classification)` head. - """, - MOBILEBERT_START_DOCSTRING, -) -class TFMobileBertForPreTraining(TFMobileBertPreTrainedModel, TFMobileBertPreTrainingLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.mobilebert = TFMobileBertMainLayer(config, name="mobilebert") - self.predictions = TFMobileBertMLMHead(config, name="predictions___cls") - self.seq_relationship = TFMobileBertOnlyNSPHead(config, name="seq_relationship___cls") - - def get_lm_head(self): - return self.predictions.predictions - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.predictions.name + "/" + self.predictions.predictions.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(MOBILEBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFMobileBertForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - next_sentence_label: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFMobileBertForPreTrainingOutput: - r""" - Return: - - Examples: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFMobileBertForPreTraining - - >>> tokenizer = AutoTokenizer.from_pretrained("google/mobilebert-uncased") - >>> model = TFMobileBertForPreTraining.from_pretrained("google/mobilebert-uncased") - >>> input_ids = tf.constant(tokenizer.encode("Hello, my dog is cute"))[None, :] # Batch size 1 - >>> outputs = model(input_ids) - >>> prediction_scores, seq_relationship_scores = outputs[:2] - ```""" - outputs = self.mobilebert( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output, pooled_output = outputs[:2] - prediction_scores = self.predictions(sequence_output) - seq_relationship_score = self.seq_relationship(pooled_output) - - total_loss = None - if labels is not None and next_sentence_label is not None: - d_labels = {"labels": labels} - d_labels["next_sentence_label"] = next_sentence_label - total_loss = self.hf_compute_loss(labels=d_labels, logits=(prediction_scores, seq_relationship_score)) - - if not return_dict: - output = (prediction_scores, seq_relationship_score) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - - return TFMobileBertForPreTrainingOutput( - loss=total_loss, - prediction_logits=prediction_scores, - seq_relationship_logits=seq_relationship_score, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilebert", None) is not None: - with tf.name_scope(self.mobilebert.name): - self.mobilebert.build(None) - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - if getattr(self, "seq_relationship", None) is not None: - with tf.name_scope(self.seq_relationship.name): - self.seq_relationship.build(None) - - def tf_to_pt_weight_rename(self, tf_weight): - if tf_weight == "cls.predictions.decoder.weight": - return tf_weight, "mobilebert.embeddings.word_embeddings.weight" - else: - return (tf_weight,) - - -@add_start_docstrings("""MobileBert Model with a `language modeling` head on top.""", MOBILEBERT_START_DOCSTRING) -class TFMobileBertForMaskedLM(TFMobileBertPreTrainedModel, TFMaskedLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"pooler", - r"seq_relationship___cls", - r"cls.seq_relationship", - ] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.mobilebert = TFMobileBertMainLayer(config, add_pooling_layer=False, name="mobilebert") - self.predictions = TFMobileBertMLMHead(config, name="predictions___cls") - - def get_lm_head(self): - return self.predictions.predictions - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.mlm.name + "/" + self.mlm.predictions.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(MOBILEBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="'paris'", - expected_loss=0.57, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFMaskedLMOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels - """ - outputs = self.mobilebert( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.predictions(sequence_output, training=training) - - loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilebert", None) is not None: - with tf.name_scope(self.mobilebert.name): - self.mobilebert.build(None) - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - def tf_to_pt_weight_rename(self, tf_weight): - if tf_weight == "cls.predictions.decoder.weight": - return tf_weight, "mobilebert.embeddings.word_embeddings.weight" - else: - return (tf_weight,) - - -class TFMobileBertOnlyNSPHead(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.seq_relationship = keras.layers.Dense(2, name="seq_relationship") - self.config = config - - def call(self, pooled_output): - seq_relationship_score = self.seq_relationship(pooled_output) - return seq_relationship_score - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "seq_relationship", None) is not None: - with tf.name_scope(self.seq_relationship.name): - self.seq_relationship.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """MobileBert Model with a `next sentence prediction (classification)` head on top.""", - MOBILEBERT_START_DOCSTRING, -) -class TFMobileBertForNextSentencePrediction(TFMobileBertPreTrainedModel, TFNextSentencePredictionLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"predictions___cls", r"cls.predictions"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.mobilebert = TFMobileBertMainLayer(config, name="mobilebert") - self.cls = TFMobileBertOnlyNSPHead(config, name="seq_relationship___cls") - - @unpack_inputs - @add_start_docstrings_to_model_forward(MOBILEBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFNextSentencePredictorOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - next_sentence_label: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFNextSentencePredictorOutput: - r""" - Return: - - Examples: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFMobileBertForNextSentencePrediction - - >>> tokenizer = AutoTokenizer.from_pretrained("google/mobilebert-uncased") - >>> model = TFMobileBertForNextSentencePrediction.from_pretrained("google/mobilebert-uncased") - - >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced." - >>> next_sentence = "The sky is blue due to the shorter wavelength of blue light." - >>> encoding = tokenizer(prompt, next_sentence, return_tensors="tf") - - >>> logits = model(encoding["input_ids"], token_type_ids=encoding["token_type_ids"])[0] - ```""" - outputs = self.mobilebert( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - seq_relationship_scores = self.cls(pooled_output) - - next_sentence_loss = ( - None - if next_sentence_label is None - else self.hf_compute_loss(labels=next_sentence_label, logits=seq_relationship_scores) - ) - - if not return_dict: - output = (seq_relationship_scores,) + outputs[2:] - return ((next_sentence_loss,) + output) if next_sentence_loss is not None else output - - return TFNextSentencePredictorOutput( - loss=next_sentence_loss, - logits=seq_relationship_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilebert", None) is not None: - with tf.name_scope(self.mobilebert.name): - self.mobilebert.build(None) - if getattr(self, "cls", None) is not None: - with tf.name_scope(self.cls.name): - self.cls.build(None) - - -@add_start_docstrings( - """ - MobileBert Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - MOBILEBERT_START_DOCSTRING, -) -class TFMobileBertForSequenceClassification(TFMobileBertPreTrainedModel, TFSequenceClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"predictions___cls", - r"seq_relationship___cls", - r"cls.predictions", - r"cls.seq_relationship", - ] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.mobilebert = TFMobileBertMainLayer(config, name="mobilebert") - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(MOBILEBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_SEQUENCE_CLASSIFICATION, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_SEQ_CLASS_EXPECTED_OUTPUT, - expected_loss=_SEQ_CLASS_EXPECTED_LOSS, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFSequenceClassifierOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.mobilebert( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - - pooled_output = self.dropout(pooled_output, training=training) - logits = self.classifier(pooled_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilebert", None) is not None: - with tf.name_scope(self.mobilebert.name): - self.mobilebert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - MobileBert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a - linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - MOBILEBERT_START_DOCSTRING, -) -class TFMobileBertForQuestionAnswering(TFMobileBertPreTrainedModel, TFQuestionAnsweringLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"pooler", - r"predictions___cls", - r"seq_relationship___cls", - r"cls.predictions", - r"cls.seq_relationship", - ] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.mobilebert = TFMobileBertMainLayer(config, add_pooling_layer=False, name="mobilebert") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(MOBILEBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_QA, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - qa_target_start_index=_QA_TARGET_START_INDEX, - qa_target_end_index=_QA_TARGET_END_INDEX, - expected_output=_QA_EXPECTED_OUTPUT, - expected_loss=_QA_EXPECTED_LOSS, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFQuestionAnsweringModelOutput: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.mobilebert( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions, "end_position": end_positions} - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilebert", None) is not None: - with tf.name_scope(self.mobilebert.name): - self.mobilebert.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - MobileBert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and - a softmax) e.g. for RocStories/SWAG tasks. - """, - MOBILEBERT_START_DOCSTRING, -) -class TFMobileBertForMultipleChoice(TFMobileBertPreTrainedModel, TFMultipleChoiceLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"predictions___cls", - r"seq_relationship___cls", - r"cls.predictions", - r"cls.seq_relationship", - ] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.mobilebert = TFMobileBertMainLayer(config, name="mobilebert") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward( - MOBILEBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") - ) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFMultipleChoiceModelOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - flat_inputs_embeds = ( - tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - outputs = self.mobilebert( - flat_input_ids, - flat_attention_mask, - flat_token_type_ids, - flat_position_ids, - head_mask, - flat_inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, training=training) - logits = self.classifier(pooled_output) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilebert", None) is not None: - with tf.name_scope(self.mobilebert.name): - self.mobilebert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - MobileBert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. - for Named-Entity-Recognition (NER) tasks. - """, - MOBILEBERT_START_DOCSTRING, -) -class TFMobileBertForTokenClassification(TFMobileBertPreTrainedModel, TFTokenClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [ - r"pooler", - r"predictions___cls", - r"seq_relationship___cls", - r"cls.predictions", - r"cls.seq_relationship", - ] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.mobilebert = TFMobileBertMainLayer(config, add_pooling_layer=False, name="mobilebert") - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(MOBILEBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_TOKEN_CLASSIFICATION, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_TOKEN_CLASS_EXPECTED_OUTPUT, - expected_loss=_TOKEN_CLASS_EXPECTED_LOSS, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFTokenClassifierOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.mobilebert( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilebert", None) is not None: - with tf.name_scope(self.mobilebert.name): - self.mobilebert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFMobileBertForMaskedLM", - "TFMobileBertForMultipleChoice", - "TFMobileBertForNextSentencePrediction", - "TFMobileBertForPreTraining", - "TFMobileBertForQuestionAnswering", - "TFMobileBertForSequenceClassification", - "TFMobileBertForTokenClassification", - "TFMobileBertMainLayer", - "TFMobileBertModel", - "TFMobileBertPreTrainedModel", -] diff --git a/src/transformers/models/mobilenet_v1/convert_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/mobilenet_v1/convert_original_tf_checkpoint_to_pytorch.py index 1b53bbeab475..b0eeb2874aa6 100644 --- a/src/transformers/models/mobilenet_v1/convert_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/mobilenet_v1/convert_original_tf_checkpoint_to_pytorch.py @@ -28,7 +28,6 @@ MobileNetV1Config, MobileNetV1ForImageClassification, MobileNetV1ImageProcessor, - load_tf_weights_in_mobilenet_v1, ) from transformers.utils import logging @@ -37,6 +36,109 @@ logger = logging.get_logger(__name__) +def _build_tf_to_pytorch_map(model, config, tf_weights=None): + """ + A map of modules from TF to PyTorch. + """ + + tf_to_pt_map = {} + + if isinstance(model, MobileNetV1ForImageClassification): + backbone = model.mobilenet_v1 + else: + backbone = model + + prefix = "MobilenetV1/Conv2d_0/" + tf_to_pt_map[prefix + "weights"] = backbone.conv_stem.convolution.weight + tf_to_pt_map[prefix + "BatchNorm/beta"] = backbone.conv_stem.normalization.bias + tf_to_pt_map[prefix + "BatchNorm/gamma"] = backbone.conv_stem.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = backbone.conv_stem.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = backbone.conv_stem.normalization.running_var + + for i in range(13): + tf_index = i + 1 + pt_index = i * 2 + + pointer = backbone.layer[pt_index] + prefix = f"MobilenetV1/Conv2d_{tf_index}_depthwise/" + tf_to_pt_map[prefix + "depthwise_weights"] = pointer.convolution.weight + tf_to_pt_map[prefix + "BatchNorm/beta"] = pointer.normalization.bias + tf_to_pt_map[prefix + "BatchNorm/gamma"] = pointer.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = pointer.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = pointer.normalization.running_var + + pointer = backbone.layer[pt_index + 1] + prefix = f"MobilenetV1/Conv2d_{tf_index}_pointwise/" + tf_to_pt_map[prefix + "weights"] = pointer.convolution.weight + tf_to_pt_map[prefix + "BatchNorm/beta"] = pointer.normalization.bias + tf_to_pt_map[prefix + "BatchNorm/gamma"] = pointer.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = pointer.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = pointer.normalization.running_var + + if isinstance(model, MobileNetV1ForImageClassification): + prefix = "MobilenetV1/Logits/Conv2d_1c_1x1/" + tf_to_pt_map[prefix + "weights"] = model.classifier.weight + tf_to_pt_map[prefix + "biases"] = model.classifier.bias + + return tf_to_pt_map + + +def load_tf_weights_in_mobilenet_v1(model, config, tf_checkpoint_path): + """Load TensorFlow checkpoints in a PyTorch model.""" + try: + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + + # Load weights from TF model + init_vars = tf.train.list_variables(tf_checkpoint_path) + tf_weights = {} + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_checkpoint_path, name) + tf_weights[name] = array + + # Build TF to PyTorch weights loading map + tf_to_pt_map = _build_tf_to_pytorch_map(model, config, tf_weights) + + for name, pointer in tf_to_pt_map.items(): + logger.info(f"Importing {name}") + if name not in tf_weights: + logger.info(f"{name} not in tf pre-trained weights, skipping") + continue + + array = tf_weights[name] + + if "depthwise_weights" in name: + logger.info("Transposing depthwise") + array = np.transpose(array, (2, 3, 0, 1)) + elif "weights" in name: + logger.info("Transposing") + if len(pointer.shape) == 2: # copying into linear layer + array = array.squeeze().transpose() + else: + array = np.transpose(array, (3, 2, 0, 1)) + + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + + logger.info(f"Initialize PyTorch weight {name} {array.shape}") + pointer.data = torch.from_numpy(array) + + tf_weights.pop(name, None) + tf_weights.pop(name + "/RMSProp", None) + tf_weights.pop(name + "/RMSProp_1", None) + tf_weights.pop(name + "/ExponentialMovingAverage", None) + + logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}") + return model + + def get_mobilenet_v1_config(model_name): config = MobileNetV1Config(layer_norm_eps=0.001) diff --git a/src/transformers/models/mobilenet_v1/image_processing_mobilenet_v1.py b/src/transformers/models/mobilenet_v1/image_processing_mobilenet_v1.py index 6fa3f443c53b..da384d40b3ed 100644 --- a/src/transformers/models/mobilenet_v1/image_processing_mobilenet_v1.py +++ b/src/transformers/models/mobilenet_v1/image_processing_mobilenet_v1.py @@ -216,10 +216,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -248,10 +246,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/mobilenet_v1/modeling_mobilenet_v1.py b/src/transformers/models/mobilenet_v1/modeling_mobilenet_v1.py index 25997a46790c..f80c6977bf18 100755 --- a/src/transformers/models/mobilenet_v1/modeling_mobilenet_v1.py +++ b/src/transformers/models/mobilenet_v1/modeling_mobilenet_v1.py @@ -29,109 +29,6 @@ logger = logging.get_logger(__name__) -def _build_tf_to_pytorch_map(model, config, tf_weights=None): - """ - A map of modules from TF to PyTorch. - """ - - tf_to_pt_map = {} - - if isinstance(model, MobileNetV1ForImageClassification): - backbone = model.mobilenet_v1 - else: - backbone = model - - prefix = "MobilenetV1/Conv2d_0/" - tf_to_pt_map[prefix + "weights"] = backbone.conv_stem.convolution.weight - tf_to_pt_map[prefix + "BatchNorm/beta"] = backbone.conv_stem.normalization.bias - tf_to_pt_map[prefix + "BatchNorm/gamma"] = backbone.conv_stem.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = backbone.conv_stem.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = backbone.conv_stem.normalization.running_var - - for i in range(13): - tf_index = i + 1 - pt_index = i * 2 - - pointer = backbone.layer[pt_index] - prefix = f"MobilenetV1/Conv2d_{tf_index}_depthwise/" - tf_to_pt_map[prefix + "depthwise_weights"] = pointer.convolution.weight - tf_to_pt_map[prefix + "BatchNorm/beta"] = pointer.normalization.bias - tf_to_pt_map[prefix + "BatchNorm/gamma"] = pointer.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = pointer.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = pointer.normalization.running_var - - pointer = backbone.layer[pt_index + 1] - prefix = f"MobilenetV1/Conv2d_{tf_index}_pointwise/" - tf_to_pt_map[prefix + "weights"] = pointer.convolution.weight - tf_to_pt_map[prefix + "BatchNorm/beta"] = pointer.normalization.bias - tf_to_pt_map[prefix + "BatchNorm/gamma"] = pointer.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = pointer.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = pointer.normalization.running_var - - if isinstance(model, MobileNetV1ForImageClassification): - prefix = "MobilenetV1/Logits/Conv2d_1c_1x1/" - tf_to_pt_map[prefix + "weights"] = model.classifier.weight - tf_to_pt_map[prefix + "biases"] = model.classifier.bias - - return tf_to_pt_map - - -def load_tf_weights_in_mobilenet_v1(model, config, tf_checkpoint_path): - """Load TensorFlow checkpoints in a PyTorch model.""" - try: - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - - # Load weights from TF model - init_vars = tf.train.list_variables(tf_checkpoint_path) - tf_weights = {} - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_checkpoint_path, name) - tf_weights[name] = array - - # Build TF to PyTorch weights loading map - tf_to_pt_map = _build_tf_to_pytorch_map(model, config, tf_weights) - - for name, pointer in tf_to_pt_map.items(): - logger.info(f"Importing {name}") - if name not in tf_weights: - logger.info(f"{name} not in tf pre-trained weights, skipping") - continue - - array = tf_weights[name] - - if "depthwise_weights" in name: - logger.info("Transposing depthwise") - array = np.transpose(array, (2, 3, 0, 1)) - elif "weights" in name: - logger.info("Transposing") - if len(pointer.shape) == 2: # copying into linear layer - array = array.squeeze().transpose() - else: - array = np.transpose(array, (3, 2, 0, 1)) - - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - - logger.info(f"Initialize PyTorch weight {name} {array.shape}") - pointer.data = torch.from_numpy(array) - - tf_weights.pop(name, None) - tf_weights.pop(name + "/RMSProp", None) - tf_weights.pop(name + "/RMSProp_1", None) - tf_weights.pop(name + "/ExponentialMovingAverage", None) - - logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}") - return model - - def apply_tf_padding(features: torch.Tensor, conv_layer: nn.Conv2d) -> torch.Tensor: """ Apply TensorFlow-style "SAME" padding to a convolution layer. See the notes at: @@ -229,7 +126,6 @@ def forward(self, features: torch.Tensor) -> torch.Tensor: @auto_docstring class MobileNetV1PreTrainedModel(PreTrainedModel): config: MobileNetV1Config - load_tf_weights = load_tf_weights_in_mobilenet_v1 base_model_prefix = "mobilenet_v1" main_input_name = "pixel_values" supports_gradient_checkpointing = False @@ -410,5 +306,4 @@ def forward( "MobileNetV1ForImageClassification", "MobileNetV1Model", "MobileNetV1PreTrainedModel", - "load_tf_weights_in_mobilenet_v1", ] diff --git a/src/transformers/models/mobilenet_v2/convert_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/mobilenet_v2/convert_original_tf_checkpoint_to_pytorch.py index 1fdb9783ccf0..6f94b074b440 100644 --- a/src/transformers/models/mobilenet_v2/convert_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/mobilenet_v2/convert_original_tf_checkpoint_to_pytorch.py @@ -29,7 +29,6 @@ MobileNetV2ForImageClassification, MobileNetV2ForSemanticSegmentation, MobileNetV2ImageProcessor, - load_tf_weights_in_mobilenet_v2, ) from transformers.utils import logging @@ -38,6 +37,175 @@ logger = logging.get_logger(__name__) +def _build_tf_to_pytorch_map(model, config, tf_weights=None): + """ + A map of modules from TF to PyTorch. + """ + + tf_to_pt_map = {} + + if isinstance(model, (MobileNetV2ForImageClassification, MobileNetV2ForSemanticSegmentation)): + backbone = model.mobilenet_v2 + else: + backbone = model + + # Use the EMA weights if available + def ema(x): + return x + "/ExponentialMovingAverage" if x + "/ExponentialMovingAverage" in tf_weights else x + + prefix = "MobilenetV2/Conv/" + tf_to_pt_map[ema(prefix + "weights")] = backbone.conv_stem.first_conv.convolution.weight + tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = backbone.conv_stem.first_conv.normalization.bias + tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = backbone.conv_stem.first_conv.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = backbone.conv_stem.first_conv.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = backbone.conv_stem.first_conv.normalization.running_var + + prefix = "MobilenetV2/expanded_conv/depthwise/" + tf_to_pt_map[ema(prefix + "depthwise_weights")] = backbone.conv_stem.conv_3x3.convolution.weight + tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = backbone.conv_stem.conv_3x3.normalization.bias + tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = backbone.conv_stem.conv_3x3.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = backbone.conv_stem.conv_3x3.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = backbone.conv_stem.conv_3x3.normalization.running_var + + prefix = "MobilenetV2/expanded_conv/project/" + tf_to_pt_map[ema(prefix + "weights")] = backbone.conv_stem.reduce_1x1.convolution.weight + tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = backbone.conv_stem.reduce_1x1.normalization.bias + tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = backbone.conv_stem.reduce_1x1.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = backbone.conv_stem.reduce_1x1.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = backbone.conv_stem.reduce_1x1.normalization.running_var + + for i in range(16): + tf_index = i + 1 + pt_index = i + pointer = backbone.layer[pt_index] + + prefix = f"MobilenetV2/expanded_conv_{tf_index}/expand/" + tf_to_pt_map[ema(prefix + "weights")] = pointer.expand_1x1.convolution.weight + tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = pointer.expand_1x1.normalization.bias + tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = pointer.expand_1x1.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = pointer.expand_1x1.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = pointer.expand_1x1.normalization.running_var + + prefix = f"MobilenetV2/expanded_conv_{tf_index}/depthwise/" + tf_to_pt_map[ema(prefix + "depthwise_weights")] = pointer.conv_3x3.convolution.weight + tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = pointer.conv_3x3.normalization.bias + tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = pointer.conv_3x3.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = pointer.conv_3x3.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = pointer.conv_3x3.normalization.running_var + + prefix = f"MobilenetV2/expanded_conv_{tf_index}/project/" + tf_to_pt_map[ema(prefix + "weights")] = pointer.reduce_1x1.convolution.weight + tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = pointer.reduce_1x1.normalization.bias + tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = pointer.reduce_1x1.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = pointer.reduce_1x1.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = pointer.reduce_1x1.normalization.running_var + + prefix = "MobilenetV2/Conv_1/" + tf_to_pt_map[ema(prefix + "weights")] = backbone.conv_1x1.convolution.weight + tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = backbone.conv_1x1.normalization.bias + tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = backbone.conv_1x1.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = backbone.conv_1x1.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = backbone.conv_1x1.normalization.running_var + + if isinstance(model, MobileNetV2ForImageClassification): + prefix = "MobilenetV2/Logits/Conv2d_1c_1x1/" + tf_to_pt_map[ema(prefix + "weights")] = model.classifier.weight + tf_to_pt_map[ema(prefix + "biases")] = model.classifier.bias + + if isinstance(model, MobileNetV2ForSemanticSegmentation): + prefix = "image_pooling/" + tf_to_pt_map[prefix + "weights"] = model.segmentation_head.conv_pool.convolution.weight + tf_to_pt_map[prefix + "BatchNorm/beta"] = model.segmentation_head.conv_pool.normalization.bias + tf_to_pt_map[prefix + "BatchNorm/gamma"] = model.segmentation_head.conv_pool.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = model.segmentation_head.conv_pool.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = ( + model.segmentation_head.conv_pool.normalization.running_var + ) + + prefix = "aspp0/" + tf_to_pt_map[prefix + "weights"] = model.segmentation_head.conv_aspp.convolution.weight + tf_to_pt_map[prefix + "BatchNorm/beta"] = model.segmentation_head.conv_aspp.normalization.bias + tf_to_pt_map[prefix + "BatchNorm/gamma"] = model.segmentation_head.conv_aspp.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = model.segmentation_head.conv_aspp.normalization.running_mean + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = ( + model.segmentation_head.conv_aspp.normalization.running_var + ) + + prefix = "concat_projection/" + tf_to_pt_map[prefix + "weights"] = model.segmentation_head.conv_projection.convolution.weight + tf_to_pt_map[prefix + "BatchNorm/beta"] = model.segmentation_head.conv_projection.normalization.bias + tf_to_pt_map[prefix + "BatchNorm/gamma"] = model.segmentation_head.conv_projection.normalization.weight + tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = ( + model.segmentation_head.conv_projection.normalization.running_mean + ) + tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = ( + model.segmentation_head.conv_projection.normalization.running_var + ) + + prefix = "logits/semantic/" + tf_to_pt_map[ema(prefix + "weights")] = model.segmentation_head.classifier.convolution.weight + tf_to_pt_map[ema(prefix + "biases")] = model.segmentation_head.classifier.convolution.bias + + return tf_to_pt_map + + +def load_tf_weights_in_mobilenet_v2(model, config, tf_checkpoint_path): + """Load TensorFlow checkpoints in a PyTorch model.""" + try: + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + + # Load weights from TF model + init_vars = tf.train.list_variables(tf_checkpoint_path) + tf_weights = {} + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_checkpoint_path, name) + tf_weights[name] = array + + # Build TF to PyTorch weights loading map + tf_to_pt_map = _build_tf_to_pytorch_map(model, config, tf_weights) + + for name, pointer in tf_to_pt_map.items(): + logger.info(f"Importing {name}") + if name not in tf_weights: + logger.info(f"{name} not in tf pre-trained weights, skipping") + continue + + array = tf_weights[name] + + if "depthwise_weights" in name: + logger.info("Transposing depthwise") + array = np.transpose(array, (2, 3, 0, 1)) + elif "weights" in name: + logger.info("Transposing") + if len(pointer.shape) == 2: # copying into linear layer + array = array.squeeze().transpose() + else: + array = np.transpose(array, (3, 2, 0, 1)) + + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + + logger.info(f"Initialize PyTorch weight {name} {array.shape}") + pointer.data = torch.from_numpy(array) + + tf_weights.pop(name, None) + tf_weights.pop(name + "/RMSProp", None) + tf_weights.pop(name + "/RMSProp_1", None) + tf_weights.pop(name + "/ExponentialMovingAverage", None) + tf_weights.pop(name + "/Momentum", None) + + logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}") + return model + + def get_mobilenet_v2_config(model_name): config = MobileNetV2Config(layer_norm_eps=0.001) diff --git a/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2.py b/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2.py index eb6e6388bff4..186dc3cf5772 100644 --- a/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2.py +++ b/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2.py @@ -377,10 +377,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -413,15 +411,11 @@ def preprocess( segmentation_maps = make_flat_list_of_images(segmentation_maps, expected_ndims=2) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") if segmentation_maps is not None and not valid_images(segmentation_maps): raise ValueError( - "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." + "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor" ) validate_preprocess_arguments( @@ -478,7 +472,7 @@ def preprocess( # Copied from transformers.models.beit.image_processing_beit.BeitImageProcessor.post_process_semantic_segmentation with Beit->MobileNetV2 def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[list[tuple]] = None): """ - Converts the output of [`MobileNetV2ForSemanticSegmentation`] into semantic segmentation maps. Only supports PyTorch. + Converts the output of [`MobileNetV2ForSemanticSegmentation`] into semantic segmentation maps. Args: outputs ([`MobileNetV2ForSemanticSegmentation`]): @@ -492,7 +486,6 @@ def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[lis segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each `torch.Tensor` correspond to a semantic class id. """ - # TODO: add support for other frameworks logits = outputs.logits # Resize logits and compute semantic segmentation maps diff --git a/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2_fast.py b/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2_fast.py index 97ca39da78bf..948f9e96d7d9 100644 --- a/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2_fast.py +++ b/src/transformers/models/mobilenet_v2/image_processing_mobilenet_v2_fast.py @@ -206,7 +206,7 @@ def _preprocess( # Copied from transformers.models.beit.image_processing_beit_fast.BeitImageProcessorFast.post_process_semantic_segmentation with Beit->MobileNetV2 def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[list[tuple]] = None): """ - Converts the output of [`MobileNetV2ForSemanticSegmentation`] into semantic segmentation maps. Only supports PyTorch. + Converts the output of [`MobileNetV2ForSemanticSegmentation`] into semantic segmentation maps. Args: outputs ([`MobileNetV2ForSemanticSegmentation`]): @@ -220,7 +220,6 @@ def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[lis segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each `torch.Tensor` correspond to a semantic class id. """ - # TODO: add support for other frameworks logits = outputs.logits # Resize logits and compute semantic segmentation maps diff --git a/src/transformers/models/mobilenet_v2/modeling_mobilenet_v2.py b/src/transformers/models/mobilenet_v2/modeling_mobilenet_v2.py index 8f178f0480dd..2d30da8f756d 100755 --- a/src/transformers/models/mobilenet_v2/modeling_mobilenet_v2.py +++ b/src/transformers/models/mobilenet_v2/modeling_mobilenet_v2.py @@ -34,180 +34,9 @@ logger = logging.get_logger(__name__) -def _build_tf_to_pytorch_map(model, config, tf_weights=None): - """ - A map of modules from TF to PyTorch. - """ - - tf_to_pt_map = {} - - if isinstance(model, (MobileNetV2ForImageClassification, MobileNetV2ForSemanticSegmentation)): - backbone = model.mobilenet_v2 - else: - backbone = model - - # Use the EMA weights if available - def ema(x): - return x + "/ExponentialMovingAverage" if x + "/ExponentialMovingAverage" in tf_weights else x - - prefix = "MobilenetV2/Conv/" - tf_to_pt_map[ema(prefix + "weights")] = backbone.conv_stem.first_conv.convolution.weight - tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = backbone.conv_stem.first_conv.normalization.bias - tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = backbone.conv_stem.first_conv.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = backbone.conv_stem.first_conv.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = backbone.conv_stem.first_conv.normalization.running_var - - prefix = "MobilenetV2/expanded_conv/depthwise/" - tf_to_pt_map[ema(prefix + "depthwise_weights")] = backbone.conv_stem.conv_3x3.convolution.weight - tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = backbone.conv_stem.conv_3x3.normalization.bias - tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = backbone.conv_stem.conv_3x3.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = backbone.conv_stem.conv_3x3.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = backbone.conv_stem.conv_3x3.normalization.running_var - - prefix = "MobilenetV2/expanded_conv/project/" - tf_to_pt_map[ema(prefix + "weights")] = backbone.conv_stem.reduce_1x1.convolution.weight - tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = backbone.conv_stem.reduce_1x1.normalization.bias - tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = backbone.conv_stem.reduce_1x1.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = backbone.conv_stem.reduce_1x1.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = backbone.conv_stem.reduce_1x1.normalization.running_var - - for i in range(16): - tf_index = i + 1 - pt_index = i - pointer = backbone.layer[pt_index] - - prefix = f"MobilenetV2/expanded_conv_{tf_index}/expand/" - tf_to_pt_map[ema(prefix + "weights")] = pointer.expand_1x1.convolution.weight - tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = pointer.expand_1x1.normalization.bias - tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = pointer.expand_1x1.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = pointer.expand_1x1.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = pointer.expand_1x1.normalization.running_var - - prefix = f"MobilenetV2/expanded_conv_{tf_index}/depthwise/" - tf_to_pt_map[ema(prefix + "depthwise_weights")] = pointer.conv_3x3.convolution.weight - tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = pointer.conv_3x3.normalization.bias - tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = pointer.conv_3x3.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = pointer.conv_3x3.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = pointer.conv_3x3.normalization.running_var - - prefix = f"MobilenetV2/expanded_conv_{tf_index}/project/" - tf_to_pt_map[ema(prefix + "weights")] = pointer.reduce_1x1.convolution.weight - tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = pointer.reduce_1x1.normalization.bias - tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = pointer.reduce_1x1.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = pointer.reduce_1x1.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = pointer.reduce_1x1.normalization.running_var - - prefix = "MobilenetV2/Conv_1/" - tf_to_pt_map[ema(prefix + "weights")] = backbone.conv_1x1.convolution.weight - tf_to_pt_map[ema(prefix + "BatchNorm/beta")] = backbone.conv_1x1.normalization.bias - tf_to_pt_map[ema(prefix + "BatchNorm/gamma")] = backbone.conv_1x1.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = backbone.conv_1x1.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = backbone.conv_1x1.normalization.running_var - - if isinstance(model, MobileNetV2ForImageClassification): - prefix = "MobilenetV2/Logits/Conv2d_1c_1x1/" - tf_to_pt_map[ema(prefix + "weights")] = model.classifier.weight - tf_to_pt_map[ema(prefix + "biases")] = model.classifier.bias - - if isinstance(model, MobileNetV2ForSemanticSegmentation): - prefix = "image_pooling/" - tf_to_pt_map[prefix + "weights"] = model.segmentation_head.conv_pool.convolution.weight - tf_to_pt_map[prefix + "BatchNorm/beta"] = model.segmentation_head.conv_pool.normalization.bias - tf_to_pt_map[prefix + "BatchNorm/gamma"] = model.segmentation_head.conv_pool.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = model.segmentation_head.conv_pool.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = ( - model.segmentation_head.conv_pool.normalization.running_var - ) - - prefix = "aspp0/" - tf_to_pt_map[prefix + "weights"] = model.segmentation_head.conv_aspp.convolution.weight - tf_to_pt_map[prefix + "BatchNorm/beta"] = model.segmentation_head.conv_aspp.normalization.bias - tf_to_pt_map[prefix + "BatchNorm/gamma"] = model.segmentation_head.conv_aspp.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = model.segmentation_head.conv_aspp.normalization.running_mean - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = ( - model.segmentation_head.conv_aspp.normalization.running_var - ) - - prefix = "concat_projection/" - tf_to_pt_map[prefix + "weights"] = model.segmentation_head.conv_projection.convolution.weight - tf_to_pt_map[prefix + "BatchNorm/beta"] = model.segmentation_head.conv_projection.normalization.bias - tf_to_pt_map[prefix + "BatchNorm/gamma"] = model.segmentation_head.conv_projection.normalization.weight - tf_to_pt_map[prefix + "BatchNorm/moving_mean"] = ( - model.segmentation_head.conv_projection.normalization.running_mean - ) - tf_to_pt_map[prefix + "BatchNorm/moving_variance"] = ( - model.segmentation_head.conv_projection.normalization.running_var - ) - - prefix = "logits/semantic/" - tf_to_pt_map[ema(prefix + "weights")] = model.segmentation_head.classifier.convolution.weight - tf_to_pt_map[ema(prefix + "biases")] = model.segmentation_head.classifier.convolution.bias - - return tf_to_pt_map - - -def load_tf_weights_in_mobilenet_v2(model, config, tf_checkpoint_path): - """Load TensorFlow checkpoints in a PyTorch model.""" - try: - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - - # Load weights from TF model - init_vars = tf.train.list_variables(tf_checkpoint_path) - tf_weights = {} - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_checkpoint_path, name) - tf_weights[name] = array - - # Build TF to PyTorch weights loading map - tf_to_pt_map = _build_tf_to_pytorch_map(model, config, tf_weights) - - for name, pointer in tf_to_pt_map.items(): - logger.info(f"Importing {name}") - if name not in tf_weights: - logger.info(f"{name} not in tf pre-trained weights, skipping") - continue - - array = tf_weights[name] - - if "depthwise_weights" in name: - logger.info("Transposing depthwise") - array = np.transpose(array, (2, 3, 0, 1)) - elif "weights" in name: - logger.info("Transposing") - if len(pointer.shape) == 2: # copying into linear layer - array = array.squeeze().transpose() - else: - array = np.transpose(array, (3, 2, 0, 1)) - - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - - logger.info(f"Initialize PyTorch weight {name} {array.shape}") - pointer.data = torch.from_numpy(array) - - tf_weights.pop(name, None) - tf_weights.pop(name + "/RMSProp", None) - tf_weights.pop(name + "/RMSProp_1", None) - tf_weights.pop(name + "/ExponentialMovingAverage", None) - tf_weights.pop(name + "/Momentum", None) - - logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}") - return model - - def make_divisible(value: int, divisor: int = 8, min_value: Optional[int] = None) -> int: """ - Ensure that all layers have a channel count that is divisible by `divisor`. This function is taken from the - original TensorFlow repo. It can be seen here: - https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + Ensure that all layers have a channel count that is divisible by `divisor`. """ if min_value is None: min_value = divisor @@ -423,7 +252,6 @@ def forward(self, features: torch.Tensor) -> torch.Tensor: @auto_docstring class MobileNetV2PreTrainedModel(PreTrainedModel): config: MobileNetV2Config - load_tf_weights = load_tf_weights_in_mobilenet_v2 base_model_prefix = "mobilenet_v2" main_input_name = "pixel_values" supports_gradient_checkpointing = False @@ -782,5 +610,4 @@ def forward( "MobileNetV2ForSemanticSegmentation", "MobileNetV2Model", "MobileNetV2PreTrainedModel", - "load_tf_weights_in_mobilenet_v2", ] diff --git a/src/transformers/models/mobilevit/__init__.py b/src/transformers/models/mobilevit/__init__.py index 6750449a3eae..282e858e6798 100644 --- a/src/transformers/models/mobilevit/__init__.py +++ b/src/transformers/models/mobilevit/__init__.py @@ -23,7 +23,6 @@ from .image_processing_mobilevit import * from .image_processing_mobilevit_fast import * from .modeling_mobilevit import * - from .modeling_tf_mobilevit import * else: import sys diff --git a/src/transformers/models/mobilevit/image_processing_mobilevit.py b/src/transformers/models/mobilevit/image_processing_mobilevit.py index 5411023c3104..0ea7a0706cc4 100644 --- a/src/transformers/models/mobilevit/image_processing_mobilevit.py +++ b/src/transformers/models/mobilevit/image_processing_mobilevit.py @@ -373,10 +373,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -412,15 +410,11 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") if segmentation_maps is not None and not valid_images(segmentation_maps): raise ValueError( - "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." + "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor" ) validate_preprocess_arguments( @@ -473,7 +467,7 @@ def preprocess( # Copied from transformers.models.beit.image_processing_beit.BeitImageProcessor.post_process_semantic_segmentation with Beit->MobileViT def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[list[tuple]] = None): """ - Converts the output of [`MobileViTForSemanticSegmentation`] into semantic segmentation maps. Only supports PyTorch. + Converts the output of [`MobileViTForSemanticSegmentation`] into semantic segmentation maps. Args: outputs ([`MobileViTForSemanticSegmentation`]): @@ -487,7 +481,6 @@ def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[lis segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each `torch.Tensor` correspond to a semantic class id. """ - # TODO: add support for other frameworks logits = outputs.logits # Resize logits and compute semantic segmentation maps diff --git a/src/transformers/models/mobilevit/modeling_mobilevit.py b/src/transformers/models/mobilevit/modeling_mobilevit.py index 415c33a7cb85..db8b8cd58f5a 100755 --- a/src/transformers/models/mobilevit/modeling_mobilevit.py +++ b/src/transformers/models/mobilevit/modeling_mobilevit.py @@ -42,9 +42,7 @@ def make_divisible(value: int, divisor: int = 8, min_value: Optional[int] = None) -> int: """ - Ensure that all layers have a channel count that is divisible by `divisor`. This function is taken from the - original TensorFlow repo. It can be seen here: - https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + Ensure that all layers have a channel count that is divisible by `divisor`. """ if min_value is None: min_value = divisor @@ -631,8 +629,6 @@ class MobileViTPreTrainedModel(PreTrainedModel): def _init_weights(self, module: nn.Module) -> None: """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/mobilevit/modeling_tf_mobilevit.py b/src/transformers/models/mobilevit/modeling_tf_mobilevit.py deleted file mode 100644 index dcad0f302a8e..000000000000 --- a/src/transformers/models/mobilevit/modeling_tf_mobilevit.py +++ /dev/null @@ -1,1376 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Apple Inc. and The HuggingFace Inc. team. All rights reserved. -# -# 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. -# -# Original license: https://github.com/apple/ml-cvnets/blob/main/LICENSE -"""TensorFlow 2.0 MobileViT model.""" - -from __future__ import annotations - -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...file_utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - replace_return_docstrings, -) -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPooling, - TFImageClassifierOutputWithNoAttention, - TFSemanticSegmenterOutputWithNoAttention, -) -from ...modeling_tf_utils import ( - TFPreTrainedModel, - TFSequenceClassificationLoss, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list, stable_softmax -from ...utils import logging -from .configuration_mobilevit import MobileViTConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "MobileViTConfig" - -# Base docstring -_CHECKPOINT_FOR_DOC = "apple/mobilevit-small" -_EXPECTED_OUTPUT_SHAPE = [1, 640, 8, 8] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "apple/mobilevit-small" -_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" - - -def make_divisible(value: int, divisor: int = 8, min_value: int | None = None) -> int: - """ - Ensure that all layers have a channel count that is divisible by `divisor`. This function is taken from the - original TensorFlow repo. It can be seen here: - https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py - """ - if min_value is None: - min_value = divisor - new_value = max(min_value, int(value + divisor / 2) // divisor * divisor) - # Make sure that round down does not go down by more than 10%. - if new_value < 0.9 * value: - new_value += divisor - return int(new_value) - - -class TFMobileViTConvLayer(keras.layers.Layer): - def __init__( - self, - config: MobileViTConfig, - in_channels: int, - out_channels: int, - kernel_size: int, - stride: int = 1, - groups: int = 1, - bias: bool = False, - dilation: int = 1, - use_normalization: bool = True, - use_activation: bool | str = True, - **kwargs, - ) -> None: - super().__init__(**kwargs) - logger.warning( - f"\n{self.__class__.__name__} has backpropagation operations that are NOT supported on CPU. If you wish " - "to train/fine-tune this model, you need a GPU or a TPU" - ) - - padding = int((kernel_size - 1) / 2) * dilation - self.padding = keras.layers.ZeroPadding2D(padding) - - if out_channels % groups != 0: - raise ValueError(f"Output channels ({out_channels}) are not divisible by {groups} groups.") - - self.convolution = keras.layers.Conv2D( - filters=out_channels, - kernel_size=kernel_size, - strides=stride, - padding="VALID", - dilation_rate=dilation, - groups=groups, - use_bias=bias, - name="convolution", - ) - - if use_normalization: - self.normalization = keras.layers.BatchNormalization(epsilon=1e-5, momentum=0.1, name="normalization") - else: - self.normalization = None - - if use_activation: - if isinstance(use_activation, str): - self.activation = get_tf_activation(use_activation) - elif isinstance(config.hidden_act, str): - self.activation = get_tf_activation(config.hidden_act) - else: - self.activation = config.hidden_act - else: - self.activation = None - self.in_channels = in_channels - self.out_channels = out_channels - - def call(self, features: tf.Tensor, training: bool = False) -> tf.Tensor: - padded_features = self.padding(features) - features = self.convolution(padded_features) - if self.normalization is not None: - features = self.normalization(features, training=training) - if self.activation is not None: - features = self.activation(features) - return features - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convolution", None) is not None: - with tf.name_scope(self.convolution.name): - self.convolution.build([None, None, None, self.in_channels]) - if getattr(self, "normalization", None) is not None: - if hasattr(self.normalization, "name"): - with tf.name_scope(self.normalization.name): - self.normalization.build([None, None, None, self.out_channels]) - - -class TFMobileViTInvertedResidual(keras.layers.Layer): - """ - Inverted residual block (MobileNetv2): https://huggingface.co/papers/1801.04381 - """ - - def __init__( - self, config: MobileViTConfig, in_channels: int, out_channels: int, stride: int, dilation: int = 1, **kwargs - ) -> None: - super().__init__(**kwargs) - expanded_channels = make_divisible(int(round(in_channels * config.expand_ratio)), 8) - - if stride not in [1, 2]: - raise ValueError(f"Invalid stride {stride}.") - - self.use_residual = (stride == 1) and (in_channels == out_channels) - - self.expand_1x1 = TFMobileViTConvLayer( - config, in_channels=in_channels, out_channels=expanded_channels, kernel_size=1, name="expand_1x1" - ) - - self.conv_3x3 = TFMobileViTConvLayer( - config, - in_channels=expanded_channels, - out_channels=expanded_channels, - kernel_size=3, - stride=stride, - groups=expanded_channels, - dilation=dilation, - name="conv_3x3", - ) - - self.reduce_1x1 = TFMobileViTConvLayer( - config, - in_channels=expanded_channels, - out_channels=out_channels, - kernel_size=1, - use_activation=False, - name="reduce_1x1", - ) - - def call(self, features: tf.Tensor, training: bool = False) -> tf.Tensor: - residual = features - - features = self.expand_1x1(features, training=training) - features = self.conv_3x3(features, training=training) - features = self.reduce_1x1(features, training=training) - - return residual + features if self.use_residual else features - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "expand_1x1", None) is not None: - with tf.name_scope(self.expand_1x1.name): - self.expand_1x1.build(None) - if getattr(self, "conv_3x3", None) is not None: - with tf.name_scope(self.conv_3x3.name): - self.conv_3x3.build(None) - if getattr(self, "reduce_1x1", None) is not None: - with tf.name_scope(self.reduce_1x1.name): - self.reduce_1x1.build(None) - - -class TFMobileViTMobileNetLayer(keras.layers.Layer): - def __init__( - self, - config: MobileViTConfig, - in_channels: int, - out_channels: int, - stride: int = 1, - num_stages: int = 1, - **kwargs, - ) -> None: - super().__init__(**kwargs) - - self.layers = [] - for i in range(num_stages): - layer = TFMobileViTInvertedResidual( - config, - in_channels=in_channels, - out_channels=out_channels, - stride=stride if i == 0 else 1, - name=f"layer.{i}", - ) - self.layers.append(layer) - in_channels = out_channels - - def call(self, features: tf.Tensor, training: bool = False) -> tf.Tensor: - for layer_module in self.layers: - features = layer_module(features, training=training) - return features - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer_module in self.layers: - with tf.name_scope(layer_module.name): - layer_module.build(None) - - -class TFMobileViTSelfAttention(keras.layers.Layer): - def __init__(self, config: MobileViTConfig, hidden_size: int, **kwargs) -> None: - super().__init__(**kwargs) - - if hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size {hidden_size} is not a multiple of the number of attention " - f"heads {config.num_attention_heads}." - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - scale = tf.cast(self.attention_head_size, dtype=tf.float32) - self.scale = tf.math.sqrt(scale) - - self.query = keras.layers.Dense(self.all_head_size, use_bias=config.qkv_bias, name="query") - self.key = keras.layers.Dense(self.all_head_size, use_bias=config.qkv_bias, name="key") - self.value = keras.layers.Dense(self.all_head_size, use_bias=config.qkv_bias, name="value") - - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.hidden_size = hidden_size - - def transpose_for_scores(self, x: tf.Tensor) -> tf.Tensor: - batch_size = tf.shape(x)[0] - x = tf.reshape(x, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - return tf.transpose(x, perm=[0, 2, 1, 3]) - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - batch_size = tf.shape(hidden_states)[0] - - key_layer = self.transpose_for_scores(self.key(hidden_states)) - value_layer = self.transpose_for_scores(self.value(hidden_states)) - query_layer = self.transpose_for_scores(self.query(hidden_states)) - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - attention_scores = attention_scores / self.scale - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs, training=training) - - context_layer = tf.matmul(attention_probs, value_layer) - - context_layer = tf.transpose(context_layer, perm=[0, 2, 1, 3]) - context_layer = tf.reshape(context_layer, shape=(batch_size, -1, self.all_head_size)) - return context_layer - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.hidden_size]) - - -class TFMobileViTSelfOutput(keras.layers.Layer): - def __init__(self, config: MobileViTConfig, hidden_size: int, **kwargs) -> None: - super().__init__(**kwargs) - self.dense = keras.layers.Dense(hidden_size, name="dense") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.hidden_size = hidden_size - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.hidden_size]) - - -class TFMobileViTAttention(keras.layers.Layer): - def __init__(self, config: MobileViTConfig, hidden_size: int, **kwargs) -> None: - super().__init__(**kwargs) - self.attention = TFMobileViTSelfAttention(config, hidden_size, name="attention") - self.dense_output = TFMobileViTSelfOutput(config, hidden_size, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - self_outputs = self.attention(hidden_states, training=training) - attention_output = self.dense_output(self_outputs, training=training) - return attention_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -class TFMobileViTIntermediate(keras.layers.Layer): - def __init__(self, config: MobileViTConfig, hidden_size: int, intermediate_size: int, **kwargs) -> None: - super().__init__(**kwargs) - self.dense = keras.layers.Dense(intermediate_size, name="dense") - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.hidden_size = hidden_size - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.hidden_size]) - - -class TFMobileViTOutput(keras.layers.Layer): - def __init__(self, config: MobileViTConfig, hidden_size: int, intermediate_size: int, **kwargs) -> None: - super().__init__(**kwargs) - self.dense = keras.layers.Dense(hidden_size, name="dense") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.intermediate_size = intermediate_size - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = hidden_states + input_tensor - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.intermediate_size]) - - -class TFMobileViTTransformerLayer(keras.layers.Layer): - def __init__(self, config: MobileViTConfig, hidden_size: int, intermediate_size: int, **kwargs) -> None: - super().__init__(**kwargs) - self.attention = TFMobileViTAttention(config, hidden_size, name="attention") - self.intermediate = TFMobileViTIntermediate(config, hidden_size, intermediate_size, name="intermediate") - self.mobilevit_output = TFMobileViTOutput(config, hidden_size, intermediate_size, name="output") - self.layernorm_before = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_before") - self.layernorm_after = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_after") - self.hidden_size = hidden_size - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - attention_output = self.attention(self.layernorm_before(hidden_states), training=training) - hidden_states = attention_output + hidden_states - - layer_output = self.layernorm_after(hidden_states) - layer_output = self.intermediate(layer_output) - layer_output = self.mobilevit_output(layer_output, hidden_states, training=training) - return layer_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "mobilevit_output", None) is not None: - with tf.name_scope(self.mobilevit_output.name): - self.mobilevit_output.build(None) - if getattr(self, "layernorm_before", None) is not None: - with tf.name_scope(self.layernorm_before.name): - self.layernorm_before.build([None, None, self.hidden_size]) - if getattr(self, "layernorm_after", None) is not None: - with tf.name_scope(self.layernorm_after.name): - self.layernorm_after.build([None, None, self.hidden_size]) - - -class TFMobileViTTransformer(keras.layers.Layer): - def __init__(self, config: MobileViTConfig, hidden_size: int, num_stages: int, **kwargs) -> None: - super().__init__(**kwargs) - - self.layers = [] - for i in range(num_stages): - transformer_layer = TFMobileViTTransformerLayer( - config, - hidden_size=hidden_size, - intermediate_size=int(hidden_size * config.mlp_ratio), - name=f"layer.{i}", - ) - self.layers.append(transformer_layer) - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - for layer_module in self.layers: - hidden_states = layer_module(hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer_module in self.layers: - with tf.name_scope(layer_module.name): - layer_module.build(None) - - -class TFMobileViTLayer(keras.layers.Layer): - """ - MobileViT block: https://huggingface.co/papers/2110.02178 - """ - - def __init__( - self, - config: MobileViTConfig, - in_channels: int, - out_channels: int, - stride: int, - hidden_size: int, - num_stages: int, - dilation: int = 1, - **kwargs, - ) -> None: - super().__init__(**kwargs) - self.patch_width = config.patch_size - self.patch_height = config.patch_size - - if stride == 2: - self.downsampling_layer = TFMobileViTInvertedResidual( - config, - in_channels=in_channels, - out_channels=out_channels, - stride=stride if dilation == 1 else 1, - dilation=dilation // 2 if dilation > 1 else 1, - name="downsampling_layer", - ) - in_channels = out_channels - else: - self.downsampling_layer = None - - self.conv_kxk = TFMobileViTConvLayer( - config, - in_channels=in_channels, - out_channels=in_channels, - kernel_size=config.conv_kernel_size, - name="conv_kxk", - ) - - self.conv_1x1 = TFMobileViTConvLayer( - config, - in_channels=in_channels, - out_channels=hidden_size, - kernel_size=1, - use_normalization=False, - use_activation=False, - name="conv_1x1", - ) - - self.transformer = TFMobileViTTransformer( - config, hidden_size=hidden_size, num_stages=num_stages, name="transformer" - ) - - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - - self.conv_projection = TFMobileViTConvLayer( - config, in_channels=hidden_size, out_channels=in_channels, kernel_size=1, name="conv_projection" - ) - - self.fusion = TFMobileViTConvLayer( - config, - in_channels=2 * in_channels, - out_channels=in_channels, - kernel_size=config.conv_kernel_size, - name="fusion", - ) - self.hidden_size = hidden_size - - def unfolding(self, features: tf.Tensor) -> tuple[tf.Tensor, dict]: - patch_width, patch_height = self.patch_width, self.patch_height - patch_area = tf.cast(patch_width * patch_height, "int32") - - batch_size = tf.shape(features)[0] - orig_height = tf.shape(features)[1] - orig_width = tf.shape(features)[2] - channels = tf.shape(features)[3] - - new_height = tf.cast(tf.math.ceil(orig_height / patch_height) * patch_height, "int32") - new_width = tf.cast(tf.math.ceil(orig_width / patch_width) * patch_width, "int32") - - interpolate = new_width != orig_width or new_height != orig_height - if interpolate: - # Note: Padding can be done, but then it needs to be handled in attention function. - features = tf.image.resize(features, size=(new_height, new_width), method="bilinear") - - # number of patches along width and height - num_patch_width = new_width // patch_width - num_patch_height = new_height // patch_height - num_patches = num_patch_height * num_patch_width - - # convert from shape (batch_size, orig_height, orig_width, channels) - # to the shape (batch_size * patch_area, num_patches, channels) - features = tf.transpose(features, [0, 3, 1, 2]) - patches = tf.reshape( - features, (batch_size * channels * num_patch_height, patch_height, num_patch_width, patch_width) - ) - patches = tf.transpose(patches, [0, 2, 1, 3]) - patches = tf.reshape(patches, (batch_size, channels, num_patches, patch_area)) - patches = tf.transpose(patches, [0, 3, 2, 1]) - patches = tf.reshape(patches, (batch_size * patch_area, num_patches, channels)) - - info_dict = { - "orig_size": (orig_height, orig_width), - "batch_size": batch_size, - "channels": channels, - "interpolate": interpolate, - "num_patches": num_patches, - "num_patches_width": num_patch_width, - "num_patches_height": num_patch_height, - } - return patches, info_dict - - def folding(self, patches: tf.Tensor, info_dict: dict) -> tf.Tensor: - patch_width, patch_height = self.patch_width, self.patch_height - patch_area = int(patch_width * patch_height) - - batch_size = info_dict["batch_size"] - channels = info_dict["channels"] - num_patches = info_dict["num_patches"] - num_patch_height = info_dict["num_patches_height"] - num_patch_width = info_dict["num_patches_width"] - - # convert from shape (batch_size * patch_area, num_patches, channels) - # back to shape (batch_size, channels, orig_height, orig_width) - features = tf.reshape(patches, (batch_size, patch_area, num_patches, -1)) - features = tf.transpose(features, perm=(0, 3, 2, 1)) - features = tf.reshape( - features, (batch_size * channels * num_patch_height, num_patch_width, patch_height, patch_width) - ) - features = tf.transpose(features, perm=(0, 2, 1, 3)) - features = tf.reshape( - features, (batch_size, channels, num_patch_height * patch_height, num_patch_width * patch_width) - ) - features = tf.transpose(features, perm=(0, 2, 3, 1)) - - if info_dict["interpolate"]: - features = tf.image.resize(features, size=info_dict["orig_size"], method="bilinear") - - return features - - def call(self, features: tf.Tensor, training: bool = False) -> tf.Tensor: - # reduce spatial dimensions if needed - if self.downsampling_layer: - features = self.downsampling_layer(features, training=training) - - residual = features - - # local representation - features = self.conv_kxk(features, training=training) - features = self.conv_1x1(features, training=training) - - # convert feature map to patches - patches, info_dict = self.unfolding(features) - - # learn global representations - patches = self.transformer(patches, training=training) - patches = self.layernorm(patches) - - # convert patches back to feature maps - features = self.folding(patches, info_dict) - - features = self.conv_projection(features, training=training) - features = self.fusion(tf.concat([residual, features], axis=-1), training=training) - return features - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv_kxk", None) is not None: - with tf.name_scope(self.conv_kxk.name): - self.conv_kxk.build(None) - if getattr(self, "conv_1x1", None) is not None: - with tf.name_scope(self.conv_1x1.name): - self.conv_1x1.build(None) - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, self.hidden_size]) - if getattr(self, "conv_projection", None) is not None: - with tf.name_scope(self.conv_projection.name): - self.conv_projection.build(None) - if getattr(self, "fusion", None) is not None: - with tf.name_scope(self.fusion.name): - self.fusion.build(None) - if getattr(self, "downsampling_layer", None) is not None: - with tf.name_scope(self.downsampling_layer.name): - self.downsampling_layer.build(None) - - -class TFMobileViTEncoder(keras.layers.Layer): - def __init__(self, config: MobileViTConfig, **kwargs) -> None: - super().__init__(**kwargs) - self.config = config - - self.layers = [] - - # segmentation architectures like DeepLab and PSPNet modify the strides - # of the classification backbones - dilate_layer_4 = dilate_layer_5 = False - if config.output_stride == 8: - dilate_layer_4 = True - dilate_layer_5 = True - elif config.output_stride == 16: - dilate_layer_5 = True - - dilation = 1 - - layer_1 = TFMobileViTMobileNetLayer( - config, - in_channels=config.neck_hidden_sizes[0], - out_channels=config.neck_hidden_sizes[1], - stride=1, - num_stages=1, - name="layer.0", - ) - self.layers.append(layer_1) - - layer_2 = TFMobileViTMobileNetLayer( - config, - in_channels=config.neck_hidden_sizes[1], - out_channels=config.neck_hidden_sizes[2], - stride=2, - num_stages=3, - name="layer.1", - ) - self.layers.append(layer_2) - - layer_3 = TFMobileViTLayer( - config, - in_channels=config.neck_hidden_sizes[2], - out_channels=config.neck_hidden_sizes[3], - stride=2, - hidden_size=config.hidden_sizes[0], - num_stages=2, - name="layer.2", - ) - self.layers.append(layer_3) - - if dilate_layer_4: - dilation *= 2 - - layer_4 = TFMobileViTLayer( - config, - in_channels=config.neck_hidden_sizes[3], - out_channels=config.neck_hidden_sizes[4], - stride=2, - hidden_size=config.hidden_sizes[1], - num_stages=4, - dilation=dilation, - name="layer.3", - ) - self.layers.append(layer_4) - - if dilate_layer_5: - dilation *= 2 - - layer_5 = TFMobileViTLayer( - config, - in_channels=config.neck_hidden_sizes[4], - out_channels=config.neck_hidden_sizes[5], - stride=2, - hidden_size=config.hidden_sizes[2], - num_stages=3, - dilation=dilation, - name="layer.4", - ) - self.layers.append(layer_5) - - def call( - self, - hidden_states: tf.Tensor, - output_hidden_states: bool = False, - return_dict: bool = True, - training: bool = False, - ) -> tuple | TFBaseModelOutput: - all_hidden_states = () if output_hidden_states else None - - for i, layer_module in enumerate(self.layers): - hidden_states = layer_module(hidden_states, training=training) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states] if v is not None) - - return TFBaseModelOutput(last_hidden_state=hidden_states, hidden_states=all_hidden_states) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer_module in self.layers: - with tf.name_scope(layer_module.name): - layer_module.build(None) - - -@keras_serializable -class TFMobileViTMainLayer(keras.layers.Layer): - config_class = MobileViTConfig - - def __init__(self, config: MobileViTConfig, expand_output: bool = True, **kwargs): - super().__init__(**kwargs) - self.config = config - self.expand_output = expand_output - - self.conv_stem = TFMobileViTConvLayer( - config, - in_channels=config.num_channels, - out_channels=config.neck_hidden_sizes[0], - kernel_size=3, - stride=2, - name="conv_stem", - ) - - self.encoder = TFMobileViTEncoder(config, name="encoder") - - if self.expand_output: - self.conv_1x1_exp = TFMobileViTConvLayer( - config, - in_channels=config.neck_hidden_sizes[5], - out_channels=config.neck_hidden_sizes[6], - kernel_size=1, - name="conv_1x1_exp", - ) - - self.pooler = keras.layers.GlobalAveragePooling2D(data_format="channels_first", name="pooler") - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFBaseModelOutputWithPooling: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # When running on CPU, `keras.layers.Conv2D` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - # shape = (batch_size, in_height, in_width, in_channels=num_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - - embedding_output = self.conv_stem(pixel_values, training=training) - - encoder_outputs = self.encoder( - embedding_output, output_hidden_states=output_hidden_states, return_dict=return_dict, training=training - ) - - if self.expand_output: - last_hidden_state = self.conv_1x1_exp(encoder_outputs[0]) - - # Change to NCHW output format to have uniformity in the modules - last_hidden_state = tf.transpose(last_hidden_state, perm=[0, 3, 1, 2]) - - # global average pooling: (batch_size, channels, height, width) -> (batch_size, channels) - pooled_output = self.pooler(last_hidden_state) - else: - last_hidden_state = encoder_outputs[0] - # Change to NCHW output format to have uniformity in the modules - last_hidden_state = tf.transpose(last_hidden_state, perm=[0, 3, 1, 2]) - pooled_output = None - - if not return_dict: - output = (last_hidden_state, pooled_output) if pooled_output is not None else (last_hidden_state,) - - # Change to NCHW output format to have uniformity in the modules - if not self.expand_output: - remaining_encoder_outputs = encoder_outputs[1:] - remaining_encoder_outputs = tuple( - tf.transpose(h, perm=(0, 3, 1, 2)) for h in remaining_encoder_outputs[0] - ) - remaining_encoder_outputs = (remaining_encoder_outputs,) - return output + remaining_encoder_outputs - else: - return output + encoder_outputs[1:] - - # Change the other hidden state outputs to NCHW as well - if output_hidden_states: - hidden_states = tuple(tf.transpose(h, perm=(0, 3, 1, 2)) for h in encoder_outputs[1]) - - return TFBaseModelOutputWithPooling( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=hidden_states if output_hidden_states else encoder_outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv_stem", None) is not None: - with tf.name_scope(self.conv_stem.name): - self.conv_stem.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build([None, None, None, None]) - if getattr(self, "conv_1x1_exp", None) is not None: - with tf.name_scope(self.conv_1x1_exp.name): - self.conv_1x1_exp.build(None) - - -class TFMobileViTPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = MobileViTConfig - base_model_prefix = "mobilevit" - main_input_name = "pixel_values" - - -MOBILEVIT_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `pixel_values` only and nothing else: `model(pixel_values)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([pixel_values, attention_mask])` or `model([pixel_values, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"pixel_values": pixel_values, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`MobileViTConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -MOBILEVIT_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]`, `dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`MobileViTImageProcessor.__call__`] for details. - - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. -""" - - -@add_start_docstrings( - "The bare MobileViT model outputting raw hidden-states without any specific head on top.", - MOBILEVIT_START_DOCSTRING, -) -class TFMobileViTModel(TFMobileViTPreTrainedModel): - def __init__(self, config: MobileViTConfig, expand_output: bool = True, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.config = config - self.expand_output = expand_output - - self.mobilevit = TFMobileViTMainLayer(config, expand_output=expand_output, name="mobilevit") - - @unpack_inputs - @add_start_docstrings_to_model_forward(MOBILEVIT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPooling, - config_class=_CONFIG_FOR_DOC, - modality="vision", - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - def call( - self, - pixel_values: tf.Tensor | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFBaseModelOutputWithPooling: - output = self.mobilevit(pixel_values, output_hidden_states, return_dict, training=training) - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilevit", None) is not None: - with tf.name_scope(self.mobilevit.name): - self.mobilevit.build(None) - - -@add_start_docstrings( - """ - MobileViT model with an image classification head on top (a linear layer on top of the pooled features), e.g. for - ImageNet. - """, - MOBILEVIT_START_DOCSTRING, -) -class TFMobileViTForImageClassification(TFMobileViTPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: MobileViTConfig, *inputs, **kwargs) -> None: - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.mobilevit = TFMobileViTMainLayer(config, name="mobilevit") - - # Classifier head - self.dropout = keras.layers.Dropout(config.classifier_dropout_prob) - self.classifier = ( - keras.layers.Dense(config.num_labels, name="classifier") if config.num_labels > 0 else tf.identity - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(MOBILEVIT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFImageClassifierOutputWithNoAttention, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - def call( - self, - pixel_values: tf.Tensor | None = None, - output_hidden_states: bool | None = None, - labels: tf.Tensor | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFImageClassifierOutputWithNoAttention: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss). If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.mobilevit( - pixel_values, output_hidden_states=output_hidden_states, return_dict=return_dict, training=training - ) - - pooled_output = outputs.pooler_output if return_dict else outputs[1] - - logits = self.classifier(self.dropout(pooled_output, training=training)) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFImageClassifierOutputWithNoAttention(loss=loss, logits=logits, hidden_states=outputs.hidden_states) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilevit", None) is not None: - with tf.name_scope(self.mobilevit.name): - self.mobilevit.build(None) - if getattr(self, "classifier", None) is not None: - if hasattr(self.classifier, "name"): - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.neck_hidden_sizes[-1]]) - - -class TFMobileViTASPPPooling(keras.layers.Layer): - def __init__(self, config: MobileViTConfig, in_channels: int, out_channels: int, **kwargs) -> None: - super().__init__(**kwargs) - - self.global_pool = keras.layers.GlobalAveragePooling2D(keepdims=True, name="global_pool") - - self.conv_1x1 = TFMobileViTConvLayer( - config, - in_channels=in_channels, - out_channels=out_channels, - kernel_size=1, - stride=1, - use_normalization=True, - use_activation="relu", - name="conv_1x1", - ) - - def call(self, features: tf.Tensor, training: bool = False) -> tf.Tensor: - spatial_size = shape_list(features)[1:-1] - features = self.global_pool(features) - features = self.conv_1x1(features, training=training) - features = tf.image.resize(features, size=spatial_size, method="bilinear") - return features - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "global_pool", None) is not None: - with tf.name_scope(self.global_pool.name): - self.global_pool.build([None, None, None, None]) - if getattr(self, "conv_1x1", None) is not None: - with tf.name_scope(self.conv_1x1.name): - self.conv_1x1.build(None) - - -class TFMobileViTASPP(keras.layers.Layer): - """ - ASPP module defined in DeepLab papers: https://huggingface.co/papers/1606.00915, https://huggingface.co/papers/1706.05587 - """ - - def __init__(self, config: MobileViTConfig, **kwargs) -> None: - super().__init__(**kwargs) - - in_channels = config.neck_hidden_sizes[-2] - out_channels = config.aspp_out_channels - - if len(config.atrous_rates) != 3: - raise ValueError("Expected 3 values for atrous_rates") - - self.convs = [] - - in_projection = TFMobileViTConvLayer( - config, - in_channels=in_channels, - out_channels=out_channels, - kernel_size=1, - use_activation="relu", - name="convs.0", - ) - self.convs.append(in_projection) - - self.convs.extend( - [ - TFMobileViTConvLayer( - config, - in_channels=in_channels, - out_channels=out_channels, - kernel_size=3, - dilation=rate, - use_activation="relu", - name=f"convs.{i + 1}", - ) - for i, rate in enumerate(config.atrous_rates) - ] - ) - - pool_layer = TFMobileViTASPPPooling( - config, in_channels, out_channels, name=f"convs.{len(config.atrous_rates) + 1}" - ) - self.convs.append(pool_layer) - - self.project = TFMobileViTConvLayer( - config, - in_channels=5 * out_channels, - out_channels=out_channels, - kernel_size=1, - use_activation="relu", - name="project", - ) - - self.dropout = keras.layers.Dropout(config.aspp_dropout_prob) - - def call(self, features: tf.Tensor, training: bool = False) -> tf.Tensor: - # since the hidden states were transposed to have `(batch_size, channels, height, width)` - # layout we transpose them back to have `(batch_size, height, width, channels)` layout. - features = tf.transpose(features, perm=[0, 2, 3, 1]) - pyramid = [] - for conv in self.convs: - pyramid.append(conv(features, training=training)) - pyramid = tf.concat(pyramid, axis=-1) - - pooled_features = self.project(pyramid, training=training) - pooled_features = self.dropout(pooled_features, training=training) - return pooled_features - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "project", None) is not None: - with tf.name_scope(self.project.name): - self.project.build(None) - if getattr(self, "convs", None) is not None: - for conv in self.convs: - with tf.name_scope(conv.name): - conv.build(None) - - -class TFMobileViTDeepLabV3(keras.layers.Layer): - """ - DeepLabv3 architecture: https://huggingface.co/papers/1706.05587 - """ - - def __init__(self, config: MobileViTConfig, **kwargs) -> None: - super().__init__(**kwargs) - self.aspp = TFMobileViTASPP(config, name="aspp") - - self.dropout = keras.layers.Dropout(config.classifier_dropout_prob) - - self.classifier = TFMobileViTConvLayer( - config, - in_channels=config.aspp_out_channels, - out_channels=config.num_labels, - kernel_size=1, - use_normalization=False, - use_activation=False, - bias=True, - name="classifier", - ) - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - features = self.aspp(hidden_states[-1], training=training) - features = self.dropout(features, training=training) - features = self.classifier(features, training=training) - return features - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "aspp", None) is not None: - with tf.name_scope(self.aspp.name): - self.aspp.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - MobileViT model with a semantic segmentation head on top, e.g. for Pascal VOC. - """, - MOBILEVIT_START_DOCSTRING, -) -class TFMobileViTForSemanticSegmentation(TFMobileViTPreTrainedModel): - def __init__(self, config: MobileViTConfig, **kwargs) -> None: - super().__init__(config, **kwargs) - - self.num_labels = config.num_labels - self.mobilevit = TFMobileViTMainLayer(config, expand_output=False, name="mobilevit") - self.segmentation_head = TFMobileViTDeepLabV3(config, name="segmentation_head") - - def hf_compute_loss(self, logits, labels): - # upsample logits to the images' original size - # `labels` is of shape (batch_size, height, width) - label_interp_shape = shape_list(labels)[1:] - - upsampled_logits = tf.image.resize(logits, size=label_interp_shape, method="bilinear") - # compute weighted loss - loss_fct = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction="none") - - def masked_loss(real, pred): - unmasked_loss = loss_fct(real, pred) - mask = tf.cast(real != self.config.semantic_loss_ignore_index, dtype=unmasked_loss.dtype) - masked_loss = unmasked_loss * mask - # Reduction strategy in the similar spirit with - # https://github.com/huggingface/transformers/blob/main/src/transformers/modeling_tf_utils.py#L210 - reduced_masked_loss = tf.reduce_sum(masked_loss) / tf.reduce_sum(mask) - return tf.reshape(reduced_masked_loss, (1,)) - - return masked_loss(labels, upsampled_logits) - - @unpack_inputs - @add_start_docstrings_to_model_forward(MOBILEVIT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSemanticSegmenterOutputWithNoAttention, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: tf.Tensor | None = None, - labels: tf.Tensor | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple | TFSemanticSegmenterOutputWithNoAttention: - r""" - labels (`tf.Tensor` of shape `(batch_size, height, width)`, *optional*): - Ground truth semantic segmentation maps for computing the loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels > 1`, a classification loss is computed (Cross-Entropy). - - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, TFMobileViTForSemanticSegmentation - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("apple/deeplabv3-mobilevit-small") - >>> model = TFMobileViTForSemanticSegmentation.from_pretrained("apple/deeplabv3-mobilevit-small") - - >>> inputs = image_processor(images=image, return_tensors="tf") - - >>> outputs = model(**inputs) - - >>> # logits are of shape (batch_size, num_labels, height, width) - >>> logits = outputs.logits - ```""" - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if labels is not None and not self.config.num_labels > 1: - raise ValueError("The number of labels should be greater than one") - - outputs = self.mobilevit( - pixel_values, - output_hidden_states=True, # we need the intermediate hidden states - return_dict=return_dict, - training=training, - ) - - encoder_hidden_states = outputs.hidden_states if return_dict else outputs[1] - - logits = self.segmentation_head(encoder_hidden_states, training=training) - - loss = None - if labels is not None: - loss = self.hf_compute_loss(logits=logits, labels=labels) - - # make logits of shape (batch_size, num_labels, height, width) to - # keep them consistent across APIs - logits = tf.transpose(logits, perm=[0, 3, 1, 2]) - - if not return_dict: - if output_hidden_states: - output = (logits,) + outputs[1:] - else: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSemanticSegmenterOutputWithNoAttention( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states if output_hidden_states else None, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mobilevit", None) is not None: - with tf.name_scope(self.mobilevit.name): - self.mobilevit.build(None) - if getattr(self, "segmentation_head", None) is not None: - with tf.name_scope(self.segmentation_head.name): - self.segmentation_head.build(None) - - -__all__ = [ - "TFMobileViTForImageClassification", - "TFMobileViTForSemanticSegmentation", - "TFMobileViTModel", - "TFMobileViTPreTrainedModel", -] diff --git a/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py b/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py index 4e0e972a648a..d842acf7b6e5 100644 --- a/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py +++ b/src/transformers/models/mobilevitv2/modeling_mobilevitv2.py @@ -41,9 +41,7 @@ # Copied from transformers.models.mobilevit.modeling_mobilevit.make_divisible def make_divisible(value: int, divisor: int = 8, min_value: Optional[int] = None) -> int: """ - Ensure that all layers have a channel count that is divisible by `divisor`. This function is taken from the - original TensorFlow repo. It can be seen here: - https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + Ensure that all layers have a channel count that is divisible by `divisor`. """ if min_value is None: min_value = divisor @@ -578,8 +576,6 @@ class MobileViTV2PreTrainedModel(PreTrainedModel): def _init_weights(self, module: nn.Module) -> None: """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/mpnet/__init__.py b/src/transformers/models/mpnet/__init__.py index 0b7abc8357cc..402cc164b979 100644 --- a/src/transformers/models/mpnet/__init__.py +++ b/src/transformers/models/mpnet/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_mpnet import * from .modeling_mpnet import * - from .modeling_tf_mpnet import * from .tokenization_mpnet import * from .tokenization_mpnet_fast import * else: diff --git a/src/transformers/models/mpnet/modeling_mpnet.py b/src/transformers/models/mpnet/modeling_mpnet.py index b25e5491738b..e2ea5cf300ad 100644 --- a/src/transformers/models/mpnet/modeling_mpnet.py +++ b/src/transformers/models/mpnet/modeling_mpnet.py @@ -49,8 +49,6 @@ class MPNetPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/mpnet/modeling_tf_mpnet.py b/src/transformers/models/mpnet/modeling_tf_mpnet.py deleted file mode 100644 index 1afea867df35..000000000000 --- a/src/transformers/models/mpnet/modeling_tf_mpnet.py +++ /dev/null @@ -1,1353 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The HuggingFace Inc. team, Microsoft Corporation. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 MPNet model.""" - -from __future__ import annotations - -import math -import warnings - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPooling, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_mpnet import MPNetConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "microsoft/mpnet-base" -_CONFIG_FOR_DOC = "MPNetConfig" - - -class TFMPNetPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = MPNetConfig - base_model_prefix = "mpnet" - - -class TFMPNetEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position embeddings.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.padding_idx = 1 - self.config = config - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(initializer_range=self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(initializer_range=self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - def create_position_ids_from_input_ids(self, input_ids): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding - symbols are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - input_ids: tf.Tensor - Returns: tf.Tensor - """ - mask = tf.cast(tf.math.not_equal(input_ids, self.padding_idx), dtype=input_ids.dtype) - incremental_indices = tf.math.cumsum(mask, axis=1) * mask - - return incremental_indices + self.padding_idx - - def call(self, input_ids=None, position_ids=None, inputs_embeds=None, training=False): - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if position_ids is None: - if input_ids is not None: - # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = self.create_position_ids_from_input_ids(input_ids=input_ids) - else: - position_ids = tf.expand_dims( - tf.range(start=self.padding_idx + 1, limit=input_shape[-1] + self.padding_idx + 1), axis=0 - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - final_embeddings = inputs_embeds + position_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->MPNet -class TFMPNetPooler(keras.layers.Layer): - def __init__(self, config: MPNetConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFMPNetSelfAttention(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " - f"heads ({config.num_attention_heads}" - ) - - self.num_attention_heads = config.num_attention_heads - assert config.hidden_size % config.num_attention_heads == 0 - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - - self.q = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="q" - ) - self.k = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="k" - ) - self.v = keras.layers.Dense( - self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="v" - ) - self.o = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="o" - ) - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - self.config = config - - def transpose_for_scores(self, x, batch_size): - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - x = tf.reshape(x, (batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - return tf.transpose(x, perm=[0, 2, 1, 3]) - - def call(self, hidden_states, attention_mask, head_mask, output_attentions, position_bias=None, training=False): - batch_size = shape_list(hidden_states)[0] - - q = self.q(hidden_states) - k = self.k(hidden_states) - v = self.v(hidden_states) - - q = self.transpose_for_scores(q, batch_size) - k = self.transpose_for_scores(k, batch_size) - v = self.transpose_for_scores(v, batch_size) - - attention_scores = tf.matmul(q, k, transpose_b=True) - dk = tf.cast(shape_list(k)[-1], attention_scores.dtype) - attention_scores = attention_scores / tf.math.sqrt(dk) - - # Apply relative position embedding (precomputed in MPNetEncoder) if provided. - if position_bias is not None: - attention_scores += position_bias - - if attention_mask is not None: - attention_scores = attention_scores + attention_mask - - attention_probs = stable_softmax(attention_scores, axis=-1) - - attention_probs = self.dropout(attention_probs, training=training) - - if head_mask is not None: - attention_probs = attention_probs * head_mask - - c = tf.matmul(attention_probs, v) - c = tf.transpose(c, perm=[0, 2, 1, 3]) - c = tf.reshape(c, (batch_size, -1, self.all_head_size)) - o = self.o(c) - - outputs = (o, attention_probs) if output_attentions else (o,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "q", None) is not None: - with tf.name_scope(self.q.name): - self.q.build([None, None, self.config.hidden_size]) - if getattr(self, "k", None) is not None: - with tf.name_scope(self.k.name): - self.k.build([None, None, self.config.hidden_size]) - if getattr(self, "v", None) is not None: - with tf.name_scope(self.v.name): - self.v.build([None, None, self.config.hidden_size]) - if getattr(self, "o", None) is not None: - with tf.name_scope(self.o.name): - self.o.build([None, None, self.config.hidden_size]) - - -class TFMPNetAttention(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.attn = TFMPNetSelfAttention(config, name="attn") - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.config = config - - def prune_heads(self, heads): - raise NotImplementedError - - def call(self, input_tensor, attention_mask, head_mask, output_attentions, position_bias=None, training=False): - self_outputs = self.attn( - input_tensor, attention_mask, head_mask, output_attentions, position_bias=position_bias, training=training - ) - attention_output = self.LayerNorm(self.dropout(self_outputs[0]) + input_tensor) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attn", None) is not None: - with tf.name_scope(self.attn.name): - self.attn.build(None) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->MPNet -class TFMPNetIntermediate(keras.layers.Layer): - def __init__(self, config: MPNetConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->MPNet -class TFMPNetOutput(keras.layers.Layer): - def __init__(self, config: MPNetConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFMPNetLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.attention = TFMPNetAttention(config, name="attention") - self.intermediate = TFMPNetIntermediate(config, name="intermediate") - self.out = TFMPNetOutput(config, name="output") - - def call(self, hidden_states, attention_mask, head_mask, output_attentions, position_bias=None, training=False): - self_attention_outputs = self.attention( - hidden_states, attention_mask, head_mask, output_attentions, position_bias=position_bias, training=training - ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - intermediate_output = self.intermediate(attention_output) - layer_output = self.out(intermediate_output, attention_output, training=training) - outputs = (layer_output,) + outputs # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "out", None) is not None: - with tf.name_scope(self.out.name): - self.out.build(None) - - -class TFMPNetEncoder(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.n_heads = config.num_attention_heads - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.relative_attention_num_buckets = config.relative_attention_num_buckets - self.initializer_range = config.initializer_range - - self.layer = [TFMPNetLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - self.relative_attention_num_buckets = config.relative_attention_num_buckets - - def build(self, input_shape=None): - if self.built: - return - self.built = True - with tf.name_scope("relative_attention_bias"): - self.relative_attention_bias = self.add_weight( - name="embeddings", - shape=[self.relative_attention_num_buckets, self.n_heads], - initializer=get_initializer(self.initializer_range), - ) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - def call( - self, - hidden_states, - attention_mask, - head_mask, - output_attentions, - output_hidden_states, - return_dict, - training=False, - ): - position_bias = self.compute_position_bias(hidden_states) - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states, - attention_mask, - head_mask[i], - output_attentions, - position_bias=position_bias, - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - @staticmethod - def _relative_position_bucket(relative_position, num_buckets=32, max_distance=128): - ret = 0 - n = -relative_position - - num_buckets //= 2 - ret += tf.cast(tf.math.less(n, 0), dtype=relative_position.dtype) * num_buckets - n = tf.math.abs(n) - - # now n is in the range [0, inf) - max_exact = num_buckets // 2 - is_small = tf.math.less(n, max_exact) - - val_if_large = max_exact + tf.cast( - tf.math.log(n / max_exact) / math.log(max_distance / max_exact) * (num_buckets - max_exact), - dtype=relative_position.dtype, - ) - - val_if_large = tf.math.minimum(val_if_large, num_buckets - 1) - ret += tf.where(is_small, n, val_if_large) - return ret - - def compute_position_bias(self, x, position_ids=None): - """Compute binned relative position bias""" - input_shape = shape_list(x) - qlen, klen = input_shape[1], input_shape[1] - - if position_ids is not None: - context_position = position_ids[:, :, None] - memory_position = position_ids[:, None, :] - else: - context_position = tf.range(qlen)[:, None] - memory_position = tf.range(klen)[None, :] - - relative_position = memory_position - context_position # shape (qlen, klen) - - rp_bucket = self._relative_position_bucket( - relative_position, - num_buckets=self.relative_attention_num_buckets, - ) - values = tf.gather(self.relative_attention_bias, rp_bucket) # shape (qlen, klen, num_heads) - values = tf.expand_dims(tf.transpose(values, [2, 0, 1]), axis=0) # shape (1, num_heads, qlen, klen) - return values - - -@keras_serializable -class TFMPNetMainLayer(keras.layers.Layer): - config_class = MPNetConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.num_hidden_layers = config.num_hidden_layers - self.initializer_range = config.initializer_range - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - self.encoder = TFMPNetEncoder(config, name="encoder") - self.pooler = TFMPNetPooler(config, name="pooler") - # The embeddings must be the last declaration in order to follow the weights order - self.embeddings = TFMPNetEmbeddings(config, name="embeddings") - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.get_input_embeddings - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.set_input_embeddings - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer._prune_heads - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - position_ids=None, - head_mask=None, - inputs_embeds=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(input_shape, 1) - - embedding_output = self.embeddings( - input_ids, - position_ids, - inputs_embeds, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - extended_attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.num_hidden_layers - - encoder_outputs = self.encoder( - embedding_output, - extended_attention_mask, - head_mask, - output_attentions, - output_hidden_states, - return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(sequence_output) - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - - -MPNET_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`MPNetConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -MPNET_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare MPNet Model transformer outputting raw hidden-states without any specific head on top.", - MPNET_START_DOCSTRING, -) -class TFMPNetModel(TFMPNetPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.mpnet = TFMPNetMainLayer(config, name="mpnet") - - @unpack_inputs - @add_start_docstrings_to_model_forward(MPNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.array | tf.Tensor | None = None, - position_ids: np.array | tf.Tensor | None = None, - head_mask: np.array | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - outputs = self.mpnet( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mpnet", None) is not None: - with tf.name_scope(self.mpnet.name): - self.mpnet.build(None) - - -class TFMPNetLMHead(keras.layers.Layer): - """MPNet head for masked and permuted language modeling""" - - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.act = get_tf_activation("gelu") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.decoder = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - - def get_output_embeddings(self): - return self.decoder - - def set_output_embeddings(self, value): - self.decoder.weight = value - self.decoder.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.layer_norm(hidden_states) - - # project back to size of vocabulary with bias - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.decoder.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -@add_start_docstrings("""MPNet Model with a `language modeling` head on top.""", MPNET_START_DOCSTRING) -class TFMPNetForMaskedLM(TFMPNetPreTrainedModel, TFMaskedLanguageModelingLoss): - _keys_to_ignore_on_load_missing = [r"pooler"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.mpnet = TFMPNetMainLayer(config, name="mpnet") - self.lm_head = TFMPNetLMHead(config, self.mpnet.embeddings, name="lm_head") - - def get_lm_head(self): - return self.lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(MPNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.mpnet( - input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.lm_head(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mpnet", None) is not None: - with tf.name_scope(self.mpnet.name): - self.mpnet.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -class TFMPNetClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.out_proj = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="out_proj" - ) - self.config = config - - def call(self, features, training=False): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x, training=training) - x = self.dense(x) - x = self.dropout(x, training=training) - x = self.out_proj(x) - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - MPNet Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled - output) e.g. for GLUE tasks. - """, - MPNET_START_DOCSTRING, -) -class TFMPNetForSequenceClassification(TFMPNetPreTrainedModel, TFSequenceClassificationLoss): - _keys_to_ignore_on_load_missing = [r"pooler"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.mpnet = TFMPNetMainLayer(config, name="mpnet") - self.classifier = TFMPNetClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(MPNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.array | tf.Tensor | None = None, - position_ids: np.array | tf.Tensor | None = None, - head_mask: np.array | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.mpnet( - input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - logits = self.classifier(sequence_output, training=training) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mpnet", None) is not None: - with tf.name_scope(self.mpnet.name): - self.mpnet.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - MPNet Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - MPNET_START_DOCSTRING, -) -class TFMPNetForMultipleChoice(TFMPNetPreTrainedModel, TFMultipleChoiceLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.mpnet = TFMPNetMainLayer(config, name="mpnet") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(MPNET_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - flat_inputs_embeds = ( - tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - outputs = self.mpnet( - flat_input_ids, - flat_attention_mask, - flat_position_ids, - head_mask, - flat_inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, training=training) - logits = self.classifier(pooled_output) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mpnet", None) is not None: - with tf.name_scope(self.mpnet.name): - self.mpnet.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - MPNet Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - MPNET_START_DOCSTRING, -) -class TFMPNetForTokenClassification(TFMPNetPreTrainedModel, TFTokenClassificationLoss): - _keys_to_ignore_on_load_missing = [r"pooler"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.mpnet = TFMPNetMainLayer(config, name="mpnet") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(MPNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.mpnet( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mpnet", None) is not None: - with tf.name_scope(self.mpnet.name): - self.mpnet.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - MPNet Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - MPNET_START_DOCSTRING, -) -class TFMPNetForQuestionAnswering(TFMPNetPreTrainedModel, TFQuestionAnsweringLoss): - _keys_to_ignore_on_load_missing = [r"pooler"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.mpnet = TFMPNetMainLayer(config, name="mpnet") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(MPNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.array | tf.Tensor | None = None, - position_ids: np.array | tf.Tensor | None = None, - head_mask: np.array | tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: tf.Tensor | None = None, - end_positions: tf.Tensor | None = None, - training: bool = False, - **kwargs, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.mpnet( - input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions, "end_position": end_positions} - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "mpnet", None) is not None: - with tf.name_scope(self.mpnet.name): - self.mpnet.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFMPNetEmbeddings", - "TFMPNetForMaskedLM", - "TFMPNetForMultipleChoice", - "TFMPNetForQuestionAnswering", - "TFMPNetForSequenceClassification", - "TFMPNetForTokenClassification", - "TFMPNetMainLayer", - "TFMPNetModel", - "TFMPNetPreTrainedModel", -] diff --git a/src/transformers/models/mpt/modeling_mpt.py b/src/transformers/models/mpt/modeling_mpt.py index c7bf0a795d42..18df615794cf 100644 --- a/src/transformers/models/mpt/modeling_mpt.py +++ b/src/transformers/models/mpt/modeling_mpt.py @@ -232,8 +232,6 @@ def __init__(self, *inputs, **kwargs): def _init_weights(self, module: nn.Module): """Initialize the weights.""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/mra/modeling_mra.py b/src/transformers/models/mra/modeling_mra.py index 86bee4d09b5a..6612336b6794 100644 --- a/src/transformers/models/mra/modeling_mra.py +++ b/src/transformers/models/mra/modeling_mra.py @@ -469,8 +469,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings + 2, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -824,8 +822,6 @@ def _init_weights(self, module: nn.Module): """Initialize the weights""" std = self.config.initializer_range if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/mt5/__init__.py b/src/transformers/models/mt5/__init__.py index 444a8f8cc8e0..f04d056d6e08 100644 --- a/src/transformers/models/mt5/__init__.py +++ b/src/transformers/models/mt5/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_mt5 import * - from .modeling_flax_mt5 import * from .modeling_mt5 import * - from .modeling_tf_mt5 import * from .tokenization_mt5 import * else: import sys diff --git a/src/transformers/models/mt5/modeling_flax_mt5.py b/src/transformers/models/mt5/modeling_flax_mt5.py deleted file mode 100644 index 13bd83b75034..000000000000 --- a/src/transformers/models/mt5/modeling_flax_mt5.py +++ /dev/null @@ -1,123 +0,0 @@ -# coding=utf-8 -# Copyright 2021 Mesh TensorFlow authors, T5 Authors and 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. -"""Flax mT5 model.""" - -import jax.numpy as jnp - -from ...utils import logging -from ..t5.modeling_flax_t5 import FlaxT5EncoderModel, FlaxT5ForConditionalGeneration, FlaxT5Model -from .configuration_mt5 import MT5Config - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "T5Config" - - -# Copied from transformers.models.bart.modeling_flax_bart.shift_tokens_right -def shift_tokens_right(input_ids: jnp.ndarray, pad_token_id: int, decoder_start_token_id: int) -> jnp.ndarray: - """ - Shift input ids one token to the right. - """ - shifted_input_ids = jnp.zeros_like(input_ids) - shifted_input_ids = shifted_input_ids.at[:, 1:].set(input_ids[:, :-1]) - shifted_input_ids = shifted_input_ids.at[:, 0].set(decoder_start_token_id) - - shifted_input_ids = jnp.where(shifted_input_ids == -100, pad_token_id, shifted_input_ids) - return shifted_input_ids - - -class FlaxMT5Model(FlaxT5Model): - r""" - This class overrides [`FlaxT5Model`]. Please check the superclass for the appropriate documentation alongside usage - examples. - - Examples: - - ```python - >>> from transformers import FlaxMT5Model, AutoTokenizer - - >>> model = FlaxMT5Model.from_pretrained("google/mt5-small") - >>> tokenizer = AutoTokenizer.from_pretrained("google/mt5-small") - - >>> article = "UN Offizier sagt, dass weiter verhandelt werden muss in Syrien." - >>> summary = "Weiter Verhandlung in Syrien." - >>> inputs = tokenizer(article, return_tensors="np") - - >>> decoder_input_ids = tokenizer(text_target=summary, return_tensors="np").input_ids - - >>> outputs = model(input_ids=inputs["input_ids"], decoder_input_ids=decoder_input_ids) - >>> hidden_states = outputs.last_hidden_state - ```""" - - model_type = "mt5" - config_class = MT5Config - - -class FlaxMT5EncoderModel(FlaxT5EncoderModel): - r""" - This class overrides [`FlaxT5EncoderModel`]. Please check the superclass for the appropriate documentation - alongside usage examples. - - Examples: - - ```python - >>> from transformers import FlaxT5EncoderModel, AutoTokenizer - - >>> model = FlaxT5EncoderModel.from_pretrained("google/mt5-small") - >>> tokenizer = AutoTokenizer.from_pretrained("google/mt5-small") - - >>> article = "UN Offizier sagt, dass weiter verhandelt werden muss in Syrien." - >>> summary = "Weiter Verhandlung in Syrien." - >>> inputs = tokenizer(article, return_tensors="np") - - >>> decoder_input_ids = tokenizer(text_target=summary, return_tensors="np").input_ids - - >>> outputs = model(input_ids=inputs["input_ids"]) - >>> hidden_states = outputs.last_hidden_state - ```""" - - model_type = "mt5" - config_class = MT5Config - - -class FlaxMT5ForConditionalGeneration(FlaxT5ForConditionalGeneration): - r""" - This class overrides [`FlaxT5ForConditionalGeneration`]. Please check the superclass for the appropriate - documentation alongside usage examples. - - Examples: - - ```python - >>> from transformers import FlaxMT5ForConditionalGeneration, AutoTokenizer - - >>> model = FlaxMT5ForConditionalGeneration.from_pretrained("google/mt5-small") - >>> tokenizer = AutoTokenizer.from_pretrained("google/mt5-small") - - >>> article = "UN Offizier sagt, dass weiter verhandelt werden muss in Syrien." - >>> summary = "Weiter Verhandlung in Syrien." - >>> inputs = tokenizer(article, return_tensors="np") - - >>> decoder_input_ids = tokenizer(text_target=summary, return_tensors="np").input_ids - - >>> outputs = model(**inputs, decoder_input_ids=decoder_input_ids) - >>> logits = outputs.logits - ```""" - - model_type = "mt5" - config_class = MT5Config - - -__all__ = ["FlaxMT5EncoderModel", "FlaxMT5ForConditionalGeneration", "FlaxMT5Model"] diff --git a/src/transformers/models/mt5/modeling_mt5.py b/src/transformers/models/mt5/modeling_mt5.py index 4e57d0aadda2..50d514be4a14 100644 --- a/src/transformers/models/mt5/modeling_mt5.py +++ b/src/transformers/models/mt5/modeling_mt5.py @@ -16,7 +16,6 @@ import copy import math -import os import warnings from typing import Optional, Union @@ -245,7 +244,6 @@ def __init__( "when creating this class." ) - # Mesh TensorFlow initialization to avoid scaling before softmax self.q = nn.Linear(self.d_model, self.inner_dim, bias=False) self.k = nn.Linear(self.d_model, self.inner_dim, bias=False) self.v = nn.Linear(self.d_model, self.inner_dim, bias=False) @@ -630,112 +628,6 @@ def forward( ) # hidden-states, (self-attention position bias), (self-attention weights), (cross-attention position bias), (cross-attention weights) -def load_tf_weights_in_mt5(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - tf_weights = {} - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - tf_weights[name] = array - - for txt_name in names: - name = txt_name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - tf_weights.pop(txt_name, None) - continue - if "_slot_" in name[-1]: - logger.info(f"Skipping {'/'.join(name)}") - tf_weights.pop(txt_name, None) - continue - pointer = model - array = tf_weights[txt_name] - - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] in ["kernel", "scale", "embedding"]: - pointer = getattr(pointer, "weight") - elif scope_names[0] == "self_attention": - pointer = getattr(pointer, "layer") - pointer = pointer[0] - elif scope_names[0] == "enc_dec_attention": - pointer = getattr(pointer, "layer") - pointer = pointer[1] - elif scope_names[0] == "dense_relu_dense": - pointer = getattr(pointer, "layer") - pointer = pointer[2] - elif scope_names[0] == "rms_norm": - if hasattr(pointer, "layer_norm"): - pointer = getattr(pointer, "layer_norm") - elif hasattr(pointer, "final_layer_norm"): - pointer = getattr(pointer, "final_layer_norm") - elif scope_names[0] == "scale": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - elif scope_names[0] == "decoder" and name[1] == "logits": - continue - elif scope_names[0] == "logits": - pointer = getattr(pointer, "lm_head") - elif scope_names[0] == "wi" and len(scope_names) > 1 and scope_names[1].isdigit(): - pointer = getattr(pointer, f"wi_{scope_names[1]}") - continue - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if scope_names[0] not in ["kernel", "scale", "embedding"]: - pointer = getattr(pointer, "weight") - if scope_names[0] != "embedding": - logger.info(f"Transposing numpy weight of shape {array.shape} for {name}") - array = np.transpose(array) - try: - assert pointer.shape == array.shape, ( - f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched" - ) - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array.astype(np.float32)) - tf_weights.pop(txt_name, None) - - logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}.") - return model - - # Copied from transformers.models.t5.modeling_t5.T5ClassificationHead with T5->MT5 class MT5ClassificationHead(nn.Module): """Head for sentence-level classification tasks.""" @@ -759,7 +651,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: # Copied from transformers.models.t5.modeling_t5.T5PreTrainedModel with T5->MT5, t5->mt5 class MT5PreTrainedModel(PreTrainedModel): config: MT5Config - load_tf_weights = load_tf_weights_in_mt5 base_model_prefix = "transformer" is_parallelizable = True supports_gradient_checkpointing = True @@ -788,8 +679,6 @@ def _init_weights(self, module): module, (MT5Model, MT5ForConditionalGeneration, MT5EncoderModel, MT5ForQuestionAnswering), ): - # Mesh TensorFlow embeddings initialization - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L1624 module.shared.weight.data.normal_(mean=0.0, std=factor * 1.0) if hasattr(module, "lm_head") and not self.config.tie_word_embeddings: module.lm_head.weight.data.normal_(mean=0.0, std=factor * 1.0) @@ -808,9 +697,6 @@ def _init_weights(self, module): if hasattr(module.out_proj, "bias") and module.out_proj.bias is not None: module.out_proj.bias.data.zero_() elif isinstance(module, MT5DenseActDense): - # Mesh TensorFlow FF initialization - # See https://github.com/tensorflow/mesh/blob/master/mesh_tensorflow/transformer/transformer_layers.py#L56 - # and https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L89 module.wi.weight.data.normal_(mean=0.0, std=factor * ((self.config.d_model) ** -0.5)) if hasattr(module.wi, "bias") and module.wi.bias is not None: module.wi.bias.data.zero_() @@ -828,8 +714,6 @@ def _init_weights(self, module): if hasattr(module.wo, "bias") and module.wo.bias is not None: module.wo.bias.data.zero_() elif isinstance(module, MT5Attention): - # Mesh TensorFlow attention initialization to avoid scaling before softmax - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/attention.py#L136 d_model = self.config.d_model key_value_proj_dim = self.config.d_kv n_heads = self.config.num_heads @@ -1809,8 +1693,6 @@ def forward( sequence_output = sequence_output.to(self.lm_head.weight.device) if self.config.tie_word_embeddings: - # Rescale output before projecting on vocab - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586 sequence_output = sequence_output * (self.model_dim**-0.5) lm_logits = self.lm_head(sequence_output) @@ -1821,7 +1703,6 @@ def forward( # move labels to correct device to enable PP labels = labels.to(lm_logits.device) loss = loss_fct(lm_logits.view(-1, lm_logits.size(-1)), labels.view(-1)) - # TODO(thom): Add z_loss https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L666 if not return_dict: output = (lm_logits,) + decoder_outputs[1:] + encoder_outputs diff --git a/src/transformers/models/mt5/modeling_tf_mt5.py b/src/transformers/models/mt5/modeling_tf_mt5.py deleted file mode 100644 index 6152aea0a5ac..000000000000 --- a/src/transformers/models/mt5/modeling_tf_mt5.py +++ /dev/null @@ -1,98 +0,0 @@ -# coding=utf-8 -# Copyright 2020 Mesh TensorFlow authors, T5 Authors and 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. -"""Tensorflow mT5 model.""" - -from ...utils import logging -from ..t5.modeling_tf_t5 import TFT5EncoderModel, TFT5ForConditionalGeneration, TFT5Model -from .configuration_mt5 import MT5Config - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "T5Config" - - -class TFMT5Model(TFT5Model): - r""" - This class overrides [`TFT5Model`]. Please check the superclass for the appropriate documentation alongside usage - examples. - - Examples: - - ```python - >>> from transformers import TFMT5Model, AutoTokenizer - - >>> model = TFMT5Model.from_pretrained("google/mt5-small") - >>> tokenizer = AutoTokenizer.from_pretrained("google/mt5-small") - >>> article = "UN Offizier sagt, dass weiter verhandelt werden muss in Syrien." - >>> summary = "Weiter Verhandlung in Syrien." - >>> inputs = tokenizer(article, return_tensors="tf") - >>> labels = tokenizer(text_target=summary, return_tensors="tf") - - >>> outputs = model(input_ids=inputs["input_ids"], decoder_input_ids=labels["input_ids"]) - >>> hidden_states = outputs.last_hidden_state - ```""" - - model_type = "mt5" - config_class = MT5Config - - -class TFMT5ForConditionalGeneration(TFT5ForConditionalGeneration): - r""" - This class overrides [`TFT5ForConditionalGeneration`]. Please check the superclass for the appropriate - documentation alongside usage examples. - - Examples: - - ```python - >>> from transformers import TFMT5ForConditionalGeneration, AutoTokenizer - - >>> model = TFMT5ForConditionalGeneration.from_pretrained("google/mt5-small") - >>> tokenizer = AutoTokenizer.from_pretrained("google/mt5-small") - >>> article = "UN Offizier sagt, dass weiter verhandelt werden muss in Syrien." - >>> summary = "Weiter Verhandlung in Syrien." - >>> inputs = tokenizer(article, text_target=summary, return_tensors="tf") - - >>> outputs = model(**inputs) - >>> loss = outputs.loss - ```""" - - model_type = "mt5" - config_class = MT5Config - - -class TFMT5EncoderModel(TFT5EncoderModel): - r""" - This class overrides [`TFT5EncoderModel`]. Please check the superclass for the appropriate documentation alongside - usage examples. - - Examples: - - ```python - >>> from transformers import TFMT5EncoderModel, AutoTokenizer - - >>> model = TFMT5EncoderModel.from_pretrained("google/mt5-small") - >>> tokenizer = AutoTokenizer.from_pretrained("google/mt5-small") - >>> article = "UN Offizier sagt, dass weiter verhandelt werden muss in Syrien." - >>> input_ids = tokenizer(article, return_tensors="tf").input_ids - >>> outputs = model(input_ids) - >>> hidden_state = outputs.last_hidden_state - ```""" - - model_type = "mt5" - config_class = MT5Config - - -__all__ = ["TFMT5EncoderModel", "TFMT5ForConditionalGeneration", "TFMT5Model"] diff --git a/src/transformers/models/musicgen_melody/feature_extraction_musicgen_melody.py b/src/transformers/models/musicgen_melody/feature_extraction_musicgen_melody.py index ec23899e91e9..744471bab553 100644 --- a/src/transformers/models/musicgen_melody/feature_extraction_musicgen_melody.py +++ b/src/transformers/models/musicgen_melody/feature_extraction_musicgen_melody.py @@ -211,7 +211,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. return_attention_mask (`bool`, *optional*): diff --git a/src/transformers/models/myt5/convert_myt5_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/myt5/convert_myt5_original_tf_checkpoint_to_pytorch.py index 39653e4b1c77..0f8a17d1adce 100644 --- a/src/transformers/models/myt5/convert_myt5_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/myt5/convert_myt5_original_tf_checkpoint_to_pytorch.py @@ -15,14 +15,123 @@ """Convert MyT5 checkpoint.""" import argparse +import os -from transformers import T5Config, T5ForConditionalGeneration, load_tf_weights_in_t5 +import torch + +from transformers import T5Config, T5ForConditionalGeneration from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +def load_tf_weights_in_t5(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + tf_weights = {} + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + tf_weights[name] = array + + for txt_name in names: + name = txt_name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any( + n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + tf_weights.pop(txt_name, None) + continue + if "_slot_" in name[-1]: + logger.info(f"Skipping {'/'.join(name)}") + tf_weights.pop(txt_name, None) + continue + pointer = model + array = tf_weights[txt_name] + + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] in ["kernel", "scale", "embedding"]: + pointer = getattr(pointer, "weight") + elif scope_names[0] == "self_attention": + pointer = getattr(pointer, "layer") + pointer = pointer[0] + elif scope_names[0] == "enc_dec_attention": + pointer = getattr(pointer, "layer") + pointer = pointer[1] + elif scope_names[0] == "dense_relu_dense": + pointer = getattr(pointer, "layer") + pointer = pointer[2] + elif scope_names[0] == "rms_norm": + if hasattr(pointer, "layer_norm"): + pointer = getattr(pointer, "layer_norm") + elif hasattr(pointer, "final_layer_norm"): + pointer = getattr(pointer, "final_layer_norm") + elif scope_names[0] == "scale": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + elif scope_names[0] == "decoder" and name[1] == "logits": + continue + elif scope_names[0] == "logits": + pointer = getattr(pointer, "lm_head") + elif scope_names[0] == "wi" and len(scope_names) > 1 and scope_names[1].isdigit(): + pointer = getattr(pointer, f"wi_{scope_names[1]}") + continue + else: + try: + pointer = getattr(pointer, scope_names[0]) + except AttributeError: + logger.info(f"Skipping {'/'.join(name)}") + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if scope_names[0] not in ["kernel", "scale", "embedding"]: + pointer = getattr(pointer, "weight") + if scope_names[0] != "embedding": + logger.info(f"Transposing numpy weight of shape {array.shape} for {name}") + array = np.transpose(array) + try: + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array.astype(np.float32)) + tf_weights.pop(txt_name, None) + + logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}.") + return model + + # Copied from transformers.models.t5.convert_t5_original_tf_checkpoint_to_pytorch.convert_tf_checkpoint_to_pytorch def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, config_file, pytorch_dump_path): # Initialise PyTorch model diff --git a/src/transformers/models/nougat/image_processing_nougat.py b/src/transformers/models/nougat/image_processing_nougat.py index 0c0a51464b43..9cb26feafa10 100644 --- a/src/transformers/models/nougat/image_processing_nougat.py +++ b/src/transformers/models/nougat/image_processing_nougat.py @@ -419,10 +419,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -451,10 +449,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/nystromformer/modeling_nystromformer.py b/src/transformers/models/nystromformer/modeling_nystromformer.py index 3eb1fad24019..03c134ccadae 100755 --- a/src/transformers/models/nystromformer/modeling_nystromformer.py +++ b/src/transformers/models/nystromformer/modeling_nystromformer.py @@ -52,8 +52,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings + 2, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -449,8 +447,6 @@ class NystromformerPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/oneformer/image_processing_oneformer.py b/src/transformers/models/oneformer/image_processing_oneformer.py index 615c71593062..abd178926d71 100644 --- a/src/transformers/models/oneformer/image_processing_oneformer.py +++ b/src/transformers/models/oneformer/image_processing_oneformer.py @@ -700,10 +700,7 @@ def preprocess( do_reduce_labels = do_reduce_labels if do_reduce_labels is not None else self.do_reduce_labels if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, @@ -718,8 +715,7 @@ def preprocess( if segmentation_maps is not None and not valid_images(segmentation_maps): raise ValueError( - "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." + "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor" ) images = make_flat_list_of_images(images) @@ -815,10 +811,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): diff --git a/src/transformers/models/openai/__init__.py b/src/transformers/models/openai/__init__.py index a07b0ab669f3..98a22135ea40 100644 --- a/src/transformers/models/openai/__init__.py +++ b/src/transformers/models/openai/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_openai import * from .modeling_openai import * - from .modeling_tf_openai import * from .tokenization_openai import * from .tokenization_openai_fast import * else: diff --git a/src/transformers/models/openai/convert_openai_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/openai/convert_openai_original_tf_checkpoint_to_pytorch.py index 3d5218c20426..df8dddce9828 100755 --- a/src/transformers/models/openai/convert_openai_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/openai/convert_openai_original_tf_checkpoint_to_pytorch.py @@ -15,14 +15,95 @@ """Convert OpenAI GPT checkpoint.""" import argparse +import json +import os import torch -from transformers import OpenAIGPTConfig, OpenAIGPTModel, load_tf_weights_in_openai_gpt +from transformers import OpenAIGPTConfig, OpenAIGPTModel from transformers.utils import CONFIG_NAME, WEIGHTS_NAME, logging logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def load_tf_weights_in_openai_gpt(model, config, openai_checkpoint_folder_path): + """Load tf pre-trained weights in a pytorch model (from NumPy arrays here)""" + import re + + import numpy as np + + if ".ckpt" in openai_checkpoint_folder_path: + openai_checkpoint_folder_path = os.path.dirname(openai_checkpoint_folder_path) + + logger.info(f"Loading weights from {openai_checkpoint_folder_path}") + + with open(openai_checkpoint_folder_path + "/parameters_names.json", "r", encoding="utf-8") as names_handle: + names = json.load(names_handle) + with open(openai_checkpoint_folder_path + "/params_shapes.json", "r", encoding="utf-8") as shapes_handle: + shapes = json.load(shapes_handle) + offsets = np.cumsum([np.prod(shape) for shape in shapes]) + init_params = [np.load(openai_checkpoint_folder_path + f"/params_{n}.npy") for n in range(10)] + init_params = np.split(np.concatenate(init_params, 0), offsets)[:-1] + init_params = [param.reshape(shape) for param, shape in zip(init_params, shapes)] + + # This was used when we had a single embedding matrix for positions and tokens + # init_params[0] = np.concatenate([init_params[1], init_params[0]], 0) + # del init_params[1] + init_params = [arr.squeeze() for arr in init_params] + + # Check that the token and position embeddings weight dimensions map those of the init parameters. + if model.tokens_embed.weight.shape != init_params[1].shape: + raise ValueError( + f"tokens_embed.weight.shape: {model.tokens_embed.weight.shape} does not match init_param[1].shape:" + f" {init_params[1].shape}" + ) + + if model.positions_embed.weight.shape != init_params[0].shape: + raise ValueError( + f"positions_embed.weight.shape: {model.positions_embed.weight.shape} does not match init_param[0].shape:" + f" {init_params[0].shape}" + ) + + model.tokens_embed.weight.data = torch.from_numpy(init_params[1]) + model.positions_embed.weight.data = torch.from_numpy(init_params[0]) + names.pop(0) + # Pop position and token embedding arrays + init_params.pop(0) + init_params.pop(0) + + for name, array in zip(names, init_params): # names[1:n_transfer], init_params[1:n_transfer]): + name = name[6:] # skip "model/" + if name[-2:] != ":0": + raise ValueError(f"Layer {name} does not end with :0") + name = name[:-2] + name = name.split("/") + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+\d+", m_name): + scope_names = re.split(r"(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "g": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "b": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "w": + pointer = getattr(pointer, "weight") + else: + pointer = getattr(pointer, scope_names[0]) + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + + # Ensure that the pointer and array have compatible shapes. + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + return model def convert_openai_checkpoint_to_pytorch(openai_checkpoint_folder_path, openai_config_file, pytorch_dump_folder_path): diff --git a/src/transformers/models/openai/modeling_openai.py b/src/transformers/models/openai/modeling_openai.py index 44fa05227ff8..a1b6bf2ed579 100644 --- a/src/transformers/models/openai/modeling_openai.py +++ b/src/transformers/models/openai/modeling_openai.py @@ -15,9 +15,7 @@ # limitations under the License. """PyTorch OpenAI GPT model.""" -import json import math -import os from dataclasses import dataclass from typing import Any, Callable, Optional, Union @@ -41,84 +39,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_openai_gpt(model, config, openai_checkpoint_folder_path): - """Load tf pre-trained weights in a pytorch model (from NumPy arrays here)""" - import re - - import numpy as np - - if ".ckpt" in openai_checkpoint_folder_path: - openai_checkpoint_folder_path = os.path.dirname(openai_checkpoint_folder_path) - - logger.info(f"Loading weights from {openai_checkpoint_folder_path}") - - with open(openai_checkpoint_folder_path + "/parameters_names.json", "r", encoding="utf-8") as names_handle: - names = json.load(names_handle) - with open(openai_checkpoint_folder_path + "/params_shapes.json", "r", encoding="utf-8") as shapes_handle: - shapes = json.load(shapes_handle) - offsets = np.cumsum([np.prod(shape) for shape in shapes]) - init_params = [np.load(openai_checkpoint_folder_path + f"/params_{n}.npy") for n in range(10)] - init_params = np.split(np.concatenate(init_params, 0), offsets)[:-1] - init_params = [param.reshape(shape) for param, shape in zip(init_params, shapes)] - - # This was used when we had a single embedding matrix for positions and tokens - # init_params[0] = np.concatenate([init_params[1], init_params[0]], 0) - # del init_params[1] - init_params = [arr.squeeze() for arr in init_params] - - # Check that the token and position embeddings weight dimensions map those of the init parameters. - if model.tokens_embed.weight.shape != init_params[1].shape: - raise ValueError( - f"tokens_embed.weight.shape: {model.tokens_embed.weight.shape} does not match init_param[1].shape:" - f" {init_params[1].shape}" - ) - - if model.positions_embed.weight.shape != init_params[0].shape: - raise ValueError( - f"positions_embed.weight.shape: {model.positions_embed.weight.shape} does not match init_param[0].shape:" - f" {init_params[0].shape}" - ) - - model.tokens_embed.weight.data = torch.from_numpy(init_params[1]) - model.positions_embed.weight.data = torch.from_numpy(init_params[0]) - names.pop(0) - # Pop position and token embedding arrays - init_params.pop(0) - init_params.pop(0) - - for name, array in zip(names, init_params): # names[1:n_transfer], init_params[1:n_transfer]): - name = name[6:] # skip "model/" - if name[-2:] != ":0": - raise ValueError(f"Layer {name} does not end with :0") - name = name[:-2] - name = name.split("/") - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+\d+", m_name): - scope_names = re.split(r"(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "g": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "b": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "w": - pointer = getattr(pointer, "weight") - else: - pointer = getattr(pointer, scope_names[0]) - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - - # Ensure that the pointer and array have compatible shapes. - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - ACT_FNS = {"relu": nn.ReLU(), "silu": silu, "gelu": gelu_new, "swish": silu} @@ -126,7 +46,6 @@ class Attention(nn.Module): def __init__(self, nx, n_positions, config, scale=False): super().__init__() n_state = nx # in Attention: n_state=768 (nx=n_embd) - # [switch nx => n_state from Block to Attention to keep identical to TF implementation] if n_state % config.n_head != 0: raise ValueError(f"Attention n_state shape: {n_state} must be divisible by config.n_head {config.n_head}") self.register_buffer( @@ -163,7 +82,6 @@ def _attn(self, q, k, v, attention_mask=None, head_mask=None, output_attentions= w = torch.matmul(q, k) if self.scale: w = w / math.sqrt(v.size(-1)) - # w = w * self.bias + -1e9 * (1 - self.bias) # TF implementation method: mask_attn_weights # XD: self.b may be larger than w, so we need to crop it b = self.bias[:, :, : w.size(-2), : w.size(-1)] w = w * b + -1e4 * (1 - b) @@ -187,11 +105,11 @@ def _attn(self, q, k, v, attention_mask=None, head_mask=None, output_attentions= def merge_heads(self, x): x = x.permute(0, 2, 1, 3).contiguous() new_x_shape = x.size()[:-2] + (x.size(-2) * x.size(-1),) - return x.view(*new_x_shape) # in Tensorflow implementation: fct merge_states + return x.view(*new_x_shape) def split_heads(self, x, k=False): new_x_shape = x.size()[:-1] + (self.n_head, x.size(-1) // self.n_head) - x = x.view(*new_x_shape) # in Tensorflow implementation: fct split_states + x = x.view(*new_x_shape) if k: return x.permute(0, 2, 3, 1) else: @@ -359,14 +277,11 @@ def forward( @auto_docstring class OpenAIGPTPreTrainedModel(PreTrainedModel): config: OpenAIGPTConfig - load_tf_weights = load_tf_weights_in_openai_gpt base_model_prefix = "transformer" def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, (nn.Linear, Conv1D)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -849,5 +764,4 @@ def forward( "OpenAIGPTLMHeadModel", "OpenAIGPTModel", "OpenAIGPTPreTrainedModel", - "load_tf_weights_in_openai_gpt", ] diff --git a/src/transformers/models/openai/modeling_tf_openai.py b/src/transformers/models/openai/modeling_tf_openai.py deleted file mode 100644 index 0235159633b4..000000000000 --- a/src/transformers/models/openai/modeling_tf_openai.py +++ /dev/null @@ -1,936 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The OpenAI Team Authors and HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 OpenAI GPT model.""" - -from __future__ import annotations - -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import TFBaseModelOutput, TFCausalLMOutput, TFSequenceClassifierOutput -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFConv1D, - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - TFSequenceSummary, - TFSharedEmbeddings, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_openai import OpenAIGPTConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "openai-community/openai-gpt" -_CONFIG_FOR_DOC = "OpenAIGPTConfig" - - -class TFAttention(keras.layers.Layer): - def __init__(self, nx, config, scale=False, **kwargs): - super().__init__(**kwargs) - - n_state = nx # in Attention: n_state=768 (nx=n_embd) - # [switch nx => n_state from Block to Attention to keep identical to TF implementation] - assert n_state % config.n_head == 0, ( - f"Hidden dimension {n_state} not dividable by number of heads {config.n_head}" - ) - self.n_head = config.n_head - self.split_size = n_state - self.scale = scale - self.output_attentions = config.output_attentions - - self.c_attn = TFConv1D(n_state * 3, nx, initializer_range=config.initializer_range, name="c_attn") - self.c_proj = TFConv1D(n_state, nx, initializer_range=config.initializer_range, name="c_proj") - self.attn_dropout = keras.layers.Dropout(config.attn_pdrop) - self.resid_dropout = keras.layers.Dropout(config.resid_pdrop) - self.n_state = n_state - self.pruned_heads = set() - - def prune_heads(self, heads): - pass - - @staticmethod - def causal_attention_mask(nd, ns): - """ - 1's in the lower triangle, counting from the lower right corner. Same as tf.matrix_band_part(tf.ones([nd, ns]), - -1, ns-nd), but doesn't produce garbage on TPUs. - """ - i = tf.range(nd)[:, None] - j = tf.range(ns) - m = i >= j - ns + nd - return m - - def _attn(self, q, k, v, attention_mask, head_mask, output_attentions, training=False): - # q, k, v have shape [batch, heads, sequence, features] - w = tf.matmul(q, k, transpose_b=True) - if self.scale: - dk = tf.cast(shape_list(k)[-1], dtype=w.dtype) # scale attention_scores - w = w / tf.math.sqrt(dk) - - # w has shape [batch, heads, dst_sequence, src_sequence], where information flows from src to dst. - _, _, nd, ns = shape_list(w) - b = tf.cast(self.causal_attention_mask(nd, ns), dtype=w.dtype) - b = tf.reshape(b, [1, 1, nd, ns]) - w = w * b - 1e4 * (1 - b) - - if attention_mask is not None: - # Apply the attention mask - attention_mask = tf.cast(attention_mask, dtype=w.dtype) - w = w + attention_mask - - w = stable_softmax(w, axis=-1) - w = self.attn_dropout(w, training=training) - - # Mask heads if we want to - if head_mask is not None: - w = w * head_mask - - outputs = [tf.matmul(w, v)] - if output_attentions: - outputs.append(w) - return outputs - - def merge_heads(self, x): - x = tf.transpose(x, [0, 2, 1, 3]) - x_shape = shape_list(x) - new_x_shape = x_shape[:-2] + [x_shape[-2] * x_shape[-1]] - return tf.reshape(x, new_x_shape) - - def split_heads(self, x): - x_shape = shape_list(x) - new_x_shape = x_shape[:-1] + [self.n_head, x_shape[-1] // self.n_head] - x = tf.reshape(x, new_x_shape) - return tf.transpose(x, (0, 2, 1, 3)) # (batch, head, seq_length, head_features) - - def call(self, x, attention_mask, head_mask, output_attentions, training=False): - x = self.c_attn(x) - query, key, value = tf.split(x, 3, axis=2) - query = self.split_heads(query) - key = self.split_heads(key) - value = self.split_heads(value) - - attn_outputs = self._attn(query, key, value, attention_mask, head_mask, output_attentions, training=training) - a = attn_outputs[0] - - a = self.merge_heads(a) - a = self.c_proj(a) - a = self.resid_dropout(a, training=training) - - outputs = [a] + attn_outputs[1:] - return outputs # a, (attentions) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "c_attn", None) is not None: - with tf.name_scope(self.c_attn.name): - self.c_attn.build([None, None, self.n_state * 3]) - if getattr(self, "c_proj", None) is not None: - with tf.name_scope(self.c_proj.name): - self.c_proj.build([None, None, self.n_state]) - - -class TFMLP(keras.layers.Layer): - def __init__(self, n_state, config, **kwargs): - super().__init__(**kwargs) - nx = config.n_embd - self.c_fc = TFConv1D(n_state, nx, initializer_range=config.initializer_range, name="c_fc") - self.c_proj = TFConv1D(nx, n_state, initializer_range=config.initializer_range, name="c_proj") - self.act = get_tf_activation("gelu") - self.dropout = keras.layers.Dropout(config.resid_pdrop) - self.nx = nx - self.n_state = n_state - - def call(self, x, training=False): - h = self.act(self.c_fc(x)) - h2 = self.c_proj(h) - h2 = self.dropout(h2, training=training) - return h2 - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "c_fc", None) is not None: - with tf.name_scope(self.c_fc.name): - self.c_fc.build([None, None, self.n_state]) - if getattr(self, "c_proj", None) is not None: - with tf.name_scope(self.c_proj.name): - self.c_proj.build([None, None, self.nx]) - - -class TFBlock(keras.layers.Layer): - def __init__(self, config, scale=False, **kwargs): - super().__init__(**kwargs) - nx = config.n_embd - self.attn = TFAttention(nx, config, scale, name="attn") - self.ln_1 = keras.layers.LayerNormalization(epsilon=config.layer_norm_epsilon, name="ln_1") - self.mlp = TFMLP(4 * nx, config, name="mlp") - self.ln_2 = keras.layers.LayerNormalization(epsilon=config.layer_norm_epsilon, name="ln_2") - self.nx = nx - - def call(self, x, attention_mask, head_mask, output_attentions, training=False): - output_attn = self.attn(x, attention_mask, head_mask, output_attentions, training=training) - a = output_attn[0] # output_attn: a, (attentions) - - n = self.ln_1(x + a) - m = self.mlp(n, training=training) - h = self.ln_2(n + m) - - outputs = [h] + output_attn[1:] - return outputs # x, (attentions) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attn", None) is not None: - with tf.name_scope(self.attn.name): - self.attn.build(None) - if getattr(self, "ln_1", None) is not None: - with tf.name_scope(self.ln_1.name): - self.ln_1.build([None, None, self.nx]) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "ln_2", None) is not None: - with tf.name_scope(self.ln_2.name): - self.ln_2.build([None, None, self.nx]) - - -@keras_serializable -class TFOpenAIGPTMainLayer(keras.layers.Layer): - config_class = OpenAIGPTConfig - - def __init__(self, config, *inputs, **kwargs): - super().__init__(*inputs, **kwargs) - - self.config = config - self.output_hidden_states = config.output_hidden_states - self.output_attentions = config.output_attentions - self.return_dict = config.use_return_dict - self.num_hidden_layers = config.n_layer - self.n_embd = config.n_embd - self.n_positions = config.n_positions - self.initializer_range = config.initializer_range - - self.tokens_embed = TFSharedEmbeddings( - config.vocab_size, config.n_embd, initializer_range=config.initializer_range, name="tokens_embed" - ) - self.drop = keras.layers.Dropout(config.embd_pdrop) - self.h = [TFBlock(config, scale=True, name=f"h_._{i}") for i in range(config.n_layer)] - - def build(self, input_shape=None): - with tf.name_scope("positions_embed"): - self.positions_embed = self.add_weight( - name="embeddings", - shape=[self.n_positions, self.n_embd], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "tokens_embed", None) is not None: - with tf.name_scope(self.tokens_embed.name): - self.tokens_embed.build(None) - if getattr(self, "h", None) is not None: - for layer in self.h: - with tf.name_scope(layer.name): - layer.build(None) - - def get_input_embeddings(self): - return self.tokens_embed - - def set_input_embeddings(self, value): - self.tokens_embed.weight = value - self.tokens_embed.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutput: - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - input_ids = tf.reshape(input_ids, [-1, input_shape[-1]]) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if position_ids is None: - position_ids = tf.expand_dims(tf.range(input_shape[-1]), axis=0) - - if attention_mask is not None: - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - - one_cst = tf.constant(1.0) - attention_mask = tf.cast(attention_mask, dtype=one_cst.dtype) - attention_mask = tf.multiply(tf.subtract(one_cst, attention_mask), tf.constant(-10000.0)) - else: - attention_mask = None - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.num_hidden_layers - # head_mask = tf.constant([0] * self.num_hidden_layers) - - position_ids = tf.reshape(position_ids, [-1, shape_list(position_ids)[-1]]) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = self.tokens_embed(input_ids, mode="embedding") - position_embeds = tf.gather(self.positions_embed, position_ids) - if token_type_ids is not None: - token_type_ids = tf.reshape(token_type_ids, [-1, shape_list(token_type_ids)[-1]]) - check_embeddings_within_bounds(token_type_ids, self.config.vocab_size, "token_type_ids") - token_type_embeds = self.tokens_embed(token_type_ids, mode="embedding") - else: - token_type_embeds = 0 - hidden_states = inputs_embeds + position_embeds + token_type_embeds - hidden_states = self.drop(hidden_states, training=training) - - output_shape = input_shape + [shape_list(hidden_states)[-1]] - - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - for i, block in enumerate(self.h): - if output_hidden_states: - all_hidden_states = all_hidden_states + (tf.reshape(hidden_states, output_shape),) - - outputs = block( - hidden_states, - attention_mask, - head_mask[i], - output_attentions, - training=training, - ) - hidden_states = outputs[0] - if output_attentions: - all_attentions = all_attentions + (outputs[1],) - - hidden_states = tf.reshape(hidden_states, output_shape) - # Add last hidden state - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if output_attentions: - # let the number of heads free (-1) so we can extract attention even after head pruning - attention_output_shape = input_shape[:-1] + [-1] + shape_list(all_attentions[0])[-2:] - all_attentions = tuple(tf.reshape(t, attention_output_shape) for t in all_attentions) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - ) - - -class TFOpenAIGPTPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = OpenAIGPTConfig - base_model_prefix = "transformer" - - -@dataclass -class TFOpenAIGPTDoubleHeadsModelOutput(ModelOutput): - """ - Base class for outputs of models predicting if two sentences are consecutive or not. - - Args: - logits (`tf.Tensor` of shape `(batch_size, num_choices, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - mc_logits (`tf.Tensor` of shape `(batch_size, num_choices)`): - Prediction scores of the multiple choice classification head (scores for each choice before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: tf.Tensor | None = None - mc_logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -OPENAI_GPT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`OpenAIGPTConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -OPENAI_GPT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`tf.Tensor` or `Numpy array` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare OpenAI GPT transformer model outputting raw hidden-states without any specific head on top.", - OPENAI_GPT_START_DOCSTRING, -) -class TFOpenAIGPTModel(TFOpenAIGPTPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFOpenAIGPTMainLayer(config, name="transformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(OPENAI_GPT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutput: - outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -@add_start_docstrings( - """ - OpenAI GPT Model transformer with a language modeling head on top (linear layer with weights tied to the input - embeddings). - """, - OPENAI_GPT_START_DOCSTRING, -) -class TFOpenAIGPTLMHeadModel(TFOpenAIGPTPreTrainedModel, TFCausalLanguageModelingLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFOpenAIGPTMainLayer(config, name="transformer") - # OpenAIGPT does not have past caching features - self.supports_xla_generation = False - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - @unpack_inputs - @add_start_docstrings_to_model_forward(OPENAI_GPT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFCausalLMOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = transformer_outputs[0] - - logits = self.transformer.tokens_embed(hidden_states, mode="linear") - - loss = None - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels, shifted_logits) - - if not return_dict: - output = (logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutput( - loss=loss, - logits=logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def prepare_inputs_for_generation(self, inputs, **kwargs): - return {"input_ids": inputs} - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -@add_start_docstrings( - """ - OpenAI GPT Model transformer with a language modeling and a multiple-choice classification head on top e.g. for - RocStories/SWAG tasks. The two heads are two linear layers. The language modeling head has its weights tied to the - input embeddings, the classification head takes as input the input of a specified classification token index in the - input sequence). - """, - OPENAI_GPT_START_DOCSTRING, -) -class TFOpenAIGPTDoubleHeadsModel(TFOpenAIGPTPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - config.num_labels = 1 - self.transformer = TFOpenAIGPTMainLayer(config, name="transformer") - self.multiple_choice_head = TFSequenceSummary( - config, initializer_range=config.initializer_range, name="multiple_choice_head" - ) - - @unpack_inputs - @add_start_docstrings_to_model_forward(OPENAI_GPT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFOpenAIGPTDoubleHeadsModelOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - mc_token_ids: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFOpenAIGPTDoubleHeadsModelOutput: - r""" - mc_token_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, num_choices)`, *optional*, default to index of the last token of the input): - Index of the classification token in each input sequence. Selected in the range `[0, input_ids.size(-1) - - 1]`. - - Return: - - Examples: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, TFOpenAIGPTDoubleHeadsModel - - >>> tokenizer = AutoTokenizer.from_pretrained("openai-community/openai-gpt") - >>> model = TFOpenAIGPTDoubleHeadsModel.from_pretrained("openai-community/openai-gpt") - - >>> # Add a [CLS] to the vocabulary (we should train it also!) - >>> tokenizer.add_special_tokens({"cls_token": "[CLS]"}) - >>> model.resize_token_embeddings(len(tokenizer)) # Update the model embeddings with the new vocabulary size - >>> print(tokenizer.cls_token_id, len(tokenizer)) # The newly token the last token of the vocabulary - - >>> choices = ["Hello, my dog is cute [CLS]", "Hello, my cat is cute [CLS]"] - >>> encoding = tokenizer(choices, return_tensors="tf") - >>> inputs = {k: tf.expand_dims(v, 0) for k, v in encoding.items()} - >>> inputs["mc_token_ids"] = tf.constant( - ... [inputs["input_ids"].shape[-1] - 1, inputs["input_ids"].shape[-1] - 1] - ... )[ - ... None, : - ... ] # Batch size 1 - >>> outputs = model(inputs) - >>> lm_prediction_scores, mc_prediction_scores = outputs[:2] - ```""" - - if input_ids is not None: - input_shapes = shape_list(input_ids) - else: - input_shapes = shape_list(inputs_embeds)[:-1] - - seq_length = input_shapes[-1] - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - transformer_outputs = self.transformer( - flat_input_ids, - flat_attention_mask, - flat_token_type_ids, - flat_position_ids, - head_mask, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = transformer_outputs[0] - hidden_states = tf.reshape(hidden_states, input_shapes + shape_list(hidden_states)[-1:]) - if return_dict and output_hidden_states: - # We do this to match the slightly odd PT behaviour - the final hidden state is reshaped to rank 4 when the - # input is rank 3, but all other hidden states remain at rank-3 (with the first 2 dims merged) - all_hidden_states = transformer_outputs.hidden_states[:-1] + (hidden_states,) - else: - all_hidden_states = None - lm_logits = self.transformer.tokens_embed(hidden_states, mode="linear") - mc_logits = self.multiple_choice_head(hidden_states, mc_token_ids, training=training) - mc_logits = tf.squeeze(mc_logits, axis=-1) - - if not return_dict: - return (lm_logits, mc_logits) + transformer_outputs[1:] - - return TFOpenAIGPTDoubleHeadsModelOutput( - logits=lm_logits, - mc_logits=mc_logits, - hidden_states=all_hidden_states, - attentions=transformer_outputs.attentions, - ) - - @property - def input_signature(self): - return { - "input_ids": tf.TensorSpec((None, None, None), tf.int32, name="input_ids"), - "attention_mask": tf.TensorSpec((None, None, None), tf.int32, name="attention_mask"), - "mc_token_ids": tf.TensorSpec((None, None), tf.int32, name="token_type_ids"), - } - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "multiple_choice_head", None) is not None: - with tf.name_scope(self.multiple_choice_head.name): - self.multiple_choice_head.build(None) - - -@add_start_docstrings( - """ - The OpenAI GPT Model transformer with a sequence classification head on top (linear layer). - - [`TFOpenAIGPTForSequenceClassification`] uses the last token in order to do the classification, as other causal - models (e.g. GPT-2) do. - - Since it does classification on the last token, it requires to know the position of the last token. If a - `pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If - no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the - padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in - each row of the batch). - """, - OPENAI_GPT_START_DOCSTRING, -) -class TFOpenAIGPTForSequenceClassification(TFOpenAIGPTPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.score = keras.layers.Dense( - config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="score", - use_bias=False, - ) - self.transformer = TFOpenAIGPTMainLayer(config, name="transformer") - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(OPENAI_GPT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple | TFSequenceClassifierOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = transformer_outputs[0] - logits = self.score(hidden_states) - logits_shape = shape_list(logits) - batch_size = logits_shape[0] - - if self.config.pad_token_id is None: - last_non_pad_token = tf.fill((batch_size,), value=logits_shape[1] - 1) - else: - if input_ids is not None: - token_indices = tf.range(shape_list(input_ids)[-1]) - non_pad_mask = tf.cast(input_ids != self.config.pad_token_id, token_indices.dtype) - last_non_pad_token = tf.reduce_max(token_indices * non_pad_mask, axis=-1) - else: - last_non_pad_token = tf.fill((batch_size,), value=logits_shape[1] - 1) - logger.warning_once( - f"{self.__class__.__name__} will not detect padding tokens in `inputs_embeds`. Results may be " - "unexpected if using padding tokens in conjunction with `inputs_embeds.`" - ) - loss = None - - pooled_logits = tf.gather(logits, last_non_pad_token, batch_dims=1, axis=1) - - if labels is not None: - if self.config.pad_token_id is None and logits_shape[0] != 1: - raise ValueError("Cannot handle batch sizes > 1 if no padding token is defined.") - - loss = self.hf_compute_loss(tf.reshape(labels, [-1]), tf.reshape(pooled_logits, [-1, self.num_labels])) - - if not return_dict: - output = (pooled_logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=pooled_logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "score", None) is not None: - with tf.name_scope(self.score.name): - self.score.build([None, None, self.config.n_embd]) - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -__all__ = [ - "TFOpenAIGPTDoubleHeadsModel", - "TFOpenAIGPTForSequenceClassification", - "TFOpenAIGPTLMHeadModel", - "TFOpenAIGPTMainLayer", - "TFOpenAIGPTModel", - "TFOpenAIGPTPreTrainedModel", -] diff --git a/src/transformers/models/opt/__init__.py b/src/transformers/models/opt/__init__.py index d230de5ecadc..ecf8f8dee945 100644 --- a/src/transformers/models/opt/__init__.py +++ b/src/transformers/models/opt/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_opt import * - from .modeling_flax_opt import * from .modeling_opt import * - from .modeling_tf_opt import * else: import sys diff --git a/src/transformers/models/opt/modeling_flax_opt.py b/src/transformers/models/opt/modeling_flax_opt.py deleted file mode 100644 index d2f77ecbee26..000000000000 --- a/src/transformers/models/opt/modeling_flax_opt.py +++ /dev/null @@ -1,802 +0,0 @@ -# coding=utf-8 -# Copyright 2022 The Fairseq Authors and The Google Flax Team Authors And The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax OPT model.""" - -from functools import partial -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxMaskedLMOutput -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring -from ...utils import add_start_docstrings, logging -from .configuration_opt import OPTConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/opt-350m" -_CONFIG_FOR_DOC = "OPTConfig" - - -OPT_START_DOCSTRING = r""" - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`OPTConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -OPT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention with Bart->OPT -class FlaxOPTAttention(nn.Module): - config: OPTConfig - embed_dim: int - num_heads: int - dropout: float = 0.0 - causal: bool = False - bias: bool = True - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self) -> None: - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {self.num_heads})." - ) - - dense = partial( - nn.Dense, - self.embed_dim, - use_bias=self.bias, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() - self.out_proj = dense() - - self.dropout_layer = nn.Dropout(rate=self.dropout) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states: jnp.ndarray, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.q_proj(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.k_proj(key_value_states) - value_states = self.v_proj(key_value_states) - else: - # self_attention - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights - - -class FlaxOPTDecoderLayer(nn.Module): - config: OPTConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.hidden_size - self.self_attn = FlaxOPTAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.num_attention_heads, - dropout=self.config.attention_dropout, - causal=True, - dtype=self.dtype, - ) - self.do_layer_norm_before = self.config.do_layer_norm_before - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.fc1 = nn.Dense( - self.config.ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - init_cache: bool = False, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - - # 125m, 1.7B, ..., 175B applies layer norm BEFORE attention - if self.do_layer_norm_before: - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - hidden_states, self_attn_weights = self.self_attn( - hidden_states=hidden_states, - attention_mask=attention_mask, - init_cache=init_cache, - deterministic=deterministic, - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - # 350m applies layer norm AFTER attention - if not self.do_layer_norm_before: - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Fully Connected - hidden_states_shape = hidden_states.shape - hidden_states = hidden_states.reshape(-1, hidden_states.shape[-1]) - residual = hidden_states - - # 125m, 1.7B, ..., 175B applies layer norm BEFORE attention - if self.do_layer_norm_before: - hidden_states = self.final_layer_norm(hidden_states) - - hidden_states = self.fc1(hidden_states) - hidden_states = self.activation_fn(hidden_states) - - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - hidden_states = (residual + hidden_states).reshape(hidden_states_shape) - - # 350m applies layer norm AFTER attention - if not self.do_layer_norm_before: - hidden_states = self.final_layer_norm(hidden_states) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights,) - - return outputs - - -class FlaxOPTDecoderLayerCollection(nn.Module): - config: OPTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxOPTDecoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - self.layerdrop = self.config.layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - ): - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - - for decoder_layer in self.layers: - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = decoder_layer( - hidden_states, - attention_mask=attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - deterministic=deterministic, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attns += (layer_outputs[1],) - - outputs = [hidden_states, all_hidden_states, all_self_attns] - return outputs - - -class FlaxOPTLearnedPositionalEmbedding(nn.Embed): - """ - This module learns positional embeddings up to a fixed maximum size. - """ - - def setup(self): - self.offset = 2 - self.embedding = self.param( - "embedding", self.embedding_init, (self.num_embeddings + self.offset, self.features), self.param_dtype - ) - - def __call__(self, positions): - """`input_ids_shape` is expected to be [bsz x seqlen].""" - - return super().__call__(positions + self.offset) - - -class FlaxOPTDecoder(nn.Module): - config: OPTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - offset: int = 2 - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.hidden_size - self.padding_idx = self.config.pad_token_id - self.max_target_positions = self.config.max_position_embeddings - - self.embed_tokens = nn.Embed( - self.config.vocab_size, - self.config.word_embed_proj_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - - self.embed_positions = FlaxOPTLearnedPositionalEmbedding( - self.config.max_position_embeddings, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - - if self.config.word_embed_proj_dim != self.config.hidden_size: - self.project_in = nn.Dense(self.config.hidden_size, use_bias=False) - self.project_out = nn.Dense(self.config.word_embed_proj_dim, use_bias=False) - - else: - self.project_in = None - self.project_out = None - - # Note that the only purpose of `config._remove_final_layer_norm` is to keep backward compatibility - # with checkpoints that have been fine-tuned before transformers v4.20.1 - # see https://github.com/facebookresearch/metaseq/pull/164 - if self.config.do_layer_norm_before and not self.config._remove_final_layer_norm: - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - else: - self.final_layer_norm = None - - self.layers = FlaxOPTDecoderLayerCollection(self.config, self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) - if self.project_in is not None: - inputs_embeds = self.project_in(inputs_embeds) - - positions = self.embed_positions(position_ids) - - hidden_states = inputs_embeds + positions - - hidden_state, all_hidden_states, attentions = self.layers( - hidden_states, - attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - ) - - if self.final_layer_norm is not None: - hidden_state = self.final_layer_norm(hidden_state) - - if self.project_out is not None: - hidden_state = self.project_out(hidden_state) - - if output_hidden_states: - all_hidden_states += (hidden_state,) - - outputs = [hidden_state, all_hidden_states, attentions] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_state, - hidden_states=all_hidden_states, - attentions=attentions, - ) - - -class FlaxOPTPreTrainedModel(FlaxPreTrainedModel): - config_class = OPTConfig - base_model_prefix: str = "model" - module_class: nn.Module = None - - def __init__( - self, - config: OPTConfig, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - position_ids, - return_dict=False, - ) - - random_params = module_init_outputs["params"] - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length), dtype="i4") - attention_mask = jnp.ones_like(input_ids, dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - params: Optional[dict] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - dropout_rng: PRNGKey = None, - deterministic: bool = True, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - if position_ids is None: - position_ids = (attention_mask.cumsum(axis=1) * attention_mask) - 1 - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed - # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be - # changed by FlaxOPTAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - return outputs - - -class FlaxOPTModule(nn.Module): - config: OPTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.decoder = FlaxOPTDecoder(self.config, dtype=self.dtype) - - def _get_decoder_module(self): - return self.decoder - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - init_cache=False, - ): - decoder_outputs = self.decoder( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - init_cache=init_cache, - ) - - if not return_dict: - return decoder_outputs - - return FlaxBaseModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - hidden_states=decoder_outputs.hidden_states, - attentions=decoder_outputs.attentions, - ) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartModel with Bart->OPT -class FlaxOPTModel(FlaxOPTPreTrainedModel): - config: OPTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - module_class = FlaxOPTModule - - -append_call_sample_docstring(FlaxOPTModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutput, _CONFIG_FOR_DOC) - - -@add_start_docstrings( - "The bare OPT Model transformer outputting raw hidden-states without any specific head on top.", - OPT_START_DOCSTRING, -) -class FlaxOPTForCausalLMModule(nn.Module): - config: OPTConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.model = FlaxOPTModule(config=self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids, - attention_mask, - position_ids, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = self.model.variables["params"]["decoder"]["embed_tokens"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - return (lm_logits,) + outputs[1:] - - return FlaxMaskedLMOutput( - logits=lm_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - OPT Model with a language modeling head on top (linear layer with weights tied to the input embeddings) e.g for - autoregressive tasks. - """, - OPT_START_DOCSTRING, -) -class FlaxOPTForCausalLM(FlaxOPTPreTrainedModel): - module_class = FlaxOPTForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyway. - # Thus, we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxOPTForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxBaseModelOutput, - _CONFIG_FOR_DOC, -) - - -__all__ = ["FlaxOPTForCausalLM", "FlaxOPTModel", "FlaxOPTPreTrainedModel"] diff --git a/src/transformers/models/opt/modeling_tf_opt.py b/src/transformers/models/opt/modeling_tf_opt.py deleted file mode 100644 index f996256063c0..000000000000 --- a/src/transformers/models/opt/modeling_tf_opt.py +++ /dev/null @@ -1,1092 +0,0 @@ -# coding=utf-8 -# Copyright 2022 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 OPT model.""" - -from __future__ import annotations - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import TFBaseModelOutputWithPast, TFCausalLMOutputWithPast - -# Public API -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - TFSharedEmbeddings, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_opt import OPTConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/opt-350m" -_CONFIG_FOR_DOC = "OPTConfig" - -# Base model docstring -_EXPECTED_OUTPUT_SHAPE = [1, 8, 1024] - -# Causal LM output -_CAUSAL_LM_EXPECTED_OUTPUT = ( - "Hey, are you conscious? Can you talk to me?\nI'm not conscious. I'm just a little bit of a weirdo." -) - -LARGE_NEGATIVE = -1e8 - - -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - # We need triu with k = 1 but TF expects known compile-time dims for that, so we hack around it - mask = tf.fill((tgt_len, tgt_len), tf.cast(LARGE_NEGATIVE, tf.float32)) - mask = tf.linalg.band_part(mask, 0, -1) - tf.linalg.band_part(mask, 0, 0) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -class TFOPTLearnedPositionalEmbedding(keras.layers.Embedding): - """ - This module learns positional embeddings up to a fixed maximum size. - """ - - def __init__(self, num_embeddings: int, embedding_dim: int, **kwargs): - # OPT is set up so that if padding_idx is specified then offset the embedding ids by 2 - # and adjust num_embeddings appropriately. Other models don't have this hack - self.offset = 2 - super().__init__(num_embeddings + self.offset, embedding_dim, **kwargs) - - def call(self, attention_mask, past_key_values_length: int = 0): - """`input_ids_shape` is expected to be [bsz x seqlen].""" - attention_mask = tf.cast(attention_mask, tf.int64) - - # create positions depending on attention_mask - positions = tf.math.cumsum(attention_mask, axis=1) * attention_mask - 1 - - # cut positions if `past_key_values_length` is > 0 - positions = positions[:, past_key_values_length:] - - return super().call(positions + self.offset) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with Bart->OPT -class TFOPTAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -class TFOPTDecoderLayer(keras.layers.Layer): - def __init__(self, config: OPTConfig, **kwargs): - super().__init__(**kwargs) - self.do_layer_norm_before = config.do_layer_norm_before - self.embed_dim = config.hidden_size - self.self_attn = TFOPTAttention( - embed_dim=self.embed_dim, - num_heads=config.num_attention_heads, - dropout=config.attention_dropout, - name="self_attn", - is_decoder=True, - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: np.ndarray | tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - training: bool | None = False, - output_attentions: bool | None = False, - use_cache: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`, *optional*): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`, *optional*): mask for attention heads in a given layer of size - `(decoder_attention_heads,)` - past_key_value (`Tuple(tf.Tensor)`, *optional*): cached past key and value projection states - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - residual = hidden_states - - # 125m, 1.7B, ..., 175B applies layer norm BEFORE attention - if self.do_layer_norm_before: - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # 350m applies layer norm AFTER attention - if not self.do_layer_norm_before: - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Fully Connected - residual = hidden_states - # 125m, 1.7B, ..., 175B applies layer norm BEFORE attention - if self.do_layer_norm_before: - hidden_states = self.final_layer_norm(hidden_states) - - hidden_states = self.fc1(hidden_states) - hidden_states = self.activation_fn(hidden_states) - - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # 350m applies layer norm AFTER attention - if not self.do_layer_norm_before: - hidden_states = self.final_layer_norm(hidden_states) - - return (hidden_states, self_attn_weights, present_key_value) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -OPT_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`OPTConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - - -@add_start_docstrings( - "The bare OPT Model outputting raw hidden-states without any specific head on top.", - OPT_START_DOCSTRING, -) -class TFOPTPreTrainedModel(TFPreTrainedModel): - """ - TFOPT Pretrained Model that inheritates from transformers.TFPreTrainedModel - - Args: - config: OPTConfig - """ - - config_class = OPTConfig - base_model_prefix = "model" - - -OPT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@keras_serializable -class TFOPTDecoder(keras.layers.Layer): - config_class = OPTConfig - - def __init__(self, config: OPTConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.padding_idx = config.pad_token_id - self.layerdrop = config.layerdrop - num_embeddings = config.max_position_embeddings - self.embed_tokens = TFSharedEmbeddings( - config.vocab_size, config.word_embed_proj_dim, config.pad_token_id, name="embed_tokens" - ) - self.embed_positions = TFOPTLearnedPositionalEmbedding( - num_embeddings, - config.hidden_size, - name="embed_positions", - ) - - # Note that the only purpose of `config._remove_final_layer_norm` is to keep backward compatibility - # with checkpoints that have been fine-tuned before transformers v4.20.1 - # see https://github.com/facebookresearch/metaseq/pull/164 - if config.do_layer_norm_before and not config._remove_final_layer_norm: - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - else: - self.final_layer_norm = None - - if config.word_embed_proj_dim != config.hidden_size: - self.project_out = keras.layers.Dense(config.word_embed_proj_dim, name="project_out", use_bias=False) - self.project_in = keras.layers.Dense(config.hidden_size, name="project_in", use_bias=False) - - else: - self.project_in = None - self.project_out = None - - self.layers = [TFOPTDecoderLayer(config, name=f"layers.{i}") for i in range(config.num_hidden_layers)] - self.dropout = keras.layers.Dropout(config.dropout) - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - def set_input_embeddings(self, new_embeddings): - self.embed_tokens.vocab_size = new_embeddings.shape[0] - self.embed_tokens.weight = new_embeddings - - def _prepare_decoder_attention_mask(self, attention_mask, input_shape, past_key_values_length): - # create causal mask - # # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - _, seq_length = input_shape - tf.debugging.assert_equal( - seq_length + past_key_values_length, - shape_list(attention_mask)[1], - message="Attention mask shape should be (batch_size, seq_length + past_key_values_length)" - f" but is {shape_list(attention_mask)[1]} with input_ids shape {input_shape} and past length" - f" {past_key_values_length}.", - ) - - expanded_attn_mask = _expand_mask(attention_mask, tgt_len=input_shape[-1]) - if seq_length > 1: - combined_attention_mask = ( - _make_causal_mask(input_shape, past_key_values_length=past_key_values_length) + expanded_attn_mask - ) - else: - combined_attention_mask = expanded_attn_mask - - return combined_attention_mask - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPast | tuple[tf.Tensor]: - r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - - head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers` with each tuple having 2 tuples each of which has 2 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up - decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those - that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of - all `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of - shape `(batch_size, sequence_length, hidden_size)`, *optional*): Optionally, instead of passing - `input_ids` you can choose to directly pass an embedded representation. This is useful if you want more - control over how to convert `input_ids` indices into associated vectors than the model's internal - embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - use_cache = use_cache if use_cache is not None else self.config.use_cache - - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - past_key_values_length = shape_list(past_key_values[0][0])[2] if past_key_values is not None else 0 - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.vocab_size) - inputs_embeds = self.embed_tokens(input_ids) - - if attention_mask is None: - attention_mask = tf.ones((input_shape[0], input_shape[1] + past_key_values_length), dtype=tf.bool) - else: - tf.debugging.assert_equal( - shape_list(attention_mask)[1], - past_key_values_length + input_shape[1], - message=( - f"The provided attention mask has length {tf.shape(attention_mask)[1]}, but its length should be " - f"{past_key_values_length + input_shape[1]} (sum of the lengths of current and past inputs)" - ), - ) - pos_embeds = self.embed_positions(attention_mask, past_key_values_length) - - attention_mask = self._prepare_decoder_attention_mask(attention_mask, input_shape, past_key_values_length) - - if self.project_in is not None: - inputs_embeds = self.project_in(inputs_embeds) - - hidden_states = inputs_embeds + pos_embeds - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - present_key_values = () if use_cache else None - - # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired - for attn_mask_name, attn_mask in [("head_mask", head_mask)]: - if attn_mask is not None: - tf.debugging.assert_equal( - shape_list(attn_mask)[0], - len(self.layers), - message=( - f"The {attn_mask_name} should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(attn_mask)[0]}." - ), - ) - - for idx, decoder_layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - hidden_states, layer_self_attn, present_key_value = decoder_layer( - hidden_states, - attention_mask=attention_mask, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - past_key_value=past_key_value, - ) - - if use_cache: - present_key_values += (present_key_value,) - - if output_attentions: - all_self_attns += (layer_self_attn,) - - if self.final_layer_norm is not None: - hidden_states = self.final_layer_norm(hidden_states) - - if self.project_out is not None: - hidden_states = self.project_out(hidden_states) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - if not return_dict: - return tuple( - v for v in [hidden_states, present_key_values, all_hidden_states, all_self_attns] if v is not None - ) - - else: - return TFBaseModelOutputWithPast( - last_hidden_state=hidden_states, - past_key_values=present_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_tokens", None) is not None: - with tf.name_scope(self.embed_tokens.name): - self.embed_tokens.build(None) - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "project_out", None) is not None: - with tf.name_scope(self.project_out.name): - self.project_out.build([None, None, self.config.hidden_size]) - if getattr(self, "project_in", None) is not None: - with tf.name_scope(self.project_in.name): - self.project_in.build([None, None, self.config.word_embed_proj_dim]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFOPTMainLayer(keras.layers.Layer): - config_class = OPTConfig - - def __init__(self, config: OPTConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.decoder = TFOPTDecoder(config, name="decoder") - - def get_input_embeddings(self): - return self.decoder.embed_tokens - - def set_input_embeddings(self, new_embeddings): - self.decoder.set_input_embeddings(new_embeddings) - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ) -> TFBaseModelOutputWithPast | tuple[tf.Tensor]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - use_cache = use_cache if use_cache is not None else self.config.use_cache - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.decoder( - input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return outputs - - return TFBaseModelOutputWithPast( - last_hidden_state=outputs.last_hidden_state, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - "The bare TF OPT Model outputting raw hidden-states without any specific head on top.", - OPT_START_DOCSTRING, -) -@keras_serializable -class TFOPTModel(TFOPTPreTrainedModel): - config_class = OPTConfig - - def __init__(self, config: OPTConfig, **kwargs): - super().__init__(config, **kwargs) - self.config = config - self.model = TFOPTMainLayer(config, name="model") - - def get_input_embeddings(self): - return self.model.decoder.embed_tokens - - def set_input_embeddings(self, new_embeddings): - self.model.set_input_embeddings(new_embeddings) - - @unpack_inputs - @add_start_docstrings_to_model_forward(OPT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPast, - config_class=_CONFIG_FOR_DOC, - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ) -> TFBaseModelOutputWithPast | tuple[tf.Tensor]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - use_cache = use_cache if use_cache is not None else self.config.use_cache - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.model( - input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return outputs - - return TFBaseModelOutputWithPast( - last_hidden_state=outputs.last_hidden_state, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None - attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None - - return TFBaseModelOutputWithPast( - last_hidden_state=output.last_hidden_state, - past_key_values=pkv, - hidden_states=hs, - attentions=attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -@add_start_docstrings( - """ - The OPT Model transformer with a language modeling head on top. - """, - OPT_START_DOCSTRING, -) -@keras_serializable -class TFOPTForCausalLM(TFOPTPreTrainedModel, TFCausalLanguageModelingLoss): - config_class = OPTConfig - - def __init__(self, config: OPTConfig, **kwargs): - super().__init__(config, **kwargs) - self.config = config - self.model = TFOPTMainLayer(config, name="model") - - def get_output_embeddings(self): - return self.model.get_input_embeddings() - - def prepare_inputs_for_generation(self, inputs, past_key_values=None, use_cache=None, **kwargs): - attention_mask = kwargs.get("attention_mask") - - # only last token for inputs_ids if past is defined in kwargs - if past_key_values: - inputs = tf.expand_dims(inputs[:, -1], -1) - - return { - "input_ids": inputs, - "attention_mask": attention_mask, - "past_key_values": past_key_values, - "use_cache": use_cache, - } - - @unpack_inputs - @replace_return_docstrings(output_type=TFCausalLMOutputWithPast, config_class=_CONFIG_FOR_DOC) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutputWithPast, - config_class=_CONFIG_FOR_DOC, - expected_output=_CAUSAL_LM_EXPECTED_OUTPUT, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ) -> TFCausalLMOutputWithPast | tuple[tf.Tensor]: - r""" - Args: - input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`torch.Tensor` of shape `(num_hidden_layers, num_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of - shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of - shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. The two additional - tensors are only required when the model is used as a decoder in a Sequence to Sequence model. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and in the - cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. - - If `past_key_values` are used, the user can optionally input only the last `input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., - config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding - (see `past_key_values`). - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.model( - input_ids=input_ids, - past_key_values=past_key_values, - attention_mask=attention_mask, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - logits = self.model.decoder.embed_tokens(outputs[0], mode="linear") - loss = None - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels, shifted_logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithPast( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None - attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None - - return TFCausalLMOutputWithPast( - past_key_values=pkv, - hidden_states=hs, - attentions=attns, - loss=output.loss, - logits=output.logits, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -__all__ = ["TFOPTForCausalLM", "TFOPTModel", "TFOPTPreTrainedModel"] diff --git a/src/transformers/models/ovis2/image_processing_ovis2.py b/src/transformers/models/ovis2/image_processing_ovis2.py index bd6d63e83914..c235504d2d89 100644 --- a/src/transformers/models/ovis2/image_processing_ovis2.py +++ b/src/transformers/models/ovis2/image_processing_ovis2.py @@ -367,10 +367,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -404,10 +402,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/owlv2/image_processing_owlv2.py b/src/transformers/models/owlv2/image_processing_owlv2.py index 64399d433f5e..a79cc57a6c94 100644 --- a/src/transformers/models/owlv2/image_processing_owlv2.py +++ b/src/transformers/models/owlv2/image_processing_owlv2.py @@ -407,10 +407,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -437,10 +435,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # Here, pad and resize methods are different from the rest of image processors # as they don't have any resampling in resize() # or pad size in pad() (the maximum of (height, width) is taken instead). diff --git a/src/transformers/models/owlv2/image_processing_owlv2_fast.py b/src/transformers/models/owlv2/image_processing_owlv2_fast.py index 70441feba3c2..c17a45b6e427 100644 --- a/src/transformers/models/owlv2/image_processing_owlv2_fast.py +++ b/src/transformers/models/owlv2/image_processing_owlv2_fast.py @@ -86,7 +86,6 @@ def post_process(self, outputs, target_sizes): `list[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image in the batch as predicted by the model. """ - # TODO: (amy) add support for other frameworks warnings.warn( "`post_process` is deprecated and will be removed in v5 of Transformers, please use" " `post_process_object_detection` instead, with `threshold=0.` for equivalent results.", diff --git a/src/transformers/models/owlv2/processing_owlv2.py b/src/transformers/models/owlv2/processing_owlv2.py index 2e69379af73f..271bea054931 100644 --- a/src/transformers/models/owlv2/processing_owlv2.py +++ b/src/transformers/models/owlv2/processing_owlv2.py @@ -30,7 +30,7 @@ Unpack, ) from ...tokenization_utils_base import PreTokenizedInput, TextInput -from ...utils import TensorType, is_flax_available, is_tf_available, is_torch_available +from ...utils import TensorType, is_torch_available if TYPE_CHECKING: @@ -105,10 +105,8 @@ def __call__( should be of shape (C, H, W), where C is a number of channels, H and W are image height and width. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: @@ -157,24 +155,11 @@ def __call__( input_ids = np.concatenate([encoding["input_ids"] for encoding in encodings], axis=0) attention_mask = np.concatenate([encoding["attention_mask"] for encoding in encodings], axis=0) - elif return_tensors == "jax" and is_flax_available(): - import jax.numpy as jnp - - input_ids = jnp.concatenate([encoding["input_ids"] for encoding in encodings], axis=0) - attention_mask = jnp.concatenate([encoding["attention_mask"] for encoding in encodings], axis=0) - elif return_tensors == "pt" and is_torch_available(): import torch input_ids = torch.cat([encoding["input_ids"] for encoding in encodings], dim=0) attention_mask = torch.cat([encoding["attention_mask"] for encoding in encodings], dim=0) - - elif return_tensors == "tf" and is_tf_available(): - import tensorflow as tf - - input_ids = tf.stack([encoding["input_ids"] for encoding in encodings], axis=0) - attention_mask = tf.stack([encoding["attention_mask"] for encoding in encodings], axis=0) - else: raise ValueError("Target return tensor type could not be returned") diff --git a/src/transformers/models/owlvit/configuration_owlvit.py b/src/transformers/models/owlvit/configuration_owlvit.py index d4873ff4a08b..4f615dece67e 100644 --- a/src/transformers/models/owlvit/configuration_owlvit.py +++ b/src/transformers/models/owlvit/configuration_owlvit.py @@ -16,12 +16,11 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from ...processing_utils import ProcessorMixin - from ...utils import TensorType from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig @@ -318,13 +317,15 @@ def generate_dummy_inputs( processor: "ProcessorMixin", batch_size: int = -1, seq_length: int = -1, - framework: Optional["TensorType"] = None, ) -> Mapping[str, Any]: text_input_dict = super().generate_dummy_inputs( - processor.tokenizer, batch_size=batch_size, seq_length=seq_length, framework=framework + processor.tokenizer, + batch_size=batch_size, + seq_length=seq_length, ) image_input_dict = super().generate_dummy_inputs( - processor.image_processor, batch_size=batch_size, framework=framework + processor.image_processor, + batch_size=batch_size, ) return {**text_input_dict, **image_input_dict} diff --git a/src/transformers/models/owlvit/image_processing_owlvit.py b/src/transformers/models/owlvit/image_processing_owlvit.py index cc9c6cfdeaa8..42e3f10269b4 100644 --- a/src/transformers/models/owlvit/image_processing_owlvit.py +++ b/src/transformers/models/owlvit/image_processing_owlvit.py @@ -355,10 +355,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -385,10 +383,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, @@ -461,7 +456,6 @@ def post_process(self, outputs, target_sizes): `list[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image in the batch as predicted by the model. """ - # TODO: (amy) add support for other frameworks warnings.warn( "`post_process` is deprecated and will be removed in v5 of Transformers, please use" " `post_process_object_detection` instead, with `threshold=0.` for equivalent results.", diff --git a/src/transformers/models/owlvit/image_processing_owlvit_fast.py b/src/transformers/models/owlvit/image_processing_owlvit_fast.py index 1e458f964a04..53d94313ece9 100644 --- a/src/transformers/models/owlvit/image_processing_owlvit_fast.py +++ b/src/transformers/models/owlvit/image_processing_owlvit_fast.py @@ -65,7 +65,6 @@ def post_process(self, outputs, target_sizes): `list[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image in the batch as predicted by the model. """ - # TODO: (amy) add support for other frameworks warnings.warn( "`post_process` is deprecated and will be removed in v5 of Transformers, please use" " `post_process_object_detection` instead, with `threshold=0.` for equivalent results.", diff --git a/src/transformers/models/owlvit/processing_owlvit.py b/src/transformers/models/owlvit/processing_owlvit.py index 0e0c59d555f2..08f19924e80b 100644 --- a/src/transformers/models/owlvit/processing_owlvit.py +++ b/src/transformers/models/owlvit/processing_owlvit.py @@ -30,7 +30,7 @@ Unpack, ) from ...tokenization_utils_base import PreTokenizedInput, TextInput -from ...utils import TensorType, is_flax_available, is_tf_available, is_torch_available +from ...utils import TensorType, is_torch_available if TYPE_CHECKING: @@ -115,10 +115,8 @@ def __call__( should be of shape (C, H, W), where C is a number of channels, H and W are image height and width. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: @@ -166,25 +164,11 @@ def __call__( if return_tensors == "np": input_ids = np.concatenate([encoding["input_ids"] for encoding in encodings], axis=0) attention_mask = np.concatenate([encoding["attention_mask"] for encoding in encodings], axis=0) - - elif return_tensors == "jax" and is_flax_available(): - import jax.numpy as jnp - - input_ids = jnp.concatenate([encoding["input_ids"] for encoding in encodings], axis=0) - attention_mask = jnp.concatenate([encoding["attention_mask"] for encoding in encodings], axis=0) - elif return_tensors == "pt" and is_torch_available(): import torch input_ids = torch.cat([encoding["input_ids"] for encoding in encodings], dim=0) attention_mask = torch.cat([encoding["attention_mask"] for encoding in encodings], dim=0) - - elif return_tensors == "tf" and is_tf_available(): - import tensorflow as tf - - input_ids = tf.stack([encoding["input_ids"] for encoding in encodings], axis=0) - attention_mask = tf.stack([encoding["attention_mask"] for encoding in encodings], axis=0) - else: raise ValueError("Target return tensor type could not be returned") diff --git a/src/transformers/models/paligemma/processing_paligemma.py b/src/transformers/models/paligemma/processing_paligemma.py index 242627a0eb71..7bf7fe403d5f 100644 --- a/src/transformers/models/paligemma/processing_paligemma.py +++ b/src/transformers/models/paligemma/processing_paligemma.py @@ -192,10 +192,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. suffix (`str`, `list[str]`, `list[list[str]]`): The suffixes or batch of suffixes to be encoded. Only necessary for finetuning. See https://github.com/google-research/big_vision/blob/main/big_vision/configs/proj/paligemma/README.md for more information. If your prompt is " What is on the image", the suffix corresponds to the expected prediction "a cow sitting on a bench". diff --git a/src/transformers/models/pegasus/__init__.py b/src/transformers/models/pegasus/__init__.py index 4903c400f982..4070d841ea3d 100644 --- a/src/transformers/models/pegasus/__init__.py +++ b/src/transformers/models/pegasus/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_pegasus import * - from .modeling_flax_pegasus import * from .modeling_pegasus import * - from .modeling_tf_pegasus import * from .tokenization_pegasus import * from .tokenization_pegasus_fast import * else: diff --git a/src/transformers/models/pegasus/modeling_flax_pegasus.py b/src/transformers/models/pegasus/modeling_flax_pegasus.py deleted file mode 100644 index ddf0ae492407..000000000000 --- a/src/transformers/models/pegasus/modeling_flax_pegasus.py +++ /dev/null @@ -1,1532 +0,0 @@ -# coding=utf-8 -# Copyright 2021, Google and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax PEGASUS model.""" - -import math -import random -from functools import partial -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxSeq2SeqLMOutput, - FlaxSeq2SeqModelOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - add_start_docstrings_to_model_forward, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, logging, replace_return_docstrings -from .configuration_pegasus import PegasusConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "google/pegasus-large" -_CONFIG_FOR_DOC = "PegasusConfig" - -PEGASUS_START_DOCSTRING = r""" - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`PegasusConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -PEGASUS_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -PEGASUS_ENCODE_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -PEGASUS_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.bart.modeling_flax_bart.shift_tokens_right -def shift_tokens_right(input_ids: jnp.ndarray, pad_token_id: int, decoder_start_token_id: int) -> jnp.ndarray: - """ - Shift input ids one token to the right. - """ - shifted_input_ids = jnp.zeros_like(input_ids) - shifted_input_ids = shifted_input_ids.at[:, 1:].set(input_ids[:, :-1]) - shifted_input_ids = shifted_input_ids.at[:, 0].set(decoder_start_token_id) - - shifted_input_ids = jnp.where(shifted_input_ids == -100, pad_token_id, shifted_input_ids) - return shifted_input_ids - - -# Copied from transformers.models.marian.modeling_flax_marian.create_sinusoidal_positions -def create_sinusoidal_positions(n_pos, dim): - position_enc = np.array([[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)]) - sentinel = dim // 2 + dim % 2 - out = np.zeros_like(position_enc) - out[:, 0:sentinel] = np.sin(position_enc[:, 0::2]) - out[:, sentinel:] = np.cos(position_enc[:, 1::2]) - - return jnp.array(out) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention with Bart->Pegasus -class FlaxPegasusAttention(nn.Module): - config: PegasusConfig - embed_dim: int - num_heads: int - dropout: float = 0.0 - causal: bool = False - bias: bool = True - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self) -> None: - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {self.num_heads})." - ) - - dense = partial( - nn.Dense, - self.embed_dim, - use_bias=self.bias, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() - self.out_proj = dense() - - self.dropout_layer = nn.Dropout(rate=self.dropout) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states: jnp.ndarray, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.q_proj(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.k_proj(key_value_states) - value_states = self.v_proj(key_value_states) - else: - # self_attention - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights - - -# Copied from transformers.models.mbart.modeling_flax_mbart.FlaxMBartEncoderLayer with MBart->Pegasus -class FlaxPegasusEncoderLayer(nn.Module): - config: PegasusConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxPegasusAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.encoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - self.fc1 = nn.Dense( - self.config.encoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - hidden_states, attn_weights = self.self_attn(hidden_states=hidden_states, attention_mask=attention_mask) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartEncoderLayerCollection with Bart->Pegasus -class FlaxPegasusEncoderLayerCollection(nn.Module): - config: PegasusConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxPegasusEncoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.encoder_layers) - ] - self.layerdrop = self.config.encoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for encoder_layer in self.layers: - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): # skip the layer - layer_outputs = (None, None) - else: - layer_outputs = encoder_layer( - hidden_states, - attention_mask, - output_attentions, - deterministic, - ) - hidden_states = layer_outputs[0] - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -# Copied from transformers.models.mbart.modeling_flax_mbart.FlaxMBartDecoderLayer with MBart->Pegasus -class FlaxPegasusDecoderLayer(nn.Module): - config: PegasusConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxPegasusAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - causal=True, - dtype=self.dtype, - ) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.encoder_attn = FlaxPegasusAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.fc1 = nn.Dense( - self.config.decoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - hidden_states, self_attn_weights = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - hidden_states = self.encoder_attn_layer_norm(hidden_states) - hidden_states, cross_attn_weights = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights, cross_attn_weights) - - return outputs - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderLayerCollection with Bart->Pegasus -class FlaxPegasusDecoderLayerCollection(nn.Module): - config: PegasusConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxPegasusDecoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.decoder_layers) - ] - self.layerdrop = self.config.decoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - for decoder_layer in self.layers: - if output_hidden_states: - all_hidden_states += (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): - layer_outputs = (None, None, None) - else: - layer_outputs = decoder_layer( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - deterministic=deterministic, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attns += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = [hidden_states, all_hidden_states, all_self_attns, all_cross_attentions] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - -class FlaxPegasusEncoder(nn.Module): - config: PegasusConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_source_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(embed_dim) if self.config.scale_embedding else 1.0 - - self.embed_positions = create_sinusoidal_positions(self.config.max_position_embeddings, embed_dim) - self.layers = FlaxPegasusEncoderLayerCollection(self.config, self.dtype) - self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - # embed positions - embed_pos = jnp.take(self.embed_positions, position_ids, axis=0) - # explicitly cast the positions here, since self.embed_positions are not registered as parameters - embed_pos = embed_pos.astype(inputs_embeds.dtype) - - hidden_states = inputs_embeds + embed_pos - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - outputs = self.layers( - hidden_states, - attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - last_hidden_state = outputs[0] - last_hidden_state = self.layer_norm(last_hidden_state) - - # update the last element in `hidden_states` after applying `layernorm` above - hidden_states = None - if output_hidden_states: - hidden_states = outputs[1] - hidden_states = hidden_states[:-1] + (last_hidden_state,) - - if not return_dict: - outputs = (last_hidden_state, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=last_hidden_state, - hidden_states=hidden_states, - attentions=outputs.attentions, - ) - - -class FlaxPegasusDecoder(nn.Module): - config: PegasusConfig - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_target_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(self.config.d_model) if self.config.scale_embedding else 1.0 - - self.embed_positions = create_sinusoidal_positions(self.config.max_position_embeddings, embed_dim) - - self.layers = FlaxPegasusDecoderLayerCollection(self.config, self.dtype) - self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - # embed positions - positions = jnp.take(self.embed_positions, position_ids, axis=0) - # explicitly cast the positions here, since self.embed_positions are not registered as parameters - positions = positions.astype(inputs_embeds.dtype) - - hidden_states = inputs_embeds + positions - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - outputs = self.layers( - hidden_states, - attention_mask, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - last_hidden_state = outputs[0] - last_hidden_state = self.layer_norm(last_hidden_state) - - # update the last element in `hidden_states` after applying `layernorm` above - hidden_states = None - if output_hidden_states: - hidden_states = outputs[1] - hidden_states = hidden_states[:-1] + (last_hidden_state,) - - if not return_dict: - outputs = (last_hidden_state, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=last_hidden_state, - hidden_states=hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartModule with Bart->Pegasus -class FlaxPegasusModule(nn.Module): - config: PegasusConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - - self.encoder = FlaxPegasusEncoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - self.decoder = FlaxPegasusDecoder(self.config, dtype=self.dtype, embed_tokens=self.shared) - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -class FlaxPegasusPreTrainedModel(FlaxPreTrainedModel): - config_class = PegasusConfig - base_model_prefix: str = "model" - module_class: nn.Module = None - - def __init__( - self, - config: PegasusConfig, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - decoder_input_ids = input_ids - decoder_attention_mask = jnp.ones_like(input_ids) - - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - decoder_position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape - ) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(PEGASUS_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=PegasusConfig) - def encode( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxPegasusForConditionalGeneration - - >>> model = FlaxPegasusForConditionalGeneration.from_pretrained("google/pegasus-large") - >>> tokenizer = AutoTokenizer.from_pretrained("google/pegasus-large") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, input_ids, attention_mask, position_ids, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(input_ids, attention_mask, position_ids, **kwargs) - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - @add_start_docstrings(PEGASUS_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=PegasusConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoTokenizer, FlaxPegasusForConditionalGeneration - - >>> model = FlaxPegasusForConditionalGeneration.from_pretrained("google/pegasus-large") - >>> tokenizer = AutoTokenizer.from_pretrained("google/pegasus-large") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> last_decoder_hidden_states = outputs.last_hidden_state - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxPegasusAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - @add_start_docstrings_to_model_forward(PEGASUS_INPUTS_DOCSTRING) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_input_ids: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # prepare decoder inputs - if decoder_input_ids is None: - decoder_input_ids = shift_tokens_right( - input_ids, self.config.pad_token_id, decoder_start_token_id=self.config.decoder_start_token_id - ) - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - if decoder_position_ids is None: - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - -@add_start_docstrings( - "The bare Pegasus Model transformer outputting raw hidden-states without any specific head on top.", - PEGASUS_START_DOCSTRING, -) -class FlaxPegasusModel(FlaxPegasusPreTrainedModel): - config: PegasusConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - module_class = FlaxPegasusModule - - -append_call_sample_docstring(FlaxPegasusModel, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) - - -# Copied from transformers.models.bart.modeling_flax_bart.FlaxBartForConditionalGenerationModule with Bart->Pegasus -class FlaxPegasusForConditionalGenerationModule(nn.Module): - config: PegasusConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., jnp.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.model = FlaxPegasusModule(config=self.config, dtype=self.dtype) - self.lm_head = nn.Dense( - self.model.shared.num_embeddings, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.final_logits_bias = self.param("final_logits_bias", self.bias_init, (1, self.model.shared.num_embeddings)) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_ids, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - position_ids, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - position_ids=position_ids, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = self.model.variables["params"]["shared"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - lm_logits += jax.lax.stop_gradient(self.final_logits_bias.astype(self.dtype)) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return output - - return FlaxSeq2SeqLMOutput( - logits=lm_logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings( - "The PEGASUS Model with a language modeling head. Can be used for summarization.", PEGASUS_START_DOCSTRING -) -class FlaxPegasusForConditionalGeneration(FlaxPegasusPreTrainedModel): - module_class = FlaxPegasusForConditionalGenerationModule - dtype: jnp.dtype = jnp.float32 - - @add_start_docstrings(PEGASUS_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=PegasusConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - deterministic: bool = True, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoTokenizer, FlaxPegasusForConditionalGeneration - - >>> model = FlaxPegasusForConditionalGeneration.from_pretrained("google/pegasus-large") - >>> tokenizer = AutoTokenizer.from_pretrained("google/pegasus-large") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, max_length=1024, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxPegasusAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - outputs = decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = module.model.variables["params"]["shared"]["embedding"] - lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = module.lm_head(hidden_states) - - lm_logits += module.final_logits_bias.astype(self.dtype) - return lm_logits, outputs - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - if past_key_values is None: - lm_logits, decoder_outputs = outputs - else: - (lm_logits, decoder_outputs), past = outputs - - if return_dict: - outputs = FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=decoder_outputs.hidden_states, - attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - ) - else: - outputs = (lm_logits,) + decoder_outputs[1:] - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - position_ids = decoder_attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - "decoder_position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 - return model_kwargs - - -FLAX_PEGASUS_CONDITIONAL_GENERATION_DOCSTRING = """ - Returns: - - Summarization example: - - ```python - >>> from transformers import AutoTokenizer, FlaxPegasusForConditionalGeneration - - >>> model = FlaxPegasusForConditionalGeneration.from_pretrained('google/pegasus-large') - >>> tokenizer = AutoTokenizer.from_pretrained('google/pegasus-large') - - >>> ARTICLE_TO_SUMMARIZE = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], max_length=1024, return_tensors='np') - - >>> # Generate Summary - >>> summary_ids = model.generate(inputs['input_ids']).sequences - >>> print(tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)) - ``` - - Mask filling example: - - ```python - >>> from transformers import AutoTokenizer, FlaxPegasusForConditionalGeneration - - >>> tokenizer = AutoTokenizer.from_pretrained("google/pegasus-large") - >>> TXT = "My friends are but they eat too many carbs." - - >>> model = FlaxPegasusForConditionalGeneration.from_pretrained("google/pegasus-large") - >>> input_ids = tokenizer([TXT], return_tensors="np")["input_ids"] - >>> logits = model(input_ids).logits - - >>> masked_index = (input_ids[0] == tokenizer.mask_token_id).nonzero().item() - >>> probs = jax.nn.softmax(logits[0, masked_index], axis=0) - >>> values, predictions = jax.lax.top_k(probs) - - >>> tokenizer.decode(predictions).split() - ``` -""" - -overwrite_call_docstring( - FlaxPegasusForConditionalGeneration, PEGASUS_INPUTS_DOCSTRING + FLAX_PEGASUS_CONDITIONAL_GENERATION_DOCSTRING -) -append_replace_return_docstrings( - FlaxPegasusForConditionalGeneration, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC -) - - -__all__ = ["FlaxPegasusForConditionalGeneration", "FlaxPegasusModel", "FlaxPegasusPreTrainedModel"] diff --git a/src/transformers/models/pegasus/modeling_tf_pegasus.py b/src/transformers/models/pegasus/modeling_tf_pegasus.py deleted file mode 100644 index d159fc00138d..000000000000 --- a/src/transformers/models/pegasus/modeling_tf_pegasus.py +++ /dev/null @@ -1,1573 +0,0 @@ -# coding=utf-8 -# Copyright 2021, Google Inc. and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 Pegasus model.""" - -from __future__ import annotations - -import random - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPastAndCrossAttentions, - TFSeq2SeqLMOutput, - TFSeq2SeqModelOutput, -) - -# Public API -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_end_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_pegasus import PegasusConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "google/pegasus-large" -_CONFIG_FOR_DOC = "PegasusConfig" - - -LARGE_NEGATIVE = -1e8 - - -# Copied from transformers.models.bart.modeling_tf_bart.shift_tokens_right -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): - pad_token_id = tf.cast(pad_token_id, input_ids.dtype) - decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) - start_tokens = tf.fill( - (shape_list(input_ids)[0], 1), tf.convert_to_tensor(decoder_start_token_id, input_ids.dtype) - ) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.fill(shape_list(shifted_input_ids), tf.convert_to_tensor(pad_token_id, input_ids.dtype)), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE - mask_cond = tf.range(shape_list(mask)[-1]) - - mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -# Copied from transformers.models.marian.modeling_tf_marian.TFMarianSinusoidalPositionalEmbedding with Marian->Pegasus -class TFPegasusSinusoidalPositionalEmbedding(keras.layers.Layer): - """This module produces sinusoidal positional embeddings of any length.""" - - def __init__(self, num_positions: int, embedding_dim: int, **kwargs): - super().__init__(**kwargs) - - if embedding_dim % 2 != 0: - raise NotImplementedError(f"odd embedding_dim {embedding_dim} not supported") - - self.embedding_dim = embedding_dim - self.num_positions = num_positions - - def build(self, input_shape: tf.TensorShape): - """ - Build shared token embedding layer Shared weights logic adapted from - https://github.com/tensorflow/models/blob/a009f4fb9d2fc4949e32192a944688925ef78659/official/transformer/v2/embedding_layer.py#L24 - """ - - weight = self._init_weight(self.num_positions, self.embedding_dim) - - self.weight = self.add_weight( - name="embeddings", - shape=[self.num_positions, self.embedding_dim], - ) - weight = tf.cast(weight, dtype=self.weight.dtype) - - self.weight.assign(weight) - - super().build(input_shape) - - @staticmethod - def _init_weight(n_pos: int, dim: int): - """ - Identical to the XLM create_sinusoidal_embeddings except features are not interleaved. The cos features are in - the 2nd half of the vector. [dim // 2:] - """ - position_enc = np.array( - [[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)] - ) - table = np.zeros_like(position_enc) - # index 0 is all zero - table[:, 0 : dim // 2] = np.sin(position_enc[:, 0::2]) - table[:, dim // 2 :] = np.cos(position_enc[:, 1::2]) - # convert to tensor - table = tf.convert_to_tensor(table) - tf.stop_gradient(table) - return table - - def call( - self, input_shape: tf.TensorShape, past_key_values_length: int = 0, position_ids: tf.Tensor | None = None - ): - """Input is expected to be of size [bsz x seqlen].""" - if position_ids is None: - seq_len = input_shape[1] - position_ids = tf.range(past_key_values_length, seq_len + past_key_values_length, delta=1, name="range") - return tf.gather(self.weight, position_ids) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with Bart->Pegasus -class TFPegasusAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.mbart.modeling_tf_mbart.TFMBartEncoderLayer with MBart->Pegasus -class TFPegasusEncoderLayer(keras.layers.Layer): - def __init__(self, config: PegasusConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFPegasusAttention( - self.embed_dim, config.encoder_attention_heads, dropout=config.attention_dropout, name="self_attn" - ) - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - self.fc1 = keras.layers.Dense(config.encoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - layer_head_mask: tf.Tensor, - training: bool | None = False, - ): - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape *(batch, seq_len, embed_dim)* - attention_mask (`tf.Tensor`): attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - *(encoder_attention_heads,)* - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - hidden_states, self_attn_weights, _ = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, layer_head_mask=layer_head_mask - ) - - tf.debugging.assert_equal( - shape_list(hidden_states), - shape_list(residual), - message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", - ) - - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return hidden_states, self_attn_weights - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.encoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.mbart.modeling_tf_mbart.TFMBartDecoderLayer with MBart->Pegasus -class TFPegasusDecoderLayer(keras.layers.Layer): - def __init__(self, config: PegasusConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFPegasusAttention( - embed_dim=self.embed_dim, - num_heads=config.decoder_attention_heads, - dropout=config.attention_dropout, - name="self_attn", - is_decoder=True, - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.encoder_attn = TFPegasusAttention( - self.embed_dim, - config.decoder_attention_heads, - dropout=config.attention_dropout, - name="encoder_attn", - is_decoder=True, - ) - self.encoder_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.decoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - cross_attn_layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tf.Tensor] | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape *(batch, seq_len, embed_dim)* - attention_mask (`tf.Tensor`): attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - encoder_hidden_states (`tf.Tensor`): - cross attention input to the layer of shape *(batch, seq_len, embed_dim)* - encoder_attention_mask (`tf.Tensor`): encoder attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - *(decoder_attention_heads,)* - cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. - *(decoder_attention_heads,)* - past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_present_key_value = None - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - layer_head_mask=cross_attn_layer_head_mask, - past_key_value=cross_attn_past_key_value, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # add cross-attn to positions 3,4 of present_key_value tuple - present_key_value = present_key_value + cross_attn_present_key_value - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return ( - hidden_states, - self_attn_weights, - cross_attn_weights, - present_key_value, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "encoder_attn", None) is not None: - with tf.name_scope(self.encoder_attn.name): - self.encoder_attn.build(None) - if getattr(self, "encoder_attn_layer_norm", None) is not None: - with tf.name_scope(self.encoder_attn_layer_norm.name): - self.encoder_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.decoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFPegasusPreTrainedModel(TFPreTrainedModel): - config_class = PegasusConfig - base_model_prefix = "model" - - -PEGASUS_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`PegasusConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -PEGASUS_GENERATION_EXAMPLE = r""" - Summarization example: - - ```python - >>> from transformers import AutoTokenizer, TFPegasusForConditionalGeneration - - >>> model = TFPegasusForConditionalGeneration.from_pretrained("google/pegasus-xsum") - >>> tokenizer = AutoTokenizer.from_pretrained("google/pegasus-xsum") - - >>> ARTICLE_TO_SUMMARIZE = ( - ... "PG&E stated it scheduled the blackouts in response to forecasts for high winds " - ... "amid dry conditions. The aim is to reduce the risk of wildfires. Nearly 800 thousand customers were " - ... "scheduled to be affected by the shutoffs which were expected to last through at least midday tomorrow." - ... ) - >>> inputs = tokenizer(ARTICLE_TO_SUMMARIZE, max_length=1024, return_tensors="tf") - - >>> # Generate Summary - >>> summary_ids = model.generate(input_ids) - >>> print(tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)) - ``` -""" - -PEGASUS_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - Pegasus uses the `pad_token_id` as the starting token for `decoder_input_ids` generation. If - `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - will be made by default and ignore pad tokens. It is not recommended to set this for most use cases. - decoder_position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_outputs (`tf.FloatTensor`, *optional*): - hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - of shape `(batch_size, sequence_length, hidden_size)` is a sequence of - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation output_attentions (`bool`, - *optional*): Whether or not to return the attentions tensors of all attention layers. See `attentions` - under returned tensors for more detail. This argument can be used only in eager mode, in graph mode the - value in the config will be used instead. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@keras_serializable -class TFPegasusEncoder(keras.layers.Layer): - config_class = PegasusConfig - """ - Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a - [`TFPegasusEncoderLayer`]. - - Args: - config: PegasusConfig - """ - - def __init__(self, config: PegasusConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.dropout = keras.layers.Dropout(config.dropout) - self.layerdrop = config.encoder_layerdrop - self.padding_idx = config.pad_token_id - self.max_source_positions = config.max_position_embeddings - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - - self.embed_tokens = embed_tokens - self.embed_positions = TFPegasusSinusoidalPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.layers = [TFPegasusEncoderLayer(config, name=f"layers.{i}") for i in range(config.encoder_layers)] - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ): - """ - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. This argument can be used only in eager mode, in graph mode the value - in the config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. This argument can be used only in eager mode, in graph mode the value in the config - will be used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - embed_pos = self.embed_positions(input_shape) - hidden_states = inputs_embeds + embed_pos - hidden_states = self.dropout(hidden_states, training=training) - - # check attention mask and invert - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - attention_mask = _expand_mask(attention_mask) - else: - attention_mask = None - - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - # check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - tf.debugging.assert_equal( - shape_list(head_mask)[0], - len(self.layers), - message=( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(head_mask)[0]}." - ), - ) - - # encoder layers - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): # skip the layer - continue - - hidden_states, attn = encoder_layer( - hidden_states, - attention_mask, - head_mask[idx] if head_mask is not None else None, - ) - - if output_attentions: - all_attentions += (attn,) - - hidden_states = self.layer_norm(hidden_states) - - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFPegasusDecoder(keras.layers.Layer): - config_class = PegasusConfig - """ - Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFPegasusDecoderLayer`] - - Args: - config: PegasusConfig - embed_tokens: output embedding - """ - - def __init__(self, config: PegasusConfig, embed_tokens: keras.layers.Embedding | None = None, **kwargs): - super().__init__(**kwargs) - self.config = config - self.padding_idx = config.pad_token_id - self.embed_tokens = embed_tokens - self.layerdrop = config.decoder_layerdrop - self.embed_positions = TFPegasusSinusoidalPositionalEmbedding( - config.max_position_embeddings, - config.d_model, - name="embed_positions", - ) - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - self.layers = [TFPegasusDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - self.dropout = keras.layers.Dropout(config.dropout) - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ): - r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention - of the decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): - Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values - selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers` with each tuple having 2 tuples each of which has 2 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up - decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those - that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of - all `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. This argument can be used only in eager mode, in graph mode the value - in the config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. This argument can be used only in eager mode, in graph mode the value in the config - will be used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - """ - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - past_key_values_length = shape_list(past_key_values[0][0])[2] if past_key_values is not None else 0 - - # embed positions - if position_ids is None: - positions = self.embed_positions(input_shape, past_key_values_length) - else: - positions = self.embed_positions(input_shape, position_ids=position_ids) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - hidden_states = inputs_embeds - - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - if input_shape[-1] > 1: - combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length=past_key_values_length) - else: - combined_attention_mask = _expand_mask( - tf.ones((input_shape[0], input_shape[1] + past_key_values_length)), tgt_len=input_shape[-1] - ) - - if attention_mask is not None: - combined_attention_mask = combined_attention_mask + _expand_mask(attention_mask, tgt_len=input_shape[-1]) - - if encoder_hidden_states is not None and encoder_attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) - - hidden_states = self.dropout(hidden_states + positions, training=training) - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attns = () if (output_attentions and encoder_hidden_states is not None) else None - present_key_values = () if use_cache else None - - # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired - for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: - if attn_mask is not None: - tf.debugging.assert_equal( - shape_list(attn_mask)[0], - len(self.layers), - message=( - f"The {attn_mask_name} should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(attn_mask)[0]}." - ), - ) - - for idx, decoder_layer in enumerate(self.layers): - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - if output_hidden_states: - all_hidden_states += (hidden_states,) - dropout_probability = random.uniform(0, 1) - - if training and (dropout_probability < self.layerdrop): - continue - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( - hidden_states, - attention_mask=combined_attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - cross_attn_layer_head_mask=cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None, - past_key_value=past_key_value, - ) - - if use_cache: - present_key_values += (present_key_value,) - - if output_attentions: - all_self_attns += (layer_self_attn,) - - if encoder_hidden_states is not None: - all_cross_attns += (layer_cross_attn,) - - hidden_states = self.layer_norm(hidden_states) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - if not return_dict: - return hidden_states, present_key_values, all_hidden_states, all_self_attns, all_cross_attns - else: - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=present_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFPegasusMainLayer(keras.layers.Layer): - config_class = PegasusConfig - - def __init__(self, config: PegasusConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.shared = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.d_model, - embeddings_initializer=keras.initializers.TruncatedNormal(stddev=self.config.init_std), - name="model.shared", - ) - # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) - self.shared.load_weight_prefix = "model.shared" - - self.encoder = TFPegasusEncoder(config, self.shared, name="encoder") - self.decoder = TFPegasusDecoder(config, self.shared, name="decoder") - - def get_input_embeddings(self): - return self.shared - - def set_input_embeddings(self, new_embeddings): - self.shared = new_embeddings - self.encoder.embed_tokens = self.shared - self.decoder.embed_tokens = self.shared - - @unpack_inputs - def call( - self, - input_ids: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - decoder_input_ids: tf.Tensor | None = None, - decoder_attention_mask: tf.Tensor | None = None, - decoder_position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - decoder_head_mask: tf.Tensor | None = None, - cross_attn_head_mask: tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[tf.Tensor]] | None = None, - inputs_embeds: tf.Tensor | None = None, - decoder_inputs_embeds: tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ): - if decoder_input_ids is None and decoder_inputs_embeds is None: - use_cache = False - - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True - elif return_dict and not isinstance(encoder_outputs, TFBaseModelOutput): - encoder_outputs = TFBaseModelOutput( - last_hidden_state=encoder_outputs[0], - hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, - attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, - ) - # If the user passed a TFBaseModelOutput for encoder_outputs, we wrap it in a tuple when return_dict=False - elif not return_dict and not isinstance(encoder_outputs, tuple): - encoder_outputs = encoder_outputs.to_tuple() - - decoder_outputs = self.decoder( - decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return TFSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # The shared/tied weights expect to be in the model base namespace - # Adding "/" to the end (not the start!) of a tf.name_scope puts it in the root namespace rather than - # the current one. - with tf.name_scope(self.shared.load_weight_prefix + "/" + self.shared.name + "/"): - self.shared.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - "The bare PEGASUS Model outputting raw hidden-states without any specific head on top.", - PEGASUS_START_DOCSTRING, -) -class TFPegasusModel(TFPegasusPreTrainedModel): - def __init__(self, config: PegasusConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.model = TFPegasusMainLayer(config, name="model") - - def get_encoder(self): - return self.model.encoder - - def get_decoder(self): - return self.model.decoder - - @unpack_inputs - @add_start_docstrings_to_model_forward(PEGASUS_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSeq2SeqModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ) -> TFSeq2SeqModelOutput | tuple[tf.Tensor]: - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - encoder_outputs=encoder_outputs, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartModel.serving_output - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqModelOutput( - last_hidden_state=output.last_hidden_state, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -# Copied from transformers.models.bart.modeling_tf_bart.BiasLayer -class BiasLayer(keras.layers.Layer): - """ - Bias as a layer. It is used for serialization purposes: `keras.Model.save_weights` stores on a per-layer basis, - so all weights have to be registered in a layer. - """ - - def __init__(self, shape, initializer, trainable, name, **kwargs): - super().__init__(name=name, **kwargs) - # Note: the name of this variable will NOT be scoped when serialized, i.e. it will not be in the format of - # "outer_layer/inner_layer/.../name:0". Instead, it will be "name:0". For further details, see: - # https://github.com/huggingface/transformers/pull/18833#issuecomment-1233090214 - self.bias = self.add_weight(name=name, shape=shape, initializer=initializer, trainable=trainable) - - def call(self, x): - return x + self.bias - - -@add_start_docstrings( - "The PEGASUS Model with a language modeling head. Can be used for summarization.", - PEGASUS_START_DOCSTRING, -) -class TFPegasusForConditionalGeneration(TFPegasusPreTrainedModel, TFCausalLanguageModelingLoss): - _keys_to_ignore_on_load_unexpected = [ - r"model.encoder.embed_tokens.weight", - r"model.decoder.embed_tokens.weight", - ] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.model = TFPegasusMainLayer(config, name="model") - self.use_cache = config.use_cache - # final_bias_logits is registered as a buffer in pytorch, so not trainable for the sake of consistency. - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, config.vocab_size], initializer="zeros", trainable=False - ) - - def get_decoder(self): - return self.model.decoder - - def get_encoder(self): - return self.model.encoder - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - def get_bias(self): - return {"final_logits_bias": self.bias_layer.bias} - - def set_bias(self, value): - # Replaces the existing layers containing bias for correct (de)serialization. - vocab_size = value["final_logits_bias"].shape[-1] - self.bias_layer = BiasLayer( - name="final_logits_bias", shape=[1, vocab_size], initializer="zeros", trainable=False - ) - self.bias_layer.bias.assign(value["final_logits_bias"]) - - @unpack_inputs - @add_start_docstrings_to_model_forward(PEGASUS_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - @add_end_docstrings(PEGASUS_GENERATION_EXAMPLE) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFSeq2SeqLMOutput | tuple[tf.Tensor]: - """ - labels (`tf.tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., - config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - - Returns: - - """ - - if labels is not None: - labels = tf.where( - labels == self.config.pad_token_id, - tf.cast(tf.fill(shape_list(labels), -100), labels.dtype), - labels, - ) - use_cache = False - if decoder_input_ids is None and decoder_inputs_embeds is None: - decoder_input_ids = shift_tokens_right( - labels, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - outputs = self.model( - input_ids, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - encoder_outputs=encoder_outputs, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - lm_logits = tf.matmul(outputs[0], self.model.shared.weights, transpose_b=True) - lm_logits = self.bias_layer(lm_logits) - masked_lm_loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return TFSeq2SeqLMOutput( - loss=masked_lm_loss, - logits=lm_logits, - past_key_values=outputs.past_key_values, # index 1 of d outputs - decoder_hidden_states=outputs.decoder_hidden_states, # index 2 of d outputs - decoder_attentions=outputs.decoder_attentions, # index 3 of d outputs - cross_attentions=outputs.cross_attentions, # index 4 of d outputs - encoder_last_hidden_state=outputs.encoder_last_hidden_state, # index 0 of encoder outputs - encoder_hidden_states=outputs.encoder_hidden_states, # 1 of e out - encoder_attentions=outputs.encoder_attentions, # 2 of e out - ) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartForConditionalGeneration.serving_output - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartForConditionalGeneration.prepare_inputs_for_generation - def prepare_inputs_for_generation( - self, - decoder_input_ids, - past_key_values=None, - attention_mask=None, - decoder_attention_mask=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - use_cache=None, - encoder_outputs=None, - **kwargs, - ): - # cut decoder_input_ids if past_key_values is used - if past_key_values is not None: - decoder_input_ids = decoder_input_ids[:, -1:] - - if decoder_attention_mask is not None: # xla - decoder_position_ids = tf.math.cumsum(decoder_attention_mask, axis=-1, exclusive=True)[:, -1:] - elif past_key_values is not None: # no xla + past_key_values - decoder_position_ids = past_key_values[0][0].shape[2] - else: # no xla + no past_key_values - decoder_position_ids = tf.range(decoder_input_ids.shape[1]) - - return { - "input_ids": None, # encoder_outputs is defined. input_ids not needed - "encoder_outputs": encoder_outputs, - "past_key_values": past_key_values, - "decoder_input_ids": decoder_input_ids, - "attention_mask": attention_mask, - "decoder_attention_mask": decoder_attention_mask, - "decoder_position_ids": decoder_position_ids, - "head_mask": head_mask, - "decoder_head_mask": decoder_head_mask, - "cross_attn_head_mask": cross_attn_head_mask, - "use_cache": use_cache, # change this to avoid caching (presumably for debugging) - } - - def prepare_decoder_input_ids_from_labels(self, labels: tf.Tensor): - return shift_tokens_right(labels, self.config.pad_token_id, self.config.decoder_start_token_id) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "bias_layer", None) is not None: - with tf.name_scope(self.bias_layer.name): - self.bias_layer.build(None) - - -__all__ = ["TFPegasusForConditionalGeneration", "TFPegasusModel", "TFPegasusPreTrainedModel"] diff --git a/src/transformers/models/pegasus_x/modeling_pegasus_x.py b/src/transformers/models/pegasus_x/modeling_pegasus_x.py index 0c1ae32cabe2..231d6601d28a 100755 --- a/src/transformers/models/pegasus_x/modeling_pegasus_x.py +++ b/src/transformers/models/pegasus_x/modeling_pegasus_x.py @@ -67,9 +67,6 @@ class DimensionInfo: global_len: int # global length padded_seq_len: int # padded token seq length - # Note: Compared to the original Flax implementation, we will pad the token representations to - # a multiple of block size at the start of the encoder layers, so T=P always. - # Copied from transformers.models.bart.modeling_bart.shift_tokens_right def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start_token_id: int): diff --git a/src/transformers/models/perceiver/configuration_perceiver.py b/src/transformers/models/perceiver/configuration_perceiver.py index 91e7bcd58fdc..d983779c6add 100644 --- a/src/transformers/models/perceiver/configuration_perceiver.py +++ b/src/transformers/models/perceiver/configuration_perceiver.py @@ -16,14 +16,14 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import Any, Optional, Union +from typing import Any, Union from ...configuration_utils import PretrainedConfig from ...feature_extraction_utils import FeatureExtractionMixin from ...onnx import OnnxConfig from ...onnx.utils import compute_effective_axis_dimension from ...tokenization_utils_base import PreTrainedTokenizerBase -from ...utils import TensorType, logging +from ...utils import logging logger = logging.get_logger(__name__) @@ -207,7 +207,6 @@ def generate_dummy_inputs( seq_length: int = -1, num_choices: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, num_channels: int = 3, image_width: int = 40, image_height: int = 40, @@ -226,14 +225,14 @@ def generate_dummy_inputs( ) # Generate dummy inputs according to compute batch and sequence dummy_input = [" ".join(["a"]) * seq_length] * batch_size - inputs = dict(preprocessor(dummy_input, return_tensors=framework)) + inputs = dict(preprocessor(dummy_input, return_tensors="pt")) inputs["inputs"] = inputs.pop("input_ids") return inputs elif isinstance(preprocessor, FeatureExtractionMixin) and preprocessor.model_input_names[0] == "pixel_values": # If dynamic axis (-1) we forward with a fixed dimension of 2 samples to avoid optimizations made by ONNX batch_size = compute_effective_axis_dimension(batch_size, fixed_dimension=OnnxConfig.default_fixed_batch) dummy_input = self._generate_dummy_images(batch_size, num_channels, image_height, image_width) - inputs = dict(preprocessor(images=dummy_input, return_tensors=framework)) + inputs = dict(preprocessor(images=dummy_input, return_tensors="pt")) inputs["inputs"] = inputs.pop("pixel_values") return inputs else: diff --git a/src/transformers/models/perceiver/image_processing_perceiver.py b/src/transformers/models/perceiver/image_processing_perceiver.py index c66d7b51d463..376d33f8c356 100644 --- a/src/transformers/models/perceiver/image_processing_perceiver.py +++ b/src/transformers/models/perceiver/image_processing_perceiver.py @@ -258,10 +258,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -289,10 +287,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/perceiver/modeling_perceiver.py b/src/transformers/models/perceiver/modeling_perceiver.py index f0e4e3e5dbe0..58267db8c19a 100755 --- a/src/transformers/models/perceiver/modeling_perceiver.py +++ b/src/transformers/models/perceiver/modeling_perceiver.py @@ -566,8 +566,6 @@ class PerceiverPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -2379,8 +2377,6 @@ def space_to_depth(frames: torch.Tensor, temporal_block_size: int = 1, spatial_b Space to depth transform. Rearranges blocks of spatial data, into depth. This function assumes the channels to be first, but will place the channels last after transformation. - - Based on https://discuss.pytorch.org/t/is-there-any-layer-like-tensorflows-space-to-depth-function/3487/15. """ if len(frames.shape) == 4: batch_size, num_channels, height, width = frames.shape diff --git a/src/transformers/models/perception_lm/processing_perception_lm.py b/src/transformers/models/perception_lm/processing_perception_lm.py index f61c54554d32..35f0fef6c4ca 100644 --- a/src/transformers/models/perception_lm/processing_perception_lm.py +++ b/src/transformers/models/perception_lm/processing_perception_lm.py @@ -110,10 +110,8 @@ def __call__( The video or batch of videos to be processed. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/phi4_multimodal/feature_extraction_phi4_multimodal.py b/src/transformers/models/phi4_multimodal/feature_extraction_phi4_multimodal.py index 71ada3a8c62a..16b5875eb001 100644 --- a/src/transformers/models/phi4_multimodal/feature_extraction_phi4_multimodal.py +++ b/src/transformers/models/phi4_multimodal/feature_extraction_phi4_multimodal.py @@ -110,7 +110,6 @@ def __call__( If set, will return tensors instead of numpy arrays. Acceptable values are: - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. - - `'tf'`: Return TensorFlow `tf.constant` objects. return_attention_mask (`bool`, *optional*, defaults to `True`): Whether to return the extracted audio input features' attention mask. device (`str`, *optional*, defaults to "cpu"): diff --git a/src/transformers/models/pix2struct/image_processing_pix2struct.py b/src/transformers/models/pix2struct/image_processing_pix2struct.py index 94ae65777692..316f2021461c 100644 --- a/src/transformers/models/pix2struct/image_processing_pix2struct.py +++ b/src/transformers/models/pix2struct/image_processing_pix2struct.py @@ -316,9 +316,6 @@ def normalize( """ Normalize an image. image = (image - image_mean) / image_std. - The image std is to mimic the tensorflow implementation of the `per_image_standardization`: - https://www.tensorflow.org/api_docs/python/tf/image/per_image_standardization - Args: image (`np.ndarray`): Image to normalize. @@ -361,10 +358,7 @@ def preprocess( """ Preprocess an image or batch of images. The processor first computes the maximum possible number of aspect-ratio preserving patches of size `patch_size` that can be extracted from the image. It then pads the - image with zeros to make the image respect the constraint of `max_patches`. Before extracting the patches the - images are standardized following the tensorflow implementation of `per_image_standardization` - (https://www.tensorflow.org/api_docs/python/tf/image/per_image_standardization). - + image with zeros to make the image respect the constraint of `max_patches`. Args: images (`ImageInput`): @@ -382,10 +376,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -410,10 +402,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # PIL RGBA images are converted to RGB if do_convert_rgb: diff --git a/src/transformers/models/pix2struct/modeling_pix2struct.py b/src/transformers/models/pix2struct/modeling_pix2struct.py index 463fec98256f..049cb7f0bd43 100644 --- a/src/transformers/models/pix2struct/modeling_pix2struct.py +++ b/src/transformers/models/pix2struct/modeling_pix2struct.py @@ -142,7 +142,6 @@ def __init__(self, config): self.dropout = config.attention_dropout self.inner_dim = self.n_heads * self.key_value_proj_dim - # Mesh TensorFlow initialization to avoid scaling before softmax self.query = nn.Linear(self.hidden_size, self.inner_dim, bias=False) self.key = nn.Linear(self.hidden_size, self.inner_dim, bias=False) self.value = nn.Linear(self.hidden_size, self.inner_dim, bias=False) @@ -387,8 +386,6 @@ def _init_weights(self, module): if hasattr(module.wo, "bias") and module.wo.bias is not None: module.wo.bias.data.zero_() elif isinstance(module, Pix2StructTextAttention): - # Mesh TensorFlow attention initialization to avoid scaling before softmax - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/attention.py#L136 hidden_size = ( self.config.text_config.hidden_size if isinstance(self.config, Pix2StructConfig) @@ -651,7 +648,6 @@ def __init__( "when creating this class." ) - # Mesh TensorFlow initialization to avoid scaling before softmax self.query = nn.Linear(self.hidden_size, self.hidden_size, bias=False) self.key = nn.Linear(self.hidden_size, self.hidden_size, bias=False) self.value = nn.Linear(self.hidden_size, self.hidden_size, bias=False) diff --git a/src/transformers/models/pixtral/image_processing_pixtral.py b/src/transformers/models/pixtral/image_processing_pixtral.py index c6c6fdb163ab..86b11cd1f61a 100644 --- a/src/transformers/models/pixtral/image_processing_pixtral.py +++ b/src/transformers/models/pixtral/image_processing_pixtral.py @@ -366,10 +366,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -401,10 +399,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images[0]): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/pixtral/processing_pixtral.py b/src/transformers/models/pixtral/processing_pixtral.py index bb868156fb40..bf4eb9307c72 100644 --- a/src/transformers/models/pixtral/processing_pixtral.py +++ b/src/transformers/models/pixtral/processing_pixtral.py @@ -142,10 +142,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/poolformer/image_processing_poolformer.py b/src/transformers/models/poolformer/image_processing_poolformer.py index ee5500c823cc..ce3cd398745c 100644 --- a/src/transformers/models/poolformer/image_processing_poolformer.py +++ b/src/transformers/models/poolformer/image_processing_poolformer.py @@ -261,10 +261,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -294,10 +292,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/poolformer/modeling_poolformer.py b/src/transformers/models/poolformer/modeling_poolformer.py index 8c6dc8191630..b7ee51991f94 100755 --- a/src/transformers/models/poolformer/modeling_poolformer.py +++ b/src/transformers/models/poolformer/modeling_poolformer.py @@ -35,11 +35,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/pop2piano/modeling_pop2piano.py b/src/transformers/models/pop2piano/modeling_pop2piano.py index ea6d3a5eea9e..83bc759e72cf 100644 --- a/src/transformers/models/pop2piano/modeling_pop2piano.py +++ b/src/transformers/models/pop2piano/modeling_pop2piano.py @@ -189,7 +189,6 @@ def __init__( "when creating this class." ) - # Mesh TensorFlow initialization to avoid scaling before softmax self.q = nn.Linear(self.d_model, self.inner_dim, bias=False) self.k = nn.Linear(self.d_model, self.inner_dim, bias=False) self.v = nn.Linear(self.d_model, self.inner_dim, bias=False) @@ -595,15 +594,10 @@ def _init_weights(self, module): elif isinstance(module, Pop2PianoConcatEmbeddingToMel): module.embedding.weight.data.normal_(mean=0.0, std=factor * 1.0) elif isinstance(module, Pop2PianoForConditionalGeneration): - # Mesh TensorFlow embeddings initialization - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L1624 module.shared.weight.data.normal_(mean=0.0, std=factor * 1.0) if hasattr(module, "lm_head") and not self.config.tie_word_embeddings: module.lm_head.weight.data.normal_(mean=0.0, std=factor * 1.0) elif isinstance(module, Pop2PianoDenseActDense): - # Mesh TensorFlow FF initialization - # See https://github.com/tensorflow/mesh/blob/master/mesh_tensorflow/transformer/transformer_layers.py#L56 - # and https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L89 module.wi.weight.data.normal_(mean=0.0, std=factor * ((self.config.d_model) ** -0.5)) if hasattr(module.wi, "bias") and module.wi.bias is not None: module.wi.bias.data.zero_() @@ -621,8 +615,6 @@ def _init_weights(self, module): if hasattr(module.wo, "bias") and module.wo.bias is not None: module.wo.bias.data.zero_() elif isinstance(module, Pop2PianoAttention): - # Mesh TensorFlow attention initialization to avoid scaling before softmax - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/attention.py#L136 d_model = self.config.d_model key_value_proj_dim = self.config.d_kv n_heads = self.config.num_heads @@ -1207,8 +1199,6 @@ def forward( sequence_output = decoder_outputs[0] if self.config.tie_word_embeddings: - # Rescale output before projecting on vocab - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586 sequence_output = sequence_output * (self.model_dim**-0.5) lm_logits = self.lm_head(sequence_output) diff --git a/src/transformers/models/pop2piano/tokenization_pop2piano.py b/src/transformers/models/pop2piano/tokenization_pop2piano.py index f7aea3479f6f..0c2feec52d57 100644 --- a/src/transformers/models/pop2piano/tokenization_pop2piano.py +++ b/src/transformers/models/pop2piano/tokenization_pop2piano.py @@ -542,7 +542,6 @@ def __call__( return_tensors (`str` or [`~file_utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. verbose (`bool`, *optional*, defaults to `True`): @@ -609,7 +608,7 @@ def batch_decode( transformer to midi_notes and returns them. Args: - token_ids (`Union[np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[np.ndarray, torch.Tensor]`): Output token_ids of `Pop2PianoConditionalGeneration` model. feature_extractor_output (`BatchFeature`): Denotes the output of `Pop2PianoFeatureExtractor.__call__`. It must contain `"beatstep"` and diff --git a/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py b/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py index 4f0f68240f9a..7224aeef8612 100644 --- a/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py +++ b/src/transformers/models/prompt_depth_anything/image_processing_prompt_depth_anything.py @@ -336,10 +336,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -368,10 +366,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/pvt/image_processing_pvt.py b/src/transformers/models/pvt/image_processing_pvt.py index 9f687fe7548f..faec1739c811 100644 --- a/src/transformers/models/pvt/image_processing_pvt.py +++ b/src/transformers/models/pvt/image_processing_pvt.py @@ -189,10 +189,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -219,10 +217,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/pvt/modeling_pvt.py b/src/transformers/models/pvt/modeling_pvt.py index 21af67542d70..e77f0d5d748a 100755 --- a/src/transformers/models/pvt/modeling_pvt.py +++ b/src/transformers/models/pvt/modeling_pvt.py @@ -41,11 +41,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/pvt_v2/modeling_pvt_v2.py b/src/transformers/models/pvt_v2/modeling_pvt_v2.py index 204198787e45..a5c2f1e97d8d 100644 --- a/src/transformers/models/pvt_v2/modeling_pvt_v2.py +++ b/src/transformers/models/pvt_v2/modeling_pvt_v2.py @@ -40,11 +40,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py b/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py index b59644c37df9..817d9708d1d6 100644 --- a/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py +++ b/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py @@ -908,10 +908,8 @@ def __call__( tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/qwen2_5_vl/processing_qwen2_5_vl.py b/src/transformers/models/qwen2_5_vl/processing_qwen2_5_vl.py index b357ba850deb..0b2fc3dbfc38 100644 --- a/src/transformers/models/qwen2_5_vl/processing_qwen2_5_vl.py +++ b/src/transformers/models/qwen2_5_vl/processing_qwen2_5_vl.py @@ -121,10 +121,8 @@ def __call__( tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/qwen2_vl/image_processing_qwen2_vl.py b/src/transformers/models/qwen2_vl/image_processing_qwen2_vl.py index 552b289f58c0..36a58d68730b 100644 --- a/src/transformers/models/qwen2_vl/image_processing_qwen2_vl.py +++ b/src/transformers/models/qwen2_vl/image_processing_qwen2_vl.py @@ -360,10 +360,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -408,10 +406,7 @@ def preprocess( images = make_flat_list_of_images(images) if images is not None and not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( rescale_factor=rescale_factor, diff --git a/src/transformers/models/qwen2_vl/processing_qwen2_vl.py b/src/transformers/models/qwen2_vl/processing_qwen2_vl.py index 5bbbf6ac1aec..b237cb6079fb 100644 --- a/src/transformers/models/qwen2_vl/processing_qwen2_vl.py +++ b/src/transformers/models/qwen2_vl/processing_qwen2_vl.py @@ -116,10 +116,8 @@ def __call__( tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py index 7a2fa852739e..0a97489e285f 100644 --- a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py +++ b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py @@ -1337,10 +1337,8 @@ def __call__( tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/qwen3_vl/processing_qwen3_vl.py b/src/transformers/models/qwen3_vl/processing_qwen3_vl.py index cac82e738f39..7535d28a4ad0 100644 --- a/src/transformers/models/qwen3_vl/processing_qwen3_vl.py +++ b/src/transformers/models/qwen3_vl/processing_qwen3_vl.py @@ -137,10 +137,8 @@ def __call__( tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/rag/__init__.py b/src/transformers/models/rag/__init__.py index 8a8f135ba454..ce12d1526149 100644 --- a/src/transformers/models/rag/__init__.py +++ b/src/transformers/models/rag/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_rag import * from .modeling_rag import * - from .modeling_tf_rag import * from .retrieval_rag import * from .tokenization_rag import * else: diff --git a/src/transformers/models/rag/modeling_rag.py b/src/transformers/models/rag/modeling_rag.py index 13389107a2cb..3f646536c66c 100644 --- a/src/transformers/models/rag/modeling_rag.py +++ b/src/transformers/models/rag/modeling_rag.py @@ -257,10 +257,6 @@ def from_pretrained_question_encoder_generator( - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In - this case, `from_tf` should be set to `True` and a configuration object should be provided as - `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a - PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. generator_pretrained_model_name_or_path (`str`, *optional*, defaults to `None`): Information necessary to initiate the generator. Can be either: @@ -268,10 +264,6 @@ def from_pretrained_question_encoder_generator( - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In - this case, `from_tf` should be set to `True` and a configuration object should be provided as - `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a - PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. model_args (remaining positional arguments, *optional*): All remaining positional arguments will be passed to the underlying model's `__init__` method. diff --git a/src/transformers/models/rag/modeling_tf_rag.py b/src/transformers/models/rag/modeling_tf_rag.py deleted file mode 100644 index 155383772871..000000000000 --- a/src/transformers/models/rag/modeling_tf_rag.py +++ /dev/null @@ -1,1776 +0,0 @@ -# coding=utf-8 -# Copyright 2020, The RAG Authors and 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. - -"""TFRAG model implementation.""" - -from __future__ import annotations - -import copy -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...configuration_utils import PretrainedConfig -from ...generation import TFLogitsProcessorList -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - keras, - shape_list, - unpack_inputs, -) -from ...utils import ModelOutput, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_rag import RagConfig -from .retrieval_rag import RagRetriever - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "RagConfig" - - -@dataclass -class TFRetrievAugLMMarginOutput(ModelOutput): - """ - Base class for retriever augmented marginalized models outputs. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Language modeling loss. - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head. The score is possibly marginalized over all documents for - each vocabulary token. - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains precomputed hidden-states (key and values in the attention blocks) of the decoder that can be used - (see `past_key_values` input) to speed up sequential decoding. - doc_scores (`tf.Tensor` of shape `(batch_size, config.n_docs)`): - Score between each retrieved document embeddings (see `retrieved_doc_embeds`) and - `question_encoder_last_hidden_state`. - retrieved_doc_embeds (`tf.Tensor` of shape `(batch_size, config.n_docs, hidden_size)`, *optional*, returned when *output_retrieved=True*): - Embedded documents retrieved by the retriever. Is used with `question_encoder_last_hidden_state` to compute - the `doc_scores`. - retrieved_doc_ids (`tf.Tensor` (int32) of shape `(batch_size, config.n_docs)`, *optional*, returned when *output_retrieved=True*): - The indexes of the embedded documents retrieved by the retriever. - context_input_ids (`tf.Tensor`(int32) of shape `(batch_size * config.n_docs, config.max_combined_length)`, *optional*, returned when *output_retrieved=True*): - Input ids post-processed from the retrieved documents and the question encoder input_ids by the retriever. - context_attention_mask (`tf.Tensor` (int32) of shape `(batch_size * config.n_docs, config.max_combined_length)`, *optional*, returned when *output_retrieved=True*): - Attention mask post-processed from the retrieved documents and the question encoder `input_ids` by the - retriever. - question_encoder_last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden states at the output of the last layer of the question encoder pooled output of the - model. - question_enc_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings and one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden states of the question encoder at the output of each layer plus the initial embedding outputs. - question_enc_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the question encoder, after the attention softmax, used to compute the weighted - average in the self-attention heads. - generator_enc_last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the generator encoder of the model. - generator_enc_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings and one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden states of the generator encoder at the output of each layer plus the initial embedding outputs. - generator_enc_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the generator encoder, after the attention softmax, used to compute the weighted - average in the self-attention heads. - generator_dec_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings and one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden states of the generator decoder at the output of each layer plus the initial embedding outputs. - generator_dec_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the generator decoder, after the attention softmax, used to compute the weighted - average in the self-attention heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - doc_scores: tf.Tensor | None = None - retrieved_doc_embeds: tf.Tensor | None = None - retrieved_doc_ids: tf.Tensor | None = None - context_input_ids: tf.Tensor | None = None - context_attention_mask: tf.Tensor | None = None - question_encoder_last_hidden_state: tf.Tensor | None = None - question_enc_hidden_states: tuple[tf.Tensor, ...] | None = None - question_enc_attentions: tuple[tf.Tensor, ...] | None = None - generator_enc_last_hidden_state: tf.Tensor | None = None - generator_enc_hidden_states: tuple[tf.Tensor, ...] | None = None - generator_enc_attentions: tuple[tf.Tensor, ...] | None = None - generator_dec_hidden_states: tuple[tf.Tensor, ...] | None = None - generator_dec_attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFRetrievAugLMOutput(ModelOutput): - """ - Args: - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head. The score is possibly marginalized over all documents for - each vocabulary token. - past_key_values (`list[tf.Tensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - List of `tf.Tensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, num_heads, - sequence_length, embed_size_per_head)`). - - Contains precomputed hidden-states (key and values in the attention blocks) of the decoder that can be used - (see `past_key_values` input) to speed up sequential decoding. - doc_scores (`tf.Tensor` of shape `(batch_size, config.n_docs)`): - Score between each retrieved document embeddings (see `retrieved_doc_embeds`) and - `question_encoder_last_hidden_state`. - retrieved_doc_embeds (`tf.Tensor` of shape `(batch_size, config.n_docs, hidden_size)`, *optional*, returned when *output_retrieved=True*): - Embedded documents retrieved by the retriever. Is used with `question_encoder_last_hidden_state` to compute - the `doc_scores`. - retrieved_doc_ids (`tf.Tensor` of shape `(batch_size, config.n_docs)`, *optional*, returned when *output_retrieved=True*): - The indexes of the embedded documents retrieved by the retriever. - context_input_ids (`tf.Tensor` of shape `(batch_size * config.n_docs, config.max_combined_length)`, *optional*, returned when *output_retrieved=True*): - Input ids post-processed from the retrieved documents and the question encoder input_ids by the retriever. - context_attention_mask (`tf.Tensor` of shape `(batch_size * config.n_docs, config.max_combined_length)`, *optional*, returned when *output_retrieved=True*): - Attention mask post-processed from the retrieved documents and the question encoder `input_ids` by the - retriever. - question_encoder_last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden states at the output of the last layer of the question encoder pooled output of the - model. - question_enc_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings and one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden states of the question encoder at the output of each layer plus the initial embedding outputs. - question_enc_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the question encoder, after the attention softmax, used to compute the weighted - average in the self-attention heads. - generator_enc_last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the generator encoder of the model. - generator_enc_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings and one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden states of the generator encoder at the output of each layer plus the initial embedding outputs. - generator_enc_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the generator encoder, after the attention softmax, used to compute the weighted - average in the self-attention heads. - generator_dec_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings and one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden states of the generator decoder at the output of each layer plus the initial embedding outputs. - generator_dec_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights of the generator decoder, after the attention softmax, used to compute the weighted - average in the self-attention heads. - """ - - logits: tf.Tensor | None = None - past_key_values: list[tf.Tensor] | None = None - doc_scores: tf.Tensor | None = None - retrieved_doc_embeds: tf.Tensor | None = None - retrieved_doc_ids: tf.Tensor | None = None - context_input_ids: tf.Tensor | None = None - context_attention_mask: tf.Tensor | None = None - question_encoder_last_hidden_state: tf.Tensor | None = None - question_enc_hidden_states: tuple[tf.Tensor, ...] | None = None - question_enc_attentions: tuple[tf.Tensor, ...] | None = None - generator_enc_last_hidden_state: tf.Tensor | None = None - generator_enc_hidden_states: tuple[tf.Tensor, ...] | None = None - generator_enc_attentions: tuple[tf.Tensor, ...] | None = None - generator_dec_hidden_states: tuple[tf.Tensor, ...] | None = None - generator_dec_attentions: tuple[tf.Tensor, ...] | None = None - - -class TFRagPreTrainedModel(TFPreTrainedModel): - r""" - RAG models were released with the paper [Retrieval-Augmented Generation for Knowledge-Intensive NLP - Tasks](https://huggingface.co/papers/2005.11401) by Patrick Lewis, Ethan Perez, Aleksandra Piktus et al. - - RAG is a retriever augmented model and encapsulate three components: a question encoder, a dataset retriever and a - generator, the encoder and generator are trainable while the retriever is just an indexed dataset. - - """ - - config_class = RagConfig - base_model_prefix = "rag" - _keys_to_ignore_on_load_missing = [r"position_ids"] - - @classmethod - def from_pretrained_question_encoder_generator( - cls, - question_encoder_pretrained_model_name_or_path: str | None = None, - generator_pretrained_model_name_or_path: str | None = None, - retriever: RagRetriever = None, - *model_args, - **kwargs, - ) -> TFPreTrainedModel: - r""" - Instantiates an question encoder and a generator from one or two base classes of the library from pretrained - model checkpoints. - - Params: - question_encoder_pretrained_model_name_or_path (`str`, *optional*): - Information necessary to initiate the question encoder. Can be either: - - - A string with the *shortcut name* of a pretrained model to load from cache or download, e.g., - `google-bert/bert-base-uncased`. - - A string with the *identifier name* of a pretrained model that was user-uploaded to our S3, e.g., - `dbmdz/bert-base-german-cased`. - - A path to a *directory* containing model weights saved using - [`~TFPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *pytorch index checkpoint file* (e.g, `./pt_model/`). In this case, - `question_encoder_from_pt` should be set to `True`. - - generator_pretrained_model_name_or_path (`str`, *optional*, defaults to `None`): - Information necessary to initiate the generator. Can be either: - - - A string with the *shortcut name* of a pretrained model to load from cache or download, e.g., - `google-t5/t5-small`. - - A string with the *identifier name* of a pretrained model that was user-uploaded to our S3, e.g., - `facebook/bart-base`. - - A path to a *directory* containing model weights saved using - [`~TFPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *pytorch checkpoint file* (e.g, `./pt_model/`). In this case, - `generator_from_pt` should be set to `True`. - - model_args (remaining positional arguments, *optional*): - All remaining positional arguments will be passed to the underlying model's `__init__` method. - retriever ([`RagRetriever`], *optional*): - The retriever to use. - kwargs (remaining dictionary of keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). - - - To update the question_encoder configuration, use the prefix *question_encoder_* for each - configuration parameter. - - To update the generator configuration, use the prefix *generator_* for each configuration parameter. - - To update the parent model configuration, do not use a prefix for each configuration parameter. - - Behaves differently depending on whether a `config` is provided or automatically loaded. - - Example: - - ```python - >>> from transformers import RagRetriever, TFRagModel - - >>> # initialize a RAG from two pretrained models. - >>> model = TFRagModel.from_pretrained_question_encoder_generator( - ... "facebook/dpr-question_encoder-single-nq-base", "google-t5/t5-small" - ... ) - >>> # alternatively, initialize from pytorch pretrained models can also be done - >>> model = TFRagModel.from_pretrained_question_encoder_generator( - ... "facebook/dpr-question_encoder-single-nq-base", - ... "facebook/bart-base", - ... generator_from_pt=True, - ... question_encoder_from_pt=True, - ... ) - - >>> # saving model after fine-tuning - >>> model.save_pretrained("./rag") - - >>> # load retriever - >>> retriever = RagRetriever.from_pretrained( - ... "facebook/rag-token-base", index_name="exact", use_dummy_dataset=True - ... ) - >>> # load fine-tuned model with retriever - >>> model = TFRagModel.from_pretrained("./rag", retriever=retriever) - ```""" - - kwargs_question_encoder = { - argument[len("question_encoder_") :]: value - for argument, value in kwargs.items() - if argument.startswith("question_encoder_") - } - - kwargs_generator = { - argument[len("generator_") :]: value - for argument, value in kwargs.items() - if argument.startswith("generator_") - } - - # remove question_encoder, generator kwargs from kwargs - for key in kwargs_question_encoder: - del kwargs["question_encoder_" + key] - for key in kwargs_generator: - del kwargs["generator_" + key] - - # Load and initialize the question_encoder and generator - # The distinction between question_encoder and generator at the model level is made - # by the value of the flag `is_generator` that we need to set correctly. - question_encoder = kwargs_question_encoder.pop("model", None) - if question_encoder is None: - assert question_encoder_pretrained_model_name_or_path is not None, ( - "If `model` is not defined as an argument, a `question_encoder_pretrained_model_name_or_path` has to" - " be defined" - ) - - from ..auto.modeling_tf_auto import TFAutoModel - - if "config" not in kwargs_question_encoder: - from ..auto.configuration_auto import AutoConfig - - question_encoder_config = AutoConfig.from_pretrained(question_encoder_pretrained_model_name_or_path) - kwargs_question_encoder["config"] = question_encoder_config - - question_encoder = TFAutoModel.from_pretrained( - question_encoder_pretrained_model_name_or_path, - name="question_encoder", - load_weight_prefix=cls.load_weight_prefix, - *model_args, - **kwargs_question_encoder, - ) - - generator = kwargs_generator.pop("generator", None) - if generator is None: - assert generator_pretrained_model_name_or_path is not None, ( - "If `generator_model` is not defined as an argument, a `generator_pretrained_model_name_or_path` has" - " to be defined" - ) - - from ..auto.modeling_tf_auto import TFAutoModelForSeq2SeqLM - - if "config" not in kwargs_generator: - from ..auto.configuration_auto import AutoConfig - - generator_config = AutoConfig.from_pretrained(generator_pretrained_model_name_or_path) - kwargs_generator["config"] = generator_config - - generator = TFAutoModelForSeq2SeqLM.from_pretrained( - generator_pretrained_model_name_or_path, - name="generator", - load_weight_prefix=cls.load_weight_prefix, - **kwargs_generator, - ) - - # instantiate config with corresponding kwargs - config = kwargs.get("config") - if config is None: - config = RagConfig.from_question_encoder_generator_configs( - question_encoder.config, generator.config, **kwargs - ) - - return cls(question_encoder=question_encoder, generator=generator, config=config, retriever=retriever) - - -RAG_START_DOCSTRING = r""" - - RAG is a sequence-to-sequence model which encapsulates two core components: a question encoder and a generator. - During a forward pass, we encode the input with the question encoder and pass it to the retriever to extract - relevant context documents. The documents are then prepended to the input. Such contextualized inputs is passed to - the generator. - - The question encoder can be any *autoencoding* model, preferably [`TFDPRQuestionEncoder`], and the generator can be - any *seq2seq* model, preferably [`TFBartForConditionalGeneration`]. - - The model can be initialized with a [`RagRetriever`] for end-to-end generation or used in combination with the - outputs of a retriever in multiple steps---see examples for more details. The model is compatible any - *autoencoding* model as the `question_encoder` and any *seq2seq* model with language model head as the `generator`. - It has been tested with [`TFDPRQuestionEncoder`] as the `question_encoder` and [`TFBartForConditionalGeneration`] - as the `generator`. - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Tensorflow [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) - subclass. Use it as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to - general usage and behavior. - - The model is in a developing state as it is now fully supports in eager-mode only, and may not be exported in - SavedModel format. - - Args: - config ([`RagConfig`]): - Model configuration class with all the parameters of the model. Initializing with a config file does not - load the weights associated with the model, only the configuration. Check out the - [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. - question_encoder ([`TFPreTrainedModel`]): - An encoder model compatible with the faiss index encapsulated by the `retriever`. - generator ([`TFPreTrainedModel`]): - A seq2seq model used as the generator in the RAG architecture. - retriever ([`RagRetriever`]): - A retriever class encapsulating a faiss index queried to obtain context documents for current inputs. -""" - - -RAG_FORWARD_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. [`RagConfig`], used to initialize the model, specifies - which generator to use, it also specifies a compatible generator tokenizer. Use that tokenizer class to - obtain the indices. - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - encoder_outputs (`tuple(tuple(tf.Tensor)`, *optional*) - Tuple consists of (`generator_enc_last_hidden_state`, *optional*: `generator_enc_hidden_states`, - *optional*: `generator_enc_attentions`). `generator_enc_last_hidden_state` of shape `(batch_size, n_docs * - sequence_length, hidden_size)` is a sequence of hidden-states at the output of the last layer of the - generator's encoder. - - Used by the ([`TFRagModel`]) model during decoding. - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Provide for generation tasks. `None` by default, construct as per instructions for the generator model - you're using with your RAG instance. - decoder_attention_mask (`torch.BoolTensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - past_key_values (`tuple(tuple(tf.Tensor))`): - Tuple consists of two elements: `encoder_outputs` of the RAG model (see `encoder_outputs`) and - `past_key_values` of the underlying generator. Can be used to speed up decoding. `past_key_values` are used - in the ([`RagTokenForGeneration`]) model during decoding. - doc_scores (`tf.Tensor` of shape `(batch_size, config.n_docs)`): - Score between each retrieved document embeddings (see `retrieved_doc_embeds`) and - `question_encoder_last_hidden_state`. If the model has is not initialized with a `retriever` `doc_scores` - has to be provided to the forward pass. `doc_scores` can be computed via - `question_encoder_last_hidden_state` and `retrieved_doc_embeds`, see examples for more information. - context_input_ids (`tf.Tensor` of shape `(batch_size * config.n_docs, config.max_combined_length)`, *optional*, returned when *output_retrieved=True*): - Input IDs post-processed from the retrieved documents and the question encoder `input_ids` by the - retriever. - - If the model has is not initialized with a `retriever` ``context_input_ids` has to be provided to the - forward pass. `context_input_ids` are returned by [`~RagRetriever.__call__`]. context_attention_mask - (`tf.Tensor` of shape `(batch_size * config.n_docs, config.max_combined_length)`, *optional*, returned when - *output_retrieved=True*): Attention mask post-processed from the retrieved documents and the question - encoder `input_ids` by the retriever. - - If the model has is not initialized with a `retriever` `context_attention_mask` has to be provided to the - forward pass. `context_attention_mask` are returned by [`~RagRetriever.__call__`]. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - output_retrieved(`bool`, *optional*): - Whether or not to return the `retrieved_doc_embeds`, `retrieved_doc_ids`, `context_input_ids` and - `context_attention_mask`. See returned tensors for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`TFRetrievAugLMOutput`] instead of a plain tuple. - n_docs (`int`, *optional*, defaults to `config.n_docs``) - Number of documents to retrieve and/or number of documents for which to generate an answer. -""" - - -@add_start_docstrings_to_model_forward(RAG_START_DOCSTRING) -class TFRagModel(TFRagPreTrainedModel): - load_weight_prefix = "tf_rag_model_1" - - def __init__( - self, - config: PretrainedConfig | None = None, - question_encoder: TFPreTrainedModel | None = None, - generator: TFPreTrainedModel | None = None, - retriever: RagRetriever | None = None, - load_weight_prefix: str | None = None, - **kwargs, - ): - assert config is not None or (question_encoder is not None and generator is not None), ( - "Either a configuration or an question_encoder and a generator has to be provided." - ) - - if config is None: - config = RagConfig.from_question_encoder_generator_configs( - question_encoder.config, generator.config, **kwargs - ) - else: - assert isinstance(config, self.config_class), f"config: {config} has to be of type {self.config_class}" - super().__init__(config, **kwargs) - - if question_encoder is None: - from ..auto.modeling_tf_auto import TFAutoModel - - question_encoder = TFAutoModel.from_config(config.question_encoder, name="question_encoder") - - if generator is None: - from ..auto.modeling_tf_auto import TFAutoModelForSeq2SeqLM - - load_weight_prefix = load_weight_prefix if load_weight_prefix is not None else self.load_weight_prefix - generator = TFAutoModelForSeq2SeqLM.from_config( - config.generator, name="generator", load_weight_prefix=load_weight_prefix + "/generator" - ) - - self.retriever = retriever - if self.retriever is not None: - assert isinstance(retriever, RagRetriever), ( - f"`self.retriever` is of type {type(self.retriever)}, but should be of type `RagRetriever`" - ) - self.retriever = retriever - - self.question_encoder = question_encoder - self.generator = generator - - def set_retriever(self, retriever: RagRetriever): - self.retriever = retriever - - @unpack_inputs - @add_start_docstrings_to_model_forward(RAG_FORWARD_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFRetrievAugLMOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - doc_scores: np.ndarray | tf.Tensor | None = None, - context_input_ids: np.ndarray | tf.Tensor | None = None, - context_attention_mask: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - output_retrieved: bool | None = None, - n_docs: int | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ) -> TFRetrievAugLMOutput: - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, RagRetriever, TFRagModel - >>> import torch - from ...utils.deprecation import deprecate_kwarg - from ...utils.deprecation import deprecate_kwarg - from ...utils.deprecation import deprecate_kwarg - from ...utils.deprecation import deprecate_kwarg - - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/rag-token-base") - >>> retriever = RagRetriever.from_pretrained( - ... "facebook/rag-token-base", index_name="exact", use_dummy_dataset=True - ... ) - >>> # initialize with RagRetriever to do everything in one forward call - >>> model = TFRagModel.from_pretrained("facebook/rag-token-base", retriever=retriever, from_pt=True) - - >>> input_dict = tokenizer.prepare_seq2seq_batch( - ... "How many people live in Paris?", "In Paris, there are 10 million people.", return_tensors="tf" - ... ) - >>> input_ids = input_dict["input_ids"] - >>> outputs = model(input_ids) - ```""" - assert "decoder_cached_states" not in kwargs, ( - "Please use past_key_values to cache intermediate outputs" - ) # from modeling_tf_bart.py - - # aliasing to minimize code changing - n_docs = n_docs if n_docs is not None else self.config.n_docs - - # whether retriever has to be used - has_to_retrieve = ( - self.retriever is not None - and (context_input_ids is None or context_attention_mask is None or doc_scores is None) - and encoder_outputs is None - ) - - # encoder_outputs are pre-computed during RAG-token generation - if encoder_outputs is None: - if has_to_retrieve: - question_enc_outputs = self.question_encoder( - input_ids, attention_mask=attention_mask, return_dict=True, training=training - ) - # see https://github.com/huggingface/transformers/blob/main/src/transformers/models/dpr/modeling_tf_dpr.py#L91 - question_encoder_last_hidden_state = question_enc_outputs[ - 0 - ] # hidden states of question encoder => pooler_output - - retriever_outputs = self.retriever( - input_ids, - question_encoder_last_hidden_state.numpy(), - prefix=self.generator.config.prefix, - n_docs=n_docs, - return_tensors="tf", - ) - context_input_ids, context_attention_mask, retrieved_doc_embeds, retrieved_doc_ids = ( - retriever_outputs["context_input_ids"], - retriever_outputs["context_attention_mask"], - retriever_outputs["retrieved_doc_embeds"], - retriever_outputs["doc_ids"], - ) - - context_input_ids = tf.cast(context_input_ids, tf.int32) - context_attention_mask = tf.cast(context_attention_mask, tf.int32) - retrieved_doc_embeds = tf.cast(retrieved_doc_embeds, tf.float32) - retrieved_doc_ids = tf.cast(retrieved_doc_ids, tf.int32) - - # compute doc_scores - doc_scores = tf.squeeze( - tf.matmul( - tf.expand_dims(question_encoder_last_hidden_state, axis=1), - retrieved_doc_embeds, - transpose_b=True, - ), - axis=1, - ) - - else: - assert context_input_ids is not None, ( - "Make sure that `context_input_ids` are passed, if no `retriever` is set. Alternatively, you can" - " set a retriever using the `set_retriever(...)` function." - ) - assert context_attention_mask is not None, ( - "Make sure that `context_attention_mask` are passed, if no `retriever` is set. Alternatively, you" - " can set a retriever using the `set_retriever(...)` function." - ) - assert doc_scores is not None, ( - "Make sure that `doc_scores` are passed, if no `retriever` is set. Alternatively, you can set a" - " retriever using the `set_retriever(...)` function." - ) - - assert doc_scores is not None, ( - "Make sure that `doc_scores` are passed when passing `encoder_outputs` to the forward function." - ) - - assert (doc_scores.shape[1] % n_docs) == 0, ( - f" The first dimension of `context_input_ids` should be a multiple of `n_docs`={n_docs}, but is" - f" {context_input_ids.shape[0]}." - ) - - # Decoder input without context documents - if decoder_input_ids is not None: - decoder_input_ids = tf.repeat(decoder_input_ids, n_docs, axis=0) - - if decoder_attention_mask is not None: - decoder_attention_mask = tf.repeat(decoder_attention_mask, n_docs, axis=0) - - gen_outputs = self.generator( - context_input_ids, - attention_mask=context_attention_mask, - encoder_outputs=encoder_outputs, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - return_dict=True, - training=training, - ) - - if not has_to_retrieve: - question_encoder_last_hidden_state = None - question_enc_hidden_states = None - question_enc_attentions = None - retrieved_doc_embeds = None - retrieved_doc_ids = None - else: - question_enc_hidden_states = question_enc_outputs.hidden_states - question_enc_attentions = question_enc_outputs.attentions - - if not has_to_retrieve or not output_retrieved: - # don't output retrieved docs - context_input_ids = (None,) - context_attention_mask = None - retrieved_doc_embeds = None - retrieved_doc_ids = None - - return TFRetrievAugLMOutput( - logits=gen_outputs.logits, - doc_scores=doc_scores, - past_key_values=gen_outputs.past_key_values, - context_input_ids=context_input_ids, - context_attention_mask=context_attention_mask, - retrieved_doc_embeds=retrieved_doc_embeds, - retrieved_doc_ids=retrieved_doc_ids, - question_encoder_last_hidden_state=question_encoder_last_hidden_state, - question_enc_hidden_states=question_enc_hidden_states, - question_enc_attentions=question_enc_attentions, - generator_enc_last_hidden_state=gen_outputs.encoder_last_hidden_state, - generator_enc_hidden_states=gen_outputs.encoder_hidden_states, - generator_enc_attentions=gen_outputs.encoder_attentions, - generator_dec_hidden_states=gen_outputs.decoder_hidden_states, - generator_dec_attentions=gen_outputs.decoder_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - with tf.name_scope(self.generator.name): - self.generator.build(None) - with tf.name_scope(self.question_encoder.name): - self.question_encoder.build(None) - - -@add_start_docstrings_to_model_forward( - """ - A TF RAG-token model implementation. It performs RAG-token specific marginalization in the forward pass. - """, - RAG_START_DOCSTRING, -) -class TFRagTokenForGeneration(TFRagPreTrainedModel, TFCausalLanguageModelingLoss): - load_weight_prefix = "tf_rag_token_for_generation_1/rag" - - def __init__( - self, - config: PretrainedConfig | None = None, - question_encoder: TFPreTrainedModel | None = None, - generator: TFPreTrainedModel | None = None, - retriever: RagRetriever | None = None, - **kwargs, - ): - assert config is not None or (question_encoder is not None and generator is not None), ( - "Either a configuration or an encoder and a generator has to be provided." - ) - - if config is None: - config = RagConfig.from_question_encoder_generator_configs( - question_encoder.config, generator.config, **kwargs - ) - - super().__init__(config) - - # instantiate model - self.rag = TFRagModel( - config=config, - question_encoder=question_encoder, - generator=generator, - retriever=retriever, - load_weight_prefix=self.load_weight_prefix, - name="rag", - ) - - def set_retriever(self, retriever: RagRetriever): - self.rag.retriever = retriever - - # Adapted from https://github.com/huggingface/transformers/blob/main/src/transformers/modeling_tf_bart.py - def prepare_inputs_for_generation( - self, - decoder_input_ids, - past_key_values=None, - attention_mask=None, - use_cache=None, - encoder_outputs=None, - doc_scores=None, - n_docs=None, - **kwargs, - ): - if past_key_values is not None: - # if past is defined use only last decoder_input_ids - decoder_input_ids = decoder_input_ids[:, -1:] - - return { - "input_ids": None, - "encoder_outputs": encoder_outputs, - "doc_scores": doc_scores, - "context_attention_mask": attention_mask, - "decoder_input_ids": decoder_input_ids, - "past_key_values": past_key_values, - "use_cache": use_cache, - "do_marginalize": True, - "n_docs": n_docs, - } - - @property - def retriever(self): - return self.rag.retriever - - @property - def generator(self): - return self.rag.generator - - @property - def question_encoder(self): - return self.rag.question_encoder - - @staticmethod - def _gather_beams(nested, beam_indices, batch_axis=0): - """ - RAG-specific `_gather_beams`: gathers the beam slices indexed by beam_indices into new beam array. If the - nested tensor has a shape mismatch with the beam indices, then it means it is the cache. In that case, isolates - and takes care of the extra dimension for ndocs. - """ - - def gather_fn(tensor): - is_rag_cache = tensor.shape[0] != beam_indices.shape[0] - if is_rag_cache: - n_docs = tensor.shape[0] // beam_indices.shape[0] - batch_size = beam_indices.shape[0] - # reshapes into (batch size, num beams, n_docs, ...), the cache format expected by RAG - tensor = tf.reshape(tensor, (batch_size, -1, n_docs, *tensor.shape[2:])) - - gathered_tensor = tf.gather(params=tensor, indices=beam_indices, axis=1, batch_dims=1) - - if is_rag_cache: - # reshapes back into the shape expected by beam search - gathered_tensor = tf.reshape(gathered_tensor, (batch_size * n_docs, -1, *gathered_tensor.shape[3:])) - - return gathered_tensor - - return tf.nest.map_structure(gather_fn, nested) - - def marginalize(self, seq_logits, doc_scores, n_docs=None): - n_docs = n_docs if n_docs is not None else self.config.n_docs - - # RAG-token marginalization - seq_logprobs = tf.nn.log_softmax(seq_logits, axis=-1) - seq_logprobs = tf.reshape(seq_logprobs, [seq_logits.shape[0] // n_docs, n_docs, -1, seq_logits.shape[-1]]) - doc_logprobs = tf.nn.log_softmax(doc_scores, axis=1) - doc_logprobs = tf.expand_dims(doc_logprobs, axis=-1) - doc_logprobs = tf.expand_dims(doc_logprobs, axis=-1) # twice - log_prob_sum = seq_logprobs + doc_logprobs - return tf.reduce_logsumexp(log_prob_sum, axis=1) - - @unpack_inputs - @add_start_docstrings_to_model_forward(RAG_FORWARD_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFRetrievAugLMMarginOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - doc_scores: np.ndarray | tf.Tensor | None = None, - context_input_ids: np.ndarray | tf.Tensor | None = None, - context_attention_mask: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - output_retrieved: bool | None = None, - n_docs: int | None = None, - do_marginalize: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - reduce_loss: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, # needs kwargs for generation - ) -> TFRetrievAugLMMarginOutput: - r""" - do_marginalize (`bool`, *optional*): - If `True`, the logits are marginalized over all documents by making use of - `torch.nn.functional.log_softmax`. - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss according to Rag-Token model formulation See - https://huggingface.co/papers/2005.11401 Section 2.1 for details about Rag-Token formulation. Indices should be - in `[0, ..., config.vocab_size - 1]`. - reduce_loss (`bool`, *optional*): - Only relevant if `labels` is passed. If `True`, the NLL loss is reduced using the `tf.Tensor.sum` - operation. - kwargs (`dict[str, any]`, *optional*, defaults to `{}`): - Legacy dictionary, which is required so that model can use *generate()* function. - - Returns: - - Example: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoTokenizer, RagRetriever, TFRagTokenForGeneration - - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/rag-token-nq") - >>> retriever = RagRetriever.from_pretrained( - ... "facebook/rag-token-nq", index_name="exact", use_dummy_dataset=True - ... ) - >>> # initialize with RagRetriever to do everything in one forward call - >>> model = TFRagTokenForGeneration.from_pretrained("facebook/rag-token-nq", retriever=retriever, from_pt=True) - - >>> input_dict = tokenizer.prepare_seq2seq_batch( - ... "How many people live in Paris?", "In Paris, there are 10 million people.", return_tensors="tf" - ... ) - >>> outputs = model(input_dict, output_retrieved=True) - - >>> # or use retriever separately - >>> # 1. Encode - >>> input_ids = input_dict["input_ids"] - >>> question_hidden_states = model.question_encoder(input_ids)[0] - >>> # 2. Retrieve - >>> docs_dict = retriever(input_ids.numpy(), question_hidden_states.numpy(), return_tensors="tf") - >>> doc_scores = tf.squeeze( - ... tf.matmul( - ... tf.expand_dims(question_hidden_states, axis=1), docs_dict["retrieved_doc_embeds"], transpose_b=True - ... ), - ... axis=1, - ... ) - >>> # 3. Forward to generator - >>> outputs = model( - ... inputs=None, - ... context_input_ids=docs_dict["context_input_ids"], - ... context_attention_mask=docs_dict["context_attention_mask"], - ... doc_scores=doc_scores, - ... decoder_input_ids=input_dict["labels"], - ... ) - - >>> # or directly generate - >>> generated = model.generate( - ... context_input_ids=docs_dict["context_input_ids"], - ... context_attention_mask=docs_dict["context_attention_mask"], - ... doc_scores=doc_scores, - ... ) - >>> generated_string = tokenizer.batch_decode(generated, skip_special_tokens=True) - ```""" - - assert "decoder_cached_states" not in kwargs, ( - "Please use past_key_values to cache intermediate outputs" - ) # from modeling_tf_bart.py - - do_marginalize = do_marginalize if do_marginalize else self.config.do_marginalize - reduce_loss = reduce_loss if reduce_loss else self.config.reduce_loss - - if labels is not None: - if decoder_input_ids is None: - decoder_input_ids = labels - use_cache = False - - outputs = self.rag( - input_ids, - attention_mask=attention_mask, - encoder_outputs=encoder_outputs, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - context_input_ids=context_input_ids, - context_attention_mask=context_attention_mask, - doc_scores=doc_scores, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - output_retrieved=output_retrieved, - n_docs=n_docs, - training=training, - ) - - loss = None - logits = outputs.logits - if labels is not None: - assert decoder_input_ids is not None - loss = self.get_nll( - outputs.logits, - outputs.doc_scores, - labels, - reduce_loss=reduce_loss, - epsilon=self.config.label_smoothing, - n_docs=n_docs, - ) - - if do_marginalize: - logits = self.marginalize(logits, outputs.doc_scores, n_docs) - - return TFRetrievAugLMMarginOutput( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - doc_scores=outputs.doc_scores, - context_input_ids=outputs.context_input_ids, - context_attention_mask=outputs.context_attention_mask, - retrieved_doc_embeds=outputs.retrieved_doc_embeds, - retrieved_doc_ids=outputs.retrieved_doc_ids, - question_encoder_last_hidden_state=outputs.question_encoder_last_hidden_state, - question_enc_hidden_states=outputs.question_enc_hidden_states, - question_enc_attentions=outputs.question_enc_attentions, - generator_enc_last_hidden_state=outputs.generator_enc_last_hidden_state, - generator_enc_hidden_states=outputs.generator_enc_hidden_states, - generator_enc_attentions=outputs.generator_enc_attentions, - generator_dec_hidden_states=outputs.generator_dec_hidden_states, - generator_dec_attentions=outputs.generator_dec_attentions, - ) - - def generate( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - context_input_ids=None, - context_attention_mask=None, - doc_scores=None, - n_docs=None, - generation_config=None, - logits_processor=TFLogitsProcessorList(), - **kwargs, - ): - """ - Implements TFRAG token decoding. - - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - The sequence used as a prompt for the generation. If `input_ids` is not passed, then - `context_input_ids` has to be provided. - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - context_input_ids (`tf.Tensor` of shape `(batch_size * config.n_docs, config.max_combined_length)`, *optional*, returned when *output_retrieved=True*): - Input IDs post-processed from the retrieved documents and the question encoder `input_ids` by the - retriever. - - If the model has is not initialized with a `retriever`, `context_input_ids` has to be provided to the - forward pass. `context_input_ids` are returned by [`~RagRetriever.__call__`]. - context_attention_mask (`tf.Tensor` of shape `(batch_size * config.n_docs, config.max_combined_length)`, *optional*, returned when *output_retrieved=True*): - Attention mask post-processed from the retrieved documents and the question encoder `input_ids` by the - retriever. - - If the model has is not initialized with a `retriever`, `context_input_ids` has to be provided to the - forward pass. `context_input_ids` are returned by [`~RagRetriever.__call__`]. - doc_scores (`tf.Tensor` of shape `(batch_size, config.n_docs)`): - Score between each retrieved document embeddings (see `retrieved_doc_embeds`) and - `question_encoder_last_hidden_state`. - - If the model has is not initialized with a `retriever`, `context_input_ids` has to be provided to the - forward pass. `context_input_ids` are returned by [`~RagRetriever.__call__`]. - n_docs (`int`, *optional*, defaults to `config.n_docs`) - Number of documents to retrieve and/or number of documents for which to generate an answer. - generation_config (`~generation.GenerationConfig`, *optional*): - The generation configuration to be used as base parametrization for the generation call. `**kwargs` - passed to generate matching the attributes of `generation_config` will override them. If - `generation_config` is not provided, the default will be used, which had the following loading - priority: 1) from the `generation_config.json` model file, if it exists; 2) from the model - configuration. Please note that unspecified parameters will inherit [`~generation.GenerationConfig`]'s - default values, whose documentation should be checked to parameterize generation. - logits_processor (`TFLogitsProcessorList`, *optional*): - Custom logits processors that complement the default logits processors built from arguments and a - model's config. If a logit processor is passed that is already created with the arguments or a model's - config an error is thrown. - kwargs (`dict[str, Any]`, *optional*): - Ad hoc parametrization of `generate_config` and/or additional model-specific kwargs that will be - forwarded to the `forward` function of the model. - - Return: - `tf.Tensor` of shape `(batch_size * num_return_sequences, sequence_length)`: The generated sequences. The - second dimension (sequence_length) is either equal to `max_length` or shorter if all batches finished early - due to the `eos_token_id`. - """ - # Handle `generation_config` and kwargs that might update it - if generation_config is None: - generation_config = self.generation_config - generation_config = copy.deepcopy(generation_config) - model_kwargs = generation_config.update(**kwargs) # All unused kwargs must be model kwargs - - # set default parameters - n_docs = n_docs if n_docs is not None else self.config.n_docs - - # retrieve docs - if self.retriever is not None and context_input_ids is None: - question_hidden_states = self.question_encoder(input_ids, attention_mask=attention_mask)[0] - out = self.retriever( - input_ids, - question_hidden_states.numpy().astype(np.float32), - prefix=self.generator.config.prefix, - n_docs=n_docs, - return_tensors="tf", - ) - context_input_ids, context_attention_mask, retrieved_doc_embeds = ( - out["context_input_ids"], - out["context_attention_mask"], - out["retrieved_doc_embeds"], - ) - - context_input_ids = tf.cast(context_input_ids, tf.int32) - context_attention_mask = tf.cast(context_attention_mask, tf.int32) - retrieved_doc_embeds = tf.cast(retrieved_doc_embeds, tf.float32) - - # compute doc_scores - doc_scores = tf.matmul( - tf.expand_dims(question_hidden_states, axis=1), retrieved_doc_embeds, transpose_b=True - ) - doc_scores = tf.squeeze(doc_scores, axis=1) - - assert (context_input_ids.shape[0] % n_docs) == 0, ( - f" The first dimension of `context_input_ids` should be a multiple of `n_docs`={n_docs}, but is" - f" {context_input_ids.shape[0]}." - ) - - batch_size = context_input_ids.shape[0] // n_docs - - encoder = self.rag.generator.get_encoder() - encoder_outputs = encoder( - input_ids=context_input_ids, - attention_mask=context_attention_mask, - output_attentions=generation_config.output_attentions, - output_hidden_states=generation_config.output_hidden_states, - return_dict=True, - ) - - decoder_input_ids = tf.fill( - (batch_size * generation_config.num_beams, 1), - tf.cast(generation_config.decoder_start_token_id, tf.int32), - ) - last_hidden_state = encoder_outputs["last_hidden_state"] - - def extend_enc_output(tensor, num_beams=None): - """ - Broadcast tensor with `num_beams` replica, with correct order Input: tensor of shape (batch_size*n_docs , - d) Output: tensor of shape (batch_size*num_beams*n_docs , d) - """ - - # expand batch_size & num_beam dimensions - d_shape_list = tensor.shape[1:] - - # split n_docs dimensions - new_shape = (batch_size, 1, n_docs) + d_shape_list - tensor = tf.reshape(tensor, new_shape) - - # repeat same last hidden states over `num_beams` dimension - new_shape = (batch_size, num_beams, n_docs) + d_shape_list - tensor = tf.broadcast_to(tensor, new_shape) - - # merge `batch_size`, `num_beams`, `num_docs` dims again - new_shape = (batch_size * num_beams * n_docs,) + d_shape_list - return tf.reshape(tensor, new_shape) - - # correctly extend last_hidden_state and attention mask - context_attention_mask = extend_enc_output(context_attention_mask, num_beams=generation_config.num_beams) - encoder_outputs["last_hidden_state"] = extend_enc_output( - last_hidden_state, num_beams=generation_config.num_beams - ) - - doc_scores = tf.repeat(doc_scores, generation_config.num_beams, axis=0) - - # define start_len & additional parameters - model_kwargs["doc_scores"] = doc_scores - model_kwargs["encoder_outputs"] = encoder_outputs - model_kwargs["attention_mask"] = context_attention_mask - model_kwargs["n_docs"] = n_docs - - pre_processor = self._get_logits_processor( - generation_config=generation_config, - input_ids_seq_length=tf.shape(decoder_input_ids)[-1], - logits_processor=logits_processor, - ) - - if generation_config.num_beams == 1: - return self.greedy_search( - input_ids=decoder_input_ids, - max_length=generation_config.max_length, - pad_token_id=generation_config.pad_token_id, - eos_token_id=generation_config.eos_token_id, - logits_processor=pre_processor, - output_attentions=generation_config.output_attentions, - output_hidden_states=generation_config.output_hidden_states, - output_scores=generation_config.output_scores, - return_dict_in_generate=generation_config.return_dict_in_generate, - **model_kwargs, - ) - elif generation_config.num_beams > 1: - if generation_config.num_beams < generation_config.num_return_sequences: - raise ValueError( - "Beam search decoding cannot return more sequences than it has beams. Please set num_beams >=" - f" num_return_sequences, got {generation_config.num_beams} and" - f" {generation_config.num_return_sequences} (respectively)" - ) - - def unflatten_beam_dim(tensor): - """Unflattens the first, flat batch*beam dimension of a non-scalar array.""" - shape = shape_list(tensor) - return tf.reshape(tensor, [-1, generation_config.num_beams] + shape[1:]) - - decoder_input_ids = unflatten_beam_dim(decoder_input_ids) - model_kwargs["attention_mask"] = unflatten_beam_dim(model_kwargs["attention_mask"]) - model_kwargs["encoder_outputs"]["last_hidden_state"] = unflatten_beam_dim( - model_kwargs["encoder_outputs"]["last_hidden_state"] - ) - - return self.beam_search( - input_ids=decoder_input_ids, - max_length=generation_config.max_length, - pad_token_id=generation_config.pad_token_id, - eos_token_id=generation_config.eos_token_id, - logits_processor=pre_processor, - output_attentions=generation_config.output_attentions, - output_hidden_states=generation_config.output_hidden_states, - output_scores=generation_config.output_scores, - return_dict_in_generate=generation_config.return_dict_in_generate, - **model_kwargs, - ) - else: - raise ValueError( - f"`num_beams` has to be an integer strictly superior to 0 (≥ 1), but is {generation_config.num_beams}" - ) - - def get_input_embeddings(self): - return self.rag.generator.get_input_embeddings() - - def get_output_embeddings(self): - return self.rag.generator.get_output_embeddings() - - # Adapted from tf_t5's & tf_bart's _shift_right - def shift_tokens_right(self, input_ids, start_token_id=None): - """Shift input ids one token to the right, and pad with start_token_id""" - - if start_token_id is None: - start_token_id = self.generator.config.decoder_start_token_id - assert start_token_id is not None, ( - "self.generator.config.decoder_start_token_id has to be defined. In Rag we commonly use Bart as" - " generator, see Bart docs for more information" - ) - - pad_token_id = self.generator.config.pad_token_id - assert pad_token_id is not None, "self.model.config.pad_token_id has to be defined." - - start_tokens = tf.fill((shape_list(input_ids)[0], 1), tf.cast(start_token_id, input_ids.dtype)) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.fill(shape_list(shifted_input_ids), tf.cast(pad_token_id, input_ids.dtype)), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.cast(0, shifted_input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - # nll stands for 'negative log likelihood' - def get_nll(self, seq_logits, doc_scores, target, reduce_loss=False, epsilon=0.0, n_docs=None): - n_docs = n_docs if n_docs is not None else self.config.n_docs - # shift tokens left (from original Pytorch's version) - - target = tf.concat( - [target[:, 1:], tf.fill([target.shape[0], 1], tf.cast(self.config.generator.pad_token_id, target.dtype))], - axis=1, - ) - rag_logprobs = self.marginalize(seq_logits, doc_scores, n_docs) - loss = self.hf_compute_loss(target, rag_logprobs, from_logits=True, reduce_loss=reduce_loss) - - return loss - - # Adopted modeling_tf_bart + add smooth_loss to match with pytorch version - def hf_compute_loss(self, labels, y_pred, smooth_epsilon=0.0, from_logits=True, reduce_loss=False): - """CrossEntropyLoss that ignores pad tokens""" - # Matt: As written, this loss is not XLA-compatible, but it's doing some very weird things - # and I don't feel comfortable converting it. - loss_fn = keras.losses.SparseCategoricalCrossentropy( - from_logits=True, - reduction=keras.losses.Reduction.SUM, - ) - - if from_logits is False: # convert to logits - eps = 1e-9 - y_pred = tf.clip_by_value(y_pred, clip_value_min=eps, clip_value_max=1 - eps) - y_pred = tf.math.log(y_pred) - - logits = y_pred - melted_labels = tf.reshape(labels, (-1,)) - active_loss = tf.not_equal(melted_labels, self.config.generator.pad_token_id) - - reduced_logits = tf.boolean_mask(tf.reshape(logits, (-1, logits.shape[2])), active_loss) - labels = tf.boolean_mask(melted_labels, active_loss) - nll_loss = loss_fn(labels, reduced_logits) - - smooth_loss = -tf.reduce_sum(reduced_logits, axis=-1) - smooth_loss = tf.reduce_sum(smooth_loss) # sum and squeeze like torch - eps_i = smooth_epsilon / reduced_logits.shape[-1] - - loss = (1.0 - smooth_epsilon) * nll_loss + eps_i * smooth_loss - - return loss - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rag", None) is not None: - with tf.name_scope(self.rag.name): - self.rag.build(None) - - -@add_start_docstrings_to_model_forward( - """ - A TF RAG-sequence model implementation. It performs RAG-sequence specific marginalization in the forward pass. - """, - RAG_START_DOCSTRING, -) -class TFRagSequenceForGeneration(TFRagPreTrainedModel, TFCausalLanguageModelingLoss): - load_weight_prefix = "tf_rag_sequence_for_generation_1/rag" - - def __init__( - self, - config: PretrainedConfig | None = None, - question_encoder: TFPreTrainedModel | None = None, - generator: TFPreTrainedModel | None = None, - retriever: RagRetriever | None = None, - **kwargs, - ): - assert config is not None or (question_encoder is not None and generator is not None), ( - "Either a configuration or an encoder and a generator has to be provided." - ) - - if config is None: - config = RagConfig.from_question_encoder_generator_configs( - question_encoder.config, generator.config, **kwargs - ) - - super().__init__(config) - - # instantiate model - self.rag = TFRagModel( - config=config, - question_encoder=question_encoder, - generator=generator, - retriever=retriever, - load_weight_prefix=self.load_weight_prefix, - name="rag", - ) - - def set_retriever(self, retriever: RagRetriever): - self.rag.retriever = retriever - - @property - def retriever(self): - return self.rag.retriever - - @property - def generator(self): - return self.rag.generator - - @property - def question_encoder(self): - return self.rag.question_encoder - - @unpack_inputs - @add_start_docstrings_to_model_forward(RAG_FORWARD_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFRetrievAugLMMarginOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - doc_scores: np.ndarray | tf.Tensor | None = None, - context_input_ids: np.ndarray | tf.Tensor | None = None, - context_attention_mask: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - output_retrieved: bool | None = None, - n_docs: int | None = None, - exclude_bos_score: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - reduce_loss: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, # needs kwargs for generation - ) -> tuple[tf.Tensor] | TFRetrievAugLMMarginOutput: - r""" - exclude_bos_score (`bool`, *optional*): - Only relevant if `labels` is passed. If `True`, the score of the BOS token is disregarded when computing - the loss. - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss according to Rag-Sequence model formulation See - https://huggingface.co/papers/2005.11401 Section 2.1 for details about Rag-Sequence formulation. Indices should - be in `[0, ..., config.vocab_size - 1]`. - reduce_loss (`bool`, *optional*): - Only relevant if `labels` is passed. If `True`, the NLL loss is reduced using the `tf.Tensor.sum` - operation. - kwargs (`dict[str, any]`, *optional*, defaults to `{}`): - Legacy dictionary, which is required so that model can use *generate()* function. - - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, RagRetriever, TFRagSequenceForGeneration - - >>> tokenizer = AutoTokenizer.from_pretrained("facebook/rag-sequence-nq") - >>> retriever = RagRetriever.from_pretrained( - ... "facebook/rag-sequence-nq", index_name="exact", use_dummy_dataset=True - ... ) - >>> # initialize with RagRetriever to do everything in one forward call - >>> model = TFRagSequenceForGeneration.from_pretrained( - ... "facebook/rag-sequence-nq", retriever=retriever, from_pt=True - ... ) - - >>> input_dict = tokenizer.prepare_seq2seq_batch( - ... "How many people live in Paris?", "In Paris, there are 10 million people.", return_tensors="tf" - ... ) - >>> outputs = model(input_dict, output_retrieved=True) - - >>> # or use retriever separately - >>> # 1. Encode - >>> input_ids = input_dict["input_ids"] - >>> question_hidden_states = model.question_encoder(input_ids)[0] - >>> # 2. Retrieve - >>> docs_dict = retriever(input_ids.numpy(), question_hidden_states.numpy(), return_tensors="tf") - >>> doc_scores = tf.squeeze( - ... tf.matmul( - ... tf.expand_dims(question_hidden_states, axis=1), docs_dict["retrieved_doc_embeds"], transpose_b=True - ... ), - ... axis=1, - ... ) - >>> # 3. Forward to generator - >>> outputs = model( - ... inputs=None, - ... context_input_ids=docs_dict["context_input_ids"], - ... context_attention_mask=docs_dict["context_attention_mask"], - ... doc_scores=doc_scores, - ... decoder_input_ids=input_dict["labels"], - ... ) - - >>> # or directly generate - >>> generated = model.generate( - ... context_input_ids=docs_dict["context_input_ids"], - ... context_attention_mask=docs_dict["context_attention_mask"], - ... doc_scores=doc_scores, - ... ) - >>> generated_string = tokenizer.batch_decode(generated, skip_special_tokens=True) - ```""" - - assert "decoder_cached_states" not in kwargs, ( - "Please use past_key_values to cache intermediate outputs" - ) # from modeling_tf_bart.py - - exclude_bos_score = exclude_bos_score if exclude_bos_score else self.config.exclude_bos_score - reduce_loss = reduce_loss if reduce_loss else self.config.reduce_loss - - if labels is not None: - if decoder_input_ids is None: - decoder_input_ids = labels - use_cache = False - - outputs = self.rag( - input_ids, - attention_mask=attention_mask, - encoder_outputs=encoder_outputs, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - context_input_ids=context_input_ids, - context_attention_mask=context_attention_mask, - doc_scores=doc_scores, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - output_retrieved=output_retrieved, - n_docs=n_docs, - training=training, - ) - - loss = None - if labels is not None: - loss = self.get_nll( - outputs.logits, - outputs.doc_scores, - labels, - reduce_loss=reduce_loss, - epsilon=self.config.label_smoothing, - n_docs=n_docs, - ) - - return TFRetrievAugLMMarginOutput( - loss=loss, - logits=outputs.logits, - doc_scores=outputs.doc_scores, - past_key_values=outputs.past_key_values, - context_input_ids=outputs.context_input_ids, - context_attention_mask=outputs.context_attention_mask, - retrieved_doc_embeds=outputs.retrieved_doc_embeds, - retrieved_doc_ids=outputs.retrieved_doc_ids, - question_encoder_last_hidden_state=outputs.question_encoder_last_hidden_state, - question_enc_hidden_states=outputs.question_enc_hidden_states, - question_enc_attentions=outputs.question_enc_attentions, - generator_enc_last_hidden_state=outputs.generator_enc_last_hidden_state, - generator_enc_hidden_states=outputs.generator_enc_hidden_states, - generator_enc_attentions=outputs.generator_enc_attentions, - generator_dec_hidden_states=outputs.generator_dec_hidden_states, - generator_dec_attentions=outputs.generator_dec_attentions, - ) - - def get_nll( - self, seq_logits, doc_scores, target, reduce_loss=False, epsilon=0.0, exclude_bos_score=False, n_docs=None - ): - # shift tokens left - target = tf.concat( - [target[:, 1:], tf.fill([target.shape[0], 1], tf.cast(self.config.generator.pad_token_id, target.dtype))], - axis=1, - ) - - # bos_token_id is None for T5 - bos_token_id = self.config.bos_token_id or self.config.generator.bos_token_id - n_docs = n_docs if n_docs is not None else self.config.n_docs - equal_bos_token_id_all = tf.reduce_all(tf.equal(target[:, 0], bos_token_id)) - use_bos = bos_token_id is not None and equal_bos_token_id_all - - def _mask_pads(ll, smooth_obj): - pad_mask = tf.equal(target, tf.cast(self.config.generator.pad_token_id, target.dtype)) - if tf.reduce_any(pad_mask): - ll = tf.where(pad_mask, 0.0, ll) - smooth_obj = tf.where(pad_mask, 0.0, smooth_obj) - return tf.squeeze(ll, axis=-1), tf.squeeze(smooth_obj, axis=-1) - - # seq_logits.shape = (batch*n_docs, tgt_len , vocabs) - seq_logprobs = tf.nn.log_softmax(seq_logits, axis=-1) - seq_logprobs = tf.reshape( - seq_logprobs, (seq_logits.shape[0] // n_docs, n_docs, -1, seq_logits.shape[-1]) - ) # (batch_size, n_docs, tgt_len, vocabs) - doc_logprobs = tf.nn.log_softmax(doc_scores, axis=1) - doc_logprobs = tf.expand_dims(doc_logprobs, axis=-1) - doc_logprobs = tf.expand_dims(doc_logprobs, axis=-1) # done twice to get 4-D - - # RAG-sequence marginalization - first_token_scores = seq_logprobs[:, :, :1, :] - second_token_scores = seq_logprobs[:, :, 1:2, :] - remainder = seq_logprobs[:, :, 2:, :] - rag_logprobs = tf.concat([first_token_scores, second_token_scores + doc_logprobs, remainder], axis=2) - - # calculate loss - target = tf.expand_dims(target, axis=1) # n_docs dimension - target = tf.expand_dims(target, axis=-1) # logits dimension - target = tf.repeat(target, n_docs, axis=1) - assert len(target.shape) == len(rag_logprobs.shape) - - # last-axis gathering only - use 2D-reshape-trick for Torch's style nD gathering - def torch_gather(param, id_tensor): - # 2d-gather torch equivalent: https://stackoverflow.com/questions/52129909/tensorflow-equivalent-of-torch-gather - def gather2d(target, id_tensor): - idx = tf.stack([tf.range(tf.shape(id_tensor)[0], dtype=id_tensor.dtype), id_tensor[:, 0]], axis=-1) - result = tf.gather_nd(target, idx) - return tf.expand_dims(result, axis=-1) - - target = tf.reshape(param, (-1, param.shape[-1])) # reshape 2D - target_shape = id_tensor.shape - - id_tensor = tf.reshape(id_tensor, (-1, 1)) # also 2D-index - result = gather2d(target, id_tensor) - return tf.reshape(result, target_shape) - - ll = torch_gather(rag_logprobs, id_tensor=target) - smooth_obj = tf.reduce_sum(rag_logprobs, axis=-1, keepdims=True) # total sum of all (normalised) logits - - ll, smooth_obj = _mask_pads(ll, smooth_obj) - - # sum over tokens, exclude bos while scoring - if exclude_bos_score and use_bos: - ll = tf.reduce_sum(ll[:, :, 1:], axis=2) - else: - ll = tf.reduce_sum(ll, axis=2) - - smooth_obj = tf.reduce_sum(smooth_obj, axis=2) - ll = tf.math.reduce_logsumexp(ll, axis=1) # logsumexp over docs - smooth_obj = tf.math.reduce_logsumexp(smooth_obj, axis=1) - - nll_loss = -ll - smooth_loss = -smooth_obj - - if reduce_loss: - nll_loss = tf.reduce_sum(nll_loss) - smooth_loss = tf.reduce_sum(smooth_loss) - - eps_i = epsilon / rag_logprobs.shape[-1] - loss = (1.0 - epsilon) * nll_loss + eps_i * smooth_loss - return loss - - def generate( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - context_input_ids=None, - context_attention_mask=None, - doc_scores=None, - do_deduplication=None, # defaults to True - num_return_sequences=None, # defaults to 1 - num_beams=None, # defaults to 1 - n_docs=None, - **model_kwargs, - ): - """ - Implements RAG sequence "thorough" decoding. Read the [`~generation.GenerationMixin.generate`]` documentation - for more information on how to set other generate input parameters - - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - The sequence used as a prompt for the generation. If `input_ids` is not passed, then - `context_input_ids` has to be provided. - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - 1 for - tokens that are **not masked**, - 0 for tokens that are **masked**. [What are attention - masks?](../glossary#attention-mask) - context_input_ids (`tf.Tensor` of shape `(batch_size * config.n_docs, config.max_combined_length)`, *optional*, returned when *output_retrieved=True*): - Input IDs post-processed from the retrieved documents and the question encoder input_ids by the - retriever. - context_attention_mask (`tf.Tensor` of shape `(batch_size * config.n_docs, config.max_combined_length)`, *optional*, returned when *output_retrieved=True*): - Attention mask post-processed from the retrieved documents and the question encoder `input_ids` by the - retriever. If the model has is not initialized with a `retriever` or `input_ids` is not given, - `context_input_ids` and `context_attention_mask` have to be provided to the forward pass. They are - returned by [`~RagRetriever.__call__`]. - doc_scores (`tf.Tensor` of shape `(batch_size, config.n_docs)`): - Score between each retrieved document embeddings (see `retrieved_doc_embeds`) and - `question_encoder_last_hidden_state`. If the model has is not initialized with a `retriever` or - `input_ids` is not given, `doc_scores` has to be provided to the forward pass. `doc_scores` are - returned by [`~RagRetriever.__call__`]. - do_deduplication (`bool`, *optional*): - Whether or not to deduplicate the generations from different context documents for a given input. Has - to be set to `False` if used while training with distributed backend. - num_return_sequences(`int`, *optional*, defaults to 1): - The number of independently computed returned sequences for each element in the batch. Note that this - is not the value we pass to the `generator`'s `[`~generation.GenerationMixin.generate`]` function, - where we set `num_return_sequences` to `num_beams`. - num_beams (`int`, *optional*, defaults to 1): - Number of beams for beam search. 1 means no beam search. - n_docs (`int`, *optional*, defaults to `config.n_docs`) - Number of documents to retrieve and/or number of documents for which to generate an answer. - kwargs (`dict[str, Any]`, *optional*): - Additional kwargs will be passed to [`~generation.GenerationMixin.generate`] - - Return: - `tf.Tensor` of shape `(batch_size * num_return_sequences, sequence_length)`: The generated sequences. The - second dimension (sequence length) is either equal to `max_length` or shorter if all batches finished early - due to the `eos_token_id`. - """ - - n_docs = n_docs if n_docs is not None else self.config.n_docs - do_deduplication = do_deduplication if do_deduplication is not None else self.config.do_deduplication - num_doc_return_sequences = ( - num_return_sequences if num_return_sequences is not None else self.config.num_return_sequences - ) - num_beams = num_beams if num_beams is not None else self.config.num_beams - - assert input_ids is not None or context_input_ids is not None, ( - " At least one of input_ids or context_input_ids must be given" - ) - - if self.retriever is not None and context_input_ids is None: - question_hidden_states = self.question_encoder(input_ids, attention_mask=attention_mask)[0] - context_input_ids = self.retriever( - input_ids, - question_hidden_states.numpy(), - prefix=self.generator.config.prefix, - n_docs=n_docs, - return_tensors="tf", - )["context_input_ids"] - - hypos = [] - model_kwargs["num_beams"] = num_beams - model_kwargs["num_return_sequences"] = num_beams # put here so that not confused with num_doc_return_sequences - model_kwargs["attention_mask"] = None - - batch_size = input_ids.shape[0] if input_ids is not None else context_input_ids.shape[0] // n_docs - - for index in range(batch_size): - # first, generate beams from documents: - generator_input_ids = context_input_ids[index * n_docs : (index + 1) * n_docs] # (n_docs, max_len) - - output_sequences = self.generator.generate( - generator_input_ids, - **model_kwargs, - ) # n_docs * n_beam, tgt_len - if do_deduplication: - # do_deduplication -- for TF, work on Eager mode only! - output_sequences = tf.stack(list({str(k.numpy().tolist()): k for k in output_sequences}.values())) - - num_candidates = output_sequences.shape[ - 0 - ] # after deduplication, this number can be less than n_docs*n_beam - - # then, run model forwards to get nll scores: - if input_ids is not None: - new_input_ids = tf.tile(input_ids[index : index + 1], (num_candidates, 1)) - outputs = self(new_input_ids, labels=output_sequences, exclude_bos_score=True) - else: # input_ids is None, need context_input_ids/mask and doc_scores - assert context_attention_mask is not None, ( - "Make sure that `context_attention_mask` are passed, if no `input_ids` is set. Alternatively, you" - " can set a retriever using the `set_retriever(...)` function." - ) - assert doc_scores is not None, ( - "Make sure that `doc_scores` are passed, if no `input_ids` is set. Alternatively, you can set a" - " retriever using the `set_retriever(...)` function." - ) - - individual_input_ids = tf.tile( - generator_input_ids, (num_candidates, 1) - ) # (num_candidates*n_docs, max_len) - - individual_attention_mask = context_attention_mask[index * n_docs : (index + 1) * n_docs] - individual_attention_mask = tf.tile(individual_attention_mask, (num_candidates, 1)) - - individual_doc_scores = doc_scores[index : (index + 1), :] # doc_scores.shape = [batch, n_docs] - individual_doc_scores = tf.tile(individual_doc_scores, (num_candidates, 1)) # [num_candidates, n_docs] - - outputs = self( - input_ids=None, - context_input_ids=individual_input_ids, - context_attention_mask=individual_attention_mask, - doc_scores=individual_doc_scores, - labels=output_sequences, - exclude_bos_score=True, - ) - - top_cand_inds = tf.math.top_k((-outputs["loss"]), k=num_doc_return_sequences)[1] - - # add hypothesis - hypos.append(tf.gather(output_sequences, top_cand_inds)) - - return self._cat_and_pad(hypos, pad_token_id=self.config.generator.pad_token_id) - - @staticmethod - def _cat_and_pad(tensors, pad_token_id): - # used by generate(): tensors is a (batched) list of (candidates, len); len is varied across batch - - # Initialize padded tensor with shape ( all_candidates , max_candidate_length ), - # where all_candidates counted from all inputs - new_shape = sum([t.shape[0] for t in tensors]), max([t.shape[1] for t in tensors]) - output = tf.fill(new_shape, pad_token_id) - - # Normal tensor doesn't support slice assignment, so we need tf.Variable - output = tf.Variable(output) - - # Assign, and then convert back to tensor - ind = 0 - for t in tensors: - output[ind : ind + t.shape[0], : t.shape[1]].assign(t) - ind += t.shape[0] - - output = tf.convert_to_tensor(output) - return tf.cast(output, tensors[0][0][0].dtype) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rag", None) is not None: - with tf.name_scope(self.rag.name): - self.rag.build(None) - - -__all__ = ["TFRagModel", "TFRagPreTrainedModel", "TFRagSequenceForGeneration", "TFRagTokenForGeneration"] diff --git a/src/transformers/models/rag/retrieval_rag.py b/src/transformers/models/rag/retrieval_rag.py index e397d111a0a4..6fb924c8b7bc 100644 --- a/src/transformers/models/rag/retrieval_rag.py +++ b/src/transformers/models/rag/retrieval_rag.py @@ -610,7 +610,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*, defaults to "pt"): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. diff --git a/src/transformers/models/reformer/modeling_reformer.py b/src/transformers/models/reformer/modeling_reformer.py index 990f21359bc0..2160663ed5ba 100755 --- a/src/transformers/models/reformer/modeling_reformer.py +++ b/src/transformers/models/reformer/modeling_reformer.py @@ -1920,8 +1920,6 @@ def _init_weights(self, module): if module.padding_idx is not None: module.weight.data[module.padding_idx].zero_() elif isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/regnet/__init__.py b/src/transformers/models/regnet/__init__.py index cac770fdd0bc..a49c5ee7f2e4 100644 --- a/src/transformers/models/regnet/__init__.py +++ b/src/transformers/models/regnet/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_regnet import * - from .modeling_flax_regnet import * from .modeling_regnet import * - from .modeling_tf_regnet import * else: import sys diff --git a/src/transformers/models/regnet/modeling_flax_regnet.py b/src/transformers/models/regnet/modeling_flax_regnet.py deleted file mode 100644 index 2cc3707fa51a..000000000000 --- a/src/transformers/models/regnet/modeling_flax_regnet.py +++ /dev/null @@ -1,822 +0,0 @@ -# coding=utf-8 -# Copyright 2023 The Google Flax Team Authors and 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. - - -from functools import partial -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.traverse_util import flatten_dict, unflatten_dict - -from transformers import RegNetConfig -from transformers.modeling_flax_outputs import ( - FlaxBaseModelOutputWithNoAttention, - FlaxBaseModelOutputWithPooling, - FlaxBaseModelOutputWithPoolingAndNoAttention, - FlaxImageClassifierOutputWithNoAttention, -) -from transformers.modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from transformers.utils import ( - add_start_docstrings, - add_start_docstrings_to_model_forward, -) - - -REGNET_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`RegNetConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -REGNET_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`numpy.ndarray` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`RegNetImageProcessor.__call__`] for details. - - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.resnet.modeling_flax_resnet.Identity -class Identity(nn.Module): - """Identity function.""" - - @nn.compact - def __call__(self, x, **kwargs): - return x - - -class FlaxRegNetConvLayer(nn.Module): - out_channels: int - kernel_size: int = 3 - stride: int = 1 - groups: int = 1 - activation: Optional[str] = "relu" - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.convolution = nn.Conv( - self.out_channels, - kernel_size=(self.kernel_size, self.kernel_size), - strides=self.stride, - padding=self.kernel_size // 2, - feature_group_count=self.groups, - use_bias=False, - kernel_init=nn.initializers.variance_scaling(2.0, mode="fan_out", distribution="truncated_normal"), - dtype=self.dtype, - ) - self.normalization = nn.BatchNorm(momentum=0.9, epsilon=1e-05, dtype=self.dtype) - self.activation_func = ACT2FN[self.activation] if self.activation is not None else Identity() - - def __call__(self, hidden_state: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - hidden_state = self.convolution(hidden_state) - hidden_state = self.normalization(hidden_state, use_running_average=deterministic) - hidden_state = self.activation_func(hidden_state) - return hidden_state - - -class FlaxRegNetEmbeddings(nn.Module): - config: RegNetConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.embedder = FlaxRegNetConvLayer( - self.config.embedding_size, - kernel_size=3, - stride=2, - activation=self.config.hidden_act, - dtype=self.dtype, - ) - - def __call__(self, pixel_values: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - num_channels = pixel_values.shape[-1] - if num_channels != self.config.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - hidden_state = self.embedder(pixel_values, deterministic=deterministic) - return hidden_state - - -# Copied from transformers.models.resnet.modeling_flax_resnet.FlaxResNetShortCut with ResNet->RegNet -class FlaxRegNetShortCut(nn.Module): - """ - RegNet shortcut, used to project the residual features to the correct size. If needed, it is also used to - downsample the input using `stride=2`. - """ - - out_channels: int - stride: int = 2 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.convolution = nn.Conv( - self.out_channels, - kernel_size=(1, 1), - strides=self.stride, - use_bias=False, - kernel_init=nn.initializers.variance_scaling(2.0, mode="fan_out", distribution="truncated_normal"), - dtype=self.dtype, - ) - self.normalization = nn.BatchNorm(momentum=0.9, epsilon=1e-05, dtype=self.dtype) - - def __call__(self, x: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - hidden_state = self.convolution(x) - hidden_state = self.normalization(hidden_state, use_running_average=deterministic) - return hidden_state - - -class FlaxRegNetSELayerCollection(nn.Module): - in_channels: int - reduced_channels: int - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.conv_1 = nn.Conv( - self.reduced_channels, - kernel_size=(1, 1), - kernel_init=nn.initializers.variance_scaling(2.0, mode="fan_out", distribution="truncated_normal"), - dtype=self.dtype, - name="0", - ) # 0 is the name used in corresponding pytorch implementation - self.conv_2 = nn.Conv( - self.in_channels, - kernel_size=(1, 1), - kernel_init=nn.initializers.variance_scaling(2.0, mode="fan_out", distribution="truncated_normal"), - dtype=self.dtype, - name="2", - ) # 2 is the name used in corresponding pytorch implementation - - def __call__(self, hidden_state: jnp.ndarray) -> jnp.ndarray: - hidden_state = self.conv_1(hidden_state) - hidden_state = nn.relu(hidden_state) - hidden_state = self.conv_2(hidden_state) - attention = nn.sigmoid(hidden_state) - - return attention - - -class FlaxRegNetSELayer(nn.Module): - """ - Squeeze and Excitation layer (SE) proposed in [Squeeze-and-Excitation Networks](https://huggingface.co/papers/1709.01507). - """ - - in_channels: int - reduced_channels: int - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.pooler = partial(nn.avg_pool, padding=((0, 0), (0, 0))) - self.attention = FlaxRegNetSELayerCollection(self.in_channels, self.reduced_channels, dtype=self.dtype) - - def __call__(self, hidden_state: jnp.ndarray) -> jnp.ndarray: - pooled = self.pooler( - hidden_state, - window_shape=(hidden_state.shape[1], hidden_state.shape[2]), - strides=(hidden_state.shape[1], hidden_state.shape[2]), - ) - attention = self.attention(pooled) - hidden_state = hidden_state * attention - return hidden_state - - -class FlaxRegNetXLayerCollection(nn.Module): - config: RegNetConfig - out_channels: int - stride: int = 1 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - groups = max(1, self.out_channels // self.config.groups_width) - - self.layer = [ - FlaxRegNetConvLayer( - self.out_channels, - kernel_size=1, - activation=self.config.hidden_act, - dtype=self.dtype, - name="0", - ), - FlaxRegNetConvLayer( - self.out_channels, - stride=self.stride, - groups=groups, - activation=self.config.hidden_act, - dtype=self.dtype, - name="1", - ), - FlaxRegNetConvLayer( - self.out_channels, - kernel_size=1, - activation=None, - dtype=self.dtype, - name="2", - ), - ] - - def __call__(self, hidden_state: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - for layer in self.layer: - hidden_state = layer(hidden_state, deterministic=deterministic) - return hidden_state - - -class FlaxRegNetXLayer(nn.Module): - """ - RegNet's layer composed by three `3x3` convolutions, same as a ResNet bottleneck layer with reduction = 1. - """ - - config: RegNetConfig - in_channels: int - out_channels: int - stride: int = 1 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - should_apply_shortcut = self.in_channels != self.out_channels or self.stride != 1 - self.shortcut = ( - FlaxRegNetShortCut( - self.out_channels, - stride=self.stride, - dtype=self.dtype, - ) - if should_apply_shortcut - else Identity() - ) - self.layer = FlaxRegNetXLayerCollection( - self.config, - in_channels=self.in_channels, - out_channels=self.out_channels, - stride=self.stride, - dtype=self.dtype, - ) - self.activation_func = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_state: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - residual = hidden_state - hidden_state = self.layer(hidden_state) - residual = self.shortcut(residual, deterministic=deterministic) - hidden_state += residual - hidden_state = self.activation_func(hidden_state) - return hidden_state - - -class FlaxRegNetYLayerCollection(nn.Module): - config: RegNetConfig - in_channels: int - out_channels: int - stride: int = 1 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - groups = max(1, self.out_channels // self.config.groups_width) - - self.layer = [ - FlaxRegNetConvLayer( - self.out_channels, - kernel_size=1, - activation=self.config.hidden_act, - dtype=self.dtype, - name="0", - ), - FlaxRegNetConvLayer( - self.out_channels, - stride=self.stride, - groups=groups, - activation=self.config.hidden_act, - dtype=self.dtype, - name="1", - ), - FlaxRegNetSELayer( - self.out_channels, - reduced_channels=int(round(self.in_channels / 4)), - dtype=self.dtype, - name="2", - ), - FlaxRegNetConvLayer( - self.out_channels, - kernel_size=1, - activation=None, - dtype=self.dtype, - name="3", - ), - ] - - def __call__(self, hidden_state: jnp.ndarray) -> jnp.ndarray: - for layer in self.layer: - hidden_state = layer(hidden_state) - return hidden_state - - -class FlaxRegNetYLayer(nn.Module): - """ - RegNet's Y layer: an X layer with Squeeze and Excitation. - """ - - config: RegNetConfig - in_channels: int - out_channels: int - stride: int = 1 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - should_apply_shortcut = self.in_channels != self.out_channels or self.stride != 1 - - self.shortcut = ( - FlaxRegNetShortCut( - self.out_channels, - stride=self.stride, - dtype=self.dtype, - ) - if should_apply_shortcut - else Identity() - ) - self.layer = FlaxRegNetYLayerCollection( - self.config, - in_channels=self.in_channels, - out_channels=self.out_channels, - stride=self.stride, - dtype=self.dtype, - ) - self.activation_func = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_state: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - residual = hidden_state - hidden_state = self.layer(hidden_state) - residual = self.shortcut(residual, deterministic=deterministic) - hidden_state += residual - hidden_state = self.activation_func(hidden_state) - return hidden_state - - -class FlaxRegNetStageLayersCollection(nn.Module): - """ - A RegNet stage composed by stacked layers. - """ - - config: RegNetConfig - in_channels: int - out_channels: int - stride: int = 2 - depth: int = 2 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - layer = FlaxRegNetXLayer if self.config.layer_type == "x" else FlaxRegNetYLayer - - layers = [ - # downsampling is done in the first layer with stride of 2 - layer( - self.config, - self.in_channels, - self.out_channels, - stride=self.stride, - dtype=self.dtype, - name="0", - ) - ] - - for i in range(self.depth - 1): - layers.append( - layer( - self.config, - self.out_channels, - self.out_channels, - dtype=self.dtype, - name=str(i + 1), - ) - ) - - self.layers = layers - - def __call__(self, x: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - hidden_state = x - for layer in self.layers: - hidden_state = layer(hidden_state, deterministic=deterministic) - return hidden_state - - -# Copied from transformers.models.resnet.modeling_flax_resnet.FlaxResNetStage with ResNet->RegNet -class FlaxRegNetStage(nn.Module): - """ - A RegNet stage composed by stacked layers. - """ - - config: RegNetConfig - in_channels: int - out_channels: int - stride: int = 2 - depth: int = 2 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.layers = FlaxRegNetStageLayersCollection( - self.config, - in_channels=self.in_channels, - out_channels=self.out_channels, - stride=self.stride, - depth=self.depth, - dtype=self.dtype, - ) - - def __call__(self, x: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - return self.layers(x, deterministic=deterministic) - - -# Copied from transformers.models.resnet.modeling_flax_resnet.FlaxResNetStageCollection with ResNet->RegNet -class FlaxRegNetStageCollection(nn.Module): - config: RegNetConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - in_out_channels = zip(self.config.hidden_sizes, self.config.hidden_sizes[1:]) - stages = [ - FlaxRegNetStage( - self.config, - self.config.embedding_size, - self.config.hidden_sizes[0], - stride=2 if self.config.downsample_in_first_stage else 1, - depth=self.config.depths[0], - dtype=self.dtype, - name="0", - ) - ] - - for i, ((in_channels, out_channels), depth) in enumerate(zip(in_out_channels, self.config.depths[1:])): - stages.append( - FlaxRegNetStage(self.config, in_channels, out_channels, depth=depth, dtype=self.dtype, name=str(i + 1)) - ) - - self.stages = stages - - def __call__( - self, - hidden_state: jnp.ndarray, - output_hidden_states: bool = False, - deterministic: bool = True, - ) -> FlaxBaseModelOutputWithNoAttention: - hidden_states = () if output_hidden_states else None - - for stage_module in self.stages: - if output_hidden_states: - hidden_states = hidden_states + (hidden_state.transpose(0, 3, 1, 2),) - - hidden_state = stage_module(hidden_state, deterministic=deterministic) - - return hidden_state, hidden_states - - -# Copied from transformers.models.resnet.modeling_flax_resnet.FlaxResNetEncoder with ResNet->RegNet -class FlaxRegNetEncoder(nn.Module): - config: RegNetConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.stages = FlaxRegNetStageCollection(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_state: jnp.ndarray, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ) -> FlaxBaseModelOutputWithNoAttention: - hidden_state, hidden_states = self.stages( - hidden_state, output_hidden_states=output_hidden_states, deterministic=deterministic - ) - - if output_hidden_states: - hidden_states = hidden_states + (hidden_state.transpose(0, 3, 1, 2),) - - if not return_dict: - return tuple(v for v in [hidden_state, hidden_states] if v is not None) - - return FlaxBaseModelOutputWithNoAttention( - last_hidden_state=hidden_state, - hidden_states=hidden_states, - ) - - -# Copied from transformers.models.resnet.modeling_flax_resnet.FlaxResNetPreTrainedModel with ResNet->RegNet,resnet->regnet,RESNET->REGNET -class FlaxRegNetPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = RegNetConfig - base_model_prefix = "regnet" - main_input_name = "pixel_values" - module_class: nn.Module = None - - def __init__( - self, - config: RegNetConfig, - input_shape=(1, 224, 224, 3), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - if input_shape is None: - input_shape = (1, config.image_size, config.image_size, config.num_channels) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - pixel_values = jnp.zeros(input_shape, dtype=self.dtype) - - rngs = {"params": rng} - - random_params = self.module.init(rngs, pixel_values, return_dict=False) - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(REGNET_INPUTS_DOCSTRING) - def __call__( - self, - pixel_values, - params: Optional[dict] = None, - train: bool = False, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - - # Handle any PRNG if needed - rngs = {} - - return self.module.apply( - { - "params": params["params"] if params is not None else self.params["params"], - "batch_stats": params["batch_stats"] if params is not None else self.params["batch_stats"], - }, - jnp.array(pixel_values, dtype=jnp.float32), - not train, - output_hidden_states, - return_dict, - rngs=rngs, - mutable=["batch_stats"] if train else False, # Returning tuple with batch_stats only when train is True - ) - - -# Copied from transformers.models.resnet.modeling_flax_resnet.FlaxResNetModule with ResNet->RegNet -class FlaxRegNetModule(nn.Module): - config: RegNetConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.embedder = FlaxRegNetEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxRegNetEncoder(self.config, dtype=self.dtype) - - # Adaptive average pooling used in resnet - self.pooler = partial( - nn.avg_pool, - padding=((0, 0), (0, 0)), - ) - - def __call__( - self, - pixel_values, - deterministic: bool = True, - output_hidden_states: bool = False, - return_dict: bool = True, - ) -> FlaxBaseModelOutputWithPoolingAndNoAttention: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - embedding_output = self.embedder(pixel_values, deterministic=deterministic) - - encoder_outputs = self.encoder( - embedding_output, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - last_hidden_state = encoder_outputs[0] - - pooled_output = self.pooler( - last_hidden_state, - window_shape=(last_hidden_state.shape[1], last_hidden_state.shape[2]), - strides=(last_hidden_state.shape[1], last_hidden_state.shape[2]), - ).transpose(0, 3, 1, 2) - - last_hidden_state = last_hidden_state.transpose(0, 3, 1, 2) - - if not return_dict: - return (last_hidden_state, pooled_output) + encoder_outputs[1:] - - return FlaxBaseModelOutputWithPoolingAndNoAttention( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - ) - - -@add_start_docstrings( - "The bare RegNet model outputting raw features without any specific head on top.", - REGNET_START_DOCSTRING, -) -class FlaxRegNetModel(FlaxRegNetPreTrainedModel): - module_class = FlaxRegNetModule - - -FLAX_VISION_MODEL_DOCSTRING = """ - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, FlaxRegNetModel - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/regnet-y-040") - >>> model = FlaxRegNetModel.from_pretrained("facebook/regnet-y-040") - - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> last_hidden_states = outputs.last_hidden_state - ``` -""" - -overwrite_call_docstring(FlaxRegNetModel, FLAX_VISION_MODEL_DOCSTRING) -append_replace_return_docstrings( - FlaxRegNetModel, - output_type=FlaxBaseModelOutputWithPooling, - config_class=RegNetConfig, -) - - -# Copied from transformers.models.resnet.modeling_flax_resnet.FlaxResNetClassifierCollection with ResNet->RegNet -class FlaxRegNetClassifierCollection(nn.Module): - config: RegNetConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype, name="1") - - def __call__(self, x: jnp.ndarray) -> jnp.ndarray: - return self.classifier(x) - - -# Copied from transformers.models.resnet.modeling_flax_resnet.FlaxResNetForImageClassificationModule with ResNet->RegNet,resnet->regnet,RESNET->REGNET -class FlaxRegNetForImageClassificationModule(nn.Module): - config: RegNetConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.regnet = FlaxRegNetModule(config=self.config, dtype=self.dtype) - - if self.config.num_labels > 0: - self.classifier = FlaxRegNetClassifierCollection(self.config, dtype=self.dtype) - else: - self.classifier = Identity() - - def __call__( - self, - pixel_values=None, - deterministic: bool = True, - output_hidden_states=None, - return_dict=None, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.regnet( - pixel_values, - deterministic=deterministic, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs.pooler_output if return_dict else outputs[1] - - logits = self.classifier(pooled_output[:, :, 0, 0]) - - if not return_dict: - output = (logits,) + outputs[2:] - return output - - return FlaxImageClassifierOutputWithNoAttention(logits=logits, hidden_states=outputs.hidden_states) - - -@add_start_docstrings( - """ - RegNet Model with an image classification head on top (a linear layer on top of the pooled features), e.g. for - ImageNet. - """, - REGNET_START_DOCSTRING, -) -class FlaxRegNetForImageClassification(FlaxRegNetPreTrainedModel): - module_class = FlaxRegNetForImageClassificationModule - - -FLAX_VISION_CLASSIF_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoImageProcessor, FlaxRegNetForImageClassification - >>> from PIL import Image - >>> import jax - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/regnet-y-040") - >>> model = FlaxRegNetForImageClassification.from_pretrained("facebook/regnet-y-040") - - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> logits = outputs.logits - - >>> # model predicts one of the 1000 ImageNet classes - >>> predicted_class_idx = jax.numpy.argmax(logits, axis=-1) - >>> print("Predicted class:", model.config.id2label[predicted_class_idx.item()]) - ``` -""" - -overwrite_call_docstring(FlaxRegNetForImageClassification, FLAX_VISION_CLASSIF_DOCSTRING) -append_replace_return_docstrings( - FlaxRegNetForImageClassification, - output_type=FlaxImageClassifierOutputWithNoAttention, - config_class=RegNetConfig, -) - - -__all__ = ["FlaxRegNetForImageClassification", "FlaxRegNetModel", "FlaxRegNetPreTrainedModel"] diff --git a/src/transformers/models/regnet/modeling_tf_regnet.py b/src/transformers/models/regnet/modeling_tf_regnet.py deleted file mode 100644 index 13714b4e69aa..000000000000 --- a/src/transformers/models/regnet/modeling_tf_regnet.py +++ /dev/null @@ -1,611 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Meta Platforms, Inc. and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow RegNet model.""" - -from typing import Optional, Union - -import tensorflow as tf - -from ...activations_tf import ACT2FN -from ...file_utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithNoAttention, - TFBaseModelOutputWithPoolingAndNoAttention, - TFSequenceClassifierOutput, -) -from ...modeling_tf_utils import ( - TFPreTrainedModel, - TFSequenceClassificationLoss, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list -from ...utils import logging -from .configuration_regnet import RegNetConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "RegNetConfig" - -# Base docstring -_CHECKPOINT_FOR_DOC = "facebook/regnet-y-040" -_EXPECTED_OUTPUT_SHAPE = [1, 1088, 7, 7] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "facebook/regnet-y-040" -_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" - - -class TFRegNetConvLayer(keras.layers.Layer): - def __init__( - self, - in_channels: int, - out_channels: int, - kernel_size: int = 3, - stride: int = 1, - groups: int = 1, - activation: Optional[str] = "relu", - **kwargs, - ): - super().__init__(**kwargs) - # The padding and conv has been verified in - # https://colab.research.google.com/gist/sayakpaul/854bc10eeaf21c9ee2119e0b9f3841a7/scratchpad.ipynb - self.padding = keras.layers.ZeroPadding2D(padding=kernel_size // 2) - self.convolution = keras.layers.Conv2D( - filters=out_channels, - kernel_size=kernel_size, - strides=stride, - padding="VALID", - groups=groups, - use_bias=False, - name="convolution", - ) - self.normalization = keras.layers.BatchNormalization(epsilon=1e-5, momentum=0.9, name="normalization") - self.activation = ACT2FN[activation] if activation is not None else tf.identity - self.in_channels = in_channels - self.out_channels = out_channels - - def call(self, hidden_state): - hidden_state = self.convolution(self.padding(hidden_state)) - hidden_state = self.normalization(hidden_state) - hidden_state = self.activation(hidden_state) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convolution", None) is not None: - with tf.name_scope(self.convolution.name): - self.convolution.build([None, None, None, self.in_channels]) - if getattr(self, "normalization", None) is not None: - with tf.name_scope(self.normalization.name): - self.normalization.build([None, None, None, self.out_channels]) - - -class TFRegNetEmbeddings(keras.layers.Layer): - """ - RegNet Embeddings (stem) composed of a single aggressive convolution. - """ - - def __init__(self, config: RegNetConfig, **kwargs): - super().__init__(**kwargs) - self.num_channels = config.num_channels - self.embedder = TFRegNetConvLayer( - in_channels=config.num_channels, - out_channels=config.embedding_size, - kernel_size=3, - stride=2, - activation=config.hidden_act, - name="embedder", - ) - - def call(self, pixel_values): - num_channels = shape_list(pixel_values)[1] - if tf.executing_eagerly() and num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - - # When running on CPU, `keras.layers.Conv2D` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - # shape = (batch_size, in_height, in_width, in_channels=num_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - hidden_state = self.embedder(pixel_values) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embedder", None) is not None: - with tf.name_scope(self.embedder.name): - self.embedder.build(None) - - -class TFRegNetShortCut(keras.layers.Layer): - """ - RegNet shortcut, used to project the residual features to the correct size. If needed, it is also used to - downsample the input using `stride=2`. - """ - - def __init__(self, in_channels: int, out_channels: int, stride: int = 2, **kwargs): - super().__init__(**kwargs) - self.convolution = keras.layers.Conv2D( - filters=out_channels, kernel_size=1, strides=stride, use_bias=False, name="convolution" - ) - self.normalization = keras.layers.BatchNormalization(epsilon=1e-5, momentum=0.9, name="normalization") - self.in_channels = in_channels - self.out_channels = out_channels - - def call(self, inputs: tf.Tensor, training: bool = False) -> tf.Tensor: - return self.normalization(self.convolution(inputs), training=training) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convolution", None) is not None: - with tf.name_scope(self.convolution.name): - self.convolution.build([None, None, None, self.in_channels]) - if getattr(self, "normalization", None) is not None: - with tf.name_scope(self.normalization.name): - self.normalization.build([None, None, None, self.out_channels]) - - -class TFRegNetSELayer(keras.layers.Layer): - """ - Squeeze and Excitation layer (SE) proposed in [Squeeze-and-Excitation Networks](https://huggingface.co/papers/1709.01507). - """ - - def __init__(self, in_channels: int, reduced_channels: int, **kwargs): - super().__init__(**kwargs) - self.pooler = keras.layers.GlobalAveragePooling2D(keepdims=True, name="pooler") - self.attention = [ - keras.layers.Conv2D(filters=reduced_channels, kernel_size=1, activation="relu", name="attention.0"), - keras.layers.Conv2D(filters=in_channels, kernel_size=1, activation="sigmoid", name="attention.2"), - ] - self.in_channels = in_channels - self.reduced_channels = reduced_channels - - def call(self, hidden_state): - # [batch_size, h, w, num_channels] -> [batch_size, 1, 1, num_channels] - pooled = self.pooler(hidden_state) - for layer_module in self.attention: - pooled = layer_module(pooled) - hidden_state = hidden_state * pooled - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build((None, None, None, None)) - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention[0].name): - self.attention[0].build([None, None, None, self.in_channels]) - with tf.name_scope(self.attention[1].name): - self.attention[1].build([None, None, None, self.reduced_channels]) - - -class TFRegNetXLayer(keras.layers.Layer): - """ - RegNet's layer composed by three `3x3` convolutions, same as a ResNet bottleneck layer with reduction = 1. - """ - - def __init__(self, config: RegNetConfig, in_channels: int, out_channels: int, stride: int = 1, **kwargs): - super().__init__(**kwargs) - should_apply_shortcut = in_channels != out_channels or stride != 1 - groups = max(1, out_channels // config.groups_width) - self.shortcut = ( - TFRegNetShortCut(in_channels, out_channels, stride=stride, name="shortcut") - if should_apply_shortcut - else keras.layers.Activation("linear", name="shortcut") - ) - # `self.layers` instead of `self.layer` because that is a reserved argument. - self.layers = [ - TFRegNetConvLayer(in_channels, out_channels, kernel_size=1, activation=config.hidden_act, name="layer.0"), - TFRegNetConvLayer( - out_channels, out_channels, stride=stride, groups=groups, activation=config.hidden_act, name="layer.1" - ), - TFRegNetConvLayer(out_channels, out_channels, kernel_size=1, activation=None, name="layer.2"), - ] - self.activation = ACT2FN[config.hidden_act] - - def call(self, hidden_state): - residual = hidden_state - for layer_module in self.layers: - hidden_state = layer_module(hidden_state) - residual = self.shortcut(residual) - hidden_state += residual - hidden_state = self.activation(hidden_state) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "shortcut", None) is not None: - with tf.name_scope(self.shortcut.name): - self.shortcut.build(None) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFRegNetYLayer(keras.layers.Layer): - """ - RegNet's Y layer: an X layer with Squeeze and Excitation. - """ - - def __init__(self, config: RegNetConfig, in_channels: int, out_channels: int, stride: int = 1, **kwargs): - super().__init__(**kwargs) - should_apply_shortcut = in_channels != out_channels or stride != 1 - groups = max(1, out_channels // config.groups_width) - self.shortcut = ( - TFRegNetShortCut(in_channels, out_channels, stride=stride, name="shortcut") - if should_apply_shortcut - else keras.layers.Activation("linear", name="shortcut") - ) - self.layers = [ - TFRegNetConvLayer(in_channels, out_channels, kernel_size=1, activation=config.hidden_act, name="layer.0"), - TFRegNetConvLayer( - out_channels, out_channels, stride=stride, groups=groups, activation=config.hidden_act, name="layer.1" - ), - TFRegNetSELayer(out_channels, reduced_channels=int(round(in_channels / 4)), name="layer.2"), - TFRegNetConvLayer(out_channels, out_channels, kernel_size=1, activation=None, name="layer.3"), - ] - self.activation = ACT2FN[config.hidden_act] - - def call(self, hidden_state): - residual = hidden_state - for layer_module in self.layers: - hidden_state = layer_module(hidden_state) - residual = self.shortcut(residual) - hidden_state += residual - hidden_state = self.activation(hidden_state) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "shortcut", None) is not None: - with tf.name_scope(self.shortcut.name): - self.shortcut.build(None) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFRegNetStage(keras.layers.Layer): - """ - A RegNet stage composed by stacked layers. - """ - - def __init__( - self, config: RegNetConfig, in_channels: int, out_channels: int, stride: int = 2, depth: int = 2, **kwargs - ): - super().__init__(**kwargs) - - layer = TFRegNetXLayer if config.layer_type == "x" else TFRegNetYLayer - self.layers = [ - # downsampling is done in the first layer with stride of 2 - layer(config, in_channels, out_channels, stride=stride, name="layers.0"), - *[layer(config, out_channels, out_channels, name=f"layers.{i + 1}") for i in range(depth - 1)], - ] - - def call(self, hidden_state): - for layer_module in self.layers: - hidden_state = layer_module(hidden_state) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFRegNetEncoder(keras.layers.Layer): - def __init__(self, config: RegNetConfig, **kwargs): - super().__init__(**kwargs) - self.stages = [] - # based on `downsample_in_first_stage`, the first layer of the first stage may or may not downsample the input - self.stages.append( - TFRegNetStage( - config, - config.embedding_size, - config.hidden_sizes[0], - stride=2 if config.downsample_in_first_stage else 1, - depth=config.depths[0], - name="stages.0", - ) - ) - in_out_channels = zip(config.hidden_sizes, config.hidden_sizes[1:]) - for i, ((in_channels, out_channels), depth) in enumerate(zip(in_out_channels, config.depths[1:])): - self.stages.append(TFRegNetStage(config, in_channels, out_channels, depth=depth, name=f"stages.{i + 1}")) - - def call( - self, hidden_state: tf.Tensor, output_hidden_states: bool = False, return_dict: bool = True - ) -> TFBaseModelOutputWithNoAttention: - hidden_states = () if output_hidden_states else None - - for stage_module in self.stages: - if output_hidden_states: - hidden_states = hidden_states + (hidden_state,) - - hidden_state = stage_module(hidden_state) - - if output_hidden_states: - hidden_states = hidden_states + (hidden_state,) - - if not return_dict: - return tuple(v for v in [hidden_state, hidden_states] if v is not None) - - return TFBaseModelOutputWithNoAttention(last_hidden_state=hidden_state, hidden_states=hidden_states) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - for stage in self.stages: - with tf.name_scope(stage.name): - stage.build(None) - - -@keras_serializable -class TFRegNetMainLayer(keras.layers.Layer): - config_class = RegNetConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.embedder = TFRegNetEmbeddings(config, name="embedder") - self.encoder = TFRegNetEncoder(config, name="encoder") - self.pooler = keras.layers.GlobalAveragePooling2D(keepdims=True, name="pooler") - - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> TFBaseModelOutputWithPoolingAndNoAttention: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - embedding_output = self.embedder(pixel_values, training=training) - - encoder_outputs = self.encoder( - embedding_output, output_hidden_states=output_hidden_states, return_dict=return_dict, training=training - ) - - last_hidden_state = encoder_outputs[0] - pooled_output = self.pooler(last_hidden_state) - - # Change to NCHW output format have uniformity in the modules - pooled_output = tf.transpose(pooled_output, perm=(0, 3, 1, 2)) - last_hidden_state = tf.transpose(last_hidden_state, perm=(0, 3, 1, 2)) - - # Change the other hidden state outputs to NCHW as well - if output_hidden_states: - hidden_states = tuple(tf.transpose(h, perm=(0, 3, 1, 2)) for h in encoder_outputs[1]) - - if not return_dict: - return (last_hidden_state, pooled_output) + encoder_outputs[1:] - - return TFBaseModelOutputWithPoolingAndNoAttention( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=hidden_states if output_hidden_states else encoder_outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embedder", None) is not None: - with tf.name_scope(self.embedder.name): - self.embedder.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build((None, None, None, None)) - - -class TFRegNetPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = RegNetConfig - base_model_prefix = "regnet" - main_input_name = "pixel_values" - - @property - def input_signature(self): - return {"pixel_values": tf.TensorSpec(shape=(None, self.config.num_channels, 224, 224), dtype=tf.float32)} - - -REGNET_START_DOCSTRING = r""" - This model is a Tensorflow - [keras.layers.Layer](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer) sub-class. Use it as a - regular Tensorflow Module and refer to the Tensorflow documentation for all matter related to general usage and - behavior. - - Parameters: - config ([`RegNetConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -REGNET_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`ConveNextImageProcessor.__call__`] for details. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@add_start_docstrings( - "The bare RegNet model outputting raw features without any specific head on top.", - REGNET_START_DOCSTRING, -) -class TFRegNetModel(TFRegNetPreTrainedModel): - def __init__(self, config: RegNetConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.regnet = TFRegNetMainLayer(config, name="regnet") - - @unpack_inputs - @add_start_docstrings_to_model_forward(REGNET_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPoolingAndNoAttention, - config_class=_CONFIG_FOR_DOC, - modality="vision", - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - def call( - self, - pixel_values: tf.Tensor, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[TFBaseModelOutputWithPoolingAndNoAttention, tuple[tf.Tensor]]: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.regnet( - pixel_values=pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - if not return_dict: - return (outputs[0],) + outputs[1:] - - return TFBaseModelOutputWithPoolingAndNoAttention( - last_hidden_state=outputs.last_hidden_state, - pooler_output=outputs.pooler_output, - hidden_states=outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "regnet", None) is not None: - with tf.name_scope(self.regnet.name): - self.regnet.build(None) - - -@add_start_docstrings( - """ - RegNet Model with an image classification head on top (a linear layer on top of the pooled features), e.g. for - ImageNet. - """, - REGNET_START_DOCSTRING, -) -class TFRegNetForImageClassification(TFRegNetPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: RegNetConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - self.regnet = TFRegNetMainLayer(config, name="regnet") - # classification head - self.classifier = [ - keras.layers.Flatten(), - keras.layers.Dense(config.num_labels, name="classifier.1") if config.num_labels > 0 else tf.identity, - ] - - @unpack_inputs - @add_start_docstrings_to_model_forward(REGNET_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - def call( - self, - pixel_values: Optional[tf.Tensor] = None, - labels: Optional[tf.Tensor] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[TFSequenceClassifierOutput, tuple[tf.Tensor]]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.regnet( - pixel_values, output_hidden_states=output_hidden_states, return_dict=return_dict, training=training - ) - - pooled_output = outputs.pooler_output if return_dict else outputs[1] - - flattened_output = self.classifier[0](pooled_output) - logits = self.classifier[1](flattened_output) - - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput(loss=loss, logits=logits, hidden_states=outputs.hidden_states) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "regnet", None) is not None: - with tf.name_scope(self.regnet.name): - self.regnet.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier[1].name): - self.classifier[1].build([None, None, None, self.config.hidden_sizes[-1]]) - - -__all__ = ["TFRegNetForImageClassification", "TFRegNetModel", "TFRegNetPreTrainedModel"] diff --git a/src/transformers/models/rembert/__init__.py b/src/transformers/models/rembert/__init__.py index 38566f502ad0..23b308c7f13d 100644 --- a/src/transformers/models/rembert/__init__.py +++ b/src/transformers/models/rembert/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_rembert import * from .modeling_rembert import * - from .modeling_tf_rembert import * from .tokenization_rembert import * from .tokenization_rembert_fast import * else: diff --git a/src/transformers/models/rembert/convert_rembert_tf_checkpoint_to_pytorch.py b/src/transformers/models/rembert/convert_rembert_tf_checkpoint_to_pytorch.py index 369388c540f9..7964ba9fb275 100755 --- a/src/transformers/models/rembert/convert_rembert_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/rembert/convert_rembert_tf_checkpoint_to_pytorch.py @@ -15,14 +15,99 @@ """Convert RemBERT checkpoint.""" import argparse +import os import torch -from transformers import RemBertConfig, RemBertModel, load_tf_weights_in_rembert +from transformers import RemBertConfig, RemBertModel from transformers.utils import logging logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def load_tf_weights_in_rembert(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + # Checkpoint is 12Gb, save memory by not loading useless variables + # Output embedding and cls are reset at classification time + if any(deny in name for deny in ("adam_v", "adam_m", "output_embedding", "cls")): + # logger.info("Skipping loading of %s", name) + continue + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array) + + for name, array in zip(names, arrays): + # Replace prefix with right one + name = name.replace("bert/", "rembert/") + # The pooler is a linear layer + # name = name.replace("pooler/dense", "pooler") + + name = name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any( + n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + continue + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "kernel" or scope_names[0] == "gamma": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + else: + try: + pointer = getattr(pointer, scope_names[0]) + except AttributeError: + logger.info("Skipping {}".format("/".join(name))) + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if m_name[-11:] == "_embeddings": + pointer = getattr(pointer, "weight") + elif m_name == "kernel": + array = np.transpose(array) + try: + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + return model def convert_rembert_tf_checkpoint_to_pytorch(tf_checkpoint_path, bert_config_file, pytorch_dump_path): diff --git a/src/transformers/models/rembert/modeling_rembert.py b/src/transformers/models/rembert/modeling_rembert.py index 0fc9635cda88..3a1980885339 100755 --- a/src/transformers/models/rembert/modeling_rembert.py +++ b/src/transformers/models/rembert/modeling_rembert.py @@ -15,7 +15,6 @@ """PyTorch RemBERT model.""" import math -import os from typing import Optional, Union import torch @@ -46,89 +45,6 @@ logger = logging.get_logger(__name__) -def load_tf_weights_in_rembert(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - # Checkpoint is 12Gb, save memory by not loading useless variables - # Output embedding and cls are reset at classification time - if any(deny in name for deny in ("adam_v", "adam_m", "output_embedding", "cls")): - # logger.info("Skipping loading of %s", name) - continue - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - # Replace prefix with right one - name = name.replace("bert/", "rembert/") - # The pooler is a linear layer - # name = name.replace("pooler/dense", "pooler") - - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info("Skipping {}".format("/".join(name))) - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class RemBertEmbeddings(nn.Module): """Construct the embeddings from word, position and token_type embeddings.""" @@ -140,8 +56,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.input_embedding_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.input_embedding_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.input_embedding_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -614,15 +528,12 @@ def forward(self, sequence_output: torch.Tensor) -> torch.Tensor: @auto_docstring class RemBertPreTrainedModel(PreTrainedModel): config: RemBertConfig - load_tf_weights = load_tf_weights_in_rembert base_model_prefix = "rembert" supports_gradient_checkpointing = True def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1357,5 +1268,4 @@ def forward( "RemBertLayer", "RemBertModel", "RemBertPreTrainedModel", - "load_tf_weights_in_rembert", ] diff --git a/src/transformers/models/rembert/modeling_tf_rembert.py b/src/transformers/models/rembert/modeling_tf_rembert.py deleted file mode 100644 index baf7b6e8adc9..000000000000 --- a/src/transformers/models/rembert/modeling_tf_rembert.py +++ /dev/null @@ -1,1720 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The HuggingFace Team and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 RemBERT model.""" - -from __future__ import annotations - -import math - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFBaseModelOutputWithPoolingAndCrossAttentions, - TFCausalLMOutputWithCrossAttentions, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_rembert import RemBertConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "RemBertConfig" - - -class TFRemBertEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config: RemBertConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.input_embedding_size = config.input_embedding_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.input_embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.input_embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.input_embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.input_embedding_size]) - - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - past_key_values_length=0, - training: bool = False, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - position_ids = tf.expand_dims( - tf.range(start=past_key_values_length, limit=input_shape[1] + past_key_values_length), axis=0 - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention with Bert->RemBert -class TFRemBertSelfAttention(keras.layers.Layer): - def __init__(self, config: RemBertConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - - self.is_decoder = config.is_decoder - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_layer = past_key_value[0] - value_layer = past_key_value[1] - attention_mask = encoder_attention_mask - elif is_cross_attention: - key_layer = self.transpose_for_scores(self.key(inputs=encoder_hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=encoder_hidden_states), batch_size) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_layer, value_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFRemBertModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - if self.is_decoder: - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfOutput with Bert->RemBert -class TFRemBertSelfOutput(keras.layers.Layer): - def __init__(self, config: RemBertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertAttention with Bert->RemBert -class TFRemBertAttention(keras.layers.Layer): - def __init__(self, config: RemBertConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFRemBertSelfAttention(config, name="self") - self.dense_output = TFRemBertSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - # add attentions (possibly with past_key_value) if we output them - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->RemBert -class TFRemBertIntermediate(keras.layers.Layer): - def __init__(self, config: RemBertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->RemBert -class TFRemBertOutput(keras.layers.Layer): - def __init__(self, config: RemBertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLayer with Bert->RemBert -class TFRemBertLayer(keras.layers.Layer): - def __init__(self, config: RemBertConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFRemBertAttention(config, name="attention") - self.is_decoder = config.is_decoder - self.add_cross_attention = config.add_cross_attention - if self.add_cross_attention: - if not self.is_decoder: - raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = TFRemBertAttention(config, name="crossattention") - self.intermediate = TFRemBertIntermediate(config, name="intermediate") - self.bert_output = TFRemBertOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_value: tuple[tf.Tensor] | None, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=self_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - cross_attn_present_key_value = None - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" - " by setting `config.add_cross_attention=True`" - ) - - # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - cross_attention_outputs = self.crossattention( - input_tensor=attention_output, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=cross_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - - # add cross-attn cache to positions 3,4 of present_key_value tuple - cross_attn_present_key_value = cross_attention_outputs[-1] - present_key_value = present_key_value + cross_attn_present_key_value - - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + outputs # add attentions if we output them - - # if decoder, return the attn key/values as the last output - if self.is_decoder: - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - - -class TFRemBertEncoder(keras.layers.Layer): - def __init__(self, config: RemBertConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - - self.embedding_hidden_mapping_in = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="embedding_hidden_mapping_in", - ) - self.layer = [TFRemBertLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_values: tuple[tuple[tf.Tensor]], - use_cache: bool, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - hidden_states = self.embedding_hidden_mapping_in(inputs=hidden_states) - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - next_decoder_cache = () if use_cache else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[i], - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - if self.config.add_cross_attention and encoder_hidden_states is not None: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v for v in [hidden_states, all_hidden_states, all_attentions, all_cross_attentions] if v is not None - ) - - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embedding_hidden_mapping_in", None) is not None: - with tf.name_scope(self.embedding_hidden_mapping_in.name): - self.embedding_hidden_mapping_in.build([None, None, self.config.input_embedding_size]) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->RemBert -class TFRemBertPooler(keras.layers.Layer): - def __init__(self, config: RemBertConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFRemBertLMPredictionHead(keras.layers.Layer): - def __init__(self, config: RemBertConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.initializer_range = config.initializer_range - self.output_embedding_size = config.output_embedding_size - self.dense = keras.layers.Dense( - config.output_embedding_size, kernel_initializer=get_initializer(self.initializer_range), name="dense" - ) - if isinstance(config.hidden_act, str): - self.activation = get_tf_activation(config.hidden_act) - else: - self.activation = config.hidden_act - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - - def build(self, input_shape=None): - self.decoder = self.add_weight( - name="decoder/weight", - shape=[self.config.vocab_size, self.output_embedding_size], - initializer=get_initializer(self.initializer_range), - ) - self.decoder_bias = self.add_weight( - shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="decoder/bias" - ) - - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, self.config.output_embedding_size]) - - def get_output_embeddings(self) -> keras.layers.Layer: - return self - - def set_output_embeddings(self, value): - self.decoder = value - self.decoder.vocab_size = shape_list(value)[0] - - def get_bias(self) -> dict[str, tf.Variable]: - return {"decoder_bias": self.decoder_bias} - - def set_bias(self, value: tf.Variable): - self.decoder_bias = value["decoder_bias"] - self.config.vocab_size = shape_list(value["decoder_bias"])[0] - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.activation(hidden_states) - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.output_embedding_size]) - hidden_states = self.LayerNorm(hidden_states) - hidden_states = tf.matmul(a=hidden_states, b=self.decoder, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.decoder_bias) - return hidden_states - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertMLMHead with Bert->RemBert -class TFRemBertMLMHead(keras.layers.Layer): - def __init__(self, config: RemBertConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.predictions = TFRemBertLMPredictionHead(config, input_embeddings, name="predictions") - - def call(self, sequence_output: tf.Tensor) -> tf.Tensor: - prediction_scores = self.predictions(hidden_states=sequence_output) - - return prediction_scores - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -@keras_serializable -class TFRemBertMainLayer(keras.layers.Layer): - config_class = RemBertConfig - - def __init__(self, config: RemBertConfig, add_pooling_layer: bool = True, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.is_decoder = config.is_decoder - - self.embeddings = TFRemBertEmbeddings(config, name="embeddings") - self.encoder = TFRemBertEncoder(config, name="encoder") - self.pooler = TFRemBertPooler(config, name="pooler") if add_pooling_layer else None - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.call - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - if not self.config.is_decoder: - use_cache = False - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - - if past_key_values is None: - past_key_values_length = 0 - past_key_values = [None] * len(self.encoder.layer) - else: - past_key_values_length = shape_list(past_key_values[0][0])[-2] - - if attention_mask is None: - attention_mask = tf.fill(dims=(batch_size, seq_length + past_key_values_length), value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - - mask_seq_length = seq_length + past_key_values_length - # Copied from `modeling_tf_t5.py` - # Provided a padding mask of dimensions [batch_size, mask_seq_length] - # - if the model is a decoder, apply a causal mask in addition to the padding mask - # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - if self.is_decoder: - seq_ids = tf.range(mask_seq_length) - causal_mask = tf.less_equal( - tf.tile(seq_ids[None, None, :], (batch_size, mask_seq_length, 1)), - seq_ids[None, :, None], - ) - causal_mask = tf.cast(causal_mask, dtype=attention_mask.dtype) - extended_attention_mask = causal_mask * attention_mask[:, None, :] - attention_mask_shape = shape_list(extended_attention_mask) - extended_attention_mask = tf.reshape( - extended_attention_mask, (attention_mask_shape[0], 1, attention_mask_shape[1], attention_mask_shape[2]) - ) - if past_key_values[0] is not None: - # attention_mask needs to be sliced to the shape `[batch_size, 1, from_seq_length - cached_seq_length, to_seq_length] - extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :] - else: - extended_attention_mask = tf.reshape( - attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1]) - ) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Copied from `modeling_tf_t5.py` with -1e9 -> -10000 - if self.is_decoder and encoder_attention_mask is not None: - # If a 2D ou 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=extended_attention_mask.dtype) - num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) - if num_dims_encoder_attention_mask == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if num_dims_encoder_attention_mask == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, - # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) - - encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -10000.0 - else: - encoder_extended_attention_mask = None - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -class TFRemBertPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = RemBertConfig - base_model_prefix = "rembert" - - -REMBERT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`RemBertConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -REMBERT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare RemBERT Model transformer outputting raw hidden-states without any specific head on top.", - REMBERT_START_DOCSTRING, -) -class TFRemBertModel(TFRemBertPreTrainedModel): - def __init__(self, config: RemBertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.rembert = TFRemBertMainLayer(config, name="rembert") - - @unpack_inputs - @add_start_docstrings_to_model_forward(REMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="google/rembert", - output_type=TFBaseModelOutputWithPoolingAndCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - """ - outputs = self.rembert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rembert", None) is not None: - with tf.name_scope(self.rembert.name): - self.rembert.build(None) - - -@add_start_docstrings("""RemBERT Model with a `language modeling` head on top.""", REMBERT_START_DOCSTRING) -class TFRemBertForMaskedLM(TFRemBertPreTrainedModel, TFMaskedLanguageModelingLoss): - def __init__(self, config: RemBertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if config.is_decoder: - logger.warning( - "If you want to use `TFRemBertForMaskedLM` make sure `config.is_decoder=False` for " - "bi-directional self-attention." - ) - - self.rembert = TFRemBertMainLayer(config, name="rembert", add_pooling_layer=False) - self.mlm = TFRemBertMLMHead(config, input_embeddings=self.rembert.embeddings, name="mlm___cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.mlm.predictions - - @unpack_inputs - @add_start_docstrings_to_model_forward(REMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="google/rembert", - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.rembert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.mlm(sequence_output=sequence_output, training=training) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rembert", None) is not None: - with tf.name_scope(self.rembert.name): - self.rembert.build(None) - if getattr(self, "mlm", None) is not None: - with tf.name_scope(self.mlm.name): - self.mlm.build(None) - - -@add_start_docstrings( - """RemBERT Model with a `language modeling` head on top for CLM fine-tuning.""", REMBERT_START_DOCSTRING -) -class TFRemBertForCausalLM(TFRemBertPreTrainedModel, TFCausalLanguageModelingLoss): - def __init__(self, config: RemBertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if not config.is_decoder: - logger.warning("If you want to use `TFRemBertForCausalLM` as a standalone, add `is_decoder=True.`") - - self.rembert = TFRemBertMainLayer(config, name="rembert", add_pooling_layer=False) - self.mlm = TFRemBertMLMHead(config, input_embeddings=self.rembert.embeddings, name="mlm___cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.mlm.predictions - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertLMHeadModel.prepare_inputs_for_generation - def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): - input_shape = input_ids.shape - # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly - if attention_mask is None: - attention_mask = tf.ones(input_shape) - - # cut decoder_input_ids if past is used - if past_key_values is not None: - input_ids = input_ids[:, -1:] - - return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} - - @unpack_inputs - @add_code_sample_docstrings( - checkpoint="google/rembert", - output_type=TFCausalLMOutputWithCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFCausalLMOutputWithCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - outputs = self.rembert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.mlm(sequence_output=sequence_output, training=training) - loss = None - - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels=labels, logits=shifted_logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithCrossAttentions( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rembert", None) is not None: - with tf.name_scope(self.rembert.name): - self.rembert.build(None) - if getattr(self, "mlm", None) is not None: - with tf.name_scope(self.mlm.name): - self.mlm.build(None) - - -@add_start_docstrings( - """ - RemBERT Model transformer with a sequence classification/regression head on top e.g., for GLUE tasks. - """, - REMBERT_START_DOCSTRING, -) -class TFRemBertForSequenceClassification(TFRemBertPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: RemBertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.rembert = TFRemBertMainLayer(config, name="rembert") - self.dropout = keras.layers.Dropout(rate=config.classifier_dropout_prob) - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(REMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="google/rembert", - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.rembert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(inputs=pooled_output, training=training) - logits = self.classifier(inputs=pooled_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rembert", None) is not None: - with tf.name_scope(self.rembert.name): - self.rembert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RemBERT Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - REMBERT_START_DOCSTRING, -) -class TFRemBertForMultipleChoice(TFRemBertPreTrainedModel, TFMultipleChoiceLoss): - def __init__(self, config: RemBertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.rembert = TFRemBertMainLayer(config, name="rembert") - self.dropout = keras.layers.Dropout(rate=config.classifier_dropout_prob) - self.classifier = keras.layers.Dense( - units=1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(REMBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @add_code_sample_docstrings( - checkpoint="google/rembert", - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(tensor=input_ids, shape=(-1, seq_length)) if input_ids is not None else None - flat_attention_mask = ( - tf.reshape(tensor=attention_mask, shape=(-1, seq_length)) if attention_mask is not None else None - ) - flat_token_type_ids = ( - tf.reshape(tensor=token_type_ids, shape=(-1, seq_length)) if token_type_ids is not None else None - ) - flat_position_ids = ( - tf.reshape(tensor=position_ids, shape=(-1, seq_length)) if position_ids is not None else None - ) - flat_inputs_embeds = ( - tf.reshape(tensor=inputs_embeds, shape=(-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - outputs = self.rembert( - input_ids=flat_input_ids, - attention_mask=flat_attention_mask, - token_type_ids=flat_token_type_ids, - position_ids=flat_position_ids, - head_mask=head_mask, - inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(inputs=pooled_output, training=training) - logits = self.classifier(inputs=pooled_output) - reshaped_logits = tf.reshape(tensor=logits, shape=(-1, num_choices)) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rembert", None) is not None: - with tf.name_scope(self.rembert.name): - self.rembert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RemBERT Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - REMBERT_START_DOCSTRING, -) -class TFRemBertForTokenClassification(TFRemBertPreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config: RemBertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.rembert = TFRemBertMainLayer(config, name="rembert", add_pooling_layer=False) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(REMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="google/rembert", - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.rembert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - sequence_output = self.dropout(inputs=sequence_output, training=training) - logits = self.classifier(inputs=sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rembert", None) is not None: - with tf.name_scope(self.rembert.name): - self.rembert.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RemBERT Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layer on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - REMBERT_START_DOCSTRING, -) -class TFRemBertForQuestionAnswering(TFRemBertPreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config: RemBertConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.rembert = TFRemBertMainLayer(config, add_pooling_layer=False, name="rembert") - self.qa_outputs = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(REMBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="google/rembert", - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.rembert( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.qa_outputs(inputs=sequence_output) - start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) - start_logits = tf.squeeze(input=start_logits, axis=-1) - end_logits = tf.squeeze(input=end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels=labels, logits=(start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rembert", None) is not None: - with tf.name_scope(self.rembert.name): - self.rembert.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFRemBertForCausalLM", - "TFRemBertForMaskedLM", - "TFRemBertForMultipleChoice", - "TFRemBertForQuestionAnswering", - "TFRemBertForSequenceClassification", - "TFRemBertForTokenClassification", - "TFRemBertLayer", - "TFRemBertModel", - "TFRemBertPreTrainedModel", -] diff --git a/src/transformers/models/resnet/__init__.py b/src/transformers/models/resnet/__init__.py index 625e93a25543..db16908bff31 100644 --- a/src/transformers/models/resnet/__init__.py +++ b/src/transformers/models/resnet/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_resnet import * - from .modeling_flax_resnet import * from .modeling_resnet import * - from .modeling_tf_resnet import * else: import sys diff --git a/src/transformers/models/resnet/modeling_flax_resnet.py b/src/transformers/models/resnet/modeling_flax_resnet.py deleted file mode 100644 index a2a9418b7cf2..000000000000 --- a/src/transformers/models/resnet/modeling_flax_resnet.py +++ /dev/null @@ -1,704 +0,0 @@ -# coding=utf-8 -# Copyright 2023 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. - -from functools import partial -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.traverse_util import flatten_dict, unflatten_dict - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutputWithNoAttention, - FlaxBaseModelOutputWithPoolingAndNoAttention, - FlaxImageClassifierOutputWithNoAttention, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward -from .configuration_resnet import ResNetConfig - - -RESNET_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`ResNetConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - - -RESNET_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`jax.numpy.float32` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`AutoImageProcessor.__call__`] for details. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -class Identity(nn.Module): - """Identity function.""" - - @nn.compact - def __call__(self, x, **kwargs): - return x - - -class FlaxResNetConvLayer(nn.Module): - out_channels: int - kernel_size: int = 3 - stride: int = 1 - activation: Optional[str] = "relu" - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.convolution = nn.Conv( - self.out_channels, - kernel_size=(self.kernel_size, self.kernel_size), - strides=self.stride, - padding=self.kernel_size // 2, - dtype=self.dtype, - use_bias=False, - kernel_init=nn.initializers.variance_scaling(2.0, mode="fan_out", distribution="normal", dtype=self.dtype), - ) - self.normalization = nn.BatchNorm(momentum=0.9, epsilon=1e-05, dtype=self.dtype) - self.activation_func = ACT2FN[self.activation] if self.activation is not None else Identity() - - def __call__(self, x: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - hidden_state = self.convolution(x) - hidden_state = self.normalization(hidden_state, use_running_average=deterministic) - hidden_state = self.activation_func(hidden_state) - return hidden_state - - -class FlaxResNetEmbeddings(nn.Module): - """ - ResNet Embeddings (stem) composed of a single aggressive convolution. - """ - - config: ResNetConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.embedder = FlaxResNetConvLayer( - self.config.embedding_size, - kernel_size=7, - stride=2, - activation=self.config.hidden_act, - dtype=self.dtype, - ) - - self.max_pool = partial(nn.max_pool, window_shape=(3, 3), strides=(2, 2), padding=((1, 1), (1, 1))) - - def __call__(self, pixel_values: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - num_channels = pixel_values.shape[-1] - if num_channels != self.config.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - embedding = self.embedder(pixel_values, deterministic=deterministic) - embedding = self.max_pool(embedding) - return embedding - - -class FlaxResNetShortCut(nn.Module): - """ - ResNet shortcut, used to project the residual features to the correct size. If needed, it is also used to - downsample the input using `stride=2`. - """ - - out_channels: int - stride: int = 2 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.convolution = nn.Conv( - self.out_channels, - kernel_size=(1, 1), - strides=self.stride, - use_bias=False, - kernel_init=nn.initializers.variance_scaling(2.0, mode="fan_out", distribution="truncated_normal"), - dtype=self.dtype, - ) - self.normalization = nn.BatchNorm(momentum=0.9, epsilon=1e-05, dtype=self.dtype) - - def __call__(self, x: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - hidden_state = self.convolution(x) - hidden_state = self.normalization(hidden_state, use_running_average=deterministic) - return hidden_state - - -class FlaxResNetBasicLayerCollection(nn.Module): - out_channels: int - stride: int = 1 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.layer = [ - FlaxResNetConvLayer(self.out_channels, stride=self.stride, dtype=self.dtype), - FlaxResNetConvLayer(self.out_channels, activation=None, dtype=self.dtype), - ] - - def __call__(self, hidden_state: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - for layer in self.layer: - hidden_state = layer(hidden_state, deterministic=deterministic) - return hidden_state - - -class FlaxResNetBasicLayer(nn.Module): - """ - A classic ResNet's residual layer composed by two `3x3` convolutions. - """ - - in_channels: int - out_channels: int - stride: int = 1 - activation: Optional[str] = "relu" - dtype: jnp.dtype = jnp.float32 - - def setup(self): - should_apply_shortcut = self.in_channels != self.out_channels or self.stride != 1 - self.shortcut = ( - FlaxResNetShortCut(self.out_channels, stride=self.stride, dtype=self.dtype) - if should_apply_shortcut - else None - ) - self.layer = FlaxResNetBasicLayerCollection( - out_channels=self.out_channels, - stride=self.stride, - dtype=self.dtype, - ) - self.activation_func = ACT2FN[self.activation] - - def __call__(self, hidden_state, deterministic: bool = True): - residual = hidden_state - hidden_state = self.layer(hidden_state, deterministic=deterministic) - - if self.shortcut is not None: - residual = self.shortcut(residual, deterministic=deterministic) - hidden_state += residual - - hidden_state = self.activation_func(hidden_state) - return hidden_state - - -class FlaxResNetBottleNeckLayerCollection(nn.Module): - out_channels: int - stride: int = 1 - activation: Optional[str] = "relu" - reduction: int = 4 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - reduces_channels = self.out_channels // self.reduction - - self.layer = [ - FlaxResNetConvLayer(reduces_channels, kernel_size=1, dtype=self.dtype, name="0"), - FlaxResNetConvLayer(reduces_channels, stride=self.stride, dtype=self.dtype, name="1"), - FlaxResNetConvLayer(self.out_channels, kernel_size=1, activation=None, dtype=self.dtype, name="2"), - ] - - def __call__(self, hidden_state: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - for layer in self.layer: - hidden_state = layer(hidden_state, deterministic=deterministic) - return hidden_state - - -class FlaxResNetBottleNeckLayer(nn.Module): - """ - A classic ResNet's bottleneck layer composed by three `3x3` convolutions. The first `1x1` convolution reduces the - input by a factor of `reduction` in order to make the second `3x3` convolution faster. The last `1x1` convolution - remaps the reduced features to `out_channels`. - """ - - in_channels: int - out_channels: int - stride: int = 1 - activation: Optional[str] = "relu" - reduction: int = 4 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - should_apply_shortcut = self.in_channels != self.out_channels or self.stride != 1 - self.shortcut = ( - FlaxResNetShortCut(self.out_channels, stride=self.stride, dtype=self.dtype) - if should_apply_shortcut - else None - ) - - self.layer = FlaxResNetBottleNeckLayerCollection( - self.out_channels, - stride=self.stride, - activation=self.activation, - reduction=self.reduction, - dtype=self.dtype, - ) - - self.activation_func = ACT2FN[self.activation] - - def __call__(self, hidden_state: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - residual = hidden_state - - if self.shortcut is not None: - residual = self.shortcut(residual, deterministic=deterministic) - hidden_state = self.layer(hidden_state, deterministic) - hidden_state += residual - hidden_state = self.activation_func(hidden_state) - return hidden_state - - -class FlaxResNetStageLayersCollection(nn.Module): - """ - A ResNet stage composed by stacked layers. - """ - - config: ResNetConfig - in_channels: int - out_channels: int - stride: int = 2 - depth: int = 2 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - layer = FlaxResNetBottleNeckLayer if self.config.layer_type == "bottleneck" else FlaxResNetBasicLayer - - layers = [ - # downsampling is done in the first layer with stride of 2 - layer( - self.in_channels, - self.out_channels, - stride=self.stride, - activation=self.config.hidden_act, - dtype=self.dtype, - name="0", - ), - ] - - for i in range(self.depth - 1): - layers.append( - layer( - self.out_channels, - self.out_channels, - activation=self.config.hidden_act, - dtype=self.dtype, - name=str(i + 1), - ) - ) - - self.layers = layers - - def __call__(self, x: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - hidden_state = x - for layer in self.layers: - hidden_state = layer(hidden_state, deterministic=deterministic) - return hidden_state - - -class FlaxResNetStage(nn.Module): - """ - A ResNet stage composed by stacked layers. - """ - - config: ResNetConfig - in_channels: int - out_channels: int - stride: int = 2 - depth: int = 2 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.layers = FlaxResNetStageLayersCollection( - self.config, - in_channels=self.in_channels, - out_channels=self.out_channels, - stride=self.stride, - depth=self.depth, - dtype=self.dtype, - ) - - def __call__(self, x: jnp.ndarray, deterministic: bool = True) -> jnp.ndarray: - return self.layers(x, deterministic=deterministic) - - -class FlaxResNetStageCollection(nn.Module): - config: ResNetConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - in_out_channels = zip(self.config.hidden_sizes, self.config.hidden_sizes[1:]) - stages = [ - FlaxResNetStage( - self.config, - self.config.embedding_size, - self.config.hidden_sizes[0], - stride=2 if self.config.downsample_in_first_stage else 1, - depth=self.config.depths[0], - dtype=self.dtype, - name="0", - ) - ] - - for i, ((in_channels, out_channels), depth) in enumerate(zip(in_out_channels, self.config.depths[1:])): - stages.append( - FlaxResNetStage(self.config, in_channels, out_channels, depth=depth, dtype=self.dtype, name=str(i + 1)) - ) - - self.stages = stages - - def __call__( - self, - hidden_state: jnp.ndarray, - output_hidden_states: bool = False, - deterministic: bool = True, - ) -> FlaxBaseModelOutputWithNoAttention: - hidden_states = () if output_hidden_states else None - - for stage_module in self.stages: - if output_hidden_states: - hidden_states = hidden_states + (hidden_state.transpose(0, 3, 1, 2),) - - hidden_state = stage_module(hidden_state, deterministic=deterministic) - - return hidden_state, hidden_states - - -class FlaxResNetEncoder(nn.Module): - config: ResNetConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.stages = FlaxResNetStageCollection(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_state: jnp.ndarray, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ) -> FlaxBaseModelOutputWithNoAttention: - hidden_state, hidden_states = self.stages( - hidden_state, output_hidden_states=output_hidden_states, deterministic=deterministic - ) - - if output_hidden_states: - hidden_states = hidden_states + (hidden_state.transpose(0, 3, 1, 2),) - - if not return_dict: - return tuple(v for v in [hidden_state, hidden_states] if v is not None) - - return FlaxBaseModelOutputWithNoAttention( - last_hidden_state=hidden_state, - hidden_states=hidden_states, - ) - - -class FlaxResNetPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = ResNetConfig - base_model_prefix = "resnet" - main_input_name = "pixel_values" - module_class: nn.Module = None - - def __init__( - self, - config: ResNetConfig, - input_shape=(1, 224, 224, 3), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - if input_shape is None: - input_shape = (1, config.image_size, config.image_size, config.num_channels) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - pixel_values = jnp.zeros(input_shape, dtype=self.dtype) - - rngs = {"params": rng} - - random_params = self.module.init(rngs, pixel_values, return_dict=False) - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(RESNET_INPUTS_DOCSTRING) - def __call__( - self, - pixel_values, - params: Optional[dict] = None, - train: bool = False, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - - # Handle any PRNG if needed - rngs = {} - - return self.module.apply( - { - "params": params["params"] if params is not None else self.params["params"], - "batch_stats": params["batch_stats"] if params is not None else self.params["batch_stats"], - }, - jnp.array(pixel_values, dtype=jnp.float32), - not train, - output_hidden_states, - return_dict, - rngs=rngs, - mutable=["batch_stats"] if train else False, # Returning tuple with batch_stats only when train is True - ) - - -class FlaxResNetModule(nn.Module): - config: ResNetConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.embedder = FlaxResNetEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxResNetEncoder(self.config, dtype=self.dtype) - - # Adaptive average pooling used in resnet - self.pooler = partial( - nn.avg_pool, - padding=((0, 0), (0, 0)), - ) - - def __call__( - self, - pixel_values, - deterministic: bool = True, - output_hidden_states: bool = False, - return_dict: bool = True, - ) -> FlaxBaseModelOutputWithPoolingAndNoAttention: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - embedding_output = self.embedder(pixel_values, deterministic=deterministic) - - encoder_outputs = self.encoder( - embedding_output, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - last_hidden_state = encoder_outputs[0] - - pooled_output = self.pooler( - last_hidden_state, - window_shape=(last_hidden_state.shape[1], last_hidden_state.shape[2]), - strides=(last_hidden_state.shape[1], last_hidden_state.shape[2]), - ).transpose(0, 3, 1, 2) - - last_hidden_state = last_hidden_state.transpose(0, 3, 1, 2) - - if not return_dict: - return (last_hidden_state, pooled_output) + encoder_outputs[1:] - - return FlaxBaseModelOutputWithPoolingAndNoAttention( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - ) - - -@add_start_docstrings( - "The bare ResNet model outputting raw features without any specific head on top.", - RESNET_START_DOCSTRING, -) -class FlaxResNetModel(FlaxResNetPreTrainedModel): - module_class = FlaxResNetModule - - -FLAX_VISION_MODEL_DOCSTRING = """ - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, FlaxResNetModel - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/resnet-50") - >>> model = FlaxResNetModel.from_pretrained("microsoft/resnet-50") - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> last_hidden_states = outputs.last_hidden_state - ``` -""" - -overwrite_call_docstring(FlaxResNetModel, FLAX_VISION_MODEL_DOCSTRING) -append_replace_return_docstrings( - FlaxResNetModel, output_type=FlaxBaseModelOutputWithPoolingAndNoAttention, config_class=ResNetConfig -) - - -class FlaxResNetClassifierCollection(nn.Module): - config: ResNetConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype, name="1") - - def __call__(self, x: jnp.ndarray) -> jnp.ndarray: - return self.classifier(x) - - -class FlaxResNetForImageClassificationModule(nn.Module): - config: ResNetConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.resnet = FlaxResNetModule(config=self.config, dtype=self.dtype) - - if self.config.num_labels > 0: - self.classifier = FlaxResNetClassifierCollection(self.config, dtype=self.dtype) - else: - self.classifier = Identity() - - def __call__( - self, - pixel_values=None, - deterministic: bool = True, - output_hidden_states=None, - return_dict=None, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.resnet( - pixel_values, - deterministic=deterministic, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs.pooler_output if return_dict else outputs[1] - - logits = self.classifier(pooled_output[:, :, 0, 0]) - - if not return_dict: - output = (logits,) + outputs[2:] - return output - - return FlaxImageClassifierOutputWithNoAttention(logits=logits, hidden_states=outputs.hidden_states) - - -@add_start_docstrings( - """ - ResNet Model with an image classification head on top (a linear layer on top of the pooled features), e.g. for - ImageNet. - """, - RESNET_START_DOCSTRING, -) -class FlaxResNetForImageClassification(FlaxResNetPreTrainedModel): - module_class = FlaxResNetForImageClassificationModule - - -FLAX_VISION_CLASSIF_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoImageProcessor, FlaxResNetForImageClassification - >>> from PIL import Image - >>> import jax - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/resnet-50") - >>> model = FlaxResNetForImageClassification.from_pretrained("microsoft/resnet-50") - - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> logits = outputs.logits - - >>> # model predicts one of the 1000 ImageNet classes - >>> predicted_class_idx = jax.numpy.argmax(logits, axis=-1) - >>> print("Predicted class:", model.config.id2label[predicted_class_idx.item()]) - ``` -""" - -overwrite_call_docstring(FlaxResNetForImageClassification, FLAX_VISION_CLASSIF_DOCSTRING) -append_replace_return_docstrings( - FlaxResNetForImageClassification, output_type=FlaxImageClassifierOutputWithNoAttention, config_class=ResNetConfig -) - - -__all__ = ["FlaxResNetForImageClassification", "FlaxResNetModel", "FlaxResNetPreTrainedModel"] diff --git a/src/transformers/models/resnet/modeling_tf_resnet.py b/src/transformers/models/resnet/modeling_tf_resnet.py deleted file mode 100644 index f7c415f97b05..000000000000 --- a/src/transformers/models/resnet/modeling_tf_resnet.py +++ /dev/null @@ -1,596 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Microsoft Research, Inc. and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow ResNet model.""" - -from typing import Optional, Union - -import tensorflow as tf - -from ...activations_tf import ACT2FN -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithNoAttention, - TFBaseModelOutputWithPoolingAndNoAttention, - TFImageClassifierOutputWithNoAttention, -) -from ...modeling_tf_utils import ( - TFPreTrainedModel, - TFSequenceClassificationLoss, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list -from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_resnet import ResNetConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "ResNetConfig" - -# Base docstring -_CHECKPOINT_FOR_DOC = "microsoft/resnet-50" -_EXPECTED_OUTPUT_SHAPE = [1, 2048, 7, 7] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "microsoft/resnet-50" -_IMAGE_CLASS_EXPECTED_OUTPUT = "tiger cat" - - -class TFResNetConvLayer(keras.layers.Layer): - def __init__( - self, - in_channels: int, - out_channels: int, - kernel_size: int = 3, - stride: int = 1, - activation: str = "relu", - **kwargs, - ) -> None: - super().__init__(**kwargs) - self.pad_value = kernel_size // 2 - self.conv = keras.layers.Conv2D( - out_channels, kernel_size=kernel_size, strides=stride, padding="valid", use_bias=False, name="convolution" - ) - # Use same default momentum and epsilon as PyTorch equivalent - self.normalization = keras.layers.BatchNormalization(epsilon=1e-5, momentum=0.9, name="normalization") - self.activation = ACT2FN[activation] if activation is not None else keras.layers.Activation("linear") - self.in_channels = in_channels - self.out_channels = out_channels - - def convolution(self, hidden_state: tf.Tensor) -> tf.Tensor: - # Pad to match that done in the PyTorch Conv2D model - height_pad = width_pad = (self.pad_value, self.pad_value) - hidden_state = tf.pad(hidden_state, [(0, 0), height_pad, width_pad, (0, 0)]) - hidden_state = self.conv(hidden_state) - return hidden_state - - def call(self, hidden_state: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_state = self.convolution(hidden_state) - hidden_state = self.normalization(hidden_state, training=training) - hidden_state = self.activation(hidden_state) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build([None, None, None, self.in_channels]) - if getattr(self, "normalization", None) is not None: - with tf.name_scope(self.normalization.name): - self.normalization.build([None, None, None, self.out_channels]) - - -class TFResNetEmbeddings(keras.layers.Layer): - """ - ResNet Embeddings (stem) composed of a single aggressive convolution. - """ - - def __init__(self, config: ResNetConfig, **kwargs) -> None: - super().__init__(**kwargs) - self.embedder = TFResNetConvLayer( - config.num_channels, - config.embedding_size, - kernel_size=7, - stride=2, - activation=config.hidden_act, - name="embedder", - ) - self.pooler = keras.layers.MaxPool2D(pool_size=3, strides=2, padding="valid", name="pooler") - self.num_channels = config.num_channels - - def call(self, pixel_values: tf.Tensor, training: bool = False) -> tf.Tensor: - _, _, _, num_channels = shape_list(pixel_values) - if tf.executing_eagerly() and num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - hidden_state = pixel_values - hidden_state = self.embedder(hidden_state) - hidden_state = tf.pad(hidden_state, [[0, 0], [1, 1], [1, 1], [0, 0]]) - hidden_state = self.pooler(hidden_state) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embedder", None) is not None: - with tf.name_scope(self.embedder.name): - self.embedder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -class TFResNetShortCut(keras.layers.Layer): - """ - ResNet shortcut, used to project the residual features to the correct size. If needed, it is also used to - downsample the input using `stride=2`. - """ - - def __init__(self, in_channels: int, out_channels: int, stride: int = 2, **kwargs) -> None: - super().__init__(**kwargs) - self.convolution = keras.layers.Conv2D( - out_channels, kernel_size=1, strides=stride, use_bias=False, name="convolution" - ) - # Use same default momentum and epsilon as PyTorch equivalent - self.normalization = keras.layers.BatchNormalization(epsilon=1e-5, momentum=0.9, name="normalization") - self.in_channels = in_channels - self.out_channels = out_channels - - def call(self, x: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_state = x - hidden_state = self.convolution(hidden_state) - hidden_state = self.normalization(hidden_state, training=training) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "convolution", None) is not None: - with tf.name_scope(self.convolution.name): - self.convolution.build([None, None, None, self.in_channels]) - if getattr(self, "normalization", None) is not None: - with tf.name_scope(self.normalization.name): - self.normalization.build([None, None, None, self.out_channels]) - - -class TFResNetBasicLayer(keras.layers.Layer): - """ - A classic ResNet's residual layer composed by two `3x3` convolutions. - """ - - def __init__( - self, in_channels: int, out_channels: int, stride: int = 1, activation: str = "relu", **kwargs - ) -> None: - super().__init__(**kwargs) - should_apply_shortcut = in_channels != out_channels or stride != 1 - self.conv1 = TFResNetConvLayer(in_channels, out_channels, stride=stride, name="layer.0") - self.conv2 = TFResNetConvLayer(out_channels, out_channels, activation=None, name="layer.1") - self.shortcut = ( - TFResNetShortCut(in_channels, out_channels, stride=stride, name="shortcut") - if should_apply_shortcut - else keras.layers.Activation("linear", name="shortcut") - ) - self.activation = ACT2FN[activation] - - def call(self, hidden_state: tf.Tensor, training: bool = False) -> tf.Tensor: - residual = hidden_state - hidden_state = self.conv1(hidden_state, training=training) - hidden_state = self.conv2(hidden_state, training=training) - residual = self.shortcut(residual, training=training) - hidden_state += residual - hidden_state = self.activation(hidden_state) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv1", None) is not None: - with tf.name_scope(self.conv1.name): - self.conv1.build(None) - if getattr(self, "conv2", None) is not None: - with tf.name_scope(self.conv2.name): - self.conv2.build(None) - if getattr(self, "shortcut", None) is not None: - with tf.name_scope(self.shortcut.name): - self.shortcut.build(None) - - -class TFResNetBottleNeckLayer(keras.layers.Layer): - """ - A classic ResNet's bottleneck layer composed by three `3x3` convolutions. - - The first `1x1` convolution reduces the input by a factor of `reduction` in order to make the second `3x3` - convolution faster. The last `1x1` convolution remaps the reduced features to `out_channels`. - """ - - def __init__( - self, - in_channels: int, - out_channels: int, - stride: int = 1, - activation: str = "relu", - reduction: int = 4, - **kwargs, - ) -> None: - super().__init__(**kwargs) - should_apply_shortcut = in_channels != out_channels or stride != 1 - reduces_channels = out_channels // reduction - self.conv0 = TFResNetConvLayer(in_channels, reduces_channels, kernel_size=1, name="layer.0") - self.conv1 = TFResNetConvLayer(reduces_channels, reduces_channels, stride=stride, name="layer.1") - self.conv2 = TFResNetConvLayer(reduces_channels, out_channels, kernel_size=1, activation=None, name="layer.2") - self.shortcut = ( - TFResNetShortCut(in_channels, out_channels, stride=stride, name="shortcut") - if should_apply_shortcut - else keras.layers.Activation("linear", name="shortcut") - ) - self.activation = ACT2FN[activation] - - def call(self, hidden_state: tf.Tensor, training: bool = False) -> tf.Tensor: - residual = hidden_state - hidden_state = self.conv0(hidden_state, training=training) - hidden_state = self.conv1(hidden_state, training=training) - hidden_state = self.conv2(hidden_state, training=training) - residual = self.shortcut(residual, training=training) - hidden_state += residual - hidden_state = self.activation(hidden_state) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv0", None) is not None: - with tf.name_scope(self.conv0.name): - self.conv0.build(None) - if getattr(self, "conv1", None) is not None: - with tf.name_scope(self.conv1.name): - self.conv1.build(None) - if getattr(self, "conv2", None) is not None: - with tf.name_scope(self.conv2.name): - self.conv2.build(None) - if getattr(self, "shortcut", None) is not None: - with tf.name_scope(self.shortcut.name): - self.shortcut.build(None) - - -class TFResNetStage(keras.layers.Layer): - """ - A ResNet stage composed of stacked layers. - """ - - def __init__( - self, config: ResNetConfig, in_channels: int, out_channels: int, stride: int = 2, depth: int = 2, **kwargs - ) -> None: - super().__init__(**kwargs) - - layer = TFResNetBottleNeckLayer if config.layer_type == "bottleneck" else TFResNetBasicLayer - - layers = [layer(in_channels, out_channels, stride=stride, activation=config.hidden_act, name="layers.0")] - layers += [ - layer(out_channels, out_channels, activation=config.hidden_act, name=f"layers.{i + 1}") - for i in range(depth - 1) - ] - self.stage_layers = layers - - def call(self, hidden_state: tf.Tensor, training: bool = False) -> tf.Tensor: - for layer in self.stage_layers: - hidden_state = layer(hidden_state, training=training) - return hidden_state - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "stage_layers", None) is not None: - for layer in self.stage_layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFResNetEncoder(keras.layers.Layer): - def __init__(self, config: ResNetConfig, **kwargs) -> None: - super().__init__(**kwargs) - # based on `downsample_in_first_stage` the first layer of the first stage may or may not downsample the input - self.stages = [ - TFResNetStage( - config, - config.embedding_size, - config.hidden_sizes[0], - stride=2 if config.downsample_in_first_stage else 1, - depth=config.depths[0], - name="stages.0", - ) - ] - for i, (in_channels, out_channels, depth) in enumerate( - zip(config.hidden_sizes, config.hidden_sizes[1:], config.depths[1:]) - ): - self.stages.append(TFResNetStage(config, in_channels, out_channels, depth=depth, name=f"stages.{i + 1}")) - - def call( - self, - hidden_state: tf.Tensor, - output_hidden_states: bool = False, - return_dict: bool = True, - training: bool = False, - ) -> TFBaseModelOutputWithNoAttention: - hidden_states = () if output_hidden_states else None - - for stage_module in self.stages: - if output_hidden_states: - hidden_states = hidden_states + (hidden_state,) - - hidden_state = stage_module(hidden_state, training=training) - - if output_hidden_states: - hidden_states = hidden_states + (hidden_state,) - - if not return_dict: - return tuple(v for v in [hidden_state, hidden_states] if v is not None) - - return TFBaseModelOutputWithNoAttention(last_hidden_state=hidden_state, hidden_states=hidden_states) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "stages", None) is not None: - for layer in self.stages: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFResNetPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = ResNetConfig - base_model_prefix = "resnet" - main_input_name = "pixel_values" - - @property - def input_signature(self): - return {"pixel_values": tf.TensorSpec(shape=(None, self.config.num_channels, 224, 224), dtype=tf.float32)} - - -RESNET_START_DOCSTRING = r""" - This model is a TensorFlow - [keras.layers.Layer](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer) sub-class. Use it as a - regular TensorFlow Module and refer to the TensorFlow documentation for all matter related to general usage and - behavior. - - Parameters: - config ([`ResNetConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - - -RESNET_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`ConvNextImageProcessor.__call__`] for details. - - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@keras_serializable -class TFResNetMainLayer(keras.layers.Layer): - config_class = ResNetConfig - - def __init__(self, config: ResNetConfig, **kwargs) -> None: - super().__init__(**kwargs) - self.config = config - self.embedder = TFResNetEmbeddings(config, name="embedder") - self.encoder = TFResNetEncoder(config, name="encoder") - self.pooler = keras.layers.GlobalAveragePooling2D(keepdims=True) - - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[tuple[tf.Tensor], TFBaseModelOutputWithPoolingAndNoAttention]: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # TF 2.0 image layers can't use NCHW format when running on CPU. - # We transpose to NHWC format and then transpose back after the full forward pass. - # (batch_size, num_channels, height, width) -> (batch_size, height, width, num_channels) - pixel_values = tf.transpose(pixel_values, perm=[0, 2, 3, 1]) - embedding_output = self.embedder(pixel_values, training=training) - - encoder_outputs = self.encoder( - embedding_output, output_hidden_states=output_hidden_states, return_dict=return_dict, training=training - ) - - last_hidden_state = encoder_outputs[0] - - pooled_output = self.pooler(last_hidden_state) - - # Transpose all the outputs to the NCHW format - # (batch_size, height, width, num_channels) -> (batch_size, num_channels, height, width) - last_hidden_state = tf.transpose(last_hidden_state, (0, 3, 1, 2)) - pooled_output = tf.transpose(pooled_output, (0, 3, 1, 2)) - hidden_states = () - for hidden_state in encoder_outputs[1:]: - hidden_states = hidden_states + tuple(tf.transpose(h, (0, 3, 1, 2)) for h in hidden_state) - - if not return_dict: - return (last_hidden_state, pooled_output) + hidden_states - - hidden_states = hidden_states if output_hidden_states else None - - return TFBaseModelOutputWithPoolingAndNoAttention( - last_hidden_state=last_hidden_state, - pooler_output=pooled_output, - hidden_states=hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embedder", None) is not None: - with tf.name_scope(self.embedder.name): - self.embedder.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - - -@add_start_docstrings( - "The bare ResNet model outputting raw features without any specific head on top.", - RESNET_START_DOCSTRING, -) -class TFResNetModel(TFResNetPreTrainedModel): - def __init__(self, config: ResNetConfig, **kwargs) -> None: - super().__init__(config, **kwargs) - self.resnet = TFResNetMainLayer(config=config, name="resnet") - - @add_start_docstrings_to_model_forward(RESNET_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPoolingAndNoAttention, - config_class=_CONFIG_FOR_DOC, - modality="vision", - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[tuple[tf.Tensor], TFBaseModelOutputWithPoolingAndNoAttention]: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - resnet_outputs = self.resnet( - pixel_values=pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return resnet_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "resnet", None) is not None: - with tf.name_scope(self.resnet.name): - self.resnet.build(None) - - -@add_start_docstrings( - """ - ResNet Model with an image classification head on top (a linear layer on top of the pooled features), e.g. for - ImageNet. - """, - RESNET_START_DOCSTRING, -) -class TFResNetForImageClassification(TFResNetPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: ResNetConfig, **kwargs) -> None: - super().__init__(config, **kwargs) - self.num_labels = config.num_labels - self.resnet = TFResNetMainLayer(config, name="resnet") - # classification head - self.classifier_layer = ( - keras.layers.Dense(config.num_labels, name="classifier.1") - if config.num_labels > 0 - else keras.layers.Activation("linear", name="classifier.1") - ) - self.config = config - - def classifier(self, x: tf.Tensor) -> tf.Tensor: - x = keras.layers.Flatten()(x) - logits = self.classifier_layer(x) - return logits - - @add_start_docstrings_to_model_forward(RESNET_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFImageClassifierOutputWithNoAttention, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - @unpack_inputs - def call( - self, - pixel_values: Optional[tf.Tensor] = None, - labels: Optional[tf.Tensor] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[tuple[tf.Tensor], TFImageClassifierOutputWithNoAttention]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.resnet( - pixel_values, output_hidden_states=output_hidden_states, return_dict=return_dict, training=training - ) - - pooled_output = outputs.pooler_output if return_dict else outputs[1] - - logits = self.classifier(pooled_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return (loss,) + output if loss is not None else output - - return TFImageClassifierOutputWithNoAttention(loss=loss, logits=logits, hidden_states=outputs.hidden_states) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "resnet", None) is not None: - with tf.name_scope(self.resnet.name): - self.resnet.build(None) - if getattr(self, "classifier_layer", None) is not None: - with tf.name_scope(self.classifier_layer.name): - self.classifier_layer.build([None, None, self.config.hidden_sizes[-1]]) - - -__all__ = ["TFResNetForImageClassification", "TFResNetModel", "TFResNetPreTrainedModel"] diff --git a/src/transformers/models/roberta/__init__.py b/src/transformers/models/roberta/__init__.py index 9f9418d33d35..a82d4c9bc617 100644 --- a/src/transformers/models/roberta/__init__.py +++ b/src/transformers/models/roberta/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_roberta import * - from .modeling_flax_roberta import * from .modeling_roberta import * - from .modeling_tf_roberta import * from .tokenization_roberta import * from .tokenization_roberta_fast import * else: diff --git a/src/transformers/models/roberta/modeling_flax_roberta.py b/src/transformers/models/roberta/modeling_flax_roberta.py deleted file mode 100644 index 3b46c0fa682f..000000000000 --- a/src/transformers/models/roberta/modeling_flax_roberta.py +++ /dev/null @@ -1,1500 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Google Flax Team Authors and 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. -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen import partitioning as nn_partitioning -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxBaseModelOutputWithPooling, - FlaxBaseModelOutputWithPoolingAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxMaskedLMOutput, - FlaxMultipleChoiceModelOutput, - FlaxQuestionAnsweringModelOutput, - FlaxSequenceClassifierOutput, - FlaxTokenClassifierOutput, -) -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring, overwrite_call_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_roberta import RobertaConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "FacebookAI/roberta-base" -_CONFIG_FOR_DOC = "RobertaConfig" - -remat = nn_partitioning.remat - - -def create_position_ids_from_input_ids(input_ids, padding_idx): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - input_ids: jnp.ndarray - padding_idx: int - - Returns: jnp.ndarray - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = (input_ids != padding_idx).astype("i4") - - if mask.ndim > 2: - mask = mask.reshape((-1, mask.shape[-1])) - incremental_indices = jnp.cumsum(mask, axis=1).astype("i4") * mask - incremental_indices = incremental_indices.reshape(input_ids.shape) - else: - incremental_indices = jnp.cumsum(mask, axis=1).astype("i4") * mask - - return incremental_indices.astype("i4") + padding_idx - - -ROBERTA_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`RobertaConfig`]): Model configuration class with all the parameters of the - model. Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -ROBERTA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - head_mask (`numpy.ndarray` of shape `({0})`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEmbeddings with Bert->Roberta -class FlaxRobertaEmbeddings(nn.Module): - """Construct the embeddings from word, position and token_type embeddings.""" - - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.word_embeddings = nn.Embed( - self.config.vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.position_embeddings = nn.Embed( - self.config.max_position_embeddings, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.token_type_embeddings = nn.Embed( - self.config.type_vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, input_ids, token_type_ids, position_ids, attention_mask, deterministic: bool = True): - # Embed - inputs_embeds = self.word_embeddings(input_ids.astype("i4")) - position_embeds = self.position_embeddings(position_ids.astype("i4")) - token_type_embeddings = self.token_type_embeddings(token_type_ids.astype("i4")) - - # Sum all embeddings - hidden_states = inputs_embeds + token_type_embeddings + position_embeds - - # Layer Norm - hidden_states = self.LayerNorm(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfAttention with Bert->Roberta -class FlaxRobertaSelfAttention(nn.Module): - config: RobertaConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.head_dim = self.config.hidden_size // self.config.num_attention_heads - if self.config.hidden_size % self.config.num_attention_heads != 0: - raise ValueError( - "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads` " - " : {self.config.num_attention_heads}" - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.num_attention_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.hidden_size,)) - - @nn.compact - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention._concatenate_to_cache - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic=True, - output_attentions: bool = False, - ): - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.query(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.key(key_value_states) - value_states = self.value(key_value_states) - else: - # self_attention - key_states = self.key(hidden_states) - value_states = self.value(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - # Mask heads if we want to - if layer_head_mask is not None: - attn_weights = jnp.einsum("...hqk,h->...hqk", attn_weights, layer_head_mask) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfOutput with Bert->Roberta -class FlaxRobertaSelfOutput(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, input_tensor, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertAttention with Bert->Roberta -class FlaxRobertaAttention(nn.Module): - config: RobertaConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.self = FlaxRobertaSelfAttention(self.config, causal=self.causal, dtype=self.dtype) - self.output = FlaxRobertaSelfOutput(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states=None, - init_cache=False, - deterministic=True, - output_attentions: bool = False, - ): - # Attention mask comes in as attention_mask.shape == (*batch_sizes, kv_length) - # FLAX expects: attention_mask.shape == (*batch_sizes, 1, 1, kv_length) such that it is broadcastable - # with attn_weights.shape == (*batch_sizes, num_heads, q_length, kv_length) - attn_outputs = self.self( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=key_value_states, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attn_output = attn_outputs[0] - hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_outputs[1],) - - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertIntermediate with Bert->Roberta -class FlaxRobertaIntermediate(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertOutput with Bert->Roberta -class FlaxRobertaOutput(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states, attention_output, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + attention_output) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayer with Bert->Roberta -class FlaxRobertaLayer(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.attention = FlaxRobertaAttention(self.config, causal=self.config.is_decoder, dtype=self.dtype) - self.intermediate = FlaxRobertaIntermediate(self.config, dtype=self.dtype) - self.output = FlaxRobertaOutput(self.config, dtype=self.dtype) - if self.config.add_cross_attention: - self.crossattention = FlaxRobertaAttention(self.config, causal=False, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - ): - # Self Attention - attention_outputs = self.attention( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = attention_outputs[0] - - # Cross-Attention Block - if encoder_hidden_states is not None: - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=encoder_hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = cross_attention_outputs[0] - - hidden_states = self.intermediate(attention_output) - hidden_states = self.output(hidden_states, attention_output, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attention_outputs[1],) - if encoder_hidden_states is not None: - outputs += (cross_attention_outputs[1],) - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayerCollection with Bert->Roberta -class FlaxRobertaLayerCollection(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - if self.gradient_checkpointing: - FlaxRobertaCheckpointLayer = remat(FlaxRobertaLayer, static_argnums=(5, 6, 7)) - self.layers = [ - FlaxRobertaCheckpointLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - else: - self.layers = [ - FlaxRobertaLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - # Check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - if head_mask.shape[0] != (len(self.layers)): - raise ValueError( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for " - f" {head_mask.shape[0]}." - ) - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer( - hidden_states, - attention_mask, - head_mask[i] if head_mask is not None else None, - encoder_hidden_states, - encoder_attention_mask, - init_cache, - deterministic, - output_attentions, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions, all_cross_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEncoder with Bert->Roberta -class FlaxRobertaEncoder(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.layer = FlaxRobertaLayerCollection( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.layer( - hidden_states, - attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPooler with Bert->Roberta -class FlaxRobertaPooler(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - - def __call__(self, hidden_states): - cls_hidden_state = hidden_states[:, 0] - cls_hidden_state = self.dense(cls_hidden_state) - return nn.tanh(cls_hidden_state) - - -class FlaxRobertaLMHead(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.decoder = nn.Dense( - self.config.vocab_size, - dtype=self.dtype, - use_bias=False, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) - - def __call__(self, hidden_states, shared_embedding=None): - hidden_states = self.dense(hidden_states) - hidden_states = ACT2FN["gelu"](hidden_states) - hidden_states = self.layer_norm(hidden_states) - - if shared_embedding is not None: - hidden_states = self.decoder.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - hidden_states = self.decoder(hidden_states) - - bias = jnp.asarray(self.bias, self.dtype) - hidden_states += bias - return hidden_states - - -class FlaxRobertaClassificationHead(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.out_proj = nn.Dense( - self.config.num_labels, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - def __call__(self, hidden_states, deterministic=True): - hidden_states = hidden_states[:, 0, :] # take token (equiv. to [CLS]) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.dense(hidden_states) - hidden_states = nn.tanh(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.out_proj(hidden_states) - return hidden_states - - -class FlaxRobertaPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = RobertaConfig - base_model_prefix = "roberta" - - module_class: nn.Module = None - - def __init__( - self, - config: RobertaConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - gradient_checkpointing: bool = False, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, gradient_checkpointing=gradient_checkpointing, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPreTrainedModel.enable_gradient_checkpointing - def enable_gradient_checkpointing(self): - self._module = self.module_class( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=True, - ) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - token_type_ids = jnp.ones_like(input_ids) - position_ids = create_position_ids_from_input_ids(input_ids, self.config.pad_token_id) - attention_mask = jnp.ones_like(input_ids) - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - if self.config.add_cross_attention: - encoder_hidden_states = jnp.zeros(input_shape + (self.config.hidden_size,)) - encoder_attention_mask = attention_mask - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - return_dict=False, - ) - else: - module_init_outputs = self.module.init( - rngs, input_ids, attention_mask, token_type_ids, position_ids, head_mask, return_dict=False - ) - - random_params = module_init_outputs["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderPreTrainedModel.init_cache - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length), dtype="i4") - attention_mask = jnp.ones_like(input_ids, dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - past_key_values: Optional[dict] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # init input tensors if not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - if position_ids is None: - position_ids = create_position_ids_from_input_ids(input_ids, self.config.pad_token_id) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - if head_mask is None: - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - if self.config.add_cross_attention: - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed - # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be - # changed by FlaxRobertaAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - else: - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - ) - - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertModule with Bert->Roberta -class FlaxRobertaModule(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - add_pooling_layer: bool = True - gradient_checkpointing: bool = False - - def setup(self): - self.embeddings = FlaxRobertaEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxRobertaEncoder( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.pooler = FlaxRobertaPooler(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - head_mask: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # make sure `token_type_ids` is correctly initialized when not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - # make sure `position_ids` is correctly initialized when not passed - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - hidden_states = self.embeddings( - input_ids, token_type_ids, position_ids, attention_mask, deterministic=deterministic - ) - outputs = self.encoder( - hidden_states, - attention_mask, - head_mask=head_mask, - deterministic=deterministic, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - pooled = self.pooler(hidden_states) if self.add_pooling_layer else None - - if not return_dict: - # if pooled is None, don't return it - if pooled is None: - return (hidden_states,) + outputs[1:] - return (hidden_states, pooled) + outputs[1:] - - return FlaxBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=hidden_states, - pooler_output=pooled, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - "The bare RoBERTa Model transformer outputting raw hidden-states without any specific head on top.", - ROBERTA_START_DOCSTRING, -) -class FlaxRobertaModel(FlaxRobertaPreTrainedModel): - module_class = FlaxRobertaModule - - -append_call_sample_docstring(FlaxRobertaModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutputWithPooling, _CONFIG_FOR_DOC) - - -class FlaxRobertaForMaskedLMModule(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxRobertaModule( - config=self.config, - add_pooling_layer=False, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.lm_head = FlaxRobertaLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.roberta.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.lm_head(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxMaskedLMOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings("""RoBERTa Model with a `language modeling` head on top.""", ROBERTA_START_DOCSTRING) -class FlaxRobertaForMaskedLM(FlaxRobertaPreTrainedModel): - module_class = FlaxRobertaForMaskedLMModule - - -append_call_sample_docstring( - FlaxRobertaForMaskedLM, - _CHECKPOINT_FOR_DOC, - FlaxBaseModelOutputWithPooling, - _CONFIG_FOR_DOC, - mask="", -) - - -class FlaxRobertaForSequenceClassificationModule(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxRobertaModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.classifier = FlaxRobertaClassificationHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - sequence_output = outputs[0] - logits = self.classifier(sequence_output, deterministic=deterministic) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Roberta Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - ROBERTA_START_DOCSTRING, -) -class FlaxRobertaForSequenceClassification(FlaxRobertaPreTrainedModel): - module_class = FlaxRobertaForSequenceClassificationModule - - -append_call_sample_docstring( - FlaxRobertaForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForMultipleChoiceModule with Bert->Roberta, with self.bert->self.roberta -class FlaxRobertaForMultipleChoiceModule(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxRobertaModule( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.classifier = nn.Dense(1, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - num_choices = input_ids.shape[1] - input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None - attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None - token_type_ids = token_type_ids.reshape(-1, token_type_ids.shape[-1]) if token_type_ids is not None else None - position_ids = position_ids.reshape(-1, position_ids.shape[-1]) if position_ids is not None else None - - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) - - reshaped_logits = logits.reshape(-1, num_choices) - - if not return_dict: - return (reshaped_logits,) + outputs[2:] - - return FlaxMultipleChoiceModelOutput( - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Roberta Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - ROBERTA_START_DOCSTRING, -) -class FlaxRobertaForMultipleChoice(FlaxRobertaPreTrainedModel): - module_class = FlaxRobertaForMultipleChoiceModule - - -overwrite_call_docstring( - FlaxRobertaForMultipleChoice, ROBERTA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") -) -append_call_sample_docstring( - FlaxRobertaForMultipleChoice, - _CHECKPOINT_FOR_DOC, - FlaxMultipleChoiceModelOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForTokenClassificationModule with Bert->Roberta, with self.bert->self.roberta -class FlaxRobertaForTokenClassificationModule(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxRobertaModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - logits = self.classifier(hidden_states) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxTokenClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Roberta Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - ROBERTA_START_DOCSTRING, -) -class FlaxRobertaForTokenClassification(FlaxRobertaPreTrainedModel): - module_class = FlaxRobertaForTokenClassificationModule - - -append_call_sample_docstring( - FlaxRobertaForTokenClassification, - _CHECKPOINT_FOR_DOC, - FlaxTokenClassifierOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForQuestionAnsweringModule with Bert->Roberta, with self.bert->self.roberta -class FlaxRobertaForQuestionAnsweringModule(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxRobertaModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - logits = self.qa_outputs(hidden_states) - start_logits, end_logits = jnp.split(logits, self.config.num_labels, axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - return (start_logits, end_logits) + outputs[1:] - - return FlaxQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - Roberta Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - ROBERTA_START_DOCSTRING, -) -class FlaxRobertaForQuestionAnswering(FlaxRobertaPreTrainedModel): - module_class = FlaxRobertaForQuestionAnsweringModule - - -append_call_sample_docstring( - FlaxRobertaForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxRobertaForCausalLMModule(nn.Module): - config: RobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxRobertaModule( - config=self.config, - add_pooling_layer=False, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.lm_head = FlaxRobertaLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - token_type_ids: Optional[jnp.ndarray] = None, - head_mask: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.roberta.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.lm_head(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxCausalLMOutputWithCrossAttentions( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - """ - Roberta Model with a language modeling head on top (a linear layer on top of the hidden-states output) e.g for - autoregressive tasks. - """, - ROBERTA_START_DOCSTRING, -) -class FlaxRobertaForCausalLM(FlaxRobertaPreTrainedModel): - module_class = FlaxRobertaForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyway. - # Thus, we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxRobertaForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutputWithCrossAttentions, - _CONFIG_FOR_DOC, -) - - -__all__ = [ - "FlaxRobertaForCausalLM", - "FlaxRobertaForMaskedLM", - "FlaxRobertaForMultipleChoice", - "FlaxRobertaForQuestionAnswering", - "FlaxRobertaForSequenceClassification", - "FlaxRobertaForTokenClassification", - "FlaxRobertaModel", - "FlaxRobertaPreTrainedModel", -] diff --git a/src/transformers/models/roberta/modeling_roberta.py b/src/transformers/models/roberta/modeling_roberta.py index 33fb44118a90..2865460718c2 100644 --- a/src/transformers/models/roberta/modeling_roberta.py +++ b/src/transformers/models/roberta/modeling_roberta.py @@ -59,8 +59,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -672,8 +670,6 @@ class RobertaPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/roberta/modeling_tf_roberta.py b/src/transformers/models/roberta/modeling_tf_roberta.py deleted file mode 100644 index c5c56b85d5f3..000000000000 --- a/src/transformers/models/roberta/modeling_tf_roberta.py +++ /dev/null @@ -1,1782 +0,0 @@ -# coding=utf-8 -# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 RoBERTa model.""" - -from __future__ import annotations - -import math -import warnings - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFBaseModelOutputWithPoolingAndCrossAttentions, - TFCausalLMOutputWithCrossAttentions, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_roberta import RobertaConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "FacebookAI/roberta-base" -_CONFIG_FOR_DOC = "RobertaConfig" - - -class TFRobertaEmbeddings(keras.layers.Layer): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.padding_idx = 1 - self.config = config - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - def create_position_ids_from_input_ids(self, input_ids, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding - symbols are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - input_ids: tf.Tensor - Returns: tf.Tensor - """ - mask = tf.cast(tf.math.not_equal(input_ids, self.padding_idx), dtype=input_ids.dtype) - incremental_indices = (tf.math.cumsum(mask, axis=1) + past_key_values_length) * mask - - return incremental_indices + self.padding_idx - - def call( - self, - input_ids=None, - position_ids=None, - token_type_ids=None, - inputs_embeds=None, - past_key_values_length=0, - training=False, - ): - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - if input_ids is not None: - # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = self.create_position_ids_from_input_ids( - input_ids=input_ids, past_key_values_length=past_key_values_length - ) - else: - position_ids = tf.expand_dims( - tf.range(start=self.padding_idx + 1, limit=input_shape[-1] + self.padding_idx + 1), axis=0 - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->Roberta -class TFRobertaPooler(keras.layers.Layer): - def __init__(self, config: RobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention with Bert->Roberta -class TFRobertaSelfAttention(keras.layers.Layer): - def __init__(self, config: RobertaConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - - self.is_decoder = config.is_decoder - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_layer = past_key_value[0] - value_layer = past_key_value[1] - attention_mask = encoder_attention_mask - elif is_cross_attention: - key_layer = self.transpose_for_scores(self.key(inputs=encoder_hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=encoder_hidden_states), batch_size) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_layer, value_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFRobertaModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - if self.is_decoder: - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfOutput with Bert->Roberta -class TFRobertaSelfOutput(keras.layers.Layer): - def __init__(self, config: RobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertAttention with Bert->Roberta -class TFRobertaAttention(keras.layers.Layer): - def __init__(self, config: RobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFRobertaSelfAttention(config, name="self") - self.dense_output = TFRobertaSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - # add attentions (possibly with past_key_value) if we output them - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->Roberta -class TFRobertaIntermediate(keras.layers.Layer): - def __init__(self, config: RobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->Roberta -class TFRobertaOutput(keras.layers.Layer): - def __init__(self, config: RobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLayer with Bert->Roberta -class TFRobertaLayer(keras.layers.Layer): - def __init__(self, config: RobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFRobertaAttention(config, name="attention") - self.is_decoder = config.is_decoder - self.add_cross_attention = config.add_cross_attention - if self.add_cross_attention: - if not self.is_decoder: - raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = TFRobertaAttention(config, name="crossattention") - self.intermediate = TFRobertaIntermediate(config, name="intermediate") - self.bert_output = TFRobertaOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_value: tuple[tf.Tensor] | None, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=self_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - cross_attn_present_key_value = None - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" - " by setting `config.add_cross_attention=True`" - ) - - # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - cross_attention_outputs = self.crossattention( - input_tensor=attention_output, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=cross_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - - # add cross-attn cache to positions 3,4 of present_key_value tuple - cross_attn_present_key_value = cross_attention_outputs[-1] - present_key_value = present_key_value + cross_attn_present_key_value - - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + outputs # add attentions if we output them - - # if decoder, return the attn key/values as the last output - if self.is_decoder: - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertEncoder with Bert->Roberta -class TFRobertaEncoder(keras.layers.Layer): - def __init__(self, config: RobertaConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layer = [TFRobertaLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_values: tuple[tuple[tf.Tensor]] | None, - use_cache: bool | None, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - next_decoder_cache = () if use_cache else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[i], - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - if self.config.add_cross_attention and encoder_hidden_states is not None: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v for v in [hidden_states, all_hidden_states, all_attentions, all_cross_attentions] if v is not None - ) - - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFRobertaMainLayer(keras.layers.Layer): - config_class = RobertaConfig - - def __init__(self, config, add_pooling_layer=True, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.is_decoder = config.is_decoder - - self.num_hidden_layers = config.num_hidden_layers - self.initializer_range = config.initializer_range - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - self.encoder = TFRobertaEncoder(config, name="encoder") - self.pooler = TFRobertaPooler(config, name="pooler") if add_pooling_layer else None - # The embeddings must be the last declaration in order to follow the weights order - self.embeddings = TFRobertaEmbeddings(config, name="embeddings") - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.get_input_embeddings - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.set_input_embeddings - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer._prune_heads - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.call - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - if not self.config.is_decoder: - use_cache = False - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - - if past_key_values is None: - past_key_values_length = 0 - past_key_values = [None] * len(self.encoder.layer) - else: - past_key_values_length = shape_list(past_key_values[0][0])[-2] - - if attention_mask is None: - attention_mask = tf.fill(dims=(batch_size, seq_length + past_key_values_length), value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - - mask_seq_length = seq_length + past_key_values_length - # Copied from `modeling_tf_t5.py` - # Provided a padding mask of dimensions [batch_size, mask_seq_length] - # - if the model is a decoder, apply a causal mask in addition to the padding mask - # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - if self.is_decoder: - seq_ids = tf.range(mask_seq_length) - causal_mask = tf.less_equal( - tf.tile(seq_ids[None, None, :], (batch_size, mask_seq_length, 1)), - seq_ids[None, :, None], - ) - causal_mask = tf.cast(causal_mask, dtype=attention_mask.dtype) - extended_attention_mask = causal_mask * attention_mask[:, None, :] - attention_mask_shape = shape_list(extended_attention_mask) - extended_attention_mask = tf.reshape( - extended_attention_mask, (attention_mask_shape[0], 1, attention_mask_shape[1], attention_mask_shape[2]) - ) - if past_key_values[0] is not None: - # attention_mask needs to be sliced to the shape `[batch_size, 1, from_seq_length - cached_seq_length, to_seq_length] - extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :] - else: - extended_attention_mask = tf.reshape( - attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1]) - ) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Copied from `modeling_tf_t5.py` with -1e9 -> -10000 - if self.is_decoder and encoder_attention_mask is not None: - # If a 2D ou 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=extended_attention_mask.dtype) - num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) - if num_dims_encoder_attention_mask == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if num_dims_encoder_attention_mask == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, - # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) - - encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -10000.0 - else: - encoder_extended_attention_mask = None - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - - -class TFRobertaPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = RobertaConfig - base_model_prefix = "roberta" - - -ROBERTA_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`RobertaConfig`]): Model configuration class with all the parameters of the - model. Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -ROBERTA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare RoBERTa Model transformer outputting raw hidden-states without any specific head on top.", - ROBERTA_START_DOCSTRING, -) -class TFRobertaModel(TFRobertaPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.roberta = TFRobertaMainLayer(config, name="roberta") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPoolingAndCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutputWithPoolingAndCrossAttentions: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - """ - outputs = self.roberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - - -class TFRobertaLMHead(keras.layers.Layer): - """Roberta Head for masked language modeling.""" - - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.act = get_tf_activation("gelu") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.decoder = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - - def get_output_embeddings(self): - return self.decoder - - def set_output_embeddings(self, value): - self.decoder.weight = value - self.decoder.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.layer_norm(hidden_states) - - # project back to size of vocabulary with bias - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.decoder.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -@add_start_docstrings("""RoBERTa Model with a `language modeling` head on top.""", ROBERTA_START_DOCSTRING) -class TFRobertaForMaskedLM(TFRobertaPreTrainedModel, TFMaskedLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head.decoder.weight"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.roberta = TFRobertaMainLayer(config, add_pooling_layer=False, name="roberta") - self.lm_head = TFRobertaLMHead(config, self.roberta.embeddings, name="lm_head") - - def get_lm_head(self): - return self.lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - mask="", - expected_output="' Paris'", - expected_loss=0.1, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - prediction_scores = self.lm_head(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -class TFRobertaForCausalLM(TFRobertaPreTrainedModel, TFCausalLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head.decoder.weight"] - - def __init__(self, config: RobertaConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if not config.is_decoder: - logger.warning("If you want to use `TFRobertaLMHeadModel` as a standalone, add `is_decoder=True.`") - - self.roberta = TFRobertaMainLayer(config, add_pooling_layer=False, name="roberta") - self.lm_head = TFRobertaLMHead(config, input_embeddings=self.roberta.embeddings, name="lm_head") - - def get_lm_head(self): - return self.lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertLMHeadModel.prepare_inputs_for_generation - def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): - input_shape = input_ids.shape - # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly - if attention_mask is None: - attention_mask = tf.ones(input_shape) - - # cut decoder_input_ids if past is used - if past_key_values is not None: - input_ids = input_ids[:, -1:] - - return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutputWithCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFCausalLMOutputWithCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - outputs = self.roberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - logits = self.lm_head(hidden_states=sequence_output, training=training) - loss = None - - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels=labels, logits=shifted_logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithCrossAttentions( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -class TFRobertaClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.out_proj = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="out_proj" - ) - self.config = config - - def call(self, features, training=False): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x, training=training) - x = self.dense(x) - x = self.dropout(x, training=training) - x = self.out_proj(x) - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RoBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - ROBERTA_START_DOCSTRING, -) -class TFRobertaForSequenceClassification(TFRobertaPreTrainedModel, TFSequenceClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta = TFRobertaMainLayer(config, add_pooling_layer=False, name="roberta") - self.classifier = TFRobertaClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="cardiffnlp/twitter-roberta-base-emotion", - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="'optimism'", - expected_loss=0.08, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.classifier(sequence_output, training=training) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - Roberta Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - ROBERTA_START_DOCSTRING, -) -class TFRobertaForMultipleChoice(TFRobertaPreTrainedModel, TFMultipleChoiceLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"lm_head"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.roberta = TFRobertaMainLayer(config, name="roberta") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - outputs = self.roberta( - flat_input_ids, - flat_attention_mask, - flat_token_type_ids, - flat_position_ids, - head_mask, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, training=training) - logits = self.classifier(pooled_output) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RoBERTa Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - ROBERTA_START_DOCSTRING, -) -class TFRobertaForTokenClassification(TFRobertaPreTrainedModel, TFTokenClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta = TFRobertaMainLayer(config, add_pooling_layer=False, name="roberta") - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="ydshieh/roberta-large-ner-english", - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="['O', 'ORG', 'ORG', 'O', 'O', 'O', 'O', 'O', 'LOC', 'O', 'LOC', 'LOC']", - expected_loss=0.01, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RoBERTa Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - ROBERTA_START_DOCSTRING, -) -class TFRobertaForQuestionAnswering(TFRobertaPreTrainedModel, TFQuestionAnsweringLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta = TFRobertaMainLayer(config, add_pooling_layer=False, name="roberta") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="ydshieh/roberta-base-squad2", - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="' puppet'", - expected_loss=0.86, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFRobertaForCausalLM", - "TFRobertaForMaskedLM", - "TFRobertaForMultipleChoice", - "TFRobertaForQuestionAnswering", - "TFRobertaForSequenceClassification", - "TFRobertaForTokenClassification", - "TFRobertaMainLayer", - "TFRobertaModel", - "TFRobertaPreTrainedModel", -] diff --git a/src/transformers/models/roberta_prelayernorm/__init__.py b/src/transformers/models/roberta_prelayernorm/__init__.py index 208878343d24..369698d84ba0 100644 --- a/src/transformers/models/roberta_prelayernorm/__init__.py +++ b/src/transformers/models/roberta_prelayernorm/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_roberta_prelayernorm import * - from .modeling_flax_roberta_prelayernorm import * from .modeling_roberta_prelayernorm import * - from .modeling_tf_roberta_prelayernorm import * else: import sys diff --git a/src/transformers/models/roberta_prelayernorm/modeling_flax_roberta_prelayernorm.py b/src/transformers/models/roberta_prelayernorm/modeling_flax_roberta_prelayernorm.py deleted file mode 100644 index f65dc07bb165..000000000000 --- a/src/transformers/models/roberta_prelayernorm/modeling_flax_roberta_prelayernorm.py +++ /dev/null @@ -1,1527 +0,0 @@ -# coding=utf-8 -# Copyright 2022 The Google Flax Team Authors and 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. -"""Flax RoBERTa-PreLayerNorm model.""" - -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen import partitioning as nn_partitioning -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxBaseModelOutputWithPooling, - FlaxBaseModelOutputWithPoolingAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxMaskedLMOutput, - FlaxMultipleChoiceModelOutput, - FlaxQuestionAnsweringModelOutput, - FlaxSequenceClassifierOutput, - FlaxTokenClassifierOutput, -) -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring, overwrite_call_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_roberta_prelayernorm import RobertaPreLayerNormConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "andreasmadsen/efficient_mlm_m0.40" -_CONFIG_FOR_DOC = "RobertaPreLayerNormConfig" - -remat = nn_partitioning.remat - - -# Copied from transformers.models.roberta.modeling_flax_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - input_ids: jnp.ndarray - padding_idx: int - - Returns: jnp.ndarray - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = (input_ids != padding_idx).astype("i4") - - if mask.ndim > 2: - mask = mask.reshape((-1, mask.shape[-1])) - incremental_indices = jnp.cumsum(mask, axis=1).astype("i4") * mask - incremental_indices = incremental_indices.reshape(input_ids.shape) - else: - incremental_indices = jnp.cumsum(mask, axis=1).astype("i4") * mask - - return incremental_indices.astype("i4") + padding_idx - - -ROBERTA_PRELAYERNORM_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`RobertaPreLayerNormConfig`]): Model configuration class with all the parameters of the - model. Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - head_mask (`numpy.ndarray` of shape `({0})`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEmbeddings with Bert->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormEmbeddings(nn.Module): - """Construct the embeddings from word, position and token_type embeddings.""" - - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.word_embeddings = nn.Embed( - self.config.vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.position_embeddings = nn.Embed( - self.config.max_position_embeddings, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.token_type_embeddings = nn.Embed( - self.config.type_vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, input_ids, token_type_ids, position_ids, attention_mask, deterministic: bool = True): - # Embed - inputs_embeds = self.word_embeddings(input_ids.astype("i4")) - position_embeds = self.position_embeddings(position_ids.astype("i4")) - token_type_embeddings = self.token_type_embeddings(token_type_ids.astype("i4")) - - # Sum all embeddings - hidden_states = inputs_embeds + token_type_embeddings + position_embeds - - # Layer Norm - hidden_states = self.LayerNorm(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfAttention with Bert->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormSelfAttention(nn.Module): - config: RobertaPreLayerNormConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.head_dim = self.config.hidden_size // self.config.num_attention_heads - if self.config.hidden_size % self.config.num_attention_heads != 0: - raise ValueError( - "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads` " - " : {self.config.num_attention_heads}" - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.num_attention_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.hidden_size,)) - - @nn.compact - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention._concatenate_to_cache - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic=True, - output_attentions: bool = False, - ): - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.query(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.key(key_value_states) - value_states = self.value(key_value_states) - else: - # self_attention - key_states = self.key(hidden_states) - value_states = self.value(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - # Mask heads if we want to - if layer_head_mask is not None: - attn_weights = jnp.einsum("...hqk,h->...hqk", attn_weights, layer_head_mask) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxRobertaPreLayerNormSelfOutput(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, input_tensor, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = hidden_states + input_tensor - return hidden_states - - -class FlaxRobertaPreLayerNormAttention(nn.Module): - config: RobertaPreLayerNormConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.self = FlaxRobertaPreLayerNormSelfAttention(self.config, causal=self.causal, dtype=self.dtype) - self.output = FlaxRobertaPreLayerNormSelfOutput(self.config, dtype=self.dtype) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states=None, - init_cache=False, - deterministic=True, - output_attentions: bool = False, - ): - hidden_states_pre_layer_norm = self.LayerNorm(hidden_states) - # Attention mask comes in as attention_mask.shape == (*batch_sizes, kv_length) - # FLAX expects: attention_mask.shape == (*batch_sizes, 1, 1, kv_length) such that it is broadcastable - # with attn_weights.shape == (*batch_sizes, num_heads, q_length, kv_length) - attn_outputs = self.self( - hidden_states_pre_layer_norm, - attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=key_value_states, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attn_output = attn_outputs[0] - hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_outputs[1],) - - return outputs - - -class FlaxRobertaPreLayerNormIntermediate(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dense = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_states): - hidden_states = self.LayerNorm(hidden_states) - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - -class FlaxRobertaPreLayerNormOutput(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, attention_output, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = hidden_states + attention_output - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayer with Bert->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormLayer(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.attention = FlaxRobertaPreLayerNormAttention(self.config, causal=self.config.is_decoder, dtype=self.dtype) - self.intermediate = FlaxRobertaPreLayerNormIntermediate(self.config, dtype=self.dtype) - self.output = FlaxRobertaPreLayerNormOutput(self.config, dtype=self.dtype) - if self.config.add_cross_attention: - self.crossattention = FlaxRobertaPreLayerNormAttention(self.config, causal=False, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - ): - # Self Attention - attention_outputs = self.attention( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = attention_outputs[0] - - # Cross-Attention Block - if encoder_hidden_states is not None: - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=encoder_hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = cross_attention_outputs[0] - - hidden_states = self.intermediate(attention_output) - hidden_states = self.output(hidden_states, attention_output, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attention_outputs[1],) - if encoder_hidden_states is not None: - outputs += (cross_attention_outputs[1],) - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayerCollection with Bert->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormLayerCollection(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - if self.gradient_checkpointing: - FlaxRobertaPreLayerNormCheckpointLayer = remat(FlaxRobertaPreLayerNormLayer, static_argnums=(5, 6, 7)) - self.layers = [ - FlaxRobertaPreLayerNormCheckpointLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - else: - self.layers = [ - FlaxRobertaPreLayerNormLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - # Check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - if head_mask.shape[0] != (len(self.layers)): - raise ValueError( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for " - f" {head_mask.shape[0]}." - ) - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer( - hidden_states, - attention_mask, - head_mask[i] if head_mask is not None else None, - encoder_hidden_states, - encoder_attention_mask, - init_cache, - deterministic, - output_attentions, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions, all_cross_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEncoder with Bert->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormEncoder(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.layer = FlaxRobertaPreLayerNormLayerCollection( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.layer( - hidden_states, - attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPooler with Bert->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormPooler(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - - def __call__(self, hidden_states): - cls_hidden_state = hidden_states[:, 0] - cls_hidden_state = self.dense(cls_hidden_state) - return nn.tanh(cls_hidden_state) - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaLMHead with Roberta->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormLMHead(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.decoder = nn.Dense( - self.config.vocab_size, - dtype=self.dtype, - use_bias=False, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) - - def __call__(self, hidden_states, shared_embedding=None): - hidden_states = self.dense(hidden_states) - hidden_states = ACT2FN["gelu"](hidden_states) - hidden_states = self.layer_norm(hidden_states) - - if shared_embedding is not None: - hidden_states = self.decoder.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - hidden_states = self.decoder(hidden_states) - - bias = jnp.asarray(self.bias, self.dtype) - hidden_states += bias - return hidden_states - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaClassificationHead with Roberta->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormClassificationHead(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.out_proj = nn.Dense( - self.config.num_labels, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - def __call__(self, hidden_states, deterministic=True): - hidden_states = hidden_states[:, 0, :] # take token (equiv. to [CLS]) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.dense(hidden_states) - hidden_states = nn.tanh(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.out_proj(hidden_states) - return hidden_states - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaPreTrainedModel with ROBERTA->ROBERTA_PRELAYERNORM,Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm -class FlaxRobertaPreLayerNormPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = RobertaPreLayerNormConfig - base_model_prefix = "roberta_prelayernorm" - - module_class: nn.Module = None - - def __init__( - self, - config: RobertaPreLayerNormConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - gradient_checkpointing: bool = False, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, gradient_checkpointing=gradient_checkpointing, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPreTrainedModel.enable_gradient_checkpointing - def enable_gradient_checkpointing(self): - self._module = self.module_class( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=True, - ) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - token_type_ids = jnp.ones_like(input_ids) - position_ids = create_position_ids_from_input_ids(input_ids, self.config.pad_token_id) - attention_mask = jnp.ones_like(input_ids) - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - if self.config.add_cross_attention: - encoder_hidden_states = jnp.zeros(input_shape + (self.config.hidden_size,)) - encoder_attention_mask = attention_mask - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - return_dict=False, - ) - else: - module_init_outputs = self.module.init( - rngs, input_ids, attention_mask, token_type_ids, position_ids, head_mask, return_dict=False - ) - - random_params = module_init_outputs["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderPreTrainedModel.init_cache - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length), dtype="i4") - attention_mask = jnp.ones_like(input_ids, dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - past_key_values: Optional[dict] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # init input tensors if not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - if position_ids is None: - position_ids = create_position_ids_from_input_ids(input_ids, self.config.pad_token_id) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - if head_mask is None: - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - if self.config.add_cross_attention: - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed - # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be - # changed by FlaxRobertaPreLayerNormAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - else: - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - ) - - return outputs - - -class FlaxRobertaPreLayerNormModule(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - add_pooling_layer: bool = True - gradient_checkpointing: bool = False - - def setup(self): - self.embeddings = FlaxRobertaPreLayerNormEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxRobertaPreLayerNormEncoder( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.pooler = FlaxRobertaPreLayerNormPooler(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - head_mask: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # make sure `token_type_ids` is correctly initialized when not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - # make sure `position_ids` is correctly initialized when not passed - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - hidden_states = self.embeddings( - input_ids, token_type_ids, position_ids, attention_mask, deterministic=deterministic - ) - outputs = self.encoder( - hidden_states, - attention_mask, - head_mask=head_mask, - deterministic=deterministic, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - hidden_states = self.LayerNorm(hidden_states) - pooled = self.pooler(hidden_states) if self.add_pooling_layer else None - - if not return_dict: - # if pooled is None, don't return it - if pooled is None: - return (hidden_states,) + outputs[1:] - return (hidden_states, pooled) + outputs[1:] - - return FlaxBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=hidden_states, - pooler_output=pooled, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - "The bare RoBERTa-PreLayerNorm Model transformer outputting raw hidden-states without any specific head on top.", - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaModel with Roberta->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormModel(FlaxRobertaPreLayerNormPreTrainedModel): - module_class = FlaxRobertaPreLayerNormModule - - -append_call_sample_docstring( - FlaxRobertaPreLayerNormModel, - _CHECKPOINT_FOR_DOC, - FlaxBaseModelOutputWithPooling, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForMaskedLMModule with Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm -class FlaxRobertaPreLayerNormForMaskedLMModule(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta_prelayernorm = FlaxRobertaPreLayerNormModule( - config=self.config, - add_pooling_layer=False, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.lm_head = FlaxRobertaPreLayerNormLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta_prelayernorm( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.roberta_prelayernorm.variables["params"]["embeddings"]["word_embeddings"][ - "embedding" - ] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.lm_head(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxMaskedLMOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """RoBERTa-PreLayerNorm Model with a `language modeling` head on top.""", ROBERTA_PRELAYERNORM_START_DOCSTRING -) -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForMaskedLM with Roberta->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormForMaskedLM(FlaxRobertaPreLayerNormPreTrainedModel): - module_class = FlaxRobertaPreLayerNormForMaskedLMModule - - -append_call_sample_docstring( - FlaxRobertaPreLayerNormForMaskedLM, - _CHECKPOINT_FOR_DOC, - FlaxBaseModelOutputWithPooling, - _CONFIG_FOR_DOC, - mask="", -) - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForSequenceClassificationModule with Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm -class FlaxRobertaPreLayerNormForSequenceClassificationModule(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta_prelayernorm = FlaxRobertaPreLayerNormModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.classifier = FlaxRobertaPreLayerNormClassificationHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta_prelayernorm( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - sequence_output = outputs[0] - logits = self.classifier(sequence_output, deterministic=deterministic) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - RobertaPreLayerNorm Model transformer with a sequence classification/regression head on top (a linear layer on top - of the pooled output) e.g. for GLUE tasks. - """, - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForSequenceClassification with Roberta->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormForSequenceClassification(FlaxRobertaPreLayerNormPreTrainedModel): - module_class = FlaxRobertaPreLayerNormForSequenceClassificationModule - - -append_call_sample_docstring( - FlaxRobertaPreLayerNormForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForMultipleChoiceModule with Bert->RobertaPreLayerNorm, with self.bert->self.roberta_prelayernorm -class FlaxRobertaPreLayerNormForMultipleChoiceModule(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta_prelayernorm = FlaxRobertaPreLayerNormModule( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.classifier = nn.Dense(1, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - num_choices = input_ids.shape[1] - input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None - attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None - token_type_ids = token_type_ids.reshape(-1, token_type_ids.shape[-1]) if token_type_ids is not None else None - position_ids = position_ids.reshape(-1, position_ids.shape[-1]) if position_ids is not None else None - - # Model - outputs = self.roberta_prelayernorm( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) - - reshaped_logits = logits.reshape(-1, num_choices) - - if not return_dict: - return (reshaped_logits,) + outputs[2:] - - return FlaxMultipleChoiceModelOutput( - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - RobertaPreLayerNorm Model with a multiple choice classification head on top (a linear layer on top of the pooled - output and a softmax) e.g. for RocStories/SWAG tasks. - """, - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForMultipleChoice with Roberta->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormForMultipleChoice(FlaxRobertaPreLayerNormPreTrainedModel): - module_class = FlaxRobertaPreLayerNormForMultipleChoiceModule - - -overwrite_call_docstring( - FlaxRobertaPreLayerNormForMultipleChoice, - ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length"), -) -append_call_sample_docstring( - FlaxRobertaPreLayerNormForMultipleChoice, - _CHECKPOINT_FOR_DOC, - FlaxMultipleChoiceModelOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForTokenClassificationModule with Bert->RobertaPreLayerNorm, with self.bert->self.roberta_prelayernorm -class FlaxRobertaPreLayerNormForTokenClassificationModule(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta_prelayernorm = FlaxRobertaPreLayerNormModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta_prelayernorm( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - logits = self.classifier(hidden_states) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxTokenClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - RobertaPreLayerNorm Model with a token classification head on top (a linear layer on top of the hidden-states - output) e.g. for Named-Entity-Recognition (NER) tasks. - """, - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForTokenClassification with Roberta->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormForTokenClassification(FlaxRobertaPreLayerNormPreTrainedModel): - module_class = FlaxRobertaPreLayerNormForTokenClassificationModule - - -append_call_sample_docstring( - FlaxRobertaPreLayerNormForTokenClassification, - _CHECKPOINT_FOR_DOC, - FlaxTokenClassifierOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForQuestionAnsweringModule with Bert->RobertaPreLayerNorm, with self.bert->self.roberta_prelayernorm -class FlaxRobertaPreLayerNormForQuestionAnsweringModule(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta_prelayernorm = FlaxRobertaPreLayerNormModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta_prelayernorm( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - logits = self.qa_outputs(hidden_states) - start_logits, end_logits = jnp.split(logits, self.config.num_labels, axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - return (start_logits, end_logits) + outputs[1:] - - return FlaxQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - RobertaPreLayerNorm Model with a span classification head on top for extractive question-answering tasks like SQuAD - (a linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForQuestionAnswering with Roberta->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormForQuestionAnswering(FlaxRobertaPreLayerNormPreTrainedModel): - module_class = FlaxRobertaPreLayerNormForQuestionAnsweringModule - - -append_call_sample_docstring( - FlaxRobertaPreLayerNormForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForCausalLMModule with Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm -class FlaxRobertaPreLayerNormForCausalLMModule(nn.Module): - config: RobertaPreLayerNormConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta_prelayernorm = FlaxRobertaPreLayerNormModule( - config=self.config, - add_pooling_layer=False, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.lm_head = FlaxRobertaPreLayerNormLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - token_type_ids: Optional[jnp.ndarray] = None, - head_mask: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta_prelayernorm( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.roberta_prelayernorm.variables["params"]["embeddings"]["word_embeddings"][ - "embedding" - ] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.lm_head(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxCausalLMOutputWithCrossAttentions( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - """ - RobertaPreLayerNorm Model with a language modeling head on top (a linear layer on top of the hidden-states output) - e.g for autoregressive tasks. - """, - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForCausalLM with Roberta->RobertaPreLayerNorm -class FlaxRobertaPreLayerNormForCausalLM(FlaxRobertaPreLayerNormPreTrainedModel): - module_class = FlaxRobertaPreLayerNormForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyway. - # Thus, we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxRobertaPreLayerNormForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutputWithCrossAttentions, - _CONFIG_FOR_DOC, -) - - -__all__ = [ - "FlaxRobertaPreLayerNormForCausalLM", - "FlaxRobertaPreLayerNormForMaskedLM", - "FlaxRobertaPreLayerNormForMultipleChoice", - "FlaxRobertaPreLayerNormForQuestionAnswering", - "FlaxRobertaPreLayerNormForSequenceClassification", - "FlaxRobertaPreLayerNormForTokenClassification", - "FlaxRobertaPreLayerNormModel", - "FlaxRobertaPreLayerNormPreTrainedModel", -] diff --git a/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py b/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py index 81481574b01e..5247c39b7553 100644 --- a/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py +++ b/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py @@ -59,8 +59,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -561,8 +559,6 @@ class RobertaPreLayerNormPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/roberta_prelayernorm/modeling_tf_roberta_prelayernorm.py b/src/transformers/models/roberta_prelayernorm/modeling_tf_roberta_prelayernorm.py deleted file mode 100644 index 0a370f390269..000000000000 --- a/src/transformers/models/roberta_prelayernorm/modeling_tf_roberta_prelayernorm.py +++ /dev/null @@ -1,1807 +0,0 @@ -# coding=utf-8 -# Copyright 2022 The Google AI Language Team Authors and The HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 RoBERTa-PreLayerNorm model.""" - -from __future__ import annotations - -import math -import warnings - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFBaseModelOutputWithPoolingAndCrossAttentions, - TFCausalLMOutputWithCrossAttentions, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_roberta_prelayernorm import RobertaPreLayerNormConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "andreasmadsen/efficient_mlm_m0.40" -_CONFIG_FOR_DOC = "RobertaPreLayerNormConfig" - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaEmbeddings with Roberta->RobertaPreLayerNorm -class TFRobertaPreLayerNormEmbeddings(keras.layers.Layer): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.padding_idx = 1 - self.config = config - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - def create_position_ids_from_input_ids(self, input_ids, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding - symbols are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - input_ids: tf.Tensor - Returns: tf.Tensor - """ - mask = tf.cast(tf.math.not_equal(input_ids, self.padding_idx), dtype=input_ids.dtype) - incremental_indices = (tf.math.cumsum(mask, axis=1) + past_key_values_length) * mask - - return incremental_indices + self.padding_idx - - def call( - self, - input_ids=None, - position_ids=None, - token_type_ids=None, - inputs_embeds=None, - past_key_values_length=0, - training=False, - ): - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - if input_ids is not None: - # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = self.create_position_ids_from_input_ids( - input_ids=input_ids, past_key_values_length=past_key_values_length - ) - else: - position_ids = tf.expand_dims( - tf.range(start=self.padding_idx + 1, limit=input_shape[-1] + self.padding_idx + 1), axis=0 - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->RobertaPreLayerNorm -class TFRobertaPreLayerNormPooler(keras.layers.Layer): - def __init__(self, config: RobertaPreLayerNormConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention with Bert->RobertaPreLayerNorm -class TFRobertaPreLayerNormSelfAttention(keras.layers.Layer): - def __init__(self, config: RobertaPreLayerNormConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - - self.is_decoder = config.is_decoder - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_layer = past_key_value[0] - value_layer = past_key_value[1] - attention_mask = encoder_attention_mask - elif is_cross_attention: - key_layer = self.transpose_for_scores(self.key(inputs=encoder_hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=encoder_hidden_states), batch_size) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_layer, value_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFRobertaPreLayerNormModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - if self.is_decoder: - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -class TFRobertaPreLayerNormSelfOutput(keras.layers.Layer): - def __init__(self, config: RobertaPreLayerNormConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = hidden_states + input_tensor - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFRobertaPreLayerNormAttention(keras.layers.Layer): - def __init__(self, config: RobertaPreLayerNormConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFRobertaPreLayerNormSelfAttention(config, name="self") - self.dense_output = TFRobertaPreLayerNormSelfOutput(config, name="output") - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertAttention.prune_heads - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - hidden_states_pre_layer_norm = self.LayerNorm(inputs=input_tensor) - self_outputs = self.self_attention( - hidden_states=hidden_states_pre_layer_norm, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - # add attentions (possibly with past_key_value) if we output them - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFRobertaPreLayerNormIntermediate(keras.layers.Layer): - def __init__(self, config: RobertaPreLayerNormConfig, **kwargs): - super().__init__(**kwargs) - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.LayerNorm(inputs=hidden_states) - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFRobertaPreLayerNormOutput(keras.layers.Layer): - def __init__(self, config: RobertaPreLayerNormConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = hidden_states + input_tensor - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLayer with Bert->RobertaPreLayerNorm -class TFRobertaPreLayerNormLayer(keras.layers.Layer): - def __init__(self, config: RobertaPreLayerNormConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFRobertaPreLayerNormAttention(config, name="attention") - self.is_decoder = config.is_decoder - self.add_cross_attention = config.add_cross_attention - if self.add_cross_attention: - if not self.is_decoder: - raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = TFRobertaPreLayerNormAttention(config, name="crossattention") - self.intermediate = TFRobertaPreLayerNormIntermediate(config, name="intermediate") - self.bert_output = TFRobertaPreLayerNormOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_value: tuple[tf.Tensor] | None, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=self_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - cross_attn_present_key_value = None - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" - " by setting `config.add_cross_attention=True`" - ) - - # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - cross_attention_outputs = self.crossattention( - input_tensor=attention_output, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=cross_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - - # add cross-attn cache to positions 3,4 of present_key_value tuple - cross_attn_present_key_value = cross_attention_outputs[-1] - present_key_value = present_key_value + cross_attn_present_key_value - - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + outputs # add attentions if we output them - - # if decoder, return the attn key/values as the last output - if self.is_decoder: - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertEncoder with Bert->RobertaPreLayerNorm -class TFRobertaPreLayerNormEncoder(keras.layers.Layer): - def __init__(self, config: RobertaPreLayerNormConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layer = [TFRobertaPreLayerNormLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_values: tuple[tuple[tf.Tensor]] | None, - use_cache: bool | None, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - next_decoder_cache = () if use_cache else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[i], - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - if self.config.add_cross_attention and encoder_hidden_states is not None: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v for v in [hidden_states, all_hidden_states, all_attentions, all_cross_attentions] if v is not None - ) - - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFRobertaPreLayerNormMainLayer(keras.layers.Layer): - config_class = RobertaPreLayerNormConfig - - def __init__(self, config, add_pooling_layer=True, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.is_decoder = config.is_decoder - - self.num_hidden_layers = config.num_hidden_layers - self.initializer_range = config.initializer_range - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - self.encoder = TFRobertaPreLayerNormEncoder(config, name="encoder") - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.pooler = TFRobertaPreLayerNormPooler(config, name="pooler") if add_pooling_layer else None - # The embeddings must be the last declaration in order to follow the weights order - self.embeddings = TFRobertaPreLayerNormEmbeddings(config, name="embeddings") - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - if not self.config.is_decoder: - use_cache = False - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - - if past_key_values is None: - past_key_values_length = 0 - past_key_values = [None] * len(self.encoder.layer) - else: - past_key_values_length = shape_list(past_key_values[0][0])[-2] - - if attention_mask is None: - attention_mask = tf.fill(dims=(batch_size, seq_length + past_key_values_length), value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - - mask_seq_length = seq_length + past_key_values_length - # Provided a padding mask of dimensions [batch_size, mask_seq_length] - # - if the model is a decoder, apply a causal mask in addition to the padding mask - # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - if self.is_decoder: - seq_ids = tf.range(mask_seq_length) - causal_mask = tf.less_equal( - tf.tile(seq_ids[None, None, :], (batch_size, mask_seq_length, 1)), - seq_ids[None, :, None], - ) - causal_mask = tf.cast(causal_mask, dtype=attention_mask.dtype) - extended_attention_mask = causal_mask * attention_mask[:, None, :] - attention_mask_shape = shape_list(extended_attention_mask) - extended_attention_mask = tf.reshape( - extended_attention_mask, (attention_mask_shape[0], 1, attention_mask_shape[1], attention_mask_shape[2]) - ) - if past_key_values[0] is not None: - # attention_mask needs to be sliced to the shape `[batch_size, 1, from_seq_length - cached_seq_length, to_seq_length] - extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :] - else: - extended_attention_mask = tf.reshape( - attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1]) - ) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - if self.is_decoder and encoder_attention_mask is not None: - # If a 2D ou 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=extended_attention_mask.dtype) - num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) - if num_dims_encoder_attention_mask == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if num_dims_encoder_attention_mask == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, - # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) - - encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -10000.0 - else: - encoder_extended_attention_mask = None - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - sequence_output = self.LayerNorm(inputs=sequence_output) - pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaPreTrainedModel with Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm -class TFRobertaPreLayerNormPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = RobertaPreLayerNormConfig - base_model_prefix = "roberta_prelayernorm" - - -ROBERTA_PRELAYERNORM_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`RobertaPreLayerNormConfig`]): Model configuration class with all the parameters of the - model. Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare RoBERTa-PreLayerNorm Model transformer outputting raw hidden-states without any specific head on top.", - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaModel with ROBERTA->ROBERTA_PRELAYERNORM,Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm -class TFRobertaPreLayerNormModel(TFRobertaPreLayerNormPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.roberta_prelayernorm = TFRobertaPreLayerNormMainLayer(config, name="roberta_prelayernorm") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPoolingAndCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutputWithPoolingAndCrossAttentions: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - """ - outputs = self.roberta_prelayernorm( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta_prelayernorm", None) is not None: - with tf.name_scope(self.roberta_prelayernorm.name): - self.roberta_prelayernorm.build(None) - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaLMHead with Roberta->RobertaPreLayerNorm -class TFRobertaPreLayerNormLMHead(keras.layers.Layer): - """RobertaPreLayerNorm Head for masked language modeling.""" - - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.act = get_tf_activation("gelu") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.decoder = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - - def get_output_embeddings(self): - return self.decoder - - def set_output_embeddings(self, value): - self.decoder.weight = value - self.decoder.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.layer_norm(hidden_states) - - # project back to size of vocabulary with bias - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.decoder.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -@add_start_docstrings( - """RoBERTa-PreLayerNorm Model with a `language modeling` head on top.""", ROBERTA_PRELAYERNORM_START_DOCSTRING -) -class TFRobertaPreLayerNormForMaskedLM(TFRobertaPreLayerNormPreTrainedModel, TFMaskedLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head.decoder.weight"] - - # Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForMaskedLM.__init__ with ROBERTA->ROBERTA_PRELAYERNORM,Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.roberta_prelayernorm = TFRobertaPreLayerNormMainLayer( - config, add_pooling_layer=False, name="roberta_prelayernorm" - ) - self.lm_head = TFRobertaPreLayerNormLMHead(config, self.roberta_prelayernorm.embeddings, name="lm_head") - - def get_lm_head(self): - return self.lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - mask="", - expected_output="' Paris'", - expected_loss=0.69, - ) - # Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForMaskedLM.call with ROBERTA->ROBERTA_PRELAYERNORM,Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.roberta_prelayernorm( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - prediction_scores = self.lm_head(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta_prelayernorm", None) is not None: - with tf.name_scope(self.roberta_prelayernorm.name): - self.roberta_prelayernorm.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForCausalLM with ROBERTA->ROBERTA_PRELAYERNORM,Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm -class TFRobertaPreLayerNormForCausalLM(TFRobertaPreLayerNormPreTrainedModel, TFCausalLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head.decoder.weight"] - - def __init__(self, config: RobertaPreLayerNormConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if not config.is_decoder: - logger.warning( - "If you want to use `TFRobertaPreLayerNormLMHeadModel` as a standalone, add `is_decoder=True.`" - ) - - self.roberta_prelayernorm = TFRobertaPreLayerNormMainLayer( - config, add_pooling_layer=False, name="roberta_prelayernorm" - ) - self.lm_head = TFRobertaPreLayerNormLMHead( - config, input_embeddings=self.roberta_prelayernorm.embeddings, name="lm_head" - ) - - def get_lm_head(self): - return self.lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertLMHeadModel.prepare_inputs_for_generation - def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): - input_shape = input_ids.shape - # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly - if attention_mask is None: - attention_mask = tf.ones(input_shape) - - # cut decoder_input_ids if past is used - if past_key_values is not None: - input_ids = input_ids[:, -1:] - - return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutputWithCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFCausalLMOutputWithCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - outputs = self.roberta_prelayernorm( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - logits = self.lm_head(hidden_states=sequence_output, training=training) - loss = None - - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels=labels, logits=shifted_logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithCrossAttentions( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta_prelayernorm", None) is not None: - with tf.name_scope(self.roberta_prelayernorm.name): - self.roberta_prelayernorm.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaClassificationHead with Roberta->RobertaPreLayerNorm -class TFRobertaPreLayerNormClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.out_proj = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="out_proj" - ) - self.config = config - - def call(self, features, training=False): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x, training=training) - x = self.dense(x) - x = self.dropout(x, training=training) - x = self.out_proj(x) - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RoBERTa-PreLayerNorm Model transformer with a sequence classification/regression head on top (a linear layer on top - of the pooled output) e.g. for GLUE tasks. - """, - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -class TFRobertaPreLayerNormForSequenceClassification( - TFRobertaPreLayerNormPreTrainedModel, TFSequenceClassificationLoss -): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta_prelayernorm = TFRobertaPreLayerNormMainLayer( - config, add_pooling_layer=False, name="roberta_prelayernorm" - ) - self.classifier = TFRobertaPreLayerNormClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - # Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForSequenceClassification.call with roberta->roberta_prelayernorm - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.roberta_prelayernorm( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.classifier(sequence_output, training=training) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta_prelayernorm", None) is not None: - with tf.name_scope(self.roberta_prelayernorm.name): - self.roberta_prelayernorm.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - RobertaPreLayerNorm Model with a multiple choice classification head on top (a linear layer on top of the pooled - output and a softmax) e.g. for RocStories/SWAG tasks. - """, - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForMultipleChoice with ROBERTA->ROBERTA_PRELAYERNORM,Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm -class TFRobertaPreLayerNormForMultipleChoice(TFRobertaPreLayerNormPreTrainedModel, TFMultipleChoiceLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"lm_head"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.roberta_prelayernorm = TFRobertaPreLayerNormMainLayer(config, name="roberta_prelayernorm") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward( - ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") - ) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - outputs = self.roberta_prelayernorm( - flat_input_ids, - flat_attention_mask, - flat_token_type_ids, - flat_position_ids, - head_mask, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, training=training) - logits = self.classifier(pooled_output) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta_prelayernorm", None) is not None: - with tf.name_scope(self.roberta_prelayernorm.name): - self.roberta_prelayernorm.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RoBERTa-PreLayerNorm Model with a token classification head on top (a linear layer on top of the hidden-states - output) e.g. for Named-Entity-Recognition (NER) tasks. - """, - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -class TFRobertaPreLayerNormForTokenClassification(TFRobertaPreLayerNormPreTrainedModel, TFTokenClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta_prelayernorm = TFRobertaPreLayerNormMainLayer( - config, add_pooling_layer=False, name="roberta_prelayernorm" - ) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - # Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForTokenClassification.call with roberta->roberta_prelayernorm - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.roberta_prelayernorm( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta_prelayernorm", None) is not None: - with tf.name_scope(self.roberta_prelayernorm.name): - self.roberta_prelayernorm.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RoBERTa-PreLayerNorm Model with a span classification head on top for extractive question-answering tasks like - SQuAD (a linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - ROBERTA_PRELAYERNORM_START_DOCSTRING, -) -class TFRobertaPreLayerNormForQuestionAnswering(TFRobertaPreLayerNormPreTrainedModel, TFQuestionAnsweringLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta_prelayernorm = TFRobertaPreLayerNormMainLayer( - config, add_pooling_layer=False, name="roberta_prelayernorm" - ) - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROBERTA_PRELAYERNORM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - # Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForQuestionAnswering.call with roberta->roberta_prelayernorm - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.roberta_prelayernorm( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta_prelayernorm", None) is not None: - with tf.name_scope(self.roberta_prelayernorm.name): - self.roberta_prelayernorm.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFRobertaPreLayerNormForCausalLM", - "TFRobertaPreLayerNormForMaskedLM", - "TFRobertaPreLayerNormForMultipleChoice", - "TFRobertaPreLayerNormForQuestionAnswering", - "TFRobertaPreLayerNormForSequenceClassification", - "TFRobertaPreLayerNormForTokenClassification", - "TFRobertaPreLayerNormMainLayer", - "TFRobertaPreLayerNormModel", - "TFRobertaPreLayerNormPreTrainedModel", -] diff --git a/src/transformers/models/roc_bert/modeling_roc_bert.py b/src/transformers/models/roc_bert/modeling_roc_bert.py index 22a72f91bc38..0b91af94bbaa 100644 --- a/src/transformers/models/roc_bert/modeling_roc_bert.py +++ b/src/transformers/models/roc_bert/modeling_roc_bert.py @@ -15,7 +15,6 @@ """PyTorch RoCBert model.""" import math -import os from typing import Optional, Union import torch @@ -46,80 +45,6 @@ logger = logging.get_logger(__name__) -# Copied from transformers.models.bert.modeling_bert.load_tf_weights_in_bert with bert->roc_bert -def load_tf_weights_in_roc_bert(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except ValueError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class RoCBertEmbeddings(nn.Module): """Construct the embeddings from word, position, shape, pronunciation and token_type embeddings.""" @@ -150,8 +75,6 @@ def __init__(self, config): else: self.map_inputs_layer = None - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -725,15 +648,12 @@ def forward(self, sequence_output: torch.Tensor) -> torch.Tensor: @auto_docstring class RoCBertPreTrainedModel(PreTrainedModel): config: RoCBertConfig - load_tf_weights = load_tf_weights_in_roc_bert base_model_prefix = "roc_bert" supports_gradient_checkpointing = True def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1929,5 +1849,4 @@ def forward( "RoCBertLayer", "RoCBertModel", "RoCBertPreTrainedModel", - "load_tf_weights_in_roc_bert", ] diff --git a/src/transformers/models/roformer/__init__.py b/src/transformers/models/roformer/__init__.py index 63c1c00e5723..4d1232523f8c 100644 --- a/src/transformers/models/roformer/__init__.py +++ b/src/transformers/models/roformer/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_roformer import * - from .modeling_flax_roformer import * from .modeling_roformer import * - from .modeling_tf_roformer import * from .tokenization_roformer import * from .tokenization_roformer_fast import * else: diff --git a/src/transformers/models/roformer/convert_roformer_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/roformer/convert_roformer_original_tf_checkpoint_to_pytorch.py index d227948e0ee3..f68152643da8 100755 --- a/src/transformers/models/roformer/convert_roformer_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/roformer/convert_roformer_original_tf_checkpoint_to_pytorch.py @@ -15,16 +15,91 @@ """Convert RoFormer checkpoint.""" import argparse +import os import torch -from transformers import RoFormerConfig, RoFormerForMaskedLM, load_tf_weights_in_roformer +from transformers import RoFormerConfig, RoFormerForMaskedLM from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +def load_tf_weights_in_roformer(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name.replace("bert", "roformer")) + arrays.append(array) + + for name, array in zip(names, arrays): + name = name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any( + n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + continue + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "kernel" or scope_names[0] == "gamma": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + else: + try: + pointer = getattr(pointer, scope_names[0]) + except AttributeError: + logger.info(f"Skipping {'/'.join(name)}") + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if m_name[-11:] == "_embeddings": + pointer = getattr(pointer, "weight") + elif m_name == "kernel": + array = np.transpose(array) + try: + if not pointer.shape == array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + return model + + def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, bert_config_file, pytorch_dump_path): # Initialise PyTorch model config = RoFormerConfig.from_json_file(bert_config_file) diff --git a/src/transformers/models/roformer/modeling_flax_roformer.py b/src/transformers/models/roformer/modeling_flax_roformer.py deleted file mode 100644 index de78eb4787c0..000000000000 --- a/src/transformers/models/roformer/modeling_flax_roformer.py +++ /dev/null @@ -1,1091 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax RoFormer model.""" - -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxMaskedLMOutput, - FlaxMultipleChoiceModelOutput, - FlaxQuestionAnsweringModelOutput, - FlaxSequenceClassifierOutput, - FlaxTokenClassifierOutput, -) -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring, overwrite_call_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_roformer import RoFormerConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "junnyu/roformer_chinese_base" -_CONFIG_FOR_DOC = "RoFormerConfig" - - -ROFORMER_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`RoFormerConfig`]): Model configuration class with all the parameters of the - model. Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -ROFORMER_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - head_mask (`numpy.ndarray` of shape `({0})`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.marian.modeling_flax_marian.create_sinusoidal_positions -def create_sinusoidal_positions(n_pos, dim): - position_enc = np.array([[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)]) - sentinel = dim // 2 + dim % 2 - out = np.zeros_like(position_enc) - out[:, 0:sentinel] = np.sin(position_enc[:, 0::2]) - out[:, sentinel:] = np.cos(position_enc[:, 1::2]) - - return jnp.array(out) - - -class FlaxRoFormerEmbeddings(nn.Module): - """Construct the embeddings from word and token_type embeddings.""" - - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.word_embeddings = nn.Embed( - self.config.vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.token_type_embeddings = nn.Embed( - self.config.type_vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, input_ids, token_type_ids, attention_mask, deterministic: bool = True): - # Embed - inputs_embeds = self.word_embeddings(input_ids.astype("i4")) - token_type_embeddings = self.token_type_embeddings(token_type_ids.astype("i4")) - - # Sum all embeddings - hidden_states = inputs_embeds + token_type_embeddings - - # Layer Norm - hidden_states = self.LayerNorm(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxRoFormerSelfAttention(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self) -> None: - if self.config.hidden_size % self.config.num_attention_heads != 0: - raise ValueError( - "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads` " - " : {self.config.num_attention_heads}" - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - self.rotary_value = self.config.rotary_value - - def __call__( - self, - hidden_states, - attention_mask, - sinusoidal_pos, - layer_head_mask, - deterministic=True, - output_attentions: bool = False, - ): - head_dim = self.config.hidden_size // self.config.num_attention_heads - - query_states = self.query(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - value_states = self.value(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - key_states = self.key(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - - if sinusoidal_pos is not None: - if self.rotary_value: - query_states, key_states, value_states = self.apply_rotary_position_embeddings( - sinusoidal_pos, query_states, key_states, value_states - ) - else: - query_states, key_states = self.apply_rotary_position_embeddings( - sinusoidal_pos, query_states, key_states - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - # Mask heads if we want to - if layer_head_mask is not None: - attn_weights = jnp.einsum("...hqk,h->...hqk", attn_weights, layer_head_mask) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - @staticmethod - def apply_rotary_position_embeddings(sinusoidal_pos, query_layer, key_layer, value_layer=None): - sin, cos = jnp.split(sinusoidal_pos, 2, axis=-1) - sin_pos = jnp.stack([sin, sin], axis=-1).reshape(sinusoidal_pos.shape) - cos_pos = jnp.stack([cos, cos], axis=-1).reshape(sinusoidal_pos.shape) - - def rotate_layer(layer, sin_pos, cos_pos): - rotate_half_layer = jnp.stack([-layer[..., 1::2], layer[..., ::2]], axis=-1).reshape(layer.shape) - rotary_matrix_cos = jnp.einsum("bslh,...sh->bslh", layer, cos_pos) - rotary_matrix_sin = jnp.einsum("bslh,...sh->bslh", rotate_half_layer, sin_pos) - return rotary_matrix_cos + rotary_matrix_sin - - query_layer = rotate_layer(query_layer, sin_pos, cos_pos) - key_layer = rotate_layer(key_layer, sin_pos, cos_pos) - if value_layer is not None: - value_layer = rotate_layer(value_layer, sin_pos, cos_pos) - return query_layer, key_layer, value_layer - return query_layer, key_layer - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfOutput with Bert->RoFormer -class FlaxRoFormerSelfOutput(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, input_tensor, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - return hidden_states - - -class FlaxRoFormerAttention(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.self = FlaxRoFormerSelfAttention(self.config, dtype=self.dtype) - self.output = FlaxRoFormerSelfOutput(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - sinusoidal_pos, - layer_head_mask, - deterministic=True, - output_attentions: bool = False, - ): - # Attention mask comes in as attention_mask.shape == (*batch_sizes, kv_length) - # FLAX expects: attention_mask.shape == (*batch_sizes, 1, 1, kv_length) such that it is broadcastable - # with attn_weights.shape == (*batch_sizes, num_heads, q_length, kv_length) - attn_outputs = self.self( - hidden_states, - attention_mask, - sinusoidal_pos, - layer_head_mask=layer_head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attn_output = attn_outputs[0] - hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_outputs[1],) - - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertIntermediate with Bert->RoFormer -class FlaxRoFormerIntermediate(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertOutput with Bert->RoFormer -class FlaxRoFormerOutput(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states, attention_output, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + attention_output) - return hidden_states - - -class FlaxRoFormerLayer(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.attention = FlaxRoFormerAttention(self.config, dtype=self.dtype) - self.intermediate = FlaxRoFormerIntermediate(self.config, dtype=self.dtype) - self.output = FlaxRoFormerOutput(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - sinusiodal_pos, - layer_head_mask, - deterministic: bool = True, - output_attentions: bool = False, - ): - attention_outputs = self.attention( - hidden_states, - attention_mask, - sinusiodal_pos, - layer_head_mask=layer_head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = attention_outputs[0] - - hidden_states = self.intermediate(attention_output) - hidden_states = self.output(hidden_states, attention_output, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attention_outputs[1],) - return outputs - - -class FlaxRoFormerLayerCollection(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxRoFormerLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask, - sinusoidal_pos, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - # Check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - if head_mask.shape[0] != (len(self.layers)): - raise ValueError( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for " - f" {head_mask.shape[0]}." - ) - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer( - hidden_states, - attention_mask, - sinusoidal_pos, - layer_head_mask=head_mask[i] if head_mask is not None else None, - deterministic=deterministic, - output_attentions=output_attentions, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states,) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -class FlaxRoFormerEncoder(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.embed_positions = create_sinusoidal_positions( - self.config.max_position_embeddings, self.config.hidden_size // self.config.num_attention_heads - ) - self.layer = FlaxRoFormerLayerCollection(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - sinusoidal_pos = self.embed_positions[: hidden_states.shape[1], :] - - return self.layer( - hidden_states, - attention_mask, - sinusoidal_pos, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPredictionHeadTransform with Bert->RoFormer -class FlaxRoFormerPredictionHeadTransform(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense(self.config.hidden_size, dtype=self.dtype) - self.activation = ACT2FN[self.config.hidden_act] - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return self.LayerNorm(hidden_states) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLMPredictionHead with Bert->RoFormer -class FlaxRoFormerLMPredictionHead(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.transform = FlaxRoFormerPredictionHeadTransform(self.config, dtype=self.dtype) - self.decoder = nn.Dense(self.config.vocab_size, dtype=self.dtype, use_bias=False) - self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) - - def __call__(self, hidden_states, shared_embedding=None): - hidden_states = self.transform(hidden_states) - - if shared_embedding is not None: - hidden_states = self.decoder.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - hidden_states = self.decoder(hidden_states) - - bias = jnp.asarray(self.bias, self.dtype) - hidden_states += bias - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertOnlyMLMHead with Bert->RoFormer -class FlaxRoFormerOnlyMLMHead(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.predictions = FlaxRoFormerLMPredictionHead(self.config, dtype=self.dtype) - - def __call__(self, hidden_states, shared_embedding=None): - hidden_states = self.predictions(hidden_states, shared_embedding=shared_embedding) - return hidden_states - - -class FlaxRoFormerClassificationHead(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.out_proj = nn.Dense( - self.config.num_labels, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.activation = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_states, deterministic=True): - hidden_states = hidden_states[:, 0, :] # take token (equiv. to [CLS]) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.out_proj(hidden_states) - return hidden_states - - -class FlaxRoFormerPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = RoFormerConfig - base_model_prefix = "roformer" - module_class: nn.Module = None - - def __init__( - self, - config: RoFormerConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - token_type_ids = jnp.zeros_like(input_ids) - attention_mask = jnp.ones_like(input_ids) - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, input_ids, attention_mask, token_type_ids, head_mask, return_dict=False - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(ROFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - head_mask=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # init input tensors if not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - if head_mask is None: - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(token_type_ids, dtype="i4"), - jnp.array(head_mask, dtype="i4"), - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - -class FlaxRoFormerModule(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.embeddings = FlaxRoFormerEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxRoFormerEncoder(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - hidden_states = self.embeddings(input_ids, token_type_ids, attention_mask, deterministic=deterministic) - outputs = self.encoder( - hidden_states, - attention_mask, - head_mask=head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - - if not return_dict: - return (hidden_states,) + outputs[1:] - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - "The bare RoFormer Model transformer outputting raw hidden-states without any specific head on top.", - ROFORMER_START_DOCSTRING, -) -class FlaxRoFormerModel(FlaxRoFormerPreTrainedModel): - module_class = FlaxRoFormerModule - - -append_call_sample_docstring(FlaxRoFormerModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutput, _CONFIG_FOR_DOC) - - -class FlaxRoFormerForMaskedLMModule(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.roformer = FlaxRoFormerModule(config=self.config, dtype=self.dtype) - self.cls = FlaxRoFormerOnlyMLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roformer( - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.roformer.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.cls(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxMaskedLMOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings("""RoFormer Model with a `language modeling` head on top.""", ROFORMER_START_DOCSTRING) -class FlaxRoFormerForMaskedLM(FlaxRoFormerPreTrainedModel): - module_class = FlaxRoFormerForMaskedLMModule - - -append_call_sample_docstring( - FlaxRoFormerForMaskedLM, - _CHECKPOINT_FOR_DOC, - FlaxMaskedLMOutput, - _CONFIG_FOR_DOC, - mask="", -) - - -class FlaxRoFormerForSequenceClassificationModule(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.roformer = FlaxRoFormerModule(config=self.config, dtype=self.dtype) - self.classifier = FlaxRoFormerClassificationHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roformer( - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - sequence_output = outputs[0] - logits = self.classifier(sequence_output, deterministic=deterministic) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - RoFormer Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - ROFORMER_START_DOCSTRING, -) -class FlaxRoFormerForSequenceClassification(FlaxRoFormerPreTrainedModel): - module_class = FlaxRoFormerForSequenceClassificationModule - - -append_call_sample_docstring( - FlaxRoFormerForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxRoFormerForMultipleChoiceModule(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.roformer = FlaxRoFormerModule(config=self.config, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.classifier = nn.Dense(1, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - num_choices = input_ids.shape[1] - input_ids = input_ids.reshape(-1, input_ids.shape[-1]) - attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) - token_type_ids = token_type_ids.reshape(-1, token_type_ids.shape[-1]) - - # Model - outputs = self.roformer( - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - # Equivalent to sequence_summary call in the PyTorch implementation - hidden_states = outputs[0] - pooled_output = hidden_states[:, -1] - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - - logits = self.classifier(pooled_output) - - reshaped_logits = logits.reshape(-1, num_choices) - - if not return_dict: - return (reshaped_logits,) + outputs[2:] - - return FlaxMultipleChoiceModelOutput( - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - RoFormer Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - ROFORMER_START_DOCSTRING, -) -class FlaxRoFormerForMultipleChoice(FlaxRoFormerPreTrainedModel): - module_class = FlaxRoFormerForMultipleChoiceModule - - -overwrite_call_docstring( - FlaxRoFormerForMultipleChoice, ROFORMER_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") -) -append_call_sample_docstring( - FlaxRoFormerForMultipleChoice, - _CHECKPOINT_FOR_DOC, - FlaxMultipleChoiceModelOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxRoFormerForTokenClassificationModule(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.roformer = FlaxRoFormerModule(config=self.config, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roformer( - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - logits = self.classifier(hidden_states) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxTokenClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - RoFormer Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - ROFORMER_START_DOCSTRING, -) -class FlaxRoFormerForTokenClassification(FlaxRoFormerPreTrainedModel): - module_class = FlaxRoFormerForTokenClassificationModule - - -append_call_sample_docstring( - FlaxRoFormerForTokenClassification, - _CHECKPOINT_FOR_DOC, - FlaxTokenClassifierOutput, - _CONFIG_FOR_DOC, -) - - -class FlaxRoFormerForQuestionAnsweringModule(nn.Module): - config: RoFormerConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.roformer = FlaxRoFormerModule(config=self.config, dtype=self.dtype) - self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roformer( - input_ids, - attention_mask, - token_type_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - logits = self.qa_outputs(hidden_states) - start_logits, end_logits = jnp.split(logits, self.config.num_labels, axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - return (start_logits, end_logits) + outputs[1:] - - return FlaxQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - RoFormer Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - ROFORMER_START_DOCSTRING, -) -class FlaxRoFormerForQuestionAnswering(FlaxRoFormerPreTrainedModel): - module_class = FlaxRoFormerForQuestionAnsweringModule - - -append_call_sample_docstring( - FlaxRoFormerForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - - -__all__ = [ - "FlaxRoFormerForMaskedLM", - "FlaxRoFormerForMultipleChoice", - "FlaxRoFormerForQuestionAnswering", - "FlaxRoFormerForSequenceClassification", - "FlaxRoFormerForTokenClassification", - "FlaxRoFormerModel", - "FlaxRoFormerPreTrainedModel", -] diff --git a/src/transformers/models/roformer/modeling_roformer.py b/src/transformers/models/roformer/modeling_roformer.py index 3fc94cf87675..03a2195da287 100644 --- a/src/transformers/models/roformer/modeling_roformer.py +++ b/src/transformers/models/roformer/modeling_roformer.py @@ -15,7 +15,6 @@ """PyTorch RoFormer model.""" import math -import os from typing import Callable, Optional, Union import numpy as np @@ -81,79 +80,6 @@ def forward( return super().forward(position_ids) -def load_tf_weights_in_roformer(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name.replace("bert", "roformer")) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if not pointer.shape == array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - return model - - class RoFormerEmbeddings(nn.Module): """Construct the embeddings from word and token_type embeddings.""" @@ -162,8 +88,6 @@ def __init__(self, config): self.word_embeddings = nn.Embedding(config.vocab_size, config.embedding_size, padding_idx=config.pad_token_id) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.embedding_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.embedding_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -761,15 +685,12 @@ def forward(self, sequence_output: torch.Tensor) -> torch.Tensor: @auto_docstring class RoFormerPreTrainedModel(PreTrainedModel): config: RoFormerConfig - load_tf_weights = load_tf_weights_in_roformer base_model_prefix = "roformer" supports_gradient_checkpointing = True def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -1501,5 +1422,4 @@ def forward( "RoFormerLayer", "RoFormerModel", "RoFormerPreTrainedModel", - "load_tf_weights_in_roformer", ] diff --git a/src/transformers/models/roformer/modeling_tf_roformer.py b/src/transformers/models/roformer/modeling_tf_roformer.py deleted file mode 100644 index e07374e9fdf5..000000000000 --- a/src/transformers/models/roformer/modeling_tf_roformer.py +++ /dev/null @@ -1,1546 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 RoFormer model.""" - -from __future__ import annotations - -import math - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPooling, - TFCausalLMOutput, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFSequenceSummary, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_roformer import RoFormerConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "junnyu/roformer_chinese_base" -_CONFIG_FOR_DOC = "RoFormerConfig" - - -class TFRoFormerSinusoidalPositionalEmbedding(keras.layers.Layer): - """This module produces sinusoidal positional embeddings of any length.""" - - def __init__(self, num_positions: int, embedding_dim: int, **kwargs): - super().__init__(**kwargs) - - if embedding_dim % 2 != 0: - raise NotImplementedError(f"odd embedding_dim {embedding_dim} not supported") - - self.embedding_dim = embedding_dim - self.num_positions = num_positions - - def build(self, input_shape: tf.TensorShape): - """ - Build shared token embedding layer Shared weights logic adapted from - https://github.com/tensorflow/models/blob/a009f4fb9d2fc4949e32192a944688925ef78659/official/transformer/v2/embedding_layer.py#L24 - """ - - weight = self._init_weight(self.num_positions, self.embedding_dim) - - self.weight = self.add_weight( - name="embeddings", - shape=[self.num_positions, self.embedding_dim], - ) - weight = tf.cast(weight, dtype=self.weight.dtype) - - self.weight.assign(weight) - - super().build(input_shape) - - @staticmethod - def _init_weight(n_pos: int, dim: int): - """ - Identical to the XLM create_sinusoidal_embeddings except features are not interleaved. The cos features are in - the 2nd half of the vector. [dim // 2:] - """ - position_enc = np.array( - [[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)] - ) - table = np.zeros_like(position_enc) - # index 0 is all zero - table[:, 0 : dim // 2] = np.sin(position_enc[:, 0::2]) - table[:, dim // 2 :] = np.cos(position_enc[:, 1::2]) - # convert to tensor - table = tf.convert_to_tensor(table) - tf.stop_gradient(table) - return table - - def call(self, input_shape: tf.TensorShape, past_key_values_length: int = 0): - """Input is expected to be of size [bsz x seqlen].""" - bsz, seq_len = input_shape[:2] - - positions = tf.range(past_key_values_length, seq_len + past_key_values_length, delta=1, name="range") - return tf.gather(self.weight, positions) - - -class TFRoFormerEmbeddings(keras.layers.Layer): - """Construct the embeddings from word, position and token_type embeddings.""" - - def __init__(self, config: RoFormerConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = config.embedding_size - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.embedding_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.embedding_size]) - - def call( - self, - input_ids: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - training: bool = False, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -class TFRoFormerSelfAttention(keras.layers.Layer): - def __init__(self, config: RoFormerConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - self.rotary_value = config.rotary_value - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - sinusoidal_pos: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - mixed_key_layer = self.key(inputs=hidden_states) - mixed_value_layer = self.value(inputs=hidden_states) - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) - - if sinusoidal_pos is not None: - if self.rotary_value: - query_layer, key_layer, value_layer = self.apply_rotary_position_embeddings( - sinusoidal_pos, query_layer, key_layer, value_layer - ) - else: - query_layer, key_layer = self.apply_rotary_position_embeddings(sinusoidal_pos, query_layer, key_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFRoFormerModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - return outputs - - @staticmethod - def apply_rotary_position_embeddings(sinusoidal_pos, query_layer, key_layer, value_layer=None): - # https://kexue.fm/archives/8265 - # sin [batch_size, num_heads, sequence_length, embed_size_per_head//2] - # cos [batch_size, num_heads, sequence_length, embed_size_per_head//2] - sin, cos = tf.split(sinusoidal_pos, num_or_size_splits=2, axis=-1) - # sin [θ0,θ1,θ2......θd/2-1]-> sin_pos [θ0,θ0,θ1,θ1,θ2,θ2......θd/2-1,θd/2-1] - # cos [θ0,θ1,θ2......θd/2-1]-> cos_pos [θ0,θ0,θ1,θ1,θ2,θ2......θd/2-1,θd/2-1] - sin_pos = tf.repeat(sin, 2, axis=-1) - cos_pos = tf.repeat(cos, 2, axis=-1) - # rotate_half_query_layer [-q1,q0,-q3,q2......,-qd-1,qd-2] - rotate_half_query_layer = tf.stack([-query_layer[..., 1::2], query_layer[..., ::2]], axis=-1) - rotate_half_query_layer = tf.reshape(rotate_half_query_layer, shape_list(query_layer)) - query_layer = query_layer * cos_pos + rotate_half_query_layer * sin_pos - # rotate_half_key_layer [-k1,k0,-k3,k2......,-kd-1,kd-2] - rotate_half_key_layer = tf.stack([-key_layer[..., 1::2], key_layer[..., ::2]], axis=-1) - rotate_half_key_layer = tf.reshape(rotate_half_key_layer, shape_list(key_layer)) - key_layer = key_layer * cos_pos + rotate_half_key_layer * sin_pos - if value_layer is not None: - # rotate_half_value_layer [-v1,v0,-v3,v2......,-vd-1,vd-2] - rotate_half_value_layer = tf.stack([-value_layer[..., 1::2], value_layer[..., ::2]], axis=-1) - rotate_half_value_layer = tf.reshape(rotate_half_value_layer, shape_list(value_layer)) - value_layer = value_layer * cos_pos + rotate_half_value_layer * sin_pos - return query_layer, key_layer, value_layer - return query_layer, key_layer - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfOutput with Bert->RoFormer -class TFRoFormerSelfOutput(keras.layers.Layer): - def __init__(self, config: RoFormerConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFRoFormerAttention(keras.layers.Layer): - def __init__(self, config: RoFormerConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFRoFormerSelfAttention(config, name="self") - self.dense_output = TFRoFormerSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - sinusoidal_pos: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, - attention_mask=attention_mask, - sinusoidal_pos=sinusoidal_pos, - head_mask=head_mask, - output_attentions=output_attentions, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->RoFormer -class TFRoFormerIntermediate(keras.layers.Layer): - def __init__(self, config: RoFormerConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->RoFormer -class TFRoFormerOutput(keras.layers.Layer): - def __init__(self, config: RoFormerConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -class TFRoFormerLayer(keras.layers.Layer): - def __init__(self, config: RoFormerConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFRoFormerAttention(config, name="attention") - self.intermediate = TFRoFormerIntermediate(config, name="intermediate") - self.roformer_output = TFRoFormerOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - sinusoidal_pos: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - sinusoidal_pos=sinusoidal_pos, - head_mask=head_mask, - output_attentions=output_attentions, - training=training, - ) - attention_output = attention_outputs[0] - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.roformer_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "roformer_output", None) is not None: - with tf.name_scope(self.roformer_output.name): - self.roformer_output.build(None) - - -class TFRoFormerEncoder(keras.layers.Layer): - def __init__(self, config: RoFormerConfig, **kwargs): - super().__init__(**kwargs) - self.embed_positions = TFRoFormerSinusoidalPositionalEmbedding( - config.max_position_embeddings, - config.hidden_size // config.num_attention_heads, - name="embed_positions", - ) - self.layer = [TFRoFormerLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - # [sequence_length, embed_size_per_head] -> [batch_size, num_heads, sequence_length, embed_size_per_head] - sinusoidal_pos = self.embed_positions(shape_list(hidden_states)[:-1])[None, None, :, :] - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - sinusoidal_pos=sinusoidal_pos, - head_mask=head_mask[i], - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFRoFormerPredictionHeadTransform(keras.layers.Layer): - def __init__(self, config: RoFormerConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.embedding_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - - if isinstance(config.hidden_act, str): - self.transform_act_fn = get_tf_activation(config.hidden_act) - else: - self.transform_act_fn = config.hidden_act - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.transform_act_fn(hidden_states) - hidden_states = self.LayerNorm(inputs=hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.embedding_size]) - - -class TFRoFormerLMPredictionHead(keras.layers.Layer): - def __init__(self, config: RoFormerConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.embedding_size = config.embedding_size - - self.transform = TFRoFormerPredictionHeadTransform(config, name="transform") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.input_embeddings = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "transform", None) is not None: - with tf.name_scope(self.transform.name): - self.transform.build(None) - - def get_output_embeddings(self) -> keras.layers.Layer: - return self.input_embeddings - - def set_output_embeddings(self, value: tf.Variable): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self) -> dict[str, tf.Variable]: - return {"bias": self.bias} - - def set_bias(self, value: tf.Variable): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.transform(hidden_states=hidden_states) - seq_length = shape_list(hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.embedding_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertMLMHead with Bert->RoFormer -class TFRoFormerMLMHead(keras.layers.Layer): - def __init__(self, config: RoFormerConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.predictions = TFRoFormerLMPredictionHead(config, input_embeddings, name="predictions") - - def call(self, sequence_output: tf.Tensor) -> tf.Tensor: - prediction_scores = self.predictions(hidden_states=sequence_output) - - return prediction_scores - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -@keras_serializable -class TFRoFormerMainLayer(keras.layers.Layer): - config_class = RoFormerConfig - - def __init__(self, config: RoFormerConfig, add_pooling_layer: bool = True, **kwargs): - super().__init__(**kwargs) - - self.config = config - - self.embeddings = TFRoFormerEmbeddings(config, name="embeddings") - if config.embedding_size != config.hidden_size: - self.embeddings_project = keras.layers.Dense(config.hidden_size, name="embeddings_project") - - self.encoder = TFRoFormerEncoder(config, name="encoder") - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - training=training, - ) - if hasattr(self, "embeddings_project"): - embedding_output = self.embeddings_project(embedding_output, training=training) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - extended_attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - - if not return_dict: - return (sequence_output,) + encoder_outputs[1:] - - return TFBaseModelOutput( - last_hidden_state=sequence_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "embeddings_project", None) is not None: - with tf.name_scope(self.embeddings_project.name): - self.embeddings_project.build([None, None, self.config.embedding_size]) - - -class TFRoFormerPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = RoFormerConfig - base_model_prefix = "roformer" - - -ROFORMER_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`RoFormerConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -ROFORMER_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare RoFormer Model transformer outputting raw hidden-states without any specific head on top.", - ROFORMER_START_DOCSTRING, -) -class TFRoFormerModel(TFRoFormerPreTrainedModel): - def __init__(self, config: RoFormerConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.roformer = TFRoFormerMainLayer(config, name="roformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPooling, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - outputs = self.roformer( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roformer", None) is not None: - with tf.name_scope(self.roformer.name): - self.roformer.build(None) - - -@add_start_docstrings("""RoFormer Model with a `language modeling` head on top.""", ROFORMER_START_DOCSTRING) -class TFRoFormerForMaskedLM(TFRoFormerPreTrainedModel, TFMaskedLanguageModelingLoss): - def __init__(self, config: RoFormerConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if config.is_decoder: - logger.warning( - "If you want to use `TFRoFormerForMaskedLM` make sure `config.is_decoder=False` for " - "bi-directional self-attention." - ) - - self.roformer = TFRoFormerMainLayer(config, name="roformer") - self.mlm = TFRoFormerMLMHead(config, input_embeddings=self.roformer.embeddings, name="mlm___cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.mlm.predictions - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.roformer( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.mlm(sequence_output=sequence_output, training=training) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roformer", None) is not None: - with tf.name_scope(self.roformer.name): - self.roformer.build(None) - if getattr(self, "mlm", None) is not None: - with tf.name_scope(self.mlm.name): - self.mlm.build(None) - - -@add_start_docstrings( - """RoFormer Model with a `language modeling` head on top for CLM fine-tuning.""", ROFORMER_START_DOCSTRING -) -class TFRoFormerForCausalLM(TFRoFormerPreTrainedModel, TFCausalLanguageModelingLoss): - def __init__(self, config: RoFormerConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if not config.is_decoder: - logger.warning("If you want to use `TFRoFormerForCausalLM` as a standalone, add `is_decoder=True.`") - - self.roformer = TFRoFormerMainLayer(config, name="roformer") - self.mlm = TFRoFormerMLMHead(config, input_embeddings=self.roformer.embeddings, name="mlm___cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.mlm.predictions - - @unpack_inputs - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFCausalLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - outputs = self.roformer( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.mlm(sequence_output=sequence_output, training=training) - loss = None - - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels=labels, logits=shifted_logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roformer", None) is not None: - with tf.name_scope(self.roformer.name): - self.roformer.build(None) - if getattr(self, "mlm", None) is not None: - with tf.name_scope(self.mlm.name): - self.mlm.build(None) - - -class TFRoFormerClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, config: RoFormerConfig, *inputs, **kwargs): - super().__init__(*inputs, **kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.out_proj = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="out_proj" - ) - - if isinstance(config.hidden_act, str): - self.classifier_act_fn = get_tf_activation(config.hidden_act) - else: - self.classifier_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = hidden_states[:, 0, :] # take token (equiv. to [CLS]) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.classifier_act_fn(hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.out_proj(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RoFormer Model transformer with a sequence classification/regression head on top e.g., for GLUE tasks. - """, - ROFORMER_START_DOCSTRING, -) -class TFRoFormerForSequenceClassification(TFRoFormerPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: RoFormerConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.roformer = TFRoFormerMainLayer(config, name="roformer") - self.classifier = TFRoFormerClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.roformer( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - logits = self.classifier(hidden_states=outputs[0], training=training) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[1:] - - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roformer", None) is not None: - with tf.name_scope(self.roformer.name): - self.roformer.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - RoFormer Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - ROFORMER_START_DOCSTRING, -) -class TFRoFormerForMultipleChoice(TFRoFormerPreTrainedModel, TFMultipleChoiceLoss): - def __init__(self, config: RoFormerConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.roformer = TFRoFormerMainLayer(config, name="roformer") - self.sequence_summary = TFSequenceSummary(config, config.initializer_range, name="sequence_summary") - self.classifier = keras.layers.Dense( - units=1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward( - ROFORMER_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") - ) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(tensor=input_ids, shape=(-1, seq_length)) if input_ids is not None else None - flat_attention_mask = ( - tf.reshape(tensor=attention_mask, shape=(-1, seq_length)) if attention_mask is not None else None - ) - flat_token_type_ids = ( - tf.reshape(tensor=token_type_ids, shape=(-1, seq_length)) if token_type_ids is not None else None - ) - flat_inputs_embeds = ( - tf.reshape(tensor=inputs_embeds, shape=(-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - outputs = self.roformer( - input_ids=flat_input_ids, - attention_mask=flat_attention_mask, - token_type_ids=flat_token_type_ids, - head_mask=head_mask, - inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - logits = self.sequence_summary(inputs=outputs[0], training=training) - logits = self.classifier(inputs=logits) - reshaped_logits = tf.reshape(tensor=logits, shape=(-1, num_choices)) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[1:] - - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roformer", None) is not None: - with tf.name_scope(self.roformer.name): - self.roformer.build(None) - if getattr(self, "sequence_summary", None) is not None: - with tf.name_scope(self.sequence_summary.name): - self.sequence_summary.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RoFormer Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - ROFORMER_START_DOCSTRING, -) -class TFRoFormerForTokenClassification(TFRoFormerPreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config: RoFormerConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.roformer = TFRoFormerMainLayer(config, name="roformer") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.roformer( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - sequence_output = self.dropout(inputs=sequence_output, training=training) - logits = self.classifier(inputs=sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roformer", None) is not None: - with tf.name_scope(self.roformer.name): - self.roformer.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - RoFormer Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layer on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - ROFORMER_START_DOCSTRING, -) -class TFRoFormerForQuestionAnswering(TFRoFormerPreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config: RoFormerConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - - self.roformer = TFRoFormerMainLayer(config, name="roformer") - self.qa_outputs = keras.layers.Dense( - units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(ROFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.roformer( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.qa_outputs(inputs=sequence_output) - start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) - start_logits = tf.squeeze(input=start_logits, axis=-1) - end_logits = tf.squeeze(input=end_logits, axis=-1) - loss = None - - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions, "end_position": end_positions} - loss = self.hf_compute_loss(labels=labels, logits=(start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roformer", None) is not None: - with tf.name_scope(self.roformer.name): - self.roformer.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFRoFormerForCausalLM", - "TFRoFormerForMaskedLM", - "TFRoFormerForMultipleChoice", - "TFRoFormerForQuestionAnswering", - "TFRoFormerForSequenceClassification", - "TFRoFormerForTokenClassification", - "TFRoFormerLayer", - "TFRoFormerModel", - "TFRoFormerPreTrainedModel", -] diff --git a/src/transformers/models/rt_detr/image_processing_rt_detr.py b/src/transformers/models/rt_detr/image_processing_rt_detr.py index de61a8019047..cf657867a9f8 100644 --- a/src/transformers/models/rt_detr/image_processing_rt_detr.py +++ b/src/transformers/models/rt_detr/image_processing_rt_detr.py @@ -16,7 +16,7 @@ import pathlib from collections.abc import Iterable -from typing import Any, Callable, Optional, Union +from typing import Any, Optional, Union import numpy as np @@ -50,12 +50,7 @@ ) from ...utils import ( filter_out_non_signature_kwargs, - is_flax_available, - is_jax_tensor, - is_tf_available, - is_tf_tensor, is_torch_available, - is_torch_tensor, logging, requires_backends, ) @@ -174,31 +169,6 @@ def get_image_size_for_max_height_width( return new_height, new_width -# Copied from transformers.models.detr.image_processing_detr.get_numpy_to_framework_fn -def get_numpy_to_framework_fn(arr) -> Callable: - """ - Returns a function that converts a numpy array to the framework of the input array. - - Args: - arr (`np.ndarray`): The array to convert. - """ - if isinstance(arr, np.ndarray): - return np.array - if is_tf_available() and is_tf_tensor(arr): - import tensorflow as tf - - return tf.convert_to_tensor - if is_torch_available() and is_torch_tensor(arr): - import torch - - return torch.tensor - if is_flax_available() and is_jax_tensor(arr): - import jax.numpy as jnp - - return jnp.array - raise ValueError(f"Cannot convert arrays of type {type(arr)}") - - # Copied from transformers.models.detr.image_processing_detr.safe_squeeze def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: """ @@ -723,10 +693,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -896,10 +864,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor.") # Here, the pad() method pads to the maximum of (width, height). It does not need to be validated. @@ -928,10 +893,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # All transformations expect numpy arrays images = [to_numpy_array(image) for image in images] diff --git a/src/transformers/models/sam/__init__.py b/src/transformers/models/sam/__init__.py index bb8a2b98e636..ac0a21f82930 100644 --- a/src/transformers/models/sam/__init__.py +++ b/src/transformers/models/sam/__init__.py @@ -22,7 +22,6 @@ from .image_processing_sam import * from .image_processing_sam_fast import * from .modeling_sam import * - from .modeling_tf_sam import * from .processing_sam import * else: import sys diff --git a/src/transformers/models/sam/image_processing_sam.py b/src/transformers/models/sam/image_processing_sam.py index c9b54f561fb6..4879d3655514 100644 --- a/src/transformers/models/sam/image_processing_sam.py +++ b/src/transformers/models/sam/image_processing_sam.py @@ -40,7 +40,6 @@ from ...utils import ( TensorType, filter_out_non_signature_kwargs, - is_tf_available, is_torch_available, is_torchvision_available, logging, @@ -55,12 +54,6 @@ if is_torchvision_available(): from torchvision.ops.boxes import batched_nms -if is_tf_available(): - import tensorflow as tf - from tensorflow.experimental import numpy as tnp - - from ...tf_utils import flatten, shape_list - logger = logging.get_logger(__name__) @@ -456,10 +449,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -497,18 +488,14 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor.") if segmentation_maps is not None: segmentation_maps = make_flat_list_of_images(segmentation_maps, expected_ndims=2) if not valid_images(segmentation_maps): raise ValueError( - "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." + "Invalid segmentation map type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor." ) validate_preprocess_arguments( do_rescale=do_rescale, @@ -588,12 +575,12 @@ def post_process_masks( Remove padding and upscale masks to the original image size. Args: - masks (`Union[list[torch.Tensor], list[np.ndarray], list[tf.Tensor]]`): + masks (`Union[list[torch.Tensor], list[np.ndarray]]`): Batched masks from the mask_decoder in (batch_size, num_channels, height, width) format. - original_sizes (`Union[torch.Tensor, tf.Tensor, list[tuple[int,int]]]`): + original_sizes (`Union[torch.Tensor, list[tuple[int,int]]]`): The original sizes of each image before it was resized to the model's expected input shape, in (height, width) format. - reshaped_input_sizes (`Union[torch.Tensor, tf.Tensor, list[tuple[int,int]]]`): + reshaped_input_sizes (`Union[torch.Tensor, list[tuple[int,int]]]`): The size of each image as it is fed to the model, in (height, width) format. Used to remove padding. mask_threshold (`float`, *optional*, defaults to 0.0): The threshold to use for binarizing the masks. @@ -603,9 +590,9 @@ def post_process_masks( The target size the images were padded to before being passed to the model. If None, the target size is assumed to be the processor's `pad_size`. return_tensors (`str`, *optional*, defaults to `"pt"`): - If `"pt"`, return PyTorch tensors. If `"tf"`, return TensorFlow tensors. + If `"pt"`, return PyTorch tensors. Returns: - (`Union[torch.Tensor, tf.Tensor]`): Batched masks in batch_size, num_channels, height, width) format, where + (`torch.Tensor`): Batched masks in batch_size, num_channels, height, width) format, where (height, width) is given by original_size. """ if return_tensors == "pt": @@ -617,17 +604,8 @@ def post_process_masks( binarize=binarize, pad_size=pad_size, ) - elif return_tensors == "tf": - return self._post_process_masks_tf( - masks=masks, - original_sizes=original_sizes, - reshaped_input_sizes=reshaped_input_sizes, - mask_threshold=mask_threshold, - binarize=binarize, - pad_size=pad_size, - ) else: - raise ValueError("return_tensors must be either 'pt' or 'tf'") + raise ValueError("return_tensors must be 'pt'") def _post_process_masks_pt( self, masks, original_sizes, reshaped_input_sizes, mask_threshold=0.0, binarize=True, pad_size=None @@ -676,48 +654,6 @@ def _post_process_masks_pt( return output_masks - def _post_process_masks_tf( - self, masks, original_sizes, reshaped_input_sizes, mask_threshold=0.0, binarize=True, pad_size=None - ): - """ - Remove padding and upscale masks to the original image size. - - Args: - masks (`tf.Tensor`): - Batched masks from the mask_decoder in (batch_size, num_channels, height, width) format. - original_sizes (`tf.Tensor`): - The original size of the images before resizing for input to the model, in (height, width) format. - reshaped_input_sizes (`tf.Tensor`): - The size of the image input to the model, in (height, width) format. Used to remove padding. - mask_threshold (`float`, *optional*, defaults to 0.0): - The threshold to use for binarizing the masks. - binarize (`bool`, *optional*, defaults to `True`): - Whether to binarize the masks. - pad_size (`int`, *optional*, defaults to `self.pad_size`): - The target size the images were padded to before being passed to the model. If None, the target size is - assumed to be the processor's `pad_size`. - Returns: - (`tf.Tensor`): Batched masks in batch_size, num_channels, height, width) format, where (height, width) is - given by original_size. - """ - requires_backends(self, ["tf"]) - pad_size = self.pad_size if pad_size is None else pad_size - target_image_size = (pad_size["height"], pad_size["width"]) - - output_masks = [] - for i, original_size in enumerate(original_sizes): - # tf.image expects NHWC, we transpose the NCHW inputs for it - mask = tf.transpose(masks[i], perm=[0, 2, 3, 1]) - interpolated_mask = tf.image.resize(mask, target_image_size, method="bilinear") - interpolated_mask = interpolated_mask[:, : reshaped_input_sizes[i][0], : reshaped_input_sizes[i][1], :] - interpolated_mask = tf.image.resize(interpolated_mask, original_size, method="bilinear") - if binarize: - interpolated_mask = interpolated_mask > mask_threshold - # And then we transpose them back at the end - output_masks.append(tf.transpose(interpolated_mask, perm=[0, 3, 1, 2])) - - return output_masks - def post_process_for_mask_generation( self, all_masks, all_scores, all_boxes, crops_nms_thresh, return_tensors="pt" ): @@ -725,21 +661,19 @@ def post_process_for_mask_generation( Post processes mask that are generated by calling the Non Maximum Suppression algorithm on the predicted masks. Args: - all_masks (`Union[list[torch.Tensor], list[tf.Tensor]]`): + all_masks (`list[torch.Tensor]`): List of all predicted segmentation masks - all_scores (`Union[list[torch.Tensor], list[tf.Tensor]]`): + all_scores (`list[torch.Tensor]`): List of all predicted iou scores - all_boxes (`Union[list[torch.Tensor], list[tf.Tensor]]`): + all_boxes (`list[torch.Tensor]`): List of all bounding boxes of the predicted masks crops_nms_thresh (`float`): Threshold for NMS (Non Maximum Suppression) algorithm. return_tensors (`str`, *optional*, defaults to `pt`): - If `pt`, returns `torch.Tensor`. If `tf`, returns `tf.Tensor`. + If `pt`, returns `torch.Tensor`. """ if return_tensors == "pt": return _postprocess_for_mg(all_masks, all_scores, all_boxes, crops_nms_thresh) - elif return_tensors == "tf": - return _postprocess_for_mg_tf(all_masks, all_scores, all_boxes, crops_nms_thresh) def generate_crop_boxes( self, @@ -776,7 +710,7 @@ def generate_crop_boxes( input_data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the input image. If not provided, it will be inferred. return_tensors (`str`, *optional*, defaults to `pt`): - If `pt`, returns `torch.Tensor`. If `tf`, returns `tf.Tensor`. + If `pt`, returns `torch.Tensor`. """ crop_boxes, points_per_crop, cropped_images, input_labels = _generate_crop_boxes( image, @@ -795,15 +729,8 @@ def generate_crop_boxes( # cropped_images stays as np input_labels = torch.tensor(input_labels, device=device) - elif return_tensors == "tf": - if device is not None: - raise ValueError("device is not a supported argument when return_tensors is tf!") - crop_boxes = tf.convert_to_tensor(crop_boxes) - points_per_crop = tf.convert_to_tensor(points_per_crop) - # cropped_images stays as np - input_labels = tf.convert_to_tensor(input_labels) else: - raise ValueError("return_tensors must be either 'pt' or 'tf'.") + raise ValueError("return_tensors must be either `'pt'` or `None`") return crop_boxes, points_per_crop, cropped_images, input_labels def filter_masks( @@ -825,9 +752,9 @@ def filter_masks( bounding boxes and pad the predicted masks if necessary. Args: - masks (`Union[torch.Tensor, tf.Tensor]`): + masks (`torch.Tensor`): Input masks. - iou_scores (`Union[torch.Tensor, tf.Tensor]`): + iou_scores (`torch.Tensor`): List of IoU scores. original_size (`tuple[int,int]`): Size of the original image. @@ -842,7 +769,7 @@ def filter_masks( stability_score_offset (`float`, *optional*, defaults to 1): The offset for the stability score used in the `_compute_stability_score` method. return_tensors (`str`, *optional*, defaults to `pt`): - If `pt`, returns `torch.Tensor`. If `tf`, returns `tf.Tensor`. + If `pt`, returns `torch.Tensor`. """ if return_tensors == "pt": return self._filter_masks_pt( @@ -855,17 +782,6 @@ def filter_masks( mask_threshold=mask_threshold, stability_score_offset=stability_score_offset, ) - elif return_tensors == "tf": - return self._filter_masks_tf( - masks=masks, - iou_scores=iou_scores, - original_size=original_size, - cropped_box_image=cropped_box_image, - pred_iou_thresh=pred_iou_thresh, - stability_score_thresh=stability_score_thresh, - mask_threshold=mask_threshold, - stability_score_offset=stability_score_offset, - ) def _filter_masks_pt( self, @@ -947,83 +863,6 @@ def _filter_masks_pt( return masks, scores, converted_boxes - def _filter_masks_tf( - self, - masks, - iou_scores, - original_size, - cropped_box_image, - pred_iou_thresh=0.88, - stability_score_thresh=0.95, - mask_threshold=0, - stability_score_offset=1, - ): - """ - Filters the predicted masks by selecting only the ones that meets several criteria. The first criterion being - that the iou scores needs to be greater than `pred_iou_thresh`. The second criterion is that the stability - score needs to be greater than `stability_score_thresh`. The method also converts the predicted masks to - bounding boxes and pad the predicted masks if necessary. - - Args: - masks (`tf.Tensor`): - Input masks. - iou_scores (`tf.Tensor`): - List of IoU scores. - original_size (`tuple[int,int]`): - Size of the original image. - cropped_box_image (`np.array`): - The cropped image. - pred_iou_thresh (`float`, *optional*, defaults to 0.88): - The threshold for the iou scores. - stability_score_thresh (`float`, *optional*, defaults to 0.95): - The threshold for the stability score. - mask_threshold (`float`, *optional*, defaults to 0): - The threshold for the predicted masks. - stability_score_offset (`float`, *optional*, defaults to 1): - The offset for the stability score used in the `_compute_stability_score` method. - - """ - requires_backends(self, ["tf"]) - original_height, original_width = original_size - iou_scores = tf.reshape(iou_scores, [iou_scores.shape[0] * iou_scores.shape[1], iou_scores.shape[2:]]) - masks = tf.reshape(masks, [masks.shape[0] * masks.shape[1], masks.shape[2:]]) - - if masks.shape[0] != iou_scores.shape[0]: - raise ValueError("masks and iou_scores must have the same batch size.") - - batch_size = masks.shape[0] - - keep_mask = tf.ones(batch_size, dtype=tf.bool) - - if pred_iou_thresh > 0.0: - keep_mask = keep_mask & (iou_scores > pred_iou_thresh) - - # compute stability score - if stability_score_thresh > 0.0: - stability_scores = _compute_stability_score_tf(masks, mask_threshold, stability_score_offset) - keep_mask = keep_mask & (stability_scores > stability_score_thresh) - - scores = iou_scores[keep_mask] - masks = masks[keep_mask] - - # binarize masks - masks = masks > mask_threshold - converted_boxes = _batched_mask_to_box_tf(masks) - - keep_mask = ~_is_box_near_crop_edge_tf( - converted_boxes, cropped_box_image, [0, 0, original_width, original_height] - ) - - scores = scores[keep_mask] - masks = masks[keep_mask] - converted_boxes = converted_boxes[keep_mask] - - masks = _pad_masks_tf(masks, cropped_box_image, original_height, original_width) - # conversion to rle is necessary to run non-maximum suppression - masks = _mask_to_rle_tf(masks) - - return masks, scores, converted_boxes - def _compute_stability_score_pt(masks: "torch.Tensor", mask_threshold: float, stability_score_offset: int): # One mask is always contained inside the other. @@ -1036,17 +875,6 @@ def _compute_stability_score_pt(masks: "torch.Tensor", mask_threshold: float, st return stability_scores -def _compute_stability_score_tf(masks: "tf.Tensor", mask_threshold: float, stability_score_offset: int): - # Torch does Py3-style division but TF does floor division with ints. We cast to float32 in TF to make sure - # we get the right division results. - intersections = tf.count_nonzero( - masks > (mask_threshold + stability_score_offset), axis=[-1, -2], dtype=tf.float32 - ) - unions = tf.count_nonzero(masks > (mask_threshold - stability_score_offset), axis=[-1, -2], dtype=tf.float32) - stability_scores = intersections / unions - return stability_scores - - def _build_point_grid(n_per_side: int) -> np.ndarray: """Generates a 2D grid of points evenly spaced in [0,1]x[0,1].""" offset = 1 / (2 * n_per_side) @@ -1215,16 +1043,6 @@ def _pad_masks(masks, crop_box: list[int], orig_height: int, orig_width: int): return torch.nn.functional.pad(masks, pad, value=0) -def _pad_masks_tf(masks, crop_box: list[int], orig_height: int, orig_width: int): - left, top, right, bottom = crop_box - if left == 0 and top == 0 and right == orig_width and bottom == orig_height: - return masks - # Coordinate transform masks - pad_x, pad_y = orig_width - (right - left), orig_height - (bottom - top) - pad = (left, pad_x - left, top, pad_y - top) - return tf.pad(masks, pad, constant_values=0) - - def _is_box_near_crop_edge(boxes, crop_box, orig_box, atol=20.0): """Filter masks at the edge of a crop, but not at the edge of the original image.""" crop_box_torch = torch.as_tensor(crop_box, dtype=torch.float, device=boxes.device) @@ -1243,24 +1061,6 @@ def _is_box_near_crop_edge(boxes, crop_box, orig_box, atol=20.0): return torch.any(near_crop_edge, dim=1) -def _is_box_near_crop_edge_tf(boxes, crop_box, orig_box, atol=20.0): - """Filter masks at the edge of a crop, but not at the edge of the original image.""" - crop_box_tf = tf.convert_to_tensor(crop_box, dtype=tf.float32) - orig_box_tf = tf.convert_to_tensor(orig_box, dtype=tf.float32) - - left, top, _, _ = crop_box - offset = tf.convert_to_tensor([[left, top, left, top]]) - # Check if boxes has a channel dimension - if len(boxes.shape) == 3: - offset = tf.expand_dims(offset, 1) - boxes = tf.cast(boxes + offset, tf.float32) - - near_crop_edge = tnp.isclose(boxes, crop_box_tf[None, :], atol=atol, rtol=0) - near_image_edge = tnp.isclose(boxes, orig_box_tf[None, :], atol=atol, rtol=0) - near_crop_edge = tf.math.logical_and(near_crop_edge, ~near_image_edge) - return tf.reduce_any(near_crop_edge, axis=1) - - def _batched_mask_to_box(masks: "torch.Tensor"): """ Computes the bounding boxes around the given input masks. The bounding boxes are in the XYXY format which @@ -1310,54 +1110,6 @@ def _batched_mask_to_box(masks: "torch.Tensor"): return out -def _batched_mask_to_box_tf(masks: "tf.Tensor"): - """ - Computes the bounding boxes around the given input masks. The bounding boxes are in the XYXY format which - corresponds the following required indices: - - LEFT: left hand side of the bounding box - - TOP: top of the bounding box - - RIGHT: right of the bounding box - - BOTTOM: bottom of the bounding box - - Return [0,0,0,0] for an empty mask. For input shape channel_1 x channel_2 x ... x height x width, the output shape - is channel_1 x channel_2 x ... x 4. - - Args: - - masks (`tf.Tensor` of shape `(batch, nb_mask, height, width)`) - """ - - if tf.size(masks) == 0: - return tf.zeros([*masks.shape[:-2], 4]) - - # Normalize shape to Cxheightxwidth - shape = shape_list(masks) - height, width = shape[-2:] - - # Get top and bottom edges - in_height = tf.reduce_max(masks, axis=-1) - in_height_coords = in_height * tf.range(height)[None, :] - bottom_edges = tf.reduce_max(in_height_coords, axis=-1) - in_height_coords = in_height_coords + height * (~in_height) - top_edges = tf.reduce_min(in_height_coords, axis=-1) - - # Get left and right edges - in_width, _ = tf.reduce_max(masks, axis=-2) - in_width_coords = in_width * tf.range(width)[None, :] - right_edges, _ = tf.reduce_max(in_width_coords, axis=-1) - in_width_coords = in_width_coords + width * (~in_width) - left_edges, _ = tf.reduce_min(in_width_coords, axis=-1) - - # If the mask is empty the right edge will be to the left of the left edge. - # Replace these boxes with [0, 0, 0, 0] - empty_filter = (right_edges < left_edges) | (bottom_edges < top_edges) - out = tf.stack([left_edges, top_edges, right_edges, bottom_edges], axis=-1) - out = out * tf.expand_dims(~empty_filter, -1) - - # Return to original shape - out = tf.reshape(out, *shape[:-2], 4) - return out - - def _mask_to_rle_pytorch(input_mask: "torch.Tensor"): """ Encodes masks the run-length encoding (RLE), in the format expected by pycoco tools. @@ -1389,39 +1141,6 @@ def _mask_to_rle_pytorch(input_mask: "torch.Tensor"): return out -def _mask_to_rle_tf(input_mask: "tf.Tensor"): - """ - Encodes masks the run-length encoding (RLE), in the format expected by pycoco tools. - """ - # Put in fortran order and flatten height and width - batch_size, height, width = input_mask.shape - input_mask = flatten(tf.transpose(input_mask, perm=(0, 2, 1)), 1) - - # Compute change indices - diff = input_mask[:, 1:] ^ input_mask[:, :-1] - change_indices = tf.where(diff) - - # Encode run length - out = [] - for i in range(batch_size): - cur_idxs = change_indices[change_indices[:, 0] == i][:, 1] + 1 - if len(cur_idxs) == 0: - # No changes => either all 0 or all 1 - # If the entire mask is 0, RLE is [height*width] or if the entire mask is 1, RLE is [0, height*width]. - if input_mask[i, 0] == 0: - out.append({"size": [height, width], "counts": [height * width]}) - else: - out.append({"size": [height, width], "counts": [0, height * width]}) - continue - btw_idxs = cur_idxs[1:] - cur_idxs[:-1] - counts = [] if input_mask[i, 0] == 0 else [0] - counts += ( - [cur_idxs[0].numpy().item()] + btw_idxs.numpy().tolist() + [height * width - cur_idxs[-1].numpy().item()] - ) - out.append({"size": [height, width], "counts": counts}) - return out - - def _rle_to_mask(rle: dict[str, Any]) -> np.ndarray: """Compute a binary mask from an uncompressed RLE.""" height, width = rle["size"] @@ -1465,33 +1184,4 @@ def _postprocess_for_mg(rle_masks, iou_scores, mask_boxes, amg_crops_nms_thresh= return masks, iou_scores, rle_masks, mask_boxes -def _postprocess_for_mg_tf(rle_masks, iou_scores, mask_boxes, amg_crops_nms_thresh=0.7): - """ - Perform NMS (Non Maximum Suppression) on the outputs. - - Args: - rle_masks (`tf.Tensor`): - binary masks in the RLE format - iou_scores (`tf.Tensor` of shape (nb_masks, 1)): - iou_scores predicted by the model - mask_boxes (`tf.Tensor`): - The bounding boxes corresponding to segmentation masks - amg_crops_nms_thresh (`float`, *optional*, defaults to 0.7): - NMS threshold. - """ - keep_by_nms = tf.image.combined_non_max_suppression( - boxes=mask_boxes.float(), - scores=iou_scores, - idxs=torch.zeros(mask_boxes.shape[0]), - iou_threshold=amg_crops_nms_thresh, - ) - - iou_scores = iou_scores[keep_by_nms] - rle_masks = [rle_masks[i] for i in keep_by_nms] - mask_boxes = mask_boxes[keep_by_nms] - masks = [_rle_to_mask(rle) for rle in rle_masks] - - return masks, iou_scores, rle_masks, mask_boxes - - __all__ = ["SamImageProcessor"] diff --git a/src/transformers/models/sam/image_processing_sam_fast.py b/src/transformers/models/sam/image_processing_sam_fast.py index ba75e73c8680..65ee02e97dac 100644 --- a/src/transformers/models/sam/image_processing_sam_fast.py +++ b/src/transformers/models/sam/image_processing_sam_fast.py @@ -270,7 +270,7 @@ def generate_crop_boxes( input_data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the input image. If not provided, it will be inferred. return_tensors (`str`, *optional*, defaults to `pt`): - If `pt`, returns `torch.Tensor`. If `tf`, returns `tf.Tensor`. + If `pt`, returns `torch.Tensor`. """ image = self._process_image(image) crop_boxes, points_per_crop, cropped_images, input_labels = _generate_crop_boxes( diff --git a/src/transformers/models/sam/modeling_tf_sam.py b/src/transformers/models/sam/modeling_tf_sam.py deleted file mode 100644 index ac81288fa182..000000000000 --- a/src/transformers/models/sam/modeling_tf_sam.py +++ /dev/null @@ -1,1723 +0,0 @@ -# coding=utf-8 -# Copyright 2023 The Meta AI Authors and The HuggingFace Team. All rights reserved. -# -# 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. -""" -TensorFlow SAM model. This file was mostly generated by auto-translation from the PyTorch original. In the event of a -discrepancy, the original file should be regarded as the 'reference' version. -""" - -from __future__ import annotations - -import collections -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import ACT2FN -from ...modeling_tf_outputs import TFBaseModelOutput -from ...modeling_tf_utils import TFModelInputType, TFPreTrainedModel, keras, shape_list, unpack_inputs -from ...tf_utils import flatten, functional_layernorm -from ...utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_sam import SamConfig, SamMaskDecoderConfig, SamPromptEncoderConfig, SamVisionConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "SamConfig" -_CHECKPOINT_FOR_DOC = "facebook/sam-vit-huge" - - -@dataclass -class TFSamVisionEncoderOutput(ModelOutput): - """ - Base class for sam vision model's outputs that also contains image embeddings obtained by applying the projection - layer to the pooler_output. - - Args: - image_embeds (`tf.Tensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`): - The image embeddings obtained by applying the projection layer to the pooler_output. - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - image_embeds: tf.Tensor | None = None - last_hidden_state: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFSamImageSegmentationOutput(ModelOutput): - """ - Base class for Segment-Anything model's output - - Args: - iou_scores (`tf.Tensor` of shape `(batch_size, num_masks)`): - The iou scores of the predicted masks. - pred_masks (`tf.Tensor` of shape `(batch_size, num_masks, height, width)`): - The predicted low resolutions masks. Needs to be post-processed by the processor - vision_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings, if the model has an embedding layer, + one for - the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the vision model at the output of each layer plus the optional initial embedding outputs. - vision_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - mask_decoder_attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - iou_scores: tf.Tensor | None = None - pred_masks: tf.Tensor | None = None - vision_hidden_states: tuple[tf.Tensor, ...] | None = None - vision_attentions: tuple[tf.Tensor, ...] | None = None - mask_decoder_attentions: tuple[tf.Tensor, ...] | None = None - - -class TFSamPatchEmbeddings(keras.layers.Layer): - """ - This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial - `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a - Transformer. - """ - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - image_size, patch_size = config.image_size, config.patch_size - num_channels, hidden_size = config.num_channels, config.hidden_size - image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) - patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) - num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) - self.image_size = image_size - self.patch_size = patch_size - self.num_channels = num_channels - self.num_patches = num_patches - - self.projection = keras.layers.Conv2D( - hidden_size, kernel_size=patch_size, strides=patch_size, name="projection" - ) - - def call(self, pixel_values): - batch_size, num_channels, height, width = shape_list(pixel_values) - if num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - if height != self.image_size[0] or width != self.image_size[1]: - raise ValueError( - f"Input image size ({height}*{width}) doesn't match model ({self.image_size[0]}*{self.image_size[1]})." - ) - embeddings = self.projection(tf.transpose(pixel_values, perm=[0, 2, 3, 1])) - return embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, None, self.num_channels]) - - -class TFSamMLPBlock(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.lin1 = keras.layers.Dense(config.mlp_dim, name="lin1") - self.lin2 = keras.layers.Dense(config.hidden_size, name="lin2") - self.act = ACT2FN[config.hidden_act] - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.lin1(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.lin2(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "lin1", None) is not None: - with tf.name_scope(self.lin1.name): - self.lin1.build([None, None, self.config.hidden_size]) - if getattr(self, "lin2", None) is not None: - with tf.name_scope(self.lin2.name): - self.lin2.build([None, None, self.config.mlp_dim]) - - -class TFSamLayerNorm(keras.layers.Layer): - r"""LayerNorm that supports two data formats: channels_last (default) or channels_first. - The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, - width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width). - """ - - def __init__(self, normalized_shape, eps=1e-6, data_format="channels_last", **kwargs): - super().__init__(**kwargs) - self.eps = eps - self.data_format = data_format - self.normalized_shape = normalized_shape - if self.data_format not in ["channels_last", "channels_first"]: - raise NotImplementedError(f"Unsupported data format: {self.data_format}") - - def build(self, input_shape): - self.weight = self.add_weight(shape=self.normalized_shape, initializer="ones", name="weight") - self.bias = self.add_weight(shape=self.normalized_shape, initializer="zeros", name="bias") - super().build(input_shape) - - def call(self, x: tf.Tensor) -> tf.Tensor: - if self.data_format == "channels_last": - x = functional_layernorm(x, weight=self.weight, bias=self.bias, epsilon=self.eps, axis=-1) - elif self.data_format == "channels_first": - x = functional_layernorm(x, weight=self.weight, bias=self.bias, epsilon=self.eps, axis=1) - return x - - -class TFSamAttention(keras.layers.Layer): - """ - SAM's attention layer that allows for downscaling the size of the embedding after projection to queries, keys, and - values. - """ - - def __init__(self, config, downsample_rate=None, **kwargs): - super().__init__(**kwargs) - self.hidden_size = config.hidden_size - - downsample_rate = config.attention_downsample_rate if downsample_rate is None else downsample_rate - - self.internal_dim = config.hidden_size // downsample_rate - self.num_attention_heads = config.num_attention_heads - if self.internal_dim % config.num_attention_heads != 0: - raise ValueError("num_attention_heads must divide hidden_size.") - - self.q_proj = keras.layers.Dense(self.internal_dim, name="q_proj") - self.k_proj = keras.layers.Dense(self.internal_dim, name="k_proj") - self.v_proj = keras.layers.Dense(self.internal_dim, name="v_proj") - self.out_proj = keras.layers.Dense(self.hidden_size, name="out_proj") - - def _separate_heads(self, hidden_states: tf.Tensor, num_attention_heads: int) -> tf.Tensor: - batch, point_batch_size, n_tokens, channel = shape_list(hidden_states) - c_per_head = channel // num_attention_heads - hidden_states = tf.reshape( - hidden_states, (batch * point_batch_size, n_tokens, num_attention_heads, c_per_head) - ) - return tf.transpose(hidden_states, perm=[0, 2, 1, 3]) - - def _recombine_heads(self, hidden_states: tf.Tensor, point_batch_size: int) -> tf.Tensor: - batch, n_heads, n_tokens, c_per_head = shape_list(hidden_states) - hidden_states = tf.transpose(hidden_states, perm=[0, 2, 1, 3]) - return tf.reshape( - hidden_states, - (batch // tf.reduce_max([1, point_batch_size]), point_batch_size, n_tokens, n_heads * c_per_head), - ) - - def call(self, query: tf.Tensor, key: tf.Tensor, value: tf.Tensor) -> tf.Tensor: - # Input projections - query = self.q_proj(query) - key = self.k_proj(key) - value = self.v_proj(value) - - point_batch_size = shape_list(query)[1] - # Separate into heads - query = self._separate_heads(query, self.num_attention_heads) - key = self._separate_heads(key, self.num_attention_heads) - value = self._separate_heads(value, self.num_attention_heads) - - # SamAttention - _, _, _, c_per_head = shape_list(query) - attn = tf.matmul( - query, tf.transpose(key, perm=[0, 1, 3, 2]) - ) # batch_size * point_batch_size x N_heads x N_tokens x N_tokens - attn = attn / tf.math.sqrt(float(c_per_head)) - attn = tf.nn.softmax(attn, axis=-1) - - # Get output - out = tf.matmul(attn, value) - out = self._recombine_heads(out, point_batch_size) - out = self.out_proj(out) - - return out - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.hidden_size]) - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.hidden_size]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.internal_dim]) - - -class TFSamTwoWayAttentionBlock(keras.layers.Layer): - def __init__(self, config, attention_downsample_rate: int = 2, skip_first_layer_pe: bool = False, **kwargs): - """ - A transformer block with four layers: - (1) self-attention of sparse inputs (2) cross attention of sparse inputs -> dense inputs (3) mlp block on - sparse inputs (4) cross attention of dense inputs -> sparse inputs - - Arguments: - config (`SamMaskDecoderConfig`): - The configuration file used to instantiate the block - attention_downsample_rate (*optionalk*, int, defaults to 2): - The downsample ratio of the block used to reduce the inner dim of the attention. - skip_first_layer_pe (*optional*, bool, defaults to `False`): - Whether or not to skip the addition of the query_point_embedding on the first layer. - """ - super().__init__(**kwargs) - - self.hidden_size = config.hidden_size - self.layer_norm_eps = config.layer_norm_eps - - self.self_attn = TFSamAttention(config, downsample_rate=1, name="self_attn") - self.layer_norm1 = keras.layers.LayerNormalization(epsilon=self.layer_norm_eps, name="layer_norm1") - - self.cross_attn_token_to_image = TFSamAttention( - config, downsample_rate=attention_downsample_rate, name="cross_attn_token_to_image" - ) - self.layer_norm2 = keras.layers.LayerNormalization(epsilon=self.layer_norm_eps, name="layer_norm2") - - self.mlp = TFSamMLPBlock(config, name="mlp") - self.layer_norm3 = keras.layers.LayerNormalization(epsilon=self.layer_norm_eps, name="layer_norm3") - - self.layer_norm4 = keras.layers.LayerNormalization(epsilon=self.layer_norm_eps, name="layer_norm4") - self.cross_attn_image_to_token = TFSamAttention( - config, downsample_rate=attention_downsample_rate, name="cross_attn_image_to_token" - ) - - self.skip_first_layer_pe = skip_first_layer_pe - - def call( - self, - queries: tf.Tensor, - keys: tf.Tensor, - query_point_embedding: tf.Tensor, - key_point_embedding: tf.Tensor, - output_attentions: bool = False, - ): - # Self attention block - if self.skip_first_layer_pe: - queries = self.self_attn(query=queries, key=queries, value=queries) - else: - query = queries + query_point_embedding - attn_out = self.self_attn(query=query, key=query, value=queries) - queries = queries + attn_out - queries = self.layer_norm1(queries) - - # Cross attention block, tokens attending to image embedding - query = queries + query_point_embedding - key = keys + key_point_embedding - - attn_out = self.cross_attn_token_to_image(query=query, key=key, value=keys) - queries = queries + attn_out - - queries = self.layer_norm2(queries) - - # MLP block - mlp_out = self.mlp(queries) - queries = queries + mlp_out - queries = self.layer_norm3(queries) - - # Cross attention block, image embedding attending to tokens - query = queries + query_point_embedding - key = keys + key_point_embedding - - attn_out = self.cross_attn_image_to_token(query=key, key=query, value=queries) - keys = keys + attn_out - - keys = self.layer_norm4(keys) - - outputs = (queries, keys) - - if output_attentions: - outputs = outputs + (attn_out,) - else: - outputs = outputs + (None,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "layer_norm1", None) is not None: - with tf.name_scope(self.layer_norm1.name): - self.layer_norm1.build([None, None, None, self.hidden_size]) - if getattr(self, "cross_attn_token_to_image", None) is not None: - with tf.name_scope(self.cross_attn_token_to_image.name): - self.cross_attn_token_to_image.build(None) - if getattr(self, "layer_norm2", None) is not None: - with tf.name_scope(self.layer_norm2.name): - self.layer_norm2.build([None, None, None, self.hidden_size]) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - if getattr(self, "layer_norm3", None) is not None: - with tf.name_scope(self.layer_norm3.name): - self.layer_norm3.build([None, None, None, self.hidden_size]) - if getattr(self, "layer_norm4", None) is not None: - with tf.name_scope(self.layer_norm4.name): - self.layer_norm4.build([None, None, None, self.hidden_size]) - if getattr(self, "cross_attn_image_to_token", None) is not None: - with tf.name_scope(self.cross_attn_image_to_token.name): - self.cross_attn_image_to_token.build(None) - - -class TFSamTwoWayTransformer(keras.layers.Layer): - def __init__(self, config: SamMaskDecoderConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - - self.num_hidden_layers = config.num_hidden_layers - self.layers = [] - - for i in range(self.num_hidden_layers): - self.layers.append(TFSamTwoWayAttentionBlock(config, skip_first_layer_pe=(i == 0), name=f"layers_._{i}")) - - self.final_attn_token_to_image = TFSamAttention(config, name="final_attn_token_to_image") - self.layer_norm_final_attn = keras.layers.LayerNormalization( - epsilon=config.layer_norm_eps, name="layer_norm_final_attn" - ) - - def call( - self, - point_embeddings: tf.Tensor, - image_embeddings: tf.Tensor, - image_positional_embeddings: tf.Tensor, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - ) -> tuple | TFBaseModelOutput: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - all_attentions = () - - if image_embeddings is None: - raise ValueError("You have to specify an image_embedding") - - image_embeddings = tf.transpose(flatten(image_embeddings, 2), perm=(0, 2, 1))[:, None] - image_positional_embeddings = tf.transpose(flatten(image_positional_embeddings, 2), (0, 2, 1))[:, None] - - # Prepare queries - queries = point_embeddings - keys = image_embeddings - - # Apply transformer blocks and final layernorm - for layer in self.layers: - queries, keys, attention_outputs = layer( - queries=queries, - keys=keys, - query_point_embedding=point_embeddings, - key_point_embedding=image_positional_embeddings, - output_attentions=output_attentions, - ) - - if output_attentions: - all_attentions = all_attentions + (attention_outputs,) - - # Apply the final attention layer from the points to the image - query = queries + point_embeddings - key = keys + image_positional_embeddings - - attn_out = self.final_attn_token_to_image(query=query, key=key, value=keys) - - queries = queries + attn_out - queries = self.layer_norm_final_attn(queries) - return queries, keys, all_attentions - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "final_attn_token_to_image", None) is not None: - with tf.name_scope(self.final_attn_token_to_image.name): - self.final_attn_token_to_image.build(None) - if getattr(self, "layer_norm_final_attn", None) is not None: - with tf.name_scope(self.layer_norm_final_attn.name): - self.layer_norm_final_attn.build([None, None, None, self.config.hidden_size]) - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFSamFeedForward(keras.layers.Layer): - def __init__( - self, input_dim: int, hidden_dim: int, output_dim: int, num_layers: int, sigmoid_output: bool = False, **kwargs - ): - super().__init__(**kwargs) - self.num_layers = num_layers - self.activation = keras.layers.ReLU() - self.proj_in = keras.layers.Dense(hidden_dim, input_shape=(input_dim,), name="proj_in") - self.proj_out = keras.layers.Dense(output_dim, input_shape=(hidden_dim,), name="proj_out") - self.layers = [ - keras.layers.Dense(hidden_dim, input_shape=(hidden_dim,), name=f"layers_._{i}") - for i in range(num_layers - 2) - ] - self.sigmoid_output = sigmoid_output - self.hidden_dim = hidden_dim - self.input_dim = input_dim - - def call(self, hidden_states): - hidden_states = self.proj_in(hidden_states) - hidden_states = self.activation(hidden_states) - for layer in self.layers: - hidden_states = self.activation(layer(hidden_states)) - - hidden_states = self.proj_out(hidden_states) - if self.sigmoid_output: - hidden_states = tf.sigmoid(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "proj_in", None) is not None: - with tf.name_scope(self.proj_in.name): - self.proj_in.build([None, None, self.input_dim]) - if getattr(self, "proj_out", None) is not None: - with tf.name_scope(self.proj_out.name): - self.proj_out.build([None, None, self.hidden_dim]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build([None, None, self.hidden_dim]) - - -class TFSamMaskDecoder(keras.layers.Layer): - def __init__(self, config: SamMaskDecoderConfig, **kwargs): - super().__init__(**kwargs) - - self.hidden_size = config.hidden_size - - self.num_multimask_outputs = config.num_multimask_outputs - self.num_mask_tokens = config.num_multimask_outputs + 1 - - self.transformer = TFSamTwoWayTransformer(config, name="transformer") - - self.upscale_conv1 = keras.layers.Conv2DTranspose( - self.hidden_size // 4, kernel_size=2, strides=2, name="upscale_conv1", data_format="channels_first" - ) - self.upscale_conv2 = keras.layers.Conv2DTranspose( - self.hidden_size // 8, kernel_size=2, strides=2, name="upscale_conv2", data_format="channels_first" - ) - self.upscale_layer_norm = TFSamLayerNorm( - self.hidden_size // 4, data_format="channels_first", name="upscale_layer_norm" - ) - self.activation = tf.nn.gelu - - mlps_list = [] - for i in range(self.num_mask_tokens): - mlps_list += [ - TFSamFeedForward( - self.hidden_size, - self.hidden_size, - self.hidden_size // 8, - 3, - name=f"output_hypernetworks_mlps_._{i}", - ) - ] - self.output_hypernetworks_mlps = mlps_list - - self.iou_prediction_head = TFSamFeedForward( - self.hidden_size, - config.iou_head_hidden_dim, - self.num_mask_tokens, - config.iou_head_depth, - name="iou_prediction_head", - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - self.iou_token = self.add_weight(shape=(1, self.hidden_size), name="iou_token.weight", trainable=True) - self.mask_tokens = self.add_weight( - shape=(self.num_mask_tokens, self.hidden_size), name="mask_tokens.weight", trainable=True - ) - - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "upscale_conv1", None) is not None: - with tf.name_scope(self.upscale_conv1.name): - self.upscale_conv1.build([None, self.hidden_size, None, None]) - if getattr(self, "upscale_conv2", None) is not None: - with tf.name_scope(self.upscale_conv2.name): - self.upscale_conv2.build([None, self.hidden_size // 4, None, None]) - if getattr(self, "upscale_layer_norm", None) is not None: - with tf.name_scope(self.upscale_layer_norm.name): - self.upscale_layer_norm.build(None) - if getattr(self, "iou_prediction_head", None) is not None: - with tf.name_scope(self.iou_prediction_head.name): - self.iou_prediction_head.build(None) - for mlp in self.output_hypernetworks_mlps: - with tf.name_scope(mlp.name): - mlp.build(None) - - def call( - self, - image_embeddings: tf.Tensor, - image_positional_embeddings: tf.Tensor, - sparse_prompt_embeddings: tf.Tensor, - dense_prompt_embeddings: tf.Tensor, - multimask_output: bool, - output_attentions: bool | None = None, - ) -> tuple[tf.Tensor, tf.Tensor]: - batch_size, num_channels, height, width = shape_list(image_embeddings) - point_batch_size = tf.math.maximum(1, tf.shape(sparse_prompt_embeddings)[1]) - - output_tokens = tf.concat([self.iou_token, self.mask_tokens], axis=0) # Should be (1, 32) + (4, 32) = (5, 32) - output_tokens = tf.tile( - output_tokens[None, None, :], [batch_size, point_batch_size, 1, 1] - ) # Should be (batch_size, point_size, 5, 32) - - # Matt: The original Torch code checked that the sum of sparse_prompt_embeddings equalled 0. However, this only - # happens when the sparse prompt embeddings are an empty tensor with shape[1] == 0. I replaced - # it with an explicit shape check to avoid data-dependent control flow which breaks XLA. - if shape_list(sparse_prompt_embeddings)[1] != 0: - tokens = tf.concat((output_tokens, sparse_prompt_embeddings), axis=2) - else: - tokens = output_tokens - point_embeddings = tf.cast(tokens, self.iou_token.dtype) - - image_embeddings = image_embeddings + dense_prompt_embeddings - image_embeddings = tf.repeat(image_embeddings, point_batch_size, axis=0) - image_positional_embeddings = tf.repeat(image_positional_embeddings, point_batch_size, axis=0) - - point_embedding, image_embeddings, attentions = self.transformer( - point_embeddings=point_embeddings, - image_embeddings=image_embeddings, - image_positional_embeddings=image_positional_embeddings, - output_attentions=output_attentions, - ) - iou_token_out = point_embedding[:, :, 0, :] - mask_tokens_out = point_embedding[:, :, 1 : (1 + self.num_mask_tokens), :] - - image_embeddings = tf.transpose(image_embeddings, perm=(0, 1, 3, 2)) - image_embeddings = tf.reshape(image_embeddings, [batch_size * point_batch_size, num_channels, height, width]) - - upscaled_embedding = self.upscale_conv1(image_embeddings) - upscaled_embedding = self.activation(self.upscale_layer_norm(upscaled_embedding)) - upscaled_embedding = self.activation(self.upscale_conv2(upscaled_embedding)) - - hyper_in_list = [] - for i in range(self.num_mask_tokens): - current_mlp = self.output_hypernetworks_mlps[i] - hyper_in_list += [current_mlp(mask_tokens_out[:, :, i, :])] - hyper_in = tf.stack(hyper_in_list, axis=2) - - _, num_channels, height, width = shape_list(upscaled_embedding) - upscaled_embedding = tf.reshape( - upscaled_embedding, [batch_size, point_batch_size, num_channels, height * width] - ) - masks = tf.reshape(hyper_in @ upscaled_embedding, [batch_size, point_batch_size, -1, height, width]) - - iou_pred = self.iou_prediction_head(iou_token_out) - - if multimask_output: - mask_slice = slice(1, None) - else: - mask_slice = slice(0, 1) - masks = masks[:, :, mask_slice, :, :] - iou_pred = iou_pred[:, :, mask_slice] - - outputs = (masks, iou_pred) - - if output_attentions: - outputs = outputs + (attentions,) - else: - outputs = outputs + (None,) - - return outputs - - -class TFSamPositionalEmbedding(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.scale = config.hidden_size // 2 - self.config = config - - def build(self, input_shape): - # TODO Matt: What is going on here? Why is a non-trainable weight randomly initialized? - self.positional_embedding = self.add_weight( - name="positional_embedding", - shape=(2, self.config.num_pos_feats), - initializer=keras.initializers.RandomNormal(mean=0.0, stddev=self.scale), - trainable=False, - ) - super().build(input_shape) - - def call(self, input_coords, input_shape=None): - """Positionally encode points that are normalized to [0,1].""" - coordinates = tf.identity(input_coords) - - if input_shape is not None: - coordinates = tf.stack( - [ - tf.cast(coordinates[:, :, :, 0], tf.float32) / input_shape[1], - tf.cast(coordinates[:, :, :, 1], tf.float32) / input_shape[0], - ], - axis=-1, - ) - - # assuming coords are in [0, 1]^2 square and have d_1 x ... x d_n x 2 shape - coordinates = 2 * coordinates - 1 - coordinates = tf.cast(coordinates, self.positional_embedding.dtype) - coordinates = tf.matmul(coordinates, self.positional_embedding) - coordinates = 2 * np.pi * coordinates - # outputs d_1 x ... x d_n x channel shape - return tf.concat([tf.sin(coordinates), tf.cos(coordinates)], axis=-1) - - -class TFSamMaskEmbedding(keras.layers.Layer): - def __init__(self, config: SamPromptEncoderConfig, **kwargs): - super().__init__(**kwargs) - self.mask_input_channels = config.mask_input_channels // 4 - self.activation = ACT2FN[config.hidden_act] - self.conv1 = keras.layers.Conv2D(self.mask_input_channels, kernel_size=2, strides=2, name="conv1") - self.conv2 = keras.layers.Conv2D(config.mask_input_channels, kernel_size=2, strides=2, name="conv2") - self.conv3 = keras.layers.Conv2D(config.hidden_size, kernel_size=1, name="conv3") - self.layer_norm1 = TFSamLayerNorm(self.mask_input_channels, config.layer_norm_eps, name="layer_norm1") - self.layer_norm2 = TFSamLayerNorm(self.mask_input_channels * 4, config.layer_norm_eps, name="layer_norm2") - self.config = config - - def call(self, masks): - masks = tf.transpose(masks, perm=(0, 2, 3, 1)) # Convert to channels-last - hidden_states = self.conv1(masks) - hidden_states = self.layer_norm1(hidden_states) - hidden_states = self.activation(hidden_states) - - hidden_states = self.conv2(hidden_states) - hidden_states = self.layer_norm2(hidden_states) - hidden_states = self.activation(hidden_states) - dense_embeddings = self.conv3(hidden_states) - dense_embeddings = tf.transpose(dense_embeddings, perm=(0, 3, 1, 2)) # Convert back to channels-first - return dense_embeddings - - def build(self, input_shape=None): - # This class needs an explicit build method because it isn't called with the standard dummy inputs - if self.built: - return - self.built = True - with tf.name_scope("conv1"): - self.conv1.build([None, None, None, 1]) - with tf.name_scope("conv2"): - self.conv2.build([None, None, None, self.mask_input_channels]) - with tf.name_scope("conv3"): - self.conv3.build([None, None, None, self.mask_input_channels * 4]) - with tf.name_scope("layer_norm1"): - self.layer_norm1.build([None, None, None, self.mask_input_channels]) - with tf.name_scope("layer_norm2"): - self.layer_norm2.build([None, None, None, self.mask_input_channels * 4]) - - -class TFSamPromptEncoder(keras.layers.Layer): - def __init__(self, config: SamPromptEncoderConfig, shared_patch_embedding, **kwargs): - super().__init__(**kwargs) - self.shared_embedding = shared_patch_embedding - self.mask_embed = TFSamMaskEmbedding(config, name="mask_embed") - self.no_mask_embed = None - - self.image_embedding_size = (config.image_embedding_size, config.image_embedding_size) - self.input_image_size = config.image_size - - self.point_embed = [] - self.hidden_size = config.hidden_size - self.not_a_point_embed = None - self.config = config - - def build(self, input_shape=None): - self.no_mask_embed = self.add_weight( - name="no_mask_embed.weight", - shape=(1, self.hidden_size), - initializer=keras.initializers.RandomNormal(mean=0.0, stddev=0.02), - trainable=True, - ) - self.point_embed = [ - self.add_weight( - name=f"point_embed_._{i}.weight", - shape=(1, self.hidden_size), - initializer=keras.initializers.RandomNormal(mean=0.0, stddev=0.02), - trainable=True, - ) - for i in range(self.config.num_point_embeddings) - ] - self.not_a_point_embed = self.add_weight( - name="not_a_point_embed.weight", - shape=(1, self.hidden_size), - initializer=keras.initializers.RandomNormal(mean=0.0, stddev=0.02), - trainable=True, - ) - with tf.name_scope("mask_embed"): - # We must explicitly build the mask embed because it isn't touched by the standard dummy inputs - self.mask_embed.build( - (None, self.config.mask_input_channels, self.config.image_size, self.config.image_size) - ) - - if self.built: - return - self.built = True - if getattr(self, "mask_embed", None) is not None: - with tf.name_scope(self.mask_embed.name): - self.mask_embed.build(None) - - def _embed_points(self, points: tf.Tensor, labels: tf.Tensor, pad: bool) -> tf.Tensor: - """Embeds point prompts.""" - points = points + 0.5 # Shift to center of pixel - if pad: - target_point_shape = (shape_list(points)[0], shape_list(points)[1], 1, shape_list(points)[-1]) - target_labels_shape = (shape_list(points)[0], shape_list(points)[1], 1) - padding_point = tf.zeros(target_point_shape, dtype=points.dtype) - padding_label = -tf.ones(target_labels_shape, dtype=labels.dtype) - points = tf.concat([points, padding_point], axis=2) - labels = tf.concat([labels, padding_label], axis=2) - input_shape = (self.input_image_size, self.input_image_size) - point_embedding = self.shared_embedding(points, input_shape) - - point_embedding = tf.where(labels[..., None] == -1, self.not_a_point_embed[0], point_embedding) - - point_embedding = tf.where( - labels[..., None] != -10, - point_embedding, - tf.zeros_like(point_embedding), - ) - point_embedding = tf.where( - (labels == 0)[:, :, :, None], point_embedding + self.point_embed[0], point_embedding - ) - point_embedding = tf.where( - (labels == 1)[:, :, :, None], point_embedding + self.point_embed[1], point_embedding - ) - return point_embedding - - def _embed_boxes(self, boxes: tf.Tensor) -> tf.Tensor: - """Embeds box prompts.""" - boxes = boxes + 0.5 # Shift to center of pixel - batch_size, nb_boxes = shape_list(boxes)[:2] - coords = tf.reshape(boxes, (batch_size, nb_boxes, 2, 2)) - input_shape = (self.input_image_size, self.input_image_size) - corner_embedding = self.shared_embedding(coords, input_shape) - corner_embedding += tf.where( - tf.range(shape_list(corner_embedding)[2])[None, None, :, None] == 0, - self.point_embed[2][0], - self.point_embed[3][0], - ) - return corner_embedding - - def call( - self, - batch_size: int | None, - input_points: tuple[tf.Tensor, tf.Tensor] | None, - input_labels: tf.Tensor | None, - input_boxes: tf.Tensor | None, - input_masks: tf.Tensor | None, - ) -> tuple[tf.Tensor, tf.Tensor]: - """ - Embeds different types of prompts, returning both sparse and dense embeddings. - - Args: - points (`tf.Tensor`, *optional*): - point coordinates and labels to embed. - boxes (`tf.Tensor`, *optional*): - boxes to embed - masks (`tf.Tensor`, *optional*): - masks to embed - """ - sparse_embeddings = None - if input_points is not None: - batch_size, point_batch_size = shape_list(input_points)[:2] - if input_labels is None: - raise ValueError("If points are provided, labels must also be provided.") - point_embeddings = self._embed_points(input_points, input_labels, pad=(input_boxes is None)) - sparse_embeddings = tf.zeros( - (batch_size, point_batch_size, 0, self.hidden_size), dtype=point_embeddings.dtype - ) - sparse_embeddings = tf.concat([sparse_embeddings, point_embeddings], axis=2) - if input_boxes is not None: - batch_size = shape_list(input_boxes)[0] - box_embeddings = self._embed_boxes(input_boxes) - if sparse_embeddings is None: - sparse_embeddings = box_embeddings - else: - sparse_embeddings = tf.concat([sparse_embeddings, box_embeddings], axis=2) - if input_masks is not None: - dense_embeddings = self.mask_embed(input_masks) - else: - dense_embeddings = self.no_mask_embed[0] - dense_embeddings = tf.reshape(dense_embeddings, (1, -1, 1, 1)) - dense_embeddings = tf.tile( - dense_embeddings, (batch_size, 1, self.image_embedding_size[0], self.image_embedding_size[1]) - ) - if sparse_embeddings is None: - sparse_embeddings = tf.zeros((batch_size, 0, 1, self.hidden_size), dtype=dense_embeddings.dtype) - - return sparse_embeddings, dense_embeddings - - -class TFSamVisionAttention(keras.layers.Layer): - """Multi-head Attention block with relative position embeddings.""" - - def __init__(self, config, window_size, **kwargs): - super().__init__(**kwargs) - input_size = ( - (config.image_size // config.patch_size, config.image_size // config.patch_size) - if window_size == 0 - else (window_size, window_size) - ) - self.input_size = input_size - - self.num_attention_heads = config.num_attention_heads - head_dim = config.hidden_size // config.num_attention_heads - self.head_dim = head_dim - self.scale = head_dim**-0.5 - self.dropout = config.attention_dropout - - self.qkv = keras.layers.Dense(config.hidden_size * 3, use_bias=config.qkv_bias, name="qkv") - self.proj = keras.layers.Dense(config.hidden_size, name="proj") - - self.use_rel_pos = config.use_rel_pos - if self.use_rel_pos: - if input_size is None: - raise ValueError("Input size must be provided if using relative positional encoding.") - self.config = config - - def build(self, input_shape=None): - if self.input_size is not None: - # initialize relative positional embeddings - self.rel_pos_h = self.add_weight( - shape=(2 * self.input_size[0] - 1, self.head_dim), initializer="zeros", name="rel_pos_h" - ) - self.rel_pos_w = self.add_weight( - shape=(2 * self.input_size[1] - 1, self.head_dim), initializer="zeros", name="rel_pos_w" - ) - - if self.built: - return - self.built = True - if getattr(self, "qkv", None) is not None: - with tf.name_scope(self.qkv.name): - self.qkv.build([None, None, self.config.hidden_size]) - if getattr(self, "proj", None) is not None: - with tf.name_scope(self.proj.name): - self.proj.build([None, None, self.config.hidden_size]) - - def get_rel_pos(self, q_size: int, k_size: int, rel_pos: tf.Tensor) -> tf.Tensor: - """ - Get relative positional embeddings according to the relative positions of - query and key sizes. - - Args: - q_size (int): - size of the query. - k_size (int): - size of key k. - rel_pos (`tf.Tensor`): - relative position embeddings (L, channel). - - Returns: - Extracted positional embeddings according to relative positions. - """ - max_rel_dist = int(2 * max(q_size, k_size) - 1) - # Interpolate rel pos if needed. - if rel_pos.shape[0] != max_rel_dist: - # Interpolate rel pos. - rel_pos_resized = tf.image.resize( - tf.reshape(rel_pos, (1, rel_pos.shape[0], -1)), - size=(max_rel_dist, rel_pos.shape[1]), - method="bilinear", - ) - rel_pos_resized = tf.reshape(rel_pos_resized, (-1, max_rel_dist)) - else: - rel_pos_resized = rel_pos - - # Scale the coords with short length if shapes for q and k are different. - q_coords = tf.expand_dims(tf.range(q_size, dtype=tf.float32), 1) * max(k_size / q_size, 1.0) - k_coords = tf.expand_dims(tf.range(k_size, dtype=tf.float32), 0) * max(q_size / k_size, 1.0) - relative_coords = (q_coords - k_coords) + (k_size - 1) * max(q_size / k_size, 1.0) - - return tf.gather(rel_pos_resized, tf.cast(relative_coords, tf.int32)) - - def get_decomposed_rel_pos( - self, - query: tf.Tensor, - rel_pos_h: tf.Tensor, - rel_pos_w: tf.Tensor, - q_size: tuple[int, int], - k_size: tuple[int, int], - ) -> tf.Tensor: - """ - Calculate decomposed Relative Positional Embeddings from :paper:`mvitv2`. - https://github.com/facebookresearch/mvit/blob/19786631e330df9f3622e5402b4a419a263a2c80/mvit/models/attention.py - - Args: - query (`tf.Tensor`): - query q in the attention layer with shape (batch_size, query_height * query_width, channel). - rel_pos_h (`tf.Tensor`): - relative position embeddings (Lh, channel) for height axis. - rel_pos_w (`tf.Tensor`): - relative position embeddings (Lw, channel) for width axis. - q_size (tuple): - spatial sequence size of query q with (query_height, query_width). - k_size (tuple): - spatial sequence size of key k with (key_height, key_width). - - Returns: - decomposed_rel_pos (`torch.Tensor`): - decomposed relative position embeddings. - """ - query_height, query_width = q_size - key_height, key_width = k_size - relative_position_height = self.get_rel_pos(query_height, key_height, rel_pos_h) - relative_position_width = self.get_rel_pos(query_width, key_width, rel_pos_w) - - batch_size, _, dim = shape_list(query) - reshaped_query = tf.reshape(query, (batch_size, query_height, query_width, dim)) - rel_h = tf.einsum("bhwc,hkc->bhwk", reshaped_query, relative_position_height) - rel_w = tf.einsum("bhwc,wkc->bhwk", reshaped_query, relative_position_width) - - rel_h = tf.expand_dims(rel_h, axis=-1) - rel_w = tf.expand_dims(rel_w, axis=-2) - decomposed_rel_pos = rel_h + rel_w - - return decomposed_rel_pos - - def call(self, hidden_states: tf.Tensor, output_attentions=False, training=False) -> tf.Tensor: - batch_size, height, width, _ = shape_list(hidden_states) - # qkv with shape (3, batch_size, nHead, height * width, channel) - qkv = tf.reshape(self.qkv(hidden_states), (batch_size, height * width, 3, self.num_attention_heads, -1)) - qkv = tf.transpose(qkv, perm=(2, 0, 3, 1, 4)) - # q, k, v with shape (batch_size * nHead, height * width, channel) - query, key, value = tf.unstack( - tf.reshape(qkv, (3, batch_size * self.num_attention_heads, height * width, -1)), axis=0 - ) - attn_weights = tf.matmul(query * self.scale, key, transpose_b=True) - - if self.use_rel_pos: - decomposed_rel_pos = self.get_decomposed_rel_pos( - query, self.rel_pos_h, self.rel_pos_w, (height, width), (height, width) - ) - decomposed_rel_pos = tf.reshape(decomposed_rel_pos, shape_list(attn_weights)) - attn_weights = attn_weights + decomposed_rel_pos - - attn_weights = tf.nn.softmax(attn_weights, axis=-1) - - if training: - attn_probs = tf.nn.dropout(attn_weights, rate=self.dropout) - else: - attn_probs = attn_weights - - attn_output = tf.reshape(attn_probs @ value, (batch_size, self.num_attention_heads, height, width, -1)) - attn_output = tf.transpose(attn_output, perm=(0, 2, 3, 1, 4)) - attn_output = tf.reshape(attn_output, (batch_size, height, width, self.config.hidden_size)) - - attn_output = self.proj(attn_output) - - if output_attentions: - outputs = (attn_output, attn_weights) - else: - outputs = (attn_output, None) - - return outputs - - -class TFSamVisionLayer(keras.layers.Layer): - def __init__(self, config, window_size, **kwargs): - super().__init__(**kwargs) - self.layer_norm1 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm1") - self.attn = TFSamVisionAttention(config, window_size, name="attn") - self.layer_norm2 = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm2") - self.mlp = TFSamMLPBlock(config, name="mlp") - self.window_size = window_size - self.config = config - - def window_partition(self, hidden_states: tf.Tensor, window_size: int) -> tuple[tf.Tensor, tuple[int, int]]: - batch_size, height, width, channel = shape_list(hidden_states) - - pad_h = (window_size - height % window_size) % window_size - pad_w = (window_size - width % window_size) % window_size - if pad_h > 0 or pad_w > 0: - hidden_states = tf.pad(hidden_states, [[0, 0], [0, pad_h], [0, pad_w], [0, 0]]) - pad_height, pad_width = height + pad_h, width + pad_w - - hidden_states = tf.reshape( - hidden_states, - [batch_size, pad_height // window_size, window_size, pad_width // window_size, window_size, channel], - ) - windows = tf.reshape( - tf.transpose(hidden_states, perm=[0, 1, 3, 2, 4, 5]), [-1, window_size, window_size, channel] - ) - return windows, (pad_height, pad_width) - - def window_unpartition( - self, windows: tf.Tensor, window_size: int, padding_shape: tuple[int, int], original_shape: tuple[int, int] - ) -> tf.Tensor: - pad_height, pad_width = padding_shape - height, width = original_shape - batch_size = shape_list(windows)[0] // (pad_height * pad_width // window_size // window_size) - hidden_states = tf.reshape( - windows, [batch_size, pad_height // window_size, pad_width // window_size, window_size, window_size, -1] - ) - hidden_states = tf.reshape( - tf.transpose(hidden_states, perm=[0, 1, 3, 2, 4, 5]), [batch_size, pad_height, pad_width, -1] - ) - - if pad_height > height or pad_width > width: - hidden_states = hidden_states[:, :height, :width, :] - return hidden_states - - def call( - self, - hidden_states: tf.Tensor, - output_attentions: bool | None = False, - training: bool | None = False, - ) -> tuple[tf.Tensor]: - residual = hidden_states - - hidden_states = self.layer_norm1(hidden_states) - if self.window_size > 0: - height, width = hidden_states.shape[1], hidden_states.shape[2] - hidden_states, padding_shape = self.window_partition(hidden_states, self.window_size) - - hidden_states, attn_weights = self.attn( - hidden_states=hidden_states, - output_attentions=output_attentions, - training=training, - ) - if self.window_size > 0: - hidden_states = self.window_unpartition(hidden_states, self.window_size, padding_shape, (height, width)) - - hidden_states = residual + hidden_states - layernorm_output = self.layer_norm2(hidden_states) - hidden_states = hidden_states + self.mlp(layernorm_output) - - outputs = (hidden_states,) - if output_attentions: - outputs += (attn_weights,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer_norm1", None) is not None: - with tf.name_scope(self.layer_norm1.name): - self.layer_norm1.build([None, None, None, self.config.hidden_size]) - if getattr(self, "attn", None) is not None: - with tf.name_scope(self.attn.name): - self.attn.build(None) - if getattr(self, "layer_norm2", None) is not None: - with tf.name_scope(self.layer_norm2.name): - self.layer_norm2.build([None, None, None, self.config.hidden_size]) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - - -class TFSamVisionNeck(keras.layers.Layer): - def __init__(self, config: SamVisionConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - - self.conv1 = keras.layers.Conv2D( - config.output_channels, - kernel_size=1, - use_bias=False, - name="conv1", - ) - self.layer_norm1 = TFSamLayerNorm(config.output_channels, name="layer_norm1") - self.conv2 = keras.layers.Conv2D( - config.output_channels, - kernel_size=3, - padding="same", - use_bias=False, - name="conv2", - ) - self.layer_norm2 = TFSamLayerNorm(config.output_channels, name="layer_norm2") - - def call(self, hidden_states): - hidden_states = self.conv1(hidden_states) - hidden_states = self.layer_norm1(hidden_states) - - hidden_states = self.conv2(hidden_states) - hidden_states = self.layer_norm2(hidden_states) - hidden_states = tf.transpose(hidden_states, perm=[0, 3, 1, 2]) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv1", None) is not None: - with tf.name_scope(self.conv1.name): - self.conv1.build([None, None, None, self.config.hidden_size]) - if getattr(self, "layer_norm1", None) is not None: - with tf.name_scope(self.layer_norm1.name): - self.layer_norm1.build(None) - if getattr(self, "conv2", None) is not None: - with tf.name_scope(self.conv2.name): - self.conv2.build([None, None, None, self.config.output_channels]) - if getattr(self, "layer_norm2", None) is not None: - with tf.name_scope(self.layer_norm2.name): - self.layer_norm2.build(None) - - -class TFSamVisionEncoder(keras.layers.Layer): - def __init__(self, config: SamVisionConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.image_size = config.image_size - - self.patch_embed = TFSamPatchEmbeddings(config, name="patch_embed") - - self.pos_embed = None - - self.layers = [] - for i in range(config.num_hidden_layers): - layer = TFSamVisionLayer( - config, - window_size=config.window_size if i not in config.global_attn_indexes else 0, - name=f"layers_._{i}", - ) - self.layers.append(layer) - - self.neck = TFSamVisionNeck(config, name="neck") - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if self.config.use_abs_pos: - # Initialize absolute positional embedding with pretrain image size. - self.pos_embed = self.add_weight( - shape=[ - 1, - self.config.image_size // self.config.patch_size, - self.config.image_size // self.config.patch_size, - self.config.hidden_size, - ], - initializer="zeros", - trainable=True, - name="pos_embed", - ) - - if getattr(self, "patch_embed", None) is not None: - with tf.name_scope(self.patch_embed.name): - self.patch_embed.build(None) - if getattr(self, "neck", None) is not None: - with tf.name_scope(self.neck.name): - self.neck.build(None) - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - def get_input_embeddings(self): - return self.patch_embed - - def call( - self, - pixel_values: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFSamVisionEncoderOutput: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - hidden_states = self.patch_embed(pixel_values) - if self.pos_embed is not None: - hidden_states = hidden_states + self.pos_embed - - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - - for i, layer_module in enumerate(self.layers): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module(hidden_states, output_attentions=output_attentions, training=training) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - hidden_states = self.neck(hidden_states) - - if not return_dict: - outputs = (hidden_states,) - if output_hidden_states: - outputs = outputs + (all_hidden_states,) - if output_attentions: - outputs = outputs + (all_self_attentions,) - return outputs - - return TFSamVisionEncoderOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - ) - - -class TFSamPreTrainedModel(TFPreTrainedModel): - config_class = SamConfig - base_model_prefix = "sam" - main_input_name = "pixel_values" - - -SAM_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a TensorFlow [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) - subclass. Use it as a regular TensorFlow Model and refer to the TensorFlow documentation for all matter related to - general usage and behavior. - - Parameters: - config ([`SamConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - - -SAM_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`SamProcessor`]. See [`SamProcessor.__call__`] for - details. - input_points (`tf.Tensor` of shape `(batch_size, num_points, 2)`): - Input 2D spatial points, this is used by the prompt encoder to encode the prompt. Generally yields to much - better results. The points can be obtained by passing a list of list of list to the processor that will - create corresponding `tf` tensors of dimension 4. The first dimension is the image batch size, the second - dimension is the point batch size (i.e. how many segmentation masks do we want the model to predict per - input point), the third dimension is the number of points per segmentation mask (it is possible to pass - multiple points for a single mask), and the last dimension is the x (vertical) and y (horizontal) - coordinates of the point. If a different number of points is passed either for each image, or for each - mask, the processor will create "PAD" points that will correspond to the (0, 0) coordinate, and the - computation of the embedding will be skipped for these points using the labels. - input_labels (`tf.Tensor` of shape `(batch_size, point_batch_size, num_points)`): - Input labels for the points, this is used by the prompt encoder to encode the prompt. According to the - official implementation, there are 3 types of labels - - - `1`: the point is a point that contains the object of interest - - `0`: the point is a point that does not contain the object of interest - - `-1`: the point corresponds to the background - - We added the label: - - - `-10`: the point is a padding point, thus should be ignored by the prompt encoder - - The padding labels should be automatically done by the processor. - input_boxes (`tf.Tensor` of shape `(batch_size, num_boxes, 4)`): - Input boxes for the points, this is used by the prompt encoder to encode the prompt. Generally yields to - much better generated masks. The boxes can be obtained by passing a list of list of list to the processor, - that will generate a `tf` tensor, with each dimension corresponding respectively to the image batch size, - the number of boxes per image and the coordinates of the top left and bottom right point of the box. In the - order (`x1`, `y1`, `x2`, `y2`): - - - `x1`: the x coordinate of the top left point of the input box - - `y1`: the y coordinate of the top left point of the input box - - `x2`: the x coordinate of the bottom right point of the input box - - `y2`: the y coordinate of the bottom right point of the input box - - input_masks (`tf.Tensor` of shape `(batch_size, image_size, image_size)`): - SAM model also accepts segmentation masks as input. The mask will be embedded by the prompt encoder to - generate a corresponding embedding, that will be fed later on to the mask decoder. These masks needs to be - manually fed by the user, and they need to be of shape (`batch_size`, `image_size`, `image_size`). - - image_embeddings (`tf.Tensor` of shape `(batch_size, output_channels, window_size, window_size)`): - Image embeddings, this is used by the mask decder to generate masks and iou scores. For more memory - efficient computation, users can first retrieve the image embeddings using the `get_image_embeddings` - method, and then feed them to the `call` method instead of feeding the `pixel_values`. - multimask_output (`bool`, *optional*): - In the original implementation and paper, the model always outputs 3 masks per image (or per point / per - bounding box if relevant). However, it is possible to just output a single mask, that corresponds to the - "best" mask, by specifying `multimask_output=False`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -SAM_VISION_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`SamProcessor`]. See [`SamProcessor.__call__`] for - details. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@add_start_docstrings( - """The vision model from Sam without any head or projection on top.""", - SAM_START_DOCSTRING, -) -class TFSamVisionModel(TFSamPreTrainedModel): - config_class = SamVisionConfig - main_input_name = "pixel_values" - - def __init__(self, config: SamVisionConfig, **kwargs): - super().__init__(config, **kwargs) - self.vision_encoder = TFSamVisionEncoder(config, name="vision_encoder") - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "vision_encoder", None) is not None: - with tf.name_scope(self.vision_encoder.name): - self.vision_encoder.build(None) - - def get_input_embeddings(self): - return self.vision_encoder.patch_embed - - @unpack_inputs - @add_start_docstrings_to_model_forward(SAM_VISION_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSamVisionEncoderOutput, config_class=SamVisionConfig) - def call( - self, - pixel_values: TFModelInputType | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ) -> TFSamVisionEncoderOutput | tuple[tf.Tensor]: - r""" - Returns: - - """ - return self.vision_encoder( - pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - -@add_start_docstrings( - "Segment Anything Model (SAM) for generating segmentation masks, given an input image and ", - " optional 2D location and bounding boxes.", - SAM_START_DOCSTRING, -) -class TFSamModel(TFSamPreTrainedModel): - _keys_to_ignore_on_load_missing = [r"prompt_encoder.shared_embedding.positional_embedding"] - - def __init__(self, config, **kwargs): - super().__init__(config, **kwargs) - self.shared_image_embedding = TFSamPositionalEmbedding(config.vision_config, name="shared_image_embedding") - - self.vision_encoder = TFSamVisionEncoder(config.vision_config, name="vision_encoder") - self.prompt_encoder = TFSamPromptEncoder( - config.prompt_encoder_config, self.shared_image_embedding, name="prompt_encoder" - ) - self.mask_decoder = TFSamMaskDecoder(config.mask_decoder_config, name="mask_decoder") - self.config = config - - def get_input_embeddings(self): - return self.vision_encoder.get_input_embeddings() - - def get_image_wide_positional_embeddings(self): - size = self.config.prompt_encoder_config.image_embedding_size - grid = tf.ones((size, size)) - y_embed = tf.math.cumsum(grid, axis=0) - 0.5 - x_embed = tf.math.cumsum(grid, axis=1) - 0.5 - y_embed = y_embed / size - x_embed = x_embed / size - - positional_embedding = self.shared_image_embedding(tf.stack([x_embed, y_embed], axis=-1)) - return tf.expand_dims(tf.transpose(positional_embedding, perm=[2, 0, 1]), axis=0) # channel x height x width - - def get_image_embeddings( - self, - pixel_values, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - ): - r""" - Returns the image embeddings by passing the pixel values through the vision encoder. - - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Input pixel values - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.TFModelOutput`] instead of a plain tuple. - - """ - vision_output = self.vision_encoder( - pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - image_embeddings = vision_output[0] - return image_embeddings - - def get_prompt_embeddings( - self, - input_points: tf.Tensor | None = None, - input_labels: tf.Tensor | None = None, - input_boxes: tf.Tensor | None = None, - input_masks: tf.Tensor | None = None, - ): - r""" - Returns the prompt embeddings by passing the input points, labels, boxes and masks through the prompt encoder. - - Args: - input_points (`tf.Tensor` of shape `(batch_size, point_batch_size, num_points_per_image, 2)`): - Optional input points for the prompt encoder. The padding of the point is automatically done by the - processor. `point_batch_size` refers to the number of masks that we want the model to predict per - point. The model will output `point_batch_size` times 3 masks in total. - input_labels (`tf.Tensor` of shape `(batch_size, point_batch_size, num_points_per_image)`): - Optional input labels for the prompt encoder. The padding of the labels is automatically done by the - processor, or can be fed by the user. - input_boxes (`tf.Tensor` of shape `(batch_size, num_boxes_per_image, 4)`): - Optional input boxes for the prompt encoder. The padding of the boxes is automatically done by the - processor. users can also pass manually the input boxes. - input_masks (`tf.Tensor` of shape `(batch_size, image_size, image_size)`): - Optional input masks for the prompt encoder. - """ - prompt_output = self.prompt_encoder( - input_points=input_points, - input_labels=input_labels, - input_boxes=input_boxes, - input_masks=input_masks, - ) - return prompt_output - - @unpack_inputs - @add_start_docstrings_to_model_forward(SAM_INPUTS_DOCSTRING) - def call( - self, - pixel_values: TFModelInputType | None = None, - input_points: tf.Tensor | None = None, - input_labels: tf.Tensor | None = None, - input_boxes: tf.Tensor | None = None, - input_masks: tf.Tensor | None = None, - image_embeddings: tf.Tensor | None = None, - multimask_output: bool = True, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ) -> TFSamImageSegmentationOutput | tuple[tf.Tensor]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None and image_embeddings is None: - raise ValueError("Either pixel_values or image_embeddings must be provided.") - - if pixel_values is not None and image_embeddings is not None: - raise ValueError("Only one of pixel_values and image_embeddings can be provided.") - - if input_points is not None and len(input_points.shape) != 4: - raise ValueError( - "The input_points must be a 4D tensor. Of shape `batch_size`, `point_batch_size`, `nb_points_per_image`, `2`.", - f" got {input_points.shape}.", - ) - if input_boxes is not None and len(input_boxes.shape) != 3: - raise ValueError( - "The input_points must be a 3D tensor. Of shape `batch_size`, `nb_boxes`, `4`.", - f" got {input_boxes.shape}.", - ) - if input_points is not None and input_boxes is not None: - point_batch_size = shape_list(input_points)[1] - box_batch_size = shape_list(input_boxes)[1] - if point_batch_size != box_batch_size: - raise ValueError( - f"You should provide as many bounding boxes as input points per box. Got {point_batch_size} and {box_batch_size}." - ) - if pixel_values is not None: - # Ensures that later checks pass even with an all-None shape from the serving signature - pixel_values = tf.ensure_shape( - pixel_values, - [ - None, - self.config.vision_config.num_channels, - self.config.vision_config.image_size, - self.config.vision_config.image_size, - ], - ) - image_positional_embeddings = self.get_image_wide_positional_embeddings() - # repeat with batch size - batch_size = shape_list(pixel_values)[0] if pixel_values is not None else shape_list(image_embeddings)[0] - image_positional_embeddings = tf.repeat(image_positional_embeddings, batch_size, axis=0) - - vision_attentions = None - vision_hidden_states = None - - if pixel_values is not None: - vision_outputs = self.vision_encoder( - pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=True, - training=training, - ) - image_embeddings = vision_outputs["last_hidden_state"] - - if output_hidden_states: - vision_hidden_states = vision_outputs["hidden_states"] - if output_attentions: - vision_attentions = vision_outputs["attentions"] - - if input_points is not None and input_labels is None: - input_labels = tf.ones_like(input_points[:, :, :, 0], dtype=tf.int32) - - if input_points is not None and image_embeddings.shape[0] != input_points.shape[0]: - raise ValueError( - "The batch size of the image embeddings and the input points must be the same. ", - f"Got {image_embeddings.shape[0]} and {input_points.shape[0]} respectively.", - " if you want to pass multiple points for the same image, make sure that you passed ", - " input_points of shape (batch_size, point_batch_size, num_points_per_image, 3) and ", - " input_labels of shape (batch_size, point_batch_size, num_points_per_image)", - ) - - sparse_embeddings, dense_embeddings = self.prompt_encoder( - batch_size=shape_list(image_embeddings)[0], - input_points=input_points, - input_labels=input_labels, - input_boxes=input_boxes, - input_masks=input_masks, - ) - - low_res_masks, iou_predictions, mask_decoder_attentions = self.mask_decoder( - image_embeddings=image_embeddings, - image_positional_embeddings=image_positional_embeddings, - sparse_prompt_embeddings=sparse_embeddings, - dense_prompt_embeddings=dense_embeddings, - multimask_output=multimask_output, - output_attentions=output_attentions, - ) - - if not return_dict: - output = (iou_predictions, low_res_masks) - if output_hidden_states: - output = output + (vision_hidden_states,) - - if output_attentions: - output = output + (vision_attentions, mask_decoder_attentions) - return output - - return TFSamImageSegmentationOutput( - iou_scores=iou_predictions, - pred_masks=low_res_masks, - vision_hidden_states=vision_hidden_states, - vision_attentions=vision_attentions, - mask_decoder_attentions=mask_decoder_attentions, - ) - - def serving_output(self, output: TFSamImageSegmentationOutput) -> TFSamImageSegmentationOutput: - hs = tf.convert_to_tensor(output.vision_hidden_states) if self.config.output_hidden_states else None - attns = tf.convert_to_tensor(output.vision_attentions) if self.config.output_attentions else None - - return TFSamImageSegmentationOutput( - iou_scores=output.iou_scores, - pred_masks=output.pred_masks, - vision_hidden_states=hs if self.config.output_hidden_states else None, - vision_attentions=attns if self.config.output_attentions else None, - mask_decoder_attentions=output.mask_decoder_attentions if self.config.output_attentions else None, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "shared_image_embedding", None) is not None: - with tf.name_scope(self.shared_image_embedding.name): - self.shared_image_embedding.build(None) - if getattr(self, "vision_encoder", None) is not None: - with tf.name_scope(self.vision_encoder.name): - self.vision_encoder.build(None) - if getattr(self, "prompt_encoder", None) is not None: - with tf.name_scope(self.prompt_encoder.name): - self.prompt_encoder.build(None) - if getattr(self, "mask_decoder", None) is not None: - with tf.name_scope(self.mask_decoder.name): - self.mask_decoder.build(None) - - -__all__ = ["TFSamVisionModel", "TFSamModel", "TFSamPreTrainedModel"] diff --git a/src/transformers/models/sam/processing_sam.py b/src/transformers/models/sam/processing_sam.py index 603adde95040..f7c862d82c40 100644 --- a/src/transformers/models/sam/processing_sam.py +++ b/src/transformers/models/sam/processing_sam.py @@ -24,16 +24,13 @@ from ...image_utils import ImageInput from ...processing_utils import ImagesKwargs, ProcessingKwargs, ProcessorMixin from ...tokenization_utils_base import AudioInput, BatchEncoding, PreTokenizedInput, TextInput -from ...utils import is_tf_available, is_torch_available +from ...utils import is_torch_available from ...video_utils import VideoInput if is_torch_available(): import torch -if is_tf_available(): - import tensorflow as tf - class SamImagesKwargs(ImagesKwargs): segmentation_maps: Optional[ImageInput] @@ -102,7 +99,7 @@ def __call__( # pop arguments that are not used in the forward but used nevertheless original_sizes = encoding_image_processor["original_sizes"] - if hasattr(original_sizes, "numpy"): # Checks if Torch or TF tensor + if hasattr(original_sizes, "numpy"): original_sizes = original_sizes.numpy() input_points, input_labels, input_boxes = self._check_and_preprocess_points( @@ -173,30 +170,18 @@ def _normalize_and_convert( input_boxes = torch.from_numpy(input_boxes) # boxes batch size of 1 by default input_boxes = input_boxes.unsqueeze(1) if len(input_boxes.shape) != 3 else input_boxes - elif return_tensors == "tf": - input_boxes = tf.convert_to_tensor(input_boxes) - # boxes batch size of 1 by default - input_boxes = tf.expand_dims(input_boxes, 1) if len(input_boxes.shape) != 3 else input_boxes encoding_image_processor.update({"input_boxes": input_boxes}) if input_points is not None: if return_tensors == "pt": input_points = torch.from_numpy(input_points) # point batch size of 1 by default input_points = input_points.unsqueeze(1) if len(input_points.shape) != 4 else input_points - elif return_tensors == "tf": - input_points = tf.convert_to_tensor(input_points) - # point batch size of 1 by default - input_points = tf.expand_dims(input_points, 1) if len(input_points.shape) != 4 else input_points encoding_image_processor.update({"input_points": input_points}) if input_labels is not None: if return_tensors == "pt": input_labels = torch.from_numpy(input_labels) # point batch size of 1 by default input_labels = input_labels.unsqueeze(1) if len(input_labels.shape) != 3 else input_labels - elif return_tensors == "tf": - input_labels = tf.convert_to_tensor(input_labels) - # point batch size of 1 by default - input_labels = tf.expand_dims(input_labels, 1) if len(input_labels.shape) != 3 else input_labels encoding_image_processor.update({"input_labels": input_labels}) return encoding_image_processor @@ -250,7 +235,7 @@ def _check_and_preprocess_points( it is converted to a `numpy.ndarray` and then to a `list`. """ if input_points is not None: - if hasattr(input_points, "numpy"): # Checks for TF or Torch tensor + if hasattr(input_points, "numpy"): input_points = input_points.numpy().tolist() if not isinstance(input_points, list) or not isinstance(input_points[0], list): diff --git a/src/transformers/models/sam2/image_processing_sam2_fast.py b/src/transformers/models/sam2/image_processing_sam2_fast.py index a55188f4e786..f78e8b65bea1 100644 --- a/src/transformers/models/sam2/image_processing_sam2_fast.py +++ b/src/transformers/models/sam2/image_processing_sam2_fast.py @@ -530,7 +530,7 @@ def generate_crop_boxes( input_data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the input image. If not provided, it will be inferred. return_tensors (`str`, *optional*, defaults to `pt`): - If `pt`, returns `torch.Tensor`. If `tf`, returns `tf.Tensor`. + If `pt`, returns `torch.Tensor`. """ image = self._process_image(image) crop_boxes, points_per_crop, cropped_images, input_labels = _generate_crop_boxes( diff --git a/src/transformers/models/seamless_m4t/feature_extraction_seamless_m4t.py b/src/transformers/models/seamless_m4t/feature_extraction_seamless_m4t.py index 59a20059f869..d0a8a07b3a9e 100644 --- a/src/transformers/models/seamless_m4t/feature_extraction_seamless_m4t.py +++ b/src/transformers/models/seamless_m4t/feature_extraction_seamless_m4t.py @@ -204,7 +204,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/segformer/__init__.py b/src/transformers/models/segformer/__init__.py index 81655dfa7048..c9b88d1a98c6 100644 --- a/src/transformers/models/segformer/__init__.py +++ b/src/transformers/models/segformer/__init__.py @@ -23,7 +23,6 @@ from .image_processing_segformer import * from .image_processing_segformer_fast import * from .modeling_segformer import * - from .modeling_tf_segformer import * else: import sys diff --git a/src/transformers/models/segformer/image_processing_segformer.py b/src/transformers/models/segformer/image_processing_segformer.py index 46e66babe4de..0894c352de8b 100644 --- a/src/transformers/models/segformer/image_processing_segformer.py +++ b/src/transformers/models/segformer/image_processing_segformer.py @@ -343,10 +343,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -374,10 +372,7 @@ def preprocess( segmentation_maps = make_flat_list_of_images(segmentation_maps, expected_ndims=2) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, @@ -426,7 +421,7 @@ def preprocess( # Copied from transformers.models.beit.image_processing_beit.BeitImageProcessor.post_process_semantic_segmentation with Beit->Segformer def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[list[tuple]] = None): """ - Converts the output of [`SegformerForSemanticSegmentation`] into semantic segmentation maps. Only supports PyTorch. + Converts the output of [`SegformerForSemanticSegmentation`] into semantic segmentation maps. Args: outputs ([`SegformerForSemanticSegmentation`]): @@ -440,7 +435,6 @@ def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[lis segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each `torch.Tensor` correspond to a semantic class id. """ - # TODO: add support for other frameworks logits = outputs.logits # Resize logits and compute semantic segmentation maps diff --git a/src/transformers/models/segformer/image_processing_segformer_fast.py b/src/transformers/models/segformer/image_processing_segformer_fast.py index da4bef3e9ee8..dc18283136e1 100644 --- a/src/transformers/models/segformer/image_processing_segformer_fast.py +++ b/src/transformers/models/segformer/image_processing_segformer_fast.py @@ -196,7 +196,7 @@ def _preprocess( def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[list[tuple]] = None): """ - Converts the output of [`SegformerForSemanticSegmentation`] into semantic segmentation maps. Only supports PyTorch. + Converts the output of [`SegformerForSemanticSegmentation`] into semantic segmentation maps. Args: outputs ([`SegformerForSemanticSegmentation`]): @@ -210,7 +210,6 @@ def post_process_semantic_segmentation(self, outputs, target_sizes: Optional[lis segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each `torch.Tensor` correspond to a semantic class id. """ - # TODO: add support for other frameworks logits = outputs.logits # Resize logits and compute semantic segmentation maps diff --git a/src/transformers/models/segformer/modeling_segformer.py b/src/transformers/models/segformer/modeling_segformer.py index 8a81f68beadd..0b06c7c39e09 100755 --- a/src/transformers/models/segformer/modeling_segformer.py +++ b/src/transformers/models/segformer/modeling_segformer.py @@ -64,11 +64,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -441,8 +436,6 @@ class SegformerPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/segformer/modeling_tf_segformer.py b/src/transformers/models/segformer/modeling_tf_segformer.py deleted file mode 100644 index 2f8e68b95748..000000000000 --- a/src/transformers/models/segformer/modeling_tf_segformer.py +++ /dev/null @@ -1,1044 +0,0 @@ -# coding=utf-8 -# Copyright 2022 NVIDIA The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow SegFormer model.""" - -from __future__ import annotations - -import math - -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...file_utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - replace_return_docstrings, -) -from ...modeling_tf_outputs import TFBaseModelOutput, TFSemanticSegmenterOutput, TFSequenceClassifierOutput -from ...modeling_tf_utils import ( - TFPreTrainedModel, - TFSequenceClassificationLoss, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list, stable_softmax -from ...utils import logging -from .configuration_segformer import SegformerConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "SegformerConfig" - -# Base docstring -_CHECKPOINT_FOR_DOC = "nvidia/mit-b0" -_EXPECTED_OUTPUT_SHAPE = [1, 256, 16, 16] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "nvidia/mit-b0" -_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" - - -# Copied from transformers.models.convnext.modeling_tf_convnext.TFConvNextDropPath with ConvNext->Segformer -class TFSegformerDropPath(keras.layers.Layer): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - References: - (1) github.com:rwightman/pytorch-image-models - """ - - def __init__(self, drop_path: float, **kwargs): - super().__init__(**kwargs) - self.drop_path = drop_path - - def call(self, x: tf.Tensor, training=None): - if training: - keep_prob = 1 - self.drop_path - shape = (tf.shape(x)[0],) + (1,) * (len(tf.shape(x)) - 1) - random_tensor = keep_prob + tf.random.uniform(shape, 0, 1) - random_tensor = tf.floor(random_tensor) - return (x / keep_prob) * random_tensor - return x - - -class TFSegformerOverlapPatchEmbeddings(keras.layers.Layer): - """Construct the overlapping patch embeddings.""" - - def __init__(self, patch_size, stride, num_channels, hidden_size, **kwargs): - super().__init__(**kwargs) - self.padding = keras.layers.ZeroPadding2D(padding=patch_size // 2) - self.proj = keras.layers.Conv2D( - filters=hidden_size, kernel_size=patch_size, strides=stride, padding="VALID", name="proj" - ) - - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-05, name="layer_norm") - self.num_channels = num_channels - self.hidden_size = hidden_size - - def call(self, pixel_values: tf.Tensor) -> tuple[tf.Tensor, int, int]: - embeddings = self.proj(self.padding(pixel_values)) - height = shape_list(embeddings)[1] - width = shape_list(embeddings)[2] - hidden_dim = shape_list(embeddings)[3] - # (batch_size, height, width, num_channels) -> (batch_size, height*width, num_channels) - # this can be fed to a Transformer layer - embeddings = tf.reshape(embeddings, (-1, height * width, hidden_dim)) - embeddings = self.layer_norm(embeddings) - return embeddings, height, width - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "proj", None) is not None: - with tf.name_scope(self.proj.name): - self.proj.build([None, None, None, self.num_channels]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.hidden_size]) - - -class TFSegformerEfficientSelfAttention(keras.layers.Layer): - """SegFormer's efficient self-attention mechanism. Employs the sequence reduction process introduced in the [PvT - paper](https://huggingface.co/papers/2102.12122).""" - - def __init__( - self, - config: SegformerConfig, - hidden_size: int, - num_attention_heads: int, - sequence_reduction_ratio: int, - **kwargs, - ): - super().__init__(**kwargs) - self.hidden_size = hidden_size - self.num_attention_heads = num_attention_heads - - if self.hidden_size % self.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({self.hidden_size}) is not a multiple of the number of attention " - f"heads ({self.num_attention_heads})" - ) - - self.attention_head_size = self.hidden_size // self.num_attention_heads - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense(self.all_head_size, name="query") - self.key = keras.layers.Dense(self.all_head_size, name="key") - self.value = keras.layers.Dense(self.all_head_size, name="value") - - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - - self.sr_ratio = sequence_reduction_ratio - if sequence_reduction_ratio > 1: - self.sr = keras.layers.Conv2D( - filters=hidden_size, kernel_size=sequence_reduction_ratio, strides=sequence_reduction_ratio, name="sr" - ) - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-05, name="layer_norm") - - def transpose_for_scores(self, tensor: tf.Tensor) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] - # to [batch_size, seq_length, num_attention_heads, attention_head_size] - batch_size = shape_list(tensor)[0] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] - # to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - height: int, - width: int, - output_attentions: bool = False, - training: bool = False, - ) -> tf.Tensor | tuple[tf.Tensor, tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - num_channels = shape_list(hidden_states)[2] - - query_layer = self.transpose_for_scores(self.query(hidden_states)) - - if self.sr_ratio > 1: - # Reshape to (batch_size, height, width, num_channels) - hidden_states = tf.reshape(hidden_states, (batch_size, height, width, num_channels)) - # Apply sequence reduction - hidden_states = self.sr(hidden_states) - # Reshape back to (batch_size, seq_len, num_channels) - hidden_states = tf.reshape(hidden_states, (batch_size, -1, num_channels)) - hidden_states = self.layer_norm(hidden_states) - - key_layer = self.transpose_for_scores(self.key(hidden_states)) - value_layer = self.transpose_for_scores(self.value(hidden_states)) - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - - scale = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, scale) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs, training=training) - - context_layer = tf.matmul(attention_probs, value_layer) - - context_layer = tf.transpose(context_layer, perm=[0, 2, 1, 3]) - # (batch_size, seq_len_q, all_head_size) - context_layer = tf.reshape(context_layer, (batch_size, -1, self.all_head_size)) - - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.hidden_size]) - if getattr(self, "sr", None) is not None: - with tf.name_scope(self.sr.name): - self.sr.build([None, None, None, self.hidden_size]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.hidden_size]) - - -class TFSegformerSelfOutput(keras.layers.Layer): - def __init__(self, config: SegformerConfig, hidden_size: int, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense(hidden_size, name="dense") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.hidden_size = hidden_size - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.hidden_size]) - - -class TFSegformerAttention(keras.layers.Layer): - def __init__( - self, - config: SegformerConfig, - hidden_size: int, - num_attention_heads: int, - sequence_reduction_ratio: int, - **kwargs, - ): - super().__init__(**kwargs) - self.self = TFSegformerEfficientSelfAttention( - config=config, - hidden_size=hidden_size, - num_attention_heads=num_attention_heads, - sequence_reduction_ratio=sequence_reduction_ratio, - name="self", - ) - self.dense_output = TFSegformerSelfOutput(config, hidden_size=hidden_size, name="output") - - def call( - self, hidden_states: tf.Tensor, height: int, width: int, output_attentions: bool = False - ) -> tf.Tensor | tuple[tf.Tensor, tf.Tensor]: - self_outputs = self.self(hidden_states, height, width, output_attentions) - - attention_output = self.dense_output(self_outputs[0]) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self", None) is not None: - with tf.name_scope(self.self.name): - self.self.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -class TFSegformerDWConv(keras.layers.Layer): - def __init__(self, dim: int = 768, **kwargs): - super().__init__(**kwargs) - self.depthwise_convolution = keras.layers.Conv2D( - filters=dim, kernel_size=3, strides=1, padding="same", groups=dim, name="dwconv" - ) - self.dim = dim - - def call(self, hidden_states: tf.Tensor, height: int, width: int) -> tf.Tensor: - batch_size = shape_list(hidden_states)[0] - num_channels = shape_list(hidden_states)[-1] - hidden_states = tf.reshape(hidden_states, (batch_size, height, width, num_channels)) - hidden_states = self.depthwise_convolution(hidden_states) - - new_height = shape_list(hidden_states)[1] - new_width = shape_list(hidden_states)[2] - num_channels = shape_list(hidden_states)[3] - hidden_states = tf.reshape(hidden_states, (batch_size, new_height * new_width, num_channels)) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "depthwise_convolution", None) is not None: - with tf.name_scope(self.depthwise_convolution.name): - self.depthwise_convolution.build([None, None, None, self.dim]) - - -class TFSegformerMixFFN(keras.layers.Layer): - def __init__( - self, - config: SegformerConfig, - in_features: int, - hidden_features: int | None = None, - out_features: int | None = None, - **kwargs, - ): - super().__init__(**kwargs) - out_features = out_features or in_features - self.dense1 = keras.layers.Dense(hidden_features, name="dense1") - self.depthwise_convolution = TFSegformerDWConv(hidden_features, name="dwconv") - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.dense2 = keras.layers.Dense(out_features, name="dense2") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.hidden_features = hidden_features - self.in_features = in_features - - def call(self, hidden_states: tf.Tensor, height: int, width: int, training: bool = False) -> tf.Tensor: - hidden_states = self.dense1(hidden_states) - hidden_states = self.depthwise_convolution(hidden_states, height, width) - hidden_states = self.intermediate_act_fn(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.dense2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense1", None) is not None: - with tf.name_scope(self.dense1.name): - self.dense1.build([None, None, self.in_features]) - if getattr(self, "depthwise_convolution", None) is not None: - with tf.name_scope(self.depthwise_convolution.name): - self.depthwise_convolution.build(None) - if getattr(self, "dense2", None) is not None: - with tf.name_scope(self.dense2.name): - self.dense2.build([None, None, self.hidden_features]) - - -class TFSegformerLayer(keras.layers.Layer): - """This corresponds to the Block class in the original implementation.""" - - def __init__( - self, - config, - hidden_size: int, - num_attention_heads: int, - drop_path: float, - sequence_reduction_ratio: int, - mlp_ratio: int, - **kwargs, - ): - super().__init__(**kwargs) - self.layer_norm_1 = keras.layers.LayerNormalization(epsilon=1e-05, name="layer_norm_1") - self.attention = TFSegformerAttention( - config, - hidden_size=hidden_size, - num_attention_heads=num_attention_heads, - sequence_reduction_ratio=sequence_reduction_ratio, - name="attention", - ) - self.drop_path = TFSegformerDropPath(drop_path) if drop_path > 0.0 else keras.layers.Activation("linear") - self.layer_norm_2 = keras.layers.LayerNormalization(epsilon=1e-05, name="layer_norm_2") - mlp_hidden_size = int(hidden_size * mlp_ratio) - self.mlp = TFSegformerMixFFN(config, in_features=hidden_size, hidden_features=mlp_hidden_size, name="mlp") - self.hidden_size = hidden_size - - def call( - self, - hidden_states: tf.Tensor, - height: int, - width: int, - output_attentions: bool = False, - training: bool = False, - ) -> tuple: - self_attention_outputs = self.attention( - self.layer_norm_1(hidden_states), # in Segformer, layernorm is applied before self-attention - height, - width, - output_attentions=output_attentions, - training=training, - ) - - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - # first residual connection (with stochastic depth) - attention_output = self.drop_path(attention_output, training=training) - hidden_states = attention_output + hidden_states - mlp_output = self.mlp(self.layer_norm_2(hidden_states), height, width) - - # second residual connection (with stochastic depth) - mlp_output = self.drop_path(mlp_output, training=training) - layer_output = mlp_output + hidden_states - - outputs = (layer_output,) + outputs - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer_norm_1", None) is not None: - with tf.name_scope(self.layer_norm_1.name): - self.layer_norm_1.build([None, None, self.hidden_size]) - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "layer_norm_2", None) is not None: - with tf.name_scope(self.layer_norm_2.name): - self.layer_norm_2.build([None, None, self.hidden_size]) - if getattr(self, "mlp", None) is not None: - with tf.name_scope(self.mlp.name): - self.mlp.build(None) - - -class TFSegformerEncoder(keras.layers.Layer): - def __init__(self, config: SegformerConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - - # stochastic depth decay rule - drop_path_decays = [x.numpy() for x in tf.linspace(0.0, config.drop_path_rate, sum(config.depths))] - - # patch embeddings - embeddings = [] - for i in range(config.num_encoder_blocks): - embeddings.append( - TFSegformerOverlapPatchEmbeddings( - patch_size=config.patch_sizes[i], - stride=config.strides[i], - num_channels=config.num_channels if i == 0 else config.hidden_sizes[i - 1], - hidden_size=config.hidden_sizes[i], - name=f"patch_embeddings.{i}", - ) - ) - self.embeddings = embeddings - - # Transformer blocks - blocks = [] - cur = 0 - for i in range(config.num_encoder_blocks): - # each block consists of layers - layers = [] - if i != 0: - cur += config.depths[i - 1] - for j in range(config.depths[i]): - layers.append( - TFSegformerLayer( - config, - hidden_size=config.hidden_sizes[i], - num_attention_heads=config.num_attention_heads[i], - drop_path=drop_path_decays[cur + j], - sequence_reduction_ratio=config.sr_ratios[i], - mlp_ratio=config.mlp_ratios[i], - name=f"block.{i}.{j}", - ) - ) - blocks.append(layers) - - self.block = blocks - - # Layer norms - self.layer_norms = [ - keras.layers.LayerNormalization(epsilon=1e-05, name=f"layer_norm.{i}") - for i in range(config.num_encoder_blocks) - ] - - def call( - self, - pixel_values: tf.Tensor, - output_attentions: bool | None = False, - output_hidden_states: bool | None = False, - return_dict: bool | None = True, - training: bool = False, - ) -> tuple | TFBaseModelOutput: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - - batch_size = shape_list(pixel_values)[0] - - hidden_states = pixel_values - for idx, x in enumerate(zip(self.embeddings, self.block, self.layer_norms)): - embedding_layer, block_layer, norm_layer = x - # first, obtain patch embeddings - hidden_states, height, width = embedding_layer(hidden_states) - - # second, send embeddings through blocks - # (each block consists of multiple layers i.e., list of layers) - for i, blk in enumerate(block_layer): - layer_outputs = blk( - hidden_states, - height, - width, - output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - - # third, apply layer norm - hidden_states = norm_layer(hidden_states) - - # fourth, optionally reshape back to (batch_size, height, width, num_channels) - if idx != len(self.embeddings) - 1 or (idx == len(self.embeddings) - 1 and self.config.reshape_last_stage): - num_channels = shape_list(hidden_states)[-1] - hidden_states = tf.reshape(hidden_states, (batch_size, height, width, num_channels)) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_self_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer_norms", None) is not None: - for layer, shape in zip(self.layer_norms, self.config.hidden_sizes): - with tf.name_scope(layer.name): - layer.build([None, None, shape]) - if getattr(self, "block", None) is not None: - for block in self.block: - for layer in block: - with tf.name_scope(layer.name): - layer.build(None) - if getattr(self, "embeddings", None) is not None: - for layer in self.embeddings: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFSegformerMainLayer(keras.layers.Layer): - config_class = SegformerConfig - - def __init__(self, config: SegformerConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - # hierarchical Transformer encoder - self.encoder = TFSegformerEncoder(config, name="encoder") - - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple | TFBaseModelOutput: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # When running on CPU, `keras.layers.Conv2D` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - # shape = (batch_size, in_height, in_width, in_channels=num_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - - encoder_outputs = self.encoder( - pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = encoder_outputs[0] - # Change to NCHW output format to have uniformity in the modules - sequence_output = tf.transpose(sequence_output, perm=[0, 3, 1, 2]) - - # Change the other hidden state outputs to NCHW as well - if output_hidden_states: - hidden_states = tuple(tf.transpose(h, perm=(0, 3, 1, 2)) for h in encoder_outputs[1]) - - if not return_dict: - if tf.greater(len(encoder_outputs[1:]), 0): - transposed_encoder_outputs = tuple(tf.transpose(v, perm=[0, 3, 1, 2]) for v in encoder_outputs[1:][0]) - return (sequence_output,) + (transposed_encoder_outputs,) - else: - return (sequence_output,) + encoder_outputs[1:] - - return TFBaseModelOutput( - last_hidden_state=sequence_output, - hidden_states=hidden_states if output_hidden_states else encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - - -class TFSegformerPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = SegformerConfig - base_model_prefix = "segformer" - main_input_name = "pixel_values" - - @property - def input_signature(self): - return {"pixel_values": tf.TensorSpec(shape=(None, self.config.num_channels, 512, 512), dtype=tf.float32)} - - -SEGFORMER_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - Parameters: - config ([`SegformerConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -SEGFORMER_INPUTS_DOCSTRING = r""" - - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See - [`SegformerImageProcessor.__call__`] for details. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare SegFormer encoder (Mix-Transformer) outputting raw hidden-states without any specific head on top.", - SEGFORMER_START_DOCSTRING, -) -class TFSegformerModel(TFSegformerPreTrainedModel): - def __init__(self, config: SegformerConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.config = config - - # hierarchical Transformer encoder - self.segformer = TFSegformerMainLayer(config, name="segformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(SEGFORMER_INPUTS_DOCSTRING.format("(batch_size, sequence_length)")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - modality="vision", - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - def call( - self, - pixel_values: tf.Tensor, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple | TFBaseModelOutput: - outputs = self.segformer( - pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "segformer", None) is not None: - with tf.name_scope(self.segformer.name): - self.segformer.build(None) - - -@add_start_docstrings( - """ - SegFormer Model transformer with an image classification head on top (a linear layer on top of the final hidden - states) e.g. for ImageNet. - """, - SEGFORMER_START_DOCSTRING, -) -class TFSegformerForImageClassification(TFSegformerPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: SegformerConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.segformer = TFSegformerMainLayer(config, name="segformer") - - # Classifier head - self.classifier = keras.layers.Dense(config.num_labels, name="classifier") - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(SEGFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - def call( - self, - pixel_values: tf.Tensor | None = None, - labels: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - ) -> tuple | TFSequenceClassifierOutput: - outputs = self.segformer( - pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - sequence_output = outputs[0] - - # convert last hidden states to (batch_size, height*width, hidden_size) - batch_size = shape_list(sequence_output)[0] - sequence_output = tf.transpose(sequence_output, perm=[0, 2, 3, 1]) - sequence_output = tf.reshape(sequence_output, (batch_size, -1, self.config.hidden_sizes[-1])) - - # global average pooling - sequence_output = tf.reduce_mean(sequence_output, axis=1) - - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "segformer", None) is not None: - with tf.name_scope(self.segformer.name): - self.segformer.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_sizes[-1]]) - - -class TFSegformerMLP(keras.layers.Layer): - """ - Linear Embedding. - """ - - def __init__(self, input_dim: int, config: SegformerConfig, **kwargs): - super().__init__(**kwargs) - self.proj = keras.layers.Dense(config.decoder_hidden_size, name="proj") - self.input_dim = input_dim - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - height = shape_list(hidden_states)[1] - width = shape_list(hidden_states)[2] - hidden_dim = shape_list(hidden_states)[-1] - hidden_states = tf.reshape(hidden_states, (-1, height * width, hidden_dim)) - hidden_states = self.proj(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "proj", None) is not None: - with tf.name_scope(self.proj.name): - self.proj.build([None, None, self.input_dim]) - - -class TFSegformerDecodeHead(TFSegformerPreTrainedModel): - def __init__(self, config: SegformerConfig, **kwargs): - super().__init__(config, **kwargs) - # linear layers which will unify the channel dimension of each of the encoder blocks to the same config.decoder_hidden_size - mlps = [] - for i in range(config.num_encoder_blocks): - mlp = TFSegformerMLP(config=config, input_dim=config.hidden_sizes[i], name=f"linear_c.{i}") - mlps.append(mlp) - self.mlps = mlps - - # the following 3 layers implement the ConvModule of the original implementation - self.linear_fuse = keras.layers.Conv2D( - filters=config.decoder_hidden_size, kernel_size=1, use_bias=False, name="linear_fuse" - ) - self.batch_norm = keras.layers.BatchNormalization(epsilon=1e-5, momentum=0.9, name="batch_norm") - self.activation = keras.layers.Activation("relu") - - self.dropout = keras.layers.Dropout(config.classifier_dropout_prob) - self.classifier = keras.layers.Conv2D(filters=config.num_labels, kernel_size=1, name="classifier") - - self.config = config - - def call(self, encoder_hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - all_hidden_states = () - for encoder_hidden_state, mlp in zip(encoder_hidden_states, self.mlps): - if self.config.reshape_last_stage is False and len(shape_list(encoder_hidden_state)) == 3: - height = tf.math.sqrt(tf.cast(shape_list(encoder_hidden_state)[1], tf.float32)) - height = width = tf.cast(height, tf.int32) - channel_dim = shape_list(encoder_hidden_state)[-1] - encoder_hidden_state = tf.reshape(encoder_hidden_state, (-1, height, width, channel_dim)) - - # unify channel dimension - encoder_hidden_state = tf.transpose(encoder_hidden_state, perm=[0, 2, 3, 1]) - height, width = shape_list(encoder_hidden_state)[1:3] - encoder_hidden_state = mlp(encoder_hidden_state) - channel_dim = shape_list(encoder_hidden_state)[-1] - encoder_hidden_state = tf.reshape(encoder_hidden_state, (-1, height, width, channel_dim)) - - # upsample - temp_state = tf.transpose(encoder_hidden_states[0], perm=[0, 2, 3, 1]) - upsample_resolution = shape_list(temp_state)[1:-1] - encoder_hidden_state = tf.image.resize(encoder_hidden_state, size=upsample_resolution, method="bilinear") - all_hidden_states += (encoder_hidden_state,) - - hidden_states = self.linear_fuse(tf.concat(all_hidden_states[::-1], axis=-1)) - hidden_states = self.batch_norm(hidden_states, training=training) - hidden_states = self.activation(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - - # logits of shape (batch_size, height/4, width/4, num_labels) - logits = self.classifier(hidden_states) - - return logits - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "linear_fuse", None) is not None: - with tf.name_scope(self.linear_fuse.name): - self.linear_fuse.build( - [None, None, None, self.config.decoder_hidden_size * self.config.num_encoder_blocks] - ) - if getattr(self, "batch_norm", None) is not None: - with tf.name_scope(self.batch_norm.name): - self.batch_norm.build([None, None, None, self.config.decoder_hidden_size]) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, None, self.config.decoder_hidden_size]) - if getattr(self, "mlps", None) is not None: - for layer in self.mlps: - with tf.name_scope(layer.name): - layer.build(None) - - -@add_start_docstrings( - """SegFormer Model transformer with an all-MLP decode head on top e.g. for ADE20k, CityScapes.""", - SEGFORMER_START_DOCSTRING, -) -class TFSegformerForSemanticSegmentation(TFSegformerPreTrainedModel): - def __init__(self, config: SegformerConfig, **kwargs): - super().__init__(config, **kwargs) - self.segformer = TFSegformerMainLayer(config, name="segformer") - self.decode_head = TFSegformerDecodeHead(config, name="decode_head") - - def hf_compute_loss(self, logits, labels): - # upsample logits to the images' original size - # `labels` is of shape (batch_size, height, width) - label_interp_shape = shape_list(labels)[1:] - - upsampled_logits = tf.image.resize(logits, size=label_interp_shape, method="bilinear") - # compute weighted loss - loss_fct = keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction="none") - - def masked_loss(real, pred): - unmasked_loss = loss_fct(real, pred) - mask = tf.cast(real != self.config.semantic_loss_ignore_index, dtype=unmasked_loss.dtype) - masked_loss = unmasked_loss * mask - # Reduction strategy in the similar spirit with - # https://github.com/huggingface/transformers/blob/main/src/transformers/modeling_tf_utils.py#L210 - reduced_masked_loss = tf.reduce_sum(masked_loss) / tf.reduce_sum(mask) - return tf.reshape(reduced_masked_loss, (1,)) - - return masked_loss(labels, upsampled_logits) - - @unpack_inputs - @add_start_docstrings_to_model_forward(SEGFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFSemanticSegmenterOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: tf.Tensor, - labels: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - ) -> tuple | TFSemanticSegmenterOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, height, width)`, *optional*): - Ground truth semantic segmentation maps for computing the loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels > 1`, a (per-pixel) classification loss is computed - (Cross-Entropy). - - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, TFSegformerForSemanticSegmentation - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512") - >>> model = TFSegformerForSemanticSegmentation.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512") - - >>> inputs = image_processor(images=image, return_tensors="tf") - >>> outputs = model(**inputs, training=False) - >>> # logits are of shape (batch_size, num_labels, height/4, width/4) - >>> logits = outputs.logits - >>> list(logits.shape) - [1, 150, 128, 128] - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - - if labels is not None and not self.config.num_labels > 1: - raise ValueError("The number of labels should be greater than one") - - outputs = self.segformer( - pixel_values, - output_attentions=output_attentions, - output_hidden_states=True, # we need the intermediate hidden states - return_dict=return_dict, - ) - - encoder_hidden_states = outputs.hidden_states if return_dict else outputs[1] - - logits = self.decode_head(encoder_hidden_states) - - loss = None - if labels is not None: - loss = self.hf_compute_loss(logits=logits, labels=labels) - - # make logits of shape (batch_size, num_labels, height, width) to - # keep them consistent across APIs - logits = tf.transpose(logits, perm=[0, 3, 1, 2]) - - if not return_dict: - if output_hidden_states: - output = (logits,) + outputs[1:] - else: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSemanticSegmenterOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states if output_hidden_states else None, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "segformer", None) is not None: - with tf.name_scope(self.segformer.name): - self.segformer.build(None) - if getattr(self, "decode_head", None) is not None: - with tf.name_scope(self.decode_head.name): - self.decode_head.build(None) - - -__all__ = [ - "TFSegformerDecodeHead", - "TFSegformerForImageClassification", - "TFSegformerForSemanticSegmentation", - "TFSegformerModel", - "TFSegformerPreTrainedModel", -] diff --git a/src/transformers/models/seggpt/image_processing_seggpt.py b/src/transformers/models/seggpt/image_processing_seggpt.py index ffadfaf85edb..f78536b18867 100644 --- a/src/transformers/models/seggpt/image_processing_seggpt.py +++ b/src/transformers/models/seggpt/image_processing_seggpt.py @@ -285,10 +285,8 @@ def _preprocess_step( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -326,10 +324,7 @@ def _preprocess_step( images = make_flat_list_of_images(images, expected_ndims=2 if do_convert_rgb else 3) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") if do_resize and size is None: raise ValueError("Size must be specified if do_resize is True.") @@ -453,10 +448,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. diff --git a/src/transformers/models/seggpt/modeling_seggpt.py b/src/transformers/models/seggpt/modeling_seggpt.py index 7e82d26c9e74..1fde52bae079 100644 --- a/src/transformers/models/seggpt/modeling_seggpt.py +++ b/src/transformers/models/seggpt/modeling_seggpt.py @@ -369,11 +369,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/sew/modeling_sew.py b/src/transformers/models/sew/modeling_sew.py index d5bd617e842b..a001cdd61d58 100644 --- a/src/transformers/models/sew/modeling_sew.py +++ b/src/transformers/models/sew/modeling_sew.py @@ -529,8 +529,6 @@ def _init_weights(self, module): ) nn.init.constant_(module.conv.bias, 0) elif isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) elif isinstance(module, (nn.LayerNorm, nn.GroupNorm)): module.bias.data.zero_() diff --git a/src/transformers/models/sew/modular_sew.py b/src/transformers/models/sew/modular_sew.py index b15c2e5c23a3..1cba7595079e 100644 --- a/src/transformers/models/sew/modular_sew.py +++ b/src/transformers/models/sew/modular_sew.py @@ -276,8 +276,6 @@ def _init_weights(self, module): ) nn.init.constant_(module.conv.bias, 0) elif isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) elif isinstance(module, (nn.LayerNorm, nn.GroupNorm)): module.bias.data.zero_() diff --git a/src/transformers/models/sew_d/modeling_sew_d.py b/src/transformers/models/sew_d/modeling_sew_d.py index f8b71241c79e..68d406c5464a 100644 --- a/src/transformers/models/sew_d/modeling_sew_d.py +++ b/src/transformers/models/sew_d/modeling_sew_d.py @@ -1197,8 +1197,6 @@ def _init_weights(self, module): ) nn.init.constant_(module.conv.bias, 0) elif isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) elif isinstance(module, (nn.LayerNorm, nn.GroupNorm)): module.bias.data.zero_() diff --git a/src/transformers/models/siglip/image_processing_siglip.py b/src/transformers/models/siglip/image_processing_siglip.py index 0ffed5258de5..39ecb0e15b11 100644 --- a/src/transformers/models/siglip/image_processing_siglip.py +++ b/src/transformers/models/siglip/image_processing_siglip.py @@ -152,10 +152,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -185,10 +183,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/siglip2/image_processing_siglip2.py b/src/transformers/models/siglip2/image_processing_siglip2.py index 30b5f1b958af..74a166c440b5 100644 --- a/src/transformers/models/siglip2/image_processing_siglip2.py +++ b/src/transformers/models/siglip2/image_processing_siglip2.py @@ -235,10 +235,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. input_data_format (`ChannelDimension` or `str`, *optional*): The channel dimension format for the input image. If unset, the channel dimension format is inferred from the input image. Can be one of: @@ -271,10 +269,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/smolvlm/image_processing_smolvlm.py b/src/transformers/models/smolvlm/image_processing_smolvlm.py index c08339b81732..8a8ee5d4aa14 100644 --- a/src/transformers/models/smolvlm/image_processing_smolvlm.py +++ b/src/transformers/models/smolvlm/image_processing_smolvlm.py @@ -543,10 +543,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -654,10 +652,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. return_row_col_info (`bool`, *optional*, default to `False`): Whether to return the number of rows and columns of the split images. This is used for the `SmolVLMProcessor` to generate prompt strings based on the number of rows and columns. @@ -690,10 +686,7 @@ def preprocess( images_list = make_nested_list_of_images(images) if not valid_images(images_list[0]): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, diff --git a/src/transformers/models/speech_encoder_decoder/__init__.py b/src/transformers/models/speech_encoder_decoder/__init__.py index 4e07844d45c2..40f66540c963 100644 --- a/src/transformers/models/speech_encoder_decoder/__init__.py +++ b/src/transformers/models/speech_encoder_decoder/__init__.py @@ -19,7 +19,6 @@ if TYPE_CHECKING: from .configuration_speech_encoder_decoder import * - from .modeling_flax_speech_encoder_decoder import * from .modeling_speech_encoder_decoder import * else: import sys diff --git a/src/transformers/models/speech_encoder_decoder/modeling_flax_speech_encoder_decoder.py b/src/transformers/models/speech_encoder_decoder/modeling_flax_speech_encoder_decoder.py deleted file mode 100644 index 3614c5d4981b..000000000000 --- a/src/transformers/models/speech_encoder_decoder/modeling_flax_speech_encoder_decoder.py +++ /dev/null @@ -1,930 +0,0 @@ -# coding=utf-8 -# Copyright 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. -"""Classes to support Flax Speech-Encoder-Decoder architectures""" - -import os -from typing import Optional, Union - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxCausalLMOutputWithCrossAttentions, FlaxSeq2SeqLMOutput -from ...modeling_flax_utils import FlaxPreTrainedModel -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from ..auto.configuration_auto import AutoConfig -from ..auto.modeling_flax_auto import FlaxAutoModel, FlaxAutoModelForCausalLM -from .configuration_speech_encoder_decoder import SpeechEncoderDecoderConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "SpeechEncoderDecoderConfig" - -SPEECH_ENCODER_DECODER_START_DOCSTRING = r""" - This class can be used to initialize a speech-sequence-to-text-sequence model with any pretrained speech - autoencoding model as the encoder and any pretrained text autoregressive model as the decoder. The encoder is - loaded via [`~AutoModel.from_pretrained`] function and the decoder is loaded via - [`~AutoModelForCausalLM.from_pretrained`] function. Cross-attention layers are automatically added to the decoder - and should be fine-tuned on a downstream generative task, like summarization. - - The effectiveness of initializing sequence-to-sequence models with pretrained checkpoints for sequence generation - tasks was shown in [Leveraging Pre-trained Checkpoints for Sequence Generation - Tasks](https://huggingface.co/papers/1907.12461) by Sascha Rothe, Shashi Narayan, Aliaksei Severyn. Michael Matena, Yanqi - Zhou, Wei Li, Peter J. Liu. - - Additionally, in [Large-Scale Self- and Semi-Supervised Learning for Speech - Translation](https://huggingface.co/papers/2104.06678) it is shown how leveraging large pretrained speech models for speech - translation yields a significant performance improvement. - - After such an Speech-Encoder Decoder model has been trained/fine-tuned, it can be saved/loaded just like any other - models (see the examples for more information). - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Parameters: - config ([`SpeechEncoderDecoderConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -SPEECH_ENCODER_DECODER_INPUTS_DOCSTRING = r""" - Args: - inputs (`jnp.ndarray` of shape `(batch_size, sequence_length)` or `(batch_size, sequence_length, feature_dim)`, *optional*): - Float values of input raw speech waveform or speech features. Values can be obtained by loading a `.flac` - or `.wav` audio file into an array of type `list[float]`, a `numpy.ndarray` or a `torch.Tensor`, *e.g.* - via the torchcodec library (`pip install torchcodec`) or the soundfile library (`pip install soundfile`). - To prepare the array into `inputs`, either the [`Wav2Vec2Processor`] or - [`Speech2TextProcessor`] should be used for padding and conversion into a tensor of type - `torch.FloatTensor`. - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - For sequence to sequence training, `decoder_input_ids` should be provided. `decoder_input_ids` should be - created outside of the model by shifting the `labels` to the right, replacing -100 by the `pad_token_id` - and prepending them with the `decoder_start_token_id`. - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.decoder.max_position_embeddings - 1]`. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.FlaxSeq2SeqLMOutput`] instead of a plain tuple. -""" - -SPEECH_ENCODER_DECODER_ENCODE_INPUTS_DOCSTRING = r""" - Args: - inputs (`jnp.ndarray` of shape `(batch_size, sequence_length)` or `(batch_size, sequence_length, feature_dim)`, *optional*): - Float values of input raw speech waveform or speech features. Values can be obtained by loading a *.flac* - or *.wav* audio file into an array of type *list[float]* or a *numpy.ndarray*, *e.g.* via the torchcodec library - (`pip install torchcodec`) or the soundfile library (`pip install soundfile`). - To prepare the array into *inputs*, either the [`Wav2Vec2Processor`] or [`Speech2TextProcessor`] should be used - for padding and conversion into a tensor of type *torch.FloatTensor*. - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.FlaxBaseModelOutput`] instead of a plain tuple. -""" - -SPEECH_ENCODER_DECODER_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - For sequence to sequence training, `decoder_input_ids` should be provided. `decoder_input_ids` should be - created outside of the model by shifting the `labels` to the right, replacing -100 by the `pad_token_id` - and prepending them with the `decoder_start_token_id`. - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.decoder.max_position_embeddings - 1]`. - past_key_values (`dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.FlaxCausalLMOutputWithCrossAttentions`] instead of a - plain tuple. -""" - - -class FlaxSpeechEncoderDecoderModule(nn.Module): - config: SpeechEncoderDecoderConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - encoder_config = self.config.encoder - decoder_config = self.config.decoder - - # Copied from `modeling_hybrid_clip.py` with modifications. - from ...models.auto.modeling_flax_auto import FLAX_MODEL_FOR_CAUSAL_LM_MAPPING, FLAX_MODEL_MAPPING - - encoder_module = FLAX_MODEL_MAPPING[encoder_config.__class__].module_class - decoder_module = FLAX_MODEL_FOR_CAUSAL_LM_MAPPING[decoder_config.__class__].module_class - - self.encoder = encoder_module(encoder_config, dtype=self.dtype) - self.decoder = decoder_module(decoder_config, dtype=self.dtype) - - # encoder outputs might need to be projected to different dimension for decoder - if ( - self.encoder.config.hidden_size != self.decoder.config.hidden_size - and self.decoder.config.cross_attention_hidden_size is None - ): - self.enc_to_dec_proj = nn.Dense( - self.decoder.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.decoder.config.initializer_range), - dtype=self.dtype, - ) - else: - self.enc_to_dec_proj = None - - def _get_feat_extract_output_lengths( - self, input_lengths: Union[jnp.ndarray, int], add_adapter: Optional[bool] = None - ): - """ - Computes the output length of the convolutional layers - """ - - add_adapter = self.config.encoder.add_adapter if add_adapter is None else add_adapter - - def _conv_out_length(input_length, kernel_size, stride): - # 1D convolutional layer output length formula taken - # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html - return (input_length - kernel_size) // stride + 1 - - for kernel_size, stride in zip(self.config.encoder.conv_kernel, self.config.encoder.conv_stride): - input_lengths = _conv_out_length(input_lengths, kernel_size, stride) - - if add_adapter: - for _ in range(self.config.encoder.num_adapter_layers): - input_lengths = _conv_out_length(input_lengths, 1, self.config.encoder.adapter_stride) - - return input_lengths - - def _get_encoder_module(self): - return self.encoder - - def _get_projection_module(self): - return self.enc_to_dec_proj - - def _get_decoder_module(self): - return self.decoder - - def __call__( - self, - inputs, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - encoder_outputs=None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - freeze_feature_encoder: bool = False, - ): - if encoder_outputs is None: - encoder_outputs = self.encoder( - inputs, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - freeze_feature_encoder=freeze_feature_encoder, - ) - - encoder_hidden_states = encoder_outputs[0] - - # optionally project encoder_hidden_states - if self.enc_to_dec_proj is not None: - encoder_hidden_states = self.enc_to_dec_proj(encoder_hidden_states) - - # compute correct encoder attention mask - if attention_mask is not None: - encoder_attention_mask = self.encoder._get_feature_vector_attention_mask( - encoder_hidden_states.shape[1], attention_mask - ) - else: - encoder_attention_mask = None - - # flax script modeling_flax_wav2vec2.py - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqLMOutput( - logits=decoder_outputs.logits, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_hidden_states, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -@add_start_docstrings(SPEECH_ENCODER_DECODER_START_DOCSTRING) -class FlaxSpeechEncoderDecoderModel(FlaxPreTrainedModel): - r""" - [`FlaxSpeechEncoderDecoderModel`] is a generic model class that will be instantiated as a transformer architecture - with the module (flax.nn.Module) of one of the base model classes of the library as encoder module and another one - as decoder module when created with the :meth*~transformers.FlaxAutoModel.from_pretrained* class method for the - encoder and :meth*~transformers.FlaxAutoModelForCausalLM.from_pretrained* class method for the decoder. - """ - - config_class = SpeechEncoderDecoderConfig - base_model_prefix: str = "speech_encoder_decoder" - module_class = FlaxSpeechEncoderDecoderModule - - def __init__( - self, - config: SpeechEncoderDecoderConfig, - input_shape: Optional[tuple] = None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - if not _do_init: - raise ValueError( - "`FlaxSpeechEncoderDecoderModel` cannot be created without initializing, `_do_init` must be `True`." - ) - - if config.decoder.cross_attention_hidden_size is not None: - # Raise ValueError or option to project enc to dec hidden_size (eg EncAdapterLayer) - if config.decoder.cross_attention_hidden_size != config.encoder.hidden_size: - raise ValueError( - "If `cross_attention_hidden_size` is specified in the decoder's configuration, it has to be equal" - f" to the encoder's `hidden_size`. Got {config.decoder.cross_attention_hidden_size} for" - f" `config.decoder.cross_attention_hidden_size` and {config.encoder.hidden_size} for" - " `config.encoder.hidden_size`." - ) - - # make sure input & output embeddings are not tied - config.tie_word_embeddings = False - module = self.module_class(config=config, dtype=dtype, **kwargs) - - if input_shape is None: - # speech encoders almost always downsample the sequence length dimension - encoder_input_length = 1024 - decoder_input_length = module._get_feat_extract_output_lengths(encoder_input_length) - input_shape = ((1, encoder_input_length), (1, decoder_input_length)) - - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - encoder_input_shape, decoder_input_shape = input_shape - - # init input DeviceArrays - inputs = jnp.zeros(encoder_input_shape, dtype="f4") - attention_mask = jnp.ones_like(inputs, dtype="i4") - decoder_input_ids = jnp.zeros(decoder_input_shape, dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - - batch_size, sequence_length = inputs.shape - - decoder_batch_size, decoder_sequence_length = decoder_input_ids.shape - if not decoder_batch_size == batch_size: - raise ValueError( - f"The inputs of encoder and decoder should have the same batch size, but got {batch_size} for encoder" - f" and {decoder_batch_size} for decoder." - ) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(decoder_sequence_length)[None, :], (decoder_batch_size, decoder_sequence_length) - ) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - inputs, - attention_mask, - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape - ) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - def _get_feat_extract_output_lengths( - self, input_lengths: Union[jnp.ndarray, int], add_adapter: Optional[bool] = None - ): - return self.module._get_feat_extract_output_lengths(input_lengths, add_adapter=add_adapter) - - @add_start_docstrings(SPEECH_ENCODER_DECODER_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=_CONFIG_FOR_DOC) - def encode( - self, - inputs: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - freeze_feature_encoder: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import FlaxSpeechEncoderDecoderModel - - >>> # initialize a wav2vec2-2-bart from pretrained wav2vec2 and bart models. Note that the cross-attention layers will be randomly initialized - >>> model = FlaxSpeechEncoderDecoderModel.from_encoder_decoder_pretrained( - ... "facebook/wav2vec2-large-lv60", "facebook/bart-large" - ... ) - - >>> inputs = jnp.ones((2, 5000), dtype=jnp.float32) - >>> encoder_outputs = model.encode(inputs) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(inputs, dtype="i4") - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, inputs, attention_mask, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(inputs, attention_mask, **kwargs) - - outputs = self.module.apply( - {"params": params or self.params}, - inputs=jnp.array(inputs, dtype="f4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - freeze_feature_encoder=freeze_feature_encoder, - rngs=rngs, - method=_encoder_forward, - ) - - if return_dict: - outputs = FlaxBaseModelOutput( - last_hidden_state=outputs.last_hidden_state, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - return outputs - - @add_start_docstrings(SPEECH_ENCODER_DECODER_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=_CONFIG_FOR_DOC) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import FlaxSpeechEncoderDecoderModel - >>> import jax.numpy as jnp - - >>> # initialize a wav2vec2-2-bart from pretrained wav2vec2 and bart models. Note that the cross-attention layers will be randomly initialized - >>> model = FlaxSpeechEncoderDecoderModel.from_encoder_decoder_pretrained( - ... "facebook/wav2vec2-large-lv60", "facebook/bart-large" - ... ) - - >>> inputs = jnp.ones((2, 5000), dtype=jnp.float32) - >>> encoder_outputs = model.encode(inputs) - - >>> decoder_start_token_id = model.config.decoder.bos_token_id - >>> decoder_input_ids = jnp.ones((inputs.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - params = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxBartAttention module - if past_key_values: - params["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward( - module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, encoder_hidden_states, **kwargs - ): - projection_module = module._get_projection_module() - decoder_module = module._get_decoder_module() - - # optionally project encoder_hidden_states - if projection_module is not None: - encoder_hidden_states = projection_module(encoder_hidden_states) - - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - encoder_hidden_states=encoder_hidden_states, - **kwargs, - ) - - outputs = self.module.apply( - params, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - @add_start_docstrings_to_model_forward(SPEECH_ENCODER_DECODER_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - def __call__( - self, - inputs: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_input_ids: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - freeze_feature_encoder: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Examples: - - ```python - >>> from transformers import FlaxSpeechEncoderDecoderModel, AutoTokenizer - - >>> # load a fine-tuned wav2vec2-2-bart model - >>> model = FlaxSpeechEncoderDecoderModel.from_pretrained("patrickvonplaten/wav2vec2-2-bart-large") - >>> # load output tokenizer - >>> tokenizer_output = AutoTokenizer.from_pretrained("facebook/bart-large") - - >>> inputs = jnp.ones((2, 5000), dtype=jnp.float32) - - >>> # use bart's special bos, pad and eos tokens - >>> model.config.decoder_start_token_id = model.decoder.config.bos_token_id - >>> model.config.pad_token_id = model.decoder.config.pad_token_id - >>> model.config.eos_token_id = model.decoder.config.eos_token_id - - >>> outputs = model.generate(inputs) - # Assert something? More interesting input? dtype correct? - ``` - """ - - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(inputs, dtype="i4") - - # prepare decoder inputs - if decoder_input_ids is None: - raise ValueError( - "`decoder_input_ids` cannot be `None`. For sequence to sequence training, `decoder_position_ids` must" - " be specified as an input argument." - ) - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - if decoder_position_ids is None: - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - inputs=jnp.array(inputs, dtype="f4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - freeze_feature_encoder=freeze_feature_encoder, - rngs=rngs, - ) - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - decoder_position_ids = decoder_attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) - else: - decoder_position_ids = jnp.broadcast_to( - jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length) - ) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - "decoder_position_ids": decoder_position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 - return model_kwargs - - @classmethod - def from_encoder_decoder_pretrained( - cls, - encoder_pretrained_model_name_or_path: Optional[Union[str, os.PathLike]] = None, - decoder_pretrained_model_name_or_path: Optional[Union[str, os.PathLike]] = None, - *model_args, - **kwargs, - ) -> FlaxPreTrainedModel: - r""" - Instantiate an encoder and a decoder from one or two base classes of the library from pretrained model - checkpoints. - - Params: - encoder_pretrained_model_name_or_path (`Union[str, os.PathLike]`, *optional*): - Information necessary to initiate the encoder. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~FlaxPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - decoder_pretrained_model_name_or_path (`Union[str, os.PathLike]`, *optional*, defaults to `None`): - Information necessary to initiate the decoder. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~FlaxPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - model_args (remaining positional arguments, *optional*): - All remaining positional arguments will be passed to the underlying model's `__init__` method. - - kwargs (remaining dictionary of keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). - - - To update the encoder configuration, use the prefix *encoder_* for each configuration parameter. - - To update the decoder configuration, use the prefix *decoder_* for each configuration parameter. - - To update the parent model configuration, do not use a prefix for each configuration parameter. - - Behaves differently depending on whether a `config` is provided or automatically loaded. - - Example: - - ```python - >>> from transformers import FlaxSpeechEncoderDecoderModel - - >>> # initialize a wav2vec2-2-bart from pretrained wav2vec2 and bart models. Note that the cross-attention layers will be randomly initialized - >>> model = FlaxSpeechEncoderDecoderModel.from_encoder_decoder_pretrained( - ... "facebook/wav2vec2-large-lv60", "facebook/bart-large" - ... ) - >>> # saving model after fine-tuning - >>> model.save_pretrained("./wav2vec2-2-bart-large") - >>> # load fine-tuned model - >>> model = FlaxSpeechEncoderDecoderModel.from_pretrained("./wav2vec2-2-bart-large") - ```""" - - kwargs_encoder = { - argument[len("encoder_") :]: value for argument, value in kwargs.items() if argument.startswith("encoder_") - } - - kwargs_decoder = { - argument[len("decoder_") :]: value for argument, value in kwargs.items() if argument.startswith("decoder_") - } - - # remove encoder, decoder kwargs from kwargs - for key in kwargs_encoder: - del kwargs["encoder_" + key] - for key in kwargs_decoder: - del kwargs["decoder_" + key] - - # Load and initialize the encoder and decoder - # The distinction between encoder and decoder at the model level is made - # by the value of the flag `is_decoder` that we need to set correctly. - encoder = kwargs_encoder.pop("model", None) - if encoder is None: - if encoder_pretrained_model_name_or_path is None: - raise ValueError( - "If `encoder_model` is not defined as an argument, a `encoder_pretrained_model_name_or_path` has " - "to be defined." - ) - - if "config" not in kwargs_encoder: - encoder_config, kwargs_encoder = AutoConfig.from_pretrained( - encoder_pretrained_model_name_or_path, **kwargs_encoder, return_unused_kwargs=True - ) - if encoder_config.is_decoder is True or encoder_config.add_cross_attention is True: - logger.info( - f"Initializing {encoder_pretrained_model_name_or_path} as a encoder model " - "from a decoder model. Cross-attention and causal mask are disabled." - ) - encoder_config.is_decoder = False - encoder_config.add_cross_attention = False - - kwargs_encoder["config"] = encoder_config - - encoder = FlaxAutoModel.from_pretrained( - encoder_pretrained_model_name_or_path, *model_args, **kwargs_encoder - ) - - decoder = kwargs_decoder.pop("model", None) - if decoder is None: - if decoder_pretrained_model_name_or_path is None: - raise ValueError( - "If `decoder_model` is not defined as an argument, a `decoder_pretrained_model_name_or_path` has " - "to be defined." - ) - - if "config" not in kwargs_decoder: - decoder_config, kwargs_decoder = AutoConfig.from_pretrained( - decoder_pretrained_model_name_or_path, **kwargs_decoder, return_unused_kwargs=True - ) - if decoder_config.is_decoder is False or decoder_config.add_cross_attention is False: - logger.info( - f"Initializing {decoder_pretrained_model_name_or_path} as a decoder model. Cross attention" - f" layers are added to {decoder_pretrained_model_name_or_path} and randomly initialized if" - f" {decoder_pretrained_model_name_or_path}'s architecture allows for cross attention layers." - ) - decoder_config.is_decoder = True - decoder_config.add_cross_attention = True - - kwargs_decoder["config"] = decoder_config - - if kwargs_decoder["config"].is_decoder is False or kwargs_decoder["config"].add_cross_attention is False: - logger.warning( - f"Decoder model {decoder_pretrained_model_name_or_path} is not initialized as a decoder. " - f"In order to initialize {decoder_pretrained_model_name_or_path} as a decoder, " - "make sure that the attributes `is_decoder` and `add_cross_attention` of `decoder_config` " - "passed to `.from_encoder_decoder_pretrained(...)` are set to `True` or do not pass a " - "`decoder_config` to `.from_encoder_decoder_pretrained(...)`" - ) - - decoder = FlaxAutoModelForCausalLM.from_pretrained(decoder_pretrained_model_name_or_path, **kwargs_decoder) - - # instantiate config with corresponding kwargs - dtype = kwargs.pop("dtype", jnp.float32) - config = SpeechEncoderDecoderConfig.from_encoder_decoder_configs(encoder.config, decoder.config, **kwargs) - - # make sure input & output word embeddings are not tied - config.tie_word_embeddings = False - - # init model - model = cls(config, dtype=dtype) - model.params["encoder"] = encoder.params - model.params["decoder"] = decoder.params - - return model - - -__all__ = ["FlaxSpeechEncoderDecoderModel"] diff --git a/src/transformers/models/speech_encoder_decoder/modeling_speech_encoder_decoder.py b/src/transformers/models/speech_encoder_decoder/modeling_speech_encoder_decoder.py index 272ebdc741bc..a5a6bc2fbf0b 100644 --- a/src/transformers/models/speech_encoder_decoder/modeling_speech_encoder_decoder.py +++ b/src/transformers/models/speech_encoder_decoder/modeling_speech_encoder_decoder.py @@ -187,10 +187,6 @@ def from_encoder_decoder_pretrained( - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In - this case, `from_tf` should be set to `True` and a configuration object should be provided as - `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a - PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. decoder_pretrained_model_name_or_path (`str`, *optional*, defaults to `None`): Information necessary to initiate the decoder. Can be either: @@ -198,10 +194,6 @@ def from_encoder_decoder_pretrained( - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In - this case, `from_tf` should be set to `True` and a configuration object should be provided as - `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a - PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. model_args (remaining positional arguments, *optional*): All remaining positional arguments will be passed to the underlying model's `__init__` method. diff --git a/src/transformers/models/speech_to_text/__init__.py b/src/transformers/models/speech_to_text/__init__.py index ec094769d4ae..b4dce9e2cc61 100644 --- a/src/transformers/models/speech_to_text/__init__.py +++ b/src/transformers/models/speech_to_text/__init__.py @@ -21,7 +21,6 @@ from .configuration_speech_to_text import * from .feature_extraction_speech_to_text import * from .modeling_speech_to_text import * - from .modeling_tf_speech_to_text import * from .processing_speech_to_text import * from .tokenization_speech_to_text import * else: diff --git a/src/transformers/models/speech_to_text/feature_extraction_speech_to_text.py b/src/transformers/models/speech_to_text/feature_extraction_speech_to_text.py index 64627033671e..fe6698e9ebec 100644 --- a/src/transformers/models/speech_to_text/feature_extraction_speech_to_text.py +++ b/src/transformers/models/speech_to_text/feature_extraction_speech_to_text.py @@ -229,7 +229,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/speech_to_text/modeling_tf_speech_to_text.py b/src/transformers/models/speech_to_text/modeling_tf_speech_to_text.py deleted file mode 100755 index 402c005b7be7..000000000000 --- a/src/transformers/models/speech_to_text/modeling_tf_speech_to_text.py +++ /dev/null @@ -1,1600 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow Speech2Text model.""" - -from __future__ import annotations - -import random - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation, glu -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPastAndCrossAttentions, - TFSeq2SeqLMOutput, - TFSeq2SeqModelOutput, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - TFSharedEmbeddings, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_speech_to_text import Speech2TextConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "Speech2TextConfig" -_CHECKPOINT_FOR_DOC = "facebook/s2t-small-librispeech-asr" - - -LARGE_NEGATIVE = -1e8 - - -# Copied from transformers.models.bart.modeling_tf_bart.shift_tokens_right -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): - pad_token_id = tf.cast(pad_token_id, input_ids.dtype) - decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) - start_tokens = tf.fill( - (shape_list(input_ids)[0], 1), tf.convert_to_tensor(decoder_start_token_id, input_ids.dtype) - ) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.fill(shape_list(shifted_input_ids), tf.convert_to_tensor(pad_token_id, input_ids.dtype)), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE - mask_cond = tf.range(shape_list(mask)[-1]) - - mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -class TFConv1dSubsampler(keras.layers.Layer): - """ - Convolutional subsampler: a stack of 1D convolution (along temporal dimension) followed by non-linear activation - via gated linear units (https://huggingface.co/papers/1911.08460) - """ - - def __init__(self, config: Speech2TextConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.num_layers = config.num_conv_layers - self.in_channels = config.input_feat_per_channel * config.input_channels - self.mid_channels = config.conv_channels - self.out_channels = config.d_model - self.kernel_sizes = config.conv_kernel_sizes - - self.conv_layers = [ - keras.layers.Conv1D( - filters=self.mid_channels if i < self.num_layers - 1 else self.out_channels * 2, - kernel_size=k, - strides=2, - name=f"conv_layers.{i}", - ) - for i, k in enumerate(self.kernel_sizes) - ] - - def call(self, input_features: tf.Tensor) -> tf.Tensor: - # TF Conv1D assumes Batch x Time x Channels, same as the input - hidden_states = tf.cast(input_features, tf.float32) - for i, conv in enumerate(self.conv_layers): - # equivalent to `padding=k // 2` on PT's `nn.Conv1d` - pad_len = self.kernel_sizes[i] // 2 - hidden_shapes = shape_list(hidden_states) - hidden_states = tf.concat( - ( - tf.zeros((hidden_shapes[0], pad_len, hidden_shapes[2])), - hidden_states, - tf.zeros((hidden_shapes[0], pad_len, hidden_shapes[2])), - ), - axis=1, - ) - - hidden_states = conv(hidden_states) - hidden_states = glu(hidden_states, axis=2) # GLU over the Channel dimension - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv_layers", None) is not None: - for i, layer in enumerate(self.conv_layers): - with tf.name_scope(layer.name): - layer.build([None, None, self.in_channels] if i == 0 else [None, None, self.mid_channels // 2]) - - -class TFSpeech2TextSinusoidalPositionalEmbedding(keras.layers.Layer): - """This module produces sinusoidal positional embeddings of any length.""" - - def __init__(self, num_positions: int, embedding_dim: int, padding_idx: int | None = None, **kwargs): - super().__init__(**kwargs) - self.offset = 2 - self.embedding_dim = embedding_dim - self.padding_idx = padding_idx - self.embedding_weights = self._get_embedding(num_positions + self.offset, embedding_dim, padding_idx) - - @staticmethod - def _get_embedding(num_embeddings: int, embedding_dim: int, padding_idx: int | None = None) -> tf.Tensor: - """ - Build sinusoidal embeddings. This matches the implementation in tensor2tensor, but differs slightly from the - description in Section 3.5 of "Attention Is All You Need". - """ - half_dim = embedding_dim // 2 - emb = tf.math.log(10000.0) / (half_dim - 1) - emb = tf.math.exp(tf.range(half_dim, dtype=tf.float32) * -emb) - emb = tf.expand_dims(tf.range(num_embeddings, dtype=tf.float32), axis=1) * tf.expand_dims(emb, axis=0) - emb = tf.reshape(tf.concat([tf.math.sin(emb), tf.math.cos(emb)], axis=1), shape=[num_embeddings, -1]) - if embedding_dim % 2 == 1: - # zero pad - emb = tf.concat([emb, tf.zeros(num_embeddings, 1)], axis=1) - if padding_idx is not None: - emb = tf.concat([emb[:padding_idx, :], tf.zeros((1, tf.shape(emb)[1])), emb[padding_idx + 1 :, :]], axis=0) - return emb - - def call(self, input_ids: tf.Tensor, past_key_values_length: int = 0) -> tf.Tensor: - bsz, seq_len = shape_list(input_ids) - # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = self.create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) - - # Matt: The PyTorch code does a lot of work to cache the embeddings, setting the cached values as a - # model attribute in the forward pass. This is extremely forbidden in TF, which wants forward calls to be - # idempotent. TF doesn't need that caching anyway, since it can just store constants during compilation, - # so we just remove all of that code. - embeddings = self._get_embedding( - self.padding_idx + 1 + seq_len + self.offset + past_key_values_length, self.embedding_dim, self.padding_idx - ) - return tf.reshape(tf.gather(embeddings, tf.reshape(position_ids, (-1,)), axis=0), (bsz, seq_len, -1)) - - @staticmethod - def create_position_ids_from_input_ids( - input_ids: tf.Tensor, padding_idx: int, past_key_values_length: int | None = 0 - ) -> tf.Tensor: - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding - symbols are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: tf.Tensor x: - Returns: tf.Tensor - """ - mask = tf.cast(tf.math.not_equal(input_ids, padding_idx), dtype=tf.int32) - incremental_indices = (tf.math.cumsum(mask, axis=1) + past_key_values_length) * mask - return tf.cast(incremental_indices, dtype=tf.int64) + padding_idx - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with Bart->Speech2Text -class TFSpeech2TextAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -class TFSpeech2TextEncoderLayer(keras.layers.Layer): - def __init__(self, config: Speech2TextConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFSpeech2TextAttention( - self.embed_dim, config.encoder_attention_heads, dropout=config.attention_dropout, name="self_attn" - ) - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - self.fc1 = keras.layers.Dense(config.encoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, hidden_states: tf.Tensor, attention_mask: tf.Tensor, layer_head_mask: tf.Tensor, training: bool = False - ): - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - `(encoder_attention_heads,)` - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - hidden_states, self_attn_weights, _ = self.self_attn( - hidden_states=hidden_states, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - training=training, - ) - - tf.debugging.assert_equal( - shape_list(hidden_states), - shape_list(residual), - message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", - ) - - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return hidden_states, self_attn_weights - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.encoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFSpeech2TextDecoderLayer(keras.layers.Layer): - def __init__(self, config: Speech2TextConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - - self.self_attn = TFSpeech2TextAttention( - embed_dim=self.embed_dim, - num_heads=config.decoder_attention_heads, - dropout=config.attention_dropout, - name="self_attn", - is_decoder=True, - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.encoder_attn = TFSpeech2TextAttention( - self.embed_dim, - config.decoder_attention_heads, - dropout=config.attention_dropout, - name="encoder_attn", - is_decoder=True, - ) - self.encoder_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.decoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states, - attention_mask: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - cross_attn_layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tf.Tensor] | None = None, - training=False, - ) -> tuple[tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - encoder_hidden_states (`tf.Tensor`): - cross attention input to the layer of shape `(batch, seq_len, embed_dim)` - encoder_attention_mask (`tf.Tensor`): encoder attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - `(decoder_attention_heads,)` - cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. - `(decoder_attention_heads,)` - past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - training=training, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_present_key_value = None - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - layer_head_mask=cross_attn_layer_head_mask, - past_key_value=cross_attn_past_key_value, - training=training, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # add cross-attn to positions 3,4 of present_key_value tuple - present_key_value = present_key_value + cross_attn_present_key_value - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return ( - hidden_states, - self_attn_weights, - cross_attn_weights, - present_key_value, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "encoder_attn", None) is not None: - with tf.name_scope(self.encoder_attn.name): - self.encoder_attn.build(None) - if getattr(self, "encoder_attn_layer_norm", None) is not None: - with tf.name_scope(self.encoder_attn_layer_norm.name): - self.encoder_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.decoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFSpeech2TextPreTrainedModel(TFPreTrainedModel): - config_class = Speech2TextConfig - base_model_prefix = "model" - main_input_name = "input_features" - _keys_to_ignore_on_load_unexpected = [r"encoder.embed_positions.weights"] - - def _get_feat_extract_output_lengths(self, input_lengths: tf.Tensor): - """ - Computes the output length of the convolutional layers - """ - for _ in range(self.config.num_conv_layers): - input_lengths = (input_lengths - 1) // 2 + 1 - - return input_lengths - - @property - def input_signature(self): - return { - "input_features": tf.TensorSpec( - (None, None, self.config.input_feat_per_channel * self.config.input_channels), - tf.float32, - name="input_features", - ), - "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), - "decoder_input_ids": tf.TensorSpec((None, None), tf.int32, name="decoder_input_ids"), - "decoder_attention_mask": tf.TensorSpec((None, None), tf.int32, name="decoder_attention_mask"), - } - - -SPEECH_TO_TEXT_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`Speech2TextConfig`]): - Model configuration class with all the parameters of the model. Initializing with a config file does not - load the weights associated with the model, only the configuration. Check out the - [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - - -SPEECH_TO_TEXT_INPUTS_DOCSTRING = r""" - Args: - input_features (`tf.Tensor` of shape `(batch_size, sequence_length, feature_size)`): - Float values of fbank features extracted from the raw speech waveform. Raw speech waveform can be obtained - by loading a `.flac` or `.wav` audio file into an array of type `list[float]`, a `numpy.ndarray or a - `torch.Tensor``, *e.g.* via the torchcodec library (`pip install torchcodec`) or the soundfile library - (`pip install soundfile`). - To prepare the arrayinto `input_features`, the [`AutoFeatureExtractor`] should be used for extracting - the fbank features, padding and conversion into a tensor of floats. - See [`~Speech2TextFeatureExtractor.__call__`] - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`Speech2TextTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - SpeechToText uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If - `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - For translation and summarization training, `decoder_input_ids` should be provided. If no - `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right - for denoising pre-training following the paper. - decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - will be made by default and ignore pad tokens. It is not recommended to set this for most use cases. - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_outputs (`tf.FloatTensor`, *optional*): - hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - of shape `(batch_size, sequence_length, hidden_size)` is a sequence of - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - decoder_inputs_embeds (`tf.FloatTensor` of shape `(batch_size, target_sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `decoder_input_ids` you can choose to directly pass an embedded - representation. If `past_key_values` is used, optionally only the last `decoder_inputs_embeds` have to be - input (see `past_key_values`). This is useful if you want more control over how to convert - `decoder_input_ids` indices into associated vectors than the model's internal embedding lookup matrix. - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@keras_serializable -class TFSpeech2TextEncoder(keras.layers.Layer): - config_class = Speech2TextConfig - """ - Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a - [`TFSpeech2TextEncoderLayer`]. - - Args: - config: Speech2TextConfig - """ - - def __init__(self, config: Speech2TextConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - - self.dropout = keras.layers.Dropout(config.dropout) - self.layerdrop = config.encoder_layerdrop - - embed_dim = config.d_model - self.padding_idx = config.pad_token_id - self.max_source_positions = config.max_source_positions - self.embed_scale = tf.math.sqrt(float(embed_dim)) if config.scale_embedding else 1.0 - - self.conv = TFConv1dSubsampler(config, name="conv") - - self.embed_positions = TFSpeech2TextSinusoidalPositionalEmbedding( - num_positions=config.max_source_positions, - embedding_dim=embed_dim, - padding_idx=self.padding_idx, - name="embed_positions", - ) - self.layers = [TFSpeech2TextEncoderLayer(config, name=f"layers.{i}") for i in range(config.encoder_layers)] - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - def _get_feat_extract_output_lengths(self, input_lengths: tf.Tensor): - """ - Computes the output length of the convolutional layers - """ - for _ in range(self.config.num_conv_layers): - input_lengths = (input_lengths - 1) // 2 + 1 - - return input_lengths - - def _get_feature_vector_attention_mask(self, feature_vector_length, attention_mask): - # generate creates 3D attention mask, because of the shape of input_features - # convert it to 2D if that's the case - if len(attention_mask.shape) > 2: - attention_mask = attention_mask[:, :, -1] - - subsampled_lengths = self._get_feat_extract_output_lengths(tf.math.reduce_sum(attention_mask, -1)) - bsz = shape_list(attention_mask)[0] - indices = tf.concat( - ( - tf.expand_dims(tf.range(bsz, dtype=attention_mask.dtype), -1), - tf.expand_dims(subsampled_lengths - 1, -1), - ), - axis=-1, - ) - attention_mask = tf.scatter_nd(indices=indices, updates=tf.ones(bsz), shape=[bsz, feature_vector_length]) - attention_mask = tf.cast(tf.reverse(tf.math.cumsum(tf.reverse(attention_mask, [-1]), -1), [-1]), tf.int64) - return attention_mask - - @unpack_inputs - def call( - self, - input_features=None, - attention_mask=None, - head_mask=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - """ - Args: - input_features (`tf.Tensor` of shape `(batch_size, sequence_length, feature_size)`): - Float values of fbank features extracted from the raw speech waveform. Raw speech waveform can be - obtained by loading a `.flac` or `.wav` audio file into an array of type `list[float]`, a - `numpy.ndarray` or a `torch.Tensor`, *e.g.* via the torchcodec library (`pip install torchcodec`) or - the soundfile library (`pip install soundfile`). To prepare the array into - `input_features`, the [`AutoFeatureExtractor`] should be used for extracting the fbank features, - padding and conversion into a tensor of floats. See [`~Speech2TextFeatureExtractor.__call__`] - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - if input_features is None: - raise ValueError("You have to specify input_features") - - inputs_embeds = self.conv(input_features) - inputs_embeds = self.embed_scale * inputs_embeds - - # subsample attention mask if necessary - if attention_mask is not None: - attention_mask = self._get_feature_vector_attention_mask(tf.shape(inputs_embeds)[1], attention_mask) - padding_mask = tf.cast(tf.math.not_equal(attention_mask, 1), tf.int64) - else: - padding_mask = tf.zeros(tf.shape(inputs_embeds)[:-1], dtype=tf.int64) - - embed_pos = self.embed_positions(padding_mask) - - hidden_states = inputs_embeds + embed_pos - hidden_states = self.dropout(hidden_states, training=training) - - # check attention mask and invert - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - attention_mask = _expand_mask(attention_mask) - - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - # check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - tf.debugging.assert_equal( - shape_list(head_mask)[0], - len(self.layers), - message=( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(head_mask)[0]}." - ), - ) - - for idx, encoder_layer in enumerate(self.layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): # skip the layer - continue - - hidden_states, attn = encoder_layer( - hidden_states, - attention_mask, - head_mask[idx] if head_mask is not None else None, - training=training, - ) - - if output_attentions: - all_attentions += (attn,) - - hidden_states = self.layer_norm(hidden_states) - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build(None) - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFSpeech2TextDecoder(keras.layers.Layer): - config_class = Speech2TextConfig - """ - Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFSpeech2TextDecoderLayer`] - - Args: - config: Speech2TextConfig - """ - - def __init__(self, config: Speech2TextConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layerdrop = config.decoder_layerdrop - self.padding_idx = config.pad_token_id - self.max_target_positions = config.max_target_positions - self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 - - self.embed_tokens = TFSharedEmbeddings(config.vocab_size, config.d_model, name="embed_tokens") - - self.embed_positions = TFSpeech2TextSinusoidalPositionalEmbedding( - num_positions=config.max_target_positions, - embedding_dim=config.d_model, - padding_idx=self.padding_idx, - name="embed_positions", - ) - - self.layers = [TFSpeech2TextDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - self.dropout = keras.layers.Dropout(config.dropout) - - def get_embed_tokens(self): - return self.embed_tokens - - def set_embed_tokens(self, embed_tokens): - self.embed_tokens = embed_tokens - - @unpack_inputs - def call( - self, - input_ids=None, - inputs_embeds=None, - attention_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - head_mask=None, - cross_attn_head_mask=None, - past_key_values=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`Speech2TextTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention - of the decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): - Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values - selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers` with each tuple having 2 tuples each of which has 2 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up - decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those - that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of - all `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - # past_key_values_length - past_key_values_length = shape_list(past_key_values[0][0])[2] if past_key_values is not None else 0 - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.vocab_size) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - else: - inputs_embeds = inputs_embeds - - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - if input_shape[-1] > 1: - combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length=past_key_values_length) - else: - combined_attention_mask = _expand_mask( - tf.ones((input_shape[0], input_shape[1] + past_key_values_length)), tgt_len=input_shape[-1] - ) - - if attention_mask is not None: - combined_attention_mask = combined_attention_mask + _expand_mask(attention_mask, tgt_len=input_shape[-1]) - - # expand encoder attention mask - if encoder_hidden_states is not None and encoder_attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) - - # embed positions - positions = self.embed_positions(input_ids, past_key_values_length=past_key_values_length) - - hidden_states = inputs_embeds + positions - hidden_states = self.dropout(hidden_states, training=training) - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attns = () if (output_attentions and encoder_hidden_states is not None) else None - next_decoder_cache = () if use_cache else None - - # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired - for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: - if attn_mask is not None: - tf.debugging.assert_equal( - shape_list(attn_mask)[0], - len(self.layers), - message=( - f"The {attn_mask_name} should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(attn_mask)[0]}." - ), - ) - - for idx, decoder_layer in enumerate(self.layers): - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - if output_hidden_states: - all_hidden_states += (hidden_states,) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): - continue - - past_key_value = past_key_values[idx] if past_key_values is not None else None - cross_attn_layer_head_mask = cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None - - hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( - hidden_states, - attention_mask=combined_attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - cross_attn_layer_head_mask=cross_attn_layer_head_mask, - past_key_value=past_key_value, - ) - - if use_cache: - next_decoder_cache += (present_key_value,) - - if output_attentions: - all_self_attns += (layer_self_attn,) - - if encoder_hidden_states is not None: - all_cross_attns += (layer_cross_attn,) - - hidden_states = self.layer_norm(hidden_states) - if output_hidden_states: - all_hidden_states += (hidden_states,) - - next_cache = next_decoder_cache if use_cache else None - - if not return_dict: - return hidden_states, next_cache, all_hidden_states, all_self_attns, all_cross_attns - else: - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_cache, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_tokens", None) is not None: - with tf.name_scope(self.embed_tokens.name): - self.embed_tokens.build(None) - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFSpeech2TextMainLayer(keras.layers.Layer): - config_class = Speech2TextConfig - - def __init__(self, config: Speech2TextConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - - self.encoder = TFSpeech2TextEncoder(config, name="encoder") - self.decoder = TFSpeech2TextDecoder(config, name="decoder") - - def get_input_embeddings(self): - return self.decoder.embed_tokens - - def set_input_embeddings(self, new_embeddings): - self.decoder.embed_tokens = new_embeddings - - @unpack_inputs - def call( - self, - input_features=None, - attention_mask=None, - decoder_input_ids=None, - decoder_attention_mask=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - encoder_outputs=None, - past_key_values=None, - decoder_inputs_embeds=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - **kwargs, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - use_cache = use_cache if use_cache is not None else self.config.use_cache - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_features=input_features, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True - elif return_dict and not isinstance(encoder_outputs, TFBaseModelOutput): - encoder_outputs = TFBaseModelOutput( - last_hidden_state=encoder_outputs[0], - hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, - attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, - ) - # If the user passed a TFBaseModelOutput for encoder_outputs, we wrap it in a tuple when return_dict=False - elif not return_dict and not isinstance(encoder_outputs, tuple): - encoder_outputs = encoder_outputs.to_tuple() - - # downsample encoder attention mask - if attention_mask is not None: - encoder_attention_mask = self.encoder._get_feature_vector_attention_mask( - tf.shape(encoder_outputs[0])[1], attention_mask - ) - else: - encoder_attention_mask = None - - # decoder outputs consists of (dec_features, past_key_value, dec_hidden, dec_attn) - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=encoder_attention_mask, - head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return TFSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - "The bare Speech2Text Model outputting raw hidden-states without any specific head on top.", - SPEECH_TO_TEXT_START_DOCSTRING, -) -class TFSpeech2TextModel(TFSpeech2TextPreTrainedModel): - def __init__(self, config: Speech2TextConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.model = TFSpeech2TextMainLayer(config, name="model") - - def get_encoder(self): - return self.model.encoder - - def get_decoder(self): - return self.model.decoder - - @unpack_inputs - @add_start_docstrings_to_model_forward(SPEECH_TO_TEXT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSeq2SeqModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_features: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ) -> tuple | TFSeq2SeqModelOutput: - outputs = self.model( - input_features=input_features, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - encoder_outputs=encoder_outputs, - past_key_values=past_key_values, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqModelOutput( - last_hidden_state=output.last_hidden_state, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -@add_start_docstrings( - "The Speech2Text Model with a language modeling head. Can be used for summarization.", - SPEECH_TO_TEXT_START_DOCSTRING, -) -class TFSpeech2TextForConditionalGeneration(TFSpeech2TextPreTrainedModel, TFCausalLanguageModelingLoss): - def __init__(self, config: Speech2TextConfig): - super().__init__(config) - self.model = TFSpeech2TextMainLayer(config, name="model") - self.lm_head = keras.layers.Dense(self.config.vocab_size, use_bias=False, name="lm_head") - # TODO (Joao): investigate why Speech2Text has numerical issues in XLA generate - self.supports_xla_generation = False - self.config = config - - def get_encoder(self): - return self.model.encoder - - def get_decoder(self): - return self.model.decoder - - def resize_token_embeddings(self, new_num_tokens: int) -> tf.Variable: - new_embeddings = super().resize_token_embeddings(new_num_tokens) - return new_embeddings - - @unpack_inputs - @add_start_docstrings_to_model_forward(SPEECH_TO_TEXT_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_features: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs, - ) -> tuple | TFSeq2SeqLMOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., - config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - - Returns: - - Example: - - ```python - >>> import tensorflow as tf - >>> from transformers import Speech2TextProcessor, TFSpeech2TextForConditionalGeneration - >>> from datasets import load_dataset - - >>> model = TFSpeech2TextForConditionalGeneration.from_pretrained( - ... "facebook/s2t-small-librispeech-asr", from_pt=True - ... ) - >>> processor = Speech2TextProcessor.from_pretrained("facebook/s2t-small-librispeech-asr") - - - >>> def map_to_array(example): - ... example["speech"] = example["audio"]["array"] - ... return example - - - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> ds = ds.map(map_to_array) - >>> ds.set_format(type="tf") - - >>> input_features = processor( - ... ds["speech"][0], sampling_rate=16000, return_tensors="tf" - ... ).input_features # Batch size 1 - >>> generated_ids = model.generate(input_features) - - >>> transcription = processor.batch_decode(generated_ids) - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if labels is not None: - if decoder_input_ids is None and decoder_inputs_embeds is None: - decoder_input_ids = shift_tokens_right( - labels, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - outputs = self.model( - input_features=input_features, - attention_mask=attention_mask, - decoder_input_ids=decoder_input_ids, - encoder_outputs=encoder_outputs, - decoder_attention_mask=decoder_attention_mask, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - lm_logits = self.lm_head(outputs[0]) - masked_lm_loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - - return TFSeq2SeqLMOutput( - loss=masked_lm_loss, - logits=lm_logits, - past_key_values=outputs.past_key_values, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - past_key_values=None, - attention_mask=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - use_cache=None, - encoder_outputs=None, - **kwargs, - ): - # cut decoder_input_ids if past is used - if past_key_values is not None: - decoder_input_ids = decoder_input_ids[:, -1:] - - return { - "input_features": None, # needs to be passed to make Keras.layer.__call__ happy - "encoder_outputs": encoder_outputs, - "past_key_values": past_key_values, - "decoder_input_ids": decoder_input_ids, - "attention_mask": attention_mask, - "head_mask": head_mask, - "decoder_head_mask": decoder_head_mask, - "cross_attn_head_mask": cross_attn_head_mask, - "use_cache": use_cache, # change this to avoid caching (presumably for debugging) - } - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build([None, None, self.config.d_model]) - - def tf_to_pt_weight_rename(self, tf_weight): - if tf_weight == "lm_head.weight": - return tf_weight, "model.decoder.embed_tokens.weight" - else: - return (tf_weight,) - - -__all__ = ["TFSpeech2TextForConditionalGeneration", "TFSpeech2TextModel", "TFSpeech2TextPreTrainedModel"] diff --git a/src/transformers/models/speecht5/feature_extraction_speecht5.py b/src/transformers/models/speecht5/feature_extraction_speecht5.py index 822ae01a88d7..3c30eed90bd1 100644 --- a/src/transformers/models/speecht5/feature_extraction_speecht5.py +++ b/src/transformers/models/speecht5/feature_extraction_speecht5.py @@ -233,7 +233,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/splinter/modeling_splinter.py b/src/transformers/models/splinter/modeling_splinter.py index 116a17330923..1d9c02877841 100755 --- a/src/transformers/models/splinter/modeling_splinter.py +++ b/src/transformers/models/splinter/modeling_splinter.py @@ -46,8 +46,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -369,8 +367,6 @@ class SplinterPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/squeezebert/modeling_squeezebert.py b/src/transformers/models/squeezebert/modeling_squeezebert.py index a732e76bda6a..9e26d1953f1c 100644 --- a/src/transformers/models/squeezebert/modeling_squeezebert.py +++ b/src/transformers/models/squeezebert/modeling_squeezebert.py @@ -51,8 +51,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.embedding_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.embedding_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -423,8 +421,6 @@ class SqueezeBertPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv1d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/superglue/image_processing_superglue.py b/src/transformers/models/superglue/image_processing_superglue.py index bde3355d78ed..ead841c4f176 100644 --- a/src/transformers/models/superglue/image_processing_superglue.py +++ b/src/transformers/models/superglue/image_processing_superglue.py @@ -73,8 +73,7 @@ def convert_to_grayscale( input_data_format: Optional[Union[str, ChannelDimension]] = None, ) -> ImageInput: """ - Converts an image to grayscale format using the NTSC formula. Only support numpy and PIL Image. TODO support torch - and tensorflow grayscale conversion + Converts an image to grayscale format using the NTSC formula. Only support numpy and PIL Image. This function is supposed to return a 1-channel image, but it returns a 3-channel image with the same value in each channel, because of an issue that is discussed in : @@ -262,10 +261,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -292,10 +289,7 @@ def preprocess( images = validate_and_format_image_pairs(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_resize=do_resize, diff --git a/src/transformers/models/superglue/modeling_superglue.py b/src/transformers/models/superglue/modeling_superglue.py index 61c52d06e605..4fc524314e89 100644 --- a/src/transformers/models/superglue/modeling_superglue.py +++ b/src/transformers/models/superglue/modeling_superglue.py @@ -524,8 +524,6 @@ class SuperGluePreTrainedModel(PreTrainedModel): def _init_weights(self, module: nn.Module) -> None: """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/superpoint/image_processing_superpoint.py b/src/transformers/models/superpoint/image_processing_superpoint.py index 4c895b035feb..dc2c6ab22419 100644 --- a/src/transformers/models/superpoint/image_processing_superpoint.py +++ b/src/transformers/models/superpoint/image_processing_superpoint.py @@ -64,8 +64,7 @@ def convert_to_grayscale( input_data_format: Optional[Union[str, ChannelDimension]] = None, ) -> ImageInput: """ - Converts an image to grayscale format using the NTSC formula. Only support numpy and PIL Image. TODO support torch - and tensorflow grayscale conversion + Converts an image to grayscale format using the NTSC formula. Only support numpy and PIL Image. This function is supposed to return a 1-channel image, but it returns a 3-channel image with the same value in each channel, because of an issue that is discussed in : @@ -219,10 +218,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -248,10 +245,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") if do_resize and size is None: raise ValueError("Size must be specified if do_resize is True.") diff --git a/src/transformers/models/superpoint/modeling_superpoint.py b/src/transformers/models/superpoint/modeling_superpoint.py index efd3113eb3b0..f75cc6f9bb8f 100644 --- a/src/transformers/models/superpoint/modeling_superpoint.py +++ b/src/transformers/models/superpoint/modeling_superpoint.py @@ -330,8 +330,6 @@ class SuperPointPreTrainedModel(PreTrainedModel): def _init_weights(self, module: Union[nn.Linear, nn.Conv2d, nn.LayerNorm]) -> None: """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/swiftformer/__init__.py b/src/transformers/models/swiftformer/__init__.py index 370f6c71fadb..b239996fb976 100644 --- a/src/transformers/models/swiftformer/__init__.py +++ b/src/transformers/models/swiftformer/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_swiftformer import * from .modeling_swiftformer import * - from .modeling_tf_swiftformer import * else: import sys diff --git a/src/transformers/models/swiftformer/modeling_swiftformer.py b/src/transformers/models/swiftformer/modeling_swiftformer.py index 95114e3d332c..7ecd94a8fd52 100644 --- a/src/transformers/models/swiftformer/modeling_swiftformer.py +++ b/src/transformers/models/swiftformer/modeling_swiftformer.py @@ -62,11 +62,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/swiftformer/modeling_tf_swiftformer.py b/src/transformers/models/swiftformer/modeling_tf_swiftformer.py deleted file mode 100644 index 612c2406a1d0..000000000000 --- a/src/transformers/models/swiftformer/modeling_tf_swiftformer.py +++ /dev/null @@ -1,866 +0,0 @@ -# coding=utf-8 -# Copyright 2024 MBZUAI and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow SwiftFormer model.""" - -import collections.abc -from typing import Optional, Union - -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithNoAttention, - TFImageClassifierOutputWithNoAttention, -) -from ...modeling_tf_utils import TFPreTrainedModel, keras, keras_serializable, unpack_inputs -from ...utils import ( - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_swiftformer import SwiftFormerConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "SwiftFormerConfig" - -# Base docstring -_CHECKPOINT_FOR_DOC = "MBZUAI/swiftformer-xs" -_EXPECTED_OUTPUT_SHAPE = [1, 220, 7, 7] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "MBZUAI/swiftformer-xs" -_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" - - -class TFSwiftFormerPatchEmbeddingSequential(keras.layers.Layer): - """ - The sequential component of the patch embedding layer. - - Input: tensor of shape `[batch_size, in_channels, height, width]` - - Output: tensor of shape `[batch_size, out_channels, height/4, width/4]` - """ - - def __init__(self, config: SwiftFormerConfig, **kwargs): - super().__init__(**kwargs) - self.out_chs = config.embed_dims[0] - - self.zero_padding = keras.layers.ZeroPadding2D(padding=(1, 1)) - self.conv1 = keras.layers.Conv2D(self.out_chs // 2, kernel_size=3, strides=2, name="0") - self.batch_norm1 = keras.layers.BatchNormalization(epsilon=config.batch_norm_eps, momentum=0.9, name="1") - self.conv2 = keras.layers.Conv2D(self.out_chs, kernel_size=3, strides=2, name="3") - self.batch_norm2 = keras.layers.BatchNormalization(epsilon=config.batch_norm_eps, momentum=0.9, name="4") - self.config = config - - def call(self, x: tf.Tensor, training: bool = False) -> tf.Tensor: - x = self.zero_padding(x) - x = self.conv1(x) - x = self.batch_norm1(x, training=training) - x = get_tf_activation("relu")(x) - x = self.zero_padding(x) - x = self.conv2(x) - x = self.batch_norm2(x, training=training) - x = get_tf_activation("relu")(x) - return x - - def build(self, input_shape=None): - if self.built: - return - if getattr(self, "conv1", None) is not None: - with tf.name_scope(self.conv1.name): - self.conv1.build(self.config.num_channels) - if getattr(self, "batch_norm1", None) is not None: - with tf.name_scope(self.batch_norm1.name): - self.batch_norm1.build((None, None, None, self.out_chs // 2)) - if getattr(self, "conv2", None) is not None: - with tf.name_scope(self.conv2.name): - self.conv2.build((None, None, None, self.out_chs // 2)) - if getattr(self, "batch_norm2", None) is not None: - with tf.name_scope(self.batch_norm2.name): - self.batch_norm2.build((None, None, None, self.out_chs)) - self.built = True - - -class TFSwiftFormerPatchEmbedding(keras.layers.Layer): - """ - Patch Embedding Layer constructed of two 2D convolutional layers. - - Input: tensor of shape `[batch_size, in_channels, height, width]` - - Output: tensor of shape `[batch_size, out_channels, height/4, width/4]` - """ - - def __init__(self, config: SwiftFormerConfig, **kwargs): - super().__init__(**kwargs) - self.patch_embedding = TFSwiftFormerPatchEmbeddingSequential(config, name="patch_embedding") - - def call(self, x: tf.Tensor, training: bool = False) -> tf.Tensor: - return self.patch_embedding(x, training=training) - - def build(self, input_shape=None): - if self.built: - return - if getattr(self, "patch_embedding", None) is not None: - with tf.name_scope(self.patch_embedding.name): - self.patch_embedding.build(None) - self.built = True - - -class TFSwiftFormerDropPath(keras.layers.Layer): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" - - def __init__(self, config: SwiftFormerConfig, **kwargs) -> None: - super().__init__(**kwargs) - raise NotImplementedError("Drop path is not implemented in TF port") - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - raise NotImplementedError("Drop path is not implemented in TF port") - - -class TFSwiftFormerEmbeddings(keras.layers.Layer): - """ - Embeddings layer consisting of a single 2D convolutional and batch normalization layer. - - Input: tensor of shape `[batch_size, channels, height, width]` - - Output: tensor of shape `[batch_size, channels, height/stride, width/stride]` - """ - - def __init__(self, config: SwiftFormerConfig, index: int, **kwargs): - super().__init__(**kwargs) - - patch_size = config.down_patch_size - stride = config.down_stride - padding = config.down_pad - embed_dims = config.embed_dims - - self.in_chans = embed_dims[index] - self.embed_dim = embed_dims[index + 1] - - patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) - stride = stride if isinstance(stride, collections.abc.Iterable) else (stride, stride) - padding = padding if isinstance(padding, collections.abc.Iterable) else (padding, padding) - - self.pad = keras.layers.ZeroPadding2D(padding=padding) - self.proj = keras.layers.Conv2D(self.embed_dim, kernel_size=patch_size, strides=stride, name="proj") - self.norm = keras.layers.BatchNormalization(epsilon=config.batch_norm_eps, momentum=0.9, name="norm") - - def call(self, x: tf.Tensor, training: bool = False) -> tf.Tensor: - x = self.pad(x) - x = self.proj(x) - x = self.norm(x, training=training) - return x - - def build(self, input_shape=None): - if self.built: - return - if getattr(self, "proj", None) is not None: - with tf.name_scope(self.proj.name): - self.proj.build(self.in_chans) - if getattr(self, "norm", None) is not None: - with tf.name_scope(self.norm.name): - self.norm.build((None, None, None, self.embed_dim)) - self.built = True - - -class TFSwiftFormerConvEncoder(keras.layers.Layer): - """ - `SwiftFormerConvEncoder` with 3*3 and 1*1 convolutions. - - Input: tensor of shape `[batch_size, channels, height, width]` - - Output: tensor of shape `[batch_size, channels, height, width]` - """ - - def __init__(self, config: SwiftFormerConfig, dim: int, **kwargs): - super().__init__(**kwargs) - hidden_dim = int(config.mlp_ratio * dim) - - self.dim = dim - self.pad = keras.layers.ZeroPadding2D(padding=(1, 1)) - self.depth_wise_conv = keras.layers.Conv2D(dim, kernel_size=3, groups=dim, name="depth_wise_conv") - self.norm = keras.layers.BatchNormalization(epsilon=config.batch_norm_eps, momentum=0.9, name="norm") - self.point_wise_conv1 = keras.layers.Conv2D(hidden_dim, kernel_size=1, name="point_wise_conv1") - self.act = get_tf_activation("gelu") - self.point_wise_conv2 = keras.layers.Conv2D(dim, kernel_size=1, name="point_wise_conv2") - self.drop_path = keras.layers.Dropout(name="drop_path", rate=config.drop_conv_encoder_rate) - self.hidden_dim = int(config.mlp_ratio * self.dim) - - def build(self, input_shape=None): - if self.built: - return - self.layer_scale = self.add_weight( - name="layer_scale", - shape=self.dim, - initializer="ones", - trainable=True, - ) - - if getattr(self, "depth_wise_conv", None) is not None: - with tf.name_scope(self.depth_wise_conv.name): - self.depth_wise_conv.build(self.dim) - if getattr(self, "norm", None) is not None: - with tf.name_scope(self.norm.name): - self.norm.build((None, None, None, self.dim)) - if getattr(self, "point_wise_conv1", None) is not None: - with tf.name_scope(self.point_wise_conv1.name): - self.point_wise_conv1.build(self.dim) - if getattr(self, "point_wise_conv2", None) is not None: - with tf.name_scope(self.point_wise_conv2.name): - self.point_wise_conv2.build(self.hidden_dim) - if getattr(self, "drop_path", None) is not None: - with tf.name_scope(self.drop_path.name): - self.drop_path.build(None) - self.built = True - - def call(self, x: tf.Tensor, training: bool = False) -> tf.Tensor: - input = x - x = self.pad(x) - x = self.depth_wise_conv(x) - x = self.norm(x, training=training) - x = self.point_wise_conv1(x) - x = self.act(x) - x = self.point_wise_conv2(x) - x = input + self.drop_path(self.layer_scale * x) - return x - - -class TFSwiftFormerMlp(keras.layers.Layer): - """ - MLP layer with 1*1 convolutions. - - Input: tensor of shape `[batch_size, channels, height, width]` - - Output: tensor of shape `[batch_size, channels, height, width]` - """ - - def __init__(self, config: SwiftFormerConfig, in_features: int, **kwargs): - super().__init__(**kwargs) - - hidden_features = int(in_features * config.mlp_ratio) - self.norm1 = keras.layers.BatchNormalization(epsilon=config.batch_norm_eps, momentum=0.9, name="norm1") - self.fc1 = keras.layers.Conv2D(hidden_features, 1, name="fc1") - act_layer = get_tf_activation(config.hidden_act) - self.act = act_layer - self.fc2 = keras.layers.Conv2D(in_features, 1, name="fc2") - self.drop = keras.layers.Dropout(rate=config.drop_mlp_rate) - self.hidden_features = hidden_features - self.in_features = in_features - - def call(self, x: tf.Tensor, training: bool = False) -> tf.Tensor: - x = self.norm1(x, training=training) - x = self.fc1(x) - x = self.act(x) - x = self.drop(x, training=training) - x = self.fc2(x) - x = self.drop(x, training=training) - return x - - def build(self, input_shape=None): - if self.built: - return - if getattr(self, "norm1", None) is not None: - with tf.name_scope(self.norm1.name): - self.norm1.build((None, None, None, self.in_features)) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build((None, None, None, self.in_features)) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build((None, None, None, self.hidden_features)) - self.built = True - - -class TFSwiftFormerEfficientAdditiveAttention(keras.layers.Layer): - """ - Efficient Additive Attention module for SwiftFormer. - - Input: tensor of shape `[batch_size, channels, height, width]` - - Output: tensor of shape `[batch_size, channels, height, width]` - """ - - def __init__(self, config: SwiftFormerConfig, dim: int = 512, **kwargs): - super().__init__(**kwargs) - - self.dim = dim - - self.to_query = keras.layers.Dense(dim, name="to_query") - self.to_key = keras.layers.Dense(dim, name="to_key") - - self.scale_factor = dim**-0.5 - self.proj = keras.layers.Dense(dim, name="proj") - self.final = keras.layers.Dense(dim, name="final") - - def build(self, input_shape=None): - if self.built: - return - self.w_g = self.add_weight( - name="w_g", - shape=(self.dim, 1), - initializer=keras.initializers.RandomNormal(mean=0, stddev=1), - trainable=True, - ) - - if getattr(self, "to_query", None) is not None: - with tf.name_scope(self.to_query.name): - self.to_query.build(self.dim) - if getattr(self, "to_key", None) is not None: - with tf.name_scope(self.to_key.name): - self.to_key.build(self.dim) - if getattr(self, "proj", None) is not None: - with tf.name_scope(self.proj.name): - self.proj.build(self.dim) - if getattr(self, "final", None) is not None: - with tf.name_scope(self.final.name): - self.final.build(self.dim) - self.built = True - - def call(self, x: tf.Tensor) -> tf.Tensor: - query = self.to_query(x) - key = self.to_key(x) - - query = tf.math.l2_normalize(query, dim=-1) - key = tf.math.l2_normalize(key, dim=-1) - - query_weight = query @ self.w_g - scaled_query_weight = query_weight * self.scale_factor - scaled_query_weight = tf.nn.softmax(scaled_query_weight, axis=-1) - - global_queries = tf.math.reduce_sum(scaled_query_weight * query, axis=1) - global_queries = tf.tile(tf.expand_dims(global_queries, 1), (1, key.shape[1], 1)) - - out = self.proj(global_queries * key) + query - out = self.final(out) - - return out - - -class TFSwiftFormerLocalRepresentation(keras.layers.Layer): - """ - Local Representation module for SwiftFormer that is implemented by 3*3 depth-wise and point-wise convolutions. - - Input: tensor of shape `[batch_size, channels, height, width]` - - Output: tensor of shape `[batch_size, channels, height, width]` - """ - - def __init__(self, config: SwiftFormerConfig, dim: int, **kwargs): - super().__init__(**kwargs) - - self.dim = dim - - self.pad = keras.layers.ZeroPadding2D(padding=(1, 1)) - self.depth_wise_conv = keras.layers.Conv2D(dim, kernel_size=3, groups=dim, name="depth_wise_conv") - self.norm = keras.layers.BatchNormalization(epsilon=config.batch_norm_eps, momentum=0.9, name="norm") - self.point_wise_conv1 = keras.layers.Conv2D(dim, kernel_size=1, name="point_wise_conv1") - self.act = get_tf_activation("gelu") - self.point_wise_conv2 = keras.layers.Conv2D(dim, kernel_size=1, name="point_wise_conv2") - self.drop_path = keras.layers.Identity(name="drop_path") - - def build(self, input_shape=None): - if self.built: - return - self.layer_scale = self.add_weight( - name="layer_scale", - shape=(self.dim), - initializer="ones", - trainable=True, - ) - if getattr(self, "depth_wise_conv", None) is not None: - with tf.name_scope(self.depth_wise_conv.name): - self.depth_wise_conv.build((None, None, None, self.dim)) - if getattr(self, "norm", None) is not None: - with tf.name_scope(self.norm.name): - self.norm.build((None, None, None, self.dim)) - if getattr(self, "point_wise_conv1", None) is not None: - with tf.name_scope(self.point_wise_conv1.name): - self.point_wise_conv1.build(self.dim) - if getattr(self, "point_wise_conv2", None) is not None: - with tf.name_scope(self.point_wise_conv2.name): - self.point_wise_conv2.build(self.dim) - if getattr(self, "drop_path", None) is not None: - with tf.name_scope(self.drop_path.name): - self.drop_path.build(None) - self.built = True - - def call(self, x: tf.Tensor, training: bool = False) -> tf.Tensor: - input = x - x = self.pad(x) - x = self.depth_wise_conv(x) - x = self.norm(x, training=training) - x = self.point_wise_conv1(x) - x = self.act(x) - x = self.point_wise_conv2(x) - x = input + self.drop_path(self.layer_scale * x, training=training) - return x - - -class TFSwiftFormerEncoderBlock(keras.layers.Layer): - """ - SwiftFormer Encoder Block for SwiftFormer. It consists of (1) Local representation module, (2) - SwiftFormerEfficientAdditiveAttention, and (3) MLP block. - - Input: tensor of shape `[batch_size, channels, height, width]` - - Output: tensor of shape `[batch_size, channels,height, width]` - """ - - def __init__(self, config: SwiftFormerConfig, dim: int, drop_path: float = 0.0, **kwargs): - super().__init__(**kwargs) - - layer_scale_init_value = config.layer_scale_init_value - use_layer_scale = config.use_layer_scale - - self.local_representation = TFSwiftFormerLocalRepresentation(config, dim=dim, name="local_representation") - self.attn = TFSwiftFormerEfficientAdditiveAttention(config, dim=dim, name="attn") - self.linear = TFSwiftFormerMlp(config, in_features=dim, name="linear") - self.drop_path = TFSwiftFormerDropPath(config) if drop_path > 0.0 else keras.layers.Identity() - self.use_layer_scale = use_layer_scale - if use_layer_scale: - self.dim = dim - self.layer_scale_init_value = layer_scale_init_value - - def build(self, input_shape=None): - if self.built: - return - self.layer_scale_1 = self.add_weight( - name="layer_scale_1", - shape=self.dim, - initializer=keras.initializers.constant(self.layer_scale_init_value), - trainable=True, - ) - self.layer_scale_2 = self.add_weight( - name="layer_scale_2", - shape=self.dim, - initializer=keras.initializers.constant(self.layer_scale_init_value), - trainable=True, - ) - - if getattr(self, "local_representation", None) is not None: - with tf.name_scope(self.local_representation.name): - self.local_representation.build(None) - if getattr(self, "attn", None) is not None: - with tf.name_scope(self.attn.name): - self.attn.build(None) - if getattr(self, "linear", None) is not None: - with tf.name_scope(self.linear.name): - self.linear.build(None) - self.built = True - - def call(self, x: tf.Tensor, training: bool = False): - x = self.local_representation(x, training=training) - batch_size, height, width, channels = x.shape - - res = tf.reshape(x, [-1, height * width, channels]) - res = self.attn(res) - res = tf.reshape(res, [-1, height, width, channels]) - if self.use_layer_scale: - x = x + self.drop_path(self.layer_scale_1 * res, training=training) - x = x + self.drop_path(self.layer_scale_2 * self.linear(x), training=training) - else: - x = x + self.drop_path(res, training=training) - x = x + self.drop_path(self.linear(x), training=training) - return x - - -class TFSwiftFormerStage(keras.layers.Layer): - """ - A Swiftformer stage consisting of a series of `SwiftFormerConvEncoder` blocks and a final - `SwiftFormerEncoderBlock`. - - Input: tensor in shape `[batch_size, channels, height, width]` - - Output: tensor in shape `[batch_size, channels, height, width]` - """ - - def __init__(self, config: SwiftFormerConfig, index: int, **kwargs) -> None: - super().__init__(**kwargs) - - layer_depths = config.depths - dim = config.embed_dims[index] - depth = layer_depths[index] - - self.blocks = [] - for block_idx in range(depth): - block_dpr = config.drop_path_rate * (block_idx + sum(layer_depths[:index])) / (sum(layer_depths) - 1) - - if depth - block_idx <= 1: - self.blocks.append( - TFSwiftFormerEncoderBlock(config, dim=dim, drop_path=block_dpr, name=f"blocks_._{block_idx}") - ) - else: - self.blocks.append(TFSwiftFormerConvEncoder(config, dim=dim, name=f"blocks_._{block_idx}")) - - def call(self, input: tf.Tensor, training: bool = False) -> tf.Tensor: - for i, block in enumerate(self.blocks): - input = block(input, training=training) - return input - - def build(self, input_shape=None): - for layer in self.blocks: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFSwiftFormerEncoder(keras.layers.Layer): - def __init__(self, config: SwiftFormerConfig, **kwargs) -> None: - super().__init__(**kwargs) - self.config = config - - embed_dims = config.embed_dims - downsamples = config.downsamples - layer_depths = config.depths - - # Transformer model - self.network = [] - name_i = 0 - for i in range(len(layer_depths)): - stage = TFSwiftFormerStage(config, index=i, name=f"network_._{name_i}") - self.network.append(stage) - name_i += 1 - if i >= len(layer_depths) - 1: - break - if downsamples[i] or embed_dims[i] != embed_dims[i + 1]: - # downsampling between two stages - self.network.append(TFSwiftFormerEmbeddings(config, index=i, name=f"network_._{name_i}")) - name_i += 1 - - self.gradient_checkpointing = False - - def call( - self, - hidden_states: tf.Tensor, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[tuple, TFBaseModelOutputWithNoAttention]: - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - all_hidden_states = (hidden_states,) if output_hidden_states else None - - for i, block in enumerate(self.network): - hidden_states = block(hidden_states, training=training) - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - hidden_states = tf.transpose(hidden_states, perm=[0, 3, 1, 2]) - if all_hidden_states: - all_hidden_states = tuple(tf.transpose(s, perm=[0, 3, 1, 2]) for s in all_hidden_states) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states] if v is not None) - - return TFBaseModelOutputWithNoAttention( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - ) - - def build(self, input_shape=None): - for layer in self.network: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFSwiftFormerPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = SwiftFormerConfig - base_model_prefix = "swiftformer" - main_input_name = "pixel_values" - - -TFSWIFTFORMER_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TF 2.0 models accepts two formats as inputs: - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional arguments. - This second option is useful when using [`keras.Model.fit`] method which currently requires having all the - tensors in the first argument of the model call function: `model(inputs)`. - If you choose this second option, there are three possibilities you can use to gather all the input Tensors in the - first positional argument : - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - - - Parameters: - config ([`SwiftFormerConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -TFSWIFTFORMER_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] - for details. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - training (`bool`, *optional*, defaults to `False`): - Whether or not to run the model in training mode. -""" - - -@keras_serializable -class TFSwiftFormerMainLayer(keras.layers.Layer): - config_class = SwiftFormerConfig - - def __init__(self, config: SwiftFormerConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - - self.patch_embed = TFSwiftFormerPatchEmbedding(config, name="patch_embed") - self.encoder = TFSwiftFormerEncoder(config, name="encoder") - - @unpack_inputs - def call( - self, - pixel_values: Optional[tf.Tensor] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[tuple, TFBaseModelOutputWithNoAttention]: - r""" """ - - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # TF 2.0 image layers can't use NCHW format when running on CPU. - # We transpose to NHWC format and then transpose back after the full forward pass. - # (batch_size, num_channels, height, width) -> (batch_size, height, width, num_channels) - pixel_values = tf.transpose(pixel_values, perm=[0, 2, 3, 1]) - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - embedding_output = self.patch_embed(pixel_values, training=training) - encoder_outputs = self.encoder( - embedding_output, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return tuple(v for v in encoder_outputs if v is not None) - - return TFBaseModelOutputWithNoAttention( - last_hidden_state=encoder_outputs.last_hidden_state, - hidden_states=encoder_outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - if getattr(self, "patch_embed", None) is not None: - with tf.name_scope(self.patch_embed.name): - self.patch_embed.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - self.built = True - - -@add_start_docstrings( - "The bare TFSwiftFormer Model transformer outputting raw hidden-states without any specific head on top.", - TFSWIFTFORMER_START_DOCSTRING, -) -class TFSwiftFormerModel(TFSwiftFormerPreTrainedModel): - def __init__(self, config: SwiftFormerConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.swiftformer = TFSwiftFormerMainLayer(config, name="swiftformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(TFSWIFTFORMER_INPUTS_DOCSTRING) - def call( - self, - pixel_values: Optional[tf.Tensor] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[TFBaseModelOutputWithNoAttention, tuple[tf.Tensor]]: - outputs = self.swiftformer( - pixel_values=pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - def build(self, input_shape=None): - if self.built: - return - if getattr(self, "swiftformer", None) is not None: - with tf.name_scope(self.swiftformer.name): - self.swiftformer.build(None) - self.built = True - - -@add_start_docstrings( - """ - TFSwiftFormer Model transformer with an image classification head on top (e.g. for ImageNet). - """, - TFSWIFTFORMER_START_DOCSTRING, -) -class TFSwiftFormerForImageClassification(TFSwiftFormerPreTrainedModel): - def __init__(self, config: SwiftFormerConfig, **kwargs) -> None: - super().__init__(config, **kwargs) - - self.num_labels = config.num_labels - self.swiftformer = TFSwiftFormerMainLayer(config, name="swiftformer") - - # Classifier head - self.norm = keras.layers.BatchNormalization(epsilon=config.batch_norm_eps, momentum=0.9, name="norm") - self.head = ( - keras.layers.Dense(self.num_labels, name="head") - if self.num_labels > 0 - else keras.layers.Identity(name="head") - ) - self.dist_head = ( - keras.layers.Dense(self.num_labels, name="dist_head") - if self.num_labels > 0 - else keras.layers.Identity(name="dist_head") - ) - - def hf_compute_loss(self, labels, logits): - if self.config.problem_type is None: - if self.num_labels == 1: - self.config.problem_type = "regression" - elif self.num_labels > 1 and (labels.dtype == tf.int64 or labels.dtype == tf.int32): - self.config.problem_type = "single_label_classification" - else: - self.config.problem_type = "multi_label_classification" - - if self.config.problem_type == "regression": - loss_fct = keras.losses.MSE - if self.num_labels == 1: - loss = loss_fct(labels.squeeze(), logits.squeeze()) - else: - loss = loss_fct(labels, logits) - elif self.config.problem_type == "single_label_classification": - loss_fct = keras.losses.SparseCategoricalCrossentropy( - from_logits=True, reduction=keras.losses.Reduction.NONE - ) - loss = loss_fct(labels, logits) - elif self.config.problem_type == "multi_label_classification": - loss_fct = keras.losses.SparseCategoricalCrossentropy( - from_logits=True, - reduction=keras.losses.Reduction.NONE, - ) - loss = loss_fct(labels, logits) - else: - loss = None - - return loss - - @unpack_inputs - @add_start_docstrings_to_model_forward(TFSWIFTFORMER_INPUTS_DOCSTRING) - def call( - self, - pixel_values: Optional[tf.Tensor] = None, - labels: Optional[tf.Tensor] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - training: bool = False, - ) -> Union[tuple, TFImageClassifierOutputWithNoAttention]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # run base model - outputs = self.swiftformer( - pixel_values, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs.last_hidden_state if return_dict else outputs[0] - sequence_output = tf.transpose(sequence_output, perm=[0, 2, 3, 1]) - - # run classification head - sequence_output = self.norm(sequence_output, training=training) - sequence_output = tf.transpose(sequence_output, perm=[0, 3, 1, 2]) - _, num_channels, height, width = sequence_output.shape - sequence_output = tf.reshape(sequence_output, [-1, num_channels, height * width]) - sequence_output = tf.reduce_mean(sequence_output, axis=-1) - cls_out = self.head(sequence_output) - distillation_out = self.dist_head(sequence_output) - logits = (cls_out + distillation_out) / 2 - - # calculate loss - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFImageClassifierOutputWithNoAttention( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - if getattr(self, "swiftformer", None) is not None: - with tf.name_scope(self.swiftformer.name): - self.swiftformer.build(None) - if getattr(self, "norm", None) is not None: - with tf.name_scope(self.norm.name): - self.norm.build((None, None, None, self.config.embed_dims[-1])) - if getattr(self, "head", None) is not None: - with tf.name_scope(self.head.name): - self.head.build(self.config.embed_dims[-1]) - if getattr(self, "dist_head", None) is not None: - with tf.name_scope(self.dist_head.name): - self.dist_head.build(self.config.embed_dims[-1]) - self.built = True - - -__all__ = ["TFSwiftFormerForImageClassification", "TFSwiftFormerModel", "TFSwiftFormerPreTrainedModel"] diff --git a/src/transformers/models/swin/__init__.py b/src/transformers/models/swin/__init__.py index 3dc5871b0375..bf351e817fdf 100644 --- a/src/transformers/models/swin/__init__.py +++ b/src/transformers/models/swin/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_swin import * from .modeling_swin import * - from .modeling_tf_swin import * else: import sys diff --git a/src/transformers/models/swin/modeling_swin.py b/src/transformers/models/swin/modeling_swin.py index 18b61abbd3a4..7f9e04337ba4 100644 --- a/src/transformers/models/swin/modeling_swin.py +++ b/src/transformers/models/swin/modeling_swin.py @@ -365,11 +365,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -856,8 +851,6 @@ class SwinPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/swin/modeling_tf_swin.py b/src/transformers/models/swin/modeling_tf_swin.py deleted file mode 100644 index 7fa54e958046..000000000000 --- a/src/transformers/models/swin/modeling_tf_swin.py +++ /dev/null @@ -1,1639 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Microsoft Research and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 Swin Transformer model.""" - -from __future__ import annotations - -import collections.abc -import math -import warnings -from collections.abc import Iterable -from dataclasses import dataclass -from functools import partial -from typing import Any, Callable - -import tensorflow as tf - -from ...activations_tf import ACT2FN -from ...modeling_tf_utils import ( - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_swin import SwinConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "SwinConfig" - -# Base docstring -_CHECKPOINT_FOR_DOC = "microsoft/swin-tiny-patch4-window7-224" -_EXPECTED_OUTPUT_SHAPE = [1, 49, 768] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "microsoft/swin-tiny-patch4-window7-224" -_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" - - -# drop_path, TFSwinPatchEmbeddings, TFSwinPatchMerging and TFSwinDropPath are tensorflow -# implementations of PyTorch functionalities in the timm library. - - -@dataclass -class TFSwinEncoderOutput(ModelOutput): - """ - Swin encoder's outputs, with potential hidden states and attentions. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each stage) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each stage) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - reshaped_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each stage) of shape - `(batch_size, hidden_size, height, width)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to - include the spatial dimensions. - """ - - last_hidden_state: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - reshaped_hidden_states: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFSwinModelOutput(ModelOutput): - """ - Swin model's outputs that also contains a pooling of the last hidden states. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - pooler_output (`tf.Tensor` of shape `(batch_size, hidden_size)`, *optional*, returned when `add_pooling_layer=True` is passed): - Average pooling of the last layer hidden-state. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each stage) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each stage) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - reshaped_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each stage) of shape - `(batch_size, hidden_size, height, width)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to - include the spatial dimensions. - """ - - last_hidden_state: tf.Tensor | None = None - pooler_output: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - reshaped_hidden_states: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFSwinMaskedImageModelingOutput(ModelOutput): - """ - Swin masked image model outputs. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `bool_masked_pos` is provided): - Masked image modeling (MLM) loss. - reconstruction (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Reconstructed pixel values. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each stage) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each stage) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - reshaped_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each stage) of shape - `(batch_size, hidden_size, height, width)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to - include the spatial dimensions. - """ - - loss: tf.Tensor | None = None - reconstruction: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - reshaped_hidden_states: tuple[tf.Tensor, ...] | None = None - - @property - def logits(self): - warnings.warn( - "logits attribute is deprecated and will be removed in version 5 of Transformers." - " Please use the reconstruction attribute to retrieve the final output instead.", - FutureWarning, - ) - return self.reconstruction - - -@dataclass -class TFSwinImageClassifierOutput(ModelOutput): - """ - Swin outputs for image classification. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each stage) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each stage) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - reshaped_hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each stage) of shape - `(batch_size, hidden_size, height, width)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to - include the spatial dimensions. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - reshaped_hidden_states: tuple[tf.Tensor, ...] | None = None - - -def window_partition(input_feature: tf.Tensor, window_size: int) -> tf.Tensor: - """ - Partitions the given input into windows. - """ - batch_size, height, width, num_channels = shape_list(input_feature) - input_feature = tf.reshape( - input_feature, - (batch_size, height // window_size, window_size, width // window_size, window_size, num_channels), - ) - windows = tf.transpose(input_feature, (0, 1, 3, 2, 4, 5)) - windows = tf.reshape(windows, (-1, window_size, window_size, num_channels)) - return windows - - -def window_reverse(windows: tf.Tensor, window_size: int, height: int, width: int) -> tf.Tensor: - """ - Merges windows to produce higher resolution features. - """ - x = tf.shape(windows)[0] - y = tf.cast(height * width / (window_size * window_size), tf.int32) - batch_size = tf.math.floordiv(x, y) - windows = tf.reshape( - windows, (batch_size, height // window_size, width // window_size, window_size, window_size, -1) - ) - windows = tf.transpose(windows, (0, 1, 3, 2, 4, 5)) - windows = tf.reshape(windows, (batch_size, height, width, -1)) - return windows - - -def drop_path( - input: tf.Tensor, drop_prob: float = 0.0, training: bool = False, scale_by_keep: bool = True -) -> tf.Tensor: - """ - Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - """ - if drop_prob == 0.0 or not training: - return input - keep_prob = 1 - drop_prob - input_shape = shape_list(input) - ndim = len(input_shape) - shape = [input_shape[0]] + [1] * (ndim - 1) # work with diff dim tensors, not just 2D ConvNets - random_tensor = tf.random.uniform(shape) - random_tensor = tf.where(random_tensor <= keep_prob, 1.0, 0.0) - if keep_prob > 0.0 and scale_by_keep: - random_tensor /= keep_prob - return input * random_tensor - - -class TFSwinEmbeddings(keras.layers.Layer): - """ - Construct the patch and position embeddings. Optionally, also the mask token. - """ - - def __init__(self, config: SwinConfig, use_mask_token: bool = False, **kwargs) -> None: - super().__init__(**kwargs) - self.patch_embeddings = TFSwinPatchEmbeddings(config, name="patch_embeddings") - self.num_patches = self.patch_embeddings.num_patches - self.patch_grid = self.patch_embeddings.grid_size - self.embed_dim = config.embed_dim - self.use_mask_token = use_mask_token - self.use_absolute_embeddings = config.use_absolute_embeddings - - self.norm = keras.layers.LayerNormalization(name="norm", epsilon=1e-5) - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob, name="dropout") - self.config = config - - def build(self, input_shape: tf.TensorShape) -> None: - if self.use_mask_token: - self.mask_token = self.add_weight(shape=(1, 1, self.embed_dim), initializer="zeros", name="mask_token") - else: - self.mask_token = None - - if self.use_absolute_embeddings: - self.position_embeddings = self.add_weight( - (1, self.num_patches + 1, self.embed_dim), initializer="zeros", name="positional_embeddings" - ) - else: - self.position_embeddings = None - - if self.built: - return - self.built = True - if getattr(self, "patch_embeddings", None) is not None: - with tf.name_scope(self.patch_embeddings.name): - self.patch_embeddings.build(None) - if getattr(self, "norm", None) is not None: - with tf.name_scope(self.norm.name): - self.norm.build([None, None, self.config.embed_dim]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - def call( - self, pixel_values: tf.Tensor, bool_masked_pos: bool | None = None, training: bool = False - ) -> tuple[tf.Tensor, tuple[int, int]]: - embeddings, output_dimensions = self.patch_embeddings(pixel_values, training=training) - embeddings = self.norm(embeddings, training=training) - batch_size, seq_len, _ = shape_list(embeddings) - - if bool_masked_pos is not None: - mask_tokens = tf.repeat(self.mask_token, batch_size, 0) - mask_tokens = tf.repeat(mask_tokens, seq_len, 1) - # replace the masked visual tokens by mask_tokens - mask = tf.expand_dims(bool_masked_pos, -1) - mask = tf.cast(mask, mask_tokens.dtype) - - embeddings = embeddings * (1.0 - mask) + mask_tokens * mask - - if self.position_embeddings is not None: - embeddings = embeddings + self.position_embeddings - - embeddings = self.dropout(embeddings, training=training) - - return embeddings, output_dimensions - - -class TFSwinPatchEmbeddings(keras.layers.Layer): - """ - Image to Patch Embedding. - """ - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - image_size, patch_size = config.image_size, config.patch_size - num_channels, hidden_size = config.num_channels, config.embed_dim - image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) - patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) - num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) - self.image_size = image_size - self.patch_size = patch_size - self.num_channels = num_channels - self.num_patches = num_patches - self.grid_size = (image_size[0] // patch_size[0], image_size[1] // patch_size[1]) - - self.projection = keras.layers.Conv2D( - filters=hidden_size, - kernel_size=self.patch_size, - strides=self.patch_size, - padding="valid", - name="projection", - ) - - def maybe_pad(self, pixel_values: tf.Tensor, height: int, width: int) -> tf.Tensor: - if width % self.patch_size[1] != 0: - pad_values = ((0, 0), (0, 0), (0, 0), (0, self.patch_size[1] - width % self.patch_size[1])) - pixel_values = tf.pad(pixel_values, pad_values) - if height % self.patch_size[0] != 0: - pad_values = ((0, 0), (0, 0), (0, self.patch_size[0] - height % self.patch_size[0]), (0, 0)) - pixel_values = tf.pad(pixel_values, pad_values) - return pixel_values - - def call(self, pixel_values: tf.Tensor, training: bool = False) -> tuple[tf.Tensor, tuple[int, int]]: - _, num_channels, height, width = shape_list(pixel_values) - if tf.executing_eagerly() and num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - # pad the input to be divisible by self.patch_size, if needed - pixel_values = self.maybe_pad(pixel_values, height, width) - - # B,C,H,W -> B,H,W,C - pixel_values = tf.transpose(pixel_values, (0, 2, 3, 1)) - - embeddings = self.projection(pixel_values, training=training) - - # B,H,W,C -> B,C,H,W - embeddings = tf.transpose(embeddings, (0, 3, 1, 2)) - - batch_size, channels, height, width = shape_list(embeddings) - output_dimensions = (height, width) - - embeddings = tf.reshape(embeddings, (batch_size, channels, -1)) - embeddings = tf.transpose(embeddings, (0, 2, 1)) - return embeddings, output_dimensions - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, None, self.num_channels]) - - -class TFSwinPatchMerging(keras.layers.Layer): - """ - Patch Merging Layer. - - Args: - input_resolution (`tuple[int]`): - Resolution of input feature. - dim (`int`): - Number of input channels. - norm_layer (`keras.layer.Layer`, *optional*, defaults to `keras.layers.LayerNormalization`): - Normalization layer class. - """ - - def __init__( - self, input_resolution: tuple[int, int], dim: int, norm_layer: Callable | None = None, **kwargs - ) -> None: - super().__init__(**kwargs) - self.input_resolution = input_resolution - self.dim = dim - self.reduction = keras.layers.Dense(2 * dim, use_bias=False, name="reduction") - if norm_layer is None: - # Use same default epsilon as PyTorch - self.norm = keras.layers.LayerNormalization(epsilon=1e-5, name="norm") - else: - self.norm = norm_layer(name="norm") - - def maybe_pad(self, input_feature: tf.Tensor, height: int, width: int) -> tf.Tensor: - should_pad = (height % 2 == 1) or (width % 2 == 1) - if should_pad: - pad_values = ((0, 0), (0, height % 2), (0, width % 2), (0, 0)) - input_feature = tf.pad(input_feature, pad_values) - - return input_feature - - def call(self, input_feature: tf.Tensor, input_dimensions: tuple[int, int], training: bool = False) -> tf.Tensor: - height, width = input_dimensions - # `dim` is height * width - batch_size, _, num_channels = shape_list(input_feature) - - input_feature = tf.reshape(input_feature, (batch_size, height, width, num_channels)) - # pad input to be divisible by width and height, if needed - input_feature = self.maybe_pad(input_feature, height, width) - # [batch_size, height/2, width/2, num_channels] - input_feature_0 = input_feature[:, 0::2, 0::2, :] - # [batch_size, height/2, width/2, num_channels] - input_feature_1 = input_feature[:, 1::2, 0::2, :] - # [batch_size, height/2, width/2, num_channels] - input_feature_2 = input_feature[:, 0::2, 1::2, :] - # [batch_size, height/2, width/2, num_channels] - input_feature_3 = input_feature[:, 1::2, 1::2, :] - # batch_size height/2 width/2 4*num_channels - input_feature = tf.concat([input_feature_0, input_feature_1, input_feature_2, input_feature_3], -1) - input_feature = tf.reshape( - input_feature, (batch_size, -1, 4 * num_channels) - ) # batch_size height/2*width/2 4*C - - input_feature = self.norm(input_feature, training=training) - input_feature = self.reduction(input_feature, training=training) - - return input_feature - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "reduction", None) is not None: - with tf.name_scope(self.reduction.name): - self.reduction.build([None, None, 4 * self.dim]) - if getattr(self, "norm", None) is not None: - with tf.name_scope(self.norm.name): - self.norm.build([None, None, 4 * self.dim]) - - -class TFSwinDropPath(keras.layers.Layer): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" - - def __init__(self, drop_prob: float | None = None, scale_by_keep: bool = True, **kwargs) -> None: - super().__init__(**kwargs) - self.drop_prob = drop_prob - self.scale_by_keep = scale_by_keep - - def call(self, input: tf.Tensor, training: bool = False) -> tf.Tensor: - return drop_path(input, self.drop_prob, training, self.scale_by_keep) - - -class TFSwinSelfAttention(keras.layers.Layer): - def __init__(self, config: SwinConfig, dim: int, num_heads: int, **kwargs) -> None: - super().__init__(**kwargs) - if dim % num_heads != 0: - raise ValueError( - f"The hidden size ({dim}) is not a multiple of the number of attention heads ({num_heads})" - ) - - self.num_attention_heads = num_heads - self.attention_head_size = int(dim / num_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - window_size = config.window_size - self.window_size = ( - window_size if isinstance(window_size, collections.abc.Iterable) else (window_size, window_size) - ) - - self.query = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - use_bias=config.qkv_bias, - name="query", - ) - self.key = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - use_bias=config.qkv_bias, - name="key", - ) - self.value = keras.layers.Dense( - self.all_head_size, - kernel_initializer=get_initializer(config.initializer_range), - use_bias=config.qkv_bias, - name="value", - ) - - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob) - - def build(self, input_shape: tf.TensorShape) -> None: - self.relative_position_bias_table = self.add_weight( - shape=(((2 * self.window_size[0] - 1) * (2 * self.window_size[1] - 1)), self.num_attention_heads), - initializer="zeros", - name="relative_position_bias_table", - ) - self.relative_position_index = self.add_weight( - shape=(self.window_size[0] ** 2, self.window_size[1] ** 2), - trainable=False, - dtype=tf.int32, - name="relative_position_index", - ) - - # get pair-wise relative position index for each token inside the window - coords_h = tf.range(self.window_size[0]) - coords_w = tf.range(self.window_size[1]) - coords = tf.stack(tf.meshgrid(coords_h, coords_w, indexing="ij")) - coords_flatten = tf.reshape(coords, (shape_list(coords)[0], -1)) - relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] - relative_coords = tf.transpose(relative_coords, (1, 2, 0)) - - stack_0, stack_1 = tf.unstack(relative_coords, axis=2) - stack_0 += self.window_size[0] - 1 - stack_0 *= 2 * self.window_size[1] - 1 - stack_1 += self.window_size[1] - 1 - relative_coords = tf.stack([stack_0, stack_1], axis=2) - - self.relative_position_index.assign(tf.cast(tf.reduce_sum(relative_coords, axis=-1), tf.int32)) - - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.all_head_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.all_head_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.all_head_size]) - - def transpose_for_scores(self, x: tf.Tensor) -> tf.Tensor: - new_x_shape = shape_list(x)[:-1] + [self.num_attention_heads, self.attention_head_size] - x = tf.reshape(x, new_x_shape) - return tf.transpose(x, (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool = False, - training: bool = False, - ) -> tuple[tf.Tensor, ...]: - batch_size, dim, _ = shape_list(hidden_states) - mixed_query_layer = self.query(hidden_states) - - key_layer = self.transpose_for_scores(self.key(hidden_states)) - value_layer = self.transpose_for_scores(self.value(hidden_states)) - query_layer = self.transpose_for_scores(mixed_query_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = tf.matmul(query_layer, tf.transpose(key_layer, (0, 1, 3, 2))) - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - relative_position_bias = tf.gather( - self.relative_position_bias_table, tf.reshape(self.relative_position_index, (-1,)) - ) - relative_position_bias = tf.reshape( - relative_position_bias, - (self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1), - ) - - relative_position_bias = tf.transpose(relative_position_bias, (2, 0, 1)) - attention_scores = attention_scores + tf.expand_dims(relative_position_bias, 0) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in SwinModel call() function) - mask_shape = shape_list(attention_mask)[0] - attention_scores = tf.reshape( - attention_scores, (batch_size // mask_shape, mask_shape, self.num_attention_heads, dim, dim) - ) - attention_mask = tf.expand_dims(attention_mask, 1) - attention_mask = tf.expand_dims(attention_mask, 0) - attention_scores = attention_scores + attention_mask - attention_scores = tf.reshape(attention_scores, (-1, self.num_attention_heads, dim, dim)) - - # Normalize the attention scores to probabilities. - attention_probs = tf.nn.softmax(attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - - context_layer = tf.matmul(attention_probs, value_layer) - context_layer = tf.transpose(context_layer, (0, 2, 1, 3)) - new_context_layer_shape = shape_list(context_layer)[:-2] + [ - self.all_head_size, - ] - context_layer = tf.reshape(context_layer, new_context_layer_shape) - - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - - return outputs - - -class TFSwinSelfOutput(keras.layers.Layer): - def __init__(self, config: SwinConfig, dim: int, **kwargs) -> None: - super().__init__(**kwargs) - self.dense = keras.layers.Dense(dim, name="dense") - self.dropout = keras.layers.Dropout(config.attention_probs_dropout_prob, name="dropout") - self.dim = dim - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.dim]) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - - -class TFSwinAttention(keras.layers.Layer): - def __init__(self, config: SwinConfig, dim: int, num_heads: int, **kwargs) -> None: - super().__init__(**kwargs) - self.self = TFSwinSelfAttention(config, dim, num_heads, name="self") - self.self_output = TFSwinSelfOutput(config, dim, name="output") - self.pruned_heads = set() - - def prune_heads(self, heads): - """ - Prunes heads of the model. See base class PreTrainedModel heads: dict of {layer_num: list of heads to prune in - this layer} - """ - raise NotImplementedError - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool = False, - training: bool = False, - ) -> tf.Tensor: - self_outputs = self.self(hidden_states, attention_mask, head_mask, output_attentions, training=training) - attention_output = self.self_output(self_outputs[0], hidden_states, training=training) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self", None) is not None: - with tf.name_scope(self.self.name): - self.self.build(None) - if getattr(self, "self_output", None) is not None: - with tf.name_scope(self.self_output.name): - self.self_output.build(None) - - -class TFSwinIntermediate(keras.layers.Layer): - def __init__(self, config: SwinConfig, dim: int, **kwargs) -> None: - super().__init__(**kwargs) - self.dense = keras.layers.Dense(int(config.mlp_ratio * dim), name="dense") - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = ACT2FN[config.hidden_act] - else: - self.intermediate_act_fn = config.hidden_act - self.dim = dim - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.dim]) - - -class TFSwinOutput(keras.layers.Layer): - def __init__(self, config: SwinConfig, dim: int, **kwargs) -> None: - super().__init__(**kwargs) - self.dense = keras.layers.Dense(dim, name="dense") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob, "dropout") - self.config = config - self.dim = dim - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, int(self.config.mlp_ratio * self.dim)]) - - -class TFSwinLayer(keras.layers.Layer): - def __init__( - self, - config, - dim, - input_resolution: tuple[int, int], - num_heads: int, - drop_path_rate: float = 0.0, - shift_size: int = 0, - **kwargs, - ) -> None: - super().__init__(**kwargs) - self.chunk_size_feed_forward = config.chunk_size_feed_forward - min_res = tf.reduce_min(input_resolution) - self.window_size = min_res if min_res <= config.window_size else config.window_size - self.shift_size = 0 if min_res <= self.window_size else shift_size - self.input_resolution = input_resolution - - self.layernorm_before = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_before") - self.attention = TFSwinAttention(config, dim, num_heads, name="attention") - self.drop_path = ( - TFSwinDropPath(drop_path_rate, name="drop_path") - if drop_path_rate > 0.0 - else keras.layers.Activation("linear", name="drop_path") - ) - self.layernorm_after = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_after") - self.intermediate = TFSwinIntermediate(config, dim, name="intermediate") - self.swin_output = TFSwinOutput(config, dim, name="output") - self.dim = dim - - def get_attn_mask(self, height: int, width: int, window_size: int, shift_size: int) -> tf.Tensor | None: - img_mask = tf.zeros((height, width)) - height_slices = ((0, -window_size), (-window_size, -shift_size), (-shift_size, -1)) - width_slices = ((0, -window_size), (-window_size, -shift_size), (-shift_size, -1)) - - # calculate attention mask for SW-MSA - if shift_size > 0: - count = 0 - for height_slice in height_slices: - for width_slice in width_slices: - height_inds = tf.range(height_slice[0] % height, height_slice[1] % height + 1) - width_inds = tf.range(width_slice[0] % width, width_slice[1] % width + 1) - indices = tf.reshape(tf.stack(tf.meshgrid(height_inds, width_inds), axis=-1), (-1, 2)) - if len(indices) >= 1: - updates = tf.ones((len(indices),), dtype=img_mask.dtype) * count - img_mask = tf.tensor_scatter_nd_update(img_mask, indices, updates) - count += 1 - - img_mask = tf.expand_dims(img_mask, -1) - img_mask = tf.expand_dims(img_mask, 0) - - mask_windows = window_partition(img_mask, window_size) - mask_windows = tf.reshape(mask_windows, (-1, window_size * window_size)) - attn_mask = tf.expand_dims(mask_windows, 1) - tf.expand_dims(mask_windows, 2) - attn_mask = tf.where(attn_mask != 0, -100.0, attn_mask) - attn_mask = tf.where(attn_mask == 0, 0.0, attn_mask) - return attn_mask - - def maybe_pad( - self, hidden_states: tf.Tensor, window_size: int, height: int, width: int - ) -> tuple[tf.Tensor, tf.Tensor]: - pad_right = (window_size - width % window_size) % window_size - pad_bottom = (window_size - height % window_size) % window_size - pad_values = [[0, 0], [0, pad_bottom], [0, pad_right], [0, 0]] - hidden_states = tf.pad(hidden_states, pad_values) - pad_values = tf.reshape(pad_values, (-1,)) - return hidden_states, pad_values - - def call( - self, - hidden_states: tf.Tensor, - input_dimensions: tuple[int, int], - head_mask: tf.Tensor | None = None, - output_attentions: bool = False, - training: bool = False, - ) -> tf.Tensor: - # if window size is larger than input resolution, we don't partition windows - min_res = tf.reduce_min(input_dimensions) - shift_size = 0 if min_res <= self.window_size else self.shift_size - window_size = min_res if min_res <= self.window_size else self.window_size - - height, width = input_dimensions - batch_size, _, channels = shape_list(hidden_states) - shortcut = hidden_states - - hidden_states = self.layernorm_before(hidden_states, training=training) - hidden_states = tf.reshape(hidden_states, (batch_size, height, width, channels)) - # pad hidden_states to multiples of window size - hidden_states, pad_values = self.maybe_pad(hidden_states, window_size, height, width) - - _, height_pad, width_pad, _ = shape_list(hidden_states) - # cyclic shift - if shift_size > 0: - shifted_hidden_states = tf.roll(hidden_states, shift=(-shift_size, -shift_size), axis=(1, 2)) - else: - shifted_hidden_states = hidden_states - - # partition windows - hidden_states_windows = window_partition(shifted_hidden_states, window_size) - hidden_states_windows = tf.reshape(hidden_states_windows, (-1, window_size * window_size, channels)) - attn_mask = self.get_attn_mask( - height=height_pad, width=width_pad, window_size=window_size, shift_size=shift_size - ) - - attention_outputs = self.attention( - hidden_states_windows, attn_mask, head_mask, output_attentions=output_attentions, training=training - ) - - attention_output = attention_outputs[0] - - attention_windows = tf.reshape(attention_output, (-1, window_size, window_size, channels)) - shifted_windows = window_reverse(attention_windows, window_size, height_pad, width_pad) - - # reverse cyclic shift - if shift_size > 0: - attention_windows = tf.roll(shifted_windows, shift=(shift_size, shift_size), axis=(1, 2)) - else: - attention_windows = shifted_windows - - was_padded = pad_values[3] > 0 or pad_values[5] > 0 - if was_padded: - attention_windows = attention_windows[:, :height, :width, :] - - attention_windows = tf.reshape(attention_windows, (batch_size, height * width, channels)) - - hidden_states = shortcut + self.drop_path(attention_windows, training=training) - - layer_output = self.layernorm_after(hidden_states, training=training) - layer_output = self.intermediate(layer_output) - layer_output = hidden_states + self.swin_output(layer_output, training=training) - - layer_outputs = (layer_output, attention_outputs[1]) if output_attentions else (layer_output,) - return layer_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layernorm_before", None) is not None: - with tf.name_scope(self.layernorm_before.name): - self.layernorm_before.build([None, None, self.dim]) - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "drop_path", None) is not None: - with tf.name_scope(self.drop_path.name): - self.drop_path.build(None) - if getattr(self, "layernorm_after", None) is not None: - with tf.name_scope(self.layernorm_after.name): - self.layernorm_after.build([None, None, self.dim]) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "swin_output", None) is not None: - with tf.name_scope(self.swin_output.name): - self.swin_output.build(None) - - -class TFSwinStage(keras.layers.Layer): - def __init__( - self, - config: SwinConfig, - dim: int, - input_resolution: tuple[int, int], - depth: int, - num_heads: int, - drop_path: list[float], - downsample: Callable | None, - **kwargs, - ) -> None: - super().__init__(**kwargs) - self.config = config - self.dim = dim - self.blocks = [ - TFSwinLayer( - config=config, - dim=dim, - input_resolution=input_resolution, - num_heads=num_heads, - shift_size=0 if (i % 2 == 0) else config.window_size // 2, - drop_path_rate=drop_path[i], - name=f"blocks.{i}", - ) - for i in range(depth) - ] - - # patch merging layer - if downsample is not None: - self.downsample = downsample( - input_resolution, - dim=dim, - norm_layer=partial(keras.layers.LayerNormalization, epsilon=1e-5), - name="downsample", - ) - else: - self.downsample = None - - self.pointing = False - - def call( - self, - hidden_states: tf.Tensor, - input_dimensions: tuple[int, int], - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = False, - training: bool = False, - ) -> tuple[tf.Tensor, ...]: - height, width = input_dimensions - for i, layer_module in enumerate(self.blocks): - layer_head_mask = head_mask[i] if head_mask is not None else None - - layer_outputs = layer_module( - hidden_states, input_dimensions, layer_head_mask, output_attentions, training=training - ) - - hidden_states = layer_outputs[0] - - if self.downsample is not None: - height_downsampled, width_downsampled = (height + 1) // 2, (width + 1) // 2 - output_dimensions = (height, width, height_downsampled, width_downsampled) - hidden_states = self.downsample(layer_outputs[0], input_dimensions, training=training) - else: - output_dimensions = (height, width, height, width) - - stage_outputs = (hidden_states, output_dimensions) - - if output_attentions: - stage_outputs += layer_outputs[1:] - return stage_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "downsample", None) is not None: - with tf.name_scope(self.downsample.name): - self.downsample.build(None) - if getattr(self, "blocks", None) is not None: - for layer in self.blocks: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFSwinEncoder(keras.layers.Layer): - def __init__(self, config: SwinConfig, grid_size: tuple[int, int], **kwargs): - super().__init__(**kwargs) - self.num_layers = len(config.depths) - self.config = config - dpr = list((tf.linspace(0, 1, sum(config.depths)) * config.drop_path_rate).numpy()) - self.layers = [ - TFSwinStage( - config=config, - dim=int(config.embed_dim * 2**i_layer), - input_resolution=(grid_size[0] // (2**i_layer), grid_size[1] // (2**i_layer)), - depth=config.depths[i_layer], - num_heads=config.num_heads[i_layer], - drop_path=dpr[sum(config.depths[:i_layer]) : sum(config.depths[: i_layer + 1])], - downsample=TFSwinPatchMerging if (i_layer < self.num_layers - 1) else None, - name=f"layers.{i_layer}", - ) - for i_layer in range(self.num_layers) - ] - - self.gradient_checkpointing = False - - def call( - self, - hidden_states: tf.Tensor, - input_dimensions: tuple[int, int], - head_mask: tf.Tensor | None = None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - training: bool = False, - ) -> tuple[tf.Tensor, ...] | TFSwinEncoderOutput: - all_input_dimensions = () - all_hidden_states = () if output_hidden_states else None - all_reshaped_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - - if output_hidden_states: - batch_size, _, hidden_size = shape_list(hidden_states) - # rearrange b (h w) c -> b c h w - reshaped_hidden_state = tf.reshape(hidden_states, (batch_size, *input_dimensions, hidden_size)) - reshaped_hidden_state = tf.transpose(reshaped_hidden_state, (0, 3, 1, 2)) - all_hidden_states += (hidden_states,) - all_reshaped_hidden_states += (reshaped_hidden_state,) - - for i, layer_module in enumerate(self.layers): - layer_head_mask = head_mask[i] if head_mask is not None else None - - layer_outputs = layer_module( - hidden_states, input_dimensions, layer_head_mask, output_attentions, training=training - ) - - hidden_states = layer_outputs[0] - output_dimensions = layer_outputs[1] - - input_dimensions = (output_dimensions[-2], output_dimensions[-1]) - all_input_dimensions += (input_dimensions,) - - if output_hidden_states: - batch_size, _, hidden_size = shape_list(hidden_states) - # rearrange b (h w) c -> b c h w - reshaped_hidden_state = tf.reshape(hidden_states, (batch_size, *input_dimensions, hidden_size)) - reshaped_hidden_state = tf.transpose(reshaped_hidden_state, (0, 3, 1, 2)) - all_hidden_states += (hidden_states,) - all_reshaped_hidden_states += (reshaped_hidden_state,) - - if output_attentions: - all_self_attentions += layer_outputs[2:] - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) - - return TFSwinEncoderOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - reshaped_hidden_states=all_reshaped_hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFSwinPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = SwinConfig - base_model_prefix = "swin" - main_input_name = "pixel_values" - - -SWIN_START_DOCSTRING = r""" - This model is a Tensorflow - [keras.layers.Layer](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer) sub-class. Use it as a - regular Tensorflow Module and refer to the Tensorflow documentation for all matter related to general usage and - behavior. - - Parameters: - config ([`SwinConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -SWIN_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] - for details. - head_mask (`tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def normalize_data_format(value: str) -> str: - """ - From tensorflow addons - https://github.com/tensorflow/addons/blob/8cec33fcaaf1cf90aec7bdd55a0fcdbb251ce5c2/tensorflow_addons/utils/keras_utils.py#L71 - """ - if value is None: - value = keras.backend.image_data_format() - data_format = value.lower() - if data_format not in {"channels_first", "channels_last"}: - raise ValueError( - 'The `data_format` argument must be one of "channels_first", "channels_last". Received: ' + str(value) - ) - return data_format - - -class AdaptiveAveragePooling1D(keras.layers.Layer): - """ - Args: - Average 1D Pooling with adaptive kernel size. - output_size: An integer or tuple/list of a single integer, specifying pooled_features. - The new size of output channels. - data_format: A string, - one of `channels_last` (default) or `channels_first`. The ordering of the dimensions in the inputs. - `channels_last` corresponds to inputs with shape `(batch, steps, channels)` while `channels_first` corresponds - to inputs with shape `(batch, channels, steps)`. - Input shape: - - If `data_format='channels_last'`: 3D tensor with shape `(batch, steps, channels)`. - - If `data_format='channels_first'`: 3D tensor with shape `(batch, channels, steps)`. - Output shape: - - If `data_format='channels_last'`: 3D tensor with shape `(batch_size, pooled_steps, channels)`. - - If `data_format='channels_first'`: 3D tensor with shape `(batch_size, channels, pooled_steps)`. - - Adapted from [tensorflow-addon's adaptive pooling.py]( - https://github.com/tensorflow/addons/blob/8cec33fcaaf1cf90aec7bdd55a0fcdbb251ce5c2/tensorflow_addons/layers/adaptive_pooling.py#L90-L120 - ) - """ - - def __init__( - self, - output_size: int | Iterable[int], - reduce_function: Callable = tf.reduce_mean, - data_format: str | None = None, - **kwargs, - ) -> None: - self.data_format = normalize_data_format(data_format) - self.reduce_function = reduce_function - self.output_size = (output_size,) if isinstance(output_size, int) else tuple(output_size) - super().__init__(**kwargs) - - def call(self, inputs: tf.Tensor, *args) -> None: - bins = self.output_size[0] - if self.data_format == "channels_last": - splits = tf.split(inputs, bins, axis=1) - splits = tf.stack(splits, axis=1) - out_vect = self.reduce_function(splits, axis=2) - else: - splits = tf.split(inputs, bins, axis=2) - splits = tf.stack(splits, axis=2) - out_vect = self.reduce_function(splits, axis=3) - return out_vect - - def compute_output_shape(self, input_shape: Iterable[int]) -> tf.TensorShape: - input_shape = tf.TensorShape(input_shape).as_list() - if self.data_format == "channels_last": - shape = tf.TensorShape([input_shape[0], self.output_size[0], input_shape[2]]) - else: - shape = tf.TensorShape([input_shape[0], input_shape[1], self.output_size[0]]) - return shape - - def get_config(self) -> dict[str, Any]: - config = { - "output_size": self.output_size, - "data_format": self.data_format, - } - base_config = super().get_config() - return {**base_config, **config} - - -@keras_serializable -class TFSwinMainLayer(keras.layers.Layer): - config_class = SwinConfig - - def __init__( - self, config: SwinConfig, add_pooling_layer: bool = True, use_mask_token: bool = False, **kwargs - ) -> None: - super().__init__(**kwargs) - self.config = config - self.num_layers = len(config.depths) - self.num_features = int(config.embed_dim * 2 ** (self.num_layers - 1)) - - self.embeddings = TFSwinEmbeddings(config, use_mask_token=use_mask_token, name="embeddings") - self.encoder = TFSwinEncoder(config, self.embeddings.patch_grid, name="encoder") - - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - self.pooler = AdaptiveAveragePooling1D(output_size=(1,)) if add_pooling_layer else None - - def get_input_embeddings(self) -> TFSwinPatchEmbeddings: - return self.embeddings.patch_embeddings - - def _prune_heads(self, heads_to_prune: dict[int, list]): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - for layer, heads in heads_to_prune.items(): - self.encoder.layer[layer].attention.prune_heads(heads) - - def get_head_mask(self, head_mask: Any | None) -> list: - if head_mask is not None: - raise NotImplementedError - return [None] * len(self.config.depths) - - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor | None = None, - bool_masked_pos: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFSwinModelOutput | tuple[tf.Tensor, ...]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - head_mask = self.get_head_mask(head_mask) - embedding_output, input_dimensions = self.embeddings( - pixel_values, bool_masked_pos=bool_masked_pos, training=training - ) - - encoder_outputs = self.encoder( - embedding_output, - input_dimensions, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - sequence_output = self.layernorm(sequence_output, training=training) - - pooled_output = None - if self.pooler is not None: - batch_size, _, num_features = shape_list(sequence_output) - pooled_output = self.pooler(sequence_output) - pooled_output = tf.reshape(pooled_output, (batch_size, num_features)) - - if not return_dict: - output = (sequence_output, pooled_output) + encoder_outputs[1:] - return output - - return TFSwinModelOutput( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - reshaped_hidden_states=encoder_outputs.reshaped_hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, self.num_features]) - - -@add_start_docstrings( - "The bare Swin Model transformer outputting raw hidden-states without any specific head on top.", - SWIN_START_DOCSTRING, -) -class TFSwinModel(TFSwinPreTrainedModel): - def __init__( - self, config: SwinConfig, add_pooling_layer: bool = True, use_mask_token: bool = False, **kwargs - ) -> None: - super().__init__(config, **kwargs) - self.config = config - self.swin = TFSwinMainLayer(config, name="swin") - - @add_start_docstrings_to_model_forward(SWIN_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSwinModelOutput, - config_class=_CONFIG_FOR_DOC, - modality="vision", - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor | None = None, - bool_masked_pos: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFSwinModelOutput | tuple[tf.Tensor, ...]: - r""" - bool_masked_pos (`tf.Tensor` of shape `(batch_size, num_patches)`, *optional*): - Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). - """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - swin_outputs = self.swin( - pixel_values=pixel_values, - bool_masked_pos=bool_masked_pos, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return swin_outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "swin", None) is not None: - with tf.name_scope(self.swin.name): - self.swin.build(None) - - -class TFSwinPixelShuffle(keras.layers.Layer): - """TF layer implementation of torch.nn.PixelShuffle""" - - def __init__(self, upscale_factor: int, **kwargs) -> None: - super().__init__(**kwargs) - if not isinstance(upscale_factor, int) or upscale_factor < 2: - raise ValueError(f"upscale_factor must be an integer value >= 2 got {upscale_factor}") - self.upscale_factor = upscale_factor - - def call(self, x: tf.Tensor) -> tf.Tensor: - hidden_states = x - batch_size, _, _, num_input_channels = shape_list(hidden_states) - block_size_squared = self.upscale_factor**2 - output_depth = int(num_input_channels / block_size_squared) - # When the number of output channels >= 2, PyTorch's PixelShuffle and - # TF's depth_to_space differ in their output as the order of channels selected for combining - # is a permutation of the other c.f. - # https://stackoverflow.com/questions/68272502/tf-depth-to-space-not-same-as-torchs-pixelshuffle-when-output-channels-1 - permutation = tf.constant( - [[i + j * block_size_squared for i in range(block_size_squared) for j in range(output_depth)]] - ) - hidden_states = tf.gather(params=hidden_states, indices=tf.tile(permutation, [batch_size, 1]), batch_dims=-1) - hidden_states = tf.nn.depth_to_space(hidden_states, block_size=self.upscale_factor, data_format="NHWC") - return hidden_states - - -class TFSwinDecoder(keras.layers.Layer): - def __init__(self, config: SwinConfig, **kwargs): - super().__init__(**kwargs) - self.conv2d = keras.layers.Conv2D( - filters=config.encoder_stride**2 * config.num_channels, kernel_size=1, strides=1, name="0" - ) - self.pixel_shuffle = TFSwinPixelShuffle(config.encoder_stride, name="1") - self.config = config - - def call(self, x: tf.Tensor) -> tf.Tensor: - hidden_states = x - # B,C,H,W -> B,H,W,C - hidden_states = tf.transpose(hidden_states, (0, 2, 3, 1)) - hidden_states = self.conv2d(hidden_states) - hidden_states = self.pixel_shuffle(hidden_states) - # B,H,W,C -> B,C,H,W - hidden_states = tf.transpose(hidden_states, (0, 3, 1, 2)) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv2d", None) is not None: - with tf.name_scope(self.conv2d.name): - self.conv2d.build([None, None, None, self.config.hidden_size]) - if getattr(self, "pixel_shuffle", None) is not None: - with tf.name_scope(self.pixel_shuffle.name): - self.pixel_shuffle.build(None) - - -@add_start_docstrings( - "Swin Model with a decoder on top for masked image modeling, as proposed in" - " [SimMIM](https://huggingface.co/papers/2111.09886).", - SWIN_START_DOCSTRING, -) -class TFSwinForMaskedImageModeling(TFSwinPreTrainedModel): - def __init__(self, config: SwinConfig): - super().__init__(config) - - self.swin = TFSwinMainLayer(config, add_pooling_layer=False, use_mask_token=True, name="swin") - - self.decoder = TFSwinDecoder(config, name="decoder") - - @add_start_docstrings_to_model_forward(SWIN_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSwinMaskedImageModelingOutput, config_class=_CONFIG_FOR_DOC) - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor | None = None, - bool_masked_pos: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple | TFSwinMaskedImageModelingOutput: - r""" - bool_masked_pos (`tf.Tensor` of shape `(batch_size, num_patches)`): - Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). - - Returns: - - Examples: - ```python - >>> from transformers import AutoImageProcessor, TFSwinForMaskedImageModeling - >>> import tensorflow as tf - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/swin-tiny-patch4-window7-224") - >>> model = TFSwinForMaskedImageModeling.from_pretrained("microsoft/swin-tiny-patch4-window7-224") - - >>> num_patches = (model.config.image_size // model.config.patch_size) ** 2 - >>> pixel_values = image_processor(images=image, return_tensors="tf").pixel_values - >>> # create random boolean mask of shape (batch_size, num_patches) - >>> bool_masked_pos = tf.random.uniform((1, num_patches)) >= 0.5 - - >>> outputs = model(pixel_values, bool_masked_pos=bool_masked_pos) - >>> loss, reconstructed_pixel_values = outputs.loss, outputs.reconstruction - >>> list(reconstructed_pixel_values.shape) - [1, 3, 224, 224] - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.swin( - pixel_values, - bool_masked_pos=bool_masked_pos, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - # Reshape to (batch_size, num_channels, height, width) - sequence_output = tf.transpose(sequence_output, (0, 2, 1)) - batch_size, num_channels, sequence_length = shape_list(sequence_output) - height = width = int(sequence_length**0.5) - sequence_output = tf.reshape(sequence_output, (batch_size, num_channels, height, width)) - - # Reconstruct pixel values - reconstructed_pixel_values = self.decoder(sequence_output) - - masked_im_loss = None - if bool_masked_pos is not None: - size = self.config.image_size // self.config.patch_size - bool_masked_pos = tf.reshape(bool_masked_pos, (-1, size, size)) - mask = tf.repeat(bool_masked_pos, self.config.patch_size, 1) - mask = tf.repeat(mask, self.config.patch_size, 2) - mask = tf.expand_dims(mask, 1) - mask = tf.cast(mask, tf.float32) - - reconstruction_loss = keras.losses.mean_absolute_error( - # Swap axes as metric calculation reduces over the final dimension - tf.transpose(pixel_values, (1, 2, 3, 0)), - tf.transpose(reconstructed_pixel_values, (1, 2, 3, 0)), - ) - reconstruction_loss = tf.expand_dims(reconstruction_loss, 0) - total_loss = tf.reduce_sum(reconstruction_loss * mask) - num_masked_pixels = (tf.reduce_sum(mask) + 1e-5) * self.config.num_channels - masked_im_loss = total_loss / num_masked_pixels - masked_im_loss = tf.reshape(masked_im_loss, (1,)) - - if not return_dict: - output = (reconstructed_pixel_values,) + outputs[2:] - return ((masked_im_loss,) + output) if masked_im_loss is not None else output - - return TFSwinMaskedImageModelingOutput( - loss=masked_im_loss, - reconstruction=reconstructed_pixel_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - reshaped_hidden_states=outputs.reshaped_hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "swin", None) is not None: - with tf.name_scope(self.swin.name): - self.swin.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - """ - Swin Model transformer with an image classification head on top (a linear layer on top of the final hidden state of - the [CLS] token) e.g. for ImageNet. - """, - SWIN_START_DOCSTRING, -) -class TFSwinForImageClassification(TFSwinPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: SwinConfig): - super().__init__(config) - - self.num_labels = config.num_labels - self.swin = TFSwinMainLayer(config, name="swin") - - # Classifier head - self.classifier = ( - keras.layers.Dense(config.num_labels, name="classifier") - if config.num_labels > 0 - else keras.layers.Activation("linear", name="classifier") - ) - - @add_start_docstrings_to_model_forward(SWIN_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFSwinImageClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - @unpack_inputs - def call( - self, - pixel_values: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - labels: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple[tf.Tensor, ...] | TFSwinImageClassifierOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.swin( - pixel_values, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - pooled_output = outputs[1] - - logits = self.classifier(pooled_output, training=training) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSwinImageClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - reshaped_hidden_states=outputs.reshaped_hidden_states, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "swin", None) is not None: - with tf.name_scope(self.swin.name): - self.swin.build(None) - if getattr(self, "classifier", None) is not None: - if hasattr(self.classifier, "name"): - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.swin.num_features]) - - -__all__ = ["TFSwinForImageClassification", "TFSwinForMaskedImageModeling", "TFSwinModel", "TFSwinPreTrainedModel"] diff --git a/src/transformers/models/swin2sr/image_processing_swin2sr.py b/src/transformers/models/swin2sr/image_processing_swin2sr.py index 76c5e907da1c..b15e7a9d8f86 100644 --- a/src/transformers/models/swin2sr/image_processing_swin2sr.py +++ b/src/transformers/models/swin2sr/image_processing_swin2sr.py @@ -154,11 +154,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of typ, input_data_format=input_data_format - `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -179,10 +176,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/swin2sr/modeling_swin2sr.py b/src/transformers/models/swin2sr/modeling_swin2sr.py index e010a1d8a01e..83dfe13baded 100644 --- a/src/transformers/models/swin2sr/modeling_swin2sr.py +++ b/src/transformers/models/swin2sr/modeling_swin2sr.py @@ -75,11 +75,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/swinv2/modeling_swinv2.py b/src/transformers/models/swinv2/modeling_swinv2.py index 1463f0f82e7e..ddc4dab73768 100644 --- a/src/transformers/models/swinv2/modeling_swinv2.py +++ b/src/transformers/models/swinv2/modeling_swinv2.py @@ -182,11 +182,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input @@ -927,8 +922,6 @@ class Swinv2PreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/switch_transformers/convert_switch_transformers_original_flax_checkpoint_to_pytorch.py b/src/transformers/models/switch_transformers/convert_switch_transformers_original_flax_checkpoint_to_pytorch.py index 71d304ea96c6..e73a1f7181ba 100644 --- a/src/transformers/models/switch_transformers/convert_switch_transformers_original_flax_checkpoint_to_pytorch.py +++ b/src/transformers/models/switch_transformers/convert_switch_transformers_original_flax_checkpoint_to_pytorch.py @@ -18,17 +18,160 @@ import argparse import re +import jax +import jax.numpy as jnp +import numpy as np from flax.traverse_util import flatten_dict, unflatten_dict from t5x import checkpoints from transformers import SwitchTransformersConfig, SwitchTransformersForConditionalGeneration -from transformers.modeling_flax_pytorch_utils import load_flax_weights_in_pytorch_model from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +def load_flax_weights_in_pytorch_model(pt_model, flax_state): + """Load flax checkpoints in a PyTorch model""" + + try: + import torch # noqa: F401 + except (ImportError, ModuleNotFoundError): + logger.error( + "Loading a Flax weights in PyTorch, requires both PyTorch and Flax to be installed. Please see" + " https://pytorch.org/ and https://flax.readthedocs.io/en/latest/index.html#installation for installation" + " instructions." + ) + raise + + # check if we have bf16 weights + is_type_bf16 = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype == jnp.bfloat16, flax_state)).values() + if any(is_type_bf16): + # convert all weights to fp32 if the are bf16 since torch.from_numpy can-not handle bf16 + # and bf16 is not fully supported in PT yet. + logger.warning( + "Found ``bfloat16`` weights in Flax model. Casting all ``bfloat16`` weights to ``float32`` " + "before loading those in PyTorch model." + ) + flax_state = jax.tree_util.tree_map( + lambda params: params.astype(np.float32) if params.dtype == jnp.bfloat16 else params, flax_state + ) + + flax_state_dict = flatten_dict(flax_state) + pt_model_dict = pt_model.state_dict() + + load_model_with_head_into_base_model = (pt_model.base_model_prefix in flax_state) and ( + pt_model.base_model_prefix not in {k.split(".")[0] for k in pt_model_dict} + ) + load_base_model_into_model_with_head = (pt_model.base_model_prefix not in flax_state) and ( + pt_model.base_model_prefix in {k.split(".")[0] for k in pt_model_dict} + ) + + # keep track of unexpected & missing keys + unexpected_keys = [] + missing_keys = set(pt_model_dict.keys()) + + for flax_key_tuple, flax_tensor in flax_state_dict.items(): + has_base_model_prefix = flax_key_tuple[0] == pt_model.base_model_prefix + require_base_model_prefix = ".".join((pt_model.base_model_prefix,) + flax_key_tuple) in pt_model_dict + + # adapt flax_key to prepare for loading from/to base model only + if load_model_with_head_into_base_model and has_base_model_prefix: + flax_key_tuple = flax_key_tuple[1:] + elif load_base_model_into_model_with_head and require_base_model_prefix: + flax_key_tuple = (pt_model.base_model_prefix,) + flax_key_tuple + + # rename flax weights to PyTorch format + if flax_key_tuple[-1] == "kernel" and flax_tensor.ndim == 4 and ".".join(flax_key_tuple) not in pt_model_dict: + # conv layer + flax_key_tuple = flax_key_tuple[:-1] + ("weight",) + flax_tensor = jnp.transpose(flax_tensor, (3, 2, 0, 1)) + elif flax_key_tuple[-1] == "kernel" and ".".join(flax_key_tuple) not in pt_model_dict: + # linear layer + flax_key_tuple = flax_key_tuple[:-1] + ("weight",) + flax_tensor = flax_tensor.T + elif flax_key_tuple[-1] in ["scale", "embedding"]: + flax_key_tuple = flax_key_tuple[:-1] + ("weight",) + + # adding batch stats from flax batch norm to pt + elif "mean" in flax_key_tuple[-1]: + flax_key_tuple = flax_key_tuple[:-1] + ("running_mean",) + elif "var" in flax_key_tuple[-1]: + flax_key_tuple = flax_key_tuple[:-1] + ("running_var",) + + if "batch_stats" in flax_state: + flax_key = ".".join(flax_key_tuple[1:]) # Remove the params/batch_stats header + else: + flax_key = ".".join(flax_key_tuple) + + # We also need to look at `pt_model_dict` and see if there are keys requiring further transformation. + special_pt_names = {} + # New `weight_norm` from https://github.com/huggingface/transformers/pull/24030 + for key in pt_model_dict: + key_components = key.split(".") + name = None + if key_components[-3::2] == ["parametrizations", "original0"]: + name = key_components[-2] + "_g" + elif key_components[-3::2] == ["parametrizations", "original1"]: + name = key_components[-2] + "_v" + if name is not None: + key_components = key_components[:-3] + [name] + key_to_check = ".".join(key_components) + special_pt_names[key_to_check] = key + + if flax_key in special_pt_names: + flax_key = special_pt_names[flax_key] + + if flax_key in pt_model_dict: + if flax_tensor.shape != pt_model_dict[flax_key].shape: + raise ValueError( + f"Flax checkpoint seems to be incorrect. Weight {flax_key_tuple} was expected " + f"to be of shape {pt_model_dict[flax_key].shape}, but is {flax_tensor.shape}." + ) + else: + # add weight to pytorch dict + flax_tensor = np.asarray(flax_tensor) if not isinstance(flax_tensor, np.ndarray) else flax_tensor + pt_model_dict[flax_key] = torch.from_numpy(flax_tensor) + # remove from missing keys + missing_keys.remove(flax_key) + else: + # weight is not expected by PyTorch model + unexpected_keys.append(flax_key) + + pt_model.load_state_dict(pt_model_dict) + + # re-transform missing_keys to list + missing_keys = list(missing_keys) + + if len(unexpected_keys) > 0: + logger.warning( + "Some weights of the Flax model were not used when initializing the PyTorch model" + f" {pt_model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are initializing" + f" {pt_model.__class__.__name__} from a Flax model trained on another task or with another architecture" + " (e.g. initializing a BertForSequenceClassification model from a FlaxBertForPreTraining model).\n- This" + f" IS NOT expected if you are initializing {pt_model.__class__.__name__} from a Flax model that you expect" + " to be exactly identical (e.g. initializing a BertForSequenceClassification model from a" + " FlaxBertForSequenceClassification model)." + ) + else: + logger.warning(f"All Flax model weights were used when initializing {pt_model.__class__.__name__}.\n") + if len(missing_keys) > 0: + logger.warning( + f"Some weights of {pt_model.__class__.__name__} were not initialized from the Flax model and are newly" + f" initialized: {missing_keys}\nYou should probably TRAIN this model on a down-stream task to be able to" + " use it for predictions and inference." + ) + else: + logger.warning( + f"All the weights of {pt_model.__class__.__name__} were initialized from the Flax model.\n" + "If your task is similar to the task the model of the checkpoint was trained on, " + f"you can already use {pt_model.__class__.__name__} for predictions without further training." + ) + + return pt_model + + # should not include what is already done by the `from_pt` argument MOE_LAYER_NAME_MAPPING = { "/attention/": "/0/SelfAttention/", diff --git a/src/transformers/models/switch_transformers/modeling_switch_transformers.py b/src/transformers/models/switch_transformers/modeling_switch_transformers.py index 0c2844250968..761f1c1ccc8f 100644 --- a/src/transformers/models/switch_transformers/modeling_switch_transformers.py +++ b/src/transformers/models/switch_transformers/modeling_switch_transformers.py @@ -382,7 +382,6 @@ def __init__( "when creating this class." ) - # Mesh TensorFlow initialization to avoid scaling before softmax self.q = nn.Linear(self.d_model, self.inner_dim, bias=False) self.k = nn.Linear(self.d_model, self.inner_dim, bias=False) self.v = nn.Linear(self.d_model, self.inner_dim, bias=False) @@ -794,15 +793,10 @@ def _init_weights(self, module): module, (SwitchTransformersModel, SwitchTransformersForConditionalGeneration, SwitchTransformersEncoderModel), ): - # Mesh TensorFlow embeddings initialization - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L1624 module.shared.weight.data.normal_(mean=0.0, std=factor * 1.0) if hasattr(module, "lm_head") and not self.config.tie_word_embeddings: module.lm_head.weight.data.normal_(mean=0.0, std=factor * 1.0) elif isinstance(module, SwitchTransformersDenseActDense): - # Mesh TensorFlow FF initialization - # See https://github.com/tensorflow/mesh/blob/master/mesh_tensorflow/transformer/transformer_layers.py#L56 - # and https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L89 module.wi.weight.data.normal_(mean=0.0, std=factor * ((self.config.d_model) ** -0.5)) if hasattr(module.wi, "bias") and module.wi.bias is not None: module.wi.bias.data.zero_() @@ -810,8 +804,6 @@ def _init_weights(self, module): if hasattr(module.wo, "bias") and module.wo.bias is not None: module.wo.bias.data.zero_() elif isinstance(module, SwitchTransformersAttention): - # Mesh TensorFlow attention initialization to avoid scaling before softmax - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/attention.py#L136 d_model = self.config.d_model key_value_proj_dim = self.config.d_kv n_heads = self.config.num_heads @@ -822,8 +814,6 @@ def _init_weights(self, module): if module.has_relative_attention_bias: module.relative_attention_bias.weight.data.normal_(mean=0.0, std=factor * ((d_model) ** -0.5)) elif isinstance(module, SwitchTransformersSparseMLP): - # Mesh TensorFlow attention initialization to avoid scaling before softmax - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/attention.py#L136 d_model = self.config.d_model key_value_proj_dim = self.config.d_kv n_heads = self.config.num_heads @@ -1630,8 +1620,6 @@ def forward( sequence_output = decoder_outputs[0] if self.config.tie_word_embeddings: - # Rescale output before projecting on vocab - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586 sequence_output = sequence_output * (self.model_dim**-0.5) lm_logits = self.lm_head(sequence_output) diff --git a/src/transformers/models/t5/__init__.py b/src/transformers/models/t5/__init__.py index 366eab10826b..cdbf8a9937a7 100644 --- a/src/transformers/models/t5/__init__.py +++ b/src/transformers/models/t5/__init__.py @@ -19,9 +19,7 @@ if TYPE_CHECKING: from .configuration_t5 import * - from .modeling_flax_t5 import * from .modeling_t5 import * - from .modeling_tf_t5 import * from .tokenization_t5 import * from .tokenization_t5_fast import * else: diff --git a/src/transformers/models/t5/convert_t5_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/t5/convert_t5_original_tf_checkpoint_to_pytorch.py index 9b1b15857cea..a53efce63544 100755 --- a/src/transformers/models/t5/convert_t5_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/t5/convert_t5_original_tf_checkpoint_to_pytorch.py @@ -15,14 +15,123 @@ """Convert T5 checkpoint.""" import argparse +import os -from transformers import T5Config, T5ForConditionalGeneration, load_tf_weights_in_t5 +import torch + +from transformers import T5Config, T5ForConditionalGeneration from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +def load_tf_weights_in_t5(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + tf_weights = {} + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + tf_weights[name] = array + + for txt_name in names: + name = txt_name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any( + n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + tf_weights.pop(txt_name, None) + continue + if "_slot_" in name[-1]: + logger.info(f"Skipping {'/'.join(name)}") + tf_weights.pop(txt_name, None) + continue + pointer = model + array = tf_weights[txt_name] + + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] in ["kernel", "scale", "embedding"]: + pointer = getattr(pointer, "weight") + elif scope_names[0] == "self_attention": + pointer = getattr(pointer, "layer") + pointer = pointer[0] + elif scope_names[0] == "enc_dec_attention": + pointer = getattr(pointer, "layer") + pointer = pointer[1] + elif scope_names[0] == "dense_relu_dense": + pointer = getattr(pointer, "layer") + pointer = pointer[2] + elif scope_names[0] == "rms_norm": + if hasattr(pointer, "layer_norm"): + pointer = getattr(pointer, "layer_norm") + elif hasattr(pointer, "final_layer_norm"): + pointer = getattr(pointer, "final_layer_norm") + elif scope_names[0] == "scale": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + elif scope_names[0] == "decoder" and name[1] == "logits": + continue + elif scope_names[0] == "logits": + pointer = getattr(pointer, "lm_head") + elif scope_names[0] == "wi" and len(scope_names) > 1 and scope_names[1].isdigit(): + pointer = getattr(pointer, f"wi_{scope_names[1]}") + continue + else: + try: + pointer = getattr(pointer, scope_names[0]) + except AttributeError: + logger.info(f"Skipping {'/'.join(name)}") + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if scope_names[0] not in ["kernel", "scale", "embedding"]: + pointer = getattr(pointer, "weight") + if scope_names[0] != "embedding": + logger.info(f"Transposing numpy weight of shape {array.shape} for {name}") + array = np.transpose(array) + try: + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array.astype(np.float32)) + tf_weights.pop(txt_name, None) + + logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}.") + return model + + def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, config_file, pytorch_dump_path): # Initialise PyTorch model config = T5Config.from_json_file(config_file) diff --git a/src/transformers/models/t5/convert_t5x_checkpoint_to_flax.py b/src/transformers/models/t5/convert_t5x_checkpoint_to_flax.py deleted file mode 100644 index 12498359d21b..000000000000 --- a/src/transformers/models/t5/convert_t5x_checkpoint_to_flax.py +++ /dev/null @@ -1,235 +0,0 @@ -# coding=utf-8 -# Copyright 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. - -"""Convert T5X checkpoints from the original repository to JAX/FLAX model.""" - -import argparse - -from t5x import checkpoints - -from transformers import FlaxT5ForConditionalGeneration, T5Config - - -def convert_t5x_checkpoint_to_flax(t5x_checkpoint_path, config_name, flax_dump_folder_path): - config = T5Config.from_pretrained(config_name) - flax_model = FlaxT5ForConditionalGeneration(config=config) - t5x_model = checkpoints.load_t5x_checkpoint(t5x_checkpoint_path) - - split_mlp_wi = "wi_0" in t5x_model["target"]["encoder"]["layers_0"]["mlp"] - - # Encoder - for layer_index in range(config.num_layers): - layer_name = f"layers_{str(layer_index)}" - - # Self-Attention - t5x_attention_key = t5x_model["target"]["encoder"][layer_name]["attention"]["key"]["kernel"] - t5x_attention_out = t5x_model["target"]["encoder"][layer_name]["attention"]["out"]["kernel"] - t5x_attention_query = t5x_model["target"]["encoder"][layer_name]["attention"]["query"]["kernel"] - t5x_attention_value = t5x_model["target"]["encoder"][layer_name]["attention"]["value"]["kernel"] - - # Layer Normalization - t5x_attention_layer_norm = t5x_model["target"]["encoder"][layer_name]["pre_attention_layer_norm"]["scale"] - - if split_mlp_wi: - t5x_mlp_wi_0 = t5x_model["target"]["encoder"][layer_name]["mlp"]["wi_0"]["kernel"] - t5x_mlp_wi_1 = t5x_model["target"]["encoder"][layer_name]["mlp"]["wi_1"]["kernel"] - else: - t5x_mlp_wi = t5x_model["target"]["encoder"][layer_name]["mlp"]["wi"]["kernel"] - - t5x_mlp_wo = t5x_model["target"]["encoder"][layer_name]["mlp"]["wo"]["kernel"] - - # Layer Normalization - t5x_mlp_layer_norm = t5x_model["target"]["encoder"][layer_name]["pre_mlp_layer_norm"]["scale"] - - # Assigning - flax_model.params["encoder"]["block"][str(layer_index)]["layer"]["0"]["SelfAttention"]["k"]["kernel"] = ( - t5x_attention_key - ) - flax_model.params["encoder"]["block"][str(layer_index)]["layer"]["0"]["SelfAttention"]["o"]["kernel"] = ( - t5x_attention_out - ) - flax_model.params["encoder"]["block"][str(layer_index)]["layer"]["0"]["SelfAttention"]["q"]["kernel"] = ( - t5x_attention_query - ) - flax_model.params["encoder"]["block"][str(layer_index)]["layer"]["0"]["SelfAttention"]["v"]["kernel"] = ( - t5x_attention_value - ) - - flax_model.params["encoder"]["block"][str(layer_index)]["layer"]["0"]["layer_norm"]["weight"] = ( - t5x_attention_layer_norm - ) - - if split_mlp_wi: - flax_model.params["encoder"]["block"][str(layer_index)]["layer"]["1"]["DenseReluDense"]["wi_0"][ - "kernel" - ] = t5x_mlp_wi_0 - flax_model.params["encoder"]["block"][str(layer_index)]["layer"]["1"]["DenseReluDense"]["wi_1"][ - "kernel" - ] = t5x_mlp_wi_1 - else: - flax_model.params["encoder"]["block"][str(layer_index)]["layer"]["1"]["DenseReluDense"]["wi"]["kernel"] = ( - t5x_mlp_wi - ) - - flax_model.params["encoder"]["block"][str(layer_index)]["layer"]["1"]["DenseReluDense"]["wo"]["kernel"] = ( - t5x_mlp_wo - ) - flax_model.params["encoder"]["block"][str(layer_index)]["layer"]["1"]["layer_norm"]["weight"] = ( - t5x_mlp_layer_norm - ) - - # Only for layer 0: - t5x_encoder_rel_embedding = t5x_model["target"]["encoder"]["relpos_bias"]["rel_embedding"].T - flax_model.params["encoder"]["block"]["0"]["layer"]["0"]["SelfAttention"]["relative_attention_bias"][ - "embedding" - ] = t5x_encoder_rel_embedding - - # Assigning - t5x_encoder_norm = t5x_model["target"]["encoder"]["encoder_norm"]["scale"] - flax_model.params["encoder"]["final_layer_norm"]["weight"] = t5x_encoder_norm - - # Decoder - for layer_index in range(config.num_decoder_layers): - layer_name = f"layers_{str(layer_index)}" - - # Self-Attention - t5x_attention_key = t5x_model["target"]["decoder"][layer_name]["self_attention"]["key"]["kernel"] - t5x_attention_out = t5x_model["target"]["decoder"][layer_name]["self_attention"]["out"]["kernel"] - t5x_attention_query = t5x_model["target"]["decoder"][layer_name]["self_attention"]["query"]["kernel"] - t5x_attention_value = t5x_model["target"]["decoder"][layer_name]["self_attention"]["value"]["kernel"] - - # Layer Normalization - t5x_pre_attention_layer_norm = t5x_model["target"]["decoder"][layer_name]["pre_self_attention_layer_norm"][ - "scale" - ] - - # Encoder-Decoder-Attention - t5x_enc_dec_attention_key = t5x_model["target"]["decoder"][layer_name]["encoder_decoder_attention"]["key"][ - "kernel" - ] - t5x_enc_dec_attention_out = t5x_model["target"]["decoder"][layer_name]["encoder_decoder_attention"]["out"][ - "kernel" - ] - t5x_enc_dec_attention_query = t5x_model["target"]["decoder"][layer_name]["encoder_decoder_attention"]["query"][ - "kernel" - ] - t5x_enc_dec_attention_value = t5x_model["target"]["decoder"][layer_name]["encoder_decoder_attention"]["value"][ - "kernel" - ] - - # Layer Normalization - t5x_cross_layer_norm = t5x_model["target"]["decoder"][layer_name]["pre_cross_attention_layer_norm"]["scale"] - - # MLP - if split_mlp_wi: - t5x_mlp_wi_0 = t5x_model["target"]["decoder"][layer_name]["mlp"]["wi_0"]["kernel"] - t5x_mlp_wi_1 = t5x_model["target"]["decoder"][layer_name]["mlp"]["wi_1"]["kernel"] - else: - t5x_mlp_wi = t5x_model["target"]["decoder"][layer_name]["mlp"]["wi"]["kernel"] - - t5x_mlp_wo = t5x_model["target"]["decoder"][layer_name]["mlp"]["wo"]["kernel"] - - # Layer Normalization - tx5_mlp_layer_norm = t5x_model["target"]["decoder"][layer_name]["pre_mlp_layer_norm"]["scale"] - - # Assigning - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["0"]["SelfAttention"]["k"]["kernel"] = ( - t5x_attention_key - ) - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["0"]["SelfAttention"]["o"]["kernel"] = ( - t5x_attention_out - ) - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["0"]["SelfAttention"]["q"]["kernel"] = ( - t5x_attention_query - ) - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["0"]["SelfAttention"]["v"]["kernel"] = ( - t5x_attention_value - ) - - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["0"]["layer_norm"]["weight"] = ( - t5x_pre_attention_layer_norm - ) - - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["1"]["EncDecAttention"]["k"]["kernel"] = ( - t5x_enc_dec_attention_key - ) - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["1"]["EncDecAttention"]["o"]["kernel"] = ( - t5x_enc_dec_attention_out - ) - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["1"]["EncDecAttention"]["q"]["kernel"] = ( - t5x_enc_dec_attention_query - ) - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["1"]["EncDecAttention"]["v"]["kernel"] = ( - t5x_enc_dec_attention_value - ) - - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["1"]["layer_norm"]["weight"] = ( - t5x_cross_layer_norm - ) - - if split_mlp_wi: - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["2"]["DenseReluDense"]["wi_0"][ - "kernel" - ] = t5x_mlp_wi_0 - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["2"]["DenseReluDense"]["wi_1"][ - "kernel" - ] = t5x_mlp_wi_1 - else: - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["2"]["DenseReluDense"]["wi"]["kernel"] = ( - t5x_mlp_wi - ) - - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["2"]["DenseReluDense"]["wo"]["kernel"] = ( - t5x_mlp_wo - ) - - flax_model.params["decoder"]["block"][str(layer_index)]["layer"]["2"]["layer_norm"]["weight"] = ( - tx5_mlp_layer_norm - ) - - # Decoder Normalization - tx5_decoder_norm = t5x_model["target"]["decoder"]["decoder_norm"]["scale"] - flax_model.params["decoder"]["final_layer_norm"]["weight"] = tx5_decoder_norm - - # Only for layer 0: - t5x_decoder_rel_embedding = t5x_model["target"]["decoder"]["relpos_bias"]["rel_embedding"].T - flax_model.params["decoder"]["block"]["0"]["layer"]["0"]["SelfAttention"]["relative_attention_bias"][ - "embedding" - ] = t5x_decoder_rel_embedding - - # Token Embeddings - tx5_token_embeddings = t5x_model["target"]["token_embedder"]["embedding"] - flax_model.params["shared"]["embedding"] = tx5_token_embeddings - - # LM Head (only in v1.1 checkpoints) - if "logits_dense" in t5x_model["target"]["decoder"]: - flax_model.params["lm_head"]["kernel"] = t5x_model["target"]["decoder"]["logits_dense"]["kernel"] - - flax_model.save_pretrained(flax_dump_folder_path) - print("T5X Model was successfully converted!") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - # Required parameters - parser.add_argument( - "--t5x_checkpoint_path", default=None, type=str, required=True, help="Path the TX5 checkpoint." - ) - parser.add_argument("--config_name", default=None, type=str, required=True, help="Config name of T5 model.") - parser.add_argument( - "--flax_dump_folder_path", default=None, type=str, required=True, help="Path to the output FLAX model." - ) - args = parser.parse_args() - convert_t5x_checkpoint_to_flax(args.t5x_checkpoint_path, args.config_name, args.flax_dump_folder_path) diff --git a/src/transformers/models/t5/modeling_flax_t5.py b/src/transformers/models/t5/modeling_flax_t5.py deleted file mode 100644 index c829a084e4d9..000000000000 --- a/src/transformers/models/t5/modeling_flax_t5.py +++ /dev/null @@ -1,1801 +0,0 @@ -# coding=utf-8 -# Copyright 2021 T5 Authors and 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. -"""Flax T5 model.""" - -import copy -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen import partitioning as nn_partitioning -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax.random import PRNGKey - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxSeq2SeqLMOutput, - FlaxSeq2SeqModelOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_t5 import T5Config - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "google-t5/t5-small" -_CONFIG_FOR_DOC = "T5Config" - -remat = nn_partitioning.remat - - -# Copied from transformers.models.bart.modeling_flax_bart.shift_tokens_right -def shift_tokens_right(input_ids: jnp.ndarray, pad_token_id: int, decoder_start_token_id: int) -> jnp.ndarray: - """ - Shift input ids one token to the right. - """ - shifted_input_ids = jnp.zeros_like(input_ids) - shifted_input_ids = shifted_input_ids.at[:, 1:].set(input_ids[:, :-1]) - shifted_input_ids = shifted_input_ids.at[:, 0].set(decoder_start_token_id) - - shifted_input_ids = jnp.where(shifted_input_ids == -100, pad_token_id, shifted_input_ids) - return shifted_input_ids - - -class FlaxT5LayerNorm(nn.Module): - hidden_size: int - dtype: jnp.dtype = jnp.float32 - eps: float = 1e-6 - weight_init: Callable[..., np.ndarray] = jax.nn.initializers.ones - - def setup(self): - self.weight = self.param("weight", self.weight_init, (self.hidden_size,)) - - def __call__(self, hidden_states): - """ - Construct a layernorm module in the T5 style; No bias and no subtraction of mean. - """ - # layer norm should always be calculated in float32 - variance = jnp.power(hidden_states.astype("f4"), 2).mean(axis=-1, keepdims=True) - hidden_states = hidden_states / jnp.sqrt(variance + self.eps) - - return self.weight * hidden_states - - -class FlaxT5DenseActDense(nn.Module): - config: T5Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - wi_init_std = self.config.initializer_factor * (self.config.d_model**-0.5) - wo_init_std = self.config.initializer_factor * (self.config.d_ff**-0.5) - - self.wi = nn.Dense( - self.config.d_ff, - use_bias=False, - kernel_init=jax.nn.initializers.normal(wi_init_std), - dtype=self.dtype, - ) - self.wo = nn.Dense( - self.config.d_model, - use_bias=False, - kernel_init=jax.nn.initializers.normal(wo_init_std), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - self.act = ACT2FN[self.config.dense_act_fn] - - def __call__(self, hidden_states, deterministic=True): - hidden_states = self.wi(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.wo(hidden_states) - return hidden_states - - -class FlaxT5DenseGatedActDense(nn.Module): - config: T5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - wi_init_std = self.config.initializer_factor * (self.config.d_model**-0.5) - wo_init_std = self.config.initializer_factor * (self.config.d_ff**-0.5) - - self.wi_0 = nn.Dense( - self.config.d_ff, - use_bias=False, - kernel_init=jax.nn.initializers.normal(wi_init_std), - dtype=self.dtype, - ) - self.wi_1 = nn.Dense( - self.config.d_ff, - use_bias=False, - kernel_init=jax.nn.initializers.normal(wi_init_std), - dtype=self.dtype, - ) - self.wo = nn.Dense( - self.config.d_model, - use_bias=False, - kernel_init=jax.nn.initializers.normal(wo_init_std), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - self.act = ACT2FN[self.config.dense_act_fn] - - def __call__(self, hidden_states, deterministic): - hidden_gelu = self.act(self.wi_0(hidden_states)) - hidden_linear = self.wi_1(hidden_states) - hidden_states = hidden_gelu * hidden_linear - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.wo(hidden_states) - return hidden_states - - -class FlaxT5LayerFF(nn.Module): - config: T5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - if self.config.is_gated_act: - self.DenseReluDense = FlaxT5DenseGatedActDense(self.config, dtype=self.dtype) - else: - self.DenseReluDense = FlaxT5DenseActDense(self.config, dtype=self.dtype) - - self.layer_norm = FlaxT5LayerNorm(self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype) - self.dropout = nn.Dropout(self.config.dropout_rate) - - def __call__(self, hidden_states, deterministic=True): - forwarded_states = self.layer_norm(hidden_states) - forwarded_states = self.DenseReluDense(forwarded_states, deterministic=deterministic) - hidden_states = hidden_states + self.dropout(forwarded_states, deterministic=deterministic) - return hidden_states - - -class FlaxT5Attention(nn.Module): - config: T5Config - has_relative_attention_bias: bool = False - causal: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.relative_attention_num_buckets = self.config.relative_attention_num_buckets - self.relative_attention_max_distance = self.config.relative_attention_max_distance - self.d_model = self.config.d_model - self.key_value_proj_dim = self.config.d_kv - self.n_heads = self.config.num_heads - self.dropout = self.config.dropout_rate - self.inner_dim = self.n_heads * self.key_value_proj_dim - - q_init_std = self.config.initializer_factor * ((self.inner_dim * self.key_value_proj_dim) ** -0.5) - kv_init_std = self.config.initializer_factor * (self.inner_dim**-0.5) - o_init_std = self.config.initializer_factor * (self.inner_dim**-0.5) - - self.q = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(q_init_std), - dtype=self.dtype, - ) - self.k = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(kv_init_std), - dtype=self.dtype, - ) - self.v = nn.Dense( - self.inner_dim, - use_bias=False, - kernel_init=jax.nn.initializers.normal(kv_init_std), - dtype=self.dtype, - ) - self.o = nn.Dense( - self.d_model, - use_bias=False, - kernel_init=jax.nn.initializers.normal(o_init_std), - dtype=self.dtype, - ) - - if self.has_relative_attention_bias: - self.relative_attention_bias = nn.Embed( - self.relative_attention_num_buckets, - self.n_heads, - embedding_init=jax.nn.initializers.normal(kv_init_std), - dtype=self.dtype, - ) - - @staticmethod - def _relative_position_bucket(relative_position, bidirectional=True, num_buckets=32, max_distance=128): - """ - Adapted from Mesh Tensorflow: - https://github.com/tensorflow/mesh/blob/0cb87fe07da627bf0b7e60475d59f95ed6b5be3d/mesh_tensorflow/transformer/transformer_layers.py#L593 - - Translate relative position to a bucket number for relative attention. The relative position is defined as - memory_position - query_position, i.e. the distance in tokens from the attending position to the attended-to - position. If bidirectional=False, then positive relative positions are invalid. We use smaller buckets for - small absolute relative_position and larger buckets for larger absolute relative_positions. All relative - positions >=max_distance map to the same bucket. All relative positions <=-max_distance map to the same bucket. - This should allow for more graceful generalization to longer sequences than the model has been trained on - """ - relative_buckets = 0 - if bidirectional: - num_buckets //= 2 - relative_buckets += (relative_position > 0) * num_buckets - relative_position = jnp.abs(relative_position) - else: - relative_position = -jnp.clip(relative_position, a_max=0) - # now relative_position is in the range [0, inf) - - # half of the buckets are for exact increments in positions - max_exact = num_buckets // 2 - is_small = relative_position < max_exact - - # The other half of the buckets are for logarithmically bigger bins in positions up to max_distance - relative_position_if_large = max_exact + ( - jnp.log(relative_position / max_exact) / jnp.log(max_distance / max_exact) * (num_buckets - max_exact) - ) - relative_position_if_large = jnp.clip(relative_position_if_large, a_max=num_buckets - 1) - - relative_buckets += jnp.where(is_small, relative_position, relative_position_if_large) - - return relative_buckets.astype("i4") - - def compute_bias(self, query_length, key_length): - """Compute binned relative position bias""" - context_position = jnp.arange(query_length, dtype="i4")[:, None] - memory_position = jnp.arange(key_length, dtype="i4")[None, :] - - relative_position = memory_position - context_position - relative_position_bucket = self._relative_position_bucket( - relative_position, - bidirectional=(not self.causal), - num_buckets=self.relative_attention_num_buckets, - max_distance=self.relative_attention_max_distance, - ) - - values = self.relative_attention_bias(relative_position_bucket) - values = values.transpose((2, 0, 1))[None, :, :, :] - return values - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.n_heads, self.key_value_proj_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.inner_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = jax.lax.dynamic_update_slice(cached_key.value, key, indices) - value = jax.lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions - # that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def _create_position_bias( - self, key_states, query_states, attention_mask, init_cache, seq_length, causal_attention_mask_shift - ): - cache_is_filled = self.causal and self.has_variable("cache", "cached_key") and (not init_cache) - key_length = key_states.shape[1] - query_length = key_length if cache_is_filled else query_states.shape[1] - - if self.has_relative_attention_bias: - position_bias = self.compute_bias(query_length, key_length) - elif attention_mask is not None: - position_bias = jnp.zeros_like(attention_mask) - else: - position_bias = jnp.zeros((1, self.n_heads, query_length, key_length), dtype=self.dtype) - - # if key and values are already calculated, only the last query position bias should be taken - if cache_is_filled: - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - position_bias = jax.lax.dynamic_slice( - position_bias, - (0, 0, causal_attention_mask_shift, 0), - (1, self.n_heads, seq_length, max_decoder_length), - ) - return position_bias - - def __call__( - self, - hidden_states, - attention_mask=None, - key_value_states=None, - position_bias=None, - use_cache=False, - output_attentions=False, - deterministic=True, - init_cache=False, - ): - """ - Self-attention (if key_value_states is None) or attention over source sentence (provided by key_value_states). - """ - batch_size, seq_length = hidden_states.shape[:2] - - # q, k, v projections - query_states = self.q(hidden_states) # (batch_size, n_heads, seq_length, dim_per_head) - key_states = self.k(hidden_states) if key_value_states is None else self.k(key_value_states) - value_states = self.v(hidden_states) if key_value_states is None else self.v(key_value_states) - - # reshape to (batch_size, seq_length, n_heads, head_dim) - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # counter-act scaling in dot_product_attention_weights function - query_states *= jnp.sqrt(query_states.shape[-1]) - - # for fast decoding causal attention mask should be shifted - causal_attention_mask_shift = ( - self.variables["cache"]["cache_index"] if (self.has_variable("cache", "cached_key") and self.causal) else 0 - ) - # create causal attention_mask; attention_mask has to be defined when model is causal - if self.causal: - causal_attention_mask = make_causal_mask(attention_mask, dtype="bool") - - # fast decoding for generate requires special attention_mask - if self.has_variable("cache", "cached_key"): - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_attention_mask = jax.lax.dynamic_slice( - causal_attention_mask, - (0, 0, causal_attention_mask_shift, 0), - (1, 1, seq_length, max_decoder_length), - ) - - # broadcast causal attention mask & attention mask to fit for merge - causal_attention_mask = jnp.broadcast_to( - causal_attention_mask, (batch_size,) + causal_attention_mask.shape[1:] - ) - attention_mask = jnp.broadcast_to( - jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_attention_mask.shape - ) - attention_mask = combine_masks(attention_mask, causal_attention_mask) - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # replace masked positions with -10_000 - if attention_mask is not None: - mask_value = jnp.finfo(self.dtype).min - attention_mask = jax.lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, mask_value).astype(self.dtype), - ) - - if position_bias is None: - # compute position bias (only for first layer) - position_bias = self._create_position_bias( - key_states, query_states, attention_mask, init_cache, seq_length, causal_attention_mask_shift - ) - - if attention_mask is not None: - position_bias = position_bias + attention_mask - - # create dropout rng - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - # Softmax(QK^T) - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=position_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - ) - - # multiply with value states - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - - # bring back to (batch_size, seq_length, d_model) - attn_output = self._merge_heads(attn_output) - - # apply output matrix - attn_output = self.o(attn_output) - - outputs = (attn_output, position_bias) - - if output_attentions: - outputs = outputs + (attn_weights,) - - return outputs - - -class FlaxT5LayerSelfAttention(nn.Module): - config: T5Config - has_relative_attention_bias: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.SelfAttention = FlaxT5Attention( - self.config, - has_relative_attention_bias=self.has_relative_attention_bias, - causal=self.config.causal, - dtype=self.dtype, - ) - self.layer_norm = FlaxT5LayerNorm(self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype) - self.dropout = nn.Dropout(self.config.dropout_rate) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_bias=None, - output_attentions=False, - deterministic=True, - init_cache=False, - ): - normed_hidden_states = self.layer_norm(hidden_states) - attention_output = self.SelfAttention( - normed_hidden_states, - attention_mask=attention_mask, - position_bias=position_bias, - output_attentions=output_attentions, - deterministic=deterministic, - init_cache=init_cache, - ) - hidden_states = hidden_states + self.dropout(attention_output[0], deterministic=deterministic) - outputs = (hidden_states,) + attention_output[1:] # add attentions if we output them - return outputs - - -class FlaxT5LayerCrossAttention(nn.Module): - config: T5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.EncDecAttention = FlaxT5Attention( - self.config, has_relative_attention_bias=False, causal=False, dtype=self.dtype - ) - self.layer_norm = FlaxT5LayerNorm(self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype) - self.dropout = nn.Dropout(self.config.dropout_rate) - - def __call__( - self, - hidden_states, - key_value_states, - attention_mask=None, - position_bias=None, - output_attentions=False, - deterministic=True, - ): - normed_hidden_states = self.layer_norm(hidden_states) - attention_output = self.EncDecAttention( - normed_hidden_states, - attention_mask=attention_mask, - key_value_states=key_value_states, - position_bias=position_bias, - output_attentions=output_attentions, - ) - hidden_states = hidden_states + self.dropout(attention_output[0], deterministic=deterministic) - outputs = (hidden_states,) + attention_output[1:] # add attentions if we output them - return outputs - - -class FlaxT5Block(nn.Module): - config: T5Config - has_relative_attention_bias: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.causal = self.config.causal - self.layer = ( - FlaxT5LayerSelfAttention( - self.config, - has_relative_attention_bias=self.has_relative_attention_bias, - name=str(0), - dtype=self.dtype, - ), - ) - feed_forward_index = 1 - if self.causal: - self.layer += (FlaxT5LayerCrossAttention(self.config, name=str(1), dtype=self.dtype),) - feed_forward_index += 1 - - self.layer += (FlaxT5LayerFF(self.config, name=str(feed_forward_index), dtype=self.dtype),) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_bias=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - encoder_decoder_position_bias=None, - output_attentions=False, - return_dict=True, - deterministic=True, - init_cache=False, - ): - self_attention_outputs = self.layer[0]( - hidden_states, - attention_mask=attention_mask, - position_bias=position_bias, - output_attentions=output_attentions, - deterministic=deterministic, - init_cache=init_cache, - ) - hidden_states = self_attention_outputs[0] - attention_outputs = self_attention_outputs[1:] # Keep self-attention outputs and relative position weights - - do_cross_attention = self.causal and encoder_hidden_states is not None - if do_cross_attention: - cross_attention_outputs = self.layer[1]( - hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - position_bias=encoder_decoder_position_bias, - output_attentions=output_attentions, - deterministic=deterministic, - ) - hidden_states = cross_attention_outputs[0] - - # Keep cross-attention outputs and relative position weights - attention_outputs = attention_outputs + cross_attention_outputs[1:] - - # Apply Feed Forward layer - hidden_states = self.layer[-1](hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - outputs = outputs + attention_outputs - - # returns hidden-states, present_key_value_states, (self-attention position bias), (self-attention weights), - # (cross-attention position bias), (cross-attention weights) - return outputs - - -class FlaxT5LayerCollection(nn.Module): - config: T5Config - has_relative_attention_bias: bool - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layer = FlaxT5Block( - self.config, has_relative_attention_bias=self.has_relative_attention_bias, dtype=self.dtype - ) - - def __call__( - self, - hidden_states, - attention_mask=None, - position_bias=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - encoder_decoder_position_bias=None, - output_attentions=False, - deterministic=True, - init_cache=False, - ): - return self.layer( - hidden_states, - attention_mask=attention_mask, - position_bias=position_bias, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - encoder_decoder_position_bias=encoder_decoder_position_bias, - output_attentions=output_attentions, - deterministic=deterministic, - init_cache=init_cache, - ) - - -class FlaxT5BlockCollection(nn.Module): - config: T5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.causal = self.config.causal - if self.gradient_checkpointing: - FlaxT5CheckpointLayer = remat(FlaxT5LayerCollection, static_argnums=(6, 7, 8)) - self.blocks = [ - FlaxT5CheckpointLayer( - self.config, - has_relative_attention_bias=(i == 0), - dtype=self.dtype, - name=str(i), - ) - for i in range(self.config.num_layers) - ] - else: - self.blocks = [ - FlaxT5LayerCollection( - self.config, - has_relative_attention_bias=(i == 0), - dtype=self.dtype, - name=str(i), - ) - for i in range(self.config.num_layers) - ] - - def __call__( - self, - hidden_states=None, - attention_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - output_attentions: bool = False, - output_hidden_states: bool = False, - deterministic: bool = True, - init_cache: bool = False, - ): - # Prepare head mask if needed - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if (output_attentions and self.causal) else None - position_bias = None - encoder_decoder_position_bias = None - - for i, layer_module in enumerate(self.blocks): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states, - attention_mask, - position_bias, - encoder_hidden_states, - encoder_attention_mask, - encoder_decoder_position_bias, - output_attentions, - deterministic, - init_cache, - ) - - hidden_states = layer_outputs[0] - - # We share the position biases between the layers - the first layer store them - # layer_outputs = hidden-states, key-value-states (self-attention position bias), (self-attention weights), - # (cross-attention position bias), (cross-attention weights) - position_bias = layer_outputs[1] - - if self.causal and encoder_hidden_states is not None: - encoder_decoder_position_bias = layer_outputs[3 if output_attentions else 2] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[2],) - if self.causal: - all_cross_attentions = all_cross_attentions + (layer_outputs[4],) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - -class FlaxT5Stack(nn.Module): - config: T5Config - embed_tokens: nn.Embed - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.causal = self.config.causal - - self.block = FlaxT5BlockCollection( - self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.final_layer_norm = FlaxT5LayerNorm( - self.config.d_model, eps=self.config.layer_norm_epsilon, dtype=self.dtype - ) - self.dropout = nn.Dropout(self.config.dropout_rate) - - def __call__( - self, - input_ids=None, - attention_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - init_cache: bool = False, - ): - hidden_states = self.embed_tokens(input_ids) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - - outputs = self.block( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - deterministic=deterministic, - init_cache=init_cache, - ) - - hidden_states = outputs[0] - - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - - # Add last layer - all_hidden_states = None - - if output_hidden_states: - all_hidden_states = outputs.hidden_states - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - if output_hidden_states: - return ( - hidden_states, - all_hidden_states, - ) + outputs[2:] - return (hidden_states,) + outputs[1:] - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -T5_ENCODE_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. T5 is a model with relative position embeddings so you - should be able to pad the inputs on both the right and the left. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for detail. - - To know more on how to prepare `input_ids` for pretraining take a look a [T5 Training](./t5#training). - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -T5_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - For training, `decoder_input_ids` should be provided. - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - past_key_values (`Dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -T5_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. T5 is a model with relative position embeddings so you - should be able to pad the inputs on both the right and the left. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for detail. - - [What are input IDs?](../glossary#input-ids) - - To know more on how to prepare `input_ids` for pretraining take a look a [T5 Training](./t5#training). - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - T5 uses the `pad_token_id` as the starting token for `decoder_input_ids` generation. If `past_key_values` - is used, optionally only the last `decoder_input_ids` have to be input (see `past_key_values`). - - To know more on how to prepare `decoder_input_ids` for pretraining take a look at [T5 - Training](./t5#training). - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - encoder_outputs (`tuple(tuple(jnp.ndarray)`, *optional*): - Tuple consists of (`last_hidden_state`, `optional`: *hidden_states*, `optional`: *attentions*) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)` is a sequence of hidden states at - the output of the last layer of the encoder. Used in the cross-attention of the decoder. - past_key_values (`tuple(tuple(jnp.ndarray))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -class FlaxT5PreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = T5Config - base_model_prefix = "transformer" - module_class: nn.Module = None - - def __init__( - self, - config: T5Config, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - gradient_checkpointing: bool = False, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, gradient_checkpointing=gradient_checkpointing, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def enable_gradient_checkpointing(self): - self._module = self.module_class( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=True, - ) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - - attention_mask = jnp.ones_like(input_ids) - args = [input_ids, attention_mask] - if self.module_class not in [FlaxT5EncoderModule]: - decoder_input_ids = jnp.ones_like(input_ids) - decoder_attention_mask = jnp.ones_like(input_ids) - args.extend([decoder_input_ids, decoder_attention_mask]) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - *args, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(T5_INPUTS_DOCSTRING) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_input_ids: jnp.ndarray = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if decoder_input_ids is None: - raise ValueError( - "Make sure to provide both `input_ids` and `decoder_input_ids`. `decoder_input_ids` is not passed" - " here." - ) - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # prepare decoder inputs - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(T5_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=T5Config) - def encode( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxT5ForConditionalGeneration - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small") - >>> model = FlaxT5ForConditionalGeneration.from_pretrained("google-t5/t5-small") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, input_ids, attention_mask, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(input_ids, attention_mask, **kwargs) - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - @add_start_docstrings(T5_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=T5Config) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxT5ForConditionalGeneration - >>> import jax.numpy as jnp - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small") - >>> model = FlaxT5ForConditionalGeneration.from_pretrained("google-t5/t5-small") - - >>> text = "My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxT5Attention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - -T5_START_DOCSTRING = r""" - The T5 model was proposed in [Exploring the Limits of Transfer Learning with a Unified Text-to-Text - Transformer](https://huggingface.co/papers/1910.10683) by Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan - Narang, Michael Matena, Yanqi Zhou, Wei Li, Peter J. Liu. It's an encoder decoder transformer pre-trained in a - text-to-text denoising generative setting. - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`T5Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - - -@add_start_docstrings( - "The bare T5 Model transformer outputting raw hidden-stateswithout any specific head on top.", - T5_START_DOCSTRING, -) -class FlaxT5Module(nn.Module): - config: T5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - def setup(self): - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.initializer_factor * 1.0), - dtype=self.dtype, - ) - - encoder_config = copy.deepcopy(self.config) - encoder_config.causal = False - self.encoder = FlaxT5Stack( - encoder_config, - embed_tokens=self.shared, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - decoder_config = copy.deepcopy(self.config) - decoder_config.causal = True - decoder_config.num_layers = self.config.num_decoder_layers - self.decoder = FlaxT5Stack( - decoder_config, - embed_tokens=self.shared, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - def __call__( - self, - input_ids=None, - attention_mask=None, - decoder_input_ids=None, - decoder_attention_mask=None, - encoder_outputs=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - deterministic: bool = True, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # Encode if needed (training, first prediction pass) - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - # Decode - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - encoder_hidden_states=encoder_outputs[0], - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -class FlaxT5Model(FlaxT5PreTrainedModel): - module_class = FlaxT5Module - - -append_call_sample_docstring(FlaxT5Model, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) - -FLAX_T5_MODEL_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxT5Model - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small") - >>> model = FlaxT5Model.from_pretrained("google-t5/t5-small") - - >>> input_ids = tokenizer( - ... "Studies have been shown that owning a dog is good for you", return_tensors="np" - ... ).input_ids - >>> decoder_input_ids = tokenizer("Studies show that", return_tensors="np").input_ids - - >>> # preprocess: Prepend decoder_input_ids with start token which is pad token for T5Model. - >>> # This is not needed for torch's T5ForConditionalGeneration as it does this internally using labels arg. - >>> decoder_input_ids = model._shift_right(decoder_input_ids) - - >>> # forward pass - >>> outputs = model(input_ids=input_ids, decoder_input_ids=decoder_input_ids) - >>> last_hidden_states = outputs.last_hidden_state - ``` -""" - - -overwrite_call_docstring(FlaxT5Model, T5_INPUTS_DOCSTRING + FLAX_T5_MODEL_DOCSTRING) -append_replace_return_docstrings(FlaxT5Model, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - - -@add_start_docstrings( - "The bare T5 Model transformer outputting encoder's raw hidden-states without any specific head on top.", - T5_START_DOCSTRING, -) -class FlaxT5EncoderModule(nn.Module): - config: T5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.initializer_factor * 1.0), - dtype=self.dtype, - ) - - encoder_config = copy.deepcopy(self.config) - encoder_config.is_decoder = False - encoder_config.is_encoder_decoder = False - encoder_config.causal = False - self.encoder = FlaxT5Stack( - encoder_config, - embed_tokens=self.shared, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - def __call__( - self, - input_ids=None, - attention_mask=None, - output_attentions=False, - output_hidden_states=False, - return_dict: bool = True, - deterministic: bool = True, - ): - # Encode if needed (training, first prediction pass) - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - return encoder_outputs - - -class FlaxT5EncoderModel(FlaxT5PreTrainedModel): - module_class = FlaxT5EncoderModule - - @add_start_docstrings_to_model_forward(T5_ENCODE_INPUTS_DOCSTRING) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - -@add_start_docstrings("""T5 Model with a `language modeling` head on top.""", T5_START_DOCSTRING) -class FlaxT5ForConditionalGenerationModule(nn.Module): - config: T5Config - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - def setup(self): - self.model_dim = self.config.d_model - - self.shared = nn.Embed( - self.config.vocab_size, - self.config.d_model, - embedding_init=jax.nn.initializers.normal(self.config.initializer_factor), - dtype=self.dtype, - ) - - encoder_config = copy.deepcopy(self.config) - encoder_config.causal = False - encoder_config.use_cache = False - encoder_config.is_encoder_decoder = False - self.encoder = FlaxT5Stack( - encoder_config, self.shared, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - - decoder_config = copy.deepcopy(self.config) - decoder_config.causal = True - decoder_config.is_encoder_decoder = False - decoder_config.num_layers = self.config.num_decoder_layers - self.decoder = FlaxT5Stack( - decoder_config, self.shared, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - kernel_init=jax.nn.initializers.normal(self.config.initializer_factor), - dtype=self.dtype, - ) - - def __call__( - self, - input_ids=None, - attention_mask=None, - decoder_input_ids=None, - decoder_attention_mask=None, - encoder_outputs=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - deterministic: bool = True, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # Encode - encoder_outputs = self.encoder( - input_ids=input_ids, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = encoder_outputs[0] - - # Decode - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - encoder_hidden_states=hidden_states, - encoder_attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - sequence_output = decoder_outputs[0] - - if self.config.tie_word_embeddings: - # Rescale output before projecting on vocab - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586 - sequence_output = sequence_output * (self.model_dim**-0.5) - - if self.config.tie_word_embeddings: - shared_embedding = self.shared.variables["params"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, sequence_output) - else: - lm_logits = self.lm_head(sequence_output) - - if not return_dict: - return (lm_logits,) + decoder_outputs[1:] + encoder_outputs - - return FlaxSeq2SeqLMOutput( - logits=lm_logits, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -class FlaxT5ForConditionalGeneration(FlaxT5PreTrainedModel): - module_class = FlaxT5ForConditionalGenerationModule - - @add_start_docstrings(T5_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=T5Config) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxT5ForConditionalGeneration - >>> import jax.numpy as jnp - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small") - >>> model = FlaxT5ForConditionalGeneration.from_pretrained("google-t5/t5-small") - - >>> text = "summarize: My friends are cool but they eat too many carbs." - >>> inputs = tokenizer(text, return_tensors="np") - >>> encoder_outputs = model.encode(**inputs) - - >>> decoder_start_token_id = model.config.decoder_start_token_id - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - if encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxT5Attention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, **kwargs): - decoder_module = module._get_decoder_module() - decoder_outputs = decoder_module( - decoder_input_ids, - decoder_attention_mask, - **kwargs, - ) - - sequence_output = decoder_outputs[0] - - if self.config.tie_word_embeddings: - # Rescale output before projecting on vocab - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586 - sequence_output = sequence_output * (self.config.d_model**-0.5) - - if self.config.tie_word_embeddings: - shared_embedding = module.shared.variables["params"]["embedding"] - lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, sequence_output) - else: - lm_logits = module.lm_head(sequence_output) - - return lm_logits, decoder_outputs - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - if past_key_values is None: - lm_logits, decoder_outputs = outputs - else: - (lm_logits, decoder_outputs), past = outputs - - if return_dict: - outputs = FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=decoder_outputs.hidden_states, - attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - ) - else: - outputs = (lm_logits,) + decoder_outputs[1:] - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - extended_attention_mask = jax.lax.dynamic_update_slice( - extended_attention_mask, decoder_attention_mask, (0, 0) - ) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - return model_kwargs - - -FLAX_T5_CONDITIONAL_GENERATION_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoTokenizer, FlaxT5ForConditionalGeneration - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small") - >>> model = FlaxT5ForConditionalGeneration.from_pretrained("google-t5/t5-small") - - >>> ARTICLE_TO_SUMMARIZE = "summarize: My friends are cool but they eat too many carbs." - >>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], return_tensors="np") - - >>> # Generate Summary - >>> summary_ids = model.generate(inputs["input_ids"]).sequences - >>> print(tokenizer.decode(summary_ids[0], skip_special_tokens=True, clean_up_tokenization_spaces=False)) - ``` -""" - - -overwrite_call_docstring( - FlaxT5ForConditionalGeneration, T5_INPUTS_DOCSTRING + FLAX_T5_CONDITIONAL_GENERATION_DOCSTRING -) -append_replace_return_docstrings( - FlaxT5ForConditionalGeneration, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC -) - - -__all__ = ["FlaxT5EncoderModel", "FlaxT5ForConditionalGeneration", "FlaxT5Model", "FlaxT5PreTrainedModel"] diff --git a/src/transformers/models/t5/modeling_t5.py b/src/transformers/models/t5/modeling_t5.py index f3c6e3fb1a2a..f74569574c8f 100644 --- a/src/transformers/models/t5/modeling_t5.py +++ b/src/transformers/models/t5/modeling_t5.py @@ -16,7 +16,6 @@ import copy import math -import os import warnings from typing import Optional, Union @@ -64,126 +63,6 @@ logger = logging.get_logger(__name__) -#################################################### -# This dict contains ids and associated url -# for the pretrained weights provided with the models -#################################################### - - -#################################################### -# This is a conversion method from TF 1.0 to PyTorch -# More details: https://medium.com/huggingface/from-tensorflow-to-pytorch-265f40ef2a28 -#################################################### -def load_tf_weights_in_t5(model, config, tf_checkpoint_path): - """Load tf checkpoints in a pytorch model.""" - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - tf_weights = {} - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - tf_weights[name] = array - - for txt_name in names: - name = txt_name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if any( - n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - tf_weights.pop(txt_name, None) - continue - if "_slot_" in name[-1]: - logger.info(f"Skipping {'/'.join(name)}") - tf_weights.pop(txt_name, None) - continue - pointer = model - array = tf_weights[txt_name] - - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] in ["kernel", "scale", "embedding"]: - pointer = getattr(pointer, "weight") - elif scope_names[0] == "self_attention": - pointer = getattr(pointer, "layer") - pointer = pointer[0] - elif scope_names[0] == "enc_dec_attention": - pointer = getattr(pointer, "layer") - pointer = pointer[1] - elif scope_names[0] == "dense_relu_dense": - pointer = getattr(pointer, "layer") - pointer = pointer[2] - elif scope_names[0] == "rms_norm": - if hasattr(pointer, "layer_norm"): - pointer = getattr(pointer, "layer_norm") - elif hasattr(pointer, "final_layer_norm"): - pointer = getattr(pointer, "final_layer_norm") - elif scope_names[0] == "scale": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "output_bias" or scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - elif scope_names[0] == "squad": - pointer = getattr(pointer, "classifier") - elif scope_names[0] == "decoder" and name[1] == "logits": - continue - elif scope_names[0] == "logits": - pointer = getattr(pointer, "lm_head") - elif scope_names[0] == "wi" and len(scope_names) > 1 and scope_names[1].isdigit(): - pointer = getattr(pointer, f"wi_{scope_names[1]}") - continue - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if scope_names[0] not in ["kernel", "scale", "embedding"]: - pointer = getattr(pointer, "weight") - if scope_names[0] != "embedding": - logger.info(f"Transposing numpy weight of shape {array.shape} for {name}") - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array.astype(np.float32)) - tf_weights.pop(txt_name, None) - - logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}.") - return model - - -#################################################### -# PyTorch Models are constructed by sub-classing -# - torch.nn.Module for the layers and -# - PreTrainedModel for the models (it-self a sub-class of nn.Module) -#################################################### PARALLELIZE_DOCSTRING = r""" This is an experimental feature and is a subject to change at a moment's notice. @@ -370,7 +249,6 @@ def __init__( "when creating this class." ) - # Mesh TensorFlow initialization to avoid scaling before softmax self.q = nn.Linear(self.d_model, self.inner_dim, bias=False) self.k = nn.Linear(self.d_model, self.inner_dim, bias=False) self.v = nn.Linear(self.d_model, self.inner_dim, bias=False) @@ -773,7 +651,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: @auto_docstring class T5PreTrainedModel(PreTrainedModel): config: T5Config - load_tf_weights = load_tf_weights_in_t5 base_model_prefix = "transformer" is_parallelizable = True supports_gradient_checkpointing = True @@ -802,8 +679,6 @@ def _init_weights(self, module): module, (T5Model, T5ForConditionalGeneration, T5EncoderModel, T5ForQuestionAnswering), ): - # Mesh TensorFlow embeddings initialization - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L1624 module.shared.weight.data.normal_(mean=0.0, std=factor * 1.0) if hasattr(module, "lm_head") and not self.config.tie_word_embeddings: module.lm_head.weight.data.normal_(mean=0.0, std=factor * 1.0) @@ -822,9 +697,6 @@ def _init_weights(self, module): if hasattr(module.out_proj, "bias") and module.out_proj.bias is not None: module.out_proj.bias.data.zero_() elif isinstance(module, T5DenseActDense): - # Mesh TensorFlow FF initialization - # See https://github.com/tensorflow/mesh/blob/master/mesh_tensorflow/transformer/transformer_layers.py#L56 - # and https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L89 module.wi.weight.data.normal_(mean=0.0, std=factor * ((self.config.d_model) ** -0.5)) if hasattr(module.wi, "bias") and module.wi.bias is not None: module.wi.bias.data.zero_() @@ -842,8 +714,6 @@ def _init_weights(self, module): if hasattr(module.wo, "bias") and module.wo.bias is not None: module.wo.bias.data.zero_() elif isinstance(module, T5Attention): - # Mesh TensorFlow attention initialization to avoid scaling before softmax - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/attention.py#L136 d_model = self.config.d_model key_value_proj_dim = self.config.d_kv n_heads = self.config.num_heads @@ -1786,8 +1656,6 @@ def forward( sequence_output = sequence_output.to(self.lm_head.weight.device) if self.config.tie_word_embeddings: - # Rescale output before projecting on vocab - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586 sequence_output = sequence_output * (self.model_dim**-0.5) lm_logits = self.lm_head(sequence_output) @@ -1798,7 +1666,6 @@ def forward( # move labels to correct device to enable PP labels = labels.to(lm_logits.device) loss = loss_fct(lm_logits.view(-1, lm_logits.size(-1)), labels.view(-1)) - # TODO(thom): Add z_loss https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L666 if not return_dict: output = (lm_logits,) + decoder_outputs[1:] + encoder_outputs @@ -2400,7 +2267,6 @@ def forward( "T5ForConditionalGeneration", "T5Model", "T5PreTrainedModel", - "load_tf_weights_in_t5", "T5ForQuestionAnswering", "T5ForSequenceClassification", "T5ForTokenClassification", diff --git a/src/transformers/models/t5/modeling_tf_t5.py b/src/transformers/models/t5/modeling_tf_t5.py deleted file mode 100644 index 142a0f73115e..000000000000 --- a/src/transformers/models/t5/modeling_tf_t5.py +++ /dev/null @@ -1,1676 +0,0 @@ -# coding=utf-8 -# Copyright 2020 T5 Authors and The HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 T5 model.""" - -from __future__ import annotations - -import copy -import itertools -import math -import warnings - -import numpy as np -import tensorflow as tf -from tensorflow.compiler.tf2xla.python.xla import dynamic_slice - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPastAndCrossAttentions, - TFSeq2SeqLMOutput, - TFSeq2SeqModelOutput, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_t5 import T5Config - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "T5Config" - - -#################################################### -# TF 2.0 Models are constructed using Keras imperative API by sub-classing -# - keras.layers.Layer for the layers and -# - TFPreTrainedModel for the models (it-self a sub-class of keras.Model) -#################################################### - - -class TFT5LayerNorm(keras.layers.Layer): - def __init__(self, hidden_size, epsilon=1e-6, **kwargs): - """ - Construct a layernorm module in the T5 style No bias and no subtraction of mean. - """ - super().__init__(**kwargs) - self.variance_epsilon = epsilon - self.hidden_size = hidden_size - - def build(self, input_shape): - """Build shared word embedding layer""" - self.weight = self.add_weight("weight", shape=(self.hidden_size,), initializer="ones") - super().build(input_shape) - - def call(self, hidden_states): - variance = tf.math.reduce_mean(tf.math.square(hidden_states), axis=-1, keepdims=True) - hidden_states = hidden_states * tf.math.rsqrt(variance + self.variance_epsilon) - return self.weight * hidden_states - - -class TFT5DenseActDense(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - wi_initializer = keras.initializers.RandomNormal( - mean=0, stddev=config.initializer_factor * (config.d_model**-0.5) - ) - wo_initializer = keras.initializers.RandomNormal( - mean=0, stddev=config.initializer_factor * (config.d_ff**-0.5) - ) - self.wi = keras.layers.Dense( - config.d_ff, use_bias=False, name="wi", kernel_initializer=wi_initializer - ) # Update init weights as in flax - self.wo = keras.layers.Dense( - config.d_model, use_bias=False, name="wo", kernel_initializer=wo_initializer - ) # Update init weights as in flax - self.dropout = keras.layers.Dropout(config.dropout_rate) - self.act = get_tf_activation(config.dense_act_fn) - self.config = config - - def call(self, hidden_states, training=False): - hidden_states = self.wi(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.wo(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "wi", None) is not None: - with tf.name_scope(self.wi.name): - self.wi.build([None, None, self.config.d_model]) - if getattr(self, "wo", None) is not None: - with tf.name_scope(self.wo.name): - self.wo.build([None, None, self.config.d_ff]) - - -class TFT5DenseGatedActDense(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - wi_initializer = keras.initializers.RandomNormal( - mean=0, stddev=config.initializer_factor * (config.d_model**-0.5) - ) - wo_initializer = keras.initializers.RandomNormal( - mean=0, stddev=config.initializer_factor * (config.d_ff**-0.5) - ) - self.wi_0 = keras.layers.Dense( - config.d_ff, use_bias=False, name="wi_0", kernel_initializer=wi_initializer - ) # Update init weights as in flax - self.wi_1 = keras.layers.Dense( - config.d_ff, use_bias=False, name="wi_1", kernel_initializer=wi_initializer - ) # Update init weights as in flax - self.wo = keras.layers.Dense( - config.d_model, use_bias=False, name="wo", kernel_initializer=wo_initializer - ) # Update init weights as in flax - self.dropout = keras.layers.Dropout(config.dropout_rate) - self.act = get_tf_activation(config.dense_act_fn) - self.config = config - - def call(self, hidden_states, training=False): - hidden_gelu = self.act(self.wi_0(hidden_states)) - hidden_linear = self.wi_1(hidden_states) - hidden_states = hidden_gelu * hidden_linear - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = self.wo(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "wi_0", None) is not None: - with tf.name_scope(self.wi_0.name): - self.wi_0.build([None, None, self.config.d_model]) - if getattr(self, "wi_1", None) is not None: - with tf.name_scope(self.wi_1.name): - self.wi_1.build([None, None, self.config.d_model]) - if getattr(self, "wo", None) is not None: - with tf.name_scope(self.wo.name): - self.wo.build([None, None, self.config.d_ff]) - - -class TFT5LayerFF(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - if config.is_gated_act: - self.DenseReluDense = TFT5DenseGatedActDense(config, name="DenseReluDense") - else: - self.DenseReluDense = TFT5DenseActDense(config, name="DenseReluDense") - - self.layer_norm = TFT5LayerNorm(config.d_model, epsilon=config.layer_norm_epsilon, name="layer_norm") - self.dropout = keras.layers.Dropout(config.dropout_rate) - - def call(self, hidden_states, training=False): - normed_hidden_states = self.layer_norm(hidden_states) - dense_output = self.DenseReluDense(normed_hidden_states, training=training) - hidden_states = hidden_states + self.dropout(dense_output, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build(None) - if getattr(self, "DenseReluDense", None) is not None: - with tf.name_scope(self.DenseReluDense.name): - self.DenseReluDense.build(None) - - -class TFT5Attention(keras.layers.Layer): - NEW_ID = itertools.count() - - def __init__(self, config, has_relative_attention_bias=False, **kwargs): - super().__init__(**kwargs) - self.layer_id = next(TFT5Attention.NEW_ID) - self.is_decoder = config.is_decoder - self.use_cache = config.use_cache - self.has_relative_attention_bias = has_relative_attention_bias - self.output_attentions = config.output_attentions - - self.relative_attention_num_buckets = config.relative_attention_num_buckets - self.relative_attention_max_distance = config.relative_attention_max_distance - self.d_model = config.d_model - self.key_value_proj_dim = config.d_kv - self.n_heads = config.num_heads - self.inner_dim = self.n_heads * self.key_value_proj_dim - - # Mesh TensorFlow initialization to avoid scaling before softmax - q_initializer = keras.initializers.RandomNormal( - mean=0, stddev=config.initializer_factor * ((self.inner_dim * self.key_value_proj_dim) ** -0.5) - ) - k_initializer = keras.initializers.RandomNormal( - mean=0, stddev=config.initializer_factor * (self.inner_dim**-0.5) - ) - v_initializer = keras.initializers.RandomNormal( - mean=0, stddev=config.initializer_factor * (self.inner_dim**-0.5) - ) - o_initializer = keras.initializers.RandomNormal( - mean=0, stddev=config.initializer_factor * (self.inner_dim**-0.5) - ) - self.relative_attention_bias_initializer = keras.initializers.RandomNormal( - mean=0, stddev=config.initializer_factor * (self.inner_dim**-0.5) - ) - - self.q = keras.layers.Dense( - self.inner_dim, use_bias=False, name="q", kernel_initializer=q_initializer - ) # Update init weights as in flax - self.k = keras.layers.Dense( - self.inner_dim, use_bias=False, name="k", kernel_initializer=k_initializer - ) # Update init weights as in flax - self.v = keras.layers.Dense( - self.inner_dim, use_bias=False, name="v", kernel_initializer=v_initializer - ) # Update init weights as in flax - self.o = keras.layers.Dense( - self.d_model, use_bias=False, name="o", kernel_initializer=o_initializer - ) # Update init weights as in flax - self.dropout = keras.layers.Dropout(config.dropout_rate) - - self.pruned_heads = set() - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if self.has_relative_attention_bias: - with tf.name_scope("relative_attention_bias"): - self.relative_attention_bias = self.add_weight( - name="embeddings", - shape=[self.relative_attention_num_buckets, self.n_heads], - initializer=self.relative_attention_bias_initializer, # Add initializer - ) - if getattr(self, "q", None) is not None: - with tf.name_scope(self.q.name): - self.q.build([None, None, self.d_model]) - if getattr(self, "k", None) is not None: - with tf.name_scope(self.k.name): - self.k.build([None, None, self.d_model]) - if getattr(self, "v", None) is not None: - with tf.name_scope(self.v.name): - self.v.build([None, None, self.d_model]) - if getattr(self, "o", None) is not None: - with tf.name_scope(self.o.name): - self.o.build([None, None, self.inner_dim]) - - def prune_heads(self, heads): - raise NotImplementedError - - @staticmethod - def _relative_position_bucket(relative_position, bidirectional=True, num_buckets=32, max_distance=128): - """ - Adapted from Mesh Tensorflow: - https://github.com/tensorflow/mesh/blob/0cb87fe07da627bf0b7e60475d59f95ed6b5be3d/mesh_tensorflow/transformer/transformer_layers.py#L593 - - Translate relative position to a bucket number for relative attention. The relative position is defined as - memory_position - query_position, i.e. the distance in tokens from the attending position to the attended-to - position. If bidirectional=False, then positive relative positions are invalid. We use smaller buckets for - small absolute relative_position and larger buckets for larger absolute relative_positions. All relative - positions >=max_distance map to the same bucket. All relative positions <=-max_distance map to the same bucket. - This should allow for more graceful generalization to longer sequences than the model has been trained on - - Args: - relative_position: an int32 Tensor - bidirectional: a boolean - whether the attention is bidirectional - num_buckets: an integer - max_distance: an integer - - Returns: - a Tensor with the same shape as relative_position, containing int32 values in the range [0, num_buckets) - """ - relative_buckets = 0 - # n = -relative_position - if bidirectional: - num_buckets //= 2 - relative_buckets += ( - tf.cast(tf.math.greater(relative_position, 0), dtype=relative_position.dtype) * num_buckets - ) - relative_position = tf.math.abs(relative_position) - else: - relative_position = -tf.math.minimum(relative_position, 0) - # now n is in the range [0, inf) - max_exact = num_buckets // 2 - is_small = tf.math.less(relative_position, max_exact) - relative_position_if_large = max_exact + tf.cast( - tf.math.log(tf.cast(relative_position, tf.float32) / tf.cast(max_exact, tf.float32)) - / math.log(max_distance / max_exact) - * (num_buckets - max_exact), - dtype=relative_position.dtype, - ) - relative_position_if_large = tf.math.minimum(relative_position_if_large, num_buckets - 1) - relative_buckets += tf.where(is_small, relative_position, relative_position_if_large) - return relative_buckets - - def compute_bias(self, query_length, key_length): - """Compute binned relative position bias""" - context_position = tf.range(query_length)[:, None] - memory_position = tf.range(key_length)[None, :] - relative_position = memory_position - context_position # shape (query_length, key_length) - relative_position_bucket = self._relative_position_bucket( - relative_position, - bidirectional=(not self.is_decoder), - num_buckets=self.relative_attention_num_buckets, - max_distance=self.relative_attention_max_distance, - ) - values = tf.gather( - self.relative_attention_bias, relative_position_bucket - ) # shape (query_length, key_length, num_heads) - values = tf.expand_dims( - tf.transpose(values, [2, 0, 1]), axis=0 - ) # shape (1, num_heads, query_length, key_length) - return values - - def call( - self, - hidden_states, - mask=None, - key_value_states=None, - position_bias=None, - past_key_value=None, - layer_head_mask=None, - query_length=None, - use_cache=False, - training=False, - output_attentions=False, - ): - """ - Self-attention (if key_value_states is None) or attention over source sentence (provided by key_value_states). - """ - # Input is (batch_size, query_length, dim) - # Mask is (batch_size, key_length) (non-causal) or (batch_size, key_length, key_length) - # past_key_value[0] is (batch_size, n_heads, q_len - 1, dim_per_head) - batch_size, seq_length = shape_list(hidden_states)[:2] - - real_seq_length = seq_length - - if past_key_value is not None: - assert len(past_key_value) == 2, ( - f"past_key_value should have 2 past states: keys and values. Got {len(past_key_value)} past states" - ) - real_seq_length += shape_list(past_key_value[0])[2] if query_length is None else query_length - - key_length = real_seq_length if key_value_states is None else shape_list(key_value_states)[1] - - def shape(hidden_states): - """projection""" - return tf.transpose( - tf.reshape(hidden_states, (batch_size, -1, self.n_heads, self.key_value_proj_dim)), perm=(0, 2, 1, 3) - ) - - def unshape(hidden_states): - """compute context""" - return tf.reshape(tf.transpose(hidden_states, perm=(0, 2, 1, 3)), (batch_size, -1, self.inner_dim)) - - def project(hidden_states, proj_layer, key_value_states, past_key_value): - """projects hidden states correctly to key/query states""" - if key_value_states is None: - # self-attn - # (batch_size, n_heads, seq_length, dim_per_head) - hidden_states = shape(proj_layer(hidden_states)) - elif past_key_value is None: - # cross-attn - # (batch_size, n_heads, seq_length, dim_per_head) - hidden_states = shape(proj_layer(key_value_states)) - - if past_key_value is not None: - if key_value_states is None: - # self-attn - # (batch_size, n_heads, key_length, dim_per_head) - hidden_states = tf.concat([past_key_value, hidden_states], axis=2) - else: - # cross-attn - hidden_states = past_key_value - return hidden_states - - # get query - query_states = shape(self.q(hidden_states)) # (batch_size, n_heads, query_length, dim_per_head) - - # get key/value - key_states = project( - hidden_states, self.k, key_value_states, past_key_value[0] if past_key_value is not None else None - ) - value_states = project( - hidden_states, self.v, key_value_states, past_key_value[1] if past_key_value is not None else None - ) - - # to cope with keras serialization - if self.is_decoder and use_cache: - present_key_value_state = (key_states, value_states) - else: - present_key_value_state = None - - scores = tf.einsum( - "bnqd,bnkd->bnqk", query_states, key_states - ) # (batch_size, n_heads, query_length, key_length) - - if position_bias is None: - if not self.has_relative_attention_bias: - position_bias = tf.zeros((1, self.n_heads, real_seq_length, key_length)) - else: - position_bias = self.compute_bias(real_seq_length, key_length) - - # if key and values are already calculated we want only the last query position bias - if past_key_value is not None: - if not self.has_relative_attention_bias: - position_bias = position_bias[:, :, -seq_length:, :] - else: - # we might have a padded past structure, in which case we want to fetch the position bias slice - # right after the most recently filled past index - most_recently_filled_past_index = tf.reduce_max(tf.where(past_key_value[0][0, 0, :, 0] != 0.0)) - position_bias = dynamic_slice( - position_bias, - (0, 0, most_recently_filled_past_index + 1, 0), - (1, self.n_heads, seq_length, real_seq_length), - ) - - if mask is not None: - position_bias = tf.cast(position_bias, dtype=mask.dtype) - position_bias = position_bias + mask # (batch_size, n_heads, query_length, key_length) - - scores += position_bias - weights = stable_softmax(scores, axis=-1) # (batch_size, n_heads, query_length, key_length) - weights = self.dropout(weights, training=training) # (batch_size, n_heads, query_length, key_length) - - # Mask heads if we want to - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.n_heads], - message=( - f"Head mask for a single layer should be of size {(self.n_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * weights - - attn_output = tf.matmul(weights, value_states) # (batch_size, n_heads, query_length, dim_per_head) - - attn_output = self.o(unshape(attn_output)) - - outputs = (attn_output,) + (present_key_value_state,) + (position_bias,) - - if output_attentions: - outputs = outputs + (weights,) - - return outputs - - -class TFT5LayerSelfAttention(keras.layers.Layer): - def __init__(self, config, has_relative_attention_bias=False, **kwargs): - super().__init__(**kwargs) - self.SelfAttention = TFT5Attention( - config, - has_relative_attention_bias=has_relative_attention_bias, - name="SelfAttention", - ) - self.layer_norm = TFT5LayerNorm(config.d_model, epsilon=config.layer_norm_epsilon, name="layer_norm") - self.dropout = keras.layers.Dropout(config.dropout_rate) - - def call( - self, - hidden_states, - attention_mask=None, - position_bias=None, - layer_head_mask=None, - past_key_value=None, - use_cache=False, - output_attentions=False, - training=False, - ): - normed_hidden_states = self.layer_norm(hidden_states) - attention_output = self.SelfAttention( - normed_hidden_states, - mask=attention_mask, - position_bias=position_bias, - layer_head_mask=layer_head_mask, - past_key_value=past_key_value, - use_cache=use_cache, - output_attentions=output_attentions, - training=training, - ) - hidden_states = hidden_states + self.dropout(attention_output[0], training=training) - outputs = (hidden_states,) + attention_output[1:] # add attentions if we output them - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "SelfAttention", None) is not None: - with tf.name_scope(self.SelfAttention.name): - self.SelfAttention.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build(None) - - -class TFT5LayerCrossAttention(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.EncDecAttention = TFT5Attention( - config, - has_relative_attention_bias=False, - name="EncDecAttention", - ) - self.layer_norm = TFT5LayerNorm(config.d_model, epsilon=config.layer_norm_epsilon, name="layer_norm") - self.dropout = keras.layers.Dropout(config.dropout_rate) - - def call( - self, - hidden_states, - key_value_states, - attention_mask=None, - position_bias=None, - layer_head_mask=None, - past_key_value=None, - query_length=None, - use_cache=False, - output_attentions=False, - training=False, - ): - normed_hidden_states = self.layer_norm(hidden_states) - attention_output = self.EncDecAttention( - normed_hidden_states, - mask=attention_mask, - key_value_states=key_value_states, - position_bias=position_bias, - layer_head_mask=layer_head_mask, - past_key_value=past_key_value, - query_length=query_length, - use_cache=use_cache, - output_attentions=output_attentions, - training=training, - ) - hidden_states = hidden_states + self.dropout(attention_output[0], training=training) - outputs = (hidden_states,) + attention_output[1:] # add attentions if we output them - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "EncDecAttention", None) is not None: - with tf.name_scope(self.EncDecAttention.name): - self.EncDecAttention.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build(None) - - -class TFT5Block(keras.layers.Layer): - def __init__(self, config, has_relative_attention_bias=False, **kwargs): - super().__init__(**kwargs) - self.is_decoder = config.is_decoder - self.layer = [] - self.layer.append( - TFT5LayerSelfAttention( - config, - has_relative_attention_bias=has_relative_attention_bias, - name="layer_._0", - ) - ) - if self.is_decoder: - self.layer.append( - TFT5LayerCrossAttention( - config, - name="layer_._1", - ) - ) - - self.layer.append(TFT5LayerFF(config, name=f"layer_._{len(self.layer)}")) - - def call( - self, - hidden_states, - attention_mask=None, - position_bias=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - encoder_decoder_position_bias=None, - layer_head_mask=None, - encoder_layer_head_mask=None, - past_key_value=None, - use_cache=False, - output_attentions=False, - training=False, - ): - if past_key_value is not None: - assert self.is_decoder, "Only decoder can use `past_key_values`" - expected_num_past_key_values = 2 if encoder_hidden_states is None else 4 - - if len(past_key_value) != expected_num_past_key_values: - raise ValueError( - f"There should be {expected_num_past_key_values} past states. " - f"{'2 (key / value) for cross attention' if expected_num_past_key_values == 4 else ''}. " - f"Got {len(past_key_value)} past key / value states" - ) - - self_attn_past_key_value = past_key_value[:2] - cross_attn_past_key_value = past_key_value[2:] - else: - self_attn_past_key_value, cross_attn_past_key_value = None, None - - self_attention_outputs = self.layer[0]( - hidden_states, - attention_mask=attention_mask, - position_bias=position_bias, - layer_head_mask=layer_head_mask, - past_key_value=self_attn_past_key_value, - use_cache=use_cache, - output_attentions=output_attentions, - training=training, - ) - hidden_states, present_key_value_state = self_attention_outputs[:2] - attention_outputs = self_attention_outputs[2:] # Keep self-attention outputs and relative position weights - - if self.is_decoder and encoder_hidden_states is not None: - # the actual query length is unknown for cross attention - # if using past key value states. Need to inject it here - if present_key_value_state is not None: - query_length = shape_list(present_key_value_state[0])[2] - else: - query_length = None - - cross_attention_outputs = self.layer[1]( - hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - position_bias=encoder_decoder_position_bias, - layer_head_mask=encoder_layer_head_mask, - past_key_value=cross_attn_past_key_value, - query_length=query_length, - use_cache=use_cache, - output_attentions=output_attentions, - training=training, - ) - hidden_states = cross_attention_outputs[0] - # Combine self attn and cross attn key value states - if present_key_value_state is not None: - present_key_value_state = present_key_value_state + cross_attention_outputs[1] - - # Keep cross-attention outputs and relative position weights - attention_outputs = attention_outputs + cross_attention_outputs[2:] - - # Apply Feed Forward layer - hidden_states = self.layer[-1](hidden_states, training=training) - outputs = (hidden_states,) - - # Add attentions if we output them - outputs = outputs + (present_key_value_state,) + attention_outputs - return outputs # hidden-states, present_key_value_states, (self-attention weights), (self-attention position bias), (cross-attention weights), (cross-attention position bias) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - for layer_module in self.layer: - if hasattr(layer_module, "name"): - with tf.name_scope(layer_module.name): - layer_module.build(None) - - -#################################################### -# The full model without a specific pretrained or finetuning head is -# provided as a keras.layers.Layer usually called "TFT5MainLayer" -#################################################### -@keras_serializable -class TFT5MainLayer(keras.layers.Layer): - config_class = T5Config - - def __init__(self, config, embed_tokens=None, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.output_hidden_states = config.output_hidden_states - self.output_attentions = config.output_attentions - self.use_cache = config.use_cache - - self.embed_tokens = embed_tokens - self.is_decoder = config.is_decoder - - self.config = config - self.num_hidden_layers = config.num_layers - - self.block = [ - TFT5Block(config, has_relative_attention_bias=bool(i == 0), name=f"block_._{i}") - for i in range(config.num_layers) - ] - self.final_layer_norm = TFT5LayerNorm( - config.d_model, epsilon=config.layer_norm_epsilon, name="final_layer_norm" - ) - self.dropout = keras.layers.Dropout(config.dropout_rate) - - def _prune_heads(self, heads_to_prune): - raise NotImplementedError # Not implemented yet in the library fr TF 2.0 models - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - inputs_embeds=None, - head_mask=None, - encoder_head_mask=None, - past_key_values=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ) -> tuple: - if input_ids is not None and inputs_embeds is not None: - err_msg_prefix = "decoder_" if self.is_decoder else "" - raise ValueError( - f"You cannot specify both {err_msg_prefix}input_ids and {err_msg_prefix}inputs_embeds at the same time" - ) - elif input_ids is not None: - input_shape = shape_list(input_ids) - input_ids = tf.reshape(input_ids, (-1, input_shape[-1])) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - err_msg_prefix = "decoder_" if self.is_decoder else "" - raise ValueError(f"You have to specify either {err_msg_prefix}input_ids or {err_msg_prefix}inputs_embeds") - - if inputs_embeds is None: - assert self.embed_tokens is not None, "You have to initialize the model with valid token embeddings" - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) - - batch_size, seq_length = input_shape - - # required mask seq length can be calculated via length of past - mask_seq_length = ( - shape_list(past_key_values[0][0])[2] + seq_length if past_key_values is not None else seq_length - ) - - if attention_mask is None: - attention_mask = tf.fill((batch_size, mask_seq_length), 1) - if self.is_decoder and encoder_attention_mask is None and encoder_hidden_states is not None: - encoder_seq_length = shape_list(encoder_hidden_states)[1] - encoder_attention_mask = tf.fill((batch_size, encoder_seq_length), 1) - - # initialize past_key_values with `None` if past does not exist - if past_key_values is None: - past_key_values = [None] * len(self.block) - - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - attention_mask = tf.cast(attention_mask, dtype=inputs_embeds.dtype) - num_dims_attention_mask = len(shape_list(attention_mask)) - if num_dims_attention_mask == 3: - extended_attention_mask = attention_mask[:, None, :, :] - elif num_dims_attention_mask == 2: - # Provided a padding mask of dimensions [batch_size, mask_seq_length] - # - if the model is a decoder, apply a causal mask in addition to the padding mask - # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - if self.is_decoder: - seq_ids = tf.range(mask_seq_length) - causal_mask = tf.less_equal( - tf.tile(seq_ids[None, None, :], (batch_size, mask_seq_length, 1)), - seq_ids[None, :, None], - ) - causal_mask = tf.cast(causal_mask, dtype=attention_mask.dtype) - extended_attention_mask = causal_mask[:, None, :, :] * attention_mask[:, None, None, :] - if past_key_values[0] is not None: - extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :] - else: - extended_attention_mask = attention_mask[:, None, None, :] - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -1e9 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # extended_attention_mask = tf.math.equal(extended_attention_mask, - # tf.transpose(extended_attention_mask, perm=(-1, -2))) - - extended_attention_mask = (1.0 - extended_attention_mask) * -1e9 - - if self.is_decoder and encoder_attention_mask is not None: - # If a 2D ou 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=extended_attention_mask.dtype) - num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) - if num_dims_encoder_attention_mask == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if num_dims_encoder_attention_mask == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, - # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) - - encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -1e9 - else: - encoder_extended_attention_mask = None - - present_key_value_states = () if use_cache and self.is_decoder else None - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if (output_attentions and self.is_decoder) else None - position_bias = None - encoder_decoder_position_bias = None - - hidden_states = self.dropout(inputs_embeds, training=training) - - for idx, (layer_module, past_key_value) in enumerate(zip(self.block, past_key_values)): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_outputs = layer_module( - hidden_states, - attention_mask=extended_attention_mask, - position_bias=position_bias, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, - encoder_decoder_position_bias=encoder_decoder_position_bias, - layer_head_mask=head_mask[idx] if head_mask is not None else None, - encoder_layer_head_mask=encoder_head_mask[idx] if encoder_head_mask is not None else None, - past_key_value=past_key_value, - use_cache=use_cache, - output_attentions=output_attentions, - training=training, - ) - - # layer_outputs is a tuple with: - # hidden-states, key-value-states, (self-attention weights), (self-attention position bias), (cross-attention weights), (cross-attention position bias) - hidden_states, present_key_value_state = layer_outputs[:2] - - # We share the position biases between the layers - the first layer store them - # layer_outputs = hidden-states, past_key_values, (self-attention weights), - # (self-attention position bias), (cross-attention position bias), (cross-attention weights), - position_bias = layer_outputs[2] - - if self.is_decoder and encoder_hidden_states is not None: - encoder_decoder_position_bias = layer_outputs[4 if output_attentions else 3] - - # append next layer key value states - if present_key_value_state is not None and use_cache and self.is_decoder: - present_key_value_states = present_key_value_states + (present_key_value_state,) - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[3],) - if self.is_decoder: - all_cross_attentions = all_cross_attentions + (layer_outputs[5],) - - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - outputs = (hidden_states,) - # need to check if is decoder here as well for special cases when using keras compile - if use_cache and self.is_decoder: - outputs = outputs + (present_key_value_states,) - if output_hidden_states: - outputs = outputs + (all_hidden_states,) - if output_attentions: - outputs = outputs + (all_attentions,) - if self.is_decoder: - outputs + (all_cross_attentions,) - return outputs # last-layer hidden state, (past_key_values), (all hidden states), (all attentions), (all_cross_attentions) - - if self.is_decoder: - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=present_key_value_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - else: - return TFBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build(None) - if getattr(self, "block", None) is not None: - for layer in self.block: - with tf.name_scope(layer.name): - layer.build(None) - - -#################################################### -# TFT5PreTrainedModel is a sub-class of keras.Model -# which take care of loading and saving pretrained weights -# and various common utilities. -# Here you just need to specify a few (self-explanatory) -# pointers for your model. -#################################################### -class TFT5PreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = T5Config - base_model_prefix = "transformer" - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"decoder\Wblock[\W_0]+layer[\W_1]+EncDecAttention\Wrelative_attention_bias"] - - def get_input_embeddings(self): - return self.shared - - def set_input_embeddings(self, value): - self.shared = value - self.encoder.embed_tokens = self.shared - if hasattr(self, "decoder"): - self.decoder.embed_tokens = self.shared - - def _shift_right(self, input_ids): - decoder_start_token_id = self.config.decoder_start_token_id - pad_token_id = self.config.pad_token_id - - assert decoder_start_token_id is not None, ( - "self.model.config.decoder_start_token_id has to be defined. In TF T5 it is usually set to the" - " pad_token_id. See T5 docs for more information" - ) - - start_tokens = tf.fill((shape_list(input_ids)[0], 1), decoder_start_token_id) - start_tokens = tf.cast(start_tokens, input_ids.dtype) # Ensure compatible dtypes for concatenation - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - - assert pad_token_id is not None, "self.model.config.pad_token_id has to be defined." - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.cast(tf.fill(shape_list(shifted_input_ids), pad_token_id), shifted_input_ids.dtype), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal( - shifted_input_ids, tf.constant(0, dtype=shifted_input_ids.dtype) - ) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -T5_START_DOCSTRING = r""" - - The T5 model was proposed in [Exploring the Limits of Transfer Learning with a Unified Text-to-Text - Transformer](https://huggingface.co/papers/1910.10683) by Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan - Narang, Michael Matena, Yanqi Zhou, Wei Li, Peter J. Liu. It's an encoder decoder transformer pre-trained in a - text-to-text denoising generative setting. - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`T5Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -T5_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. T5 is a model with relative position embeddings so you - should be able to pad the inputs on the right or the left. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - - To know more on how to prepare `inputs` for pretraining take a look at [T5 Training](./t5#training). - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Provide for sequence to sequence training. T5 uses the `pad_token_id` as the starting token for - `decoder_input_ids` generation. If `past_key_values` is used, optionally only the last `decoder_input_ids` - have to be input (see `past_key_values`). - - To know more on how to prepare `decoder_input_ids` for pretraining take a look at [T5 - Training](./t5#training). - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - head_mask (`tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules in the encoder. Mask values selected in `[0, - 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - decoder_head_mask (`tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules in the decoder. Mask values selected in `[0, - 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_outputs (`tuple(tuple(tf.FloatTensor)`, *optional*): - Tuple consists of (`last_hidden_state`, `optional`: *hidden_states*, `optional`: *attentions*) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)` is a sequence of hidden states at - the output of the last layer of the encoder. Used in the cross-attention of the decoder. - past_key_values (`tuple(tuple(tf.Tensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - decoder_inputs_embeds (`tf.Tensor` of shape `(batch_size, target_sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `decoder_input_ids` you can choose to directly pass an embedded - representation. If `past_key_values` is used, optionally only the last `decoder_inputs_embeds` have to be - input (see `past_key_values`). This is useful if you want more control over how to convert - `decoder_input_ids` indices into associated vectors than the model's internal embedding lookup matrix. - - If `decoder_input_ids` and `decoder_inputs_embeds` are both unset, `decoder_inputs_embeds` takes the value - of `inputs_embeds`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - -T5_ENCODER_INPUTS_DOCSTRING = r""" - Args: - inputs (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. T5 is a model with relative position embeddings so you - should be able to pad the inputs on the right or the left. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - To know more on how to prepare `inputs` for pre-training take a look at [T5 Training](./t5#training). - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - head_mask (`tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - -_HEAD_MASK_WARNING_MSG = """ -The input argument `head_mask` was split into two arguments `head_mask` and `decoder_head_mask`. Currently, -`decoder_head_mask` is set to copy `head_mask`, but this feature is deprecated and will be removed in future versions. -If you do not want to use any `decoder_head_mask` now, please set `decoder_head_mask = tf.ones((num_layers, -num_heads))`. -""" - - -@add_start_docstrings( - "The bare T5 Model transformer outputting raw hidden-stateswithout any specific head on top.", - T5_START_DOCSTRING, -) -class TFT5Model(TFT5PreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.shared = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.d_model, - embeddings_initializer=keras.initializers.TruncatedNormal(self.config.initializer_factor), - name="shared", - ) - # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) - self.shared.load_weight_prefix = "shared" - - encoder_config = copy.deepcopy(config) - encoder_config.use_cache = False - self.encoder = TFT5MainLayer(encoder_config, self.shared, name="encoder") - - decoder_config = copy.deepcopy(config) - decoder_config.is_decoder = True - decoder_config.num_layers = config.num_decoder_layers - self.decoder = TFT5MainLayer(decoder_config, self.shared, name="decoder") - - def get_encoder(self): - return self.encoder - - @unpack_inputs - @add_start_docstrings_to_model_forward(T5_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqModelOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFSeq2SeqModelOutput: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFT5Model - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small") - >>> model = TFT5Model.from_pretrained("google-t5/t5-small") - - >>> input_ids = tokenizer( - ... "Studies have been shown that owning a dog is good for you", return_tensors="tf" - ... ).input_ids # Batch size 1 - >>> decoder_input_ids = tokenizer("Studies show that", return_tensors="tf").input_ids # Batch size 1 - - >>> # preprocess: Prepend decoder_input_ids with start token which is pad token for T5Model. - >>> # This is not needed for torch's T5ForConditionalGeneration as it does this internally using labels arg. - >>> decoder_input_ids = model._shift_right(decoder_input_ids) - - >>> # forward pass - >>> outputs = model(input_ids, decoder_input_ids=decoder_input_ids) - >>> last_hidden_states = outputs.last_hidden_state - ```""" - # FutureWarning: head_mask was separated into two input args - head_mask, decoder_head_mask - if head_mask is not None and decoder_head_mask is None: - warnings.warn(_HEAD_MASK_WARNING_MSG, FutureWarning) - decoder_head_mask = head_mask - - # Encode if needed (training, first prediction pass) - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_ids, - attention_mask=attention_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - inputs_embeds=inputs_embeds, - head_mask=head_mask, - past_key_values=None, - use_cache=False, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - hidden_states = encoder_outputs[0] - - # Decode - decoder_outputs = self.decoder( - decoder_input_ids, - attention_mask=decoder_attention_mask, - encoder_hidden_states=hidden_states, - encoder_attention_mask=attention_mask, - inputs_embeds=decoder_inputs_embeds, - head_mask=decoder_head_mask, - encoder_head_mask=head_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - past = decoder_outputs[1] if use_cache else None - - if not return_dict: - if past_key_values is not None: - decoder_outputs = decoder_outputs[:1] + (past,) + decoder_outputs[2:] - return decoder_outputs + encoder_outputs - - return TFSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=past, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # The shared/tied weights expect to be in the model base namespace - # Adding "/" to the end (not the start!) of a tf.name_scope puts it in the root namespace rather than - # the current one. - with tf.name_scope(self.shared.load_weight_prefix + "/" + self.shared.name + "/"): - self.shared.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings("""T5 Model with a `language modeling` head on top.""", T5_START_DOCSTRING) -class TFT5ForConditionalGeneration(TFT5PreTrainedModel, TFCausalLanguageModelingLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.model_dim = config.d_model - self.shared = keras.layers.Embedding( - config.vocab_size, - config.d_model, - name="shared", - embeddings_initializer=get_initializer(self.config.initializer_factor), - ) - # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) - self.shared.load_weight_prefix = "shared" - - encoder_config = copy.deepcopy(config) - encoder_config.use_cache = False - self.encoder = TFT5MainLayer(encoder_config, self.shared, name="encoder") - - decoder_config = copy.deepcopy(config) - decoder_config.is_decoder = True - decoder_config.num_layers = config.num_decoder_layers - self.decoder = TFT5MainLayer(decoder_config, self.shared, name="decoder") - - if not config.tie_word_embeddings: - lm_head_initializer = keras.initializers.RandomNormal(mean=0, stddev=config.initializer_factor) - self.lm_head = keras.layers.Dense( - config.vocab_size, use_bias=False, name="lm_head", kernel_initializer=lm_head_initializer - ) # Update init weights as in flax - self.config = config - - def get_output_embeddings(self): - if self.config.tie_word_embeddings: - return self.get_input_embeddings() - else: - # in a dense layer the kernel has a shape (last_dim, units), for us (dim, num_tokens) - # value has a shape (num_tokens, dim) then needs to be transposed - return tf.transpose(self.lm_head.kernel) - - def set_output_embeddings(self, value): - if self.config.tie_word_embeddings: - self.set_input_embeddings(value) - else: - lm_head_initializer = keras.initializers.RandomNormal(mean=0, stddev=self.config.initializer_factor) - self.lm_head = keras.layers.Dense( - shape_list(value)[0], use_bias=False, name="lm_head", kernel_initializer=lm_head_initializer - ) # Update init weights as in flax - # in a dense layer the kernel has a shape (last_dim, units), for us (dim, num_tokens) - # value has a shape (num_tokens, dim) then needs to be transposed - transposed_value = tf.transpose(value) - self.lm_head.kernel = transposed_value - - def get_encoder(self): - return self.encoder - - @unpack_inputs - @add_start_docstrings_to_model_forward(T5_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFSeq2SeqLMOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFT5ForConditionalGeneration - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small") - >>> model = TFT5ForConditionalGeneration.from_pretrained("google-t5/t5-small") - - >>> # training - >>> inputs = tokenizer("The walks in park", return_tensors="tf").input_ids - >>> labels = tokenizer(" cute dog the ", return_tensors="tf").input_ids - >>> outputs = model(inputs, labels=labels) - >>> loss = outputs.loss - >>> logits = outputs.logits - - >>> # inference - >>> inputs = tokenizer( - ... "summarize: studies have shown that owning a dog is good for you", return_tensors="tf" - ... ).input_ids # Batch size 1 - >>> outputs = model.generate(inputs) - >>> print(tokenizer.decode(outputs[0], skip_special_tokens=True)) - >>> # studies have shown that owning a dog is good for you - ```""" - # FutureWarning: head_mask was separated into two input args - head_mask, decoder_head_mask - if head_mask is not None and decoder_head_mask is None: - warnings.warn(_HEAD_MASK_WARNING_MSG, FutureWarning) - decoder_head_mask = head_mask - - # Encode if needed (training, first prediction pass) - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_ids, - attention_mask=attention_mask, - inputs_embeds=inputs_embeds, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - hidden_states = encoder_outputs[0] - - if labels is not None and decoder_input_ids is None and decoder_inputs_embeds is None: - # get decoder inputs from shifting lm labels to the right - decoder_input_ids = self._shift_right(labels) - - # Decode - decoder_outputs = self.decoder( - decoder_input_ids, - attention_mask=decoder_attention_mask, - encoder_hidden_states=hidden_states, - encoder_attention_mask=attention_mask, - inputs_embeds=decoder_inputs_embeds, - head_mask=decoder_head_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = decoder_outputs[0] - - # T5v1.1 does not tie output word embeddings and thus does not require downscaling - if self.config.tie_word_embeddings: - sequence_output = sequence_output * (self.model_dim**-0.5) - logits = tf.matmul(sequence_output, self.shared.weights, transpose_b=True) - else: - logits = self.lm_head(sequence_output) - - logits = tf.cast(logits, tf.float32) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - past = decoder_outputs[1] if use_cache else None - if not return_dict: - if past_key_values is not None: - decoder_outputs = decoder_outputs[:1] + (past,) + decoder_outputs[2:] - output = (logits,) + decoder_outputs[1:] + encoder_outputs - return ((loss,) + output) if loss is not None else output - - # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True - elif isinstance(encoder_outputs, tuple): - last_hidden_state = encoder_outputs[0] - hidden_states = None - attentions = None - idx = 0 - if output_hidden_states: - idx += 1 - hidden_states = encoder_outputs[idx] - if output_attentions: - idx += 1 - attentions = encoder_outputs[idx] - - encoder_outputs = TFBaseModelOutput( - last_hidden_state=last_hidden_state, - hidden_states=hidden_states, - attentions=attentions, - ) - - return TFSeq2SeqLMOutput( - loss=loss, - logits=logits, - past_key_values=past, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def serving_output(self, output): - pkv = tf.convert_to_tensor(output.past_key_values[1:]) if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def prepare_inputs_for_generation( - self, - input_ids, - past_key_values=None, - attention_mask=None, - decoder_attention_mask=None, - head_mask=None, - decoder_head_mask=None, - use_cache=None, - encoder_outputs=None, - **kwargs, - ): - # cut decoder_input_ids if past is used - if past_key_values is not None: - input_ids = input_ids[:, -1:] - - return { - "input_ids": None, # needs to be passed to make Keras.layer.__call__ happy - "decoder_input_ids": input_ids, - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "attention_mask": attention_mask, - "decoder_attention_mask": decoder_attention_mask, - "head_mask": head_mask, - "decoder_head_mask": decoder_head_mask, - "use_cache": use_cache, - } - - def prepare_decoder_input_ids_from_labels(self, labels: tf.Tensor): - return self._shift_right(labels) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # The shared/tied weights expect to be in the model base namespace - # Adding "/" to the end (not the start!) of a tf.name_scope puts it in the root namespace rather than - # the current one. - with tf.name_scope(self.shared.load_weight_prefix + "/" + self.shared.name + "/"): - self.shared.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build([None, None, self.config.d_model]) - - -@add_start_docstrings( - "The bare T5 Model transformer outputting encoder's raw hidden-stateswithout any specific head on top.", - T5_START_DOCSTRING, -) -class TFT5EncoderModel(TFT5PreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.shared = keras.layers.Embedding( - config.vocab_size, - config.d_model, - name="shared", - embeddings_initializer=get_initializer(self.config.initializer_factor), - ) - # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) - self.shared.load_weight_prefix = "shared" - - encoder_config = copy.deepcopy(config) - encoder_config.use_cache = False - self.encoder = TFT5MainLayer(encoder_config, self.shared, name="encoder") - - def get_encoder(self): - return self.encoder - - @unpack_inputs - @add_start_docstrings_to_model_forward(T5_ENCODER_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBaseModelOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutput: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TFT5EncoderModel - - >>> tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small") - >>> model = TFT5EncoderModel.from_pretrained("google-t5/t5-small") - - >>> input_ids = tokenizer( - ... "Studies have been shown that owning a dog is good for you", return_tensors="tf" - ... ).input_ids # Batch size 1 - >>> outputs = model(input_ids) - ```""" - - encoder_outputs = self.encoder( - input_ids, - attention_mask=attention_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - inputs_embeds=inputs_embeds, - head_mask=head_mask, - past_key_values=None, - use_cache=False, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return encoder_outputs - - return TFBaseModelOutput( - last_hidden_state=encoder_outputs.last_hidden_state, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # The shared/tied weights expect to be in the model base namespace - # Adding "/" to the end (not the start!) of a tf.name_scope puts it in the root namespace rather than - # the current one. - with tf.name_scope(self.shared.load_weight_prefix + "/" + self.shared.name + "/"): - self.shared.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - - -__all__ = ["TFT5EncoderModel", "TFT5ForConditionalGeneration", "TFT5Model", "TFT5PreTrainedModel"] diff --git a/src/transformers/models/table_transformer/modeling_table_transformer.py b/src/transformers/models/table_transformer/modeling_table_transformer.py index d55ea6740075..4ab85689ab15 100644 --- a/src/transformers/models/table_transformer/modeling_table_transformer.py +++ b/src/transformers/models/table_transformer/modeling_table_transformer.py @@ -700,8 +700,6 @@ def _init_weights(self, module): nn.init.uniform_(module.row_embeddings.weight) nn.init.uniform_(module.column_embeddings.weight) if isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/tapas/__init__.py b/src/transformers/models/tapas/__init__.py index 7df7e765f60e..d85329883381 100644 --- a/src/transformers/models/tapas/__init__.py +++ b/src/transformers/models/tapas/__init__.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from .configuration_tapas import * from .modeling_tapas import * - from .modeling_tf_tapas import * from .tokenization_tapas import * else: import sys diff --git a/src/transformers/models/tapas/convert_tapas_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/tapas/convert_tapas_original_tf_checkpoint_to_pytorch.py index 34bf77cccd6b..d9400b366e5f 100644 --- a/src/transformers/models/tapas/convert_tapas_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/tapas/convert_tapas_original_tf_checkpoint_to_pytorch.py @@ -15,6 +15,9 @@ """Convert TAPAS checkpoint.""" import argparse +import os + +import torch from transformers import ( TapasConfig, @@ -23,14 +26,148 @@ TapasForSequenceClassification, TapasModel, TapasTokenizer, - load_tf_weights_in_tapas, ) from transformers.utils import logging +logger = logging.get_logger(__name__) logging.set_verbosity_info() +def load_tf_weights_in_tapas(model, config, tf_checkpoint_path): + """ + Load tf checkpoints in a PyTorch model. This is an adaptation from load_tf_weights_in_bert + + - add cell selection and aggregation heads + - take into account additional token type embedding layers + """ + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array) + + for name, array in zip(names, arrays): + name = name.split("/") + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculate m and v + # which are not required for using pretrained model + if any( + n + in [ + "adam_v", + "adam_m", + "AdamWeightDecayOptimizer", + "AdamWeightDecayOptimizer_1", + "global_step", + "seq_relationship", + ] + for n in name + ): + logger.info(f"Skipping {'/'.join(name)}") + continue + # in case the model is TapasForSequenceClassification, we skip output_bias and output_weights + # since these are not used for classification + if isinstance(model, TapasForSequenceClassification): + if any(n in ["output_bias", "output_weights"] for n in name): + logger.info(f"Skipping {'/'.join(name)}") + continue + # in case the model is TapasModel, we skip output_bias, output_weights, output_bias_cls and output_weights_cls + # since this model does not have MLM and NSP heads + if isinstance(model, TapasModel): + if any(n in ["output_bias", "output_weights", "output_bias_cls", "output_weights_cls"] for n in name): + logger.info(f"Skipping {'/'.join(name)}") + continue + # in case the model is TapasForMaskedLM, we skip the pooler + if isinstance(model, TapasForMaskedLM): + if any(n in ["pooler"] for n in name): + logger.info(f"Skipping {'/'.join(name)}") + continue + # if first scope name starts with "bert", change it to "tapas" + if name[0] == "bert": + name[0] = "tapas" + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "kernel" or scope_names[0] == "gamma": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + # cell selection heads + elif scope_names[0] == "output_bias": + if not isinstance(model, TapasForMaskedLM): + pointer = getattr(pointer, "output_bias") + else: + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights": + pointer = getattr(pointer, "output_weights") + elif scope_names[0] == "column_output_bias": + pointer = getattr(pointer, "column_output_bias") + elif scope_names[0] == "column_output_weights": + pointer = getattr(pointer, "column_output_weights") + # aggregation head + elif scope_names[0] == "output_bias_agg": + pointer = getattr(pointer, "aggregation_classifier") + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights_agg": + pointer = getattr(pointer, "aggregation_classifier") + pointer = getattr(pointer, "weight") + # classification head + elif scope_names[0] == "output_bias_cls": + pointer = getattr(pointer, "classifier") + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights_cls": + pointer = getattr(pointer, "classifier") + pointer = getattr(pointer, "weight") + else: + try: + pointer = getattr(pointer, scope_names[0]) + except AttributeError: + logger.info(f"Skipping {'/'.join(name)}") + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if m_name[-11:] == "_embeddings": + pointer = getattr(pointer, "weight") + elif m_name[-13:] in [f"_embeddings_{i}" for i in range(7)]: + pointer = getattr(pointer, "weight") + elif m_name == "kernel": + array = np.transpose(array) + try: + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + # Added a check to see whether the array is a scalar (because bias terms in Tapas checkpoints can be + # scalar => should first be converted to numpy arrays) + if np.isscalar(array): + array = np.array(array) + pointer.data = torch.from_numpy(array) + return model + + def convert_tf_checkpoint_to_pytorch( task, reset_position_index_per_cell, tf_checkpoint_path, tapas_config_file, pytorch_dump_path ): diff --git a/src/transformers/models/tapas/modeling_tapas.py b/src/transformers/models/tapas/modeling_tapas.py index 075b834533b6..2987e7ec7467 100644 --- a/src/transformers/models/tapas/modeling_tapas.py +++ b/src/transformers/models/tapas/modeling_tapas.py @@ -16,7 +16,6 @@ import enum import math -import os from dataclasses import dataclass from typing import Optional, Union @@ -66,140 +65,6 @@ class TableQuestionAnsweringOutput(ModelOutput): attentions: Optional[tuple[torch.FloatTensor]] = None -def load_tf_weights_in_tapas(model, config, tf_checkpoint_path): - """ - Load tf checkpoints in a PyTorch model. This is an adaptation from load_tf_weights_in_bert - - - add cell selection and aggregation heads - - take into account additional token type embedding layers - """ - try: - import re - - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - tf_path = os.path.abspath(tf_checkpoint_path) - logger.info(f"Converting TensorFlow checkpoint from {tf_path}") - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - names = [] - arrays = [] - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - names.append(name) - arrays.append(array) - - for name, array in zip(names, arrays): - name = name.split("/") - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculate m and v - # which are not required for using pretrained model - if any( - n - in [ - "adam_v", - "adam_m", - "AdamWeightDecayOptimizer", - "AdamWeightDecayOptimizer_1", - "global_step", - "seq_relationship", - ] - for n in name - ): - logger.info(f"Skipping {'/'.join(name)}") - continue - # in case the model is TapasForSequenceClassification, we skip output_bias and output_weights - # since these are not used for classification - if isinstance(model, TapasForSequenceClassification): - if any(n in ["output_bias", "output_weights"] for n in name): - logger.info(f"Skipping {'/'.join(name)}") - continue - # in case the model is TapasModel, we skip output_bias, output_weights, output_bias_cls and output_weights_cls - # since this model does not have MLM and NSP heads - if isinstance(model, TapasModel): - if any(n in ["output_bias", "output_weights", "output_bias_cls", "output_weights_cls"] for n in name): - logger.info(f"Skipping {'/'.join(name)}") - continue - # in case the model is TapasForMaskedLM, we skip the pooler - if isinstance(model, TapasForMaskedLM): - if any(n in ["pooler"] for n in name): - logger.info(f"Skipping {'/'.join(name)}") - continue - # if first scope name starts with "bert", change it to "tapas" - if name[0] == "bert": - name[0] = "tapas" - pointer = model - for m_name in name: - if re.fullmatch(r"[A-Za-z]+_\d+", m_name): - scope_names = re.split(r"_(\d+)", m_name) - else: - scope_names = [m_name] - if scope_names[0] == "kernel" or scope_names[0] == "gamma": - pointer = getattr(pointer, "weight") - elif scope_names[0] == "beta": - pointer = getattr(pointer, "bias") - # cell selection heads - elif scope_names[0] == "output_bias": - if not isinstance(model, TapasForMaskedLM): - pointer = getattr(pointer, "output_bias") - else: - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights": - pointer = getattr(pointer, "output_weights") - elif scope_names[0] == "column_output_bias": - pointer = getattr(pointer, "column_output_bias") - elif scope_names[0] == "column_output_weights": - pointer = getattr(pointer, "column_output_weights") - # aggregation head - elif scope_names[0] == "output_bias_agg": - pointer = getattr(pointer, "aggregation_classifier") - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights_agg": - pointer = getattr(pointer, "aggregation_classifier") - pointer = getattr(pointer, "weight") - # classification head - elif scope_names[0] == "output_bias_cls": - pointer = getattr(pointer, "classifier") - pointer = getattr(pointer, "bias") - elif scope_names[0] == "output_weights_cls": - pointer = getattr(pointer, "classifier") - pointer = getattr(pointer, "weight") - else: - try: - pointer = getattr(pointer, scope_names[0]) - except AttributeError: - logger.info(f"Skipping {'/'.join(name)}") - continue - if len(scope_names) >= 2: - num = int(scope_names[1]) - pointer = pointer[num] - if m_name[-11:] == "_embeddings": - pointer = getattr(pointer, "weight") - elif m_name[-13:] in [f"_embeddings_{i}" for i in range(7)]: - pointer = getattr(pointer, "weight") - elif m_name == "kernel": - array = np.transpose(array) - try: - if pointer.shape != array.shape: - raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - # Added a check to see whether the array is a scalar (because bias terms in Tapas checkpoints can be - # scalar => should first be converted to numpy arrays) - if np.isscalar(array): - array = np.array(array) - pointer.data = torch.from_numpy(array) - return model - - class TapasEmbeddings(nn.Module): """ Construct the embeddings from word, position and token_type embeddings. Same as BertEmbeddings but with a number of @@ -220,8 +85,6 @@ def __init__(self, config): self.number_of_token_type_embeddings = len(config.type_vocab_sizes) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -699,8 +562,6 @@ class TapasPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -2052,8 +1913,6 @@ def _calculate_aggregate_mask(answer, pooled_output, cell_selection_preference, # Examples with non-empty cell selection supervision. is_cell_supervision_available = torch.sum(labels, dim=1) > 0 - # torch.where is not equivalent to tf.where (in tensorflow 1) - # hence the added .view on the condition to match the shape of the first tensor aggregate_mask = torch.where( torch.logical_and(is_pred_cell_selection, is_cell_supervision_available).view(aggregate_mask_init.size()), torch.zeros_like(aggregate_mask_init, dtype=torch.float32), @@ -2343,5 +2202,4 @@ def _calculate_regression_loss( "TapasForSequenceClassification", "TapasModel", "TapasPreTrainedModel", - "load_tf_weights_in_tapas", ] diff --git a/src/transformers/models/tapas/modeling_tf_tapas.py b/src/transformers/models/tapas/modeling_tf_tapas.py deleted file mode 100644 index 624df1fba176..000000000000 --- a/src/transformers/models/tapas/modeling_tf_tapas.py +++ /dev/null @@ -1,2461 +0,0 @@ -# coding=utf-8 -# Copyright 2021 Google Research and 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. -"""TF 2.0 TAPAS model.""" - -from __future__ import annotations - -import enum -import math -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFBaseModelOutputWithPooling, - TFMaskedLMOutput, - TFSequenceClassifierOutput, -) -from ...modeling_tf_utils import ( - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - is_tensorflow_probability_available, - logging, - replace_return_docstrings, -) -from .configuration_tapas import TapasConfig - - -logger = logging.get_logger(__name__) - -# soft dependency -if is_tensorflow_probability_available(): - try: - import tensorflow_probability as tfp - - # On the first call, check whether a compatible version of TensorFlow is installed - # TensorFlow Probability depends on a recent stable release of TensorFlow - n = tfp.distributions.Normal(loc=0.0, scale=1.0) - except ImportError: - logger.error( - "TAPAS models are not usable since `tensorflow_probability` can't be loaded. " - "It seems you have `tensorflow_probability` installed with the wrong tensorflow version. " - "Please try to reinstall it following the instructions here: https://github.com/tensorflow/probability." - ) -else: - try: - import tensorflow_probability as tfp - - # On the first call, check whether a compatible version of TensorFlow is installed - # TensorFlow Probability depends on a recent stable release of TensorFlow - _ = tfp.distributions.Normal(loc=0.0, scale=1.0) - except ImportError: - pass - -_CONFIG_FOR_DOC = "TapasConfig" -_CHECKPOINT_FOR_DOC = "google/tapas-base" - - -EPSILON_ZERO_DIVISION = 1e-10 -CLOSE_ENOUGH_TO_LOG_ZERO = -10000.0 - - -@dataclass -class TFTableQuestionAnsweringOutput(ModelOutput): - """ - Output type of [`TFTapasForQuestionAnswering`]. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` (and possibly `answer`, `aggregation_labels`, `numeric_values` and `numeric_values_scale` are provided)): - Total loss as the sum of the hierarchical cell selection log-likelihood loss and (optionally) the - semi-supervised regression loss and (optionally) supervised loss for aggregations. - logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Prediction scores of the cell selection head, for every token. - logits_aggregation (`tf.Tensor`, *optional*, of shape `(batch_size, num_aggregation_labels)`): - Prediction scores of the aggregation head, for every aggregation operator. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus - the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - logits_aggregation: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -class TFTapasEmbeddings(keras.layers.Layer): - """ - Construct the embeddings from word, position and token_type embeddings. Same as BertEmbeddings but with a number of - additional token type embeddings to encode tabular structure. - """ - - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.number_of_token_type_embeddings = len(config.type_vocab_sizes) - self.reset_position_index_per_cell = config.reset_position_index_per_cell - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - for i, type_vocab_size in enumerate(self.config.type_vocab_sizes): - with tf.name_scope(f"token_type_embeddings_{i}"): - setattr( - self, - f"token_type_embeddings_{i}", - self.add_weight( - name="embeddings", - shape=[type_vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - def call( - self, - input_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - training: bool = False, - ) -> tf.Tensor: - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - if input_ids is not None: - input_shape = shape_list(input_ids) - else: - input_shape = shape_list(inputs_embeds)[:-1] - - seq_length = input_shape[1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape + [self.number_of_token_type_embeddings], value=0) - - if position_ids is None: - # create absolute position embeddings - position_ids = tf.expand_dims(tf.range(start=0, limit=seq_length), axis=0) - position_ids = tf.broadcast_to(position_ids, shape=input_shape) - # when self.config.reset_position_index_per_cell is set to True, create relative position embeddings - if self.reset_position_index_per_cell: - # shape (batch_size, seq_len) - col_index = IndexMap(token_type_ids[:, :, 1], self.config.type_vocab_sizes[1], batch_dims=1) - # shape (batch_size, seq_len) - row_index = IndexMap(token_type_ids[:, :, 2], self.config.type_vocab_sizes[2], batch_dims=1) - # shape (batch_size, seq_len) - full_index = ProductIndexMap(col_index, row_index) - # shape (max_rows * max_columns,). First absolute position for every cell - first_position_per_segment = reduce_min(position_ids, full_index)[0] - # ? shape (batch_size, seq_len). First absolute position of the cell for every token - first_position = gather(first_position_per_segment, full_index) - # shape (1, seq_len) - position = tf.expand_dims(tf.range(start=0, limit=seq_length), axis=0) - position_ids = tf.math.minimum(self.max_position_embeddings - 1, position - first_position) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - position_embeddings = tf.gather(self.position_embeddings, indices=position_ids) - - final_embeddings = inputs_embeds + position_embeddings - - for i in range(self.number_of_token_type_embeddings): - name = f"token_type_embeddings_{i}" - final_embeddings += tf.gather(params=getattr(self, name), indices=token_type_ids[:, :, i]) - - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention with Bert->Tapas -class TFTapasSelfAttention(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - - self.is_decoder = config.is_decoder - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_layer = past_key_value[0] - value_layer = past_key_value[1] - attention_mask = encoder_attention_mask - elif is_cross_attention: - key_layer = self.transpose_for_scores(self.key(inputs=encoder_hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=encoder_hidden_states), batch_size) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_layer, value_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFTapasModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - if self.is_decoder: - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfOutput with Bert->Tapas -class TFTapasSelfOutput(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertAttention with Bert->Tapas -class TFTapasAttention(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFTapasSelfAttention(config, name="self") - self.dense_output = TFTapasSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - # add attentions (possibly with past_key_value) if we output them - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->Tapas -class TFTapasIntermediate(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->Tapas -class TFTapasOutput(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLayer with Bert->Tapas -class TFTapasLayer(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFTapasAttention(config, name="attention") - self.is_decoder = config.is_decoder - self.add_cross_attention = config.add_cross_attention - if self.add_cross_attention: - if not self.is_decoder: - raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = TFTapasAttention(config, name="crossattention") - self.intermediate = TFTapasIntermediate(config, name="intermediate") - self.bert_output = TFTapasOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_value: tuple[tf.Tensor] | None, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=self_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - cross_attn_present_key_value = None - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" - " by setting `config.add_cross_attention=True`" - ) - - # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - cross_attention_outputs = self.crossattention( - input_tensor=attention_output, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=cross_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - - # add cross-attn cache to positions 3,4 of present_key_value tuple - cross_attn_present_key_value = cross_attention_outputs[-1] - present_key_value = present_key_value + cross_attn_present_key_value - - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + outputs # add attentions if we output them - - # if decoder, return the attn key/values as the last output - if self.is_decoder: - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertEncoder with Bert->Tapas -class TFTapasEncoder(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layer = [TFTapasLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_values: tuple[tuple[tf.Tensor]] | None, - use_cache: bool | None, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - next_decoder_cache = () if use_cache else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[i], - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - if self.config.add_cross_attention and encoder_hidden_states is not None: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v for v in [hidden_states, all_hidden_states, all_attentions, all_cross_attentions] if v is not None - ) - - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->Tapas -class TFTapasPooler(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPredictionHeadTransform with Bert->Tapas -class TFTapasPredictionHeadTransform(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - name="dense", - ) - - if isinstance(config.hidden_act, str): - self.transform_act_fn = get_tf_activation(config.hidden_act) - else: - self.transform_act_fn = config.hidden_act - - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.transform_act_fn(hidden_states) - hidden_states = self.LayerNorm(inputs=hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLMPredictionHead with Bert->Tapas -class TFTapasLMPredictionHead(keras.layers.Layer): - def __init__(self, config: TapasConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - - self.transform = TFTapasPredictionHeadTransform(config, name="transform") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.input_embeddings = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "transform", None) is not None: - with tf.name_scope(self.transform.name): - self.transform.build(None) - - def get_output_embeddings(self) -> keras.layers.Layer: - return self.input_embeddings - - def set_output_embeddings(self, value: tf.Variable): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self) -> dict[str, tf.Variable]: - return {"bias": self.bias} - - def set_bias(self, value: tf.Variable): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.transform(hidden_states=hidden_states) - seq_length = shape_list(hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertMLMHead with Bert->Tapas -class TFTapasMLMHead(keras.layers.Layer): - def __init__(self, config: TapasConfig, input_embeddings: keras.layers.Layer, **kwargs): - super().__init__(**kwargs) - - self.predictions = TFTapasLMPredictionHead(config, input_embeddings, name="predictions") - - def call(self, sequence_output: tf.Tensor) -> tf.Tensor: - prediction_scores = self.predictions(hidden_states=sequence_output) - - return prediction_scores - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "predictions", None) is not None: - with tf.name_scope(self.predictions.name): - self.predictions.build(None) - - -@keras_serializable -class TFTapasMainLayer(keras.layers.Layer): - config_class = TapasConfig - - def __init__(self, config: TapasConfig, add_pooling_layer: bool = True, **kwargs): - super().__init__(**kwargs) - - self.config = config - - self.embeddings = TFTapasEmbeddings(config, name="embeddings") - self.encoder = TFTapasEncoder(config, name="encoder") - self.pooler = TFTapasPooler(config, name="pooler") if add_pooling_layer else None - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if attention_mask is None: - attention_mask = tf.fill(dims=input_shape, value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape + [len(self.config.type_vocab_sizes)], value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - extended_attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1])) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_values=None, - use_cache=None, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -class TFTapasPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = TapasConfig - base_model_prefix = "tapas" - - @property - def input_signature(self): - return { - "input_ids": tf.TensorSpec((None, None), tf.int32, name="input_ids"), - "attention_mask": tf.TensorSpec((None, None), tf.float32, name="attention_mask"), - "token_type_ids": tf.TensorSpec((None, None, 7), tf.int32, name="token_type_ids"), - } - - -TAPAS_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`TapasConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -TAPAS_INPUTS_DOCSTRING = r""" - Args: - input_ids (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0}, 7)`, *optional*): - Token indices that encode tabular structure. Indices can be obtained using [`AutoTokenizer`]. See this - class for more info. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. If - `reset_position_index_per_cell` of [`TapasConfig`] is set to `True`, relative position embeddings will be - used. Selected in the range `[0, config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare Tapas Model transformer outputting raw hidden-states without any specific head on top.", - TAPAS_START_DOCSTRING, -) -class TFTapasModel(TFTapasPreTrainedModel): - def __init__(self, config: TapasConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.tapas = TFTapasMainLayer(config, name="tapas") - - @unpack_inputs - @add_start_docstrings_to_model_forward(TAPAS_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFBaseModelOutputWithPooling, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TapasModel - >>> import pandas as pd - - >>> tokenizer = AutoTokenizer.from_pretrained("google/tapas-base") - >>> model = TapasModel.from_pretrained("google/tapas-base") - - >>> data = { - ... "Actors": ["Brad Pitt", "Leonardo Di Caprio", "George Clooney"], - ... "Age": ["56", "45", "59"], - ... "Number of movies": ["87", "53", "69"], - ... } - >>> table = pd.DataFrame.from_dict(data) - >>> queries = ["How many movies has George Clooney played in?", "How old is Brad Pitt?"] - - >>> inputs = tokenizer(table=table, queries=queries, padding="max_length", return_tensors="tf") - >>> outputs = model(**inputs) - - >>> last_hidden_states = outputs.last_hidden_state - ```""" - outputs = self.tapas( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "tapas", None) is not None: - with tf.name_scope(self.tapas.name): - self.tapas.build(None) - - -@add_start_docstrings("""Tapas Model with a `language modeling` head on top.""", TAPAS_START_DOCSTRING) -class TFTapasForMaskedLM(TFTapasPreTrainedModel, TFMaskedLanguageModelingLoss): - def __init__(self, config: TapasConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if config.is_decoder: - logger.warning( - "If you want to use `TFTapasForMaskedLM` make sure `config.is_decoder=False` for " - "bi-directional self-attention." - ) - - self.tapas = TFTapasMainLayer(config, add_pooling_layer=False, name="tapas") - self.lm_head = TFTapasMLMHead(config, input_embeddings=self.tapas.embeddings, name="cls") - - def get_lm_head(self) -> keras.layers.Layer: - return self.lm_head.predictions - - @unpack_inputs - @add_start_docstrings_to_model_forward(TAPAS_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFMaskedLMOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TapasForMaskedLM - >>> import pandas as pd - - >>> tokenizer = AutoTokenizer.from_pretrained("google/tapas-base") - >>> model = TapasForMaskedLM.from_pretrained("google/tapas-base") - - >>> data = { - ... "Actors": ["Brad Pitt", "Leonardo Di Caprio", "George Clooney"], - ... "Age": ["56", "45", "59"], - ... "Number of movies": ["87", "53", "69"], - ... } - >>> table = pd.DataFrame.from_dict(data) - - >>> inputs = tokenizer( - ... table=table, queries="How many [MASK] has George [MASK] played in?", return_tensors="tf" - ... ) - >>> labels = tokenizer( - ... table=table, queries="How many movies has George Clooney played in?", return_tensors="tf" - ... )["input_ids"] - - >>> outputs = model(**inputs, labels=labels) - >>> logits = outputs.logits - ```""" - outputs = self.tapas( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - prediction_scores = self.lm_head(sequence_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "tapas", None) is not None: - with tf.name_scope(self.tapas.name): - self.tapas.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -class TFTapasComputeTokenLogits(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - self.temperature = config.temperature - # cell selection heads - with tf.name_scope("output"): - self.output_weights = self.add_weight( - name="output_weights", - shape=(config.hidden_size,), - dtype=tf.float32, - trainable=True, - initializer=tf.zeros_initializer() - if config.init_cell_selection_weights_to_zero - else keras.initializers.TruncatedNormal(stddev=config.initializer_range), - ) - self.output_bias = self.add_weight( - name="output_bias", shape=(), trainable=True, initializer=tf.zeros_initializer() - ) - - def call(self, sequence_output: tf.Tensor) -> tf.Tensor: - """ - Computes logits per token - - Args: - sequence_output (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Also known as last_hidden_state. Sequence of hidden-states at the output of the last layer of the - model. - - Returns: - logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): Logits per token. - """ - logits = (tf.einsum("bsj,j->bs", sequence_output, self.output_weights) + self.output_bias) / self.temperature - return logits - - -class TFTapasComputeColumnLogits(keras.layers.Layer): - def __init__(self, config: TapasConfig, **kwargs): - super().__init__(**kwargs) - - with tf.name_scope("column_output"): - self.column_output_weights = self.add_weight( - name="column_output_weights", - shape=[config.hidden_size], - dtype=tf.float32, - trainable=True, - initializer=tf.zeros_initializer() - if config.init_cell_selection_weights_to_zero - else keras.initializers.TruncatedNormal(stddev=config.initializer_range), - ) - self.column_output_bias = self.add_weight( - name="column_output_bias", shape=(), trainable=True, initializer=tf.zeros_initializer() - ) - - def call(self, sequence_output, cell_index, cell_mask, allow_empty_column_selection) -> tf.Tensor: - """ - Computes the column logits. - - Args: - sequence_output (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Also known as last_hidden_state. Sequence of hidden-states at the output of the last layer of the - model. - cell_index (`ProductIndexMap`): - Index that groups tokens into cells. - cell_mask (`tf.Tensor` of shape `(batch_size, max_num_rows * max_num_cols)`): - Mask for cells that exist in the table (i.e. that are not padding). - allow_empty_column_selection (`bool`): - Whether to allow not to select any column - - Returns: - column_logits (`tf.Tensor`of shape `(batch_size, max_num_cols)`): Tensor containing the column logits for - every example in the batch. - """ - - # First, compute the token logits (batch_size, seq_len) - without temperature - token_logits = tf.einsum("bsj,j->bs", sequence_output, self.column_output_weights) + self.column_output_bias - - # Next, average the logits per cell (batch_size, max_num_cols*max_num_rows) - cell_logits, cell_logits_index = reduce_mean(token_logits, cell_index) - - # Finally, average the logits per column (batch_size, max_num_cols) - column_index = cell_index.project_inner(cell_logits_index) - column_logits, out_index = reduce_sum(cell_logits * cell_mask, column_index) - - cell_count, _ = reduce_sum(cell_mask, column_index) - column_logits /= cell_count + EPSILON_ZERO_DIVISION - - # Mask columns that do not appear in the example. - is_padding = tf.logical_and(cell_count < 0.5, tf.not_equal(out_index.indices, 0)) - column_logits += CLOSE_ENOUGH_TO_LOG_ZERO * tf.cast(is_padding, tf.float32) - - if not allow_empty_column_selection: - column_logits += CLOSE_ENOUGH_TO_LOG_ZERO * tf.cast(tf.equal(out_index.indices, 0), tf.float32) - - return column_logits - - -@add_start_docstrings( - """ - Tapas Model with a cell selection head and optional aggregation head on top for question-answering tasks on tables - (linear layers on top of the hidden-states output to compute `logits` and optional `logits_aggregation`), e.g. for - SQA, WTQ or WikiSQL-supervised tasks. - """, - TAPAS_START_DOCSTRING, -) -class TFTapasForQuestionAnswering(TFTapasPreTrainedModel): - def __init__(self, config: TapasConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - # base model - self.tapas = TFTapasMainLayer(config, name="tapas") - - # dropout - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - - self.compute_token_logits = TFTapasComputeTokenLogits(config, name="compute_token_logits") - - self.compute_column_logits = TFTapasComputeColumnLogits(config, name="compute_column_logits") - - if config.num_aggregation_labels > 0: - self.aggregation_classifier = keras.layers.Dense( - config.num_aggregation_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="aggregation_classifier", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(TAPAS_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFTableQuestionAnsweringOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - table_mask: np.ndarray | tf.Tensor | None = None, - aggregation_labels: np.ndarray | tf.Tensor | None = None, - float_answer: np.ndarray | tf.Tensor | None = None, - numeric_values: np.ndarray | tf.Tensor | None = None, - numeric_values_scale: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTableQuestionAnsweringOutput | tuple[tf.Tensor]: - r""" - table_mask (`tf.Tensor` of shape `(batch_size, seq_length)`, *optional*): - Mask for the table. Indicates which tokens belong to the table (1). Question tokens, table headers and - padding are 0. - labels (`tf.Tensor` of shape `(batch_size, seq_length)`, *optional*): - Labels per token for computing the hierarchical cell selection loss. This encodes the positions of the - answer appearing in the table. Can be obtained using [`AutoTokenizer`]. - - - 1 for tokens that are **part of the answer**, - - 0 for tokens that are **not part of the answer**. - - aggregation_labels (`tf.Tensor` of shape `(batch_size, )`, *optional*): - Aggregation function index for every example in the batch for computing the aggregation loss. Indices - should be in `[0, ..., config.num_aggregation_labels - 1]`. Only required in case of strong supervision for - aggregation (WikiSQL-supervised). - float_answer (`tf.Tensor` of shape `(batch_size, )`, *optional*): - Float answer for every example in the batch. Set to *float('nan')* for cell selection questions. Only - required in case of weak supervision (WTQ) to calculate the aggregate mask and regression loss. - numeric_values (`tf.Tensor` of shape `(batch_size, seq_length)`, *optional*): - Numeric values of every token, NaN for tokens which are not numeric values. Can be obtained using - [`AutoTokenizer`]. Only required in case of weak supervision for aggregation (WTQ) to calculate the - regression loss. - numeric_values_scale (`tf.Tensor` of shape `(batch_size, seq_length)`, *optional*): - Scale of the numeric values of every token. Can be obtained using [`AutoTokenizer`]. Only required in case - of weak supervision for aggregation (WTQ) to calculate the regression loss. - - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TapasForQuestionAnswering - >>> import pandas as pd - - >>> tokenizer = AutoTokenizer.from_pretrained("google/tapas-base-finetuned-wtq") - >>> model = TapasForQuestionAnswering.from_pretrained("google/tapas-base-finetuned-wtq") - - >>> data = { - ... "Actors": ["Brad Pitt", "Leonardo Di Caprio", "George Clooney"], - ... "Age": ["56", "45", "59"], - ... "Number of movies": ["87", "53", "69"], - ... } - >>> table = pd.DataFrame.from_dict(data) - >>> queries = ["How many movies has George Clooney played in?", "How old is Brad Pitt?"] - - >>> inputs = tokenizer(table=table, queries=queries, padding="max_length", return_tensors="tf") - >>> outputs = model(**inputs) - - >>> logits = outputs.logits - >>> logits_aggregation = outputs.logits_aggregation - ```""" - - outputs = self.tapas( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - pooled_output = outputs[1] - - sequence_output = self.dropout(sequence_output) - - if input_ids is not None: - input_shape = shape_list(input_ids) - else: - input_shape = shape_list(inputs_embeds)[:-1] - - # Construct indices for the table. - if token_type_ids is None: - token_type_ids = tf.fill(input_shape + [len(self.config.type_vocab_sizes)], 0) - - token_types = [ - "segment_ids", - "column_ids", - "row_ids", - "prev_labels", - "column_ranks", - "inv_column_ranks", - "numeric_relations", - ] - - row_ids = token_type_ids[:, :, token_types.index("row_ids")] - column_ids = token_type_ids[:, :, token_types.index("column_ids")] - - # Construct indices for the table. - row_index = IndexMap( - indices=tf.minimum(tf.cast(row_ids, tf.int32), self.config.max_num_rows - 1), - num_segments=self.config.max_num_rows, - batch_dims=1, - ) - col_index = IndexMap( - indices=tf.minimum(tf.cast(column_ids, tf.int32), self.config.max_num_columns - 1), - num_segments=self.config.max_num_columns, - batch_dims=1, - ) - cell_index = ProductIndexMap(row_index, col_index) - - # Masks. - input_shape = shape_list(input_ids) if input_ids is not None else shape_list(inputs_embeds)[:-1] - if attention_mask is None: - attention_mask = tf.ones(input_shape) - # Table cells only, without question tokens and table headers. - if table_mask is None: - table_mask = tf.where(row_ids > 0, tf.ones_like(row_ids), tf.zeros_like(row_ids)) - # [batch_size, seq_length] - input_mask_float = tf.cast(attention_mask, tf.float32) - table_mask_float = tf.cast(table_mask, tf.float32) - - # Mask for cells that exist in the table (i.e. that are not padding). - cell_mask, _ = reduce_mean(input_mask_float, cell_index) - - # Compute logits per token. These are used to select individual cells. - logits = self.compute_token_logits(sequence_output) - - # Compute logits per column. These are used to select a column. - column_logits = None - if self.config.select_one_column: - column_logits = self.compute_column_logits( - sequence_output, cell_index, cell_mask, self.config.allow_empty_column_selection - ) - - # Aggregate logits. - logits_aggregation = None - if self.config.num_aggregation_labels > 0: - logits_aggregation = self.aggregation_classifier(pooled_output) - - # Total loss calculation - total_loss = tf.zeros(shape=(1,), dtype=tf.float32) - calculate_loss = False - if labels is not None: - calculate_loss = True - is_supervised = not self.config.num_aggregation_labels > 0 or not self.config.use_answer_as_supervision - - # Semi-supervised cell selection in case of no aggregation: - # If the answer (the denotation) appears directly in the table we might - # select the answer without applying any aggregation function. There are - # some ambiguous cases, see utils._calculate_aggregate_mask for more info. - # `aggregate_mask` is 1 for examples where we chose to aggregate and 0 - # for examples where we chose to select the answer directly. - # `labels` encodes the positions of the answer appearing in the table. - if is_supervised: - aggregate_mask = None - else: - if float_answer is not None: - assert shape_list(labels)[0] == shape_list(float_answer)[0], ( - "Make sure the answers are a FloatTensor of shape (batch_size,)" - ) - # [batch_size] - aggregate_mask = _calculate_aggregate_mask( - float_answer, - pooled_output, - self.config.cell_selection_preference, - labels, - self.aggregation_classifier, - ) - else: - aggregate_mask = None - raise ValueError("You have to specify float answers in order to calculate the aggregate mask") - - # Cell selection log-likelihood - if self.config.average_logits_per_cell: - logits_per_cell, _ = reduce_mean(logits, cell_index) - logits = gather(logits_per_cell, cell_index) - dist_per_token = tfp.distributions.Bernoulli(logits=logits) - - # Compute cell selection loss per example. - selection_loss_per_example = None - if not self.config.select_one_column: - weight = tf.where( - labels == 0, - tf.ones_like(labels, dtype=tf.float32), - self.config.positive_label_weight * tf.ones_like(labels, dtype=tf.float32), - ) - selection_loss_per_token = -dist_per_token.log_prob(labels) * weight - selection_loss_per_example = tf.reduce_sum(selection_loss_per_token * input_mask_float, axis=1) / ( - tf.reduce_sum(input_mask_float, axis=1) + EPSILON_ZERO_DIVISION - ) - else: - selection_loss_per_example, logits = _single_column_cell_selection_loss( - logits, column_logits, labels, cell_index, col_index, cell_mask - ) - dist_per_token = tfp.distributions.Bernoulli(logits=logits) - - # Supervised cell selection - if self.config.disable_per_token_loss: - pass - elif is_supervised: - total_loss += tf.reduce_mean(selection_loss_per_example) - else: - # For the not supervised case, do not assign loss for cell selection - total_loss += tf.reduce_mean(selection_loss_per_example * (1.0 - aggregate_mask)) - - # Semi-supervised regression loss and supervised loss for aggregations - if self.config.num_aggregation_labels > 0: - if is_supervised: - # Note that `aggregate_mask` is None if the setting is supervised. - if aggregation_labels is not None: - assert shape_list(labels)[0] == shape_list(aggregation_labels)[0], ( - "Make sure the aggregation labels are a LongTensor of shape (batch_size,)" - ) - per_example_additional_loss = _calculate_aggregation_loss( - logits_aggregation, - aggregate_mask, - aggregation_labels, - self.config.use_answer_as_supervision, - self.config.num_aggregation_labels, - self.config.aggregation_loss_weight, - ) - else: - raise ValueError( - "You have to specify aggregation labels in order to calculate the aggregation loss" - ) - else: - aggregation_labels = tf.zeros(shape_list(labels)[0], dtype=tf.int32) - per_example_additional_loss = _calculate_aggregation_loss( - logits_aggregation, - aggregate_mask, - aggregation_labels, - self.config.use_answer_as_supervision, - self.config.num_aggregation_labels, - self.config.aggregation_loss_weight, - ) - - if self.config.use_answer_as_supervision: - if numeric_values is not None and numeric_values_scale is not None: - assert shape_list(numeric_values) == shape_list(numeric_values_scale) - # Add regression loss for numeric answers which require aggregation. - answer_loss, large_answer_loss_mask = _calculate_regression_loss( - float_answer, - aggregate_mask, - dist_per_token, - numeric_values, - numeric_values_scale, - table_mask_float, - logits_aggregation, - self.config, - ) - per_example_additional_loss += answer_loss - # Zero loss for examples with answer_loss > cutoff. - per_example_additional_loss *= large_answer_loss_mask - else: - raise ValueError( - "You have to specify numeric values and numeric values scale in order to calculate the" - " regression loss" - ) - total_loss += tf.reduce_mean(per_example_additional_loss) - - else: - # if no label ids are provided, set them to zeros in order to properly compute logits - labels = tf.zeros_like(logits) - _, logits = _single_column_cell_selection_loss( - logits, column_logits, labels, cell_index, col_index, cell_mask - ) - if not return_dict: - output = (logits, logits_aggregation) + outputs[2:] - return ((total_loss,) + output) if calculate_loss else output - - return TFTableQuestionAnsweringOutput( - loss=total_loss if calculate_loss else None, - logits=logits, - logits_aggregation=logits_aggregation, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "tapas", None) is not None: - with tf.name_scope(self.tapas.name): - self.tapas.build(None) - if getattr(self, "compute_token_logits", None) is not None: - with tf.name_scope(self.compute_token_logits.name): - self.compute_token_logits.build(None) - if getattr(self, "compute_column_logits", None) is not None: - with tf.name_scope(self.compute_column_logits.name): - self.compute_column_logits.build(None) - if getattr(self, "aggregation_classifier", None) is not None: - with tf.name_scope(self.aggregation_classifier.name): - self.aggregation_classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - Tapas Model with a sequence classification head on top (a linear layer on top of the pooled output), e.g. for table - entailment tasks, such as TabFact (Chen et al., 2020). - """, - TAPAS_START_DOCSTRING, -) -class TFTapasForSequenceClassification(TFTapasPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: TapasConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.tapas = TFTapasMainLayer(config, name="tapas") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob, name="dropout") - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(TAPAS_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @replace_return_docstrings(output_type=TFSequenceClassifierOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). Note: this is called - "classification_class_index" in the original implementation. - - Returns: - - Examples: - - ```python - >>> from transformers import AutoTokenizer, TapasForSequenceClassification - >>> import tensorflow as tf - >>> import pandas as pd - - >>> tokenizer = AutoTokenizer.from_pretrained("google/tapas-base-finetuned-tabfact") - >>> model = TapasForSequenceClassification.from_pretrained("google/tapas-base-finetuned-tabfact") - - >>> data = { - ... "Actors": ["Brad Pitt", "Leonardo Di Caprio", "George Clooney"], - ... "Age": ["56", "45", "59"], - ... "Number of movies": ["87", "53", "69"], - ... } - >>> table = pd.DataFrame.from_dict(data) - >>> queries = [ - ... "There is only one actor who is 45 years old", - ... "There are 3 actors which played in more than 60 movies", - ... ] - - >>> inputs = tokenizer(table=table, queries=queries, padding="max_length", return_tensors="tf") - >>> labels = tf.convert_to_tensor([1, 0]) # 1 means entailed, 0 means refuted - - >>> outputs = model(**inputs, labels=labels) - >>> loss = outputs.loss - >>> logits = outputs.logits - ```""" - - outputs = self.tapas( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(inputs=pooled_output, training=training) - logits = self.classifier(inputs=pooled_output) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "tapas", None) is not None: - with tf.name_scope(self.tapas.name): - self.tapas.build(None) - if getattr(self, "dropout", None) is not None: - with tf.name_scope(self.dropout.name): - self.dropout.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -""" TAPAS utilities.""" - - -class AverageApproximationFunction(str, enum.Enum): - RATIO = "ratio" - FIRST_ORDER = "first_order" - SECOND_ORDER = "second_order" - - -# Beginning of everything related to segmented tensors - - -class IndexMap: - """Index grouping entries within a tensor.""" - - def __init__(self, indices, num_segments, batch_dims=0): - """ - Creates an index. - - Args: - indices: Tensor of indices, same shape as `values`. - num_segments: Scalar tensor, the number of segments. All elements - in a batched segmented tensor must have the same number of segments (although many segments can be empty). - batch_dims: Python integer, the number of batch dimensions. The first - `batch_dims` dimensions of a SegmentedTensor are treated as batch dimensions. Segments in different batch - elements are always distinct even if they have the same index. - """ - self.indices = tf.convert_to_tensor(indices) - self.num_segments = tf.convert_to_tensor(num_segments) - self.batch_dims = batch_dims - - def batch_shape(self): - return tf.shape(self.indices)[: self.batch_dims] - - -class ProductIndexMap(IndexMap): - """The product of two indices.""" - - def __init__(self, outer_index, inner_index): - """ - Combines indices i and j into pairs (i, j). The result is an index where each segment (i, j) is the - intersection of segments i and j. For example if the inputs represent table cells indexed by respectively rows - and columns the output will be a table indexed by (row, column) pairs, i.e. by cell. The implementation - combines indices {0, .., n - 1} and {0, .., m - 1} into {0, .., nm - 1}. The output has `num_segments` equal to - `outer_index.num_segements` * `inner_index.num_segments`. - - Args: - outer_index: IndexMap. - inner_index: IndexMap, must have the same shape as `outer_index`. - """ - if outer_index.batch_dims != inner_index.batch_dims: - raise ValueError("outer_index.batch_dims and inner_index.batch_dims must be the same.") - - super().__init__( - indices=( - inner_index.indices - + outer_index.indices * tf.cast(inner_index.num_segments, inner_index.indices.dtype) - ), - num_segments=inner_index.num_segments * outer_index.num_segments, - batch_dims=inner_index.batch_dims, - ) - self.outer_index = outer_index - self.inner_index = inner_index - - def project_outer(self, index): - """Projects an index with the same index set onto the outer components.""" - return IndexMap( - indices=tf.math.floordiv(index.indices, self.inner_index.num_segments), - num_segments=self.outer_index.num_segments, - batch_dims=index.batch_dims, - ) - - def project_inner(self, index): - """Projects an index with the same index set onto the inner components.""" - return IndexMap( - indices=tf.math.floormod(index.indices, self.inner_index.num_segments), - num_segments=self.inner_index.num_segments, - batch_dims=index.batch_dims, - ) - - -def gather(values, index, name="segmented_gather"): - """ - Gathers from `values` using the index map. For each element in the domain of the index map this operation looks up - a value for that index in `values`. Two elements from the same segment always get assigned the same value. - - Args: - values: [B1, ..., Bn, num_segments, V1, ...] Tensor with segment values. - index: [B1, ..., Bn, I1, ..., Ik] IndexMap. - name: Name for the TensorFlow operation. - - Returns: - [B1, ..., Bn, I1, ..., Ik, V1, ...] Tensor with the gathered values. - """ - return tf.gather(values, index.indices, batch_dims=index.batch_dims, name=name) - - -def flatten(index, name="segmented_flatten"): - """ - Flattens a batched index map to a 1d index map. This operation relabels the segments to keep batch elements - distinct. The k-th batch element will have indices shifted by `num_segments` * (k - 1). The result is a tensor with - `num_segments` multiplied by the number of elements in the batch. - - Args: - index: IndexMap to flatten. - name: Name for the TensorFlow operation. - - Returns: - The flattened IndexMap. - """ - batch_size = tf.reduce_prod(index.batch_shape()) - offset = tf.range(batch_size) * index.num_segments - offset = tf.reshape(offset, index.batch_shape()) - for _ in range(index.batch_dims, index.indices.shape.rank): - offset = tf.expand_dims(offset, -1) - - indices = tf.cast(offset, index.indices.dtype) + index.indices - return IndexMap(indices=tf.reshape(indices, [-1]), num_segments=index.num_segments * batch_size, batch_dims=0) - - -def range_index_map(batch_shape, num_segments, name="range_index_map"): - """ - Constructs an index map equal to range(num_segments). - - Args: - batch_shape (`tf.Tensor`): - Batch shape - num_segments (`int`): - Number of segments - name (`str`, *optional*, defaults to 'range_index_map'): - Name for the operation. Currently not used - - Returns: - (`IndexMap`): IndexMap of shape batch_shape with elements equal to range(num_segments). - """ - batch_shape = tf.convert_to_tensor(batch_shape) - batch_shape.shape.assert_has_rank(1) - num_segments = tf.convert_to_tensor(num_segments) - num_segments.shape.assert_has_rank(0) - - indices = tf.range(num_segments) - shape = tf.concat([tf.ones_like(batch_shape, dtype=tf.int32), tf.expand_dims(num_segments, axis=0)], axis=0) - indices = tf.reshape(indices, shape) - multiples = tf.concat([batch_shape, [1]], axis=0) - indices = tf.tile(indices, multiples) - return IndexMap(indices=indices, num_segments=num_segments, batch_dims=batch_shape.shape.as_list()[0]) - - -def _segment_reduce(values, index, segment_reduce_fn, name): - """ - Applies a segment reduction segment-wise. - - Args: - values (`tf.Tensor`): - Tensor with segment values. - index (`IndexMap`): - IndexMap. - segment_reduce_fn (`str`): - Name for the reduce operation. One of "sum", "mean", "max" or "min". - name (`str`): - Name for the operation. Currently not used - - Returns: - (`IndexMap`): IndexMap of shape batch_shape with elements equal to range(num_segments). - """ - # Flatten the batch dimensions, as segments ops do not support batching. - # However if `values` has extra dimensions to the right keep them - # unflattened. Segmented ops support vector-valued operations. - flat_index = flatten(index) - vector_shape = tf.shape(values)[index.indices.shape.rank :] - flattened_shape = tf.concat([[-1], vector_shape], axis=0) - flat_values = tf.reshape(values, flattened_shape) - segment_means = segment_reduce_fn( - data=flat_values, segment_ids=flat_index.indices, num_segments=flat_index.num_segments - ) - - # Unflatten the values. - new_shape = tf.concat([index.batch_shape(), [index.num_segments], vector_shape], axis=0) - output_values = tf.reshape(segment_means, new_shape) - output_index = range_index_map(index.batch_shape(), index.num_segments) - return output_values, output_index - - -def reduce_mean(values, index, name="segmented_reduce_mean"): - """ - Averages a tensor over its segments. Outputs 0 for empty segments. This operations computes the mean over segments, - with support for: - - - Batching using the first dimensions [B1, B2, ..., Bn]. Each element in a batch can have different indices. - - Vectorization using the last dimension [V1, V2, ...]. If they are present the output will be a mean of vectors - rather than scalars. - Only the middle dimensions [I1, ..., Ik] are reduced by the operation. - - Args: - values: [B1, B2, ..., Bn, I1, .., Ik, V1, V2, ..] tensor of values to be - averaged. - index: IndexMap [B1, B2, ..., Bn, I1, .., Ik] index defining the segments. - name: Name for the TensorFlow ops. - - Returns: - A pair (output_values, output_index) where `output_values` is a tensor of shape [B1, B2, ..., Bn, num_segments, - V1, V2, ..] and `index` is an IndexMap with shape [B1, B2, ..., Bn, num_segments]. - """ - return _segment_reduce(values, index, tf.math.unsorted_segment_mean, name) - - -def reduce_sum(values, index, name="segmented_reduce_sum"): - """ - Sums a tensor over its segments. Outputs 0 for empty segments. This operations computes the sum over segments, with - support for: - - - Batching using the first dimensions [B1, B2, ..., Bn]. Each element in a batch can have different indices. - - Vectorization using the last dimension [V1, V2, ...]. If they are present the output will be a sum of vectors - rather than scalars. - Only the middle dimensions [I1, ..., Ik] are reduced by the operation. - - Args: - values: [B1, B2, ..., Bn, I1, .., Ik, V1, V2, ..] tensor of values to be - averaged. - index: IndexMap [B1, B2, ..., Bn, I1, .., Ik] index defining the segments. - name: Name for the TensorFlow ops. - - Returns: - A pair (output_values, output_index) where `output_values` is a tensor of shape [B1, B2, ..., Bn, num_segments, - V1, V2, ..] and `index` is an IndexMap with shape [B1, B2, ..., Bn, num_segments]. - """ - return _segment_reduce(values, index, tf.math.unsorted_segment_sum, name) - - -def reduce_max(values, index, name="segmented_reduce_max"): - """ - Computes the maximum over segments. This operations computes the maximum over segments, with support for: - - - Batching using the first dimensions [B1, B2, ..., Bn]. Each element in a batch can have different indices. - - Vectorization using the last dimension [V1, V2, ...]. If they are present the output will be an element-wise - maximum of vectors rather than scalars. - Only the middle dimensions [I1, ..., Ik] are reduced by the operation. - - Args: - values: [B1, B2, ..., Bn, I1, .., Ik, V1, V2, ..] tensor of values to be - averaged. - index: IndexMap [B1, B2, ..., Bn, I1, .., Ik] index defining the segments. - name: Name for the TensorFlow ops. - - Returns: - A pair (output_values, output_index) where `output_values` is a tensor of shape [B1, B2, ..., Bn, num_segments, - V1, V2, ..] and `index` is an IndexMap with shape [B1, B2, ..., Bn, num_segments]. - """ - return _segment_reduce(values, index, tf.math.unsorted_segment_max, name) - - -def reduce_min(values, index, name="segmented_reduce_min"): - """Computes the minimum over segments.""" - return _segment_reduce(values, index, tf.math.unsorted_segment_min, name) - - -def _single_column_cell_selection_loss(token_logits, column_logits, labels, cell_index, col_index, cell_mask): - """ - Computes the loss for cell selection constrained to a single column. The loss is a hierarchical log-likelihood. The - model first predicts a column and then selects cells within that column (conditioned on the column). Cells outside - the selected column are never selected. - - Args: - token_logits (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Tensor containing the logits per token. - column_logits (`tf.Tensor` of shape `(batch_size, max_num_cols)`): - Tensor containing the logits per column. - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Labels per token. - cell_index (`ProductIndexMap`): - Index that groups tokens into cells. - col_index (`IndexMap`): - Index that groups tokens into columns. - cell_mask (`tf.Tensor` of shape `(batch_size, max_num_rows * max_num_cols)`): - Mask for cells that exist in the table (i.e. that are not padding). - - Returns: - selection_loss_per_example (`tf.Tensor` of shape `(batch_size,)`): Loss for each example. logits (`tf.Tensor` - of shape `(batch_size, sequence_length)`): New logits which are only allowed to select cells in a single - column. Logits outside of the most likely column according to *column_logits* will be set to a very low value - (such that the probabilities are 0). - """ - # First find the column we should select. We use the column with maximum - # number of selected cells. - labels_per_column, _ = reduce_sum(tf.cast(labels, tf.float32), col_index) - column_label = tf.argmax(labels_per_column, axis=-1, output_type=tf.int32) - # Check if there are no selected cells in the column. In that case the model - # should predict the special column id 0, which means "select nothing". - no_cell_selected = tf.equal(tf.reduce_max(labels_per_column, axis=-1), 0) - column_label = tf.where(no_cell_selected, tf.zeros_like(column_label), column_label) - - column_dist = tfp.distributions.Categorical(logits=column_logits) - column_loss_per_example = -column_dist.log_prob(column_label) - - # Reduce the labels and logits to per-cell from per-token. - logits_per_cell, _ = reduce_mean(token_logits, cell_index) - labels_per_cell, labels_index = reduce_max(tf.cast(labels, tf.int32), cell_index) - - # Mask for the selected column. - column_id_for_cells = cell_index.project_inner(labels_index).indices - column_mask = tf.cast(tf.equal(column_id_for_cells, tf.expand_dims(column_label, axis=1)), tf.float32) - - # Compute the log-likelihood for cells, but only for the selected column. - cell_dist = tfp.distributions.Bernoulli(logits=logits_per_cell) - cell_log_prob = cell_dist.log_prob(labels_per_cell) - cell_loss = -tf.reduce_sum(cell_log_prob * column_mask * cell_mask, axis=1) - # We need to normalize the loss by the number of cells in the column. - cell_loss /= tf.reduce_sum(column_mask * cell_mask, axis=1) + EPSILON_ZERO_DIVISION - - selection_loss_per_example = column_loss_per_example - selection_loss_per_example += tf.where(no_cell_selected, tf.zeros_like(selection_loss_per_example), cell_loss) - - # Set the probs outside the selected column (selected by the *model*) - # to 0. This ensures backwards compatibility with models that select - # cells from multiple columns. - selected_column_id = tf.argmax(column_logits, axis=-1, output_type=tf.int32) - selected_column_mask = tf.cast( - tf.equal(column_id_for_cells, tf.expand_dims(selected_column_id, axis=-1)), tf.float32 - ) - # Never select cells with the special column id 0. - selected_column_mask = tf.where( - tf.equal(column_id_for_cells, 0), tf.zeros_like(selected_column_mask), selected_column_mask - ) - logits_per_cell += CLOSE_ENOUGH_TO_LOG_ZERO * (1.0 - cell_mask * selected_column_mask) - logits = gather(logits_per_cell, cell_index) - - return selection_loss_per_example, logits - - -def _calculate_aggregate_mask(answer, pooled_output, cell_selection_preference, labels, aggregation_classifier): - """ - Finds examples where the model should select cells with no aggregation. - - Returns a mask that determines for which examples should the model select answers directly from the table, without - any aggregation function. If the answer is a piece of text the case is unambiguous as aggregation functions only - apply to numbers. If the answer is a number but does not appear in the table then we must use some aggregation - case. The ambiguous case is when the answer is a number that also appears in the table. In this case we use the - aggregation function probabilities predicted by the model to decide whether to select or aggregate. The threshold - for this is a hyperparameter *cell_selection_preference* - - Args: - answer (`tf.Tensor` of shape `(batch_size, )`): - Answer for every example in the batch. Nan if there is no scalar answer. - pooled_output (`tf.Tensor` of shape `(batch_size, hidden_size)`): - Output of the pooler (BertPooler) on top of the encoder layer. - cell_selection_preference (`float`): - Preference for cell selection in ambiguous cases. - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Labels per token. aggregation_classifier (`torch.nn.Linear`): Aggregation head - - Returns: - aggregate_mask (`tf.Tensor` of shape `(batch_size,)`): A mask set to 1 for examples that should use aggregation - functions. - """ - # tf.Tensor(batch_size,) - aggregate_mask_init = tf.cast(tf.logical_not(tf.math.is_nan(answer)), tf.float32) - logits_aggregation = aggregation_classifier(pooled_output) - dist_aggregation = tfp.distributions.Categorical(logits=logits_aggregation) - # Index 0 corresponds to "no aggregation". - aggregation_ops_total_mass = tf.reduce_sum(dist_aggregation.probs_parameter()[:, 1:], axis=1) - # Cell selection examples according to current model. - is_pred_cell_selection = aggregation_ops_total_mass <= cell_selection_preference - # Examples with non-empty cell selection supervision. - is_cell_supervision_available = tf.reduce_sum(labels, axis=1) > 0 - aggregate_mask = tf.where( - tf.logical_and(is_pred_cell_selection, is_cell_supervision_available), - tf.zeros_like(aggregate_mask_init, dtype=tf.float32), - aggregate_mask_init, - ) - aggregate_mask = tf.stop_gradient(aggregate_mask) - return aggregate_mask - - -def _calculate_aggregation_loss_known( - logits_aggregation, aggregate_mask, aggregation_labels, use_answer_as_supervision, num_aggregation_labels -): - """ - Calculates aggregation loss when its type is known during training. - - In the weakly supervised setting, the only known information is that for cell selection examples, "no aggregation" - should be predicted. For other examples (those that require aggregation), no loss is accumulated. In the setting - where aggregation type is always known, standard cross entropy loss is accumulated for all examples - - Args: - logits_aggregation (`tf.Tensor` of shape `(batch_size, num_aggregation_labels)`): - Logits per aggregation operation. - aggregate_mask (`tf.Tensor` of shape `(batch_size, )`): - A mask set to 1 for examples that should use aggregation functions. - aggregation_labels (`tf.Tensor` of shape `(batch_size, )`): - Aggregation function id for every example in the batch. - use_answer_as_supervision (`bool`, *optional*): - Whether to use the answer as the only supervision for aggregation examples. - num_aggregation_labels (`int`, *optional*, defaults to 0): - The number of aggregation operators to predict. - - Returns: - aggregation_loss_known (`tf.Tensor` of shape `(batch_size,)`): Aggregation loss (when its type is known during - training) per example. - """ - if use_answer_as_supervision: - # Prepare "no aggregation" targets for cell selection examples. - target_aggregation = tf.zeros_like(aggregate_mask, dtype=tf.int32) - else: - # Use aggregation supervision as the target. - target_aggregation = aggregation_labels - - one_hot_labels = tf.one_hot(target_aggregation, depth=num_aggregation_labels, dtype=tf.float32) - log_probs = tf.nn.log_softmax(logits_aggregation, axis=-1) - - # [batch_size] - per_example_aggregation_intermediate = -tf.reduce_sum(one_hot_labels * log_probs, axis=-1) - if use_answer_as_supervision: - # Accumulate loss only for examples requiring cell selection - # (no aggregation). - return per_example_aggregation_intermediate * (1 - aggregate_mask) - else: - return per_example_aggregation_intermediate - - -def _calculate_aggregation_loss_unknown(logits_aggregation, aggregate_mask): - """ - Calculates aggregation loss in the case of answer supervision. - - Args: - logits_aggregation (`tf.Tensor` of shape `(batch_size, num_aggregation_labels)`): - Logits per aggregation operation. - aggregate_mask (`tf.Tensor` of shape `(batch_size, )`): - A mask set to 1 for examples that should use aggregation functions - - Returns: - aggregation_loss_unknown (`tf.Tensor` of shape `(batch_size,)`): Aggregation loss (in case of answer - supervision) per example. - """ - dist_aggregation = tfp.distributions.Categorical(logits=logits_aggregation) - # Index 0 corresponds to "no aggregation". - aggregation_ops_total_mass = tf.reduce_sum(dist_aggregation.probs_parameter()[:, 1:], axis=1) - # Predict some aggregation in case of an answer that needs aggregation. - # This increases the probability of all aggregation functions, in a way - # similar to MML, but without considering whether the function gives the - # correct answer. - return -tf.math.log(aggregation_ops_total_mass) * aggregate_mask - - -def _calculate_aggregation_loss( - logits_aggregation, - aggregate_mask, - aggregation_labels, - use_answer_as_supervision, - num_aggregation_labels, - aggregation_loss_weight, -): - """ - Calculates the aggregation loss per example. - - Args: - logits_aggregation (`tf.Tensor` of shape `(batch_size, num_aggregation_labels)`): - Logits per aggregation operation. - aggregate_mask (`tf.Tensor` of shape `(batch_size, )`): - A mask set to 1 for examples that should use aggregation functions. - aggregation_labels (`tf.Tensor` of shape `(batch_size, )`): - Aggregation function id for every example in the batch. - use_answer_as_supervision (`bool`, *optional*): - Whether to use the answer as the only supervision for aggregation examples. - num_aggregation_labels (`int`, *optional*, defaults to 0): - The number of aggregation operators to predict. - aggregation_loss_weight (`float`, *optional*, defaults to 1.0): - Importance weight for the aggregation loss. - - Returns: - aggregation_loss (`tf.Tensor` of shape `(batch_size,)`): Aggregation loss per example. - """ - per_example_aggregation_loss = _calculate_aggregation_loss_known( - logits_aggregation, aggregate_mask, aggregation_labels, use_answer_as_supervision, num_aggregation_labels - ) - - if use_answer_as_supervision: - # Add aggregation loss for numeric answers that need aggregation. - per_example_aggregation_loss += _calculate_aggregation_loss_unknown(logits_aggregation, aggregate_mask) - return aggregation_loss_weight * per_example_aggregation_loss - - -def _calculate_expected_result( - dist_per_cell, numeric_values, numeric_values_scale, input_mask_float, logits_aggregation, config -): - """ - Calculates the expected result given cell and aggregation probabilities. - - Args: - dist_per_cell (`tfp.distributions.Bernoulli`): - Cell selection distribution for each cell. - numeric_values (`tf.Tensor` of shape `(batch_size, seq_length)`): - Numeric values of every token. Nan for tokens which are not numeric values. - numeric_values_scale (`tf.Tensor` of shape `(batch_size, seq_length)`): - Scale of the numeric values of every token. - input_mask_float (`tf.Tensor` of shape `(batch_size, seq_length)`): - Mask for the table, without question tokens and table headers. - logits_aggregation (`tf.Tensor` of shape `(batch_size, num_aggregation_labels)`): - Logits per aggregation operation. - config ([`TapasConfig`]): - Model configuration class with all the hyperparameters of the model - - Returns: - expected_result (`tf.Tensor` of shape `(batch_size,)`): The expected result per example. - """ - if config.use_gumbel_for_cells: - gumbel_dist = tfp.distributions.RelaxedBernoulli( - # The token logits where already divided by the temperature and used for - # computing cell selection errors so we need to multiply it again here - config.temperature, - logits=dist_per_cell.logits_parameter() * config.temperature, - ) - scaled_probability_per_cell = gumbel_dist.sample() - else: - scaled_probability_per_cell = dist_per_cell.probs_parameter() - - # [batch_size, seq_length] - scaled_probability_per_cell = (scaled_probability_per_cell / numeric_values_scale) * input_mask_float - count_result = tf.reduce_sum(scaled_probability_per_cell, axis=1) - numeric_values_masked = tf.where( - tf.math.is_nan(numeric_values), tf.zeros_like(numeric_values), numeric_values - ) # Mask non-numeric table values to zero. - sum_result = tf.reduce_sum(scaled_probability_per_cell * numeric_values_masked, axis=1) - avg_approximation = config.average_approximation_function - if avg_approximation == AverageApproximationFunction.RATIO: - average_result = sum_result / (count_result + EPSILON_ZERO_DIVISION) - elif avg_approximation == AverageApproximationFunction.FIRST_ORDER: - # The sum of all probabilities except that correspond to other cells - ex = tf.reduce_sum(scaled_probability_per_cell, axis=1, keepdims=True) - scaled_probability_per_cell + 1 - average_result = tf.reduce_sum(numeric_values_masked * scaled_probability_per_cell / ex, axis=1) - elif avg_approximation == AverageApproximationFunction.SECOND_ORDER: - # The sum of all probabilities except that correspond to other cells - ex = tf.reduce_sum(scaled_probability_per_cell, axis=1, keepdims=True) - scaled_probability_per_cell + 1 - pointwise_var = scaled_probability_per_cell * (1 - scaled_probability_per_cell) - var = tf.reduce_sum(pointwise_var, axis=1, keepdims=True) - pointwise_var - multiplier = (var / tf.math.square(ex) + 1) / ex - average_result = tf.reduce_sum(numeric_values_masked * scaled_probability_per_cell * multiplier, axis=1) - else: - raise ValueError("Invalid average_approximation_function: %s", config.average_approximation_function) - - if config.use_gumbel_for_aggregation: - gumbel_dist = tfp.distributions.RelaxedOneHotCategorical( - config.aggregation_temperature, logits=logits_aggregation[:, 1:] - ) - # [batch_size, num_aggregation_labels - 1] - aggregation_op_only_probs = gumbel_dist.sample() - else: - # [batch_size, num_aggregation_labels - 1] - aggregation_op_only_probs = stable_softmax(logits_aggregation[:, 1:] / config.aggregation_temperature, axis=-1) - all_results = tf.concat( - [ - tf.expand_dims(sum_result, axis=1), - tf.expand_dims(average_result, axis=1), - tf.expand_dims(count_result, axis=1), - ], - axis=1, - ) - expected_result = tf.reduce_sum(all_results * aggregation_op_only_probs, axis=1) - return expected_result - - -def _calculate_regression_loss( - answer, - aggregate_mask, - dist_per_cell, - numeric_values, - numeric_values_scale, - input_mask_float, - logits_aggregation, - config, -): - """ - Calculates the regression loss per example. - - Args: - answer (`tf.Tensor` of shape `(batch_size,)`): - Answer for every example in the batch. Nan if there is no scalar answer. - aggregate_mask (`tf.Tensor` of shape `(batch_size,)`): - A mask set to 1 for examples that should use aggregation functions. - dist_per_cell (`torch.distributions.Bernoulli`): - Cell selection distribution for each cell. - numeric_values (`tf.Tensor` of shape `(batch_size, seq_length)`): - Numeric values of every token. Nan for tokens which are not numeric values. - numeric_values_scale (`tf.Tensor` of shape `(batch_size, seq_length)`): - Scale of the numeric values of every token. - input_mask_float (`tf.Tensor` of shape `(batch_size, seq_length)`): - Mask for the table, without question tokens and table headers. - logits_aggregation (`tf.Tensor` of shape `(batch_size, num_aggregation_labels)`): - Logits per aggregation operation. - config ([`TapasConfig`]): - Model configuration class with all the parameters of the model - - Returns: - per_example_answer_loss_scaled (`tf.Tensor` of shape `(batch_size,)`): Scales answer loss for each example in - the batch. large_answer_loss_mask (`tf.Tensor` of shape `(batch_size,)`): A mask which is 1 for examples for - which their answer loss is larger than the answer_loss_cutoff. - """ - # float32 (batch_size,) - expected_result = _calculate_expected_result( - dist_per_cell, numeric_values, numeric_values_scale, input_mask_float, logits_aggregation, config - ) - - # [batch_size] - answer_masked = tf.where(tf.math.is_nan(answer), tf.zeros_like(answer), answer) - - if config.use_normalized_answer_loss: - normalizer = tf.stop_gradient( - tf.math.maximum(tf.math.abs(expected_result), tf.math.abs(answer_masked)) + EPSILON_ZERO_DIVISION - ) - normalized_answer_masked = answer_masked / normalizer - normalized_expected_result = expected_result / normalizer - per_example_answer_loss = tf.compat.v1.losses.huber_loss( - normalized_answer_masked * aggregate_mask, - normalized_expected_result * aggregate_mask, - delta=tf.cast(1.0, tf.float32), - reduction=tf.losses.Reduction.NONE, - ) - else: - per_example_answer_loss = tf.compat.v1.losses.huber_loss( - answer_masked * aggregate_mask, - expected_result * aggregate_mask, - delta=tf.cast(config.huber_loss_delta, tf.float32), - reduction=tf.losses.Reduction.NONE, - ) - if config.answer_loss_cutoff is None: - large_answer_loss_mask = tf.ones_like(per_example_answer_loss, dtype=tf.float32) - else: - large_answer_loss_mask = tf.where( - per_example_answer_loss > config.answer_loss_cutoff, - tf.zeros_like(per_example_answer_loss, dtype=tf.float32), - tf.ones_like(per_example_answer_loss, dtype=tf.float32), - ) - per_example_answer_loss_scaled = config.answer_loss_importance * (per_example_answer_loss * aggregate_mask) - return per_example_answer_loss_scaled, large_answer_loss_mask - - -__all__ = [ - "TFTapasForMaskedLM", - "TFTapasForQuestionAnswering", - "TFTapasForSequenceClassification", - "TFTapasModel", - "TFTapasPreTrainedModel", -] diff --git a/src/transformers/models/tapas/tokenization_tapas.py b/src/transformers/models/tapas/tokenization_tapas.py index 4d91a1add944..7277f562a118 100644 --- a/src/transformers/models/tapas/tokenization_tapas.py +++ b/src/transformers/models/tapas/tokenization_tapas.py @@ -142,7 +142,6 @@ def whitespace_tokenize(text): return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. """ @@ -1897,9 +1896,9 @@ def convert_logits_to_predictions(self, data, logits, logits_agg=None, cell_clas Args: data (`dict`): Dictionary mapping features to actual values. Should be created using [`TapasTokenizer`]. - logits (`torch.Tensor` or `tf.Tensor` of shape `(batch_size, sequence_length)`): + logits (`torch.Tensor` of shape `(batch_size, sequence_length)`): Tensor containing the logits at the token level. - logits_agg (`torch.Tensor` or `tf.Tensor` of shape `(batch_size, num_aggregation_labels)`, *optional*): + logits_agg (`torch.Tensor` of shape `(batch_size, num_aggregation_labels)`, *optional*): Tensor containing the aggregation logits. cell_classification_threshold (`float`, *optional*, defaults to 0.5): Threshold to be used for cell selection. All table cells for which their probability is larger than @@ -1914,7 +1913,6 @@ def convert_logits_to_predictions(self, data, logits, logits_agg=None, cell_clas - predicted_aggregation_indices (`list[int]`of length `batch_size`, *optional*, returned when `logits_aggregation` is provided): Predicted aggregation operator indices of the aggregation head. """ - # converting to numpy arrays to work with PT/TF logits = logits.numpy() if logits_agg is not None: logits_agg = logits_agg.numpy() @@ -2207,7 +2205,7 @@ def tokenize(self, text): return output_tokens -# Below: utilities for TAPAS tokenizer (independent from PyTorch/Tensorflow). +# Below: utilities for TAPAS tokenizer # This includes functions to parse numeric values (dates and numbers) from both the table and questions in order # to create the column_ranks, inv_column_ranks, numeric_values, numeric values_scale and numeric_relations in # prepare_for_model of TapasTokenizer. diff --git a/src/transformers/models/textnet/image_processing_textnet.py b/src/transformers/models/textnet/image_processing_textnet.py index 153e29785289..578dabd3cb71 100644 --- a/src/transformers/models/textnet/image_processing_textnet.py +++ b/src/transformers/models/textnet/image_processing_textnet.py @@ -257,10 +257,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -293,10 +291,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/timesformer/modeling_timesformer.py b/src/transformers/models/timesformer/modeling_timesformer.py index 0aa06d5c33bb..1c125dac4f32 100644 --- a/src/transformers/models/timesformer/modeling_timesformer.py +++ b/src/transformers/models/timesformer/modeling_timesformer.py @@ -151,11 +151,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/tvp/image_processing_tvp.py b/src/transformers/models/tvp/image_processing_tvp.py index d3f698873d55..12356c082a03 100644 --- a/src/transformers/models/tvp/image_processing_tvp.py +++ b/src/transformers/models/tvp/image_processing_tvp.py @@ -399,10 +399,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -437,10 +435,7 @@ def preprocess( crop_size = get_size_dict(crop_size, param_name="crop_size") if not valid_images(videos): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") videos = make_batched(videos) diff --git a/src/transformers/models/tvp/modeling_tvp.py b/src/transformers/models/tvp/modeling_tvp.py index 0b8b626d2dd2..dcbd220331f9 100644 --- a/src/transformers/models/tvp/modeling_tvp.py +++ b/src/transformers/models/tvp/modeling_tvp.py @@ -557,8 +557,6 @@ class TvpPreTrainedModel(PreTrainedModel): def _init_weights(self, module: nn.Module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Embedding)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) elif isinstance(module, nn.LayerNorm): module.bias.data.zero_() diff --git a/src/transformers/models/udop/modeling_udop.py b/src/transformers/models/udop/modeling_udop.py index 668ec6bfec3b..22f45731030e 100644 --- a/src/transformers/models/udop/modeling_udop.py +++ b/src/transformers/models/udop/modeling_udop.py @@ -280,16 +280,11 @@ def _init_weights(self, module): d_model = self.config.d_model module.relative_attention_bias.weight.data.normal_(mean=0.0, std=factor * ((d_model) ** -0.5)) elif isinstance(module, UdopModel): - # Mesh TensorFlow embeddings initialization - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L1624 module.shared.weight.data.normal_(mean=0.0, std=factor * 1.0) elif isinstance(module, UdopForConditionalGeneration): if hasattr(module, "lm_head") and not self.config.tie_word_embeddings: module.lm_head.weight.data.normal_(mean=0.0, std=factor * 1.0) elif isinstance(module, UdopDenseActDense): - # Mesh TensorFlow FF initialization - # See https://github.com/tensorflow/mesh/blob/master/mesh_tensorflow/transformer/transformer_layers.py#L56 - # and https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L89 module.wi.weight.data.normal_(mean=0.0, std=factor * ((self.config.d_model) ** -0.5)) if hasattr(module.wi, "bias") and module.wi.bias is not None: module.wi.bias.data.zero_() @@ -307,8 +302,6 @@ def _init_weights(self, module): if hasattr(module.wo, "bias") and module.wo.bias is not None: module.wo.bias.data.zero_() elif isinstance(module, UdopAttention): - # Mesh TensorFlow attention initialization to avoid scaling before softmax - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/attention.py#L136 d_model = self.config.d_model key_value_proj_dim = self.config.d_kv n_heads = self.config.num_heads @@ -467,7 +460,6 @@ def __init__( "when creating this class." ) - # Mesh TensorFlow initialization to avoid scaling before softmax self.q = nn.Linear(self.d_model, self.inner_dim, bias=False) self.k = nn.Linear(self.d_model, self.inner_dim, bias=False) self.v = nn.Linear(self.d_model, self.inner_dim, bias=False) @@ -1852,8 +1844,6 @@ def forward( sequence_output = decoder_outputs[0] if self.config.tie_word_embeddings: - # Rescale output before projecting on vocab - # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586 sequence_output = sequence_output * (self.config.d_model**-0.5) lm_logits = self.lm_head(sequence_output) diff --git a/src/transformers/models/udop/tokenization_udop.py b/src/transformers/models/udop/tokenization_udop.py index 29b4b3ee24e4..a5833333e10a 100644 --- a/src/transformers/models/udop/tokenization_udop.py +++ b/src/transformers/models/udop/tokenization_udop.py @@ -86,7 +86,6 @@ return_tensors (`str` or [`~file_utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. return_token_type_ids (`bool`, *optional*): diff --git a/src/transformers/models/udop/tokenization_udop_fast.py b/src/transformers/models/udop/tokenization_udop_fast.py index a8878b9b514c..9751f5d65ddf 100644 --- a/src/transformers/models/udop/tokenization_udop_fast.py +++ b/src/transformers/models/udop/tokenization_udop_fast.py @@ -85,7 +85,6 @@ return_tensors (`str` or [`~file_utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. return_token_type_ids (`bool`, *optional*): diff --git a/src/transformers/models/umt5/modeling_umt5.py b/src/transformers/models/umt5/modeling_umt5.py index a8c592b727c6..6d7437b5a6e5 100644 --- a/src/transformers/models/umt5/modeling_umt5.py +++ b/src/transformers/models/umt5/modeling_umt5.py @@ -180,7 +180,6 @@ def __init__(self, config, has_relative_attention_bias=False, layer_idx: Optiona "when creating this class." ) - # Mesh TensorFlow initialization to avoid scaling before softmax self.q = nn.Linear(self.d_model, self.inner_dim, bias=False) self.k = nn.Linear(self.d_model, self.inner_dim, bias=False) self.v = nn.Linear(self.d_model, self.inner_dim, bias=False) diff --git a/src/transformers/models/univnet/feature_extraction_univnet.py b/src/transformers/models/univnet/feature_extraction_univnet.py index 059226afe1d1..6ff2b73df7a6 100644 --- a/src/transformers/models/univnet/feature_extraction_univnet.py +++ b/src/transformers/models/univnet/feature_extraction_univnet.py @@ -355,7 +355,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.np.array` objects. - `'np'`: Return Numpy `np.ndarray` objects. """ diff --git a/src/transformers/models/video_llava/image_processing_video_llava.py b/src/transformers/models/video_llava/image_processing_video_llava.py index 1ed8f911af8e..d02ceff80c1e 100644 --- a/src/transformers/models/video_llava/image_processing_video_llava.py +++ b/src/transformers/models/video_llava/image_processing_video_llava.py @@ -226,10 +226,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -261,10 +259,7 @@ def preprocess( images = make_flat_list_of_images(images) if images is not None and not valid_images(images): - raise ValueError( - "Invalid input type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid input type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") data = {} if videos is not None: diff --git a/src/transformers/models/video_llava/processing_video_llava.py b/src/transformers/models/video_llava/processing_video_llava.py index fc7a396853a8..a6f826fa72a3 100644 --- a/src/transformers/models/video_llava/processing_video_llava.py +++ b/src/transformers/models/video_llava/processing_video_llava.py @@ -133,10 +133,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/videomae/image_processing_videomae.py b/src/transformers/models/videomae/image_processing_videomae.py index 96545dc75311..b1e3ffd4de91 100644 --- a/src/transformers/models/videomae/image_processing_videomae.py +++ b/src/transformers/models/videomae/image_processing_videomae.py @@ -283,10 +283,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -314,10 +312,7 @@ def preprocess( crop_size = get_size_dict(crop_size, param_name="crop_size") if not valid_images(videos): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") videos = make_batched(videos) diff --git a/src/transformers/models/videomae/modeling_videomae.py b/src/transformers/models/videomae/modeling_videomae.py index 97c227f1d8bf..d249e65c5a45 100755 --- a/src/transformers/models/videomae/modeling_videomae.py +++ b/src/transformers/models/videomae/modeling_videomae.py @@ -414,8 +414,6 @@ class VideoMAEPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv3d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/vilt/image_processing_vilt.py b/src/transformers/models/vilt/image_processing_vilt.py index 87abf7f7a7d6..c7013e660332 100644 --- a/src/transformers/models/vilt/image_processing_vilt.py +++ b/src/transformers/models/vilt/image_processing_vilt.py @@ -305,10 +305,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -389,10 +387,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -420,10 +416,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # Here the pad() method does not require any additional argument as it takes the maximum of (height, width). # Hence, it does not need to be passed to a validate_preprocess_arguments() method. diff --git a/src/transformers/models/vilt/modeling_vilt.py b/src/transformers/models/vilt/modeling_vilt.py index 75e58f9858fd..8535b3c747e2 100755 --- a/src/transformers/models/vilt/modeling_vilt.py +++ b/src/transformers/models/vilt/modeling_vilt.py @@ -229,8 +229,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -548,8 +546,6 @@ class ViltPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/vision_encoder_decoder/__init__.py b/src/transformers/models/vision_encoder_decoder/__init__.py index 613aae114b33..c2afd574c8df 100644 --- a/src/transformers/models/vision_encoder_decoder/__init__.py +++ b/src/transformers/models/vision_encoder_decoder/__init__.py @@ -19,8 +19,6 @@ if TYPE_CHECKING: from .configuration_vision_encoder_decoder import * - from .modeling_flax_vision_encoder_decoder import * - from .modeling_tf_vision_encoder_decoder import * from .modeling_vision_encoder_decoder import * else: import sys diff --git a/src/transformers/models/vision_encoder_decoder/configuration_vision_encoder_decoder.py b/src/transformers/models/vision_encoder_decoder/configuration_vision_encoder_decoder.py index 248bf73ff9fa..a069a888f02f 100644 --- a/src/transformers/models/vision_encoder_decoder/configuration_vision_encoder_decoder.py +++ b/src/transformers/models/vision_encoder_decoder/configuration_vision_encoder_decoder.py @@ -16,7 +16,7 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any from packaging import version @@ -27,7 +27,7 @@ if TYPE_CHECKING: - from ... import PreTrainedTokenizerBase, TensorType + from ... import PreTrainedTokenizerBase logger = logging.get_logger(__name__) @@ -154,14 +154,16 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional["TensorType"] = None, ) -> Mapping[str, Any]: import torch common_inputs = OrderedDict() dummy_input = super().generate_dummy_inputs( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, + batch_size=batch_size, + seq_length=seq_length, + is_pair=is_pair, ) batch, encoder_sequence = dummy_input["input_ids"].shape diff --git a/src/transformers/models/vision_encoder_decoder/modeling_flax_vision_encoder_decoder.py b/src/transformers/models/vision_encoder_decoder/modeling_flax_vision_encoder_decoder.py deleted file mode 100644 index a59c799cc04a..000000000000 --- a/src/transformers/models/vision_encoder_decoder/modeling_flax_vision_encoder_decoder.py +++ /dev/null @@ -1,864 +0,0 @@ -# coding=utf-8 -# Copyright 2021 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. -"""Classes to support Vision-Encoder-Text-Decoder architectures""" - -import os -from typing import Optional, Union - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxCausalLMOutputWithCrossAttentions, FlaxSeq2SeqLMOutput -from ...modeling_flax_utils import FlaxPreTrainedModel -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from ..auto.configuration_auto import AutoConfig -from ..auto.modeling_flax_auto import FlaxAutoModel, FlaxAutoModelForCausalLM -from .configuration_vision_encoder_decoder import VisionEncoderDecoderConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "VisionEncoderDecoderConfig" - -VISION_ENCODER_DECODER_START_DOCSTRING = r""" - This class can be used to initialize an image-to-text-sequence model with any pretrained vision autoencoding model - as the encoder and any pretrained text autoregressive model as the decoder. The encoder is loaded via - [`~AutoModel.from_pretrained`] function and the decoder is loaded via [`~AutoModelForCausalLM.from_pretrained`] - function. Cross-attention layers are automatically added to the decoder and should be fine-tuned on a downstream - generative task, like image captioning. - - The effectiveness of initializing sequence-to-sequence models with pretrained checkpoints for sequence generation - tasks was shown in [Leveraging Pre-trained Checkpoints for Sequence Generation - Tasks](https://huggingface.co/papers/1907.12461) by Sascha Rothe, Shashi Narayan, Aliaksei Severyn. Michael Matena, Yanqi - Zhou, Wei Li, Peter J. Liu. - - Additionally, in [TrOCR: Transformer-based Optical Character Recognition with Pre-trained - Models](https://huggingface.co/papers/2109.10282) it is shown how leveraging large pretrained vision models for optical - character recognition (OCR) yields a significant performance improvement. - - After such a Vision-Encoder-Text-Decoder model has been trained/fine-tuned, it can be saved/loaded just like any - other models (see the examples for more information). - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Parameters: - config ([`VisionEncoderDecoderConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -VISION_ENCODER_DECODER_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`jnp.ndarray` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using the vision model's image processor. For example, using - [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] for details. - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - decoder_position_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.decoder.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.FlaxSeq2SeqLMOutput`] instead of a plain tuple. -""" - -VISION_ENCODER_DECODER_ENCODE_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`jnp.ndarray` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using the vision model's image processor. For example, using - [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] for details. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.FlaxBaseModelOutput`] instead of a plain tuple. -""" - -VISION_ENCODER_DECODER_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - For sequence to sequence training, `decoder_input_ids` should be provided. If no `decoder_input_ids` is - provided, the model will create this tensor by shifting the `input_ids` to the right for denoising - pre-training. - encoder_outputs (`tuple(tuple(jnp.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - decoder_position_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.decoder.max_position_embeddings - 1]`. - past_key_values (`dict[str, jnp.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.FlaxCausalLMOutputWithCrossAttentions`] instead of a - plain tuple. -""" - - -class FlaxVisionEncoderDecoderModule(nn.Module): - config: VisionEncoderDecoderConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - encoder_config = self.config.encoder - decoder_config = self.config.decoder - - # Copied from `modeling_hybrid_clip.py` with modifications. - from ...models.auto.modeling_flax_auto import FLAX_MODEL_FOR_CAUSAL_LM_MAPPING, FLAX_MODEL_MAPPING - - encoder_module = FLAX_MODEL_MAPPING[encoder_config.__class__].module_class - decoder_module = FLAX_MODEL_FOR_CAUSAL_LM_MAPPING[decoder_config.__class__].module_class - - self.encoder = encoder_module(encoder_config, dtype=self.dtype) - self.decoder = decoder_module(decoder_config, dtype=self.dtype) - - # encoder outputs might need to be projected to different dimension for decoder - if ( - self.encoder.config.hidden_size != self.decoder.config.hidden_size - and self.decoder.config.cross_attention_hidden_size is None - ): - self.enc_to_dec_proj = nn.Dense( - self.decoder.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.decoder.config.initializer_range), - dtype=self.dtype, - ) - else: - self.enc_to_dec_proj = None - - def _get_encoder_module(self): - return self.encoder - - def _get_projection_module(self): - return self.enc_to_dec_proj - - def _get_decoder_module(self): - return self.decoder - - def __call__( - self, - pixel_values, - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - encoder_outputs = self.encoder( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - encoder_hidden_states = encoder_outputs[0] - - # optionally project encoder_hidden_states - if self.enc_to_dec_proj is not None: - encoder_hidden_states = self.enc_to_dec_proj(encoder_hidden_states) - - # The advantage of explicitly setting this is TPU XLA compiler knows as soon as possible what shape this - # variable has and can better optimize. Also passing `None` can lead to some problems when jitting the model. - # In Flax/JAX, we only want to pass `None` for non-tensor function inputs. For all tensor function inputs, we - # should always pass a tensor and not `None`. - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqLMOutput( - logits=decoder_outputs.logits, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - -@add_start_docstrings(VISION_ENCODER_DECODER_START_DOCSTRING) -class FlaxVisionEncoderDecoderModel(FlaxPreTrainedModel): - r""" - [`FlaxVisionEncoderDecoderModel`] is a generic model class that will be instantiated as a transformer architecture - with the module (flax.nn.Module) of one of the base vision model classes of the library as encoder module and - another one as decoder module when created with the :meth*~transformers.FlaxAutoModel.from_pretrained* class method - for the encoder and :meth*~transformers.FlaxAutoModelForCausalLM.from_pretrained* class method for the decoder. - """ - - config_class = VisionEncoderDecoderConfig - base_model_prefix = "vision_encoder_decoder" - main_input_name = "pixel_values" - module_class = FlaxVisionEncoderDecoderModule - - def __init__( - self, - config: VisionEncoderDecoderConfig, - input_shape: Optional[tuple] = None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - if not _do_init: - raise ValueError( - "`FlaxVisionEncoderDecoderModel` cannot be created without initializing, `_do_init` must be `True`." - ) - - if input_shape is None: - num_channels = getattr(config.encoder, "num_channels", 3) - input_shape = ( - (1, config.encoder.image_size, config.encoder.image_size, num_channels), - (1, 1), - ) - - if config.decoder.cross_attention_hidden_size is not None: - if config.decoder.cross_attention_hidden_size != config.encoder.hidden_size: - raise ValueError( - "If `cross_attention_hidden_size` is specified in the decoder's configuration, it has to be equal" - f" to the encoder's `hidden_size`. Got {config.decoder.cross_attention_hidden_size} for" - f" `config.decoder.cross_attention_hidden_size` and {config.encoder.hidden_size} for" - " `config.encoder.hidden_size`." - ) - - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - encoder_input_shape, decoder_input_shape = input_shape - - # init input tensors - pixel_values = jnp.zeros(encoder_input_shape, dtype=self.dtype) - decoder_input_ids = jnp.zeros(decoder_input_shape, dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - - batch_size, _, _, _ = pixel_values.shape - decoder_batch_size, decoder_sequence_length = decoder_input_ids.shape - if not decoder_batch_size == batch_size: - raise ValueError( - f"The inputs of encoder and decoder should have the same batch size, but got {batch_size} for encoder " - f"and {decoder_batch_size} for decoder." - ) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(decoder_sequence_length)[None, :], (decoder_batch_size, decoder_sequence_length) - ) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - pixel_values, - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape - ) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(VISION_ENCODER_DECODER_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=_CONFIG_FOR_DOC) - def encode( - self, - pixel_values: jnp.ndarray, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoImageProcessor, FlaxVisionEncoderDecoderModel - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k") - - >>> # initialize a vit-gpt2 from pretrained ViT and GPT2 models. Note that the cross-attention layers will be randomly initialized - >>> model = FlaxVisionEncoderDecoderModel.from_encoder_decoder_pretrained( - ... "google/vit-base-patch16-224-in21k", "openai-community/gpt2" - ... ) - - >>> pixel_values = image_processor(images=image, return_tensors="np").pixel_values - >>> encoder_outputs = model.encode(pixel_values) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # `FlaxViTModel` expects channel first format, but `FlaxViTModule` expects channel last format. - # Currently, we assume this holds for all Flax vision models, and perform a transpose here. - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, pixel_values, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(pixel_values, **kwargs) - - outputs = self.module.apply( - {"params": params or self.params}, - pixel_values=jnp.array(pixel_values, dtype=self.dtype), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - if return_dict: - outputs = FlaxBaseModelOutput( - last_hidden_state=outputs.last_hidden_state, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - return outputs - - @add_start_docstrings(VISION_ENCODER_DECODER_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=_CONFIG_FOR_DOC) - def decode( - self, - decoder_input_ids, - encoder_outputs, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import AutoImageProcessor, FlaxVisionEncoderDecoderModel - >>> import jax.numpy as jnp - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k") - - >>> # initialize a vit-gpt2 from pretrained ViT and GPT2 models. Note that the cross-attention layers will be randomly initialized - >>> model = FlaxVisionEncoderDecoderModel.from_encoder_decoder_pretrained( - ... "google/vit-base-patch16-224-in21k", "openai-community/gpt2" - ... ) - - >>> pixel_values = image_processor(images=image, return_tensors="np").pixel_values - >>> encoder_outputs = model.encode(pixel_values) - - >>> decoder_start_token_id = model.config.decoder.bos_token_id - >>> decoder_input_ids = jnp.ones((pixel_values.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> logits = outputs.logits - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxBartAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward( - module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, encoder_hidden_states, **kwargs - ): - projection_module = module._get_projection_module() - decoder_module = module._get_decoder_module() - - # optionally project encoder_hidden_states - if projection_module is not None: - encoder_hidden_states = projection_module(encoder_hidden_states) - - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - encoder_hidden_states, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - @add_start_docstrings_to_model_forward(VISION_ENCODER_DECODER_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - def __call__( - self, - pixel_values: jnp.ndarray, - decoder_input_ids: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Examples: - - ```python - >>> from transformers import FlaxVisionEncoderDecoderModel, AutoImageProcessor, AutoTokenizer - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k") - - >>> # load output tokenizer - >>> tokenizer_output = AutoTokenizer.from_pretrained("openai-community/gpt2") - - >>> # initialize a vit-gpt2 from pretrained ViT and GPT2 models. Note that the cross-attention layers will be randomly initialized - >>> model = FlaxVisionEncoderDecoderModel.from_encoder_decoder_pretrained( - ... "google/vit-base-patch16-224-in21k", "openai-community/gpt2" - ... ) - - >>> pixel_values = image_processor(images=image, return_tensors="np").pixel_values - - >>> # use GPT2's eos_token as the pad as well as eos token - >>> model.config.eos_token_id = model.config.decoder.eos_token_id - >>> model.config.pad_token_id = model.config.eos_token_id - - >>> # generation - >>> sequences = model.generate(pixel_values, num_beams=4, max_length=12).sequences - - >>> captions = tokenizer_output.batch_decode(sequences, skip_special_tokens=True) - ```""" - - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare encoder inputs - - # `FlaxViTModel` expects channel first format, but `FlaxViTModule` expects channel last format. - # Currently, we assume this holds for all Flax vision models, and perform a transpose here. - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - - # prepare decoder inputs - if decoder_input_ids is None: - raise ValueError("`decoder_input_ids` can't be `None`.") - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - if decoder_position_ids is None: - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - pixel_values=jnp.array(pixel_values, dtype=self.dtype), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - decoder_position_ids = decoder_attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) - else: - decoder_position_ids = jnp.broadcast_to( - jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length) - ) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "decoder_attention_mask": extended_attention_mask, - "decoder_position_ids": decoder_position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 - return model_kwargs - - @classmethod - def from_encoder_decoder_pretrained( - cls, - encoder_pretrained_model_name_or_path: Optional[Union[str, os.PathLike]] = None, - decoder_pretrained_model_name_or_path: Optional[Union[str, os.PathLike]] = None, - *model_args, - **kwargs, - ) -> FlaxPreTrainedModel: - r""" - Instantiate an encoder and a decoder from one or two base classes of the library from pretrained model - checkpoints. - - Params: - encoder_pretrained_model_name_or_path (`Union[str, os.PathLike]`, *optional*): - Information necessary to initiate the encoder. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. An - example is `google/vit-base-patch16-224-in21k`. - - A path to a *directory* containing model weights saved using - [`~FlaxPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - decoder_pretrained_model_name_or_path (`Union[str, os.PathLike]`, *optional*, defaults to `None`): - Information necessary to initiate the decoder. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~FlaxPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - model_args (remaining positional arguments, *optional*): - All remaining positional arguments will be passed to the underlying model's `__init__` method. - - kwargs (remaining dictionary of keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). - - - To update the encoder configuration, use the prefix *encoder_* for each configuration parameter. - - To update the decoder configuration, use the prefix *decoder_* for each configuration parameter. - - To update the parent model configuration, do not use a prefix for each configuration parameter. - - Behaves differently depending on whether a `config` is provided or automatically loaded. - - Example: - - ```python - >>> from transformers import FlaxVisionEncoderDecoderModel - - >>> # initialize a vit-gpt2 from a pretrained ViT and a pretrained GPT2 model. Note that the cross-attention layers will be randomly initialized - >>> model = FlaxVisionEncoderDecoderModel.from_encoder_decoder_pretrained( - ... "google/vit-base-patch16-224-in21k", "openai-community/gpt2" - ... ) - >>> # saving model after fine-tuning - >>> model.save_pretrained("./vit-gpt2") - >>> # load fine-tuned model - >>> model = FlaxVisionEncoderDecoderModel.from_pretrained("./vit-gpt2") - ```""" - - kwargs_encoder = { - argument[len("encoder_") :]: value for argument, value in kwargs.items() if argument.startswith("encoder_") - } - - kwargs_decoder = { - argument[len("decoder_") :]: value for argument, value in kwargs.items() if argument.startswith("decoder_") - } - - # remove encoder, decoder kwargs from kwargs - for key in kwargs_encoder: - del kwargs["encoder_" + key] - for key in kwargs_decoder: - del kwargs["decoder_" + key] - - # Load and initialize the encoder and decoder - # The distinction between encoder and decoder at the model level is made - # by the value of the flag `is_decoder` that we need to set correctly. - encoder = kwargs_encoder.pop("model", None) - if encoder is None: - if encoder_pretrained_model_name_or_path is None: - raise ValueError( - "If `encoder_model` is not defined as an argument, a `encoder_pretrained_model_name_or_path` has " - "to be defined." - ) - - if "config" not in kwargs_encoder: - encoder_config = AutoConfig.from_pretrained(encoder_pretrained_model_name_or_path) - if encoder_config.is_decoder is True or encoder_config.add_cross_attention is True: - logger.info( - f"Initializing {encoder_pretrained_model_name_or_path} as a encoder model " - "from a decoder model. Cross-attention and causal mask are disabled." - ) - encoder_config.is_decoder = False - encoder_config.add_cross_attention = False - - kwargs_encoder["config"] = encoder_config - - encoder = FlaxAutoModel.from_pretrained( - encoder_pretrained_model_name_or_path, *model_args, **kwargs_encoder - ) - - decoder = kwargs_decoder.pop("model", None) - if decoder is None: - if decoder_pretrained_model_name_or_path is None: - raise ValueError( - "If `decoder_model` is not defined as an argument, a `decoder_pretrained_model_name_or_path` has " - "to be defined." - ) - - if "config" not in kwargs_decoder: - decoder_config = AutoConfig.from_pretrained(decoder_pretrained_model_name_or_path) - if decoder_config.is_decoder is False or decoder_config.add_cross_attention is False: - logger.info( - f"Initializing {decoder_pretrained_model_name_or_path} as a decoder model. Cross attention" - f" layers are added to {decoder_pretrained_model_name_or_path} and randomly initialized if" - f" {decoder_pretrained_model_name_or_path}'s architecture allows for cross attention layers." - ) - decoder_config.is_decoder = True - decoder_config.add_cross_attention = True - - kwargs_decoder["config"] = decoder_config - - if kwargs_decoder["config"].is_decoder is False or kwargs_decoder["config"].add_cross_attention is False: - logger.warning( - f"Decoder model {decoder_pretrained_model_name_or_path} is not initialized as a decoder. " - f"In order to initialize {decoder_pretrained_model_name_or_path} as a decoder, " - "make sure that the attributes `is_decoder` and `add_cross_attention` of `decoder_config` " - "passed to `.from_encoder_decoder_pretrained(...)` are set to `True` or do not pass a " - "`decoder_config` to `.from_encoder_decoder_pretrained(...)`" - ) - - decoder = FlaxAutoModelForCausalLM.from_pretrained(decoder_pretrained_model_name_or_path, **kwargs_decoder) - - # instantiate config with corresponding kwargs - dtype = kwargs.pop("dtype", jnp.float32) - config = VisionEncoderDecoderConfig.from_encoder_decoder_configs(encoder.config, decoder.config, **kwargs) - - # init model - model = cls(config, dtype=dtype) - model.params["encoder"] = encoder.params - model.params["decoder"] = decoder.params - - return model - - -__all__ = ["FlaxVisionEncoderDecoderModel"] diff --git a/src/transformers/models/vision_encoder_decoder/modeling_tf_vision_encoder_decoder.py b/src/transformers/models/vision_encoder_decoder/modeling_tf_vision_encoder_decoder.py deleted file mode 100644 index ef2ea2109987..000000000000 --- a/src/transformers/models/vision_encoder_decoder/modeling_tf_vision_encoder_decoder.py +++ /dev/null @@ -1,696 +0,0 @@ -# coding=utf-8 -# Copyright 2022 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. -"""Classes to support TF Vision-Encoder-Text-Decoder architectures""" - -from __future__ import annotations - -import re -import warnings - -import numpy as np -import tensorflow as tf - -from ...configuration_utils import PretrainedConfig -from ...modeling_tf_outputs import TFBaseModelOutput, TFSeq2SeqLMOutput -from ...modeling_tf_utils import TFCausalLanguageModelingLoss, TFPreTrainedModel, get_initializer, keras, unpack_inputs -from ...tf_utils import shape_list -from ...utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from ..auto.configuration_auto import AutoConfig -from ..auto.modeling_tf_auto import TFAutoModel, TFAutoModelForCausalLM -from .configuration_vision_encoder_decoder import VisionEncoderDecoderConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "VisionEncoderDecoderConfig" - -DEPRECATION_WARNING = ( - "Version v4.17.0 introduces a better way to train encoder-decoder models by computing the loss inside the" - " encoder-decoder framework rather than in the decoder itself. You may observe training discrepancies if" - " fine-tuning a model trained with versions anterior to 4.17.0. The decoder_input_ids are now created based on the" - " labels, no need to pass them yourself anymore." -) - -VISION_ENCODER_DECODER_START_DOCSTRING = r""" - This class can be used to initialize an image-to-text-sequence model with any pretrained vision autoencoding model - as the encoder and any pretrained text autoregressive model as the decoder. The encoder is loaded via - [`~TFAutoModel.from_pretrained`] function and the decoder is loaded via [`~TFAutoModelForCausalLM.from_pretrained`] - function. Cross-attention layers are automatically added to the decoder and should be fine-tuned on a downstream - generative task, like image captioning. - - The effectiveness of initializing sequence-to-sequence models with pretrained checkpoints for sequence generation - tasks was shown in [Leveraging Pre-trained Checkpoints for Sequence Generation - Tasks](https://huggingface.co/papers/1907.12461) by Sascha Rothe, Shashi Narayan, Aliaksei Severyn. Michael Matena, Yanqi - Zhou, Wei Li, Peter J. Liu. - - Additionally, in [TrOCR: Transformer-based Optical Character Recognition with Pre-trained - Models](https://huggingface.co/papers/2109.10282) it is shown how leveraging large pretrained vision models for optical - character recognition (OCR) yields a significant performance improvement. - - After such a Vision-Encoder-Text-Decoder model has been trained/fine-tuned, it can be saved/loaded just like any - other models (see the examples for more information). - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - Parameters: - config ([`VisionEncoderDecoderConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -VISION_ENCODER_DECODER_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using the vision's model's image processor. For example, using - [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] for details. - decoder_input_ids (`np.ndarray` or `tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - - If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - - Provide for sequence to sequence training to the decoder. Indices can be obtained using - [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and [`PreTrainedTokenizer.__call__`] for - details. - decoder_attention_mask (`np.ndarray` or `tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - encoder_outputs (`tuple(tuple(tf.Tensor)`, *optional*): - This tuple must consist of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` (`tf.Tensor` of shape `({0}, hidden_size)`) is a tensor of hidden-states at the output - of the last layer of the encoder. Used in the cross-attention of the decoder. - past_key_values (`tuple(tuple(tf.Tensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): - Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `({0})`. - decoder_inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `(batch_size, target_sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `decoder_input_ids` you can choose to directly pass an embedded - representation. This is useful if you want more control over how to convert `decoder_input_ids` indices - into associated vectors than the model's internal embedding lookup matrix. - labels (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Labels for computing the masked language modeling loss for the decoder. Indices should be in `[-100, 0, - ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored - (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - If set to `True`, the model will return a [`~utils.Seq2SeqLMOutput`] instead of a plain tuple. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - kwargs (*optional*): Remaining dictionary of keyword arguments. Keyword arguments come in two flavors: - - - Without a prefix which will be input as `**encoder_kwargs` for the encoder forward function. - - With a *decoder_* prefix which will be input as `**decoder_kwargs` for the decoder forward function. -""" - - -# Copied from transformers.models.encoder_decoder.modeling_tf_encoder_decoder.shift_tokens_right -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): - if pad_token_id is None: - raise ValueError("Make sure to set the pad_token_id attribute of the model's configuration.") - pad_token_id = tf.cast(pad_token_id, input_ids.dtype) - - if decoder_start_token_id is None: - raise ValueError("Make sure to set the decoder_start_token_id attribute of the model's configuration.") - decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) - - start_tokens = tf.fill((shape_list(input_ids)[0], 1), decoder_start_token_id) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, tf.fill(shape_list(shifted_input_ids), pad_token_id), shifted_input_ids - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -@add_start_docstrings(VISION_ENCODER_DECODER_START_DOCSTRING) -class TFVisionEncoderDecoderModel(TFPreTrainedModel, TFCausalLanguageModelingLoss): - r""" - [`TFVisionEncoderDecoderModel`] is a generic model class that will be instantiated as a transformer architecture - with one of the base vision model classes of the library as encoder and another one of the base model classes as - decoder when created with the [`~TFAutoModel.from_pretrained`] class method for the encoder and - [`~TFAutoModelForCausalLM.from_pretrained`] class method for the decoder. - """ - - config_class = VisionEncoderDecoderConfig - base_model_prefix = "vision_encoder_decoder" - load_weight_prefix = "tf_vision_encoder_decoder_model" - main_input_name = "pixel_values" - - def __init__( - self, - config: PretrainedConfig | None = None, - encoder: TFPreTrainedModel | None = None, - decoder: TFPreTrainedModel | None = None, - ): - if config is None and (encoder is None or decoder is None): - raise ValueError("Either a configuration or an encoder and a decoder has to be provided.") - if config is None: - config = VisionEncoderDecoderConfig.from_encoder_decoder_configs(encoder.config, decoder.config) - else: - if not isinstance(config, self.config_class): - raise ValueError(f"config: {config} has to be of type {self.config_class}") - - if config.decoder.cross_attention_hidden_size is not None: - if config.decoder.cross_attention_hidden_size != config.encoder.hidden_size: - raise ValueError( - "If `cross_attention_hidden_size` is specified in the decoder's configuration, it has to be equal" - f" to the encoder's `hidden_size`. Got {config.decoder.cross_attention_hidden_size} for" - f" `config.decoder.cross_attention_hidden_size` and {config.encoder.hidden_size} for" - " `config.encoder.hidden_size`." - ) - - # initialize with config - super().__init__(config) - - if encoder is None: - encoder = TFAutoModel.from_config(config.encoder, name="encoder") - - if decoder is None: - decoder = TFAutoModelForCausalLM.from_config(config.decoder, name="decoder") - - self.encoder = encoder - self.decoder = decoder - - if self.encoder.config.to_dict() != self.config.encoder.to_dict(): - logger.warning( - f"Config of the encoder: {self.encoder.__class__} is overwritten by shared encoder config:" - f" {self.config.encoder}" - ) - if self.decoder.config.to_dict() != self.config.decoder.to_dict(): - logger.warning( - f"Config of the decoder: {self.decoder.__class__} is overwritten by shared decoder config:" - f" {self.config.decoder}" - ) - - # make sure that the individual model's config refers to the shared config - # so that the updates to the config will be synced - self.encoder.config = self.config.encoder - self.decoder.config = self.config.decoder - - # encoder outputs might need to be projected to different dimension for decoder - if ( - self.encoder.config.hidden_size != self.decoder.config.hidden_size - and self.decoder.config.cross_attention_hidden_size is None - ): - self.enc_to_dec_proj = keras.layers.Dense( - units=self.decoder.config.hidden_size, - kernel_initializer=get_initializer(config.encoder.initializer_range), - name="enc_to_dec_proj", - ) - - if self.encoder.get_output_embeddings() is not None: - raise ValueError( - f"The encoder {self.encoder} should not have a LM Head. Please use a model without LM Head" - ) - - @property - def input_signature(self): - vision_config = self.config.encoder - if hasattr(vision_config, "vision_config"): - vision_config = vision_config.vision_config - if hasattr(vision_config, "image_size"): - image_size = vision_config.image_size - else: - image_size = vision_config.input_size - return { - "pixel_values": tf.TensorSpec( - shape=( - None, - vision_config.num_channels, - image_size, - image_size, - ), - dtype=tf.float32, - ), - "decoder_input_ids": tf.TensorSpec(shape=(None, None), dtype=tf.int32, name="decoder_input_ids"), - } - - def get_encoder(self): - return self.encoder - - def get_input_embeddings(self): - return self.encoder.get_input_embeddings() - - def get_output_embeddings(self): - return self.decoder.get_output_embeddings() - - def set_output_embeddings(self, new_embeddings): - return self.decoder.set_output_embeddings(new_embeddings) - - def tf_to_pt_weight_rename(self, tf_weight): - # Matt: The TF and PT weights don't align because our TF base classes have an extra layer compared to PT models - # (the main model stem is in the MainLayer class). If we remove that layer, then weight names sync up as normal. - # However, the name of that extra layer is the name of the MainLayer in the base model. We make the assumption - # here that the config model_type is the same as the name of the MainLayer. I don't know of anywhere that's - # not the case, and I wasn't sure how else to go from the config to the correct MainLayer name! - - # This override is only needed in the case where we're crossloading weights from PT. However, since weights are - # often safetensors now, we don't know if we're going to be crossloading until we sniff the weights file. - # Therefore, we specify tf_to_pt_weight_rename anyway, and let the super method figure out if it needs it - # or not. - encoder_model_type = self.config.encoder.model_type - if "encoder" in tf_weight and "decoder" not in tf_weight: - return (re.sub(rf"encoder\.{encoder_model_type}\.", "encoder.", tf_weight),) - else: - return (tf_weight,) - - @classmethod - def from_encoder_decoder_pretrained( - cls, - encoder_pretrained_model_name_or_path: str | None = None, - decoder_pretrained_model_name_or_path: str | None = None, - *model_args, - **kwargs, - ) -> TFPreTrainedModel: - r""" - Instantiate an encoder and a decoder from one or two base classes of the library from pretrained model - checkpoints. - - - Params: - encoder_pretrained_model_name_or_path (`str`, *optional*): - Information necessary to initiate the encoder. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. An - example is `google/vit-base-patch16-224-in21k`. - - A path to a *directory* containing model weights saved using - [`~TFPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *pytorch index checkpoint file* (e.g, `./pt_model/`). In this case, - `encoder_from_pt` should be set to `True`. - - decoder_pretrained_model_name_or_path (`str`, *optional*, defaults to *None*): - Information necessary to initiate the decoder. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~TFPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *pytorch checkpoint file* (e.g, `./pt_model/`). In this case, - `decoder_from_pt` should be set to `True`. - - model_args (remaining positional arguments, *optional*): - All remaining positional arguments will be passed to the underlying model's `__init__` method. - - kwargs (remaining dictionary of keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). - - - To update the encoder configuration, use the prefix *encoder_* for each configuration parameter. - - To update the decoder configuration, use the prefix *decoder_* for each configuration parameter. - - To update the parent model configuration, do not use a prefix for each configuration parameter. - - Behaves differently depending on whether a `config` is provided or automatically loaded. - - Example: - - ```python - >>> from transformers import TFVisionEncoderDecoderModel - - >>> # initialize a vit-bert from a pretrained ViT and a pretrained BERT model. Note that the cross-attention layers will be randomly initialized - >>> model = TFVisionEncoderDecoderModel.from_encoder_decoder_pretrained( - ... "google/vit-base-patch16-224-in21k", "google-bert/bert-base-uncased" - ... ) - >>> # saving model after fine-tuning - >>> model.save_pretrained("./vit-bert") - >>> # load fine-tuned model - >>> model = TFVisionEncoderDecoderModel.from_pretrained("./vit-bert") - ```""" - - kwargs_encoder = { - argument[len("encoder_") :]: value for argument, value in kwargs.items() if argument.startswith("encoder_") - } - - kwargs_decoder = { - argument[len("decoder_") :]: value for argument, value in kwargs.items() if argument.startswith("decoder_") - } - - # remove encoder, decoder kwargs from kwargs - for key in kwargs_encoder: - del kwargs["encoder_" + key] - for key in kwargs_decoder: - del kwargs["decoder_" + key] - - # Load and initialize the encoder and decoder - # The distinction between encoder and decoder at the model level is made - # by the value of the flag `is_decoder` that we need to set correctly. - encoder = kwargs_encoder.pop("model", None) - if encoder is None: - if encoder_pretrained_model_name_or_path is None: - raise ValueError( - "If `encoder_model` is not defined as an argument, a `encoder_pretrained_model_name_or_path` has " - "to be defined." - ) - - if "config" not in kwargs_encoder: - encoder_config = AutoConfig.from_pretrained(encoder_pretrained_model_name_or_path) - if encoder_config.is_decoder is True or encoder_config.add_cross_attention is True: - logger.info( - f"Initializing {encoder_pretrained_model_name_or_path} as a encoder model " - "from a decoder model. Cross-attention and causal mask are disabled." - ) - encoder_config.is_decoder = False - encoder_config.add_cross_attention = False - - kwargs_encoder["config"] = encoder_config - - kwargs_encoder["name"] = "encoder" - kwargs_encoder["load_weight_prefix"] = cls.load_weight_prefix - encoder = TFAutoModel.from_pretrained(encoder_pretrained_model_name_or_path, *model_args, **kwargs_encoder) - - decoder = kwargs_decoder.pop("model", None) - if decoder is None: - if decoder_pretrained_model_name_or_path is None: - raise ValueError( - "If `decoder_model` is not defined as an argument, a `decoder_pretrained_model_name_or_path` has " - "to be defined." - ) - - if "config" not in kwargs_decoder: - decoder_config = AutoConfig.from_pretrained(decoder_pretrained_model_name_or_path) - if decoder_config.is_decoder is False or decoder_config.add_cross_attention is False: - logger.info( - f"Initializing {decoder_pretrained_model_name_or_path} as a decoder model. Cross attention" - f" layers are added to {decoder_pretrained_model_name_or_path} and randomly initialized if" - f" {decoder_pretrained_model_name_or_path}'s architecture allows for cross attention layers." - ) - decoder_config.is_decoder = True - decoder_config.add_cross_attention = True - - kwargs_decoder["config"] = decoder_config - - if kwargs_decoder["config"].is_decoder is False or kwargs_decoder["config"].add_cross_attention is False: - logger.warning( - f"Decoder model {decoder_pretrained_model_name_or_path} is not initialized as a decoder. " - f"In order to initialize {decoder_pretrained_model_name_or_path} as a decoder, " - "make sure that the attributes `is_decoder` and `add_cross_attention` of `decoder_config` " - "passed to `.from_encoder_decoder_pretrained(...)` are set to `True` or do not pass a " - "`decoder_config` to `.from_encoder_decoder_pretrained(...)`" - ) - - kwargs_decoder["name"] = "decoder" - kwargs_decoder["load_weight_prefix"] = cls.load_weight_prefix - decoder = TFAutoModelForCausalLM.from_pretrained(decoder_pretrained_model_name_or_path, **kwargs_decoder) - - # Make sure these 2 `keras.Model` have fixed names so `from_pretrained` could load model weights correctly. - if encoder.name != "encoder": - raise ValueError("encoder model must be created with the name `encoder`.") - if decoder.name != "decoder": - raise ValueError("decoder model must be created with the name `decoder`.") - - # instantiate config with corresponding kwargs - config = VisionEncoderDecoderConfig.from_encoder_decoder_configs(encoder.config, decoder.config, **kwargs) - return cls(encoder=encoder, decoder=decoder, config=config) - - @unpack_inputs - @add_start_docstrings_to_model_forward( - VISION_ENCODER_DECODER_INPUTS_DOCSTRING.format("batch_size, sequence_length") - ) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: np.ndarray | tf.Tensor | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: tuple | TFBaseModelOutput | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - decoder_inputs_embeds: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs, - ) -> TFSeq2SeqLMOutput | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, AutoTokenizer, TFVisionEncoderDecoderModel - >>> from PIL import Image - >>> import requests - - >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k") - >>> decoder_tokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2") - - >>> # initialize a bert2gpt2 from a pretrained BERT and GPT2 models. Note that the cross-attention layers will be randomly initialized - >>> model = TFVisionEncoderDecoderModel.from_encoder_decoder_pretrained( - ... "google/vit-base-patch16-224-in21k", "openai-community/gpt2" - ... ) - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> img = Image.open(requests.get(url, stream=True).raw) - - >>> # forward - >>> pixel_values = image_processor(images=img, return_tensors="tf").pixel_values # Batch size 1 - >>> decoder_input_ids = decoder_tokenizer("Linda Davis", return_tensors="tf").input_ids # Batch size 1 - >>> outputs = model(pixel_values=pixel_values, decoder_input_ids=decoder_input_ids) - - >>> # training - >>> outputs = model(pixel_values=pixel_values, decoder_input_ids=decoder_input_ids, labels=decoder_input_ids) - >>> loss, logits = outputs.loss, outputs.logits - - >>> # save and load from pretrained - >>> model.save_pretrained("vit-gpt2") - >>> model = TFVisionEncoderDecoderModel.from_pretrained("vit-gpt2") - - >>> # generation - >>> generated = model.generate(pixel_values, decoder_start_token_id=model.config.decoder.bos_token_id) - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - kwargs_encoder = {argument: value for argument, value in kwargs.items() if not argument.startswith("decoder_")} - - kwargs_decoder = { - argument[len("decoder_") :]: value for argument, value in kwargs.items() if argument.startswith("decoder_") - } - - # Let the user be responsible for the expected format. - if encoder_outputs is not None: - if return_dict and not isinstance(encoder_outputs, ModelOutput): - raise ValueError( - "If `return_dict=True` and `encoder_outputs` is provided, it should be an instance of " - f"`ModelOutput`. Got an instance {type(encoder_outputs)} for `encoder_outputs`." - ) - - if encoder_outputs is None: - encoder_inputs = { - "input_ids": pixel_values, - "output_attentions": output_attentions, - "output_hidden_states": output_hidden_states, - "return_dict": return_dict, - "training": training, - } - - # Add arguments to encoder from `kwargs_encoder` - encoder_inputs.update(kwargs_encoder) - - if "input_ids" in encoder_inputs: - encoder_inputs["pixel_values"] = encoder_inputs.pop("input_ids") - - if encoder_inputs["pixel_values"] is None: - raise ValueError("You have to specify pixel_values") - - # Handle the case where the inputs are passed as a single dict which contains `labels`. - # The `labels` shouldn't be passed to `self.encoder` below, because it is a based model without this - # parameter (otherwise, an error occurs when `input_processing` is called inside `self.encoder.call()`). - if "labels" in encoder_inputs: - labels = encoder_inputs.pop("labels") - - # handle the init case where `dummy_inputs` returns a dict containing `decoder_input_ids`. - if "decoder_input_ids" in encoder_inputs: - decoder_input_ids = encoder_inputs.pop("decoder_input_ids") - # handle the init case where `dummy_inputs` returns a dict containing `decoder_input_ids`. - if "decoder_attention_mask" in encoder_inputs: - decoder_attention_mask = encoder_inputs.pop("decoder_attention_mask") - - encoder_outputs = self.encoder(**encoder_inputs) - - encoder_hidden_states = encoder_outputs[0] - - # optionally project encoder_hidden_states - if ( - self.encoder.config.hidden_size != self.decoder.config.hidden_size - and self.decoder.config.cross_attention_hidden_size is None - ): - encoder_hidden_states = self.enc_to_dec_proj(encoder_hidden_states) - - if (labels is not None) and (decoder_input_ids is None and decoder_inputs_embeds is None): - decoder_input_ids = shift_tokens_right( - labels, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - batch_size, sequence_length = shape_list(encoder_hidden_states)[:2] - encoder_attention_mask = tf.ones(shape=(batch_size, sequence_length), dtype=tf.int32) - - decoder_inputs = { - "input_ids": decoder_input_ids, - "attention_mask": decoder_attention_mask, - "encoder_hidden_states": encoder_hidden_states, - "encoder_attention_mask": encoder_attention_mask, - "inputs_embeds": decoder_inputs_embeds, - "output_attentions": output_attentions, - "output_hidden_states": output_hidden_states, - "use_cache": use_cache, - "past_key_values": past_key_values, - "return_dict": return_dict, - "training": training, - } - - # Add arguments to decoder from `kwargs_decoder` - decoder_inputs.update(kwargs_decoder) - - decoder_outputs = self.decoder(**decoder_inputs) - - logits = decoder_outputs[0] - - # Compute loss independent from decoder (as some shift the logits inside them) - loss = None - if labels is not None: - warnings.warn(DEPRECATION_WARNING, FutureWarning) - loss = self.hf_compute_loss(labels, logits) - - if not return_dict: - past_key_values = None - if use_cache: - past_key_values = decoder_outputs[1] - # The starting index of the remaining elements in `decoder_outputs` - start_index = sum([1 if x is not None else 0 for x in (loss, logits, past_key_values)]) - - if not isinstance(encoder_outputs, tuple): - encoder_outputs = encoder_outputs.to_tuple() - output = (loss, logits, past_key_values) + decoder_outputs[start_index:] + encoder_outputs - output = tuple(x for x in output if x is not None) - return output - - return TFSeq2SeqLMOutput( - loss=loss, - logits=decoder_outputs.logits, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.decoder.use_cache else None - dec_hs = ( - tf.convert_to_tensor(output.decoder_hidden_states) if self.config.decoder.output_hidden_states else None - ) - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.decoder.output_attentions else None - enc_hs = ( - tf.convert_to_tensor(output.encoder_hidden_states) if self.config.encoder.output_hidden_states else None - ) - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.encoder.output_attentions else None - cross_attns = ( - tf.convert_to_tensor(output.cross_attentions) - if self.config.decoder.output_attentions and output.cross_attentions is not None - else None - ) - - return TFSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - cross_attentions=cross_attns, - ) - - def prepare_inputs_for_generation( - self, input_ids, past_key_values=None, attention_mask=None, use_cache=None, encoder_outputs=None, **kwargs - ): - decoder_inputs = self.decoder.prepare_inputs_for_generation(input_ids, past_key_values=past_key_values) - decoder_attention_mask = decoder_inputs.get("attention_mask", None) - past_key_values = decoder_inputs.get("past_key_values") - input_dict = { - "pixel_values": None, # needs to be passed to make Keras.layer.__call__ happy - "attention_mask": attention_mask, - "decoder_attention_mask": decoder_attention_mask, - "decoder_input_ids": decoder_inputs["input_ids"], - # TODO (joao): the `TFBaseModelOutput` wrapper should not be needed after the generate refactor is complete - "encoder_outputs": TFBaseModelOutput(last_hidden_state=encoder_outputs[0]), - "past_key_values": past_key_values, - "use_cache": use_cache, - } - return input_dict - - def prepare_decoder_input_ids_from_labels(self, labels: tf.Tensor): - return shift_tokens_right(labels, self.config.pad_token_id, self.config.decoder_start_token_id) - - def resize_token_embeddings(self, *args, **kwargs): - raise NotImplementedError( - "Resizing the embedding layers via the TFVisionEncoderDecoderModel directly is not supported. " - "Please use the respective methods of the wrapped objects (model.decoder.resize_token_embeddings(...))" - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "enc_to_dec_proj", None) is not None: - with tf.name_scope(self.enc_to_dec_proj.name): - self.enc_to_dec_proj.build([None, None, self.encoder.config.hidden_size]) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -__all__ = ["TFVisionEncoderDecoderModel"] diff --git a/src/transformers/models/vision_encoder_decoder/modeling_vision_encoder_decoder.py b/src/transformers/models/vision_encoder_decoder/modeling_vision_encoder_decoder.py index d6bc2dcc0f8e..09eeba11add7 100644 --- a/src/transformers/models/vision_encoder_decoder/modeling_vision_encoder_decoder.py +++ b/src/transformers/models/vision_encoder_decoder/modeling_vision_encoder_decoder.py @@ -14,9 +14,6 @@ # limitations under the License. """Classes to support Vision-Encoder-Text-Decoder architectures""" -import gc -import os -import tempfile from typing import Optional, Union import torch @@ -158,130 +155,6 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): return self.decoder.set_output_embeddings(new_embeddings) - @classmethod - def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs): - r""" - Example: - - ```python - >>> from transformers import VisionEncoderDecoderModel, AutoImageProcessor, AutoTokenizer - >>> from PIL import Image - >>> import requests - - >>> image_processor = AutoImageProcessor.from_pretrained("ydshieh/vit-gpt2-coco-en") - >>> decoder_tokenizer = AutoTokenizer.from_pretrained("ydshieh/vit-gpt2-coco-en") - >>> model = VisionEncoderDecoderModel.from_pretrained("ydshieh/vit-gpt2-coco-en") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> img = Image.open(requests.get(url, stream=True).raw) - >>> pixel_values = image_processor(images=img, return_tensors="pt").pixel_values # Batch size 1 - - >>> output_ids = model.generate( - ... pixel_values, max_length=16, num_beams=4, return_dict_in_generate=True - ... ).sequences - - >>> preds = decoder_tokenizer.batch_decode(output_ids, skip_special_tokens=True) - >>> preds = [pred.strip() for pred in preds] - - >>> assert preds == ["a cat laying on top of a couch next to another cat"] - ```""" - - from_tf = kwargs.pop("from_tf", False) - if from_tf: - from transformers import TFVisionEncoderDecoderModel - - # a workaround to load from tensorflow checkpoint - # Using `_tf_model` won't work, because the weight names in the encoder/decoder of `_tf_model` get - # extended before saving those components. For example, The name of `_tf_model.encoder.vit` is - # `[top model name]/encoder/vit`, but the name of `tf_model.encoder.vit` is `[top model name]/vit`. The - # [top model name] is handled (stripped) by the conversion method, and the former case gets extra `encoder`, - # which should not occur when we want to save the components alone. - # There was a (very) ugly potential fix, which wasn't integrated to `transformers`: see - # https://github.com/huggingface/transformers/pull/13222/commits/dbb3c9de76eee235791d2064094654637c99f36d#r697304245 - # (the change in `src/transformers/modeling_tf_utils.py`) - _tf_model = TFVisionEncoderDecoderModel.from_pretrained( - pretrained_model_name_or_path, *model_args, **kwargs - ) - config = _tf_model.config - - # Using `tf_model` instead - encoder = _tf_model.encoder.__class__(_tf_model.config.encoder) - decoder = _tf_model.decoder.__class__(_tf_model.config.decoder) - # Make sure models are built - encoder(encoder.dummy_inputs) - decoder(decoder.dummy_inputs) - - # Get the variable correspondence between `_tf_model` and `encoder` and `decoder` - encoder_variables = {} - for v in encoder.trainable_variables + encoder.non_trainable_variables: - encoder_variables["/".join(v.name.split("/")[1:])] = v - decoder_variables = {} - for v in decoder.trainable_variables + decoder.non_trainable_variables: - decoder_variables["/".join(v.name.split("/")[1:])] = v - - _encoder_variables = {} - for v in _tf_model.encoder.trainable_variables + _tf_model.encoder.non_trainable_variables: - _encoder_variables["/".join(v.name.split("/")[2:])] = v - _decoder_variables = {} - for v in _tf_model.decoder.trainable_variables + _tf_model.decoder.non_trainable_variables: - _decoder_variables["/".join(v.name.split("/")[2:])] = v - - # assign weight values to `encoder` and `decoder` from `_tf_model` - for name, v in encoder_variables.items(): - v.assign(_encoder_variables[name]) - for name, v in decoder_variables.items(): - v.assign(_decoder_variables[name]) - - tf_model = TFVisionEncoderDecoderModel(encoder=encoder, decoder=decoder) - - # Deal with `enc_to_dec_proj` - if hasattr(_tf_model, "enc_to_dec_proj"): - tf_model(tf_model.dummy_inputs) - tf_model.enc_to_dec_proj.kernel.assign(_tf_model.enc_to_dec_proj.kernel) - tf_model.enc_to_dec_proj.bias.assign(_tf_model.enc_to_dec_proj.bias) - - with tempfile.TemporaryDirectory() as tmpdirname: - encoder_dir = os.path.join(tmpdirname, "encoder") - decoder_dir = os.path.join(tmpdirname, "decoder") - tf_model.encoder.save_pretrained(encoder_dir) - tf_model.decoder.save_pretrained(decoder_dir) - - if hasattr(tf_model, "enc_to_dec_proj"): - enc_to_dec_proj_weight = torch.transpose( - torch.from_numpy(tf_model.enc_to_dec_proj.kernel.numpy()), 1, 0 - ) - enc_to_dec_proj_bias = torch.from_numpy(tf_model.enc_to_dec_proj.bias.numpy()) - - del _tf_model - del tf_model - gc.collect() - - attn_implementation = kwargs.get("attn_implementation") - kwargs_encoder_decoder = {} - if attn_implementation: - kwargs_encoder_decoder = { - "encoder_attn_implementation": attn_implementation, - "decoder_attn_implementation": attn_implementation, - } - - model = VisionEncoderDecoderModel.from_encoder_decoder_pretrained( - encoder_dir, - decoder_dir, - encoder_from_tf=True, - decoder_from_tf=True, - **kwargs_encoder_decoder, - ) - # This is only for copying some specific attributes of this particular model. - model.config = config - - if hasattr(model, "enc_to_dec_proj"): - model.enc_to_dec_proj.weight.data = enc_to_dec_proj_weight.contiguous() - model.enc_to_dec_proj.bias.data = enc_to_dec_proj_bias.contiguous() - - return model - - return super().from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs) - @classmethod def from_encoder_decoder_pretrained( cls, @@ -306,10 +179,6 @@ def from_encoder_decoder_pretrained( example is `google/vit-base-patch16-224-in21k`. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In - this case, `from_tf` should be set to `True` and a configuration object should be provided as - `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a - PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. decoder_pretrained_model_name_or_path (`str`, *optional*, defaults to `None`): Information necessary to initiate the text decoder. Can be either: @@ -317,10 +186,6 @@ def from_encoder_decoder_pretrained( - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In - this case, `from_tf` should be set to `True` and a configuration object should be provided as - `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a - PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. model_args (remaining positional arguments, *optional*): All remaining positional arguments will be passed to the underlying model's `__init__` method. diff --git a/src/transformers/models/vision_text_dual_encoder/__init__.py b/src/transformers/models/vision_text_dual_encoder/__init__.py index 4b68df9c336f..8043c28bcca8 100644 --- a/src/transformers/models/vision_text_dual_encoder/__init__.py +++ b/src/transformers/models/vision_text_dual_encoder/__init__.py @@ -19,8 +19,6 @@ if TYPE_CHECKING: from .configuration_vision_text_dual_encoder import * - from .modeling_flax_vision_text_dual_encoder import * - from .modeling_tf_vision_text_dual_encoder import * from .modeling_vision_text_dual_encoder import * from .processing_vision_text_dual_encoder import * else: diff --git a/src/transformers/models/vision_text_dual_encoder/modeling_flax_vision_text_dual_encoder.py b/src/transformers/models/vision_text_dual_encoder/modeling_flax_vision_text_dual_encoder.py deleted file mode 100644 index 15ef5d48a32d..000000000000 --- a/src/transformers/models/vision_text_dual_encoder/modeling_flax_vision_text_dual_encoder.py +++ /dev/null @@ -1,601 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax VisionTextDualEncoder model.""" - -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.traverse_util import flatten_dict, unflatten_dict - -from ...modeling_flax_utils import FlaxPreTrainedModel, append_replace_return_docstrings, overwrite_call_docstring -from ...utils import add_start_docstrings, logging -from ..auto.configuration_auto import AutoConfig -from ..auto.modeling_flax_auto import FLAX_MODEL_MAPPING, FlaxAutoModel -from ..clip.modeling_flax_clip import FlaxCLIPOutput, FlaxCLIPVisionModel -from .configuration_vision_text_dual_encoder import VisionTextDualEncoderConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "VisionTextDualEncoderConfig" - -VISION_TEXT_DUAL_ENCODER_START_DOCSTRING = r""" - This class can be used to initialize a vision-text dual encoder model with any pretrained vision autoencoding model - as the vision encoder and any pretrained text model as the text encoder. The vision and text encoders are loaded - via the [`~FlaxAutoModel.from_pretrained`] method. The projection layers are automatically added to the model and - should be fine-tuned on a downstream task, like contrastive image-text modeling. - - In [LiT: Zero-Shot Transfer with Locked-image Text Tuning](https://huggingface.co/papers/2111.07991) it is shown how - leveraging pre-trained (locked/frozen) image and text model for contrastive learning yields significant improvement - on new zero-shot vision tasks such as image classification or retrieval. - - After such a Vision-Text-Dual-Encoder model has been trained/fine-tuned, it can be saved/loaded just like any other - models (see the examples for more information). - - This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it - as a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`VisionTextDualEncoderConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - - -VISION_TEXT_DUAL_ENCODER_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using - an image processor (e.g. if you use ViT as the encoder, you should use [`AutoImageProcessor`]). See - [`ViTImageProcessor.__call__`] for details. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -class FlaxVisionTextDualEncoderModule(nn.Module): - config: VisionTextDualEncoderConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - vision_config = self.config.vision_config - text_config = self.config.text_config - - self.vision_embed_dim = vision_config.hidden_size - self.text_embed_dim = text_config.hidden_size - self.projection_dim = self.config.projection_dim - - vision_module = FLAX_MODEL_MAPPING.get(self.config.vision_config.__class__, FlaxCLIPVisionModel).module_class - text_module = FLAX_MODEL_MAPPING[self.config.text_config.__class__].module_class - - self.vision_model = vision_module(vision_config, dtype=self.dtype) - self.text_model = text_module(text_config, dtype=self.dtype) - - self.visual_projection = nn.Dense( - self.projection_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(0.02), - use_bias=False, - ) - self.text_projection = nn.Dense( - self.projection_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(0.02), - use_bias=False, - ) - - self.logit_scale = self.param( - "logit_scale", lambda _, shape: jnp.ones(shape) * self.config.logit_scale_init_value, [] - ) - - def __call__( - self, - input_ids=None, - pixel_values=None, - attention_mask=None, - position_ids=None, - token_type_ids=None, - deterministic: bool = True, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - ): - return_dict = return_dict if return_dict is not None else self.config.return_dict - - vision_outputs = self.vision_model( - pixel_values=pixel_values, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - text_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - image_embeds = vision_outputs[1] - image_embeds = self.visual_projection(image_embeds) - - text_embeds = text_outputs[1] - text_embeds = self.text_projection(text_embeds) - - # normalized features - image_embeds = image_embeds / jnp.linalg.norm(image_embeds, axis=-1, keepdims=True) - text_embeds = text_embeds / jnp.linalg.norm(text_embeds, axis=-1, keepdims=True) - - # cosine similarity as logits - logit_scale = jnp.exp(self.logit_scale) - logits_per_text = jnp.matmul(text_embeds, image_embeds.T) * logit_scale - logits_per_image = logits_per_text.T - - if not return_dict: - return (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs) - - return FlaxCLIPOutput( - logits_per_image=logits_per_image, - logits_per_text=logits_per_text, - text_embeds=text_embeds, - image_embeds=image_embeds, - text_model_output=text_outputs, - vision_model_output=vision_outputs, - ) - - -@add_start_docstrings(VISION_TEXT_DUAL_ENCODER_START_DOCSTRING) -class FlaxVisionTextDualEncoderModel(FlaxPreTrainedModel): - config_class = VisionTextDualEncoderConfig - module_class = FlaxVisionTextDualEncoderModule - - def __init__( - self, - config: VisionTextDualEncoderConfig, - input_shape: Optional[tuple] = None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - if not _do_init: - raise ValueError( - "`FlaxVisionTextDualEncoderModel` cannot be created without initializing, `_do_init` must be `True`." - ) - - if input_shape is None: - input_shape = ((1, 1), (1, config.vision_config.image_size, config.vision_config.image_size, 3)) - - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensor - input_ids = jnp.zeros(input_shape[0], dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape[0]) - token_type_ids = jnp.ones_like(input_ids) - attention_mask = jnp.ones_like(input_ids) - - pixel_values = jax.random.normal(rng, input_shape[1]) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, input_ids, pixel_values, attention_mask, position_ids, token_type_ids)[ - "params" - ] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def __call__( - self, - input_ids, - pixel_values, - attention_mask=None, - position_ids=None, - token_type_ids=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(input_ids, dtype="i4"), - jnp.array(pixel_values, dtype=jnp.float32), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - jnp.array(token_type_ids, dtype="i4"), - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - def get_text_features( - self, - input_ids, - attention_mask=None, - position_ids=None, - token_type_ids=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train=False, - ): - r""" - Args: - input_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - - Returns: - text_features (`jnp.ndarray` of shape `(batch_size, output_dim`): The text embeddings obtained by applying - the projection layer to the pooled output of text model. - """ - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _get_features(module, input_ids, attention_mask, position_ids, token_type_ids, deterministic): - text_outputs = module.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - token_type_ids=token_type_ids, - deterministic=deterministic, - ) - pooled_output = text_outputs[1] - text_features = module.text_projection(pooled_output) - return text_features - - return self.module.apply( - {"params": params or self.params}, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - jnp.array(position_ids, dtype="i4"), - jnp.array(token_type_ids, dtype="i4"), - not train, - method=_get_features, - rngs=rngs, - ) - - def get_image_features( - self, pixel_values, params: Optional[dict] = None, dropout_rng: jax.random.PRNGKey = None, train=False - ): - r""" - Args: - pixel_values (`numpy.ndarray` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained - using [`ImageFeatureExtractionMixin`]. See [`ImageFeatureExtractionMixin.__call__`] for details. - - Returns: - image_features (`jnp.ndarray` of shape `(batch_size, output_dim`): The image embeddings obtained by - applying the projection layer to the pooled output of vision model. - """ - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _get_features(module, pixel_values, deterministic): - vision_outputs = module.vision_model(pixel_values=pixel_values, deterministic=deterministic) - pooled_output = vision_outputs[1] # pooled_output - image_features = module.visual_projection(pooled_output) - return image_features - - return self.module.apply( - {"params": params or self.params}, - jnp.array(pixel_values, dtype=jnp.float32), - not train, - method=_get_features, - rngs=rngs, - ) - - @classmethod - def from_vision_text_pretrained( - cls, - vision_model_name_or_path: Optional[str] = None, - text_model_name_or_path: Optional[str] = None, - *model_args, - **kwargs, - ) -> FlaxPreTrainedModel: - """ - Params: - vision_model_name_or_path (`str`, *optional*, defaults to `None`): - Information necessary to initiate the vision model. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~FlaxPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *PyTorch checkpoint folder* (e.g, `./pt_model`). In this case, `from_pt` - should be set to `True` and a configuration object should be provided as `config` argument. This - loading path is slower than converting the PyTorch checkpoint in a Flax model using the provided - conversion scripts and loading the Flax model afterwards. - - text_model_name_or_path (`str`, *optional*): - Information necessary to initiate the text model. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~FlaxPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *PyTorch checkpoint folder* (e.g, `./pt_model`). In this case, `from_pt` - should be set to `True` and a configuration object should be provided as `config` argument. This - loading path is slower than converting the PyTorch checkpoint in a Flax model using the provided - conversion scripts and loading the Flax model afterwards. - - model_args (remaining positional arguments, *optional*): - All remaining positional arguments will be passed to the underlying model's `__init__` method. - - kwargs (remaining dictionary of keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). - - - To update the text configuration, use the prefix *text_* for each configuration parameter. - - To update the vision configuration, use the prefix *vision_* for each configuration parameter. - - To update the parent model configuration, do not use a prefix for each configuration parameter. - - Behaves differently depending on whether a `config` is provided or automatically loaded. - - Example: - - ```python - >>> from transformers import FlaxVisionTextDualEncoderModel - - >>> # initialize a model from pretrained ViT and BERT models. Note that the projection layers will be randomly initialized. - >>> model = FlaxVisionTextDualEncoderModel.from_vision_text_pretrained( - ... "google/vit-base-patch16-224", "google-bert/bert-base-uncased" - ... ) - >>> # saving model after fine-tuning - >>> model.save_pretrained("./vit-bert") - >>> # load fine-tuned model - >>> model = FlaxVisionTextDualEncoderModel.from_pretrained("./vit-bert") - ```""" - - kwargs_vision = { - argument[len("vision_") :]: value for argument, value in kwargs.items() if argument.startswith("vision_") - } - - kwargs_text = { - argument[len("text_") :]: value for argument, value in kwargs.items() if argument.startswith("text_") - } - - # remove text, vision kwargs from kwargs - for key in kwargs_vision: - del kwargs["vision_" + key] - for key in kwargs_text: - del kwargs["text_" + key] - - # Load and initialize the text and vision model - vision_model = kwargs_vision.pop("model", None) - if vision_model is None: - if vision_model_name_or_path is None: - raise ValueError( - "If `vision_model` is not defined as an argument, a `vision_model_name_or_path` has to be defined" - ) - - if "config" not in kwargs_vision: - vision_config = AutoConfig.from_pretrained(vision_model_name_or_path) - - if vision_config.model_type == "clip": - kwargs_vision["config"] = vision_config.vision_config - vision_model = FlaxCLIPVisionModel.from_pretrained( - vision_model_name_or_path, *model_args, **kwargs_vision - ) - else: - kwargs_vision["config"] = vision_config - vision_model = FlaxAutoModel.from_pretrained(vision_model_name_or_path, *model_args, **kwargs_vision) - - text_model = kwargs_text.pop("model", None) - if text_model is None: - if text_model_name_or_path is None: - raise ValueError( - "If `text_model` is not defined as an argument, a `text_model_name_or_path` has to be defined" - ) - - if "config" not in kwargs_text: - text_config = AutoConfig.from_pretrained(text_model_name_or_path) - kwargs_text["config"] = text_config - - text_model = FlaxAutoModel.from_pretrained(text_model_name_or_path, *model_args, **kwargs_text) - - # instantiate config with corresponding kwargs - dtype = kwargs.pop("dtype", jnp.float32) - config = VisionTextDualEncoderConfig.from_vision_text_configs(vision_model.config, text_model.config, **kwargs) - - # init model - model = cls(config, *model_args, dtype=dtype, **kwargs) - - model.params["vision_model"] = vision_model.params - model.params["text_model"] = text_model.params - - # the projection layers are always newly initialized when loading the model - # using pre-trained vision and text model. - logger.warning( - "The projection layer and logit scale weights `[('visual_projection', 'kernel'), ('text_projection'," - " 'kernel'), ('logit_scale',)]` are newly initialized. You should probably TRAIN this model on a" - " down-stream task to be able to use it for predictions and inference." - ) - - return model - - -VISION_TEXT_DUAL_ENCODER_MODEL_DOCSTRING = r""" - Returns: - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> import jax - >>> from transformers import ( - ... FlaxVisionTextDualEncoderModel, - ... VisionTextDualEncoderProcessor, - ... AutoImageProcessor, - ... AutoTokenizer, - ... ) - - >>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased") - >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224") - >>> processor = VisionTextDualEncoderProcessor(image_processor, tokenizer) - >>> model = FlaxVisionTextDualEncoderModel.from_vision_text_pretrained( - ... "google/vit-base-patch16-224", "google-bert/bert-base-uncased" - ... ) - - >>> # contrastive training - >>> urls = [ - ... "http://images.cocodataset.org/val2017/000000039769.jpg", - ... "https://farm3.staticflickr.com/2674/5850229113_4fe05d5265_z.jpg", - ... ] - >>> images = [Image.open(requests.get(url, stream=True).raw) for url in urls] - >>> inputs = processor( - ... text=["a photo of a cat", "a photo of a dog"], images=images, return_tensors="np", padding=True - ... ) - >>> outputs = model( - ... input_ids=inputs.input_ids, - ... attention_mask=inputs.attention_mask, - ... pixel_values=inputs.pixel_values, - ... ) - >>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score - - >>> # save and load from pretrained - >>> model.save_pretrained("vit-bert") - >>> model = FlaxVisionTextDualEncoderModel.from_pretrained("vit-bert") - - >>> # inference - >>> outputs = model(**inputs) - >>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score - >>> probs = jax.nn.softmax(logits_per_image, axis=1) # we can take the softmax to get the label probabilities - ``` -""" - -overwrite_call_docstring( - FlaxVisionTextDualEncoderModel, - VISION_TEXT_DUAL_ENCODER_INPUTS_DOCSTRING + VISION_TEXT_DUAL_ENCODER_MODEL_DOCSTRING, -) -append_replace_return_docstrings( - FlaxVisionTextDualEncoderModel, output_type=FlaxCLIPOutput, config_class=_CONFIG_FOR_DOC -) - - -__all__ = ["FlaxVisionTextDualEncoderModel"] diff --git a/src/transformers/models/vision_text_dual_encoder/modeling_tf_vision_text_dual_encoder.py b/src/transformers/models/vision_text_dual_encoder/modeling_tf_vision_text_dual_encoder.py deleted file mode 100644 index 42ff0be7a9e8..000000000000 --- a/src/transformers/models/vision_text_dual_encoder/modeling_tf_vision_text_dual_encoder.py +++ /dev/null @@ -1,623 +0,0 @@ -# coding=utf-8 -# Copyright 2023 The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow VisionTextDualEncoder model.""" - -from __future__ import annotations - -import re - -import tensorflow as tf - -from ...configuration_utils import PretrainedConfig -from ...modeling_tf_utils import TFPreTrainedModel, keras, unpack_inputs -from ...tf_utils import shape_list -from ...utils import ( - DUMMY_INPUTS, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from ..auto.configuration_auto import AutoConfig -from ..auto.modeling_tf_auto import TFAutoModel -from ..clip.modeling_tf_clip import CLIPVisionConfig, TFCLIPOutput, TFCLIPVisionModel -from .configuration_vision_text_dual_encoder import VisionTextDualEncoderConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "VisionTextDualEncoderConfig" - -VISION_TEXT_DUAL_ENCODER_START_DOCSTRING = r""" - This class can be used to initialize a vision-text dual encoder model with any pretrained vision autoencoding model - as the vision encoder and any pretrained text model as the text encoder. The vision and text encoders are loaded - via the [`~TFAutoModel.from_pretrained`] method. The projection layers are automatically added to the model and - should be fine-tuned on a downstream task, like contrastive image-text modeling. - - In [LiT: Zero-Shot Transfer with Locked-image Text Tuning](https://huggingface.co/papers/2111.07991) it is shown how - leveraging pre-trained (locked/frozen) image and text model for contrastive learning yields significant improvement - on new zero-shot vision tasks such as image classification or retrieval. - - After such a Vision-Text-Dual-Encoder model has been trained/fine-tuned, it can be saved/loaded just like any other - models (see the examples for more information). - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Keras [Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it as a - regular Keras Model and refer to the TF documentation for all matter related to general usage and behavior. - - Parameters: - config ([`VisionEncoderDecoderConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - - -VISION_TEXT_DUAL_ENCODER_TEXT_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -VISION_TEXT_DUAL_ENCODER_VISION_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using - [`AutoImageProcessor`]. See [`CLIPImageProcessor.__call__`] for details. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -VISION_TEXT_DUAL_ENCODER_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using - an image processor (e.g. if you use ViT as the encoder, you should use [`AutoImageProcessor`]). See - [`ViTImageProcessor.__call__`] for details. - return_loss (`bool`, *optional*): - Whether or not to return the contrastive loss. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.clip.modeling_tf_clip.contrastive_loss -def contrastive_loss(logits: tf.Tensor) -> tf.Tensor: - return tf.math.reduce_mean( - keras.metrics.sparse_categorical_crossentropy( - y_true=tf.range(shape_list(logits)[0]), y_pred=logits, from_logits=True - ) - ) - - -# Copied from transformers.models.clip.modeling_tf_clip.clip_loss -def clip_loss(similarity: tf.Tensor) -> tf.Tensor: - caption_loss = contrastive_loss(similarity) - image_loss = contrastive_loss(tf.transpose(similarity)) - return (caption_loss + image_loss) / 2.0 - - -@add_start_docstrings(VISION_TEXT_DUAL_ENCODER_START_DOCSTRING) -class TFVisionTextDualEncoderModel(TFPreTrainedModel): - config_class = VisionTextDualEncoderConfig - base_model_prefix = "vision_text_dual_encoder" - load_weight_prefix = "tf_vision_text_dual_encoder_model" - - def __init__( - self, - config: VisionTextDualEncoderConfig | None = None, - vision_model: TFPreTrainedModel | None = None, - text_model: TFPreTrainedModel | None = None, - ): - if config is None and (vision_model is None or text_model is None): - raise ValueError("Either a configuration or an vision and a text model has to be provided") - - if config is None: - config = VisionTextDualEncoderConfig.from_vision_text_configs(vision_model.config, text_model.config) - else: - if not isinstance(config, self.config_class): - raise ValueError(f"config: {config} has to be of type {self.config_class}") - - # initialize with config - super().__init__(config) - - if vision_model is None: - if isinstance(config.vision_config, CLIPVisionConfig): - vision_model = TFCLIPVisionModel.from_config(config.vision_config, name="vision_model") - else: - vision_model = TFAutoModel.from_config(config.vision_config, name="vision_model") - - if text_model is None: - text_model = TFAutoModel.from_config(config.text_config, name="text_model") - - self.vision_model = vision_model - self.text_model = text_model - - # make sure that the individual model's config refers to the shared config - # so that the updates to the config will be synced - self.vision_model.config = self.config.vision_config - self.text_model.config = self.config.text_config - - self.vision_embed_dim = config.vision_config.hidden_size - self.text_embed_dim = config.text_config.hidden_size - self.projection_dim = config.projection_dim - - self.visual_projection = keras.layers.Dense(self.projection_dim, use_bias=False, name="visual_projection") - self.text_projection = keras.layers.Dense(self.projection_dim, use_bias=False, name="text_projection") - self.logit_scale = None - self.config = config - - def build(self, input_shape=None): - if self.built: - return - self.built = True - # Build in the build() method to make sure the names are right - initializer = keras.initializers.Constant(self.config.logit_scale_init_value) - self.logit_scale = self.add_weight(shape=(1,), initializer=initializer, name="logit_scale") - - if getattr(self, "visual_projection", None) is not None: - with tf.name_scope(self.visual_projection.name): - self.visual_projection.build([None, None, self.vision_embed_dim]) - if getattr(self, "text_projection", None) is not None: - with tf.name_scope(self.text_projection.name): - self.text_projection.build([None, None, self.text_embed_dim]) - with tf.name_scope(self.vision_model.name): - self.vision_model.build(None) - with tf.name_scope(self.text_model.name): - self.text_model.build(None) - - def tf_to_pt_weight_rename(self, tf_weight): - # Matt: The TF and PT weights don't align because our TF base classes have an extra layer compared to PT models - # (the main model stem is in the MainLayer class). If we remove that layer, then weight names sync up as normal. - # However, the name of that extra layer is the name of the MainLayer in the base model. - if "vision_model" in tf_weight: - if tf_weight.count("vision_model") == 1: - return (re.sub(r"vision_model\..*?\.", "vision_model.", tf_weight),) - elif tf_weight.count("vision_model") == 2: - return (re.sub(r"vision_model\..*?\.vision_model", "vision_model.vision_model", tf_weight),) - else: - raise ValueError( - f"Unexpected weight name {tf_weight}. Please file an issue on the" - " Transformers repo to let us know about this error!" - ) - elif "text_model" in tf_weight: - return (re.sub(r"text_model\..*?\.", "text_model.", tf_weight),) - else: - return (tf_weight,) - - @add_start_docstrings_to_model_forward(VISION_TEXT_DUAL_ENCODER_TEXT_INPUTS_DOCSTRING) - def get_text_features( - self, - input_ids=None, - attention_mask=None, - position_ids=None, - token_type_ids=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - ): - r""" - Returns: - text_features (`tf.Tensor` of shape `(batch_size, output_dim`): The text embeddings obtained by applying - the projection layer to the pooled output of [`TFCLIPTextModel`]. - - Examples: - - ```python - >>> from transformers import TFVisionTextDualEncoderModel, AutoTokenizer - - >>> model = TFVisionTextDualEncoderModel.from_pretrained("clip-italian/clip-italian", from_pt=True) - >>> tokenizer = AutoTokenizer.from_pretrained("clip-italian/clip-italian") - - >>> inputs = tokenizer(["una foto di un gatto", "una foto di un cane"], padding=True, return_tensors="np") - >>> text_features = model.get_text_features(**inputs) - ```""" - text_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - token_type_ids=token_type_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = text_outputs[1] - text_features = self.text_projection(pooled_output) - - return text_features - - @add_start_docstrings_to_model_forward(VISION_TEXT_DUAL_ENCODER_VISION_INPUTS_DOCSTRING) - def get_image_features( - self, - pixel_values=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - ): - r""" - Returns: - image_features (`tf.Tensor` of shape `(batch_size, output_dim`): The image embeddings obtained by applying - the projection layer to the pooled output of [`TFCLIPVisionModel`]. - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import TFVisionTextDualEncoderModel, AutoImageProcessor - - >>> model = TFVisionTextDualEncoderModel.from_pretrained("clip-italian/clip-italian", from_pt=True) - >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224") - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> inputs = image_processor(images=image, return_tensors="np") - - >>> image_features = model.get_image_features(**inputs) - ```""" - vision_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = vision_outputs[1] # pooled_output - image_features = self.visual_projection(pooled_output) - - return image_features - - @unpack_inputs - @add_start_docstrings_to_model_forward(VISION_TEXT_DUAL_ENCODER_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFCLIPOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: tf.Tensor | None = None, - pixel_values: tf.Tensor | None = None, - attention_mask: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - return_loss: bool | None = None, - token_type_ids: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFCLIPOutput: - r""" - Returns: - - Examples: - - ```python - >>> from PIL import Image - >>> import requests - >>> from transformers import ( - ... TFVisionTextDualEncoderModel, - ... VisionTextDualEncoderProcessor, - ... AutoImageProcessor, - ... AutoTokenizer, - ... ) - - >>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased") - >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224") - >>> processor = VisionTextDualEncoderProcessor(image_processor, tokenizer) - >>> model = TFVisionTextDualEncoderModel.from_vision_text_pretrained( - ... "google/vit-base-patch16-224", "google-bert/bert-base-uncased" - ... ) - - >>> # contrastive training - >>> urls = [ - ... "http://images.cocodataset.org/val2017/000000039769.jpg", - ... "https://farm3.staticflickr.com/2674/5850229113_4fe05d5265_z.jpg", - ... ] - >>> images = [Image.open(requests.get(url, stream=True).raw) for url in urls] - >>> inputs = processor( - ... text=["a photo of a cat", "a photo of a dog"], images=images, return_tensors="np", padding=True - ... ) - >>> outputs = model( - ... input_ids=inputs.input_ids, - ... attention_mask=inputs.attention_mask, - ... pixel_values=inputs.pixel_values, - ... return_loss=True, - ... ) - >>> loss, logits_per_image = outputs.loss, outputs.logits_per_image # this is the image-text similarity score - - >>> # save and load from pretrained - >>> model.save_pretrained("vit-bert") - >>> model = TFVisionTextDualEncoderModel.from_pretrained("vit-bert") - - >>> # inference - >>> outputs = model(**inputs) - >>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score - >>> probs = tf.nn.softmax(logits_per_image, axis=1) # we can take the softmax to get the label probabilities - ```""" - return_dict = return_dict if return_dict is not None else self.config.return_dict - - vision_outputs = self.vision_model( - pixel_values=pixel_values, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - text_outputs = self.text_model( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - image_embeds = vision_outputs[1] # pooler_output - image_embeds = self.visual_projection(image_embeds) - - text_embeds = text_outputs[1] # pooler_output - text_embeds = self.text_projection(text_embeds) - - # normalized features - image_embeds = image_embeds / tf.norm(image_embeds, axis=-1, keepdims=True) - text_embeds = text_embeds / tf.norm(text_embeds, axis=-1, keepdims=True) - - # cosine similarity as logits - logit_scale = tf.math.exp(self.logit_scale) - logits_per_text = tf.matmul(text_embeds, image_embeds, transpose_b=True) * logit_scale - logits_per_image = tf.transpose(logits_per_text) - - loss = None - if return_loss: - loss = clip_loss(logits_per_text) - if loss.shape.rank == 0: - loss = tf.expand_dims(loss, 0) - - if not return_dict: - output = (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs) - return ((loss,) + output) if loss is not None else output - - return TFCLIPOutput( - loss=loss, - logits_per_image=logits_per_image, - logits_per_text=logits_per_text, - text_embeds=text_embeds, - image_embeds=image_embeds, - text_model_output=text_outputs, - vision_model_output=vision_outputs, - ) - - @classmethod - def from_vision_text_pretrained( - cls, - vision_model_name_or_path: str | None = None, - text_model_name_or_path: str | None = None, - *model_args, - **kwargs, - ) -> TFPreTrainedModel: - """ - Params: - vision_model_name_or_path (`str`, *optional*, defaults to `None`): - Information necessary to initiate the vision model. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~TFPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *PyTorch checkpoint folder* (e.g, `./pt_model`). In this case, `from_pt` - should be set to `True` and a configuration object should be provided as `config` argument. - - text_model_name_or_path (`str`, *optional*): - Information necessary to initiate the text model. Can be either: - - - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - - A path to a *directory* containing model weights saved using - [`~TFPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *PyTorch checkpoint folder* (e.g, `./pt_model`). In this case, `from_pt` - should be set to `True` and a configuration object should be provided as `config` argument. - - model_args (remaining positional arguments, *optional*): - All remaining positional arguments will be passed to the underlying model's `__init__` method. - - kwargs (remaining dictionary of keyword arguments, *optional*): - Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., - `output_attentions=True`). - - - To update the text configuration, use the prefix *text_* for each configuration parameter. - - To update the vision configuration, use the prefix *vision_* for each configuration parameter. - - To update the parent model configuration, do not use a prefix for each configuration parameter. - - Behaves differently depending on whether a `config` is provided or automatically loaded. - - Example: - - ```python - >>> from transformers import TFVisionTextDualEncoderModel - - >>> # initialize a model from pretrained ViT and BERT models. Note that the projection layers will be randomly initialized. - >>> model = TFVisionTextDualEncoderModel.from_vision_text_pretrained( - ... "google/vit-base-patch16-224", "google-bert/bert-base-uncased" - ... ) - >>> # saving model after fine-tuning - >>> model.save_pretrained("./vit-bert") - >>> # load fine-tuned model - >>> model = TFVisionTextDualEncoderModel.from_pretrained("./vit-bert") - ```""" - kwargs_vision = { - argument[len("vision_") :]: value for argument, value in kwargs.items() if argument.startswith("vision_") - } - - kwargs_text = { - argument[len("text_") :]: value for argument, value in kwargs.items() if argument.startswith("text_") - } - - # remove vision, text kwargs from kwargs - for key in kwargs_vision: - del kwargs["vision_" + key] - for key in kwargs_text: - del kwargs["text_" + key] - - # Load and initialize the vision and text model - vision_model = kwargs_vision.pop("model", None) - if vision_model is None: - if vision_model_name_or_path is None: - raise ValueError( - "If `vision_model` is not defined as an argument, a `vision_model_name_or_path` has to be defined" - ) - kwargs_vision["name"] = "vision_model" - kwargs_vision["load_weight_prefix"] = cls.load_weight_prefix - - vision_config_dict, unused_args = PretrainedConfig.get_config_dict(vision_model_name_or_path, **kwargs) - if vision_config_dict.get("model_type", None) == "clip_vision_model": - vision_config = CLIPVisionConfig.from_dict(vision_config_dict) - else: - vision_config = AutoConfig.from_pretrained(vision_model_name_or_path) - - if vision_config.model_type == "clip_vision_model": - kwargs_vision["config"] = vision_config - vision_class = TFCLIPVisionModel - elif vision_config.model_type == "clip": - kwargs_vision["config"] = vision_config.vision_config - vision_class = TFCLIPVisionModel - else: - kwargs_vision["config"] = vision_config - vision_class = TFAutoModel - vision_model = vision_class.from_pretrained(vision_model_name_or_path, *model_args, **kwargs_vision) - - text_model = kwargs_text.pop("model", None) - if text_model is None: - if text_model_name_or_path is None: - raise ValueError( - "If `text_model` is not defined as an argument, a `text_model_name_or_path` has to be defined" - ) - kwargs_text["name"] = "text_model" - kwargs_text["load_weight_prefix"] = cls.load_weight_prefix - - if "config" not in kwargs_text: - text_config = AutoConfig.from_pretrained(text_model_name_or_path) - kwargs_text["config"] = text_config - - text_model = TFAutoModel.from_pretrained(text_model_name_or_path, *model_args, **kwargs_text) - - # instantiate config with corresponding kwargs - config = VisionTextDualEncoderConfig.from_vision_text_configs(vision_model.config, text_model.config, **kwargs) - - # init model - model = cls(config=config, vision_model=vision_model, text_model=text_model) - - # the projection layers are always newly initialized when loading the model - # using pre-trained vision and text model. - logger.warning( - "The projection layer and logit scale weights `['visual_projection.weight', 'text_projection.weight'," - " 'logit_scale']` are newly initialized. You should probably TRAIN this model on a down-stream task to be" - " able to use it for predictions and inference." - ) - - if vision_model.name != "vision_model": - raise ValueError("vision model must be created with the name `vision_model`.") - if text_model.name != "text_model": - raise ValueError("text model must be created with the name `text_model`.") - - model.build_in_name_scope() # Ensure model is fully built - - return model - - @property - def dummy_inputs(self): - """ - Dummy inputs to build the network. - - Returns: - `dict[str, tf.Tensor]`: The dummy inputs. - """ - input_ids = tf.constant(DUMMY_INPUTS, dtype=tf.int32) - batch_size, seq_len = input_ids.shape - - VISION_DUMMY_INPUTS = tf.random.uniform( - shape=( - batch_size, - self.config.vision_config.num_channels, - self.config.vision_config.image_size, - self.config.vision_config.image_size, - ), - dtype=tf.float32, - ) - pixel_values = tf.constant(VISION_DUMMY_INPUTS) - dummy = {"pixel_values": pixel_values, "input_ids": input_ids} - return dummy - - -__all__ = ["TFVisionTextDualEncoderModel"] diff --git a/src/transformers/models/vision_text_dual_encoder/modeling_vision_text_dual_encoder.py b/src/transformers/models/vision_text_dual_encoder/modeling_vision_text_dual_encoder.py index 039f9fa9e9c5..50d0c433cfce 100755 --- a/src/transformers/models/vision_text_dual_encoder/modeling_vision_text_dual_encoder.py +++ b/src/transformers/models/vision_text_dual_encoder/modeling_vision_text_dual_encoder.py @@ -299,10 +299,8 @@ def from_vision_text_pretrained( - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *PyTorch checkpoint folder* (e.g, `./pt_model`). In this case, `from_pt` - should be set to `True` and a configuration object should be provided as `config` argument. This - loading path is slower than converting the PyTorch checkpoint in a Flax model using the provided - conversion scripts and loading the Flax model afterwards. + - A path or url to a *PyTorch checkpoint folder* (e.g, `./pt_model`). In this case, a configuration + object should be provided as `config` argument. text_model_name_or_path (`str`, *optional*): Information necessary to initiate the text model. Can be either: @@ -310,10 +308,8 @@ def from_vision_text_pretrained( - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. - A path to a *directory* containing model weights saved using [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. - - A path or url to a *PyTorch checkpoint folder* (e.g, `./pt_model`). In this case, `from_pt` - should be set to `True` and a configuration object should be provided as `config` argument. This - loading path is slower than converting the PyTorch checkpoint in a Flax model using the provided - conversion scripts and loading the Flax model afterwards. + - A path or url to a *PyTorch checkpoint folder* (e.g, `./pt_model`). In this case, a configuration + object should be provided as `config` argument. model_args (remaining positional arguments, *optional*): All remaining positional arguments will be passed to the underlying model's `__init__` method. diff --git a/src/transformers/models/visual_bert/modeling_visual_bert.py b/src/transformers/models/visual_bert/modeling_visual_bert.py index cdc3e3adc69b..f0277a7bd820 100755 --- a/src/transformers/models/visual_bert/modeling_visual_bert.py +++ b/src/transformers/models/visual_bert/modeling_visual_bert.py @@ -48,9 +48,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file - self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -503,8 +500,6 @@ class VisualBertPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Embedding)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if hasattr(module, "bias") and module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/vit/__init__.py b/src/transformers/models/vit/__init__.py index 4d6a7a23fa63..fcb1027b0d6d 100644 --- a/src/transformers/models/vit/__init__.py +++ b/src/transformers/models/vit/__init__.py @@ -22,8 +22,6 @@ from .feature_extraction_vit import * from .image_processing_vit import * from .image_processing_vit_fast import * - from .modeling_flax_vit import * - from .modeling_tf_vit import * from .modeling_vit import * else: import sys diff --git a/src/transformers/models/vit/configuration_vit.py b/src/transformers/models/vit/configuration_vit.py index ead272d0086d..7d69cdf51946 100644 --- a/src/transformers/models/vit/configuration_vit.py +++ b/src/transformers/models/vit/configuration_vit.py @@ -71,9 +71,7 @@ class ViTConfig(PretrainedConfig): pooler_output_size (`int`, *optional*): Dimensionality of the pooler layer. If None, defaults to `hidden_size`. pooler_act (`str`, *optional*, defaults to `"tanh"`): - The activation function to be used by the pooler. Keys of ACT2FN are supported for Flax and - Pytorch, and elements of https://www.tensorflow.org/api_docs/python/tf/keras/activations are - supported for Tensorflow. + The activation function to be used by the pooler. Example: diff --git a/src/transformers/models/vit/image_processing_vit.py b/src/transformers/models/vit/image_processing_vit.py index 16216e2eac90..645e2616b2ee 100644 --- a/src/transformers/models/vit/image_processing_vit.py +++ b/src/transformers/models/vit/image_processing_vit.py @@ -195,10 +195,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -228,10 +226,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/vit/modeling_flax_vit.py b/src/transformers/models/vit/modeling_flax_vit.py deleted file mode 100644 index d62ef1b6b928..000000000000 --- a/src/transformers/models/vit/modeling_flax_vit.py +++ /dev/null @@ -1,677 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Google Flax Team Authors and 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. - -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxBaseModelOutputWithPooling, FlaxSequenceClassifierOutput -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward -from .configuration_vit import ViTConfig - - -VIT_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`ViTConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -VIT_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`numpy.ndarray` of shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] - for details. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -class FlaxViTPatchEmbeddings(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - image_size = self.config.image_size - patch_size = self.config.patch_size - num_patches = (image_size // patch_size) * (image_size // patch_size) - self.num_patches = num_patches - self.num_channels = self.config.num_channels - self.projection = nn.Conv( - self.config.hidden_size, - kernel_size=(patch_size, patch_size), - strides=(patch_size, patch_size), - padding="VALID", - dtype=self.dtype, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - ) - - def __call__(self, pixel_values): - num_channels = pixel_values.shape[-1] - if num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - embeddings = self.projection(pixel_values) - batch_size, _, _, channels = embeddings.shape - return jnp.reshape(embeddings, (batch_size, -1, channels)) - - -class FlaxViTEmbeddings(nn.Module): - """Construct the CLS token, position and patch embeddings.""" - - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.cls_token = self.param( - "cls_token", - jax.nn.initializers.variance_scaling(self.config.initializer_range**2, "fan_in", "truncated_normal"), - (1, 1, self.config.hidden_size), - ) - self.patch_embeddings = FlaxViTPatchEmbeddings(self.config, dtype=self.dtype) - num_patches = self.patch_embeddings.num_patches - self.position_embeddings = self.param( - "position_embeddings", - jax.nn.initializers.variance_scaling(self.config.initializer_range**2, "fan_in", "truncated_normal"), - (1, num_patches + 1, self.config.hidden_size), - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, pixel_values, deterministic=True): - batch_size = pixel_values.shape[0] - - embeddings = self.patch_embeddings(pixel_values) - - cls_tokens = jnp.broadcast_to(self.cls_token, (batch_size, 1, self.config.hidden_size)) - embeddings = jnp.concatenate((cls_tokens, embeddings), axis=1) - embeddings = embeddings + self.position_embeddings - embeddings = self.dropout(embeddings, deterministic=deterministic) - return embeddings - - -class FlaxViTSelfAttention(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - if self.config.hidden_size % self.config.num_attention_heads != 0: - raise ValueError( - "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads`:" - " {self.config.num_attention_heads}" - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, mode="fan_in", distribution="truncated_normal" - ), - use_bias=self.config.qkv_bias, - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, mode="fan_in", distribution="truncated_normal" - ), - use_bias=self.config.qkv_bias, - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, mode="fan_in", distribution="truncated_normal" - ), - use_bias=self.config.qkv_bias, - ) - - def __call__(self, hidden_states, deterministic: bool = True, output_attentions: bool = False): - head_dim = self.config.hidden_size // self.config.num_attention_heads - - query_states = self.query(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - value_states = self.value(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - key_states = self.key(hidden_states).reshape( - hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) - ) - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -class FlaxViTSelfOutput(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, input_tensor, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxViTAttention(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.attention = FlaxViTSelfAttention(self.config, dtype=self.dtype) - self.output = FlaxViTSelfOutput(self.config, dtype=self.dtype) - - def __call__(self, hidden_states, deterministic=True, output_attentions: bool = False): - attn_outputs = self.attention(hidden_states, deterministic=deterministic, output_attentions=output_attentions) - attn_output = attn_outputs[0] - hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_outputs[1],) - - return outputs - - -class FlaxViTIntermediate(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - -class FlaxViTOutput(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, attention_output, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = hidden_states + attention_output - return hidden_states - - -class FlaxViTLayer(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.attention = FlaxViTAttention(self.config, dtype=self.dtype) - self.intermediate = FlaxViTIntermediate(self.config, dtype=self.dtype) - self.output = FlaxViTOutput(self.config, dtype=self.dtype) - self.layernorm_before = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.layernorm_after = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states, deterministic: bool = True, output_attentions: bool = False): - attention_outputs = self.attention( - self.layernorm_before(hidden_states), # in ViT, layernorm is applied before self-attention - deterministic=deterministic, - output_attentions=output_attentions, - ) - - attention_output = attention_outputs[0] - - # first residual connection - attention_output = attention_output + hidden_states - - # in ViT, layernorm is also applied after self-attention - layer_output = self.layernorm_after(attention_output) - - hidden_states = self.intermediate(layer_output) - hidden_states = self.output(hidden_states, attention_output, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attention_outputs[1],) - return outputs - - -class FlaxViTLayerCollection(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxViTLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer(hidden_states, deterministic=deterministic, output_attentions=output_attentions) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states,) - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -class FlaxViTEncoder(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layer = FlaxViTLayerCollection(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.layer( - hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -class FlaxViTPooler(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.pooler_output_size, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.pooler_act] - - def __call__(self, hidden_states): - cls_hidden_state = hidden_states[:, 0] - cls_hidden_state = self.dense(cls_hidden_state) - return self.activation(cls_hidden_state) - - -class FlaxViTPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = ViTConfig - base_model_prefix = "vit" - main_input_name = "pixel_values" - module_class: nn.Module = None - - def __init__( - self, - config: ViTConfig, - input_shape=None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - if input_shape is None: - input_shape = (1, config.image_size, config.image_size, config.num_channels) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - pixel_values = jnp.zeros(input_shape, dtype=self.dtype) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, pixel_values, return_dict=False)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - pixel_values, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - return self.module.apply( - {"params": params or self.params}, - jnp.array(pixel_values, dtype=jnp.float32), - not train, - output_attentions, - output_hidden_states, - return_dict, - rngs=rngs, - ) - - -class FlaxViTModule(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - add_pooling_layer: bool = True - - def setup(self): - self.embeddings = FlaxViTEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxViTEncoder(self.config, dtype=self.dtype) - self.layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.pooler = FlaxViTPooler(self.config, dtype=self.dtype) if self.add_pooling_layer else None - - def __call__( - self, - pixel_values, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - hidden_states = self.embeddings(pixel_values, deterministic=deterministic) - - outputs = self.encoder( - hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - hidden_states = self.layernorm(hidden_states) - pooled = self.pooler(hidden_states) if self.add_pooling_layer else None - - if not return_dict: - # if pooled is None, don't return it - if pooled is None: - return (hidden_states,) + outputs[1:] - return (hidden_states, pooled) + outputs[1:] - - return FlaxBaseModelOutputWithPooling( - last_hidden_state=hidden_states, - pooler_output=pooled, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - "The bare ViT Model transformer outputting raw hidden-states without any specific head on top.", - VIT_START_DOCSTRING, -) -class FlaxViTModel(FlaxViTPreTrainedModel): - module_class = FlaxViTModule - - -FLAX_VISION_MODEL_DOCSTRING = """ - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, FlaxViTModel - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k") - >>> model = FlaxViTModel.from_pretrained("google/vit-base-patch16-224-in21k") - - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> last_hidden_states = outputs.last_hidden_state - ``` -""" - -overwrite_call_docstring(FlaxViTModel, FLAX_VISION_MODEL_DOCSTRING) -append_replace_return_docstrings(FlaxViTModel, output_type=FlaxBaseModelOutputWithPooling, config_class=ViTConfig) - - -class FlaxViTForImageClassificationModule(nn.Module): - config: ViTConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.vit = FlaxViTModule(config=self.config, dtype=self.dtype, add_pooling_layer=False) - self.classifier = nn.Dense( - self.config.num_labels, - dtype=self.dtype, - kernel_init=jax.nn.initializers.variance_scaling( - self.config.initializer_range**2, "fan_in", "truncated_normal" - ), - ) - - def __call__( - self, - pixel_values=None, - deterministic: bool = True, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - ): - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.vit( - pixel_values, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - logits = self.classifier(hidden_states[:, 0, :]) - - if not return_dict: - output = (logits,) + outputs[2:] - return output - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - ViT Model transformer with an image classification head on top (a linear layer on top of the final hidden state of - the [CLS] token) e.g. for ImageNet. - """, - VIT_START_DOCSTRING, -) -class FlaxViTForImageClassification(FlaxViTPreTrainedModel): - module_class = FlaxViTForImageClassificationModule - - -FLAX_VISION_CLASSIF_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoImageProcessor, FlaxViTForImageClassification - >>> from PIL import Image - >>> import jax - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224") - >>> model = FlaxViTForImageClassification.from_pretrained("google/vit-base-patch16-224") - - >>> inputs = image_processor(images=image, return_tensors="np") - >>> outputs = model(**inputs) - >>> logits = outputs.logits - - >>> # model predicts one of the 1000 ImageNet classes - >>> predicted_class_idx = jax.numpy.argmax(logits, axis=-1) - >>> print("Predicted class:", model.config.id2label[predicted_class_idx.item()]) - ``` -""" - -overwrite_call_docstring(FlaxViTForImageClassification, FLAX_VISION_CLASSIF_DOCSTRING) -append_replace_return_docstrings( - FlaxViTForImageClassification, output_type=FlaxSequenceClassifierOutput, config_class=ViTConfig -) - - -__all__ = ["FlaxViTForImageClassification", "FlaxViTModel", "FlaxViTPreTrainedModel"] diff --git a/src/transformers/models/vit/modeling_tf_vit.py b/src/transformers/models/vit/modeling_tf_vit.py deleted file mode 100644 index 80d785e32114..000000000000 --- a/src/transformers/models/vit/modeling_tf_vit.py +++ /dev/null @@ -1,906 +0,0 @@ -# coding=utf-8 -# Copyright 2021 Google AI, Ross Wightman, The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 ViT model.""" - -from __future__ import annotations - -import collections.abc -import math - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import TFBaseModelOutput, TFBaseModelOutputWithPooling, TFSequenceClassifierOutput -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - TFSequenceClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list, stable_softmax -from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_vit import ViTConfig - - -logger = logging.get_logger(__name__) - -# General docstring -_CONFIG_FOR_DOC = "ViTConfig" - -# Base docstring -_CHECKPOINT_FOR_DOC = "google/vit-base-patch16-224-in21k" -_EXPECTED_OUTPUT_SHAPE = [1, 197, 768] - -# Image classification docstring -_IMAGE_CLASS_CHECKPOINT = "google/vit-base-patch16-224" -_IMAGE_CLASS_EXPECTED_OUTPUT = "Egyptian cat" - - -class TFViTEmbeddings(keras.layers.Layer): - """ - Construct the CLS token, position and patch embeddings. - - """ - - def __init__(self, config: ViTConfig, **kwargs): - super().__init__(**kwargs) - - self.patch_embeddings = TFViTPatchEmbeddings(config, name="patch_embeddings") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def build(self, input_shape=None): - num_patches = self.patch_embeddings.num_patches - self.cls_token = self.add_weight( - shape=(1, 1, self.config.hidden_size), - initializer=get_initializer(self.config.initializer_range), - trainable=True, - name="cls_token", - ) - self.position_embeddings = self.add_weight( - shape=(1, num_patches + 1, self.config.hidden_size), - initializer=get_initializer(self.config.initializer_range), - trainable=True, - name="position_embeddings", - ) - - if self.built: - return - self.built = True - if getattr(self, "patch_embeddings", None) is not None: - with tf.name_scope(self.patch_embeddings.name): - self.patch_embeddings.build(None) - - def interpolate_pos_encoding(self, embeddings, height, width) -> tf.Tensor: - """ - This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher - resolution images. - - Source: - https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174 - """ - - batch_size, seq_len, dim = shape_list(embeddings) - num_patches = seq_len - 1 - - _, num_positions, _ = shape_list(self.position_embeddings) - num_positions -= 1 - - if num_patches == num_positions and height == width: - return self.position_embeddings - class_pos_embed = self.position_embeddings[:, :1] - patch_pos_embed = self.position_embeddings[:, 1:] - h0 = height // self.config.patch_size - w0 = width // self.config.patch_size - patch_pos_embed = tf.image.resize( - images=tf.reshape( - patch_pos_embed, shape=(1, int(math.sqrt(num_positions)), int(math.sqrt(num_positions)), dim) - ), - size=(h0, w0), - method="bicubic", - ) - - shape = shape_list(patch_pos_embed) - assert h0 == shape[-3] and w0 == shape[-2] - patch_pos_embed = tf.reshape(tensor=patch_pos_embed, shape=(1, -1, dim)) - return tf.concat(values=(class_pos_embed, patch_pos_embed), axis=1) - - def call( - self, pixel_values: tf.Tensor, interpolate_pos_encoding: bool = False, training: bool = False - ) -> tf.Tensor: - batch_size, num_channels, height, width = shape_list(pixel_values) - embeddings = self.patch_embeddings( - pixel_values, interpolate_pos_encoding=interpolate_pos_encoding, training=training - ) - - # add the [CLS] token to the embedded patch tokens - cls_tokens = tf.repeat(self.cls_token, repeats=batch_size, axis=0) - embeddings = tf.concat((cls_tokens, embeddings), axis=1) - - # add positional encoding to each token - if interpolate_pos_encoding: - embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width) - else: - embeddings = embeddings + self.position_embeddings - - embeddings = self.dropout(embeddings, training=training) - - return embeddings - - -# Based on timm implementation, which can be found here: -# https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py -class TFViTPatchEmbeddings(keras.layers.Layer): - """ - This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial - `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a - Transformer. - """ - - def __init__(self, config: ViTConfig, **kwargs): - super().__init__(**kwargs) - image_size, patch_size = config.image_size, config.patch_size - num_channels, hidden_size = config.num_channels, config.hidden_size - - image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) - patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) - num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) - self.image_size = image_size - self.patch_size = patch_size - self.num_patches = num_patches - self.num_channels = num_channels - self.config = config - - self.projection = keras.layers.Conv2D( - filters=hidden_size, - kernel_size=patch_size, - strides=patch_size, - padding="valid", - data_format="channels_last", - use_bias=True, - kernel_initializer=get_initializer(self.config.initializer_range), - bias_initializer="zeros", - name="projection", - ) - - def call( - self, pixel_values: tf.Tensor, interpolate_pos_encoding: bool = False, training: bool = False - ) -> tf.Tensor: - batch_size, num_channels, height, width = shape_list(pixel_values) - if tf.executing_eagerly() and num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the configuration." - ) - if not interpolate_pos_encoding: - if tf.executing_eagerly(): - if height != self.image_size[0] or width != self.image_size[1]: - raise ValueError( - f"Input image size ({height}*{width}) doesn't match model" - f" ({self.image_size[0]}*{self.image_size[1]})." - ) - - # When running on CPU, `keras.layers.Conv2D` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - # shape = (batch_size, in_height, in_width, in_channels=num_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - - projection = self.projection(pixel_values) - - # Change the 2D spatial dimensions to a single temporal dimension. - # shape = (batch_size, num_patches, out_channels=embed_dim) - num_patches = (width // self.patch_size[1]) * (height // self.patch_size[0]) - embeddings = tf.reshape(tensor=projection, shape=(batch_size, num_patches, -1)) - - return embeddings - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, None, self.num_channels]) - - -class TFViTSelfAttention(keras.layers.Layer): - def __init__(self, config: ViTConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - mixed_key_layer = self.key(inputs=hidden_states) - mixed_value_layer = self.value(inputs=hidden_states) - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -class TFViTSelfOutput(keras.layers.Layer): - """ - The residual connection is defined in TFViTLayer instead of here (as is the case with other models), due to the - layernorm applied before each block. - """ - - def __init__(self, config: ViTConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFViTAttention(keras.layers.Layer): - def __init__(self, config: ViTConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFViTSelfAttention(config, name="attention") - self.dense_output = TFViTSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, head_mask=head_mask, output_attentions=output_attentions, training=training - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -class TFViTIntermediate(keras.layers.Layer): - def __init__(self, config: ViTConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -class TFViTOutput(keras.layers.Layer): - def __init__(self, config: ViTConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = hidden_states + input_tensor - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - - -class TFViTLayer(keras.layers.Layer): - """This corresponds to the Block class in the timm implementation.""" - - def __init__(self, config: ViTConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFViTAttention(config, name="attention") - self.intermediate = TFViTIntermediate(config, name="intermediate") - self.vit_output = TFViTOutput(config, name="output") - - self.layernorm_before = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_before") - self.layernorm_after = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_after") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - attention_outputs = self.attention( - # in ViT, layernorm is applied before self-attention - input_tensor=self.layernorm_before(inputs=hidden_states), - head_mask=head_mask, - output_attentions=output_attentions, - training=training, - ) - attention_output = attention_outputs[0] - - # first residual connection - hidden_states = attention_output + hidden_states - - # in ViT, layernorm is also applied after self-attention - layer_output = self.layernorm_after(inputs=hidden_states) - - intermediate_output = self.intermediate(hidden_states=layer_output) - - # second residual connection is done here - layer_output = self.vit_output( - hidden_states=intermediate_output, input_tensor=hidden_states, training=training - ) - outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "vit_output", None) is not None: - with tf.name_scope(self.vit_output.name): - self.vit_output.build(None) - if getattr(self, "layernorm_before", None) is not None: - with tf.name_scope(self.layernorm_before.name): - self.layernorm_before.build([None, None, self.config.hidden_size]) - if getattr(self, "layernorm_after", None) is not None: - with tf.name_scope(self.layernorm_after.name): - self.layernorm_after.build([None, None, self.config.hidden_size]) - - -class TFViTEncoder(keras.layers.Layer): - def __init__(self, config: ViTConfig, **kwargs): - super().__init__(**kwargs) - - self.layer = [TFViTLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states=hidden_states, - head_mask=head_mask[i], - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFViTMainLayer(keras.layers.Layer): - config_class = ViTConfig - - def __init__(self, config: ViTConfig, add_pooling_layer: bool = True, **kwargs): - super().__init__(**kwargs) - - self.config = config - - self.embeddings = TFViTEmbeddings(config, name="embeddings") - self.encoder = TFViTEncoder(config, name="encoder") - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - self.pooler = TFViTPooler(config, name="pooler") if add_pooling_layer else None - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings.patch_embeddings - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - pixel_values: TFModelInputType | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - interpolate_pos_encoding: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - if pixel_values is None: - raise ValueError("You have to specify pixel_values") - - embedding_output = self.embeddings( - pixel_values=pixel_values, - interpolate_pos_encoding=interpolate_pos_encoding, - training=training, - ) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - sequence_output = self.layernorm(inputs=sequence_output) - pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None - - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] - - return TFBaseModelOutputWithPooling( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, self.config.hidden_size]) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - - -class TFViTPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = ViTConfig - base_model_prefix = "vit" - main_input_name = "pixel_values" - - -VIT_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `pixel_values` only and nothing else: `model(pixel_values)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([pixel_values, attention_mask])` or `model([pixel_values, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"pixel_values": pixel_values, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`ViTConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -VIT_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] - for details. - - head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - interpolate_pos_encoding (`bool`, *optional*): - Whether to interpolate the pre-trained position encodings. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare ViT Model transformer outputting raw hidden-states without any specific head on top.", - VIT_START_DOCSTRING, -) -class TFViTModel(TFViTPreTrainedModel): - def __init__(self, config: ViTConfig, *inputs, add_pooling_layer=True, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.vit = TFViTMainLayer(config, add_pooling_layer=add_pooling_layer, name="vit") - - @unpack_inputs - @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPooling, - config_class=_CONFIG_FOR_DOC, - modality="vision", - expected_output=_EXPECTED_OUTPUT_SHAPE, - ) - def call( - self, - pixel_values: TFModelInputType | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - interpolate_pos_encoding: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPooling | tuple[tf.Tensor]: - outputs = self.vit( - pixel_values=pixel_values, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - interpolate_pos_encoding=interpolate_pos_encoding, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "vit", None) is not None: - with tf.name_scope(self.vit.name): - self.vit.build(None) - - -class TFViTPooler(keras.layers.Layer): - def __init__(self, config: ViTConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.pooler_output_size, - kernel_initializer=get_initializer(config.initializer_range), - activation=config.pooler_act, - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - ViT Model transformer with an image classification head on top (a linear layer on top of the final hidden state of - the [CLS] token) e.g. for ImageNet. - - - - Note that it's possible to fine-tune ViT on higher resolution images than the ones it has been trained on, by - setting `interpolate_pos_encoding` to `True` in the forward of the model. This will interpolate the pre-trained - position embeddings to the higher resolution. - - - """, - VIT_START_DOCSTRING, -) -class TFViTForImageClassification(TFViTPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config: ViTConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.num_labels = config.num_labels - self.vit = TFViTMainLayer(config, add_pooling_layer=False, name="vit") - - # Classifier head - self.classifier = keras.layers.Dense( - units=config.num_labels, - kernel_initializer=get_initializer(config.initializer_range), - name="classifier", - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_IMAGE_CLASS_CHECKPOINT, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, - ) - def call( - self, - pixel_values: TFModelInputType | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - interpolate_pos_encoding: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): - Labels for computing the image classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - - outputs = self.vit( - pixel_values=pixel_values, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - interpolate_pos_encoding=interpolate_pos_encoding, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.classifier(inputs=sequence_output[:, 0, :]) - loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "vit", None) is not None: - with tf.name_scope(self.vit.name): - self.vit.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -__all__ = ["TFViTForImageClassification", "TFViTModel", "TFViTPreTrainedModel"] diff --git a/src/transformers/models/vit_mae/__init__.py b/src/transformers/models/vit_mae/__init__.py index 253017c39d6a..c64dd050a60b 100644 --- a/src/transformers/models/vit_mae/__init__.py +++ b/src/transformers/models/vit_mae/__init__.py @@ -19,7 +19,6 @@ if TYPE_CHECKING: from .configuration_vit_mae import * - from .modeling_tf_vit_mae import * from .modeling_vit_mae import * else: import sys diff --git a/src/transformers/models/vit_mae/modeling_tf_vit_mae.py b/src/transformers/models/vit_mae/modeling_tf_vit_mae.py deleted file mode 100644 index d0184e92b37b..000000000000 --- a/src/transformers/models/vit_mae/modeling_tf_vit_mae.py +++ /dev/null @@ -1,1374 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Facebook AI and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 ViT MAE (masked autoencoder) model.""" - -from __future__ import annotations - -import collections.abc -import math -from copy import deepcopy -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...file_utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - replace_return_docstrings, -) -from ...modeling_tf_outputs import TFBaseModelOutput -from ...modeling_tf_utils import ( - TFModelInputType, - TFPreTrainedModel, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list, stable_softmax -from ...utils import logging -from .configuration_vit_mae import ViTMAEConfig - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "ViTMAEConfig" -_CHECKPOINT_FOR_DOC = "facebook/vit-mae-base" - - -@dataclass -class TFViTMAEModelOutput(ModelOutput): - """ - Class for TFViTMAEModel's outputs, with potential hidden states and attentions. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - mask (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Tensor indicating which patches are masked (1) and which are not (0). - ids_restore (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Tensor containing the original index of the (shuffled) masked patches. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus - the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - """ - - last_hidden_state: tf.Tensor | None = None - mask: tf.Tensor | None = None - ids_restore: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFViTMAEDecoderOutput(ModelOutput): - """ - Class for TFViTMAEDecoder's outputs, with potential hidden states and attentions. - - Args: - logits (`tf.Tensor` of shape `(batch_size, sequence_length, patch_size ** 2 * num_channels)`): - Pixel reconstruction logits. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus - the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - """ - - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -@dataclass -class TFViTMAEForPreTrainingOutput(ModelOutput): - """ - Class for TFViTMAEForPreTraining's outputs, with potential hidden states and attentions. - - Args: - loss (`tf.Tensor` of shape `(1,)`): - Pixel reconstruction loss. - logits (`tf.Tensor` of shape `(batch_size, sequence_length, patch_size ** 2 * num_channels)`): - Pixel reconstruction logits. - mask (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Tensor indicating which patches are masked (1) and which are not (0). - ids_restore (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Tensor containing the original index of the (shuffled) masked patches. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus - the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in - the self-attention heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - mask: tf.Tensor | None = None - ids_restore: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -def get_2d_sincos_pos_embed(embed_dim, grid_size, add_cls_token=False): - """ - Create 2D sin/cos positional embeddings. - - Args: - embed_dim (`int`): - Embedding dimension. - grid_size (`int`): - The grid height and width. - add_cls_token (`bool`, *optional*, defaults to `False`): - Whether or not to add a classification (CLS) token. - - Returns: - (`tf.Tensor` of shape (grid_size*grid_size, embed_dim) or (1+grid_size*grid_size, embed_dim): the position - embeddings (with or without classification token) - """ - grid_h = tf.range(grid_size, dtype=tf.float32) - grid_w = tf.range(grid_size, dtype=tf.float32) - grid = tf.meshgrid(grid_w, grid_h) # here w goes first - grid = tf.stack(grid, axis=0) - - grid = tf.reshape(grid, [2, 1, grid_size, grid_size]) - pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid) - if add_cls_token: - pos_embed = tf.concat([tf.zeros((1, embed_dim)), pos_embed], axis=0) - return pos_embed - - -def get_2d_sincos_pos_embed_from_grid(embed_dim, grid): - if embed_dim % 2 != 0: - raise ValueError("embed_dim must be even") - - # use half of dimensions to encode grid_h - emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0]) # (H*W, D/2) - emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1]) # (H*W, D/2) - - emb = tf.concat([emb_h, emb_w], axis=1) # (H*W, D) - return emb - - -def get_1d_sincos_pos_embed_from_grid(embed_dim, pos): - """ - embed_dim: output dimension for each position pos: a list of positions to be encoded: size (M,) out: (M, D) - """ - if embed_dim % 2 != 0: - raise ValueError("embed_dim must be even") - - omega = tf.range(embed_dim // 2, dtype="float32") - omega /= embed_dim / 2.0 - omega = 1.0 / 10000**omega # (D/2,) - - pos = tf.reshape(pos, [-1]) # (M,) - out = tf.einsum("m,d->md", pos, omega) # (M, D/2), outer product - - # half of the positions get sinusoidal pattern and the rest gets - # cosine pattern and then they are concatenated - emb_sin = tf.sin(out) # (M, D/2) - emb_cos = tf.cos(out) # (M, D/2) - - emb = tf.concat([emb_sin, emb_cos], axis=1) # (M, D) - return emb - - -class TFViTMAEEmbeddings(keras.layers.Layer): - """ - Construct the CLS token, position and patch embeddings. - - """ - - def __init__(self, config: ViTMAEConfig, **kwargs): - super().__init__(**kwargs) - - self.patch_embeddings = TFViTMAEPatchEmbeddings(config, name="patch_embeddings") - self.num_patches = self.patch_embeddings.num_patches - - self.config = config - - def build(self, input_shape=None): - self.cls_token = self.add_weight( - shape=(1, 1, self.config.hidden_size), - initializer=tf.random_normal_initializer(stddev=self.config.initializer_range), - trainable=True, - name="cls_token", - ) - self.position_embeddings = self.add_weight( - shape=(1, self.num_patches + 1, self.config.hidden_size), - initializer="zeros", - trainable=False, # fixed sin-cos embedding - name="position_embeddings", - ) - pos_embed = get_2d_sincos_pos_embed( - self.position_embeddings.shape[-1], - int(self.patch_embeddings.num_patches**0.5), - add_cls_token=True, - )[None, ...] - self.position_embeddings.assign(pos_embed) - - if self.built: - return - self.built = True - if getattr(self, "patch_embeddings", None) is not None: - with tf.name_scope(self.patch_embeddings.name): - self.patch_embeddings.build(None) - - def interpolate_pos_encoding(self, embeddings, height, width) -> tf.Tensor: - """ - This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher - resolution images. - - Source: - https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174 - """ - - batch_size, seq_len, dim = shape_list(embeddings) - num_patches = seq_len - 1 - - _, num_positions, _ = shape_list(self.position_embeddings) - num_positions -= 1 - - if num_patches == num_positions and height == width: - return self.position_embeddings - class_pos_embed = self.position_embeddings[:, :1] - patch_pos_embed = self.position_embeddings[:, 1:] - h0 = height // self.config.patch_size - w0 = width // self.config.patch_size - patch_pos_embed = tf.image.resize( - images=tf.reshape( - patch_pos_embed, shape=(1, int(math.sqrt(num_positions)), int(math.sqrt(num_positions)), dim) - ), - size=(h0, w0), - method="bicubic", - ) - - patch_pos_embed = tf.reshape(tensor=patch_pos_embed, shape=(1, -1, dim)) - return tf.concat(values=(class_pos_embed, patch_pos_embed), axis=1) - - def random_masking(self, sequence: tf.Tensor, noise: tf.Tensor | None = None): - """ - Perform per-sample random masking by per-sample shuffling. Per-sample shuffling is done by argsort random - noise. - - Args: - sequence (`tf.Tensor` of shape `(batch_size, sequence_length, dim)`) - noise (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*) which is - mainly used for testing purposes to control randomness and maintain the reproducibility - """ - batch_size, seq_length, dim = shape_list(sequence) - len_keep = int(seq_length * (1 - self.config.mask_ratio)) - - if noise is None: - noise = tf.random.uniform(shape=(batch_size, seq_length), minval=0.0, maxval=1.0) # noise in [0, 1) - - # sort noise for each sample - ids_shuffle = tf.argsort(noise, axis=1) # ascend: small is keep, large is remove - ids_restore = tf.argsort(ids_shuffle, axis=1) - - # keep the first subset - ids_keep = ids_shuffle[:, :len_keep] - sequence_unmasked = tf.gather( - sequence, - axis=1, - batch_dims=1, - indices=ids_keep, - ) - - # generate the binary mask: 0 is keep, 1 is remove - # this hack is needed because TF's EagerTensors don't support - # assignment - mask_keep = tf.zeros((batch_size, len_keep)) - mask_remove = tf.ones((batch_size, seq_length - len_keep)) - mask = tf.concat([mask_keep, mask_remove], axis=-1) - - # unshuffle to get the binary mask - mask = tf.gather(mask, axis=1, batch_dims=1, indices=ids_restore) - - return sequence_unmasked, mask, ids_restore - - def call( - self, pixel_values: tf.Tensor, noise: tf.Tensor | None = None, interpolate_pos_encoding: bool = False - ) -> tf.Tensor: - batch_size, num_channels, height, width = shape_list(pixel_values) - embeddings = self.patch_embeddings(pixel_values, interpolate_pos_encoding=interpolate_pos_encoding) - if interpolate_pos_encoding: - position_embeddings = self.interpolate_pos_encoding(embeddings, height, width) - else: - position_embeddings = self.position_embeddings - # add position embeddings w/o cls token - embeddings = embeddings + position_embeddings[:, 1:, :] - - # masking: length -> length * config.mask_ratio - embeddings, mask, ids_restore = self.random_masking(embeddings, noise) - - # append cls token - cls_token = self.cls_token + position_embeddings[:, :1, :] - cls_tokens = tf.tile(cls_token, (shape_list(embeddings)[0], 1, 1)) - embeddings = tf.concat([cls_tokens, embeddings], axis=1) - - return embeddings, mask, ids_restore - - -class TFViTMAEPatchEmbeddings(keras.layers.Layer): - """ - This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial - `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a - Transformer. - """ - - def __init__(self, config: ViTMAEConfig, **kwargs): - super().__init__(**kwargs) - image_size, patch_size = config.image_size, config.patch_size - num_channels, hidden_size = config.num_channels, config.hidden_size - image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) - patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) - num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) - self.image_size = image_size - self.patch_size = patch_size - self.num_patches = num_patches - self.num_channels = num_channels - self.config = config - - self.projection = keras.layers.Conv2D( - filters=hidden_size, - kernel_size=patch_size, - strides=patch_size, - padding="valid", - data_format="channels_last", - kernel_initializer="glorot_uniform", # following torch.nn.Linear - bias_initializer="zeros", - name="projection", - ) - - def call( - self, pixel_values: tf.Tensor, training: bool = False, interpolate_pos_encoding: bool = False - ) -> tf.Tensor: - batch_size, num_channels, height, width = shape_list(pixel_values) - if tf.executing_eagerly(): - if num_channels != self.num_channels: - raise ValueError( - "Make sure that the channel dimension of the pixel values match with the one set in the" - " configuration." - ) - if not interpolate_pos_encoding and (height != self.image_size[0] or width != self.image_size[1]): - raise ValueError( - f"Input image size ({height}*{width}) doesn't match model" - f" ({self.image_size[0]}*{self.image_size[1]})." - ) - - # When running on CPU, `keras.layers.Conv2D` doesn't support `NCHW` format. - # So change the input format from `NCHW` to `NHWC`. - # shape = (batch_size, in_height, in_width, in_channels=num_channels) - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - - projection = self.projection(pixel_values) - - # Change the 2D spatial dimensions to a single temporal dimension. - # shape = (batch_size, num_patches, out_channels=embed_dim) - num_patches = (width // self.patch_size[1]) * (height // self.patch_size[0]) - x = tf.reshape(tensor=projection, shape=(batch_size, num_patches, -1)) - - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, None, self.num_channels]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTSelfAttention with ViT->ViTMAE -class TFViTMAESelfAttention(keras.layers.Layer): - def __init__(self, config: ViTMAEConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - mixed_key_layer = self.key(inputs=hidden_states) - mixed_value_layer = self.value(inputs=hidden_states) - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) - value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTSelfOutput with ViT->ViTMAE -class TFViTMAESelfOutput(keras.layers.Layer): - """ - The residual connection is defined in TFViTMAELayer instead of here (as is the case with other models), due to the - layernorm applied before each block. - """ - - def __init__(self, config: ViTMAEConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTAttention with ViT->ViTMAE -class TFViTMAEAttention(keras.layers.Layer): - def __init__(self, config: ViTMAEConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFViTMAESelfAttention(config, name="attention") - self.dense_output = TFViTMAESelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, head_mask=head_mask, output_attentions=output_attentions, training=training - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTIntermediate with ViT->ViTMAE -class TFViTMAEIntermediate(keras.layers.Layer): - def __init__(self, config: ViTMAEConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTOutput with ViT->ViTMAE -class TFViTMAEOutput(keras.layers.Layer): - def __init__(self, config: ViTMAEConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = hidden_states + input_tensor - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTLayer with ViT->ViTMAE -class TFViTMAELayer(keras.layers.Layer): - """This corresponds to the Block class in the timm implementation.""" - - def __init__(self, config: ViTMAEConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFViTMAEAttention(config, name="attention") - self.intermediate = TFViTMAEIntermediate(config, name="intermediate") - self.vit_output = TFViTMAEOutput(config, name="output") - - self.layernorm_before = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_before") - self.layernorm_after = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm_after") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - attention_outputs = self.attention( - # in ViTMAE, layernorm is applied before self-attention - input_tensor=self.layernorm_before(inputs=hidden_states), - head_mask=head_mask, - output_attentions=output_attentions, - training=training, - ) - attention_output = attention_outputs[0] - - # first residual connection - hidden_states = attention_output + hidden_states - - # in ViTMAE, layernorm is also applied after self-attention - layer_output = self.layernorm_after(inputs=hidden_states) - - intermediate_output = self.intermediate(hidden_states=layer_output) - - # second residual connection is done here - layer_output = self.vit_output( - hidden_states=intermediate_output, input_tensor=hidden_states, training=training - ) - outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "vit_output", None) is not None: - with tf.name_scope(self.vit_output.name): - self.vit_output.build(None) - if getattr(self, "layernorm_before", None) is not None: - with tf.name_scope(self.layernorm_before.name): - self.layernorm_before.build([None, None, self.config.hidden_size]) - if getattr(self, "layernorm_after", None) is not None: - with tf.name_scope(self.layernorm_after.name): - self.layernorm_after.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.vit.modeling_tf_vit.TFViTEncoder with ViT->ViTMAE -class TFViTMAEEncoder(keras.layers.Layer): - def __init__(self, config: ViTMAEConfig, **kwargs): - super().__init__(**kwargs) - - self.layer = [TFViTMAELayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - head_mask: tf.Tensor, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states=hidden_states, - head_mask=head_mask[i], - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFViTMAEMainLayer(keras.layers.Layer): - config_class = ViTMAEConfig - - def __init__(self, config: ViTMAEConfig, **kwargs): - super().__init__(**kwargs) - - self.config = config - - self.embeddings = TFViTMAEEmbeddings(config, name="embeddings") - self.encoder = TFViTMAEEncoder(config, name="encoder") - self.layernorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") - - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings.patch_embeddings - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - pixel_values: TFModelInputType | None = None, - noise: tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - interpolate_pos_encoding: bool = False, - ) -> TFViTMAEModelOutput | tuple[tf.Tensor]: - embedding_output, mask, ids_restore = self.embeddings( - pixel_values=pixel_values, - training=training, - noise=noise, - interpolate_pos_encoding=interpolate_pos_encoding, - ) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - embedding_output, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - sequence_output = self.layernorm(inputs=sequence_output) - - if not return_dict: - return (sequence_output, mask, ids_restore) + encoder_outputs[1:] - - return TFViTMAEModelOutput( - last_hidden_state=sequence_output, - mask=mask, - ids_restore=ids_restore, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "layernorm", None) is not None: - with tf.name_scope(self.layernorm.name): - self.layernorm.build([None, None, self.config.hidden_size]) - - -class TFViTMAEPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = ViTMAEConfig - base_model_prefix = "vit" - main_input_name = "pixel_values" - - -VIT_MAE_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `pixel_values` only and nothing else: `model(pixel_values)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([pixel_values, attention_mask])` or `model([pixel_values, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"pixel_values": pixel_values, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`ViTMAEConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -VIT_MAE_INPUTS_DOCSTRING = r""" - Args: - pixel_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` ``dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): - Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] - for details. - - head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - - return_dict (`bool`, *optional*): - Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. This argument can be used - in eager mode, in graph mode the value will always be set to True. - - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). - - interpolate_pos_encoding (`bool`, *optional*, defaults to `False`): - Whether to interpolate the position encodings at the encoder and decoder. -""" - - -@add_start_docstrings( - "The bare ViTMAE Model transformer outputting raw hidden-states without any specific head on top.", - VIT_MAE_START_DOCSTRING, -) -class TFViTMAEModel(TFViTMAEPreTrainedModel): - def __init__(self, config: ViTMAEConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.vit = TFViTMAEMainLayer(config, name="vit") - - def get_input_embeddings(self): - return self.vit.get_input_embeddings() - - @unpack_inputs - @add_start_docstrings_to_model_forward(VIT_MAE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFViTMAEModelOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: TFModelInputType | None = None, - noise: tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - interpolate_pos_encoding: bool = False, - ) -> TFViTMAEModelOutput | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, TFViTMAEModel - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/vit-mae-base") - >>> model = TFViTMAEModel.from_pretrained("facebook/vit-mae-base") - - >>> inputs = image_processor(images=image, return_tensors="tf") - >>> outputs = model(**inputs) - >>> last_hidden_states = outputs.last_hidden_state - ```""" - outputs = self.vit( - pixel_values=pixel_values, - noise=noise, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - interpolate_pos_encoding=interpolate_pos_encoding, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "vit", None) is not None: - with tf.name_scope(self.vit.name): - self.vit.build(None) - - -class TFViTMAEDecoder(keras.layers.Layer): - def __init__(self, config, num_patches, **kwargs): - super().__init__(**kwargs) - self.decoder_embed = keras.layers.Dense(config.decoder_hidden_size, name="decoder_embed") - - decoder_config = deepcopy(config) - decoder_config.hidden_size = config.decoder_hidden_size - decoder_config.num_hidden_layers = config.decoder_num_hidden_layers - decoder_config.num_attention_heads = config.decoder_num_attention_heads - decoder_config.intermediate_size = config.decoder_intermediate_size - self.decoder_layers = [ - TFViTMAELayer(decoder_config, name=f"decoder_layers.{j}") for j in range(config.decoder_num_hidden_layers) - ] - - self.decoder_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="decoder_norm") - self.decoder_pred = keras.layers.Dense( - config.patch_size**2 * config.num_channels, - kernel_initializer=get_initializer(config.initializer_range), - name="decoder_pred", - ) # encoder to decoder - self.config = config - self.num_patches = num_patches - - def build(self, input_shape=None): - self.mask_token = self.add_weight( - shape=(1, 1, self.config.decoder_hidden_size), - initializer=tf.random_normal_initializer(stddev=self.config.initializer_range), - trainable=True, - name="mask_token", - ) - self.decoder_pos_embed = self.add_weight( - shape=(1, self.num_patches + 1, self.config.decoder_hidden_size), - initializer="zeros", - trainable=False, - name="decoder_pos_embed", - ) - decoder_pos_embed = get_2d_sincos_pos_embed( - self.decoder_pos_embed.shape[-1], - int(self.num_patches**0.5), - add_cls_token=True, - )[None, ...] - self.decoder_pos_embed.assign(decoder_pos_embed) - - if self.built: - return - self.built = True - if getattr(self, "decoder_embed", None) is not None: - with tf.name_scope(self.decoder_embed.name): - self.decoder_embed.build([None, None, self.config.hidden_size]) - if getattr(self, "decoder_norm", None) is not None: - with tf.name_scope(self.decoder_norm.name): - self.decoder_norm.build([None, None, self.config.decoder_hidden_size]) - if getattr(self, "decoder_pred", None) is not None: - with tf.name_scope(self.decoder_pred.name): - self.decoder_pred.build([None, None, self.config.decoder_hidden_size]) - if getattr(self, "decoder_layers", None) is not None: - for layer in self.decoder_layers: - with tf.name_scope(layer.name): - layer.build(None) - - def interpolate_pos_encoding(self, embeddings) -> tf.Tensor: - """ - This method is a modified version of the interpolation function for ViT-mae model at the decoder, that - allows to interpolate the pre-trained decoder position encodings, to be able to use the model on higher - resolution images. - - Source: - https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174 - """ - - # [batch_size, num_patches + 1, hidden_size] - _, num_positions, dim = shape_list(self.decoder_pos_embed) - - # -1 removes the class dimension since we later append it without interpolation - seq_len = shape_list(embeddings)[1] - 1 - num_positions = num_positions - 1 - - # Separation of class token and patch tokens - class_pos_embed = self.decoder_pos_embed[:, :1, :] - patch_pos_embed = self.decoder_pos_embed[:, 1:, :] - - # interpolate the position embeddings - patch_pos_embed = tf.image.resize( - images=tf.reshape(patch_pos_embed, shape=(1, 1, -1, dim)), - size=(1, seq_len), - method="bicubic", - ) - - # [1, seq_len, hidden_size] - patch_pos_embed = tf.reshape(tensor=patch_pos_embed, shape=(1, -1, dim)) - # Adding the class token back - return tf.concat(values=(class_pos_embed, patch_pos_embed), axis=1) - - def call( - self, - hidden_states, - ids_restore, - output_attentions=False, - output_hidden_states=False, - return_dict=True, - interpolate_pos_encoding=False, - ): - # embed tokens - x = self.decoder_embed(hidden_states) - # append mask tokens to sequence - mask_tokens = tf.tile( - self.mask_token, - (shape_list(x)[0], shape_list(ids_restore)[1] + 1 - shape_list(x)[1], 1), - ) - x_ = tf.concat([x[:, 1:, :], mask_tokens], axis=1) # no cls token - x_ = tf.gather(x_, axis=1, batch_dims=1, indices=ids_restore) # unshuffle - x = tf.concat([x[:, :1, :], x_], axis=1) # append cls token - if interpolate_pos_encoding: - decoder_pos_embed = self.interpolate_pos_encoding(x) - else: - decoder_pos_embed = self.decoder_pos_embed - # add pos embed - hidden_states = x + decoder_pos_embed - # apply Transformer layers (blocks) - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - for i, layer_module in enumerate(self.decoder_layers): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( - hidden_states, - head_mask=None, - output_attentions=output_attentions, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - hidden_states = self.decoder_norm(hidden_states) - - # predictor projection - logits = self.decoder_pred(hidden_states) - - # remove cls token - logits = logits[:, 1:, :] - - if not return_dict: - return tuple(v for v in [logits, all_hidden_states, all_self_attentions] if v is not None) - return TFViTMAEDecoderOutput(logits=logits, hidden_states=all_hidden_states, attentions=all_self_attentions) - - -@add_start_docstrings( - "The ViTMAE Model transformer with the decoder on top for self-supervised pre-training.", - VIT_MAE_START_DOCSTRING, -) -class TFViTMAEForPreTraining(TFViTMAEPreTrainedModel): - def __init__(self, config): - super().__init__(config) - self.config = config - - self.vit = TFViTMAEMainLayer(config, name="vit") - self.decoder = TFViTMAEDecoder( - config, - num_patches=self.vit.embeddings.num_patches, - name="decoder", - ) - - def get_input_embeddings(self): - return self.vit.get_input_embeddings() - - def _prune_heads(self, heads_to_prune): - raise NotImplementedError - - def patchify(self, pixel_values, interpolate_pos_encoding: bool = False): - """ - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, height, width, num_channels)` or `(batch_size, num_channels, height, width)`): - Pixel values. - interpolate_pos_encoding (`bool`, default `False`): - interpolation flag passed during the forward pass. - - Returns: - `tf.Tensor` of shape `(batch_size, num_patches, patch_size**2 * num_channels)`: - Patchified pixel values. - """ - patch_size, num_channels = self.config.patch_size, self.config.num_channels - # make sure channels are last - if shape_list(pixel_values)[1] == num_channels: - pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) - - # sanity checks - if not interpolate_pos_encoding: - tf.debugging.assert_equal( - shape_list(pixel_values)[1], - shape_list(pixel_values)[2], - message="Make sure the pixel values have a squared size", - ) - tf.debugging.assert_equal( - shape_list(pixel_values)[1] % patch_size, - 0, - message="Make sure the pixel values have a size that is divisible by the patch size", - ) - tf.debugging.assert_equal( - shape_list(pixel_values)[3], - num_channels, - message=( - "Make sure the number of channels of the pixel values is equal to the one set in the configuration" - ), - ) - - # patchify - batch_size = shape_list(pixel_values)[0] - num_patches_h = shape_list(pixel_values)[1] // patch_size - num_patches_w = shape_list(pixel_values)[2] // patch_size - patchified_pixel_values = tf.reshape( - pixel_values, - (batch_size, num_patches_h, patch_size, num_patches_w, patch_size, num_channels), - ) - patchified_pixel_values = tf.einsum("nhpwqc->nhwpqc", patchified_pixel_values) - patchified_pixel_values = tf.reshape( - patchified_pixel_values, - (batch_size, num_patches_h * num_patches_w, patch_size**2 * num_channels), - ) - return patchified_pixel_values - - def unpatchify(self, patchified_pixel_values, original_image_size: tuple[int, int] | None = None): - """ - Args: - patchified_pixel_values (`tf.Tensor` of shape `(batch_size, num_patches, patch_size**2 * num_channels)`: - Patchified pixel values. - original_image_size (`tuple[int, int]`, *optional*): - Original image size. - - Returns: - `tf.Tensor` of shape `(batch_size, height, width, num_channels)`: - Pixel values. - """ - patch_size, num_channels = self.config.patch_size, self.config.num_channels - original_image_size = ( - original_image_size - if original_image_size is not None - else (self.config.image_size, self.config.image_size) - ) - original_height, original_width = original_image_size - num_patches_h = original_height // patch_size - num_patches_w = original_width // patch_size - # sanity check - tf.debugging.assert_equal( - num_patches_h * num_patches_w, - shape_list(patchified_pixel_values)[1], - message=f"The number of patches in the patchified pixel values is {shape_list(patchified_pixel_values)[1]} does not match the patches of original image {num_patches_w}*{num_patches_h}", - ) - - # unpatchify - batch_size = shape_list(patchified_pixel_values)[0] - patchified_pixel_values = tf.reshape( - patchified_pixel_values, - (batch_size, num_patches_h, num_patches_w, patch_size, patch_size, num_channels), - ) - patchified_pixel_values = tf.einsum("nhwpqc->nhpwqc", patchified_pixel_values) - pixel_values = tf.reshape( - patchified_pixel_values, - (batch_size, num_patches_h * patch_size, num_patches_w * patch_size, num_channels), - ) - return pixel_values - - def forward_loss(self, pixel_values, pred, mask, interpolate_pos_encoding: bool = False): - """ - Args: - pixel_values (`tf.Tensor` of shape `(batch_size, height, width, num_channels)`): - Pixel values. - pred (`tf.Tensor` of shape `(batch_size, num_patches, patch_size**2 * num_channels)`: - Predicted pixel values. - mask (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Tensor indicating which patches are masked (1) and which are not (0). - interpolate_pos_encoding (`bool`, *optional*, default `False`): - interpolation flag passed during the forward pass. - - Returns: - `tf.Tensor`: Pixel reconstruction loss. - """ - target = self.patchify(pixel_values, interpolate_pos_encoding=interpolate_pos_encoding) - if self.config.norm_pix_loss: - mean = tf.reduce_mean(target, axis=-1, keepdims=True) - var = tf.math.reduce_variance(target, axis=-1, keepdims=True) - target = (target - mean) / (var + 1.0e-6) ** 0.5 - - loss = (pred - target) ** 2 - loss = tf.reduce_mean(loss, axis=-1) # [batch_size, num_patches], mean loss per patch - - loss = tf.reduce_sum(loss * mask) / tf.reduce_sum(mask) # mean loss on removed patches - loss = tf.reshape(loss, (1,)) - return loss - - @unpack_inputs - @add_start_docstrings_to_model_forward(VIT_MAE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFViTMAEForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - pixel_values: TFModelInputType | None = None, - noise: tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - interpolate_pos_encoding: bool = False, - ) -> TFViTMAEForPreTrainingOutput | tuple[tf.Tensor]: - r""" - Returns: - - Examples: - - ```python - >>> from transformers import AutoImageProcessor, TFViTMAEForPreTraining - >>> from PIL import Image - >>> import requests - - >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" - >>> image = Image.open(requests.get(url, stream=True).raw) - - >>> image_processor = AutoImageProcessor.from_pretrained("facebook/vit-mae-base") - >>> model = TFViTMAEForPreTraining.from_pretrained("facebook/vit-mae-base") - - >>> inputs = image_processor(images=image, return_tensors="pt") - >>> outputs = model(**inputs) - >>> loss = outputs.loss - >>> mask = outputs.mask - >>> ids_restore = outputs.ids_restore - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.vit( - pixel_values=pixel_values, - noise=noise, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - interpolate_pos_encoding=interpolate_pos_encoding, - ) - - latent = outputs.last_hidden_state - ids_restore = outputs.ids_restore - mask = outputs.mask - - # [batch_size, num_patches, patch_size**2*3] - decoder_outputs = self.decoder(latent, ids_restore, interpolate_pos_encoding=interpolate_pos_encoding) - logits = decoder_outputs.logits - - loss = self.forward_loss(pixel_values, logits, mask, interpolate_pos_encoding=interpolate_pos_encoding) - - if not return_dict: - output = (logits, mask, ids_restore) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFViTMAEForPreTrainingOutput( - loss=loss, - logits=logits, - mask=mask, - ids_restore=ids_restore, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "vit", None) is not None: - with tf.name_scope(self.vit.name): - self.vit.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -__all__ = ["TFViTMAEForPreTraining", "TFViTMAEModel", "TFViTMAEPreTrainedModel"] diff --git a/src/transformers/models/vit_mae/modeling_vit_mae.py b/src/transformers/models/vit_mae/modeling_vit_mae.py index a74d172805bd..72c90af31f81 100755 --- a/src/transformers/models/vit_mae/modeling_vit_mae.py +++ b/src/transformers/models/vit_mae/modeling_vit_mae.py @@ -555,8 +555,6 @@ class ViTMAEPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/vit_msn/modeling_vit_msn.py b/src/transformers/models/vit_msn/modeling_vit_msn.py index eee739b13864..d66d94fcf56e 100644 --- a/src/transformers/models/vit_msn/modeling_vit_msn.py +++ b/src/transformers/models/vit_msn/modeling_vit_msn.py @@ -395,8 +395,6 @@ class ViTMSNPreTrainedModel(PreTrainedModel): def _init_weights(self, module: Union[nn.Linear, nn.Conv2d, nn.LayerNorm]) -> None: """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/vitdet/modeling_vitdet.py b/src/transformers/models/vitdet/modeling_vitdet.py index 8debcaf11fa5..f6702bc1a124 100644 --- a/src/transformers/models/vitdet/modeling_vitdet.py +++ b/src/transformers/models/vitdet/modeling_vitdet.py @@ -266,11 +266,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/vitmatte/image_processing_vitmatte.py b/src/transformers/models/vitmatte/image_processing_vitmatte.py index 6e65a634d23d..87b6d2662ef4 100644 --- a/src/transformers/models/vitmatte/image_processing_vitmatte.py +++ b/src/transformers/models/vitmatte/image_processing_vitmatte.py @@ -188,10 +188,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -216,16 +214,10 @@ def preprocess( trimaps = make_flat_list_of_images(trimaps, expected_ndims=2) if not valid_images(trimaps): - raise ValueError( - "Invalid trimap type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid trimap type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/vitpose/image_processing_vitpose.py b/src/transformers/models/vitpose/image_processing_vitpose.py index 5bdefe3064bb..c4a10d35944b 100644 --- a/src/transformers/models/vitpose/image_processing_vitpose.py +++ b/src/transformers/models/vitpose/image_processing_vitpose.py @@ -465,10 +465,8 @@ def preprocess( return_tensors (`str` or [`~utils.TensorType`], *optional*, defaults to `'np'`): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: @@ -487,10 +485,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") if isinstance(boxes, list) and len(images) != len(boxes): raise ValueError(f"Batch of images and boxes mismatch : {len(images)} != {len(boxes)}") diff --git a/src/transformers/models/vivit/image_processing_vivit.py b/src/transformers/models/vivit/image_processing_vivit.py index ab32d5b47eef..e287e1d608a2 100644 --- a/src/transformers/models/vivit/image_processing_vivit.py +++ b/src/transformers/models/vivit/image_processing_vivit.py @@ -338,10 +338,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -370,10 +368,7 @@ def preprocess( crop_size = get_size_dict(crop_size, param_name="crop_size") if not valid_images(videos): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") videos = make_batched(videos) diff --git a/src/transformers/models/vivit/modeling_vivit.py b/src/transformers/models/vivit/modeling_vivit.py index b27b56e640c6..a18bcc49bf5c 100755 --- a/src/transformers/models/vivit/modeling_vivit.py +++ b/src/transformers/models/vivit/modeling_vivit.py @@ -400,8 +400,6 @@ class VivitPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv3d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/vjepa2/modeling_vjepa2.py b/src/transformers/models/vjepa2/modeling_vjepa2.py index eedc94b845a4..714c3d92d827 100644 --- a/src/transformers/models/vjepa2/modeling_vjepa2.py +++ b/src/transformers/models/vjepa2/modeling_vjepa2.py @@ -350,11 +350,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/voxtral/processing_voxtral.py b/src/transformers/models/voxtral/processing_voxtral.py index 0cf2d121f9da..1166c9636307 100644 --- a/src/transformers/models/voxtral/processing_voxtral.py +++ b/src/transformers/models/voxtral/processing_voxtral.py @@ -251,10 +251,8 @@ def __call__( `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] with the following fields: diff --git a/src/transformers/models/wav2vec2/__init__.py b/src/transformers/models/wav2vec2/__init__.py index 3516b478194d..aa3a5c4c82f8 100644 --- a/src/transformers/models/wav2vec2/__init__.py +++ b/src/transformers/models/wav2vec2/__init__.py @@ -20,8 +20,6 @@ if TYPE_CHECKING: from .configuration_wav2vec2 import * from .feature_extraction_wav2vec2 import * - from .modeling_flax_wav2vec2 import * - from .modeling_tf_wav2vec2 import * from .modeling_wav2vec2 import * from .processing_wav2vec2 import * from .tokenization_wav2vec2 import * diff --git a/src/transformers/models/wav2vec2/feature_extraction_wav2vec2.py b/src/transformers/models/wav2vec2/feature_extraction_wav2vec2.py index 6bca69e82d09..3b830c314b31 100644 --- a/src/transformers/models/wav2vec2/feature_extraction_wav2vec2.py +++ b/src/transformers/models/wav2vec2/feature_extraction_wav2vec2.py @@ -160,7 +160,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/wav2vec2/modeling_flax_wav2vec2.py b/src/transformers/models/wav2vec2/modeling_flax_wav2vec2.py deleted file mode 100644 index bc5a396dcad4..000000000000 --- a/src/transformers/models/wav2vec2/modeling_flax_wav2vec2.py +++ /dev/null @@ -1,1423 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Fairseq Authors and the HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax Wav2Vec2 model.""" - -from functools import partial -from typing import Optional, Union - -import flax -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxCausalLMOutput -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import ModelOutput, add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_wav2vec2 import Wav2Vec2Config - - -logger = logging.get_logger(__name__) - - -@flax.struct.dataclass -class FlaxWav2Vec2BaseModelOutput(ModelOutput): - """ - Output type of [`FlaxWav2Vec2BaseModelOutput`], with potential hidden states and attentions. - - Args: - last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - extract_features (`jnp.ndarray` of shape `(batch_size, sequence_length, last_conv_dim)`): - Sequence of extracted feature vectors of the last convolutional layer of the model with `last_conv_dim` - being the dimension of the last convolutional layer. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: jnp.ndarray = None - extract_features: jnp.ndarray = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -@flax.struct.dataclass -class FlaxWav2Vec2ForPreTrainingOutput(ModelOutput): - """ - Output type of [`FlaxWav2Vec2ForPreTrainingOutput`], with potential hidden states and attentions. - - Args: - loss (*optional*, returned when model is in train mode, `jnp.ndarray` of shape `(1,)`): - Total loss as the sum of the contrastive loss (L_m) and the diversity loss (L_d) as stated in the [official - paper](https://huggingface.co/papers/2006.11477). - projected_states (`jnp.ndarray` of shape `(batch_size, sequence_length, config.proj_codevector_dim)`): - Hidden-states of the model projected to *config.proj_codevector_dim* that can be used to predict the masked - projected quantized states. - projected_quantized_states (`jnp.ndarray` of shape `(batch_size, sequence_length, config.proj_codevector_dim)`): - Quantized extracted feature vectors projected to *config.proj_codevector_dim* representing the positive - target vectors for contrastive loss. - hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - projected_states: jnp.ndarray = None - projected_quantized_states: jnp.ndarray = None - codevector_perplexity: jnp.ndarray = None - hidden_states: Optional[tuple[jnp.ndarray]] = None - attentions: Optional[tuple[jnp.ndarray]] = None - - -def _compute_mask_indices( - shape: tuple[int, int], - mask_prob: float, - mask_length: int, - attention_mask: Optional[np.ndarray] = None, - min_masks: int = 0, -) -> np.ndarray: - """ - Computes random mask spans for a given shape. Used to implement [SpecAugment: A Simple Data Augmentation Method for - ASR](https://huggingface.co/papers/1904.08779). Note that this method is not optimized to run on TPU and should be run on - CPU as part of the preprocessing during training. - - Args: - shape: the shape for which to compute masks. - should be of size 2 where first element is batch size and 2nd is timesteps - mask_prob: - probability for each token to be chosen as start of the span to be masked. this will be multiplied by - number of timesteps divided by length of mask span to mask approximately this percentage of all elements. - however due to overlaps, the actual number will be smaller (unless no_overlap is True) - mask_length: size of the mask - min_masks: minimum number of masked spans - - """ - batch_size, sequence_length = shape - - if mask_length < 1: - raise ValueError("`mask_length` has to be bigger than 0.") - - if mask_length > sequence_length: - raise ValueError( - f"`mask_length` has to be smaller than `sequence_length`, but got `mask_length`: {mask_length} and" - f" `sequence_length`: {sequence_length}`" - ) - - # compute number of masked spans in batch - num_masked_spans = int(mask_prob * sequence_length / mask_length + np.random.rand(1).item()) - num_masked_spans = max(num_masked_spans, min_masks) - - # make sure num masked indices <= sequence_length - if num_masked_spans * mask_length > sequence_length: - num_masked_spans = sequence_length // mask_length - - # SpecAugment mask to fill - spec_aug_mask = np.zeros((batch_size, sequence_length), dtype=bool) - - # get random indices to mask - spec_aug_mask_idxs = np.array( - [ - np.random.choice(np.arange(sequence_length - (mask_length - 1)), num_masked_spans, replace=False) - for _ in range(batch_size) - ] - ) - - # expand masked indices to masked spans - spec_aug_mask_idxs = np.broadcast_to(spec_aug_mask_idxs[:, :, None], (batch_size, num_masked_spans, mask_length)) - spec_aug_mask_idxs = spec_aug_mask_idxs.reshape(batch_size, num_masked_spans * mask_length) - - offsets = np.arange(mask_length)[None, None, :] - offsets = np.broadcast_to(offsets, (batch_size, num_masked_spans, mask_length)).reshape( - batch_size, num_masked_spans * mask_length - ) - spec_aug_mask_idxs = spec_aug_mask_idxs + offsets - - # scatter indices to mask - np.put_along_axis(spec_aug_mask, spec_aug_mask_idxs, 1, -1) - - if attention_mask is not None: - # make sure padded input ids cannot be masked - spec_aug_mask = np.where(attention_mask, spec_aug_mask, False) - - return spec_aug_mask - - -def _sample_negative_indices(features_shape: tuple, num_negatives: int, attention_mask: Optional[np.ndarray] = None): - """ - Sample `num_negatives` vectors from feature vectors. - """ - batch_size, sequence_length, hidden_size = features_shape - if sequence_length <= 1: - raise ValueError( - "`features should have `sequence_length` > 1, but are of shape " - f"(batch_size, sequence_length, hidden_size) = ({batch_size, sequence_length, hidden_size})." - ) - - # get `num_negatives` random vector indices from the same utterance - sampled_negative_indices = [] - for batch_idx in range(batch_size): - high = attention_mask[batch_idx].sum() - 1 if attention_mask is not None else sequence_length - 1 - sampled_indices_slice = np.random.randint(0, high, size=(num_negatives * sequence_length,)) - sampled_negative_indices.append(sampled_indices_slice) - - sampled_negative_indices = np.asarray(sampled_negative_indices, dtype=np.int32) - - # generate indices of the positive vectors themselves, repeat them `num_negatives` times - feature_indices = np.broadcast_to(np.arange(sequence_length)[:, None], (sequence_length, num_negatives)).flatten() - - # avoid sampling the same positive vector, but keep the distribution uniform - sampled_negative_indices[sampled_negative_indices >= feature_indices] += 1 - - # correct for batch size - for batch_idx in range(1, batch_size): - sampled_negative_indices[batch_idx] += batch_idx * sequence_length - - return sampled_negative_indices - - -WAV2VEC2_START_DOCSTRING = r""" - Wav2Vec2 was proposed in [wav2vec 2.0: A Framework for Self-Supervised Learning of Speech - Representations](https://huggingface.co/papers/2006.11477) by Alexei Baevski, Henry Zhou, Abdelrahman Mohamed, Michael - Auli. - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`Wav2Vec2Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - - -WAV2VEC2_INPUTS_DOCSTRING = r""" - Args: - input_values (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Float values of input raw speech waveform. Values can be obtained by loading a `.flac` or `.wav` audio file - into an array of type `list[float]`, a `numpy.ndarray` or a `torch.Tensor`, *e.g.* via the torchcodec library - (`pip install torchcodec`) or the soundfile library (`pip install soundfile`). - To prepare the array into `input_values`, the [`AutoProcessor`] should be used for padding and conversion - into a tensor of type `jnp.ndarray`. See [`Wav2Vec2Processor.__call__`] for details. - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing convolution and attention on padding token indices. Mask values selected in `[0, - 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) .. warning:: `attention_mask` should only be passed - if the corresponding processor has `config.return_attention_mask == True`. For all models whose processor - has `config.return_attention_mask == False`, such as - [wav2vec2-base](https://huggingface.co/facebook/wav2vec2-base-960h), `attention_mask` should **not** be - passed to avoid degraded performance when doing batched inference. For such models `input_values` should - simply be padded with 0 and passed without `attention_mask`. Be aware that these models also yield slightly - different results depending on whether `input_values` is padded or not. - mask_time_indices (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices to mask extracted features for contrastive loss. When in training mode, model learns to predict - masked extracted features in *config.proj_codevector_dim* space. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -class FlaxWav2Vec2LayerNormConvLayer(nn.Module): - config: Wav2Vec2Config - layer_id: int = 0 - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.in_conv_dim = self.config.conv_dim[self.layer_id] if self.layer_id > 0 else 1 - self.out_conv_dim = self.config.conv_dim[self.layer_id] - - self.conv = nn.Conv( - features=self.config.conv_dim[self.layer_id], - kernel_size=(self.config.conv_kernel[self.layer_id],), - strides=(self.config.conv_stride[self.layer_id],), - use_bias=self.config.conv_bias, - kernel_init=jax.nn.initializers.he_normal(), - padding="VALID", - dtype=self.dtype, - ) - self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.activation = ACT2FN[self.config.feat_extract_activation] - - def __call__(self, hidden_states): - hidden_states = self.conv(hidden_states) - hidden_states = self.layer_norm(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - -class FlaxConvWithWeightNorm(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.conv = nn.Conv( - features=self.config.hidden_size, - kernel_size=(self.config.num_conv_pos_embeddings,), - kernel_init=jax.nn.initializers.he_normal(), - padding="VALID", - feature_group_count=self.config.num_conv_pos_embedding_groups, - dtype=self.dtype, - ) - weight_shape = ( - self.conv.features, - self.conv.features // self.conv.feature_group_count, - self.conv.kernel_size[0], - ) - self.weight_v = self.param("weight_v", jax.nn.initializers.he_normal(), weight_shape) - self.weight_g = self.param("weight_g", lambda _: jnp.linalg.norm(self.weight_v, axis=(0, 1))[None, None, :]) - self.bias = self.param("bias", jax.nn.initializers.zeros, (self.conv.features,)) - self.prev_padding = self.conv.kernel_size[0] // 2 - - def _get_normed_weights(self): - weight_v_norm = jnp.linalg.norm(self.weight_v, axis=(0, 1))[None, None, :] - normed_weight_v = jnp.divide(self.weight_v, weight_v_norm) - normed_kernel = jnp.multiply(normed_weight_v, self.weight_g) - return normed_kernel - - def __call__(self, hidden_states): - kernel = self._get_normed_weights() - hidden_states = jnp.pad(hidden_states, ((0, 0), (self.prev_padding, self.prev_padding), (0, 0))) - hidden_states = self.conv.apply({"params": {"kernel": kernel.T, "bias": self.bias}}, hidden_states) - return hidden_states - - -class FlaxWav2Vec2PositionalConvEmbedding(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.conv = FlaxConvWithWeightNorm(self.config, dtype=self.dtype) - self.activation = ACT2FN[self.config.feat_extract_activation] - self.num_pad_remove = 1 if self.config.num_conv_pos_embeddings % 2 == 0 else 0 - - def __call__(self, hidden_states): - hidden_states = hidden_states.transpose((0, 1, 2)) - - hidden_states = self.conv(hidden_states) - - if self.num_pad_remove > 0: - hidden_states = hidden_states[:, : -self.num_pad_remove, :] - hidden_states = self.activation(hidden_states) - - hidden_states = hidden_states.transpose((0, 1, 2)) - return hidden_states - - -class FlaxConvLayersCollection(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - if self.config.feat_extract_norm == "layer": - self.layers = [ - FlaxWav2Vec2LayerNormConvLayer(self.config, layer_id=i, name=str(i), dtype=self.dtype) - for i in range(self.config.num_feat_extract_layers) - ] - elif self.config.feat_extract_norm == "group": - raise NotImplementedError("At the moment only ``config.feat_extract_norm == 'layer'`` is supported") - else: - raise ValueError( - f"`config.feat_extract_norm` is {self.config.feat_extract_norm}, but has to be one of ['group'," - " 'layer']" - ) - - def __call__(self, hidden_states): - for i, conv_layer in enumerate(self.layers): - hidden_states = conv_layer(hidden_states) - return hidden_states - - -class FlaxWav2Vec2FeatureEncoder(nn.Module): - """Construct the features from raw audio waveform""" - - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.conv_layers = FlaxConvLayersCollection(self.config, dtype=self.dtype) - - def __call__(self, input_values, freeze_feature_encoder=False): - hidden_states = input_values[:, :, None] - hidden_states = self.conv_layers(hidden_states) - if freeze_feature_encoder: - hidden_states = jax.lax.stop_gradient(hidden_states) - return hidden_states - - -class FlaxWav2Vec2FeatureProjection(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.projection = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.feat_proj_dropout) - - def __call__(self, hidden_states, deterministic=True): - norm_hidden_states = self.layer_norm(hidden_states) - hidden_states = self.projection(norm_hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states, norm_hidden_states - - -class FlaxWav2Vec2Attention(nn.Module): - config: Wav2Vec2Config - embed_dim: int - num_heads: int - dropout: float = 0.0 - bias: bool = True - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self) -> None: - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" - f" {self.num_heads})." - ) - - dense = partial( - nn.Dense, - self.embed_dim, - use_bias=self.bias, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() - self.out_proj = dense() - - self.dropout_layer = nn.Dropout(rate=self.dropout) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - def __call__( - self, - hidden_states: jnp.ndarray, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - """Input shape: Batch x Time x Channel""" - - # get query proj - query_states = self.q_proj(hidden_states) - - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - if attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights - - -class FlaxWav2Vec2FeedForward(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.intermediate_dropout = nn.Dropout(rate=self.config.activation_dropout) - - self.intermediate_dense = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - if isinstance(self.config.hidden_act, str): - self.intermediate_act_fn = ACT2FN[self.config.hidden_act] - else: - self.intermediate_act_fn = self.config.hidden_act - - self.output_dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.output_dropout = nn.Dropout(rate=self.config.hidden_dropout) - - def __call__(self, hidden_states, deterministic=True): - hidden_states = self.intermediate_dense(hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - hidden_states = self.intermediate_dropout(hidden_states, deterministic=deterministic) - - hidden_states = self.output_dense(hidden_states) - hidden_states = self.output_dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -class FlaxWav2Vec2EncoderLayerStableLayerNorm(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.attention = FlaxWav2Vec2Attention( - config=self.config, - embed_dim=self.config.hidden_size, - num_heads=self.config.num_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout) - self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.feed_forward = FlaxWav2Vec2FeedForward(self.config, dtype=self.dtype) - self.final_layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states, attention_mask=None, deterministic=True, output_attentions=False): - attn_residual = hidden_states - hidden_states = self.layer_norm(hidden_states) - hidden_states, attn_weights = self.attention( - hidden_states, attention_mask=attention_mask, deterministic=deterministic - ) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = attn_residual + hidden_states - hidden_states = hidden_states + self.feed_forward( - self.final_layer_norm(hidden_states), deterministic=deterministic - ) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - -class FlaxWav2Vec2EncoderLayerStableLayerNormCollection(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.layers = [ - FlaxWav2Vec2EncoderLayerStableLayerNorm(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask=None, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer( - hidden_states, attention_mask, deterministic=deterministic, output_attentions=output_attentions - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -class FlaxWav2Vec2StableLayerNormEncoder(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.pos_conv_embed = FlaxWav2Vec2PositionalConvEmbedding(self.config, dtype=self.dtype) - self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout) - self.layers = FlaxWav2Vec2EncoderLayerStableLayerNormCollection(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask=None, - deterministic=True, - output_attentions=False, - output_hidden_states=False, - return_dict=True, - ): - if attention_mask is not None: - # make sure padded tokens are not attended to - hidden_states = jnp.where( - jnp.broadcast_to(attention_mask[:, :, None], hidden_states.shape), hidden_states, 0 - ) - - position_embeddings = self.pos_conv_embed(hidden_states) - - hidden_states = hidden_states + position_embeddings - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - last_hidden_state = self.layer_norm(outputs[0]) - - # update the last element in `hidden_states` after applying `layernorm` above - hidden_states = None - if output_hidden_states: - hidden_states = outputs[1] - hidden_states = hidden_states[:-1] + (last_hidden_state,) - - if not return_dict: - outputs = (last_hidden_state, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=last_hidden_state, hidden_states=hidden_states, attentions=outputs.attentions - ) - - -class FlaxWav2Vec2GumbelVectorQuantizer(nn.Module): - """ - Vector quantization using gumbel softmax. See [CATEGORICAL REPARAMETERIZATION WITH - GUMBEL-SOFTMAX](https://huggingface.co/papers/1611.01144) for more information. - """ - - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.num_groups = self.config.num_codevector_groups - self.num_vars = self.config.num_codevectors_per_group - - if self.config.codevector_dim % self.num_groups != 0: - raise ValueError( - f"`config.codevector_dim {self.config.codevector_dim} must be divisible by" - f" `config.num_codevector_groups` {self.num_groups} for concatenation" - ) - - # storage for codebook variables (codewords) - self.codevectors = self.param( - "codevectors", - jax.nn.initializers.uniform(), - (1, self.num_groups * self.num_vars, self.config.codevector_dim // self.num_groups), - ) - self.weight_proj = nn.Dense( - self.num_groups * self.num_vars, - kernel_init=jax.nn.initializers.normal(1.0), - dtype=self.dtype, - ) - - @staticmethod - def _compute_perplexity(probs, mask=None): - if mask is not None: - mask_extended = jnp.broadcast_to(mask.flatten()[:, None, None], probs.shape) - probs = jnp.where(mask_extended, probs, jnp.zeros_like(probs)) - marginal_probs = probs.sum(axis=0) / mask.sum() - else: - marginal_probs = probs.mean(axis=0) - - perplexity = jnp.exp(-jnp.sum(marginal_probs * jnp.log(marginal_probs + 1e-7), axis=-1)).sum() - return perplexity - - def __call__(self, hidden_states, mask_time_indices=None, deterministic=True, temperature=1): - batch_size, sequence_length, hidden_size = hidden_states.shape - - # project to codevector dim - hidden_states = self.weight_proj(hidden_states) - hidden_states = hidden_states.reshape(batch_size * sequence_length * self.num_groups, -1) - - if not deterministic: - # sample code vector probs via gumbel in differentiateable way - gumbel_rng = self.make_rng("gumbel") - gumbels = jax.random.gumbel(gumbel_rng, hidden_states.shape) - codevector_probs = nn.softmax((hidden_states + gumbels) / temperature) - - # compute perplexity - codevector_soft_dist = nn.softmax( - hidden_states.reshape(batch_size * sequence_length, self.num_groups, -1), axis=-1 - ) - perplexity = self._compute_perplexity(codevector_soft_dist, mask_time_indices) - else: - # take argmax in non-differentiable way - # comptute hard codevector distribution (one hot) - codevector_idx = hidden_states.argmax(axis=-1) - codevector_probs = jax.nn.one_hot(codevector_idx, hidden_states.shape[-1]) * 1.0 - codevector_probs = codevector_probs.reshape(batch_size * sequence_length, self.num_groups, -1) - perplexity = self._compute_perplexity(codevector_probs, mask_time_indices) - - codevector_probs = codevector_probs.reshape(batch_size * sequence_length, -1) - # use probs to retrieve codevectors - codevectors_per_group = jnp.expand_dims(codevector_probs, axis=-1) * self.codevectors - codevectors = codevectors_per_group.reshape(batch_size * sequence_length, self.num_groups, self.num_vars, -1) - codevectors = codevectors.sum(-2).reshape(batch_size, sequence_length, -1) - - return codevectors, perplexity - - -class FlaxWav2Vec2Adapter(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - # hidden_states require down-projection if feature dims don't match - if self.config.output_hidden_size != self.config.hidden_size: - self.proj = nn.Dense( - self.config.output_hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.proj_layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - else: - self.proj = self.proj_layer_norm = None - - self.layers = FlaxWav2Vec2AdapterLayersCollection(self.config, dtype=self.dtype) - - def __call__(self, hidden_states, deterministic=True): - # down-project hidden_states if required - if self.proj is not None and self.proj_layer_norm is not None: - hidden_states = self.proj(hidden_states) - hidden_states = self.proj_layer_norm(hidden_states) - - hidden_states = self.layers(hidden_states) - - return hidden_states - - -class FlaxWav2Vec2AdapterLayer(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.conv = nn.Conv( - features=2 * self.config.output_hidden_size, - kernel_size=(self.config.adapter_kernel_size,), - strides=(self.config.adapter_stride,), - padding=((1, 1),), - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - - def __call__(self, hidden_states): - hidden_states = self.conv(hidden_states) - hidden_states = nn.glu(hidden_states, axis=2) - - return hidden_states - - -class FlaxWav2Vec2AdapterLayersCollection(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.layers = [ - FlaxWav2Vec2AdapterLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_adapter_layers) - ] - - def __call__(self, hidden_states): - for conv_layer in self.layers: - hidden_states = conv_layer(hidden_states) - - return hidden_states - - -class FlaxWav2Vec2PreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = Wav2Vec2Config - base_model_prefix: str = "wav2vec2" - main_input_name = "input_values" - module_class: nn.Module = None - - def __init__( - self, - config: Wav2Vec2Config, - input_shape: tuple = (1, 1024), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_values = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_values) - params_rng, dropout_rng = jax.random.split(rng, 2) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init(rngs, input_values, attention_mask, return_dict=False)["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(WAV2VEC2_INPUTS_DOCSTRING) - def __call__( - self, - input_values, - attention_mask=None, - mask_time_indices=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - freeze_feature_encoder: bool = False, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - batch_size, sequence_length = input_values.shape - - if attention_mask is None: - attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - return self.module.apply( - inputs, - jnp.array(input_values, dtype="f4"), - jnp.array(attention_mask, dtype="i4"), - mask_time_indices, - not train, - output_attentions, - output_hidden_states, - freeze_feature_encoder, - return_dict, - rngs=rngs, - ) - - def _get_feat_extract_output_lengths( - self, input_lengths: Union[jnp.ndarray, int], add_adapter: Optional[bool] = None - ): - return self.module._get_feat_extract_output_lengths(input_lengths, add_adapter=add_adapter) - - -class FlaxWav2Vec2Module(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.feature_extractor = FlaxWav2Vec2FeatureEncoder(self.config, dtype=self.dtype) - self.feature_projection = FlaxWav2Vec2FeatureProjection(self.config, dtype=self.dtype) - self.masked_spec_embed = self.param( - "masked_spec_embed", jax.nn.initializers.uniform(), (self.config.hidden_size,) - ) - - if self.config.do_stable_layer_norm: - self.encoder = FlaxWav2Vec2StableLayerNormEncoder(self.config, dtype=self.dtype) - else: - raise NotImplementedError("``config.do_stable_layer_norm is False`` is currently not supported.") - - self.adapter = FlaxWav2Vec2Adapter(self.config, dtype=self.dtype) if self.config.add_adapter else None - - def __call__( - self, - input_values, - attention_mask=None, - mask_time_indices=None, - deterministic=True, - output_attentions=None, - output_hidden_states=None, - freeze_feature_encoder=False, - return_dict=None, - ): - extract_features = self.feature_extractor(input_values, freeze_feature_encoder=freeze_feature_encoder) - - # make sure that no loss is computed on padded inputs - if attention_mask is not None: - # compute reduced attention_mask corresponding to feature vectors - attention_mask = self._get_feature_vector_attention_mask( - extract_features.shape[1], attention_mask, add_adapter=False - ) - - hidden_states, extract_features = self.feature_projection(extract_features, deterministic=deterministic) - if mask_time_indices is not None: # apply SpecAugment along time axis with given indices - hidden_states = jnp.where( - jnp.broadcast_to(mask_time_indices[:, :, None], hidden_states.shape), - jnp.broadcast_to(self.masked_spec_embed[None, None, :], hidden_states.shape), - hidden_states, - ) - - encoder_outputs = self.encoder( - hidden_states, - attention_mask=attention_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = encoder_outputs[0] - - if self.adapter is not None: - hidden_states = self.adapter(hidden_states) - - if not return_dict: - return (hidden_states, extract_features) + encoder_outputs[1:] - - return FlaxWav2Vec2BaseModelOutput( - last_hidden_state=hidden_states, - extract_features=extract_features, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - def _get_feat_extract_output_lengths( - self, input_lengths: Union[jnp.ndarray, int], add_adapter: Optional[bool] = None - ): - """ - Computes the output length of the convolutional layers - """ - - add_adapter = self.config.add_adapter if add_adapter is None else add_adapter - - def _conv_out_length(input_length, kernel_size, stride): - # 1D convolutional layer output length formula taken - # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html - return (input_length - kernel_size) // stride + 1 - - for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): - input_lengths = _conv_out_length(input_lengths, kernel_size, stride) - - if add_adapter: - for _ in range(self.config.num_adapter_layers): - input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) - - return input_lengths - - def _get_feature_vector_attention_mask( - self, feature_vector_length: int, attention_mask: jnp.ndarray, add_adapter=None - ): - # Effectively attention_mask.sum(-1), but not inplace to be able to run - # on inference mode. - non_padded_lengths = attention_mask.cumsum(axis=-1)[:, -1] - - output_lengths = self._get_feat_extract_output_lengths(non_padded_lengths, add_adapter=add_adapter) - - batch_size = attention_mask.shape[0] - - attention_mask = jnp.zeros((batch_size, feature_vector_length), dtype=attention_mask.dtype) - # these two operations makes sure that all values - # before the output lengths indices are attended to - attention_mask = attention_mask.at[jnp.arange(attention_mask.shape[0]), output_lengths - 1].set(1) - attention_mask = jnp.flip(jnp.flip(attention_mask, -1).cumsum(-1), -1).astype("bool") - return attention_mask - - -@add_start_docstrings( - "The bare Wav2Vec2 Model transformer outputting raw hidden-states without any specific head on top.", - WAV2VEC2_START_DOCSTRING, -) -class FlaxWav2Vec2Model(FlaxWav2Vec2PreTrainedModel): - module_class = FlaxWav2Vec2Module - - -FLAX_WAV2VEC2_MODEL_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> from transformers import AutoProcessor, FlaxWav2Vec2Model - >>> from datasets import load_dataset - - >>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-large-lv60") - >>> model = FlaxWav2Vec2Model.from_pretrained("facebook/wav2vec2-large-lv60") - - - >>> def map_to_array(example): - ... example["speech"] = example["audio"]["array"] - ... return example - - - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> ds = ds.map(map_to_array) - - >>> input_values = processor( - ... ds["speech"][0], sampling_rate=16_000, return_tensors="np" - ... ).input_values # Batch size 1 - >>> hidden_states = model(input_values).last_hidden_state - ``` -""" - -overwrite_call_docstring( - FlaxWav2Vec2Model, - WAV2VEC2_INPUTS_DOCSTRING + FLAX_WAV2VEC2_MODEL_DOCSTRING, -) -append_replace_return_docstrings( - FlaxWav2Vec2Model, output_type=FlaxWav2Vec2BaseModelOutput, config_class=Wav2Vec2Config -) - - -class FlaxWav2Vec2ForCTCModule(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.wav2vec2 = FlaxWav2Vec2Module(self.config, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.final_dropout) - self.lm_head = nn.Dense( - self.config.vocab_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - - def __call__( - self, - input_values, - attention_mask=None, - mask_time_indices=None, - deterministic=True, - output_attentions=None, - output_hidden_states=None, - freeze_feature_encoder=False, - return_dict=None, - ): - outputs = self.wav2vec2( - input_values, - attention_mask=attention_mask, - mask_time_indices=mask_time_indices, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - freeze_feature_encoder=freeze_feature_encoder, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - - logits = self.lm_head(hidden_states) - - if not return_dict: - return (logits,) + outputs[2:] - - return FlaxCausalLMOutput(logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions) - - def _get_feat_extract_output_lengths( - self, - input_lengths: Union[jnp.ndarray, int], - add_adapter: Optional[bool] = None, - ): - """ - Computes the output length of the convolutional layers - """ - - add_adapter = self.config.add_adapter if add_adapter is None else add_adapter - - def _conv_out_length(input_length, kernel_size, stride): - # 1D convolutional layer output length formula taken - # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html - return (input_length - kernel_size) // stride + 1 - - for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): - input_lengths = _conv_out_length(input_lengths, kernel_size, stride) - - if add_adapter: - for _ in range(self.config.num_adapter_layers): - input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) - - return input_lengths - - -@add_start_docstrings( - "Wav2Vec2 Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).", - WAV2VEC2_START_DOCSTRING, -) -class FlaxWav2Vec2ForCTC(FlaxWav2Vec2PreTrainedModel): - module_class = FlaxWav2Vec2ForCTCModule - - -FLAX_WAV2VEC2_FOR_CTC_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoProcessor, FlaxWav2Vec2ForCTC - >>> from datasets import load_dataset - - >>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-large-960h-lv60") - >>> model = FlaxWav2Vec2ForCTC.from_pretrained("facebook/wav2vec2-large-960h-lv60") - - - >>> def map_to_array(example): - ... example["speech"] = example["audio"]["array"] - ... return example - - - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> ds = ds.map(map_to_array) - - >>> input_values = processor( - ... ds["speech"][0], sampling_rate=16_000, return_tensors="np" - ... ).input_values # Batch size 1 - >>> logits = model(input_values).logits - >>> predicted_ids = jnp.argmax(logits, axis=-1) - - >>> transcription = processor.decode(predicted_ids[0]) - >>> # should give: "A MAN SAID TO THE UNIVERSE SIR I EXIST" - ``` -""" - -overwrite_call_docstring( - FlaxWav2Vec2ForCTC, - WAV2VEC2_INPUTS_DOCSTRING + FLAX_WAV2VEC2_FOR_CTC_DOCSTRING, -) -append_replace_return_docstrings(FlaxWav2Vec2ForCTC, output_type=FlaxCausalLMOutput, config_class=Wav2Vec2Config) - - -class FlaxWav2Vec2ForPreTrainingModule(nn.Module): - config: Wav2Vec2Config - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.wav2vec2 = FlaxWav2Vec2Module(self.config, dtype=self.dtype) - self.dropout_features = nn.Dropout(self.config.feat_quantizer_dropout) - - self.quantizer = FlaxWav2Vec2GumbelVectorQuantizer(self.config, dtype=self.dtype) - self.project_q = nn.Dense( - self.config.proj_codevector_dim, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.project_hid = nn.Dense( - self.config.proj_codevector_dim, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - - def __call__( - self, - input_values, - attention_mask=None, - mask_time_indices=None, - gumbel_temperature: int = 1, - deterministic: bool = True, - output_attentions=None, - output_hidden_states=None, - freeze_feature_encoder=False, - return_dict=None, - ): - r""" - Returns: - - Example: - - ```python - - ```""" - - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - outputs = self.wav2vec2( - input_values, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - mask_time_indices=mask_time_indices, - deterministic=deterministic, - freeze_feature_encoder=freeze_feature_encoder, - return_dict=return_dict, - ) - - # project all transformed features (including masked) to final vq dim - transformer_features = self.project_hid(outputs[0]) - - # quantize all (unmasked) extracted features and project to final vq dim - extract_features = self.dropout_features(outputs[1], deterministic=deterministic) - quantized_features, codevector_perplexity = self.quantizer( - extract_features, mask_time_indices, deterministic=deterministic, temperature=gumbel_temperature - ) - quantized_features = self.project_q(quantized_features) - - if not return_dict: - return (transformer_features, quantized_features, codevector_perplexity) + outputs[2:] - - return FlaxWav2Vec2ForPreTrainingOutput( - projected_states=transformer_features, - projected_quantized_states=quantized_features, - codevector_perplexity=codevector_perplexity, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def _get_feat_extract_output_lengths( - self, input_lengths: Union[jnp.ndarray, int], add_adapter: Optional[bool] = None - ): - """ - Computes the output length of the convolutional layers - """ - - add_adapter = self.config.add_adapter if add_adapter is None else add_adapter - - def _conv_out_length(input_length, kernel_size, stride): - # 1D convolutional layer output length formula taken - # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html - return (input_length - kernel_size) // stride + 1 - - for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): - input_lengths = _conv_out_length(input_lengths, kernel_size, stride) - - if add_adapter: - for _ in range(self.config.num_adapter_layers): - input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) - - return input_lengths - - -@add_start_docstrings("""Wav2Vec2 Model with a quantizer and `VQ` head on top.""", WAV2VEC2_START_DOCSTRING) -class FlaxWav2Vec2ForPreTraining(FlaxWav2Vec2PreTrainedModel): - module_class = FlaxWav2Vec2ForPreTrainingModule - - @add_start_docstrings_to_model_forward(WAV2VEC2_INPUTS_DOCSTRING) - # overwrite since has `gumbel_temperature` input - def __call__( - self, - input_values, - attention_mask=None, - mask_time_indices=None, - gumbel_temperature: int = 1, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - gumbel_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - freeze_feature_encoder: bool = False, - return_dict: Optional[bool] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - batch_size, sequence_length = input_values.shape - - if attention_mask is None: - attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - if gumbel_rng is not None: - rngs["gumbel"] = gumbel_rng - - inputs = {"params": params or self.params} - - return self.module.apply( - inputs, - jnp.array(input_values, dtype="f4"), - jnp.array(attention_mask, dtype="i4"), - mask_time_indices, - gumbel_temperature, - not train, - output_attentions, - output_hidden_states, - freeze_feature_encoder, - return_dict, - rngs=rngs, - ) - - -FLAX_WAV2VEC2_FOR_PRETRAINING_DOCSTRING = """ - Returns: - - Example: - - ```python - >>> import optax - >>> import numpy as np - >>> import jax.numpy as jnp - >>> from transformers import AutoFeatureExtractor, FlaxWav2Vec2ForPreTraining - >>> from transformers.models.wav2vec2.modeling_flax_wav2vec2 import _compute_mask_indices - >>> from datasets import load_dataset - - >>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-large-lv60") - >>> model = FlaxWav2Vec2ForPreTraining.from_pretrained("facebook/wav2vec2-large-lv60") - - - >>> def map_to_array(example): - ... example["speech"] = example["audio"]["array"] - ... return example - - - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> ds = ds.map(map_to_array) - - >>> input_values = feature_extractor(ds["speech"][0], return_tensors="np").input_values # Batch size 1 - - >>> # compute masked indices - >>> batch_size, raw_sequence_length = input_values.shape - >>> sequence_length = model._get_feat_extract_output_lengths(raw_sequence_length) - >>> mask_time_indices = _compute_mask_indices((batch_size, sequence_length), mask_prob=0.2, mask_length=2) - - >>> outputs = model(input_values, mask_time_indices=mask_time_indices) - - >>> # compute cosine similarity between predicted (=projected_states) and target (=projected_quantized_states) - >>> cosine_sim = optax.cosine_similarity(outputs.projected_states, outputs.projected_quantized_states) - - >>> # show that cosine similarity is much higher than random - >>> assert np.asarray(cosine_sim)[mask_time_indices].mean() > 0.5 - ``` -""" - -overwrite_call_docstring( - FlaxWav2Vec2ForPreTraining, - WAV2VEC2_INPUTS_DOCSTRING + FLAX_WAV2VEC2_FOR_PRETRAINING_DOCSTRING, -) -append_replace_return_docstrings( - FlaxWav2Vec2ForPreTraining, output_type=FlaxWav2Vec2ForPreTrainingOutput, config_class=Wav2Vec2Config -) - - -__all__ = ["FlaxWav2Vec2ForCTC", "FlaxWav2Vec2ForPreTraining", "FlaxWav2Vec2Model", "FlaxWav2Vec2PreTrainedModel"] diff --git a/src/transformers/models/wav2vec2/modeling_tf_wav2vec2.py b/src/transformers/models/wav2vec2/modeling_tf_wav2vec2.py deleted file mode 100644 index 54011bb969fd..000000000000 --- a/src/transformers/models/wav2vec2/modeling_tf_wav2vec2.py +++ /dev/null @@ -1,1855 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Fairseq Authors and the HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow Wav2Vec2 model.""" - -from __future__ import annotations - -import warnings -from dataclasses import dataclass -from typing import Any - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import TFBaseModelOutput, TFCausalLMOutput, TFSequenceClassifierOutput -from ...modeling_tf_utils import ( - TFPreTrainedModel, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_wav2vec2 import Wav2Vec2Config - - -logger = logging.get_logger(__name__) - - -_HIDDEN_STATES_START_POSITION = 2 - -_CHECKPOINT_FOR_DOC = "facebook/wav2vec2-base-960h" -_CONFIG_FOR_DOC = "Wav2Vec2Config" - - -LARGE_NEGATIVE = -1e8 - - -@dataclass -class TFWav2Vec2BaseModelOutput(ModelOutput): - """ - Output type of [`TFWav2Vec2BaseModelOutput`], with potential hidden states and attentions. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): - Sequence of hidden-states at the output of the last layer of the model. - extract_features (`tf.Tensor` of shape `(batch_size, sequence_length, conv_dim[-1])`): - Sequence of extracted feature vectors of the last convolutional layer of the model. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: tf.Tensor | None = None - extract_features: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor] | None = None - attentions: tuple[tf.Tensor] | None = None - - -def _sample_without_replacement(distribution, num_samples): - """ - Categorical sampling without replacement is currently not implemented. The gumbel-max trick will do for now - see - https://github.com/tensorflow/tensorflow/issues/9260 for more info - """ - z = -tf.math.log(tf.random.uniform(shape_list(distribution), 0, 1)) - _, indices = tf.nn.top_k(distribution + z, num_samples) - return indices - - -def _scatter_values_on_batch_indices(values, batch_indices, output_shape): - """ - Scatter function as in PyTorch with indices in format (batch_dim, indices) - """ - indices_shape = shape_list(batch_indices) - # broadcast batch dim to indices_shape - broad_casted_batch_dims = tf.reshape( - tf.broadcast_to(tf.expand_dims(tf.range(indices_shape[0]), axis=-1), indices_shape), [1, -1] - ) - # transform batch_indices to pair_indices - pair_indices = tf.transpose(tf.concat([broad_casted_batch_dims, tf.reshape(batch_indices, [1, -1])], 0)) - # scatter values to pair indices - return tf.scatter_nd(pair_indices, tf.reshape(values, [-1]), output_shape) - - -def _compute_mask_indices( - shape: tuple[int, int], - mask_prob: float, - mask_length: int, - min_masks: int = 0, -) -> tf.Tensor: - """ - Computes random mask spans for a given shape - - Args: - shape: the shape for which to compute masks. - should be of size 2 where first element is batch size and 2nd is timesteps - attention_mask: optional padding mask of the same size as shape, which will prevent masking padded elements - mask_prob: - probability for each token to be chosen as start of the span to be masked. this will be multiplied by - number of timesteps divided by length of mask span to mask approximately this percentage of all elements. - however due to overlaps, the actual number will be smaller (unless no_overlap is True) - mask_length: size of the mask - min_masks: minimum number of masked spans - - Adapted from [fairseq's - data_utils.py](https://github.com/pytorch/fairseq/blob/e0788f7007a8473a76db573985031f3c94201e79/fairseq/data/data_utils.py#L376). - """ - batch_size, sequence_length = shape - - if mask_length < 1: - raise ValueError("`mask_length` has to be bigger than 0.") - - tf.debugging.assert_less( - mask_length, - sequence_length, - message=( - f"`mask_length` has to be smaller than `sequence_length`, but got `mask_length`: {mask_length} and" - f" `sequence_length`: {sequence_length}`" - ), - ) - - # compute number of masked spans in batch - num_masked_spans = mask_prob * tf.cast(sequence_length, tf.float32) / mask_length + tf.random.uniform((1,)) - num_masked_spans = tf.maximum(num_masked_spans, min_masks) - num_masked_spans = tf.cast(num_masked_spans, tf.int32) - - # make sure num masked indices <= sequence_length - num_masked_spans = tf.math.minimum(sequence_length // mask_length, num_masked_spans) - num_masked_spans = tf.squeeze(num_masked_spans) - - # SpecAugment mask to fill - spec_aug_mask = tf.zeros((batch_size, sequence_length), dtype=tf.int32) - - # uniform distribution to sample from, make sure that offset samples are < sequence_length - uniform_dist = tf.ones((batch_size, sequence_length - (mask_length - 1))) - - # get random indices to mask - spec_aug_mask_idxs = _sample_without_replacement(uniform_dist, num_masked_spans) - - # expand masked indices to masked spans - spec_aug_mask_idxs = tf.expand_dims(spec_aug_mask_idxs, -1) - spec_aug_mask_idxs = tf.tile(spec_aug_mask_idxs, (1, 1, mask_length)) - spec_aug_mask_idxs = tf.reshape(spec_aug_mask_idxs, (batch_size, num_masked_spans * mask_length)) - - offsets = tf.range(mask_length)[tf.newaxis, tf.newaxis, :] - offsets = tf.tile(offsets, (batch_size, num_masked_spans, 1)) - offsets = tf.reshape(offsets, (batch_size, num_masked_spans * mask_length)) - - spec_aug_mask_idxs = spec_aug_mask_idxs + offsets - - # scatter indices to mask - spec_aug_mask = _scatter_values_on_batch_indices( - tf.ones_like(spec_aug_mask_idxs), spec_aug_mask_idxs, tf.shape(spec_aug_mask) - ) - - return spec_aug_mask - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -class TFWav2Vec2GroupNorm(keras.layers.Layer): - """ - From tensorflow-addons https://www.tensorflow.org/addons/api_docs/python/tfa/layers/GroupNormalization - """ - - def __init__( - self, - groups: int = 32, - axis: int = -1, - epsilon: float = 1e-3, - center: bool = True, - scale: bool = True, - beta_initializer: keras.initializers.Initializer = "zeros", - gamma_initializer: keras.initializers.Initializer = "ones", - beta_regularizer: keras.regularizers.Regularizer = None, - gamma_regularizer: keras.regularizers.Regularizer = None, - beta_constraint: keras.constraints.Constraint = None, - gamma_constraint: keras.constraints.Constraint = None, - **kwargs, - ): - super().__init__(**kwargs) - self.supports_masking = True - self.groups = groups - self.axis = axis - self.epsilon = epsilon - self.center = center - self.scale = scale - self.beta_initializer = keras.initializers.get(beta_initializer) - self.gamma_initializer = keras.initializers.get(gamma_initializer) - self.beta_regularizer = keras.regularizers.get(beta_regularizer) - self.gamma_regularizer = keras.regularizers.get(gamma_regularizer) - self.beta_constraint = keras.constraints.get(beta_constraint) - self.gamma_constraint = keras.constraints.get(gamma_constraint) - self._check_axis() - - def build(self, input_shape): - self._check_if_input_shape_is_none(input_shape) - self._set_number_of_groups_for_instance_norm(input_shape) - self._check_size_of_dimensions(input_shape) - self._create_input_spec(input_shape) - - self._add_gamma_weight(input_shape) - self._add_beta_weight(input_shape) - self.built = True - super().build(input_shape) - - def call(self, inputs): - input_shape = keras.backend.int_shape(inputs) - tensor_input_shape = tf.shape(inputs) - - reshaped_inputs, group_shape = self._reshape_into_groups(inputs, input_shape, tensor_input_shape) - - normalized_inputs = self._apply_normalization(reshaped_inputs, input_shape) - - is_instance_norm = (input_shape[self.axis] // self.groups) == 1 - if not is_instance_norm: - outputs = tf.reshape(normalized_inputs, tensor_input_shape) - else: - outputs = normalized_inputs - - return outputs - - def get_config(self): - config = { - "groups": self.groups, - "axis": self.axis, - "epsilon": self.epsilon, - "center": self.center, - "scale": self.scale, - "beta_initializer": keras.initializers.serialize(self.beta_initializer), - "gamma_initializer": keras.initializers.serialize(self.gamma_initializer), - "beta_regularizer": keras.regularizers.serialize(self.beta_regularizer), - "gamma_regularizer": keras.regularizers.serialize(self.gamma_regularizer), - "beta_constraint": keras.constraints.serialize(self.beta_constraint), - "gamma_constraint": keras.constraints.serialize(self.gamma_constraint), - } - base_config = super().get_config() - return {**base_config, **config} - - def compute_output_shape(self, input_shape): - return input_shape - - def _reshape_into_groups(self, inputs, input_shape, tensor_input_shape): - group_shape = [tensor_input_shape[i] for i in range(len(input_shape))] - is_instance_norm = (input_shape[self.axis] // self.groups) == 1 - if not is_instance_norm: - group_shape[self.axis] = input_shape[self.axis] // self.groups - group_shape.insert(self.axis, self.groups) - group_shape = tf.stack(group_shape) - reshaped_inputs = tf.reshape(inputs, group_shape) - return reshaped_inputs, group_shape - else: - return inputs, group_shape - - def _apply_normalization(self, reshaped_inputs, input_shape): - group_shape = keras.backend.int_shape(reshaped_inputs) - group_reduction_axes = list(range(1, len(group_shape))) - is_instance_norm = (input_shape[self.axis] // self.groups) == 1 - if not is_instance_norm: - axis = -2 if self.axis == -1 else self.axis - 1 - else: - axis = -1 if self.axis == -1 else self.axis - 1 - group_reduction_axes.pop(axis) - - mean, variance = tf.nn.moments(reshaped_inputs, group_reduction_axes, keepdims=True) - - gamma, beta = self._get_reshaped_weights(input_shape) - normalized_inputs = tf.nn.batch_normalization( - reshaped_inputs, - mean=mean, - variance=variance, - scale=gamma, - offset=beta, - variance_epsilon=self.epsilon, - ) - return normalized_inputs - - def _get_reshaped_weights(self, input_shape): - broadcast_shape = self._create_broadcast_shape(input_shape) - gamma = None - beta = None - if self.scale: - gamma = tf.reshape(self.gamma, broadcast_shape) - - if self.center: - beta = tf.reshape(self.beta, broadcast_shape) - return gamma, beta - - def _check_if_input_shape_is_none(self, input_shape): - dim = input_shape[self.axis] - if dim is None: - raise ValueError( - "Axis " - + str(self.axis) - + " of input tensor should have a defined dimension but the layer received an input with shape " - + str(input_shape) - + "." - ) - - def _set_number_of_groups_for_instance_norm(self, input_shape): - dim = input_shape[self.axis] - - if self.groups == -1: - self.groups = dim - - def _check_size_of_dimensions(self, input_shape): - dim = input_shape[self.axis] - if dim < self.groups: - raise ValueError( - "Number of groups (" - + str(self.groups) - + ") cannot be more than the number of channels (" - + str(dim) - + ")." - ) - - if dim % self.groups != 0: - raise ValueError( - "Number of groups (" - + str(self.groups) - + ") must be a multiple of the number of channels (" - + str(dim) - + ")." - ) - - def _check_axis(self): - if self.axis == 0: - raise ValueError( - "You are trying to normalize your batch axis. Do you want to use tf.layer.batch_normalization instead" - ) - - def _create_input_spec(self, input_shape): - dim = input_shape[self.axis] - self.input_spec = keras.layers.InputSpec(ndim=len(input_shape), axes={self.axis: dim}) - - def _add_gamma_weight(self, input_shape): - dim = input_shape[self.axis] - shape = (dim,) - - if self.scale: - self.gamma = self.add_weight( - shape=shape, - name="gamma", - initializer=self.gamma_initializer, - regularizer=self.gamma_regularizer, - constraint=self.gamma_constraint, - ) - else: - self.gamma = None - - def _add_beta_weight(self, input_shape): - dim = input_shape[self.axis] - shape = (dim,) - - if self.center: - self.beta = self.add_weight( - shape=shape, - name="beta", - initializer=self.beta_initializer, - regularizer=self.beta_regularizer, - constraint=self.beta_constraint, - ) - else: - self.beta = None - - def _create_broadcast_shape(self, input_shape): - broadcast_shape = [1] * len(input_shape) - is_instance_norm = (input_shape[self.axis] // self.groups) == 1 - if not is_instance_norm: - broadcast_shape[self.axis] = input_shape[self.axis] // self.groups - broadcast_shape.insert(self.axis, self.groups) - else: - broadcast_shape[self.axis] = self.groups - return broadcast_shape - - -class TFWav2Vec2WeightNormConv1D(keras.layers.Conv1D): - """Adapted from https://www.tensorflow.org/probability/api_docs/python/tfp/layers/weight_norm/WeightNorm""" - - def __init__(self, filters, kernel_size, groups, explicit_padding, **kwargs): - super().__init__( - filters=filters, - kernel_size=kernel_size, - groups=groups, - padding="valid", - use_bias=True, - bias_initializer="he_normal", - **kwargs, - ) - self.explicit_padding = explicit_padding - self.filter_axis = 2 - self.kernel_norm_axes = tf.constant([0, 1]) - - def _init_norm(self): - """Set the norm of the weight vector.""" - kernel_norm = tf.sqrt(tf.reduce_sum(tf.square(self.weight_v), axis=self.kernel_norm_axes)) - self.weight_g.assign(kernel_norm[:, tf.newaxis, tf.newaxis]) - - def _normalize_kernel(self): - """Generate normalized weights.""" - kernel = tf.nn.l2_normalize(self.weight_v, axis=self.kernel_norm_axes) * tf.transpose(self.weight_g) - self.kernel = tf.transpose(kernel) - - def build(self, input_shape): - if not self.built: - super().build(input_shape) - - self.kernel = tf.Variable(tf.transpose(self.kernel), name="weight_v", trainable=True) - self.weight_v = self.kernel - - self.weight_g = self.add_weight( - name="weight_g", - shape=(int(self.weight_v.shape[self.filter_axis]), 1, 1), - initializer="ones", - dtype=self.weight_v.dtype, - trainable=True, - ) - self._init_norm() - self.bias = self.add_weight(name="bias", shape=(self.filters,), initializer="zeros", trainable=True) - - def call(self, inputs): - # TODO Matt: Assigning to attributes in call() is deeply sinful in TensorFlow, as it should be idempotent. - # This whole layer should be replaced by a layer that doesn't inherit from Conv1D, but instead calls - # a functional 1d convolution with normalized weights that it generates (but does not store!) - self._normalize_kernel() - - padded_inputs = tf.pad(inputs, ((0, 0), (self.explicit_padding, self.explicit_padding), (0, 0))) - output = super().call(padded_inputs) - - return output - - -class TFWav2Vec2NoLayerNormConvLayer(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, layer_id: int = 0, **kwargs: Any) -> None: - super().__init__(**kwargs) - self.in_conv_dim = config.conv_dim[layer_id] if layer_id > 0 else 1 - self.out_conv_dim = config.conv_dim[layer_id] - - self.conv = keras.layers.Conv1D( - filters=self.out_conv_dim, - kernel_size=config.conv_kernel[layer_id], - strides=config.conv_stride[layer_id], - use_bias=config.conv_bias, - name="conv", - ) - self.activation = get_tf_activation(config.feat_extract_activation) - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.conv(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build([None, None, self.in_conv_dim]) - - -class TFWav2Vec2LayerNormConvLayer(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, layer_id: int = 0, **kwargs: Any) -> None: - super().__init__(**kwargs) - self.in_conv_dim = config.conv_dim[layer_id] if layer_id > 0 else 1 - self.out_conv_dim = config.conv_dim[layer_id] - - self.conv = keras.layers.Conv1D( - filters=self.out_conv_dim, - kernel_size=config.conv_kernel[layer_id], - strides=config.conv_stride[layer_id], - use_bias=config.conv_bias, - name="conv", - ) - self.layer_norm = keras.layers.LayerNormalization(name="layer_norm", epsilon=config.layer_norm_eps) - self.activation = get_tf_activation(config.feat_extract_activation) - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.conv(hidden_states) - hidden_states = self.layer_norm(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build([None, None, self.in_conv_dim]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.out_conv_dim]) - - -class TFWav2Vec2GroupNormConvLayer(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, layer_id: int = 0, **kwargs: Any) -> None: - super().__init__(**kwargs) - self.in_conv_dim = config.conv_dim[layer_id] if layer_id > 0 else 1 - self.out_conv_dim = config.conv_dim[layer_id] - - self.conv = keras.layers.Conv1D( - filters=self.out_conv_dim, - kernel_size=config.conv_kernel[layer_id], - strides=config.conv_stride[layer_id], - use_bias=config.conv_bias, - name="conv", - ) - self.activation = get_tf_activation(config.feat_extract_activation) - self.layer_norm = TFWav2Vec2GroupNorm( - groups=self.out_conv_dim, epsilon=config.layer_norm_eps, name="layer_norm" - ) - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.conv(hidden_states) - hidden_states = self.layer_norm(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build([None, None, self.in_conv_dim]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.out_conv_dim]) - - -class TFWav2Vec2PositionalConvEmbedding(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, **kwargs: Any) -> None: - super().__init__(**kwargs) - self.conv = TFWav2Vec2WeightNormConv1D( - filters=config.hidden_size, - kernel_size=config.num_conv_pos_embeddings, - groups=config.num_conv_pos_embedding_groups, - explicit_padding=config.num_conv_pos_embeddings // 2, - name="conv", - ) - self.padding = TFWav2Vec2SamePadLayer(config.num_conv_pos_embeddings) - self.activation = get_tf_activation(config.feat_extract_activation) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.conv(hidden_states) - hidden_states = self.padding(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv", None) is not None: - with tf.name_scope(self.conv.name): - self.conv.build([None, None, self.config.hidden_size]) - - -class TFWav2Vec2SamePadLayer(keras.layers.Layer): - def __init__(self, num_conv_pos_embeddings, **kwargs): - super().__init__(**kwargs) - self.num_pad_remove = 1 if num_conv_pos_embeddings % 2 == 0 else 0 - - def call(self, hidden_states): - if self.num_pad_remove > 0: - hidden_states = hidden_states[:, : -self.num_pad_remove, :] - return hidden_states - - -class TFWav2Vec2FeatureEncoder(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, **kwargs: Any) -> None: - super().__init__(**kwargs) - - if config.feat_extract_norm == "group": - conv_layers = [TFWav2Vec2GroupNormConvLayer(config, layer_id=0, name=f"conv_layers.{0}")] + [ - TFWav2Vec2NoLayerNormConvLayer(config, layer_id=i + 1, name=f"conv_layers.{i + 1}") - for i in range(config.num_feat_extract_layers - 1) - ] - elif config.feat_extract_norm == "layer": - conv_layers = [ - TFWav2Vec2LayerNormConvLayer(config, layer_id=i, name=f"conv_layers.{i}") - for i in range(config.num_feat_extract_layers) - ] - else: - raise ValueError( - f"`config.feat_extract_norm` is {config.feat_extract_norm}, but has to be one of ['group', 'layer']" - ) - self.conv_layers = conv_layers - - def call(self, input_values): - hidden_states = tf.expand_dims(input_values, -1) - for conv_layer in self.conv_layers: - hidden_states = conv_layer(hidden_states) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv_layers", None) is not None: - for conv_layer in self.conv_layers: - with tf.name_scope(conv_layer.name): - conv_layer.build(None) - - -class TFWav2Vec2FeatureExtractor(TFWav2Vec2FeatureEncoder): - def __init__(self, config, **kwargs): - super().__init__(config, **kwargs) - warnings.warn( - f"The class `{self.__class__.__name__}` has been depreciated " - "and will be removed in Transformers v5. " - f"Use `{self.__class__.__bases__[0].__name__}` instead.", - FutureWarning, - ) - - -class TFWav2Vec2FeatureProjection(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, **kwargs): - super().__init__(**kwargs) - - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.projection = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer="zeros", - name="projection", - ) - self.dropout = keras.layers.Dropout(rate=config.feat_proj_dropout) - self.config = config - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - norm_hidden_states = self.layer_norm(hidden_states) - hidden_states = self.projection(norm_hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - return hidden_states, norm_hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.conv_dim[-1]]) - if getattr(self, "projection", None) is not None: - with tf.name_scope(self.projection.name): - self.projection.build([None, None, self.config.conv_dim[-1]]) - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with TFBart->TFWav2Vec2 -class TFWav2Vec2Attention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -class TFWav2Vec2FeedForward(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, **kwargs): - super().__init__(**kwargs) - - self.intermediate_dropout = keras.layers.Dropout(config.activation_dropout) - - self.intermediate_dense = keras.layers.Dense( - units=config.intermediate_size, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer="zeros", - name="intermediate_dense", - ) - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - - self.output_dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - bias_initializer="zeros", - name="output_dense", - ) - self.output_dropout = keras.layers.Dropout(config.hidden_dropout) - self.config = config - - def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.intermediate_dense(hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - hidden_states = self.intermediate_dropout(hidden_states, training=training) - - hidden_states = self.output_dense(hidden_states) - hidden_states = self.output_dropout(hidden_states, training=training) - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "intermediate_dense", None) is not None: - with tf.name_scope(self.intermediate_dense.name): - self.intermediate_dense.build([None, None, self.config.hidden_size]) - if getattr(self, "output_dense", None) is not None: - with tf.name_scope(self.output_dense.name): - self.output_dense.build([None, None, self.config.intermediate_size]) - - -class TFWav2Vec2EncoderLayer(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, **kwargs): - super().__init__(**kwargs) - self.attention = TFWav2Vec2Attention( - embed_dim=config.hidden_size, - num_heads=config.num_attention_heads, - dropout=config.attention_dropout, - is_decoder=False, - name="attention", - ) - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.feed_forward = TFWav2Vec2FeedForward(config, name="feed_forward") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - attn_residual = hidden_states - hidden_states, attn_weights, _ = self.attention( - hidden_states, attention_mask=attention_mask, training=training - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = attn_residual + hidden_states - - hidden_states = self.layer_norm(hidden_states) - hidden_states = hidden_states + self.feed_forward(hidden_states) - hidden_states = self.final_layer_norm(hidden_states) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "feed_forward", None) is not None: - with tf.name_scope(self.feed_forward.name): - self.feed_forward.build(None) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.config.hidden_size]) - - -class TFWav2Vec2EncoderLayerStableLayerNorm(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, **kwargs): - super().__init__(**kwargs) - self.attention = TFWav2Vec2Attention( - embed_dim=config.hidden_size, - num_heads=config.num_attention_heads, - dropout=config.attention_dropout, - is_decoder=False, - name="attention", - ) - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.feed_forward = TFWav2Vec2FeedForward(config, name="feed_forward") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = False, - training: bool = False, - ) -> tuple[tf.Tensor]: - attn_residual = hidden_states - hidden_states = self.layer_norm(hidden_states) - hidden_states, attn_weights, _ = self.attention( - hidden_states, attention_mask=attention_mask, training=training - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = attn_residual + hidden_states - hidden_states = hidden_states + self.feed_forward(self.final_layer_norm(hidden_states)) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "feed_forward", None) is not None: - with tf.name_scope(self.feed_forward.name): - self.feed_forward.build(None) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.config.hidden_size]) - - -class TFWav2Vec2Encoder(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.pos_conv_embed = TFWav2Vec2PositionalConvEmbedding(config, name="pos_conv_embed") - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.layer = [TFWav2Vec2EncoderLayer(config, name=f"layers.{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = False, - output_hidden_states: bool | None = False, - return_dict: bool | None = True, - training: bool | None = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - - if attention_mask is not None: - hidden_states = hidden_states * tf.expand_dims(attention_mask, -1) - attention_mask = _expand_mask(attention_mask) - else: - attention_mask = None - - position_embeddings = self.pos_conv_embed(hidden_states) - hidden_states = hidden_states + position_embeddings - hidden_states = self.layer_norm(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = np.random.uniform(0, 1) - if training and (dropout_probability < self.config.layerdrop): # skip the layer - continue - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "pos_conv_embed", None) is not None: - with tf.name_scope(self.pos_conv_embed.name): - self.pos_conv_embed.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFWav2Vec2EncoderStableLayerNorm(keras.layers.Layer): - def __init__(self, config: Wav2Vec2Config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.pos_conv_embed = TFWav2Vec2PositionalConvEmbedding(config, name="pos_conv_embed") - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.dropout = keras.layers.Dropout(config.hidden_dropout) - self.layer = [ - TFWav2Vec2EncoderLayerStableLayerNorm(config, name=f"layers.{i}") for i in range(config.num_hidden_layers) - ] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = False, - output_hidden_states: bool | None = False, - return_dict: bool | None = True, - training: bool | None = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - - if attention_mask is not None: - hidden_states = hidden_states * tf.expand_dims(attention_mask, -1) - attention_mask = _expand_mask(attention_mask) - else: - attention_mask = None - - position_embeddings = self.pos_conv_embed(hidden_states) - hidden_states = hidden_states + position_embeddings - hidden_states = self.dropout(hidden_states, training=training) - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = np.random.uniform(0, 1) - if training and (dropout_probability < self.config.layerdrop): # skip the layer - continue - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - - hidden_states = self.layer_norm(hidden_states) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "pos_conv_embed", None) is not None: - with tf.name_scope(self.pos_conv_embed.name): - self.pos_conv_embed.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFWav2Vec2MainLayer(keras.layers.Layer): - config_class = Wav2Vec2Config - - def __init__(self, config: Wav2Vec2Config, **kwargs): - super().__init__(**kwargs) - self.config = config - self.feature_extractor = TFWav2Vec2FeatureEncoder(config, name="feature_extractor") - self.feature_projection = TFWav2Vec2FeatureProjection(config, name="feature_projection") - - if config.do_stable_layer_norm: - self.encoder = TFWav2Vec2EncoderStableLayerNorm(config, name="encoder") - else: - self.encoder = TFWav2Vec2Encoder(config, name="encoder") - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if self.config.mask_time_prob > 0.0 or self.config.mask_feature_prob > 0.0: - self.masked_spec_embed = self.add_weight( - shape=(self.config.hidden_size,), initializer="uniform", trainable=True, name="masked_spec_embed" - ) - if getattr(self, "feature_extractor", None) is not None: - with tf.name_scope(self.feature_extractor.name): - self.feature_extractor.build(None) - if getattr(self, "feature_projection", None) is not None: - with tf.name_scope(self.feature_projection.name): - self.feature_projection.build(None) - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - - def _get_feat_extract_output_lengths(self, input_lengths: tf.Tensor): - """ - Computes the output length of the convolutional layers - """ - - def _conv_out_length(input_length, kernel_size, stride): - # 1D convolutional layer output length formula taken - # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html - return (input_length - kernel_size) // stride + 1 - - for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): - input_lengths = _conv_out_length(input_lengths, kernel_size, stride) - - return input_lengths - - def _mask_hidden_states(self, hidden_states: tf.Tensor, mask_time_indices: tf.Tensor | None = None): - """ - Masks extracted features along time axis and/or along feature axis according to - [SpecAugment](https://huggingface.co/papers/1904.08779). - """ - batch_size, sequence_length, hidden_size = shape_list(hidden_states) - - # `config.apply_spec_augment` can set masking to False - if not getattr(self.config, "apply_spec_augment", True): - return hidden_states - - if mask_time_indices is not None: - # apply SpecAugment along time axis with given mask_time_indices - hidden_states = tf.where( - tf.cast(mask_time_indices[:, :, tf.newaxis], tf.bool), - self.masked_spec_embed[tf.newaxis, tf.newaxis, :], - hidden_states, - ) - - elif self.config.mask_time_prob > 0: - # generate indices & apply SpecAugment along time axis - mask_time_indices = _compute_mask_indices( - (batch_size, sequence_length), - mask_prob=self.config.mask_time_prob, - mask_length=self.config.mask_time_length, - min_masks=2, - ) - hidden_states = tf.where( - tf.cast(mask_time_indices[:, :, tf.newaxis], tf.bool), - self.masked_spec_embed[tf.newaxis, tf.newaxis, :], - hidden_states, - ) - - # apply SpecAugment along feature axis - if self.config.mask_feature_prob > 0: - mask_feature_indices = _compute_mask_indices( - (batch_size, hidden_size), - mask_prob=self.config.mask_feature_prob, - mask_length=self.config.mask_feature_length, - ) - hidden_states = tf.where(mask_feature_indices[:, tf.newaxis, :], hidden_states, 0) - - return hidden_states - - @unpack_inputs - def call( - self, - input_values: tf.Tensor, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - **kwargs: Any, - ): - extract_features = self.feature_extractor(tf.cast(input_values, tf.float32), training=training) - # extract_features = tf.transpose(extract_features, perm=(0, 2, 1)) - - if attention_mask is not None: - # compute real output lengths according to convolution formula - output_lengths = self._get_feat_extract_output_lengths(tf.reduce_sum(attention_mask, -1)) - - attention_mask = tf.sequence_mask( - output_lengths, maxlen=shape_list(extract_features)[1], dtype=extract_features.dtype - ) - - hidden_states, extract_features = self.feature_projection(extract_features, training=training) - - mask_time_indices = kwargs.get("mask_time_indices") - if training: - hidden_states = self._mask_hidden_states(hidden_states, mask_time_indices=mask_time_indices) - - encoder_outputs = self.encoder( - hidden_states, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = encoder_outputs[0] - - if not return_dict: - return (hidden_states, extract_features) + encoder_outputs[1:] - - return TFWav2Vec2BaseModelOutput( - last_hidden_state=hidden_states, - extract_features=extract_features, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - -class TFWav2Vec2PreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = Wav2Vec2Config - base_model_prefix = "wav2vec2" - main_input_name = "input_values" - - @property - def input_signature(self): - return { - "input_values": tf.TensorSpec((None, None), tf.float32, name="input_values"), - "attention_mask": tf.TensorSpec((None, None), tf.float32, name="attention_mask"), - } - - @property - def dummy_inputs(self): - return { - "input_values": tf.random.uniform(shape=(1, 500), dtype=tf.float32), - "attention_mask": tf.ones(shape=(1, 500), dtype=tf.float32), - } - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - logger.warning( - f"\n{self.__class__.__name__} has backpropagation operations that are NOT supported on CPU. If you wish " - "to train/fine-tune this model, you need a GPU or a TPU" - ) - - def _get_feat_extract_output_lengths(self, input_lengths, add_adapter=None): - """ - Computes the output length of the convolutional layers - """ - add_adapter = self.config.add_adapter if add_adapter is None else add_adapter - - def _conv_out_length(input_length, kernel_size, stride): - return tf.math.floordiv(input_length - kernel_size, stride) + 1 - - for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): - input_lengths = _conv_out_length(input_lengths, kernel_size, stride) - - if add_adapter: - for _ in range(self.config.num_adapter_layers): - input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) - return input_lengths - - def _get_feature_vector_attention_mask( - self, feature_vector_length: int, attention_mask: tf.Tensor, add_adapter=None - ): - non_padded_lengths = tf.math.cumsum(attention_mask, axis=-1)[:, -1] - output_lengths = self._get_feat_extract_output_lengths(non_padded_lengths, add_adapter=add_adapter) - output_lengths = tf.cast(output_lengths, tf.int32) - batch_size = tf.shape(attention_mask)[0] - # check device here - attention_mask = tf.zeros( - (batch_size, feature_vector_length), dtype=attention_mask.dtype, name="attention_mask" - ) # these two operations makes sure that all values before the output lengths idxs are attended to - ## check device - attention_mask = tf.tensor_scatter_nd_update( - attention_mask, - indices=tf.stack([tf.range(batch_size), output_lengths - 1], axis=1), - updates=tf.ones([batch_size], dtype=attention_mask.dtype), - ) - attention_mask = tf.reverse(attention_mask, axis=[-1]) - attention_mask = tf.cumsum(attention_mask, axis=-1) - attention_mask = tf.reverse(attention_mask, axis=[-1]) - attention_mask = tf.cast(attention_mask, tf.bool) - return attention_mask - - -WAV2VEC2_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_values` only and nothing else: `model(input_values)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_values, attention_mask])` or `model([input_values, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_values": input_values, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`Wav2Vec2Config`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -WAV2VEC2_INPUTS_DOCSTRING = r""" - Args: - input_values (`np.ndarray`, `tf.Tensor`, `list[tf.Tensor]` `dict[str, tf.Tensor]` or `dict[str, np.ndarray]` and each example must have the shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_values` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_values` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False``): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare TFWav2Vec2 Model transformer outputting raw hidden-states without any specific head on top.", - WAV2VEC2_START_DOCSTRING, -) -class TFWav2Vec2Model(TFWav2Vec2PreTrainedModel): - def __init__(self, config: Wav2Vec2Config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.config = config - self.wav2vec2 = TFWav2Vec2MainLayer(config, name="wav2vec2") - - @add_start_docstrings_to_model_forward(WAV2VEC2_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFBaseModelOutput, config_class=_CONFIG_FOR_DOC) - @unpack_inputs - def call( - self, - input_values: tf.Tensor, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - """ - - Returns: - - Example: - - ```python - >>> from transformers import AutoProcessor, TFWav2Vec2Model - >>> from datasets import load_dataset - - >>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-base-960h") - >>> model = TFWav2Vec2Model.from_pretrained("facebook/wav2vec2-base-960h") - - - >>> def map_to_array(example): - ... example["speech"] = example["audio"]["array"] - ... return example - - - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> ds = ds.map(map_to_array) - - >>> input_values = processor(ds["speech"][0], return_tensors="tf").input_values # Batch size 1 - >>> hidden_states = model(input_values).last_hidden_state - ```""" - - output_hidden_states = output_hidden_states if output_hidden_states else self.config.output_hidden_states - output_attentions = output_attentions if output_attentions else self.config.output_attentions - return_dict = return_dict if return_dict else self.config.return_dict - - outputs = self.wav2vec2( - input_values=input_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "wav2vec2", None) is not None: - with tf.name_scope(self.wav2vec2.name): - self.wav2vec2.build(None) - - -@add_start_docstrings( - """TFWav2Vec2 Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).""", - WAV2VEC2_START_DOCSTRING, -) -class TFWav2Vec2ForCTC(TFWav2Vec2PreTrainedModel): - def __init__(self, config: Wav2Vec2Config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.wav2vec2 = TFWav2Vec2MainLayer(config, name="wav2vec2") - self.dropout = keras.layers.Dropout(config.final_dropout) - self.lm_head = keras.layers.Dense(config.vocab_size, name="lm_head") - self.output_hidden_size = ( - config.output_hidden_size if hasattr(config, "add_adapter") and config.add_adapter else config.hidden_size - ) - - def freeze_feature_extractor(self): - """ - Calling this function will disable the gradient computation for the feature encoder so that its parameters will - not be updated during training. - """ - warnings.warn( - "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5. " - "Please use the equivalent `freeze_feature_encoder` method instead.", - FutureWarning, - ) - self.freeze_feature_encoder() - - def freeze_feature_encoder(self): - """ - Calling this function will disable the gradient computation for the feature encoder so that its parameter will - not be updated during training. - """ - self.wav2vec2.feature_extractor.trainable = False - - @unpack_inputs - @add_start_docstrings_to_model_forward(WAV2VEC2_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFCausalLMOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_values: tf.Tensor, - attention_mask: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - labels: tf.Tensor | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> TFCausalLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_values` docstring) Tokens with indices set to `-100` are ignored (masked), - the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - - Returns: - - Example: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoProcessor, TFWav2Vec2ForCTC - >>> from datasets import load_dataset - >>> from torchcodec.decoders import AudioDecoder - - >>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-base-960h") - >>> model = TFWav2Vec2ForCTC.from_pretrained("facebook/wav2vec2-base-960h") - - - >>> def map_to_array(example): - ... example["speech"] = example["audio"]["array"] - ... return example - - - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> ds = ds.map(map_to_array) - - >>> input_values = processor(ds["speech"][0], return_tensors="tf").input_values # Batch size 1 - >>> logits = model(input_values).logits - >>> predicted_ids = tf.argmax(logits, axis=-1) - - >>> transcription = processor.decode(predicted_ids[0]) - - >>> # compute loss - >>> target_transcription = "A MAN SAID TO THE UNIVERSE SIR I EXIST" - - >>> # Pass transcription as `text` to encode labels - >>> labels = processor(text=transcription, return_tensors="tf").input_ids - - >>> loss = model(input_values, labels=labels).loss - ```""" - if labels is not None and tf.reduce_max(labels) >= self.config.vocab_size: - raise ValueError(f"Label values must be <= vocab_size: {self.config.vocab_size}") - - outputs = self.wav2vec2( - input_values=input_values, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, training=training) - - logits = self.lm_head(hidden_states) - - if labels is not None: - attention_mask = ( - attention_mask if attention_mask is not None else tf.ones_like(input_values, dtype=tf.float32) - ) - input_lengths = self.wav2vec2._get_feat_extract_output_lengths(tf.reduce_sum(attention_mask, axis=-1)) - - # assuming that padded tokens are filled with -100 - # when not being attended to - labels_mask = tf.cast(labels >= 0, tf.int32) - target_lengths = tf.reduce_sum(labels_mask, axis=-1) - - loss = tf.nn.ctc_loss( - logits=logits, - labels=labels, - logit_length=input_lengths, - label_length=target_lengths, - blank_index=self.config.pad_token_id, - logits_time_major=False, - ) - - if self.config.ctc_loss_reduction == "sum": - loss = tf.reduce_sum(loss) - if self.config.ctc_loss_reduction == "mean": - loss = tf.reduce_mean(loss) - - loss = tf.reshape(loss, (1,)) - else: - loss = None - - if not return_dict: - output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "wav2vec2", None) is not None: - with tf.name_scope(self.wav2vec2.name): - self.wav2vec2.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build([None, None, self.output_hidden_size]) - - -class TFWav2Vec2ForSequenceClassification(TFWav2Vec2PreTrainedModel): - def __init__(self, config): - super().__init__(config) - self.wav2vec2 = TFWav2Vec2MainLayer(config, name="wav2vec2") - self.num_layers = config.num_hidden_layers + 1 - with tf.name_scope(self._name_scope()): - if config.use_weighted_layer_sum: - self.layer_weights = self.add_weight( - shape=(self.num_layers,), initializer="ones", trainable=True, name="layer_weights" - ) - self.config = config - self.projector = keras.layers.Dense(units=config.classifier_proj_size, name="projector") - self.classifier = keras.layers.Dense(units=config.num_labels, activation=None, name="classifier") - - def freeze_feature_extractor(self): - """ - Calling this function will disable the gradient computation for the feature encoder so that its parameters will - not be updated during training. - """ - warnings.warn( - "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5. " - "Please use the equivalent `freeze_feature_encoder` method instead.", - FutureWarning, - ) - self.freeze_feature_encoder() - - def freeze_feature_encoder(self): - """ - Calling this function will disable the gradient computation for the feature encoder so that its parameter will - not be updated during training. - """ - self.wav2vec2.feature_extractor.trainable = False - - def freeze_base_model(self): - """ - Calling this function will disable the gradient computation for the base model so that its parameters will not - be updated during training. Only the classification head will be updated. - """ - for layer in self.wav2vec2.layers: - layer.trainable = False - - @unpack_inputs - def call( - self, - input_values: tf.Tensor, - attention_mask: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: tf.Tensor | None = None, - training: bool = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states - - outputs = self.wav2vec2( - input_values, - attention_mask=attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - if self.config.use_weighted_layer_sum: - hidden_states = outputs[_HIDDEN_STATES_START_POSITION] - hidden_states = tf.stack(hidden_states, axis=1) - norm_weights = tf.nn.softmax(self.layer_weights, axis=-1) - hidden_states = tf.reduce_sum(hidden_states * tf.reshape(norm_weights, [-1, 1, 1]), axis=1) - else: - hidden_states = outputs[0] - - hidden_states = self.projector(hidden_states) - if attention_mask is None: - pooled_output = tf.reduce_mean(hidden_states, axis=1) - else: - padding_mask = self._get_feature_vector_attention_mask(shape_list(hidden_states)[1], attention_mask) - padding_mask_float = tf.cast(padding_mask, hidden_states.dtype) - hidden_states = tf.multiply(hidden_states, tf.expand_dims(padding_mask_float, axis=-1)) - pooled_output = tf.divide( - tf.reduce_sum(hidden_states, axis=1), tf.expand_dims(tf.reduce_sum(padding_mask_float, axis=1), axis=1) - ) - logits = self.classifier(pooled_output) - loss = None - if labels is not None: - loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True) - loss = loss_fn(tf.reshape(labels, [-1]), tf.reshape(logits, [-1, self.config.num_labels])) - if not return_dict: - output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "wav2vec2", None) is not None: - with tf.name_scope(self.wav2vec2.name): - self.wav2vec2.build(None) - if getattr(self, "projector", None) is not None: - with tf.name_scope(self.projector.name): - self.projector.build([None, None, self.config.hidden_size]) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.classifier_proj_size]) - - -__all__ = ["TFWav2Vec2ForCTC", "TFWav2Vec2Model", "TFWav2Vec2PreTrainedModel", "TFWav2Vec2ForSequenceClassification"] diff --git a/src/transformers/models/wav2vec2/tokenization_wav2vec2.py b/src/transformers/models/wav2vec2/tokenization_wav2vec2.py index 7fab73706421..bce68eacd68e 100644 --- a/src/transformers/models/wav2vec2/tokenization_wav2vec2.py +++ b/src/transformers/models/wav2vec2/tokenization_wav2vec2.py @@ -30,9 +30,6 @@ PaddingStrategy, TensorType, add_end_docstrings, - is_flax_available, - is_tf_available, - is_torch_available, logging, to_py_obj, ) @@ -42,12 +39,7 @@ if TYPE_CHECKING: - if is_torch_available(): - import torch - if is_tf_available(): - import tensorflow as tf - if is_flax_available(): - import jax.numpy as jnp # noqa: F401 + import torch VOCAB_FILES_NAMES = { @@ -80,7 +72,6 @@ return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. verbose (`bool`, *optional*, defaults to `True`): @@ -457,7 +448,7 @@ def _decode( # because we need docs for `output_char_offsets` here def batch_decode( self, - sequences: Union[list[int], list[list[int]], "np.ndarray", "torch.Tensor", "tf.Tensor"], + sequences: Union[list[int], list[list[int]], "np.ndarray", "torch.Tensor"], skip_special_tokens: bool = False, clean_up_tokenization_spaces: Optional[bool] = None, output_char_offsets: bool = False, @@ -468,7 +459,7 @@ def batch_decode( Convert a list of lists of token ids into a list of strings by calling decode. Args: - sequences (`Union[list[int], list[list[int]], np.ndarray, torch.Tensor, tf.Tensor]`): + sequences (`Union[list[int], list[list[int]], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. @@ -527,7 +518,7 @@ def batch_decode( # and `output_word_offsets` here def decode( self, - token_ids: Union[int, list[int], "np.ndarray", "torch.Tensor", "tf.Tensor"], + token_ids: Union[int, list[int], "np.ndarray", "torch.Tensor"], skip_special_tokens: bool = False, clean_up_tokenization_spaces: Optional[bool] = None, output_char_offsets: bool = False, @@ -541,7 +532,7 @@ def decode( Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. Args: - token_ids (`Union[int, list[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. diff --git a/src/transformers/models/wav2vec2_phoneme/tokenization_wav2vec2_phoneme.py b/src/transformers/models/wav2vec2_phoneme/tokenization_wav2vec2_phoneme.py index 0715e3ce60f2..bd8a89303deb 100644 --- a/src/transformers/models/wav2vec2_phoneme/tokenization_wav2vec2_phoneme.py +++ b/src/transformers/models/wav2vec2_phoneme/tokenization_wav2vec2_phoneme.py @@ -26,9 +26,6 @@ from ...tokenization_utils_base import AddedToken from ...utils import ( ModelOutput, - is_flax_available, - is_tf_available, - is_torch_available, logging, requires_backends, to_py_obj, @@ -39,12 +36,7 @@ if TYPE_CHECKING: - if is_torch_available(): - import torch - if is_tf_available(): - import tensorflow as tf - if is_flax_available(): - import jax.numpy as jnp # noqa: F401 + import torch VOCAB_FILES_NAMES = { @@ -453,7 +445,7 @@ def _decode( # overwritten from `tokenization_utils_base.py` because we need docs for `output_char_offsets` here def decode( self, - token_ids: Union[int, list[int], "np.ndarray", "torch.Tensor", "tf.Tensor"], + token_ids: Union[int, list[int], "np.ndarray", "torch.Tensor"], skip_special_tokens: bool = False, clean_up_tokenization_spaces: Optional[bool] = None, output_char_offsets: bool = False, @@ -466,7 +458,7 @@ def decode( Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. Args: - token_ids (`Union[int, list[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. @@ -509,7 +501,7 @@ def decode( # we need docs for `output_char_offsets` here def batch_decode( self, - sequences: Union[list[int], list[list[int]], "np.ndarray", "torch.Tensor", "tf.Tensor"], + sequences: Union[list[int], list[list[int]], "np.ndarray", "torch.Tensor"], skip_special_tokens: bool = False, clean_up_tokenization_spaces: Optional[bool] = None, output_char_offsets: bool = False, @@ -519,7 +511,7 @@ def batch_decode( Convert a list of lists of token ids into a list of strings by calling decode. Args: - sequences (`Union[list[int], list[list[int]], np.ndarray, torch.Tensor, tf.Tensor]`): + sequences (`Union[list[int], list[list[int]], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. diff --git a/src/transformers/models/whisper/__init__.py b/src/transformers/models/whisper/__init__.py index a4956c5fbb25..ec73ac2b8fe9 100644 --- a/src/transformers/models/whisper/__init__.py +++ b/src/transformers/models/whisper/__init__.py @@ -20,8 +20,6 @@ if TYPE_CHECKING: from .configuration_whisper import * from .feature_extraction_whisper import * - from .modeling_flax_whisper import * - from .modeling_tf_whisper import * from .modeling_whisper import * from .processing_whisper import * from .tokenization_whisper import * diff --git a/src/transformers/models/whisper/configuration_whisper.py b/src/transformers/models/whisper/configuration_whisper.py index a8837cb1cdd2..1950e03f54e2 100644 --- a/src/transformers/models/whisper/configuration_whisper.py +++ b/src/transformers/models/whisper/configuration_whisper.py @@ -16,7 +16,7 @@ from collections import OrderedDict from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Any, Union from ...configuration_utils import PretrainedConfig from ...onnx import OnnxConfig, OnnxSeq2SeqConfigWithPast @@ -26,7 +26,6 @@ if TYPE_CHECKING: from ...feature_extraction_utils import FeatureExtractionMixin from ...tokenization_utils_base import PreTrainedTokenizerBase - from ...utils import TensorType logger = logging.get_logger(__name__) @@ -310,7 +309,6 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional["TensorType"] = None, sampling_rate: int = 22050, time_duration: float = 5.0, frequency: int = 220, @@ -320,7 +318,6 @@ def generate_dummy_inputs( self, preprocessor=preprocessor.feature_extractor, batch_size=batch_size, - framework=framework, sampling_rate=sampling_rate, time_duration=time_duration, frequency=frequency, @@ -329,7 +326,10 @@ def generate_dummy_inputs( seq_length = encoder_sequence_length // 2 if self.use_past else seq_length decoder_inputs = super().generate_dummy_inputs( - preprocessor.tokenizer, batch_size, seq_length, is_pair, framework + preprocessor.tokenizer, + batch_size, + seq_length, + is_pair, ) dummy_inputs["input_features"] = encoder_inputs.pop("input_features") diff --git a/src/transformers/models/whisper/feature_extraction_whisper.py b/src/transformers/models/whisper/feature_extraction_whisper.py index bf548ac8408f..e11895191f95 100644 --- a/src/transformers/models/whisper/feature_extraction_whisper.py +++ b/src/transformers/models/whisper/feature_extraction_whisper.py @@ -236,7 +236,6 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. sampling_rate (`int`, *optional*): diff --git a/src/transformers/models/whisper/modeling_flax_whisper.py b/src/transformers/models/whisper/modeling_flax_whisper.py deleted file mode 100644 index 183fdd58f42c..000000000000 --- a/src/transformers/models/whisper/modeling_flax_whisper.py +++ /dev/null @@ -1,1707 +0,0 @@ -# coding=utf-8 -# Copyright 2022 The OpenAI Authors and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax whisper model.""" - -import math -import random -from functools import partial -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen import partitioning as nn_partitioning -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...generation.flax_logits_process import FlaxWhisperTimeStampLogitsProcessor -from ...modeling_flax_outputs import ( - FlaxBaseModelOutput, - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxSeq2SeqLMOutput, - FlaxSeq2SeqModelOutput, - FlaxSequenceClassifierOutput, -) -from ...modeling_flax_utils import ( - ACT2FN, - FlaxPreTrainedModel, - append_call_sample_docstring, - append_replace_return_docstrings, - overwrite_call_docstring, -) -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_whisper import WhisperConfig - - -logger = logging.get_logger(__name__) - - -_CHECKPOINT_FOR_DOC = "openai/whisper-tiny" -_CONFIG_FOR_DOC = "WhisperConfig" - -remat = nn_partitioning.remat - - -def sinusoidal_embedding_init(key, shape, dtype=jnp.float_) -> jax.Array: - """Returns sinusoids for positional embedding""" - length, channels = shape - if channels % 2 != 0: - raise ValueError( - f"Number of channels has to be divisible by 2 for sinusoidal positional embeddings, got {channels} channels." - ) - log_timescale_increment = math.log(10000) / (channels // 2 - 1) - inv_timescales = jnp.exp(-log_timescale_increment * jnp.arange(channels // 2)) - scaled_time = jnp.arange(length).reshape(-1, 1) * inv_timescales.reshape(1, -1) - return jnp.concatenate([jnp.sin(scaled_time), jnp.cos(scaled_time)], axis=1).astype(dtype) - - -WHISPER_START_DOCSTRING = r""" - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its models (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - Finally, this model supports inherent JAX features such as: - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`WhisperConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). This can be used to enable mixed-precision training or half-precision - inference on GPUs or TPUs. If specified all the computation will be performed with the given `dtype`. - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] - and [`~FlaxPreTrainedModel.to_bf16`]. -""" - -WHISPER_INPUTS_DOCSTRING = r""" - Args: - input_features (`numpy.ndarray` of shape `(batch_size, feature_size, sequence_length)`): - Float values mel features extracted from the raw speech waveform. Raw speech waveform can be obtained by - loading a `.flac` or `.wav` audio file into an array of type `list[float]`, a `numpy.ndarray` or a - `torch.Tensor`, *e.g.* via the torchcodec library (`pip install torchcodec`) or the soundfile library - (`pip install soundfile`). - To prepare the array into `input_features`, the [`WhisperFeatureExtractor`] should be used for extracting - the features, padding and conversion into a tensor of type `numpy.ndarray`. - See [`~WhisperFeatureExtractor.__call__`] - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Whisper does not support masking of the `input_features`, this argument is preserved for compatibility, but - is not used. By default the silence in the input log mel spectrogram are ignored. - decoder_input_ids (`numpy.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. Indices can be obtained using - [`WhisperTokenizer`]. See [`PreTrainedTokenizer.encode`] and [`PreTrainedTokenizer.__call__`] for details. - [What are decoder input IDs?](../glossary#decoder-input-ids) Whisper uses the `decoder_start_token_id` as - the starting token for `decoder_input_ids` generation. - decoder_attention_mask (`numpy.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. If you want to change padding behavior, you should modify to your needs. See diagram 1 - in [the paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Whisper does not use `position_ids` in the encoder as `input_features` is always the same size and doesn't - use masking, but this argument is preserved for compatibility. By default the silence in the input log mel - spectrogram are ignored. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -WHISPER_ENCODE_INPUTS_DOCSTRING = r""" - Args: - input_features (`numpy.ndarray` of shape `(batch_size, feature_size, sequence_length)`): - Float values mel features extracted from the raw speech waveform. Raw speech waveform can be obtained by - loading a `.flac` or `.wav` audio file into an array of type `list[float]`, a `numpy.ndarray` or a `torch.Tensor`, *e.g.* via - the torchcodec library (`pip install torchcodec`) or the soundfile library (`pip install soundfile`). - To prepare the array into `input_features`, the [`WhisperFeatureExtractor`] should be used for extracting - the mel features, padding and conversion into a tensor of type `numpy.ndarray`. - See [`~WhisperFeatureExtractor.__call__`]. - attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Whisper does not support masking of the `input_features`, this argument is preserved for compatibility, but - is not used. By default the silence in the input log mel spectrogram are ignored. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - -WHISPER_DECODE_INPUTS_DOCSTRING = r""" - Args: - decoder_input_ids (`numpy.ndarray` of shape `(batch_size, target_sequence_length)`): - Indices of decoder input sequence tokens in the vocabulary. Indices can be obtained using - [`WhisperTokenizer`]. See [`PreTrainedTokenizer.encode`] and [`PreTrainedTokenizer.__call__`] for details. - [What are decoder input IDs?](../glossary#decoder-input-ids) - encoder_outputs (`tuple(tuple(numpy.ndarray)`): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - encoder_attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Whisper does not support masking of the `input_features`, this argument is preserved for compatibility, - but it is not used. By default the silence in the input log mel spectrogram are ignored. - decoder_attention_mask (`numpy.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. If you want to change padding behavior, you should modify to your needs. See diagram 1 - in [the paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - past_key_values (`dict[str, numpy.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): - Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast - auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -class FlaxWhisperAttention(nn.Module): - config: WhisperConfig - embed_dim: int - num_heads: int - dropout: float = 0.0 - causal: bool = False - bias: bool = True - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.head_dim = self.embed_dim // self.num_heads - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {self.num_heads})." - ) - - dense = partial( - nn.Dense, - self.embed_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.q_proj = dense(use_bias=self.bias) - self.k_proj = dense(use_bias=False) - self.v_proj = dense(use_bias=self.bias) - self.out_proj = dense(use_bias=self.bias) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_target_positions), dtype="bool"), dtype="bool" - ) - - def __call__( - self, - hidden_states: jnp.ndarray, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - query_states = self.q_proj(hidden_states) - - if is_cross_attention: - key_states = self.k_proj(key_value_states) - value_states = self.v_proj(key_value_states) - else: - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, - (0, 0, mask_shift, 0), - (1, 1, query_length, max_decoder_length), - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights - - def _split_heads(self, hidden_state) -> jnp.ndarray: - return hidden_state.reshape(hidden_state.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_state) -> jnp.ndarray: - return hidden_state.reshape(hidden_state.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask) -> tuple[jnp.ndarray, jnp.ndarray, jnp.ndarray]: - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only - # attend to those key positions that have already been generated and cached, not the - # remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - - return key, value, attention_mask - - -# Copied from transformers.models.mbart.modeling_flax_mbart.FlaxMBartEncoderLayer with MBart->Whisper -class FlaxWhisperEncoderLayer(nn.Module): - config: WhisperConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxWhisperAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.encoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - self.fc1 = nn.Dense( - self.config.encoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - hidden_states, attn_weights = self.self_attn(hidden_states=hidden_states, attention_mask=attention_mask) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_weights,) - - return outputs - - -class FlaxWhisperEncoderLayerCollection(nn.Module): - config: WhisperConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - if self.gradient_checkpointing: - FlaxWhisperEncoderCheckpointLayer = remat(FlaxWhisperEncoderLayer, static_argnums=(2, 3)) - self.layers = [ - FlaxWhisperEncoderCheckpointLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.encoder_layers) - ] - else: - self.layers = [ - FlaxWhisperEncoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.encoder_layers) - ] - self.layerdrop = self.config.encoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - - for encoder_layer in self.layers: - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): # skip the layer - layer_outputs = (None, None) - else: - layer_outputs = encoder_layer( - hidden_states, - attention_mask, - output_attentions, - deterministic, - ) - hidden_states = layer_outputs[0] - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) - - -# Copied from transformers.models.mbart.modeling_flax_mbart.FlaxMBartDecoderLayer with MBart->Whisper -class FlaxWhisperDecoderLayer(nn.Module): - config: WhisperConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxWhisperAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - causal=True, - dtype=self.dtype, - ) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.encoder_attn = FlaxWhisperAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.fc1 = nn.Dense( - self.config.decoder_ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - hidden_states, self_attn_weights = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - hidden_states = self.encoder_attn_layer_norm(hidden_states) - hidden_states, cross_attn_weights = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights, cross_attn_weights) - - return outputs - - -class FlaxWhisperDecoderLayerCollection(nn.Module): - config: WhisperConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - if self.gradient_checkpointing: - FlaxWhisperDecoderCheckpointLayer = remat(FlaxWhisperDecoderLayer, static_argnums=(4, 5, 6)) - self.layers = [ - FlaxWhisperDecoderCheckpointLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.decoder_layers) - ] - else: - self.layers = [ - FlaxWhisperDecoderLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.decoder_layers) - ] - self.layerdrop = self.config.decoder_layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - for decoder_layer in self.layers: - if output_hidden_states: - all_hidden_states += (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): - layer_outputs = (None, None, None) - else: - layer_outputs = decoder_layer( - hidden_states, - attention_mask, - encoder_hidden_states, - encoder_attention_mask, - init_cache, - output_attentions, - deterministic, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attns += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = [hidden_states, all_hidden_states, all_self_attns, all_cross_attentions] - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - -class FlaxWhisperEncoder(nn.Module): - config: WhisperConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self) -> None: - self.conv1 = nn.Conv( - self.config.d_model, - kernel_size=(3,), - padding=1, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - self.conv2 = nn.Conv( - self.config.d_model, - kernel_size=(3,), - strides=2, - padding=1, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - dtype=self.dtype, - ) - - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - self.layers = FlaxWhisperEncoderLayerCollection( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - self.embed_positions = nn.Embed( - self.config.max_source_positions, - self.config.d_model, - dtype=self.dtype, - embedding_init=sinusoidal_embedding_init, - ) - - self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_features: jnp.ndarray, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - if input_features.shape[1:] != (self.config.num_mel_bins, self.config.max_source_positions * 2): - raise ValueError( - "input_features.shape[1:], must be equal to (self.config.num_mel_bins," - f" self.config.max_source_positions * 2) (got {input_features.shape[1:]}, but should be" - f" ({self.config.num_mel_bins}, {self.config.max_source_positions * 2}))" - ) - - input_features = input_features.transpose(0, 2, 1) - hidden_states = jax.nn.gelu(self.conv1(input_features), approximate=False) - hidden_states = jax.nn.gelu(self.conv2(hidden_states), approximate=False) - - embed_positions = self.embed_positions(jnp.arange(self.config.max_source_positions)) - # freeze the sinusoidal embeddings by stopping the back-prop - embed_positions = jax.lax.stop_gradient(embed_positions) - hidden_states = hidden_states + embed_positions - - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask=None, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - last_hidden_states = outputs[0] - last_hidden_states = self.layer_norm(last_hidden_states) - - # update the last element in `hidden_states` after applying `layernorm` above - hidden_states = None - if output_hidden_states: - hidden_states = outputs[1] - hidden_states = hidden_states[:-1] + (last_hidden_states,) - - if not return_dict: - outputs = (last_hidden_states, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutput( - last_hidden_state=last_hidden_states, - hidden_states=hidden_states, - attentions=outputs.attentions, - ) - - -class FlaxWhisperDecoder(nn.Module): - config: WhisperConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self) -> None: - self.embed_tokens = nn.Embed(self.config.vocab_size, self.config.d_model, dtype=self.dtype) - self.embed_positions = nn.Embed(self.config.max_target_positions, self.config.d_model, dtype=self.dtype) - - self.layers = FlaxWhisperDecoderLayerCollection( - self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-5) - - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: jnp.ndarray, - position_ids: jnp.ndarray, - encoder_hidden_states: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - input_embeds = self.embed_tokens(input_ids) - position_embeds = self.embed_positions(position_ids) - - hidden_states = input_embeds + position_embeds - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - last_hidden_states = outputs[0] - last_hidden_states = self.layer_norm(last_hidden_states) - - # update the last element in `hidden_states` after applying `layernorm` above - hidden_states = None - if output_hidden_states: - hidden_states = outputs[1] - hidden_states = hidden_states[:-1] + (last_hidden_states,) - - if not return_dict: - outputs = (last_hidden_states, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=last_hidden_states, - hidden_states=hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -class FlaxWhisperModule(nn.Module): - config: WhisperConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self) -> None: - self.encoder = FlaxWhisperEncoder( - self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.decoder = FlaxWhisperDecoder( - self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - - def __call__( - self, - input_features: jnp.ndarray, - decoder_input_ids: jnp.ndarray, - decoder_attention_mask: jnp.ndarray, - decoder_position_ids: jnp.ndarray, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - encoder_outputs = self.encoder( - input_features, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return FlaxSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def _get_encoder_module(self): - return self.encoder - - def _get_decoder_module(self): - return self.decoder - - -class FlaxWhisperPreTrainedModel(FlaxPreTrainedModel): - config_class = WhisperConfig - base_model_prefix: str = "model" - main_input_name = "input_features" - module_class: nn.Module = None - - def __init__( - self, - config: WhisperConfig, - input_shape: Optional[tuple[int]] = None, - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - gradient_checkpointing: bool = False, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, gradient_checkpointing=gradient_checkpointing, **kwargs) - if input_shape is None: - input_shape = (1, config.num_mel_bins, 2 * config.max_source_positions) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def enable_gradient_checkpointing(self): - self._module = self.module_class( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=True, - ) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_features = jnp.zeros(input_shape, dtype="f4") - input_features = input_features.at[(..., -1)].set(self.config.eos_token_id) - - decoder_input_ids = jnp.zeros((input_shape[0], 1), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - input_features=input_features, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartPreTrainedModel.init_cache with Bart->Whisper - def init_cache(self, batch_size, max_length, encoder_outputs): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): - `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: - `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) - is a sequence of hidden-states at the output of the last layer of the encoder. Used in the - cross-attention of the decoder. - """ - # init input variables to retrieve cache - decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - decoder_position_ids = jnp.broadcast_to( - jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape - ) - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - decoder_input_ids, - decoder_attention_mask, - decoder_position_ids, - **kwargs, - ) - - init_variables = self.module.init( - jax.random.PRNGKey(0), - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - init_cache=True, - method=_decoder_forward, # we only need to call the decoder to init the cache - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings(WHISPER_ENCODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=WhisperConfig) - def encode( - self, - input_features: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - **kwargs, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import WhisperProcessor, FlaxWhisperForConditionalGeneration - >>> from datasets import load_dataset - - >>> processor = WhisperProcessor.from_pretrained("openai/whisper-tiny.en") - >>> model = FlaxWhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en", from_pt=True) - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="np") - >>> input_features = inputs.input_features - >>> encoder_outputs = model.encode(input_features=input_features) - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - def _encoder_forward(module, input_features, **kwargs): - encode_module = module._get_encoder_module() - return encode_module(input_features, **kwargs) - - return self.module.apply( - {"params": params or self.params}, - input_features=jnp.array(input_features, dtype="f4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - method=_encoder_forward, - ) - - @add_start_docstrings(WHISPER_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=WhisperConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import WhisperProcessor, FlaxWhisperForConditionalGeneration - >>> from datasets import load_dataset - >>> import jax.numpy as jnp - - >>> processor = WhisperProcessor.from_pretrained("openai/whisper-tiny.en") - >>> model = FlaxWhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en", from_pt=True) - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> input_features = processor(ds[0]["audio"]["array"], return_tensors="np").input_features - - >>> encoder_outputs = model.encode(input_features=input_features) - >>> decoder_start_token_id = model.config.decoder_start_token_id - - >>> decoder_input_ids = jnp.ones((input_features.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> last_decoder_hidden_states = outputs.last_hidden_state - ```""" - - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - if decoder_attention_mask is not None: - decoder_position_ids = (decoder_attention_mask.cumsum(-1) * decoder_attention_mask) - 1 - else: - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxWhisperAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - return decoder_module( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - **kwargs, - ) - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past = outputs - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past = outputs - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) - def __call__( - self, - input_features: jnp.ndarray, - decoder_input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # prepare decoder inputs - if decoder_position_ids is None: - if decoder_attention_mask is not None: - decoder_position_ids = (decoder_attention_mask.cumsum(-1) * decoder_attention_mask) - 1 - else: - batch_size, sequence_length = decoder_input_ids.shape - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones_like(decoder_input_ids) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - return self.module.apply( - {"params": params or self.params}, - input_features=jnp.array(input_features, dtype="f4"), - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - ) - - -@add_start_docstrings( - "The bare Whisper Model transformer outputting raw hidden-states without any specific head on top.", - WHISPER_START_DOCSTRING, -) -class FlaxWhisperModel(FlaxWhisperPreTrainedModel): - config: WhisperConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - module_class = FlaxWhisperModule - - -append_call_sample_docstring(FlaxWhisperModel, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) - - -class FlaxWhisperForConditionalGenerationModule(nn.Module): - config: WhisperConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self) -> None: - self.model = FlaxWhisperModule( - config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - def _get_encoder_module(self): - return self.model.encoder - - def _get_decoder_module(self): - return self.model.decoder - - def __call__( - self, - input_features, - decoder_input_ids, - decoder_attention_mask: jnp.ndarray = None, - decoder_position_ids: jnp.ndarray = None, - position_ids: jnp.ndarray = None, - attention_mask: jnp.ndarray = None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_features=input_features, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=deterministic, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = self.model.decoder.embed_tokens.variables["params"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return output - - return FlaxSeq2SeqLMOutput( - logits=lm_logits, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - -@add_start_docstrings("The Whisper Model with a language modeling head.", WHISPER_START_DOCSTRING) -class FlaxWhisperForConditionalGeneration(FlaxWhisperPreTrainedModel): - module_class = FlaxWhisperForConditionalGenerationModule - dtype: jnp.dtype = jnp.float32 - - @add_start_docstrings(WHISPER_DECODE_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=WhisperConfig) - def decode( - self, - decoder_input_ids, - encoder_outputs, - encoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_attention_mask: Optional[jnp.ndarray] = None, - decoder_position_ids: Optional[jnp.ndarray] = None, - past_key_values: Optional[dict] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - r""" - Returns: - - Example: - - ```python - >>> from transformers import WhisperProcessor, FlaxWhisperForConditionalGeneration - >>> from datasets import load_dataset - - >>> processor = WhisperProcessor.from_pretrained("openai/whisper-tiny.en") - >>> model = FlaxWhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en", from_pt=True) - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="np") - >>> input_features = inputs.input_features - >>> encoder_outputs = model.encode(input_features=input_features) - >>> decoder_start_token_id = model.config.decoder_start_token_id - - >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id - - >>> outputs = model.decode(decoder_input_ids, encoder_outputs) - >>> last_decoder_hidden_states = outputs.last_hidden_state - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - encoder_hidden_states = encoder_outputs[0] - - batch_size, sequence_length = decoder_input_ids.shape - if decoder_position_ids is None: - if past_key_values is not None: - raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") - - if decoder_attention_mask is not None: - decoder_position_ids = (decoder_attention_mask.cumsum(-1) * decoder_attention_mask) - 1 - else: - decoder_position_ids = jnp.broadcast_to( - jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) - ) - if decoder_attention_mask is None: - decoder_attention_mask = jnp.ones((batch_size, sequence_length), dtype="i4") - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be - # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that - # it can be changed by FlaxWhisperAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): - decoder_module = module._get_decoder_module() - outputs = decoder_module( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - **kwargs, - ) - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = module.model.decoder.embed_tokens.variables["params"]["embedding"] - lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = module.lm_head(hidden_states) - - return lm_logits, outputs - - outputs = self.module.apply( - inputs, - decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), - decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), - decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - method=_decoder_forward, - ) - - if past_key_values is None: - lm_logits, decoder_outputs = outputs - else: - (lm_logits, decoder_outputs), past = outputs - - if return_dict: - outputs = FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=decoder_outputs.hidden_states, - attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - ) - else: - outputs = (lm_logits,) + decoder_outputs[1:] - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs["past_key_values"] = unfreeze(past["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] - - return outputs - - def generate( - self, - input_features, - generation_config=None, - logits_processor=None, - return_timestamps=None, - task=None, - language=None, - is_multilingual=None, - **kwargs, - ): - if generation_config is None: - generation_config = self.generation_config - - if return_timestamps is not None: - generation_config.return_timestamps = return_timestamps - - if task is not None: - generation_config.task = task - - if is_multilingual is not None: - generation_config.is_multilingual = is_multilingual - - if language is not None: - generation_config.language = language - - if kwargs is not None and "decoder_input_ids" in kwargs: - decoder_input_length = len(kwargs["decoder_input_ids"]) - else: - decoder_input_length = 1 - - forced_decoder_ids = [] - - if hasattr(generation_config, "is_multilingual") and generation_config.is_multilingual: - if hasattr(generation_config, "language"): - forced_decoder_ids.append((1, generation_config.lang_to_id[generation_config.language])) - else: - forced_decoder_ids.append((1, None)) - - if hasattr(generation_config, "task"): - forced_decoder_ids.append((2, generation_config.task_to_id[generation_config.task])) - else: - forced_decoder_ids.append((2, generation_config.task_to_id["transcribe"])) - - if ( - hasattr(generation_config, "return_timestamps") and generation_config.return_timestamps - ) or return_timestamps: - logits_processor = [ - FlaxWhisperTimeStampLogitsProcessor(generation_config, self.config, decoder_input_length) - ] - else: - if forced_decoder_ids and forced_decoder_ids[-1][0] != generation_config.no_timestamps_token_id: - idx = forced_decoder_ids[-1][0] + 1 if forced_decoder_ids else 1 - forced_decoder_ids.append((idx, generation_config.no_timestamps_token_id)) - - if len(forced_decoder_ids) > 0: - generation_config.forced_decoder_ids = forced_decoder_ids - - return super().generate( - input_features, - generation_config, - logits_processor=logits_processor, - **kwargs, - ) - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - max_length, - attention_mask: Optional[jax.Array] = None, - decoder_attention_mask: Optional[jax.Array] = None, - encoder_outputs=None, - **kwargs, - ): - # initializing the cache - batch_size, seq_length = decoder_input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if decoder_attention_mask is not None: - position_ids = decoder_attention_mask.cumsum(-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "encoder_outputs": encoder_outputs, - "encoder_attention_mask": attention_mask, - "decoder_attention_mask": extended_attention_mask, - "decoder_position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 - return model_kwargs - - -FLAX_WHISPER_CONDITIONAL_GENERATION_DOCSTRING = r""" - Returns: - - Transcription example: - - ```python - >>> from transformers import WhisperProcessor, FlaxWhisperForConditionalGeneration - >>> from datasets import load_dataset - - >>> processor = WhisperProcessor.from_pretrained("openai/whisper-tiny.en") - >>> model = FlaxWhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en", from_pt=True) - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="np") - >>> input_features = inputs.input_features - >>> generated_ids = model.generate(input_ids=input_features) - >>> transcription = processor.batch_decode(generated_ids, skip_special_tokens=True)[0] - >>> transcription - ' Mr. Quilter is the apostle of the middle classes, and we are glad to welcome his gospel.' - ``` -""" - -overwrite_call_docstring( - FlaxWhisperForConditionalGeneration, WHISPER_INPUTS_DOCSTRING + FLAX_WHISPER_CONDITIONAL_GENERATION_DOCSTRING -) -append_replace_return_docstrings( - FlaxWhisperForConditionalGeneration, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC -) - - -class FlaxWhisperForAudioClassificationModule(nn.Module): - config: WhisperConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self) -> None: - self.encoder = FlaxWhisperEncoder( - config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing - ) - self.config.is_encoder_decoder = False - num_layers = self.config.num_hidden_layers + 1 - if self.config.use_weighted_layer_sum: - self.layer_weights = jnp.repeat(1 / num_layers, num_layers) - self.projector = nn.Dense(self.config.classifier_proj_size, dtype=self.dtype) - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_features, - encoder_outputs=None, - output_attentions=None, - output_hidden_states: bool = True, - return_dict: bool = True, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_features, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - if self.config.use_weighted_layer_sum: - hidden_states = jnp.stack(encoder_outputs, axis=1) - norm_weights = jax.nn.softmax(self.layer_weights, axis=-1) - hidden_states = jnp.sum(hidden_states * jnp.reshape(norm_weights, [-1, 1, 1]), axis=1) - else: - hidden_states = encoder_outputs[0] - - hidden_states = self.projector(hidden_states) - pooled_output = jnp.mean(hidden_states, axis=1) - - logits = self.classifier(pooled_output) - - if not return_dict: - return (logits,) + encoder_outputs[1:] - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - ) - - -@add_start_docstrings("The Whisper Model with an audio classification head on top.", WHISPER_START_DOCSTRING) -class FlaxWhisperForAudioClassification(FlaxWhisperPreTrainedModel): - module_class = FlaxWhisperForAudioClassificationModule - dtype: jnp.dtype = jnp.float32 - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_features = jnp.zeros(input_shape, dtype="f4") - input_features = input_features.at[(..., -1)].set(self.config.eos_token_id) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - random_params = self.module.init( - rngs, - input_features=input_features, - )["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) - def __call__( - self, - input_features: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - dropout_rng: PRNGKey = None, - **kwargs, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - return self.module.apply( - {"params": params or self.params}, - input_features=jnp.array(input_features, dtype="f4"), - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - ) - - -FLAX_WHISPER_AUDIO_CLASSIFICATION_DOCSTRING = r""" - Returns: - - Transcription example: - - ```python - >>> import jax.numpy as jnp - >>> from transformers import AutoFeatureExtractor, FlaxWhisperForAudioClassification - >>> from datasets import load_dataset - - >>> feature_extractor = AutoFeatureExtractor.from_pretrained("sanchit-gandhi/whisper-medium-fleurs-lang-id") - >>> model = FlaxWhisperForAudioClassification.from_pretrained( - ... "sanchit-gandhi/whisper-medium-fleurs-lang-id", from_pt=True - ... ) - >>> ds = load_dataset("google/fleurs", "all", split="validation", streaming=True) - - >>> sample = next(iter(ds)) - - >>> inputs = feature_extractor( - ... sample["audio"]["array"], sampling_rate=sample["audio"]["sampling_rate"], return_tensors="np" - ... ) - >>> input_features = inputs.input_features - - >>> logits = model(input_features).logits - - >>> predicted_class_ids = jnp.argmax(logits).item() - >>> predicted_label = model.config.id2label[predicted_class_ids] - >>> predicted_label - 'af_za' - ``` -""" - -overwrite_call_docstring( - FlaxWhisperForAudioClassification, WHISPER_INPUTS_DOCSTRING + FLAX_WHISPER_AUDIO_CLASSIFICATION_DOCSTRING -) -append_replace_return_docstrings( - FlaxWhisperForAudioClassification, output_type=FlaxSequenceClassifierOutput, config_class=_CONFIG_FOR_DOC -) - - -__all__ = [ - "FlaxWhisperForConditionalGeneration", - "FlaxWhisperModel", - "FlaxWhisperPreTrainedModel", - "FlaxWhisperForAudioClassification", -] diff --git a/src/transformers/models/whisper/modeling_tf_whisper.py b/src/transformers/models/whisper/modeling_tf_whisper.py deleted file mode 100644 index c768db3c3070..000000000000 --- a/src/transformers/models/whisper/modeling_tf_whisper.py +++ /dev/null @@ -1,1754 +0,0 @@ -# coding=utf-8 -# Copyright 2022 The OpenAI Authors and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TensorFlow Whisper model.""" - -from __future__ import annotations - -import math -import random - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...generation.configuration_utils import GenerationConfig -from ...generation.tf_logits_process import TFLogitsProcessorList -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFBaseModelOutputWithPastAndCrossAttentions, - TFSeq2SeqLMOutput, - TFSeq2SeqModelOutput, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings -from .configuration_whisper import WhisperConfig -from .tokenization_whisper import TASK_IDS, TO_LANGUAGE_CODE - - -logger = logging.get_logger(__name__) - -_CONFIG_FOR_DOC = "WhisperConfig" - - -LARGE_NEGATIVE = -1e8 - - -def sinusoidal_embedding_init(shape, dtype=tf.float32) -> tf.Tensor: - """Returns sinusoids for positional embedding""" - length, channels = shape - if channels % 2 != 0: - raise ValueError( - f"Number of channels has to be divisible by 2 for sinusoidal positional embeddings, got {channels} channels." - ) - log_timescale_increment = math.log(10000) / (channels // 2 - 1) - inv_timescales = tf.exp(-log_timescale_increment * tf.range(channels // 2, dtype=tf.float32)) - scaled_time = tf.reshape(tf.range(length, dtype=tf.float32), (-1, 1)) * tf.reshape(inv_timescales, (1, -1)) - return tf.cast(tf.concat([tf.sin(scaled_time), tf.cos(scaled_time)], axis=1), dtype) - - -# Copied from transformers.models.bart.modeling_tf_bart.shift_tokens_right -def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): - pad_token_id = tf.cast(pad_token_id, input_ids.dtype) - decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) - start_tokens = tf.fill( - (shape_list(input_ids)[0], 1), tf.convert_to_tensor(decoder_start_token_id, input_ids.dtype) - ) - shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) - # replace possible -100 values in labels by `pad_token_id` - shifted_input_ids = tf.where( - shifted_input_ids == -100, - tf.fill(shape_list(shifted_input_ids), tf.convert_to_tensor(pad_token_id, input_ids.dtype)), - shifted_input_ids, - ) - - # "Verify that `labels` has only positive values and -100" - assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) - - # Make sure the assertion op is called by wrapping the result in an identity no-op - with tf.control_dependencies([assert_gte0]): - shifted_input_ids = tf.identity(shifted_input_ids) - - return shifted_input_ids - - -# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE - mask_cond = tf.range(shape_list(mask)[-1]) - - mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -class TFWhisperPositionalEmbedding(keras.layers.Layer): - def __init__( - self, - num_positions: int, - embedding_dim: int, - padding_idx: int | None = None, - embedding_initializer=None, - **kwargs, - ): - super().__init__(**kwargs) - self.num_positions = num_positions - self.embedding_dim = embedding_dim - self.padding_idx = padding_idx - self.embedding_initializer = keras.initializers.get(embedding_initializer) - - def build(self, input_shape): - self.weight = self.add_weight( - name="weight", - shape=[self.num_positions, self.embedding_dim], - initializer=self.embedding_initializer, - trainable=True, - ) - super().build(input_shape) - - def call(self, input_ids, past_key_values_length=0): - past_key_values_length = tf.cast(past_key_values_length, tf.int32) - gather_indices = tf.range(tf.shape(input_ids)[1], delta=1) + past_key_values_length - return tf.gather(self.weight, gather_indices) - - -class TFWhisperAttention(keras.layers.Layer): - """Multi-headed attention from 'Attention Is All You Need' paper""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=False, name="k_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention._shape with BART->whisper - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - # Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention.call with BART->whisper - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.speech_to_text.modeling_tf_speech_to_text.TFSpeech2TextEncoderLayer with Speech2Text->Whisper -class TFWhisperEncoderLayer(keras.layers.Layer): - def __init__(self, config: WhisperConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFWhisperAttention( - self.embed_dim, config.encoder_attention_heads, dropout=config.attention_dropout, name="self_attn" - ) - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - self.fc1 = keras.layers.Dense(config.encoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, hidden_states: tf.Tensor, attention_mask: tf.Tensor, layer_head_mask: tf.Tensor, training: bool = False - ): - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - `(encoder_attention_heads,)` - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - hidden_states, self_attn_weights, _ = self.self_attn( - hidden_states=hidden_states, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - training=training, - ) - - tf.debugging.assert_equal( - shape_list(hidden_states), - shape_list(residual), - message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", - ) - - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return hidden_states, self_attn_weights - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.encoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -# Copied from transformers.models.speech_to_text.modeling_tf_speech_to_text.TFSpeech2TextDecoderLayer with Speech2Text->Whisper -class TFWhisperDecoderLayer(keras.layers.Layer): - def __init__(self, config: WhisperConfig, **kwargs): - super().__init__(**kwargs) - self.embed_dim = config.d_model - - self.self_attn = TFWhisperAttention( - embed_dim=self.embed_dim, - num_heads=config.decoder_attention_heads, - dropout=config.attention_dropout, - name="self_attn", - is_decoder=True, - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.encoder_attn = TFWhisperAttention( - self.embed_dim, - config.decoder_attention_heads, - dropout=config.attention_dropout, - name="encoder_attn", - is_decoder=True, - ) - self.encoder_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.decoder_ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - def call( - self, - hidden_states, - attention_mask: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - cross_attn_layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tf.Tensor] | None = None, - training=False, - ) -> tuple[tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape `(batch, seq_len, embed_dim)` - attention_mask (`tf.Tensor`): attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - encoder_hidden_states (`tf.Tensor`): - cross attention input to the layer of shape `(batch, seq_len, embed_dim)` - encoder_attention_mask (`tf.Tensor`): encoder attention mask of size - `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - `(decoder_attention_heads,)` - cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. - `(decoder_attention_heads,)` - past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - training=training, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_present_key_value = None - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - layer_head_mask=cross_attn_layer_head_mask, - past_key_value=cross_attn_past_key_value, - training=training, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # add cross-attn to positions 3,4 of present_key_value tuple - present_key_value = present_key_value + cross_attn_present_key_value - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return ( - hidden_states, - self_attn_weights, - cross_attn_weights, - present_key_value, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "encoder_attn", None) is not None: - with tf.name_scope(self.encoder_attn.name): - self.encoder_attn.build(None) - if getattr(self, "encoder_attn_layer_norm", None) is not None: - with tf.name_scope(self.encoder_attn_layer_norm.name): - self.encoder_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.decoder_ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - - -class TFWhisperPreTrainedModel(TFPreTrainedModel): - config_class = WhisperConfig - base_model_prefix = "model" - main_input_name = "input_features" - - def _get_feat_extract_output_lengths(self, input_lengths: tf.Tensor) -> int: - """ - Computes the output length of the convolutional layers - """ - input_lengths = (input_lengths - 1) // 2 + 1 - - return input_lengths - - @property - def dummy_inputs(self) -> dict[str, tf.Tensor]: - """ - Dummy inputs to build the network. - - Returns: - `dict[str, tf.Tensor]`: The dummy inputs. - """ - return { - self.main_input_name: tf.random.uniform( - [1, self.config.num_mel_bins, self.config.max_source_positions * 2 - 1], dtype=tf.float32 - ), - "decoder_input_ids": tf.constant([[1, 3]], dtype=tf.int32), - } - - @property - def input_signature(self): - return { - "input_features": tf.TensorSpec((None, self.config.num_mel_bins, None), tf.float32, name="input_features"), - "decoder_input_ids": tf.TensorSpec((None, None), tf.int32, name="decoder_input_ids"), - "decoder_attention_mask": tf.TensorSpec((None, None), tf.int32, name="decoder_attention_mask"), - } - - -WHISPER_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - Parameters: - config ([`WhisperConfig`]): - Model configuration class with all the parameters of the model. Initializing with a config file does not - load the weights associated with the model, only the configuration. Check out the - [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -WHISPER_INPUTS_DOCSTRING = r""" - Args: - input_features (`tf.Tensor` of shape `(batch_size, feature_size, sequence_length)`): - Float values of fbank features extracted from the raw speech waveform. Raw speech waveform can be obtained - by loading a `.flac` or `.wav` audio file into an array of type `list[float]`, a `numpy.ndarray` or a - `torch.Tensor`, *e.g.* via the torchcodec library (`pip install torchcodec`) or the soundfile library - (`pip install soundfile`). - To prepare the array into `input_features`, the [`AutoFeatureExtractor`] should be used for extracting the - fbank features, padding and conversion into a tensor of type `tf.Tensor`. - See [`~WhisperFeatureExtractor.__call__`] - decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Indices of decoder input sequence tokens in the vocabulary. - - Indices can be obtained using [`SpeechToTextTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are decoder input IDs?](../glossary#decoder-input-ids) - - SpeechToText uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If - `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see - `past_key_values`). - decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): - Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also - be used by default. - - If you want to change padding behavior, you should read - [`modeling_whisper._prepare_decoder_attention_mask`] and modify to your needs. See diagram 1 in [the - paper](https://huggingface.co/papers/1910.13461) for more information on the default strategy. - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - encoder_outputs (`tuple(tuple(tf.Tensor)`, *optional*): - Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) - `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of - hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. - past_key_values (`tuple(tuple(tf.Tensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(tf.Tensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape - `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention - blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - decoder_inputs_embeds (`tf.Tensor` of shape `(batch_size, target_sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `decoder_input_ids` you can choose to directly pass an embedded - representation. If `past_key_values` is used, optionally only the last `decoder_inputs_embeds` have to be - input (see `past_key_values`). This is useful if you want more control over how to convert - `decoder_input_ids` indices into associated vectors than the model's internal embedding lookup matrix. - use_cache (`bool`, *optional*): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@keras_serializable -class TFWhisperEncoder(keras.layers.Layer): - config_class = WhisperConfig - """ - Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a - [`TFWhisperEncoderLayer`]. - - Args: - config: WhisperConfig - embed_tokens (TFWhisperEmbedding): output embedding - """ - - def __init__(self, config: WhisperConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layerdrop = config.encoder_layerdrop - - self.embed_dim = config.d_model - self.num_mel_bins = config.num_mel_bins - self.padding_idx = config.pad_token_id - self.max_source_positions = config.max_source_positions - self.embed_scale = math.sqrt(self.embed_dim) if config.scale_embedding else 1.0 - - # Padding is added in call() to match the PyTorch implementation - self.conv1 = keras.layers.Conv1D(self.embed_dim, kernel_size=3, strides=1, padding="valid", name="conv1") - self.conv2 = keras.layers.Conv1D(self.embed_dim, kernel_size=3, strides=2, padding="valid", name="conv2") - - self.embed_positions = TFWhisperPositionalEmbedding( - num_positions=self.max_source_positions, - embedding_dim=self.embed_dim, - embedding_initializer=sinusoidal_embedding_init, - name="embed_positions", - ) - self.embed_positions.trainable = False - - self.encoder_layers = [TFWhisperEncoderLayer(config, name=f"layers.{i}") for i in range(config.encoder_layers)] - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - self.dropout = keras.layers.Dropout(config.dropout) - - @unpack_inputs - def call( - self, - input_features=None, - head_mask=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - r""" - Args: - input_features (`tf.Tensor` of shape `(batch_size, feature_size, sequence_length)`): - Float values of fbank features extracted from the raw speech waveform. Raw speech waveform can be - obtained by loading a `.flac` or `.wav` audio file into an array of type `list[float]`, a - `numpy.ndarray` or a `torch.Tensor`, *e.g.* via the torchcodec library (`pip install torchcodec`) or - the soundfile library (`pip install soundfile`). To prepare the array into - `input_features`, the [`AutoFeatureExtractor`] should be used for extracting the fbank features, - padding and conversion into a tensor of type `tf.Tensor`. See [`~WhisperFeatureExtractor.__call__`] - head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # TF 2.0 layers can't use channels first format when running on CPU. - input_features = tf.transpose(input_features, perm=(0, 2, 1)) - input_features = tf.pad(input_features, [[0, 0], [1, 1], [0, 0]]) - inputs_embeds = keras.activations.gelu(self.conv1(input_features)) - inputs_embeds = tf.pad(inputs_embeds, [[0, 0], [1, 1], [0, 0]]) - inputs_embeds = keras.activations.gelu(self.conv2(inputs_embeds)) - inputs_embeds = tf.transpose(inputs_embeds, perm=(0, 1, 2)) - - embed_pos = self.embed_positions(input_ids=tf.zeros((1, self.max_source_positions), dtype=tf.int32)) - - hidden_states = inputs_embeds + embed_pos - hidden_states = self.dropout(hidden_states, training=training) - - encoder_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - - # check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - tf.debugging.assert_equal( - shape_list(head_mask)[0], - len(self.encoder_layers), - message=( - f"The head_mask should be specified for {len(self.encoder_layers)} layers, but it is for" - f" {shape_list(head_mask)[0]}." - ), - ) - - for idx, encoder_layer in enumerate(self.encoder_layers): - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): # skip the layer - continue - - hidden_states, attn = encoder_layer( - hidden_states, - None, - layer_head_mask=(head_mask[idx] if head_mask is not None else None), - training=training, - ) - - if output_attentions: - all_attentions += (attn,) - - hidden_states = self.layer_norm(hidden_states) - if output_hidden_states: - encoder_states = encoder_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) - return TFBaseModelOutput( - last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "conv1", None) is not None: - with tf.name_scope(self.conv1.name): - self.conv1.build([None, None, self.num_mel_bins]) - if getattr(self, "conv2", None) is not None: - with tf.name_scope(self.conv2.name): - self.conv2.build([None, None, self.embed_dim]) - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "encoder_layers", None) is not None: - for layer in self.encoder_layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -class TFWhisperDecoder(keras.layers.Layer): - config_class = WhisperConfig - """ - Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFWhisperDecoderLayer`] - - Args: - config: WhisperConfig - """ - - def __init__(self, config: WhisperConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.dropout = keras.layers.Dropout(config.dropout) - self.layerdrop = config.decoder_layerdrop - self.padding_idx = config.pad_token_id - self.max_target_positions = config.max_target_positions - self.max_source_positions = config.max_source_positions - self.embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0 - - self.embed_tokens = keras.layers.Embedding( - input_dim=config.vocab_size, - output_dim=config.d_model, - embeddings_initializer=keras.initializers.TruncatedNormal(stddev=self.config.init_std), - name="embed_tokens", - ) - self.embed_positions = TFWhisperPositionalEmbedding( - self.max_target_positions, config.d_model, name="embed_positions" - ) - - self.decoder_layers = [TFWhisperDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] - - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - def _prepare_decoder_attention_mask(self, attention_mask, input_shape, past_key_values_length): - # create causal mask - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - batch_size, seq_len = input_shape[0], input_shape[1] - - combined_attention_mask = tf.cond( - tf.math.greater(seq_len, 1), - lambda: _make_causal_mask(input_shape, past_key_values_length=past_key_values_length), - lambda: _expand_mask(tf.ones((batch_size, seq_len + past_key_values_length)), tgt_len=seq_len), - ) - - if attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - expanded_attn_mask = _expand_mask(attention_mask, tgt_len=input_shape[-1]) - combined_attention_mask = ( - expanded_attn_mask if combined_attention_mask is None else expanded_attn_mask + combined_attention_mask - ) - return combined_attention_mask - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - position_ids=None, - encoder_hidden_states=None, - head_mask=None, - cross_attn_head_mask=None, - past_key_values=None, - inputs_embeds=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - r""" - Args: - input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you - provide it. - - Indices can be obtained using [`WhisperTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the - range `[0, config.max_position_embeddings - 1]`. - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention - of the decoder. - head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in encoder to avoid performing cross-attention - on hidden heads. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple(tuple(tf.Tensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): - Tuple of `tuple(tf.Tensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape - `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape - `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. - - Contains pre-computed hidden-states (key and values in the self-attention blocks and in the - cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. - - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those - that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of - all `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. - This is useful if you want more control over how to convert `input_ids` indices into associated vectors - than the model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under - returned tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors - for more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. - """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - use_cache = use_cache if use_cache is not None else self.config.use_cache - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # retrieve input_ids and inputs_embeds - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") - elif input_ids is not None: - input_shape = tf.shape(input_ids) - input_ids = tf.reshape(input_ids, (-1, input_shape[-1])) - elif inputs_embeds is not None: - input_shape = tf.shape(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") - - # past_key_values_length - past_key_values_length = tf.shape(past_key_values[0][0])[2] if past_key_values is not None else 0 - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.input_dim) - inputs_embeds = self.embed_tokens(input_ids) - - attention_mask = self._prepare_decoder_attention_mask(attention_mask, input_shape, past_key_values_length) - - # embed positions - filled_past_positions = past_key_values_length if position_ids is None else position_ids[0, -1] - positions = self.embed_positions(input_ids, past_key_values_length=filled_past_positions) - - hidden_states = inputs_embeds + positions - hidden_states = self.dropout(hidden_states, training=training) - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - next_decoder_cache = () if use_cache else None - - # check if head_mask/cross_attn_head_mask has a correct number of layers specified if desired - for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: - if attn_mask is not None: - tf.debugging.assert_equal( - shape_list(attn_mask)[0], - len(self.decoder_layers), - message=( - f"The {attn_mask_name} should be specified for {len(self.decoder_layers)} layers, but it is" - f" for {shape_list(attn_mask)[0]}." - ), - ) - - for idx, decoder_layer in enumerate(self.decoder_layers): - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - if output_hidden_states: - all_hidden_states += (hidden_states,) - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): - continue - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - layer_outputs = decoder_layer( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - layer_head_mask=(head_mask[idx] if head_mask is not None else None), - cross_attn_layer_head_mask=(cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None), - past_key_value=past_key_value, - training=training, - ) - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[3],) - - if output_attentions: - all_self_attns += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - hidden_states = self.layer_norm(hidden_states) - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - next_cache = next_decoder_cache if use_cache else None - if not return_dict: - return tuple( - v - for v in [hidden_states, next_cache, all_hidden_states, all_self_attns, all_cross_attentions] - if v is not None - ) - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_cache, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "embed_tokens", None) is not None: - with tf.name_scope(self.embed_tokens.name): - self.embed_tokens.build(None) - if getattr(self, "embed_positions", None) is not None: - with tf.name_scope(self.embed_positions.name): - self.embed_positions.build(None) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "decoder_layers", None) is not None: - for layer in self.decoder_layers: - with tf.name_scope(layer.name): - layer.build(None) - - -@add_start_docstrings( - "The bare Whisper Model outputting raw hidden-states without any specific head on top.", - WHISPER_START_DOCSTRING, -) -@keras_serializable -class TFWhisperMainLayer(keras.layers.Layer): - config_class = WhisperConfig - - def __init__(self, config: WhisperConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.encoder = TFWhisperEncoder(config, name="encoder") - self.decoder = TFWhisperDecoder(config, name="decoder") - - def get_input_embeddings(self): - return self.decoder.embed_tokens - - def set_input_embeddings(self, value): - self.decoder.embed_tokens = value - - def get_encoder(self): - return self.encoder - - @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - @unpack_inputs - def call( - self, - input_features=None, - decoder_input_ids=None, - decoder_attention_mask=None, - decoder_position_ids=None, - head_mask=None, - decoder_head_mask=None, - cross_attn_head_mask=None, - encoder_outputs=None, - past_key_values=None, - decoder_inputs_embeds=None, - use_cache=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ): - r""" - Returns: - - Example: - - ```python - >>> import tensorflow as tf - >>> from transformers import TFWhisperModel, AutoFeatureExtractor - >>> from datasets import load_dataset - - >>> model = TFWhisperModel.from_pretrained("openai/whisper-base") - >>> feature_extractor = AutoFeatureExtractor.from_pretrained("openai/whisper-base") - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> inputs = feature_extractor(ds[0]["audio"]["array"], return_tensors="tf") - >>> input_features = inputs.input_features - >>> decoder_input_ids = tf.convert_to_tensor([[1, 1]]) * model.config.decoder_start_token_id - >>> last_hidden_state = model(input_features, decoder_input_ids=decoder_input_ids).last_hidden_state - >>> list(last_hidden_state.shape) - [1, 2, 512] - ```""" - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - use_cache = use_cache if use_cache is not None else self.config.use_cache - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if encoder_outputs is None: - encoder_outputs = self.encoder( - input_features, - head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True - elif return_dict and not isinstance(encoder_outputs, TFBaseModelOutput): - encoder_outputs = TFBaseModelOutput( - last_hidden_state=encoder_outputs[0], - hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, - attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, - ) - - # decoder outputs consists of (dec_features, past_key_value, dec_hidden, dec_attn) - decoder_outputs = self.decoder( - input_ids=decoder_input_ids, - attention_mask=decoder_attention_mask, - position_ids=decoder_position_ids, - encoder_hidden_states=encoder_outputs[0], - head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - if not return_dict: - return decoder_outputs + encoder_outputs - - return TFSeq2SeqModelOutput( - last_hidden_state=decoder_outputs.last_hidden_state, - past_key_values=decoder_outputs.past_key_values, - decoder_hidden_states=decoder_outputs.hidden_states, - decoder_attentions=decoder_outputs.attentions, - cross_attentions=decoder_outputs.cross_attentions, - encoder_last_hidden_state=encoder_outputs.last_hidden_state, - encoder_hidden_states=encoder_outputs.hidden_states, - encoder_attentions=encoder_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "decoder", None) is not None: - with tf.name_scope(self.decoder.name): - self.decoder.build(None) - - -@add_start_docstrings( - "The bare Whisper Model outputting raw hidden-states without any specific head on top.", - WHISPER_START_DOCSTRING, -) -class TFWhisperModel(TFWhisperPreTrainedModel): - def __init__(self, config: WhisperConfig, **kwargs): - super().__init__(config, **kwargs) - - self.model = TFWhisperMainLayer(config, name="model") - - def get_input_embeddings(self): - return self.model.decoder.embed_tokens - - def set_input_embeddings(self, value): - self.model.decoder.embed_tokens = value - - def get_encoder(self): - return self.model.encoder - - def get_decoder(self): - return self.model.decoder - - def decoder(self): - return self.model.decoder - - def encoder(self): - return self.model.encoder - - @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqModelOutput, config_class=_CONFIG_FOR_DOC) - @unpack_inputs - def call( - self, - input_features: TFModelInputType | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - decoder_inputs_embeds: tuple[np.ndarray | tf.Tensor] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFSeq2SeqModelOutput: - r""" - Returns: - - Example: - - ```python - >>> import tensorflow as tf - >>> from transformers import TFWhisperModel, AutoFeatureExtractor - >>> from datasets import load_dataset - - >>> model = TFWhisperModel.from_pretrained("openai/whisper-base") - >>> feature_extractor = AutoFeatureExtractor.from_pretrained("openai/whisper-base") - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - >>> inputs = feature_extractor(ds[0]["audio"]["array"], return_tensors="tf") - >>> input_features = inputs.input_features - >>> decoder_input_ids = tf.convert_to_tensor([[1, 1]]) * model.config.decoder_start_token_id - >>> last_hidden_state = model(input_features, decoder_input_ids=decoder_input_ids).last_hidden_state - >>> list(last_hidden_state.shape) - [1, 2, 512] - ```""" - outputs = self.model( - input_features=input_features, - decoder_input_ids=decoder_input_ids, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - encoder_outputs=encoder_outputs, - past_key_values=past_key_values, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - return outputs - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqModelOutput( - last_hidden_state=output.last_hidden_state, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -@add_start_docstrings( - "The Whisper Model with a language modeling head. Can be used for automatic speech recognition.", - WHISPER_START_DOCSTRING, -) -class TFWhisperForConditionalGeneration(TFWhisperPreTrainedModel, TFCausalLanguageModelingLoss): - base_model_prefix = "model" - _keys_to_ignore_on_load_missing = [ - r"encoder.version", - r"decoder.version", - r"proj_out.weight", - ] - _keys_to_ignore_on_save = [ - r"proj_out.weight", - ] - - def __init__(self, config: WhisperConfig, **kwargs): - super().__init__(config, **kwargs) - self.model = TFWhisperMainLayer(config, name="model") - - def get_encoder(self): - return self.model.get_encoder() - - def get_decoder(self): - return self.model.get_decoder() - - def get_output_embeddings(self): - return self.get_input_embeddings() - - def set_output_embeddings(self, value): - self.set_input_embeddings(value) - - def resize_token_embeddings(self, new_num_tokens: int) -> keras.layers.Embedding: - new_embeddings = super().resize_token_embeddings(new_num_tokens) - return new_embeddings - - @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) - @unpack_inputs - def call( - self, - input_features: TFModelInputType | None = None, - decoder_input_ids: np.ndarray | tf.Tensor | None = None, - decoder_attention_mask: np.ndarray | tf.Tensor | None = None, - decoder_position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - decoder_head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - encoder_outputs: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - decoder_inputs_embeds: tuple[np.ndarray | tf.Tensor] | None = None, - labels: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> tuple[tf.Tensor] | TFSeq2SeqLMOutput: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the language modeling loss. Indices should either be in `[0, ..., config.vocab_size]` - or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored (masked), the loss is - only computed for the tokens with labels in `[0, ..., config.vocab_size]`. - - Returns: - - Example: - - ```python - >>> import tensorflow as tf - >>> from transformers import AutoProcessor, TFWhisperForConditionalGeneration - >>> from datasets import load_dataset - - >>> processor = AutoProcessor.from_pretrained("openai/whisper-tiny.en") - >>> model = TFWhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en") - - >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") - - >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="tf") - >>> input_features = inputs.input_features - - >>> generated_ids = model.generate(input_features=input_features) - - >>> transcription = processor.batch_decode(generated_ids, skip_special_tokens=True)[0] - >>> transcription - ' Mr. Quilter is the apostle of the middle classes, and we are glad to welcome his gospel.' - ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if labels is not None: - if decoder_input_ids is None and decoder_inputs_embeds is None: - decoder_input_ids = shift_tokens_right( - labels, self.config.pad_token_id, self.config.decoder_start_token_id - ) - - outputs = self.model( - input_features, - decoder_input_ids=decoder_input_ids, - encoder_outputs=encoder_outputs, - decoder_attention_mask=decoder_attention_mask, - decoder_position_ids=decoder_position_ids, - head_mask=head_mask, - decoder_head_mask=decoder_head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - decoder_inputs_embeds=decoder_inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - decoder_last_hidden_state = outputs[0] - # Decoder and encoder embeddings are tied - lm_logits = tf.matmul(decoder_last_hidden_state, self.get_output_embeddings().weights, transpose_b=True) - - loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSeq2SeqLMOutput( - loss=loss, - logits=lm_logits, - past_key_values=outputs.past_key_values, - decoder_hidden_states=outputs.decoder_hidden_states, - decoder_attentions=outputs.decoder_attentions, - cross_attentions=outputs.cross_attentions, - encoder_last_hidden_state=outputs.encoder_last_hidden_state, - encoder_hidden_states=outputs.encoder_hidden_states, - encoder_attentions=outputs.encoder_attentions, - ) - - def generate( - self, - inputs: tf.Tensor | None = None, - generation_config: GenerationConfig | None = None, - logits_processor: TFLogitsProcessorList | None = None, - seed: list[int] | None = None, - return_timestamps: bool | None = None, - task: str | None = None, - language: str | None = None, - is_multilingual: bool | None = None, - prompt_ids: tf.Tensor | None = None, - return_token_timestamps=None, - **kwargs, - ): - r""" - Generates sequences of token ids for models with a language modeling head. - - - - Most generation-controlling parameters are set in `generation_config` which, if not passed, will be set to the - model's default generation configuration. You can override any `generation_config` by passing the corresponding - parameters to generate, e.g. `.generate(inputs, num_beams=4, do_sample=True)`. - - For an overview of generation strategies and code examples, check out the [following - guide](../generation_strategies). - - - - Parameters: - inputs (`tf.Tensor` of varying shape depending on the modality, *optional*): - The sequence used as a prompt for the generation or as model inputs to the encoder. If unset the method - initializes it with `bos_token_id` and a batch size of 1. For decoder-only models `inputs` should of in - the format of `input_ids`. For encoder-decoder models *inputs* can represent any of `input_ids`, - `input_values`, `input_features`, or `pixel_values`. - generation_config (`~generation.GenerationConfig`, *optional*): - The generation configuration to be used as base parametrization for the generation call. `**kwargs` - passed to generate matching the attributes of `generation_config` will override them. If - `generation_config` is not provided, the default will be used, which had the following loading - priority: 1) from the `generation_config.json` model file, if it exists; 2) from the model - configuration. Please note that unspecified parameters will inherit [`~generation.GenerationConfig`]'s - default values, whose documentation should be checked to parameterize generation. - logits_processor (`LogitsProcessorList`, *optional*): - Custom logits processors that complement the default logits processors built from arguments and - generation config. If a logit processor is passed that is already created with the arguments or a - generation config an error is thrown. This feature is intended for advanced users. - seed (`list[int]`, *optional*): - Random seed to control sampling, containing two integers, used when `do_sample` is `True`. See the - `seed` argument from stateless functions in `tf.random`. - return_timestamps (`bool`, *optional*): - Whether to return the timestamps with the text. This enables the `TFWhisperTimestampsLogitsProcessor`. - task (`str`, *optional*): - Task to use for generation, either "translate" or "transcribe". The `model.config.forced_decoder_ids` - will be updated accordingly. - language (`str`, *optional*): - Language token to use for generation, can be either in the form of `<|en|>`, `en` or `english`. You can - find all the possible language tokens in the `model.generation_config.lang_to_id` dictionary. - is_multilingual (`bool`, *optional*): - Whether or not the model is multilingual. - prompt_ids (`tf.Tensor`, *optional*): - Rank-1 tensor of token IDs created by passing text to [`~WhisperProcessor.get_prompt_ids`] that is - provided as a prompt to each chunk. This can be used to provide or "prompt-engineer" a context for - transcription, e.g. custom vocabularies or proper nouns to make it more likely to predict those words - correctly. It cannot be used in conjunction with `decoder_start_token_id` as it overwrites this value. - return_token_timestamps (`bool`, *optional*): - Whether to return token-level timestamps with the text. This can be used with or without the - `return_timestamps` option. To get word-level timestamps, use the tokenizer to group the tokens into - words. - kwargs (`dict[str, Any]`, *optional*): - Ad hoc parametrization of `generate_config` and/or additional model-specific kwargs that will be - forwarded to the `forward` function of the model. If the model is an encoder-decoder model, encoder - specific kwargs should not be prefixed and decoder specific kwargs should be prefixed with *decoder_*. - - Return: - [`~utils.ModelOutput`] or `tf.Tensor`: A [`~utils.ModelOutput`] (if `return_dict_in_generate=True` or when - `config.return_dict_in_generate=True`) or a `tf.Tensor`. - - If the model is *not* an encoder-decoder model (`model.config.is_encoder_decoder=False`), the possible - [`~utils.ModelOutput`] types are: - - - [`~generation.TFGreedySearchDecoderOnlyOutput`], - - [`~generation.TFSampleDecoderOnlyOutput`], - - [`~generation.TFBeamSearchDecoderOnlyOutput`], - - [`~generation.TFBeamSampleDecoderOnlyOutput`] - - If the model is an encoder-decoder model (`model.config.is_encoder_decoder=True`), the possible - [`~utils.ModelOutput`] types are: - - - [`~generation.TFGreedySearchEncoderDecoderOutput`], - - [`~generation.TFSampleEncoderDecoderOutput`], - - [`~generation.TFBeamSearchEncoderDecoderOutput`], - - [`~generation.TFBeamSampleEncoderDecoderOutput`] - - """ - if generation_config is None: - generation_config = self.generation_config - - if return_timestamps is not None: - if not hasattr(generation_config, "no_timestamps_token_id"): - raise ValueError( - "You are trying to return timestamps, but the generation config is not properly set. " - "Make sure to initialize the generation config with the correct attributes that are needed such as `no_timestamps_token_id`. " - "For more details on how to generate the approtiate config, refer to https://github.com/huggingface/transformers/issues/21878#issuecomment-1451902363" - ) - - generation_config.return_timestamps = return_timestamps - else: - generation_config.return_timestamps = False - - if language is not None: - language = language.lower() - generation_config.language = language - if task is not None: - generation_config.task = task - - forced_decoder_ids = None - - # Legacy code for backward compatibility - if hasattr(self.config, "forced_decoder_ids") and self.config.forced_decoder_ids is not None: - forced_decoder_ids = self.config.forced_decoder_ids - elif ( - hasattr(self.generation_config, "forced_decoder_ids") - and self.generation_config.forced_decoder_ids is not None - ): - forced_decoder_ids = self.generation_config.forced_decoder_ids - else: - forced_decoder_ids = kwargs.get("forced_decoder_ids") - - if task is not None or language is not None or (forced_decoder_ids is None and prompt_ids is not None): - forced_decoder_ids = [] - if hasattr(generation_config, "language"): - if generation_config.language in generation_config.lang_to_id: - language_token = generation_config.language - elif generation_config.language in TO_LANGUAGE_CODE: - language_token = f"<|{TO_LANGUAGE_CODE[generation_config.language]}|>" - elif generation_config.language in TO_LANGUAGE_CODE.values(): - language_token = f"<|{generation_config.language}|>" - else: - is_language_code = len(generation_config.language) == 2 - raise ValueError( - f"Unsupported language: {generation_config.language}. Language should be one of:" - f" {list(TO_LANGUAGE_CODE.values()) if is_language_code else list(TO_LANGUAGE_CODE.keys())}." - ) - if language_token not in generation_config.lang_to_id: - raise ValueError( - f"{language_token} is not supported by this specific model as it is not in the `generation_config.lang_to_id`." - "(You should just add it to the generation config)" - ) - forced_decoder_ids.append((1, generation_config.lang_to_id[language_token])) - else: - forced_decoder_ids.append((1, None)) # automatically detect the language - - if hasattr(generation_config, "task"): - if generation_config.task in TASK_IDS: - forced_decoder_ids.append((2, generation_config.task_to_id[generation_config.task])) - else: - raise ValueError( - f"The `{generation_config.task}`task is not supported. The task should be one of `{TASK_IDS}`" - ) - elif hasattr(generation_config, "task_to_id"): - forced_decoder_ids.append((2, generation_config.task_to_id["transcribe"])) # defaults to transcribe - if hasattr(generation_config, "no_timestamps_token_id") and not generation_config.return_timestamps: - idx = forced_decoder_ids[-1][0] + 1 if forced_decoder_ids else 1 - forced_decoder_ids.append((idx, generation_config.no_timestamps_token_id)) - - if forced_decoder_ids is not None: - generation_config.forced_decoder_ids = forced_decoder_ids - - if prompt_ids is not None: - if kwargs.get("decoder_start_token_id") is not None: - raise ValueError( - "When specifying `prompt_ids`, you cannot also specify `decoder_start_token_id` as it gets overwritten." - ) - prompt_ids = prompt_ids.tolist() - decoder_start_token_id, *text_prompt_ids = prompt_ids - # Slicing the text prompt ids in a manner consistent with the OpenAI implementation - # to accommodate context space for the prefix (see https://github.com/openai/whisper/blob/c09a7ae299c4c34c5839a76380ae407e7d785914/whisper/decoding.py#L599) - text_prompt_ids = text_prompt_ids[-self.config.max_length // 2 - 1 :] - # Set the decoder_start_token_id to <|startofprev|> - kwargs.update({"decoder_start_token_id": decoder_start_token_id}) - - # Update the max generation length to include the prompt - specified_max_length = kwargs.pop("max_new_tokens", None) or kwargs.pop("max_length", None) - default_max_length = generation_config.max_new_tokens or generation_config.max_length - non_prompt_max_length = specified_max_length or default_max_length - kwargs["max_new_tokens"] = non_prompt_max_length + len(text_prompt_ids) - - # Reformat the forced_decoder_ids to incorporate the prompt - non_prompt_forced_decoder_ids = ( - kwargs.pop("forced_decoder_ids", None) or generation_config.forced_decoder_ids - ) - forced_decoder_ids = [ - *text_prompt_ids, - generation_config.decoder_start_token_id, - *[token for _rank, token in non_prompt_forced_decoder_ids], - ] - forced_decoder_ids = [(rank + 1, token) for rank, token in enumerate(forced_decoder_ids)] - generation_config.forced_decoder_ids = forced_decoder_ids - - # TODO: Implement `WhisperTimeStampLogitsProcessor`. - if generation_config.return_timestamps: - # logits_processor = [TFWhisperTimeStampLogitsProcessor(generation_config)] - raise ValueError("`TFWhisperForConditionalGeneration` doesn't support returning the timestamps yet.") - - if return_token_timestamps: - kwargs["output_attentions"] = True - kwargs["return_dict_in_generate"] = True - - if getattr(generation_config, "task", None) == "translate": - logger.warning("Token-level timestamps may not be reliable for task 'translate'.") - if not hasattr(generation_config, "alignment_heads"): - raise ValueError( - "Model generation config has no `alignment_heads`, token-level timestamps not available. " - "See https://gist.github.com/hollance/42e32852f24243b748ae6bc1f985b13a on how to add this property to the generation config." - ) - - outputs = super().generate( - inputs, - generation_config, - logits_processor, - **kwargs, - ) - - if return_token_timestamps and hasattr(generation_config, "alignment_heads"): - outputs["token_timestamps"] = self._extract_token_timestamps(outputs, generation_config.alignment_heads) - - return outputs - - def serving_output(self, output): - pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None - dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None - dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None - cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None - enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None - enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None - - return TFSeq2SeqLMOutput( - logits=output.logits, - past_key_values=pkv, - decoder_hidden_states=dec_hs, - decoder_attentions=dec_attns, - cross_attentions=cross_attns, - encoder_last_hidden_state=output.encoder_last_hidden_state, - encoder_hidden_states=enc_hs, - encoder_attentions=enc_attns, - ) - - def prepare_inputs_for_generation( - self, - decoder_input_ids, - past_key_values=None, - use_cache=None, - encoder_outputs=None, - attention_mask=None, - decoder_attention_mask=None, - **kwargs, - ): - # cut decoder_input_ids if past is used - if past_key_values is not None: - decoder_input_ids = decoder_input_ids[:, -1:] - - if decoder_attention_mask is not None: # xla - decoder_position_ids = tf.math.cumsum(decoder_attention_mask, axis=-1, exclusive=True)[:, -1:] - elif past_key_values is not None: # no xla + past - decoder_position_ids = past_key_values[0][0].shape[2] - else: # no xla + no past - decoder_position_ids = tf.range(decoder_input_ids.shape[1]) - decoder_position_ids = tf.broadcast_to(decoder_position_ids, decoder_input_ids.shape) - - return { - "input_features": None, # Needs to be passed to make Keras.layer.__call__ happy - "encoder_outputs": encoder_outputs, - "past_key_values": past_key_values, - "decoder_input_ids": decoder_input_ids, - "use_cache": use_cache, - "decoder_attention_mask": decoder_attention_mask, - "decoder_position_ids": decoder_position_ids, - } - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -__all__ = ["TFWhisperForConditionalGeneration", "TFWhisperModel", "TFWhisperPreTrainedModel"] diff --git a/src/transformers/models/whisper/tokenization_whisper.py b/src/transformers/models/whisper/tokenization_whisper.py index 4147f14d86bd..34d9a8965be8 100644 --- a/src/transformers/models/whisper/tokenization_whisper.py +++ b/src/transformers/models/whisper/tokenization_whisper.py @@ -577,7 +577,7 @@ def _compute_offsets(self, token_ids, time_precision=0.02, segment_size=1500): Compute offsets for a given tokenized input Args: - token_ids (`Union[int, list[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. time_precision (`float`, *optional*, defaults to 0.02): The time ratio to convert from token to time. @@ -656,7 +656,7 @@ def _preprocess_token_ids(self, token_ids, skip_special_tokens: bool = False): Pre-process the token ids for decoding by removing the prompt tokens ids and timestamp token ids. Args: - token_ids (`Union[int, list[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Typically, obtained using the `__call__` method of the tokenizer. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens from the token ids. If `True`, the prompt token ids will be @@ -692,7 +692,7 @@ def decode( Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. Args: - token_ids (`Union[int, list[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. Will remove the previous tokens (pre-prompt) @@ -898,12 +898,7 @@ def _strip_prompt(self, token_ids: list[int], prompt_token_id: int, decoder_star def _convert_to_list(token_ids): # convert type to ndarray if necessary if hasattr(token_ids, "numpy"): - if "torch" in str(type(token_ids)): - token_ids = token_ids.cpu().numpy() - elif "tensorflow" in str(type(token_ids)): - token_ids = token_ids.numpy() - elif "jaxlib" in str(type(token_ids)): - token_ids = token_ids.tolist() + token_ids = token_ids.cpu().numpy() # now the token ids are either a numpy array, or a list of lists if isinstance(token_ids, np.ndarray): token_ids = token_ids.tolist() diff --git a/src/transformers/models/whisper/tokenization_whisper_fast.py b/src/transformers/models/whisper/tokenization_whisper_fast.py index 07f4fdfcb002..fbcf8ea757bd 100644 --- a/src/transformers/models/whisper/tokenization_whisper_fast.py +++ b/src/transformers/models/whisper/tokenization_whisper_fast.py @@ -210,7 +210,7 @@ def _compute_offsets(self, token_ids, time_precision=0.02, segment_size=1500): Compute offsets for a given tokenized input Args: - token_ids (`Union[int, list[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. time_precision (`float`, *optional*, defaults to 0.02): The time ratio to convert from token to time. @@ -291,7 +291,7 @@ def _preprocess_token_ids(self, token_ids, skip_special_tokens: bool = False): Pre-process the token ids for decoding by removing the prompt tokens ids and timestamp token ids. Args: - token_ids (`Union[int, list[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Typically, obtained using the `__call__` method of the tokenizer. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens from the token ids. If `True`, the prompt token ids will be @@ -329,7 +329,7 @@ def decode( Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. Args: - token_ids (`Union[int, list[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. Will remove the previous tokens (pre-prompt) @@ -624,12 +624,7 @@ def _strip_prompt(self, token_ids: list[int], prompt_token_id: int, decoder_star def _convert_to_list(token_ids): # convert type to ndarray if necessary if hasattr(token_ids, "numpy"): - if "torch" in str(type(token_ids)): - token_ids = token_ids.cpu().numpy() - elif "tensorflow" in str(type(token_ids)): - token_ids = token_ids.numpy() - elif "jaxlib" in str(type(token_ids)): - token_ids = token_ids.tolist() + token_ids = token_ids.cpu().numpy() # now the token ids are either a numpy array, or a list of lists if isinstance(token_ids, np.ndarray): token_ids = token_ids.tolist() diff --git a/src/transformers/models/x_clip/modeling_x_clip.py b/src/transformers/models/x_clip/modeling_x_clip.py index 403b9a408162..3c906a85392e 100644 --- a/src/transformers/models/x_clip/modeling_x_clip.py +++ b/src/transformers/models/x_clip/modeling_x_clip.py @@ -390,11 +390,6 @@ def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = Fals """ Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, - however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the - layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the - argument. """ if drop_prob == 0.0 or not training: return input diff --git a/src/transformers/models/xglm/__init__.py b/src/transformers/models/xglm/__init__.py index 1eefd79d4cf7..363babae7e6c 100644 --- a/src/transformers/models/xglm/__init__.py +++ b/src/transformers/models/xglm/__init__.py @@ -19,8 +19,6 @@ if TYPE_CHECKING: from .configuration_xglm import * - from .modeling_flax_xglm import * - from .modeling_tf_xglm import * from .modeling_xglm import * from .tokenization_xglm import * from .tokenization_xglm_fast import * diff --git a/src/transformers/models/xglm/configuration_xglm.py b/src/transformers/models/xglm/configuration_xglm.py index d8a3be370b7f..eae648c4726a 100644 --- a/src/transformers/models/xglm/configuration_xglm.py +++ b/src/transformers/models/xglm/configuration_xglm.py @@ -35,7 +35,7 @@ class XGLMConfig(PretrainedConfig): Args: vocab_size (`int`, *optional*, defaults to 256008): Vocabulary size of the XGLM model. Defines the number of different tokens that can be represented by the - `inputs_ids` passed when calling [`XGLMModel`] or [`FlaxXGLMModel`]. + `inputs_ids` passed when calling [`XGLMModel`]. max_position_embeddings (`int`, *optional*, defaults to 2048): 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). diff --git a/src/transformers/models/xglm/modeling_flax_xglm.py b/src/transformers/models/xglm/modeling_flax_xglm.py deleted file mode 100644 index 1366148d9a3d..000000000000 --- a/src/transformers/models/xglm/modeling_flax_xglm.py +++ /dev/null @@ -1,803 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""Flax XGLM model.""" - -import math -import random -from functools import partial -from typing import Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax -from jax.random import PRNGKey - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, -) -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_xglm import XGLMConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/xglm-564M" -_CONFIG_FOR_DOC = "XGLMConfig" - -XGLM_START_DOCSTRING = r""" - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a Flax Linen - [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a - regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`XGLMConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. - dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): - The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and - `jax.numpy.bfloat16` (on TPUs). - - This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If - specified all the computation will be performed with the given `dtype`. - - **Note that this only specifies the dtype of the computation and does not influence the dtype of model - parameters.** - - If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and - [`~FlaxPreTrainedModel.to_bf16`]. -""" - -XGLM_INPUTS_DOCSTRING = r""" - Args: - input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): - Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide - it. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -def create_sinusoidal_positions(n_pos, dim, padding_idx=1): - half_dim = dim // 2 - emb = math.log(10000) / (half_dim - 1) - emb = np.exp(np.arange(half_dim) * -emb) - emb = np.expand_dims(np.arange(n_pos), 1) * np.expand_dims(emb, 0) - emb = np.concatenate([np.sin(emb), np.cos(emb)], 1) - emb = np.reshape(emb, (n_pos, dim)) - - if padding_idx is not None: - emb[padding_idx, :] = 0 - - return jnp.array(emb) - - -class FlaxXGLMAttention(nn.Module): - config: XGLMConfig - embed_dim: int - num_heads: int - dropout: float = 0.0 - causal: bool = False - bias: bool = True - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self) -> None: - self.head_dim = self.embed_dim // self.num_heads - - if self.head_dim * self.num_heads != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} " - f"and `num_heads`: {self.num_heads})." - ) - - dense = partial( - nn.Dense, - self.embed_dim, - use_bias=self.bias, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() - self.out_proj = dense() - - self.dropout_layer = nn.Dropout(rate=self.dropout) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) - - @nn.compact - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend - # to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states: jnp.ndarray, - key_value_states: Optional[jnp.ndarray] = None, - attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.q_proj(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.k_proj(key_value_states) - value_states = self.v_proj(key_value_states) - else: - # self_attention - key_states = self.k_proj(hidden_states) - value_states = self.v_proj(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.dropout > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.dropout, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = self._merge_heads(attn_output) - attn_output = self.out_proj(attn_output) - - return attn_output, attn_weights - - -class FlaxXGLMDecoderLayer(nn.Module): - config: XGLMConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self) -> None: - self.embed_dim = self.config.d_model - self.self_attn = FlaxXGLMAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.attention_heads, - dropout=self.config.attention_dropout, - causal=True, - dtype=self.dtype, - ) - self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - self.activation_fn = ACT2FN[self.config.activation_function] - self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) - - if self.config.add_cross_attention: - self.encoder_attn = FlaxXGLMAttention( - config=self.config, - embed_dim=self.embed_dim, - num_heads=self.config.decoder_attention_heads, - dropout=self.config.attention_dropout, - dtype=self.dtype, - ) - self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - self.fc1 = nn.Dense( - self.config.ffn_dim, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - self.fc2 = nn.Dense( - self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) - ) - self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - # Copied from transformers.models.mbart.modeling_flax_mbart.FlaxMBartDecoderLayer.__call__ - def __call__( - self, - hidden_states: jnp.ndarray, - attention_mask: jnp.ndarray, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = True, - deterministic: bool = True, - ) -> tuple[jnp.ndarray]: - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - hidden_states, self_attn_weights = self.self_attn( - hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - - hidden_states = self.encoder_attn_layer_norm(hidden_states) - hidden_states, cross_attn_weights = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - ) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - hidden_states = residual + hidden_states - - outputs = (hidden_states,) - - if output_attentions: - outputs += (self_attn_weights, cross_attn_weights) - - return outputs - - -class FlaxXGLMDecoderLayerCollection(nn.Module): - config: XGLMConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.layers = [ - FlaxXGLMDecoderLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.num_layers) - ] - self.layerdrop = self.config.layerdrop - - def __call__( - self, - hidden_states, - attention_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - deterministic: bool = True, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - for decoder_layer in self.layers: - if output_hidden_states: - all_hidden_states += (hidden_states,) - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - dropout_probability = random.uniform(0, 1) - if not deterministic and (dropout_probability < self.layerdrop): - layer_outputs = (None, None, None) - else: - layer_outputs = decoder_layer( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - deterministic=deterministic, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attns += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_self_attns, all_cross_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - -class FlaxXGLMModule(nn.Module): - config: XGLMConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dropout_layer = nn.Dropout(rate=self.config.dropout) - - embed_dim = self.config.d_model - self.padding_idx = self.config.pad_token_id - self.max_target_positions = self.config.max_position_embeddings - self.embed_scale = math.sqrt(self.config.d_model) if self.config.scale_embedding else 1.0 - - self.embed_tokens = nn.Embed( - self.config.vocab_size, - embed_dim, - embedding_init=jax.nn.initializers.normal(self.config.init_std), - ) - - # XGLM is set up so that if padding_idx is specified then offset the embedding ids by 2 - # and adjust num_embeddings appropriately. Other models don't have this hack - self.offset = 2 - self.embed_positions = create_sinusoidal_positions( - self.config.max_position_embeddings + self.offset, embed_dim - ) - self.layers = FlaxXGLMDecoderLayerCollection(self.config, self.dtype) - self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - input_shape = input_ids.shape - input_ids = input_ids.reshape(-1, input_shape[-1]) - - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - # embed positions - position_ids = position_ids + self.offset - positions = jnp.take(self.embed_positions, position_ids, axis=0) - - hidden_states = inputs_embeds + positions - hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) - - outputs = self.layers( - hidden_states, - attention_mask, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - last_hidden_states = outputs[0] - last_hidden_states = self.layer_norm(last_hidden_states) - - hidden_states = None - if output_hidden_states: - hidden_states = outputs[1] - hidden_states = hidden_states[:-1] + (last_hidden_states,) - - if not return_dict: - outputs = (last_hidden_states, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=last_hidden_states, - hidden_states=hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -class FlaxXGLMPreTrainedModel(FlaxPreTrainedModel): - config_class = XGLMConfig - base_model_prefix: str = "model" - module_class: nn.Module = None - - def __init__( - self, - config: XGLMConfig, - input_shape: tuple[int] = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - attention_mask = jnp.ones_like(input_ids) - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - if self.config.add_cross_attention: - encoder_hidden_states = jnp.zeros(input_shape + (self.config.n_embd,)) - encoder_attention_mask = attention_mask - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states, - encoder_attention_mask, - return_dict=False, - ) - else: - module_init_outputs = self.module.init(rngs, input_ids, attention_mask, position_ids, return_dict=False) - - random_params = module_init_outputs["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length), dtype="i4") - attention_mask = jnp.ones_like(input_ids, dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(XGLM_INPUTS_DOCSTRING) - def __call__( - self, - input_ids: jnp.ndarray, - attention_mask: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - train: bool = False, - params: Optional[dict] = None, - past_key_values: Optional[dict] = None, - dropout_rng: PRNGKey = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - if encoder_hidden_states is not None and encoder_attention_mask is None: - batch_size, sequence_length = encoder_hidden_states.shape[:2] - encoder_attention_mask = jnp.ones((batch_size, sequence_length)) - - # prepare encoder inputs - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - if position_ids is None: - batch_size, sequence_length = input_ids.shape - position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) - - # Handle any PRNG if needed - rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} - - inputs = {"params": params or self.params} - - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed - # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be - # changed by FlaxXGLMAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - input_ids=jnp.array(input_ids, dtype="i4"), - attention_mask=jnp.array(attention_mask, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - deterministic=not train, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - return outputs - - -@add_start_docstrings( - "The bare XGLM Model transformer outputting raw hidden-states without any specific head on top.", - XGLM_START_DOCSTRING, -) -class FlaxXGLMModel(FlaxXGLMPreTrainedModel): - module_class = FlaxXGLMModule - - -append_call_sample_docstring( - FlaxXGLMModel, - _CHECKPOINT_FOR_DOC, - FlaxBaseModelOutputWithPastAndCrossAttentions, - _CONFIG_FOR_DOC, -) - - -class FlaxXGLMForCausalLMModule(nn.Module): - config: XGLMConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.model = FlaxXGLMModule(self.config, self.dtype) - self.lm_head = nn.Dense( - self.config.vocab_size, - use_bias=False, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.init_std), - ) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - deterministic: bool = True, - ): - outputs = self.model( - input_ids, - attention_mask, - position_ids, - encoder_hidden_states, - encoder_attention_mask, - deterministic=deterministic, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - if self.config.tie_word_embeddings: - shared_embedding = self.model.variables["params"]["embed_tokens"]["embedding"] - lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - lm_logits = self.lm_head(hidden_states) - - if not return_dict: - return (lm_logits,) + outputs[1:] - - return FlaxCausalLMOutputWithCrossAttentions( - logits=lm_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - """ - The XGLM Model transformer with a language modeling head on top (linear layer with weights tied to the input - embeddings). - """, - XGLM_START_DOCSTRING, -) -class FlaxXGLMForCausalLM(FlaxXGLMPreTrainedModel): - module_class = FlaxXGLMForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since GPT2 uses a causal mask, those positions are masked anyways. - # Thus we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxXGLMForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutputWithCrossAttentions, - _CONFIG_FOR_DOC, -) - - -__all__ = ["FlaxXGLMForCausalLM", "FlaxXGLMModel", "FlaxXGLMPreTrainedModel"] diff --git a/src/transformers/models/xglm/modeling_tf_xglm.py b/src/transformers/models/xglm/modeling_tf_xglm.py deleted file mode 100644 index d799ced79208..000000000000 --- a/src/transformers/models/xglm/modeling_tf_xglm.py +++ /dev/null @@ -1,1002 +0,0 @@ -# coding=utf-8 -# Copyright 2021 The Fairseq Authors The HuggingFace Inc. team. All rights reserved. -# -# 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. -"""TF 2.0 XGLM model.""" - -from __future__ import annotations - -import math -import random -from typing import Any - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation - -# Public API -from ...file_utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - replace_return_docstrings, -) -from ...modeling_tf_outputs import TFBaseModelOutputWithPastAndCrossAttentions, TFCausalLMOutputWithCrossAttentions -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFPreTrainedModel, - TFSharedEmbeddings, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import logging -from .configuration_xglm import XGLMConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "facebook/xglm-564M" -_CONFIG_FOR_DOC = "XGLMConfig" - - -LARGE_NEGATIVE = -1e8 - - -def create_sinusoidal_positions(num_positions: int, embedding_dim: int, padding_idx: int | None) -> tf.Tensor: - half_dim = embedding_dim // 2 - emb = math.log(10000) / (half_dim - 1) - emb = tf.exp(tf.range(half_dim, dtype=tf.float32) * -emb) - emb = tf.expand_dims(tf.range(num_positions, dtype=tf.float32), axis=1) * tf.expand_dims(emb, axis=0) - emb = tf.reshape(tf.concat([tf.sin(emb), tf.cos(emb)], axis=1), (num_positions, -1)) - if embedding_dim % 2 == 1: - # zero pad - emb = tf.concat([emb, tf.zeros((num_positions, 1))], axis=1) - if padding_idx is not None: - _padding_mask = tf.concat( - [ - tf.ones((padding_idx, shape_list(emb)[1])), - tf.zeros((1, shape_list(emb)[1])), - tf.ones((shape_list(emb)[0] - padding_idx - 1, shape_list(emb)[1])), - ], - axis=0, - ) - emb *= _padding_mask - - return tf.constant(emb, name="embed_positions") - - -def _create_position_ids_from_input_ids( - input_ids: tf.Tensor, past_key_values_length: int, padding_idx: int | None -) -> tf.Tensor: - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = tf.where(input_ids != padding_idx, 1, 0) - incremental_indices = (tf.cast(tf.cumsum(mask, axis=1), dtype=mask.dtype) + past_key_values_length) * mask - return tf.cast(incremental_indices, dtype=tf.int64) + padding_idx - - -def _create_position_ids_from_inputs_embeds( - inputs_embeds: tf.Tensor, past_key_values_length: int, padding_idx: int | None -) -> tf.Tensor: - """ - Args: - We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. - inputs_embeds: tf.Tensor - Returns: tf.Tensor - """ - input_shape = shape_list(inputs_embeds)[:-1] - sequence_length = input_shape[1] - - position_ids = tf.range(padding_idx + 1, sequence_length + padding_idx + 1, dtype=tf.int64) - - return tf.broadcast_to(tf.expand_dims(position_ids, axis=0), input_shape) + past_key_values_length - - -# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask -def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): - """ - Make causal mask used for bi-directional self-attention. - """ - bsz = input_ids_shape[0] - tgt_len = input_ids_shape[1] - mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE - mask_cond = tf.range(shape_list(mask)[-1]) - - mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) - - if past_key_values_length > 0: - mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) - - return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) - - -# Copied from transformers.models.bart.modeling_tf_bart._expand_mask -def _expand_mask(mask: tf.Tensor, tgt_len: int | None = None): - """ - Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. - """ - src_len = shape_list(mask)[1] - tgt_len = tgt_len if tgt_len is not None else src_len - one_cst = tf.constant(1.0) - mask = tf.cast(mask, dtype=one_cst.dtype) - expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) - - return (one_cst - expanded_mask) * LARGE_NEGATIVE - - -# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with Bart->XGLM -class TFXGLMAttention(keras.layers.Layer): - """Multi-headed attention from "Attention Is All You Need""" - - def __init__( - self, - embed_dim: int, - num_heads: int, - dropout: float = 0.0, - is_decoder: bool = False, - bias: bool = True, - **kwargs, - ): - super().__init__(**kwargs) - self.embed_dim = embed_dim - - self.num_heads = num_heads - self.dropout = keras.layers.Dropout(dropout) - self.head_dim = embed_dim // num_heads - if (self.head_dim * num_heads) != self.embed_dim: - raise ValueError( - f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" - f" and `num_heads`: {num_heads})." - ) - self.scaling = self.head_dim**-0.5 - self.is_decoder = is_decoder - - self.k_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") - self.q_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") - self.v_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") - self.out_proj = keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") - - def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): - return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) - - def call( - self, - hidden_states: tf.Tensor, - key_value_states: tf.Tensor | None = None, - past_key_value: tuple[tuple[tf.Tensor]] | None = None, - attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor | None]: - """Input shape: Batch x Time x Channel""" - - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - bsz, tgt_len, embed_dim = shape_list(hidden_states) - - # get query proj - query_states = self.q_proj(hidden_states) * self.scaling - # get key, value proj - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_states = past_key_value[0] - value_states = past_key_value[1] - elif is_cross_attention: - # cross_attentions - key_states = self._shape(self.k_proj(key_value_states), -1, bsz) - value_states = self._shape(self.v_proj(key_value_states), -1, bsz) - elif past_key_value is not None: - # reuse k, v, self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - key_states = tf.concat([past_key_value[0], key_states], axis=2) - value_states = tf.concat([past_key_value[1], value_states], axis=2) - else: - # self_attention - key_states = self._shape(self.k_proj(hidden_states), -1, bsz) - value_states = self._shape(self.v_proj(hidden_states), -1, bsz) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_states, value_states) - - proj_shape = (bsz * self.num_heads, -1, self.head_dim) - query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) - key_states = tf.reshape(key_states, proj_shape) - value_states = tf.reshape(value_states, proj_shape) - - src_len = shape_list(key_states)[1] - attn_weights = tf.matmul(query_states, key_states, transpose_b=True) - - tf.debugging.assert_equal( - shape_list(attn_weights), - [bsz * self.num_heads, tgt_len, src_len], - message=( - f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" - f" {shape_list(attn_weights)}" - ), - ) - - if attention_mask is not None: - tf.debugging.assert_equal( - shape_list(attention_mask), - [bsz, 1, tgt_len, src_len], - message=( - f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" - f" {shape_list(attention_mask)}" - ), - ) - - attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) - attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_weights = stable_softmax(attn_weights, axis=-1) - - if layer_head_mask is not None: - tf.debugging.assert_equal( - shape_list(layer_head_mask), - [self.num_heads], - message=( - f"Head mask for a single layer should be of size {(self.num_heads)}, but is" - f" {shape_list(layer_head_mask)}" - ), - ) - - attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( - attn_weights, (bsz, self.num_heads, tgt_len, src_len) - ) - attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) - - attn_probs = self.dropout(attn_weights, training=training) - attn_output = tf.matmul(attn_probs, value_states) - - tf.debugging.assert_equal( - shape_list(attn_output), - [bsz * self.num_heads, tgt_len, self.head_dim], - message=( - f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" - f" {shape_list(attn_output)}" - ), - ) - - attn_output = tf.transpose( - tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) - ) - attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) - - attn_output = self.out_proj(attn_output) - attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) - - return attn_output, attn_weights, past_key_value - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "k_proj", None) is not None: - with tf.name_scope(self.k_proj.name): - self.k_proj.build([None, None, self.embed_dim]) - if getattr(self, "q_proj", None) is not None: - with tf.name_scope(self.q_proj.name): - self.q_proj.build([None, None, self.embed_dim]) - if getattr(self, "v_proj", None) is not None: - with tf.name_scope(self.v_proj.name): - self.v_proj.build([None, None, self.embed_dim]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.embed_dim]) - - -class TFXGLMDecoderLayer(keras.layers.Layer): - def __init__(self, config: XGLMConfig, **kwargs: Any) -> None: - super().__init__(**kwargs) - self.embed_dim = config.d_model - self.self_attn = TFXGLMAttention( - embed_dim=self.embed_dim, - num_heads=config.attention_heads, - dropout=config.attention_dropout, - is_decoder=True, - name="self_attn", - ) - self.dropout = keras.layers.Dropout(config.dropout) - self.activation_fn = get_tf_activation(config.activation_function) - self.activation_dropout = keras.layers.Dropout(config.activation_dropout) - - if config.add_cross_attention: - self.encoder_attn = TFXGLMAttention( - embed_dim=self.embed_dim, - num_heads=config.attention_heads, - dropout=config.attention_dropout, - is_decoder=True, - name="encoder_attn", - ) - self.encoder_attn_layer_norm = keras.layers.LayerNormalization( - epsilon=1e-5, name="encoder_attn_layer_norm" - ) - - self.self_attn_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") - self.fc1 = keras.layers.Dense(config.ffn_dim, name="fc1") - self.fc2 = keras.layers.Dense(self.embed_dim, name="fc2") - self.final_layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") - self.config = config - - # Copied from transformers.models.mbart.modeling_tf_mbart.TFMBartDecoderLayer.call - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor | None = None, - encoder_hidden_states: tf.Tensor | None = None, - encoder_attention_mask: tf.Tensor | None = None, - layer_head_mask: tf.Tensor | None = None, - cross_attn_layer_head_mask: tf.Tensor | None = None, - past_key_value: tuple[tf.Tensor] | None = None, - training: bool | None = False, - ) -> tuple[tf.Tensor, tf.Tensor, tuple[tuple[tf.Tensor]]]: - """ - Args: - hidden_states (`tf.Tensor`): input to the layer of shape *(batch, seq_len, embed_dim)* - attention_mask (`tf.Tensor`): attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - encoder_hidden_states (`tf.Tensor`): - cross attention input to the layer of shape *(batch, seq_len, embed_dim)* - encoder_attention_mask (`tf.Tensor`): encoder attention mask of size - *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. - layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size - *(decoder_attention_heads,)* - cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. - *(decoder_attention_heads,)* - past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states - """ - residual = hidden_states - hidden_states = self.self_attn_layer_norm(hidden_states) - - # Self Attention - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - # add present self-attn cache to positions 1,2 of present_key_value tuple - hidden_states, self_attn_weights, present_key_value = self.self_attn( - hidden_states=hidden_states, - past_key_value=self_attn_past_key_value, - attention_mask=attention_mask, - layer_head_mask=layer_head_mask, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # Cross-Attention Block - cross_attn_present_key_value = None - cross_attn_weights = None - if encoder_hidden_states is not None: - residual = hidden_states - hidden_states = self.encoder_attn_layer_norm(hidden_states) - - # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( - hidden_states=hidden_states, - key_value_states=encoder_hidden_states, - attention_mask=encoder_attention_mask, - layer_head_mask=cross_attn_layer_head_mask, - past_key_value=cross_attn_past_key_value, - ) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - # add cross-attn to positions 3,4 of present_key_value tuple - present_key_value = present_key_value + cross_attn_present_key_value - - # Fully Connected - residual = hidden_states - hidden_states = self.final_layer_norm(hidden_states) - hidden_states = self.activation_fn(self.fc1(hidden_states)) - hidden_states = self.activation_dropout(hidden_states, training=training) - hidden_states = self.fc2(hidden_states) - hidden_states = self.dropout(hidden_states, training=training) - hidden_states = residual + hidden_states - - return ( - hidden_states, - self_attn_weights, - cross_attn_weights, - present_key_value, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attn", None) is not None: - with tf.name_scope(self.self_attn.name): - self.self_attn.build(None) - if getattr(self, "self_attn_layer_norm", None) is not None: - with tf.name_scope(self.self_attn_layer_norm.name): - self.self_attn_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "fc1", None) is not None: - with tf.name_scope(self.fc1.name): - self.fc1.build([None, None, self.embed_dim]) - if getattr(self, "fc2", None) is not None: - with tf.name_scope(self.fc2.name): - self.fc2.build([None, None, self.config.ffn_dim]) - if getattr(self, "final_layer_norm", None) is not None: - with tf.name_scope(self.final_layer_norm.name): - self.final_layer_norm.build([None, None, self.embed_dim]) - if getattr(self, "encoder_attn", None) is not None: - with tf.name_scope(self.encoder_attn.name): - self.encoder_attn.build(None) - if getattr(self, "encoder_attn_layer_norm", None) is not None: - with tf.name_scope(self.encoder_attn_layer_norm.name): - self.encoder_attn_layer_norm.build([None, None, self.embed_dim]) - - -@keras_serializable -class TFXGLMMainLayer(keras.layers.Layer): - config_class = XGLMConfig - - def __init__( - self, config: XGLMConfig, embed_tokens: TFSharedEmbeddings | None = None, *inputs, **kwargs: Any - ) -> None: - super().__init__(*inputs, **kwargs) - - self.config = config - self.padding_idx = config.pad_token_id - self.max_target_positions = config.max_position_embeddings - self.embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0 - - if embed_tokens is not None: - self.embed_tokens = embed_tokens - else: - self.embed_tokens = TFSharedEmbeddings( - config.vocab_size, config.d_model, self.padding_idx, name="embed_tokens" - ) - - self.offset = 2 - self._embed_positions_weights = create_sinusoidal_positions( - num_positions=config.max_position_embeddings + self.offset, - embedding_dim=config.d_model, - padding_idx=config.pad_token_id, - ) - - self.dropout = keras.layers.Dropout(config.dropout) - self.layers = [TFXGLMDecoderLayer(config, name=f"layers.{i}") for i in range(config.num_layers)] - self.layerdrop = config.layerdrop - self.layer_norm = keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") - - def get_input_embeddings(self) -> TFSharedEmbeddings: - return self.embed_tokens - - def set_input_embeddings(self, value: TFSharedEmbeddings) -> None: - self.embed_tokens = value - - def _prepare_decoder_attention_mask( - self, - attention_mask: tf.Tensor | None, - input_shape: tf.TensorShape, - past_key_values_length: int, - ) -> tf.Tensor: - # create causal mask - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length) - combined_attention_mask = tf.cond( - input_shape[-1] > 1, lambda: combined_attention_mask, lambda: tf.ones_like(combined_attention_mask) - ) - if attention_mask is None: - return combined_attention_mask - expand_attention_mask = _expand_mask(attention_mask, tgt_len=input_shape[-1]) - return expand_attention_mask + combined_attention_mask - - def embed_positions(self, position_ids: np.ndarray | tf.Tensor | None = None) -> tf.Tensor: - position_ids += self.offset - positions = tf.gather(self._embed_positions_weights, position_ids, axis=0) - return positions - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs: Any, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - use_cache = use_cache if use_cache is not None else self.config.use_cache - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - # retrieve input_ids and inputs_embeds - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = tf.shape(input_ids) - input_ids = tf.reshape(input_ids, (-1, input_shape[-1])) - elif inputs_embeds is not None: - input_shape = tf.shape(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 - - if position_ids is None: - position_ids = tf.expand_dims( - tf.range(past_key_values_length, input_shape[-1] + past_key_values_length), axis=0 - ) - position_ids = tf.reshape(position_ids, [-1, shape_list(position_ids)[-1]]) - - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embed_tokens.vocab_size) - inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale - - attention_mask = self._prepare_decoder_attention_mask(attention_mask, input_shape, past_key_values_length) - - # expand encoder attention mask - if encoder_hidden_states is not None and encoder_attention_mask is not None: - # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] - encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) - - # embed positions - positions = self.embed_positions(position_ids) - - hidden_states = tf.cast(inputs_embeds, dtype=tf.float32) + positions - - hidden_states = self.dropout(hidden_states, training=training) - - # decoder layers - all_hidden_states = () if output_hidden_states else None - all_self_attns = () if output_attentions else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - next_decoder_cache = () if use_cache else None - - # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired - for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: - if attn_mask is not None: - tf.debugging.assert_equal( - shape_list(attn_mask)[0], - len(self.layers), - message=( - f"The {attn_mask_name} should be specified for {len(self.layers)} layers, but it is for" - f" {shape_list(attn_mask)[0]}." - ), - ) - - for idx, decoder_layer in enumerate(self.layers): - # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description) - if output_hidden_states: - all_hidden_states += (hidden_states,) - - dropout_probability = random.uniform(0, 1) - if training and (dropout_probability < self.layerdrop): - continue - - past_key_value = past_key_values[idx] if past_key_values is not None else None - - hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( - hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - layer_head_mask=(head_mask[idx] if head_mask is not None else None), - cross_attn_layer_head_mask=(cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None), - past_key_value=past_key_value, - ) - - if use_cache: - next_decoder_cache += (present_key_value,) - - if output_attentions: - all_self_attns += (layer_self_attn,) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_cross_attn,) - - hidden_states = self.layer_norm(hidden_states) - - # add hidden states from the last decoder layer - if output_hidden_states: - all_hidden_states += (hidden_states,) - - next_cache = next_decoder_cache if use_cache else None - if not return_dict: - return tuple( - v - for v in [hidden_states, next_cache, all_hidden_states, all_self_attns, all_cross_attentions] - if v is not None - ) - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_cache, - hidden_states=all_hidden_states, - attentions=all_self_attns, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "embed_tokens", None) is not None: - with tf.name_scope(self.embed_tokens.name): - self.embed_tokens.build(None) - if getattr(self, "layers", None) is not None: - for layer in self.layers: - with tf.name_scope(layer.name): - layer.build(None) - - -class TFXGLMPreTrainedModel(TFPreTrainedModel): - config_class = XGLMConfig - base_model_prefix = "model" - - -XGLM_START_DOCSTRING = r""" - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Args: - config ([`XGLMConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -XGLM_INPUTS_DOCSTRING = r""" - Args: - input_ids (`tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - position_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention of - the decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): - Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values - selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - head_mask (`tf.Tensor` of shape `(num_layers, attention_heads)`, *optional*): - Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - cross_attn_head_mask (`tf.Tensor` of shape `(num_layers, attention_heads)`, *optional*): - Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.num_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare XGLM Model transformer outputting raw hidden-states without any specific head on top.", - XGLM_START_DOCSTRING, -) -class TFXGLMModel(TFXGLMPreTrainedModel): - """ - Transformer decoder consisting of *config.num_layers* layers. Each layer is a [`TFXGLMDecoderLayer`] - - Args: - config: XGLMConfig - embed_tokens: [TFSharedEmbeddings]: output embedding - """ - - def __init__( - self, config: XGLMConfig, embed_tokens: TFSharedEmbeddings | None = None, *inputs: Any, **kwargs: Any - ) -> None: - super().__init__(config, *inputs, **kwargs) - - self.model = TFXGLMMainLayer(config, embed_tokens=embed_tokens, name="model") - - @unpack_inputs - @add_start_docstrings_to_model_forward(XGLM_INPUTS_DOCSTRING) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPastAndCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs: Any, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - head_mask=head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - - -@add_start_docstrings( - """ - The XGLM Model transformer with a language modeling head on top (linear layer with weights tied to the input - embeddings). - """, - XGLM_START_DOCSTRING, -) -class TFXGLMForCausalLM(TFXGLMPreTrainedModel, TFCausalLanguageModelingLoss): - base_model_prefix = "model" - _keys_to_ignore_on_load_missing = [ - r"model.embed_positions.weights", - r"lm_head.weight", - ] - _keys_to_ignore_on_save = [ - r"model.embed_positions.weights", - ] - - def __init__( - self, config: XGLMConfig, embed_tokens: TFSharedEmbeddings | None = None, *inputs: Any, **kwargs: Any - ) -> None: - super().__init__(config, *inputs, **kwargs) - - self.model = TFXGLMMainLayer(config, embed_tokens=embed_tokens, name="model") - self.lm_head = keras.layers.Dense( - config.vocab_size, - use_bias=False, - kernel_initializer=get_initializer(config.init_std), - name="lm_head", - ) - self.config = config - - def prepare_inputs_for_generation(self, inputs, past_key_values=None, use_cache=None, **kwargs): - # only last token for inputs_ids if past is defined in kwargs - if past_key_values: - inputs = tf.expand_dims(inputs[:, -1], -1) - - position_ids = kwargs.get("position_ids") - attention_mask = kwargs.get("attention_mask") - - if attention_mask is not None and position_ids is None: - position_ids = tf.math.cumsum(attention_mask, axis=-1, exclusive=True) - if past_key_values: - position_ids = tf.expand_dims(position_ids[:, -1], -1) - - return { - "input_ids": inputs, - "attention_mask": attention_mask, - "position_ids": position_ids, - "past_key_values": past_key_values, - "use_cache": use_cache, - } - - @unpack_inputs - @add_start_docstrings_to_model_forward(XGLM_INPUTS_DOCSTRING) - @replace_return_docstrings(output_type=TFCausalLMOutputWithCrossAttentions, config_class=_CONFIG_FOR_DOC) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutputWithCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - cross_attn_head_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - labels: np.ndarray | tf.Tensor | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - **kwargs: Any, - ) -> TFCausalLMOutputWithCrossAttentions | tuple[tf.Tensor]: - r""" - labels (`np.ndarray` or `tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for language modeling. Note that the labels **are shifted** inside the model, i.e. you can set - `labels = input_ids` Indices are selected in `[-100, 0, ..., config.vocab_size]` All labels set to `-100` - are ignored (masked), the loss is only computed for labels in `[0, ..., config.vocab_size]` - """ - - outputs = self.model( - input_ids=input_ids, - attention_mask=attention_mask, - position_ids=position_ids, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - head_mask=head_mask, - cross_attn_head_mask=cross_attn_head_mask, - past_key_values=past_key_values, - inputs_embeds=inputs_embeds, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_states = outputs[0] - lm_logits = self.lm_head(hidden_states) - - loss = None - if labels is not None: - # shift labels to the left and cut last logit token - labels = tf.concat( - [labels[:, 1:], tf.fill((labels.shape[0], 1), tf.cast(-100, labels.dtype))], - axis=-1, - ) - loss = self.hf_compute_loss(labels, lm_logits) - - if not return_dict: - output = (lm_logits,) + outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithCrossAttentions( - loss=loss, - logits=lm_logits, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "model", None) is not None: - with tf.name_scope(self.model.name): - self.model.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build([None, None, self.config.hidden_size]) - - def tf_to_pt_weight_rename(self, tf_weight): - if tf_weight == "lm_head.weight": - return tf_weight, "model.embed_tokens.weight" - else: - return (tf_weight,) - - -__all__ = ["TFXGLMForCausalLM", "TFXGLMModel", "TFXGLMPreTrainedModel"] diff --git a/src/transformers/models/xlm/__init__.py b/src/transformers/models/xlm/__init__.py index 1167fc93a101..d6ad3ff9c90d 100644 --- a/src/transformers/models/xlm/__init__.py +++ b/src/transformers/models/xlm/__init__.py @@ -19,7 +19,6 @@ if TYPE_CHECKING: from .configuration_xlm import * - from .modeling_tf_xlm import * from .modeling_xlm import * from .tokenization_xlm import * else: diff --git a/src/transformers/models/xlm/modeling_tf_xlm.py b/src/transformers/models/xlm/modeling_tf_xlm.py deleted file mode 100644 index db89b4686f84..000000000000 --- a/src/transformers/models/xlm/modeling_tf_xlm.py +++ /dev/null @@ -1,1356 +0,0 @@ -# coding=utf-8 -# Copyright 2019-present, Facebook, Inc and 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. -""" -TF 2.0 XLM model. -""" - -from __future__ import annotations - -import itertools -import warnings -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFSequenceSummary, - TFSharedEmbeddings, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - MULTIPLE_CHOICE_DUMMY_INPUTS, - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_xlm import XLMConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "FacebookAI/xlm-mlm-en-2048" -_CONFIG_FOR_DOC = "XLMConfig" - - -def create_sinusoidal_embeddings(n_pos, dim, out): - position_enc = np.array([[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)]) - out[:, 0::2] = tf.constant(np.sin(position_enc[:, 0::2])) - out[:, 1::2] = tf.constant(np.cos(position_enc[:, 1::2])) - - -def get_masks(slen, lengths, causal, padding_mask=None): - """ - Generate hidden states mask, and optionally an attention mask. - """ - bs = shape_list(lengths)[0] - if padding_mask is not None: - mask = padding_mask - else: - # assert lengths.max().item() <= slen - alen = tf.range(slen, dtype=lengths.dtype) - mask = alen < tf.expand_dims(lengths, axis=1) - - # attention mask is the same as mask, or triangular inferior attention (causal) - if causal: - attn_mask = tf.less_equal( - tf.tile(tf.reshape(alen, (1, 1, slen)), (bs, slen, 1)), tf.reshape(alen, (1, slen, 1)) - ) - else: - attn_mask = mask - - # sanity check - # assert shape_list(mask) == [bs, slen] - tf.debugging.assert_equal(shape_list(mask), [bs, slen]) - if causal: - tf.debugging.assert_equal(shape_list(attn_mask), [bs, slen, slen]) - - return mask, attn_mask - - -class TFXLMMultiHeadAttention(keras.layers.Layer): - NEW_ID = itertools.count() - - def __init__(self, n_heads, dim, config, **kwargs): - super().__init__(**kwargs) - self.layer_id = next(TFXLMMultiHeadAttention.NEW_ID) - self.dim = dim - self.n_heads = n_heads - self.output_attentions = config.output_attentions - assert self.dim % self.n_heads == 0 - - self.q_lin = keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="q_lin") - self.k_lin = keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="k_lin") - self.v_lin = keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="v_lin") - self.out_lin = keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="out_lin") - self.dropout = keras.layers.Dropout(config.attention_dropout) - self.pruned_heads = set() - self.dim = dim - - def prune_heads(self, heads): - raise NotImplementedError - - def call(self, input, mask, kv, cache, head_mask, output_attentions, training=False): - """ - Self-attention (if kv is None) or attention over source sentence (provided by kv). - """ - # Input is (bs, qlen, dim) - # Mask is (bs, klen) (non-causal) or (bs, klen, klen) - bs, qlen, dim = shape_list(input) - - if kv is None: - klen = qlen if cache is None else cache["slen"] + qlen - else: - klen = shape_list(kv)[1] - - # assert dim == self.dim, f'Dimensions do not match: {dim} input vs {self.dim} configured' - dim_per_head = self.dim // self.n_heads - mask_reshape = (bs, 1, qlen, klen) if len(shape_list(mask)) == 3 else (bs, 1, 1, klen) - - def shape(x): - """projection""" - return tf.transpose(tf.reshape(x, (bs, -1, self.n_heads, dim_per_head)), perm=(0, 2, 1, 3)) - - def unshape(x): - """compute context""" - return tf.reshape(tf.transpose(x, perm=(0, 2, 1, 3)), (bs, -1, self.n_heads * dim_per_head)) - - q = shape(self.q_lin(input)) # (bs, n_heads, qlen, dim_per_head) - - if kv is None: - k = shape(self.k_lin(input)) # (bs, n_heads, qlen, dim_per_head) - v = shape(self.v_lin(input)) # (bs, n_heads, qlen, dim_per_head) - elif cache is None or self.layer_id not in cache: - k = v = kv - k = shape(self.k_lin(k)) # (bs, n_heads, qlen, dim_per_head) - v = shape(self.v_lin(v)) # (bs, n_heads, qlen, dim_per_head) - - if cache is not None: - if self.layer_id in cache: - if kv is None: - k_, v_ = cache[self.layer_id] - k = tf.concat([k_, k], axis=2) # (bs, n_heads, klen, dim_per_head) - v = tf.concat([v_, v], axis=2) # (bs, n_heads, klen, dim_per_head) - else: - k, v = cache[self.layer_id] - - cache[self.layer_id] = (k, v) - - f_dim_per_head = tf.cast(dim_per_head, dtype=q.dtype) - q = tf.multiply(q, tf.math.rsqrt(f_dim_per_head)) # (bs, n_heads, qlen, dim_per_head) - k = tf.cast(k, dtype=q.dtype) - scores = tf.matmul(q, k, transpose_b=True) # (bs, n_heads, qlen, klen) - mask = tf.reshape(mask, mask_reshape) # (bs, n_heads, qlen, klen) - # scores.masked_fill_(mask, -float('inf')) # (bs, n_heads, qlen, klen) - mask = tf.cast(mask, dtype=scores.dtype) - scores = scores - 1e30 * (1.0 - mask) - weights = stable_softmax(scores, axis=-1) # (bs, n_heads, qlen, klen) - weights = self.dropout(weights, training=training) # (bs, n_heads, qlen, klen) - - # Mask heads if we want to - if head_mask is not None: - weights = weights * head_mask - - context = tf.matmul(weights, v) # (bs, n_heads, qlen, dim_per_head) - context = unshape(context) # (bs, qlen, dim) - outputs = (self.out_lin(context),) - - if output_attentions: - outputs = outputs + (weights,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "q_lin", None) is not None: - with tf.name_scope(self.q_lin.name): - self.q_lin.build([None, None, self.dim]) - if getattr(self, "k_lin", None) is not None: - with tf.name_scope(self.k_lin.name): - self.k_lin.build([None, None, self.dim]) - if getattr(self, "v_lin", None) is not None: - with tf.name_scope(self.v_lin.name): - self.v_lin.build([None, None, self.dim]) - if getattr(self, "out_lin", None) is not None: - with tf.name_scope(self.out_lin.name): - self.out_lin.build([None, None, self.dim]) - - -class TFXLMTransformerFFN(keras.layers.Layer): - def __init__(self, in_dim, dim_hidden, out_dim, config, **kwargs): - super().__init__(**kwargs) - - self.lin1 = keras.layers.Dense(dim_hidden, kernel_initializer=get_initializer(config.init_std), name="lin1") - self.lin2 = keras.layers.Dense(out_dim, kernel_initializer=get_initializer(config.init_std), name="lin2") - self.act = get_tf_activation("gelu") if config.gelu_activation else get_tf_activation("relu") - self.dropout = keras.layers.Dropout(config.dropout) - self.in_dim = in_dim - self.dim_hidden = dim_hidden - - def call(self, input, training=False): - x = self.lin1(input) - x = self.act(x) - x = self.lin2(x) - x = self.dropout(x, training=training) - - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "lin1", None) is not None: - with tf.name_scope(self.lin1.name): - self.lin1.build([None, None, self.in_dim]) - if getattr(self, "lin2", None) is not None: - with tf.name_scope(self.lin2.name): - self.lin2.build([None, None, self.dim_hidden]) - - -@keras_serializable -class TFXLMMainLayer(keras.layers.Layer): - config_class = XLMConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.output_hidden_states = config.output_hidden_states - self.output_attentions = config.output_attentions - self.return_dict = config.use_return_dict - - # encoder / decoder, output layer - self.is_encoder = config.is_encoder - self.is_decoder = not config.is_encoder - - if self.is_decoder: - raise NotImplementedError("Currently XLM can only be used as an encoder") - - # self.with_output = with_output - self.causal = config.causal - - # dictionary / languages - self.n_langs = config.n_langs - self.use_lang_emb = config.use_lang_emb - self.n_words = config.n_words - self.eos_index = config.eos_index - self.pad_index = config.pad_index - # self.dico = dico - # self.id2lang = config.id2lang - # self.lang2id = config.lang2id - # assert len(self.dico) == self.n_words - # assert len(self.id2lang) == len(self.lang2id) == self.n_langs - - # model parameters - self.dim = config.emb_dim # 512 by default - self.hidden_dim = self.dim * 4 # 2048 by default - self.n_heads = config.n_heads # 8 by default - self.n_layers = config.n_layers - self.max_position_embeddings = config.max_position_embeddings - self.embed_init_std = config.embed_init_std - if self.dim % self.n_heads != 0: - raise ValueError("transformer dim must be a multiple of n_heads") - - # embeddings - self.dropout = keras.layers.Dropout(config.dropout) - self.attention_dropout = keras.layers.Dropout(config.attention_dropout) - - if config.sinusoidal_embeddings: - raise NotImplementedError - # create_sinusoidal_embeddings(config.max_position_embeddings, self.dim, out=self.position_embeddings.weight) - - self.embeddings = TFSharedEmbeddings( - self.n_words, self.dim, initializer_range=config.embed_init_std, name="embeddings" - ) # padding_idx=self.pad_index) - self.layer_norm_emb = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm_emb") - - # transformer layers - self.attentions = [] - self.layer_norm1 = [] - self.ffns = [] - self.layer_norm2 = [] - # if self.is_decoder: - # self.layer_norm15 = [] - # self.encoder_attn = [] - - for i in range(self.n_layers): - self.attentions.append( - TFXLMMultiHeadAttention(self.n_heads, self.dim, config=config, name=f"attentions_._{i}") - ) - self.layer_norm1.append( - keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name=f"layer_norm1_._{i}") - ) - # if self.is_decoder: - # self.layer_norm15.append(nn.LayerNorm(self.dim, eps=config.layer_norm_eps)) - # self.encoder_attn.append(MultiHeadAttention(self.n_heads, self.dim, dropout=self.attention_dropout)) - self.ffns.append( - TFXLMTransformerFFN(self.dim, self.hidden_dim, self.dim, config=config, name=f"ffns_._{i}") - ) - self.layer_norm2.append( - keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name=f"layer_norm2_._{i}") - ) - - if hasattr(config, "pruned_heads"): - pruned_heads = config.pruned_heads.copy().items() - config.pruned_heads = {} - - for layer, heads in pruned_heads: - if self.attentions[int(layer)].n_heads == config.n_heads: - self.prune_heads({int(layer): list(map(int, heads))}) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.dim], - initializer=get_initializer(self.embed_init_std), - ) - - if self.n_langs > 1 and self.use_lang_emb: - with tf.name_scope("lang_embeddings"): - self.lang_embeddings = self.add_weight( - name="embeddings", - shape=[self.n_langs, self.dim], - initializer=get_initializer(self.embed_init_std), - ) - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - if getattr(self, "layer_norm_emb", None) is not None: - with tf.name_scope(self.layer_norm_emb.name): - self.layer_norm_emb.build([None, None, self.dim]) - for layer in self.attentions: - with tf.name_scope(layer.name): - layer.build(None) - for layer in self.layer_norm1: - with tf.name_scope(layer.name): - layer.build([None, None, self.dim]) - for layer in self.ffns: - with tf.name_scope(layer.name): - layer.build(None) - for layer in self.layer_norm2: - with tf.name_scope(layer.name): - layer.build([None, None, self.dim]) - - def get_input_embeddings(self): - return self.embeddings - - def set_input_embeddings(self, value): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - def call( - self, - input_ids=None, - attention_mask=None, - langs=None, - token_type_ids=None, - position_ids=None, - lengths=None, - cache=None, - head_mask=None, - inputs_embeds=None, - output_attentions=None, - output_hidden_states=None, - return_dict=None, - training=False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - # removed: src_enc=None, src_len=None - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - bs, slen = shape_list(input_ids) - elif inputs_embeds is not None: - bs, slen = shape_list(inputs_embeds)[:2] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - if lengths is None: - if input_ids is not None: - lengths = tf.reduce_sum( - tf.cast(tf.not_equal(input_ids, self.pad_index), dtype=input_ids.dtype), axis=1 - ) - else: - lengths = tf.convert_to_tensor([slen] * bs) - # mask = input_ids != self.pad_index - - # check inputs - # assert shape_list(lengths)[0] == bs - ( - tf.debugging.assert_equal(shape_list(lengths)[0], bs), - f"Expected batch size {shape_list(lengths)[0]} and received batch size {bs} mismatched", - ) - # assert lengths.max().item() <= slen - # input_ids = input_ids.transpose(0, 1) # batch size as dimension 0 - # assert (src_enc is None) == (src_len is None) - # if src_enc is not None: - # assert self.is_decoder - # assert src_enc.size(0) == bs - - # generate masks - mask, attn_mask = get_masks(slen, lengths, self.causal, padding_mask=attention_mask) - # if self.is_decoder and src_enc is not None: - # src_mask = torch.arange(src_len.max(), dtype=torch.long, device=lengths.device) < src_len[:, None] - - # position_ids - if position_ids is None: - position_ids = tf.expand_dims(tf.range(slen), axis=0) - position_ids = tf.tile(position_ids, (bs, 1)) - - # assert shape_list(position_ids) == [bs, slen] # (slen, bs) - ( - tf.debugging.assert_equal(shape_list(position_ids), [bs, slen]), - f"Position id shape {shape_list(position_ids)} and input shape {[bs, slen]} mismatched", - ) - # position_ids = position_ids.transpose(0, 1) - - # langs - if langs is not None: - # assert shape_list(langs) == [bs, slen] # (slen, bs) - ( - tf.debugging.assert_equal(shape_list(langs), [bs, slen]), - f"Lang shape {shape_list(langs)} and input shape {[bs, slen]} mismatched", - ) - # langs = langs.transpose(0, 1) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x qlen x klen] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.n_layers - - # do not recompute cached elements - if cache is not None and input_ids is not None: - _slen = slen - cache["slen"] - input_ids = input_ids[:, -_slen:] - position_ids = position_ids[:, -_slen:] - if langs is not None: - langs = langs[:, -_slen:] - mask = mask[:, -_slen:] - attn_mask = attn_mask[:, -_slen:] - - # embeddings - if inputs_embeds is None: - check_embeddings_within_bounds(input_ids, self.embeddings.vocab_size) - inputs_embeds = self.embeddings(input_ids) - - tensor = inputs_embeds + tf.gather(self.position_embeddings, position_ids) - - if langs is not None and self.use_lang_emb and self.n_langs > 1: - tensor = tensor + tf.gather(self.lang_embeddings, langs) - if token_type_ids is not None: - tensor = tensor + self.embeddings(token_type_ids) - - tensor = self.layer_norm_emb(tensor) - tensor = self.dropout(tensor, training=training) - mask = tf.cast(mask, dtype=tensor.dtype) - tensor = tensor * tf.expand_dims(mask, axis=-1) - - # transformer layers - hidden_states = () if output_hidden_states else None - attentions = () if output_attentions else None - - for i in range(self.n_layers): - if output_hidden_states: - hidden_states = hidden_states + (tensor,) - - # self attention - attn_outputs = self.attentions[i]( - tensor, - attn_mask, - None, - cache, - head_mask[i], - output_attentions, - training=training, - ) - attn = attn_outputs[0] - - if output_attentions: - attentions = attentions + (attn_outputs[1],) - - attn = self.dropout(attn, training=training) - tensor = tensor + attn - tensor = self.layer_norm1[i](tensor) - - # encoder attention (for decoder only) - # if self.is_decoder and src_enc is not None: - # attn = self.encoder_attn[i](tensor, src_mask, kv=src_enc, cache=cache) - # attn = nn.functional.dropout(attn, p=self.dropout, training=self.training) - # tensor = tensor + attn - # tensor = self.layer_norm15[i](tensor) - - # FFN - tensor = tensor + self.ffns[i](tensor) - tensor = self.layer_norm2[i](tensor) - tensor = tensor * tf.expand_dims(mask, axis=-1) - - # Add last hidden state - if output_hidden_states: - hidden_states = hidden_states + (tensor,) - - # update cache length - if cache is not None: - cache["slen"] += tensor.size(1) - - # move back sequence length to dimension 0 - # tensor = tensor.transpose(0, 1) - - if not return_dict: - return tuple(v for v in [tensor, hidden_states, attentions] if v is not None) - - return TFBaseModelOutput(last_hidden_state=tensor, hidden_states=hidden_states, attentions=attentions) - - -class TFXLMPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = XLMConfig - base_model_prefix = "transformer" - - @property - def dummy_inputs(self): - # Sometimes XLM has language embeddings so don't forget to build them as well if needed - inputs_list = tf.constant([[7, 6, 0, 0, 1], [1, 2, 3, 0, 0], [0, 0, 0, 4, 5]], dtype=tf.int32) - attns_list = tf.constant([[1, 1, 0, 0, 1], [1, 1, 1, 0, 0], [1, 0, 0, 1, 1]], dtype=tf.int32) - if self.config.use_lang_emb and self.config.n_langs > 1: - return { - "input_ids": inputs_list, - "attention_mask": attns_list, - "langs": tf.constant([[1, 1, 0, 0, 1], [1, 1, 1, 0, 0], [1, 0, 0, 1, 1]], dtype=tf.int32), - } - else: - return {"input_ids": inputs_list, "attention_mask": attns_list} - - -# Remove when XLMWithLMHead computes loss like other LM models -@dataclass -class TFXLMWithLMHeadModelOutput(ModelOutput): - """ - Base class for [`TFXLMWithLMHeadModel`] outputs. - - Args: - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - logits: tf.Tensor | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -XLM_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`XLMConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -XLM_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and - [`PreTrainedTokenizer.encode`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - langs (`tf.Tensor` or `Numpy array` of shape `({0})`, *optional*): - A parallel sequence of tokens to be used to indicate the language of each token in the input. Indices are - languages ids which can be obtained from the language names by using two conversion mappings provided in - the configuration of the model (only provided for multilingual models). More precisely, the *language name - to language id* mapping is in `model.config.lang2id` (which is a dictionary string to int) and the - *language id to language name* mapping is in `model.config.id2lang` (dictionary int to string). - - See usage examples detailed in the [multilingual documentation](../multilingual). - token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - - [What are position IDs?](../glossary#position-ids) - lengths (`tf.Tensor` or `Numpy array` of shape `(batch_size,)`, *optional*): - Length of each sentence that can be used to avoid performing attention on padding token indices. You can - also use *attention_mask* for the same result (see above), kept here for compatibility. Indices selected in - `[0, ..., input_ids.size(-1)]`. - cache (`dict[str, tf.Tensor]`, *optional*): - Dictionary string to `tf.Tensor` that contains precomputed hidden states (key and values in the attention - blocks) as computed by the model (see `cache` output below). Can be used to speed up sequential decoding. - - The dictionary object will be modified in-place during the forward pass to add newly computed - hidden-states. - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -@add_start_docstrings( - "The bare XLM Model transformer outputting raw hidden-states without any specific head on top.", - XLM_START_DOCSTRING, -) -class TFXLMModel(TFXLMPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFXLMMainLayer(config, name="transformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: tf.Tensor | None = None, - langs: tf.Tensor | None = None, - token_type_ids: tf.Tensor | None = None, - position_ids: tf.Tensor | None = None, - lengths: tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: tf.Tensor | None = None, - inputs_embeds: tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutput | tuple[tf.Tensor]: - outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - langs=langs, - token_type_ids=token_type_ids, - position_ids=position_ids, - lengths=lengths, - cache=cache, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -class TFXLMPredLayer(keras.layers.Layer): - """ - Prediction layer (cross_entropy or adaptive_softmax). - """ - - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.asm = config.asm - self.n_words = config.n_words - self.pad_index = config.pad_index - - if config.asm is False: - self.input_embeddings = input_embeddings - else: - raise NotImplementedError - # self.proj = nn.AdaptiveLogSoftmaxWithLoss( - # in_features=dim, - # n_classes=config.n_words, - # cutoffs=config.asm_cutoffs, - # div_value=config.asm_div_value, - # head_bias=True, # default is False - # ) - - def build(self, input_shape): - # The output weights are the same as the input embeddings, but there is an output-only bias for each token. - self.bias = self.add_weight(shape=(self.n_words,), initializer="zeros", trainable=True, name="bias") - - super().build(input_shape) - - def get_output_embeddings(self): - return self.input_embeddings - - def set_output_embeddings(self, value): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - hidden_states = self.input_embeddings(hidden_states, mode="linear") - hidden_states = hidden_states + self.bias - - return hidden_states - - -@add_start_docstrings( - """ - The XLM Model transformer with a language modeling head on top (linear layer with weights tied to the input - embeddings). - """, - XLM_START_DOCSTRING, -) -class TFXLMWithLMHeadModel(TFXLMPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFXLMMainLayer(config, name="transformer") - self.pred_layer = TFXLMPredLayer(config, self.transformer.embeddings, name="pred_layer_._proj") - # XLM does not have past caching features - self.supports_xla_generation = False - - def get_lm_head(self): - return self.pred_layer - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.pred_layer.name - - def prepare_inputs_for_generation(self, inputs, **kwargs): - mask_token_id = self.config.mask_token_id - lang_id = self.config.lang_id - - effective_batch_size = inputs.shape[0] - mask_token = tf.fill((effective_batch_size, 1), 1) * mask_token_id - inputs = tf.concat([inputs, mask_token], axis=1) - - if lang_id is not None: - langs = tf.ones_like(inputs) * lang_id - else: - langs = None - return {"input_ids": inputs, "langs": langs} - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFXLMWithLMHeadModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFXLMWithLMHeadModelOutput | tuple[tf.Tensor]: - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - langs=langs, - token_type_ids=token_type_ids, - position_ids=position_ids, - lengths=lengths, - cache=cache, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - output = transformer_outputs[0] - outputs = self.pred_layer(output) - - if not return_dict: - return (outputs,) + transformer_outputs[1:] - - return TFXLMWithLMHeadModelOutput( - logits=outputs, hidden_states=transformer_outputs.hidden_states, attentions=transformer_outputs.attentions - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "pred_layer", None) is not None: - with tf.name_scope(self.pred_layer.name): - self.pred_layer.build(None) - - -@add_start_docstrings( - """ - XLM Model with a sequence classification/regression head on top (a linear layer on top of the pooled output) e.g. - for GLUE tasks. - """, - XLM_START_DOCSTRING, -) -class TFXLMForSequenceClassification(TFXLMPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.transformer = TFXLMMainLayer(config, name="transformer") - self.sequence_summary = TFSequenceSummary(config, initializer_range=config.init_std, name="sequence_summary") - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - langs=langs, - token_type_ids=token_type_ids, - position_ids=position_ids, - lengths=lengths, - cache=cache, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - output = transformer_outputs[0] - - logits = self.sequence_summary(output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "sequence_summary", None) is not None: - with tf.name_scope(self.sequence_summary.name): - self.sequence_summary.build(None) - - -@add_start_docstrings( - """ - XLM Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - XLM_START_DOCSTRING, -) -class TFXLMForMultipleChoice(TFXLMPreTrainedModel, TFMultipleChoiceLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.transformer = TFXLMMainLayer(config, name="transformer") - self.sequence_summary = TFSequenceSummary(config, initializer_range=config.init_std, name="sequence_summary") - self.logits_proj = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="logits_proj" - ) - self.config = config - - @property - def dummy_inputs(self): - """ - Dummy inputs to build the network. - - Returns: - tf.Tensor with dummy inputs - """ - # Sometimes XLM has language embeddings so don't forget to build them as well if needed - if self.config.use_lang_emb and self.config.n_langs > 1: - return { - "input_ids": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32), - "langs": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32), - } - else: - return { - "input_ids": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32), - } - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - flat_langs = tf.reshape(langs, (-1, seq_length)) if langs is not None else None - flat_inputs_embeds = ( - tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - - if lengths is not None: - logger.warning( - "The `lengths` parameter cannot be used with the XLM multiple choice models. Please use the " - "attention mask instead.", - ) - lengths = None - - transformer_outputs = self.transformer( - flat_input_ids, - flat_attention_mask, - flat_langs, - flat_token_type_ids, - flat_position_ids, - lengths, - cache, - head_mask, - flat_inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - output = transformer_outputs[0] - logits = self.sequence_summary(output) - logits = self.logits_proj(logits) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "sequence_summary", None) is not None: - with tf.name_scope(self.sequence_summary.name): - self.sequence_summary.build(None) - if getattr(self, "logits_proj", None) is not None: - with tf.name_scope(self.logits_proj.name): - self.logits_proj.build([None, None, self.config.num_labels]) - - -@add_start_docstrings( - """ - XLM Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - XLM_START_DOCSTRING, -) -class TFXLMForTokenClassification(TFXLMPreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.transformer = TFXLMMainLayer(config, name="transformer") - self.dropout = keras.layers.Dropout(config.dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.init_std), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - langs=langs, - token_type_ids=token_type_ids, - position_ids=position_ids, - lengths=lengths, - cache=cache, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = transformer_outputs[0] - - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - XLM Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear layer - on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - XLM_START_DOCSTRING, -) -class TFXLMForQuestionAnsweringSimple(TFXLMPreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFXLMMainLayer(config, name="transformer") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.init_std), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - langs: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - lengths: np.ndarray | tf.Tensor | None = None, - cache: dict[str, tf.Tensor] | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - langs=langs, - token_type_ids=token_type_ids, - position_ids=position_ids, - lengths=lengths, - cache=cache, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = transformer_outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFXLMForMultipleChoice", - "TFXLMForQuestionAnsweringSimple", - "TFXLMForSequenceClassification", - "TFXLMForTokenClassification", - "TFXLMMainLayer", - "TFXLMModel", - "TFXLMPreTrainedModel", - "TFXLMWithLMHeadModel", -] diff --git a/src/transformers/models/xlm/modeling_xlm.py b/src/transformers/models/xlm/modeling_xlm.py index a73b4a51cea4..fafdd770ce12 100755 --- a/src/transformers/models/xlm/modeling_xlm.py +++ b/src/transformers/models/xlm/modeling_xlm.py @@ -619,7 +619,6 @@ def ff_chunk(self, input): @auto_docstring class XLMPreTrainedModel(PreTrainedModel): config: XLMConfig - load_tf_weights = None base_model_prefix = "transformer" def __init__(self, *inputs, **kwargs): diff --git a/src/transformers/models/xlm_roberta/__init__.py b/src/transformers/models/xlm_roberta/__init__.py index 0e684c6c9b2c..1706e6dbefae 100644 --- a/src/transformers/models/xlm_roberta/__init__.py +++ b/src/transformers/models/xlm_roberta/__init__.py @@ -19,8 +19,6 @@ if TYPE_CHECKING: from .configuration_xlm_roberta import * - from .modeling_flax_xlm_roberta import * - from .modeling_tf_xlm_roberta import * from .modeling_xlm_roberta import * from .tokenization_xlm_roberta import * from .tokenization_xlm_roberta_fast import * diff --git a/src/transformers/models/xlm_roberta/modeling_flax_xlm_roberta.py b/src/transformers/models/xlm_roberta/modeling_flax_xlm_roberta.py deleted file mode 100644 index bdbc06620a1b..000000000000 --- a/src/transformers/models/xlm_roberta/modeling_flax_xlm_roberta.py +++ /dev/null @@ -1,1511 +0,0 @@ -# coding=utf-8 -# Copyright 2022 Facebook AI Research and the HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""Flax XLM-RoBERTa model.""" - -from typing import Callable, Optional - -import flax.linen as nn -import jax -import jax.numpy as jnp -import numpy as np -from flax.core.frozen_dict import FrozenDict, freeze, unfreeze -from flax.linen import combine_masks, make_causal_mask -from flax.linen import partitioning as nn_partitioning -from flax.linen.attention import dot_product_attention_weights -from flax.traverse_util import flatten_dict, unflatten_dict -from jax import lax - -from ...modeling_flax_outputs import ( - FlaxBaseModelOutputWithPastAndCrossAttentions, - FlaxBaseModelOutputWithPooling, - FlaxBaseModelOutputWithPoolingAndCrossAttentions, - FlaxCausalLMOutputWithCrossAttentions, - FlaxMaskedLMOutput, - FlaxMultipleChoiceModelOutput, - FlaxQuestionAnsweringModelOutput, - FlaxSequenceClassifierOutput, - FlaxTokenClassifierOutput, -) -from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring, overwrite_call_docstring -from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging -from .configuration_xlm_roberta import XLMRobertaConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "FacebookAI/xlm-roberta-base" -_CONFIG_FOR_DOC = "XLMRobertaConfig" - -remat = nn_partitioning.remat - - -# Copied from transformers.models.roberta.modeling_flax_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - input_ids: jnp.ndarray - padding_idx: int - - Returns: jnp.ndarray - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = (input_ids != padding_idx).astype("i4") - - if mask.ndim > 2: - mask = mask.reshape((-1, mask.shape[-1])) - incremental_indices = jnp.cumsum(mask, axis=1).astype("i4") * mask - incremental_indices = incremental_indices.reshape(input_ids.shape) - else: - incremental_indices = jnp.cumsum(mask, axis=1).astype("i4") * mask - - return incremental_indices.astype("i4") + padding_idx - - -XLM_ROBERTA_START_DOCSTRING = r""" - - This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading, saving and converting weights from PyTorch models) - - This model is also a - [flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) subclass. Use it as - a regular Flax linen Module and refer to the Flax documentation for all matter related to general usage and - behavior. - - Finally, this model supports inherent JAX features such as: - - - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) - - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) - - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) - - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) - - Parameters: - config ([`XLMRobertaConfig`]): Model configuration class with all the parameters of the - model. Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. -""" - -XLM_ROBERTA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`numpy.ndarray` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`numpy.ndarray` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. - head_mask (`numpy.ndarray` of shape `({0})`, `optional): - Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEmbeddings with Bert->XLMRoberta -class FlaxXLMRobertaEmbeddings(nn.Module): - """Construct the embeddings from word, position and token_type embeddings.""" - - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.word_embeddings = nn.Embed( - self.config.vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.position_embeddings = nn.Embed( - self.config.max_position_embeddings, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.token_type_embeddings = nn.Embed( - self.config.type_vocab_size, - self.config.hidden_size, - embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, input_ids, token_type_ids, position_ids, attention_mask, deterministic: bool = True): - # Embed - inputs_embeds = self.word_embeddings(input_ids.astype("i4")) - position_embeds = self.position_embeddings(position_ids.astype("i4")) - token_type_embeddings = self.token_type_embeddings(token_type_ids.astype("i4")) - - # Sum all embeddings - hidden_states = inputs_embeds + token_type_embeddings + position_embeds - - # Layer Norm - hidden_states = self.LayerNorm(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfAttention with Bert->XLMRoberta -class FlaxXLMRobertaSelfAttention(nn.Module): - config: XLMRobertaConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.head_dim = self.config.hidden_size // self.config.num_attention_heads - if self.config.hidden_size % self.config.num_attention_heads != 0: - raise ValueError( - "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads` " - " : {self.config.num_attention_heads}" - ) - - self.query = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.key = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.value = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - if self.causal: - self.causal_mask = make_causal_mask( - jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" - ) - - def _split_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.num_attention_heads, self.head_dim)) - - def _merge_heads(self, hidden_states): - return hidden_states.reshape(hidden_states.shape[:2] + (self.config.hidden_size,)) - - @nn.compact - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention._concatenate_to_cache - def _concatenate_to_cache(self, key, value, query, attention_mask): - """ - This function takes projected key, value states from a single input token and concatenates the states to cached - states from previous steps. This function is slightly adapted from the official Flax repository: - https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 - """ - # detect if we're initializing by absence of existing cache data. - is_initialized = self.has_variable("cache", "cached_key") - cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) - cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) - cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) - - if is_initialized: - *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape - # update key, value caches with our new 1d spatial slices - cur_index = cache_index.value - indices = (0,) * len(batch_dims) + (cur_index, 0, 0) - key = lax.dynamic_update_slice(cached_key.value, key, indices) - value = lax.dynamic_update_slice(cached_value.value, value, indices) - cached_key.value = key - cached_value.value = value - num_updated_cache_vectors = query.shape[1] - cache_index.value = cache_index.value + num_updated_cache_vectors - # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. - pad_mask = jnp.broadcast_to( - jnp.arange(max_length) < cur_index + num_updated_cache_vectors, - tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), - ) - attention_mask = combine_masks(pad_mask, attention_mask) - return key, value, attention_mask - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic=True, - output_attentions: bool = False, - ): - # if key_value_states are provided this layer is used as a cross-attention layer - # for the decoder - is_cross_attention = key_value_states is not None - batch_size = hidden_states.shape[0] - - # get query proj - query_states = self.query(hidden_states) - # get key, value proj - if is_cross_attention: - # cross_attentions - key_states = self.key(key_value_states) - value_states = self.value(key_value_states) - else: - # self_attention - key_states = self.key(hidden_states) - value_states = self.value(hidden_states) - - query_states = self._split_heads(query_states) - key_states = self._split_heads(key_states) - value_states = self._split_heads(value_states) - - # handle cache prepare causal attention mask - if self.causal: - query_length, key_length = query_states.shape[1], key_states.shape[1] - if self.has_variable("cache", "cached_key"): - mask_shift = self.variables["cache"]["cache_index"] - max_decoder_length = self.variables["cache"]["cached_key"].shape[1] - causal_mask = lax.dynamic_slice( - self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) - ) - else: - causal_mask = self.causal_mask[:, :, :query_length, :key_length] - causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) - - # combine masks if needed - if attention_mask is not None and self.causal: - attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) - attention_mask = combine_masks(attention_mask, causal_mask) - elif self.causal: - attention_mask = causal_mask - elif attention_mask is not None: - attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) - - # During fast autoregressive decoding, we feed one position at a time, - # and cache the keys and values step by step. - if self.causal and (self.has_variable("cache", "cached_key") or init_cache): - key_states, value_states, attention_mask = self._concatenate_to_cache( - key_states, value_states, query_states, attention_mask - ) - - # Convert the boolean attention mask to an attention bias. - if attention_mask is not None: - # attention mask in the form of attention bias - attention_bias = lax.select( - attention_mask > 0, - jnp.full(attention_mask.shape, 0.0).astype(self.dtype), - jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), - ) - else: - attention_bias = None - - dropout_rng = None - if not deterministic and self.config.attention_probs_dropout_prob > 0.0: - dropout_rng = self.make_rng("dropout") - - attn_weights = dot_product_attention_weights( - query_states, - key_states, - bias=attention_bias, - dropout_rng=dropout_rng, - dropout_rate=self.config.attention_probs_dropout_prob, - broadcast_dropout=True, - deterministic=deterministic, - dtype=self.dtype, - precision=None, - ) - - # Mask heads if we want to - if layer_head_mask is not None: - attn_weights = jnp.einsum("...hqk,h->...hqk", attn_weights, layer_head_mask) - - attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) - attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) - - outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfOutput with Bert->XLMRoberta -class FlaxXLMRobertaSelfOutput(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - - def __call__(self, hidden_states, input_tensor, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + input_tensor) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertAttention with Bert->XLMRoberta -class FlaxXLMRobertaAttention(nn.Module): - config: XLMRobertaConfig - causal: bool = False - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.self = FlaxXLMRobertaSelfAttention(self.config, causal=self.causal, dtype=self.dtype) - self.output = FlaxXLMRobertaSelfOutput(self.config, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - key_value_states=None, - init_cache=False, - deterministic=True, - output_attentions: bool = False, - ): - # Attention mask comes in as attention_mask.shape == (*batch_sizes, kv_length) - # FLAX expects: attention_mask.shape == (*batch_sizes, 1, 1, kv_length) such that it is broadcastable - # with attn_weights.shape == (*batch_sizes, num_heads, q_length, kv_length) - attn_outputs = self.self( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=key_value_states, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attn_output = attn_outputs[0] - hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attn_outputs[1],) - - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertIntermediate with Bert->XLMRoberta -class FlaxXLMRobertaIntermediate(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.intermediate_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.activation = ACT2FN[self.config.hidden_act] - - def __call__(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.activation(hidden_states) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertOutput with Bert->XLMRoberta -class FlaxXLMRobertaOutput(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - - def __call__(self, hidden_states, attention_output, deterministic: bool = True): - hidden_states = self.dense(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.LayerNorm(hidden_states + attention_output) - return hidden_states - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayer with Bert->XLMRoberta -class FlaxXLMRobertaLayer(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.attention = FlaxXLMRobertaAttention(self.config, causal=self.config.is_decoder, dtype=self.dtype) - self.intermediate = FlaxXLMRobertaIntermediate(self.config, dtype=self.dtype) - self.output = FlaxXLMRobertaOutput(self.config, dtype=self.dtype) - if self.config.add_cross_attention: - self.crossattention = FlaxXLMRobertaAttention(self.config, causal=False, dtype=self.dtype) - - def __call__( - self, - hidden_states, - attention_mask, - layer_head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - ): - # Self Attention - attention_outputs = self.attention( - hidden_states, - attention_mask, - layer_head_mask=layer_head_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = attention_outputs[0] - - # Cross-Attention Block - if encoder_hidden_states is not None: - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - layer_head_mask=layer_head_mask, - key_value_states=encoder_hidden_states, - deterministic=deterministic, - output_attentions=output_attentions, - ) - attention_output = cross_attention_outputs[0] - - hidden_states = self.intermediate(attention_output) - hidden_states = self.output(hidden_states, attention_output, deterministic=deterministic) - - outputs = (hidden_states,) - - if output_attentions: - outputs += (attention_outputs[1],) - if encoder_hidden_states is not None: - outputs += (cross_attention_outputs[1],) - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayerCollection with Bert->XLMRoberta -class FlaxXLMRobertaLayerCollection(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - if self.gradient_checkpointing: - FlaxXLMRobertaCheckpointLayer = remat(FlaxXLMRobertaLayer, static_argnums=(5, 6, 7)) - self.layers = [ - FlaxXLMRobertaCheckpointLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - else: - self.layers = [ - FlaxXLMRobertaLayer(self.config, name=str(i), dtype=self.dtype) - for i in range(self.config.num_hidden_layers) - ] - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - all_attentions = () if output_attentions else None - all_hidden_states = () if output_hidden_states else None - all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None - - # Check if head_mask has a correct number of layers specified if desired - if head_mask is not None: - if head_mask.shape[0] != (len(self.layers)): - raise ValueError( - f"The head_mask should be specified for {len(self.layers)} layers, but it is for " - f" {head_mask.shape[0]}." - ) - - for i, layer in enumerate(self.layers): - if output_hidden_states: - all_hidden_states += (hidden_states,) - - layer_outputs = layer( - hidden_states, - attention_mask, - head_mask[i] if head_mask is not None else None, - encoder_hidden_states, - encoder_attention_mask, - init_cache, - deterministic, - output_attentions, - ) - - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions += (layer_outputs[1],) - - if encoder_hidden_states is not None: - all_cross_attentions += (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states += (hidden_states,) - - outputs = (hidden_states, all_hidden_states, all_attentions, all_cross_attentions) - - if not return_dict: - return tuple(v for v in outputs if v is not None) - - return FlaxBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEncoder with Bert->XLMRoberta -class FlaxXLMRobertaEncoder(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - gradient_checkpointing: bool = False - - def setup(self): - self.layer = FlaxXLMRobertaLayerCollection( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - - def __call__( - self, - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - return self.layer( - hidden_states, - attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPooler with Bert->XLMRoberta -class FlaxXLMRobertaPooler(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - dtype=self.dtype, - ) - - def __call__(self, hidden_states): - cls_hidden_state = hidden_states[:, 0] - cls_hidden_state = self.dense(cls_hidden_state) - return nn.tanh(cls_hidden_state) - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaLMHead with Roberta->XLMRoberta -class FlaxXLMRobertaLMHead(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 - bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) - self.decoder = nn.Dense( - self.config.vocab_size, - dtype=self.dtype, - use_bias=False, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) - - def __call__(self, hidden_states, shared_embedding=None): - hidden_states = self.dense(hidden_states) - hidden_states = ACT2FN["gelu"](hidden_states) - hidden_states = self.layer_norm(hidden_states) - - if shared_embedding is not None: - hidden_states = self.decoder.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) - else: - hidden_states = self.decoder(hidden_states) - - bias = jnp.asarray(self.bias, self.dtype) - hidden_states += bias - return hidden_states - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaClassificationHead with Roberta->XLMRoberta -class FlaxXLMRobertaClassificationHead(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 - - def setup(self): - self.dense = nn.Dense( - self.config.hidden_size, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.out_proj = nn.Dense( - self.config.num_labels, - dtype=self.dtype, - kernel_init=jax.nn.initializers.normal(self.config.initializer_range), - ) - - def __call__(self, hidden_states, deterministic=True): - hidden_states = hidden_states[:, 0, :] # take token (equiv. to [CLS]) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.dense(hidden_states) - hidden_states = nn.tanh(hidden_states) - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - hidden_states = self.out_proj(hidden_states) - return hidden_states - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaPreTrainedModel with Roberta->XLMRoberta, roberta->xlm-roberta, ROBERTA->XLM_ROBERTA -class FlaxXLMRobertaPreTrainedModel(FlaxPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = XLMRobertaConfig - base_model_prefix = "xlm-roberta" - - module_class: nn.Module = None - - def __init__( - self, - config: XLMRobertaConfig, - input_shape: tuple = (1, 1), - seed: int = 0, - dtype: jnp.dtype = jnp.float32, - _do_init: bool = True, - gradient_checkpointing: bool = False, - **kwargs, - ): - module = self.module_class(config=config, dtype=dtype, gradient_checkpointing=gradient_checkpointing, **kwargs) - super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) - - # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPreTrainedModel.enable_gradient_checkpointing - def enable_gradient_checkpointing(self): - self._module = self.module_class( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=True, - ) - - def init_weights(self, rng: jax.random.PRNGKey, input_shape: tuple, params: FrozenDict = None) -> FrozenDict: - # init input tensors - input_ids = jnp.zeros(input_shape, dtype="i4") - token_type_ids = jnp.ones_like(input_ids) - position_ids = create_position_ids_from_input_ids(input_ids, self.config.pad_token_id) - attention_mask = jnp.ones_like(input_ids) - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - params_rng, dropout_rng = jax.random.split(rng) - rngs = {"params": params_rng, "dropout": dropout_rng} - - if self.config.add_cross_attention: - encoder_hidden_states = jnp.zeros(input_shape + (self.config.hidden_size,)) - encoder_attention_mask = attention_mask - module_init_outputs = self.module.init( - rngs, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states, - encoder_attention_mask, - return_dict=False, - ) - else: - module_init_outputs = self.module.init( - rngs, input_ids, attention_mask, token_type_ids, position_ids, head_mask, return_dict=False - ) - - random_params = module_init_outputs["params"] - - if params is not None: - random_params = flatten_dict(unfreeze(random_params)) - params = flatten_dict(unfreeze(params)) - for missing_key in self._missing_keys: - params[missing_key] = random_params[missing_key] - self._missing_keys = set() - return freeze(unflatten_dict(params)) - else: - return random_params - - # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderPreTrainedModel.init_cache - def init_cache(self, batch_size, max_length): - r""" - Args: - batch_size (`int`): - batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. - max_length (`int`): - maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized - cache. - """ - # init input variables to retrieve cache - input_ids = jnp.ones((batch_size, max_length), dtype="i4") - attention_mask = jnp.ones_like(input_ids, dtype="i4") - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - init_variables = self.module.init( - jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True - ) - return unfreeze(init_variables["cache"]) - - @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - def __call__( - self, - input_ids, - attention_mask=None, - token_type_ids=None, - position_ids=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - params: Optional[dict] = None, - dropout_rng: jax.random.PRNGKey = None, - train: bool = False, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - past_key_values: Optional[dict] = None, - ): - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.return_dict - - # init input tensors if not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - if position_ids is None: - position_ids = create_position_ids_from_input_ids(input_ids, self.config.pad_token_id) - - if attention_mask is None: - attention_mask = jnp.ones_like(input_ids) - - if head_mask is None: - head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) - - # Handle any PRNG if needed - rngs = {} - if dropout_rng is not None: - rngs["dropout"] = dropout_rng - - inputs = {"params": params or self.params} - - if self.config.add_cross_attention: - # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed - # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be - # changed by FlaxXLMRobertaAttention module - if past_key_values: - inputs["cache"] = past_key_values - mutable = ["cache"] - else: - mutable = False - - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - mutable=mutable, - ) - - # add updated cache to model output - if past_key_values is not None and return_dict: - outputs, past_key_values = outputs - outputs["past_key_values"] = unfreeze(past_key_values["cache"]) - return outputs - elif past_key_values is not None and not return_dict: - outputs, past_key_values = outputs - outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] - - else: - outputs = self.module.apply( - inputs, - jnp.array(input_ids, dtype="i4"), - jnp.array(attention_mask, dtype="i4"), - token_type_ids=jnp.array(token_type_ids, dtype="i4"), - position_ids=jnp.array(position_ids, dtype="i4"), - head_mask=jnp.array(head_mask, dtype="i4"), - deterministic=not train, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - rngs=rngs, - ) - - return outputs - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertModule with Bert->XLMRoberta -class FlaxXLMRobertaModule(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 # the dtype of the computation - add_pooling_layer: bool = True - gradient_checkpointing: bool = False - - def setup(self): - self.embeddings = FlaxXLMRobertaEmbeddings(self.config, dtype=self.dtype) - self.encoder = FlaxXLMRobertaEncoder( - self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.pooler = FlaxXLMRobertaPooler(self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids: Optional[jnp.ndarray] = None, - position_ids: Optional[jnp.ndarray] = None, - head_mask: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # make sure `token_type_ids` is correctly initialized when not passed - if token_type_ids is None: - token_type_ids = jnp.zeros_like(input_ids) - - # make sure `position_ids` is correctly initialized when not passed - if position_ids is None: - position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) - - hidden_states = self.embeddings( - input_ids, token_type_ids, position_ids, attention_mask, deterministic=deterministic - ) - outputs = self.encoder( - hidden_states, - attention_mask, - head_mask=head_mask, - deterministic=deterministic, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - hidden_states = outputs[0] - pooled = self.pooler(hidden_states) if self.add_pooling_layer else None - - if not return_dict: - # if pooled is None, don't return it - if pooled is None: - return (hidden_states,) + outputs[1:] - return (hidden_states, pooled) + outputs[1:] - - return FlaxBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=hidden_states, - pooler_output=pooled, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - "The bare XLM RoBERTa Model transformer outputting raw hidden-states without any specific head on top.", - XLM_ROBERTA_START_DOCSTRING, -) -class FlaxXLMRobertaModel(FlaxXLMRobertaPreTrainedModel): - module_class = FlaxXLMRobertaModule - - -append_call_sample_docstring(FlaxXLMRobertaModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutputWithPooling, _CONFIG_FOR_DOC) - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForMaskedLMModule with Roberta->XLMRoberta -class FlaxXLMRobertaForMaskedLMModule(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxXLMRobertaModule( - config=self.config, - add_pooling_layer=False, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.lm_head = FlaxXLMRobertaLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.roberta.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.lm_head(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxMaskedLMOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings("""XLM RoBERTa Model with a `language modeling` head on top.""", XLM_ROBERTA_START_DOCSTRING) -class FlaxXLMRobertaForMaskedLM(FlaxXLMRobertaPreTrainedModel): - module_class = FlaxXLMRobertaForMaskedLMModule - - -append_call_sample_docstring( - FlaxXLMRobertaForMaskedLM, - _CHECKPOINT_FOR_DOC, - FlaxBaseModelOutputWithPooling, - _CONFIG_FOR_DOC, - mask="", -) - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForSequenceClassificationModule with Roberta->XLMRoberta -class FlaxXLMRobertaForSequenceClassificationModule(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxXLMRobertaModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.classifier = FlaxXLMRobertaClassificationHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - sequence_output = outputs[0] - logits = self.classifier(sequence_output, deterministic=deterministic) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxSequenceClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - XLM Roberta Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - XLM_ROBERTA_START_DOCSTRING, -) -class FlaxXLMRobertaForSequenceClassification(FlaxXLMRobertaPreTrainedModel): - module_class = FlaxXLMRobertaForSequenceClassificationModule - - -append_call_sample_docstring( - FlaxXLMRobertaForSequenceClassification, - _CHECKPOINT_FOR_DOC, - FlaxSequenceClassifierOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForMultipleChoiceModule with Bert->XLMRoberta, with self.bert->self.roberta -class FlaxXLMRobertaForMultipleChoiceModule(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxXLMRobertaModule( - config=self.config, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) - self.classifier = nn.Dense(1, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - num_choices = input_ids.shape[1] - input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None - attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None - token_type_ids = token_type_ids.reshape(-1, token_type_ids.shape[-1]) if token_type_ids is not None else None - position_ids = position_ids.reshape(-1, position_ids.shape[-1]) if position_ids is not None else None - - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, deterministic=deterministic) - logits = self.classifier(pooled_output) - - reshaped_logits = logits.reshape(-1, num_choices) - - if not return_dict: - return (reshaped_logits,) + outputs[2:] - - return FlaxMultipleChoiceModelOutput( - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - XLM Roberta Model with a multiple choice classification head on top (a linear layer on top of the pooled output and - a softmax) e.g. for RocStories/SWAG tasks. - """, - XLM_ROBERTA_START_DOCSTRING, -) -class FlaxXLMRobertaForMultipleChoice(FlaxXLMRobertaPreTrainedModel): - module_class = FlaxXLMRobertaForMultipleChoiceModule - - -overwrite_call_docstring( - FlaxXLMRobertaForMultipleChoice, XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") -) -append_call_sample_docstring( - FlaxXLMRobertaForMultipleChoice, - _CHECKPOINT_FOR_DOC, - FlaxMultipleChoiceModelOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForTokenClassificationModule with Bert->XLMRoberta, with self.bert->self.roberta -class FlaxXLMRobertaForTokenClassificationModule(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxXLMRobertaModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - classifier_dropout = ( - self.config.classifier_dropout - if self.config.classifier_dropout is not None - else self.config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(rate=classifier_dropout) - self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - hidden_states = self.dropout(hidden_states, deterministic=deterministic) - logits = self.classifier(hidden_states) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxTokenClassifierOutput( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - XLM Roberta Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. - for Named-Entity-Recognition (NER) tasks. - """, - XLM_ROBERTA_START_DOCSTRING, -) -class FlaxXLMRobertaForTokenClassification(FlaxXLMRobertaPreTrainedModel): - module_class = FlaxXLMRobertaForTokenClassificationModule - - -append_call_sample_docstring( - FlaxXLMRobertaForTokenClassification, - _CHECKPOINT_FOR_DOC, - FlaxTokenClassifierOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForQuestionAnsweringModule with Bert->XLMRoberta, with self.bert->self.roberta -class FlaxXLMRobertaForQuestionAnsweringModule(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxXLMRobertaModule( - config=self.config, - dtype=self.dtype, - add_pooling_layer=False, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - - logits = self.qa_outputs(hidden_states) - start_logits, end_logits = jnp.split(logits, self.config.num_labels, axis=-1) - start_logits = start_logits.squeeze(-1) - end_logits = end_logits.squeeze(-1) - - if not return_dict: - return (start_logits, end_logits) + outputs[1:] - - return FlaxQuestionAnsweringModelOutput( - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - -@add_start_docstrings( - """ - XLM Roberta Model with a span classification head on top for extractive question-answering tasks like SQuAD (a - linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - XLM_ROBERTA_START_DOCSTRING, -) -class FlaxXLMRobertaForQuestionAnswering(FlaxXLMRobertaPreTrainedModel): - module_class = FlaxXLMRobertaForQuestionAnsweringModule - - -append_call_sample_docstring( - FlaxXLMRobertaForQuestionAnswering, - _CHECKPOINT_FOR_DOC, - FlaxQuestionAnsweringModelOutput, - _CONFIG_FOR_DOC, -) - - -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForCausalLMModule with Roberta->XLMRoberta -class FlaxXLMRobertaForCausalLMModule(nn.Module): - config: XLMRobertaConfig - dtype: jnp.dtype = jnp.float32 - gradient_checkpointing: bool = False - - def setup(self): - self.roberta = FlaxXLMRobertaModule( - config=self.config, - add_pooling_layer=False, - dtype=self.dtype, - gradient_checkpointing=self.gradient_checkpointing, - ) - self.lm_head = FlaxXLMRobertaLMHead(config=self.config, dtype=self.dtype) - - def __call__( - self, - input_ids, - attention_mask, - position_ids, - token_type_ids: Optional[jnp.ndarray] = None, - head_mask: Optional[jnp.ndarray] = None, - encoder_hidden_states: Optional[jnp.ndarray] = None, - encoder_attention_mask: Optional[jnp.ndarray] = None, - init_cache: bool = False, - deterministic: bool = True, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, - ): - # Model - outputs = self.roberta( - input_ids, - attention_mask, - token_type_ids, - position_ids, - head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - init_cache=init_cache, - deterministic=deterministic, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - ) - - hidden_states = outputs[0] - if self.config.tie_word_embeddings: - shared_embedding = self.roberta.variables["params"]["embeddings"]["word_embeddings"]["embedding"] - else: - shared_embedding = None - - # Compute the prediction scores - logits = self.lm_head(hidden_states, shared_embedding=shared_embedding) - - if not return_dict: - return (logits,) + outputs[1:] - - return FlaxCausalLMOutputWithCrossAttentions( - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - -@add_start_docstrings( - """ - XLM Roberta Model with a language modeling head on top (a linear layer on top of the hidden-states output) e.g for - autoregressive tasks. - """, - XLM_ROBERTA_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForCausalLM with Roberta->XLMRoberta -class FlaxXLMRobertaForCausalLM(FlaxXLMRobertaPreTrainedModel): - module_class = FlaxXLMRobertaForCausalLMModule - - def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jax.Array] = None): - # initializing the cache - batch_size, seq_length = input_ids.shape - - past_key_values = self.init_cache(batch_size, max_length) - # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. - # But since the decoder uses a causal mask, those positions are masked anyway. - # Thus, we can create a single static attention_mask here, which is more efficient for compilation - extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") - if attention_mask is not None: - position_ids = attention_mask.cumsum(axis=-1) - 1 - extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) - else: - position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) - - return { - "past_key_values": past_key_values, - "attention_mask": extended_attention_mask, - "position_ids": position_ids, - } - - def update_inputs_for_generation(self, model_outputs, model_kwargs): - model_kwargs["past_key_values"] = model_outputs.past_key_values - model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 - return model_kwargs - - -append_call_sample_docstring( - FlaxXLMRobertaForCausalLM, - _CHECKPOINT_FOR_DOC, - FlaxCausalLMOutputWithCrossAttentions, - _CONFIG_FOR_DOC, -) - - -__all__ = [ - "FlaxXLMRobertaForMaskedLM", - "FlaxXLMRobertaForCausalLM", - "FlaxXLMRobertaForMultipleChoice", - "FlaxXLMRobertaForQuestionAnswering", - "FlaxXLMRobertaForSequenceClassification", - "FlaxXLMRobertaForTokenClassification", - "FlaxXLMRobertaModel", - "FlaxXLMRobertaPreTrainedModel", -] diff --git a/src/transformers/models/xlm_roberta/modeling_tf_xlm_roberta.py b/src/transformers/models/xlm_roberta/modeling_tf_xlm_roberta.py deleted file mode 100644 index 0def1bfdb00d..000000000000 --- a/src/transformers/models/xlm_roberta/modeling_tf_xlm_roberta.py +++ /dev/null @@ -1,1790 +0,0 @@ -# coding=utf-8 -# Copyright 2019 Facebook AI Research and the HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -"""TF 2.0 XLM-RoBERTa model.""" - -from __future__ import annotations - -import math -import warnings - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_outputs import ( - TFBaseModelOutputWithPastAndCrossAttentions, - TFBaseModelOutputWithPoolingAndCrossAttentions, - TFCausalLMOutputWithCrossAttentions, - TFMaskedLMOutput, - TFMultipleChoiceModelOutput, - TFQuestionAnsweringModelOutput, - TFSequenceClassifierOutput, - TFTokenClassifierOutput, -) -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFMaskedLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, -) -from .configuration_xlm_roberta import XLMRobertaConfig - - -logger = logging.get_logger(__name__) - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "FacebookAI/xlm-roberta-base" -_CONFIG_FOR_DOC = "XLMRobertaConfig" - - -XLM_ROBERTA_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`XLMRobertaConfig`]): Model configuration class with all the parameters of the - model. Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -XLM_ROBERTA_INPUTS_DOCSTRING = r""" - Args: - input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. Indices can be obtained using [`AutoTokenizer`]. See - [`PreTrainedTokenizer.__call__`] and [`PreTrainedTokenizer.encode`] for details. [What are input - IDs?](../glossary#input-ids) - attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - [What are attention masks?](../glossary#attention-mask) - token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - [What are token type IDs?](../glossary#token-type-ids) - position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): - Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, - config.max_position_embeddings - 1]`. [What are position IDs?](../glossary#position-ids) - head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the - config will be used instead. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. This argument can be used only in eager mode, in graph mode the value in the config will be - used instead. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in - eager mode, in graph mode the value will always be set to True. - training (`bool`, *optional*, defaults to `False`): - Whether or not to use the model in training mode (some modules like dropout modules have different - behaviors between training and evaluation). -""" - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaEmbeddings with Roberta->XLMRoberta -class TFXLMRobertaEmbeddings(keras.layers.Layer): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.padding_idx = 1 - self.config = config - self.hidden_size = config.hidden_size - self.max_position_embeddings = config.max_position_embeddings - self.initializer_range = config.initializer_range - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - - def build(self, input_shape=None): - with tf.name_scope("word_embeddings"): - self.weight = self.add_weight( - name="weight", - shape=[self.config.vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("token_type_embeddings"): - self.token_type_embeddings = self.add_weight( - name="embeddings", - shape=[self.config.type_vocab_size, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - with tf.name_scope("position_embeddings"): - self.position_embeddings = self.add_weight( - name="embeddings", - shape=[self.max_position_embeddings, self.hidden_size], - initializer=get_initializer(self.initializer_range), - ) - - if self.built: - return - self.built = True - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - def create_position_ids_from_input_ids(self, input_ids, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding - symbols are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - input_ids: tf.Tensor - Returns: tf.Tensor - """ - mask = tf.cast(tf.math.not_equal(input_ids, self.padding_idx), dtype=input_ids.dtype) - incremental_indices = (tf.math.cumsum(mask, axis=1) + past_key_values_length) * mask - - return incremental_indices + self.padding_idx - - def call( - self, - input_ids=None, - position_ids=None, - token_type_ids=None, - inputs_embeds=None, - past_key_values_length=0, - training=False, - ): - """ - Applies embedding based on inputs tensor. - - Returns: - final_embeddings (`tf.Tensor`): output embedding tensor. - """ - assert not (input_ids is None and inputs_embeds is None) - - if input_ids is not None: - check_embeddings_within_bounds(input_ids, self.config.vocab_size) - inputs_embeds = tf.gather(params=self.weight, indices=input_ids) - - input_shape = shape_list(inputs_embeds)[:-1] - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - if position_ids is None: - if input_ids is not None: - # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = self.create_position_ids_from_input_ids( - input_ids=input_ids, past_key_values_length=past_key_values_length - ) - else: - position_ids = tf.expand_dims( - tf.range(start=self.padding_idx + 1, limit=input_shape[-1] + self.padding_idx + 1), axis=0 - ) - - position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) - token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) - final_embeddings = inputs_embeds + position_embeds + token_type_embeds - final_embeddings = self.LayerNorm(inputs=final_embeddings) - final_embeddings = self.dropout(inputs=final_embeddings, training=training) - - return final_embeddings - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->XLMRoberta -class TFXLMRobertaPooler(keras.layers.Layer): - def __init__(self, config: XLMRobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(inputs=first_token_tensor) - - return pooled_output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention with Bert->XLMRoberta -class TFXLMRobertaSelfAttention(keras.layers.Layer): - def __init__(self, config: XLMRobertaConfig, **kwargs): - super().__init__(**kwargs) - - if config.hidden_size % config.num_attention_heads != 0: - raise ValueError( - f"The hidden size ({config.hidden_size}) is not a multiple of the number " - f"of attention heads ({config.num_attention_heads})" - ) - - self.num_attention_heads = config.num_attention_heads - self.attention_head_size = int(config.hidden_size / config.num_attention_heads) - self.all_head_size = self.num_attention_heads * self.attention_head_size - self.sqrt_att_head_size = math.sqrt(self.attention_head_size) - - self.query = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" - ) - self.key = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" - ) - self.value = keras.layers.Dense( - units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" - ) - self.dropout = keras.layers.Dropout(rate=config.attention_probs_dropout_prob) - - self.is_decoder = config.is_decoder - self.config = config - - def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: - # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] - tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) - - # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] - return tf.transpose(tensor, perm=[0, 2, 1, 3]) - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - batch_size = shape_list(hidden_states)[0] - mixed_query_layer = self.query(inputs=hidden_states) - - # If this is instantiated as a cross-attention module, the keys - # and values come from an encoder; the attention mask needs to be - # such that the encoder's padding tokens are not attended to. - is_cross_attention = encoder_hidden_states is not None - - if is_cross_attention and past_key_value is not None: - # reuse k,v, cross_attentions - key_layer = past_key_value[0] - value_layer = past_key_value[1] - attention_mask = encoder_attention_mask - elif is_cross_attention: - key_layer = self.transpose_for_scores(self.key(inputs=encoder_hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=encoder_hidden_states), batch_size) - attention_mask = encoder_attention_mask - elif past_key_value is not None: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - key_layer = tf.concat([past_key_value[0], key_layer], axis=2) - value_layer = tf.concat([past_key_value[1], value_layer], axis=2) - else: - key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) - value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) - - query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) - - if self.is_decoder: - # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. - # Further calls to cross_attention layer can then reuse all cross-attention - # key/value_states (first "if" case) - # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of - # all previous decoder key/value_states. Further calls to uni-directional self-attention - # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) - # if encoder bi-directional self-attention `past_key_value` is always `None` - past_key_value = (key_layer, value_layer) - - # Take the dot product between "query" and "key" to get the raw attention scores. - # (batch size, num_heads, seq_len_q, seq_len_k) - attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) - dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) - attention_scores = tf.divide(attention_scores, dk) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in TFXLMRobertaModel call() function) - attention_scores = tf.add(attention_scores, attention_mask) - - # Normalize the attention scores to probabilities. - attention_probs = stable_softmax(logits=attention_scores, axis=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(inputs=attention_probs, training=training) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = tf.multiply(attention_probs, head_mask) - - attention_output = tf.matmul(attention_probs, value_layer) - attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) - - # (batch_size, seq_len_q, all_head_size) - attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) - outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) - - if self.is_decoder: - outputs = outputs + (past_key_value,) - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "query", None) is not None: - with tf.name_scope(self.query.name): - self.query.build([None, None, self.config.hidden_size]) - if getattr(self, "key", None) is not None: - with tf.name_scope(self.key.name): - self.key.build([None, None, self.config.hidden_size]) - if getattr(self, "value", None) is not None: - with tf.name_scope(self.value.name): - self.value.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfOutput with Bert->XLMRoberta -class TFXLMRobertaSelfOutput(keras.layers.Layer): - def __init__(self, config: XLMRobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertAttention with Bert->XLMRoberta -class TFXLMRobertaAttention(keras.layers.Layer): - def __init__(self, config: XLMRobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.self_attention = TFXLMRobertaSelfAttention(config, name="self") - self.dense_output = TFXLMRobertaSelfOutput(config, name="output") - - def prune_heads(self, heads): - raise NotImplementedError - - def call( - self, - input_tensor: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor, - encoder_attention_mask: tf.Tensor, - past_key_value: tuple[tf.Tensor], - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - self_outputs = self.self_attention( - hidden_states=input_tensor, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self.dense_output( - hidden_states=self_outputs[0], input_tensor=input_tensor, training=training - ) - # add attentions (possibly with past_key_value) if we output them - outputs = (attention_output,) + self_outputs[1:] - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "self_attention", None) is not None: - with tf.name_scope(self.self_attention.name): - self.self_attention.build(None) - if getattr(self, "dense_output", None) is not None: - with tf.name_scope(self.dense_output.name): - self.dense_output.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->XLMRoberta -class TFXLMRobertaIntermediate(keras.layers.Layer): - def __init__(self, config: XLMRobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - - if isinstance(config.hidden_act, str): - self.intermediate_act_fn = get_tf_activation(config.hidden_act) - else: - self.intermediate_act_fn = config.hidden_act - self.config = config - - def call(self, hidden_states: tf.Tensor) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.intermediate_act_fn(hidden_states) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->XLMRoberta -class TFXLMRobertaOutput(keras.layers.Layer): - def __init__(self, config: XLMRobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.dense = keras.layers.Dense( - units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.LayerNorm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") - self.dropout = keras.layers.Dropout(rate=config.hidden_dropout_prob) - self.config = config - - def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: - hidden_states = self.dense(inputs=hidden_states) - hidden_states = self.dropout(inputs=hidden_states, training=training) - hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) - - return hidden_states - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.intermediate_size]) - if getattr(self, "LayerNorm", None) is not None: - with tf.name_scope(self.LayerNorm.name): - self.LayerNorm.build([None, None, self.config.hidden_size]) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertLayer with Bert->XLMRoberta -class TFXLMRobertaLayer(keras.layers.Layer): - def __init__(self, config: XLMRobertaConfig, **kwargs): - super().__init__(**kwargs) - - self.attention = TFXLMRobertaAttention(config, name="attention") - self.is_decoder = config.is_decoder - self.add_cross_attention = config.add_cross_attention - if self.add_cross_attention: - if not self.is_decoder: - raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = TFXLMRobertaAttention(config, name="crossattention") - self.intermediate = TFXLMRobertaIntermediate(config, name="intermediate") - self.bert_output = TFXLMRobertaOutput(config, name="output") - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_value: tuple[tf.Tensor] | None, - output_attentions: bool, - training: bool = False, - ) -> tuple[tf.Tensor]: - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None - self_attention_outputs = self.attention( - input_tensor=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_value=self_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - present_key_value = self_attention_outputs[-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights - - cross_attn_present_key_value = None - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" - " by setting `config.add_cross_attention=True`" - ) - - # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple - cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None - cross_attention_outputs = self.crossattention( - input_tensor=attention_output, - attention_mask=attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=cross_attn_past_key_value, - output_attentions=output_attentions, - training=training, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights - - # add cross-attn cache to positions 3,4 of present_key_value tuple - cross_attn_present_key_value = cross_attention_outputs[-1] - present_key_value = present_key_value + cross_attn_present_key_value - - intermediate_output = self.intermediate(hidden_states=attention_output) - layer_output = self.bert_output( - hidden_states=intermediate_output, input_tensor=attention_output, training=training - ) - outputs = (layer_output,) + outputs # add attentions if we output them - - # if decoder, return the attn key/values as the last output - if self.is_decoder: - outputs = outputs + (present_key_value,) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "attention", None) is not None: - with tf.name_scope(self.attention.name): - self.attention.build(None) - if getattr(self, "intermediate", None) is not None: - with tf.name_scope(self.intermediate.name): - self.intermediate.build(None) - if getattr(self, "bert_output", None) is not None: - with tf.name_scope(self.bert_output.name): - self.bert_output.build(None) - if getattr(self, "crossattention", None) is not None: - with tf.name_scope(self.crossattention.name): - self.crossattention.build(None) - - -# Copied from transformers.models.bert.modeling_tf_bert.TFBertEncoder with Bert->XLMRoberta -class TFXLMRobertaEncoder(keras.layers.Layer): - def __init__(self, config: XLMRobertaConfig, **kwargs): - super().__init__(**kwargs) - self.config = config - self.layer = [TFXLMRobertaLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] - - def call( - self, - hidden_states: tf.Tensor, - attention_mask: tf.Tensor, - head_mask: tf.Tensor, - encoder_hidden_states: tf.Tensor | None, - encoder_attention_mask: tf.Tensor | None, - past_key_values: tuple[tuple[tf.Tensor]] | None, - use_cache: bool | None, - output_attentions: bool, - output_hidden_states: bool, - return_dict: bool, - training: bool = False, - ) -> TFBaseModelOutputWithPastAndCrossAttentions | tuple[tf.Tensor]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - next_decoder_cache = () if use_cache else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - past_key_value = past_key_values[i] if past_key_values is not None else None - - layer_outputs = layer_module( - hidden_states=hidden_states, - attention_mask=attention_mask, - head_mask=head_mask[i], - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_value=past_key_value, - output_attentions=output_attentions, - training=training, - ) - hidden_states = layer_outputs[0] - - if use_cache: - next_decoder_cache += (layer_outputs[-1],) - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - if self.config.add_cross_attention and encoder_hidden_states is not None: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v for v in [hidden_states, all_hidden_states, all_attentions, all_cross_attentions] if v is not None - ) - - return TFBaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=next_decoder_cache, - hidden_states=all_hidden_states, - attentions=all_attentions, - cross_attentions=all_cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - -@keras_serializable -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaMainLayer with Roberta->XLMRoberta -class TFXLMRobertaMainLayer(keras.layers.Layer): - config_class = XLMRobertaConfig - - def __init__(self, config, add_pooling_layer=True, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.is_decoder = config.is_decoder - - self.num_hidden_layers = config.num_hidden_layers - self.initializer_range = config.initializer_range - self.output_attentions = config.output_attentions - self.output_hidden_states = config.output_hidden_states - self.return_dict = config.use_return_dict - self.encoder = TFXLMRobertaEncoder(config, name="encoder") - self.pooler = TFXLMRobertaPooler(config, name="pooler") if add_pooling_layer else None - # The embeddings must be the last declaration in order to follow the weights order - self.embeddings = TFXLMRobertaEmbeddings(config, name="embeddings") - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.get_input_embeddings - def get_input_embeddings(self) -> keras.layers.Layer: - return self.embeddings - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.set_input_embeddings - def set_input_embeddings(self, value: tf.Variable): - self.embeddings.weight = value - self.embeddings.vocab_size = shape_list(value)[0] - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer._prune_heads - def _prune_heads(self, heads_to_prune): - """ - Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base - class PreTrainedModel - """ - raise NotImplementedError - - @unpack_inputs - # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.call - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFBaseModelOutputWithPoolingAndCrossAttentions | tuple[tf.Tensor]: - if not self.config.is_decoder: - use_cache = False - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_shape = shape_list(input_ids) - elif inputs_embeds is not None: - input_shape = shape_list(inputs_embeds)[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - - if past_key_values is None: - past_key_values_length = 0 - past_key_values = [None] * len(self.encoder.layer) - else: - past_key_values_length = shape_list(past_key_values[0][0])[-2] - - if attention_mask is None: - attention_mask = tf.fill(dims=(batch_size, seq_length + past_key_values_length), value=1) - - if token_type_ids is None: - token_type_ids = tf.fill(dims=input_shape, value=0) - - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - training=training, - ) - - # We create a 3D attention mask from a 2D tensor mask. - # Sizes are [batch_size, 1, 1, to_seq_length] - # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] - # this attention mask is more simple than the triangular masking of causal attention - # used in OpenAI GPT, we just need to prepare the broadcast dimension here. - attention_mask_shape = shape_list(attention_mask) - - mask_seq_length = seq_length + past_key_values_length - # Copied from `modeling_tf_t5.py` - # Provided a padding mask of dimensions [batch_size, mask_seq_length] - # - if the model is a decoder, apply a causal mask in addition to the padding mask - # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - if self.is_decoder: - seq_ids = tf.range(mask_seq_length) - causal_mask = tf.less_equal( - tf.tile(seq_ids[None, None, :], (batch_size, mask_seq_length, 1)), - seq_ids[None, :, None], - ) - causal_mask = tf.cast(causal_mask, dtype=attention_mask.dtype) - extended_attention_mask = causal_mask * attention_mask[:, None, :] - attention_mask_shape = shape_list(extended_attention_mask) - extended_attention_mask = tf.reshape( - extended_attention_mask, (attention_mask_shape[0], 1, attention_mask_shape[1], attention_mask_shape[2]) - ) - if past_key_values[0] is not None: - # attention_mask needs to be sliced to the shape `[batch_size, 1, from_seq_length - cached_seq_length, to_seq_length] - extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :] - else: - extended_attention_mask = tf.reshape( - attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1]) - ) - - # Since attention_mask is 1.0 for positions we want to attend and 0.0 for - # masked positions, this operation will create a tensor which is 0.0 for - # positions we want to attend and -10000.0 for masked positions. - # Since we are adding it to the raw scores before the softmax, this is - # effectively the same as removing these entirely. - extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) - one_cst = tf.constant(1.0, dtype=embedding_output.dtype) - ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) - extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) - - # Copied from `modeling_tf_t5.py` with -1e9 -> -10000 - if self.is_decoder and encoder_attention_mask is not None: - # If a 2D ou 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=extended_attention_mask.dtype) - num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) - if num_dims_encoder_attention_mask == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if num_dims_encoder_attention_mask == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, - # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) - - encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -10000.0 - else: - encoder_extended_attention_mask = None - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.config.num_hidden_layers - - encoder_outputs = self.encoder( - hidden_states=embedding_output, - attention_mask=extended_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = encoder_outputs[0] - pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None - - if not return_dict: - return ( - sequence_output, - pooled_output, - ) + encoder_outputs[1:] - - return TFBaseModelOutputWithPoolingAndCrossAttentions( - last_hidden_state=sequence_output, - pooler_output=pooled_output, - past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "encoder", None) is not None: - with tf.name_scope(self.encoder.name): - self.encoder.build(None) - if getattr(self, "pooler", None) is not None: - with tf.name_scope(self.pooler.name): - self.pooler.build(None) - if getattr(self, "embeddings", None) is not None: - with tf.name_scope(self.embeddings.name): - self.embeddings.build(None) - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaPreTrainedModel with Roberta->XLMRoberta -class TFXLMRobertaPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = XLMRobertaConfig - base_model_prefix = "roberta" - - -@add_start_docstrings( - "The bare XLM RoBERTa Model transformer outputting raw hidden-states without any specific head on top.", - XLM_ROBERTA_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaModel with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA -class TFXLMRobertaModel(TFXLMRobertaPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.roberta = TFXLMRobertaMainLayer(config, name="roberta") - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFBaseModelOutputWithPoolingAndCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool | None = False, - ) -> tuple | TFBaseModelOutputWithPoolingAndCrossAttentions: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - """ - outputs = self.roberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaLMHead with Roberta->XLMRoberta -class TFXLMRobertaLMHead(keras.layers.Layer): - """XLMRoberta Head for masked language modeling.""" - - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.hidden_size = config.hidden_size - self.dense = keras.layers.Dense( - config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" - ) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.act = get_tf_activation("gelu") - - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.decoder = input_embeddings - - def build(self, input_shape=None): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.hidden_size]) - - def get_output_embeddings(self): - return self.decoder - - def set_output_embeddings(self, value): - self.decoder.weight = value - self.decoder.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - hidden_states = self.dense(hidden_states) - hidden_states = self.act(hidden_states) - hidden_states = self.layer_norm(hidden_states) - - # project back to size of vocabulary with bias - seq_length = shape_list(tensor=hidden_states)[1] - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) - hidden_states = tf.matmul(a=hidden_states, b=self.decoder.weight, transpose_b=True) - hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) - hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) - - return hidden_states - - -@add_start_docstrings("""XLM RoBERTa Model with a `language modeling` head on top.""", XLM_ROBERTA_START_DOCSTRING) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForMaskedLM with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA -class TFXLMRobertaForMaskedLM(TFXLMRobertaPreTrainedModel, TFMaskedLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head.decoder.weight"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.roberta = TFXLMRobertaMainLayer(config, add_pooling_layer=False, name="roberta") - self.lm_head = TFXLMRobertaLMHead(config, self.roberta.embeddings, name="lm_head") - - def get_lm_head(self): - return self.lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMaskedLMOutput, - config_class=_CONFIG_FOR_DOC, - mask="", - expected_output="' Paris'", - expected_loss=0.1, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMaskedLMOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., - config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the - loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - prediction_scores = self.lm_head(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMaskedLMOutput( - loss=loss, - logits=prediction_scores, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -@add_start_docstrings( - "XLM-RoBERTa Model with a `language modeling` head on top for CLM fine-tuning.", - XLM_ROBERTA_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForCausalLM with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA -class TFXLMRobertaForCausalLM(TFXLMRobertaPreTrainedModel, TFCausalLanguageModelingLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head.decoder.weight"] - - def __init__(self, config: XLMRobertaConfig, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - if not config.is_decoder: - logger.warning("If you want to use `TFXLMRobertaLMHeadModel` as a standalone, add `is_decoder=True.`") - - self.roberta = TFXLMRobertaMainLayer(config, add_pooling_layer=False, name="roberta") - self.lm_head = TFXLMRobertaLMHead(config, input_embeddings=self.roberta.embeddings, name="lm_head") - - def get_lm_head(self): - return self.lm_head - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_head.name - - # Copied from transformers.models.bert.modeling_tf_bert.TFBertLMHeadModel.prepare_inputs_for_generation - def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): - input_shape = input_ids.shape - # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly - if attention_mask is None: - attention_mask = tf.ones(input_shape) - - # cut decoder_input_ids if past is used - if past_key_values is not None: - input_ids = input_ids[:, -1:] - - return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFCausalLMOutputWithCrossAttentions, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - encoder_hidden_states: np.ndarray | tf.Tensor | None = None, - encoder_attention_mask: np.ndarray | tf.Tensor | None = None, - past_key_values: tuple[tuple[np.ndarray | tf.Tensor]] | None = None, - use_cache: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFCausalLMOutputWithCrossAttentions | tuple[tf.Tensor]: - r""" - encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): - Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if - the model is configured as a decoder. - encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in - the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - past_key_values (`tuple[tuple[tf.Tensor]]` of length `config.n_layers`) - contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. - If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that - don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all - `decoder_input_ids` of shape `(batch_size, sequence_length)`. - use_cache (`bool`, *optional*, defaults to `True`): - If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see - `past_key_values`). Set to `False` during training, `True` during generation - labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - """ - outputs = self.roberta( - input_ids=input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - sequence_output = outputs[0] - logits = self.lm_head(hidden_states=sequence_output, training=training) - loss = None - - if labels is not None: - # shift labels to the left and cut last logit token - shifted_logits = logits[:, :-1] - labels = labels[:, 1:] - loss = self.hf_compute_loss(labels=labels, logits=shifted_logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFCausalLMOutputWithCrossAttentions( - loss=loss, - logits=logits, - past_key_values=outputs.past_key_values, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - cross_attentions=outputs.cross_attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "lm_head", None) is not None: - with tf.name_scope(self.lm_head.name): - self.lm_head.build(None) - - -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaClassificationHead with Roberta->XLMRoberta -class TFXLMRobertaClassificationHead(keras.layers.Layer): - """Head for sentence-level classification tasks.""" - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.dense = keras.layers.Dense( - config.hidden_size, - kernel_initializer=get_initializer(config.initializer_range), - activation="tanh", - name="dense", - ) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.out_proj = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="out_proj" - ) - self.config = config - - def call(self, features, training=False): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x, training=training) - x = self.dense(x) - x = self.dropout(x, training=training) - x = self.out_proj(x) - return x - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "dense", None) is not None: - with tf.name_scope(self.dense.name): - self.dense.build([None, None, self.config.hidden_size]) - if getattr(self, "out_proj", None) is not None: - with tf.name_scope(self.out_proj.name): - self.out_proj.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - XLM RoBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the - pooled output) e.g. for GLUE tasks. - """, - XLM_ROBERTA_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForSequenceClassification with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA -class TFXLMRobertaForSequenceClassification(TFXLMRobertaPreTrainedModel, TFSequenceClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta = TFXLMRobertaMainLayer(config, add_pooling_layer=False, name="roberta") - self.classifier = TFXLMRobertaClassificationHead(config, name="classifier") - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="cardiffnlp/twitter-roberta-base-emotion", - output_type=TFSequenceClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="'optimism'", - expected_loss=0.08, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFSequenceClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - logits = self.classifier(sequence_output, training=training) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFSequenceClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build(None) - - -@add_start_docstrings( - """ - XLM Roberta Model with a multiple choice classification head on top (a linear layer on top of the pooled output and - a softmax) e.g. for RocStories/SWAG tasks. - """, - XLM_ROBERTA_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForMultipleChoice with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA -class TFXLMRobertaForMultipleChoice(TFXLMRobertaPreTrainedModel, TFMultipleChoiceLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"lm_head"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.roberta = TFXLMRobertaMainLayer(config, name="roberta") - self.dropout = keras.layers.Dropout(config.hidden_dropout_prob) - self.classifier = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward( - XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") - ) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFMultipleChoiceModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFMultipleChoiceModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None - outputs = self.roberta( - flat_input_ids, - flat_attention_mask, - flat_token_type_ids, - flat_position_ids, - head_mask, - inputs_embeds, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - pooled_output = outputs[1] - pooled_output = self.dropout(pooled_output, training=training) - logits = self.classifier(pooled_output) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFMultipleChoiceModelOutput( - loss=loss, - logits=reshaped_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - XLM RoBERTa Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. - for Named-Entity-Recognition (NER) tasks. - """, - XLM_ROBERTA_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForTokenClassification with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA -class TFXLMRobertaForTokenClassification(TFXLMRobertaPreTrainedModel, TFTokenClassificationLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - _keys_to_ignore_on_load_missing = [r"dropout"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta = TFXLMRobertaMainLayer(config, add_pooling_layer=False, name="roberta") - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = keras.layers.Dropout(classifier_dropout) - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="ydshieh/roberta-large-ner-english", - output_type=TFTokenClassifierOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="['O', 'ORG', 'ORG', 'O', 'O', 'O', 'O', 'O', 'LOC', 'O', 'LOC', 'LOC']", - expected_loss=0.01, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFTokenClassifierOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - sequence_output = self.dropout(sequence_output, training=training) - logits = self.classifier(sequence_output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFTokenClassifierOutput( - loss=loss, - logits=logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - XLM RoBERTa Model with a span classification head on top for extractive question-answering tasks like SQuAD (a - linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - XLM_ROBERTA_START_DOCSTRING, -) -# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForQuestionAnswering with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA -class TFXLMRobertaForQuestionAnswering(TFXLMRobertaPreTrainedModel, TFQuestionAnsweringLoss): - # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model - _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] - - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.roberta = TFXLMRobertaMainLayer(config, add_pooling_layer=False, name="roberta") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint="ydshieh/roberta-base-squad2", - output_type=TFQuestionAnsweringModelOutput, - config_class=_CONFIG_FOR_DOC, - expected_output="' puppet'", - expected_loss=0.86, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - position_ids: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool | None = False, - ) -> TFQuestionAnsweringModelOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - outputs = self.roberta( - input_ids, - attention_mask=attention_mask, - token_type_ids=token_type_ids, - position_ids=position_ids, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((loss,) + output) if loss is not None else output - - return TFQuestionAnsweringModelOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - hidden_states=outputs.hidden_states, - attentions=outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "roberta", None) is not None: - with tf.name_scope(self.roberta.name): - self.roberta.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFXLMRobertaForCausalLM", - "TFXLMRobertaForMaskedLM", - "TFXLMRobertaForMultipleChoice", - "TFXLMRobertaForQuestionAnswering", - "TFXLMRobertaForSequenceClassification", - "TFXLMRobertaForTokenClassification", - "TFXLMRobertaModel", - "TFXLMRobertaPreTrainedModel", -] diff --git a/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py b/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py index a3a252572ec9..4e0fab16b429 100644 --- a/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py +++ b/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py @@ -60,8 +60,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -674,8 +672,6 @@ class XLMRobertaPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py b/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py index d0c71365d214..c07f9e9bf760 100644 --- a/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py +++ b/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py @@ -57,8 +57,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") @@ -666,8 +664,6 @@ class XLMRobertaXLPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/xlnet/__init__.py b/src/transformers/models/xlnet/__init__.py index 3f4534559253..73fe8d46985c 100644 --- a/src/transformers/models/xlnet/__init__.py +++ b/src/transformers/models/xlnet/__init__.py @@ -19,7 +19,6 @@ if TYPE_CHECKING: from .configuration_xlnet import * - from .modeling_tf_xlnet import * from .modeling_xlnet import * from .tokenization_xlnet import * from .tokenization_xlnet_fast import * diff --git a/src/transformers/models/xlnet/configuration_xlnet.py b/src/transformers/models/xlnet/configuration_xlnet.py index 4a7238eb4c09..d32f05c875bb 100644 --- a/src/transformers/models/xlnet/configuration_xlnet.py +++ b/src/transformers/models/xlnet/configuration_xlnet.py @@ -49,8 +49,6 @@ class XLNetConfig(PretrainedConfig): ff_activation (`str` or `Callable`, *optional*, defaults to `"gelu"`): The non-linear activation function (function or string) in the If string, `"gelu"`, `"relu"`, `"silu"` and `"gelu_new"` are supported. - untie_r (`bool`, *optional*, defaults to `True`): - Whether or not to untie relative position biases attn_type (`str`, *optional*, defaults to `"bi"`): The attention type used by the model. Set `"bi"` for XLNet, `"uni"` for Transformer-XL. initializer_range (`float`, *optional*, defaults to 0.02): @@ -150,7 +148,6 @@ def __init__( n_head=16, d_inner=4096, ff_activation="gelu", - untie_r=True, attn_type="bi", initializer_range=0.02, layer_norm_eps=1e-12, @@ -188,7 +185,6 @@ def __init__( self.d_head = d_model // n_head self.ff_activation = ff_activation self.d_inner = d_inner - self.untie_r = untie_r self.attn_type = attn_type self.initializer_range = initializer_range diff --git a/src/transformers/models/xlnet/convert_xlnet_original_tf_checkpoint_to_pytorch.py b/src/transformers/models/xlnet/convert_xlnet_original_tf_checkpoint_to_pytorch.py index a15c5f22ad68..81aef230ac43 100755 --- a/src/transformers/models/xlnet/convert_xlnet_original_tf_checkpoint_to_pytorch.py +++ b/src/transformers/models/xlnet/convert_xlnet_original_tf_checkpoint_to_pytorch.py @@ -24,7 +24,6 @@ XLNetForQuestionAnswering, XLNetForSequenceClassification, XLNetLMHeadModel, - load_tf_weights_in_xlnet, ) from transformers.utils import CONFIG_NAME, WEIGHTS_NAME, logging @@ -43,6 +42,157 @@ logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def build_tf_xlnet_to_pytorch_map(model, config, tf_weights=None): + """ + A map of modules from TF to PyTorch. I use a map to keep the PyTorch model as identical to the original PyTorch + model as possible. + """ + + tf_to_pt_map = {} + + if hasattr(model, "transformer"): + if hasattr(model, "lm_loss"): + # We will load also the output bias + tf_to_pt_map["model/lm_loss/bias"] = model.lm_loss.bias + if hasattr(model, "sequence_summary") and "model/sequnece_summary/summary/kernel" in tf_weights: + # We will load also the sequence summary + tf_to_pt_map["model/sequnece_summary/summary/kernel"] = model.sequence_summary.summary.weight + tf_to_pt_map["model/sequnece_summary/summary/bias"] = model.sequence_summary.summary.bias + if ( + hasattr(model, "logits_proj") + and config.finetuning_task is not None + and f"model/regression_{config.finetuning_task}/logit/kernel" in tf_weights + ): + tf_to_pt_map[f"model/regression_{config.finetuning_task}/logit/kernel"] = model.logits_proj.weight + tf_to_pt_map[f"model/regression_{config.finetuning_task}/logit/bias"] = model.logits_proj.bias + + # Now load the rest of the transformer + model = model.transformer + + # Embeddings and output + tf_to_pt_map.update( + { + "model/transformer/word_embedding/lookup_table": model.word_embedding.weight, + "model/transformer/mask_emb/mask_emb": model.mask_emb, + } + ) + + # Transformer blocks + for i, b in enumerate(model.layer): + layer_str = f"model/transformer/layer_{i}/" + tf_to_pt_map.update( + { + layer_str + "rel_attn/LayerNorm/gamma": b.rel_attn.layer_norm.weight, + layer_str + "rel_attn/LayerNorm/beta": b.rel_attn.layer_norm.bias, + layer_str + "rel_attn/o/kernel": b.rel_attn.o, + layer_str + "rel_attn/q/kernel": b.rel_attn.q, + layer_str + "rel_attn/k/kernel": b.rel_attn.k, + layer_str + "rel_attn/r/kernel": b.rel_attn.r, + layer_str + "rel_attn/v/kernel": b.rel_attn.v, + layer_str + "ff/LayerNorm/gamma": b.ff.layer_norm.weight, + layer_str + "ff/LayerNorm/beta": b.ff.layer_norm.bias, + layer_str + "ff/layer_1/kernel": b.ff.layer_1.weight, + layer_str + "ff/layer_1/bias": b.ff.layer_1.bias, + layer_str + "ff/layer_2/kernel": b.ff.layer_2.weight, + layer_str + "ff/layer_2/bias": b.ff.layer_2.bias, + } + ) + + # Relative positioning biases + if config.untie_r: + r_r_list = [] + r_w_list = [] + r_s_list = [] + seg_embed_list = [] + for b in model.layer: + r_r_list.append(b.rel_attn.r_r_bias) + r_w_list.append(b.rel_attn.r_w_bias) + r_s_list.append(b.rel_attn.r_s_bias) + seg_embed_list.append(b.rel_attn.seg_embed) + else: + r_r_list = [model.r_r_bias] + r_w_list = [model.r_w_bias] + r_s_list = [model.r_s_bias] + seg_embed_list = [model.seg_embed] + tf_to_pt_map.update( + { + "model/transformer/r_r_bias": r_r_list, + "model/transformer/r_w_bias": r_w_list, + "model/transformer/r_s_bias": r_s_list, + "model/transformer/seg_embed": seg_embed_list, + } + ) + return tf_to_pt_map + + +def load_tf_weights_in_xlnet(model, config, tf_path): + """Load tf checkpoints in a pytorch model""" + try: + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + tf_weights = {} + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + tf_weights[name] = array + + # Build TF to PyTorch weights loading map + tf_to_pt_map = build_tf_xlnet_to_pytorch_map(model, config, tf_weights) + + for name, pointer in tf_to_pt_map.items(): + logger.info(f"Importing {name}") + if name not in tf_weights: + logger.info(f"{name} not in tf pre-trained weights, skipping") + continue + array = tf_weights[name] + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if "kernel" in name and ("ff" in name or "summary" in name or "logit" in name): + logger.info("Transposing") + array = np.transpose(array) + if isinstance(pointer, list): + # Here we will split the TF weights + assert len(pointer) == array.shape[0], ( + f"Pointer length {len(pointer)} and array length {array.shape[0]} mismatched" + ) + for i, p_i in enumerate(pointer): + arr_i = array[i, ...] + try: + assert p_i.shape == arr_i.shape, ( + f"Pointer shape {p_i.shape} and array shape {arr_i.shape} mismatched" + ) + except AssertionError as e: + e.args += (p_i.shape, arr_i.shape) + raise + logger.info(f"Initialize PyTorch weight {name} for layer {i}") + p_i.data = torch.from_numpy(arr_i) + else: + try: + assert pointer.shape == array.shape, ( + f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched" + ) + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + tf_weights.pop(name, None) + tf_weights.pop(name + "/Adam", None) + tf_weights.pop(name + "/Adam_1", None) + + logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}") + return model def convert_xlnet_checkpoint_to_pytorch( diff --git a/src/transformers/models/xlnet/modeling_tf_xlnet.py b/src/transformers/models/xlnet/modeling_tf_xlnet.py deleted file mode 100644 index 451d26c844d8..000000000000 --- a/src/transformers/models/xlnet/modeling_tf_xlnet.py +++ /dev/null @@ -1,1820 +0,0 @@ -# coding=utf-8 -# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team. -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. -# -# 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. -""" -TF 2.0 XLNet model. -""" - -from __future__ import annotations - -import warnings -from dataclasses import dataclass - -import numpy as np -import tensorflow as tf - -from ...activations_tf import get_tf_activation -from ...modeling_tf_utils import ( - TFCausalLanguageModelingLoss, - TFModelInputType, - TFMultipleChoiceLoss, - TFPreTrainedModel, - TFQuestionAnsweringLoss, - TFSequenceClassificationLoss, - TFSequenceSummary, - TFSharedEmbeddings, - TFTokenClassificationLoss, - get_initializer, - keras, - keras_serializable, - unpack_inputs, -) -from ...tf_utils import check_embeddings_within_bounds, shape_list, stable_softmax -from ...utils import ( - ModelOutput, - add_code_sample_docstrings, - add_start_docstrings, - add_start_docstrings_to_model_forward, - logging, - replace_return_docstrings, -) -from .configuration_xlnet import XLNetConfig - - -logger = logging.get_logger(__name__) - -_CHECKPOINT_FOR_DOC = "xlnet/xlnet-base-cased" -_CONFIG_FOR_DOC = "XLNetConfig" - - -class TFXLNetRelativeAttention(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - if config.d_model % config.n_head != 0: - raise ValueError( - f"The hidden size ({config.d_model}) is not a multiple of the number of attention " - f"heads ({config.n_head}" - ) - - self.n_head = config.n_head - self.d_head = config.d_head - self.d_model = config.d_model - self.scale = 1 / (config.d_head**0.5) - self.initializer_range = config.initializer_range - self.output_attentions = config.output_attentions - - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.dropout = keras.layers.Dropout(config.dropout) - self.config = config - - def build(self, input_shape=None): - initializer = get_initializer(self.initializer_range) - self.q = self.add_weight( - shape=(self.d_model, self.n_head, self.d_head), initializer=initializer, trainable=True, name="q" - ) - self.k = self.add_weight( - shape=(self.d_model, self.n_head, self.d_head), initializer=initializer, trainable=True, name="k" - ) - self.v = self.add_weight( - shape=(self.d_model, self.n_head, self.d_head), initializer=initializer, trainable=True, name="v" - ) - self.o = self.add_weight( - shape=(self.d_model, self.n_head, self.d_head), initializer=initializer, trainable=True, name="o" - ) - self.r = self.add_weight( - shape=(self.d_model, self.n_head, self.d_head), initializer=initializer, trainable=True, name="r" - ) - self.r_r_bias = self.add_weight( - shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_r_bias" - ) - self.r_s_bias = self.add_weight( - shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_s_bias" - ) - self.r_w_bias = self.add_weight( - shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_w_bias" - ) - self.seg_embed = self.add_weight( - shape=(2, self.n_head, self.d_head), initializer=initializer, trainable=True, name="seg_embed" - ) - - if self.built: - return - self.built = True - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - - def prune_heads(self, heads): - raise NotImplementedError - - def rel_shift(self, x, klen=-1): - """perform relative shift to form the relative attention score.""" - x_size = shape_list(x) - - x = tf.reshape(x, (x_size[1], x_size[0], x_size[2], x_size[3])) - x = x[1:, ...] - x = tf.reshape(x, (x_size[0], x_size[1] - 1, x_size[2], x_size[3])) - x = x[:, 0:klen, :, :] - # x = torch.index_select(x, 1, torch.arange(klen, device=x.device, dtype=torch.long)) - - return x - - def rel_attn_core( - self, q_head, k_head_h, v_head_h, k_head_r, seg_mat, attn_mask, head_mask, output_attentions, training=False - ): - """Core relative positional attention operations.""" - # content based attention score - ac = tf.einsum("ibnd,jbnd->ijbn", q_head + self.r_w_bias, k_head_h) - - # position based attention score - bd = tf.einsum("ibnd,jbnd->ijbn", q_head + self.r_r_bias, k_head_r) - bd = self.rel_shift(bd, klen=shape_list(ac)[1]) - - # segment based attention score - if seg_mat is None: - ef = 0 - else: - ef = tf.einsum("ibnd,snd->ibns", q_head + self.r_s_bias, self.seg_embed) - ef = tf.einsum("ijbs,ibns->ijbn", seg_mat, ef) - - # merge attention scores and perform masking - attn_score = (ac + bd + ef) * self.scale - if attn_mask is not None: - # attn_score = attn_score * (1 - attn_mask) - 1e30 * attn_mask - if attn_mask.dtype == tf.float16 or attn_mask.dtype == tf.bfloat16: - attn_score = attn_score - 65500 * attn_mask - else: - attn_score = attn_score - 1e30 * attn_mask - - # attention probability - attn_prob = stable_softmax(attn_score, axis=1) - - attn_prob = self.dropout(attn_prob, training=training) - - # Mask heads if we want to - if head_mask is not None: - attn_prob = attn_prob * head_mask - - # attention output - attn_vec = tf.einsum("ijbn,jbnd->ibnd", attn_prob, v_head_h) - - if output_attentions: - return attn_vec, attn_prob - - return attn_vec - - def post_attention(self, h, attn_vec, residual=True, training=False): - """Post-attention processing.""" - # post-attention projection (back to `d_model`) - attn_out = tf.einsum("ibnd,hnd->ibh", attn_vec, self.o) - - attn_out = self.dropout(attn_out, training=training) - - if residual: - attn_out = attn_out + h - output = self.layer_norm(attn_out) - - return output - - def call( - self, - h, - g, - attn_mask_h, - attn_mask_g, - r, - seg_mat, - mems: np.ndarray | tf.Tensor | None = None, - target_mapping: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = False, - training: bool = False, - ): - if g is not None: - # Two-stream attention with relative positional encoding. - # content based attention score - if mems is not None and len(shape_list(mems)) > 1: - cat = tf.concat([mems, h], axis=0) - else: - cat = h - - # content-based key head - k_head_h = tf.einsum("ibh,hnd->ibnd", cat, self.k) - - # content-based value head - v_head_h = tf.einsum("ibh,hnd->ibnd", cat, self.v) - - # position-based key head - k_head_r = tf.einsum("ibh,hnd->ibnd", r, self.r) - - # h-stream - # content-stream query head - q_head_h = tf.einsum("ibh,hnd->ibnd", h, self.q) - - # core attention ops - attn_vec_h = self.rel_attn_core( - q_head_h, - k_head_h, - v_head_h, - k_head_r, - seg_mat, - attn_mask_h, - head_mask, - output_attentions, - training=training, - ) - - if output_attentions: - attn_vec_h, attn_prob_h = attn_vec_h - - # post processing - output_h = self.post_attention(h, attn_vec_h, training=training) - - # g-stream - # query-stream query head - q_head_g = tf.einsum("ibh,hnd->ibnd", g, self.q) - - # core attention ops - if target_mapping is not None: - q_head_g = tf.einsum("mbnd,mlb->lbnd", q_head_g, target_mapping) - attn_vec_g = self.rel_attn_core( - q_head_g, - k_head_h, - v_head_h, - k_head_r, - seg_mat, - attn_mask_g, - head_mask, - output_attentions, - training=training, - ) - - if output_attentions: - attn_vec_g, attn_prob_g = attn_vec_g - - attn_vec_g = tf.einsum("lbnd,mlb->mbnd", attn_vec_g, target_mapping) - else: - attn_vec_g = self.rel_attn_core( - q_head_g, - k_head_h, - v_head_h, - k_head_r, - seg_mat, - attn_mask_g, - head_mask, - output_attentions, - training=training, - ) - - if output_attentions: - attn_vec_g, attn_prob_g = attn_vec_g - - # post processing - output_g = self.post_attention(g, attn_vec_g, training=training) - - if output_attentions: - attn_prob = attn_prob_h, attn_prob_g - - else: - # Multi-head attention with relative positional encoding - if mems is not None and len(shape_list(mems)) > 1: - cat = tf.concat([mems, h], axis=0) - else: - cat = h - - # content heads - q_head_h = tf.einsum("ibh,hnd->ibnd", h, self.q) - k_head_h = tf.einsum("ibh,hnd->ibnd", cat, self.k) - v_head_h = tf.einsum("ibh,hnd->ibnd", cat, self.v) - - # positional heads - k_head_r = tf.einsum("ibh,hnd->ibnd", r, self.r) - - # core attention ops - attn_vec = self.rel_attn_core( - q_head_h, - k_head_h, - v_head_h, - k_head_r, - seg_mat, - attn_mask_h, - head_mask, - output_attentions, - training=training, - ) - - if output_attentions: - attn_vec, attn_prob = attn_vec - - # post processing - output_h = self.post_attention(h, attn_vec, training=training) - output_g = None - - outputs = (output_h, output_g) - if output_attentions: - outputs = outputs + (attn_prob,) - return outputs - - -class TFXLNetFeedForward(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.layer_norm = keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") - self.layer_1 = keras.layers.Dense( - config.d_inner, kernel_initializer=get_initializer(config.initializer_range), name="layer_1" - ) - self.layer_2 = keras.layers.Dense( - config.d_model, kernel_initializer=get_initializer(config.initializer_range), name="layer_2" - ) - self.dropout = keras.layers.Dropout(config.dropout) - if isinstance(config.ff_activation, str): - self.activation_function = get_tf_activation(config.ff_activation) - else: - self.activation_function = config.ff_activation - self.config = config - - def call(self, inp, training=False): - output = inp - output = self.layer_1(output) - output = self.activation_function(output) - output = self.dropout(output, training=training) - output = self.layer_2(output) - output = self.dropout(output, training=training) - output = self.layer_norm(output + inp) - return output - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "layer_norm", None) is not None: - with tf.name_scope(self.layer_norm.name): - self.layer_norm.build([None, None, self.config.d_model]) - if getattr(self, "layer_1", None) is not None: - with tf.name_scope(self.layer_1.name): - self.layer_1.build([None, None, self.config.d_model]) - if getattr(self, "layer_2", None) is not None: - with tf.name_scope(self.layer_2.name): - self.layer_2.build([None, None, self.config.d_inner]) - - -class TFXLNetLayer(keras.layers.Layer): - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - self.rel_attn = TFXLNetRelativeAttention(config, name="rel_attn") - self.ff = TFXLNetFeedForward(config, name="ff") - self.dropout = keras.layers.Dropout(config.dropout) - - def call( - self, - output_h, - output_g, - non_tgt_mask, - attn_mask, - pos_emb, - seg_mat, - mems: np.ndarray | tf.Tensor | None = None, - target_mapping: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - output_attentions: bool | None = False, - training: bool = False, - ): - outputs = self.rel_attn( - output_h, - output_g, - non_tgt_mask, - attn_mask, - pos_emb, - seg_mat, - mems, - target_mapping, - head_mask, - output_attentions, - training=training, - ) - output_h, output_g = outputs[:2] - - if output_g is not None: - output_g = self.ff(output_g, training=training) - output_h = self.ff(output_h, training=training) - - outputs = (output_h, output_g) + outputs[2:] # Add again attentions if there are there - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "rel_attn", None) is not None: - with tf.name_scope(self.rel_attn.name): - self.rel_attn.build(None) - if getattr(self, "ff", None) is not None: - with tf.name_scope(self.ff.name): - self.ff.build(None) - - -class TFXLNetLMHead(keras.layers.Layer): - def __init__(self, config, input_embeddings, **kwargs): - super().__init__(**kwargs) - self.config = config - # The output weights are the same as the input embeddings, but there is - # an output-only bias for each token. - self.input_embeddings = input_embeddings - - def build(self, input_shape): - self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") - super().build(input_shape) - - def get_output_embeddings(self): - return self.input_embeddings - - def set_output_embeddings(self, value): - self.input_embeddings.weight = value - self.input_embeddings.vocab_size = shape_list(value)[0] - - def get_bias(self): - return {"bias": self.bias} - - def set_bias(self, value): - self.bias = value["bias"] - self.config.vocab_size = shape_list(value["bias"])[0] - - def call(self, hidden_states): - hidden_states = self.input_embeddings(hidden_states, mode="linear") - hidden_states = hidden_states + self.bias - return hidden_states - - -@keras_serializable -class TFXLNetMainLayer(keras.layers.Layer): - config_class = XLNetConfig - - def __init__(self, config, **kwargs): - super().__init__(**kwargs) - - self.config = config - self.output_hidden_states = config.output_hidden_states - self.output_attentions = config.output_attentions - self.return_dict = config.return_dict - - self.mem_len = config.mem_len - self.reuse_len = config.reuse_len - self.d_model = config.d_model - self.same_length = config.same_length - self.attn_type = config.attn_type - self.bi_data = config.bi_data - self.clamp_len = config.clamp_len - self.n_layer = config.n_layer - self.use_bfloat16 = config.use_bfloat16 - self.initializer_range = config.initializer_range - - self.word_embedding = TFSharedEmbeddings( - config.vocab_size, config.d_model, initializer_range=config.initializer_range, name="word_embedding" - ) - self.layer = [TFXLNetLayer(config, name=f"layer_._{i}") for i in range(config.n_layer)] - self.dropout = keras.layers.Dropout(config.dropout) - - self.use_mems_eval = config.use_mems_eval - self.use_mems_train = config.use_mems_train - - def get_input_embeddings(self): - return self.word_embedding - - def set_input_embeddings(self, value): - self.word_embedding.weight = value - self.word_embedding.vocab_size = shape_list(value)[0] - - def build(self, input_shape=None): - initializer = get_initializer(self.initializer_range) - self.mask_emb = self.add_weight( - shape=(1, 1, self.d_model), initializer=initializer, trainable=True, name="mask_emb" - ) - - if self.built: - return - self.built = True - if getattr(self, "word_embedding", None) is not None: - with tf.name_scope(self.word_embedding.name): - self.word_embedding.build(None) - if getattr(self, "layer", None) is not None: - for layer in self.layer: - with tf.name_scope(layer.name): - layer.build(None) - - def _prune_heads(self, heads_to_prune): - raise NotImplementedError - - def create_mask(self, qlen, mlen): - """ - Creates causal attention mask. Float mask where 1.0 indicates masked, 0.0 indicates not-masked. - - Args: - qlen: TODO Lysandre didn't fill - mlen: TODO Lysandre didn't fill - - ``` - - same_length=False: same_length=True: - < qlen > < qlen > - ^ [0 0 0 0 0 1 1 1 1] [0 0 0 0 0 1 1 1 1] - [0 0 0 0 0 0 1 1 1] [1 0 0 0 0 0 1 1 1] - qlen [0 0 0 0 0 0 0 1 1] [1 1 0 0 0 0 0 1 1] - [0 0 0 0 0 0 0 0 1] [1 1 1 0 0 0 0 0 1] - v [0 0 0 0 0 0 0 0 0] [1 1 1 1 0 0 0 0 0] - ``` - """ - attn_mask = tf.ones([qlen, qlen]) - mask_u = tf.linalg.band_part(attn_mask, 0, -1) - mask_dia = tf.linalg.band_part(attn_mask, 0, 0) - attn_mask_pad = tf.zeros([qlen, mlen]) - ret = tf.concat([attn_mask_pad, mask_u - mask_dia], 1) - if self.same_length: - mask_l = tf.linalg.band_part(attn_mask, -1, 0) - ret = tf.concat([ret[:, :qlen] + mask_l - mask_dia, ret[:, qlen:]], 1) - return ret - - def cache_mem(self, curr_out, prev_mem): - # cache hidden states into memory. - if self.reuse_len is not None and self.reuse_len > 0: - curr_out = curr_out[: self.reuse_len] - - if self.mem_len is None or self.mem_len == 0: - # If `use_mems` is active but no `mem_len` is defined, the model behaves like GPT-2 at inference time - # and returns all of the past and current hidden states. - cutoff = 0 - else: - # If `use_mems` is active and `mem_len` is defined, the model returns the last `mem_len` hidden - # states. This is the preferred setting for training and long-form generation. - cutoff = -self.mem_len - if prev_mem is None: - # if `use_mems` is active and `mem_len` is defined, the model - new_mem = curr_out[cutoff:] - else: - new_mem = tf.concat([prev_mem, curr_out], 0)[cutoff:] - - return tf.stop_gradient(new_mem) - - @staticmethod - def positional_embedding(pos_seq, inv_freq, bsz=None): - sinusoid_inp = tf.einsum("i,d->id", pos_seq, inv_freq) - pos_emb = tf.concat([tf.sin(sinusoid_inp), tf.cos(sinusoid_inp)], axis=-1) - pos_emb = pos_emb[:, None, :] - - if bsz is not None: - pos_emb = tf.tile(pos_emb, [1, bsz, 1]) - - return pos_emb - - def relative_positional_encoding(self, qlen, klen, bsz=None): - """create relative positional encoding.""" - freq_seq = tf.range(0, self.d_model, 2.0) - inv_freq = 1 / (10000 ** (freq_seq / self.d_model)) - - if self.attn_type == "bi": - # beg, end = klen - 1, -qlen - beg, end = klen, -qlen - elif self.attn_type == "uni": - # beg, end = klen - 1, -1 - beg, end = klen, -1 - else: - raise ValueError(f"Unknown `attn_type` {self.attn_type}.") - - if self.bi_data: - fwd_pos_seq = tf.range(beg, end, -1.0) - bwd_pos_seq = tf.range(-beg, -end, 1.0) - - if self.clamp_len > 0: - fwd_pos_seq = tf.clip_by_value(fwd_pos_seq, -self.clamp_len, self.clamp_len) - bwd_pos_seq = tf.clip_by_value(bwd_pos_seq, -self.clamp_len, self.clamp_len) - - if bsz is not None: - if bsz % 2 != 0: - raise ValueError(f"With bi_data, the batch size {bsz} should be divisible by 2") - fwd_pos_emb = self.positional_embedding(fwd_pos_seq, inv_freq, bsz // 2) - bwd_pos_emb = self.positional_embedding(bwd_pos_seq, inv_freq, bsz // 2) - else: - fwd_pos_emb = self.positional_embedding(fwd_pos_seq, inv_freq) - bwd_pos_emb = self.positional_embedding(bwd_pos_seq, inv_freq) - - pos_emb = tf.concat([fwd_pos_emb, bwd_pos_emb], axis=1) - else: - fwd_pos_seq = tf.range(beg, end, -1.0) - if self.clamp_len > 0: - fwd_pos_seq = tf.clip_by_value(fwd_pos_seq, -self.clamp_len, self.clamp_len) - pos_emb = self.positional_embedding(fwd_pos_seq, inv_freq, bsz) - - return pos_emb - - @unpack_inputs - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - mems: np.ndarray | tf.Tensor | None = None, - perm_mask: np.ndarray | tf.Tensor | None = None, - target_mapping: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - input_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_mems: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ): - if training and use_mems is None: - use_mems = self.use_mems_train - else: - use_mems = self.use_mems_eval - - # the original code for XLNet uses shapes [len, bsz] with the batch dimension at the end - # but we want a unified interface in the library with the batch size on the first dimension - # so we move here the first dimension (batch) to the end - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - input_ids = tf.transpose(input_ids, perm=(1, 0)) - qlen, bsz = shape_list(input_ids)[:2] - elif inputs_embeds is not None: - inputs_embeds = tf.transpose(inputs_embeds, perm=(1, 0, 2)) - qlen, bsz = shape_list(inputs_embeds)[:2] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - token_type_ids = tf.transpose(token_type_ids, perm=(1, 0)) if token_type_ids is not None else None - input_mask = tf.transpose(input_mask, perm=(1, 0)) if input_mask is not None else None - attention_mask = tf.transpose(attention_mask, perm=(1, 0)) if attention_mask is not None else None - perm_mask = tf.transpose(perm_mask, perm=(1, 2, 0)) if perm_mask is not None else None - target_mapping = tf.transpose(target_mapping, perm=(1, 2, 0)) if target_mapping is not None else None - - mlen = shape_list(mems[0])[0] if mems is not None and mems[0] is not None else 0 - klen = mlen + qlen - - # Attention mask - # causal attention mask - if self.attn_type == "uni": - attn_mask = self.create_mask(qlen, mlen) - attn_mask = attn_mask[:, :, None, None] - elif self.attn_type == "bi": - attn_mask = None - else: - raise ValueError(f"Unsupported attention type: {self.attn_type}") - - # data mask: input mask & perm mask - assert input_mask is None or attention_mask is None, ( - "You can only use one of input_mask (uses 1 for padding) " - "or attention_mask (uses 0 for padding, added for compatibility with BERT). Please choose one." - ) - if input_mask is None and attention_mask is not None: - one_cst = tf.constant(1.0) - input_mask = 1.0 - tf.cast(attention_mask, dtype=one_cst.dtype) - if input_mask is not None and perm_mask is not None: - data_mask = input_mask[None] + perm_mask - elif input_mask is not None and perm_mask is None: - data_mask = input_mask[None] - elif input_mask is None and perm_mask is not None: - data_mask = perm_mask - else: - data_mask = None - - if data_mask is not None: - # all mems can be attended to - if mlen > 0: - mems_mask = tf.zeros([shape_list(data_mask)[0], mlen, bsz]) - data_mask = tf.concat([mems_mask, data_mask], axis=1) - if attn_mask is None: - attn_mask = data_mask[:, :, :, None] - else: - attn_mask += data_mask[:, :, :, None] - - if attn_mask is not None: - attn_mask = tf.cast(attn_mask > 0, dtype=attn_mask.dtype) - - if attn_mask is not None: - non_tgt_mask = -tf.eye(qlen) - if mlen > 0: - non_tgt_mask = tf.concat([tf.zeros([qlen, mlen]), non_tgt_mask], axis=-1) - non_tgt_mask = tf.cast((attn_mask + non_tgt_mask[:, :, None, None]) > 0, dtype=non_tgt_mask.dtype) - else: - non_tgt_mask = None - - # Word embeddings and prepare h & g hidden states - if inputs_embeds is not None: - word_emb_k = inputs_embeds - else: - check_embeddings_within_bounds(input_ids, self.word_embedding.vocab_size) - word_emb_k = self.word_embedding(input_ids) - output_h = self.dropout(word_emb_k, training=training) - if target_mapping is not None: - word_emb_q = tf.tile(self.mask_emb, [shape_list(target_mapping)[0], bsz, 1]) - # else: # We removed the inp_q input which was same as target mapping - # inp_q_ext = inp_q[:, :, None] - # word_emb_q = inp_q_ext * self.mask_emb + (1 - inp_q_ext) * word_emb_k - output_g = self.dropout(word_emb_q, training=training) - else: - output_g = None - - # Segment embedding - if token_type_ids is not None: - # Convert `token_type_ids` to one-hot `seg_mat` - if mlen > 0: - mem_pad = tf.zeros([mlen, bsz], dtype=token_type_ids.dtype) - cat_ids = tf.concat([mem_pad, token_type_ids], 0) - else: - cat_ids = token_type_ids - - # `1` indicates not in the same segment [qlen x klen x bsz] - seg_mat = tf.cast( - tf.logical_not(tf.equal(token_type_ids[:, None], cat_ids[None, :])), - dtype=token_type_ids.dtype, - ) - seg_mat = tf.one_hot(seg_mat, 2) - else: - seg_mat = None - - # Positional encoding - pos_emb = self.relative_positional_encoding(qlen, klen, bsz=bsz) - pos_emb = self.dropout(pos_emb, training=training) - - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] (a head_mask for each layer) - # and head_mask is converted to shape [num_hidden_layers x qlen x klen x bsz x n_head] - if head_mask is not None: - raise NotImplementedError - else: - head_mask = [None] * self.n_layer - - new_mems = () - if mems is None: - mems = [None] * len(self.layer) - - attentions = [] if output_attentions else None - hidden_states = [] if output_hidden_states else None - for i, layer_module in enumerate(self.layer): - # cache new mems - if use_mems: - new_mems = new_mems + (self.cache_mem(output_h, mems[i]),) - if output_hidden_states: - hidden_states.append((output_h, output_g) if output_g is not None else output_h) - - outputs = layer_module( - output_h, - output_g, - non_tgt_mask, - attn_mask, - pos_emb, - seg_mat, - mems[i], - target_mapping, - head_mask[i], - output_attentions, - training=training, - ) - output_h, output_g = outputs[:2] - if output_attentions: - attentions.append(outputs[2]) - - # Add last hidden state - if output_hidden_states: - hidden_states.append((output_h, output_g) if output_g is not None else output_h) - - output = self.dropout(output_g if output_g is not None else output_h, training=training) - - # Prepare outputs, we transpose back here to shape [bsz, len, hidden_dim] (cf. beginning of forward() method) - output = tf.transpose(output, perm=(1, 0, 2)) - - if not use_mems: - new_mems = None - if output_hidden_states: - if output_g is not None: - hidden_states = tuple(tf.transpose(h, perm=(1, 0, 2)) for hs in hidden_states for h in hs) - else: - hidden_states = tuple(tf.transpose(hs, perm=(1, 0, 2)) for hs in hidden_states) - if output_attentions: - if target_mapping is not None: - # when target_mapping is provided, there are 2-tuple of attentions - attentions = tuple( - tuple(tf.transpose(attn_stream, perm=(2, 3, 0, 1)) for attn_stream in t) for t in attentions - ) - else: - attentions = tuple(tf.transpose(t, perm=(2, 3, 0, 1)) for t in attentions) - - if not return_dict: - return tuple(v for v in [output, new_mems, hidden_states, attentions] if v is not None) - - return TFXLNetModelOutput( - last_hidden_state=output, mems=new_mems, hidden_states=hidden_states, attentions=attentions - ) - - -class TFXLNetPreTrainedModel(TFPreTrainedModel): - """ - An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained - models. - """ - - config_class = XLNetConfig - base_model_prefix = "transformer" - - -@dataclass -class TFXLNetModelOutput(ModelOutput): - """ - Output type of [`TFXLNetModel`]. - - Args: - last_hidden_state (`tf.Tensor` of shape `(batch_size, num_predict, hidden_size)`): - Sequence of hidden-states at the last layer of the model. - - `num_predict` corresponds to `target_mapping.shape[1]`. If `target_mapping` is `None`, then `num_predict` - corresponds to `sequence_length`. - mems (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The - token ids which have their past given to this model should not be passed as `input_ids` as they have - already been computed. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - last_hidden_state: tf.Tensor | None = None - mems: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFXLNetLMHeadModelOutput(ModelOutput): - """ - Output type of [`TFXLNetLMHeadModel`]. - - Args: - loss (`tf.Tensor` of shape *(1,)*, *optional*, returned when `labels` is provided) - Language modeling loss (for next-token prediction). - logits (`tf.Tensor` of shape `(batch_size, num_predict, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - - `num_predict` corresponds to `target_mapping.shape[1]`. If `target_mapping` is `None`, then `num_predict` - corresponds to `sequence_length`. - mems (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The - token ids which have their past given to this model should not be passed as `input_ids` as they have - already been computed. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - mems: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFXLNetForSequenceClassificationOutput(ModelOutput): - """ - Output type of [`TFXLNetForSequenceClassification`]. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `label` is provided): - Classification (or regression if config.num_labels==1) loss. - logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): - Classification (or regression if config.num_labels==1) scores (before SoftMax). - mems (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The - token ids which have their past given to this model should not be passed as `input_ids` as they have - already been computed. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - mems: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFXLNetForTokenClassificationOutput(ModelOutput): - """ - Output type of [`TFXLNetForTokenClassificationOutput`]. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided) : - Classification loss. - logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.num_labels)`): - Classification scores (before SoftMax). - mems (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The - token ids which have their past given to this model should not be passed as `input_ids` as they have - already been computed. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - mems: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFXLNetForMultipleChoiceOutput(ModelOutput): - """ - Output type of [`TFXLNetForMultipleChoice`]. - - Args: - loss (`tf.Tensor` of shape *(1,)*, *optional*, returned when `labels` is provided): - Classification loss. - logits (`tf.Tensor` of shape `(batch_size, num_choices)`): - *num_choices* is the second dimension of the input tensors. (see *input_ids* above). - - Classification scores (before SoftMax). - mems (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The - token ids which have their past given to this model should not be passed as `input_ids` as they have - already been computed. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - logits: tf.Tensor | None = None - mems: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -@dataclass -class TFXLNetForQuestionAnsweringSimpleOutput(ModelOutput): - """ - Output type of [`TFXLNetForQuestionAnsweringSimple`]. - - Args: - loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): - Total span extraction loss is the sum of a Cross-Entropy for the start and end positions. - start_logits (`tf.Tensor` of shape `(batch_size, sequence_length,)`): - Span-start scores (before SoftMax). - end_logits (`tf.Tensor` of shape `(batch_size, sequence_length,)`): - Span-end scores (before SoftMax). - mems (`list[tf.Tensor]` of length `config.n_layers`): - Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The - token ids which have their past given to this model should not be passed as `input_ids` as they have - already been computed. - hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): - Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape - `(batch_size, sequence_length, hidden_size)`. - - Hidden-states of the model at the output of each layer plus the initial embedding outputs. - attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): - Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, - sequence_length)`. - - Attentions weights after the attention softmax, used to compute the weighted average in the self-attention - heads. - """ - - loss: tf.Tensor | None = None - start_logits: tf.Tensor | None = None - end_logits: tf.Tensor | None = None - mems: list[tf.Tensor] | None = None - hidden_states: tuple[tf.Tensor, ...] | None = None - attentions: tuple[tf.Tensor, ...] | None = None - - -XLNET_START_DOCSTRING = r""" - - This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the - library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads - etc.) - - This model is also a [keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it - as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and - behavior. - - - - TensorFlow models and layers in `transformers` accept two formats as input: - - - having all inputs as keyword arguments (like PyTorch models), or - - having all inputs as a list, tuple or dict in the first positional argument. - - The reason the second format is supported is that Keras methods prefer this format when passing inputs to models - and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just - pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second - format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with - the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first - positional argument: - - - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` - - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: - `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` - - a dictionary with one or several input Tensors associated to the input names given in the docstring: - `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` - - Note that when creating models and layers with - [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry - about any of this, as you can just pass inputs like you would to any other Python function! - - - - Parameters: - config ([`XLNetConfig`]): Model configuration class with all the parameters of the model. - Initializing with a config file does not load the weights associated with the model, only the - configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. -""" - -XLNET_INPUTS_DOCSTRING = r""" - Args: - input_ids (`torch.LongTensor` of shape `({0})`): - Indices of input sequence tokens in the vocabulary. - - Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and - [`PreTrainedTokenizer.__call__`] for details. - - [What are input IDs?](../glossary#input-ids) - attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): - Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: - - - 1 for tokens that are **not masked**, - - 0 for tokens that are **masked**. - - [What are attention masks?](../glossary#attention-mask) - mems (`list[torch.FloatTensor]` of length `config.n_layers`): - Contains pre-computed hidden-states (see `mems` output below) . Can be used to speed up sequential - decoding. The token ids which have their past given to this model should not be passed as `input_ids` as - they have already been computed. - - `use_mems` has to be set to `True` to make use of `mems`. - perm_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length, sequence_length)`, *optional*): - Mask to indicate the attention pattern for each input token with values selected in `[0, 1]`: - - - if `perm_mask[k, i, j] = 0`, i attend to j in batch k; - - if `perm_mask[k, i, j] = 1`, i does not attend to j in batch k. - - If not set, each token attends to all the others (full bidirectional attention). Only used during - pretraining (to define factorization order) or for sequential decoding (generation). - target_mapping (`torch.FloatTensor` of shape `(batch_size, num_predict, sequence_length)`, *optional*): - Mask to indicate the output tokens to use. If `target_mapping[k, i, j] = 1`, the i-th predict in batch k is - on the j-th token. Only used during pretraining for partial prediction or for sequential decoding - (generation). - token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): - Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, - 1]`: - - - 0 corresponds to a *sentence A* token, - - 1 corresponds to a *sentence B* token. - - [What are token type IDs?](../glossary#token-type-ids) - input_mask (`torch.FloatTensor` of shape `{0}`, *optional*): - Mask to avoid performing attention on padding token indices. Negative of `attention_mask`, i.e. with 0 for - real tokens and 1 for padding which is kept for compatibility with the original code base. - - Mask values selected in `[0, 1]`: - - - 1 for tokens that are **masked**, - - 0 for tokens that are **not masked**. - - You can only uses one of `input_mask` and `attention_mask`. - head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): - Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: - - - 1 indicates the head is **not masked**, - - 0 indicates the head is **masked**. - - inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): - Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This - is useful if you want more control over how to convert `input_ids` indices into associated vectors than the - model's internal embedding lookup matrix. - output_attentions (`bool`, *optional*): - Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned - tensors for more detail. - output_hidden_states (`bool`, *optional*): - Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for - more detail. - return_dict (`bool`, *optional*): - Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. -""" - - -@add_start_docstrings( - "The bare XLNet Model transformer outputting raw hidden-states without any specific head on top.", - XLNET_START_DOCSTRING, -) -class TFXLNetModel(TFXLNetPreTrainedModel): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFXLNetMainLayer(config, name="transformer") - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFXLNetModelOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - mems: np.ndarray | tf.Tensor | None = None, - perm_mask: np.ndarray | tf.Tensor | None = None, - target_mapping: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - input_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_mems: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - training: bool = False, - ) -> TFXLNetModelOutput | tuple[tf.Tensor]: - outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - mems=mems, - perm_mask=perm_mask, - target_mapping=target_mapping, - token_type_ids=token_type_ids, - input_mask=input_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_mems=use_mems, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - - return outputs - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - - -@add_start_docstrings( - """ - XLNet Model with a language modeling head on top (linear layer with weights tied to the input embeddings). - """, - XLNET_START_DOCSTRING, -) -class TFXLNetLMHeadModel(TFXLNetPreTrainedModel, TFCausalLanguageModelingLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFXLNetMainLayer(config, name="transformer") - self.lm_loss = TFXLNetLMHead(config, self.transformer.word_embedding, name="lm_loss") - # generate fails to convert to a graph with XLNet - self.supports_xla_generation = False - - def get_lm_head(self): - return self.lm_loss - - def get_prefix_bias_name(self): - warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) - return self.name + "/" + self.lm_loss.name - - def prepare_inputs_for_generation(self, inputs, past_key_values=None, use_mems=None, **kwargs): - # Add dummy token at the end (no attention on this one) - effective_batch_size = inputs.shape[0] - dummy_token = tf.zeros((effective_batch_size, 1), dtype=inputs.dtype) - - # At every pass, the attention values for the new token and the two last generated tokens - # are computed, the rest is reloaded from the `past` cache. A purely auto-regressive model would have - # offset = 1; offset = 2 seems to have slightly better computation. - offset = 2 - - if past_key_values: - input_ids = tf.concat([inputs[:, -offset:], dummy_token], axis=1) - else: - input_ids = tf.concat([inputs, dummy_token], axis=1) - - # Build permutation mask so that previous tokens don't see last token - sequence_length = input_ids.shape[1] - perm_mask = tf.zeros((effective_batch_size, sequence_length, sequence_length - 1)) - perm_mask_seq_end = tf.ones((effective_batch_size, sequence_length, 1)) - perm_mask = tf.concat([perm_mask, perm_mask_seq_end], axis=-1) - - # We'll only predict the last token - target_mapping = tf.zeros((effective_batch_size, 1, sequence_length - 1)) - target_mapping_seq_end = tf.ones((effective_batch_size, 1, 1)) - target_mapping = tf.concat([target_mapping, target_mapping_seq_end], axis=-1) - - inputs = { - "input_ids": input_ids, - "perm_mask": perm_mask, - "target_mapping": target_mapping, - "use_mems": use_mems, - } - - # if past is defined in model kwargs then use it for faster decoding - if past_key_values: - inputs["mems"] = tuple(layer_past[:-offset, :, :] for layer_past in past_key_values) - - return inputs - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @replace_return_docstrings(output_type=TFXLNetLMHeadModelOutput, config_class=_CONFIG_FOR_DOC) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - mems: np.ndarray | tf.Tensor | None = None, - perm_mask: np.ndarray | tf.Tensor | None = None, - target_mapping: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - input_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_mems: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFXLNetLMHeadModelOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., - config.vocab_size - 1]`. - - Return: - - Examples: - - ```python - >>> import tensorflow as tf - >>> import numpy as np - >>> from transformers import AutoTokenizer, TFXLNetLMHeadModel - - >>> tokenizer = AutoTokenizer.from_pretrained("xlnet/xlnet-large-cased") - >>> model = TFXLNetLMHeadModel.from_pretrained("xlnet/xlnet-large-cased") - - >>> # We show how to setup inputs to predict a next token using a bi-directional context. - >>> input_ids = tf.constant(tokenizer.encode("Hello, my dog is very ", add_special_tokens=True))[ - ... None, : - ... ] # We will predict the masked token - - >>> perm_mask = np.zeros((1, input_ids.shape[1], input_ids.shape[1])) - >>> perm_mask[:, :, -1] = 1.0 # Previous tokens don't see last token - - >>> target_mapping = np.zeros( - ... (1, 1, input_ids.shape[1]) - ... ) # Shape [1, 1, seq_length] => let's predict one token - >>> target_mapping[ - ... 0, 0, -1 - ... ] = 1.0 # Our first (and only) prediction will be the last token of the sequence (the masked token) - - >>> outputs = model( - ... input_ids, - ... perm_mask=tf.constant(perm_mask, dtype=tf.float32), - ... target_mapping=tf.constant(target_mapping, dtype=tf.float32), - ... ) - - >>> next_token_logits = outputs[ - ... 0 - ... ] # Output has shape [target_mapping.size(0), target_mapping.size(1), config.vocab_size] - ```""" - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - mems=mems, - perm_mask=perm_mask, - target_mapping=target_mapping, - token_type_ids=token_type_ids, - input_mask=input_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_mems=use_mems, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - hidden_state = transformer_outputs[0] - logits = self.lm_loss(hidden_state, training=training) - - loss = None - if labels is not None: - loss = self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFXLNetLMHeadModelOutput( - loss=loss, - logits=logits, - mems=transformer_outputs.mems, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "lm_loss", None) is not None: - with tf.name_scope(self.lm_loss.name): - self.lm_loss.build(None) - - -@add_start_docstrings( - """ - XLNet Model with a sequence classification/regression head on top (a linear layer on top of the pooled output) e.g. - for GLUE tasks. - """, - XLNET_START_DOCSTRING, -) -class TFXLNetForSequenceClassification(TFXLNetPreTrainedModel, TFSequenceClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.transformer = TFXLNetMainLayer(config, name="transformer") - self.sequence_summary = TFSequenceSummary( - config, initializer_range=config.initializer_range, name="sequence_summary" - ) - self.logits_proj = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="logits_proj" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFXLNetForSequenceClassificationOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - mems: np.ndarray | tf.Tensor | None = None, - perm_mask: np.ndarray | tf.Tensor | None = None, - target_mapping: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - input_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_mems: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFXLNetForSequenceClassificationOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., - config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If - `config.num_labels > 1` a classification loss is computed (Cross-Entropy). - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - mems=mems, - perm_mask=perm_mask, - target_mapping=target_mapping, - token_type_ids=token_type_ids, - input_mask=input_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_mems=use_mems, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - output = transformer_outputs[0] - - output = self.sequence_summary(output) - logits = self.logits_proj(output) - - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFXLNetForSequenceClassificationOutput( - loss=loss, - logits=logits, - mems=transformer_outputs.mems, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "sequence_summary", None) is not None: - with tf.name_scope(self.sequence_summary.name): - self.sequence_summary.build(None) - if getattr(self, "logits_proj", None) is not None: - with tf.name_scope(self.logits_proj.name): - self.logits_proj.build([None, None, self.config.d_model]) - - -@add_start_docstrings( - """ - XLNET Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a - softmax) e.g. for RocStories/SWAG tasks. - """, - XLNET_START_DOCSTRING, -) -class TFXLNetForMultipleChoice(TFXLNetPreTrainedModel, TFMultipleChoiceLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - - self.transformer = TFXLNetMainLayer(config, name="transformer") - self.sequence_summary = TFSequenceSummary( - config, initializer_range=config.initializer_range, name="sequence_summary" - ) - self.logits_proj = keras.layers.Dense( - 1, kernel_initializer=get_initializer(config.initializer_range), name="logits_proj" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFXLNetForMultipleChoiceOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - input_mask: np.ndarray | tf.Tensor | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - mems: np.ndarray | tf.Tensor | None = None, - perm_mask: np.ndarray | tf.Tensor | None = None, - target_mapping: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_mems: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFXLNetForMultipleChoiceOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` - where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) - """ - - if input_ids is not None: - num_choices = shape_list(input_ids)[1] - seq_length = shape_list(input_ids)[2] - else: - num_choices = shape_list(inputs_embeds)[1] - seq_length = shape_list(inputs_embeds)[2] - - flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None - flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None - flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None - flat_input_mask = tf.reshape(input_mask, (-1, seq_length)) if input_mask is not None else None - flat_inputs_embeds = ( - tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) - if inputs_embeds is not None - else None - ) - transformer_outputs = self.transformer( - flat_input_ids, - flat_attention_mask, - mems, - perm_mask, - target_mapping, - flat_token_type_ids, - flat_input_mask, - head_mask, - flat_inputs_embeds, - use_mems, - output_attentions, - output_hidden_states, - return_dict=return_dict, - training=training, - ) - output = transformer_outputs[0] - logits = self.sequence_summary(output) - logits = self.logits_proj(logits) - reshaped_logits = tf.reshape(logits, (-1, num_choices)) - loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) - - if not return_dict: - output = (reshaped_logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFXLNetForMultipleChoiceOutput( - loss=loss, - logits=reshaped_logits, - mems=transformer_outputs.mems, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "sequence_summary", None) is not None: - with tf.name_scope(self.sequence_summary.name): - self.sequence_summary.build(None) - if getattr(self, "logits_proj", None) is not None: - with tf.name_scope(self.logits_proj.name): - self.logits_proj.build([None, None, self.config.d_model]) - - -@add_start_docstrings( - """ - XLNet Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for - Named-Entity-Recognition (NER) tasks. - """, - XLNET_START_DOCSTRING, -) -class TFXLNetForTokenClassification(TFXLNetPreTrainedModel, TFTokenClassificationLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.num_labels = config.num_labels - - self.transformer = TFXLNetMainLayer(config, name="transformer") - self.classifier = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFXLNetForTokenClassificationOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - mems: np.ndarray | tf.Tensor | None = None, - perm_mask: np.ndarray | tf.Tensor | None = None, - target_mapping: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - input_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_mems: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - labels: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFXLNetForTokenClassificationOutput | tuple[tf.Tensor]: - r""" - labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): - Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. - """ - - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - mems=mems, - perm_mask=perm_mask, - target_mapping=target_mapping, - token_type_ids=token_type_ids, - input_mask=input_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_mems=use_mems, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - output = transformer_outputs[0] - logits = self.classifier(output) - loss = None if labels is None else self.hf_compute_loss(labels, logits) - - if not return_dict: - output = (logits,) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFXLNetForTokenClassificationOutput( - loss=loss, - logits=logits, - mems=transformer_outputs.mems, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "classifier", None) is not None: - with tf.name_scope(self.classifier.name): - self.classifier.build([None, None, self.config.hidden_size]) - - -@add_start_docstrings( - """ - XLNet Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear - layers on top of the hidden-states output to compute `span start logits` and `span end logits`). - """, - XLNET_START_DOCSTRING, -) -class TFXLNetForQuestionAnsweringSimple(TFXLNetPreTrainedModel, TFQuestionAnsweringLoss): - def __init__(self, config, *inputs, **kwargs): - super().__init__(config, *inputs, **kwargs) - self.transformer = TFXLNetMainLayer(config, name="transformer") - self.qa_outputs = keras.layers.Dense( - config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" - ) - self.config = config - - @unpack_inputs - @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) - @add_code_sample_docstrings( - checkpoint=_CHECKPOINT_FOR_DOC, - output_type=TFXLNetForQuestionAnsweringSimpleOutput, - config_class=_CONFIG_FOR_DOC, - ) - def call( - self, - input_ids: TFModelInputType | None = None, - attention_mask: np.ndarray | tf.Tensor | None = None, - mems: np.ndarray | tf.Tensor | None = None, - perm_mask: np.ndarray | tf.Tensor | None = None, - target_mapping: np.ndarray | tf.Tensor | None = None, - token_type_ids: np.ndarray | tf.Tensor | None = None, - input_mask: np.ndarray | tf.Tensor | None = None, - head_mask: np.ndarray | tf.Tensor | None = None, - inputs_embeds: np.ndarray | tf.Tensor | None = None, - use_mems: bool | None = None, - output_attentions: bool | None = None, - output_hidden_states: bool | None = None, - return_dict: bool | None = None, - start_positions: np.ndarray | tf.Tensor | None = None, - end_positions: np.ndarray | tf.Tensor | None = None, - training: bool = False, - ) -> TFXLNetForQuestionAnsweringSimpleOutput | tuple[tf.Tensor]: - r""" - start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the start of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): - Labels for position (index) of the end of the labelled span for computing the token classification loss. - Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence - are not taken into account for computing the loss. - """ - transformer_outputs = self.transformer( - input_ids=input_ids, - attention_mask=attention_mask, - mems=mems, - perm_mask=perm_mask, - target_mapping=target_mapping, - token_type_ids=token_type_ids, - input_mask=input_mask, - head_mask=head_mask, - inputs_embeds=inputs_embeds, - use_mems=use_mems, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, - training=training, - ) - sequence_output = transformer_outputs[0] - - logits = self.qa_outputs(sequence_output) - start_logits, end_logits = tf.split(logits, 2, axis=-1) - start_logits = tf.squeeze(start_logits, axis=-1) - end_logits = tf.squeeze(end_logits, axis=-1) - - loss = None - if start_positions is not None and end_positions is not None: - labels = {"start_position": start_positions} - labels["end_position"] = end_positions - loss = self.hf_compute_loss(labels, (start_logits, end_logits)) - - if not return_dict: - output = (start_logits, end_logits) + transformer_outputs[1:] - return ((loss,) + output) if loss is not None else output - - return TFXLNetForQuestionAnsweringSimpleOutput( - loss=loss, - start_logits=start_logits, - end_logits=end_logits, - mems=transformer_outputs.mems, - hidden_states=transformer_outputs.hidden_states, - attentions=transformer_outputs.attentions, - ) - - def build(self, input_shape=None): - if self.built: - return - self.built = True - if getattr(self, "transformer", None) is not None: - with tf.name_scope(self.transformer.name): - self.transformer.build(None) - if getattr(self, "qa_outputs", None) is not None: - with tf.name_scope(self.qa_outputs.name): - self.qa_outputs.build([None, None, self.config.hidden_size]) - - -__all__ = [ - "TFXLNetForMultipleChoice", - "TFXLNetForQuestionAnsweringSimple", - "TFXLNetForSequenceClassification", - "TFXLNetForTokenClassification", - "TFXLNetLMHeadModel", - "TFXLNetMainLayer", - "TFXLNetModel", - "TFXLNetPreTrainedModel", -] diff --git a/src/transformers/models/xlnet/modeling_xlnet.py b/src/transformers/models/xlnet/modeling_xlnet.py index 0c6b9f76eade..c5ede2870711 100755 --- a/src/transformers/models/xlnet/modeling_xlnet.py +++ b/src/transformers/models/xlnet/modeling_xlnet.py @@ -36,156 +36,6 @@ logger = logging.get_logger(__name__) -def build_tf_xlnet_to_pytorch_map(model, config, tf_weights=None): - """ - A map of modules from TF to PyTorch. I use a map to keep the PyTorch model as identical to the original PyTorch - model as possible. - """ - - tf_to_pt_map = {} - - if hasattr(model, "transformer"): - if hasattr(model, "lm_loss"): - # We will load also the output bias - tf_to_pt_map["model/lm_loss/bias"] = model.lm_loss.bias - if hasattr(model, "sequence_summary") and "model/sequnece_summary/summary/kernel" in tf_weights: - # We will load also the sequence summary - tf_to_pt_map["model/sequnece_summary/summary/kernel"] = model.sequence_summary.summary.weight - tf_to_pt_map["model/sequnece_summary/summary/bias"] = model.sequence_summary.summary.bias - if ( - hasattr(model, "logits_proj") - and config.finetuning_task is not None - and f"model/regression_{config.finetuning_task}/logit/kernel" in tf_weights - ): - tf_to_pt_map[f"model/regression_{config.finetuning_task}/logit/kernel"] = model.logits_proj.weight - tf_to_pt_map[f"model/regression_{config.finetuning_task}/logit/bias"] = model.logits_proj.bias - - # Now load the rest of the transformer - model = model.transformer - - # Embeddings and output - tf_to_pt_map.update( - { - "model/transformer/word_embedding/lookup_table": model.word_embedding.weight, - "model/transformer/mask_emb/mask_emb": model.mask_emb, - } - ) - - # Transformer blocks - for i, b in enumerate(model.layer): - layer_str = f"model/transformer/layer_{i}/" - tf_to_pt_map.update( - { - layer_str + "rel_attn/LayerNorm/gamma": b.rel_attn.layer_norm.weight, - layer_str + "rel_attn/LayerNorm/beta": b.rel_attn.layer_norm.bias, - layer_str + "rel_attn/o/kernel": b.rel_attn.o, - layer_str + "rel_attn/q/kernel": b.rel_attn.q, - layer_str + "rel_attn/k/kernel": b.rel_attn.k, - layer_str + "rel_attn/r/kernel": b.rel_attn.r, - layer_str + "rel_attn/v/kernel": b.rel_attn.v, - layer_str + "ff/LayerNorm/gamma": b.ff.layer_norm.weight, - layer_str + "ff/LayerNorm/beta": b.ff.layer_norm.bias, - layer_str + "ff/layer_1/kernel": b.ff.layer_1.weight, - layer_str + "ff/layer_1/bias": b.ff.layer_1.bias, - layer_str + "ff/layer_2/kernel": b.ff.layer_2.weight, - layer_str + "ff/layer_2/bias": b.ff.layer_2.bias, - } - ) - - # Relative positioning biases - if config.untie_r: - r_r_list = [] - r_w_list = [] - r_s_list = [] - seg_embed_list = [] - for b in model.layer: - r_r_list.append(b.rel_attn.r_r_bias) - r_w_list.append(b.rel_attn.r_w_bias) - r_s_list.append(b.rel_attn.r_s_bias) - seg_embed_list.append(b.rel_attn.seg_embed) - else: - r_r_list = [model.r_r_bias] - r_w_list = [model.r_w_bias] - r_s_list = [model.r_s_bias] - seg_embed_list = [model.seg_embed] - tf_to_pt_map.update( - { - "model/transformer/r_r_bias": r_r_list, - "model/transformer/r_w_bias": r_w_list, - "model/transformer/r_s_bias": r_s_list, - "model/transformer/seg_embed": seg_embed_list, - } - ) - return tf_to_pt_map - - -def load_tf_weights_in_xlnet(model, config, tf_path): - """Load tf checkpoints in a pytorch model""" - try: - import numpy as np - import tensorflow as tf - except ImportError: - logger.error( - "Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see " - "https://www.tensorflow.org/install/ for installation instructions." - ) - raise - # Load weights from TF model - init_vars = tf.train.list_variables(tf_path) - tf_weights = {} - for name, shape in init_vars: - logger.info(f"Loading TF weight {name} with shape {shape}") - array = tf.train.load_variable(tf_path, name) - tf_weights[name] = array - - # Build TF to PyTorch weights loading map - tf_to_pt_map = build_tf_xlnet_to_pytorch_map(model, config, tf_weights) - - for name, pointer in tf_to_pt_map.items(): - logger.info(f"Importing {name}") - if name not in tf_weights: - logger.info(f"{name} not in tf pre-trained weights, skipping") - continue - array = tf_weights[name] - # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v - # which are not required for using pretrained model - if "kernel" in name and ("ff" in name or "summary" in name or "logit" in name): - logger.info("Transposing") - array = np.transpose(array) - if isinstance(pointer, list): - # Here we will split the TF weights - assert len(pointer) == array.shape[0], ( - f"Pointer length {len(pointer)} and array length {array.shape[0]} mismatched" - ) - for i, p_i in enumerate(pointer): - arr_i = array[i, ...] - try: - assert p_i.shape == arr_i.shape, ( - f"Pointer shape {p_i.shape} and array shape {arr_i.shape} mismatched" - ) - except AssertionError as e: - e.args += (p_i.shape, arr_i.shape) - raise - logger.info(f"Initialize PyTorch weight {name} for layer {i}") - p_i.data = torch.from_numpy(arr_i) - else: - try: - assert pointer.shape == array.shape, ( - f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched" - ) - except AssertionError as e: - e.args += (pointer.shape, array.shape) - raise - logger.info(f"Initialize PyTorch weight {name}") - pointer.data = torch.from_numpy(array) - tf_weights.pop(name, None) - tf_weights.pop(name + "/Adam", None) - tf_weights.pop(name + "/Adam_1", None) - - logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}") - return model - - class XLNetRelativeAttention(nn.Module): def __init__(self, config): super().__init__() @@ -797,14 +647,11 @@ def forward( @auto_docstring class XLNetPreTrainedModel(PreTrainedModel): config: XLNetConfig - load_tf_weights = load_tf_weights_in_xlnet base_model_prefix = "transformer" def _init_weights(self, module): """Initialize the weights.""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -2385,5 +2232,4 @@ def forward( "XLNetLMHeadModel", "XLNetModel", "XLNetPreTrainedModel", - "load_tf_weights_in_xlnet", ] diff --git a/src/transformers/models/xmod/modeling_xmod.py b/src/transformers/models/xmod/modeling_xmod.py index 7c8328447cb0..f7242a64d5d4 100644 --- a/src/transformers/models/xmod/modeling_xmod.py +++ b/src/transformers/models/xmod/modeling_xmod.py @@ -58,8 +58,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized @@ -625,8 +623,6 @@ class XmodPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/yolos/image_processing_yolos.py b/src/transformers/models/yolos/image_processing_yolos.py index 48a1300191af..50da604db8d3 100644 --- a/src/transformers/models/yolos/image_processing_yolos.py +++ b/src/transformers/models/yolos/image_processing_yolos.py @@ -16,7 +16,7 @@ import pathlib from collections.abc import Iterable -from typing import Any, Callable, Optional, Union +from typing import Any, Optional, Union import numpy as np @@ -53,11 +53,7 @@ ) from ...utils import ( TensorType, - is_flax_available, - is_jax_tensor, is_scipy_available, - is_tf_available, - is_tf_tensor, is_torch_available, is_torch_tensor, is_vision_available, @@ -217,31 +213,6 @@ def get_resize_output_image_size( return get_size_with_aspect_ratio(image_size, size, max_size) -# Copied from transformers.models.detr.image_processing_detr.get_numpy_to_framework_fn -def get_numpy_to_framework_fn(arr) -> Callable: - """ - Returns a function that converts a numpy array to the framework of the input array. - - Args: - arr (`np.ndarray`): The array to convert. - """ - if isinstance(arr, np.ndarray): - return np.array - if is_tf_available() and is_tf_tensor(arr): - import tensorflow as tf - - return tf.convert_to_tensor - if is_torch_available() and is_torch_tensor(arr): - import torch - - return torch.tensor - if is_flax_available() and is_jax_tensor(arr): - import jax.numpy as jnp - - return jnp.array - raise ValueError(f"Cannot convert arrays of type {type(arr)}") - - # Copied from transformers.models.detr.image_processing_detr.safe_squeeze def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: """ @@ -1119,10 +1090,8 @@ def pad( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`str` or `ChannelDimension`, *optional*): The channel dimension format of the image. If not provided, it will be the same as the input image. input_data_format (`ChannelDimension` or `str`, *optional*): @@ -1304,10 +1273,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor.") # Here the pad() method pads using the max of (width, height) and does not need to be validated. validate_preprocess_arguments( do_rescale=do_rescale, @@ -1436,12 +1402,11 @@ def preprocess( return encoded_inputs - # POSTPROCESSING METHODS - TODO: add support for other frameworks # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.post_process with Detr->Yolos def post_process(self, outputs, target_sizes): """ Converts the raw output of [`YolosForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y, - bottom_right_x, bottom_right_y) format. Only supports PyTorch. + bottom_right_x, bottom_right_y) format. Args: outputs ([`YolosObjectDetectionOutput`]): diff --git a/src/transformers/models/yolos/modeling_yolos.py b/src/transformers/models/yolos/modeling_yolos.py index 13fd9886ea96..7677dcae64a7 100755 --- a/src/transformers/models/yolos/modeling_yolos.py +++ b/src/transformers/models/yolos/modeling_yolos.py @@ -471,8 +471,6 @@ class YolosPreTrainedModel(PreTrainedModel): def _init_weights(self, module: Union[nn.Linear, nn.Conv2d, nn.LayerNorm]) -> None: """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/yoso/modeling_yoso.py b/src/transformers/models/yoso/modeling_yoso.py index 0ad53b81f492..b1d8e5e752a1 100644 --- a/src/transformers/models/yoso/modeling_yoso.py +++ b/src/transformers/models/yoso/modeling_yoso.py @@ -237,8 +237,6 @@ def __init__(self, config): self.position_embeddings = nn.Embedding(config.max_position_embeddings + 2, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load - # any TensorFlow checkpoint file self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -646,8 +644,6 @@ def _init_weights(self, module: nn.Module): """Initialize the weights""" std = self.config.initializer_range if isinstance(module, nn.Linear): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=std) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/models/zoedepth/image_processing_zoedepth.py b/src/transformers/models/zoedepth/image_processing_zoedepth.py index 973b5279822c..1ef2b8a59ec1 100644 --- a/src/transformers/models/zoedepth/image_processing_zoedepth.py +++ b/src/transformers/models/zoedepth/image_processing_zoedepth.py @@ -357,10 +357,8 @@ def preprocess( return_tensors (`str` or `TensorType`, *optional*): The type of tensors to return. Can be one of: - Unset: Return a list of `np.ndarray`. - - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. - - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): The channel dimension format for the output image. Can be one of: - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. @@ -388,10 +386,7 @@ def preprocess( images = make_flat_list_of_images(images) if not valid_images(images): - raise ValueError( - "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " - "torch.Tensor, tf.Tensor or jax.ndarray." - ) + raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") validate_preprocess_arguments( do_rescale=do_rescale, rescale_factor=rescale_factor, diff --git a/src/transformers/models/zoedepth/modeling_zoedepth.py b/src/transformers/models/zoedepth/modeling_zoedepth.py index 7bbad31c2ee0..f03804c2c57b 100644 --- a/src/transformers/models/zoedepth/modeling_zoedepth.py +++ b/src/transformers/models/zoedepth/modeling_zoedepth.py @@ -1213,8 +1213,6 @@ class ZoeDepthPreTrainedModel(PreTrainedModel): def _init_weights(self, module): """Initialize the weights""" if isinstance(module, (nn.Linear, nn.Conv2d, nn.ConvTranspose2d)): - # Slightly different from the TF version which uses truncated_normal for initialization - # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() diff --git a/src/transformers/onnx/__main__.py b/src/transformers/onnx/__main__.py index e3dc6dfb78aa..db43126fd3fb 100644 --- a/src/transformers/onnx/__main__.py +++ b/src/transformers/onnx/__main__.py @@ -53,7 +53,6 @@ def export_with_optimum(args): "optimum.exporters.onnx", f"--model {args.model}", f"--task {args.feature}", - f"--framework {args.framework}" if args.framework is not None else "", f"{args.output}", ] proc = subprocess.Popen(cmd_line, stdout=subprocess.PIPE) @@ -72,9 +71,7 @@ def export_with_transformers(args): args.output.parent.mkdir(parents=True) # Allocate the model - model = FeaturesManager.get_model_from_feature( - args.feature, args.model, framework=args.framework, cache_dir=args.cache_dir - ) + model = FeaturesManager.get_model_from_feature(args.feature, args.model, cache_dir=args.cache_dir) model_kind, model_onnx_config = FeaturesManager.check_supported_model_or_raise(model, feature=args.feature) onnx_config = model_onnx_config(model.config) @@ -199,17 +196,6 @@ def main(): parser.add_argument( "--atol", type=float, default=None, help="Absolute difference tolerance when validating the model." ) - parser.add_argument( - "--framework", - type=str, - choices=["pt", "tf"], - default=None, - help=( - "The framework to use for the ONNX export." - " If not provided, will attempt to use the local checkpoint's original framework" - " or what is available in the environment." - ), - ) parser.add_argument("output", type=Path, help="Path indicating where to store generated ONNX model.") parser.add_argument("--cache_dir", type=str, default=None, help="Path indicating where to store cache.") parser.add_argument( diff --git a/src/transformers/onnx/config.py b/src/transformers/onnx/config.py index 2a47127b3855..46c9d32b7341 100644 --- a/src/transformers/onnx/config.py +++ b/src/transformers/onnx/config.py @@ -22,7 +22,7 @@ import numpy as np from packaging import version -from ..utils import TensorType, is_torch_available, is_vision_available, logging +from ..utils import is_torch_available, is_vision_available, logging from .utils import ParameterFormat, compute_effective_axis_dimension, compute_serialized_parameters_size @@ -287,7 +287,6 @@ def generate_dummy_inputs( seq_length: int = -1, num_choices: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, num_channels: int = 3, image_width: int = 40, image_height: int = 40, @@ -297,7 +296,7 @@ def generate_dummy_inputs( tokenizer: Optional["PreTrainedTokenizerBase"] = None, ) -> Mapping[str, Any]: """ - Generate inputs to provide to the ONNX exporter for the specific framework + Generate inputs to provide to the ONNX exporter Args: preprocessor: ([`PreTrainedTokenizerBase`], [`FeatureExtractionMixin`], or [`ImageProcessingMixin`]): @@ -310,8 +309,6 @@ def generate_dummy_inputs( The sequence length to export the model for (-1 means dynamic axis). is_pair (`bool`, *optional*, defaults to `False`): Indicate if the input is a pair (sentence 1, sentence 2) - framework (`TensorType`, *optional*, defaults to `None`): - The framework (PyTorch or TensorFlow) that the tokenizer will generate tensors for. num_channels (`int`, *optional*, defaults to 3): The number of channels of the generated images. image_width (`int`, *optional*, defaults to 40): @@ -371,8 +368,8 @@ def generate_dummy_inputs( # Unflatten the tokenized inputs values expanding it to the shape [batch_size, num_choices, seq_length] for k, v in tokenized_input.items(): tokenized_input[k] = [v[i : i + num_choices] for i in range(0, len(v), num_choices)] - return dict(tokenized_input.convert_to_tensors(tensor_type=framework)) - return dict(preprocessor(dummy_input, return_tensors=framework)) + return dict(tokenized_input.convert_to_tensors(tensor_type="pt")) + return dict(preprocessor(dummy_input, return_tensors="pt")) elif isinstance(preprocessor, ImageProcessingMixin): if preprocessor.model_input_names[0] != "pixel_values": raise ValueError( @@ -382,19 +379,19 @@ def generate_dummy_inputs( # If dynamic axis (-1) we forward with a fixed dimension of 2 samples to avoid optimizations made by ONNX batch_size = compute_effective_axis_dimension(batch_size, fixed_dimension=OnnxConfig.default_fixed_batch) dummy_input = self._generate_dummy_images(batch_size, num_channels, image_height, image_width) - return dict(preprocessor(images=dummy_input, return_tensors=framework)) + return dict(preprocessor(images=dummy_input, return_tensors="pt")) elif isinstance(preprocessor, FeatureExtractionMixin) and preprocessor.model_input_names[0] == "pixel_values": # If dynamic axis (-1) we forward with a fixed dimension of 2 samples to avoid optimizations made by ONNX batch_size = compute_effective_axis_dimension(batch_size, fixed_dimension=OnnxConfig.default_fixed_batch) dummy_input = self._generate_dummy_images(batch_size, num_channels, image_height, image_width) - return dict(preprocessor(images=dummy_input, return_tensors=framework)) + return dict(preprocessor(images=dummy_input, return_tensors="pt")) elif ( isinstance(preprocessor, FeatureExtractionMixin) and preprocessor.model_input_names[0] == "input_features" ): # If dynamic axis (-1) we forward with a fixed dimension of 2 samples to avoid optimizations made by ONNX batch_size = compute_effective_axis_dimension(batch_size, fixed_dimension=OnnxConfig.default_fixed_batch) dummy_input = self._generate_dummy_audio(batch_size, sampling_rate, time_duration, frequency) - return dict(preprocessor(dummy_input, return_tensors=framework)) + return dict(preprocessor(dummy_input, return_tensors="pt")) else: raise ValueError( "Unable to generate dummy inputs for the model. Please provide a tokenizer or a preprocessor." @@ -514,11 +511,13 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: # TODO: should we set seq_length = 1 when self.use_past = True? common_inputs = super().generate_dummy_inputs( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, + batch_size=batch_size, + seq_length=seq_length, + is_pair=is_pair, ) if self.use_past: @@ -646,16 +645,21 @@ def generate_dummy_inputs( batch_size: int = -1, seq_length: int = -1, is_pair: bool = False, - framework: Optional[TensorType] = None, ) -> Mapping[str, Any]: encoder_inputs = super(OnnxConfigWithPast, self).generate_dummy_inputs( - tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + tokenizer, + batch_size=batch_size, + seq_length=seq_length, + is_pair=is_pair, ) # Generate decoder inputs decoder_seq_length = seq_length if not self.use_past else 1 decoder_inputs = super(OnnxConfigWithPast, self).generate_dummy_inputs( - tokenizer, batch_size=batch_size, seq_length=decoder_seq_length, is_pair=is_pair, framework=framework + tokenizer, + batch_size=batch_size, + seq_length=decoder_seq_length, + is_pair=is_pair, ) decoder_inputs = {f"decoder_{name}": tensor for name, tensor in decoder_inputs.items()} common_inputs = dict(**encoder_inputs, **decoder_inputs) diff --git a/src/transformers/onnx/convert.py b/src/transformers/onnx/convert.py index 778fa7046f7d..bcf7fc878890 100644 --- a/src/transformers/onnx/convert.py +++ b/src/transformers/onnx/convert.py @@ -24,8 +24,6 @@ from ..tokenization_utils_base import PreTrainedTokenizerBase from ..utils import ( - TensorType, - is_tf_available, is_torch_available, logging, ) @@ -35,9 +33,6 @@ if is_torch_available(): from ..modeling_utils import PreTrainedModel -if is_tf_available(): - from ..modeling_tf_utils import TFPreTrainedModel - if TYPE_CHECKING: from ..feature_extraction_utils import FeatureExtractionMixin from ..processing_utils import ProcessorMixin @@ -126,7 +121,6 @@ def export_pytorch( import torch from torch.onnx import export as onnx_export - logger.info(f"Using framework PyTorch: {torch.__version__}") with torch.no_grad(): model.config.return_dict = True model.eval() @@ -140,7 +134,7 @@ def export_pytorch( # Ensure inputs match # TODO: Check when exporting QA we provide "is_pair=True" - model_inputs = config.generate_dummy_inputs(preprocessor, framework=TensorType.PYTORCH) + model_inputs = config.generate_dummy_inputs(preprocessor) device = torch.device(device) if device.type == "cuda" and torch.cuda.is_available(): model.to(device) @@ -183,75 +177,9 @@ def export_pytorch( return matched_inputs, onnx_outputs -def export_tensorflow( - preprocessor: Union["PreTrainedTokenizer", "FeatureExtractionMixin"], - model: "TFPreTrainedModel", - config: OnnxConfig, - opset: int, - output: Path, - tokenizer: Optional["PreTrainedTokenizer"] = None, -) -> tuple[list[str], list[str]]: - """ - Export a TensorFlow model to an ONNX Intermediate Representation (IR) - - Args: - preprocessor: ([`PreTrainedTokenizer`] or [`FeatureExtractionMixin`]): - The preprocessor used for encoding the data. - model ([`TFPreTrainedModel`]): - The model to export. - config ([`~onnx.config.OnnxConfig`]): - The ONNX configuration associated with the exported model. - opset (`int`): - The version of the ONNX operator set to use. - output (`Path`): - Directory to store the exported ONNX model. - - Returns: - `tuple[list[str], list[str]]`: A tuple with an ordered list of the model's inputs, and the named inputs from - the ONNX configuration. - """ - import onnx - import tensorflow as tf - import tf2onnx - - if isinstance(preprocessor, PreTrainedTokenizerBase) and tokenizer is not None: - raise ValueError("You cannot provide both a tokenizer and preprocessor to export the model.") - if tokenizer is not None: - warnings.warn( - "The `tokenizer` argument is deprecated and will be removed in version 5 of Transformers. Use" - " `preprocessor` instead.", - FutureWarning, - ) - logger.info("Overwriting the `preprocessor` argument with `tokenizer` to generate dummy inputs.") - preprocessor = tokenizer - - model.config.return_dict = True - - # Check if we need to override certain configuration item - if config.values_override is not None: - logger.info(f"Overriding {len(config.values_override)} configuration item(s)") - for override_config_key, override_config_value in config.values_override.items(): - logger.info(f"\t- {override_config_key} -> {override_config_value}") - setattr(model.config, override_config_key, override_config_value) - - # Ensure inputs match - model_inputs = config.generate_dummy_inputs(preprocessor, framework=TensorType.TENSORFLOW) - inputs_match, matched_inputs = ensure_model_and_config_inputs_match(model, model_inputs.keys()) - onnx_outputs = list(config.outputs.keys()) - - input_signature = [ - tf.TensorSpec([None] * tensor.ndim, dtype=tensor.dtype, name=key) for key, tensor in model_inputs.items() - ] - onnx_model, _ = tf2onnx.convert.from_keras(model, input_signature, opset=opset) - onnx.save(onnx_model, output.as_posix()) - config.restore_ops() - - return matched_inputs, onnx_outputs - - def export( preprocessor: Union["PreTrainedTokenizer", "FeatureExtractionMixin", "ProcessorMixin"], - model: Union["PreTrainedModel", "TFPreTrainedModel"], + model: "PreTrainedModel", config: OnnxConfig, opset: int, output: Path, @@ -259,12 +187,12 @@ def export( device: str = "cpu", ) -> tuple[list[str], list[str]]: """ - Export a Pytorch or TensorFlow model to an ONNX Intermediate Representation (IR) + Export a Pytorch model to an ONNX Intermediate Representation (IR) Args: preprocessor: ([`PreTrainedTokenizer`], [`FeatureExtractionMixin`] or [`ProcessorMixin`]): The preprocessor used for encoding the data. - model ([`PreTrainedModel`] or [`TFPreTrainedModel`]): + model ([`PreTrainedModel`): The model to export. config ([`~onnx.config.OnnxConfig`]): The ONNX configuration associated with the exported model. @@ -280,14 +208,8 @@ def export( `tuple[list[str], list[str]]`: A tuple with an ordered list of the model's inputs, and the named inputs from the ONNX configuration. """ - if not (is_torch_available() or is_tf_available()): - raise ImportError( - "Cannot convert because neither PyTorch nor TensorFlow are not installed. " - "Please install torch or tensorflow first." - ) - - if is_tf_available() and isinstance(model, TFPreTrainedModel) and device == "cuda": - raise RuntimeError("`tf2onnx` does not support export on CUDA device.") + if not is_torch_available(): + raise ImportError("Cannot convert because PyTorchis not installed. Please install it first.") if isinstance(preprocessor, PreTrainedTokenizerBase) and tokenizer is not None: raise ValueError("You cannot provide both a tokenizer and a preprocessor to export the model.") @@ -300,25 +222,22 @@ def export( logger.info("Overwriting the `preprocessor` argument with `tokenizer` to generate dummy inputs.") preprocessor = tokenizer - if is_torch_available(): - from ..utils import get_torch_version + from ..utils import get_torch_version - if not config.is_torch_support_available: - logger.warning( - f"Unsupported PyTorch version for this model. Minimum required is {config.torch_onnx_minimum_version}," - f" got: {get_torch_version()}" - ) + if not config.is_torch_support_available: + logger.warning( + f"Unsupported PyTorch version for this model. Minimum required is {config.torch_onnx_minimum_version}," + f" got: {get_torch_version()}" + ) - if is_torch_available() and issubclass(type(model), PreTrainedModel): + if issubclass(type(model), PreTrainedModel): return export_pytorch(preprocessor, model, config, opset, output, tokenizer=tokenizer, device=device) - elif is_tf_available() and issubclass(type(model), TFPreTrainedModel): - return export_tensorflow(preprocessor, model, config, opset, output, tokenizer=tokenizer) def validate_model_outputs( config: OnnxConfig, preprocessor: Union["PreTrainedTokenizer", "FeatureExtractionMixin", "ProcessorMixin"], - reference_model: Union["PreTrainedModel", "TFPreTrainedModel"], + reference_model: "PreTrainedModel", onnx_model: Path, onnx_named_outputs: list[str], atol: float, @@ -341,19 +260,11 @@ def validate_model_outputs( # generate inputs with a different batch_size and seq_len that was used for conversion to properly test # dynamic input shapes. - if is_torch_available() and issubclass(type(reference_model), PreTrainedModel): + if issubclass(type(reference_model), PreTrainedModel): reference_model_inputs = config.generate_dummy_inputs( preprocessor, batch_size=config.default_fixed_batch + 1, seq_length=config.default_fixed_sequence + 1, - framework=TensorType.PYTORCH, - ) - else: - reference_model_inputs = config.generate_dummy_inputs( - preprocessor, - batch_size=config.default_fixed_batch + 1, - seq_length=config.default_fixed_sequence + 1, - framework=TensorType.TENSORFLOW, ) # Create ONNX Runtime session @@ -361,7 +272,7 @@ def validate_model_outputs( session = InferenceSession(onnx_model.as_posix(), options, providers=["CPUExecutionProvider"]) # Compute outputs from the reference model - if is_torch_available() and issubclass(type(reference_model), PreTrainedModel): + if issubclass(type(reference_model), PreTrainedModel): reference_model.to("cpu") ref_outputs = reference_model(**reference_model_inputs) ref_outputs_dict = {} @@ -439,16 +350,12 @@ def validate_model_outputs( def ensure_model_and_config_inputs_match( - model: Union["PreTrainedModel", "TFPreTrainedModel"], model_inputs: Iterable[str] + model: "PreTrainedModel", model_inputs: Iterable[str] ) -> tuple[bool, list[str]]: """ - :param model_inputs: :param config_inputs: :return: """ - if is_torch_available() and issubclass(type(model), PreTrainedModel): - forward_parameters = signature(model.forward).parameters - else: - forward_parameters = signature(model.call).parameters + forward_parameters = signature(model.forward).parameters model_inputs_set = set(model_inputs) # We are fine if config_inputs has more keys than model_inputs diff --git a/src/transformers/onnx/features.py b/src/transformers/onnx/features.py index a24aa79a5968..1c57c68e8c87 100644 --- a/src/transformers/onnx/features.py +++ b/src/transformers/onnx/features.py @@ -1,16 +1,15 @@ -import os from functools import partial, reduce -from typing import TYPE_CHECKING, Callable, Optional, Union +from typing import TYPE_CHECKING, Callable, Optional import transformers -from .. import PretrainedConfig, is_tf_available, is_torch_available -from ..utils import TF2_WEIGHTS_NAME, WEIGHTS_NAME, logging +from .. import PretrainedConfig, is_torch_available +from ..utils import logging from .config import OnnxConfig if TYPE_CHECKING: - from transformers import PreTrainedModel, TFPreTrainedModel + from transformers import PreTrainedModel logger = logging.get_logger(__name__) # pylint: disable=invalid-name @@ -33,22 +32,9 @@ AutoModelForTokenClassification, AutoModelForVision2Seq, ) -if is_tf_available(): - from transformers.models.auto import ( - TFAutoModel, - TFAutoModelForCausalLM, - TFAutoModelForMaskedLM, - TFAutoModelForMultipleChoice, - TFAutoModelForQuestionAnswering, - TFAutoModelForSemanticSegmentation, - TFAutoModelForSeq2SeqLM, - TFAutoModelForSequenceClassification, - TFAutoModelForTokenClassification, - ) -if not is_torch_available() and not is_tf_available(): +else: logger.warning( - "The ONNX export features are only supported for PyTorch or TensorFlow. You will not be able to export models" - " without one of these libraries installed." + "The ONNX export features is only supported for PyTorch. You will not be able to export models without it installed." ) @@ -84,7 +70,6 @@ def supported_features_mapping( class FeaturesManager: _TASKS_TO_AUTOMODELS = {} - _TASKS_TO_TF_AUTOMODELS = {} if is_torch_available(): _TASKS_TO_AUTOMODELS = { "default": AutoModel, @@ -103,18 +88,6 @@ class FeaturesManager: "vision2seq-lm": AutoModelForVision2Seq, "speech2seq-lm": AutoModelForSpeechSeq2Seq, } - if is_tf_available(): - _TASKS_TO_TF_AUTOMODELS = { - "default": TFAutoModel, - "masked-lm": TFAutoModelForMaskedLM, - "causal-lm": TFAutoModelForCausalLM, - "seq2seq-lm": TFAutoModelForSeq2SeqLM, - "sequence-classification": TFAutoModelForSequenceClassification, - "token-classification": TFAutoModelForTokenClassification, - "multiple-choice": TFAutoModelForMultipleChoice, - "question-answering": TFAutoModelForQuestionAnswering, - "semantic-segmentation": TFAutoModelForSemanticSegmentation, - } # Set of model topologies we support associated to the features supported by each topology and the factory _SUPPORTED_MODEL_TYPE = { @@ -584,40 +557,19 @@ def feature_to_task(feature: str) -> str: return feature.replace("-with-past", "") @staticmethod - def _validate_framework_choice(framework: str): - """ - Validates if the framework requested for the export is both correct and available, otherwise throws an - exception. - """ - if framework not in ["pt", "tf"]: - raise ValueError( - f"Only two frameworks are supported for ONNX export: pt or tf, but {framework} was provided." - ) - elif framework == "pt" and not is_torch_available(): - raise RuntimeError("Cannot export model to ONNX using PyTorch because no PyTorch package was found.") - elif framework == "tf" and not is_tf_available(): - raise RuntimeError("Cannot export model to ONNX using TensorFlow because no TensorFlow package was found.") - - @staticmethod - def get_model_class_for_feature(feature: str, framework: str = "pt") -> type: + def get_model_class_for_feature(feature: str) -> type: """ Attempts to retrieve an AutoModel class from a feature name. Args: feature (`str`): The feature required. - framework (`str`, *optional*, defaults to `"pt"`): - The framework to use for the export. Returns: The AutoModel class corresponding to the feature. """ task = FeaturesManager.feature_to_task(feature) - FeaturesManager._validate_framework_choice(framework) - if framework == "pt": - task_to_automodel = FeaturesManager._TASKS_TO_AUTOMODELS - else: - task_to_automodel = FeaturesManager._TASKS_TO_TF_AUTOMODELS + task_to_automodel = FeaturesManager._TASKS_TO_AUTOMODELS if task not in task_to_automodel: raise KeyError( f"Unknown task: {feature}. Possible values are {list(FeaturesManager._TASKS_TO_AUTOMODELS.values())}" @@ -626,59 +578,7 @@ def get_model_class_for_feature(feature: str, framework: str = "pt") -> type: return task_to_automodel[task] @staticmethod - def determine_framework(model: str, framework: Optional[str] = None) -> str: - """ - Determines the framework to use for the export. - - The priority is in the following order: - 1. User input via `framework`. - 2. If local checkpoint is provided, use the same framework as the checkpoint. - 3. Available framework in environment, with priority given to PyTorch - - Args: - model (`str`): - The name of the model to export. - framework (`str`, *optional*, defaults to `None`): - The framework to use for the export. See above for priority if none provided. - - Returns: - The framework to use for the export. - - """ - if framework is not None: - return framework - - framework_map = {"pt": "PyTorch", "tf": "TensorFlow"} - exporter_map = {"pt": "torch", "tf": "tf2onnx"} - - if os.path.isdir(model): - if os.path.isfile(os.path.join(model, WEIGHTS_NAME)): - framework = "pt" - elif os.path.isfile(os.path.join(model, TF2_WEIGHTS_NAME)): - framework = "tf" - else: - raise FileNotFoundError( - "Cannot determine framework from given checkpoint location." - f" There should be a {WEIGHTS_NAME} for PyTorch" - f" or {TF2_WEIGHTS_NAME} for TensorFlow." - ) - logger.info(f"Local {framework_map[framework]} model found.") - else: - if is_torch_available(): - framework = "pt" - elif is_tf_available(): - framework = "tf" - else: - raise OSError("Neither PyTorch nor TensorFlow found in environment. Cannot export to ONNX.") - - logger.info(f"Framework not requested. Using {exporter_map[framework]} to export to ONNX.") - - return framework - - @staticmethod - def get_model_from_feature( - feature: str, model: str, framework: Optional[str] = None, cache_dir: Optional[str] = None - ) -> Union["PreTrainedModel", "TFPreTrainedModel"]: + def get_model_from_feature(feature: str, model: str, cache_dir: Optional[str] = None) -> "PreTrainedModel": """ Attempts to retrieve a model from a model's name and the feature to be enabled. @@ -687,31 +587,17 @@ def get_model_from_feature( The feature required. model (`str`): The name of the model to export. - framework (`str`, *optional*, defaults to `None`): - The framework to use for the export. See `FeaturesManager.determine_framework` for the priority should - none be provided. Returns: The instance of the model. """ - framework = FeaturesManager.determine_framework(model, framework) - model_class = FeaturesManager.get_model_class_for_feature(feature, framework) - try: - model = model_class.from_pretrained(model, cache_dir=cache_dir) - except OSError: - if framework == "pt": - logger.info("Loading TensorFlow model in PyTorch before exporting to ONNX.") - model = model_class.from_pretrained(model, from_tf=True, cache_dir=cache_dir) - else: - logger.info("Loading PyTorch model in TensorFlow before exporting to ONNX.") - model = model_class.from_pretrained(model, from_pt=True, cache_dir=cache_dir) + model_class = FeaturesManager.get_model_class_for_feature(feature) + model = model_class.from_pretrained(model, cache_dir=cache_dir) return model @staticmethod - def check_supported_model_or_raise( - model: Union["PreTrainedModel", "TFPreTrainedModel"], feature: str = "default" - ) -> tuple[str, Callable]: + def check_supported_model_or_raise(model: "PreTrainedModel", feature: str = "default") -> tuple[str, Callable]: """ Check whether or not the model has the requested features. diff --git a/src/transformers/optimization_tf.py b/src/transformers/optimization_tf.py deleted file mode 100644 index 71a77251f2bf..000000000000 --- a/src/transformers/optimization_tf.py +++ /dev/null @@ -1,378 +0,0 @@ -# Copyright 2019 The TensorFlow Authors, The Hugging Face Team. All Rights Reserved. -# -# 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. -# ============================================================================== -"""Functions and classes related to optimization (weight updates).""" - -from typing import Callable, Optional, Union - -import tensorflow as tf - - -try: - from tf_keras.optimizers.legacy import Adam -except (ImportError, ModuleNotFoundError): - from tensorflow.keras.optimizers.legacy import Adam - -from .modeling_tf_utils import keras - - -# This block because Keras loves randomly moving things to different places - this changed somewhere between 2.10 - 2.15 -if hasattr(keras.optimizers.schedules, "learning_rate_schedule"): - schedules = keras.optimizers.schedules.learning_rate_schedule -else: - schedules = keras.optimizers.schedules - - -class WarmUp(schedules.LearningRateSchedule): - """ - Applies a warmup schedule on a given learning rate decay schedule. - - Args: - initial_learning_rate (`float`): - The initial learning rate for the schedule after the warmup (so this will be the learning rate at the end - of the warmup). - decay_schedule_fn (`Callable`): - The schedule function to apply after the warmup for the rest of training. - warmup_steps (`int`): - The number of steps for the warmup part of training. - power (`float`, *optional*, defaults to 1.0): - The power to use for the polynomial warmup (defaults is a linear warmup). - name (`str`, *optional*): - Optional name prefix for the returned tensors during the schedule. - """ - - def __init__( - self, - initial_learning_rate: float, - decay_schedule_fn: Callable, - warmup_steps: int, - power: float = 1.0, - name: Optional[str] = None, - ): - super().__init__() - self.initial_learning_rate = initial_learning_rate - self.warmup_steps = warmup_steps - self.power = power - self.decay_schedule_fn = decay_schedule_fn - self.name = name - - def __call__(self, step): - with tf.name_scope(self.name or "WarmUp") as name: - # Implements polynomial warmup. i.e., if global_step < warmup_steps, the - # learning rate will be `global_step/num_warmup_steps * init_lr`. - global_step_float = tf.cast(step, tf.float32) - warmup_steps_float = tf.cast(self.warmup_steps, tf.float32) - warmup_percent_done = global_step_float / warmup_steps_float - warmup_learning_rate = self.initial_learning_rate * tf.math.pow(warmup_percent_done, self.power) - return tf.cond( - global_step_float < warmup_steps_float, - lambda: warmup_learning_rate, - lambda: self.decay_schedule_fn(step - self.warmup_steps), - name=name, - ) - - def get_config(self): - return { - "initial_learning_rate": self.initial_learning_rate, - "decay_schedule_fn": self.decay_schedule_fn, - "warmup_steps": self.warmup_steps, - "power": self.power, - "name": self.name, - } - - -def create_optimizer( - init_lr: float, - num_train_steps: int, - num_warmup_steps: int, - min_lr_ratio: float = 0.0, - adam_beta1: float = 0.9, - adam_beta2: float = 0.999, - adam_epsilon: float = 1e-8, - adam_clipnorm: Optional[float] = None, - adam_global_clipnorm: Optional[float] = None, - weight_decay_rate: float = 0.0, - power: float = 1.0, - include_in_weight_decay: Optional[list[str]] = None, -): - """ - Creates an optimizer with a learning rate schedule using a warmup phase followed by a linear decay. - - Args: - init_lr (`float`): - The desired learning rate at the end of the warmup phase. - num_train_steps (`int`): - The total number of training steps. - num_warmup_steps (`int`): - The number of warmup steps. - min_lr_ratio (`float`, *optional*, defaults to 0): - The final learning rate at the end of the linear decay will be `init_lr * min_lr_ratio`. - adam_beta1 (`float`, *optional*, defaults to 0.9): - The beta1 to use in Adam. - adam_beta2 (`float`, *optional*, defaults to 0.999): - The beta2 to use in Adam. - adam_epsilon (`float`, *optional*, defaults to 1e-8): - The epsilon to use in Adam. - adam_clipnorm (`float`, *optional*, defaults to `None`): - If not `None`, clip the gradient norm for each weight tensor to this value. - adam_global_clipnorm (`float`, *optional*, defaults to `None`) - If not `None`, clip gradient norm to this value. When using this argument, the norm is computed over all - weight tensors, as if they were concatenated into a single vector. - weight_decay_rate (`float`, *optional*, defaults to 0): - The weight decay to use. - power (`float`, *optional*, defaults to 1.0): - The power to use for PolynomialDecay. - include_in_weight_decay (`list[str]`, *optional*): - List of the parameter names (or re patterns) to apply weight decay to. If none is passed, weight decay is - applied to all parameters except bias and layer norm parameters. - """ - # Implements linear decay of the learning rate. - lr_schedule = schedules.PolynomialDecay( - initial_learning_rate=init_lr, - decay_steps=num_train_steps - num_warmup_steps, - end_learning_rate=init_lr * min_lr_ratio, - power=power, - ) - if num_warmup_steps: - lr_schedule = WarmUp( - initial_learning_rate=init_lr, - decay_schedule_fn=lr_schedule, - warmup_steps=num_warmup_steps, - ) - if weight_decay_rate > 0.0: - optimizer = AdamWeightDecay( - learning_rate=lr_schedule, - weight_decay_rate=weight_decay_rate, - beta_1=adam_beta1, - beta_2=adam_beta2, - epsilon=adam_epsilon, - clipnorm=adam_clipnorm, - global_clipnorm=adam_global_clipnorm, - exclude_from_weight_decay=["LayerNorm", "layer_norm", "bias"], - include_in_weight_decay=include_in_weight_decay, - ) - else: - optimizer = keras.optimizers.Adam( - learning_rate=lr_schedule, - beta_1=adam_beta1, - beta_2=adam_beta2, - epsilon=adam_epsilon, - clipnorm=adam_clipnorm, - global_clipnorm=adam_global_clipnorm, - ) - # We return the optimizer and the LR scheduler in order to better track the - # evolution of the LR independently of the optimizer. - return optimizer, lr_schedule - - -class AdamWeightDecay(Adam): - """ - Adam enables L2 weight decay and clip_by_global_norm on gradients. Just adding the square of the weights to the - loss function is *not* the correct way of using L2 regularization/weight decay with Adam, since that will interact - with the m and v parameters in strange ways as shown in [Decoupled Weight Decay - Regularization](https://huggingface.co/papers/1711.05101). - - Instead we want to decay the weights in a manner that doesn't interact with the m/v parameters. This is equivalent - to adding the square of the weights to the loss with plain (non-momentum) SGD. - - Args: - learning_rate (`Union[float, LearningRateSchedule]`, *optional*, defaults to 0.001): - The learning rate to use or a schedule. - beta_1 (`float`, *optional*, defaults to 0.9): - The beta1 parameter in Adam, which is the exponential decay rate for the 1st momentum estimates. - beta_2 (`float`, *optional*, defaults to 0.999): - The beta2 parameter in Adam, which is the exponential decay rate for the 2nd momentum estimates. - epsilon (`float`, *optional*, defaults to 1e-07): - The epsilon parameter in Adam, which is a small constant for numerical stability. - amsgrad (`bool`, *optional*, defaults to `False`): - Whether to apply AMSGrad variant of this algorithm or not, see [On the Convergence of Adam and - Beyond](https://huggingface.co/papers/1904.09237). - weight_decay_rate (`float`, *optional*, defaults to 0.0): - The weight decay to apply. - include_in_weight_decay (`list[str]`, *optional*): - List of the parameter names (or re patterns) to apply weight decay to. If none is passed, weight decay is - applied to all parameters by default (unless they are in `exclude_from_weight_decay`). - exclude_from_weight_decay (`list[str]`, *optional*): - List of the parameter names (or re patterns) to exclude from applying weight decay to. If a - `include_in_weight_decay` is passed, the names in it will supersede this list. - name (`str`, *optional*, defaults to `"AdamWeightDecay"`): - Optional name for the operations created when applying gradients. - kwargs (`dict[str, Any]`, *optional*): - Keyword arguments. Allowed to be {`clipnorm`, `clipvalue`, `lr`, `decay`}. `clipnorm` is clip gradients by - norm; `clipvalue` is clip gradients by value, `decay` is included for backward compatibility to allow time - inverse decay of learning rate. `lr` is included for backward compatibility, recommended to use - `learning_rate` instead. - """ - - def __init__( - self, - learning_rate: Union[float, schedules.LearningRateSchedule] = 0.001, - beta_1: float = 0.9, - beta_2: float = 0.999, - epsilon: float = 1e-7, - amsgrad: bool = False, - weight_decay_rate: float = 0.0, - include_in_weight_decay: Optional[list[str]] = None, - exclude_from_weight_decay: Optional[list[str]] = None, - name: str = "AdamWeightDecay", - **kwargs, - ): - super().__init__(learning_rate, beta_1, beta_2, epsilon, amsgrad, name, **kwargs) - self.weight_decay_rate = weight_decay_rate - self._include_in_weight_decay = include_in_weight_decay - self._exclude_from_weight_decay = exclude_from_weight_decay - - @classmethod - def from_config(cls, config): - """Creates an optimizer from its config with WarmUp custom object.""" - custom_objects = {"WarmUp": WarmUp} - return super().from_config(config, custom_objects=custom_objects) - - def _prepare_local(self, var_device, var_dtype, apply_state): - super()._prepare_local(var_device, var_dtype, apply_state) - apply_state[(var_device, var_dtype)]["weight_decay_rate"] = tf.constant( - self.weight_decay_rate, name="adam_weight_decay_rate" - ) - - def _decay_weights_op(self, var, learning_rate, apply_state): - do_decay = self._do_use_weight_decay(var.name) - if do_decay: - return var.assign_sub( - learning_rate * var * apply_state[(var.device, var.dtype.base_dtype)]["weight_decay_rate"], - use_locking=self._use_locking, - ) - return tf.no_op() - - def apply_gradients(self, grads_and_vars, name=None, **kwargs): - grads, tvars = list(zip(*grads_and_vars)) - return super().apply_gradients(zip(grads, tvars), name=name, **kwargs) - - def _get_lr(self, var_device, var_dtype, apply_state): - """Retrieves the learning rate with the given state.""" - if apply_state is None: - return self._decayed_lr_t[var_dtype], {} - - apply_state = apply_state or {} - coefficients = apply_state.get((var_device, var_dtype)) - if coefficients is None: - coefficients = self._fallback_apply_state(var_device, var_dtype) - apply_state[(var_device, var_dtype)] = coefficients - - return coefficients["lr_t"], {"apply_state": apply_state} - - def _resource_apply_dense(self, grad, var, apply_state=None): - lr_t, kwargs = self._get_lr(var.device, var.dtype.base_dtype, apply_state) - decay = self._decay_weights_op(var, lr_t, apply_state) - with tf.control_dependencies([decay]): - return super()._resource_apply_dense(grad, var, **kwargs) - - def _resource_apply_sparse(self, grad, var, indices, apply_state=None): - lr_t, kwargs = self._get_lr(var.device, var.dtype.base_dtype, apply_state) - decay = self._decay_weights_op(var, lr_t, apply_state) - with tf.control_dependencies([decay]): - return super()._resource_apply_sparse(grad, var, indices, **kwargs) - - def get_config(self): - config = super().get_config() - config.update({"weight_decay_rate": self.weight_decay_rate}) - return config - - def _do_use_weight_decay(self, param_name): - """Whether to use L2 weight decay for `param_name`.""" - if self.weight_decay_rate == 0: - return False - - if self._include_in_weight_decay: - for r in self._include_in_weight_decay: - if r in param_name: - return True - - if self._exclude_from_weight_decay: - for r in self._exclude_from_weight_decay: - if r in param_name: - return False - return True - - -# Extracted from https://github.com/OpenNMT/OpenNMT-tf/blob/master/opennmt/optimizers/utils.py -class GradientAccumulator: - """ - Gradient accumulation utility. When used with a distribution strategy, the accumulator should be called in a - replica context. Gradients will be accumulated locally on each replica and without synchronization. Users should - then call `.gradients`, scale the gradients if required, and pass the result to `apply_gradients`. - """ - - # We use the ON_READ synchronization policy so that no synchronization is - # performed on assignment. To get the value, we call .value() which returns the - # value on the current replica without synchronization. - - def __init__(self): - """Initializes the accumulator.""" - self._gradients = [] - self._accum_steps = None - - @property - def step(self): - """Number of accumulated steps.""" - if self._accum_steps is None: - self._accum_steps = tf.Variable( - tf.constant(0, dtype=tf.int64), - trainable=False, - synchronization=tf.VariableSynchronization.ON_READ, - aggregation=tf.VariableAggregation.ONLY_FIRST_REPLICA, - ) - - return self._accum_steps.value() - - @property - def gradients(self): - """The accumulated gradients on the current replica.""" - if not self._gradients: - raise ValueError("The accumulator should be called first to initialize the gradients") - return [gradient.value() if gradient is not None else gradient for gradient in self._gradients] - - def __call__(self, gradients): - """Accumulates `gradients` on the current replica.""" - if not self._gradients: - _ = self.step # Create the step variable. - self._gradients.extend( - [ - tf.Variable( - tf.zeros_like(gradient), - trainable=False, - synchronization=tf.VariableSynchronization.ON_READ, - aggregation=tf.VariableAggregation.ONLY_FIRST_REPLICA, - ) - if gradient is not None - else gradient - for gradient in gradients - ] - ) - if len(gradients) != len(self._gradients): - raise ValueError(f"Expected {len(self._gradients)} gradients, but got {len(gradients)}") - - for accum_gradient, gradient in zip(self._gradients, gradients): - if accum_gradient is not None and gradient is not None: - accum_gradient.assign_add(gradient) - - self._accum_steps.assign_add(1) - - def reset(self): - """Resets the accumulated gradients on the current replica.""" - if not self._gradients: - return - self._accum_steps.assign(0) - for gradient in self._gradients: - if gradient is not None: - gradient.assign(tf.zeros_like(gradient)) diff --git a/src/transformers/pipelines/__init__.py b/src/transformers/pipelines/__init__.py index 92da22477f55..a029bb32df03 100755 --- a/src/transformers/pipelines/__init__.py +++ b/src/transformers/pipelines/__init__.py @@ -42,7 +42,6 @@ is_offline_mode, is_peft_available, is_pyctcdecode_available, - is_tf_available, is_torch_available, logging, ) @@ -58,7 +57,7 @@ PipelineException, PipelineRegistry, get_default_model_and_revision, - infer_framework_load_model, + load_model, ) from .depth_estimation import DepthEstimationPipeline from .document_question_answering import DocumentQuestionAnsweringPipeline @@ -93,23 +92,6 @@ from .zero_shot_object_detection import ZeroShotObjectDetectionPipeline -if is_tf_available(): - import tensorflow as tf - - from ..models.auto.modeling_tf_auto import ( - TFAutoModel, - TFAutoModelForCausalLM, - TFAutoModelForImageClassification, - TFAutoModelForMaskedLM, - TFAutoModelForQuestionAnswering, - TFAutoModelForSeq2SeqLM, - TFAutoModelForSequenceClassification, - TFAutoModelForTableQuestionAnswering, - TFAutoModelForTokenClassification, - TFAutoModelForVision2Seq, - TFAutoModelForZeroShotImageClassification, - ) - if is_torch_available(): import torch @@ -144,7 +126,6 @@ if TYPE_CHECKING: - from ..modeling_tf_utils import TFPreTrainedModel from ..modeling_utils import PreTrainedModel from ..tokenization_utils_fast import PreTrainedTokenizerFast @@ -162,290 +143,190 @@ SUPPORTED_TASKS = { "audio-classification": { "impl": AudioClassificationPipeline, - "tf": (), "pt": (AutoModelForAudioClassification,) if is_torch_available() else (), - "default": {"model": {"pt": ("superb/wav2vec2-base-superb-ks", "372e048")}}, + "default": {"model": ("superb/wav2vec2-base-superb-ks", "372e048")}, "type": "audio", }, "automatic-speech-recognition": { "impl": AutomaticSpeechRecognitionPipeline, - "tf": (), "pt": (AutoModelForCTC, AutoModelForSpeechSeq2Seq) if is_torch_available() else (), - "default": {"model": {"pt": ("facebook/wav2vec2-base-960h", "22aad52")}}, + "default": {"model": ("facebook/wav2vec2-base-960h", "22aad52")}, "type": "multimodal", }, "text-to-audio": { "impl": TextToAudioPipeline, - "tf": (), "pt": (AutoModelForTextToWaveform, AutoModelForTextToSpectrogram) if is_torch_available() else (), - "default": {"model": {"pt": ("suno/bark-small", "1dbd7a1")}}, + "default": {"model": ("suno/bark-small", "1dbd7a1")}, "type": "text", }, "feature-extraction": { "impl": FeatureExtractionPipeline, - "tf": (TFAutoModel,) if is_tf_available() else (), "pt": (AutoModel,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("distilbert/distilbert-base-cased", "6ea8117"), - "tf": ("distilbert/distilbert-base-cased", "6ea8117"), - } - }, + "default": {"model": ("distilbert/distilbert-base-cased", "6ea8117")}, "type": "multimodal", }, "text-classification": { "impl": TextClassificationPipeline, - "tf": (TFAutoModelForSequenceClassification,) if is_tf_available() else (), "pt": (AutoModelForSequenceClassification,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("distilbert/distilbert-base-uncased-finetuned-sst-2-english", "714eb0f"), - "tf": ("distilbert/distilbert-base-uncased-finetuned-sst-2-english", "714eb0f"), - }, - }, + "default": {"model": ("distilbert/distilbert-base-uncased-finetuned-sst-2-english", "714eb0f")}, "type": "text", }, "token-classification": { "impl": TokenClassificationPipeline, - "tf": (TFAutoModelForTokenClassification,) if is_tf_available() else (), "pt": (AutoModelForTokenClassification,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("dbmdz/bert-large-cased-finetuned-conll03-english", "4c53496"), - "tf": ("dbmdz/bert-large-cased-finetuned-conll03-english", "4c53496"), - }, - }, + "default": {"model": ("dbmdz/bert-large-cased-finetuned-conll03-english", "4c53496")}, "type": "text", }, "question-answering": { "impl": QuestionAnsweringPipeline, - "tf": (TFAutoModelForQuestionAnswering,) if is_tf_available() else (), "pt": (AutoModelForQuestionAnswering,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("distilbert/distilbert-base-cased-distilled-squad", "564e9b5"), - "tf": ("distilbert/distilbert-base-cased-distilled-squad", "564e9b5"), - }, - }, + "default": {"model": ("distilbert/distilbert-base-cased-distilled-squad", "564e9b5")}, "type": "text", }, "table-question-answering": { "impl": TableQuestionAnsweringPipeline, "pt": (AutoModelForTableQuestionAnswering,) if is_torch_available() else (), - "tf": (TFAutoModelForTableQuestionAnswering,) if is_tf_available() else (), - "default": { - "model": { - "pt": ("google/tapas-base-finetuned-wtq", "e3dde19"), - "tf": ("google/tapas-base-finetuned-wtq", "e3dde19"), - }, - }, + "default": {"model": ("google/tapas-base-finetuned-wtq", "e3dde19")}, "type": "text", }, "visual-question-answering": { "impl": VisualQuestionAnsweringPipeline, "pt": (AutoModelForVisualQuestionAnswering,) if is_torch_available() else (), - "tf": (), - "default": { - "model": {"pt": ("dandelin/vilt-b32-finetuned-vqa", "d0a1f6a")}, - }, + "default": {"model": ("dandelin/vilt-b32-finetuned-vqa", "d0a1f6a")}, "type": "multimodal", }, "document-question-answering": { "impl": DocumentQuestionAnsweringPipeline, "pt": (AutoModelForDocumentQuestionAnswering,) if is_torch_available() else (), - "tf": (), - "default": { - "model": {"pt": ("impira/layoutlm-document-qa", "beed3c4")}, - }, + "default": {"model": ("impira/layoutlm-document-qa", "beed3c4")}, "type": "multimodal", }, "fill-mask": { "impl": FillMaskPipeline, - "tf": (TFAutoModelForMaskedLM,) if is_tf_available() else (), "pt": (AutoModelForMaskedLM,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("distilbert/distilroberta-base", "fb53ab8"), - "tf": ("distilbert/distilroberta-base", "fb53ab8"), - } - }, + "default": {"model": ("distilbert/distilroberta-base", "fb53ab8")}, "type": "text", }, "summarization": { "impl": SummarizationPipeline, - "tf": (TFAutoModelForSeq2SeqLM,) if is_tf_available() else (), "pt": (AutoModelForSeq2SeqLM,) if is_torch_available() else (), - "default": { - "model": {"pt": ("sshleifer/distilbart-cnn-12-6", "a4f8f3e"), "tf": ("google-t5/t5-small", "df1b051")} - }, + "default": {"model": ("sshleifer/distilbart-cnn-12-6", "a4f8f3e")}, "type": "text", }, # This task is a special case as it's parametrized by SRC, TGT languages. "translation": { "impl": TranslationPipeline, - "tf": (TFAutoModelForSeq2SeqLM,) if is_tf_available() else (), "pt": (AutoModelForSeq2SeqLM,) if is_torch_available() else (), "default": { - ("en", "fr"): {"model": {"pt": ("google-t5/t5-base", "a9723ea"), "tf": ("google-t5/t5-base", "a9723ea")}}, - ("en", "de"): {"model": {"pt": ("google-t5/t5-base", "a9723ea"), "tf": ("google-t5/t5-base", "a9723ea")}}, - ("en", "ro"): {"model": {"pt": ("google-t5/t5-base", "a9723ea"), "tf": ("google-t5/t5-base", "a9723ea")}}, + ("en", "fr"): {"model": ("google-t5/t5-base", "a9723ea")}, + ("en", "de"): {"model": ("google-t5/t5-base", "a9723ea")}, + ("en", "ro"): {"model": ("google-t5/t5-base", "a9723ea")}, }, "type": "text", }, "text2text-generation": { "impl": Text2TextGenerationPipeline, - "tf": (TFAutoModelForSeq2SeqLM,) if is_tf_available() else (), "pt": (AutoModelForSeq2SeqLM,) if is_torch_available() else (), - "default": {"model": {"pt": ("google-t5/t5-base", "a9723ea"), "tf": ("google-t5/t5-base", "a9723ea")}}, + "default": {"model": ("google-t5/t5-base", "a9723ea")}, "type": "text", }, "text-generation": { "impl": TextGenerationPipeline, - "tf": (TFAutoModelForCausalLM,) if is_tf_available() else (), "pt": (AutoModelForCausalLM,) if is_torch_available() else (), - "default": {"model": {"pt": ("openai-community/gpt2", "607a30d"), "tf": ("openai-community/gpt2", "607a30d")}}, + "default": {"model": ("openai-community/gpt2", "607a30d")}, "type": "text", }, "zero-shot-classification": { "impl": ZeroShotClassificationPipeline, - "tf": (TFAutoModelForSequenceClassification,) if is_tf_available() else (), "pt": (AutoModelForSequenceClassification,) if is_torch_available() else (), "default": { - "model": { - "pt": ("facebook/bart-large-mnli", "d7645e1"), - "tf": ("FacebookAI/roberta-large-mnli", "2a8f12d"), - }, - "config": { - "pt": ("facebook/bart-large-mnli", "d7645e1"), - "tf": ("FacebookAI/roberta-large-mnli", "2a8f12d"), - }, + "model": ("facebook/bart-large-mnli", "d7645e1"), + "config": ("facebook/bart-large-mnli", "d7645e1"), }, "type": "text", }, "zero-shot-image-classification": { "impl": ZeroShotImageClassificationPipeline, - "tf": (TFAutoModelForZeroShotImageClassification,) if is_tf_available() else (), "pt": (AutoModelForZeroShotImageClassification,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("openai/clip-vit-base-patch32", "3d74acf"), - "tf": ("openai/clip-vit-base-patch32", "3d74acf"), - } - }, + "default": {"model": ("openai/clip-vit-base-patch32", "3d74acf")}, "type": "multimodal", }, "zero-shot-audio-classification": { "impl": ZeroShotAudioClassificationPipeline, - "tf": (), "pt": (AutoModel,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("laion/clap-htsat-fused", "cca9e28"), - } - }, + "default": {"model": ("laion/clap-htsat-fused", "cca9e28")}, "type": "multimodal", }, "image-classification": { "impl": ImageClassificationPipeline, - "tf": (TFAutoModelForImageClassification,) if is_tf_available() else (), "pt": (AutoModelForImageClassification,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("google/vit-base-patch16-224", "3f49326"), - "tf": ("google/vit-base-patch16-224", "3f49326"), - } - }, + "default": {"model": ("google/vit-base-patch16-224", "3f49326")}, "type": "image", }, "image-feature-extraction": { "impl": ImageFeatureExtractionPipeline, - "tf": (TFAutoModel,) if is_tf_available() else (), "pt": (AutoModel,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("google/vit-base-patch16-224", "3f49326"), - "tf": ("google/vit-base-patch16-224", "3f49326"), - } - }, + "default": {"model": ("google/vit-base-patch16-224", "3f49326")}, "type": "image", }, "image-segmentation": { "impl": ImageSegmentationPipeline, - "tf": (), "pt": (AutoModelForImageSegmentation, AutoModelForSemanticSegmentation) if is_torch_available() else (), - "default": {"model": {"pt": ("facebook/detr-resnet-50-panoptic", "d53b52a")}}, + "default": {"model": ("facebook/detr-resnet-50-panoptic", "d53b52a")}, "type": "multimodal", }, "image-to-text": { "impl": ImageToTextPipeline, - "tf": (TFAutoModelForVision2Seq,) if is_tf_available() else (), "pt": (AutoModelForVision2Seq,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("ydshieh/vit-gpt2-coco-en", "5bebf1e"), - "tf": ("ydshieh/vit-gpt2-coco-en", "5bebf1e"), - } - }, + "default": {"model": ("ydshieh/vit-gpt2-coco-en", "5bebf1e")}, "type": "multimodal", }, "image-text-to-text": { "impl": ImageTextToTextPipeline, - "tf": (), "pt": (AutoModelForImageTextToText,) if is_torch_available() else (), - "default": { - "model": { - "pt": ("llava-hf/llava-onevision-qwen2-0.5b-ov-hf", "2c9ba3b"), - } - }, + "default": {"model": ("llava-hf/llava-onevision-qwen2-0.5b-ov-hf", "2c9ba3b")}, "type": "multimodal", }, "object-detection": { "impl": ObjectDetectionPipeline, - "tf": (), "pt": (AutoModelForObjectDetection,) if is_torch_available() else (), - "default": {"model": {"pt": ("facebook/detr-resnet-50", "1d5f47b")}}, + "default": {"model": ("facebook/detr-resnet-50", "1d5f47b")}, "type": "multimodal", }, "zero-shot-object-detection": { "impl": ZeroShotObjectDetectionPipeline, - "tf": (), "pt": (AutoModelForZeroShotObjectDetection,) if is_torch_available() else (), - "default": {"model": {"pt": ("google/owlvit-base-patch32", "cbc355f")}}, + "default": {"model": ("google/owlvit-base-patch32", "cbc355f")}, "type": "multimodal", }, "depth-estimation": { "impl": DepthEstimationPipeline, - "tf": (), "pt": (AutoModelForDepthEstimation,) if is_torch_available() else (), - "default": {"model": {"pt": ("Intel/dpt-large", "bc15f29")}}, + "default": {"model": ("Intel/dpt-large", "bc15f29")}, "type": "image", }, "video-classification": { "impl": VideoClassificationPipeline, - "tf": (), "pt": (AutoModelForVideoClassification,) if is_torch_available() else (), - "default": {"model": {"pt": ("MCG-NJU/videomae-base-finetuned-kinetics", "488eb9a")}}, + "default": {"model": ("MCG-NJU/videomae-base-finetuned-kinetics", "488eb9a")}, "type": "video", }, "mask-generation": { "impl": MaskGenerationPipeline, - "tf": (), "pt": (AutoModelForMaskGeneration,) if is_torch_available() else (), - "default": {"model": {"pt": ("facebook/sam-vit-huge", "87aecf0")}}, + "default": {"model": ("facebook/sam-vit-huge", "87aecf0")}, "type": "multimodal", }, "image-to-image": { "impl": ImageToImagePipeline, - "tf": (), "pt": (AutoModelForImageToImage,) if is_torch_available() else (), - "default": {"model": {"pt": ("caidas/swin2SR-classical-sr-x2-64", "cee1c92")}}, + "default": {"model": ("caidas/swin2SR-classical-sr-x2-64", "cee1c92")}, "type": "image", }, "keypoint-matching": { "impl": KeypointMatchingPipeline, - "tf": (), "pt": (AutoModelForKeypointMatching,) if is_torch_available() else (), - "default": {"model": {"pt": ("magic-leap-community/superglue_outdoor", "f4041f8")}}, + "default": {"model": ("magic-leap-community/superglue_outdoor", "f4041f8")}, "type": "image", }, } @@ -545,10 +426,6 @@ def clean_custom_task(task_info): if isinstance(pt_class_names, str): pt_class_names = [pt_class_names] task_info["pt"] = tuple(getattr(transformers, c) for c in pt_class_names) - tf_class_names = task_info.get("tf", ()) - if isinstance(tf_class_names, str): - tf_class_names = [tf_class_names] - task_info["tf"] = tuple(getattr(transformers, c) for c in tf_class_names) return task_info, None @@ -565,67 +442,67 @@ def clean_custom_task(task_info): @overload -def pipeline(task: Literal[None], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> Pipeline: ... +def pipeline(task: Literal[None], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> Pipeline: ... @overload -def pipeline(task: Literal["audio-classification"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> AudioClassificationPipeline: ... +def pipeline(task: Literal["audio-classification"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> AudioClassificationPipeline: ... @overload -def pipeline(task: Literal["automatic-speech-recognition"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> AutomaticSpeechRecognitionPipeline: ... +def pipeline(task: Literal["automatic-speech-recognition"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> AutomaticSpeechRecognitionPipeline: ... @overload -def pipeline(task: Literal["depth-estimation"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> DepthEstimationPipeline: ... +def pipeline(task: Literal["depth-estimation"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> DepthEstimationPipeline: ... @overload -def pipeline(task: Literal["document-question-answering"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> DocumentQuestionAnsweringPipeline: ... +def pipeline(task: Literal["document-question-answering"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> DocumentQuestionAnsweringPipeline: ... @overload -def pipeline(task: Literal["feature-extraction"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> FeatureExtractionPipeline: ... +def pipeline(task: Literal["feature-extraction"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> FeatureExtractionPipeline: ... @overload -def pipeline(task: Literal["fill-mask"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> FillMaskPipeline: ... +def pipeline(task: Literal["fill-mask"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> FillMaskPipeline: ... @overload -def pipeline(task: Literal["image-classification"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageClassificationPipeline: ... +def pipeline(task: Literal["image-classification"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageClassificationPipeline: ... @overload -def pipeline(task: Literal["image-feature-extraction"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageFeatureExtractionPipeline: ... +def pipeline(task: Literal["image-feature-extraction"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageFeatureExtractionPipeline: ... @overload -def pipeline(task: Literal["image-segmentation"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageSegmentationPipeline: ... +def pipeline(task: Literal["image-segmentation"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageSegmentationPipeline: ... @overload -def pipeline(task: Literal["image-text-to-text"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageTextToTextPipeline: ... +def pipeline(task: Literal["image-text-to-text"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageTextToTextPipeline: ... @overload -def pipeline(task: Literal["image-to-image"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageToImagePipeline: ... +def pipeline(task: Literal["image-to-image"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageToImagePipeline: ... @overload -def pipeline(task: Literal["image-to-text"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageToTextPipeline: ... +def pipeline(task: Literal["image-to-text"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ImageToTextPipeline: ... @overload -def pipeline(task: Literal["keypoint-matching"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> KeypointMatchingPipeline: ... +def pipeline(task: Literal["keypoint-matching"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> KeypointMatchingPipeline: ... @overload -def pipeline(task: Literal["mask-generation"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> MaskGenerationPipeline: ... +def pipeline(task: Literal["mask-generation"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> MaskGenerationPipeline: ... @overload -def pipeline(task: Literal["object-detection"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ObjectDetectionPipeline: ... +def pipeline(task: Literal["object-detection"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ObjectDetectionPipeline: ... @overload -def pipeline(task: Literal["question-answering"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> QuestionAnsweringPipeline: ... +def pipeline(task: Literal["question-answering"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> QuestionAnsweringPipeline: ... @overload -def pipeline(task: Literal["summarization"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> SummarizationPipeline: ... +def pipeline(task: Literal["summarization"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> SummarizationPipeline: ... @overload -def pipeline(task: Literal["table-question-answering"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TableQuestionAnsweringPipeline: ... +def pipeline(task: Literal["table-question-answering"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TableQuestionAnsweringPipeline: ... @overload -def pipeline(task: Literal["text-classification"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TextClassificationPipeline: ... +def pipeline(task: Literal["text-classification"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TextClassificationPipeline: ... @overload -def pipeline(task: Literal["text-generation"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TextGenerationPipeline: ... +def pipeline(task: Literal["text-generation"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TextGenerationPipeline: ... @overload -def pipeline(task: Literal["text-to-audio"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TextToAudioPipeline: ... +def pipeline(task: Literal["text-to-audio"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TextToAudioPipeline: ... @overload -def pipeline(task: Literal["text2text-generation"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> Text2TextGenerationPipeline: ... +def pipeline(task: Literal["text2text-generation"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> Text2TextGenerationPipeline: ... @overload -def pipeline(task: Literal["token-classification"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TokenClassificationPipeline: ... +def pipeline(task: Literal["token-classification"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TokenClassificationPipeline: ... @overload -def pipeline(task: Literal["translation"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TranslationPipeline: ... +def pipeline(task: Literal["translation"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> TranslationPipeline: ... @overload -def pipeline(task: Literal["video-classification"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> VideoClassificationPipeline: ... +def pipeline(task: Literal["video-classification"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> VideoClassificationPipeline: ... @overload -def pipeline(task: Literal["visual-question-answering"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> VisualQuestionAnsweringPipeline: ... +def pipeline(task: Literal["visual-question-answering"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> VisualQuestionAnsweringPipeline: ... @overload -def pipeline(task: Literal["zero-shot-audio-classification"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ZeroShotAudioClassificationPipeline: ... +def pipeline(task: Literal["zero-shot-audio-classification"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ZeroShotAudioClassificationPipeline: ... @overload -def pipeline(task: Literal["zero-shot-classification"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ZeroShotClassificationPipeline: ... +def pipeline(task: Literal["zero-shot-classification"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ZeroShotClassificationPipeline: ... @overload -def pipeline(task: Literal["zero-shot-image-classification"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ZeroShotImageClassificationPipeline: ... +def pipeline(task: Literal["zero-shot-image-classification"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ZeroShotImageClassificationPipeline: ... @overload -def pipeline(task: Literal["zero-shot-object-detection"], model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ZeroShotObjectDetectionPipeline: ... +def pipeline(task: Literal["zero-shot-object-detection"], model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, device: Optional[Union[int, str, "torch.device"]] = None, device_map: Optional[Union[str, dict[str, Union[int, str]]]] = None, dtype: Optional[Union[str, "torch.dtype"]] = "auto", trust_remote_code: Optional[bool] = None, model_kwargs: Optional[dict[str, Any]] = None, pipeline_class: Optional[Any] = None, **kwargs: Any) -> ZeroShotObjectDetectionPipeline: ... # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 # The part of the file above was automatically generated from the code. @@ -636,13 +513,12 @@ def pipeline(task: Literal["zero-shot-object-detection"], model: Optional[Union[ def pipeline( task: Optional[str] = None, - model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None, + model: Optional[Union[str, "PreTrainedModel"]] = None, config: Optional[Union[str, PretrainedConfig]] = None, tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, image_processor: Optional[Union[str, BaseImageProcessor]] = None, processor: Optional[Union[str, ProcessorMixin]] = None, - framework: Optional[str] = None, revision: Optional[str] = None, use_fast: bool = True, token: Optional[Union[str, bool]] = None, @@ -708,10 +584,9 @@ def pipeline( - `"zero-shot-audio-classification"`: will return a [`ZeroShotAudioClassificationPipeline`]. - `"zero-shot-object-detection"`: will return a [`ZeroShotObjectDetectionPipeline`]. - model (`str` or [`PreTrainedModel`] or [`TFPreTrainedModel`], *optional*): + model (`str` or [`PreTrainedModel`], *optional*): The model that will be used by the pipeline to make predictions. This can be a model identifier or an - actual instance of a pretrained model inheriting from [`PreTrainedModel`] (for PyTorch) or - [`TFPreTrainedModel`] (for TensorFlow). + actual instance of a pretrained model inheriting from [`PreTrainedModel`]. If not provided, the default for the `task` will be loaded. config (`str` or [`PretrainedConfig`], *optional*): @@ -759,13 +634,6 @@ def pipeline( If not provided, the default processor for the given `model` will be loaded (if it is a string). If `model` is not specified or not a string, then the default processor for `config` is loaded (if it is a string). - framework (`str`, *optional*): - The framework to use, either `"pt"` for PyTorch or `"tf"` for TensorFlow. The specified framework must be - installed. - - If no framework is specified, will default to the one currently installed. If no framework is specified and - both frameworks are installed, will default to the framework of the `model`, or to PyTorch if no model is - provided. revision (`str`, *optional*, defaults to `"main"`): When passing a task name or a string model identifier: The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a git-based system for storing models and other @@ -969,8 +837,7 @@ def pipeline( # Use default model/config/tokenizer for the task if no model is provided if model is None: - # At that point framework might still be undetermined - model, default_revision = get_default_model_and_revision(targeted_task, framework, task_options) + model, default_revision = get_default_model_and_revision(targeted_task, task_options) revision = revision if revision is not None else default_revision logger.warning( f"No model was supplied, defaulted to {model} and revision" @@ -1022,14 +889,12 @@ def pipeline( model_name = model if isinstance(model, str) else None # Load the correct model if possible - # Infer the framework from the model if not already defined - if isinstance(model, str) or framework is None: - model_classes = {"tf": targeted_task["tf"], "pt": targeted_task["pt"]} - framework, model = infer_framework_load_model( + if isinstance(model, str): + model_classes = targeted_task["pt"] + model = load_model( adapter_path if adapter_path is not None else model, model_classes=model_classes, config=config, - framework=framework, task=task, **hub_kwargs, **model_kwargs, @@ -1227,4 +1092,4 @@ def pipeline( if processor is not None: kwargs["processor"] = processor - return pipeline_class(model=model, framework=framework, task=task, **kwargs) + return pipeline_class(model=model, task=task, **kwargs) diff --git a/src/transformers/pipelines/audio_classification.py b/src/transformers/pipelines/audio_classification.py index 9f4822e2b2be..58fb3ab4fcab 100644 --- a/src/transformers/pipelines/audio_classification.py +++ b/src/transformers/pipelines/audio_classification.py @@ -103,9 +103,6 @@ def __init__(self, *args, **kwargs): kwargs["top_k"] = 5 super().__init__(*args, **kwargs) - if self.framework != "pt": - raise ValueError(f"The {self.__class__} is only available in PyTorch.") - self.check_model_type(MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES) def __call__(self, inputs: Union[np.ndarray, bytes, str, dict], **kwargs: Any) -> list[dict[str, Any]]: diff --git a/src/transformers/pipelines/automatic_speech_recognition.py b/src/transformers/pipelines/automatic_speech_recognition.py index b4d1b96ea87f..960bc00f4c51 100644 --- a/src/transformers/pipelines/automatic_speech_recognition.py +++ b/src/transformers/pipelines/automatic_speech_recognition.py @@ -134,9 +134,9 @@ class AutomaticSpeechRecognitionPipeline(ChunkPipeline): Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) Arguments: - model ([`PreTrainedModel`] or [`TFPreTrainedModel`]): + model ([`PreTrainedModel`]): The model that will be used by the pipeline to make predictions. This needs to be a model inheriting from - [`PreTrainedModel`] for PyTorch and [`TFPreTrainedModel`] for TensorFlow. + [`PreTrainedModel`]. feature_extractor ([`SequenceFeatureExtractor`]): The feature extractor that will be used by the pipeline to encode waveform for the model. tokenizer ([`PreTrainedTokenizer`]): @@ -168,11 +168,6 @@ class AutomaticSpeechRecognitionPipeline(ChunkPipeline): - framework (`str`, *optional*): - The framework to use, either `"pt"` for PyTorch or `"tf"` for TensorFlow. The specified framework must be - installed. If no framework is specified, will default to the one currently installed. If no framework is - specified and both frameworks are installed, will default to the framework of the `model`, or to PyTorch if - no model is provided. device (Union[`int`, `torch.device`], *optional*): Device ordinal for CPU/GPU supports. Setting this to `None` will leverage CPU, a positive will run the model on the associated CUDA device id. @@ -592,7 +587,7 @@ def postprocess( key = "logits" if self.type == "ctc_with_lm" else "tokens" stride = None for outputs in model_outputs: - if self.framework == "pt" and outputs[key].dtype in (torch.bfloat16, torch.float16): + if outputs[key].dtype in (torch.bfloat16, torch.float16): items = outputs[key].to(torch.float32).numpy() else: items = outputs[key].numpy() diff --git a/src/transformers/pipelines/base.py b/src/transformers/pipelines/base.py index 944c7a90a184..61c0aff4e029 100644 --- a/src/transformers/pipelines/base.py +++ b/src/transformers/pipelines/base.py @@ -42,8 +42,6 @@ PushToHubMixin, add_end_docstrings, copy_func, - infer_framework, - is_tf_available, is_torch_available, is_torch_cuda_available, is_torch_hpu_available, @@ -54,22 +52,15 @@ is_torch_xpu_available, logging, ) -from ..utils.deprecation import deprecate_kwarg -GenericTensor = Union[list["GenericTensor"], "torch.Tensor", "tf.Tensor"] - -if is_tf_available(): - import tensorflow as tf - - from ..models.auto.modeling_tf_auto import TFAutoModel +GenericTensor = Union[list["GenericTensor"], "torch.Tensor"] if is_torch_available(): import torch from torch.utils.data import DataLoader, Dataset from ..modeling_utils import PreTrainedModel - from ..models.auto.modeling_auto import AutoModel # Re-export for backward compatibility from .pt_utils import KeyDataset @@ -78,7 +69,6 @@ KeyDataset = None if TYPE_CHECKING: - from ..modeling_tf_utils import TFPreTrainedModel from ..modeling_utils import PreTrainedModel @@ -207,30 +197,27 @@ def inner(items): return inner -def infer_framework_load_model( +def load_model( model, config: AutoConfig, - model_classes: Optional[dict[str, tuple[type]]] = None, + model_classes: Optional[tuple[type]] = None, task: Optional[str] = None, - framework: Optional[str] = None, **model_kwargs, ): """ - Select framework (TensorFlow or PyTorch) to use from the `model` passed. Returns a tuple (framework, model). + Load a model. - If `model` is instantiated, this function will just infer the framework from the model class. Otherwise `model` is + If `model` is instantiated, this function will just return it. Otherwise `model` is actually a checkpoint name and this method will try to instantiate it using `model_classes`. Since we don't want to instantiate the model twice, this model is returned for use by the pipeline. - If both frameworks are installed and available for `model`, PyTorch is selected. - Args: - model (`str`, [`PreTrainedModel`] or [`TFPreTrainedModel]`): - The model to infer the framework from. If `str`, a checkpoint name. The model to infer the framewrok from. + model (`str`, or [`PreTrainedModel`]): + If `str`, a checkpoint name. The model to load. config ([`AutoConfig`]): The config associated with the model to help using the correct class - model_classes (dictionary `str` to `type`, *optional*): - A mapping framework to class. + model_classes (`tuple[type]`, *optional*): + A tuple of model classes. task (`str`): The task defining which pipeline will be returned. model_kwargs: @@ -238,36 +225,21 @@ def infer_framework_load_model( **model_kwargs)` function. Returns: - `Tuple`: A tuple framework, model. + The model. """ - if not is_tf_available() and not is_torch_available(): - raise RuntimeError( - "At least one of TensorFlow 2.0 or PyTorch should be installed. " - "To install TensorFlow 2.0, read the instructions at https://www.tensorflow.org/install/ " - "To install PyTorch, read the instructions at https://pytorch.org/." - ) + if not is_torch_available(): + raise RuntimeError("PyTorch should be installed. Please follow the instructions at https://pytorch.org/.") + if isinstance(model, str): model_kwargs["_from_pipeline"] = task - class_tuple = () - look_pt = is_torch_available() and framework in {"pt", None} - look_tf = is_tf_available() and framework in {"tf", None} - if model_classes: - if look_pt: - class_tuple = class_tuple + model_classes.get("pt", (AutoModel,)) - if look_tf: - class_tuple = class_tuple + model_classes.get("tf", (TFAutoModel,)) + class_tuple = model_classes if model_classes is not None else () if config.architectures: classes = [] for architecture in config.architectures: transformers_module = importlib.import_module("transformers") - if look_pt: - _class = getattr(transformers_module, architecture, None) - if _class is not None: - classes.append(_class) - if look_tf: - _class = getattr(transformers_module, f"TF{architecture}", None) - if _class is not None: - classes.append(_class) + _class = getattr(transformers_module, architecture, None) + if _class is not None: + classes.append(_class) class_tuple = class_tuple + tuple(classes) if len(class_tuple) == 0: @@ -276,23 +248,9 @@ def infer_framework_load_model( all_traceback = {} for model_class in class_tuple: kwargs = model_kwargs.copy() - if framework == "pt" and model.endswith(".h5"): - kwargs["from_tf"] = True - logger.warning( - "Model might be a TensorFlow model (ending with `.h5`) but TensorFlow is not available. " - "Trying to load the model with PyTorch." - ) - elif framework == "tf" and model.endswith(".bin"): - kwargs["from_pt"] = True - logger.warning( - "Model might be a PyTorch model (ending with `.bin`) but PyTorch is not available. " - "Trying to load the model with Tensorflow." - ) try: model = model_class.from_pretrained(model, **kwargs) - if hasattr(model, "eval"): - model = model.eval() # Stop loading on the first successful load. break except (OSError, ValueError, TypeError, RuntimeError): @@ -300,8 +258,8 @@ def infer_framework_load_model( # is not supported on the execution device (e.g. bf16 on a consumer GPU). We capture those so # we can transparently retry the load in float32 before surfacing an error to the user. fallback_tried = False - if is_torch_available() and ("dtype" in kwargs): - import torch # local import to avoid unnecessarily importing torch for TF/JAX users + if "dtype" in kwargs: + import torch fallback_tried = True fp32_kwargs = kwargs.copy() @@ -309,8 +267,6 @@ def infer_framework_load_model( try: model = model_class.from_pretrained(model, **fp32_kwargs) - if hasattr(model, "eval"): - model = model.eval() logger.warning( "Falling back to torch.float32 because loading with the original dtype failed on the" " target device." @@ -334,97 +290,17 @@ def infer_framework_load_model( f"Could not load model {model} with any of the following classes: {class_tuple}. See the original errors:\n\n{error}\n" ) - if framework is None: - framework = infer_framework(model.__class__) - return framework, model - - -def infer_framework_from_model( - model, - model_classes: Optional[dict[str, tuple[type]]] = None, - task: Optional[str] = None, - framework: Optional[str] = None, - **model_kwargs, -): - """ - Select framework (TensorFlow or PyTorch) to use from the `model` passed. Returns a tuple (framework, model). - - If `model` is instantiated, this function will just infer the framework from the model class. Otherwise `model` is - actually a checkpoint name and this method will try to instantiate it using `model_classes`. Since we don't want to - instantiate the model twice, this model is returned for use by the pipeline. - - If both frameworks are installed and available for `model`, PyTorch is selected. - - Args: - model (`str`, [`PreTrainedModel`] or [`TFPreTrainedModel]`): - The model to infer the framework from. If `str`, a checkpoint name. The model to infer the framewrok from. - model_classes (dictionary `str` to `type`, *optional*): - A mapping framework to class. - task (`str`): - The task defining which pipeline will be returned. - model_kwargs: - Additional dictionary of keyword arguments passed along to the model's `from_pretrained(..., - **model_kwargs)` function. - - Returns: - `Tuple`: A tuple framework, model. - """ - if isinstance(model, str): - config = AutoConfig.from_pretrained(model, _from_pipeline=task, **model_kwargs) - else: - config = model.config - return infer_framework_load_model( - model, config, model_classes=model_classes, _from_pipeline=task, task=task, framework=framework, **model_kwargs - ) - + return model -def get_framework(model, revision: Optional[str] = None): - """ - Select framework (TensorFlow or PyTorch) to use. - Args: - model (`str`, [`PreTrainedModel`] or [`TFPreTrainedModel]`): - If both frameworks are installed, picks the one corresponding to the model passed (either a model class or - the model name). If no specific model is provided, defaults to using PyTorch. +def get_default_model_and_revision(targeted_task: dict, task_options: Optional[Any]) -> tuple[str, str]: """ - warnings.warn( - "`get_framework` is deprecated and will be removed in v5, use `infer_framework_from_model` instead.", - FutureWarning, - ) - if not is_tf_available() and not is_torch_available(): - raise RuntimeError( - "At least one of TensorFlow 2.0 or PyTorch should be installed. " - "To install TensorFlow 2.0, read the instructions at https://www.tensorflow.org/install/ " - "To install PyTorch, read the instructions at https://pytorch.org/." - ) - if isinstance(model, str): - if is_torch_available() and not is_tf_available(): - model = AutoModel.from_pretrained(model, revision=revision) - elif is_tf_available() and not is_torch_available(): - model = TFAutoModel.from_pretrained(model, revision=revision) - else: - try: - model = AutoModel.from_pretrained(model, revision=revision) - except OSError: - model = TFAutoModel.from_pretrained(model, revision=revision) - - framework = infer_framework(model.__class__) - return framework - - -def get_default_model_and_revision( - targeted_task: dict, framework: Optional[str], task_options: Optional[Any] -) -> tuple[str, str]: - """ - Select a default model to use for a given task. Defaults to pytorch if ambiguous. + Select a default model to use for a given task. Args: targeted_task (`Dict`): Dictionary representing the given task, that should contain default models - framework (`str`, None) - "pt", "tf" or None, representing a specific framework if it was specified, or None if we don't know yet. - task_options (`Any`, None) Any further value required by the task to get fully specified, for instance (SRC, TGT) languages for translation task. @@ -435,11 +311,6 @@ def get_default_model_and_revision( - `str` The model string representing the default model for this pipeline. - `str` The revision of the model. """ - if is_torch_available() and not is_tf_available(): - framework = "pt" - elif is_tf_available() and not is_torch_available(): - framework = "tf" - defaults = targeted_task["default"] if task_options: if task_options not in defaults: @@ -452,10 +323,7 @@ def get_default_model_and_revision( # parametrized raise ValueError('The task defaults can\'t be correctly selected. You probably meant "translation_xx_to_yy"') - if framework is None: - framework = "pt" - - return default_models[framework] + return default_models def load_assistant_model( @@ -480,16 +348,10 @@ def load_assistant_model( if not model.can_generate() or assistant_model is None: return None, None - if getattr(model, "framework") != "pt" or not isinstance(model, PreTrainedModel): - raise ValueError( - "Assisted generation, triggered by the `assistant_model` argument, is only available for " - "`PreTrainedModel` model instances. For instance, TF or JAX models are not supported." - ) - # If the model is passed as a string, load the model and the corresponding tokenizer if isinstance(assistant_model, str): assistant_config = AutoConfig.from_pretrained(assistant_model) - _, loaded_assistant_model = infer_framework_load_model(assistant_model, config=assistant_config) + loaded_assistant_model = load_model(assistant_model, config=assistant_config) loaded_assistant_model = loaded_assistant_model.to(device=model.device, dtype=model.dtype) loaded_assistant_tokenizer = AutoTokenizer.from_pretrained(assistant_model) else: @@ -811,9 +673,9 @@ def build_pipeline_init_args( ) -> str: docstring = r""" Arguments: - model ([`PreTrainedModel`] or [`TFPreTrainedModel`]): + model ([`PreTrainedModel`]): The model that will be used by the pipeline to make predictions. This needs to be a model inheriting from - [`PreTrainedModel`] for PyTorch and [`TFPreTrainedModel`] for TensorFlow.""" + [`PreTrainedModel`].""" if has_tokenizer: docstring += r""" tokenizer ([`PreTrainedTokenizer`]): @@ -838,13 +700,6 @@ def build_pipeline_init_args( docstring += r""" modelcard (`str` or [`ModelCard`], *optional*): Model card attributed to the model for this pipeline. - framework (`str`, *optional*): - The framework to use, either `"pt"` for PyTorch or `"tf"` for TensorFlow. The specified framework must be - installed. - - If no framework is specified, will default to the one currently installed. If no framework is specified and - both frameworks are installed, will default to the framework of the `model`, or to PyTorch if no model is - provided. task (`str`, defaults to `""`): A task-identifier for the pipeline. num_workers (`int`, *optional*, defaults to 8): @@ -943,13 +798,12 @@ class Pipeline(_ScikitCompat, PushToHubMixin): def __init__( self, - model: Union["PreTrainedModel", "TFPreTrainedModel"], + model: "PreTrainedModel", tokenizer: Optional[PreTrainedTokenizer] = None, feature_extractor: Optional[PreTrainedFeatureExtractor] = None, image_processor: Optional[BaseImageProcessor] = None, processor: Optional[ProcessorMixin] = None, modelcard: Optional[ModelCard] = None, - framework: Optional[str] = None, task: str = "", device: Optional[Union[int, "torch.device"]] = None, binary_output: bool = False, @@ -957,13 +811,6 @@ def __init__( ): # We need to pop them for _sanitize_parameters call later _, _, _ = kwargs.pop("args_parser", None), kwargs.pop("torch_dtype", None), kwargs.pop("dtype", None) - if framework is None: - framework, model = infer_framework_load_model(model, config=model.config) - if framework in ("tf", "jax"): - logger.warning_once( - "TensorFlow and JAX classes are deprecated and will be removed in Transformers v5. We " - "recommend migrating to PyTorch classes or pinning your version of Transformers." - ) self.task = task self.model = model @@ -972,7 +819,6 @@ def __init__( self.image_processor = image_processor self.processor = processor self.modelcard = modelcard - self.framework = framework # `accelerate` device map hf_device_map = getattr(self.model, "hf_device_map", None) @@ -990,45 +836,42 @@ def __init__( else: device = 0 - if is_torch_available() and self.framework == "pt": - if device == -1 and self.model.device is not None: - device = self.model.device - if isinstance(device, torch.device): - if (device.type == "xpu" and not is_torch_xpu_available(check_device=True)) or ( - device.type == "hpu" and not is_torch_hpu_available() - ): - raise ValueError(f'{device} is not available, you should use device="cpu" instead') + if device == -1 and self.model.device is not None: + device = self.model.device + if isinstance(device, torch.device): + if (device.type == "xpu" and not is_torch_xpu_available(check_device=True)) or ( + device.type == "hpu" and not is_torch_hpu_available() + ): + raise ValueError(f'{device} is not available, you should use device="cpu" instead') - self.device = device - elif isinstance(device, str): - if ("xpu" in device and not is_torch_xpu_available(check_device=True)) or ( - "hpu" in device and not is_torch_hpu_available() - ): - raise ValueError(f'{device} is not available, you should use device="cpu" instead') - - self.device = torch.device(device) - elif device < 0: - self.device = torch.device("cpu") - elif is_torch_mlu_available(): - self.device = torch.device(f"mlu:{device}") - elif is_torch_musa_available(): - self.device = torch.device(f"musa:{device}") - elif is_torch_cuda_available(): - self.device = torch.device(f"cuda:{device}") - elif is_torch_npu_available(): - self.device = torch.device(f"npu:{device}") - elif is_torch_hpu_available(): - self.device = torch.device(f"hpu:{device}") - elif is_torch_xpu_available(check_device=True): - self.device = torch.device(f"xpu:{device}") - elif is_torch_mps_available(): - self.device = torch.device(f"mps:{device}") - else: - self.device = torch.device("cpu") + self.device = device + elif isinstance(device, str): + if ("xpu" in device and not is_torch_xpu_available(check_device=True)) or ( + "hpu" in device and not is_torch_hpu_available() + ): + raise ValueError(f'{device} is not available, you should use device="cpu" instead') + + self.device = torch.device(device) + elif device < 0: + self.device = torch.device("cpu") + elif is_torch_mlu_available(): + self.device = torch.device(f"mlu:{device}") + elif is_torch_musa_available(): + self.device = torch.device(f"musa:{device}") + elif is_torch_cuda_available(): + self.device = torch.device(f"cuda:{device}") + elif is_torch_npu_available(): + self.device = torch.device(f"npu:{device}") + elif is_torch_hpu_available(): + self.device = torch.device(f"hpu:{device}") + elif is_torch_xpu_available(check_device=True): + self.device = torch.device(f"xpu:{device}") + elif is_torch_mps_available(): + self.device = torch.device(f"mps:{device}") else: - self.device = device if device is not None else -1 + self.device = torch.device("cpu") - if is_torch_available() and torch.distributed.is_available() and torch.distributed.is_initialized(): + if torch.distributed.is_available() and torch.distributed.is_initialized(): self.device = self.model.device logger.warning(f"Device set to use {self.device}") @@ -1036,8 +879,7 @@ def __init__( # We shouldn't call `model.to()` for models loaded with accelerate as well as the case that model is already on device if ( - self.framework == "pt" - and self.model.device != self.device + self.model.device != self.device and not (isinstance(self.device, int) and self.device < 0) and hf_device_map is None ): @@ -1055,7 +897,7 @@ def __init__( # each pipeline with text generation capabilities should define its own default generation in a # `_default_generation_config` class attribute default_pipeline_generation_config = getattr(self, "_default_generation_config", GenerationConfig()) - if hasattr(self.model, "_prepare_generation_config"): # TF doesn't have `_prepare_generation_config` + if hasattr(self.model, "_prepare_generation_config"): # Uses `generate`'s logic to enforce the following priority of arguments: # 1. user-defined config options in `**kwargs` # 2. model's generation config values @@ -1131,7 +973,7 @@ def save_pretrained( save_directory (`str` or `os.PathLike`): A path to the directory where to saved. It will be created if it doesn't exist. safe_serialization (`str`): - Whether to save the model using `safetensors` or the traditional way for PyTorch or Tensorflow. + Whether to save the model using `safetensors` or PyTorch serialization. kwargs (`dict[str, Any]`, *optional*): Additional key word arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method. """ @@ -1167,7 +1009,6 @@ def save_pretrained( # Change classes into their names/full names info["impl"] = f"{last_module}.{info['impl'].__name__}" info["pt"] = tuple(c.__name__ for c in info["pt"]) - info["tf"] = tuple(c.__name__ for c in info["tf"]) custom_pipelines[task] = info self.model.config.custom_pipelines = custom_pipelines @@ -1219,7 +1060,7 @@ def torch_dtype(self) -> Optional["torch.dtype"]: @contextmanager def device_placement(self): """ - Context Manager allowing tensor allocation on the user-specified device in framework agnostic way. + Context Manager allowing tensor allocation on the user-specified device. Returns: Context manager @@ -1230,27 +1071,23 @@ def device_placement(self): # Explicitly ask for tensor allocation on CUDA device :0 pipe = pipeline(..., device=0) with pipe.device_placement(): - # Every framework specific tensor allocation will be done on the request device + # Every tensor allocation will be done on the request device output = pipe(...) ```""" - if self.framework == "tf": - with tf.device("/CPU:0" if self.device == -1 else f"/device:GPU:{self.device}"): + if self.device.type == "cuda": + with torch.cuda.device(self.device): yield - else: - if self.device.type == "cuda": - with torch.cuda.device(self.device): - yield - elif self.device.type == "mlu": - with torch.mlu.device(self.device): - yield - elif self.device.type == "musa": - with torch.musa.device(self.device): - yield - elif self.device.type == "xpu": - with torch.xpu.device(self.device): - yield - else: + elif self.device.type == "mlu": + with torch.mlu.device(self.device): + yield + elif self.device.type == "musa": + with torch.musa.device(self.device): + yield + elif self.device.type == "xpu": + with torch.xpu.device(self.device): yield + else: + yield def ensure_tensor_on_device(self, **inputs): """ @@ -1364,17 +1201,11 @@ def get_inference_context(self): def forward(self, model_inputs, **forward_params): with self.device_placement(): - if self.framework == "tf": - model_inputs["training"] = False + inference_context = self.get_inference_context() + with inference_context(): + model_inputs = self._ensure_tensor_on_device(model_inputs, device=self.device) model_outputs = self._forward(model_inputs, **forward_params) - elif self.framework == "pt": - inference_context = self.get_inference_context() - with inference_context(): - model_inputs = self._ensure_tensor_on_device(model_inputs, device=self.device) - model_outputs = self._forward(model_inputs, **forward_params) - model_outputs = self._ensure_tensor_on_device(model_outputs, device=torch.device("cpu")) - else: - raise ValueError(f"Framework {self.framework} is not supported") + model_outputs = self._ensure_tensor_on_device(model_outputs, device=torch.device("cpu")) return model_outputs def get_iterator( @@ -1425,7 +1256,7 @@ def __call__(self, inputs, *args, num_workers=None, batch_size=None, **kwargs): postprocess_params = {**self._postprocess_params, **postprocess_params} self.call_count += 1 - if self.call_count > 10 and self.framework == "pt" and self.device.type == "cuda": + if self.call_count > 10 and self.device.type == "cuda": logger.warning_once( "You seem to be using the pipelines sequentially on GPU. In order to maximize efficiency please use a" " dataset", @@ -1436,9 +1267,7 @@ def __call__(self, inputs, *args, num_workers=None, batch_size=None, **kwargs): is_list = isinstance(inputs, list) is_iterable = is_dataset or is_generator or is_list - - # TODO make the get_iterator work also for `tf` (and `flax`). - can_use_iterator = self.framework == "pt" and (is_dataset or is_generator or is_list) + can_use_iterator = is_dataset or is_generator or is_list if is_list: if can_use_iterator: @@ -1455,7 +1284,7 @@ def __call__(self, inputs, *args, num_workers=None, batch_size=None, **kwargs): ) elif is_iterable: return self.iterate(inputs, preprocess_params, forward_params, postprocess_params) - elif self.framework == "pt" and isinstance(self, ChunkPipeline): + elif isinstance(self, ChunkPipeline): return next( iter( self.get_iterator( @@ -1550,13 +1379,11 @@ def check_task(self, task: str) -> tuple[str, dict, Any]: f"Unknown task {task}, available tasks are {self.get_supported_tasks() + ['translation_XX_to_YY']}" ) - @deprecate_kwarg(old_name="tf_model", version="5.0.0") def register_pipeline( self, task: str, pipeline_class: type, pt_model: Optional[Union[type, tuple[type]]] = None, - tf_model: Optional[Union[type, tuple[type]]] = None, default: Optional[dict] = None, type: Optional[str] = None, ) -> None: @@ -1568,15 +1395,10 @@ def register_pipeline( elif not isinstance(pt_model, tuple): pt_model = (pt_model,) - if tf_model is None: - tf_model = () - elif not isinstance(tf_model, tuple): - tf_model = (tf_model,) - - task_impl = {"impl": pipeline_class, "pt": pt_model, "tf": tf_model} + task_impl = {"impl": pipeline_class, "pt": pt_model} if default is not None: - if "model" not in default and ("pt" in default or "tf" in default): + if "model" not in default: default = {"model": default} task_impl["default"] = default diff --git a/src/transformers/pipelines/depth_estimation.py b/src/transformers/pipelines/depth_estimation.py index 588cee770639..36bbe46b4e3e 100644 --- a/src/transformers/pipelines/depth_estimation.py +++ b/src/transformers/pipelines/depth_estimation.py @@ -115,9 +115,8 @@ def _sanitize_parameters(self, timeout=None, parameters=None, **kwargs): def preprocess(self, image, timeout=None): image = load_image(image, timeout) - model_inputs = self.image_processor(images=image, return_tensors=self.framework) - if self.framework == "pt": - model_inputs = model_inputs.to(self.dtype) + model_inputs = self.image_processor(images=image, return_tensors="pt") + model_inputs = model_inputs.to(self.dtype) model_inputs["target_size"] = image.size[::-1] return model_inputs diff --git a/src/transformers/pipelines/document_question_answering.py b/src/transformers/pipelines/document_question_answering.py index d45e756b0f3f..e6592a8ab4a3 100644 --- a/src/transformers/pipelines/document_question_answering.py +++ b/src/transformers/pipelines/document_question_answering.py @@ -331,12 +331,11 @@ def preprocess( if input.get("image", None) is not None: image = load_image(input["image"], timeout=timeout) if self.image_processor is not None: - image_inputs = self.image_processor(images=image, return_tensors=self.framework) - if self.framework == "pt": - image_inputs = image_inputs.to(self.dtype) + image_inputs = self.image_processor(images=image, return_tensors="pt") + image_inputs = image_inputs.to(self.dtype) image_features.update(image_inputs) elif self.feature_extractor is not None: - image_features.update(self.feature_extractor(images=image, return_tensors=self.framework)) + image_features.update(self.feature_extractor(images=image, return_tensors="pt")) elif self.model_type == ModelType.VisionEncoderDecoder: raise ValueError("If you are using a VisionEncoderDecoderModel, you must provide a feature extractor") @@ -374,7 +373,7 @@ def preprocess( encoding = { "inputs": image_features["pixel_values"], "decoder_input_ids": self.tokenizer( - task_prompt, add_special_tokens=False, return_tensors=self.framework + task_prompt, add_special_tokens=False, return_tensors="pt" ).input_ids, "return_dict_in_generate": True, } @@ -417,12 +416,9 @@ def preprocess( # This logic mirrors the logic in the question_answering pipeline p_mask = [[tok != 1 for tok in encoding.sequence_ids(span_id)] for span_id in range(num_spans)] for span_idx in range(num_spans): - if self.framework == "pt": - span_encoding = {k: torch.tensor(v[span_idx : span_idx + 1]) for (k, v) in encoding.items()} - if "pixel_values" in image_features: - span_encoding["image"] = image_features["pixel_values"] - else: - raise ValueError("Unsupported: Tensorflow preprocessing for DocumentQuestionAnsweringPipeline") + span_encoding = {k: torch.tensor(v[span_idx : span_idx + 1]) for (k, v) in encoding.items()} + if "pixel_values" in image_features: + span_encoding["image"] = image_features["pixel_values"] input_ids_span_idx = encoding["input_ids"][span_idx] # keep the cls_token unmasked (some models use it to indicate unanswerable questions) @@ -447,10 +443,7 @@ def preprocess( else: bbox.append([0] * 4) - if self.framework == "pt": - span_encoding["bbox"] = torch.tensor(bbox).unsqueeze(0) - elif self.framework == "tf": - raise ValueError("Unsupported: Tensorflow preprocessing for DocumentQuestionAnsweringPipeline") + span_encoding["bbox"] = torch.tensor(bbox).unsqueeze(0) yield { **span_encoding, "p_mask": p_mask[span_idx], @@ -515,9 +508,9 @@ def postprocess_extractive_qa( for output in model_outputs: words = output["words"] - if self.framework == "pt" and output["start_logits"].dtype in (torch.bfloat16, torch.float16): + if output["start_logits"].dtype in (torch.bfloat16, torch.float16): output["start_logits"] = output["start_logits"].float() - if self.framework == "pt" and output["end_logits"].dtype in (torch.bfloat16, torch.float16): + if output["end_logits"].dtype in (torch.bfloat16, torch.float16): output["end_logits"] = output["end_logits"].float() starts, ends, scores, min_null_score = select_starts_ends( diff --git a/src/transformers/pipelines/feature_extraction.py b/src/transformers/pipelines/feature_extraction.py index 9c8005d05f22..69c341d3d846 100644 --- a/src/transformers/pipelines/feature_extraction.py +++ b/src/transformers/pipelines/feature_extraction.py @@ -62,7 +62,7 @@ def _sanitize_parameters(self, truncation=None, tokenize_kwargs=None, return_ten return preprocess_params, {}, postprocess_params def preprocess(self, inputs, **tokenize_kwargs) -> dict[str, GenericTensor]: - model_inputs = self.tokenizer(inputs, return_tensors=self.framework, **tokenize_kwargs) + model_inputs = self.tokenizer(inputs, return_tensors="pt", **tokenize_kwargs) return model_inputs def _forward(self, model_inputs): @@ -73,10 +73,7 @@ def postprocess(self, model_outputs, return_tensors=False): # [0] is the first available tensor, logits or last_hidden_state. if return_tensors: return model_outputs[0] - if self.framework == "pt": - return model_outputs[0].tolist() - elif self.framework == "tf": - return model_outputs[0].numpy().tolist() + return model_outputs[0].tolist() def __call__(self, *args: Union[str, list[str]], **kwargs: Any) -> Union[Any, list[Any]]: """ diff --git a/src/transformers/pipelines/fill_mask.py b/src/transformers/pipelines/fill_mask.py index cc69cf6d2792..eb5ec7d0d362 100644 --- a/src/transformers/pipelines/fill_mask.py +++ b/src/transformers/pipelines/fill_mask.py @@ -2,16 +2,10 @@ import numpy as np -from ..utils import add_end_docstrings, is_tf_available, is_torch_available, logging +from ..utils import add_end_docstrings, is_torch_available, logging from .base import GenericTensor, Pipeline, PipelineException, build_pipeline_init_args -if is_tf_available(): - import tensorflow as tf - - from ..tf_utils import stable_softmax - - if is_torch_available(): import torch @@ -90,12 +84,7 @@ class FillMaskPipeline(Pipeline): """ def get_masked_index(self, input_ids: GenericTensor) -> np.ndarray: - if self.framework == "tf": - masked_index = tf.where(input_ids == self.tokenizer.mask_token_id).numpy() - elif self.framework == "pt": - masked_index = torch.nonzero(input_ids == self.tokenizer.mask_token_id, as_tuple=False) - else: - raise ValueError("Unsupported framework") + masked_index = torch.nonzero(input_ids == self.tokenizer.mask_token_id, as_tuple=False) return masked_index def _ensure_exactly_one_mask_token(self, input_ids: GenericTensor) -> np.ndarray: @@ -120,7 +109,7 @@ def preprocess( self, inputs, return_tensors=None, tokenizer_kwargs=None, **preprocess_parameters ) -> dict[str, GenericTensor]: if return_tensors is None: - return_tensors = self.framework + return_tensors = "pt" if tokenizer_kwargs is None: tokenizer_kwargs = {} @@ -140,29 +129,15 @@ def postprocess(self, model_outputs, top_k=5, target_ids=None): input_ids = model_outputs["input_ids"][0] outputs = model_outputs["logits"] - if self.framework == "tf": - masked_index = tf.where(input_ids == self.tokenizer.mask_token_id).numpy()[:, 0] - - outputs = outputs.numpy() - - logits = outputs[0, masked_index, :] - probs = stable_softmax(logits, axis=-1) - if target_ids is not None: - probs = tf.gather_nd(tf.squeeze(probs, 0), target_ids.reshape(-1, 1)) - probs = tf.expand_dims(probs, 0) - - topk = tf.math.top_k(probs, k=top_k) - values, predictions = topk.values.numpy(), topk.indices.numpy() - else: - masked_index = torch.nonzero(input_ids == self.tokenizer.mask_token_id, as_tuple=False).squeeze(-1) - # Fill mask pipeline supports only one ${mask_token} per sample + masked_index = torch.nonzero(input_ids == self.tokenizer.mask_token_id, as_tuple=False).squeeze(-1) + # Fill mask pipeline supports only one ${mask_token} per sample - logits = outputs[0, masked_index, :] - probs = logits.softmax(dim=-1) - if target_ids is not None: - probs = probs[..., target_ids] + logits = outputs[0, masked_index, :] + probs = logits.softmax(dim=-1) + if target_ids is not None: + probs = probs[..., target_ids] - values, predictions = probs.topk(top_k) + values, predictions = probs.topk(top_k) result = [] single_mask = values.shape[0] == 1 diff --git a/src/transformers/pipelines/image_classification.py b/src/transformers/pipelines/image_classification.py index a30c45285982..6f87fb3aebdf 100644 --- a/src/transformers/pipelines/image_classification.py +++ b/src/transformers/pipelines/image_classification.py @@ -18,7 +18,6 @@ from ..utils import ( ExplicitEnum, add_end_docstrings, - is_tf_available, is_torch_available, is_vision_available, logging, @@ -32,9 +31,6 @@ from ..image_utils import load_image -if is_tf_available(): - from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES - if is_torch_available(): import torch @@ -107,11 +103,7 @@ class ImageClassificationPipeline(Pipeline): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) requires_backends(self, "vision") - self.check_model_type( - TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES - if self.framework == "tf" - else MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES - ) + self.check_model_type(MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES) def _sanitize_parameters(self, top_k=None, function_to_apply=None, timeout=None): preprocess_params = {} @@ -190,9 +182,8 @@ def __call__( def preprocess(self, image, timeout=None): image = load_image(image, timeout=timeout) - model_inputs = self.image_processor(images=image, return_tensors=self.framework) - if self.framework == "pt": - model_inputs = model_inputs.to(self.dtype) + model_inputs = self.image_processor(images=image, return_tensors="pt") + model_inputs = model_inputs.to(self.dtype) return model_inputs def _forward(self, model_inputs): @@ -214,7 +205,7 @@ def postprocess(self, model_outputs, function_to_apply=None, top_k=5): top_k = self.model.config.num_labels outputs = model_outputs["logits"][0] - if self.framework == "pt" and outputs.dtype in (torch.bfloat16, torch.float16): + if outputs.dtype in (torch.bfloat16, torch.float16): outputs = outputs.to(torch.float32).numpy() else: outputs = outputs.numpy() diff --git a/src/transformers/pipelines/image_feature_extraction.py b/src/transformers/pipelines/image_feature_extraction.py index a87ecafb684e..d049957a4138 100644 --- a/src/transformers/pipelines/image_feature_extraction.py +++ b/src/transformers/pipelines/image_feature_extraction.py @@ -66,9 +66,8 @@ def _sanitize_parameters(self, image_processor_kwargs=None, return_tensors=None, def preprocess(self, image, timeout=None, **image_processor_kwargs) -> dict[str, GenericTensor]: image = load_image(image, timeout=timeout) - model_inputs = self.image_processor(image, return_tensors=self.framework, **image_processor_kwargs) - if self.framework == "pt": - model_inputs = model_inputs.to(self.dtype) + model_inputs = self.image_processor(image, return_tensors="pt", **image_processor_kwargs) + model_inputs = model_inputs.to(self.dtype) return model_inputs def _forward(self, model_inputs): @@ -90,10 +89,7 @@ def postprocess(self, model_outputs, pool=None, return_tensors=False): if return_tensors: return outputs - if self.framework == "pt": - return outputs.tolist() - elif self.framework == "tf": - return outputs.numpy().tolist() + return outputs.tolist() def __call__(self, *args: Union[str, "Image.Image", list["Image.Image"], list[str]], **kwargs: Any) -> list[Any]: """ diff --git a/src/transformers/pipelines/image_segmentation.py b/src/transformers/pipelines/image_segmentation.py index ed09f15d5e13..a6c7ef362d95 100644 --- a/src/transformers/pipelines/image_segmentation.py +++ b/src/transformers/pipelines/image_segmentation.py @@ -68,9 +68,6 @@ class ImageSegmentationPipeline(Pipeline): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if self.framework == "tf": - raise ValueError(f"The {self.__class__} is only available in PyTorch.") - requires_backends(self, "vision") mapping = MODEL_FOR_IMAGE_SEGMENTATION_MAPPING_NAMES.copy() mapping.update(MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES) @@ -160,18 +157,16 @@ def preprocess(self, image, subtask=None, timeout=None): else: kwargs = {"task_inputs": [subtask]} inputs = self.image_processor(images=[image], return_tensors="pt", **kwargs) - if self.framework == "pt": - inputs = inputs.to(self.dtype) + inputs = inputs.to(self.dtype) inputs["task_inputs"] = self.tokenizer( inputs["task_inputs"], padding="max_length", max_length=self.model.config.task_seq_len, - return_tensors=self.framework, + return_tensors="pt", )["input_ids"] else: inputs = self.image_processor(images=[image], return_tensors="pt") - if self.framework == "pt": - inputs = inputs.to(self.dtype) + inputs = inputs.to(self.dtype) inputs["target_size"] = target_size return inputs diff --git a/src/transformers/pipelines/image_text_to_text.py b/src/transformers/pipelines/image_text_to_text.py index 2564d53ba1d7..d42ed96213a6 100644 --- a/src/transformers/pipelines/image_text_to_text.py +++ b/src/transformers/pipelines/image_text_to_text.py @@ -396,7 +396,7 @@ def preprocess(self, inputs=None, timeout=None, continue_final_message=None, **p inputs.messages, add_generation_prompt=not continue_final_message, continue_final_message=continue_final_message, - return_tensors=self.framework, + return_tensors="pt", tokenize=True, return_dict=True, ) @@ -415,7 +415,7 @@ def preprocess(self, inputs=None, timeout=None, continue_final_message=None, **p # if batched text inputs, we set padding to True unless specified otherwise if isinstance(text, (list, tuple)) and len(text) > 1: processing_kwargs.setdefault("padding", True) - model_inputs = self.processor(images=images, text=text, return_tensors=self.framework, **processing_kwargs).to( + model_inputs = self.processor(images=images, text=text, return_tensors="pt", **processing_kwargs).to( dtype=self.dtype ) diff --git a/src/transformers/pipelines/image_to_image.py b/src/transformers/pipelines/image_to_image.py index d469024bff17..094a511449d6 100644 --- a/src/transformers/pipelines/image_to_image.py +++ b/src/transformers/pipelines/image_to_image.py @@ -130,8 +130,7 @@ def _forward(self, model_inputs): def preprocess(self, image, timeout=None): image = load_image(image, timeout=timeout) inputs = self.image_processor(images=[image], return_tensors="pt") - if self.framework == "pt": - inputs = inputs.to(self.dtype) + inputs = inputs.to(self.dtype) return inputs def postprocess(self, model_outputs): diff --git a/src/transformers/pipelines/image_to_text.py b/src/transformers/pipelines/image_to_text.py index 51f9e70cdd61..f77a19603072 100644 --- a/src/transformers/pipelines/image_to_text.py +++ b/src/transformers/pipelines/image_to_text.py @@ -18,7 +18,6 @@ from ..generation import GenerationConfig from ..utils import ( add_end_docstrings, - is_tf_available, is_torch_available, is_vision_available, logging, @@ -32,9 +31,6 @@ from ..image_utils import load_image -if is_tf_available(): - from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES - if is_torch_available(): import torch @@ -84,9 +80,7 @@ class ImageToTextPipeline(Pipeline): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) requires_backends(self, "vision") - self.check_model_type( - TF_MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES if self.framework == "tf" else MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES - ) + self.check_model_type(MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES) def _sanitize_parameters(self, max_new_tokens=None, generate_kwargs=None, prompt=None, timeout=None): forward_params = {} @@ -174,34 +168,30 @@ def preprocess(self, image, prompt=None, timeout=None): model_type = self.model.config.model_type if model_type == "git": - model_inputs = self.image_processor(images=image, return_tensors=self.framework) - if self.framework == "pt": - model_inputs = model_inputs.to(self.dtype) + model_inputs = self.image_processor(images=image, return_tensors="pt") + model_inputs = model_inputs.to(self.dtype) input_ids = self.tokenizer(text=prompt, add_special_tokens=False).input_ids input_ids = [self.tokenizer.cls_token_id] + input_ids input_ids = torch.tensor(input_ids).unsqueeze(0) model_inputs.update({"input_ids": input_ids}) elif model_type == "pix2struct": - model_inputs = self.image_processor(images=image, header_text=prompt, return_tensors=self.framework) - if self.framework == "pt": - model_inputs = model_inputs.to(self.dtype) + model_inputs = self.image_processor(images=image, header_text=prompt, return_tensors="pt") + model_inputs = model_inputs.to(self.dtype) elif model_type != "vision-encoder-decoder": # vision-encoder-decoder does not support conditional generation - model_inputs = self.image_processor(images=image, return_tensors=self.framework) - if self.framework == "pt": - model_inputs = model_inputs.to(self.dtype) - text_inputs = self.tokenizer(prompt, return_tensors=self.framework) + model_inputs = self.image_processor(images=image, return_tensors="pt") + model_inputs = model_inputs.to(self.dtype) + text_inputs = self.tokenizer(prompt, return_tensors="pt") model_inputs.update(text_inputs) else: raise ValueError(f"Model type {model_type} does not support conditional text generation") else: - model_inputs = self.image_processor(images=image, return_tensors=self.framework) - if self.framework == "pt": - model_inputs = model_inputs.to(self.dtype) + model_inputs = self.image_processor(images=image, return_tensors="pt") + model_inputs = model_inputs.to(self.dtype) if self.model.config.model_type == "git" and prompt is None: model_inputs["input_ids"] = None @@ -222,10 +212,6 @@ def _forward(self, model_inputs, **generate_kwargs): if "generation_config" not in generate_kwargs: generate_kwargs["generation_config"] = self.generation_config - # FIXME: We need to pop here due to a difference in how `generation.py` and `generation.tf_utils.py` - # parse inputs. In the Tensorflow version, `generate` raises an error if we don't use `input_ids` whereas - # the PyTorch version matches it with `self.model.main_input_name` or `self.model.encoder.main_input_name` - # in the `_prepare_model_inputs` method. inputs = model_inputs.pop(self.model.main_input_name) model_outputs = self.model.generate(inputs, **model_inputs, **generate_kwargs) return model_outputs diff --git a/src/transformers/pipelines/keypoint_matching.py b/src/transformers/pipelines/keypoint_matching.py index 6878f40ad985..1e0d57d254e0 100644 --- a/src/transformers/pipelines/keypoint_matching.py +++ b/src/transformers/pipelines/keypoint_matching.py @@ -79,8 +79,6 @@ class KeypointMatchingPipeline(Pipeline): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) requires_backends(self, "vision") - if self.framework != "pt": - raise ValueError("Keypoint matching pipeline only supports PyTorch (framework='pt').") def _sanitize_parameters(self, threshold=None, timeout=None): preprocess_params = {} @@ -146,7 +144,7 @@ def __call__( def preprocess(self, images, timeout=None): images = [load_image(image, timeout=timeout) for image in images] - model_inputs = self.image_processor(images=images, return_tensors=self.framework) + model_inputs = self.image_processor(images=images, return_tensors="pt") model_inputs = model_inputs.to(self.dtype) target_sizes = [image.size for image in images] preprocess_outputs = {"model_inputs": model_inputs, "target_sizes": target_sizes} diff --git a/src/transformers/pipelines/mask_generation.py b/src/transformers/pipelines/mask_generation.py index 3a65fdff617a..f7354807afa2 100644 --- a/src/transformers/pipelines/mask_generation.py +++ b/src/transformers/pipelines/mask_generation.py @@ -94,9 +94,6 @@ def __init__(self, **kwargs): requires_backends(self, "vision") requires_backends(self, "torch") - if self.framework != "pt": - raise ValueError(f"The {self.__class__} is only available in PyTorch.") - self.check_model_type(MODEL_FOR_MASK_GENERATION_MAPPING_NAMES) def _sanitize_parameters(self, **kwargs): @@ -205,26 +202,24 @@ def preprocess( image, target_size, crops_n_layers, crop_overlap_ratio, points_per_crop, crop_n_points_downscale_factor ) model_inputs = self.image_processor(images=cropped_images, return_tensors="pt") - if self.framework == "pt": - model_inputs = model_inputs.to(self.dtype) + model_inputs = model_inputs.to(self.dtype) with self.device_placement(): - if self.framework == "pt": - inference_context = self.get_inference_context() - with inference_context(): - model_inputs = self._ensure_tensor_on_device(model_inputs, device=self.device) - embeddings = self.model.get_image_embeddings(model_inputs.pop("pixel_values")) - - # Handle both SAM (single tensor) and SAM-HQ (tuple) outputs - if isinstance(embeddings, tuple): - image_embeddings, intermediate_embeddings = embeddings - model_inputs["intermediate_embeddings"] = intermediate_embeddings - else: - image_embeddings = embeddings - # TODO: Identifying the model by the type of its returned embeddings is brittle. - # Consider using a more robust method for distinguishing model types here. - - model_inputs["image_embeddings"] = image_embeddings + inference_context = self.get_inference_context() + with inference_context(): + model_inputs = self._ensure_tensor_on_device(model_inputs, device=self.device) + embeddings = self.model.get_image_embeddings(model_inputs.pop("pixel_values")) + + # Handle both SAM (single tensor) and SAM-HQ (tuple) outputs + if isinstance(embeddings, tuple): + image_embeddings, intermediate_embeddings = embeddings + model_inputs["intermediate_embeddings"] = intermediate_embeddings + else: + image_embeddings = embeddings + # TODO: Identifying the model by the type of its returned embeddings is brittle. + # Consider using a more robust method for distinguishing model types here. + + model_inputs["image_embeddings"] = image_embeddings n_points = grid_points.shape[1] points_per_batch = points_per_batch if points_per_batch is not None else n_points diff --git a/src/transformers/pipelines/object_detection.py b/src/transformers/pipelines/object_detection.py index 0db67f84d248..49739e383810 100644 --- a/src/transformers/pipelines/object_detection.py +++ b/src/transformers/pipelines/object_detection.py @@ -56,9 +56,6 @@ class ObjectDetectionPipeline(Pipeline): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if self.framework == "tf": - raise ValueError(f"The {self.__class__} is only available in PyTorch.") - requires_backends(self, "vision") mapping = MODEL_FOR_OBJECT_DETECTION_MAPPING_NAMES.copy() mapping.update(MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES) @@ -121,8 +118,7 @@ def preprocess(self, image, timeout=None): image = load_image(image, timeout=timeout) target_size = torch.IntTensor([[image.height, image.width]]) inputs = self.image_processor(images=[image], return_tensors="pt") - if self.framework == "pt": - inputs = inputs.to(self.dtype) + inputs = inputs.to(self.dtype) if self.tokenizer is not None: inputs = self.tokenizer(text=inputs["words"], boxes=inputs["boxes"], return_tensors="pt") inputs["target_size"] = target_size @@ -191,8 +187,6 @@ def _get_bounding_box(self, box: "torch.Tensor") -> dict[str, int]: Returns: bbox (`dict[str, int]`): Dict containing the coordinates in corners format. """ - if self.framework != "pt": - raise ValueError("The ObjectDetectionPipeline is only available in PyTorch.") xmin, ymin, xmax, ymax = box.int().tolist() bbox = { "xmin": xmin, diff --git a/src/transformers/pipelines/question_answering.py b/src/transformers/pipelines/question_answering.py index ee86074a4c58..c62aafc4fc68 100644 --- a/src/transformers/pipelines/question_answering.py +++ b/src/transformers/pipelines/question_answering.py @@ -12,7 +12,6 @@ from ..utils import ( PaddingStrategy, add_end_docstrings, - is_tf_available, is_tokenizers_available, is_torch_available, logging, @@ -23,18 +22,11 @@ logger = logging.get_logger(__name__) if TYPE_CHECKING: - from ..modeling_tf_utils import TFPreTrainedModel from ..modeling_utils import PreTrainedModel if is_tokenizers_available(): import tokenizers -if is_tf_available(): - import tensorflow as tf - - from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES - - Dataset = None if is_torch_available(): import torch @@ -265,10 +257,9 @@ class QuestionAnsweringPipeline(ChunkPipeline): def __init__( self, - model: Union["PreTrainedModel", "TFPreTrainedModel"], + model: "PreTrainedModel", tokenizer: PreTrainedTokenizer, modelcard: Optional[ModelCard] = None, - framework: Optional[str] = None, task: str = "", **kwargs, ): @@ -276,17 +267,12 @@ def __init__( model=model, tokenizer=tokenizer, modelcard=modelcard, - framework=framework, task=task, **kwargs, ) self._args_parser = QuestionAnsweringArgumentHandler() - self.check_model_type( - TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES - if self.framework == "tf" - else MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES - ) + self.check_model_type(MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES) @staticmethod def create_sample( @@ -503,16 +489,10 @@ def preprocess(self, example, padding="do_not_pad", doc_stride=None, max_questio for k, v in feature.__dict__.items(): if k in model_input_names: - if self.framework == "tf": - tensor = tf.constant(v) - if tensor.dtype == tf.int64: - tensor = tf.cast(tensor, tf.int32) - fw_args[k] = tf.expand_dims(tensor, 0) - elif self.framework == "pt": - tensor = torch.tensor(v) - if tensor.dtype == torch.int32: - tensor = tensor.long() - fw_args[k] = tensor.unsqueeze(0) + tensor = torch.tensor(v) + if tensor.dtype == torch.int32: + tensor = tensor.long() + fw_args[k] = tensor.unsqueeze(0) else: others[k] = v @@ -523,7 +503,7 @@ def _forward(self, inputs): example = inputs["example"] model_inputs = {k: inputs[k] for k in self.tokenizer.model_input_names} # `XXXForSequenceClassification` models should not use `use_cache=True` even if it's supported - model_forward = self.model.forward if self.framework == "pt" else self.model.call + model_forward = self.model.forward if "use_cache" in inspect.signature(model_forward).parameters: model_inputs["use_cache"] = False output = self.model(**model_inputs) @@ -544,7 +524,7 @@ def postprocess( min_null_score = 1000000 # large and positive answers = [] for output in model_outputs: - if self.framework == "pt" and output["start"].dtype == torch.bfloat16: + if output["start"].dtype == torch.bfloat16: start_ = output["start"].to(torch.float32) end_ = output["end"].to(torch.float32) else: diff --git a/src/transformers/pipelines/table_question_answering.py b/src/transformers/pipelines/table_question_answering.py index da579423d2d4..04190b552910 100644 --- a/src/transformers/pipelines/table_question_answering.py +++ b/src/transformers/pipelines/table_question_answering.py @@ -6,7 +6,6 @@ from ..generation import GenerationConfig from ..utils import ( add_end_docstrings, - is_tf_available, is_torch_available, requires_backends, ) @@ -21,14 +20,6 @@ MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES, ) -if is_tf_available(): - import tensorflow as tf - - from ..models.auto.modeling_tf_auto import ( - TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES, - TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES, - ) - class TableQuestionAnsweringArgumentHandler(ArgumentHandler): """ @@ -135,12 +126,8 @@ def __init__(self, args_parser=TableQuestionAnsweringArgumentHandler(), *args, * super().__init__(*args, **kwargs) self._args_parser = args_parser - if self.framework == "tf": - mapping = TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES.copy() - mapping.update(TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES) - else: - mapping = MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES.copy() - mapping.update(MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES) + mapping = MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES.copy() + mapping.update(MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES) self.check_model_type(mapping) self.aggregate = getattr(self.model.config, "aggregation_labels", None) and getattr( @@ -156,129 +143,67 @@ def sequential_inference(self, **inputs): Inference used for models that need to process sequences in a sequential fashion, like the SQA models which handle conversational query related to a table. """ - if self.framework == "pt": - all_logits = [] - all_aggregations = [] - prev_answers = None - batch_size = inputs["input_ids"].shape[0] - - input_ids = inputs["input_ids"].to(self.device) - attention_mask = inputs["attention_mask"].to(self.device) - token_type_ids = inputs["token_type_ids"].to(self.device) - token_type_ids_example = None - - for index in range(batch_size): - # If sequences have already been processed, the token type IDs will be created according to the previous - # answer. - if prev_answers is not None: - prev_labels_example = token_type_ids_example[:, 3] # shape (seq_len,) - model_labels = np.zeros_like(prev_labels_example.cpu().numpy()) # shape (seq_len,) - - token_type_ids_example = token_type_ids[index] # shape (seq_len, 7) - for i in range(model_labels.shape[0]): - segment_id = token_type_ids_example[:, 0].tolist()[i] - col_id = token_type_ids_example[:, 1].tolist()[i] - 1 - row_id = token_type_ids_example[:, 2].tolist()[i] - 1 - - if row_id >= 0 and col_id >= 0 and segment_id == 1: - model_labels[i] = int(prev_answers[(col_id, row_id)]) - - token_type_ids_example[:, 3] = torch.from_numpy(model_labels).type(torch.long).to(self.device) - - input_ids_example = input_ids[index] - attention_mask_example = attention_mask[index] # shape (seq_len,) - token_type_ids_example = token_type_ids[index] # shape (seq_len, 7) - outputs = self.model( - input_ids=input_ids_example.unsqueeze(0), - attention_mask=attention_mask_example.unsqueeze(0), - token_type_ids=token_type_ids_example.unsqueeze(0), - ) - logits = outputs.logits - - if self.aggregate: - all_aggregations.append(outputs.logits_aggregation) + all_logits = [] + all_aggregations = [] + prev_answers = None + batch_size = inputs["input_ids"].shape[0] + + input_ids = inputs["input_ids"].to(self.device) + attention_mask = inputs["attention_mask"].to(self.device) + token_type_ids = inputs["token_type_ids"].to(self.device) + token_type_ids_example = None + + for index in range(batch_size): + # If sequences have already been processed, the token type IDs will be created according to the previous + # answer. + if prev_answers is not None: + prev_labels_example = token_type_ids_example[:, 3] # shape (seq_len,) + model_labels = np.zeros_like(prev_labels_example.cpu().numpy()) # shape (seq_len,) - all_logits.append(logits) - - dist_per_token = torch.distributions.Bernoulli(logits=logits) - probabilities = dist_per_token.probs * attention_mask_example.type(torch.float32).to( - dist_per_token.probs.device - ) - - coords_to_probs = collections.defaultdict(list) - for i, p in enumerate(probabilities.squeeze().tolist()): + token_type_ids_example = token_type_ids[index] # shape (seq_len, 7) + for i in range(model_labels.shape[0]): segment_id = token_type_ids_example[:, 0].tolist()[i] - col = token_type_ids_example[:, 1].tolist()[i] - 1 - row = token_type_ids_example[:, 2].tolist()[i] - 1 - if col >= 0 and row >= 0 and segment_id == 1: - coords_to_probs[(col, row)].append(p) + col_id = token_type_ids_example[:, 1].tolist()[i] - 1 + row_id = token_type_ids_example[:, 2].tolist()[i] - 1 - prev_answers = {key: np.array(coords_to_probs[key]).mean() > 0.5 for key in coords_to_probs} + if row_id >= 0 and col_id >= 0 and segment_id == 1: + model_labels[i] = int(prev_answers[(col_id, row_id)]) - logits_batch = torch.cat(tuple(all_logits), 0) + token_type_ids_example[:, 3] = torch.from_numpy(model_labels).type(torch.long).to(self.device) - return (logits_batch,) if not self.aggregate else (logits_batch, torch.cat(tuple(all_aggregations), 0)) - else: - all_logits = [] - all_aggregations = [] - prev_answers = None - batch_size = inputs["input_ids"].shape[0] - - input_ids = inputs["input_ids"] - attention_mask = inputs["attention_mask"] - token_type_ids = inputs["token_type_ids"].numpy() - token_type_ids_example = None - - for index in range(batch_size): - # If sequences have already been processed, the token type IDs will be created according to the previous - # answer. - if prev_answers is not None: - prev_labels_example = token_type_ids_example[:, 3] # shape (seq_len,) - model_labels = np.zeros_like(prev_labels_example, dtype=np.int32) # shape (seq_len,) - - token_type_ids_example = token_type_ids[index] # shape (seq_len, 7) - for i in range(model_labels.shape[0]): - segment_id = token_type_ids_example[:, 0].tolist()[i] - col_id = token_type_ids_example[:, 1].tolist()[i] - 1 - row_id = token_type_ids_example[:, 2].tolist()[i] - 1 - - if row_id >= 0 and col_id >= 0 and segment_id == 1: - model_labels[i] = int(prev_answers[(col_id, row_id)]) - - token_type_ids_example[:, 3] = model_labels - - input_ids_example = input_ids[index] - attention_mask_example = attention_mask[index] # shape (seq_len,) - token_type_ids_example = token_type_ids[index] # shape (seq_len, 7) - outputs = self.model( - input_ids=np.expand_dims(input_ids_example, axis=0), - attention_mask=np.expand_dims(attention_mask_example, axis=0), - token_type_ids=np.expand_dims(token_type_ids_example, axis=0), - ) - logits = outputs.logits + input_ids_example = input_ids[index] + attention_mask_example = attention_mask[index] # shape (seq_len,) + token_type_ids_example = token_type_ids[index] # shape (seq_len, 7) + outputs = self.model( + input_ids=input_ids_example.unsqueeze(0), + attention_mask=attention_mask_example.unsqueeze(0), + token_type_ids=token_type_ids_example.unsqueeze(0), + ) + logits = outputs.logits - if self.aggregate: - all_aggregations.append(outputs.logits_aggregation) + if self.aggregate: + all_aggregations.append(outputs.logits_aggregation) - all_logits.append(logits) + all_logits.append(logits) - probabilities = tf.math.sigmoid(tf.cast(logits, tf.float32)) * tf.cast( - attention_mask_example, tf.float32 - ) + dist_per_token = torch.distributions.Bernoulli(logits=logits) + probabilities = dist_per_token.probs * attention_mask_example.type(torch.float32).to( + dist_per_token.probs.device + ) - coords_to_probs = collections.defaultdict(list) - for i, p in enumerate(tf.squeeze(probabilities).numpy().tolist()): - segment_id = token_type_ids_example[:, 0].tolist()[i] - col = token_type_ids_example[:, 1].tolist()[i] - 1 - row = token_type_ids_example[:, 2].tolist()[i] - 1 - if col >= 0 and row >= 0 and segment_id == 1: - coords_to_probs[(col, row)].append(p) + coords_to_probs = collections.defaultdict(list) + for i, p in enumerate(probabilities.squeeze().tolist()): + segment_id = token_type_ids_example[:, 0].tolist()[i] + col = token_type_ids_example[:, 1].tolist()[i] - 1 + row = token_type_ids_example[:, 2].tolist()[i] - 1 + if col >= 0 and row >= 0 and segment_id == 1: + coords_to_probs[(col, row)].append(p) - prev_answers = {key: np.array(coords_to_probs[key]).mean() > 0.5 for key in coords_to_probs} + prev_answers = {key: np.array(coords_to_probs[key]).mean() > 0.5 for key in coords_to_probs} - logits_batch = tf.concat(tuple(all_logits), 0) + logits_batch = torch.cat(tuple(all_logits), 0) - return (logits_batch,) if not self.aggregate else (logits_batch, tf.concat(tuple(all_aggregations), 0)) + return (logits_batch,) if not self.aggregate else (logits_batch, torch.cat(tuple(all_aggregations), 0)) def __call__(self, *args, **kwargs): r""" @@ -393,7 +318,7 @@ def preprocess(self, pipeline_input, sequential=None, padding=True, truncation=N raise ValueError("table is empty") if query is None or query == "": raise ValueError("query is empty") - inputs = self.tokenizer(table, query, return_tensors=self.framework, truncation=truncation, padding=padding) + inputs = self.tokenizer(table, query, return_tensors="pt", truncation=truncation, padding=padding) inputs["table"] = table return inputs diff --git a/src/transformers/pipelines/text2text_generation.py b/src/transformers/pipelines/text2text_generation.py index 8952b5820867..eb7e0bce8a34 100644 --- a/src/transformers/pipelines/text2text_generation.py +++ b/src/transformers/pipelines/text2text_generation.py @@ -4,15 +4,10 @@ from ..generation import GenerationConfig from ..tokenization_utils import TruncationStrategy -from ..utils import add_end_docstrings, is_tf_available, is_torch_available, logging +from ..utils import add_end_docstrings, is_torch_available, logging from .base import Pipeline, build_pipeline_init_args -if is_tf_available(): - import tensorflow as tf - - from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES - if is_torch_available(): from ..models.auto.modeling_auto import MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES @@ -84,11 +79,7 @@ class Text2TextGenerationPipeline(Pipeline): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.check_model_type( - TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES - if self.framework == "tf" - else MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES - ) + self.check_model_type(MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES) def _sanitize_parameters( self, @@ -153,7 +144,7 @@ def _parse_and_tokenize(self, *args, truncation): raise TypeError( f" `args[0]`: {args[0]} have the wrong format. The should be either of type `str` or type `list`" ) - inputs = self.tokenizer(*args, padding=padding, truncation=truncation, return_tensors=self.framework) + inputs = self.tokenizer(*args, padding=padding, truncation=truncation, return_tensors="pt") # This is produced by tokenizers but is an invalid generate kwargs if "token_type_ids" in inputs: del inputs["token_type_ids"] @@ -178,13 +169,13 @@ def __call__(self, *args: Union[str, list[str]], **kwargs: Any) -> list[dict[str max_length instead of throwing an error down the line. generate_kwargs: Additional keyword arguments to pass along to the generate method of the model (see the generate method - corresponding to your framework [here](./text_generation)). + [here](./text_generation)). Return: A list or a list of list of `dict`: Each result comes as a dictionary with the following keys: - **generated_text** (`str`, present when `return_text=True`) -- The generated text. - - **generated_token_ids** (`torch.Tensor` or `tf.Tensor`, present when `return_tensors=True`) -- The token + - **generated_token_ids** (`torch.Tensor`, present when `return_tensors=True`) -- The token ids of the generated text. """ @@ -202,10 +193,7 @@ def preprocess(self, inputs, truncation=TruncationStrategy.DO_NOT_TRUNCATE, **kw return inputs def _forward(self, model_inputs, **generate_kwargs): - if self.framework == "pt": - in_b, input_length = model_inputs["input_ids"].shape - elif self.framework == "tf": - in_b, input_length = tf.shape(model_inputs["input_ids"]).numpy() + in_b, input_length = model_inputs["input_ids"].shape self.check_inputs( input_length, @@ -219,10 +207,7 @@ def _forward(self, model_inputs, **generate_kwargs): output_ids = self.model.generate(**model_inputs, **generate_kwargs) out_b = output_ids.shape[0] - if self.framework == "pt": - output_ids = output_ids.reshape(in_b, out_b // in_b, *output_ids.shape[1:]) - elif self.framework == "tf": - output_ids = tf.reshape(output_ids, (in_b, out_b // in_b, *output_ids.shape[1:])) + output_ids = output_ids.reshape(in_b, out_b // in_b, *output_ids.shape[1:]) return {"output_ids": output_ids} def postprocess(self, model_outputs, return_type=ReturnType.TEXT, clean_up_tokenization_spaces=False): @@ -264,13 +249,10 @@ class SummarizationPipeline(Text2TextGenerationPipeline): Usage: ```python - # use bart in pytorch + # use bart summarizer = pipeline("summarization") summarizer("An apple a day, keeps the doctor away", min_length=5, max_length=20) - # use t5 in tf - summarizer = pipeline("summarization", model="google-t5/t5-base", tokenizer="google-t5/t5-base", framework="tf") - summarizer("An apple a day, keeps the doctor away", min_length=5, max_length=20) ```""" # Used in the return key of the pipeline. @@ -291,13 +273,13 @@ def __call__(self, *args, **kwargs): Whether or not to clean up the potential extra spaces in the text output. generate_kwargs: Additional keyword arguments to pass along to the generate method of the model (see the generate method - corresponding to your framework [here](./text_generation)). + [here](./text_generation)). Return: A list or a list of list of `dict`: Each result comes as a dictionary with the following keys: - **summary_text** (`str`, present when `return_text=True`) -- The summary of the corresponding input. - - **summary_token_ids** (`torch.Tensor` or `tf.Tensor`, present when `return_tensors=True`) -- The token + - **summary_token_ids** (`torch.Tensor`, present when `return_tensors=True`) -- The token ids of the summary. """ return super().__call__(*args, **kwargs) @@ -356,7 +338,7 @@ def check_inputs(self, input_length: int, min_length: int, max_length: int): def preprocess(self, *args, truncation=TruncationStrategy.DO_NOT_TRUNCATE, src_lang=None, tgt_lang=None): if getattr(self.tokenizer, "_build_translation_inputs", None): return self.tokenizer._build_translation_inputs( - *args, return_tensors=self.framework, truncation=truncation, src_lang=src_lang, tgt_lang=tgt_lang + *args, return_tensors="pt", truncation=truncation, src_lang=src_lang, tgt_lang=tgt_lang ) else: return super()._parse_and_tokenize(*args, truncation=truncation) @@ -398,13 +380,13 @@ def __call__(self, *args, **kwargs): for single pair translation models generate_kwargs: Additional keyword arguments to pass along to the generate method of the model (see the generate method - corresponding to your framework [here](./text_generation)). + [here](./text_generation)). Return: A list or a list of list of `dict`: Each result comes as a dictionary with the following keys: - **translation_text** (`str`, present when `return_text=True`) -- The translation. - - **translation_token_ids** (`torch.Tensor` or `tf.Tensor`, present when `return_tensors=True`) -- The + - **translation_token_ids** (`torch.Tensor`, present when `return_tensors=True`) -- The token ids of the translation. """ return super().__call__(*args, **kwargs) diff --git a/src/transformers/pipelines/text_classification.py b/src/transformers/pipelines/text_classification.py index 6f11f3bc9741..949f1ff498be 100644 --- a/src/transformers/pipelines/text_classification.py +++ b/src/transformers/pipelines/text_classification.py @@ -4,13 +4,10 @@ import numpy as np -from ..utils import ExplicitEnum, add_end_docstrings, is_tf_available, is_torch_available +from ..utils import ExplicitEnum, add_end_docstrings, is_torch_available from .base import GenericTensor, Pipeline, build_pipeline_init_args -if is_tf_available(): - from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES - if is_torch_available(): from ..models.auto.modeling_auto import MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES @@ -89,11 +86,7 @@ class TextClassificationPipeline(Pipeline): def __init__(self, **kwargs): super().__init__(**kwargs) - self.check_model_type( - TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES - if self.framework == "tf" - else MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES - ) + self.check_model_type(MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES) def _sanitize_parameters(self, return_all_scores=None, function_to_apply=None, top_k="", **tokenizer_kwargs): # Using "" as default argument because we're going to use `top_k=None` in user code to declare @@ -175,7 +168,7 @@ def __call__( return result def preprocess(self, inputs, **tokenizer_kwargs) -> dict[str, GenericTensor]: - return_tensors = self.framework + return_tensors = "pt" if isinstance(inputs, dict): return self.tokenizer(**inputs, return_tensors=return_tensors, **tokenizer_kwargs) elif isinstance(inputs, list) and len(inputs) == 1 and isinstance(inputs[0], list) and len(inputs[0]) == 2: @@ -193,7 +186,7 @@ def preprocess(self, inputs, **tokenizer_kwargs) -> dict[str, GenericTensor]: def _forward(self, model_inputs): # `XXXForSequenceClassification` models should not use `use_cache=True` even if it's supported - model_forward = self.model.forward if self.framework == "pt" else self.model.call + model_forward = self.model.forward if "use_cache" in inspect.signature(model_forward).parameters: model_inputs["use_cache"] = False return self.model(**model_inputs) @@ -217,11 +210,8 @@ def postprocess(self, model_outputs, function_to_apply=None, top_k=1, _legacy=Tr outputs = model_outputs["logits"][0] - if self.framework == "pt": - # To enable using fp16 and bf16 - outputs = outputs.float().numpy() - else: - outputs = outputs.numpy() + # To enable using fp16 and bf16 + outputs = outputs.float().numpy() if function_to_apply == ClassificationFunction.SIGMOID: scores = sigmoid(outputs) diff --git a/src/transformers/pipelines/text_generation.py b/src/transformers/pipelines/text_generation.py index 7d703ba50117..c77ca1d4bd37 100644 --- a/src/transformers/pipelines/text_generation.py +++ b/src/transformers/pipelines/text_generation.py @@ -4,7 +4,7 @@ from typing import Any, overload from ..generation import GenerationConfig -from ..utils import ModelOutput, add_end_docstrings, is_tf_available, is_torch_available +from ..utils import ModelOutput, add_end_docstrings, is_torch_available from .base import Pipeline, build_pipeline_init_args @@ -14,11 +14,6 @@ from ..models.auto.modeling_auto import MODEL_FOR_CAUSAL_LM_MAPPING_NAMES from .pt_utils import KeyDataset -if is_tf_available(): - import tensorflow as tf - - from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_CAUSAL_LM_MAPPING_NAMES - ChatType = list[dict[str, str]] @@ -119,9 +114,7 @@ class TextGenerationPipeline(Pipeline): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.check_model_type( - TF_MODEL_FOR_CAUSAL_LM_MAPPING_NAMES if self.framework == "tf" else MODEL_FOR_CAUSAL_LM_MAPPING_NAMES - ) + self.check_model_type(MODEL_FOR_CAUSAL_LM_MAPPING_NAMES) if "prefix" not in self._preprocess_params: # This is very specific. The logic is quite complex and needs to be done # as a "default". @@ -181,7 +174,7 @@ def _sanitize_parameters( preprocess_params["prefix"] = prefix if prefix: prefix_inputs = self.tokenizer( - prefix, padding=False, add_special_tokens=add_special_tokens, return_tensors=self.framework + prefix, padding=False, add_special_tokens=add_special_tokens, return_tensors="pt" ) generate_kwargs["prefix_length"] = prefix_inputs["input_ids"].shape[-1] @@ -298,14 +291,14 @@ def __call__(self, text_inputs, **kwargs): a chat, it is passed to `apply_chat_template`. Otherwise, it is passed to `__call__`. generate_kwargs (`dict`, *optional*): Additional keyword arguments to pass along to the generate method of the model (see the generate method - corresponding to your framework [here](./text_generation)). + [here](./text_generation)). Return: A list or a list of lists of `dict`: Returns one of the following dictionaries (cannot return a combination of both `generated_text` and `generated_token_ids`): - **generated_text** (`str`, present when `return_text=True`) -- The generated text. - - **generated_token_ids** (`torch.Tensor` or `tf.Tensor`, present when `return_tensors=True`) -- The token + - **generated_token_ids** (`torch.Tensor`, present when `return_tensors=True`) -- The token ids of the generated text. """ if isinstance( @@ -365,11 +358,11 @@ def preprocess( add_generation_prompt=not continue_final_message, continue_final_message=continue_final_message, return_dict=True, - return_tensors=self.framework, + return_tensors="pt", **tokenizer_kwargs, ) else: - inputs = self.tokenizer(prefix + prompt_text, return_tensors=self.framework, **tokenizer_kwargs) + inputs = self.tokenizer(prefix + prompt_text, return_tensors="pt", **tokenizer_kwargs) inputs["prompt_text"] = prompt_text @@ -436,29 +429,18 @@ def _forward(self, model_inputs, **generate_kwargs): other_outputs = {k: v for k, v in output.items() if k not in {"sequences", "past_key_values"}} out_b = generated_sequence.shape[0] - if self.framework == "pt": - for key, value in other_outputs.items(): - if isinstance(value, torch.Tensor) and value.shape[0] == out_b: - other_outputs[key] = value.reshape(in_b, out_b // in_b, *value.shape[1:]) - if isinstance(value, tuple) and len(value[0]) == out_b: - value = torch.stack(value).swapaxes(0, 1) - other_outputs[key] = value - elif self.framework == "tf": - for key, value in other_outputs.items(): - if isinstance(value, tf.Tensor) and value.shape[0] == out_b: - other_outputs[key] = tf.reshape(value, (in_b, out_b // in_b, *value.shape[1:])) - if isinstance(value, tuple) and len(value[0]) == out_b: - value = tf.stack(value).swapaxes(0, 1) - other_outputs[key] = value + for key, value in other_outputs.items(): + if isinstance(value, torch.Tensor) and value.shape[0] == out_b: + other_outputs[key] = value.reshape(in_b, out_b // in_b, *value.shape[1:]) + if isinstance(value, tuple) and len(value[0]) == out_b: + value = torch.stack(value).swapaxes(0, 1) + other_outputs[key] = value else: generated_sequence = output other_outputs = {} out_b = generated_sequence.shape[0] - if self.framework == "pt": - generated_sequence = generated_sequence.reshape(in_b, out_b // in_b, *generated_sequence.shape[1:]) - elif self.framework == "tf": - generated_sequence = tf.reshape(generated_sequence, (in_b, out_b // in_b, *generated_sequence.shape[1:])) + generated_sequence = generated_sequence.reshape(in_b, out_b // in_b, *generated_sequence.shape[1:]) model_outputs = { "generated_sequence": generated_sequence, @@ -485,14 +467,9 @@ def postprocess( other_outputs = model_outputs.get("additional_outputs", {}) split_keys = {} if other_outputs: - if self.framework == "pt": - for k, v in other_outputs.items(): - if isinstance(v, torch.Tensor) and v.shape[0] == len(generated_sequence): - split_keys[k] = v.numpy().tolist() - elif self.framework == "tf": - for k, v in other_outputs.items(): - if isinstance(v, tf.Tensor) and v.shape[0] == len(generated_sequence): - split_keys[k] = v.numpy().tolist() + for k, v in other_outputs.items(): + if isinstance(v, torch.Tensor) and v.shape[0] == len(generated_sequence): + split_keys[k] = v.numpy().tolist() skip_special_tokens = skip_special_tokens if skip_special_tokens is not None else True for idx, sequence in enumerate(generated_sequence): diff --git a/src/transformers/pipelines/text_to_audio.py b/src/transformers/pipelines/text_to_audio.py index 17eaba1466b3..d43695b37399 100644 --- a/src/transformers/pipelines/text_to_audio.py +++ b/src/transformers/pipelines/text_to_audio.py @@ -60,7 +60,7 @@ class TextToAudioPipeline(Pipeline): ```python >>> from transformers import pipeline - >>> music_generator = pipeline(task="text-to-audio", model="facebook/musicgen-small", framework="pt") + >>> music_generator = pipeline(task="text-to-audio", model="facebook/musicgen-small") >>> # diversify the music generation by adding randomness with a high temperature and set a maximum music length >>> generate_kwargs = { @@ -100,9 +100,6 @@ def __init__(self, *args, vocoder=None, sampling_rate=None, no_processor=True, * # Legacy behaviour just uses the tokenizer while new models use the processor as a whole at any given time self.no_processor = no_processor - if self.framework == "tf": - raise ValueError("The TextToAudioPipeline is only available in PyTorch.") - self.vocoder = None if self.model.__class__ in MODEL_FOR_TEXT_TO_SPECTROGRAM_MAPPING.values(): self.vocoder = ( diff --git a/src/transformers/pipelines/token_classification.py b/src/transformers/pipelines/token_classification.py index efa70ca1851f..0df615edcfd3 100644 --- a/src/transformers/pipelines/token_classification.py +++ b/src/transformers/pipelines/token_classification.py @@ -8,16 +8,11 @@ from ..utils import ( ExplicitEnum, add_end_docstrings, - is_tf_available, is_torch_available, ) from .base import ArgumentHandler, ChunkPipeline, Dataset, build_pipeline_init_args -if is_tf_available(): - import tensorflow as tf - - from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES if is_torch_available(): import torch @@ -144,11 +139,7 @@ class TokenClassificationPipeline(ChunkPipeline): def __init__(self, args_parser=TokenClassificationArgumentHandler(), *args, **kwargs): super().__init__(*args, **kwargs) - self.check_model_type( - TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES - if self.framework == "tf" - else MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES - ) + self.check_model_type(MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES) self._basic_tokenizer = BasicTokenizer(do_lower_case=False) self._args_parser = args_parser @@ -308,7 +299,7 @@ def preprocess(self, sentence, offset_mapping=None, **preprocess_params): inputs = self.tokenizer( text_to_tokenize, - return_tensors=self.framework, + return_tensors="pt", truncation=truncation, return_special_tokens_mask=True, return_offsets_mapping=self.tokenizer.is_fast, @@ -322,10 +313,7 @@ def preprocess(self, sentence, offset_mapping=None, **preprocess_params): num_chunks = len(inputs["input_ids"]) for i in range(num_chunks): - if self.framework == "tf": - model_inputs = {k: tf.expand_dims(v[i], 0) for k, v in inputs.items()} - else: - model_inputs = {k: v[i].unsqueeze(0) for k, v in inputs.items()} + model_inputs = {k: v[i].unsqueeze(0) for k, v in inputs.items()} if offset_mapping is not None: model_inputs["offset_mapping"] = offset_mapping @@ -346,11 +334,8 @@ def _forward(self, model_inputs): word_ids = model_inputs.pop("word_ids", None) word_to_chars_map = model_inputs.pop("word_to_chars_map", None) - if self.framework == "tf": - logits = self.model(**model_inputs)[0] - else: - output = self.model(**model_inputs) - logits = output["logits"] if isinstance(output, dict) else output[0] + output = self.model(**model_inputs) + logits = output["logits"] if isinstance(output, dict) else output[0] return { "logits": logits, @@ -372,7 +357,7 @@ def postprocess(self, all_outputs, aggregation_strategy=AggregationStrategy.NONE word_to_chars_map = all_outputs[0].get("word_to_chars_map") for model_outputs in all_outputs: - if self.framework == "pt" and model_outputs["logits"][0].dtype in (torch.bfloat16, torch.float16): + if model_outputs["logits"][0].dtype in (torch.bfloat16, torch.float16): logits = model_outputs["logits"][0].to(torch.float32).numpy() else: logits = model_outputs["logits"][0].numpy() @@ -389,10 +374,6 @@ def postprocess(self, all_outputs, aggregation_strategy=AggregationStrategy.NONE shifted_exp = np.exp(logits - maxes) scores = shifted_exp / shifted_exp.sum(axis=-1, keepdims=True) - if self.framework == "tf": - input_ids = input_ids.numpy() - offset_mapping = offset_mapping.numpy() if offset_mapping is not None else None - pre_entities = self.gather_pre_entities( sentence, input_ids, @@ -470,9 +451,8 @@ def gather_pre_entities( end_ind += start_char if not isinstance(start_ind, int): - if self.framework == "pt": - start_ind = start_ind.item() - end_ind = end_ind.item() + start_ind = start_ind.item() + end_ind = end_ind.item() word_ref = sentence[start_ind:end_ind] if getattr(self.tokenizer, "_tokenizer", None) and getattr( self.tokenizer._tokenizer.model, "continuing_subword_prefix", None diff --git a/src/transformers/pipelines/video_classification.py b/src/transformers/pipelines/video_classification.py index 1ee8dc86e161..ab57d46e7ccd 100644 --- a/src/transformers/pipelines/video_classification.py +++ b/src/transformers/pipelines/video_classification.py @@ -153,9 +153,8 @@ def preprocess(self, video, num_frames=None, frame_sampling_rate=1): video = read_video_pyav(container, indices) video = list(video) - model_inputs = self.image_processor(video, return_tensors=self.framework) - if self.framework == "pt": - model_inputs = model_inputs.to(self.dtype) + model_inputs = self.image_processor(video, return_tensors="pt") + model_inputs = model_inputs.to(self.dtype) return model_inputs def _forward(self, model_inputs): @@ -166,16 +165,13 @@ def postprocess(self, model_outputs, top_k=5, function_to_apply="softmax"): if top_k > self.model.config.num_labels: top_k = self.model.config.num_labels - if self.framework == "pt": - if function_to_apply == "softmax": - probs = model_outputs.logits[0].softmax(-1) - elif function_to_apply == "sigmoid": - probs = model_outputs.logits[0].sigmoid() - else: - probs = model_outputs.logits[0] - scores, ids = probs.topk(top_k) + if function_to_apply == "softmax": + probs = model_outputs.logits[0].softmax(-1) + elif function_to_apply == "sigmoid": + probs = model_outputs.logits[0].sigmoid() else: - raise ValueError(f"Unsupported framework: {self.framework}") + probs = model_outputs.logits[0] + scores, ids = probs.topk(top_k) scores = scores.tolist() ids = ids.tolist() diff --git a/src/transformers/pipelines/visual_question_answering.py b/src/transformers/pipelines/visual_question_answering.py index 609eaf2e9d55..c3f0514e1a8f 100644 --- a/src/transformers/pipelines/visual_question_answering.py +++ b/src/transformers/pipelines/visual_question_answering.py @@ -174,13 +174,12 @@ def preprocess(self, inputs, padding=False, truncation=False, timeout=None): image = load_image(inputs["image"], timeout=timeout) model_inputs = self.tokenizer( inputs["question"], - return_tensors=self.framework, + return_tensors="pt", padding=padding, truncation=truncation, ) - image_features = self.image_processor(images=image, return_tensors=self.framework) - if self.framework == "pt": - image_features = image_features.to(self.dtype) + image_features = self.image_processor(images=image, return_tensors="pt") + image_features = image_features.to(self.dtype) model_inputs.update(image_features) return model_inputs @@ -205,11 +204,8 @@ def postprocess(self, model_outputs, top_k=5): if top_k > self.model.config.num_labels: top_k = self.model.config.num_labels - if self.framework == "pt": - probs = model_outputs.logits.sigmoid()[0] - scores, ids = probs.topk(top_k) - else: - raise ValueError(f"Unsupported framework: {self.framework}") + probs = model_outputs.logits.sigmoid()[0] + scores, ids = probs.topk(top_k) scores = scores.tolist() ids = ids.tolist() diff --git a/src/transformers/pipelines/zero_shot_audio_classification.py b/src/transformers/pipelines/zero_shot_audio_classification.py index 9c21681a0d8e..fa9a2fe6ecfc 100644 --- a/src/transformers/pipelines/zero_shot_audio_classification.py +++ b/src/transformers/pipelines/zero_shot_audio_classification.py @@ -68,10 +68,6 @@ class ZeroShotAudioClassificationPipeline(Pipeline): def __init__(self, **kwargs): super().__init__(**kwargs) - if self.framework != "pt": - raise ValueError(f"The {self.__class__} is only available in PyTorch.") - # No specific FOR_XXX available yet - def __call__(self, audios: Union[np.ndarray, bytes, str, dict], **kwargs: Any) -> list[dict[str, Any]]: """ Assign labels to the audio(s) passed as inputs. @@ -127,11 +123,10 @@ def preprocess(self, audio, candidate_labels=None, hypothesis_template="This is inputs = self.feature_extractor( [audio], sampling_rate=self.feature_extractor.sampling_rate, return_tensors="pt" ) - if self.framework == "pt": - inputs = inputs.to(self.dtype) + inputs = inputs.to(self.dtype) inputs["candidate_labels"] = candidate_labels sequences = [hypothesis_template.format(x) for x in candidate_labels] - text_inputs = self.tokenizer(sequences, return_tensors=self.framework, padding=True) + text_inputs = self.tokenizer(sequences, return_tensors="pt", padding=True) inputs["text_inputs"] = [text_inputs] return inputs @@ -156,11 +151,8 @@ def postprocess(self, model_outputs): candidate_labels = model_outputs.pop("candidate_labels") logits = model_outputs["logits"][0] - if self.framework == "pt": - probs = logits.softmax(dim=0) - scores = probs.tolist() - else: - raise ValueError("`tf` framework not supported.") + probs = logits.softmax(dim=0) + scores = probs.tolist() result = [ {"score": score, "label": candidate_label} diff --git a/src/transformers/pipelines/zero_shot_classification.py b/src/transformers/pipelines/zero_shot_classification.py index 20675d4a2928..7d30d85b61cf 100644 --- a/src/transformers/pipelines/zero_shot_classification.py +++ b/src/transformers/pipelines/zero_shot_classification.py @@ -109,7 +109,7 @@ def _parse_and_tokenize( """ Parse arguments and tokenize only_first so that hypothesis (label) is not truncated """ - return_tensors = self.framework + return_tensors = "pt" if self.tokenizer.pad_token is None: # Override for tokenizers not supporting padding logger.error( @@ -226,7 +226,7 @@ def _forward(self, inputs): sequence = inputs["sequence"] model_inputs = {k: inputs[k] for k in self.tokenizer.model_input_names} # `XXXForSequenceClassification` models should not use `use_cache=True` even if it's supported - model_forward = self.model.forward if self.framework == "pt" else self.model.call + model_forward = self.model.forward if "use_cache" in inspect.signature(model_forward).parameters: model_inputs["use_cache"] = False outputs = self.model(**model_inputs) @@ -242,10 +242,7 @@ def _forward(self, inputs): def postprocess(self, model_outputs, multi_label=False): candidate_labels = [outputs["candidate_label"] for outputs in model_outputs] sequences = [outputs["sequence"] for outputs in model_outputs] - if self.framework == "pt": - logits = np.concatenate([output["logits"].float().numpy() for output in model_outputs]) - else: - logits = np.concatenate([output["logits"].numpy() for output in model_outputs]) + logits = np.concatenate([output["logits"].float().numpy() for output in model_outputs]) N = logits.shape[0] n = len(candidate_labels) num_sequences = N // n diff --git a/src/transformers/pipelines/zero_shot_image_classification.py b/src/transformers/pipelines/zero_shot_image_classification.py index 6aeb91620306..e43e85879f9d 100644 --- a/src/transformers/pipelines/zero_shot_image_classification.py +++ b/src/transformers/pipelines/zero_shot_image_classification.py @@ -4,7 +4,6 @@ from ..utils import ( add_end_docstrings, - is_tf_available, is_torch_available, is_vision_available, logging, @@ -23,9 +22,6 @@ from ..models.auto.modeling_auto import MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES -if is_tf_available(): - from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES - from ..tf_utils import stable_softmax logger = logging.get_logger(__name__) @@ -73,11 +69,7 @@ def __init__(self, **kwargs): super().__init__(**kwargs) requires_backends(self, "vision") - self.check_model_type( - TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES - if self.framework == "tf" - else MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES - ) + self.check_model_type(MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES) @overload def __call__( @@ -160,16 +152,15 @@ def preprocess( if tokenizer_kwargs is None: tokenizer_kwargs = {} image = load_image(image, timeout=timeout) - inputs = self.image_processor(images=[image], return_tensors=self.framework) - if self.framework == "pt": - inputs = inputs.to(self.dtype) + inputs = self.image_processor(images=[image], return_tensors="pt") + inputs = inputs.to(self.dtype) inputs["candidate_labels"] = candidate_labels sequences = [hypothesis_template.format(x) for x in candidate_labels] tokenizer_default_kwargs = {"padding": True} if "siglip" in self.model.config.model_type: tokenizer_default_kwargs.update(padding="max_length", max_length=64, truncation=True) tokenizer_default_kwargs.update(tokenizer_kwargs) - text_inputs = self.tokenizer(sequences, return_tensors=self.framework, **tokenizer_default_kwargs) + text_inputs = self.tokenizer(sequences, return_tensors="pt", **tokenizer_default_kwargs) inputs["text_inputs"] = [text_inputs] return inputs @@ -193,21 +184,16 @@ def _forward(self, model_inputs): def postprocess(self, model_outputs): candidate_labels = model_outputs.pop("candidate_labels") logits = model_outputs["logits"][0] - if self.framework == "pt" and "siglip" in self.model.config.model_type: + if "siglip" in self.model.config.model_type: probs = torch.sigmoid(logits).squeeze(-1) scores = probs.tolist() if not isinstance(scores, list): scores = [scores] - elif self.framework == "pt": + else: probs = logits.softmax(dim=-1).squeeze(-1) scores = probs.tolist() if not isinstance(scores, list): scores = [scores] - elif self.framework == "tf": - probs = stable_softmax(logits, axis=-1) - scores = probs.numpy().tolist() - else: - raise ValueError(f"Unsupported framework: {self.framework}") result = [ {"score": score, "label": candidate_label} diff --git a/src/transformers/pipelines/zero_shot_object_detection.py b/src/transformers/pipelines/zero_shot_object_detection.py index 55154af9ab3b..ef4563027c19 100644 --- a/src/transformers/pipelines/zero_shot_object_detection.py +++ b/src/transformers/pipelines/zero_shot_object_detection.py @@ -61,9 +61,6 @@ class ZeroShotObjectDetectionPipeline(ChunkPipeline): def __init__(self, **kwargs): super().__init__(**kwargs) - if self.framework == "tf": - raise ValueError(f"The {self.__class__} is only available in PyTorch.") - requires_backends(self, "vision") self.check_model_type(MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING_NAMES) @@ -182,10 +179,9 @@ def preprocess(self, inputs, timeout=None): target_size = torch.tensor([[image.height, image.width]], dtype=torch.int32) for i, candidate_label in enumerate(candidate_labels): - text_inputs = self.tokenizer(candidate_label, return_tensors=self.framework) - image_features = self.image_processor(image, return_tensors=self.framework) - if self.framework == "pt": - image_features = image_features.to(self.dtype) + text_inputs = self.tokenizer(candidate_label, return_tensors="pt") + image_features = self.image_processor(image, return_tensors="pt") + image_features = image_features.to(self.dtype) yield { "is_last": i == len(candidate_labels) - 1, "target_size": target_size, @@ -236,8 +232,6 @@ def _get_bounding_box(self, box: "torch.Tensor") -> dict[str, int]: Returns: bbox (`dict[str, int]`): Dict containing the coordinates in corners format. """ - if self.framework != "pt": - raise ValueError("The ZeroShotObjectDetectionPipeline is only available in PyTorch.") xmin, ymin, xmax, ymax = box.int().tolist() bbox = { "xmin": xmin, diff --git a/src/transformers/processing_utils.py b/src/transformers/processing_utils.py index b864d2971cae..faaae0c32157 100644 --- a/src/transformers/processing_utils.py +++ b/src/transformers/processing_utils.py @@ -563,10 +563,8 @@ def __call__( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. Returns: [`BatchFeature`]: A [`BatchFeature`] object with processed inputs in a dict format. diff --git a/src/transformers/quantizers/auto.py b/src/transformers/quantizers/auto.py index 42d8626ceaec..6b5bdd3e9c3c 100644 --- a/src/transformers/quantizers/auto.py +++ b/src/transformers/quantizers/auto.py @@ -295,7 +295,7 @@ def register_quantizer_fn(cls): return register_quantizer_fn -def get_hf_quantizer(config, quantization_config, dtype, from_tf, from_flax, device_map, weights_only, user_agent): +def get_hf_quantizer(config, quantization_config, dtype, device_map, weights_only, user_agent): pre_quantized = hasattr(config, "quantization_config") if pre_quantized and not AutoHfQuantizer.supports_quant_method(config.quantization_config): pre_quantized = False @@ -318,8 +318,6 @@ def get_hf_quantizer(config, quantization_config, dtype, from_tf, from_flax, dev if hf_quantizer is not None: hf_quantizer.validate_environment( dtype=dtype, - from_tf=from_tf, - from_flax=from_flax, device_map=device_map, weights_only=weights_only, ) diff --git a/src/transformers/quantizers/quantizer_bitnet.py b/src/transformers/quantizers/quantizer_bitnet.py index a57e732b9823..b8b7e1eb3bd0 100644 --- a/src/transformers/quantizers/quantizer_bitnet.py +++ b/src/transformers/quantizers/quantizer_bitnet.py @@ -50,12 +50,6 @@ def validate_environment(self, *args, **kwargs): if not is_accelerate_available(): raise ImportError("Loading a BitNet quantized model requires accelerate (`pip install accelerate`)") - if kwargs.get("from_tf", False) or kwargs.get("from_flax", False): - raise ValueError( - "Loading ternary weights from tf/flax is currently not supported, please make" - " sure the weights are in PyTorch format." - ) - if not torch.cuda.is_available(): logger.warning_once( "You don't have a GPU available to load the model, the inference will be slow because of weight unpacking" diff --git a/src/transformers/quantizers/quantizer_bnb_4bit.py b/src/transformers/quantizers/quantizer_bnb_4bit.py index 74879fa17ac4..b1fc580142eb 100644 --- a/src/transformers/quantizers/quantizer_bnb_4bit.py +++ b/src/transformers/quantizers/quantizer_bnb_4bit.py @@ -96,12 +96,6 @@ def validate_environment(self, *args, **kwargs): bnb_multibackend_is_enabled = is_bitsandbytes_multi_backend_available() validate_bnb_backend_availability(raise_exception=True) - if kwargs.get("from_tf", False) or kwargs.get("from_flax", False): - raise ValueError( - "Converting into 4-bit or 8-bit weights from tf/flax weights is currently not supported, please make" - " sure the weights are in PyTorch format." - ) - device_map = kwargs.get("device_map") if ( device_map is not None diff --git a/src/transformers/quantizers/quantizer_bnb_8bit.py b/src/transformers/quantizers/quantizer_bnb_8bit.py index 1d269765f57f..be044ac3b325 100644 --- a/src/transformers/quantizers/quantizer_bnb_8bit.py +++ b/src/transformers/quantizers/quantizer_bnb_8bit.py @@ -93,12 +93,6 @@ def validate_environment(self, *args, **kwargs): bnb_multibackend_is_enabled = is_bitsandbytes_multi_backend_available() validate_bnb_backend_availability(raise_exception=True) - if kwargs.get("from_tf", False) or kwargs.get("from_flax", False): - raise ValueError( - "Converting into 4-bit or 8-bit weights from tf/flax weights is currently not supported, please make" - " sure the weights are in PyTorch format." - ) - device_map = kwargs.get("device_map") if ( device_map is not None diff --git a/src/transformers/quantizers/quantizer_eetq.py b/src/transformers/quantizers/quantizer_eetq.py index 00a8117be9d2..8953f07ea859 100644 --- a/src/transformers/quantizers/quantizer_eetq.py +++ b/src/transformers/quantizers/quantizer_eetq.py @@ -70,12 +70,6 @@ def validate_environment(self, *args, **kwargs): if not is_accelerate_available(): raise ImportError("Loading an EETQ quantized model requires accelerate (`pip install accelerate`)") - if kwargs.get("from_tf", False) or kwargs.get("from_flax", False): - raise ValueError( - "Converting into 8-bit weights from tf/flax weights is currently not supported, please make" - " sure the weights are in PyTorch format." - ) - if not torch.cuda.is_available(): raise RuntimeError("No GPU found. A GPU is needed for quantization.") diff --git a/src/transformers/quantizers/quantizer_finegrained_fp8.py b/src/transformers/quantizers/quantizer_finegrained_fp8.py index dc30221b590e..c2f1414eced3 100644 --- a/src/transformers/quantizers/quantizer_finegrained_fp8.py +++ b/src/transformers/quantizers/quantizer_finegrained_fp8.py @@ -38,12 +38,6 @@ def validate_environment(self, *args, **kwargs): if not is_accelerate_available(): raise ImportError("Loading an FP8 quantized model requires accelerate (`pip install accelerate`)") - if kwargs.get("from_tf", False) or kwargs.get("from_flax", False): - raise ValueError( - "Converting into FP8 weights from tf/flax weights is currently not supported, " - "please make sure the weights are in PyTorch format." - ) - if not (torch.cuda.is_available() or is_torch_xpu_available()): raise RuntimeError("No GPU or XPU found. A GPU or XPU is needed for FP8 quantization.") diff --git a/src/transformers/quantizers/quantizer_hqq.py b/src/transformers/quantizers/quantizer_hqq.py index fa1d276c6a1a..f5f60a6d9e4b 100755 --- a/src/transformers/quantizers/quantizer_hqq.py +++ b/src/transformers/quantizers/quantizer_hqq.py @@ -65,12 +65,6 @@ def validate_environment(self, *args, **kwargs): "A valid HQQ version (>=0.2.1) is not available. Please follow the instructions to install it: `https://github.com/mobiusml/hqq/`." ) - if kwargs.get("from_tf", False) or kwargs.get("from_flax", False): - raise ValueError( - "Converting weights from tf/flax weights is currently not supported, please make" - " sure the weights are in PyTorch format." - ) - if self.dtype is None: if "dtype" in kwargs: self.dtype = kwargs["dtype"] diff --git a/src/transformers/testing_utils.py b/src/transformers/testing_utils.py index d8ec62124556..57b7b118f27a 100644 --- a/src/transformers/testing_utils.py +++ b/src/transformers/testing_utils.py @@ -91,7 +91,6 @@ is_fbgemm_gpu_available, is_flash_attn_2_available, is_flash_attn_3_available, - is_flax_available, is_flute_available, is_fp_quant_available, is_fsdp_available, @@ -107,7 +106,6 @@ is_ipex_available, is_jinja_available, is_jumanpp_available, - is_keras_nlp_available, is_kernels_available, is_levenshtein_available, is_librosa_available, @@ -143,7 +141,6 @@ is_spqr_available, is_sudachi_available, is_sudachi_projection_available, - is_tf_available, is_tiktoken_available, is_timm_available, is_tokenizers_available, @@ -680,18 +677,6 @@ def require_torchcodec(test_case): return unittest.skipUnless(is_torchcodec_available(), "test requires Torchcodec")(test_case) -def require_torch_or_tf(test_case): - """ - Decorator marking a test that requires PyTorch or TensorFlow. - - These tests are skipped when neither PyTorch not TensorFlow is installed. - - """ - return unittest.skipUnless(is_torch_available() or is_tf_available(), "test requires PyTorch or TensorFlow")( - test_case - ) - - def require_intel_extension_for_pytorch(test_case): """ Decorator marking a test that requires Intel Extension for PyTorch. @@ -749,13 +734,6 @@ def require_tokenizers(test_case): return unittest.skipUnless(is_tokenizers_available(), "test requires tokenizers")(test_case) -def require_keras_nlp(test_case): - """ - Decorator marking a test that requires keras_nlp. These tests are skipped when keras_nlp isn't installed. - """ - return unittest.skipUnless(is_keras_nlp_available(), "test requires keras_nlp")(test_case) - - def require_pandas(test_case): """ Decorator marking a test that requires pandas. These tests are skipped when pandas isn't installed. @@ -1023,16 +1001,6 @@ def require_torch_multi_hpu(test_case): else: torch_device = None -if is_tf_available(): - import tensorflow as tf - -if is_flax_available(): - import jax - - jax_device = jax.default_backend() -else: - jax_device = None - def require_torchdynamo(test_case): """Decorator marking a test that requires TorchDynamo""" @@ -1545,20 +1513,12 @@ def require_mistral_common(test_case): def get_gpu_count(): """ - Return the number of available gpus (regardless of whether torch, tf or jax is used) + Return the number of available gpus """ if is_torch_available(): import torch return torch.cuda.device_count() - elif is_tf_available(): - import tensorflow as tf - - return len(tf.config.list_physical_devices("GPU")) - elif is_flax_available(): - import jax - - return jax.device_count() else: return 0 @@ -2581,8 +2541,6 @@ def nested_simplify(obj, decimals=3): return obj elif is_torch_available() and isinstance(obj, torch.Tensor): return nested_simplify(obj.tolist(), decimals) - elif is_tf_available() and tf.is_tensor(obj): - return nested_simplify(obj.numpy().tolist()) elif isinstance(obj, float): return round(obj, decimals) elif isinstance(obj, (np.int32, np.float32, np.float16)): diff --git a/src/transformers/tf_utils.py b/src/transformers/tf_utils.py deleted file mode 100644 index 11d07f8d7eda..000000000000 --- a/src/transformers/tf_utils.py +++ /dev/null @@ -1,294 +0,0 @@ -# Copyright 2022 The HuggingFace Team. All rights reserved. -# -# 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. - -from typing import Optional, Union - -import numpy as np -import tensorflow as tf - -from .feature_extraction_utils import BatchFeature -from .tokenization_utils_base import BatchEncoding -from .utils import logging - - -logger = logging.get_logger(__name__) - - -def shape_list(tensor: Union[tf.Tensor, np.ndarray]) -> list[int]: - """ - Deal with dynamic shape in tensorflow cleanly. - - Args: - tensor (`tf.Tensor` or `np.ndarray`): The tensor we want the shape of. - - Returns: - `list[int]`: The shape of the tensor as a list. - """ - if isinstance(tensor, np.ndarray): - return list(tensor.shape) - - dynamic = tf.shape(tensor) - - if tensor.shape == tf.TensorShape(None): - return dynamic - - static = tensor.shape.as_list() - - return [dynamic[i] if s is None else s for i, s in enumerate(static)] - - -def stable_softmax(logits: tf.Tensor, axis: Optional[int] = None, name: Optional[str] = None) -> tf.Tensor: - """ - Stable wrapper that returns the same output as `tf.nn.softmax`, but that works reliably with XLA on CPU. It is - meant as a workaround for the [following issue](https://github.com/tensorflow/tensorflow/issues/55682), and will be - removed after it gets fixed. The arguments and outputs are the same as `tf.nn.softmax`, and relies on the fact that - `softmax(x) = softmax(x + c)` (see https://ogunlao.github.io/2020/04/26/you_dont_really_know_softmax.html). - - Args: - logits (`tf.Tensor`): - Must be one of the following types: half, float32, float64. - axis (`int`, *optional*): - The dimension softmax would be performed on. The default is -1 which indicates the last dimension. - name (`str`, *optional*): - A name for the operation. - - Returns: - `tf.Tensor`: - A Tensor. Has the same type and shape as logits. - """ - # TODO: When the issue linked above gets sorted, add a check on TF version here and use the original function if - # it has the fix. After we drop the support for unfixed versions, remove this function. - return tf.nn.softmax(logits=logits + 1e-9, axis=axis, name=name) - - -def functional_layernorm(inputs, weight, bias, epsilon=1e-5, axis=-1): - # This is a very simplified functional layernorm, designed to duplicate - # the functionality of PyTorch nn.functional.layer_norm when this is needed to port - # models in Transformers. - - if weight.shape.rank != 1 or bias.shape.rank != 1 or not isinstance(axis, int): - raise NotImplementedError("Only 1D weight and bias tensors are supported for now, with only a single axis.") - - # Get mean and variance on the axis to be normalized - mean, variance = tf.nn.moments(inputs, axes=[axis], keepdims=True) - - if axis != -1: - # Reshape scale and weight to have the same rank as inputs, but with 1 dimensions - # on every dimension except axis - shape = [1] * inputs.shape.rank - shape[axis] = shape_list(inputs)[axis] - weight = tf.reshape(weight, shape) - bias = tf.reshape(bias, shape) - - # Compute layer normalization using the batch_normalization - # function. - outputs = tf.nn.batch_normalization( - inputs, - mean, - variance, - offset=bias, - scale=weight, - variance_epsilon=epsilon, - ) - return outputs - - -def scaled_dot_product_attention( - query, key, value, attn_mask=None, dropout_p=0.0, is_causal=False, scale: Optional[float] = None -): - """TF equivalent for torch's nn.functional.scaled_dot_product_attention""" - if dropout_p != 0.0: - raise ValueError( - "Dropout is not supported in this implementation - file an issue " - "with Transformers and ping @Rocketknight1 if you need it for a port!" - ) - if is_causal and attn_mask is not None: - raise ValueError("You cannot specify an attn_mask and is_causal at the same time!") - if is_causal: - attn_mask = tf.ones((tf.shape(query)[-2], tf.shape(key)[-2]), dtype=tf.int32) - attn_mask = tf.experimental.numpy.tril(attn_mask, k=0) - if attn_mask is not None and (attn_mask.dtype.is_integer or attn_mask.dtype.is_bool): - # Convert boolean mask to a negative logit bias - attn_mask = tf.where(attn_mask > 0, tf.cast(0.0, query.dtype), tf.cast(-1000.0, query.dtype)) - logits = tf.einsum("...qd, ...kd -> ...qk", query, key) - if scale is None: - scale = tf.cast(tf.shape(key)[-1], logits.dtype) ** -0.5 - logits *= scale # scale by 1/sqrt(key_dim) - if attn_mask is not None: - logits += attn_mask - probs = tf.nn.softmax(logits) - return probs @ value - - -def flatten(input, start_dim=0, end_dim=-1): - # Replicates the behavior of torch.flatten in TF - - # If end_dim or start_dim is negative, count them from the end - if end_dim < 0: - end_dim += input.shape.rank - if start_dim < 0: - start_dim += input.shape.rank - - if start_dim == end_dim: - return input - - in_shape = tf.shape(input) - flattened_dim = tf.math.reduce_prod(in_shape[start_dim : end_dim + 1]) - out_shape = tf.concat([in_shape[:start_dim], [flattened_dim], in_shape[end_dim + 1 :]], axis=0) - return tf.reshape(input, out_shape) - - -def invert_attention_mask(encoder_attention_mask: tf.Tensor) -> tf.Tensor: - """ - Invert an attention mask (e.g., switches 0. and 1.). - - Args: - encoder_attention_mask (`torch.Tensor`): An attention mask. - - Returns: - `tf.Tensor`: The inverted attention mask. - """ - if not isinstance(encoder_attention_mask, tf.Tensor): - encoder_attention_mask = tf.convert_to_tensor(encoder_attention_mask) # Catches stray NumPy inputs - if encoder_attention_mask.shape.rank == 3: - encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] - if encoder_attention_mask.shape.rank == 2: - encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] - # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition - # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow - # /transformer/transformer_layers.py#L270 - # encoder_extended_attention_mask = (encoder_extended_attention_mask == - # encoder_extended_attention_mask.transpose(-1, -2)) - encoder_extended_attention_mask = ( - tf.cast(1, encoder_attention_mask.dtype) - encoder_extended_attention_mask - ) * encoder_extended_attention_mask.dtype.min - - return encoder_extended_attention_mask - - -def check_embeddings_within_bounds(tensor: tf.Tensor, embed_dim: int, tensor_name: str = "input_ids") -> None: - """ - `tf.gather`, on which TF embedding layers are based, won't check positive out of bound indices on GPU, returning - zeros instead. This function adds a check against that dangerous silent behavior. - - Args: - tensor (`tf.Tensor`): The tensor of indices to check. - embed_dim (`int`): The embedding dimension. - tensor_name (`str`, *optional*): The name of the tensor to use in the error message. - """ - tf.debugging.assert_less( - tensor, - tf.cast(embed_dim, dtype=tensor.dtype), - message=( - f"The maximum value of {tensor_name} ({tf.math.reduce_max(tensor)}) must be smaller than the embedding " - f"layer's input dimension ({embed_dim}). The likely cause is some problem at tokenization time." - ), - ) - - -def save_attributes_to_hdf5_group(group, name, data): - """Saves attributes (data) of the specified name into the HDF5 group. - - This method deals with an inherent problem of HDF5 file which is not able to store data larger than - HDF5_OBJECT_HEADER_LIMIT bytes. - - Args: - group: A pointer to a HDF5 group. - name: A name of the attributes to save. - data: Attributes data to store. - - Raises: - RuntimeError: If any single attribute is too large to be saved. - - Copied from Keras to Transformers to avoid versioning issues. - """ - HDF5_OBJECT_HEADER_LIMIT = 64512 - # Check that no item in `data` is larger than `HDF5_OBJECT_HEADER_LIMIT` - # because in that case even chunking the array would not make the saving - # possible. - bad_attributes = [x for x in data if len(x) > HDF5_OBJECT_HEADER_LIMIT] - - # Expecting this to never be true. - if bad_attributes: - raise RuntimeError( - "The following attributes cannot be saved to HDF5 file because " - f"they are larger than {HDF5_OBJECT_HEADER_LIMIT} " - f"bytes: {bad_attributes}" - ) - - data_npy = np.asarray(data) - - num_chunks = 1 - chunked_data = np.array_split(data_npy, num_chunks) - - # This will never loop forever thanks to the test above. - while any(x.nbytes > HDF5_OBJECT_HEADER_LIMIT for x in chunked_data): - num_chunks += 1 - chunked_data = np.array_split(data_npy, num_chunks) - - if num_chunks > 1: - for chunk_id, chunk_data in enumerate(chunked_data): - group.attrs["%s%d" % (name, chunk_id)] = chunk_data - else: - group.attrs[name] = data - - -def load_attributes_from_hdf5_group(group, name): - """Loads attributes of the specified name from the HDF5 group. - - This method deals with an inherent problem of HDF5 file which is not able to store data larger than - HDF5_OBJECT_HEADER_LIMIT bytes. - - Args: - group: A pointer to a HDF5 group. - name: A name of the attributes to load. - - Returns: - data: Attributes data. - - Copied from Keras to Transformers to avoid versioning issues. - """ - if name in group.attrs: - data = [n.decode("utf8") if hasattr(n, "decode") else n for n in group.attrs[name]] - else: - data = [] - chunk_id = 0 - while "%s%d" % (name, chunk_id) in group.attrs: - data.extend( - [n.decode("utf8") if hasattr(n, "decode") else n for n in group.attrs["%s%d" % (name, chunk_id)]] - ) - chunk_id += 1 - return data - - -def expand_1d(data): - """Expands 1-dimensional `Tensor`s into 2-dimensional `Tensor`s. - Copied from Keras to here to avoid versioning issues.""" - - def _expand_single_1d_tensor(t): - if isinstance(t, tf.Tensor) and t.shape.rank == 1: - return tf.expand_dims(t, axis=-1) - return t - - return tf.nest.map_structure(_expand_single_1d_tensor, data) - - -def convert_batch_encoding(*args, **kwargs): - # Convert HF BatchEncoding/BatchFeature objects in the inputs to dicts that Keras understands - if args and isinstance(args[0], (BatchEncoding, BatchFeature)): - args = list(args) - args[0] = dict(args[0]) - elif "x" in kwargs and isinstance(kwargs["x"], (BatchEncoding, BatchFeature)): - kwargs["x"] = dict(kwargs["x"]) - return args, kwargs diff --git a/src/transformers/tokenization_mistral_common.py b/src/transformers/tokenization_mistral_common.py index a362a7c8b066..90d3b673e20e 100644 --- a/src/transformers/tokenization_mistral_common.py +++ b/src/transformers/tokenization_mistral_common.py @@ -1219,7 +1219,7 @@ def pad( encoded_inputs["attention_mask"] = [] return encoded_inputs - # If we have PyTorch/TF/NumPy tensors/arrays as inputs, we cast them as python objects + # If we have PyTorch/NumPy tensors/arrays as inputs, we cast them as python objects # and rebuild them afterwards if no return_tensors is specified # Note that we lose the specific device the tensor may be on for PyTorch @@ -1239,7 +1239,7 @@ def pad( else: raise ValueError( f"type of {first_element} unknown: {type(first_element)}. " - "Should be one of a python, numpy, pytorch or tensorflow object." + "Should be one of a python, numpy, or pytorch object." ) for key, value in encoded_inputs.items(): @@ -1607,11 +1607,6 @@ def __call__( "`text_pair`, `text_target` and `text_pair_target` are not supported by `MistralCommonTokenizer`." ) - if return_tensors in ("tf", "jax"): - raise ValueError( - "`MistralCommonTokenizer` does not support `return_tensors='tf'` or `return_tensors='jax'`." - ) - def _is_valid_text_input(t): if isinstance(t, str): # Strings are fine diff --git a/src/transformers/tokenization_utils_base.py b/src/transformers/tokenization_utils_base.py index f88711fdb655..36a99d66e23d 100644 --- a/src/transformers/tokenization_utils_base.py +++ b/src/transformers/tokenization_utils_base.py @@ -47,15 +47,11 @@ copy_func, download_url, extract_commit_hash, - is_flax_available, - is_jax_tensor, is_mlx_available, is_numpy_array, is_offline_mode, is_protobuf_available, is_remote_url, - is_tf_available, - is_tf_tensor, is_tokenizers_available, is_torch_available, is_torch_device, @@ -72,10 +68,6 @@ if TYPE_CHECKING: if is_torch_available(): import torch - if is_tf_available(): - import tensorflow as tf - if is_flax_available(): - import jax.numpy as jnp # noqa: F401 def import_protobuf_decode_error(error_message=""): @@ -214,13 +206,13 @@ class BatchEncoding(UserDict): space to token space the `tokenizers.Encoding` instance or list of instance (for batches) hold this information. tensor_type (`Union[None, str, TensorType]`, *optional*): - You can give a tensor_type here to convert the lists of integers in PyTorch/TensorFlow/Numpy Tensors at + You can give a tensor_type here to convert the lists of integers in PyTorch/Numpy Tensors at initialization. prepend_batch_axis (`bool`, *optional*, defaults to `False`): Whether or not to add a batch axis when converting to tensors (see `tensor_type` above). Note that this parameter has an effect if the parameter `tensor_type` is set, *otherwise has no effect*. n_sequences (`Optional[int]`, *optional*): - You can give a tensor_type here to convert the lists of integers in PyTorch/TensorFlow/Numpy Tensors at + You can give a tensor_type here to convert the lists of integers in PyTorch/Numpy Tensors at initialization. """ @@ -714,22 +706,7 @@ def convert_to_tensors( if not isinstance(tensor_type, TensorType): tensor_type = TensorType(tensor_type) - # Get a function reference for the correct framework - if tensor_type == TensorType.TENSORFLOW: - if not is_tf_available(): - raise ImportError( - "Unable to convert output to TensorFlow tensors format, TensorFlow is not installed." - ) - import tensorflow as tf - - def as_tensor(value, dtype=None): - if len(flatten(value)) == 0 and dtype is None: - dtype = tf.int32 - return tf.constant(value, dtype=dtype) - - is_tensor = tf.is_tensor - - elif tensor_type == TensorType.PYTORCH: + if tensor_type == TensorType.PYTORCH: if not is_torch_available(): raise ImportError("Unable to convert output to PyTorch tensors format, PyTorch is not installed.") import torch @@ -743,18 +720,6 @@ def as_tensor(value, dtype=None): is_tensor = torch.is_tensor - elif tensor_type == TensorType.JAX: - if not is_flax_available(): - raise ImportError("Unable to convert output to JAX tensors format, JAX is not installed.") - import jax.numpy as jnp # noqa: F811 - - def as_tensor(value, dtype=None): - if len(flatten(value)) == 0 and dtype is None: - dtype = jnp.int32 - return jnp.array(value, dtype=dtype) - - is_tensor = is_jax_tensor - elif tensor_type == TensorType.MLX: if not is_mlx_available(): raise ImportError("Unable to convert output to MLX tensors format, MLX is not installed.") @@ -1269,7 +1234,6 @@ def _set_model_specific_special_tokens(self, special_tokens: list[str]): return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. """ @@ -1614,10 +1578,8 @@ def apply_chat_template( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors of a particular framework. Has no effect if tokenize is `False`. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.Tensor` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return NumPy `np.ndarray` objects. - - `'jax'`: Return JAX `jnp.ndarray` objects. return_dict (`bool`, defaults to `False`): Whether to return a dictionary with named outputs. Has no effect if tokenize is `False`. tokenizer_kwargs (`dict[str: Any]`, *optional*): Additional kwargs to pass to the tokenizer. @@ -2700,7 +2662,7 @@ def tokenize(self, text: str, pair: Optional[str] = None, add_special_tokens: bo """, """ Returns: - `list[int]`, `torch.Tensor`, `tf.Tensor` or `np.ndarray`: The tokenized ids of the text. + `list[int]`, `torch.Tensor`, or `np.ndarray`: The tokenized ids of the text. """, ) def encode( @@ -2924,11 +2886,6 @@ def __call__( "verbose": verbose, } - if return_tensors in ("tf", "jax"): - logger.warning_once( - "TensorFlow and JAX classes are deprecated and will be removed in Transformers v5. We " - "recommend migrating to PyTorch classes or pinning your version of Transformers." - ) all_kwargs.update(kwargs) if text is None and text_target is None: raise ValueError("You need to specify either `text` or `text_target`.") @@ -3308,7 +3265,7 @@ def pad( - If the `encoded_inputs` passed are dictionary of numpy arrays, PyTorch tensors or TensorFlow tensors, the + If the `encoded_inputs` passed are dictionary of numpy arrays, or PyTorch tensors, the result will use the same type unless you provide a different tensor type with `return_tensors`. In the case of PyTorch tensors, you will lose the specific device of your tensors however. @@ -3321,7 +3278,7 @@ def pad( list[int]]]*) so you can use this method during preprocessing as well as in a PyTorch Dataloader collate function. - Instead of `list[int]` you can have tensors (numpy arrays, PyTorch tensors or TensorFlow tensors), see + Instead of `list[int]` you can have tensors (numpy arrays, or PyTorch tensors), see the note above for the return type. padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `True`): Select a strategy to pad the returned sequences (according to the model's padding side and padding @@ -3351,7 +3308,6 @@ def pad( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. verbose (`bool`, *optional*, defaults to `True`): @@ -3385,7 +3341,7 @@ def pad( encoded_inputs["attention_mask"] = [] return encoded_inputs - # If we have PyTorch/TF/NumPy tensors/arrays as inputs, we cast them as python objects + # If we have PyTorch/NumPy tensors/arrays as inputs, we cast them as python objects # and rebuild them afterwards if no return_tensors is specified # Note that we lose the specific device the tensor may be on for PyTorch @@ -3398,16 +3354,14 @@ def pad( break # At this state, if `first_element` is still a list/tuple, it's an empty one so there is nothing to do. if not isinstance(first_element, (int, list, tuple)): - if is_tf_tensor(first_element): - return_tensors = "tf" if return_tensors is None else return_tensors - elif is_torch_tensor(first_element): + if is_torch_tensor(first_element): return_tensors = "pt" if return_tensors is None else return_tensors elif isinstance(first_element, np.ndarray): return_tensors = "np" if return_tensors is None else return_tensors else: raise ValueError( f"type of {first_element} unknown: {type(first_element)}. " - "Should be one of a python, numpy, pytorch or tensorflow object." + "Should be one of a python, numpy, or pytorch object." ) for key, value in encoded_inputs.items(): @@ -3861,7 +3815,7 @@ def convert_tokens_to_string(self, tokens: list[str]) -> str: def batch_decode( self, - sequences: Union[list[int], list[list[int]], "np.ndarray", "torch.Tensor", "tf.Tensor"], + sequences: Union[list[int], list[list[int]], "np.ndarray", "torch.Tensor"], skip_special_tokens: bool = False, clean_up_tokenization_spaces: Optional[bool] = None, **kwargs, @@ -3870,7 +3824,7 @@ def batch_decode( Convert a list of lists of token ids into a list of strings by calling decode. Args: - sequences (`Union[list[int], list[list[int]], np.ndarray, torch.Tensor, tf.Tensor]`): + sequences (`Union[list[int], list[list[int]], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. @@ -3895,7 +3849,7 @@ def batch_decode( def decode( self, - token_ids: Union[int, list[int], "np.ndarray", "torch.Tensor", "tf.Tensor"], + token_ids: Union[int, list[int], "np.ndarray", "torch.Tensor"], skip_special_tokens: bool = False, clean_up_tokenization_spaces: Optional[bool] = None, **kwargs, @@ -3907,7 +3861,7 @@ def decode( Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. Args: - token_ids (`Union[int, list[int], np.ndarray, torch.Tensor, tf.Tensor]`): + token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`): List of tokenized input ids. Can be obtained using the `__call__` method. skip_special_tokens (`bool`, *optional*, defaults to `False`): Whether or not to remove special tokens in the decoding. @@ -4105,7 +4059,6 @@ def prepare_seq2seq_batch( return_tensors (`str` or [`~utils.TensorType`], *optional*): If set, will return tensors instead of list of python integers. Acceptable values are: - - `'tf'`: Return TensorFlow `tf.constant` objects. - `'pt'`: Return PyTorch `torch.Tensor` objects. - `'np'`: Return Numpy `np.ndarray` objects. truncation (`bool`, `str` or [`~tokenization_utils_base.TruncationStrategy`], *optional*, defaults to `True`): diff --git a/src/transformers/trainer_utils.py b/src/transformers/trainer_utils.py index e2a382db6c91..055580c96177 100644 --- a/src/transformers/trainer_utils.py +++ b/src/transformers/trainer_utils.py @@ -31,7 +31,6 @@ from .utils import ( ExplicitEnum, is_psutil_available, - is_tf_available, is_torch_available, is_torch_cuda_available, is_torch_hpu_available, @@ -61,8 +60,7 @@ def seed_worker(worker_id: int, num_workers: int, rank: int): def enable_full_determinism(seed: int, warn_only: bool = False): """ Helper function for reproducible behavior during distributed training. See - - https://pytorch.org/docs/stable/notes/randomness.html for pytorch - - https://www.tensorflow.org/api_docs/python/tf/config/experimental/enable_op_determinism for tensorflow + https://pytorch.org/docs/stable/notes/randomness.html for pytorch """ # set seed first set_seed(seed) @@ -84,15 +82,10 @@ def enable_full_determinism(seed: int, warn_only: bool = False): torch.backends.cudnn.deterministic = True torch.backends.cudnn.benchmark = False - if is_tf_available(): - import tensorflow as tf - - tf.config.experimental.enable_op_determinism() - def set_seed(seed: int, deterministic: bool = False): """ - Helper function for reproducible behavior to set the seed in `random`, `numpy`, `torch` and/or `tf` (if installed). + Helper function for reproducible behavior to set the seed in `random`, `numpy`, `torch` (if installed). Args: seed (`int`): @@ -118,12 +111,6 @@ def set_seed(seed: int, deterministic: bool = False): torch.hpu.manual_seed_all(seed) if is_torch_xpu_available(): torch.xpu.manual_seed_all(seed) - if is_tf_available(): - import tensorflow as tf - - tf.random.set_seed(seed) - if deterministic: - tf.config.experimental.enable_op_determinism() def neftune_post_forward_hook(module, input, output): @@ -465,8 +452,6 @@ class TrainerMemoryTracker: self._memory_tracker.stop_and_update_metrics(metrics) ``` - At the moment GPU tracking is only for `pytorch`, but can be extended to support `tensorflow`. - To understand this class' intricacies please read the documentation of [`~Trainer.log_metrics`]. """ diff --git a/src/transformers/training_args.py b/src/transformers/training_args.py index b232dcb76454..be77f1876f3c 100644 --- a/src/transformers/training_args.py +++ b/src/transformers/training_args.py @@ -822,7 +822,6 @@ class TrainingArguments: "gradient_checkpointing_kwargs", "lr_scheduler_kwargs", ] - framework = "pt" output_dir: Optional[str] = field( default=None, @@ -1705,7 +1704,7 @@ def __post_init__(self): self.metric_for_best_model = "loss" if self.greater_is_better is None and self.metric_for_best_model is not None: self.greater_is_better = not self.metric_for_best_model.endswith("loss") - if self.framework == "pt" and is_torch_available(): + if is_torch_available(): if self.fp16_backend and self.fp16_backend != "auto": warnings.warn( "`fp16_backend` is deprecated and will be removed in version 5 of 🤗 Transformers. Use" @@ -1787,7 +1786,7 @@ def __post_init__(self): ) # Initialize device before we proceed - if self.framework == "pt" and is_torch_available(): + if is_torch_available(): self.device if self.torchdynamo is not None: @@ -1813,7 +1812,7 @@ def __post_init__(self): if self.torch_compile_mode is not None: os.environ[prefix + "MODE"] = self.torch_compile_mode - if self.framework == "pt" and is_torch_available() and self.torch_compile: + if is_torch_available() and self.torch_compile: if is_torch_tf32_available(): if self.tf32 is None and not self.fp16 or self.bf16: device_str = "MUSA" if is_torch_musa_available() else "CUDA" @@ -1830,7 +1829,7 @@ def __post_init__(self): logger.warning( "The speedups for torchdynamo mostly come with GPU Ampere or higher and which is not detected here." ) - if self.framework == "pt" and is_torch_available() and self.tf32 is not None: + if is_torch_available() and self.tf32 is not None: if self.tf32: if is_torch_tf32_available(): if is_torch_musa_available(): diff --git a/src/transformers/training_args_tf.py b/src/transformers/training_args_tf.py deleted file mode 100644 index 24763dabf916..000000000000 --- a/src/transformers/training_args_tf.py +++ /dev/null @@ -1,300 +0,0 @@ -# Copyright 2020 The HuggingFace Team. All rights reserved. -# -# 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. - -import warnings -from dataclasses import dataclass, field -from functools import cached_property -from typing import Optional - -from .training_args import TrainingArguments -from .utils import is_tf_available, logging, requires_backends - - -logger = logging.get_logger(__name__) - -if is_tf_available(): - import tensorflow as tf - - from .modeling_tf_utils import keras - - -@dataclass -class TFTrainingArguments(TrainingArguments): - """ - TrainingArguments is the subset of the arguments we use in our example scripts **which relate to the training loop - itself**. - - Using [`HfArgumentParser`] we can turn this class into - [argparse](https://docs.python.org/3/library/argparse#module-argparse) arguments that can be specified on the - command line. - - Parameters: - output_dir (`str`): - The output directory where the model predictions and checkpoints will be written. - overwrite_output_dir (`bool`, *optional*, defaults to `False`): - If `True`, overwrite the content of the output directory. Use this to continue training if `output_dir` - points to a checkpoint directory. - do_train (`bool`, *optional*, defaults to `False`): - Whether to run training or not. This argument is not directly used by [`Trainer`], it's intended to be used - by your training/evaluation scripts instead. See the [example - scripts](https://github.com/huggingface/transformers/tree/main/examples) for more details. - do_eval (`bool`, *optional*): - Whether to run evaluation on the validation set or not. Will be set to `True` if `eval_strategy` is - different from `"no"`. This argument is not directly used by [`Trainer`], it's intended to be used by your - training/evaluation scripts instead. See the [example - scripts](https://github.com/huggingface/transformers/tree/main/examples) for more details. - do_predict (`bool`, *optional*, defaults to `False`): - Whether to run predictions on the test set or not. This argument is not directly used by [`Trainer`], it's - intended to be used by your training/evaluation scripts instead. See the [example - scripts](https://github.com/huggingface/transformers/tree/main/examples) for more details. - eval_strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"no"`): - The evaluation strategy to adopt during training. Possible values are: - - - `"no"`: No evaluation is done during training. - - `"steps"`: Evaluation is done (and logged) every `eval_steps`. - - `"epoch"`: Evaluation is done at the end of each epoch. - - per_device_train_batch_size (`int`, *optional*, defaults to 8): - The batch size per GPU/TPU core/CPU for training. - per_device_eval_batch_size (`int`, *optional*, defaults to 8): - The batch size per GPU/TPU core/CPU for evaluation. - gradient_accumulation_steps (`int`, *optional*, defaults to 1): - Number of updates steps to accumulate the gradients for, before performing a backward/update pass. - - - - When using gradient accumulation, one step is counted as one step with backward pass. Therefore, logging, - evaluation, save will be conducted every `gradient_accumulation_steps * xxx_step` training examples. - - - - learning_rate (`float`, *optional*, defaults to 5e-5): - The initial learning rate for Adam. - weight_decay (`float`, *optional*, defaults to 0): - The weight decay to apply (if not zero). - adam_beta1 (`float`, *optional*, defaults to 0.9): - The beta1 hyperparameter for the Adam optimizer. - adam_beta2 (`float`, *optional*, defaults to 0.999): - The beta2 hyperparameter for the Adam optimizer. - adam_epsilon (`float`, *optional*, defaults to 1e-8): - The epsilon hyperparameter for the Adam optimizer. - max_grad_norm (`float`, *optional*, defaults to 1.0): - Maximum gradient norm (for gradient clipping). - num_train_epochs(`float`, *optional*, defaults to 3.0): - Total number of training epochs to perform. - max_steps (`int`, *optional*, defaults to -1): - If set to a positive number, the total number of training steps to perform. Overrides `num_train_epochs`. - For a finite dataset, training is reiterated through the dataset (if all data is exhausted) until - `max_steps` is reached. - warmup_ratio (`float`, *optional*, defaults to 0.0): - Ratio of total training steps used for a linear warmup from 0 to `learning_rate`. - warmup_steps (`int`, *optional*, defaults to 0): - Number of steps used for a linear warmup from 0 to `learning_rate`. Overrides any effect of `warmup_ratio`. - logging_dir (`str`, *optional*): - [TensorBoard](https://www.tensorflow.org/tensorboard) log directory. Will default to - *runs/**CURRENT_DATETIME_HOSTNAME***. - logging_strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"steps"`): - The logging strategy to adopt during training. Possible values are: - - - `"no"`: No logging is done during training. - - `"epoch"`: Logging is done at the end of each epoch. - - `"steps"`: Logging is done every `logging_steps`. - - logging_first_step (`bool`, *optional*, defaults to `False`): - Whether to log and evaluate the first `global_step` or not. - logging_steps (`int`, *optional*, defaults to 500): - Number of update steps between two logs if `logging_strategy="steps"`. - save_strategy (`str` or [`~trainer_utils.SaveStrategy`], *optional*, defaults to `"steps"`): - The checkpoint save strategy to adopt during training. Possible values are: - - - `"no"`: No save is done during training. - - `"epoch"`: Save is done at the end of each epoch. - - `"steps"`: Save is done every `save_steps`. - - save_steps (`int`, *optional*, defaults to 500): - Number of updates steps before two checkpoint saves if `save_strategy="steps"`. - save_total_limit (`int`, *optional*): - If a value is passed, will limit the total amount of checkpoints. Deletes the older checkpoints in - `output_dir`. - no_cuda (`bool`, *optional*, defaults to `False`): - Whether to not use CUDA even when it is available or not. - seed (`int`, *optional*, defaults to 42): - Random seed that will be set at the beginning of training. - fp16 (`bool`, *optional*, defaults to `False`): - Whether to use 16-bit (mixed) precision training (through NVIDIA Apex) instead of 32-bit training. - fp16_opt_level (`str`, *optional*, defaults to 'O1'): - For `fp16` training, Apex AMP optimization level selected in ['O0', 'O1', 'O2', and 'O3']. See details on - the [Apex documentation](https://nvidia.github.io/apex/amp). - local_rank (`int`, *optional*, defaults to -1): - During distributed training, the rank of the process. - tpu_num_cores (`int`, *optional*): - When training on TPU, the number of TPU cores (automatically passed by launcher script). - debug (`bool`, *optional*, defaults to `False`): - Whether to activate the trace to record computation graphs and profiling information or not. - dataloader_drop_last (`bool`, *optional*, defaults to `False`): - Whether to drop the last incomplete batch (if the length of the dataset is not divisible by the batch size) - or not. - eval_steps (`int`, *optional*, defaults to 1000): - Number of update steps before two evaluations. - past_index (`int`, *optional*, defaults to -1): - Some models like [TransformerXL](../model_doc/transformerxl) or :doc*XLNet <../model_doc/xlnet>* can make - use of the past hidden states for their predictions. If this argument is set to a positive int, the - `Trainer` will use the corresponding output (usually index 2) as the past state and feed it to the model at - the next training step under the keyword argument `mems`. - tpu_name (`str`, *optional*): - The name of the TPU the process is running on. - tpu_zone (`str`, *optional*): - The zone of the TPU the process is running on. If not specified, we will attempt to automatically detect - from metadata. - gcp_project (`str`, *optional*): - Google Cloud Project name for the Cloud TPU-enabled project. If not specified, we will attempt to - automatically detect from metadata. - run_name (`str`, *optional*): - A descriptor for the run. Notably used for trackio, wandb, mlflow, comet and swanlab logging. - xla (`bool`, *optional*): - Whether to activate the XLA compilation or not. - """ - - framework = "tf" - tpu_name: Optional[str] = field( - default=None, - metadata={"help": "Name of TPU"}, - ) - - tpu_zone: Optional[str] = field( - default=None, - metadata={"help": "Zone of TPU"}, - ) - - gcp_project: Optional[str] = field( - default=None, - metadata={"help": "Name of Cloud TPU-enabled project"}, - ) - - poly_power: float = field( - default=1.0, - metadata={"help": "Power for the Polynomial decay LR scheduler."}, - ) - - xla: bool = field(default=False, metadata={"help": "Whether to activate the XLA compilation or not"}) - - @cached_property - def _setup_strategy(self) -> tuple["tf.distribute.Strategy", int]: - requires_backends(self, ["tf"]) - logger.info("Tensorflow: setting up strategy") - - gpus = tf.config.list_physical_devices("GPU") - - # Set to float16 at first - if self.fp16: - keras.mixed_precision.set_global_policy("mixed_float16") - - if self.no_cuda: - strategy = tf.distribute.OneDeviceStrategy(device="/cpu:0") - else: - try: - if self.tpu_name: - tpu = tf.distribute.cluster_resolver.TPUClusterResolver( - self.tpu_name, zone=self.tpu_zone, project=self.gcp_project - ) - else: - tpu = tf.distribute.cluster_resolver.TPUClusterResolver() - except ValueError: - if self.tpu_name: - raise RuntimeError(f"Couldn't connect to TPU {self.tpu_name}!") - else: - tpu = None - - if tpu: - # Set to bfloat16 in case of TPU - if self.fp16: - keras.mixed_precision.set_global_policy("mixed_bfloat16") - - tf.config.experimental_connect_to_cluster(tpu) - tf.tpu.experimental.initialize_tpu_system(tpu) - - strategy = tf.distribute.TPUStrategy(tpu) - - elif len(gpus) == 0: - strategy = tf.distribute.OneDeviceStrategy(device="/cpu:0") - elif len(gpus) == 1: - strategy = tf.distribute.OneDeviceStrategy(device="/gpu:0") - elif len(gpus) > 1: - # If you only want to use a specific subset of GPUs use `CUDA_VISIBLE_DEVICES=0` - strategy = tf.distribute.MirroredStrategy() - else: - raise ValueError("Cannot find the proper strategy, please check your environment properties.") - - return strategy - - @property - def strategy(self) -> "tf.distribute.Strategy": - """ - The strategy used for distributed training. - """ - requires_backends(self, ["tf"]) - return self._setup_strategy - - @property - def n_replicas(self) -> int: - """ - The number of replicas (CPUs, GPUs or TPU cores) used in this training. - """ - requires_backends(self, ["tf"]) - return self._setup_strategy.num_replicas_in_sync - - @property - def should_log(self): - """ - Whether or not the current process should produce log. - """ - return False # TF Logging is handled by Keras not the Trainer - - @property - def train_batch_size(self) -> int: - """ - The actual batch size for training (may differ from `per_gpu_train_batch_size` in distributed training). - """ - if self.per_gpu_train_batch_size: - logger.warning( - "Using deprecated `--per_gpu_train_batch_size` argument which will be removed in a future " - "version. Using `--per_device_train_batch_size` is preferred." - ) - per_device_batch_size = self.per_gpu_train_batch_size or self.per_device_train_batch_size - return per_device_batch_size * self.n_replicas - - @property - def eval_batch_size(self) -> int: - """ - The actual batch size for evaluation (may differ from `per_gpu_eval_batch_size` in distributed training). - """ - if self.per_gpu_eval_batch_size: - logger.warning( - "Using deprecated `--per_gpu_eval_batch_size` argument which will be removed in a future " - "version. Using `--per_device_eval_batch_size` is preferred." - ) - per_device_batch_size = self.per_gpu_eval_batch_size or self.per_device_eval_batch_size - return per_device_batch_size * self.n_replicas - - @property - def n_gpu(self) -> int: - """ - The number of replicas (CPUs, GPUs or TPU cores) used in this training. - """ - requires_backends(self, ["tf"]) - warnings.warn( - "The n_gpu argument is deprecated and will be removed in a future version, use n_replicas instead.", - FutureWarning, - ) - return self._setup_strategy.num_replicas_in_sync diff --git a/src/transformers/utils/__init__.py b/src/transformers/utils/__init__.py index 1b4671a55e8c..70eed29f3a65 100644 --- a/src/transformers/utils/__init__.py +++ b/src/transformers/utils/__init__.py @@ -57,12 +57,8 @@ filter_out_non_signature_kwargs, find_labels, flatten_dict, - infer_framework, - is_jax_tensor, is_numpy_array, is_tensor, - is_tf_symbolic_tensor, - is_tf_tensor, is_timm_config_dict, is_timm_local_checkpoint, is_torch_device, @@ -117,9 +113,6 @@ GGUF_MIN_VERSION, TORCH_FX_REQUIRED_VERSION, TRITON_MIN_VERSION, - USE_JAX, - USE_TF, - USE_TORCH, XLA_FSDPV2_MIN_VERSION, DummyObject, OptionalDependencyNotAvailable, @@ -156,7 +149,6 @@ is_flash_attn_3_available, is_flash_attn_greater_or_equal, is_flash_attn_greater_or_equal_2_10, - is_flax_available, is_flute_available, is_fp_quant_available, is_fsdp_available, @@ -175,7 +167,6 @@ is_jinja_available, is_jumanpp_available, is_kenlm_available, - is_keras_nlp_available, is_kernels_available, is_levenshtein_available, is_libcst_available, @@ -225,10 +216,6 @@ is_spqr_available, is_sudachi_available, is_sudachi_projection_available, - is_tensorflow_probability_available, - is_tensorflow_text_available, - is_tf2onnx_available, - is_tf_available, is_tiktoken_available, is_timm_available, is_tokenizers_available, @@ -288,11 +275,6 @@ WEIGHTS_NAME = "pytorch_model.bin" WEIGHTS_INDEX_NAME = "pytorch_model.bin.index.json" -TF2_WEIGHTS_NAME = "tf_model.h5" -TF2_WEIGHTS_INDEX_NAME = "tf_model.h5.index.json" -TF_WEIGHTS_NAME = "model.ckpt" -FLAX_WEIGHTS_NAME = "flax_model.msgpack" -FLAX_WEIGHTS_INDEX_NAME = "flax_model.msgpack.index.json" SAFE_WEIGHTS_NAME = "model.safetensors" SAFE_WEIGHTS_INDEX_NAME = "model.safetensors.index.json" CONFIG_NAME = "config.json" diff --git a/src/transformers/utils/doc.py b/src/transformers/utils/doc.py index 6488c6d16bdd..f9a787a74a13 100644 --- a/src/transformers/utils/doc.py +++ b/src/transformers/utils/doc.py @@ -95,15 +95,6 @@ def docstring_decorator(fn): """ -TF_RETURN_INTRODUCTION = r""" - Returns: - [`{full_output_type}`] or `tuple(tf.Tensor)`: A [`{full_output_type}`] or a tuple of `tf.Tensor` (if - `return_dict=False` is passed or when `config.return_dict=False`) comprising various elements depending on the - configuration ([`{config_class}`]) and inputs. - -""" - - def _get_indent(t): """Returns the indentation in the first line of t""" search = re.search(r"^(\s*)\S", t) @@ -160,8 +151,7 @@ def _prepare_output_docstrings(output_type, config_class, min_indent=None, add_i # Add the return introduction if add_intro: full_output_type = f"{output_type.__module__}.{output_type.__name__}" - intro = TF_RETURN_INTRODUCTION if output_type.__name__.startswith("TF") else PT_RETURN_INTRODUCTION - intro = intro.format(full_output_type=full_output_type, config_class=config_class) + intro = PT_RETURN_INTRODUCTION.format(full_output_type=full_output_type, config_class=config_class) else: full_output_type = str(output_type) intro = f"\nReturns:\n `{full_output_type}`" @@ -999,445 +989,6 @@ def _prepare_output_docstrings(output_type, config_class, min_indent=None, add_i ) -TF_TOKEN_CLASSIFICATION_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = tokenizer( - ... "HuggingFace is a company based in Paris and New York", add_special_tokens=False, return_tensors="tf" - ... ) - - >>> logits = model(**inputs).logits - >>> predicted_token_class_ids = tf.math.argmax(logits, axis=-1) - - >>> # Note that tokens are classified rather then input words which means that - >>> # there might be more predicted token classes than words. - >>> # Multiple token classes might account for the same word - >>> predicted_tokens_classes = [model.config.id2label[t] for t in predicted_token_class_ids[0].numpy().tolist()] - >>> predicted_tokens_classes - {expected_output} - ``` - - ```python - >>> labels = predicted_token_class_ids - >>> loss = tf.math.reduce_mean(model(**inputs, labels=labels).loss) - >>> round(float(loss), 2) - {expected_loss} - ``` -""" - -TF_QUESTION_ANSWERING_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> question, text = "Who was Jim Henson?", "Jim Henson was a nice puppet" - - >>> inputs = tokenizer(question, text, return_tensors="tf") - >>> outputs = model(**inputs) - - >>> answer_start_index = int(tf.math.argmax(outputs.start_logits, axis=-1)[0]) - >>> answer_end_index = int(tf.math.argmax(outputs.end_logits, axis=-1)[0]) - - >>> predict_answer_tokens = inputs.input_ids[0, answer_start_index : answer_end_index + 1] - >>> tokenizer.decode(predict_answer_tokens) - {expected_output} - ``` - - ```python - >>> # target is "nice puppet" - >>> target_start_index = tf.constant([{qa_target_start_index}]) - >>> target_end_index = tf.constant([{qa_target_end_index}]) - - >>> outputs = model(**inputs, start_positions=target_start_index, end_positions=target_end_index) - >>> loss = tf.math.reduce_mean(outputs.loss) - >>> round(float(loss), 2) - {expected_loss} - ``` -""" - -TF_SEQUENCE_CLASSIFICATION_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="tf") - - >>> logits = model(**inputs).logits - - >>> predicted_class_id = int(tf.math.argmax(logits, axis=-1)[0]) - >>> model.config.id2label[predicted_class_id] - {expected_output} - ``` - - ```python - >>> # To train a model on `num_labels` classes, you can pass `num_labels=num_labels` to `.from_pretrained(...)` - >>> num_labels = len(model.config.id2label) - >>> model = {model_class}.from_pretrained("{checkpoint}", num_labels=num_labels) - - >>> labels = tf.constant(1) - >>> loss = model(**inputs, labels=labels).loss - >>> round(float(loss), 2) - {expected_loss} - ``` -""" - -TF_MASKED_LM_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = tokenizer("The capital of France is {mask}.", return_tensors="tf") - >>> logits = model(**inputs).logits - - >>> # retrieve index of {mask} - >>> mask_token_index = tf.where((inputs.input_ids == tokenizer.mask_token_id)[0]) - >>> selected_logits = tf.gather_nd(logits[0], indices=mask_token_index) - - >>> predicted_token_id = tf.math.argmax(selected_logits, axis=-1) - >>> tokenizer.decode(predicted_token_id) - {expected_output} - ``` - - ```python - >>> labels = tokenizer("The capital of France is Paris.", return_tensors="tf")["input_ids"] - >>> # mask labels of non-{mask} tokens - >>> labels = tf.where(inputs.input_ids == tokenizer.mask_token_id, labels, -100) - - >>> outputs = model(**inputs, labels=labels) - >>> round(float(outputs.loss), 2) - {expected_loss} - ``` -""" - -TF_BASE_MODEL_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="tf") - >>> outputs = model(inputs) - - >>> last_hidden_states = outputs.last_hidden_state - ``` -""" - -TF_MULTIPLE_CHOICE_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced." - >>> choice0 = "It is eaten with a fork and a knife." - >>> choice1 = "It is eaten while held in the hand." - - >>> encoding = tokenizer([prompt, prompt], [choice0, choice1], return_tensors="tf", padding=True) - >>> inputs = {{k: tf.expand_dims(v, 0) for k, v in encoding.items()}} - >>> outputs = model(inputs) # batch size is 1 - - >>> # the linear classifier still needs to be trained - >>> logits = outputs.logits - ``` -""" - -TF_CAUSAL_LM_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - >>> import tensorflow as tf - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="tf") - >>> outputs = model(inputs) - >>> logits = outputs.logits - ``` -""" - -TF_SPEECH_BASE_MODEL_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoProcessor, {model_class} - >>> from datasets import load_dataset - - >>> dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation") - >>> dataset = dataset.sort("id") - >>> sampling_rate = dataset.features["audio"].sampling_rate - - >>> processor = AutoProcessor.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> # audio file is decoded on the fly - >>> inputs = processor(dataset[0]["audio"]["array"], sampling_rate=sampling_rate, return_tensors="tf") - >>> outputs = model(**inputs) - - >>> last_hidden_states = outputs.last_hidden_state - >>> list(last_hidden_states.shape) - {expected_output} - ``` -""" - -TF_SPEECH_CTC_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoProcessor, {model_class} - >>> from datasets import load_dataset - >>> import tensorflow as tf - - >>> dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation") - >>> dataset = dataset.sort("id") - >>> sampling_rate = dataset.features["audio"].sampling_rate - - >>> processor = AutoProcessor.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> # audio file is decoded on the fly - >>> inputs = processor(dataset[0]["audio"]["array"], sampling_rate=sampling_rate, return_tensors="tf") - >>> logits = model(**inputs).logits - >>> predicted_ids = tf.math.argmax(logits, axis=-1) - - >>> # transcribe speech - >>> transcription = processor.batch_decode(predicted_ids) - >>> transcription[0] - {expected_output} - ``` - - ```python - >>> inputs["labels"] = processor(text=dataset[0]["text"], return_tensors="tf").input_ids - - >>> # compute loss - >>> loss = model(**inputs).loss - >>> round(float(loss), 2) - {expected_loss} - ``` -""" - -TF_VISION_BASE_MODEL_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoImageProcessor, {model_class} - >>> from datasets import load_dataset - - >>> dataset = load_dataset("huggingface/cats-image") - >>> image = dataset["test"]["image"][0] - - >>> image_processor = AutoImageProcessor.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = image_processor(image, return_tensors="tf") - >>> outputs = model(**inputs) - - >>> last_hidden_states = outputs.last_hidden_state - >>> list(last_hidden_states.shape) - {expected_output} - ``` -""" - -TF_VISION_SEQ_CLASS_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoImageProcessor, {model_class} - >>> import tensorflow as tf - >>> from datasets import load_dataset - - >>> dataset = load_dataset("huggingface/cats-image")) - >>> image = dataset["test"]["image"][0] - - >>> image_processor = AutoImageProcessor.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = image_processor(image, return_tensors="tf") - >>> logits = model(**inputs).logits - - >>> # model predicts one of the 1000 ImageNet classes - >>> predicted_label = int(tf.math.argmax(logits, axis=-1)) - >>> print(model.config.id2label[predicted_label]) - {expected_output} - ``` -""" - -TF_SAMPLE_DOCSTRINGS = { - "SequenceClassification": TF_SEQUENCE_CLASSIFICATION_SAMPLE, - "QuestionAnswering": TF_QUESTION_ANSWERING_SAMPLE, - "TokenClassification": TF_TOKEN_CLASSIFICATION_SAMPLE, - "MultipleChoice": TF_MULTIPLE_CHOICE_SAMPLE, - "MaskedLM": TF_MASKED_LM_SAMPLE, - "LMHead": TF_CAUSAL_LM_SAMPLE, - "BaseModel": TF_BASE_MODEL_SAMPLE, - "SpeechBaseModel": TF_SPEECH_BASE_MODEL_SAMPLE, - "CTC": TF_SPEECH_CTC_SAMPLE, - "VisionBaseModel": TF_VISION_BASE_MODEL_SAMPLE, - "ImageClassification": TF_VISION_SEQ_CLASS_SAMPLE, -} - - -FLAX_TOKEN_CLASSIFICATION_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="jax") - - >>> outputs = model(**inputs) - >>> logits = outputs.logits - ``` -""" - -FLAX_QUESTION_ANSWERING_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> question, text = "Who was Jim Henson?", "Jim Henson was a nice puppet" - >>> inputs = tokenizer(question, text, return_tensors="jax") - - >>> outputs = model(**inputs) - >>> start_scores = outputs.start_logits - >>> end_scores = outputs.end_logits - ``` -""" - -FLAX_SEQUENCE_CLASSIFICATION_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="jax") - - >>> outputs = model(**inputs) - >>> logits = outputs.logits - ``` -""" - -FLAX_MASKED_LM_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = tokenizer("The capital of France is {mask}.", return_tensors="jax") - - >>> outputs = model(**inputs) - >>> logits = outputs.logits - ``` -""" - -FLAX_BASE_MODEL_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="jax") - >>> outputs = model(**inputs) - - >>> last_hidden_states = outputs.last_hidden_state - ``` -""" - -FLAX_MULTIPLE_CHOICE_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced." - >>> choice0 = "It is eaten with a fork and a knife." - >>> choice1 = "It is eaten while held in the hand." - - >>> encoding = tokenizer([prompt, prompt], [choice0, choice1], return_tensors="jax", padding=True) - >>> outputs = model(**{{k: v[None, :] for k, v in encoding.items()}}) - - >>> logits = outputs.logits - ``` -""" - -FLAX_CAUSAL_LM_SAMPLE = r""" - Example: - - ```python - >>> from transformers import AutoTokenizer, {model_class} - - >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") - >>> model = {model_class}.from_pretrained("{checkpoint}") - - >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="np") - >>> outputs = model(**inputs) - - >>> # retrieve logts for next token - >>> next_token_logits = outputs.logits[:, -1] - ``` -""" - -FLAX_SAMPLE_DOCSTRINGS = { - "SequenceClassification": FLAX_SEQUENCE_CLASSIFICATION_SAMPLE, - "QuestionAnswering": FLAX_QUESTION_ANSWERING_SAMPLE, - "TokenClassification": FLAX_TOKEN_CLASSIFICATION_SAMPLE, - "MultipleChoice": FLAX_MULTIPLE_CHOICE_SAMPLE, - "MaskedLM": FLAX_MASKED_LM_SAMPLE, - "BaseModel": FLAX_BASE_MODEL_SAMPLE, - "LMHead": FLAX_CAUSAL_LM_SAMPLE, -} - - def filter_outputs_from_example(docstring, **kwargs): """ Removes the lines testing an output with the doctest syntax in a code sample when it's set to `None`. @@ -1472,12 +1023,7 @@ def docstring_decorator(fn): # model_class defaults to function's class if not specified otherwise model_class = fn.__qualname__.split(".")[0] if model_cls is None else model_cls - if model_class[:2] == "TF": - sample_docstrings = TF_SAMPLE_DOCSTRINGS - elif model_class[:4] == "Flax": - sample_docstrings = FLAX_SAMPLE_DOCSTRINGS - else: - sample_docstrings = PT_SAMPLE_DOCSTRINGS + sample_docstrings = PT_SAMPLE_DOCSTRINGS # putting all kwargs for docstrings in a dict to be used # with the `.format(**doc_kwargs)`. Note that string might diff --git a/src/transformers/utils/dummy_flax_objects.py b/src/transformers/utils/dummy_flax_objects.py deleted file mode 100644 index 6f886de28246..000000000000 --- a/src/transformers/utils/dummy_flax_objects.py +++ /dev/null @@ -1,107 +0,0 @@ -# This file is autogenerated by the command `make fix-copies`, do not edit. -from ..utils import DummyObject, requires_backends - - -class FlaxForcedBOSTokenLogitsProcessor(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxForcedEOSTokenLogitsProcessor(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxForceTokensLogitsProcessor(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxGenerationMixin(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxLogitsProcessor(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxLogitsProcessorList(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxLogitsWarper(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxMinLengthLogitsProcessor(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxSuppressTokensAtBeginLogitsProcessor(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxSuppressTokensLogitsProcessor(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxTemperatureLogitsWarper(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxTopKLogitsWarper(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxTopPLogitsWarper(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxWhisperTimeStampLogitsProcessor(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) - - -class FlaxPreTrainedModel(metaclass=DummyObject): - _backends = ["flax"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["flax"]) diff --git a/src/transformers/utils/dummy_tensorflow_text_objects.py b/src/transformers/utils/dummy_tensorflow_text_objects.py deleted file mode 100644 index 70c7ad5cbf40..000000000000 --- a/src/transformers/utils/dummy_tensorflow_text_objects.py +++ /dev/null @@ -1,9 +0,0 @@ -# This file is autogenerated by the command `make fix-copies`, do not edit. -from ..utils import DummyObject, requires_backends - - -class TFBertTokenizer(metaclass=DummyObject): - _backends = ["tensorflow_text"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tensorflow_text"]) diff --git a/src/transformers/utils/dummy_tf_objects.py b/src/transformers/utils/dummy_tf_objects.py deleted file mode 100644 index de7b6f505df5..000000000000 --- a/src/transformers/utils/dummy_tf_objects.py +++ /dev/null @@ -1,178 +0,0 @@ -# This file is autogenerated by the command `make fix-copies`, do not edit. -from ..utils import DummyObject, requires_backends - - -class TFForcedBOSTokenLogitsProcessor(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFForcedEOSTokenLogitsProcessor(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFForceTokensLogitsProcessor(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFGenerationMixin(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFLogitsProcessor(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFLogitsProcessorList(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFLogitsWarper(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFMinLengthLogitsProcessor(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFNoBadWordsLogitsProcessor(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFNoRepeatNGramLogitsProcessor(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFRepetitionPenaltyLogitsProcessor(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFSuppressTokensAtBeginLogitsProcessor(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFSuppressTokensLogitsProcessor(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFTemperatureLogitsWarper(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFTopKLogitsWarper(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFTopPLogitsWarper(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class KerasMetricCallback(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class PushToHubCallback(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFPreTrainedModel(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFSequenceSummary(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class TFSharedEmbeddings(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -def shape_list(*args, **kwargs): - requires_backends(shape_list, ["tf"]) - - -class AdamWeightDecay(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class GradientAccumulator(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -class WarmUp(metaclass=DummyObject): - _backends = ["tf"] - - def __init__(self, *args, **kwargs): - requires_backends(self, ["tf"]) - - -def create_optimizer(*args, **kwargs): - requires_backends(create_optimizer, ["tf"]) diff --git a/src/transformers/utils/generic.py b/src/transformers/utils/generic.py index 94d842eee826..ef5e356bcd1c 100644 --- a/src/transformers/utils/generic.py +++ b/src/transformers/utils/generic.py @@ -32,9 +32,7 @@ from ..utils import logging from .import_utils import ( - is_flax_available, is_mlx_available, - is_tf_available, is_torch_available, is_torch_fx_proxy, requires, @@ -76,10 +74,6 @@ def infer_framework_from_repr(x): representation = str(type(x)) if representation.startswith(" str: ua = f"transformers/{__version__}; python/{sys.version.split()[0]}; session_id/{SESSION_ID}" if is_torch_available(): ua += f"; torch/{_torch_version}" - if is_tf_available(): - ua += f"; tensorflow/{_tf_version}" if constants.HF_HUB_DISABLE_TELEMETRY: return ua + "; telemetry/off" if is_training_run_on_sagemaker(): @@ -1020,7 +1016,7 @@ def send_example_telemetry(example_name, *example_args, framework="pytorch"): data["dataset_name"] = args_as_dict["dataset_name"] elif "task_name" in args_as_dict: # Extract script name from the example_name - script_name = example_name.replace("tf_", "").replace("flax_", "").replace("run_", "") + script_name = example_name.replace("run_", "") script_name = script_name.replace("_no_trainer", "") data["dataset_name"] = f"{script_name}-{args_as_dict['task_name']}" diff --git a/src/transformers/utils/import_utils.py b/src/transformers/utils/import_utils.py index 2f6dc0b8e714..df06bd05842d 100644 --- a/src/transformers/utils/import_utils.py +++ b/src/transformers/utils/import_utils.py @@ -99,15 +99,9 @@ def _is_package_available(pkg_name: str, return_version: bool = False) -> Union[ ENV_VARS_TRUE_VALUES = {"1", "ON", "YES", "TRUE"} ENV_VARS_TRUE_AND_AUTO_VALUES = ENV_VARS_TRUE_VALUES.union({"AUTO"}) -USE_TF = os.environ.get("USE_TF", "AUTO").upper() -USE_TORCH = os.environ.get("USE_TORCH", "AUTO").upper() -USE_JAX = os.environ.get("USE_FLAX", "AUTO").upper() - # Try to run a native pytorch job in an environment with TorchXLA installed by setting this value to 0. USE_TORCH_XLA = os.environ.get("USE_TORCH_XLA", "1").upper() -FORCE_TF_AVAILABLE = os.environ.get("FORCE_TF_AVAILABLE", "AUTO").upper() - # `transformers` requires `torch>=1.11` but this variable is exposed publicly, and we can't simply remove it. # This is the version of torch required to run torch.fx features and torch.onnx with dictionary inputs. TORCH_FX_REQUIRED_VERSION = version.parse("1.10") @@ -221,9 +215,6 @@ def _is_package_available(pkg_name: str, return_version: bool = False) -> Union[ _soundfile_available = _is_package_available("soundfile") _spacy_available = _is_package_available("spacy") _sudachipy_available, _sudachipy_version = _is_package_available("sudachipy", return_version=True) -_tensorflow_probability_available = _is_package_available("tensorflow_probability") -_tensorflow_text_available = _is_package_available("tensorflow_text") -_tf2onnx_available = _is_package_available("tf2onnx") _timm_available = _is_package_available("timm") _tokenizers_available = _is_package_available("tokenizers") _torchaudio_available = _is_package_available("torchaudio") @@ -243,60 +234,11 @@ def _is_package_available(pkg_name: str, return_version: bool = False) -> Union[ _mistral_common_available = _is_package_available("mistral_common") _triton_available, _triton_version = _is_package_available("triton", return_version=True) -_torch_version = "N/A" -_torch_available = False -if USE_TORCH in ENV_VARS_TRUE_AND_AUTO_VALUES and USE_TF not in ENV_VARS_TRUE_VALUES: - _torch_available, _torch_version = _is_package_available("torch", return_version=True) - if _torch_available: - _torch_available = version.parse(_torch_version) >= version.parse("2.1.0") - if not _torch_available: - logger.warning(f"Disabling PyTorch because PyTorch >= 2.1 is required but found {_torch_version}") -else: - logger.info("Disabling PyTorch because USE_TF is set") - _torch_available = False - - -_tf_version = "N/A" -_tf_available = False -if FORCE_TF_AVAILABLE in ENV_VARS_TRUE_VALUES: - _tf_available = True -else: - if USE_TF in ENV_VARS_TRUE_AND_AUTO_VALUES and USE_TORCH not in ENV_VARS_TRUE_VALUES: - # Note: _is_package_available("tensorflow") fails for tensorflow-cpu. Please test any changes to the line below - # with tensorflow-cpu to make sure it still works! - _tf_available = importlib.util.find_spec("tensorflow") is not None - if _tf_available: - candidates = ( - "tensorflow", - "tensorflow-cpu", - "tensorflow-gpu", - "tf-nightly", - "tf-nightly-cpu", - "tf-nightly-gpu", - "tf-nightly-rocm", - "intel-tensorflow", - "intel-tensorflow-avx512", - "tensorflow-rocm", - "tensorflow-macos", - "tensorflow-aarch64", - ) - _tf_version = None - # For the metadata, we have to look for both tensorflow and tensorflow-cpu - for pkg in candidates: - try: - _tf_version = importlib.metadata.version(pkg) - break - except importlib.metadata.PackageNotFoundError: - pass - _tf_available = _tf_version is not None - if _tf_available: - if version.parse(_tf_version) < version.parse("2"): - logger.info( - f"TensorFlow found but with version {_tf_version}. Transformers requires version 2 minimum." - ) - _tf_available = False - else: - logger.info("Disabling Tensorflow because USE_TORCH is set") +_torch_available, _torch_version = _is_package_available("torch", return_version=True) +if _torch_available: + _torch_available = version.parse(_torch_version) >= version.parse("2.1.0") + if not _torch_available: + logger.warning(f"Disabling PyTorch because PyTorch >= 2.1 is required but found {_torch_version}") _essentia_available = importlib.util.find_spec("essentia") is not None @@ -351,18 +293,6 @@ def _is_package_available(pkg_name: str, return_version: bool = False) -> Union[ _is_ccl_available = False -_flax_available = False -if USE_JAX in ENV_VARS_TRUE_AND_AUTO_VALUES: - _flax_available, _flax_version = _is_package_available("flax", return_version=True) - if _flax_available: - _jax_available, _jax_version = _is_package_available("jax", return_version=True) - if _jax_available: - logger.info(f"JAX version {_jax_version}, Flax version {_flax_version} available.") - else: - _flax_available = _jax_available = False - _jax_version = _flax_version = "N/A" - - _torch_xla_available = False if USE_TORCH_XLA in ENV_VARS_TRUE_VALUES: _torch_xla_available, _torch_xla_version = _is_package_available("torch_xla", return_version=True) @@ -761,26 +691,14 @@ def is_bs4_available() -> Union[tuple[bool, str], bool]: return _bs4_available -def is_tf_available() -> bool: - return _tf_available - - def is_coloredlogs_available() -> Union[tuple[bool, str], bool]: return _coloredlogs_available -def is_tf2onnx_available() -> Union[tuple[bool, str], bool]: - return _tf2onnx_available - - def is_onnx_available() -> Union[tuple[bool, str], bool]: return _onnx_available -def is_flax_available() -> bool: - return _flax_available - - def is_flute_available() -> bool: try: return importlib.util.find_spec("flute") is not None and importlib.metadata.version("flute-kernel") >= "0.4.1" @@ -1446,14 +1364,6 @@ def is_spacy_available() -> Union[tuple[bool, str], bool]: return _spacy_available -def is_tensorflow_text_available() -> Union[tuple[bool, str], bool]: - return is_tf_available() and _tensorflow_text_available - - -def is_keras_nlp_available() -> Union[tuple[bool, str], bool]: - return is_tensorflow_text_available() and _keras_nlp_available - - def is_in_notebook() -> bool: try: # Check if we are running inside Marimo @@ -1478,10 +1388,6 @@ def is_pytorch_quantization_available() -> Union[tuple[bool, str], bool]: return _pytorch_quantization_available -def is_tensorflow_probability_available() -> Union[tuple[bool, str], bool]: - return _tensorflow_probability_available - - def is_pandas_available() -> Union[tuple[bool, str], bool]: return _pandas_available @@ -1572,10 +1478,7 @@ def is_uroman_available() -> Union[tuple[bool, str], bool]: def torch_only_method(fn: Callable) -> Callable: def wrapper(*args, **kwargs): if not _torch_available: - raise ImportError( - "You need to install pytorch to use this method or class, " - "or activate it with environment variables USE_TORCH=1 and USE_TF=0." - ) + raise ImportError("You need to install pytorch to use this method or class") else: return fn(*args, **kwargs) @@ -1771,30 +1674,6 @@ def check_torch_load_is_safe() -> None: Please note that you may need to restart your runtime after installation. """ -# docstyle-ignore -PYTORCH_IMPORT_ERROR_WITH_TF = """ -{0} requires the PyTorch library but it was not found in your environment. -However, we were able to find a TensorFlow installation. TensorFlow classes begin -with "TF", but are otherwise identically named to our PyTorch classes. This -means that the TF equivalent of the class you tried to import would be "TF{0}". -If you want to use TensorFlow, please use TF classes instead! - -If you really do want to use PyTorch please go to -https://pytorch.org/get-started/locally/ and follow the instructions that -match your environment. -""" - -# docstyle-ignore -TF_IMPORT_ERROR_WITH_PYTORCH = """ -{0} requires the TensorFlow library but it was not found in your environment. -However, we were able to find a PyTorch installation. PyTorch classes do not begin -with "TF", but are otherwise identically named to our TF classes. -If you want to use PyTorch, please use those classes instead! - -If you really do want to use TensorFlow, please follow the instructions on the -installation page https://www.tensorflow.org/install that match your environment. -""" - # docstyle-ignore BS4_IMPORT_ERROR = """ {0} requires the Beautiful Soup library but it was not found in your environment. You can install it with pip: @@ -1816,14 +1695,6 @@ def check_torch_load_is_safe() -> None: """ -# docstyle-ignore -TENSORFLOW_IMPORT_ERROR = """ -{0} requires the TensorFlow library but it was not found in your environment. Check out the instructions on the -installation page: https://www.tensorflow.org/install and follow the ones that match your environment. -Please note that you may need to restart your runtime after installation. -""" - - # docstyle-ignore DETECTRON2_IMPORT_ERROR = """ {0} requires the detectron2 library but it was not found in your environment. Check out the instructions on the @@ -1832,13 +1703,6 @@ def check_torch_load_is_safe() -> None: """ -# docstyle-ignore -FLAX_IMPORT_ERROR = """ -{0} requires the FLAX library but it was not found in your environment. Check out the instructions on the -installation page: https://github.com/google/flax and follow the ones that match your environment. -Please note that you may need to restart your runtime after installation. -""" - # docstyle-ignore FTFY_IMPORT_ERROR = """ {0} requires the ftfy library but it was not found in your environment. Check out the instructions on the @@ -1864,19 +1728,6 @@ def check_torch_load_is_safe() -> None: Please note that you may need to restart your runtime after installation. """ -# docstyle-ignore -TENSORFLOW_PROBABILITY_IMPORT_ERROR = """ -{0} requires the tensorflow_probability library but it was not found in your environment. You can install it with pip as -explained here: https://github.com/tensorflow/probability. Please note that you may need to restart your runtime after installation. -""" - -# docstyle-ignore -TENSORFLOW_TEXT_IMPORT_ERROR = """ -{0} requires the tensorflow_text library but it was not found in your environment. You can install it with pip as -explained here: https://www.tensorflow.org/text/guide/tf_text_intro. -Please note that you may need to restart your runtime after installation. -""" - # docstyle-ignore TORCHAUDIO_IMPORT_ERROR = """ {0} requires the torchaudio library but it was not found in your environment. Please install it and restart your @@ -2071,7 +1922,6 @@ def check_torch_load_is_safe() -> None: ("detectron2", (is_detectron2_available, DETECTRON2_IMPORT_ERROR)), ("essentia", (is_essentia_available, ESSENTIA_IMPORT_ERROR)), ("faiss", (is_faiss_available, FAISS_IMPORT_ERROR)), - ("flax", (is_flax_available, FLAX_IMPORT_ERROR)), ("ftfy", (is_ftfy_available, FTFY_IMPORT_ERROR)), ("g2p_en", (is_g2p_en_available, G2P_EN_IMPORT_ERROR)), ("pandas", (is_pandas_available, PANDAS_IMPORT_ERROR)), @@ -2088,9 +1938,6 @@ def check_torch_load_is_safe() -> None: ("sentencepiece", (is_sentencepiece_available, SENTENCEPIECE_IMPORT_ERROR)), ("sklearn", (is_sklearn_available, SKLEARN_IMPORT_ERROR)), ("speech", (is_speech_available, SPEECH_IMPORT_ERROR)), - ("tensorflow_probability", (is_tensorflow_probability_available, TENSORFLOW_PROBABILITY_IMPORT_ERROR)), - ("tf", (is_tf_available, TENSORFLOW_IMPORT_ERROR)), - ("tensorflow_text", (is_tensorflow_text_available, TENSORFLOW_TEXT_IMPORT_ERROR)), ("timm", (is_timm_available, TIMM_IMPORT_ERROR)), ("torchaudio", (is_torchaudio_available, TORCHAUDIO_IMPORT_ERROR)), ("natten", (is_natten_available, NATTEN_IMPORT_ERROR)), @@ -2109,7 +1956,6 @@ def check_torch_load_is_safe() -> None: ("jinja", (is_jinja_available, JINJA_IMPORT_ERROR)), ("yt_dlp", (is_yt_dlp_available, YT_DLP_IMPORT_ERROR)), ("rich", (is_rich_available, RICH_IMPORT_ERROR)), - ("keras_nlp", (is_keras_nlp_available, KERAS_NLP_IMPORT_ERROR)), ("pydantic", (is_pydantic_available, PYDANTIC_IMPORT_ERROR)), ("fastapi", (is_fastapi_available, FASTAPI_IMPORT_ERROR)), ("uvicorn", (is_uvicorn_available, UVICORN_IMPORT_ERROR)), @@ -2125,14 +1971,6 @@ def requires_backends(obj, backends): name = obj.__name__ if hasattr(obj, "__name__") else obj.__class__.__name__ - # Raise an error for users who might not realize that classes without "TF" are torch-only - if "torch" in backends and "tf" not in backends and not is_torch_available() and is_tf_available(): - raise ImportError(PYTORCH_IMPORT_ERROR_WITH_TF.format(name)) - - # Raise the inverse error for PyTorch users trying to load TF classes - if "tf" in backends and "torch" not in backends and is_torch_available() and not is_tf_available(): - raise ImportError(TF_IMPORT_ERROR_WITH_PYTORCH.format(name)) - failed = [] for backend in backends: if isinstance(backend, Backend): @@ -2464,8 +2302,6 @@ def inner_fn(fun): BASE_FILE_REQUIREMENTS = { - lambda e: "modeling_tf_" in e: ("tf",), - lambda e: "modeling_flax_" in e: ("flax",), lambda e: "modeling_" in e: ("torch",), lambda e: e.startswith("tokenization_") and e.endswith("_fast"): ("tokenizers",), lambda e: e.startswith("image_processing_") and e.endswith("_fast"): ("vision", "torch", "torchvision"), @@ -2536,8 +2372,6 @@ def create_import_structure_from_path(module_path): backend specified. The default backends are defined according to the filename: - If a file is named like `modeling_*.py`, it will have a `torch` backend - - If a file is named like `modeling_tf_*.py`, it will have a `tf` backend - - If a file is named like `modeling_flax_*.py`, it will have a `flax` backend - If a file is named like `tokenization_*_fast.py`, it will have a `tokenizers` backend - If a file is named like `image_processing*_fast.py`, it will have a `torchvision` + `torch` backend @@ -2615,8 +2449,8 @@ def find_substring(substring, list_): previous_index = 0 # Some files have some requirements by default. - # For example, any file named `modeling_tf_xxx.py` - # should have TensorFlow as a required backend. + # For example, any file named `modeling_xxx.py` + # should have torch as a required backend. base_requirements = () for string_check, requirements in BASE_FILE_REQUIREMENTS.items(): if string_check(module_name): @@ -2652,7 +2486,6 @@ def find_substring(substring, list_): # backends=( # "sentencepiece", # "torch", - # "tf", # ) # ) # @@ -2660,7 +2493,7 @@ def find_substring(substring, list_): # # @export( # backends=( - # "sentencepiece", "tf" + # "sentencepiece", # ) # ) elif "backends" in lines[previous_index + 1]: diff --git a/tests/fixtures/add_distilbert_like_config.json b/tests/fixtures/add_distilbert_like_config.json deleted file mode 100644 index 6603796a0418..000000000000 --- a/tests/fixtures/add_distilbert_like_config.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "add_copied_from": true, - "old_model_type": "distilbert", - "new_model_patterns": { - "model_name": "BERT New", - "checkpoint": "huggingface/bert-new-base", - "model_type": "bert-new", - "model_lower_cased": "bert_new", - "model_camel_cased": "BertNew", - "model_upper_cased": "BERT_NEW", - "config_class": "BertNewConfig", - "tokenizer_class": "DistilBertTokenizer" - }, - "frameworks": [ - "pt", - "tf", - "flax" - ] -} diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index 094c5861ab10..b8931c9988f6 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -3252,7 +3252,6 @@ def test_logits_processor_not_inplace(self): self.assertNotEqual(out_with_temp.logits[-1].tolist(), out_with_temp.scores[-1].tolist()) def test_eos_token_id_int_and_list_top_k_top_sampling(self): - # Has TF equivalent: this test relies on random sampling generation_kwargs = { "do_sample": True, "num_beams": 1, @@ -3280,7 +3279,6 @@ def test_eos_token_id_int_and_list_top_k_top_sampling(self): self.assertTrue(expectation == len(generated_tokens[0])) def test_model_kwarg_encoder_signature_filtering(self): - # Has TF equivalent: ample use of framework-specific code bart_tokenizer = AutoTokenizer.from_pretrained("hf-internal-testing/tiny-random-bart") article = """Hugging Face is a technology company based in New York and Paris.""" input_ids = bart_tokenizer(article, return_tensors="pt").input_ids.to(torch_device) diff --git a/tests/models/auto/test_modeling_auto.py b/tests/models/auto/test_modeling_auto.py index 7af5315f844c..352df1fe7b58 100644 --- a/tests/models/auto/test_modeling_auto.py +++ b/tests/models/auto/test_modeling_auto.py @@ -514,12 +514,16 @@ def test_model_file_not_found(self): ): _ = AutoModel.from_pretrained("hf-internal-testing/config-no-model") - def test_model_from_tf_suggestion(self): - with self.assertRaisesRegex(EnvironmentError, "Use `from_tf=True` to load this model"): + def test_model_from_tf_error(self): + with self.assertRaisesRegex( + EnvironmentError, "does not appear to have a file named pytorch_model.bin or model.safetensors." + ): _ = AutoModel.from_pretrained("hf-internal-testing/tiny-bert-tf-only") - def test_model_from_flax_suggestion(self): - with self.assertRaisesRegex(EnvironmentError, "Use `from_flax=True` to load this model"): + def test_model_from_flax_error(self): + with self.assertRaisesRegex( + EnvironmentError, "does not appear to have a file named pytorch_model.bin or model.safetensors." + ): _ = AutoModel.from_pretrained("hf-internal-testing/tiny-bert-flax-only") @unittest.skip("Failing on main") diff --git a/tests/models/aya_vision/test_modeling_aya_vision.py b/tests/models/aya_vision/test_modeling_aya_vision.py index 436cba19c290..8911d39ec10c 100644 --- a/tests/models/aya_vision/test_modeling_aya_vision.py +++ b/tests/models/aya_vision/test_modeling_aya_vision.py @@ -198,7 +198,7 @@ def test_training_gradient_checkpointing_use_reentrant(self): def test_training_gradient_checkpointing_use_reentrant_false(self): pass - @unittest.skip(reason="Siglip uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip uses a non-standard initialization scheme") def test_initialization(self): pass diff --git a/tests/models/big_bird/test_tokenization_big_bird.py b/tests/models/big_bird/test_tokenization_big_bird.py index 09ad1fe992dc..35837c44b876 100644 --- a/tests/models/big_bird/test_tokenization_big_bird.py +++ b/tests/models/big_bird/test_tokenization_big_bird.py @@ -201,22 +201,6 @@ def test_torch_encode_plus_sent_to_model(self): @slow def test_special_tokens(self): - """ - To reproduce: - - $ wget https://github.com/google-research/bigbird/blob/master/bigbird/vocab/gpt2.model?raw=true - $ mv gpt2.model?raw=true gpt2.model - - ``` - import tensorflow_text as tft - import tensorflow as tf - - vocab_model_file = "./gpt2.model" - tokenizer = tft.SentencepieceTokenizer(model=tf.io.gfile.GFile(vocab_model_file, "rb").read())) - ids = tokenizer.tokenize("Paris is the [MASK].") - ids = tf.concat([tf.constant([65]), ids, tf.constant([66])], axis=0) - detokenized = tokenizer.detokenize(ids) # should give [CLS] Paris is the [MASK].[SEP] - """ tokenizer = BigBirdTokenizer.from_pretrained("google/bigbird-roberta-base") decoded_text = tokenizer.decode(tokenizer("Paris is the [MASK].").input_ids) diff --git a/tests/models/blip/test_modeling_blip.py b/tests/models/blip/test_modeling_blip.py index 189773afd399..a59cf4fefffa 100644 --- a/tests/models/blip/test_modeling_blip.py +++ b/tests/models/blip/test_modeling_blip.py @@ -705,7 +705,7 @@ def __init__(self, parent, text_kwargs=None, vision_kwargs=None, is_training=Tru self.text_model_tester = BlipTextModelTester(parent, **text_kwargs) self.vision_model_tester = BlipVisionModelTester(parent, **vision_kwargs) self.batch_size = self.text_model_tester.batch_size # need bs for batching_equivalence test - self.seq_length = self.text_model_tester.seq_length # need seq_length for pt-tf equivalence test + self.seq_length = self.text_model_tester.seq_length self.is_training = is_training def prepare_config_and_inputs(self): diff --git a/tests/models/byt5/test_tokenization_byt5.py b/tests/models/byt5/test_tokenization_byt5.py index 35dd95424dcc..baadfc67c2b8 100644 --- a/tests/models/byt5/test_tokenization_byt5.py +++ b/tests/models/byt5/test_tokenization_byt5.py @@ -21,19 +21,10 @@ from functools import cached_property from transformers import AddedToken, BatchEncoding, ByT5Tokenizer -from transformers.utils import is_tf_available, is_torch_available from ...test_tokenization_common import TokenizerTesterMixin -if is_torch_available(): - FRAMEWORK = "pt" -elif is_tf_available(): - FRAMEWORK = "tf" -else: - FRAMEWORK = "jax" - - class ByT5TokenizationTest(TokenizerTesterMixin, unittest.TestCase): tokenizer_class = ByT5Tokenizer test_rust_tokenizer = False @@ -122,13 +113,10 @@ def test_prepare_batch_integration(self): tokenizer = self.t5_base_tokenizer src_text = ["A long paragraph for summarization.", "Another paragraph for summarization."] expected_src_tokens = [68, 35, 111, 114, 113, 106, 35, 115, 100, 117, 100, 106, 117, 100, 115, 107, 35, 105, 114, 117, 35, 118, 120, 112, 112, 100, 117, 108, 125, 100, 119, 108, 114, 113, 49, 1, 0] # fmt: skip - batch = tokenizer(src_text, padding=True, return_tensors=FRAMEWORK) + batch = tokenizer(src_text, padding=True, return_tensors="pt") self.assertIsInstance(batch, BatchEncoding) - if FRAMEWORK != "jax": - result = list(batch.input_ids.numpy()[0]) - else: - result = list(batch.input_ids.tolist()[0]) + result = list(batch.input_ids.numpy()[0]) self.assertListEqual(expected_src_tokens, result) @@ -138,7 +126,7 @@ def test_prepare_batch_integration(self): def test_empty_target_text(self): tokenizer = self.t5_base_tokenizer src_text = ["A long paragraph for summarization.", "Another paragraph for summarization."] - batch = tokenizer(src_text, padding=True, return_tensors=FRAMEWORK) + batch = tokenizer(src_text, padding=True, return_tensors="pt") # check if input_ids are returned and no decoder_input_ids self.assertIn("input_ids", batch) self.assertIn("attention_mask", batch) @@ -152,7 +140,7 @@ def test_max_length_integration(self): "Another summary.", ] targets = tokenizer( - text_target=tgt_text, max_length=32, padding="max_length", truncation=True, return_tensors=FRAMEWORK + text_target=tgt_text, max_length=32, padding="max_length", truncation=True, return_tensors="pt" ) self.assertEqual(32, targets["input_ids"].shape[1]) diff --git a/tests/models/camembert/test_tokenization_camembert.py b/tests/models/camembert/test_tokenization_camembert.py index 33a49b33958e..704c757fc41d 100644 --- a/tests/models/camembert/test_tokenization_camembert.py +++ b/tests/models/camembert/test_tokenization_camembert.py @@ -18,7 +18,6 @@ from transformers import AddedToken, CamembertTokenizer, CamembertTokenizerFast from transformers.testing_utils import get_tests_dir, require_sentencepiece, require_tokenizers, slow -from transformers.utils import is_torch_available from ...test_tokenization_common import TokenizerTesterMixin @@ -26,8 +25,6 @@ SAMPLE_VOCAB = get_tests_dir("fixtures/test_sentencepiece.model") SAMPLE_BPE_VOCAB = get_tests_dir("fixtures/test_sentencepiece_bpe.model") -FRAMEWORK = "pt" if is_torch_available() else "tf" - @require_sentencepiece @require_tokenizers diff --git a/tests/models/clip/test_modeling_clip.py b/tests/models/clip/test_modeling_clip.py index b352b8160468..0217c5914300 100644 --- a/tests/models/clip/test_modeling_clip.py +++ b/tests/models/clip/test_modeling_clip.py @@ -754,7 +754,7 @@ def test_training_gradient_checkpointing_use_reentrant(self): def test_training_gradient_checkpointing_use_reentrant_false(self): pass - @unittest.skip(reason="CLIP uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="CLIP uses a non-standard initialization scheme") def test_initialization(self): pass diff --git a/tests/models/cohere2_vision/test_modeling_cohere2_vision.py b/tests/models/cohere2_vision/test_modeling_cohere2_vision.py index 96843faa95f7..7a12c2ad9fca 100644 --- a/tests/models/cohere2_vision/test_modeling_cohere2_vision.py +++ b/tests/models/cohere2_vision/test_modeling_cohere2_vision.py @@ -170,7 +170,7 @@ def setUp(self): def test_config(self): self.config_tester.run_common_tests() - @unittest.skip(reason="Siglip backbone uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip backbone uses a non-standard initialization scheme") def test_initialization(self): pass diff --git a/tests/models/colpali/test_modeling_colpali.py b/tests/models/colpali/test_modeling_colpali.py index 7966e34ce323..e051e431bfa8 100644 --- a/tests/models/colpali/test_modeling_colpali.py +++ b/tests/models/colpali/test_modeling_colpali.py @@ -272,9 +272,7 @@ def test_training_gradient_checkpointing_use_reentrant_false(self): def test_model_parallelism(self): pass - @unittest.skip( - reason="PaliGemma's SigLip encoder uses the same initialization scheme as the Flax original implementation" - ) + @unittest.skip(reason="PaliGemma's SigLip encoder uses a non-standard initialization scheme") def test_initialization(self): pass diff --git a/tests/models/deepseek_vl/test_modeling_deepseek_vl.py b/tests/models/deepseek_vl/test_modeling_deepseek_vl.py index a2d1950dcdc4..55ced08a09d3 100644 --- a/tests/models/deepseek_vl/test_modeling_deepseek_vl.py +++ b/tests/models/deepseek_vl/test_modeling_deepseek_vl.py @@ -187,7 +187,7 @@ def test_inputs_embeds_matches_input_ids(self): out_embeds = model(inputs_embeds=inputs_embeds, **inputs)[0] torch.testing.assert_close(out_embeds, out_ids) - @unittest.skip(reason="Siglip uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip uses a non-standard initialization scheme") # Copied from tests.models.siglip.test_modeling_siglip.SiglipVisionModelTest.test_initialization def test_initialization(self): pass diff --git a/tests/models/deepseek_vl_hybrid/test_modeling_deepseek_vl_hybrid.py b/tests/models/deepseek_vl_hybrid/test_modeling_deepseek_vl_hybrid.py index fbb904da735b..02a934275012 100644 --- a/tests/models/deepseek_vl_hybrid/test_modeling_deepseek_vl_hybrid.py +++ b/tests/models/deepseek_vl_hybrid/test_modeling_deepseek_vl_hybrid.py @@ -218,7 +218,7 @@ def test_inputs_embeds_matches_input_ids(self): out_embeds = model(inputs_embeds=inputs_embeds, **inputs)[0] torch.testing.assert_close(out_embeds, out_ids) - @unittest.skip(reason="Siglip uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip uses a non-standard initialization scheme") # Copied from tests.models.siglip.test_modeling_siglip.SiglipVisionModelTest.test_initialization def test_initialization(self): pass diff --git a/tests/models/fnet/test_modeling_fnet.py b/tests/models/fnet/test_modeling_fnet.py index eca30656dd20..f2bc7b099437 100644 --- a/tests/models/fnet/test_modeling_fnet.py +++ b/tests/models/fnet/test_modeling_fnet.py @@ -439,61 +439,6 @@ def test_model_from_pretrained(self): class FNetModelIntegrationTest(unittest.TestCase): @slow def test_inference_for_masked_lm(self): - """ - For comparison: - 1. Modify the pre-training model `__call__` to skip computing metrics and return masked_lm_output like so: - ``` - ... - sequence_output, pooled_output = EncoderModel( - self.config, random_seed=self.random_seed, name="encoder")( - input_ids, input_mask, type_ids, deterministic=deterministic) - - masked_lm_output = nn.Dense( - self.config.d_emb, - kernel_init=default_kernel_init, - name="predictions_dense")( - sequence_output) - masked_lm_output = nn.gelu(masked_lm_output) - masked_lm_output = nn.LayerNorm( - epsilon=LAYER_NORM_EPSILON, name="predictions_layer_norm")( - masked_lm_output) - masked_lm_logits = layers.OutputProjection( - kernel=self._get_embedding_table(), name="predictions_output")( - masked_lm_output) - - next_sentence_logits = layers.OutputProjection( - n_out=2, kernel_init=default_kernel_init, name="classification")( - pooled_output) - - return masked_lm_logits - ... - ``` - 2. Run the following: - >>> import jax.numpy as jnp - >>> import sentencepiece as spm - >>> from flax.training import checkpoints - >>> from f_net.models import PreTrainingModel - >>> from f_net.configs.pretraining import get_config, ModelArchitecture - - >>> pretrained_params = checkpoints.restore_checkpoint('./f_net/f_net_checkpoint', None) # Location of original checkpoint - >>> pretrained_config = get_config() - >>> pretrained_config.model_arch = ModelArchitecture.F_NET - - >>> vocab_filepath = "./f_net/c4_bpe_sentencepiece.model" # Location of the sentence piece model - >>> tokenizer = spm.SentencePieceProcessor() - >>> tokenizer.Load(vocab_filepath) - >>> with pretrained_config.unlocked(): - >>> pretrained_config.vocab_size = tokenizer.GetPieceSize() - >>> tokens = jnp.array([[0, 1, 2, 3, 4, 5]]) - >>> type_ids = jnp.zeros_like(tokens, dtype="i4") - >>> attention_mask = jnp.ones_like(tokens) # Dummy. This gets deleted inside the model. - - >>> flax_pretraining_model = PreTrainingModel(pretrained_config) - >>> pretrained_model_params = freeze(pretrained_params['target']) - >>> flax_model_outputs = flax_pretraining_model.apply({"params": pretrained_model_params}, tokens, attention_mask, type_ids, None, None, None, None, deterministic=True) - >>> masked_lm_logits[:, :3, :3] - """ - model = FNetForMaskedLM.from_pretrained("google/fnet-base") model.to(torch_device) diff --git a/tests/models/fsmt/test_modeling_fsmt.py b/tests/models/fsmt/test_modeling_fsmt.py index 39a2d5b26a24..df57cc1dba83 100644 --- a/tests/models/fsmt/test_modeling_fsmt.py +++ b/tests/models/fsmt/test_modeling_fsmt.py @@ -545,7 +545,7 @@ def test_translation_direct(self, pair): @slow def test_translation_pipeline(self, pair): tokenizer, model, src_text, tgt_text = self.translation_setup(pair) - pipeline = TranslationPipeline(model, tokenizer, framework="pt", device=torch_device) + pipeline = TranslationPipeline(model, tokenizer, device=torch_device) output = pipeline([src_text]) self.assertEqual([tgt_text], [x["translation_text"] for x in output]) diff --git a/tests/models/gemma3n/test_modeling_gemma3n.py b/tests/models/gemma3n/test_modeling_gemma3n.py index 5e4b774a8bd0..eca8cfdc56ee 100644 --- a/tests/models/gemma3n/test_modeling_gemma3n.py +++ b/tests/models/gemma3n/test_modeling_gemma3n.py @@ -714,9 +714,7 @@ def test_training_gradient_checkpointing_use_reentrant(self): def test_training_gradient_checkpointing_use_reentrant_false(self): pass - @unittest.skip( - reason="Siglip (vision backbone) uses the same initialization scheme as the Flax original implementation" - ) + @unittest.skip(reason="Siglip (vision backbone) uses a non-standard initialization scheme") def test_initialization(self): pass diff --git a/tests/models/layoutlmv2/test_tokenization_layoutlmv2.py b/tests/models/layoutlmv2/test_tokenization_layoutlmv2.py index a96f3b5b6aad..b3e7adc68257 100644 --- a/tests/models/layoutlmv2/test_tokenization_layoutlmv2.py +++ b/tests/models/layoutlmv2/test_tokenization_layoutlmv2.py @@ -25,9 +25,7 @@ AddedToken, LayoutLMv2TokenizerFast, SpecialTokensMixin, - is_flax_available, is_mlx_available, - is_tf_available, is_torch_available, logging, ) @@ -1720,12 +1718,7 @@ def test_batch_encode_dynamic_overflowing(self): tokenizer = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name}, {tokenizer.__class__.__name__})"): - if is_torch_available(): - returned_tensor = "pt" - elif is_tf_available(): - returned_tensor = "tf" - else: - returned_tensor = "jax" + returned_tensor = "pt" # Single example words, boxes = self.get_words_and_boxes() @@ -2405,7 +2398,7 @@ def test_layoutlmv2_integration_test(self): self.assertDictEqual(dict(encoding_p), expected_results) self.assertDictEqual(dict(encoding_r), expected_results) - @unittest.skip(reason="Doesn't support another framework than PyTorch") + @unittest.skip(reason="Doesn't support returning Numpy arrays") def test_np_encode_plus_sent_to_model(self): pass @@ -2434,18 +2427,6 @@ def test_empty_input_string(self): tokenizer_return_type.append("np") output_tensor_type.append(np.int64) - if is_tf_available(): - import tensorflow as tf - - tokenizer_return_type.append("tf") - output_tensor_type.append(tf.int32) - - if is_flax_available(): - import jax.numpy as jnp - - tokenizer_return_type.append("jax") - output_tensor_type.append(jnp.int32) - if is_mlx_available(): import mlx.core as mx @@ -2453,7 +2434,7 @@ def test_empty_input_string(self): output_tensor_type.append(mx.int32) if len(tokenizer_return_type) == 0: - self.skipTest(reason="No expected framework from PT, TF, JAX or MLX found") + self.skipTest(reason="No expected framework from PT or MLX found") tokenizers = self.get_tokenizers() for tokenizer in tokenizers: diff --git a/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py b/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py index c487e662bf9a..729a7f4034f7 100644 --- a/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py +++ b/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py @@ -26,9 +26,7 @@ AddedToken, LayoutLMv3TokenizerFast, SpecialTokensMixin, - is_flax_available, is_mlx_available, - is_tf_available, is_torch_available, logging, ) @@ -1605,12 +1603,7 @@ def test_batch_encode_dynamic_overflowing(self): tokenizer = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name}, {tokenizer.__class__.__name__})"): - if is_torch_available(): - returned_tensor = "pt" - elif is_tf_available(): - returned_tensor = "tf" - else: - returned_tensor = "jax" + returned_tensor = "pt" # Single example words = ["HuggingFace", "is", "solving", "NLP", "one", "commit", "at", "a", "time"] @@ -2329,7 +2322,7 @@ def test_layoutlmv3_integration_test(self): self.assertDictEqual(dict(encoding_p), expected_results) self.assertDictEqual(dict(encoding_r), expected_results) - @unittest.skip(reason="Doesn't support another framework than PyTorch") + @unittest.skip(reason="Doesn't support returning Numpy arrays") def test_np_encode_plus_sent_to_model(self): pass @@ -2358,18 +2351,6 @@ def test_empty_input_string(self): tokenizer_return_type.append("np") output_tensor_type.append(np.int64) - if is_tf_available(): - import tensorflow as tf - - tokenizer_return_type.append("tf") - output_tensor_type.append(tf.int32) - - if is_flax_available(): - import jax.numpy as jnp - - tokenizer_return_type.append("jax") - output_tensor_type.append(jnp.int32) - if is_mlx_available(): import mlx.core as mx @@ -2377,7 +2358,7 @@ def test_empty_input_string(self): output_tensor_type.append(mx.int32) if len(tokenizer_return_type) == 0: - self.skipTest(reason="No expected framework from PT, TF, JAX or MLX found") + self.skipTest(reason="No expected framework from PT, or MLX found") tokenizers = self.get_tokenizers() for tokenizer in tokenizers: diff --git a/tests/models/layoutxlm/test_tokenization_layoutxlm.py b/tests/models/layoutxlm/test_tokenization_layoutxlm.py index 21bd0a469dd4..da77177a3f62 100644 --- a/tests/models/layoutxlm/test_tokenization_layoutxlm.py +++ b/tests/models/layoutxlm/test_tokenization_layoutxlm.py @@ -23,9 +23,7 @@ AddedToken, LayoutXLMTokenizerFast, SpecialTokensMixin, - is_flax_available, is_mlx_available, - is_tf_available, is_torch_available, logging, ) @@ -1649,12 +1647,7 @@ def test_batch_encode_dynamic_overflowing(self): tokenizer = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name}, {tokenizer.__class__.__name__})"): - if is_torch_available(): - returned_tensor = "pt" - elif is_tf_available(): - returned_tensor = "tf" - else: - returned_tensor = "jax" + returned_tensor = "pt" # Single example words, boxes = self.get_words_and_boxes() @@ -1891,7 +1884,7 @@ def test_layoutxlm_integration_test(self): self.assertDictEqual(dict(encoding_p), expected_results) self.assertDictEqual(dict(encoding_r), expected_results) - @unittest.skip(reason="Doesn't support another framework than PyTorch") + @unittest.skip(reason="Doesn't support returning Numpy arrays") def test_np_encode_plus_sent_to_model(self): pass @@ -1928,18 +1921,6 @@ def test_empty_input_string(self): tokenizer_return_type.append("np") output_tensor_type.append(np.int64) - if is_tf_available(): - import tensorflow as tf - - tokenizer_return_type.append("tf") - output_tensor_type.append(tf.int32) - - if is_flax_available(): - import jax.numpy as jnp - - tokenizer_return_type.append("jax") - output_tensor_type.append(jnp.int32) - if is_mlx_available(): import mlx.core as mx @@ -1947,7 +1928,7 @@ def test_empty_input_string(self): output_tensor_type.append(mx.int32) if len(tokenizer_return_type) == 0: - self.skipTest(reason="No expected framework from PT, TF, JAX or MLX found") + self.skipTest(reason="No expected framework from PT or MLX found") tokenizers = self.get_tokenizers() for tokenizer in tokenizers: diff --git a/tests/models/lxmert/test_modeling_lxmert.py b/tests/models/lxmert/test_modeling_lxmert.py index 754e06a3c729..033fcc0605d6 100644 --- a/tests/models/lxmert/test_modeling_lxmert.py +++ b/tests/models/lxmert/test_modeling_lxmert.py @@ -18,7 +18,7 @@ import numpy as np -from transformers import LxmertConfig, is_tf_available, is_torch_available +from transformers import LxmertConfig, is_torch_available from transformers.models.auto import get_values from transformers.testing_utils import require_torch, slow, torch_device @@ -39,10 +39,6 @@ ) -if is_tf_available(): - import tensorflow as tf - - class LxmertModelTester: def __init__( self, @@ -58,7 +54,6 @@ def __init__( max_position_embeddings=512, type_vocab_size=2, initializer_range=0.02, - layer_norm_eps=1e-12, pad_token_id=0, num_qa_labels=30, num_object_labels=16, @@ -98,7 +93,6 @@ def __init__( self.max_position_embeddings = max_position_embeddings self.type_vocab_size = type_vocab_size self.initializer_range = initializer_range - self.layer_norm_eps = layer_norm_eps self.pad_token_id = pad_token_id self.num_qa_labels = num_qa_labels self.num_object_labels = num_object_labels @@ -198,7 +192,6 @@ def get_config(self): max_position_embeddings=self.max_position_embeddings, type_vocab_size=self.type_vocab_size, initializer_range=self.initializer_range, - layer_norm_eps=self.layer_norm_eps, pad_token_id=self.pad_token_id, num_qa_labels=self.num_qa_labels, num_object_labels=self.num_object_labels, @@ -741,30 +734,6 @@ def test_retain_grad_hidden_states_attentions(self): self.assertIsNotNone(hidden_states_vision.grad) self.assertIsNotNone(attentions_vision.grad) - def prepare_tf_inputs_from_pt_inputs(self, pt_inputs_dict): - tf_inputs_dict = {} - for key, value in pt_inputs_dict.items(): - # skip key that does not exist in tf - if isinstance(value, dict): - tf_inputs_dict[key] = self.prepare_pt_inputs_from_tf_inputs(value) - elif isinstance(value, (list, tuple)): - tf_inputs_dict[key] = (self.prepare_pt_inputs_from_tf_inputs(iter_value) for iter_value in value) - elif isinstance(value, bool): - tf_inputs_dict[key] = value - elif key == "input_values": - tf_inputs_dict[key] = tf.convert_to_tensor(value.cpu().numpy(), dtype=tf.float32) - elif key == "pixel_values": - tf_inputs_dict[key] = tf.convert_to_tensor(value.cpu().numpy(), dtype=tf.float32) - elif key == "input_features": - tf_inputs_dict[key] = tf.convert_to_tensor(value.cpu().numpy(), dtype=tf.float32) - # other general float inputs - elif value.is_floating_point(): - tf_inputs_dict[key] = tf.convert_to_tensor(value.cpu().numpy(), dtype=tf.float32) - else: - tf_inputs_dict[key] = tf.convert_to_tensor(value.cpu().numpy(), dtype=tf.int32) - - return tf_inputs_dict - @unittest.skip( reason="This architecture has tied weights by default and there is no way to remove it, check: https://github.com/huggingface/transformers/pull/31771#issuecomment-2210915245" ) diff --git a/tests/models/marian/test_modeling_marian.py b/tests/models/marian/test_modeling_marian.py index 8f938cb7b0f7..3387e785ccbe 100644 --- a/tests/models/marian/test_modeling_marian.py +++ b/tests/models/marian/test_modeling_marian.py @@ -597,7 +597,7 @@ def test_batch_generation_en_ROMANCE_multi(self): @slow @require_torch def test_pipeline(self): - pipeline = TranslationPipeline(self.model, self.tokenizer, framework="pt", device=torch_device) + pipeline = TranslationPipeline(self.model, self.tokenizer, device=torch_device) output = pipeline(self.src_text) self.assertEqual(self.expected_text, [x["translation_text"] for x in output]) diff --git a/tests/models/marian/test_tokenization_marian.py b/tests/models/marian/test_tokenization_marian.py index ebe26c5babb7..fbcd94c29f85 100644 --- a/tests/models/marian/test_tokenization_marian.py +++ b/tests/models/marian/test_tokenization_marian.py @@ -19,7 +19,7 @@ from transformers import BatchEncoding, MarianTokenizer from transformers.testing_utils import get_tests_dir, require_sentencepiece, slow -from transformers.utils import is_sentencepiece_available, is_tf_available, is_torch_available +from transformers.utils import is_sentencepiece_available if is_sentencepiece_available(): @@ -34,13 +34,6 @@ zh_code = ">>zh<<" ORG_NAME = "Helsinki-NLP/" -if is_torch_available(): - FRAMEWORK = "pt" -elif is_tf_available(): - FRAMEWORK = "tf" -else: - FRAMEWORK = "jax" - @require_sentencepiece class MarianTokenizationTest(TokenizerTesterMixin, unittest.TestCase): @@ -112,14 +105,14 @@ def test_outputs_not_longer_than_maxlen(self): tok = self.get_tokenizer() batch = tok( - ["I am a small frog" * 1000, "I am a small frog"], padding=True, truncation=True, return_tensors=FRAMEWORK + ["I am a small frog" * 1000, "I am a small frog"], padding=True, truncation=True, return_tensors="pt" ) self.assertIsInstance(batch, BatchEncoding) self.assertEqual(batch.input_ids.shape, (2, 512)) def test_outputs_can_be_shorter(self): tok = self.get_tokenizer() - batch_smaller = tok(["I am a tiny frog", "I am a small frog"], padding=True, return_tensors=FRAMEWORK) + batch_smaller = tok(["I am a tiny frog", "I am a small frog"], padding=True, return_tensors="pt") self.assertIsInstance(batch_smaller, BatchEncoding) self.assertEqual(batch_smaller.input_ids.shape, (2, 10)) diff --git a/tests/models/markuplm/test_tokenization_markuplm.py b/tests/models/markuplm/test_tokenization_markuplm.py index ee08dbf51b01..8232269c53d4 100644 --- a/tests/models/markuplm/test_tokenization_markuplm.py +++ b/tests/models/markuplm/test_tokenization_markuplm.py @@ -26,9 +26,7 @@ AddedToken, MarkupLMTokenizerFast, SpecialTokensMixin, - is_flax_available, is_mlx_available, - is_tf_available, is_torch_available, logging, ) @@ -1505,12 +1503,7 @@ def test_batch_encode_dynamic_overflowing(self): tokenizer = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name}, {tokenizer.__class__.__name__})"): - if is_torch_available(): - returned_tensor = "pt" - elif is_tf_available(): - returned_tensor = "tf" - else: - returned_tensor = "jax" + returned_tensor = "pt" # Single example nodes, xpaths = self.get_nodes_and_xpaths() @@ -2202,7 +2195,7 @@ def test_markuplm_integration_test(self): self.assertDictEqual(dict(encoding_p), expected_results) self.assertDictEqual(dict(encoding_r), expected_results) - @unittest.skip(reason="Doesn't support another framework than PyTorch") + @unittest.skip(reason="Doesn't support returning Numpy arrays") def test_np_encode_plus_sent_to_model(self): pass @@ -2276,18 +2269,6 @@ def test_empty_input_string(self): tokenizer_return_type.append("np") output_tensor_type.append(np.int64) - if is_tf_available(): - import tensorflow as tf - - tokenizer_return_type.append("tf") - output_tensor_type.append(tf.int32) - - if is_flax_available(): - import jax.numpy as jnp - - tokenizer_return_type.append("jax") - output_tensor_type.append(jnp.int32) - if is_mlx_available(): import mlx.core as mx @@ -2295,7 +2276,7 @@ def test_empty_input_string(self): output_tensor_type.append(mx.int32) if len(tokenizer_return_type) == 0: - self.skipTest(reason="No expected framework from PT, TF, JAX or MLX found") + self.skipTest(reason="No expected framework from PT, or MLX found") tokenizers = self.get_tokenizers() for tokenizer in tokenizers: diff --git a/tests/models/metaclip_2/test_modeling_metaclip_2.py b/tests/models/metaclip_2/test_modeling_metaclip_2.py index f8ad7701eab3..19823ba4ac73 100644 --- a/tests/models/metaclip_2/test_modeling_metaclip_2.py +++ b/tests/models/metaclip_2/test_modeling_metaclip_2.py @@ -765,7 +765,7 @@ def test_training_gradient_checkpointing_use_reentrant(self): def test_training_gradient_checkpointing_use_reentrant_false(self): pass - @unittest.skip(reason="MetaClip2 uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="MetaClip2 uses a non-standard initialization scheme") def test_initialization(self): pass diff --git a/tests/models/myt5/test_tokenization_myt5.py b/tests/models/myt5/test_tokenization_myt5.py index f36b6c7ec56c..5f57aa051b71 100644 --- a/tests/models/myt5/test_tokenization_myt5.py +++ b/tests/models/myt5/test_tokenization_myt5.py @@ -16,19 +16,10 @@ from transformers import MyT5Tokenizer from transformers.testing_utils import slow -from transformers.utils import is_tf_available, is_torch_available from ...test_tokenization_common import TokenizerTesterMixin -if is_torch_available(): - FRAMEWORK = "pt" -elif is_tf_available(): - FRAMEWORK = "tf" -else: - FRAMEWORK = "jax" - - def bytes_to_hex(bline: bytes, sep: str = " ") -> str: return str(binascii.hexlify(bline, sep), "utf-8") diff --git a/tests/models/paligemma/test_modeling_paligemma.py b/tests/models/paligemma/test_modeling_paligemma.py index d130122b16ff..21b9b8a4711e 100644 --- a/tests/models/paligemma/test_modeling_paligemma.py +++ b/tests/models/paligemma/test_modeling_paligemma.py @@ -264,9 +264,7 @@ def test_disk_offload_safetensors(self): def test_model_parallelism(self): pass - @unittest.skip( - reason="PaliGemma's SigLip encoder uses the same initialization scheme as the Flax original implementation" - ) + @unittest.skip(reason="PaliGemma's SigLip encoder uses a non-standard initialization scheme") def test_initialization(self): pass diff --git a/tests/models/paligemma2/test_modeling_paligemma2.py b/tests/models/paligemma2/test_modeling_paligemma2.py index ad345e70e03e..a33f03194f8a 100644 --- a/tests/models/paligemma2/test_modeling_paligemma2.py +++ b/tests/models/paligemma2/test_modeling_paligemma2.py @@ -247,9 +247,7 @@ def test_disk_offload_safetensors(self): def test_model_parallelism(self): pass - @unittest.skip( - reason="PaliGemma's SigLip encoder uses the same initialization scheme as the Flax original implementation" - ) + @unittest.skip(reason="PaliGemma's SigLip encoder uses a non-standard initialization scheme") def test_initialization(self): pass diff --git a/tests/models/pegasus/test_tokenization_pegasus.py b/tests/models/pegasus/test_tokenization_pegasus.py index bd8d07cdabae..ce65a1065c9f 100644 --- a/tests/models/pegasus/test_tokenization_pegasus.py +++ b/tests/models/pegasus/test_tokenization_pegasus.py @@ -187,25 +187,6 @@ def test_large_seq2seq_truncation(self): assert len(batch) == 2 # input_ids, attention_mask. def test_equivalence_to_orig_tokenizer(self): - """ - To run with original TF tokenizer: - - !wget https://github.com/google-research/bigbird/raw/master/bigbird/vocab/pegasus.model - !pip install tensorflow-text - - import tensorflow.compat.v2 as tf - import tensorflow_text as tft - - VOCAB_FILE = "./pegasus.model" - - tf.enable_v2_behavior() - - test_str = "This is an example string that is used to test the original TF implementation against the HF implementation" - tokenizer = tft.SentencepieceTokenizer(model=tf.io.gfile.GFile(VOCAB_FILE, "rb").read()) - - tokenizer.tokenize(test_str) - """ - test_str = ( "This is an example string that is used to test the original TF implementation against the HF" " implementation" diff --git a/tests/models/perceiver/test_tokenization_perceiver.py b/tests/models/perceiver/test_tokenization_perceiver.py index 87d9f3d0075c..7dc0ae6e9867 100644 --- a/tests/models/perceiver/test_tokenization_perceiver.py +++ b/tests/models/perceiver/test_tokenization_perceiver.py @@ -21,19 +21,10 @@ from functools import cached_property from transformers import AddedToken, BatchEncoding, PerceiverTokenizer -from transformers.utils import is_tf_available, is_torch_available from ...test_tokenization_common import TokenizerTesterMixin -if is_torch_available(): - FRAMEWORK = "pt" -elif is_tf_available(): - FRAMEWORK = "tf" -else: - FRAMEWORK = "jax" - - class PerceiverTokenizationTest(TokenizerTesterMixin, unittest.TestCase): from_pretrained_id = "deepmind/language-perceiver" tokenizer_class = PerceiverTokenizer @@ -117,13 +108,10 @@ def test_prepare_batch_integration(self): tokenizer = self.perceiver_tokenizer src_text = ["A long paragraph for summarization.", "Another paragraph for summarization."] expected_src_tokens = [4, 71, 38, 114, 117, 116, 109, 38, 118, 103, 120, 103, 109, 120, 103, 118, 110, 38, 108, 117, 120, 38, 121, 123, 115, 115, 103, 120, 111, 128, 103, 122, 111, 117, 116, 52, 5, 0] # fmt: skip - batch = tokenizer(src_text, padding=True, return_tensors=FRAMEWORK) + batch = tokenizer(src_text, padding=True, return_tensors="pt") self.assertIsInstance(batch, BatchEncoding) - if FRAMEWORK != "jax": - result = list(batch.input_ids.numpy()[0]) - else: - result = list(batch.input_ids.tolist()[0]) + result = list(batch.input_ids.numpy()[0]) self.assertListEqual(expected_src_tokens, result) @@ -133,7 +121,7 @@ def test_prepare_batch_integration(self): def test_empty_target_text(self): tokenizer = self.perceiver_tokenizer src_text = ["A long paragraph for summarization.", "Another paragraph for summarization."] - batch = tokenizer(src_text, padding=True, return_tensors=FRAMEWORK) + batch = tokenizer(src_text, padding=True, return_tensors="pt") # check if input_ids are returned and no decoder_input_ids self.assertIn("input_ids", batch) self.assertIn("attention_mask", batch) @@ -147,7 +135,7 @@ def test_max_length_integration(self): "Another summary.", ] targets = tokenizer( - text_target=tgt_text, max_length=32, padding="max_length", truncation=True, return_tensors=FRAMEWORK + text_target=tgt_text, max_length=32, padding="max_length", truncation=True, return_tensors="pt" ) self.assertEqual(32, targets["input_ids"].shape[1]) diff --git a/tests/models/rembert/test_modeling_rembert.py b/tests/models/rembert/test_modeling_rembert.py index e7804c59799b..93a16866601b 100644 --- a/tests/models/rembert/test_modeling_rembert.py +++ b/tests/models/rembert/test_modeling_rembert.py @@ -477,17 +477,6 @@ def test_inference_model(self): ] ) - # Running on the original tf implementation gives slightly different results here. - # Not clear why this variations is present - # TODO: Find reason for discrepancy - # expected_original_implementation = [[ - # [0.07630594074726105, -0.20146065950393677, 0.19107051193714142], - # [-0.3405614495277405, -0.36971670389175415, -0.4808273911476135], - # [-0.22587086260318756, -0.6656315922737122, -0.07844287157058716], - # [-0.04145475849509239, -0.3077218234539032, -0.42316967248916626], - # [-0.15887849032878876, -0.054529931396245956, 0.5356100797653198] - # ]] - torch.testing.assert_close( output["last_hidden_state"][:, :, :3], expected_implementation, rtol=1e-4, atol=1e-4 ) diff --git a/tests/models/sam2/test_processor_sam2.py b/tests/models/sam2/test_processor_sam2.py index d0b099c77698..1c388e210836 100644 --- a/tests/models/sam2/test_processor_sam2.py +++ b/tests/models/sam2/test_processor_sam2.py @@ -22,7 +22,7 @@ require_torchvision, require_vision, ) -from transformers.utils import is_tf_available, is_torch_available, is_vision_available +from transformers.utils import is_torch_available, is_vision_available if is_vision_available(): @@ -31,9 +31,6 @@ if is_torch_available(): import torch -if is_tf_available(): - pass - @require_vision @require_torchvision diff --git a/tests/models/sam2_video/test_processor_sam2_video.py b/tests/models/sam2_video/test_processor_sam2_video.py index 0e359e716b9d..6e071158be11 100644 --- a/tests/models/sam2_video/test_processor_sam2_video.py +++ b/tests/models/sam2_video/test_processor_sam2_video.py @@ -22,7 +22,7 @@ require_torchvision, require_vision, ) -from transformers.utils import is_tf_available, is_torch_available, is_vision_available +from transformers.utils import is_torch_available, is_vision_available if is_vision_available(): @@ -31,9 +31,6 @@ if is_torch_available(): import torch -if is_tf_available(): - pass - @require_vision @require_torchvision diff --git a/tests/models/siglip/test_modeling_siglip.py b/tests/models/siglip/test_modeling_siglip.py index a4c829493b17..0005c44e634a 100644 --- a/tests/models/siglip/test_modeling_siglip.py +++ b/tests/models/siglip/test_modeling_siglip.py @@ -240,7 +240,7 @@ def test_training_gradient_checkpointing_use_reentrant(self): def test_training_gradient_checkpointing_use_reentrant_false(self): pass - @unittest.skip(reason="Siglip uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip uses a non-standard initialization scheme") def test_initialization(self): pass @@ -386,7 +386,7 @@ def test_training_gradient_checkpointing_use_reentrant_false(self): def test_inputs_embeds(self): pass - @unittest.skip(reason="Siglip uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip uses a non-standard initialization scheme") def test_initialization(self): pass @@ -498,7 +498,7 @@ def test_retain_grad_hidden_states_attentions(self): def test_model_get_set_embeddings(self): pass - @unittest.skip(reason="Siglip uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip uses a non-standard initialization scheme") def test_initialization(self): pass @@ -658,7 +658,7 @@ def test_training_gradient_checkpointing_use_reentrant(self): def test_training_gradient_checkpointing_use_reentrant_false(self): pass - @unittest.skip(reason="Siglip uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip uses a non-standard initialization scheme") def test_initialization(self): pass diff --git a/tests/models/siglip/test_tokenization_siglip.py b/tests/models/siglip/test_tokenization_siglip.py index 68e7f1fbf4b1..843058c8a019 100644 --- a/tests/models/siglip/test_tokenization_siglip.py +++ b/tests/models/siglip/test_tokenization_siglip.py @@ -20,20 +20,12 @@ from transformers import SPIECE_UNDERLINE, AddedToken, BatchEncoding, SiglipTokenizer from transformers.testing_utils import get_tests_dir, require_sentencepiece, require_tokenizers, slow -from transformers.utils import is_tf_available, is_torch_available from ...test_tokenization_common import TokenizerTesterMixin SAMPLE_VOCAB = get_tests_dir("fixtures/test_sentencepiece.model") -if is_torch_available(): - FRAMEWORK = "pt" -elif is_tf_available(): - FRAMEWORK = "tf" -else: - FRAMEWORK = "jax" - @require_sentencepiece @require_tokenizers @@ -173,13 +165,10 @@ def test_prepare_batch(self): tokenizer = self.siglip_tokenizer src_text = ["A long paragraph for summarization.", "Another paragraph for summarization."] expected_src_tokens = [262, 266, 476, 8532, 270, 4460, 3949, 1682, tokenizer.eos_token_id] - batch = tokenizer(src_text, padding=True, return_tensors=FRAMEWORK) + batch = tokenizer(src_text, padding=True, return_tensors="pt") self.assertIsInstance(batch, BatchEncoding) - if FRAMEWORK != "jax": - result = list(batch.input_ids.numpy()[0]) - else: - result = list(batch.input_ids.tolist()[0]) + result = list(batch.input_ids.numpy()[0]) self.assertListEqual(expected_src_tokens, result) @@ -188,7 +177,7 @@ def test_prepare_batch(self): def test_empty_target_text(self): tokenizer = self.siglip_tokenizer src_text = ["A long paragraph for summarization.", "Another paragraph for summarization."] - batch = tokenizer(src_text, padding=True, return_tensors=FRAMEWORK) + batch = tokenizer(src_text, padding=True, return_tensors="pt") # check if input_ids are returned and no decoder_input_ids self.assertIn("input_ids", batch) self.assertNotIn("decoder_input_ids", batch) @@ -198,7 +187,7 @@ def test_max_length(self): tokenizer = self.siglip_tokenizer tgt_text = ["Summary of the text.", "Another summary."] targets = tokenizer( - text_target=tgt_text, max_length=32, padding="max_length", truncation=True, return_tensors=FRAMEWORK + text_target=tgt_text, max_length=32, padding="max_length", truncation=True, return_tensors="pt" ) self.assertEqual(32, targets["input_ids"].shape[1]) diff --git a/tests/models/siglip2/test_modeling_siglip2.py b/tests/models/siglip2/test_modeling_siglip2.py index e7147e6055aa..d6054dd8d15d 100644 --- a/tests/models/siglip2/test_modeling_siglip2.py +++ b/tests/models/siglip2/test_modeling_siglip2.py @@ -332,7 +332,7 @@ def test_training_gradient_checkpointing_use_reentrant(self): def test_training_gradient_checkpointing_use_reentrant_false(self): pass - @unittest.skip(reason="Siglip2 uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip2 uses a non-standard initialization scheme") def test_initialization(self): pass @@ -474,7 +474,7 @@ def test_training_gradient_checkpointing_use_reentrant_false(self): def test_inputs_embeds(self): pass - @unittest.skip(reason="Siglip2 uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip2 uses a non-standard initialization scheme") def test_initialization(self): pass @@ -591,7 +591,7 @@ def test_retain_grad_hidden_states_attentions(self): def test_model_get_set_embeddings(self): pass - @unittest.skip(reason="Siglip2 uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip2 uses a non-standard initialization scheme") def test_initialization(self): pass @@ -689,7 +689,7 @@ def test_training_gradient_checkpointing_use_reentrant(self): def test_training_gradient_checkpointing_use_reentrant_false(self): pass - @unittest.skip(reason="Siglip2 uses the same initialization scheme as the Flax original implementation") + @unittest.skip(reason="Siglip2 uses a non-standard initialization scheme") def test_initialization(self): pass diff --git a/tests/models/splinter/test_tokenization_splinter.py b/tests/models/splinter/test_tokenization_splinter.py index 8fdf5b75b00e..c87d3590d7d2 100644 --- a/tests/models/splinter/test_tokenization_splinter.py +++ b/tests/models/splinter/test_tokenization_splinter.py @@ -14,7 +14,7 @@ import unittest from tests.test_tokenization_common import TokenizerTesterMixin -from transformers import SplinterTokenizerFast, is_tf_available, is_torch_available +from transformers import SplinterTokenizerFast from transformers.models.splinter import SplinterTokenizer from transformers.testing_utils import get_tests_dir, slow @@ -22,14 +22,6 @@ SAMPLE_VOCAB = get_tests_dir("fixtures/vocab.txt") -if is_torch_available(): - FRAMEWORK = "pt" -elif is_tf_available(): - FRAMEWORK = "tf" -else: - FRAMEWORK = "jax" - - class SplinterTokenizationTest(TokenizerTesterMixin, unittest.TestCase): tokenizer_class = SplinterTokenizer rust_tokenizer_class = SplinterTokenizerFast @@ -128,7 +120,7 @@ def test_max_length(self): max_length=max_length, padding="max_length", truncation=True, - return_tensors=FRAMEWORK, + return_tensors="pt", ) self.assertEqual(len(tokenized["input_ids"]), len(texts)) self.assertEqual(len(tokenized["input_ids"][0]), max_length) diff --git a/tests/models/t5/test_tokenization_t5.py b/tests/models/t5/test_tokenization_t5.py index cfc689eaf1c0..cbbe6e2c916e 100644 --- a/tests/models/t5/test_tokenization_t5.py +++ b/tests/models/t5/test_tokenization_t5.py @@ -20,20 +20,12 @@ from transformers import SPIECE_UNDERLINE, AddedToken, BatchEncoding, T5Tokenizer, T5TokenizerFast from transformers.testing_utils import get_tests_dir, require_sentencepiece, require_seqio, require_tokenizers, slow -from transformers.utils import is_tf_available, is_torch_available from ...test_tokenization_common import TokenizerTesterMixin SAMPLE_VOCAB = get_tests_dir("fixtures/test_sentencepiece.model") -if is_torch_available(): - FRAMEWORK = "pt" -elif is_tf_available(): - FRAMEWORK = "tf" -else: - FRAMEWORK = "jax" - @require_sentencepiece @require_tokenizers @@ -188,13 +180,10 @@ def test_prepare_batch(self): tokenizer = self.t5_base_tokenizer src_text = ["A long paragraph for summarization.", "Another paragraph for summarization."] expected_src_tokens = [71, 307, 8986, 21, 4505, 1635, 1707, 5, tokenizer.eos_token_id] - batch = tokenizer(src_text, padding=True, return_tensors=FRAMEWORK) + batch = tokenizer(src_text, padding=True, return_tensors="pt") self.assertIsInstance(batch, BatchEncoding) - if FRAMEWORK != "jax": - result = list(batch.input_ids.numpy()[0]) - else: - result = list(batch.input_ids.tolist()[0]) + result = list(batch.input_ids.numpy()[0]) self.assertListEqual(expected_src_tokens, result) @@ -204,7 +193,7 @@ def test_prepare_batch(self): def test_empty_target_text(self): tokenizer = self.t5_base_tokenizer src_text = ["A long paragraph for summarization.", "Another paragraph for summarization."] - batch = tokenizer(src_text, padding=True, return_tensors=FRAMEWORK) + batch = tokenizer(src_text, padding=True, return_tensors="pt") # check if input_ids are returned and no decoder_input_ids self.assertIn("input_ids", batch) self.assertIn("attention_mask", batch) @@ -218,7 +207,7 @@ def test_max_length(self): "Another summary.", ] targets = tokenizer( - text_target=tgt_text, max_length=32, padding="max_length", truncation=True, return_tensors=FRAMEWORK + text_target=tgt_text, max_length=32, padding="max_length", truncation=True, return_tensors="pt" ) self.assertEqual(32, targets["input_ids"].shape[1]) @@ -226,7 +215,7 @@ def test_outputs_not_longer_than_maxlen(self): tokenizer = self.t5_base_tokenizer batch = tokenizer( - ["I am a small frog" * 1000, "I am a small frog"], padding=True, truncation=True, return_tensors=FRAMEWORK + ["I am a small frog" * 1000, "I am a small frog"], padding=True, truncation=True, return_tensors="pt" ) self.assertIsInstance(batch, BatchEncoding) # Since T5 does NOT have a max input length, diff --git a/tests/models/tapas/test_modeling_tapas.py b/tests/models/tapas/test_modeling_tapas.py index c96c7691687c..65e5e4d2758a 100644 --- a/tests/models/tapas/test_modeling_tapas.py +++ b/tests/models/tapas/test_modeling_tapas.py @@ -576,9 +576,6 @@ def default_tokenizer(self): @slow def test_inference_no_head(self): - # ideally we want to test this with the weights of tapas_inter_masklm_base_reset, - # but since it's not straightforward to do this with the TF 1 implementation, we test it with - # the weights of the WTQ base model (i.e. tapas_wtq_wikisql_sqa_inter_masklm_base_reset) model = TapasModel.from_pretrained("google/tapas-base-finetuned-wtq").to(torch_device) tokenizer = self.default_tokenizer @@ -767,7 +764,6 @@ def test_training_question_answering_head_weak_supervision(self): # note that google/tapas-base-finetuned-wtq should correspond to tapas_wtq_wikisql_sqa_inter_masklm_base_reset model = TapasForQuestionAnswering.from_pretrained("google/tapas-base-finetuned-wtq").to(torch_device) model.to(torch_device) - # normally we should put the model in training mode but it's a pain to do this with the TF 1 implementation tokenizer = self.default_tokenizer # let's test on a batch @@ -972,11 +968,9 @@ def test_product_index(self): self.assertEqual(cell_index.num_segments, 9) # Projections should give back the original indices. - # we use np.testing.assert_array_equal rather than Tensorflow's assertAllEqual np.testing.assert_array_equal(row_index.indices.numpy(), row_index_proj.indices.numpy()) self.assertEqual(row_index.num_segments, row_index_proj.num_segments) self.assertEqual(row_index.batch_dims, row_index_proj.batch_dims) - # We use np.testing.assert_array_equal rather than Tensorflow's assertAllEqual np.testing.assert_array_equal(col_index.indices.numpy(), col_index_proj.indices.numpy()) self.assertEqual(col_index.batch_dims, col_index_proj.batch_dims) @@ -1006,7 +1000,6 @@ def test_flatten(self): batched_index = IndexMap(indices=torch.zeros(shape).type(torch.LongTensor), num_segments=1, batch_dims=3) batched_index_flat = flatten(batched_index) - # We use np.testing.assert_array_equal rather than Tensorflow's assertAllEqual np.testing.assert_array_equal( row_index_flat.indices.numpy(), [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5] ) @@ -1024,11 +1017,9 @@ def test_range_index_map(self): self.assertEqual(num_segments, index.num_segments) self.assertEqual(2, index.batch_dims) indices = index.indices - # We use np.testing.assert_array_equal rather than Tensorflow's assertAllEqual np.testing.assert_array_equal(list(indices.size()), [3, 4, 5]) for i in range(batch_shape[0]): for j in range(batch_shape[1]): - # We use np.testing.assert_array_equal rather than Tensorflow's assertAllEqual np.testing.assert_array_equal(indices[i, j, :].numpy(), range(num_segments)) def test_reduce_sum(self): @@ -1038,7 +1029,6 @@ def test_reduce_sum(self): col_sum, _ = reduce_sum(values, col_index) cell_sum, _ = reduce_sum(values, cell_index) - # We use np.testing.assert_allclose rather than Tensorflow's assertAllClose np.testing.assert_allclose(row_sum.numpy(), [[6.0, 3.0, 8.0], [6.0, 3.0, 8.0]]) np.testing.assert_allclose(col_sum.numpy(), [[9.0, 8.0, 0.0], [4.0, 5.0, 8.0]]) np.testing.assert_allclose( @@ -1053,7 +1043,6 @@ def test_reduce_mean(self): col_mean, _ = reduce_mean(values, col_index) cell_mean, _ = reduce_mean(values, cell_index) - # We use np.testing.assert_allclose rather than Tensorflow's assertAllClose np.testing.assert_allclose( row_mean.numpy(), [[6.0 / 3.0, 3.0 / 3.0, 8.0 / 3.0], [6.0 / 3.0, 3.0 / 3.0, 8.0 / 3.0]] ) @@ -1071,7 +1060,6 @@ def test_reduce_max(self): index = IndexMap(indices=torch.as_tensor([0, 1, 0, 1]), num_segments=2) maximum, _ = reduce_max(values, index) - # We use np.testing.assert_array_equal rather than Tensorflow's assertAllEqual np.testing.assert_array_equal(maximum.numpy(), [2, 3]) def test_reduce_sum_vectorized(self): @@ -1079,9 +1067,7 @@ def test_reduce_sum_vectorized(self): index = IndexMap(indices=torch.as_tensor([[0, 0, 1]]), num_segments=2, batch_dims=0) sums, new_index = reduce_sum(values, index) - # We use np.testing.assert_allclose rather than Tensorflow's assertAllClose np.testing.assert_allclose(sums.numpy(), [3.0, 3.0]) - # We use np.testing.assert_array_equal rather than Tensorflow's assertAllEqual np.testing.assert_array_equal(new_index.indices.numpy(), [0, 1]) np.testing.assert_array_equal(new_index.num_segments.numpy(), 2) np.testing.assert_array_equal(new_index.batch_dims, 0) @@ -1097,7 +1083,6 @@ def test_gather(self): cell_sum = gather(sums, cell_index) assert cell_sum.size() == values.size() - # We use np.testing.assert_array_equal rather than Tensorflow's assertAllEqual np.testing.assert_allclose( cell_sum.numpy(), [[[3.0, 3.0, 3.0], [2.0, 2.0, 1.0], [4.0, 4.0, 4.0]], [[1.0, 2.0, 3.0], [2.0, 0.0, 1.0], [1.0, 3.0, 4.0]]], @@ -1108,5 +1093,4 @@ def test_gather_vectorized(self): index = IndexMap(indices=torch.as_tensor([[0, 1], [1, 0]]), num_segments=2, batch_dims=1) result = gather(values, index) - # We use np.testing.assert_array_equal rather than Tensorflow's assertAllEqual np.testing.assert_array_equal(result.numpy(), [[[1, 2], [3, 4]], [[7, 8], [5, 6]]]) diff --git a/tests/models/tapas/test_tokenization_tapas.py b/tests/models/tapas/test_tokenization_tapas.py index 86c6f6c2124e..6dc57b94b064 100644 --- a/tests/models/tapas/test_tokenization_tapas.py +++ b/tests/models/tapas/test_tokenization_tapas.py @@ -21,7 +21,7 @@ import pandas as pd from parameterized import parameterized -from transformers import AddedToken, is_flax_available, is_mlx_available, is_tf_available, is_torch_available +from transformers import AddedToken, is_mlx_available, is_torch_available from transformers.models.tapas.tokenization_tapas import ( VOCAB_FILES_NAMES, BasicTokenizer, @@ -1150,7 +1150,7 @@ def test_full_tokenizer(self): self.assertListEqual(column_ids.tolist(), expected_results["column_ids"]) self.assertListEqual(row_ids.tolist(), expected_results["row_ids"]) - @unittest.skip(reason="Doesn't support another framework than PyTorch") + @unittest.skip(reason="Doesn't support returning Numpy arrays") def test_np_encode_plus_sent_to_model(self): pass @@ -1184,18 +1184,6 @@ def test_empty_input_string(self): tokenizer_return_type.append("np") output_tensor_type.append(np.int64) - if is_tf_available(): - import tensorflow as tf - - tokenizer_return_type.append("tf") - output_tensor_type.append(tf.int32) - - if is_flax_available(): - import jax.numpy as jnp - - tokenizer_return_type.append("jax") - output_tensor_type.append(jnp.int32) - if is_mlx_available(): import mlx.core as mx @@ -1203,7 +1191,7 @@ def test_empty_input_string(self): output_tensor_type.append(mx.int32) if len(tokenizer_return_type) == 0: - self.skipTest(reason="No expected framework from PT, TF, JAX or MLX found") + self.skipTest(reason="No expected framework from PT, or MLX found") tokenizers = self.get_tokenizers() for tokenizer in tokenizers: diff --git a/tests/models/udop/test_tokenization_udop.py b/tests/models/udop/test_tokenization_udop.py index 3a05d98bfc0a..a7d301607e84 100644 --- a/tests/models/udop/test_tokenization_udop.py +++ b/tests/models/udop/test_tokenization_udop.py @@ -22,9 +22,7 @@ SpecialTokensMixin, UdopTokenizer, UdopTokenizerFast, - is_flax_available, is_mlx_available, - is_tf_available, is_torch_available, logging, ) @@ -1593,12 +1591,7 @@ def test_batch_encode_dynamic_overflowing(self): tokenizer = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name}, {tokenizer.__class__.__name__})"): - if is_torch_available(): - returned_tensor = "pt" - elif is_tf_available(): - returned_tensor = "tf" - else: - returned_tensor = "jax" + returned_tensor = "pt" # Single example words, boxes = self.get_words_and_boxes() @@ -1780,7 +1773,7 @@ def test_udop_integration_test(self): self.assertDictEqual(dict(encoding_p), expected_results) self.assertDictEqual(dict(encoding_r), expected_results) - @unittest.skip(reason="Doesn't support another framework than PyTorch") + @unittest.skip(reason="Doesn't support returning Numpy arrays") def test_np_encode_plus_sent_to_model(self): pass @@ -1897,18 +1890,6 @@ def test_empty_input_string(self): tokenizer_return_type.append("np") output_tensor_type.append(np.int64) - if is_tf_available(): - import tensorflow as tf - - tokenizer_return_type.append("tf") - output_tensor_type.append(tf.int32) - - if is_flax_available(): - import jax.numpy as jnp - - tokenizer_return_type.append("jax") - output_tensor_type.append(jnp.int32) - if is_mlx_available(): import mlx.core as mx @@ -1916,7 +1897,7 @@ def test_empty_input_string(self): output_tensor_type.append(mx.int32) if len(tokenizer_return_type) == 0: - self.skipTest(reason="No expected framework from PT, TF, JAX or MLX found") + self.skipTest(reason="No expected framework from PT, or MLX found") tokenizers = self.get_tokenizers() for tokenizer in tokenizers: diff --git a/tests/models/upernet/test_modeling_upernet.py b/tests/models/upernet/test_modeling_upernet.py index 9bca31677f36..349766fe575e 100644 --- a/tests/models/upernet/test_modeling_upernet.py +++ b/tests/models/upernet/test_modeling_upernet.py @@ -11,7 +11,7 @@ # 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 UperNet framework.""" +"""Testing suite for the PyTorch UperNet.""" import unittest diff --git a/tests/models/vit_mae/test_modeling_vit_mae.py b/tests/models/vit_mae/test_modeling_vit_mae.py index a79bcec8af72..b28d4711d589 100644 --- a/tests/models/vit_mae/test_modeling_vit_mae.py +++ b/tests/models/vit_mae/test_modeling_vit_mae.py @@ -358,7 +358,6 @@ def default_model(self): @slow def test_inference_for_pretraining(self): - # make random mask reproducible across the PT and TF model np.random.seed(2) model = self.default_model @@ -367,8 +366,6 @@ def test_inference_for_pretraining(self): image = prepare_img() inputs = image_processor(images=image, return_tensors="pt").to(torch_device) - # prepare a noise vector that will be also used for testing the TF model - # (this way we can ensure that the PT and TF models operate on the same inputs) vit_mae_config = ViTMAEConfig() num_patches = int((vit_mae_config.image_size // vit_mae_config.patch_size) ** 2) noise = torch.from_numpy(np.random.uniform(size=(1, num_patches))).to(device=torch_device) @@ -394,7 +391,6 @@ def test_inference_interpolate_pos_encoding(self): # the model on higher resolutions. The DINO model by Facebook AI leverages this # to visualize self-attention on higher resolution images. - # make random mask reproducible across the PT and TF model np.random.seed(2) model = self.default_model @@ -403,8 +399,6 @@ def test_inference_interpolate_pos_encoding(self): image = prepare_img() inputs = image_processor(images=image, return_tensors="pt", do_resize=False).to(torch_device) - # prepare a noise vector that will be also used for testing the TF model - # (this way we can ensure that the PT and TF models operate on the same inputs) vit_mae_config = ViTMAEConfig() num_patches = (image.height // vit_mae_config.patch_size) * (image.width // vit_mae_config.patch_size) noise = torch.from_numpy(np.random.uniform(size=(1, num_patches))).to(device=torch_device) @@ -421,7 +415,6 @@ def test_inference_interpolate_pos_encoding(self): def test_inference_interpolate_pos_encoding_custom_sizes(self): # Ensure custom sizes are correctly handled when interpolating the position embeddings - # make random mask reproducible across the PT and TF model np.random.seed(2) model = self.default_model diff --git a/tests/models/xlnet/test_modeling_xlnet.py b/tests/models/xlnet/test_modeling_xlnet.py index b8bed5c822af..ae0e2b9d56df 100644 --- a/tests/models/xlnet/test_modeling_xlnet.py +++ b/tests/models/xlnet/test_modeling_xlnet.py @@ -56,7 +56,6 @@ def __init__( d_inner=128, num_hidden_layers=2, type_sequence_label_size=2, - untie_r=True, bi_data=False, same_length=False, initializer_range=0.05, @@ -83,7 +82,6 @@ def __init__( self.d_inner = 128 self.num_hidden_layers = 5 self.type_sequence_label_size = 2 - self.untie_r = True self.bi_data = False self.same_length = False self.initializer_range = 0.05 @@ -152,7 +150,6 @@ def get_config(self): n_head=self.num_attention_heads, d_inner=self.d_inner, n_layer=self.num_hidden_layers, - untie_r=self.untie_r, mem_len=self.mem_len, clamp_len=self.clamp_len, same_length=self.same_length, diff --git a/tests/pipelines/test_pipelines_audio_classification.py b/tests/pipelines/test_pipelines_audio_classification.py index 19c16b486514..e30fd976cc97 100644 --- a/tests/pipelines/test_pipelines_audio_classification.py +++ b/tests/pipelines/test_pipelines_audio_classification.py @@ -20,7 +20,6 @@ from transformers import ( MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING, - TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING, is_torch_available, ) from transformers.pipelines import AudioClassificationPipeline, pipeline @@ -43,7 +42,6 @@ @is_pipeline_test class AudioClassificationPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING - tf_model_mapping = TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING _dataset = None @classmethod diff --git a/tests/pipelines/test_pipelines_automatic_speech_recognition.py b/tests/pipelines/test_pipelines_automatic_speech_recognition.py index c7aa7b686b1f..8776961bec14 100644 --- a/tests/pipelines/test_pipelines_automatic_speech_recognition.py +++ b/tests/pipelines/test_pipelines_automatic_speech_recognition.py @@ -160,7 +160,7 @@ def run_pipeline_test(self, speech_recognizer, examples): @require_torch def test_pt_defaults(self): - pipeline("automatic-speech-recognition", framework="pt") + pipeline("automatic-speech-recognition") @require_torch def test_small_model_pt(self): @@ -168,7 +168,6 @@ def test_small_model_pt(self): task="automatic-speech-recognition", model="facebook/s2t-small-mustc-en-fr-st", tokenizer="facebook/s2t-small-mustc-en-fr-st", - framework="pt", ) waveform = np.tile(np.arange(1000, dtype=np.float32), 34) output = speech_recognizer(waveform) @@ -188,7 +187,6 @@ def test_small_model_pt_fp16(self): task="automatic-speech-recognition", model="facebook/s2t-small-mustc-en-fr-st", tokenizer="facebook/s2t-small-mustc-en-fr-st", - framework="pt", dtype=torch.float16, ) waveform = np.tile(np.arange(1000, dtype=np.float32), 34) @@ -209,7 +207,6 @@ def test_small_model_pt_bf16(self): task="automatic-speech-recognition", model="facebook/s2t-small-mustc-en-fr-st", tokenizer="facebook/s2t-small-mustc-en-fr-st", - framework="pt", dtype=torch.bfloat16, ) waveform = np.tile(np.arange(1000, dtype=np.float32), 34) @@ -239,7 +236,6 @@ def test_whisper_fp16(self): def test_small_model_pt_seq2seq(self): speech_recognizer = pipeline( model="hf-internal-testing/tiny-random-speech-encoder-decoder", - framework="pt", max_new_tokens=19, num_beams=1, ) @@ -252,7 +248,6 @@ def test_small_model_pt_seq2seq(self): def test_small_model_pt_seq2seq_gen_kwargs(self): speech_recognizer = pipeline( model="hf-internal-testing/tiny-random-speech-encoder-decoder", - framework="pt", max_new_tokens=10, ) @@ -269,7 +264,6 @@ def test_large_model_pt_with_lm(self): speech_recognizer = pipeline( task="automatic-speech-recognition", model="patrickvonplaten/wav2vec2-large-xlsr-53-spanish-with-lm", - framework="pt", ) self.assertEqual(speech_recognizer.type, "ctc_with_lm") @@ -333,7 +327,6 @@ def test_torch_small_no_tokenizer_files(self): pipeline( task="automatic-speech-recognition", model="patrickvonplaten/tiny-wav2vec2-no-tokenizer", - framework="pt", ) @require_torch @@ -343,7 +336,6 @@ def test_torch_large(self): task="automatic-speech-recognition", model="facebook/wav2vec2-base-960h", tokenizer="facebook/wav2vec2-base-960h", - framework="pt", ) waveform = np.tile(np.arange(1000, dtype=np.float32), 34) output = speech_recognizer(waveform) @@ -360,7 +352,6 @@ def test_torch_large_with_input_features(self): speech_recognizer = pipeline( task="automatic-speech-recognition", model="hf-audio/wav2vec2-bert-CV16-en", - framework="pt", ) waveform = np.tile(np.arange(1000, dtype=np.float32), 34) output = speech_recognizer(waveform) @@ -600,7 +591,6 @@ def test_torch_whisper(self): speech_recognizer = pipeline( task="automatic-speech-recognition", model="openai/whisper-tiny", - framework="pt", num_beams=1, ) ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation").sort("id") @@ -617,7 +607,6 @@ def test_torch_whisper_batched(self): speech_recognizer = pipeline( task="automatic-speech-recognition", model="openai/whisper-tiny", - framework="pt", num_beams=1, ) ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation[:2]") @@ -913,7 +902,6 @@ def test_torch_speech_encoder_decoder(self): task="automatic-speech-recognition", model="facebook/s2t-wav2vec2-large-en-de", feature_extractor="facebook/s2t-wav2vec2-large-en-de", - framework="pt", ) ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation").sort("id") @@ -977,7 +965,6 @@ def test_simple_whisper_asr(self): speech_recognizer = pipeline( task="automatic-speech-recognition", model="openai/whisper-tiny.en", - framework="pt", num_beams=1, ) ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") @@ -1047,7 +1034,6 @@ def test_simple_whisper_translation(self): speech_recognizer = pipeline( task="automatic-speech-recognition", model="openai/whisper-large", - framework="pt", ) ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation").sort("id") audio = ds[40]["audio"] @@ -1083,7 +1069,6 @@ def test_whisper_language(self): speech_recognizer = pipeline( task="automatic-speech-recognition", model="openai/whisper-tiny.en", - framework="pt", ) ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") audio = ds[0]["audio"] @@ -1107,7 +1092,6 @@ def test_whisper_language(self): speech_recognizer = pipeline( task="automatic-speech-recognition", model="openai/whisper-tiny", - framework="pt", ) output = speech_recognizer(ds[0]["audio"], generate_kwargs={"language": "en"}) self.assertEqual( @@ -1207,7 +1191,6 @@ def test_xls_r_to_en(self): task="automatic-speech-recognition", model="facebook/wav2vec2-xls-r-1b-21-to-en", feature_extractor="facebook/wav2vec2-xls-r-1b-21-to-en", - framework="pt", ) ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation").sort("id") @@ -1223,7 +1206,6 @@ def test_xls_r_from_en(self): task="automatic-speech-recognition", model="facebook/wav2vec2-xls-r-1b-en-to-15", feature_extractor="facebook/wav2vec2-xls-r-1b-en-to-15", - framework="pt", ) ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation").sort("id") @@ -1240,7 +1222,6 @@ def test_speech_to_text_leveraged(self): model="patrickvonplaten/wav2vec2-2-bart-base", feature_extractor="patrickvonplaten/wav2vec2-2-bart-base", tokenizer=AutoTokenizer.from_pretrained("patrickvonplaten/wav2vec2-2-bart-base"), - framework="pt", ) ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation").sort("id") @@ -1256,7 +1237,6 @@ def test_wav2vec2_conformer_float16(self): model="facebook/wav2vec2-conformer-rope-large-960h-ft", device=torch_device, dtype=torch.float16, - framework="pt", ) dataset = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") @@ -1516,7 +1496,6 @@ def test_chunking_and_timestamps(self): model=model, tokenizer=tokenizer, feature_extractor=feature_extractor, - framework="pt", chunk_length_s=10.0, ) diff --git a/tests/pipelines/test_pipelines_common.py b/tests/pipelines/test_pipelines_common.py index 8fb87136a024..aa3b1b55beba 100644 --- a/tests/pipelines/test_pipelines_common.py +++ b/tests/pipelines/test_pipelines_common.py @@ -21,7 +21,6 @@ from pathlib import Path import datasets -import numpy as np from huggingface_hub import HfFolder, Repository, delete_repo from requests.exceptions import HTTPError @@ -34,7 +33,6 @@ T5ForConditionalGeneration, TextClassificationPipeline, TextGenerationPipeline, - TFAutoModelForSequenceClassification, pipeline, ) from transformers.pipelines import PIPELINE_REGISTRY, get_task @@ -51,11 +49,10 @@ require_torch, require_torch_accelerator, require_torch_multi_accelerator, - require_torch_or_tf, slow, torch_device, ) -from transformers.utils import direct_transformers_import, is_tf_available, is_torch_available +from transformers.utils import direct_transformers_import, is_torch_available from transformers.utils import logging as transformers_logging @@ -104,9 +101,7 @@ def __len__(self): def __getitem__(self, i): return self.data[i] - text_classifier = pipeline( - task="text-classification", model="hf-internal-testing/tiny-random-distilbert", framework="pt" - ) + text_classifier = pipeline(task="text-classification", model="hf-internal-testing/tiny-random-distilbert") dataset = MyDataset() for output in text_classifier(dataset): self.assertEqual(output, {"label": ANY(str), "score": ANY(float)}) @@ -251,9 +246,7 @@ class PipelineScikitCompatTest(unittest.TestCase): def test_pipeline_predict(self): data = ["This is a test"] - text_classifier = pipeline( - task="text-classification", model="hf-internal-testing/tiny-random-distilbert", framework="pt" - ) + text_classifier = pipeline(task="text-classification", model="hf-internal-testing/tiny-random-distilbert") expected_output = [{"label": ANY(str), "score": ANY(float)}] actual_output = text_classifier.predict(data) @@ -262,9 +255,7 @@ def test_pipeline_predict(self): def test_pipeline_transform(self): data = ["This is a test"] - text_classifier = pipeline( - task="text-classification", model="hf-internal-testing/tiny-random-distilbert", framework="pt" - ) + text_classifier = pipeline(task="text-classification", model="hf-internal-testing/tiny-random-distilbert") expected_output = [{"label": ANY(str), "score": ANY(float)}] actual_output = text_classifier.transform(data) @@ -573,7 +564,7 @@ def test_load_default_pipelines_pt(self): # test table in separate test due to more dependencies continue - self.check_default_pipeline(task, "pt", set_seed_fn, self.check_models_equal_pt) + self.check_default_pipeline(task, set_seed_fn, self.check_models_equal_pt) # clean-up as much as possible GPU memory occupied by PyTorch gc.collect() @@ -585,7 +576,7 @@ def test_load_default_pipelines_pt_table_qa(self): import torch set_seed_fn = lambda: torch.manual_seed(0) # noqa: E731 - self.check_default_pipeline("table-question-answering", "pt", set_seed_fn, self.check_models_equal_pt) + self.check_default_pipeline("table-question-answering", set_seed_fn, self.check_models_equal_pt) # clean-up as much as possible GPU memory occupied by PyTorch gc.collect() @@ -633,18 +624,17 @@ def test_bc_torch_device(self): self.assertEqual(k1, k2) self.assertEqual(v1.dtype, v2.dtype) - def check_default_pipeline(self, task, framework, set_seed_fn, check_models_equal_fn): + def check_default_pipeline(self, task, set_seed_fn, check_models_equal_fn): from transformers.pipelines import SUPPORTED_TASKS, pipeline task_dict = SUPPORTED_TASKS[task] # test to compare pipeline to manually loading the respective model model = None - relevant_auto_classes = task_dict[framework] + relevant_auto_classes = task_dict["pt"] if len(relevant_auto_classes) == 0: # task has no default - logger.debug(f"{task} in {framework} has no default") - self.skipTest(f"{task} in {framework} has no default") + self.skipTest(f"{task} in pytorch has no default") # by default use first class auto_model_cls = relevant_auto_classes[0] @@ -656,14 +646,14 @@ def check_default_pipeline(self, task, framework, set_seed_fn, check_models_equa revisions = [] tasks = [] for translation_pair in task_dict["default"]: - model_id, revision = task_dict["default"][translation_pair]["model"][framework] + model_id, revision = task_dict["default"][translation_pair]["model"] model_ids.append(model_id) revisions.append(revision) tasks.append(task + f"_{'_to_'.join(translation_pair)}") else: # normal case - non-translation pipeline - model_id, revision = task_dict["default"]["model"][framework] + model_id, revision = task_dict["default"]["model"] model_ids = [model_id] revisions = [revision] @@ -683,14 +673,12 @@ def check_default_pipeline(self, task, framework, set_seed_fn, check_models_equa # load default pipeline set_seed_fn() - default_pipeline = pipeline(task, framework=framework) + default_pipeline = pipeline(task) # compare pipeline model with default model models_are_equal = check_models_equal_fn(default_pipeline.model, model) self.assertTrue(models_are_equal, f"{task} model doesn't match pipeline.") - logger.debug(f"{task} in {framework} succeeded with {model_id}.") - def check_models_equal_pt(self, model1, model2): models_are_equal = True for model1_p, model2_p in zip(model1.parameters(), model2.parameters()): @@ -699,14 +687,6 @@ def check_models_equal_pt(self, model1, model2): return models_are_equal - def check_models_equal_tf(self, model1, model2): - models_are_equal = True - for model1_p, model2_p in zip(model1.weights, model2.weights): - if np.abs(model1_p.numpy() - model2_p.numpy()).sum() > 1e-5: - models_are_equal = False - - return models_are_equal - class CustomPipeline(Pipeline): def _sanitize_parameters(self, **kwargs): @@ -751,31 +731,26 @@ def test_register_pipeline(self): "custom-text-classification", pipeline_class=PairClassificationPipeline, pt_model=AutoModelForSequenceClassification if is_torch_available() else None, - tf_model=TFAutoModelForSequenceClassification if is_tf_available() else None, - default={"pt": ("hf-internal-testing/tiny-random-distilbert", "2ef615d")}, + default={"model": ("hf-internal-testing/tiny-random-distilbert", "2ef615d")}, type="text", ) assert "custom-text-classification" in PIPELINE_REGISTRY.get_supported_tasks() _, task_def, _ = PIPELINE_REGISTRY.check_task("custom-text-classification") self.assertEqual(task_def["pt"], (AutoModelForSequenceClassification,) if is_torch_available() else ()) - self.assertEqual(task_def["tf"], (TFAutoModelForSequenceClassification,) if is_tf_available() else ()) self.assertEqual(task_def["type"], "text") self.assertEqual(task_def["impl"], PairClassificationPipeline) - self.assertEqual( - task_def["default"], {"model": {"pt": ("hf-internal-testing/tiny-random-distilbert", "2ef615d")}} - ) + self.assertEqual(task_def["default"], {"model": ("hf-internal-testing/tiny-random-distilbert", "2ef615d")}) # Clean registry for next tests. del PIPELINE_REGISTRY.supported_tasks["custom-text-classification"] - @require_torch_or_tf + @require_torch def test_dynamic_pipeline(self): PIPELINE_REGISTRY.register_pipeline( "pair-classification", pipeline_class=PairClassificationPipeline, pt_model=AutoModelForSequenceClassification if is_torch_available() else None, - tf_model=TFAutoModelForSequenceClassification if is_tf_available() else None, ) classifier = pipeline("pair-classification", model="hf-internal-testing/tiny-random-bert") @@ -792,7 +767,6 @@ def test_dynamic_pipeline(self): "pair-classification": { "impl": "custom_pipeline.PairClassificationPipeline", "pt": ("AutoModelForSequenceClassification",) if is_torch_available() else (), - "tf": ("TFAutoModelForSequenceClassification",) if is_tf_available() else (), } }, ) @@ -821,7 +795,7 @@ def test_dynamic_pipeline(self): [{"label": "LABEL_0", "score": 0.505}], ) - @require_torch_or_tf + @require_torch def test_cached_pipeline_has_minimum_calls_to_head(self): # Make sure we have cached the pipeline. _ = pipeline("text-classification", model="hf-internal-testing/tiny-random-bert") @@ -943,7 +917,6 @@ def test_push_to_hub_dynamic_pipeline(self): "pair-classification": { "impl": "custom_pipeline.PairClassificationPipeline", "pt": ("AutoModelForSequenceClassification",), - "tf": (), } }, ) @@ -966,7 +939,6 @@ def test_push_to_hub_dynamic_pipeline(self): "pair-classification": { "impl": f"{USER}/test-dynamic-pipeline--custom_pipeline.PairClassificationPipeline", "pt": ("AutoModelForSequenceClassification",), - "tf": (), } }, ) diff --git a/tests/pipelines/test_pipelines_feature_extraction.py b/tests/pipelines/test_pipelines_feature_extraction.py index f6cbbb2fea2e..2d8a5618eaf2 100644 --- a/tests/pipelines/test_pipelines_feature_extraction.py +++ b/tests/pipelines/test_pipelines_feature_extraction.py @@ -20,7 +20,6 @@ FEATURE_EXTRACTOR_MAPPING, IMAGE_PROCESSOR_MAPPING, MODEL_MAPPING, - TF_MODEL_MAPPING, FeatureExtractionPipeline, LxmertConfig, is_torch_available, @@ -36,13 +35,10 @@ @is_pipeline_test class FeatureExtractionPipelineTests(unittest.TestCase): model_mapping = MODEL_MAPPING - tf_model_mapping = TF_MODEL_MAPPING @require_torch def test_small_model_pt(self): - feature_extractor = pipeline( - task="feature-extraction", model="hf-internal-testing/tiny-random-distilbert", framework="pt" - ) + feature_extractor = pipeline(task="feature-extraction", model="hf-internal-testing/tiny-random-distilbert") outputs = feature_extractor("This is a test") self.assertEqual( nested_simplify(outputs), @@ -50,9 +46,7 @@ def test_small_model_pt(self): @require_torch def test_tokenization_small_model_pt(self): - feature_extractor = pipeline( - task="feature-extraction", model="hf-internal-testing/tiny-random-distilbert", framework="pt" - ) + feature_extractor = pipeline(task="feature-extraction", model="hf-internal-testing/tiny-random-distilbert") # test with empty parameters outputs = feature_extractor("This is a test") self.assertEqual( @@ -90,9 +84,7 @@ def test_tokenization_small_model_pt(self): @require_torch def test_return_tensors_pt(self): - feature_extractor = pipeline( - task="feature-extraction", model="hf-internal-testing/tiny-random-distilbert", framework="pt" - ) + feature_extractor = pipeline(task="feature-extraction", model="hf-internal-testing/tiny-random-distilbert") outputs = feature_extractor("This is a test", return_tensors=True) self.assertTrue(torch.is_tensor(outputs)) diff --git a/tests/pipelines/test_pipelines_fill_mask.py b/tests/pipelines/test_pipelines_fill_mask.py index e1e88f63f7fe..4c85529c0613 100644 --- a/tests/pipelines/test_pipelines_fill_mask.py +++ b/tests/pipelines/test_pipelines_fill_mask.py @@ -15,7 +15,7 @@ import gc import unittest -from transformers import MODEL_FOR_MASKED_LM_MAPPING, TF_MODEL_FOR_MASKED_LM_MAPPING, FillMaskPipeline, pipeline +from transformers import MODEL_FOR_MASKED_LM_MAPPING, FillMaskPipeline, pipeline from transformers.pipelines import PipelineException from transformers.testing_utils import ( backend_empty_cache, @@ -34,7 +34,6 @@ @is_pipeline_test class FillMaskPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_MASKED_LM_MAPPING - tf_model_mapping = TF_MODEL_FOR_MASKED_LM_MAPPING def tearDown(self): super().tearDown() @@ -45,7 +44,7 @@ def tearDown(self): @require_torch def test_small_model_pt(self): - unmasker = pipeline(task="fill-mask", model="sshleifer/tiny-distilroberta-base", top_k=2, framework="pt") + unmasker = pipeline(task="fill-mask", model="sshleifer/tiny-distilroberta-base", top_k=2) outputs = unmasker("My name is ") self.assertEqual( @@ -112,7 +111,6 @@ def test_fp16_casting(self): "fill-mask", model="hf-internal-testing/tiny-random-distilbert", device=torch_device, - framework="pt", ) # convert model to fp16 @@ -127,7 +125,7 @@ def test_fp16_casting(self): @slow @require_torch def test_large_model_pt(self): - unmasker = pipeline(task="fill-mask", model="distilbert/distilroberta-base", top_k=2, framework="pt") + unmasker = pipeline(task="fill-mask", model="distilbert/distilroberta-base", top_k=2) self.run_large_test(unmasker) def run_large_test(self, unmasker): @@ -191,7 +189,7 @@ def run_large_test(self, unmasker): @require_torch def test_model_no_pad_pt(self): - unmasker = pipeline(task="fill-mask", model="sshleifer/tiny-distilroberta-base", framework="pt") + unmasker = pipeline(task="fill-mask", model="sshleifer/tiny-distilroberta-base") unmasker.tokenizer.pad_token_id = None unmasker.tokenizer.pad_token = None self.run_pipeline_test(unmasker, []) diff --git a/tests/pipelines/test_pipelines_image_classification.py b/tests/pipelines/test_pipelines_image_classification.py index 04d2dc876b33..f8f8c908095c 100644 --- a/tests/pipelines/test_pipelines_image_classification.py +++ b/tests/pipelines/test_pipelines_image_classification.py @@ -19,7 +19,6 @@ from transformers import ( MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING, - TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING, PreTrainedTokenizerBase, is_torch_available, is_vision_available, @@ -30,7 +29,6 @@ is_pipeline_test, nested_simplify, require_torch, - require_torch_or_tf, require_vision, slow, ) @@ -52,11 +50,10 @@ def open(*args, **kwargs): @is_pipeline_test -@require_torch_or_tf +@require_torch @require_vision class ImageClassificationPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING - tf_model_mapping = TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING _dataset = None @classmethod diff --git a/tests/pipelines/test_pipelines_image_feature_extraction.py b/tests/pipelines/test_pipelines_image_feature_extraction.py index 8254517c35d8..c80bb2ec3453 100644 --- a/tests/pipelines/test_pipelines_image_feature_extraction.py +++ b/tests/pipelines/test_pipelines_image_feature_extraction.py @@ -19,7 +19,6 @@ from transformers import ( MODEL_MAPPING, - TF_MODEL_MAPPING, TOKENIZER_MAPPING, ImageFeatureExtractionPipeline, is_torch_available, @@ -45,13 +44,10 @@ def prepare_img(): @is_pipeline_test class ImageFeatureExtractionPipelineTests(unittest.TestCase): model_mapping = MODEL_MAPPING - tf_model_mapping = TF_MODEL_MAPPING @require_torch def test_small_model_pt(self): - feature_extractor = pipeline( - task="image-feature-extraction", model="hf-internal-testing/tiny-random-vit", framework="pt" - ) + feature_extractor = pipeline(task="image-feature-extraction", model="hf-internal-testing/tiny-random-vit") img = prepare_img() outputs = feature_extractor(img) self.assertEqual( @@ -61,7 +57,7 @@ def test_small_model_pt(self): @require_torch def test_small_model_w_pooler_pt(self): feature_extractor = pipeline( - task="image-feature-extraction", model="hf-internal-testing/tiny-random-vit-w-pooler", framework="pt" + task="image-feature-extraction", model="hf-internal-testing/tiny-random-vit-w-pooler" ) img = prepare_img() outputs = feature_extractor(img, pool=True) @@ -71,9 +67,7 @@ def test_small_model_w_pooler_pt(self): @require_torch def test_image_processing_small_model_pt(self): - feature_extractor = pipeline( - task="image-feature-extraction", model="hf-internal-testing/tiny-random-vit", framework="pt" - ) + feature_extractor = pipeline(task="image-feature-extraction", model="hf-internal-testing/tiny-random-vit") # test with image processor parameters image_processor_kwargs = {"size": {"height": 300, "width": 300}} @@ -93,9 +87,7 @@ def test_image_processing_small_model_pt(self): @require_torch def test_return_tensors_pt(self): - feature_extractor = pipeline( - task="image-feature-extraction", model="hf-internal-testing/tiny-random-vit", framework="pt" - ) + feature_extractor = pipeline(task="image-feature-extraction", model="hf-internal-testing/tiny-random-vit") img = prepare_img() outputs = feature_extractor(img, return_tensors=True) self.assertTrue(torch.is_tensor(outputs)) diff --git a/tests/pipelines/test_pipelines_image_to_text.py b/tests/pipelines/test_pipelines_image_to_text.py index ee73a1dfb63b..bc8ac76548ea 100644 --- a/tests/pipelines/test_pipelines_image_to_text.py +++ b/tests/pipelines/test_pipelines_image_to_text.py @@ -16,7 +16,7 @@ import requests -from transformers import MODEL_FOR_VISION_2_SEQ_MAPPING, TF_MODEL_FOR_VISION_2_SEQ_MAPPING, is_vision_available +from transformers import MODEL_FOR_VISION_2_SEQ_MAPPING, is_vision_available from transformers.pipelines import ImageToTextPipeline, pipeline from transformers.testing_utils import ( is_pipeline_test, @@ -42,7 +42,6 @@ def open(*args, **kwargs): @require_vision class ImageToTextPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_VISION_2_SEQ_MAPPING - tf_model_mapping = TF_MODEL_FOR_VISION_2_SEQ_MAPPING def get_test_pipeline( self, diff --git a/tests/pipelines/test_pipelines_mask_generation.py b/tests/pipelines/test_pipelines_mask_generation.py index 3fd8f7b5c44a..ff194764b44b 100644 --- a/tests/pipelines/test_pipelines_mask_generation.py +++ b/tests/pipelines/test_pipelines_mask_generation.py @@ -19,7 +19,6 @@ from transformers import ( MODEL_FOR_MASK_GENERATION_MAPPING, - is_tf_available, is_torch_available, is_vision_available, pipeline, @@ -35,11 +34,6 @@ ) -if is_tf_available(): - from transformers import TF_MODEL_FOR_MASK_GENERATION_MAPPING -else: - TF_MODEL_FOR_MASK_GENERATION_MAPPING = None - if is_torch_available(): from transformers import MODEL_FOR_MASK_GENERATION_MAPPING else: @@ -72,9 +66,6 @@ def mask_to_test_readable(mask: Image) -> dict: @require_torch class MaskGenerationPipelineTests(unittest.TestCase): model_mapping = dict(list(MODEL_FOR_MASK_GENERATION_MAPPING.items()) if MODEL_FOR_MASK_GENERATION_MAPPING else []) - tf_model_mapping = dict( - list(TF_MODEL_FOR_MASK_GENERATION_MAPPING.items()) if TF_MODEL_FOR_MASK_GENERATION_MAPPING else [] - ) def get_test_pipeline( self, diff --git a/tests/pipelines/test_pipelines_question_answering.py b/tests/pipelines/test_pipelines_question_answering.py index e6bd82a846bc..fd02ae8eea94 100644 --- a/tests/pipelines/test_pipelines_question_answering.py +++ b/tests/pipelines/test_pipelines_question_answering.py @@ -18,7 +18,6 @@ from transformers import ( MODEL_FOR_QUESTION_ANSWERING_MAPPING, - TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING, LxmertConfig, QuestionAnsweringPipeline, ) @@ -30,7 +29,6 @@ is_torch_available, nested_simplify, require_torch, - require_torch_or_tf, slow, ) @@ -48,14 +46,9 @@ @is_pipeline_test class QAPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_QUESTION_ANSWERING_MAPPING - tf_model_mapping = TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING if not hasattr(model_mapping, "is_dummy"): model_mapping = {config: model for config, model in model_mapping.items() if config.__name__ not in _TO_SKIP} - if not hasattr(tf_model_mapping, "is_dummy"): - tf_model_mapping = { - config: model for config, model in tf_model_mapping.items() if config.__name__ not in _TO_SKIP - } def get_test_pipeline( self, @@ -207,7 +200,7 @@ def test_small_model_pt_bf16(self): @require_torch def test_small_model_pt_iterator(self): # https://github.com/huggingface/transformers/issues/18510 - pipe = pipeline(model="sshleifer/tiny-distilbert-base-cased-distilled-squad", batch_size=16, framework="pt") + pipe = pipeline(model="sshleifer/tiny-distilbert-base-cased-distilled-squad", batch_size=16) def data(): for i in range(10): @@ -416,7 +409,7 @@ def test_large_model_course(self): ) -@require_torch_or_tf +@require_torch class QuestionAnsweringArgumentHandlerTests(unittest.TestCase): def test_argument_handler(self): qa = QuestionAnsweringArgumentHandler() diff --git a/tests/pipelines/test_pipelines_summarization.py b/tests/pipelines/test_pipelines_summarization.py index 99c2faf72b54..02cd9fe084c6 100644 --- a/tests/pipelines/test_pipelines_summarization.py +++ b/tests/pipelines/test_pipelines_summarization.py @@ -16,9 +16,7 @@ from transformers import ( MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, - TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, SummarizationPipeline, - TFPreTrainedModel, pipeline, ) from transformers.testing_utils import is_pipeline_test, require_torch, slow, torch_device @@ -30,7 +28,6 @@ @is_pipeline_test class SummarizationPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING - tf_model_mapping = TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING def get_test_pipeline( self, @@ -78,22 +75,14 @@ def run_pipeline_test(self, summarizer, _): "ProphetNetConfig", # positional embeddings up to a fixed maximum size (otherwise clamping the values) ] if model.config.__class__.__name__ not in model_can_handle_longer_seq: - # Too long and exception is expected. - # For TF models, if the weights are initialized in GPU context, we won't get expected index error from - # the embedding layer. - if not ( - isinstance(model, TFPreTrainedModel) - and len(summarizer.model.trainable_weights) > 0 - and "GPU" in summarizer.model.trainable_weights[0].device - ): - if str(summarizer.device) == "cpu": - with self.assertRaises(Exception): - outputs = summarizer("This " * 1000) + if str(summarizer.device) == "cpu": + with self.assertRaises(Exception): + outputs = summarizer("This " * 1000) outputs = summarizer("This " * 1000, truncation=TruncationStrategy.ONLY_FIRST) @require_torch def test_small_model_pt(self): - summarizer = pipeline(task="summarization", model="sshleifer/tiny-mbart", framework="pt", max_new_tokens=19) + summarizer = pipeline(task="summarization", model="sshleifer/tiny-mbart", max_new_tokens=19) outputs = summarizer("This is a small test") self.assertEqual( outputs, diff --git a/tests/pipelines/test_pipelines_text2text_generation.py b/tests/pipelines/test_pipelines_text2text_generation.py index 5e3ed2b32f09..b52d68e22cfb 100644 --- a/tests/pipelines/test_pipelines_text2text_generation.py +++ b/tests/pipelines/test_pipelines_text2text_generation.py @@ -16,7 +16,6 @@ from transformers import ( MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, - TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, Text2TextGenerationPipeline, pipeline, ) @@ -33,7 +32,6 @@ @is_pipeline_test class Text2TextGenerationPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING - tf_model_mapping = TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING def get_test_pipeline( self, @@ -89,7 +87,6 @@ def test_small_model_pt(self): generator = pipeline( "text2text-generation", model="patrickvonplaten/t5-tiny-random", - framework="pt", num_beams=1, max_new_tokens=9, ) diff --git a/tests/pipelines/test_pipelines_text_classification.py b/tests/pipelines/test_pipelines_text_classification.py index 6400ad039bcb..b2310e8e087f 100644 --- a/tests/pipelines/test_pipelines_text_classification.py +++ b/tests/pipelines/test_pipelines_text_classification.py @@ -16,7 +16,6 @@ from transformers import ( MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, - TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, TextClassificationPipeline, pipeline, ) @@ -45,20 +44,13 @@ @is_pipeline_test class TextClassificationPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING - tf_model_mapping = TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING if not hasattr(model_mapping, "is_dummy"): model_mapping = {config: model for config, model in model_mapping.items() if config.__name__ not in _TO_SKIP} - if not hasattr(tf_model_mapping, "is_dummy"): - tf_model_mapping = { - config: model for config, model in tf_model_mapping.items() if config.__name__ not in _TO_SKIP - } @require_torch def test_small_model_pt(self): - text_classifier = pipeline( - task="text-classification", model="hf-internal-testing/tiny-random-distilbert", framework="pt" - ) + text_classifier = pipeline(task="text-classification", model="hf-internal-testing/tiny-random-distilbert") outputs = text_classifier("This is great !") self.assertEqual(nested_simplify(outputs), [{"label": "LABEL_0", "score": 0.504}]) @@ -118,7 +110,6 @@ def test_accepts_torch_device(self): text_classifier = pipeline( task="text-classification", model="hf-internal-testing/tiny-random-distilbert", - framework="pt", device=torch_device, ) @@ -130,7 +121,6 @@ def test_accepts_torch_fp16(self): text_classifier = pipeline( task="text-classification", model="hf-internal-testing/tiny-random-distilbert", - framework="pt", device=torch_device, dtype=torch.float16, ) @@ -143,7 +133,6 @@ def test_accepts_torch_bf16(self): text_classifier = pipeline( task="text-classification", model="hf-internal-testing/tiny-random-distilbert", - framework="pt", device=torch_device, dtype=torch.bfloat16, ) diff --git a/tests/pipelines/test_pipelines_text_generation.py b/tests/pipelines/test_pipelines_text_generation.py index a408266036c3..f0f576364c41 100644 --- a/tests/pipelines/test_pipelines_text_generation.py +++ b/tests/pipelines/test_pipelines_text_generation.py @@ -17,7 +17,6 @@ from transformers import ( MODEL_FOR_CAUSAL_LM_MAPPING, - TF_MODEL_FOR_CAUSAL_LM_MAPPING, TextGenerationPipeline, logging, pipeline, @@ -28,7 +27,6 @@ require_accelerate, require_torch, require_torch_accelerator, - require_torch_or_tf, torch_device, ) @@ -36,17 +34,15 @@ @is_pipeline_test -@require_torch_or_tf +@require_torch class TextGenerationPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_CAUSAL_LM_MAPPING - tf_model_mapping = TF_MODEL_FOR_CAUSAL_LM_MAPPING @require_torch def test_small_model_pt(self): text_generator = pipeline( task="text-generation", model="hf-internal-testing/tiny-random-LlamaForCausalLM", - framework="pt", max_new_tokens=10, ) # Using `do_sample=False` to force deterministic output @@ -76,7 +72,6 @@ def test_small_chat_model_pt(self): text_generator = pipeline( task="text-generation", model="hf-internal-testing/tiny-gpt2-with-chatml-template", - framework="pt", ) # Using `do_sample=False` to force deterministic output chat1 = [ @@ -124,7 +119,6 @@ def test_small_chat_model_continue_final_message(self): text_generator = pipeline( task="text-generation", model="hf-internal-testing/tiny-gpt2-with-chatml-template", - framework="pt", ) # Using `do_sample=False` to force deterministic output chat1 = [ @@ -158,7 +152,6 @@ def test_small_chat_model_continue_final_message_override(self): text_generator = pipeline( task="text-generation", model="hf-internal-testing/tiny-gpt2-with-chatml-template", - framework="pt", ) # Using `do_sample=False` to force deterministic output chat1 = [ @@ -206,7 +199,6 @@ def __getitem__(self, i): text_generator = pipeline( task="text-generation", model="hf-internal-testing/tiny-gpt2-with-chatml-template", - framework="pt", ) dataset = MyDataset() @@ -233,7 +225,6 @@ def test_small_chat_model_with_iterator_pt(self): text_generator = pipeline( task="text-generation", model="hf-internal-testing/tiny-gpt2-with-chatml-template", - framework="pt", ) # Using `do_sample=False` to force deterministic output @@ -372,11 +363,6 @@ def run_pipeline_test(self, text_generator, _): with self.assertRaises((ValueError, AssertionError)): outputs = text_generator("", add_special_tokens=False) - if text_generator.framework == "tf": - # TF generation does not support max_new_tokens, and it's impossible - # to control long generation with only max_length without - # fancy calculation, dismissing tests for now. - self.skipTest(reason="TF generation does not support max_new_tokens") # We don't care about infinite range models. # They already work. # Skip this test for XGLM, since it uses sinusoidal positional embeddings which are resized on-the-fly. @@ -483,10 +469,7 @@ def test_pipeline_accelerate_top_p(self): def test_pipeline_length_setting_warning(self): prompt = """Hello world""" text_generator = pipeline("text-generation", model="hf-internal-testing/tiny-random-gpt2", max_new_tokens=5) - if text_generator.model.framework == "tf": - logger = logging.get_logger("transformers.generation.tf_utils") - else: - logger = logging.get_logger("transformers.generation.utils") + logger = logging.get_logger("transformers.generation.utils") logger_msg = "Both `max_new_tokens`" # The beginning of the message to be checked in this test # Both are set by the user -> log warning diff --git a/tests/pipelines/test_pipelines_text_to_audio.py b/tests/pipelines/test_pipelines_text_to_audio.py index be49e1c7bdc5..c13d0830c6e6 100644 --- a/tests/pipelines/test_pipelines_text_to_audio.py +++ b/tests/pipelines/test_pipelines_text_to_audio.py @@ -26,7 +26,6 @@ is_pipeline_test, require_torch, require_torch_accelerator, - require_torch_or_tf, slow, torch_device, ) @@ -36,7 +35,7 @@ @is_pipeline_test -@require_torch_or_tf +@require_torch class TextToAudioPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_TEXT_TO_WAVEFORM_MAPPING # for now only test text_to_waveform and not text_to_spectrogram @@ -44,7 +43,7 @@ class TextToAudioPipelineTests(unittest.TestCase): @require_torch def test_small_musicgen_pt(self): music_generator = pipeline( - task="text-to-audio", model="facebook/musicgen-small", framework="pt", do_sample=False, max_new_tokens=5 + task="text-to-audio", model="facebook/musicgen-small", do_sample=False, max_new_tokens=5 ) outputs = music_generator("This is a test") @@ -56,7 +55,7 @@ def test_small_musicgen_pt(self): self.assertEqual([ANY(np.ndarray), ANY(np.ndarray)], audio) # test batching, this time with parameterization in the forward pass - music_generator = pipeline(task="text-to-audio", model="facebook/musicgen-small", framework="pt") + music_generator = pipeline(task="text-to-audio", model="facebook/musicgen-small") forward_params = {"do_sample": False, "max_new_tokens": 5} outputs = music_generator( ["This is a test", "This is a second test"], forward_params=forward_params, batch_size=2 @@ -67,9 +66,7 @@ def test_small_musicgen_pt(self): @slow @require_torch def test_medium_seamless_m4t_pt(self): - speech_generator = pipeline( - task="text-to-audio", model="facebook/hf-seamless-m4t-medium", framework="pt", max_new_tokens=5 - ) + speech_generator = pipeline(task="text-to-audio", model="facebook/hf-seamless-m4t-medium", max_new_tokens=5) for forward_params in [{"tgt_lang": "eng"}, {"return_intermediate_token_ids": True, "tgt_lang": "eng"}]: outputs = speech_generator("This is a test", forward_params=forward_params) @@ -90,7 +87,7 @@ def test_medium_seamless_m4t_pt(self): @slow @require_torch def test_small_bark_pt(self): - speech_generator = pipeline(task="text-to-audio", model="suno/bark-small", framework="pt") + speech_generator = pipeline(task="text-to-audio", model="suno/bark-small") forward_params = { # Using `do_sample=False` to force deterministic output @@ -140,7 +137,7 @@ def test_small_bark_pt(self): @slow @require_torch_accelerator def test_conversion_additional_tensor(self): - speech_generator = pipeline(task="text-to-audio", model="suno/bark-small", framework="pt", device=torch_device) + speech_generator = pipeline(task="text-to-audio", model="suno/bark-small", device=torch_device) processor = AutoProcessor.from_pretrained("suno/bark-small") forward_params = { @@ -178,7 +175,7 @@ def test_conversion_additional_tensor(self): @require_torch def test_vits_model_pt(self): - speech_generator = pipeline(task="text-to-audio", model="facebook/mms-tts-eng", framework="pt") + speech_generator = pipeline(task="text-to-audio", model="facebook/mms-tts-eng") outputs = speech_generator("This is a test") self.assertEqual(outputs["sampling_rate"], 16000) @@ -198,7 +195,7 @@ def test_vits_model_pt(self): @require_torch def test_forward_model_kwargs(self): # use vits - a forward model - speech_generator = pipeline(task="text-to-audio", model="kakao-enterprise/vits-vctk", framework="pt") + speech_generator = pipeline(task="text-to-audio", model="kakao-enterprise/vits-vctk") # for reproducibility set_seed(555) @@ -222,7 +219,7 @@ def test_forward_model_kwargs(self): @require_torch def test_generative_model_kwargs(self): # use musicgen - a generative model - music_generator = pipeline(task="text-to-audio", model="facebook/musicgen-small", framework="pt") + music_generator = pipeline(task="text-to-audio", model="facebook/musicgen-small") forward_params = { "do_sample": True, @@ -250,7 +247,7 @@ def test_generative_model_kwargs(self): @slow @require_torch def test_csm_model_pt(self): - speech_generator = pipeline(task="text-to-audio", model="sesame/csm-1b", framework="pt") + speech_generator = pipeline(task="text-to-audio", model="sesame/csm-1b") outputs = speech_generator("[0]This is a test") self.assertEqual(outputs["sampling_rate"], 24000) diff --git a/tests/pipelines/test_pipelines_token_classification.py b/tests/pipelines/test_pipelines_token_classification.py index c5a4d3b89aa8..5f04d3857cb8 100644 --- a/tests/pipelines/test_pipelines_token_classification.py +++ b/tests/pipelines/test_pipelines_token_classification.py @@ -18,7 +18,6 @@ from transformers import ( MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING, - TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING, AutoModelForTokenClassification, AutoTokenizer, TokenClassificationPipeline, @@ -51,14 +50,9 @@ @is_pipeline_test class TokenClassificationPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING - tf_model_mapping = TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING if not hasattr(model_mapping, "is_dummy"): model_mapping = {config: model for config, model in model_mapping.items() if config.__name__ not in _TO_SKIP} - if not hasattr(tf_model_mapping, "is_dummy"): - tf_model_mapping = { - config: model for config, model in tf_model_mapping.items() if config.__name__ not in _TO_SKIP - } def get_test_pipeline( self, @@ -550,7 +544,7 @@ def test_aggregation_strategy_byte_level_tokenizer(self): def test_aggregation_strategy_no_b_i_prefix(self): model_name = "sshleifer/tiny-dbmdz-bert-large-cased-finetuned-conll03-english" tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True) - token_classifier = pipeline(task="ner", model=model_name, tokenizer=tokenizer, framework="pt") + token_classifier = pipeline(task="ner", model=model_name, tokenizer=tokenizer) # Just to understand scores indexes in this test token_classifier.model.config.id2label = {0: "O", 1: "MISC", 2: "PER", 3: "ORG", 4: "LOC"} example = [ @@ -599,7 +593,7 @@ def test_aggregation_strategy_no_b_i_prefix(self): def test_aggregation_strategy(self): model_name = "sshleifer/tiny-dbmdz-bert-large-cased-finetuned-conll03-english" tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True) - token_classifier = pipeline(task="ner", model=model_name, tokenizer=tokenizer, framework="pt") + token_classifier = pipeline(task="ner", model=model_name, tokenizer=tokenizer) # Just to understand scores indexes in this test self.assertEqual( token_classifier.model.config.id2label, @@ -672,7 +666,7 @@ def test_aggregation_strategy(self): def test_aggregation_strategy_example2(self): model_name = "sshleifer/tiny-dbmdz-bert-large-cased-finetuned-conll03-english" tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True) - token_classifier = pipeline(task="ner", model=model_name, tokenizer=tokenizer, framework="pt") + token_classifier = pipeline(task="ner", model=model_name, tokenizer=tokenizer) # Just to understand scores indexes in this test self.assertEqual( token_classifier.model.config.id2label, @@ -748,7 +742,7 @@ def test_aggregation_strategy_offsets_with_leading_space(self): def test_gather_pre_entities(self): model_name = "sshleifer/tiny-dbmdz-bert-large-cased-finetuned-conll03-english" tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True) - token_classifier = pipeline(task="ner", model=model_name, tokenizer=tokenizer, framework="pt") + token_classifier = pipeline(task="ner", model=model_name, tokenizer=tokenizer) sentence = "Hello there" @@ -793,7 +787,7 @@ def test_gather_pre_entities(self): def test_word_heuristic_leading_space(self): model_name = "hf-internal-testing/tiny-random-deberta-v2" tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True) - token_classifier = pipeline(task="ner", model=model_name, tokenizer=tokenizer, framework="pt") + token_classifier = pipeline(task="ner", model=model_name, tokenizer=tokenizer) sentence = "I play the theremin" @@ -828,7 +822,7 @@ def test_word_heuristic_leading_space(self): def test_no_offset_tokenizer(self): model_name = "hf-internal-testing/tiny-bert-for-token-classification" tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False) - token_classifier = pipeline(task="token-classification", model=model_name, tokenizer=tokenizer, framework="pt") + token_classifier = pipeline(task="token-classification", model=model_name, tokenizer=tokenizer) outputs = token_classifier("This is a test !") self.assertEqual( nested_simplify(outputs), @@ -841,7 +835,7 @@ def test_no_offset_tokenizer(self): @require_torch def test_small_model_pt(self): model_name = "hf-internal-testing/tiny-bert-for-token-classification" - token_classifier = pipeline(task="token-classification", model=model_name, framework="pt") + token_classifier = pipeline(task="token-classification", model=model_name) outputs = token_classifier("This is a test !") self.assertEqual( nested_simplify(outputs), @@ -851,16 +845,14 @@ def test_small_model_pt(self): ], ) - token_classifier = pipeline( - task="token-classification", model=model_name, framework="pt", ignore_labels=["O", "I-MISC"] - ) + token_classifier = pipeline(task="token-classification", model=model_name, ignore_labels=["O", "I-MISC"]) outputs = token_classifier("This is a test !") self.assertEqual( nested_simplify(outputs), [], ) - token_classifier = pipeline(task="token-classification", model=model_name, framework="pt") + token_classifier = pipeline(task="token-classification", model=model_name) # Overload offset_mapping outputs = token_classifier( "This is a test !", offset_mapping=[(0, 0), (0, 1), (0, 2), (0, 0), (0, 0), (0, 0), (0, 0)] @@ -893,7 +885,7 @@ def test_small_model_pt(self): @require_torch def test_small_model_pt_fp16(self): model_name = "hf-internal-testing/tiny-bert-for-token-classification" - token_classifier = pipeline(task="token-classification", model=model_name, framework="pt", dtype=torch.float16) + token_classifier = pipeline(task="token-classification", model=model_name, dtype=torch.float16) outputs = token_classifier("This is a test !") self.assertEqual( nested_simplify(outputs), @@ -906,9 +898,7 @@ def test_small_model_pt_fp16(self): @require_torch def test_small_model_pt_bf16(self): model_name = "hf-internal-testing/tiny-bert-for-token-classification" - token_classifier = pipeline( - task="token-classification", model=model_name, framework="pt", dtype=torch.bfloat16 - ) + token_classifier = pipeline(task="token-classification", model=model_name, dtype=torch.bfloat16) outputs = token_classifier("This is a test !") self.assertEqual( nested_simplify(outputs), diff --git a/tests/pipelines/test_pipelines_translation.py b/tests/pipelines/test_pipelines_translation.py index 0bb34ba5e635..9f3225bee72e 100644 --- a/tests/pipelines/test_pipelines_translation.py +++ b/tests/pipelines/test_pipelines_translation.py @@ -18,7 +18,6 @@ from transformers import ( MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, - TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, MBart50TokenizerFast, MBartConfig, MBartForConditionalGeneration, @@ -33,7 +32,6 @@ @is_pipeline_test class TranslationPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING - tf_model_mapping = TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING def get_test_pipeline( self, @@ -81,7 +79,7 @@ def run_pipeline_test(self, translator, _): @require_torch def test_small_model_pt(self): - translator = pipeline("translation_en_to_ro", model="patrickvonplaten/t5-tiny-random", framework="pt") + translator = pipeline("translation_en_to_ro", model="patrickvonplaten/t5-tiny-random") outputs = translator("This is a test string", max_length=20) self.assertEqual( outputs, @@ -97,7 +95,7 @@ def test_small_model_pt(self): @require_torch def test_en_to_de_pt(self): - translator = pipeline("translation_en_to_de", model="patrickvonplaten/t5-tiny-random", framework="pt") + translator = pipeline("translation_en_to_de", model="patrickvonplaten/t5-tiny-random") outputs = translator("This is a test string", max_length=20) self.assertEqual( outputs, diff --git a/tests/pipelines/test_pipelines_video_classification.py b/tests/pipelines/test_pipelines_video_classification.py index d92281fc890d..cea7a94c3910 100644 --- a/tests/pipelines/test_pipelines_video_classification.py +++ b/tests/pipelines/test_pipelines_video_classification.py @@ -24,7 +24,6 @@ nested_simplify, require_av, require_torch, - require_torch_or_tf, require_vision, ) @@ -32,7 +31,7 @@ @is_pipeline_test -@require_torch_or_tf +@require_torch @require_vision @require_av class VideoClassificationPipelineTests(unittest.TestCase): diff --git a/tests/pipelines/test_pipelines_zero_shot.py b/tests/pipelines/test_pipelines_zero_shot.py index ed26e911ee57..9591936cedcd 100644 --- a/tests/pipelines/test_pipelines_zero_shot.py +++ b/tests/pipelines/test_pipelines_zero_shot.py @@ -16,7 +16,6 @@ from transformers import ( MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, - TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, Pipeline, ZeroShotClassificationPipeline, pipeline, @@ -43,14 +42,9 @@ @is_pipeline_test class ZeroShotClassificationPipelineTests(unittest.TestCase): model_mapping = MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING - tf_model_mapping = TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING if not hasattr(model_mapping, "is_dummy"): model_mapping = {config: model for config, model in model_mapping.items() if config.__name__ not in _TO_SKIP} - if not hasattr(tf_model_mapping, "is_dummy"): - tf_model_mapping = { - config: model for config, model in tf_model_mapping.items() if config.__name__ not in _TO_SKIP - } def get_test_pipeline( self, @@ -171,7 +165,6 @@ def test_truncation(self): zero_shot_classifier = pipeline( "zero-shot-classification", model="sshleifer/tiny-distilbert-base-cased-distilled-squad", - framework="pt", ) # There was a regression in 4.10 for this # Adding a test so we don't make the mistake again. @@ -185,7 +178,6 @@ def test_small_model_pt(self): zero_shot_classifier = pipeline( "zero-shot-classification", model="sshleifer/tiny-distilbert-base-cased-distilled-squad", - framework="pt", ) outputs = zero_shot_classifier( "Who are you voting for in 2020?", candidate_labels=["politics", "public health", "science"] @@ -205,7 +197,6 @@ def test_small_model_pt_fp16(self): zero_shot_classifier = pipeline( "zero-shot-classification", model="sshleifer/tiny-distilbert-base-cased-distilled-squad", - framework="pt", dtype=torch.float16, ) outputs = zero_shot_classifier( @@ -226,7 +217,6 @@ def test_small_model_pt_bf16(self): zero_shot_classifier = pipeline( "zero-shot-classification", model="sshleifer/tiny-distilbert-base-cased-distilled-squad", - framework="pt", dtype=torch.bfloat16, ) outputs = zero_shot_classifier( @@ -245,9 +235,7 @@ def test_small_model_pt_bf16(self): @slow @require_torch def test_large_model_pt(self): - zero_shot_classifier = pipeline( - "zero-shot-classification", model="FacebookAI/roberta-large-mnli", framework="pt" - ) + zero_shot_classifier = pipeline("zero-shot-classification", model="FacebookAI/roberta-large-mnli") outputs = zero_shot_classifier( "Who are you voting for in 2020?", candidate_labels=["politics", "public health", "science"] ) diff --git a/tests/pipelines/test_pipelines_zero_shot_audio_classification.py b/tests/pipelines/test_pipelines_zero_shot_audio_classification.py index 0f884240bf12..acd64d7705fb 100644 --- a/tests/pipelines/test_pipelines_zero_shot_audio_classification.py +++ b/tests/pipelines/test_pipelines_zero_shot_audio_classification.py @@ -46,10 +46,6 @@ def test_small_model_pt(self, dtype="float32"): def test_small_model_pt_fp16(self): self.test_small_model_pt(dtype="float16") - @unittest.skip(reason="No models are available in TF") - def test_small_model_tf(self): - pass - @slow @require_torch def test_large_model_pt(self): @@ -94,7 +90,3 @@ def test_large_model_pt(self): ] * 5, ) - - @unittest.skip(reason="No models are available in TF") - def test_large_model_tf(self): - pass diff --git a/tests/repo_utils/test_tests_fetcher.py b/tests/repo_utils/test_tests_fetcher.py index 727cb2affa08..0a7917e6033c 100644 --- a/tests/repo_utils/test_tests_fetcher.py +++ b/tests/repo_utils/test_tests_fetcher.py @@ -151,15 +151,14 @@ def create_tmp_repo(tmp_dir, models=None): example_dir = tmp_dir / "examples" example_dir.mkdir(exist_ok=True) - for framework in ["flax", "pytorch", "tensorflow"]: - framework_dir = example_dir / framework - framework_dir.mkdir(exist_ok=True) - with open(framework_dir / f"test_{framework}_examples.py", "w") as f: - f.write("""test_args = "run_glue.py"\n""") - glue_dir = framework_dir / "text-classification" - glue_dir.mkdir(exist_ok=True) - with open(glue_dir / "run_glue.py", "w") as f: - f.write("from transformers import BertModel\n\ncode") + framework_dir = example_dir / "pytorch" + framework_dir.mkdir(exist_ok=True) + with open(framework_dir / "test_pytorch_examples.py", "w") as f: + f.write("""test_args = "run_glue.py"\n""") + glue_dir = framework_dir / "text-classification" + glue_dir.mkdir(exist_ok=True) + with open(glue_dir / "run_glue.py", "w") as f: + f.write("from transformers import BertModel\n\ncode") repo.index.add(["examples", "src", "tests"]) repo.index.commit("Initial commit") @@ -525,27 +524,15 @@ def test_init_test_examples_dependencies(self): create_tmp_repo(tmp_folder) expected_example_deps = { - "examples/flax/test_flax_examples.py": [ - "examples/flax/text-classification/run_glue.py", - "examples/flax/test_flax_examples.py", - ], "examples/pytorch/test_pytorch_examples.py": [ "examples/pytorch/text-classification/run_glue.py", "examples/pytorch/test_pytorch_examples.py", ], - "examples/tensorflow/test_tensorflow_examples.py": [ - "examples/tensorflow/text-classification/run_glue.py", - "examples/tensorflow/test_tensorflow_examples.py", - ], } expected_examples = { - "examples/flax/test_flax_examples.py", - "examples/flax/text-classification/run_glue.py", "examples/pytorch/test_pytorch_examples.py", "examples/pytorch/text-classification/run_glue.py", - "examples/tensorflow/test_tensorflow_examples.py", - "examples/tensorflow/text-classification/run_glue.py", } with patch_transformer_repo_path(tmp_folder): @@ -565,12 +552,8 @@ def test_create_reverse_dependency_map(self): "src/transformers/__init__.py", "src/transformers/models/bert/__init__.py", "tests/models/bert/test_modeling_bert.py", - "examples/flax/test_flax_examples.py", - "examples/flax/text-classification/run_glue.py", "examples/pytorch/test_pytorch_examples.py", "examples/pytorch/text-classification/run_glue.py", - "examples/tensorflow/test_tensorflow_examples.py", - "examples/tensorflow/text-classification/run_glue.py", } assert set(reverse_map["src/transformers/models/bert/modeling_bert.py"]) == expected_bert_deps @@ -586,12 +569,8 @@ def test_create_reverse_dependency_map(self): "src/transformers/modeling_utils.py", "tests/test_modeling_common.py", "tests/models/bert/test_modeling_bert.py", - "examples/flax/test_flax_examples.py", - "examples/flax/text-classification/run_glue.py", "examples/pytorch/test_pytorch_examples.py", "examples/pytorch/text-classification/run_glue.py", - "examples/tensorflow/test_tensorflow_examples.py", - "examples/tensorflow/text-classification/run_glue.py", } assert set(reverse_map["src/transformers/__init__.py"]) == expected_init_deps @@ -600,12 +579,8 @@ def test_create_reverse_dependency_map(self): "src/transformers/models/bert/configuration_bert.py", "src/transformers/models/bert/modeling_bert.py", "tests/models/bert/test_modeling_bert.py", - "examples/flax/test_flax_examples.py", - "examples/flax/text-classification/run_glue.py", "examples/pytorch/test_pytorch_examples.py", "examples/pytorch/text-classification/run_glue.py", - "examples/tensorflow/test_tensorflow_examples.py", - "examples/tensorflow/text-classification/run_glue.py", } assert set(reverse_map["src/transformers/models/bert/__init__.py"]) == expected_init_deps @@ -620,12 +595,8 @@ def test_create_reverse_dependency_map(self): "src/transformers/models/bert/configuration_bert.py", "src/transformers/models/bert/modeling_bert.py", "tests/models/bert/test_modeling_bert.py", - "examples/flax/test_flax_examples.py", - "examples/flax/text-classification/run_glue.py", "examples/pytorch/test_pytorch_examples.py", "examples/pytorch/text-classification/run_glue.py", - "examples/tensorflow/test_tensorflow_examples.py", - "examples/tensorflow/text-classification/run_glue.py", } assert set(reverse_map["src/transformers/models/bert/__init__.py"]) == expected_init_deps @@ -639,9 +610,7 @@ def test_infer_tests_to_run(self): commit_changes("src/transformers/models/bert/modeling_bert.py", BERT_MODEL_FILE_NEW_CODE, repo) example_tests = { - "examples/flax/test_flax_examples.py", "examples/pytorch/test_pytorch_examples.py", - "examples/tensorflow/test_tensorflow_examples.py", } with patch_transformer_repo_path(tmp_folder): diff --git a/tests/sagemaker/conftest.py b/tests/sagemaker/conftest.py index 89b89966d542..5daf3c4147f9 100644 --- a/tests/sagemaker/conftest.py +++ b/tests/sagemaker/conftest.py @@ -12,7 +12,6 @@ @dataclass class SageMakerTestEnvironment: - framework: str role = "arn:aws:iam::558105141721:role/sagemaker_execution_role" hyperparameters = { "task_name": "mnli", @@ -30,35 +29,25 @@ class SageMakerTestEnvironment: @property def metric_definitions(self) -> str: - if self.framework == "pytorch": - return [ - {"Name": "train_runtime", "Regex": r"train_runtime.*=\D*(.*?)$"}, - {"Name": "eval_accuracy", "Regex": r"eval_accuracy.*=\D*(.*?)$"}, - {"Name": "eval_loss", "Regex": r"eval_loss.*=\D*(.*?)$"}, - ] - else: - return [ - {"Name": "train_runtime", "Regex": r"train_runtime.*=\D*(.*?)$"}, - {"Name": "eval_accuracy", "Regex": r"loss.*=\D*(.*?)]?$"}, - {"Name": "eval_loss", "Regex": r"sparse_categorical_accuracy.*=\D*(.*?)]?$"}, - ] + return [ + {"Name": "train_runtime", "Regex": r"train_runtime.*=\D*(.*?)$"}, + {"Name": "eval_accuracy", "Regex": r"eval_accuracy.*=\D*(.*?)$"}, + {"Name": "eval_loss", "Regex": r"eval_loss.*=\D*(.*?)$"}, + ] @property def base_job_name(self) -> str: - return f"{self.framework}-transformers-test" + return "pytorch-transformers-test" @property def test_path(self) -> str: - return f"./tests/sagemaker/scripts/{self.framework}" + return "./tests/sagemaker/scripts/pytorch" @property def image_uri(self) -> str: - if self.framework == "pytorch": - return "763104351884.dkr.ecr.us-east-1.amazonaws.com/huggingface-pytorch-training:1.7.1-transformers4.6.1-gpu-py36-cu110-ubuntu18.04" - else: - return "763104351884.dkr.ecr.us-east-1.amazonaws.com/huggingface-tensorflow-training:2.4.1-transformers4.6.1-gpu-py37-cu110-ubuntu18.04" + return "763104351884.dkr.ecr.us-east-1.amazonaws.com/huggingface-pytorch-training:1.7.1-transformers4.6.1-gpu-py36-cu110-ubuntu18.04" @pytest.fixture(scope="class") def sm_env(request): - request.cls.env = SageMakerTestEnvironment(framework=request.cls.framework) + request.cls.env = SageMakerTestEnvironment() diff --git a/tests/sagemaker/scripts/tensorflow/run_tf.py b/tests/sagemaker/scripts/tensorflow/run_tf.py deleted file mode 100644 index a5b8e3fe1f05..000000000000 --- a/tests/sagemaker/scripts/tensorflow/run_tf.py +++ /dev/null @@ -1,104 +0,0 @@ -import argparse -import logging -import sys -import time - -import tensorflow as tf -from datasets import load_dataset -from packaging.version import parse - -from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - - -try: - import tf_keras as keras -except (ModuleNotFoundError, ImportError): - import keras - - if parse(keras.__version__).major > 2: - raise ValueError( - "Your currently installed version of Keras is Keras 3, but this is not yet supported in " - "Transformers. Please install the backwards-compatible tf-keras package with " - "`pip install tf-keras`." - ) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - - # Hyperparameters sent by the client are passed as command-line arguments to the script. - parser.add_argument("--epochs", type=int, default=1) - parser.add_argument("--per_device_train_batch_size", type=int, default=16) - parser.add_argument("--per_device_eval_batch_size", type=int, default=8) - parser.add_argument("--model_name_or_path", type=str) - parser.add_argument("--learning_rate", type=str, default=5e-5) - parser.add_argument("--do_train", type=bool, default=True) - parser.add_argument("--do_eval", type=bool, default=True) - parser.add_argument("--output_dir", type=str) - - args, _ = parser.parse_known_args() - - # overwrite batch size until we have tf_glue.py - args.per_device_train_batch_size = 16 - args.per_device_eval_batch_size = 16 - - # Set up logging - logger = logging.getLogger(__name__) - - logging.basicConfig( - level=logging.getLevelName("INFO"), - handlers=[logging.StreamHandler(sys.stdout)], - format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", - ) - - # Load model and tokenizer - model = TFAutoModelForSequenceClassification.from_pretrained(args.model_name_or_path) - tokenizer = AutoTokenizer.from_pretrained(args.model_name_or_path) - - # Load dataset - train_dataset, test_dataset = load_dataset("stanfordnlp/imdb", split=["train", "test"]) - train_dataset = train_dataset.shuffle().select(range(5000)) # smaller the size for train dataset to 5k - test_dataset = test_dataset.shuffle().select(range(500)) # smaller the size for test dataset to 500 - - # Preprocess train dataset - train_dataset = train_dataset.map( - lambda e: tokenizer(e["text"], truncation=True, padding="max_length"), batched=True - ) - train_dataset.set_format(type="tensorflow", columns=["input_ids", "attention_mask", "label"]) - - train_features = { - x: train_dataset[x].to_tensor(default_value=0, shape=[None, tokenizer.model_max_length]) - for x in ["input_ids", "attention_mask"] - } - tf_train_dataset = tf.data.Dataset.from_tensor_slices((train_features, train_dataset["label"])).batch( - args.per_device_train_batch_size - ) - - # Preprocess test dataset - test_dataset = test_dataset.map( - lambda e: tokenizer(e["text"], truncation=True, padding="max_length"), batched=True - ) - test_dataset.set_format(type="tensorflow", columns=["input_ids", "attention_mask", "label"]) - - test_features = { - x: test_dataset[x].to_tensor(default_value=0, shape=[None, tokenizer.model_max_length]) - for x in ["input_ids", "attention_mask"] - } - tf_test_dataset = tf.data.Dataset.from_tensor_slices((test_features, test_dataset["label"])).batch( - args.per_device_eval_batch_size - ) - - # fine optimizer and loss - optimizer = keras.optimizers.Adam(learning_rate=args.learning_rate) - loss = keras.losses.SparseCategoricalCrossentropy(from_logits=True) - metrics = [keras.metrics.SparseCategoricalAccuracy()] - model.compile(optimizer=optimizer, loss=loss, metrics=metrics) - - start_train_time = time.time() - train_results = model.fit(tf_train_dataset, epochs=args.epochs, batch_size=args.per_device_train_batch_size) - end_train_time = time.time() - start_train_time - - logger.info("*** Train ***") - logger.info(f"train_runtime = {end_train_time}") - for key, value in train_results.history.items(): - logger.info(f" {key} = {value}") diff --git a/tests/sagemaker/test_multi_node_data_parallel.py b/tests/sagemaker/test_multi_node_data_parallel.py index 2ea029a28551..3f2fd7c04166 100644 --- a/tests/sagemaker/test_multi_node_data_parallel.py +++ b/tests/sagemaker/test_multi_node_data_parallel.py @@ -23,36 +23,26 @@ @parameterized_class( [ { - "framework": "pytorch", "script": "run_glue.py", "model_name_or_path": "distilbert/distilbert-base-cased", "instance_type": "ml.p3.16xlarge", "results": {"train_runtime": 650, "eval_accuracy": 0.7, "eval_loss": 0.6}, }, { - "framework": "pytorch", "script": "run_ddp.py", "model_name_or_path": "distilbert/distilbert-base-cased", "instance_type": "ml.p3.16xlarge", "results": {"train_runtime": 600, "eval_accuracy": 0.7, "eval_loss": 0.6}, }, - { - "framework": "tensorflow", - "script": "run_tf_dist.py", - "model_name_or_path": "distilbert/distilbert-base-cased", - "instance_type": "ml.p3.16xlarge", - "results": {"train_runtime": 600, "eval_accuracy": 0.6, "eval_loss": 0.7}, - }, ] ) class MultiNodeTest(unittest.TestCase): def setUp(self): - if self.framework == "pytorch": - subprocess.run( - f"cp ./examples/pytorch/text-classification/run_glue.py {self.env.test_path}/run_glue.py".split(), - encoding="utf-8", - check=True, - ) + subprocess.run( + f"cp ./examples/pytorch/text-classification/run_glue.py {self.env.test_path}/run_glue.py".split(), + encoding="utf-8", + check=True, + ) assert hasattr(self, "env") def create_estimator(self, instance_count): diff --git a/tests/sagemaker/test_multi_node_model_parallel.py b/tests/sagemaker/test_multi_node_model_parallel.py index 216d31de4710..818028a75783 100644 --- a/tests/sagemaker/test_multi_node_model_parallel.py +++ b/tests/sagemaker/test_multi_node_model_parallel.py @@ -23,14 +23,12 @@ @parameterized_class( [ { - "framework": "pytorch", "script": "run_glue_model_parallelism.py", "model_name_or_path": "FacebookAI/roberta-large", "instance_type": "ml.p3dn.24xlarge", "results": {"train_runtime": 1600, "eval_accuracy": 0.3, "eval_loss": 1.2}, }, { - "framework": "pytorch", "script": "run_glue.py", "model_name_or_path": "FacebookAI/roberta-large", "instance_type": "ml.p3dn.24xlarge", @@ -40,12 +38,11 @@ ) class MultiNodeTest(unittest.TestCase): def setUp(self): - if self.framework == "pytorch": - subprocess.run( - f"cp ./examples/pytorch/text-classification/run_glue.py {self.env.test_path}/run_glue.py".split(), - encoding="utf-8", - check=True, - ) + subprocess.run( + f"cp ./examples/pytorch/text-classification/run_glue.py {self.env.test_path}/run_glue.py".split(), + encoding="utf-8", + check=True, + ) assert hasattr(self, "env") def create_estimator(self, instance_count): diff --git a/tests/sagemaker/test_single_node_gpu.py b/tests/sagemaker/test_single_node_gpu.py index 53d966bd1e85..7fc764810eb0 100644 --- a/tests/sagemaker/test_single_node_gpu.py +++ b/tests/sagemaker/test_single_node_gpu.py @@ -23,29 +23,20 @@ @parameterized_class( [ { - "framework": "pytorch", "script": "run_glue.py", "model_name_or_path": "distilbert/distilbert-base-cased", "instance_type": "ml.g4dn.xlarge", "results": {"train_runtime": 650, "eval_accuracy": 0.6, "eval_loss": 0.9}, }, - { - "framework": "tensorflow", - "script": "run_tf.py", - "model_name_or_path": "distilbert/distilbert-base-cased", - "instance_type": "ml.g4dn.xlarge", - "results": {"train_runtime": 600, "eval_accuracy": 0.3, "eval_loss": 0.9}, - }, ] ) class SingleNodeTest(unittest.TestCase): def setUp(self): - if self.framework == "pytorch": - subprocess.run( - f"cp ./examples/pytorch/text-classification/run_glue.py {self.env.test_path}/run_glue.py".split(), - encoding="utf-8", - check=True, - ) + subprocess.run( + f"cp ./examples/pytorch/text-classification/run_glue.py {self.env.test_path}/run_glue.py".split(), + encoding="utf-8", + check=True, + ) assert hasattr(self, "env") def create_estimator(self, instance_count=1): diff --git a/tests/test_pipeline_mixin.py b/tests/test_pipeline_mixin.py index aae6ff9413f1..5002a3e9b946 100644 --- a/tests/test_pipeline_mixin.py +++ b/tests/test_pipeline_mixin.py @@ -56,7 +56,6 @@ require_pytesseract, require_timm, require_torch, - require_torch_or_tf, require_vision, ) from transformers.utils import direct_transformers_import, logging @@ -143,7 +142,6 @@ test = task_info["test"] task_info["mapping"] = { "pt": getattr(test, "model_mapping", None), - "tf": getattr(test, "tf_model_mapping", None), } @@ -171,7 +169,6 @@ class PipelineTesterMixin: model_tester = None pipeline_model_mapping = None - supported_frameworks = ["pt", "tf"] def run_task_tests(self, task, dtype="float32"): """Run pipeline tests for a specific `task` @@ -200,12 +197,6 @@ def run_task_tests(self, task, dtype="float32"): model_arch_name = model_architecture.__name__ model_type = model_architecture.config_class.model_type - # Get the canonical name - for _prefix in ["Flax", "TF"]: - if model_arch_name.startswith(_prefix): - model_arch_name = model_arch_name[len(_prefix) :] - break - if model_arch_name not in tiny_model_summary: continue @@ -562,7 +553,7 @@ def test_pipeline_fill_mask_fp16(self): self.run_task_tests(task="fill-mask", dtype="float16") @is_pipeline_test - @require_torch_or_tf + @require_torch @require_vision def test_pipeline_image_classification(self): self.run_task_tests(task="image-classification") @@ -698,7 +689,7 @@ def test_pipeline_text_classification_fp16(self): self.run_task_tests(task="text-classification", dtype="float16") @is_pipeline_test - @require_torch_or_tf + @require_torch def test_pipeline_text_generation(self): self.run_task_tests(task="text-generation") @@ -736,7 +727,7 @@ def test_pipeline_translation_fp16(self): self.run_task_tests(task="translation", dtype="float16") @is_pipeline_test - @require_torch_or_tf + @require_torch @require_vision @require_av def test_pipeline_video_classification(self): diff --git a/tests/test_tokenization_common.py b/tests/test_tokenization_common.py index b0e6bcf2ce29..c0d025e1e23d 100644 --- a/tests/test_tokenization_common.py +++ b/tests/test_tokenization_common.py @@ -42,9 +42,7 @@ SpecialTokensMixin, Trainer, TrainingArguments, - is_flax_available, is_mlx_available, - is_tf_available, is_torch_available, logging, ) @@ -67,7 +65,7 @@ if TYPE_CHECKING: - from transformers import PretrainedConfig, PreTrainedModel, TFPreTrainedModel + from transformers import PretrainedConfig, PreTrainedModel def use_cache_if_possible(func): @@ -122,11 +120,11 @@ def filter_roberta_detectors(_, pretrained_name: str): def merge_model_tokenizer_mappings( - model_mapping: dict["PretrainedConfig", Union["PreTrainedModel", "TFPreTrainedModel"]], + model_mapping: dict["PretrainedConfig", "PreTrainedModel"], tokenizer_mapping: dict["PretrainedConfig", tuple["PreTrainedTokenizer", "PreTrainedTokenizerFast"]], ) -> dict[ Union["PreTrainedTokenizer", "PreTrainedTokenizerFast"], - tuple["PretrainedConfig", Union["PreTrainedModel", "TFPreTrainedModel"]], + tuple["PretrainedConfig", "PreTrainedModel"], ]: configurations = list(model_mapping.keys()) model_tokenizer_mapping = OrderedDict([]) @@ -4703,18 +4701,6 @@ def test_empty_input_string(self): tokenizer_return_type.append("np") output_tensor_type.append(np.int64) - if is_tf_available(): - import tensorflow as tf - - tokenizer_return_type.append("tf") - output_tensor_type.append(tf.int32) - - if is_flax_available(): - import jax.numpy as jnp - - tokenizer_return_type.append("jax") - output_tensor_type.append(jnp.int32) - if is_mlx_available(): import mlx.core as mx @@ -4722,7 +4708,7 @@ def test_empty_input_string(self): output_tensor_type.append(mx.int32) if len(tokenizer_return_type) == 0: - self.skipTest(reason="No expected framework from PT, TF, JAX or MLX found") + self.skipTest(reason="No expected framework from PT, or MLX found") tokenizers = self.get_tokenizers() for tokenizer in tokenizers: diff --git a/tests/tokenization/test_tokenization_utils.py b/tests/tokenization/test_tokenization_utils.py index fc74223110f8..e1d98ae8ba4f 100644 --- a/tests/tokenization/test_tokenization_utils.py +++ b/tests/tokenization/test_tokenization_utils.py @@ -92,7 +92,6 @@ def test_pretrained_tokenizers(self): self.check_tokenizer_from_pretrained(GPT2Tokenizer) def test_tensor_type_from_str(self): - self.assertEqual(TensorType("tf"), TensorType.TENSORFLOW) self.assertEqual(TensorType("pt"), TensorType.PYTORCH) self.assertEqual(TensorType("np"), TensorType.NUMPY) diff --git a/tests/utils/import_structures/import_structure_raw_register.py b/tests/utils/import_structures/import_structure_raw_register.py index a1df4a9c2e93..b57772e901b9 100644 --- a/tests/utils/import_structures/import_structure_raw_register.py +++ b/tests/utils/import_structures/import_structure_raw_register.py @@ -28,19 +28,19 @@ def a0(): pass -@requires(backends=("torch", "tf")) +@requires(backends=("torch",)) class A1: def __init__(self): pass -@requires(backends=("torch", "tf")) +@requires(backends=("torch",)) def a1(): pass @requires( - backends=("torch", "tf") + backends=("torch",) ) class A2: def __init__(self): @@ -48,7 +48,7 @@ def __init__(self): @requires( - backends=("torch", "tf") + backends=("torch",) ) def a2(): pass @@ -57,7 +57,6 @@ def a2(): @requires( backends=( "torch", - "tf" ) ) class A3: @@ -68,7 +67,6 @@ def __init__(self): @requires( backends=( "torch", - "tf" ) ) def a3(): diff --git a/tests/utils/import_structures/import_structure_register_with_comments.py b/tests/utils/import_structures/import_structure_register_with_comments.py index aed2b196ca68..9d367cb10772 100644 --- a/tests/utils/import_structures/import_structure_register_with_comments.py +++ b/tests/utils/import_structures/import_structure_register_with_comments.py @@ -30,27 +30,27 @@ def b0(): pass -@requires(backends=("torch", "tf")) +@requires(backends=("torch",)) # That's a statement class B1: def __init__(self): pass -@requires(backends=("torch", "tf")) +@requires(backends=("torch",)) # That's a statement def b1(): pass -@requires(backends=("torch", "tf")) +@requires(backends=("torch",)) # That's a statement class B2: def __init__(self): pass -@requires(backends=("torch", "tf")) +@requires(backends=("torch",)) # That's a statement def b2(): pass @@ -59,7 +59,6 @@ def b2(): @requires( backends=( "torch", - "tf" ) ) # That's a statement @@ -71,7 +70,6 @@ def __init__(self): @requires( backends=( "torch", - "tf" ) ) # That's a statement diff --git a/tests/utils/test_auto_docstring.py b/tests/utils/test_auto_docstring.py index 1874631f5e87..4dc3ec1efb27 100644 --- a/tests/utils/test_auto_docstring.py +++ b/tests/utils/test_auto_docstring.py @@ -26,13 +26,13 @@ GEMMA3_IMAGE_PROCESSOR_FAST_DOCSTRING = """\nConstructs a fast Gemma3 image processor.\n\nParameters:\n do_resize (`Optional[bool]`, defaults to `True`):\n Whether to resize the image.\n size (`Optional[dict[str, int]]`, defaults to `{\'height\': 224, \'width\': 224}`):\n Describes the maximum input dimensions to the model.\n default_to_square (`Optional[bool]`, defaults to `True`):\n Whether to default to a square image when resizing, if size is an int.\n resample (`Union[PILImageResampling, F.InterpolationMode, NoneType]`, defaults to `2`):\n Resampling filter to use if resizing the image. This can be one of the enum `PILImageResampling`. Only\n has an effect if `do_resize` is set to `True`.\n do_center_crop (`Optional[bool]`, defaults to `None`):\n Whether to center crop the image.\n crop_size (`Optional[dict[str, int]]`, defaults to `None`):\n Size of the output image after applying `center_crop`.\n do_rescale (`Optional[bool]`, defaults to `True`):\n Whether to rescale the image.\n rescale_factor (`Union[int, float, NoneType]`, defaults to `0.00392156862745098`):\n Rescale factor to rescale the image by if `do_rescale` is set to `True`.\n do_normalize (`Optional[bool]`, defaults to `True`):\n Whether to normalize the image.\n image_mean (`Union[float, list[float], NoneType]`, defaults to `[0.5, 0.5, 0.5]`):\n Image mean to use for normalization. Only has an effect if `do_normalize` is set to `True`.\n image_std (`Union[float, list[float], NoneType]`, defaults to `[0.5, 0.5, 0.5]`):\n Image standard deviation to use for normalization. Only has an effect if `do_normalize` is set to\n `True`.\n do_convert_rgb (`Optional[bool]`, defaults to `None`):\n Whether to convert the image to RGB.\n return_tensors (`Union[str, ~utils.generic.TensorType, NoneType]`, defaults to `None`):\n Returns stacked tensors if set to `pt, otherwise returns a list of tensors.\n data_format (`Optional[~image_utils.ChannelDimension]`, defaults to `ChannelDimension.FIRST`):\n Only `ChannelDimension.FIRST` is supported. Added for compatibility with slow processors.\n input_data_format (`Union[str, ~image_utils.ChannelDimension, NoneType]`, defaults to `None`):\n The channel dimension format for the input image. If unset, the channel dimension format is inferred\n from the input image. Can be one of:\n - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.\n - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.\n - `"none"` or `ChannelDimension.NONE`: image in (height, width) format.\n device (`Optional[torch.device]`, defaults to `None`):\n The device to process the images on. If unset, the device is inferred from the input images.\n do_pan_and_scan (`Optional[bool]`, defaults to `None`):\n Whether to apply `pan_and_scan` to images.\n pan_and_scan_min_crop_size (`Optional[int]`, defaults to `None`):\n Minimum size of each crop in pan and scan.\n pan_and_scan_max_num_crops (`Optional[int]`, defaults to `None`):\n Maximum number of crops per image in pan and scan.\n pan_and_scan_min_ratio_to_activate (`Optional[float]`, defaults to `None`):\n Minimum aspect ratio to activate pan and scan.\n""" -GEMMA3_IMAGE_PROCESSOR_FAST_PREPROCESS_DOCSTRING = """ Args:\n images (`Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, list[\'PIL.Image.Image\'], list[numpy.ndarray], list[\'torch.Tensor\']]`):\n Image to preprocess. Expects a single or batch of images with pixel values ranging from 0 to 255. If\n passing in images with pixel values between 0 and 1, set `do_rescale=False`.\n do_resize (`Optional[bool]`):\n Whether to resize the image.\n size (`Optional[dict[str, int]]`):\n Describes the maximum input dimensions to the model.\n default_to_square (`Optional[bool]`):\n Whether to default to a square image when resizing, if size is an int.\n resample (`Union[PILImageResampling, F.InterpolationMode, NoneType]`):\n Resampling filter to use if resizing the image. This can be one of the enum `PILImageResampling`. Only\n has an effect if `do_resize` is set to `True`.\n do_center_crop (`Optional[bool]`):\n Whether to center crop the image.\n crop_size (`Optional[dict[str, int]]`):\n Size of the output image after applying `center_crop`.\n do_rescale (`Optional[bool]`):\n Whether to rescale the image.\n rescale_factor (`Union[int, float, NoneType]`):\n Rescale factor to rescale the image by if `do_rescale` is set to `True`.\n do_normalize (`Optional[bool]`):\n Whether to normalize the image.\n image_mean (`Union[float, list[float], NoneType]`):\n Image mean to use for normalization. Only has an effect if `do_normalize` is set to `True`.\n image_std (`Union[float, list[float], NoneType]`):\n Image standard deviation to use for normalization. Only has an effect if `do_normalize` is set to\n `True`.\n do_convert_rgb (`Optional[bool]`):\n Whether to convert the image to RGB.\n return_tensors (`Union[str, ~utils.generic.TensorType, NoneType]`):\n Returns stacked tensors if set to `pt, otherwise returns a list of tensors.\n data_format (`Optional[~image_utils.ChannelDimension]`):\n Only `ChannelDimension.FIRST` is supported. Added for compatibility with slow processors.\n input_data_format (`Union[str, ~image_utils.ChannelDimension, NoneType]`):\n The channel dimension format for the input image. If unset, the channel dimension format is inferred\n from the input image. Can be one of:\n - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.\n - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.\n - `"none"` or `ChannelDimension.NONE`: image in (height, width) format.\n device (`Optional[torch.device]`):\n The device to process the images on. If unset, the device is inferred from the input images.\n do_pan_and_scan (`Optional[bool]`):\n Whether to apply `pan_and_scan` to images.\n pan_and_scan_min_crop_size (`Optional[int]`):\n Minimum size of each crop in pan and scan.\n pan_and_scan_max_num_crops (`Optional[int]`):\n Maximum number of crops per image in pan and scan.\n pan_and_scan_min_ratio_to_activate (`Optional[float]`):\n Minimum aspect ratio to activate pan and scan.\n\n Returns:\n ``:\n - **data** (`dict`) -- Dictionary of lists/arrays/tensors returned by the __call__ method (\'pixel_values\', etc.).\n - **tensor_type** (`Union[None, str, TensorType]`, *optional*) -- You can give a tensor_type here to convert the lists of integers in PyTorch/TensorFlow/Numpy Tensors at\n initialization.\n""" +GEMMA3_IMAGE_PROCESSOR_FAST_PREPROCESS_DOCSTRING = """ Args:\n images (`Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, list[\'PIL.Image.Image\'], list[numpy.ndarray], list[\'torch.Tensor\']]`):\n Image to preprocess. Expects a single or batch of images with pixel values ranging from 0 to 255. If\n passing in images with pixel values between 0 and 1, set `do_rescale=False`.\n do_resize (`Optional[bool]`):\n Whether to resize the image.\n size (`Optional[dict[str, int]]`):\n Describes the maximum input dimensions to the model.\n default_to_square (`Optional[bool]`):\n Whether to default to a square image when resizing, if size is an int.\n resample (`Union[PILImageResampling, F.InterpolationMode, NoneType]`):\n Resampling filter to use if resizing the image. This can be one of the enum `PILImageResampling`. Only\n has an effect if `do_resize` is set to `True`.\n do_center_crop (`Optional[bool]`):\n Whether to center crop the image.\n crop_size (`Optional[dict[str, int]]`):\n Size of the output image after applying `center_crop`.\n do_rescale (`Optional[bool]`):\n Whether to rescale the image.\n rescale_factor (`Union[int, float, NoneType]`):\n Rescale factor to rescale the image by if `do_rescale` is set to `True`.\n do_normalize (`Optional[bool]`):\n Whether to normalize the image.\n image_mean (`Union[float, list[float], NoneType]`):\n Image mean to use for normalization. Only has an effect if `do_normalize` is set to `True`.\n image_std (`Union[float, list[float], NoneType]`):\n Image standard deviation to use for normalization. Only has an effect if `do_normalize` is set to\n `True`.\n do_convert_rgb (`Optional[bool]`):\n Whether to convert the image to RGB.\n return_tensors (`Union[str, ~utils.generic.TensorType, NoneType]`):\n Returns stacked tensors if set to `pt, otherwise returns a list of tensors.\n data_format (`Optional[~image_utils.ChannelDimension]`):\n Only `ChannelDimension.FIRST` is supported. Added for compatibility with slow processors.\n input_data_format (`Union[str, ~image_utils.ChannelDimension, NoneType]`):\n The channel dimension format for the input image. If unset, the channel dimension format is inferred\n from the input image. Can be one of:\n - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.\n - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.\n - `"none"` or `ChannelDimension.NONE`: image in (height, width) format.\n device (`Optional[torch.device]`):\n The device to process the images on. If unset, the device is inferred from the input images.\n do_pan_and_scan (`Optional[bool]`):\n Whether to apply `pan_and_scan` to images.\n pan_and_scan_min_crop_size (`Optional[int]`):\n Minimum size of each crop in pan and scan.\n pan_and_scan_max_num_crops (`Optional[int]`):\n Maximum number of crops per image in pan and scan.\n pan_and_scan_min_ratio_to_activate (`Optional[float]`):\n Minimum aspect ratio to activate pan and scan.\n\n Returns:\n ``:\n - **data** (`dict`) -- Dictionary of lists/arrays/tensors returned by the __call__ method (\'pixel_values\', etc.).\n - **tensor_type** (`Union[None, str, TensorType]`, *optional*) -- You can give a tensor_type here to convert the lists of integers in PyTorch/Numpy Tensors at\n initialization.\n""" class AutoDocstringTest(unittest.TestCase): pass # def test_modeling_docstring(self): - # llama_docstring = " Args:\n images (`Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, list['PIL.Image.Image'], list[numpy.ndarray], list['torch.Tensor']]`):\n Image to preprocess. Expects a single or batch of images with pixel values ranging from 0 to 255. If\n passing in images with pixel values between 0 and 1, set `do_rescale=False`.\n do_resize (`Optional[bool]`):\n Whether to resize the image.\n size (`Optional[dict[str, int]]`):\n Describes the maximum input dimensions to the model.\n default_to_square (`Optional[bool]`):\n Whether to default to a square image when resizing, if size is an int.\n resample (`Union[PILImageResampling, F.InterpolationMode, NoneType]`):\n Resampling filter to use if resizing the image. This can be one of the enum `PILImageResampling`. Only\n has an effect if `do_resize` is set to `True`.\n do_center_crop (`Optional[bool]`):\n Whether to center crop the image.\n crop_size (`Optional[dict[str, int]]`):\n Size of the output image after applying `center_crop`.\n do_rescale (`Optional[bool]`):\n Whether to rescale the image.\n rescale_factor (`Union[int, float, NoneType]`):\n Rescale factor to rescale the image by if `do_rescale` is set to `True`.\n do_normalize (`Optional[bool]`):\n Whether to normalize the image.\n image_mean (`Union[float, list[float], NoneType]`):\n Image mean to use for normalization. Only has an effect if `do_normalize` is set to `True`.\n image_std (`Union[float, list[float], NoneType]`):\n Image standard deviation to use for normalization. Only has an effect if `do_normalize` is set to\n `True`.\n do_convert_rgb (`Optional[bool]`):\n Whether to convert the image to RGB.\n return_tensors (`Union[str, ~utils.generic.TensorType, NoneType]`):\n Returns stacked tensors if set to `pt, otherwise returns a list of tensors.\n data_format (`Optional[~image_utils.ChannelDimension]`):\n Only `ChannelDimension.FIRST` is supported. Added for compatibility with slow processors.\n input_data_format (`Union[str, ~image_utils.ChannelDimension, NoneType]`):\n The channel dimension format for the input image. If unset, the channel dimension format is inferred\n from the input image. Can be one of:\n - `\"channels_first\"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.\n - `\"channels_last\"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.\n - `\"none\"` or `ChannelDimension.NONE`: image in (height, width) format.\n device (`Optional[torch.device]`):\n The device to process the images on. If unset, the device is inferred from the input images.\n do_pan_and_scan (`Optional[bool]`):\n Whether to apply `pan_and_scan` to images.\n pan_and_scan_min_crop_size (`Optional[int]`):\n Minimum size of each crop in pan and scan.\n pan_and_scan_max_num_crops (`Optional[int]`):\n Maximum number of crops per image in pan and scan.\n pan_and_scan_min_ratio_to_activate (`Optional[float]`):\n Minimum aspect ratio to activate pan and scan.\n\n Returns:\n ``:\n - **data** (`dict`) -- Dictionary of lists/arrays/tensors returned by the __call__ method ('pixel_values', etc.).\n - **tensor_type** (`Union[None, str, TensorType]`, *optional*) -- You can give a tensor_type here to convert the lists of integers in PyTorch/TensorFlow/Numpy Tensors at\n initialization.\n" + # llama_docstring = " Args:\n images (`Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, list['PIL.Image.Image'], list[numpy.ndarray], list['torch.Tensor']]`):\n Image to preprocess. Expects a single or batch of images with pixel values ranging from 0 to 255. If\n passing in images with pixel values between 0 and 1, set `do_rescale=False`.\n do_resize (`Optional[bool]`):\n Whether to resize the image.\n size (`Optional[dict[str, int]]`):\n Describes the maximum input dimensions to the model.\n default_to_square (`Optional[bool]`):\n Whether to default to a square image when resizing, if size is an int.\n resample (`Union[PILImageResampling, F.InterpolationMode, NoneType]`):\n Resampling filter to use if resizing the image. This can be one of the enum `PILImageResampling`. Only\n has an effect if `do_resize` is set to `True`.\n do_center_crop (`Optional[bool]`):\n Whether to center crop the image.\n crop_size (`Optional[dict[str, int]]`):\n Size of the output image after applying `center_crop`.\n do_rescale (`Optional[bool]`):\n Whether to rescale the image.\n rescale_factor (`Union[int, float, NoneType]`):\n Rescale factor to rescale the image by if `do_rescale` is set to `True`.\n do_normalize (`Optional[bool]`):\n Whether to normalize the image.\n image_mean (`Union[float, list[float], NoneType]`):\n Image mean to use for normalization. Only has an effect if `do_normalize` is set to `True`.\n image_std (`Union[float, list[float], NoneType]`):\n Image standard deviation to use for normalization. Only has an effect if `do_normalize` is set to\n `True`.\n do_convert_rgb (`Optional[bool]`):\n Whether to convert the image to RGB.\n return_tensors (`Union[str, ~utils.generic.TensorType, NoneType]`):\n Returns stacked tensors if set to `pt, otherwise returns a list of tensors.\n data_format (`Optional[~image_utils.ChannelDimension]`):\n Only `ChannelDimension.FIRST` is supported. Added for compatibility with slow processors.\n input_data_format (`Union[str, ~image_utils.ChannelDimension, NoneType]`):\n The channel dimension format for the input image. If unset, the channel dimension format is inferred\n from the input image. Can be one of:\n - `\"channels_first\"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.\n - `\"channels_last\"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.\n - `\"none\"` or `ChannelDimension.NONE`: image in (height, width) format.\n device (`Optional[torch.device]`):\n The device to process the images on. If unset, the device is inferred from the input images.\n do_pan_and_scan (`Optional[bool]`):\n Whether to apply `pan_and_scan` to images.\n pan_and_scan_min_crop_size (`Optional[int]`):\n Minimum size of each crop in pan and scan.\n pan_and_scan_max_num_crops (`Optional[int]`):\n Maximum number of crops per image in pan and scan.\n pan_and_scan_min_ratio_to_activate (`Optional[float]`):\n Minimum aspect ratio to activate pan and scan.\n\n Returns:\n ``:\n - **data** (`dict`) -- Dictionary of lists/arrays/tensors returned by the __call__ method ('pixel_values', etc.).\n - **tensor_type** (`Union[None, str, TensorType]`, *optional*) -- You can give a tensor_type here to convert the lists of integers in PyTorch/Numpy Tensors at\n initialization.\n" # self.assertEqual(llama_docstring, LlamaModel.__doc__) # self.assertEqual(LLAMA_MODEL_DOCSTRING, LlamaModel.forward.__doc__) diff --git a/tests/utils/test_configuration_utils.py b/tests/utils/test_configuration_utils.py index 60e8703937cd..50b5b11db1b7 100644 --- a/tests/utils/test_configuration_utils.py +++ b/tests/utils/test_configuration_utils.py @@ -40,8 +40,6 @@ "output_attentions": True, "torchscript": True, "dtype": "float16", - "use_bfloat16": True, - "tf_legacy_loss": True, "pruned_heads": {"a": 1}, "tie_word_embeddings": False, "is_decoder": True, diff --git a/tests/utils/test_hub_utils.py b/tests/utils/test_hub_utils.py index b86773793a84..df3af3d97a83 100644 --- a/tests/utils/test_hub_utils.py +++ b/tests/utils/test_hub_utils.py @@ -24,8 +24,6 @@ from transformers.utils import ( CONFIG_NAME, - FLAX_WEIGHTS_NAME, - TF2_WEIGHTS_NAME, TRANSFORMERS_CACHE, WEIGHTS_NAME, cached_file, @@ -97,8 +95,8 @@ def test_non_existence_is_cached(self): def test_has_file(self): self.assertTrue(has_file(TINY_BERT_PT_ONLY, WEIGHTS_NAME)) - self.assertFalse(has_file(TINY_BERT_PT_ONLY, TF2_WEIGHTS_NAME)) - self.assertFalse(has_file(TINY_BERT_PT_ONLY, FLAX_WEIGHTS_NAME)) + self.assertFalse(has_file(TINY_BERT_PT_ONLY, "tf_model.h5")) + self.assertFalse(has_file(TINY_BERT_PT_ONLY, "flax_model.msgpack")) def test_has_file_in_cache(self): with tempfile.TemporaryDirectory() as tmp_dir: diff --git a/tests/utils/test_import_structure.py b/tests/utils/test_import_structure.py index 1a4588a0d393..6d40cedaea14 100644 --- a/tests/utils/test_import_structure.py +++ b/tests/utils/test_import_structure.py @@ -53,10 +53,8 @@ def test_definition(self): }, frozenset({"random_item_that_should_not_exist"}): {"failing_export": {"A0"}}, frozenset({"torch"}): { - "import_structure_register_with_duplicates": {"C0", "C1", "C2", "C3", "c0", "c1", "c2", "c3"} - }, - frozenset({"tf", "torch"}): { "import_structure_raw_register": {"A1", "A2", "A3", "a1", "a2", "a3"}, + "import_structure_register_with_duplicates": {"C0", "C1", "C2", "C3", "c0", "c1", "c2", "c3"}, "import_structure_register_with_comments": {"B1", "B2", "B3", "b1", "b2", "b3"}, }, frozenset({"torch>=2.5"}): {"import_structure_raw_register_with_versions": {"D0", "d0"}}, @@ -73,7 +71,9 @@ def test_definition(self): self.assertEqual(len(import_structure.keys()), len(valid_frozensets.keys())) for _frozenset in valid_frozensets: self.assertTrue(_frozenset in import_structure) - self.assertListEqual(list(import_structure[_frozenset].keys()), list(valid_frozensets[_frozenset].keys())) + self.assertListEqual( + sorted(import_structure[_frozenset].keys()), sorted(valid_frozensets[_frozenset].keys()) + ) for module, objects in valid_frozensets[_frozenset].items(): self.assertTrue(module in import_structure[_frozenset]) self.assertSetEqual(objects, import_structure[_frozenset][module]) @@ -198,7 +198,6 @@ def test_import_spread(self): "backend,package_name,version_comparison,version", [ pytest.param(Backend("torch>=2.5 "), "torch", VersionComparison.GREATER_THAN_OR_EQUAL.value, "2.5"), - pytest.param(Backend("tf<=1"), "tf", VersionComparison.LESS_THAN_OR_EQUAL.value, "1"), pytest.param(Backend("torchvision==0.19.1"), "torchvision", VersionComparison.EQUAL.value, "0.19.1"), ], ) diff --git a/tests/utils/test_modeling_utils.py b/tests/utils/test_modeling_utils.py index be55cc563300..bf6889338b0e 100644 --- a/tests/utils/test_modeling_utils.py +++ b/tests/utils/test_modeling_utils.py @@ -1290,7 +1290,7 @@ def test_use_safetensors(self): BertModel.from_pretrained("hf-internal-testing/config-no-model") self.assertTrue( - "does not appear to have a file named pytorch_model.bin, model.safetensors," + "does not appear to have a file named pytorch_model.bin or model.safetensors." in str(missing_model_file_error.exception) ) @@ -1302,7 +1302,7 @@ def test_use_safetensors(self): BertModel.from_pretrained(tmp_dir) self.assertTrue( - "Error no file named pytorch_model.bin, model.safetensors" in str(missing_model_file_error.exception) + "Error no file named model.safetensors, or pytorch_model.bin" in str(missing_model_file_error.exception) ) @require_safetensors diff --git a/utils/add_pipeline_model_mapping_to_test.py b/utils/add_pipeline_model_mapping_to_test.py index 636f018eb510..37723bf0bb9c 100644 --- a/utils/add_pipeline_model_mapping_to_test.py +++ b/utils/add_pipeline_model_mapping_to_test.py @@ -38,7 +38,7 @@ PIPELINE_TEST_MAPPING = {} for task in pipeline_test_mapping: - PIPELINE_TEST_MAPPING[task] = {"pt": None, "tf": None} + PIPELINE_TEST_MAPPING[task] = None # DO **NOT** add item to this set (unless the reason is approved) @@ -47,47 +47,26 @@ } -def get_framework(test_class): - """Infer the framework from the test class `test_class`.""" - - if "ModelTesterMixin" in [x.__name__ for x in test_class.__bases__]: - return "pt" - elif "TFModelTesterMixin" in [x.__name__ for x in test_class.__bases__]: - return "tf" - elif "FlaxModelTesterMixin" in [x.__name__ for x in test_class.__bases__]: - return "flax" - else: - return None - - -def get_mapping_for_task(task, framework): +def get_mapping_for_task(task): """Get mappings defined in `XXXPipelineTests` for the task `task`.""" # Use the cached results - if PIPELINE_TEST_MAPPING[task].get(framework, None) is not None: - return PIPELINE_TEST_MAPPING[task][framework] + if PIPELINE_TEST_MAPPING[task] is not None: + return PIPELINE_TEST_MAPPING[task] pipeline_test_class = pipeline_test_mapping[task]["test"] - mapping = None - - if framework == "pt": - mapping = getattr(pipeline_test_class, "model_mapping", None) - elif framework == "tf": - mapping = getattr(pipeline_test_class, "tf_model_mapping", None) + mapping = getattr(pipeline_test_class, "model_mapping", None) if mapping is not None: mapping = dict(mapping.items()) # cache the results - PIPELINE_TEST_MAPPING[task][framework] = mapping + PIPELINE_TEST_MAPPING[task] = mapping return mapping def get_model_for_pipeline_test(test_class, task): """Get the model architecture(s) related to the test class `test_class` for a pipeline `task`.""" - framework = get_framework(test_class) - if framework is None: - return None - mapping = get_mapping_for_task(task, framework) + mapping = get_mapping_for_task(task) if mapping is None: return None @@ -116,11 +95,7 @@ def get_pipeline_model_mapping_string(test_class): This will be a 1-line string. After this is added to a test file, `make style` will format it beautifully. """ - framework = get_framework(test_class) - if framework == "pt": - framework = "torch" default_value = "{}" - mapping = get_pipeline_model_mapping(test_class) if len(mapping) == 0: return "" @@ -135,17 +110,16 @@ def get_pipeline_model_mapping_string(test_class): value = model_classes.__name__ texts.append(f'"{task}": {value}') text = "{" + ", ".join(texts) + "}" - text = f"pipeline_model_mapping = {text} if is_{framework}_available() else {default_value}" + text = f"pipeline_model_mapping = {text} if is_torch_available() else {default_value}" return text def is_valid_test_class(test_class): """Restrict to `XXXModelTesterMixin` and should be a subclass of `unittest.TestCase`.""" - base_class_names = {"ModelTesterMixin", "TFModelTesterMixin", "FlaxModelTesterMixin"} if not issubclass(test_class, unittest.TestCase): return False - return len(base_class_names.intersection([x.__name__ for x in test_class.__bases__])) > 0 + return "ModelTesterMixin" in [x.__name__ for x in test_class.__bases__] def find_test_class(test_file): @@ -325,9 +299,7 @@ def add_pipeline_model_mapping_to_test_file(test_file, overwrite=False): else: pattern = os.path.join("tests", "models", "**", "test_modeling_*.py") for test_file in glob.glob(pattern): - # `Flax` is not concerned at this moment - if not test_file.startswith("test_modeling_flax_"): - test_files.append(test_file) + test_files.append(test_file) for test_file in test_files: if test_file in TEST_FILE_TO_IGNORE: diff --git a/utils/check_config_attributes.py b/utils/check_config_attributes.py index d3ca53a56076..a68395b0238d 100644 --- a/utils/check_config_attributes.py +++ b/utils/check_config_attributes.py @@ -306,6 +306,7 @@ "SmolLM3Config": ["no_rope_layer_interval"], "Gemma3nVisionConfig": ["architecture", "do_pooling", "model_args"], # this is for use in `timm` "VaultGemmaConfig": ["tie_word_embeddings"], + "GemmaConfig": ["tie_word_embeddings"], } @@ -472,7 +473,6 @@ def check_config_attributes_being_used(config_class): # Get the path to modeling source files config_source_file = inspect.getsourcefile(config_class) model_dir = os.path.dirname(config_source_file) - # Let's check against all frameworks: as long as one framework uses an attribute, we are good. modeling_paths = [os.path.join(model_dir, fn) for fn in os.listdir(model_dir) if fn.startswith("modeling_")] # Get the source code strings diff --git a/utils/check_docstrings.py b/utils/check_docstrings.py index 9eeda74afa48..754a86941d93 100644 --- a/utils/check_docstrings.py +++ b/utils/check_docstrings.py @@ -465,8 +465,6 @@ # below, make sure to add a comment explaining why. OBJECT_TO_IGNORE_PREFIXES = [ "_", # Private objects are not documented - "TF", # TensorFlow objects are scheduled to be removed in the future - "Flax", # Flax objects are scheduled to be removed in the future ] # Supported math operations when interpreting the value of defaults. @@ -923,14 +921,10 @@ def find_matching_model_files(check_all: bool = False): potential_files = glob.glob(modeling_glob_pattern) image_processing_glob_pattern = os.path.join(PATH_TO_TRANSFORMERS, "models/**/image_processing_*_fast.py") potential_files += glob.glob(image_processing_glob_pattern) - exclude_substrings = ["modeling_tf_", "modeling_flax_"] matching_files = [] for file_path in potential_files: if os.path.isfile(file_path): - filename = os.path.basename(file_path) - is_excluded = any(exclude in filename for exclude in exclude_substrings) - if not is_excluded: - matching_files.append(file_path) + matching_files.append(file_path) if not check_all: # intersect with module_diff_files matching_files = sorted([file for file in matching_files if file in module_diff_files]) diff --git a/utils/check_inits.py b/utils/check_inits.py index bc211baa9edc..e90990ac607a 100644 --- a/utils/check_inits.py +++ b/utils/check_inits.py @@ -308,7 +308,6 @@ def get_transformers_submodules() -> list[str]: IGNORE_SUBMODULES = [ "convert_pytorch_checkpoint_to_tf2", - "modeling_flax_pytorch_utils", "models.esm.openfold_utils", "modeling_attn_mask_utils", "safetensors_conversion", diff --git a/utils/check_model_tester.py b/utils/check_model_tester.py index 8ace411b1a4e..60f7c0d32c3d 100644 --- a/utils/check_model_tester.py +++ b/utils/check_model_tester.py @@ -25,10 +25,6 @@ pattern = os.path.join("tests", "models", "**", "test_modeling_*.py") test_files = glob.glob(pattern) - # TODO: deal with TF/Flax too - test_files = [ - x for x in test_files if not (x.startswith("test_modeling_tf_") or x.startswith("test_modeling_flax_")) - ] for test_file in test_files: tester_classes = get_tester_classes(test_file) diff --git a/utils/check_repo.py b/utils/check_repo.py index e932e5bfc24c..e92ac6f3b7eb 100644 --- a/utils/check_repo.py +++ b/utils/check_repo.py @@ -33,15 +33,13 @@ import os import re -import sys import types import warnings from collections import OrderedDict from difflib import get_close_matches -from importlib.machinery import ModuleSpec from pathlib import Path -from transformers import is_flax_available, is_tf_available, is_torch_available +from transformers import is_torch_available from transformers.models.auto.auto_factory import get_values from transformers.models.auto.configuration_auto import CONFIG_MAPPING_NAMES from transformers.models.auto.feature_extraction_auto import FEATURE_EXTRACTOR_MAPPING_NAMES @@ -74,7 +72,6 @@ "Qwen3VLVisionModel", "Qwen3VLMoeVisionModel", "SwitchTransformersStack", - "TFDPRSpanPredictor", "MaskFormerSwinModel", "MaskFormerSwinPreTrainedModel", "BridgeTowerTextModel", @@ -130,17 +127,10 @@ "RealmScorer", # Not regular model. "RealmForOpenQA", # Not regular model. "ReformerForMaskedLM", # Needs to be setup as decoder. - "TFElectraMainLayer", # Building part of bigger (tested) model (should it be a TFPreTrainedModel ?) - "TFRobertaForMultipleChoice", # TODO: fix - "TFRobertaPreLayerNormForMultipleChoice", # TODO: fix "SeparableConv1D", # Building part of bigger (tested) model. - "FlaxBartForCausalLM", # Building part of bigger (tested) model. - "FlaxBertForCausalLM", # Building part of bigger (tested) model. Tested implicitly through FlaxRobertaForCausalLM. "OPTDecoderWrapper", - "TFSegformerDecodeHead", # Not a regular model. "AltRobertaModel", # Building part of bigger (tested) model. "BlipTextLMHeadModel", # No need to test it as it is tested by BlipTextVision models - "TFBlipTextLMHeadModel", # No need to test it as it is tested by BlipTextVision models "BridgeTowerTextModel", # No need to test it as it is tested by BridgeTowerModel model. "BridgeTowerVisionModel", # No need to test it as it is tested by BridgeTowerModel model. "BarkCausalModel", # Building part of bigger (tested) model. @@ -189,19 +179,12 @@ TEST_FILES_WITH_NO_COMMON_TESTS = [ "models/decision_transformer/test_modeling_decision_transformer.py", "models/camembert/test_modeling_camembert.py", - "models/mt5/test_modeling_flax_mt5.py", "models/mbart/test_modeling_mbart.py", "models/mt5/test_modeling_mt5.py", "models/pegasus/test_modeling_pegasus.py", - "models/camembert/test_modeling_tf_camembert.py", - "models/mt5/test_modeling_tf_mt5.py", - "models/xlm_roberta/test_modeling_tf_xlm_roberta.py", - "models/xlm_roberta/test_modeling_flax_xlm_roberta.py", "models/xlm_prophetnet/test_modeling_xlm_prophetnet.py", "models/xlm_roberta/test_modeling_xlm_roberta.py", "models/vision_text_dual_encoder/test_modeling_vision_text_dual_encoder.py", - "models/vision_text_dual_encoder/test_modeling_tf_vision_text_dual_encoder.py", - "models/vision_text_dual_encoder/test_modeling_flax_vision_text_dual_encoder.py", "models/decision_transformer/test_modeling_decision_transformer.py", "models/bark/test_modeling_bark.py", "models/shieldgemma2/test_modeling_shieldgemma2.py", @@ -236,12 +219,6 @@ "BlipTextModel", "BrosSpadeEEForTokenClassification", "BrosSpadeELForTokenClassification", - "TFBlipForConditionalGeneration", - "TFBlipForImageTextRetrieval", - "TFBlipForQuestionAnswering", - "TFBlipVisionModel", - "TFBlipTextLMHeadModel", - "TFBlipTextModel", "Swin2SRForImageSuperResolution", "BridgeTowerForImageAndTextRetrieval", "BridgeTowerForMaskedLM", @@ -272,8 +249,6 @@ "PerceiverForMultimodalAutoencoding", "PerceiverForOpticalFlow", "SegformerDecodeHead", - "TFSegformerDecodeHead", - "FlaxBeitForMaskedImageModeling", "BeitForMaskedImageModeling", "ChineseCLIPTextModel", "ChineseCLIPVisionModel", @@ -283,14 +258,6 @@ "ClvpModel", "GroupViTTextModel", "GroupViTVisionModel", - "TFCLIPTextModel", - "TFCLIPVisionModel", - "TFGroupViTTextModel", - "TFGroupViTVisionModel", - "FlaxCLIPTextModel", - "FlaxCLIPTextModelWithProjection", - "FlaxCLIPVisionModel", - "FlaxWav2Vec2ForCTC", "DetrForSegmentation", "Pix2StructVisionModel", "Pix2StructTextModel", @@ -328,13 +295,6 @@ "RealmForOpenQA", "RealmScorer", "RealmReader", - "TFDPRReader", - "TFGPT2DoubleHeadsModel", - "TFLayoutLMForQuestionAnswering", - "TFOpenAIGPTDoubleHeadsModel", - "TFRagModel", - "TFRagSequenceForGeneration", - "TFRagTokenForGeneration", "Wav2Vec2ForCTC", "HubertForCTC", "SEWForCTC", @@ -346,8 +306,6 @@ "VisualBertForVisualReasoning", "VisualBertForQuestionAnswering", "VisualBertForMultipleChoice", - "TFWav2Vec2ForCTC", - "TFHubertForCTC", "XCLIPVisionModel", "XCLIPTextModel", "AltCLIPTextModel", @@ -405,20 +363,6 @@ "Florence2VisionBackbone", # Building part of a bigger model ] -# DO NOT edit this list! -# (The corresponding pytorch objects should never have been in the main `__init__`, but it's too late to remove) -OBJECT_TO_SKIP_IN_MAIN_INIT_CHECK = [ - "FlaxBertLayer", - "FlaxBigBirdLayer", - "FlaxRoFormerLayer", - "TFBertLayer", - "TFLxmertEncoder", - "TFLxmertXLayer", - "TFMPNetLayer", - "TFMobileBertLayer", - "TFSegformerLayer", - "TFViTMAELayer", -] # Update this list for models that have multiple model types for the same model doc. MODEL_TYPE_TO_DOC_MAPPING = OrderedDict( @@ -446,10 +390,7 @@ def check_missing_backends(): missing_backends = [] if not is_torch_available(): missing_backends.append("PyTorch") - if not is_tf_available(): - missing_backends.append("TensorFlow") - if not is_flax_available(): - missing_backends.append("Flax") + if len(missing_backends) > 0: missing = ", ".join(missing_backends) if os.getenv("TRANSFORMERS_IS_CI", "").upper() in ENV_VARS_TRUE_VALUES: @@ -506,15 +447,8 @@ def get_model_modules() -> list[str]: "modeling_encoder_decoder", "modeling_marian", "modeling_retribert", - "modeling_flax_auto", - "modeling_flax_encoder_decoder", "modeling_speech_encoder_decoder", - "modeling_flax_speech_encoder_decoder", - "modeling_flax_vision_encoder_decoder", "modeling_timm_backbone", - "modeling_tf_auto", - "modeling_tf_encoder_decoder", - "modeling_tf_vision_encoder_decoder", "modeling_vision_encoder_decoder", ] modules = [] @@ -545,12 +479,15 @@ def get_models(module: types.ModuleType, include_pretrained: bool = False) -> li List[Tuple[str, type]]: List of models as tuples (class name, actual class). """ models = [] - model_classes = (transformers.PreTrainedModel, transformers.TFPreTrainedModel, transformers.FlaxPreTrainedModel) for attr_name in dir(module): if not include_pretrained and ("Pretrained" in attr_name or "PreTrained" in attr_name): continue attr = getattr(module, attr_name) - if isinstance(attr, type) and issubclass(attr, model_classes) and attr.__module__ == module.__name__: + if ( + isinstance(attr, type) + and issubclass(attr, transformers.PreTrainedModel) + and attr.__module__ == module.__name__ + ): models.append((attr_name, attr)) return models @@ -606,11 +543,7 @@ def get_model_test_files() -> list[str]: _ignore_files = [ "test_modeling_common", "test_modeling_encoder_decoder", - "test_modeling_flax_encoder_decoder", - "test_modeling_flax_speech_encoder_decoder", "test_modeling_marian", - "test_modeling_tf_common", - "test_modeling_tf_encoder_decoder", ] test_files = [] model_test_root = os.path.join(PATH_TO_TESTS, "models") @@ -711,9 +644,7 @@ def check_all_models_are_tested(): # Matches a module to its test file. test_file = [file for file in test_files if f"test_{module.__name__.split('.')[-1]}.py" in file] if len(test_file) == 0: - # We do not test TF or Flax models anymore because they're deprecated. - if not ("modeling_tf" in module.__name__ or "modeling_flax" in module.__name__): - failures.append(f"{module.__name__} does not have its corresponding test file {test_file}.") + failures.append(f"{module.__name__} does not have its corresponding test file {test_file}.") elif len(test_file) > 1: failures.append(f"{module.__name__} has several test files: {test_file}.") else: @@ -732,14 +663,6 @@ def get_all_auto_configured_models() -> list[str]: for attr_name in dir(transformers.models.auto.modeling_auto): if attr_name.startswith("MODEL_") and attr_name.endswith("MAPPING_NAMES"): result = result | set(get_values(getattr(transformers.models.auto.modeling_auto, attr_name))) - if is_tf_available(): - for attr_name in dir(transformers.models.auto.modeling_tf_auto): - if attr_name.startswith("TF_MODEL_") and attr_name.endswith("MAPPING_NAMES"): - result = result | set(get_values(getattr(transformers.models.auto.modeling_tf_auto, attr_name))) - if is_flax_available(): - for attr_name in dir(transformers.models.auto.modeling_flax_auto): - if attr_name.startswith("FLAX_MODEL_") and attr_name.endswith("MAPPING_NAMES"): - result = result | set(get_values(getattr(transformers.models.auto.modeling_flax_auto, attr_name))) return list(result) @@ -807,14 +730,10 @@ def check_all_auto_object_names_being_defined(): "PROCESSOR_MAPPING_NAMES": PROCESSOR_MAPPING_NAMES, } - # Each auto modeling files contains multiple mappings. Let's get them in a dynamic way. - for module_name in ["modeling_auto", "modeling_tf_auto", "modeling_flax_auto"]: - module = getattr(transformers.models.auto, module_name, None) - if module is None: - continue - # all mappings in a single auto modeling file - mapping_names = [x for x in dir(module) if x.endswith("_MAPPING_NAMES")] - mappings_to_check.update({name: getattr(module, name) for name in mapping_names}) + module = getattr(transformers.models.auto, "modeling_auto") + # all mappings in a single auto modeling file + mapping_names = [x for x in dir(module) if x.endswith("_MAPPING_NAMES")] + mappings_to_check.update({name: getattr(module, name) for name in mapping_names}) for name, mapping in mappings_to_check.items(): for class_names in mapping.values(): @@ -851,14 +770,10 @@ def check_all_auto_mapping_names_in_config_mapping_names(): "PROCESSOR_MAPPING_NAMES": PROCESSOR_MAPPING_NAMES, } - # Each auto modeling files contains multiple mappings. Let's get them in a dynamic way. - for module_name in ["modeling_auto", "modeling_tf_auto", "modeling_flax_auto"]: - module = getattr(transformers.models.auto, module_name, None) - if module is None: - continue - # all mappings in a single auto modeling file - mapping_names = [x for x in dir(module) if x.endswith("_MAPPING_NAMES")] - mappings_to_check.update({name: getattr(module, name) for name in mapping_names}) + module = getattr(transformers.models.auto, "modeling_auto") + # all mappings in a single auto modeling file + mapping_names = [x for x in dir(module) if x.endswith("_MAPPING_NAMES")] + mappings_to_check.update({name: getattr(module, name) for name in mapping_names}) for name, mapping in mappings_to_check.items(): for model_type in mapping: @@ -878,14 +793,11 @@ def check_all_auto_mappings_importable(): failures = [] mappings_to_check = {} - # Each auto modeling files contains multiple mappings. Let's get them in a dynamic way. - for module_name in ["modeling_auto", "modeling_tf_auto", "modeling_flax_auto"]: - module = getattr(transformers.models.auto, module_name, None) - if module is None: - continue - # all mappings in a single auto modeling file - mapping_names = [x for x in dir(module) if x.endswith("_MAPPING_NAMES")] - mappings_to_check.update({name: getattr(module, name) for name in mapping_names}) + + module = getattr(transformers.models.auto, "modeling_auto") + # all mappings in a single auto modeling file + mapping_names = [x for x in dir(module) if x.endswith("_MAPPING_NAMES")] + mappings_to_check.update({name: getattr(module, name) for name in mapping_names}) for name in mappings_to_check: name = name.replace("_MAPPING_NAMES", "_MAPPING") @@ -895,53 +807,6 @@ def check_all_auto_mappings_importable(): raise Exception(f"There were {len(failures)} failures:\n" + "\n".join(failures)) -def check_objects_being_equally_in_main_init(): - """ - Check if a (TensorFlow or Flax) object is in the main __init__ if its counterpart in PyTorch is. - """ - attrs = dir(transformers) - - failures = [] - for attr in attrs: - obj = getattr(transformers, attr) - if hasattr(obj, "__module__") and isinstance(obj.__module__, ModuleSpec): - continue - if not hasattr(obj, "__module__") or "models.deprecated" in obj.__module__: - continue - - module_path = obj.__module__ - module_name = module_path.split(".")[-1] - module_dir = ".".join(module_path.split(".")[:-1]) - if ( - module_name.startswith("modeling_") - and not module_name.startswith("modeling_tf_") - and not module_name.startswith("modeling_flax_") - ): - parent_module = sys.modules[module_dir] - - frameworks = [] - if is_tf_available(): - frameworks.append("TF") - if is_flax_available(): - frameworks.append("Flax") - - for framework in frameworks: - other_module_path = module_path.replace("modeling_", f"modeling_{framework.lower()}_") - if os.path.isfile("src/" + other_module_path.replace(".", "/") + ".py"): - other_module_name = module_name.replace("modeling_", f"modeling_{framework.lower()}_") - other_module = getattr(parent_module, other_module_name) - if hasattr(other_module, f"{framework}{attr}"): - if not hasattr(transformers, f"{framework}{attr}"): - if f"{framework}{attr}" not in OBJECT_TO_SKIP_IN_MAIN_INIT_CHECK: - failures.append(f"{framework}{attr}") - if hasattr(other_module, f"{framework}_{attr}"): - if not hasattr(transformers, f"{framework}_{attr}"): - if f"{framework}_{attr}" not in OBJECT_TO_SKIP_IN_MAIN_INIT_CHECK: - failures.append(f"{framework}_{attr}") - if len(failures) > 0: - raise Exception(f"There were {len(failures)} failures:\n" + "\n".join(failures)) - - _re_decorator = re.compile(r"^\s*@(\S+)\s+$") @@ -1017,14 +882,12 @@ def find_all_documented_objects() -> list[str]: # One good reason for not being documented is to be deprecated. Put in this list deprecated objects. DEPRECATED_OBJECTS = [ - "AdamWeightDecay", # TensorFlow object, support is deprecated "AutoModelWithLMHead", "BartPretrainedModel", "DataCollator", "DataCollatorForSOP", "GlueDataset", "GlueDataTrainingArguments", - "GradientAccumulator", # TensorFlow object, support is deprecated "LineByLineTextDataset", "LineByLineWithRefDataset", "LineByLineWithSOPTextDataset", @@ -1041,11 +904,8 @@ def find_all_documented_objects() -> list[str]: "SquadV2Processor", "TextDataset", "TextDatasetForNextSentencePrediction", - "TFTrainingArguments", - "WarmUp", # TensorFlow object, support is deprecated "Wav2Vec2ForMaskedLM", "Wav2Vec2Tokenizer", - "create_optimizer", # TensorFlow object, support is deprecated "glue_compute_metrics", "glue_convert_examples_to_features", "glue_output_modes", @@ -1070,13 +930,11 @@ def find_all_documented_objects() -> list[str]: "MecabTokenizer", # Internal, should never have been in the main init. "ModelCard", # Internal type. "SqueezeBertModule", # Internal building block (should have been called SqueezeBertLayer) - "TFDPRPretrainedReader", # Like an Encoder. "TransfoXLCorpus", # Internal type. "WordpieceTokenizer", # Internal, should never have been in the main init. "absl", # External module "add_end_docstrings", # Internal, should never have been in the main init. "add_start_docstrings", # Internal, should never have been in the main init. - "convert_tf_weight_name_to_pt_weight_name", # Internal used to convert model weights "logger", # Internal logger "logging", # External module "requires_backends", # Internal function @@ -1137,7 +995,7 @@ def ignore_undocumented(name: str) -> bool: ): return True # All load functions are not documented. - if name.startswith("load_tf") or name.startswith("load_pytorch"): + if name.startswith("load_pytorch"): return True # is_xxx_available functions are not documented. if name.startswith("is_") and name.endswith("_available"): @@ -1160,8 +1018,6 @@ def check_all_objects_are_documented(): # the objects with the following prefixes are not required to be in the docs ignore_prefixes = [ "_", # internal objects - "TF", # TF objects, support is deprecated - "Flax", # Flax objects, support is deprecated ] objects = [c for c in dir(transformers) if c not in modules and not any(c.startswith(p) for p in ignore_prefixes)] undocumented_objs = [c for c in objects if c not in documented_objs and not ignore_undocumented(c)] @@ -1298,8 +1154,6 @@ def check_repo_quality(): check_all_auto_mapping_names_in_config_mapping_names() print(" - checking all auto mappings could be imported.") check_all_auto_mappings_importable() - print(" - checking all objects are equally (across frameworks) in the main __init__.") - check_objects_being_equally_in_main_init() print(" - checking the DEPRECATED_MODELS constant is up to date.") check_deprecated_constant_is_up_to_date() diff --git a/utils/check_tf_ops.py b/utils/check_tf_ops.py deleted file mode 100644 index f6c2b8bae4e2..000000000000 --- a/utils/check_tf_ops.py +++ /dev/null @@ -1,101 +0,0 @@ -# coding=utf-8 -# Copyright 2020 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. - -import argparse -import json -import os - -from tensorflow.core.protobuf.saved_model_pb2 import SavedModel - - -# All paths are set with the intent you should run this script from the root of the repo with the command -# python utils/check_copies.py -REPO_PATH = "." - -# Internal TensorFlow ops that can be safely ignored (mostly specific to a saved model) -INTERNAL_OPS = [ - "Assert", - "AssignVariableOp", - "EmptyTensorList", - "MergeV2Checkpoints", - "ReadVariableOp", - "ResourceGather", - "RestoreV2", - "SaveV2", - "ShardedFilename", - "StatefulPartitionedCall", - "StaticRegexFullMatch", - "VarHandleOp", -] - - -def onnx_compliancy(saved_model_path, strict, opset): - saved_model = SavedModel() - onnx_ops = [] - - with open(os.path.join(REPO_PATH, "utils", "tf_ops", "onnx.json")) as f: - onnx_opsets = json.load(f)["opsets"] - - for i in range(1, opset + 1): - onnx_ops.extend(onnx_opsets[str(i)]) - - with open(saved_model_path, "rb") as f: - saved_model.ParseFromString(f.read()) - - model_op_names = set() - - # Iterate over every metagraph in case there is more than one (a saved model can contain multiple graphs) - for meta_graph in saved_model.meta_graphs: - # Add operations in the graph definition - model_op_names.update(node.op for node in meta_graph.graph_def.node) - - # Go through the functions in the graph definition - for func in meta_graph.graph_def.library.function: - # Add operations in each function - model_op_names.update(node.op for node in func.node_def) - - # Convert to list, sorted if you want - model_op_names = sorted(model_op_names) - incompatible_ops = [] - - for op in model_op_names: - if op not in onnx_ops and op not in INTERNAL_OPS: - incompatible_ops.append(op) - - if strict and len(incompatible_ops) > 0: - raise Exception(f"Found the following incompatible ops for the opset {opset}:\n" + incompatible_ops) - elif len(incompatible_ops) > 0: - print(f"Found the following incompatible ops for the opset {opset}:") - print(*incompatible_ops, sep="\n") - else: - print(f"The saved model {saved_model_path} can properly be converted with ONNX.") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--saved_model_path", help="Path of the saved model to check (the .pb file).") - parser.add_argument( - "--opset", default=12, type=int, help="The ONNX opset against which the model has to be tested." - ) - parser.add_argument( - "--framework", choices=["onnx"], default="onnx", help="Frameworks against which to test the saved model." - ) - parser.add_argument( - "--strict", action="store_true", help="Whether make the checking strict (raise errors) or not (raise warnings)" - ) - args = parser.parse_args() - - if args.framework == "onnx": - onnx_compliancy(args.saved_model_path, args.strict, args.opset) diff --git a/utils/create_dummy_models.py b/utils/create_dummy_models.py index 53ee7597d89c..a561967fba10 100644 --- a/utils/create_dummy_models.py +++ b/utils/create_dummy_models.py @@ -43,7 +43,7 @@ logging, ) from transformers.feature_extraction_utils import FeatureExtractionMixin -from transformers.file_utils import is_tf_available, is_torch_available +from transformers.file_utils import is_torch_available from transformers.image_processing_utils import BaseImageProcessor from transformers.models.auto.configuration_auto import AutoConfig, model_type_to_module_name from transformers.models.fsmt import configuration_fsmt @@ -58,16 +58,10 @@ logging.disable_progress_bar() logger = logging.get_logger(__name__) -os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" - if not is_torch_available(): raise ValueError("Please install PyTorch.") -if not is_tf_available(): - raise ValueError("Please install TensorFlow.") - -FRAMEWORKS = ["pytorch", "tensorflow"] INVALID_ARCH = [] TARGET_VOCAB_SIZE = 1024 @@ -94,13 +88,6 @@ "CamembertForTokenClassification", "CamembertForQuestionAnswering", "CamembertModel", - "TFCamembertForMultipleChoice", - "TFCamembertForTokenClassification", - "TFCamembertForQuestionAnswering", - "TFCamembertForSequenceClassification", - "TFCamembertForMaskedLM", - "TFCamembertModel", - "TFCamembertForCausalLM", "DecisionTransformerModel", "GraphormerModel", "InformerModel", @@ -111,8 +98,6 @@ "MT5Model", "MT5ForConditionalGeneration", "UMT5ForConditionalGeneration", - "TFMT5ForConditionalGeneration", - "TFMT5Model", "QDQBertForSequenceClassification", "QDQBertForMaskedLM", "QDQBertModel", @@ -137,13 +122,6 @@ "XLMRobertaForCausalLM", "XLMRobertaForSequenceClassification", "XLMRobertaForQuestionAnswering", - "TFXLMRobertaForSequenceClassification", - "TFXLMRobertaForMaskedLM", - "TFXLMRobertaForCausalLM", - "TFXLMRobertaForQuestionAnswering", - "TFXLMRobertaModel", - "TFXLMRobertaForMultipleChoice", - "TFXLMRobertaForTokenClassification", } @@ -759,14 +737,8 @@ def _sanity_check(fast_tokenizer, slow_tokenizer, keep_fast_tokenizer=False): def get_checkpoint_dir(output_dir, model_arch): - """Get framework-agnostic architecture name. Used to save all PT/TF/Flax models into the same directory.""" - + """Get architecture name.""" arch_name = model_arch.__name__ - if arch_name.startswith("TF"): - arch_name = arch_name[2:] - elif arch_name.startswith("Flax"): - arch_name = arch_name[4:] - return os.path.join(output_dir, arch_name) @@ -800,11 +772,11 @@ def fill_result_with_error(result, error, trace, models_to_create): """Fill `result` with errors for all target model arch if we can't build processor""" error = (error, trace) result["error"] = error - for framework in FRAMEWORKS: - if framework in models_to_create: - result[framework] = {} - for model_arch in models_to_create[framework]: - result[framework][model_arch.__name__] = {"model": None, "checkpoint": None, "error": error} + + if "pytorch" in models_to_create: + result["pytorch"] = {} + for model_arch in models_to_create["pytorch"]: + result["pytorch"][model_arch.__name__] = {"model": None, "checkpoint": None, "error": error} result["processor"] = {p.__class__.__name__: p.__class__.__name__ for p in result["processor"].values()} @@ -874,9 +846,6 @@ def build_composite_models(config_class, output_dir): GPT2Tokenizer, GPT2TokenizerFast, SpeechEncoderDecoderModel, - TFEncoderDecoderModel, - TFVisionEncoderDecoderModel, - TFVisionTextDualEncoderModel, VisionEncoderDecoderModel, VisionTextDualEncoderModel, ViTConfig, @@ -898,7 +867,6 @@ def build_composite_models(config_class, output_dir): encoder_class = BertModel decoder_class = BertLMHeadModel model_class = EncoderDecoderModel - tf_model_class = TFEncoderDecoderModel elif config_class.model_type == "vision-encoder-decoder": encoder_config_class = ViTConfig decoder_config_class = GPT2Config @@ -907,7 +875,6 @@ def build_composite_models(config_class, output_dir): encoder_class = ViTModel decoder_class = GPT2LMHeadModel model_class = VisionEncoderDecoderModel - tf_model_class = TFVisionEncoderDecoderModel elif config_class.model_type == "speech-encoder-decoder": encoder_config_class = Wav2Vec2Config decoder_config_class = BertConfig @@ -916,7 +883,6 @@ def build_composite_models(config_class, output_dir): encoder_class = Wav2Vec2Model decoder_class = BertLMHeadModel model_class = SpeechEncoderDecoderModel - tf_model_class = None elif config_class.model_type == "vision-text-dual-encoder": # Not encoder-decoder, but encoder-encoder. We just keep the same name as above to make code easier encoder_config_class = ViTConfig @@ -926,17 +892,16 @@ def build_composite_models(config_class, output_dir): encoder_class = ViTModel decoder_class = BertModel model_class = VisionTextDualEncoderModel - tf_model_class = TFVisionTextDualEncoderModel with tempfile.TemporaryDirectory() as tmpdir: try: # build encoder - models_to_create = {"processor": encoder_processor, "pytorch": (encoder_class,), "tensorflow": []} + models_to_create = {"processor": encoder_processor, "pytorch": (encoder_class,)} encoder_output_dir = os.path.join(tmpdir, "encoder") build(encoder_config_class, models_to_create, encoder_output_dir) # build decoder - models_to_create = {"processor": decoder_processor, "pytorch": (decoder_class,), "tensorflow": []} + models_to_create = {"processor": decoder_processor, "pytorch": (decoder_class,)} decoder_output_dir = os.path.join(tmpdir, "decoder") build(decoder_config_class, models_to_create, decoder_output_dir) @@ -964,10 +929,6 @@ def build_composite_models(config_class, output_dir): ) model.save_pretrained(model_path) - if tf_model_class is not None: - model = tf_model_class.from_pretrained(model_path) - model.save_pretrained(model_path) - # copy the processors encoder_processor_path = os.path.join(encoder_output_dir, "processors") decoder_processor_path = os.path.join(decoder_output_dir, "processors") @@ -981,11 +942,6 @@ def build_composite_models(config_class, output_dir): result["pytorch"] = {model_class.__name__: {"model": model_class.__name__, "checkpoint": model_path}} - result["tensorflow"] = {} - if tf_model_class is not None: - result["tensorflow"] = { - tf_model_class.__name__: {"model": tf_model_class.__name__, "checkpoint": model_path} - } except Exception: result["error"] = ( f"Failed to build models for {config_class.__name__}.", @@ -1098,7 +1054,7 @@ def build(config_class, models_to_create, output_dir): of the same model type which is associated to `config_class`. output_dir (`str`): The directory to save all the checkpoints. Each model architecture will be saved in a subdirectory under - it. Models in different frameworks with the same architecture will be saved in the same subdirectory. + it. """ if data["training_ds"] is None or data["testing_ds"] is None: ds = load_dataset("Salesforce/wikitext", "wikitext-2-raw-v1") @@ -1226,42 +1182,6 @@ def build(config_class, models_to_create, output_dir): result["pytorch"][pytorch_arch.__name__]["error"] = (error, trace) logger.error(f"{pytorch_arch.__name__}: {error}") - for tensorflow_arch in models_to_create["tensorflow"]: - # Make PT/TF weights compatible - pt_arch_name = tensorflow_arch.__name__[2:] # Remove `TF` - pt_arch = getattr(transformers_module, pt_arch_name) - - result["tensorflow"][tensorflow_arch.__name__] = {} - error = None - if pt_arch.__name__ in result["pytorch"] and result["pytorch"][pt_arch.__name__]["checkpoint"] is not None: - ckpt = get_checkpoint_dir(output_dir, pt_arch) - # Use the same weights from PyTorch. - try: - model = tensorflow_arch.from_pretrained(ckpt) - model.save_pretrained(ckpt) - except Exception as e: - # Conversion may fail. Let's not create a model with different weights to avoid confusion (for now). - model = None - error = f"Failed to convert the pytorch model to the tensorflow model for {pt_arch}: {e}" - trace = traceback.format_exc() - else: - try: - model = build_model(tensorflow_arch, tiny_config, output_dir=output_dir) - except Exception as e: - model = None - error = f"Failed to create the tensorflow model for {tensorflow_arch}: {e}" - trace = traceback.format_exc() - - result["tensorflow"][tensorflow_arch.__name__]["model"] = ( - model.__class__.__name__ if model is not None else None - ) - result["tensorflow"][tensorflow_arch.__name__]["checkpoint"] = ( - get_checkpoint_dir(output_dir, tensorflow_arch) if model is not None else None - ) - if error is not None: - result["tensorflow"][tensorflow_arch.__name__]["error"] = (error, trace) - logger.error(f"{tensorflow_arch.__name__}: {error}") - if not result["error"]: del result["error"] if not result["warnings"]: @@ -1287,40 +1207,40 @@ def build_tiny_model_summary(results, organization=None, token=None): processors = [key for key, value in results[config_name]["processor"].items()] tokenizer_classes = sorted([x for x in processors if x.endswith("TokenizerFast") or x.endswith("Tokenizer")]) processor_classes = sorted([x for x in processors if x not in tokenizer_classes]) - for framework in FRAMEWORKS: - if framework not in results[config_name]: - continue - for arch_name in results[config_name][framework]: - model_classes = [arch_name] - base_arch_name = arch_name[2:] if arch_name.startswith("TF") else arch_name - # tiny model is not created for `arch_name` - if results[config_name][framework][arch_name]["model"] is None: - model_classes = [] - if base_arch_name not in tiny_model_summary: - tiny_model_summary[base_arch_name] = {} - tiny_model_summary[base_arch_name].update( - { - "tokenizer_classes": tokenizer_classes, - "processor_classes": processor_classes, - } - ) - tiny_model_summary[base_arch_name]["model_classes"] = sorted( - tiny_model_summary[base_arch_name].get("model_classes", []) + model_classes - ) - if organization is not None: - repo_name = f"tiny-random-{base_arch_name}" - # composite models' checkpoints have more precise repo. names on the Hub. - if base_arch_name in COMPOSITE_MODELS: - repo_name = f"tiny-random-{COMPOSITE_MODELS[base_arch_name]}" - repo_id = f"{organization}/{repo_name}" - try: - commit_hash = hf_api.repo_info(repo_id, token=token).sha - except Exception: - # The directory is not created, but processor(s) is/are included in `results`. - logger.warning(f"Failed to get information for {repo_id}.\n{traceback.format_exc()}") - del tiny_model_summary[base_arch_name] - continue - tiny_model_summary[base_arch_name]["sha"] = commit_hash + + if "pytorch" not in results[config_name]: + continue + for arch_name in results[config_name]["pytorch"]: + model_classes = [arch_name] + base_arch_name = arch_name + # tiny model is not created for `arch_name` + if results[config_name]["pytorch"][arch_name]["model"] is None: + model_classes = [] + if base_arch_name not in tiny_model_summary: + tiny_model_summary[base_arch_name] = {} + tiny_model_summary[base_arch_name].update( + { + "tokenizer_classes": tokenizer_classes, + "processor_classes": processor_classes, + } + ) + tiny_model_summary[base_arch_name]["model_classes"] = sorted( + tiny_model_summary[base_arch_name].get("model_classes", []) + model_classes + ) + if organization is not None: + repo_name = f"tiny-random-{base_arch_name}" + # composite models' checkpoints have more precise repo. names on the Hub. + if base_arch_name in COMPOSITE_MODELS: + repo_name = f"tiny-random-{COMPOSITE_MODELS[base_arch_name]}" + repo_id = f"{organization}/{repo_name}" + try: + commit_hash = hf_api.repo_info(repo_id, token=token).sha + except Exception: + # The directory is not created, but processor(s) is/are included in `results`. + logger.warning(f"Failed to get information for {repo_id}.\n{traceback.format_exc()}") + del tiny_model_summary[base_arch_name] + continue + tiny_model_summary[base_arch_name]["sha"] = commit_hash return tiny_model_summary @@ -1338,19 +1258,18 @@ def build_failed_report(results, include_warning=True): failed_results[config_name] = {} failed_results[config_name]["warnings"] = results[config_name]["warnings"] - for framework in FRAMEWORKS: - if framework not in results[config_name]: - continue - for arch_name in results[config_name][framework]: - if "error" in results[config_name][framework][arch_name]: - if config_name not in failed_results: - failed_results[config_name] = {} - if framework not in failed_results[config_name]: - failed_results[config_name][framework] = {} - if arch_name not in failed_results[config_name][framework]: - failed_results[config_name][framework][arch_name] = {} - error = results[config_name][framework][arch_name]["error"] - failed_results[config_name][framework][arch_name]["error"] = error + if "pytorch" not in results[config_name]: + continue + for arch_name in results[config_name]["pytorch"]: + if "error" in results[config_name]["pytorch"][arch_name]: + if config_name not in failed_results: + failed_results[config_name] = {} + if "pytorch" not in failed_results[config_name]: + failed_results[config_name]["pytorch"] = {} + if arch_name not in failed_results[config_name]["pytorch"]: + failed_results[config_name]["pytorch"][arch_name] = {} + error = results[config_name]["pytorch"][arch_name]["error"] + failed_results[config_name]["pytorch"][arch_name]["error"] = error return failed_results @@ -1359,16 +1278,15 @@ def build_simple_report(results): text = "" failed_text = "" for config_name in results: - for framework in FRAMEWORKS: - if framework not in results[config_name]: - continue - for arch_name in results[config_name][framework]: - if "error" in results[config_name][framework][arch_name]: - result = results[config_name][framework][arch_name]["error"] - failed_text += f"{arch_name}: {result[0]}\n" - else: - result = ("OK",) - text += f"{arch_name}: {result[0]}\n" + if "pytorch" not in results[config_name]: + continue + for arch_name in results[config_name]["pytorch"]: + if "error" in results[config_name]["pytorch"][arch_name]: + result = results[config_name]["pytorch"][arch_name]["error"] + failed_text += f"{arch_name}: {result[0]}\n" + else: + result = ("OK",) + text += f"{arch_name}: {result[0]}\n" return text, failed_text @@ -1423,12 +1341,8 @@ def create_tiny_models( for x in dir(transformers_module) if x.startswith("MODEL_") and x.endswith("_MAPPING") and x != "MODEL_NAMES_MAPPING" ] - _tensorflow_arch_mappings = [ - x for x in dir(transformers_module) if x.startswith("TF_MODEL_") and x.endswith("_MAPPING") - ] pytorch_arch_mappings = [getattr(transformers_module, x) for x in _pytorch_arch_mappings] - tensorflow_arch_mappings = [getattr(transformers_module, x) for x in _tensorflow_arch_mappings] config_classes = CONFIG_MAPPING.values() if not all: @@ -1441,9 +1355,8 @@ def create_tiny_models( for c in config_classes: processors = processor_type_map[c] models = get_architectures_from_config_class(c, pytorch_arch_mappings, models_to_skip) - tf_models = get_architectures_from_config_class(c, tensorflow_arch_mappings, models_to_skip) - if len(models) + len(tf_models) > 0: - to_create[c] = {"processor": processors, "pytorch": models, "tensorflow": tf_models} + if len(models) > 0: + to_create[c] = {"processor": processors, "pytorch": models} results = {} if num_workers <= 1: diff --git a/utils/get_test_info.py b/utils/get_test_info.py index 3c376bdbdaaf..d3be2792c3d9 100644 --- a/utils/get_test_info.py +++ b/utils/get_test_info.py @@ -81,15 +81,14 @@ def get_tester_classes(test_file): def get_test_classes(test_file): """Get all [test] classes in a model test file with attribute `all_model_classes` that are non-empty. - These are usually the (model) test classes containing the (non-slow) tests to run and are subclasses of one of the - classes `ModelTesterMixin`, `TFModelTesterMixin` or `FlaxModelTesterMixin`, as well as a subclass of - `unittest.TestCase`. Exceptions include `RagTestMixin` (and its subclasses). + These are usually the (model) test classes containing the (non-slow) tests to run and are subclasses of + `ModelTesterMixin`, as well as a subclass of `unittest.TestCase`. Exceptions include `RagTestMixin` (and its subclasses). """ test_classes = [] test_module = get_test_module(test_file) for attr in dir(test_module): attr_value = getattr(test_module, attr) - # (TF/Flax)ModelTesterMixin is also an attribute in specific model test module. Let's exclude them by checking + # ModelTesterMixin is also an attribute in specific model test module. Let's exclude them by checking # `all_model_classes` is not empty (which also excludes other special classes). model_classes = getattr(attr_value, "all_model_classes", []) if len(model_classes) > 0: @@ -118,7 +117,7 @@ def get_model_tester_from_test_class(test_class): model_tester = None if hasattr(test, "model_tester"): - # `(TF/Flax)ModelTesterMixin` has this attribute default to `None`. Let's skip this case. + # `ModelTesterMixin` has this attribute default to `None`. Let's skip this case. if test.model_tester is not None: model_tester = test.model_tester.__class__ diff --git a/utils/models_to_deprecate.py b/utils/models_to_deprecate.py index 17ea1fd28ec8..a92e1019cd1a 100644 --- a/utils/models_to_deprecate.py +++ b/utils/models_to_deprecate.py @@ -61,10 +61,6 @@ def get_list_of_repo_model_paths(models_dir): # Get list of all models in the library models = glob.glob(os.path.join(models_dir, "*/modeling_*.py")) - # Remove flax and tf models - models = [model for model in models if "_flax_" not in model] - models = [model for model in models if "_tf_" not in model] - # Get list of all deprecated models in the library deprecated_models = glob.glob(os.path.join(models_dir, "deprecated", "*")) # For each deprecated model, remove the deprecated models from the list of all models as well as the symlink path diff --git a/utils/not_doctested.txt b/utils/not_doctested.txt index 36226d289191..67015ac0c90c 100644 --- a/utils/not_doctested.txt +++ b/utils/not_doctested.txt @@ -26,7 +26,6 @@ docs/source/en/main_classes/data_collator.md docs/source/en/main_classes/deepspeed.md docs/source/en/main_classes/feature_extractor.md docs/source/en/main_classes/image_processor.md -docs/source/en/main_classes/keras_callbacks.md docs/source/en/main_classes/logging.md docs/source/en/main_classes/model.md docs/source/en/main_classes/onnx.md @@ -306,27 +305,21 @@ docs/source/en/tasks/video_classification.md docs/source/en/tasks/visual_question_answering.md docs/source/en/tasks/zero_shot_image_classification.md docs/source/en/tasks/zero_shot_object_detection.md -docs/source/en/tflite.md docs/source/en/tokenizer_summary.md docs/source/en/torchscript.md docs/source/en/training.md docs/source/en/troubleshooting.md src/transformers/activations.py -src/transformers/activations_tf.py src/transformers/audio_utils.py src/transformers/commands/add_new_model_like.py -src/transformers/commands/convert.py src/transformers/commands/download.py src/transformers/commands/env.py src/transformers/commands/run.py src/transformers/commands/serving.py -src/transformers/commands/train.py src/transformers/commands/transformers_cli.py src/transformers/configuration_utils.py -src/transformers/convert_graph_to_onnx.py src/transformers/convert_slow_tokenizer.py src/transformers/convert_slow_tokenizers_checkpoints_to_fast.py -src/transformers/convert_tf_hub_seq_to_seq_bert_to_pytorch.py src/transformers/data/data_collator.py src/transformers/data/datasets/glue.py src/transformers/data/datasets/language_modeling.py @@ -352,20 +345,10 @@ src/transformers/integrations/bitsandbytes.py src/transformers/integrations/deepspeed.py src/transformers/integrations/integration_utils.py src/transformers/integrations/peft.py -src/transformers/keras_callbacks.py src/transformers/modelcard.py -src/transformers/modeling_flax_outputs.py -src/transformers/modeling_flax_pytorch_utils.py -src/transformers/modeling_flax_utils.py src/transformers/modeling_outputs.py -src/transformers/modeling_tf_outputs.py -src/transformers/modeling_tf_pytorch_utils.py -src/transformers/modeling_tf_utils.py src/transformers/modeling_utils.py -src/transformers/models/albert/convert_albert_original_tf_checkpoint_to_pytorch.py -src/transformers/models/albert/modeling_flax_albert.py src/transformers/models/align/configuration_align.py -src/transformers/models/align/convert_align_tf_to_hf.py src/transformers/models/align/modeling_align.py src/transformers/models/altclip/configuration_altclip.py src/transformers/models/altclip/modeling_altclip.py @@ -374,25 +357,12 @@ src/transformers/models/audio_spectrogram_transformer/convert_audio_spectrogram_ src/transformers/models/auto/auto_factory.py src/transformers/models/auto/configuration_auto.py src/transformers/models/auto/modeling_auto.py -src/transformers/models/auto/modeling_flax_auto.py -src/transformers/models/auto/modeling_tf_auto.py src/transformers/models/autoformer/configuration_autoformer.py src/transformers/models/autoformer/modeling_autoformer.py src/transformers/models/bark/convert_suno_to_hf.py src/transformers/models/bart/convert_bart_original_pytorch_checkpoint_to_pytorch.py -src/transformers/models/bart/modeling_flax_bart.py -src/transformers/models/bart/modeling_tf_bart.py src/transformers/models/beit/convert_beit_unilm_to_pytorch.py -src/transformers/models/beit/modeling_flax_beit.py -src/transformers/models/bert/convert_bert_original_tf2_checkpoint_to_pytorch.py -src/transformers/models/bert/convert_bert_original_tf_checkpoint_to_pytorch.py -src/transformers/models/bert/convert_bert_pytorch_checkpoint_to_original_tf.py -src/transformers/models/bert/convert_bert_token_dropping_original_tf2_checkpoint_to_pytorch.py -src/transformers/models/bert/modeling_flax_bert.py src/transformers/models/bert_generation/modeling_bert_generation.py -src/transformers/models/big_bird/convert_bigbird_original_tf_checkpoint_to_pytorch.py -src/transformers/models/big_bird/modeling_flax_big_bird.py -src/transformers/models/bigbird_pegasus/convert_bigbird_pegasus_tf_to_pytorch.py src/transformers/models/biogpt/configuration_biogpt.py src/transformers/models/biogpt/convert_biogpt_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/biogpt/modeling_biogpt.py @@ -400,60 +370,41 @@ src/transformers/models/bit/configuration_bit.py src/transformers/models/bit/convert_bit_to_pytorch.py src/transformers/models/bit/modeling_bit.py src/transformers/models/blenderbot/convert_blenderbot_original_pytorch_checkpoint_to_pytorch.py -src/transformers/models/blenderbot/modeling_flax_blenderbot.py -src/transformers/models/blenderbot/modeling_tf_blenderbot.py -src/transformers/models/blenderbot_small/modeling_flax_blenderbot_small.py -src/transformers/models/blenderbot_small/modeling_tf_blenderbot_small.py src/transformers/models/blip/configuration_blip.py src/transformers/models/blip/convert_blip_original_pytorch_to_hf.py src/transformers/models/blip/modeling_blip_text.py -src/transformers/models/blip/modeling_tf_blip_text.py src/transformers/models/blip_2/configuration_blip_2.py src/transformers/models/blip_2/convert_blip_2_original_to_pytorch.py src/transformers/models/blip_2/modeling_blip_2.py src/transformers/models/bloom/convert_bloom_original_checkpoint_to_pytorch.py src/transformers/models/bloom/modeling_bloom.py -src/transformers/models/bloom/modeling_flax_bloom.py src/transformers/models/bridgetower/configuration_bridgetower.py src/transformers/models/bridgetower/modeling_bridgetower.py src/transformers/models/bros/convert_bros_to_pytorch.py -src/transformers/models/byt5/convert_byt5_original_tf_checkpoint_to_pytorch.py src/transformers/models/camembert/modeling_camembert.py -src/transformers/models/camembert/modeling_tf_camembert.py -src/transformers/models/canine/convert_canine_original_tf_checkpoint_to_pytorch.py src/transformers/models/chinese_clip/configuration_chinese_clip.py src/transformers/models/chinese_clip/convert_chinese_clip_original_pytorch_to_hf.py src/transformers/models/chinese_clip/modeling_chinese_clip.py src/transformers/models/clap/convert_clap_original_pytorch_to_hf.py src/transformers/models/clip/convert_clip_original_pytorch_to_hf.py src/transformers/models/clip/modeling_clip.py -src/transformers/models/clip/modeling_flax_clip.py -src/transformers/models/clip/modeling_tf_clip.py src/transformers/models/clipseg/configuration_clipseg.py src/transformers/models/clipseg/convert_clipseg_original_pytorch_to_hf.py src/transformers/models/codegen/modeling_codegen.py src/transformers/models/conditional_detr/convert_conditional_detr_original_pytorch_checkpoint_to_pytorch.py -src/transformers/models/convbert/convert_convbert_original_tf1_checkpoint_to_pytorch_and_tf2.py src/transformers/models/convbert/modeling_convbert.py -src/transformers/models/convbert/modeling_tf_convbert.py src/transformers/models/convnext/convert_convnext_to_pytorch.py -src/transformers/models/convnext/modeling_tf_convnext.py src/transformers/models/convnextv2/configuration_convnextv2.py src/transformers/models/convnextv2/convert_convnextv2_to_pytorch.py src/transformers/models/convnextv2/modeling_convnextv2.py src/transformers/models/cpmant/configuration_cpmant.py src/transformers/models/cpmant/modeling_cpmant.py src/transformers/models/cpmant/tokenization_cpmant.py -src/transformers/models/ctrl/modeling_tf_ctrl.py src/transformers/models/cvt/convert_cvt_original_pytorch_checkpoint_to_pytorch.py -src/transformers/models/cvt/modeling_tf_cvt.py src/transformers/models/data2vec/convert_data2vec_audio_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/data2vec/convert_data2vec_text_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/data2vec/convert_data2vec_vision_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/data2vec/modeling_data2vec_text.py -src/transformers/models/data2vec/modeling_tf_data2vec_vision.py -src/transformers/models/deberta/modeling_tf_deberta.py -src/transformers/models/deberta_v2/modeling_tf_deberta_v2.py src/transformers/models/decision_transformer/modeling_decision_transformer.py src/transformers/models/deformable_detr/convert_deformable_detr_to_pytorch.py src/transformers/models/deit/convert_deit_timm_to_pytorch.py @@ -474,9 +425,6 @@ src/transformers/models/deprecated/tapex/tokenization_tapex.py src/transformers/models/deprecated/trajectory_transformer/configuration_trajectory_transformer.py src/transformers/models/deprecated/trajectory_transformer/convert_trajectory_transformer_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/deprecated/trajectory_transformer/modeling_trajectory_transformer.py -src/transformers/models/deprecated/transfo_xl/convert_transfo_xl_original_tf_checkpoint_to_pytorch.py -src/transformers/models/deprecated/transfo_xl/modeling_tf_transfo_xl.py -src/transformers/models/deprecated/transfo_xl/modeling_tf_transfo_xl_utilities.py src/transformers/models/deprecated/transfo_xl/modeling_transfo_xl.py src/transformers/models/deprecated/transfo_xl/modeling_transfo_xl_utilities.py src/transformers/models/deprecated/van/configuration_van.py @@ -489,34 +437,26 @@ src/transformers/models/dinov2/configuration_dinov2.py src/transformers/models/dinov2/convert_dinov2_to_hf.py src/transformers/models/dinov2/modeling_dinov2.py src/transformers/models/distilbert/modeling_distilbert.py -src/transformers/models/distilbert/modeling_flax_distilbert.py -src/transformers/models/distilbert/modeling_tf_distilbert.py src/transformers/models/dit/convert_dit_unilm_to_pytorch.py src/transformers/models/donut/configuration_donut_swin.py src/transformers/models/donut/convert_donut_to_pytorch.py src/transformers/models/donut/modeling_donut_swin.py src/transformers/models/dpr/convert_dpr_original_checkpoint_to_pytorch.py src/transformers/models/dpr/modeling_dpr.py -src/transformers/models/dpr/modeling_tf_dpr.py src/transformers/models/dpt/configuration_dpt.py src/transformers/models/dpt/convert_dpt_hybrid_to_pytorch.py src/transformers/models/dpt/convert_dpt_to_pytorch.py src/transformers/models/efficientnet/configuration_efficientnet.py src/transformers/models/efficientnet/convert_efficientnet_to_pytorch.py src/transformers/models/efficientnet/modeling_efficientnet.py -src/transformers/models/electra/convert_electra_original_tf_checkpoint_to_pytorch.py -src/transformers/models/electra/modeling_flax_electra.py src/transformers/models/encodec/configuration_encodec.py src/transformers/models/encodec/convert_encodec_checkpoint_to_pytorch.py src/transformers/models/encoder_decoder/modeling_encoder_decoder.py -src/transformers/models/encoder_decoder/modeling_flax_encoder_decoder.py -src/transformers/models/encoder_decoder/modeling_tf_encoder_decoder.py src/transformers/models/ernie/modeling_ernie.py src/transformers/models/esm/configuration_esm.py src/transformers/models/esm/convert_esm.py src/transformers/models/esm/modeling_esm.py src/transformers/models/esm/modeling_esmfold.py -src/transformers/models/esm/modeling_tf_esm.py src/transformers/models/esm/openfold_utils/chunk_utils.py src/transformers/models/esm/openfold_utils/data_transforms.py src/transformers/models/esm/openfold_utils/feats.py @@ -529,11 +469,9 @@ src/transformers/models/falcon/configuration_falcon.py src/transformers/models/falcon/modeling_falcon.py src/transformers/models/flaubert/configuration_flaubert.py src/transformers/models/flaubert/modeling_flaubert.py -src/transformers/models/flaubert/modeling_tf_flaubert.py src/transformers/models/flava/convert_dalle_to_flava_codebook.py src/transformers/models/flava/convert_flava_original_pytorch_to_hf.py src/transformers/models/flava/modeling_flava.py -src/transformers/models/fnet/convert_fnet_original_flax_checkpoint_to_pytorch.py src/transformers/models/fnet/modeling_fnet.py src/transformers/models/focalnet/configuration_focalnet.py src/transformers/models/focalnet/convert_focalnet_to_hf_format.py @@ -541,40 +479,29 @@ src/transformers/models/focalnet/modeling_focalnet.py src/transformers/models/fsmt/convert_fsmt_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/fsmt/modeling_fsmt.py src/transformers/models/funnel/configuration_funnel.py -src/transformers/models/funnel/convert_funnel_original_tf_checkpoint_to_pytorch.py src/transformers/models/funnel/modeling_funnel.py -src/transformers/models/funnel/modeling_tf_funnel.py src/transformers/models/fuyu/convert_fuyu_model_weights_to_hf.py src/transformers/models/gemma/configuration_gemma.py src/transformers/models/gemma/convert_gemma_weights_to_hf.py -src/transformers/models/gemma/modeling_flax_gemma.py src/transformers/models/gemma/modeling_gemma.py src/transformers/models/git/configuration_git.py src/transformers/models/git/convert_git_to_pytorch.py src/transformers/models/glpn/configuration_glpn.py src/transformers/models/glpn/convert_glpn_to_pytorch.py src/transformers/models/gpt2/CONVERSION.md -src/transformers/models/gpt2/convert_gpt2_original_tf_checkpoint_to_pytorch.py -src/transformers/models/gpt2/modeling_flax_gpt2.py -src/transformers/models/gpt2/modeling_tf_gpt2.py src/transformers/models/gpt_bigcode/configuration_gpt_bigcode.py src/transformers/models/gpt_bigcode/modeling_gpt_bigcode.py -src/transformers/models/gpt_neo/convert_gpt_neo_mesh_tf_to_pytorch.py -src/transformers/models/gpt_neo/modeling_flax_gpt_neo.py src/transformers/models/gpt_neo/modeling_gpt_neo.py src/transformers/models/gpt_neox/modeling_gpt_neox.py src/transformers/models/gpt_neox_japanese/modeling_gpt_neox_japanese.py src/transformers/models/gpt_sw3/convert_megatron_to_pytorch.py src/transformers/models/gptj/configuration_gptj.py -src/transformers/models/gptj/modeling_flax_gptj.py -src/transformers/models/gptj/modeling_tf_gptj.py src/transformers/models/groupvit/configuration_groupvit.py src/transformers/models/groupvit/convert_groupvit_nvlab_to_hf.py src/transformers/models/hubert/configuration_hubert.py src/transformers/models/hubert/convert_distilhubert_original_s3prl_checkpoint_to_pytorch.py src/transformers/models/hubert/convert_hubert_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/hubert/convert_hubert_original_s3prl_checkpoint_to_pytorch.py -src/transformers/models/hubert/modeling_tf_hubert.py src/transformers/models/ibert/configuration_ibert.py src/transformers/models/ibert/modeling_ibert.py src/transformers/models/ibert/quant_modules.py @@ -584,7 +511,6 @@ src/transformers/models/idefics/modeling_idefics.py src/transformers/models/idefics/perceiver.py src/transformers/models/idefics/processing_idefics.py src/transformers/models/idefics/vision.py -src/transformers/models/imagegpt/convert_imagegpt_original_tf2_to_pytorch.py src/transformers/models/informer/configuration_informer.py src/transformers/models/informer/modeling_informer.py src/transformers/models/instructblip/configuration_instructblip.py @@ -596,7 +522,6 @@ src/transformers/models/jamba/modeling_jamba.py src/transformers/models/kosmos2/convert_kosmos2_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/led/configuration_led.py src/transformers/models/led/modeling_led.py -src/transformers/models/led/modeling_tf_led.py src/transformers/models/levit/convert_levit_timm_to_pytorch.py src/transformers/models/levit/modeling_levit.py src/transformers/models/lilt/configuration_lilt.py @@ -610,22 +535,16 @@ src/transformers/models/llava_next/modeling_llava_next.py src/transformers/models/longformer/configuration_longformer.py src/transformers/models/longformer/convert_longformer_original_pytorch_lightning_to_pytorch.py src/transformers/models/longt5/configuration_longt5.py -src/transformers/models/longt5/convert_longt5x_checkpoint_to_flax.py -src/transformers/models/longt5/modeling_flax_longt5.py src/transformers/models/luke/configuration_luke.py src/transformers/models/luke/convert_luke_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/luke/modeling_luke.py src/transformers/models/lxmert/configuration_lxmert.py -src/transformers/models/lxmert/convert_lxmert_original_tf_checkpoint_to_pytorch.py src/transformers/models/lxmert/modeling_lxmert.py -src/transformers/models/lxmert/modeling_tf_lxmert.py src/transformers/models/m2m_100/convert_m2m100_original_checkpoint_to_pytorch.py src/transformers/models/m2m_100/modeling_m2m_100.py src/transformers/models/marian/configuration_marian.py src/transformers/models/marian/convert_marian_tatoeba_to_pytorch.py src/transformers/models/marian/convert_marian_to_pytorch.py -src/transformers/models/marian/modeling_flax_marian.py -src/transformers/models/marian/modeling_tf_marian.py src/transformers/models/markuplm/configuration_markuplm.py src/transformers/models/markuplm/feature_extraction_markuplm.py src/transformers/models/mask2former/convert_mask2former_original_pytorch_checkpoint_to_pytorch.py @@ -635,7 +554,6 @@ src/transformers/models/maskformer/convert_maskformer_resnet_to_pytorch.py src/transformers/models/maskformer/convert_maskformer_swin_to_pytorch.py src/transformers/models/maskformer/modeling_maskformer_swin.py src/transformers/models/mbart/convert_mbart_original_checkpoint_to_pytorch.py -src/transformers/models/mbart/modeling_flax_mbart.py src/transformers/models/megatron_bert/convert_megatron_bert_checkpoint.py src/transformers/models/megatron_bert/modeling_megatron_bert.py src/transformers/models/megatron_gpt2/checkpoint_reshaping_and_interoperability.py @@ -647,26 +565,20 @@ src/transformers/models/mistral/modeling_mistral.py src/transformers/models/mixtral/configuration_mixtral.py src/transformers/models/mixtral/modeling_mixtral.py src/transformers/models/mluke/convert_mluke_original_pytorch_checkpoint_to_pytorch.py -src/transformers/models/mobilebert/convert_mobilebert_original_tf_checkpoint_to_pytorch.py src/transformers/models/mobilenet_v1/configuration_mobilenet_v1.py -src/transformers/models/mobilenet_v1/convert_original_tf_checkpoint_to_pytorch.py src/transformers/models/mobilenet_v2/configuration_mobilenet_v2.py -src/transformers/models/mobilenet_v2/convert_original_tf_checkpoint_to_pytorch.py src/transformers/models/mobilevit/configuration_mobilevit.py src/transformers/models/mobilevit/convert_mlcvnets_to_pytorch.py src/transformers/models/mobilevitv2/convert_mlcvnets_to_pytorch.py src/transformers/models/mpnet/configuration_mpnet.py src/transformers/models/mpnet/modeling_mpnet.py -src/transformers/models/mpnet/modeling_tf_mpnet.py src/transformers/models/mpt/configuration_mpt.py src/transformers/models/mpt/modeling_mpt.py src/transformers/models/mra/configuration_mra.py src/transformers/models/mra/convert_mra_pytorch_to_pytorch.py src/transformers/models/mra/modeling_mra.py src/transformers/models/mt5/configuration_mt5.py -src/transformers/models/mt5/modeling_flax_mt5.py src/transformers/models/mt5/modeling_mt5.py -src/transformers/models/mt5/modeling_tf_mt5.py src/transformers/models/musicgen/convert_musicgen_transformers.py src/transformers/models/musicgen_melody/convert_musicgen_melody_transformers.py src/transformers/models/mvp/modeling_mvp.py @@ -678,16 +590,9 @@ src/transformers/models/nystromformer/configuration_nystromformer.py src/transformers/models/nystromformer/convert_nystromformer_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/nystromformer/modeling_nystromformer.py src/transformers/models/oneformer/convert_to_hf_oneformer.py -src/transformers/models/openai/convert_openai_original_tf_checkpoint_to_pytorch.py src/transformers/models/openai/modeling_openai.py -src/transformers/models/openai/modeling_tf_openai.py src/transformers/models/opt/convert_opt_original_pytorch_checkpoint_to_pytorch.py -src/transformers/models/opt/modeling_flax_opt.py src/transformers/models/owlvit/configuration_owlvit.py -src/transformers/models/owlvit/convert_owlvit_original_flax_to_hf.py -src/transformers/models/pegasus/convert_pegasus_tf_to_pytorch.py -src/transformers/models/pegasus/modeling_flax_pegasus.py -src/transformers/models/pegasus/modeling_tf_pegasus.py src/transformers/models/pegasus_x/modeling_pegasus_x.py src/transformers/models/perceiver/configuration_perceiver.py src/transformers/models/perceiver/convert_perceiver_haiku_to_pytorch.py @@ -718,29 +623,19 @@ src/transformers/models/qwen2_moe/configuration_qwen2_moe.py src/transformers/models/qwen2_moe/modeling_qwen2_moe.py src/transformers/models/rag/configuration_rag.py src/transformers/models/rag/modeling_rag.py -src/transformers/models/rag/modeling_tf_rag.py src/transformers/models/rag/retrieval_rag.py src/transformers/models/recurrent_gemma/modeling_recurrent_gemma.py src/transformers/models/reformer/convert_reformer_trax_checkpoint_to_pytorch.py src/transformers/models/regnet/configuration_regnet.py src/transformers/models/regnet/convert_regnet_seer_10b_to_pytorch.py src/transformers/models/regnet/convert_regnet_to_pytorch.py -src/transformers/models/regnet/modeling_flax_regnet.py src/transformers/models/rembert/configuration_rembert.py -src/transformers/models/rembert/convert_rembert_tf_checkpoint_to_pytorch.py src/transformers/models/rembert/modeling_rembert.py -src/transformers/models/rembert/modeling_tf_rembert.py src/transformers/models/resnet/convert_resnet_to_pytorch.py -src/transformers/models/resnet/modeling_flax_resnet.py src/transformers/models/roberta/convert_roberta_original_pytorch_checkpoint_to_pytorch.py -src/transformers/models/roberta/modeling_flax_roberta.py src/transformers/models/roberta_prelayernorm/convert_roberta_prelayernorm_original_pytorch_checkpoint_to_pytorch.py -src/transformers/models/roberta_prelayernorm/modeling_flax_roberta_prelayernorm.py src/transformers/models/roc_bert/configuration_roc_bert.py -src/transformers/models/roformer/convert_roformer_original_tf_checkpoint_to_pytorch.py -src/transformers/models/roformer/modeling_flax_roformer.py src/transformers/models/roformer/modeling_roformer.py -src/transformers/models/roformer/modeling_tf_roformer.py src/transformers/models/rwkv/configuration_rwkv.py src/transformers/models/rwkv/convert_rwkv_checkpoint_to_hf.py src/transformers/models/rwkv/modeling_rwkv.py @@ -748,7 +643,6 @@ src/transformers/models/sam/configuration_sam.py src/transformers/models/sam/convert_sam_to_hf.py src/transformers/models/sam/image_processing_sam.py src/transformers/models/sam/modeling_sam.py -src/transformers/models/sam/modeling_tf_sam.py src/transformers/models/sam/processing_sam.py src/transformers/models/seamless_m4t/convert_fairseq2_to_hf.py src/transformers/models/seamless_m4t_v2/convert_fairseq2_to_hf.py @@ -759,9 +653,6 @@ src/transformers/models/sew_d/convert_sew_d_original_pytorch_checkpoint_to_pytor src/transformers/models/speech_encoder_decoder/configuration_speech_encoder_decoder.py src/transformers/models/speech_encoder_decoder/convert_mbart_wav2vec2_seq2seq_original_to_pytorch.py src/transformers/models/speech_encoder_decoder/convert_speech_to_text_wav2vec2_seq2seq_original_to_pytorch.py -src/transformers/models/speech_encoder_decoder/modeling_flax_speech_encoder_decoder.py -src/transformers/models/speech_to_text/convert_s2t_fairseq_to_tfms.py -src/transformers/models/speech_to_text/modeling_tf_speech_to_text.py src/transformers/models/speecht5/configuration_speecht5.py src/transformers/models/speecht5/convert_hifigan.py src/transformers/models/speecht5/convert_speecht5_original_pytorch_checkpoint_to_pytorch.py @@ -776,29 +667,21 @@ src/transformers/models/swiftformer/convert_swiftformer_original_to_hf.py src/transformers/models/swiftformer/modeling_swiftformer.py src/transformers/models/swin/convert_swin_simmim_to_pytorch.py src/transformers/models/swin/convert_swin_timm_to_pytorch.py -src/transformers/models/swin/modeling_tf_swin.py src/transformers/models/swin2sr/configuration_swin2sr.py src/transformers/models/swin2sr/convert_swin2sr_original_to_pytorch.py src/transformers/models/swinv2/convert_swinv2_timm_to_pytorch.py src/transformers/models/swinv2/modeling_swinv2.py src/transformers/models/switch_transformers/configuration_switch_transformers.py src/transformers/models/switch_transformers/convert_big_switch.py -src/transformers/models/switch_transformers/convert_switch_transformers_original_flax_checkpoint_to_pytorch.py src/transformers/models/switch_transformers/modeling_switch_transformers.py src/transformers/models/t5/configuration_t5.py -src/transformers/models/t5/convert_t5_original_tf_checkpoint_to_pytorch.py -src/transformers/models/t5/convert_t5x_checkpoint_to_flax.py src/transformers/models/t5/convert_t5x_checkpoint_to_pytorch.py -src/transformers/models/t5/modeling_flax_t5.py src/transformers/models/t5/modeling_t5.py -src/transformers/models/t5/modeling_tf_t5.py src/transformers/models/table_transformer/configuration_table_transformer.py src/transformers/models/table_transformer/convert_table_transformer_to_hf.py src/transformers/models/table_transformer/convert_table_transformer_to_hf_no_timm.py src/transformers/models/tapas/configuration_tapas.py -src/transformers/models/tapas/convert_tapas_original_tf_checkpoint_to_pytorch.py src/transformers/models/tapas/modeling_tapas.py -src/transformers/models/tapas/modeling_tf_tapas.py src/transformers/models/timesformer/convert_timesformer_to_pytorch.py src/transformers/models/timm_backbone/configuration_timm_backbone.py src/transformers/models/timm_backbone/modeling_timm_backbone.py @@ -819,51 +702,35 @@ src/transformers/models/vilt/configuration_vilt.py src/transformers/models/vilt/convert_vilt_original_to_pytorch.py src/transformers/models/vipllava/configuration_vipllava.py src/transformers/models/vipllava/modeling_vipllava.py -src/transformers/models/vision_encoder_decoder/modeling_flax_vision_encoder_decoder.py -src/transformers/models/vision_encoder_decoder/modeling_tf_vision_encoder_decoder.py -src/transformers/models/vision_text_dual_encoder/modeling_flax_vision_text_dual_encoder.py src/transformers/models/vision_text_dual_encoder/modeling_vision_text_dual_encoder.py src/transformers/models/visual_bert/convert_visual_bert_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/visual_bert/modeling_visual_bert.py src/transformers/models/vit/convert_dino_to_pytorch.py src/transformers/models/vit/convert_vit_timm_to_pytorch.py -src/transformers/models/vit/modeling_flax_vit.py src/transformers/models/vit_mae/convert_vit_mae_to_pytorch.py -src/transformers/models/vit_mae/modeling_tf_vit_mae.py src/transformers/models/vit_msn/configuration_vit_msn.py src/transformers/models/vit_msn/convert_msn_to_pytorch.py src/transformers/models/vivit/configuration_vivit.py -src/transformers/models/vivit/convert_vivit_flax_to_pytorch.py src/transformers/models/vivit/image_processing_vivit.py src/transformers/models/vivit/modeling_vivit.py src/transformers/models/wav2vec2/convert_wav2vec2_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/wav2vec2/convert_wav2vec2_original_s3prl_checkpoint_to_pytorch.py -src/transformers/models/wav2vec2/modeling_flax_wav2vec2.py -src/transformers/models/wav2vec2/modeling_tf_wav2vec2.py src/transformers/models/wav2vec2_bert/convert_wav2vec2_seamless_checkpoint.py src/transformers/models/wav2vec2_conformer/convert_wav2vec2_conformer_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/wavlm/convert_wavlm_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/wavlm/convert_wavlm_original_s3prl_checkpoint_to_pytorch.py src/transformers/models/whisper/convert_openai_to_hf.py src/transformers/models/whisper/english_normalizer.py -src/transformers/models/whisper/modeling_flax_whisper.py src/transformers/models/x_clip/configuration_x_clip.py src/transformers/models/x_clip/convert_x_clip_original_pytorch_to_hf.py src/transformers/models/xglm/configuration_xglm.py src/transformers/models/xglm/convert_xglm_original_ckpt_to_trfms.py -src/transformers/models/xglm/modeling_flax_xglm.py -src/transformers/models/xglm/modeling_tf_xglm.py src/transformers/models/xglm/modeling_xglm.py src/transformers/models/xlm/convert_xlm_original_pytorch_checkpoint_to_pytorch.py -src/transformers/models/xlm/modeling_tf_xlm.py src/transformers/models/xlm/modeling_xlm.py -src/transformers/models/xlm_roberta/modeling_flax_xlm_roberta.py -src/transformers/models/xlm_roberta/modeling_tf_xlm_roberta.py src/transformers/models/xlm_roberta/modeling_xlm_roberta.py src/transformers/models/xlm_roberta_xl/convert_xlm_roberta_xl_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py -src/transformers/models/xlnet/convert_xlnet_original_tf_checkpoint_to_pytorch.py -src/transformers/models/xlnet/modeling_tf_xlnet.py src/transformers/models/xlnet/modeling_xlnet.py src/transformers/models/xmod/convert_xmod_original_pytorch_checkpoint_to_pytorch.py src/transformers/models/yolos/convert_yolos_to_pytorch.py @@ -877,7 +744,6 @@ src/transformers/onnx/convert.py src/transformers/onnx/features.py src/transformers/onnx/utils.py src/transformers/optimization.py -src/transformers/optimization_tf.py src/transformers/pipelines/audio_classification.py src/transformers/pipelines/audio_utils.py src/transformers/pipelines/automatic_speech_recognition.py @@ -914,7 +780,6 @@ src/transformers/quantizers/quantizers_utils.py src/transformers/sagemaker/trainer_sm.py src/transformers/sagemaker/training_args_sm.py src/transformers/testing_utils.py -src/transformers/tf_utils.py src/transformers/time_series_utils.py src/transformers/tokenization_utils.py src/transformers/tokenization_utils_base.py @@ -926,21 +791,17 @@ src/transformers/trainer_seq2seq.py src/transformers/trainer_utils.py src/transformers/training_args.py src/transformers/training_args_seq2seq.py -src/transformers/training_args_tf.py src/transformers/utils/backbone_utils.py src/transformers/utils/bitsandbytes.py src/transformers/utils/constants.py src/transformers/utils/doc.py src/transformers/utils/dummy_detectron2_objects.py src/transformers/utils/dummy_essentia_and_librosa_and_pretty_midi_and_scipy_and_torch_objects.py -src/transformers/utils/dummy_flax_objects.py src/transformers/utils/dummy_music_objects.py src/transformers/utils/dummy_pt_objects.py src/transformers/utils/dummy_sentencepiece_and_tokenizers_objects.py src/transformers/utils/dummy_sentencepiece_objects.py src/transformers/utils/dummy_speech_objects.py -src/transformers/utils/dummy_tensorflow_text_objects.py -src/transformers/utils/dummy_tf_objects.py src/transformers/utils/dummy_tokenizers_objects.py src/transformers/utils/dummy_vision_objects.py src/transformers/utils/fx.py @@ -955,4 +816,4 @@ src/transformers/utils/peft_utils.py src/transformers/utils/quantization_config.py src/transformers/utils/sentencepiece_model_pb2.py src/transformers/utils/sentencepiece_model_pb2_new.py -src/transformers/utils/versions.py +src/transformers/utils/versions.py \ No newline at end of file diff --git a/utils/notification_service.py b/utils/notification_service.py index ccff52d28df7..a8362d0b32c9 100644 --- a/utils/notification_service.py +++ b/utils/notification_service.py @@ -37,7 +37,6 @@ "run_models_gpu": "Models", "run_trainer_and_fsdp_gpu": "Trainer & FSDP", "run_pipelines_torch_gpu": "PyTorch pipelines", - "run_pipelines_tf_gpu": "TensorFlow pipelines", "run_examples_gpu": "Examples directory", "run_torch_cuda_extensions_gpu": "DeepSpeed", "run_quantization_torch_gpu": "Quantization", @@ -48,7 +47,6 @@ "Models": "model", "Trainer & FSDP": "trainer_and_fsdp", "PyTorch pipelines": "torch_pipeline", - "TensorFlow pipelines": "tf_pipeline", "Examples directory": "example", "DeepSpeed": "deepspeed", "Quantization": "quantization", @@ -394,12 +392,10 @@ def per_model_sum(model_category_dict): # Model job has a special form for reporting if job_name == "run_models_gpu": pytorch_specific_failures = dict_failed.pop("PyTorch") - tensorflow_specific_failures = dict_failed.pop("TensorFlow") other_failures = dicts_to_sum(dict_failed.values()) failures[k] = { "PyTorch": pytorch_specific_failures, - "TensorFlow": tensorflow_specific_failures, "other": other_failures, } @@ -433,8 +429,6 @@ def per_model_sum(model_category_dict): device_report_values = [ value["PyTorch"]["single"], value["PyTorch"]["multi"], - value["TensorFlow"]["single"], - value["TensorFlow"]["multi"], sum(value["other"].values()), ] @@ -455,7 +449,7 @@ def per_model_sum(model_category_dict): # (Possibly truncated) reports for the current workflow run - to be sent to Slack channels if job_name == "run_models_gpu": - model_header = "Single PT | Multi PT | Single TF | Multi TF | Other | Category\n" + model_header = "Single PT | Multi PT | Other | Category\n" else: model_header = "Single | Multi | Category\n" @@ -1172,8 +1166,6 @@ def pop_default(l: list[Any], i: int, default: Any) -> Any: test_categories = [ "PyTorch", - "TensorFlow", - "Flax", "Tokenizers", "Pipelines", "Trainer", @@ -1282,12 +1274,6 @@ def pop_default(l: list[Any], i: int, default: Any) -> Any: if re.search("tests/quantization", line): matrix_job_results[matrix_name]["failed"]["Quantization"][artifact_gpu] += 1 - elif re.search("test_modeling_tf_", line): - matrix_job_results[matrix_name]["failed"]["TensorFlow"][artifact_gpu] += 1 - - elif re.search("test_modeling_flax_", line): - matrix_job_results[matrix_name]["failed"]["Flax"][artifact_gpu] += 1 - elif re.search("test_modeling", line): matrix_job_results[matrix_name]["failed"]["PyTorch"][artifact_gpu] += 1 @@ -1313,7 +1299,6 @@ def pop_default(l: list[Any], i: int, default: Any) -> Any: # Additional runs additional_files = { "PyTorch pipelines": "run_pipelines_torch_gpu_test_reports", - "TensorFlow pipelines": "run_pipelines_tf_gpu_test_reports", "Examples directory": "run_examples_gpu_test_reports", "DeepSpeed": "run_torch_cuda_extensions_gpu_test_reports", } @@ -1321,9 +1306,7 @@ def pop_default(l: list[Any], i: int, default: Any) -> Any: if ci_event in ["push", "Nightly CI"] or ci_event.startswith("Past CI"): del additional_files["Examples directory"] del additional_files["PyTorch pipelines"] - del additional_files["TensorFlow pipelines"] elif ci_event.startswith("Scheduled CI (AMD)"): - del additional_files["TensorFlow pipelines"] del additional_files["DeepSpeed"] elif ci_event.startswith("Push CI (AMD)"): additional_files = {} diff --git a/utils/past_ci_versions.py b/utils/past_ci_versions.py deleted file mode 100644 index 858f7184d707..000000000000 --- a/utils/past_ci_versions.py +++ /dev/null @@ -1,126 +0,0 @@ -import argparse -import os - - -past_versions_testing = { - "pytorch": { - "1.13": { - "torch": "1.13.1", - "torchvision": "0.14.1", - "torchaudio": "0.13.1", - "python": 3.9, - "cuda": "cu116", - "install": ( - "python3 -m pip install --no-cache-dir -U torch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1" - " --extra-index-url https://download.pytorch.org/whl/cu116" - ), - "base_image": "nvidia/cuda:11.6.2-cudnn8-devel-ubuntu20.04", - }, - "1.12": { - "torch": "1.12.1", - "torchvision": "0.13.1", - "torchaudio": "0.12.1", - "python": 3.9, - "cuda": "cu113", - "install": ( - "python3 -m pip install --no-cache-dir -U torch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1" - " --extra-index-url https://download.pytorch.org/whl/cu113" - ), - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - "1.11": { - "torch": "1.11.0", - "torchvision": "0.12.0", - "torchaudio": "0.11.0", - "python": 3.9, - "cuda": "cu113", - "install": ( - "python3 -m pip install --no-cache-dir -U torch==1.11.0 torchvision==0.12.0 torchaudio==0.11.0" - " --extra-index-url https://download.pytorch.org/whl/cu113" - ), - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - "1.10": { - "torch": "1.10.2", - "torchvision": "0.11.3", - "torchaudio": "0.10.2", - "python": 3.9, - "cuda": "cu113", - "install": ( - "python3 -m pip install --no-cache-dir -U torch==1.10.2 torchvision==0.11.3 torchaudio==0.10.2" - " --extra-index-url https://download.pytorch.org/whl/cu113" - ), - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - # torchaudio < 0.10 has no CUDA-enabled binary distributions - "1.9": { - "torch": "1.9.1", - "torchvision": "0.10.1", - "torchaudio": "0.9.1", - "python": 3.9, - "cuda": "cu111", - "install": ( - "python3 -m pip install --no-cache-dir -U torch==1.9.1 torchvision==0.10.1 torchaudio==0.9.1" - " --extra-index-url https://download.pytorch.org/whl/cu111" - ), - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - }, - "tensorflow": { - "2.11": { - "tensorflow": "2.11.1", - "install": "python3 -m pip install --no-cache-dir -U tensorflow==2.11.1", - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - "2.10": { - "tensorflow": "2.10.1", - "install": "python3 -m pip install --no-cache-dir -U tensorflow==2.10.1", - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - "2.9": { - "tensorflow": "2.9.3", - "install": "python3 -m pip install --no-cache-dir -U tensorflow==2.9.3", - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - "2.8": { - "tensorflow": "2.8.2", - "install": "python3 -m pip install --no-cache-dir -U tensorflow==2.8.2", - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - "2.7": { - "tensorflow": "2.7.3", - "install": "python3 -m pip install --no-cache-dir -U tensorflow==2.7.3", - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - "2.6": { - "tensorflow": "2.6.5", - "install": "python3 -m pip install --no-cache-dir -U tensorflow==2.6.5", - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - "2.5": { - "tensorflow": "2.5.3", - "install": "python3 -m pip install --no-cache-dir -U tensorflow==2.5.3", - "base_image": "nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04", - }, - }, -} - - -if __name__ == "__main__": - parser = argparse.ArgumentParser("Choose the framework and version to install") - parser.add_argument( - "--framework", help="The framework to install. Should be `torch` or `tensorflow`", type=str, required=True - ) - parser.add_argument("--version", help="The version of the framework to install.", type=str, required=True) - args = parser.parse_args() - - info = past_versions_testing[args.framework][args.version] - - os.system(f"echo \"export INSTALL_CMD='{info['install']}'\" >> ~/.profile") - print(f"echo \"export INSTALL_CMD='{info['install']}'\" >> ~/.profile") - - cuda = "" - if args.framework == "pytorch": - cuda = info["cuda"] - os.system(f"echo \"export CUDA='{cuda}'\" >> ~/.profile") - print(f"echo \"export CUDA='{cuda}'\" >> ~/.profile") diff --git a/utils/print_env.py b/utils/print_env.py index d693d7e83b6f..839bebc88c0a 100644 --- a/utils/print_env.py +++ b/utils/print_env.py @@ -64,15 +64,6 @@ except ImportError: print("DeepSpeed version:", None) -try: - import tensorflow as tf - - print("TensorFlow version:", tf.__version__) - print("TF GPUs available:", bool(tf.config.list_physical_devices("GPU"))) - print("Number of TF GPUs available:", len(tf.config.list_physical_devices("GPU"))) -except ImportError: - print("TensorFlow version:", None) - try: import torchcodec diff --git a/utils/test_module/custom_pipeline.py b/utils/test_module/custom_pipeline.py index 4c7928b1ccd1..1fbb05ff804d 100644 --- a/utils/test_module/custom_pipeline.py +++ b/utils/test_module/custom_pipeline.py @@ -17,7 +17,7 @@ def _sanitize_parameters(self, **kwargs): return preprocess_kwargs, {}, {} def preprocess(self, text, second_text=None): - return self.tokenizer(text, text_pair=second_text, return_tensors=self.framework) + return self.tokenizer(text, text_pair=second_text, return_tensors="pt") def _forward(self, model_inputs): return self.model(**model_inputs) diff --git a/utils/tests_fetcher.py b/utils/tests_fetcher.py index d200fc83b742..49821d703890 100644 --- a/utils/tests_fetcher.py +++ b/utils/tests_fetcher.py @@ -307,16 +307,7 @@ def get_impacted_files_from_tiny_model_summary(diff_with_last_commit: bool = Fal # Get the corresponding modeling file path for model_class in impacted_model_classes: module = reversed_structure[model_class] - framework = "" - if model_class.startswith("TF"): - framework = "tf" - elif model_class.startswith("Flax"): - framework = "flax" - fn = ( - f"modeling_{module.split('.')[-1]}.py" - if framework == "" - else f"modeling_{framework}_{module.split('.')[-1]}.py" - ) + fn = f"modeling_{module.split('.')[-1]}.py" files.add(f"src.transformers.{module}.{fn}".replace(".", os.path.sep).replace(f"{os.path.sep}py", ".py")) return sorted(files) @@ -808,7 +799,7 @@ def init_test_examples_dependencies() -> tuple[dict[str, list[str]], list[str]]: """ The test examples do not import from the examples (which are just scripts, not modules) so we need some extra care initializing the dependency map, which is the goal of this function. It initializes the dependency map for - example files by linking each example to the example test file for the example framework. + example files by linking each example to the example test file for the example folder. Returns: `Tuple[Dict[str, List[str]], List[str]]`: A tuple with two elements: the initialized dependency map which is a @@ -817,26 +808,22 @@ def init_test_examples_dependencies() -> tuple[dict[str, list[str]], list[str]]: """ test_example_deps = {} all_examples = [] - for framework in ["flax", "pytorch", "tensorflow"]: - test_files = list((PATH_TO_EXAMPLES / framework).glob("test_*.py")) - all_examples.extend(test_files) - # Remove the files at the root of examples/framework since they are not proper examples (they are either utils - # or example test files). - examples = [ - f for f in (PATH_TO_EXAMPLES / framework).glob("**/*.py") if f.parent != PATH_TO_EXAMPLES / framework + + test_files = list((PATH_TO_EXAMPLES / "pytorch").glob("test_*.py")) + all_examples.extend(test_files) + # Remove the files at the root of examples/pytorch since they are not proper examples (they are either utils + # or example test files). + examples = [f for f in (PATH_TO_EXAMPLES / "pytorch").glob("**/*.py") if f.parent != PATH_TO_EXAMPLES / "pytorch"] + all_examples.extend(examples) + for test_file in test_files: + with open(test_file, "r", encoding="utf-8") as f: + content = f.read() + # Map all examples to the test files found in examples/pytorch. + test_example_deps[str(test_file.relative_to(PATH_TO_REPO))] = [ + str(e.relative_to(PATH_TO_REPO)) for e in examples if e.name in content ] - all_examples.extend(examples) - for test_file in test_files: - with open(test_file, "r", encoding="utf-8") as f: - content = f.read() - # Map all examples to the test files found in examples/framework. - test_example_deps[str(test_file.relative_to(PATH_TO_REPO))] = [ - str(e.relative_to(PATH_TO_REPO)) for e in examples if e.name in content - ] - # Also map the test files to themselves. - test_example_deps[str(test_file.relative_to(PATH_TO_REPO))].append( - str(test_file.relative_to(PATH_TO_REPO)) - ) + # Also map the test files to themselves. + test_example_deps[str(test_file.relative_to(PATH_TO_REPO))].append(str(test_file.relative_to(PATH_TO_REPO))) return test_example_deps, all_examples @@ -1105,15 +1092,15 @@ def parse_commit_message(commit_message: str) -> dict[str, bool]: JOB_TO_TEST_FILE = { - "tests_torch": r"tests/models/.*/test_modeling_(?!(?:flax_|tf_)).*", - "tests_generate": r"tests/models/.*/test_modeling_(?!(?:flax_|tf_)).*", + "tests_torch": r"tests/models/.*/test_modeling_.*", + "tests_generate": r"tests/models/.*/test_modeling_.*", "tests_tokenization": r"tests/(?:models/.*/test_tokenization.*|test_tokenization_mistral_common\.py)", "tests_processors": r"tests/models/.*/test_(?!(?:modeling_|tokenization_)).*", # takes feature extractors, image processors, processors "examples_torch": r"examples/pytorch/.*test_.*", "tests_exotic_models": r"tests/models/.*(?=layoutlmv|nat|deta|udop|nougat).*", "tests_custom_tokenizers": r"tests/models/.*/test_tokenization_(?=bert_japanese|openai|clip).*", # "repo_utils": r"tests/[^models].*test.*", TODO later on we might want to do - "pipelines_torch": r"tests/models/.*/test_modeling_(?!(?:flax_|tf_)).*", + "pipelines_torch": r"tests/models/.*/test_modeling_.*", "tests_hub": r"tests/.*", "tests_non_model": r"tests/[^/]*?/test_.*\.py", } diff --git a/utils/update_metadata.py b/utils/update_metadata.py index 9f04300382e4..e122b64ce849 100755 --- a/utils/update_metadata.py +++ b/utils/update_metadata.py @@ -51,10 +51,7 @@ transformers_module = direct_transformers_import(TRANSFORMERS_PATH) -# Regexes that match TF/Flax/PT model names. -_re_tf_models = re.compile(r"TF(.*)(?:Model|Encoder|Decoder|ForConditionalGeneration)") -_re_flax_models = re.compile(r"Flax(.*)(?:Model|Encoder|Decoder|ForConditionalGeneration)") -# Will match any TF or Flax model too so need to be in an else branch afterthe two previous regexes. +# Regexes that match model names _re_pt_models = re.compile(r"(.*)(?:Model|Encoder|Decoder|ForConditionalGeneration|ForRetrieval)") @@ -157,21 +154,12 @@ def get_frameworks_table() -> pd.DataFrame: config.replace("Config", ""): model_type for model_type, config in config_mapping_names.items() } - # Dictionaries flagging if each model prefix has a backend in PT/TF/Flax. pt_models = collections.defaultdict(bool) - tf_models = collections.defaultdict(bool) - flax_models = collections.defaultdict(bool) # Let's lookup through all transformers object (once) and find if models are supported by a given backend. for attr_name in dir(transformers_module): lookup_dict = None - if _re_tf_models.match(attr_name) is not None: - lookup_dict = tf_models - attr_name = _re_tf_models.match(attr_name).groups()[0] - elif _re_flax_models.match(attr_name) is not None: - lookup_dict = flax_models - attr_name = _re_flax_models.match(attr_name).groups()[0] - elif _re_pt_models.match(attr_name) is not None: + if _re_pt_models.match(attr_name) is not None: lookup_dict = pt_models attr_name = _re_pt_models.match(attr_name).groups()[0] @@ -183,14 +171,12 @@ def get_frameworks_table() -> pd.DataFrame: # Try again after removing the last word in the name attr_name = "".join(camel_case_split(attr_name)[:-1]) - all_models = set(list(pt_models.keys()) + list(tf_models.keys()) + list(flax_models.keys())) + all_models = set(pt_models.keys()) all_models = list(all_models) all_models.sort() data = {"model_type": all_models} data["pytorch"] = [pt_models[t] for t in all_models] - data["tensorflow"] = [tf_models[t] for t in all_models] - data["flax"] = [flax_models[t] for t in all_models] # Now let's find the right processing class for each model. In order we check if there is a Processor, then a # Tokenizer, then a FeatureExtractor, then an ImageProcessor @@ -225,29 +211,20 @@ def update_pipeline_and_auto_class_table(table: dict[str, tuple[str, str]]) -> d Returns: `Dict[str, Tuple[str, str]]`: The updated table in the same format. """ - auto_modules = [ - transformers_module.models.auto.modeling_auto, - transformers_module.models.auto.modeling_tf_auto, - transformers_module.models.auto.modeling_flax_auto, - ] - for pipeline_tag, model_mapping, auto_class in PIPELINE_TAGS_AND_AUTO_MODELS: - model_mappings = [model_mapping, f"TF_{model_mapping}", f"FLAX_{model_mapping}"] - auto_classes = [auto_class, f"TF_{auto_class}", f"Flax_{auto_class}"] - # Loop through all three frameworks - for module, cls, mapping in zip(auto_modules, auto_classes, model_mappings): - # The type of pipeline may not exist in this framework - if not hasattr(module, mapping): - continue - # First extract all model_names - model_names = [] - for name in getattr(module, mapping).values(): - if isinstance(name, str): - model_names.append(name) - else: - model_names.extend(list(name)) - - # Add pipeline tag and auto model class for those models - table.update(dict.fromkeys(model_names, (pipeline_tag, cls))) + module = transformers_module.models.auto.modeling_auto + for pipeline_tag, model_mapping, cls in PIPELINE_TAGS_AND_AUTO_MODELS: + if not hasattr(module, model_mapping): + continue + # First extract all model_names + model_names = [] + for name in getattr(module, model_mapping).values(): + if isinstance(name, str): + model_names.append(name) + else: + model_names.extend(list(name)) + + # Add pipeline tag and auto model class for those models + table.update(dict.fromkeys(model_names, (pipeline_tag, cls))) return table diff --git a/utils/update_tiny_models.py b/utils/update_tiny_models.py index 9dc4cdf6e6b2..ee81407d4124 100644 --- a/utils/update_tiny_models.py +++ b/utils/update_tiny_models.py @@ -21,7 +21,6 @@ """ import argparse -import copy import json import multiprocessing import os @@ -37,18 +36,12 @@ def get_all_model_names(): model_names = set() - # Each auto modeling files contains multiple mappings. Let's get them in a dynamic way. - for module_name in ["modeling_auto", "modeling_tf_auto", "modeling_flax_auto"]: - module = getattr(transformers.models.auto, module_name, None) - if module is None: - continue + + module_name = "modeling_auto" + module = getattr(transformers.models.auto, module_name, None) + if module is not None: # all mappings in a single auto modeling file - mapping_names = [ - x - for x in dir(module) - if x.endswith("_MAPPING_NAMES") - and (x.startswith("MODEL_") or x.startswith("TF_MODEL_") or x.startswith("FLAX_MODEL_")) - ] + mapping_names = [x for x in dir(module) if x.endswith("_MAPPING_NAMES") and x.startswith("MODEL_")] for name in mapping_names: mapping = getattr(module, name) if mapping is not None: @@ -62,23 +55,12 @@ def get_all_model_names(): def get_tiny_model_names_from_repo(): - # All model names defined in auto mappings - model_names = set(get_all_model_names()) - with open("tests/utils/tiny_model_summary.json") as fp: tiny_model_info = json.load(fp) tiny_models_names = set() for model_base_name in tiny_model_info: tiny_models_names.update(tiny_model_info[model_base_name]["model_classes"]) - # Remove a tiny model name if one of its framework implementation hasn't yet a tiny version on the Hub. - not_on_hub = model_names.difference(tiny_models_names) - for model_name in copy.copy(tiny_models_names): - if not model_name.startswith("TF") and f"TF{model_name}" in not_on_hub: - tiny_models_names.remove(model_name) - elif model_name.startswith("TF") and model_name[2:] in not_on_hub: - tiny_models_names.remove(model_name) - return sorted(tiny_models_names) @@ -153,13 +135,6 @@ def get_tiny_model_summary_from_hub(output_path): content["model_classes"].add(m.__class__.__name__) except Exception: pass - try: - time.sleep(1) - model_class = getattr(transformers, f"TF{model}") - m = model_class.from_pretrained(repo_id) - content["model_classes"].add(m.__class__.__name__) - except Exception: - pass content["tokenizer_classes"] = sorted(content["tokenizer_classes"]) content["processor_classes"] = sorted(content["processor_classes"]) From 345c86a165cd37116d5d13ecc667316dc7cc2fe9 Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Thu, 18 Sep 2025 18:56:10 +0200 Subject: [PATCH 111/204] Remove `set_model_tester_for_less_flaky_tests` (#40982) remove --- src/transformers/testing_utils.py | 53 ------------------- .../test_modeling_efficientloftr.py | 3 -- 2 files changed, 56 deletions(-) diff --git a/src/transformers/testing_utils.py b/src/transformers/testing_utils.py index 57b7b118f27a..b66d92f69026 100644 --- a/src/transformers/testing_utils.py +++ b/src/transformers/testing_utils.py @@ -15,7 +15,6 @@ import ast import collections import contextlib -import copy import doctest import functools import gc @@ -1598,58 +1597,6 @@ def assert_screenout(out, what): assert match_str != -1, f"expecting to find {what} in output: f{out_pr}" -def set_model_tester_for_less_flaky_test(test_case): - # NOTE: this function edits the config object, which may lead to hard-to-debug side-effects. Use with caution. - # Do not use in tests/models where objects behave very differently based on the config's hidden layer settings - # (e.g. KV caches, sliding window attention, ...) - - # TODO (if possible): Avoid exceptional cases - exceptional_classes = [ - "ZambaModelTester", - "Zamba2ModelTester", - "RwkvModelTester", - "AriaVisionText2TextModelTester", - "GPTNeoModelTester", - "DPTModelTester", - "Qwen3NextModelTester", - ] - if test_case.model_tester.__class__.__name__ in exceptional_classes: - return - - target_num_hidden_layers = 1 - if hasattr(test_case.model_tester, "out_features") or hasattr(test_case.model_tester, "out_indices"): - target_num_hidden_layers = None - - if hasattr(test_case.model_tester, "num_hidden_layers") and target_num_hidden_layers is not None: - test_case.model_tester.num_hidden_layers = target_num_hidden_layers - if ( - hasattr(test_case.model_tester, "vision_config") - and "num_hidden_layers" in test_case.model_tester.vision_config - and target_num_hidden_layers is not None - ): - test_case.model_tester.vision_config = copy.deepcopy(test_case.model_tester.vision_config) - if isinstance(test_case.model_tester.vision_config, dict): - test_case.model_tester.vision_config["num_hidden_layers"] = 1 - else: - test_case.model_tester.vision_config.num_hidden_layers = 1 - if ( - hasattr(test_case.model_tester, "text_config") - and "num_hidden_layers" in test_case.model_tester.text_config - and target_num_hidden_layers is not None - ): - test_case.model_tester.text_config = copy.deepcopy(test_case.model_tester.text_config) - if isinstance(test_case.model_tester.text_config, dict): - test_case.model_tester.text_config["num_hidden_layers"] = 1 - else: - test_case.model_tester.text_config.num_hidden_layers = 1 - - # A few model class specific handling - - # For Albert - if hasattr(test_case.model_tester, "num_hidden_groups"): - test_case.model_tester.num_hidden_groups = test_case.model_tester.num_hidden_layers - - def set_config_for_less_flaky_test(config): target_attrs = [ "rms_norm_eps", diff --git a/tests/models/efficientloftr/test_modeling_efficientloftr.py b/tests/models/efficientloftr/test_modeling_efficientloftr.py index aef77ac85686..be428c3b4ffa 100644 --- a/tests/models/efficientloftr/test_modeling_efficientloftr.py +++ b/tests/models/efficientloftr/test_modeling_efficientloftr.py @@ -23,7 +23,6 @@ require_vision, set_config_for_less_flaky_test, set_model_for_less_flaky_test, - set_model_tester_for_less_flaky_test, slow, torch_device, ) @@ -360,8 +359,6 @@ def recursive_check(batched_object, single_row_object, model_name, key): msg += str(e) raise AssertionError(msg) - set_model_tester_for_less_flaky_test(self) - config, batched_input = self.model_tester.prepare_config_and_inputs_for_common() set_config_for_less_flaky_test(config) From b16d0544e0e242e61c24338ca11e09cec7273063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Hadnagy?= Date: Fri, 19 Sep 2025 10:54:49 +0200 Subject: [PATCH 112/204] Benchmarking v2 GH workflows (#40716) * WIP benchmark v2 workflow * Container was missing * Change to sandbox branch name * Wrong place for image name * Variable declarations * Remove references to file logging * Remove unnecessary step * Fix deps install * Syntax * Add workdir * Add upload feature * typo * No need for hf_transfer * Pass in runner * Runner config * Runner config * Runner config * Runner config * Runner config * mi325 caller * Name workflow runs properly * Copy-paste error * Add final repo IDs and schedule * Review comments * Remove wf params * Remove parametrization from worfkflow files * Fix callers * Change push trigger to pull_request + label * Add back schedule event * Push to the same dataset * Simplify parameter description --- .github/workflows/benchmark_v2.yml | 82 +++++++++ .github/workflows/benchmark_v2_a10_caller.yml | 20 +++ .../workflows/benchmark_v2_mi325_caller.yml | 20 +++ benchmark_v2/README.md | 30 ++++ benchmark_v2/benches/llama.py | 1 - benchmark_v2/requirements.txt | 3 +- benchmark_v2/run_benchmarks.py | 165 +++++++++++++++++- 7 files changed, 311 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/benchmark_v2.yml create mode 100644 .github/workflows/benchmark_v2_a10_caller.yml create mode 100644 .github/workflows/benchmark_v2_mi325_caller.yml diff --git a/.github/workflows/benchmark_v2.yml b/.github/workflows/benchmark_v2.yml new file mode 100644 index 000000000000..350ad0144101 --- /dev/null +++ b/.github/workflows/benchmark_v2.yml @@ -0,0 +1,82 @@ +name: Benchmark v2 Framework + +on: + workflow_call: + inputs: + runner: + description: 'GH Actions runner group to use' + required: true + type: string + commit_sha: + description: 'Commit SHA to benchmark' + required: false + type: string + default: '' + upload_to_hub: + description: 'Uploading results to a HuggingFace Dataset' + required: false + type: string + default: 'false' + run_id: + description: 'Custom run ID for organizing results (auto-generated if not provided)' + required: false + type: string + default: '' + benchmark_repo_id: + description: 'HuggingFace Dataset to upload results to (e.g., "org/benchmark-results")' + required: false + type: string + default: '' + +env: + HF_HOME: /mnt/cache + TRANSFORMERS_IS_CI: yes + # For gated repositories, we still need to agree to share information on the Hub repo. page in order to get access. + # This token is created under the bot `hf-transformers-bot`. + HF_HUB_READ_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }} + +jobs: + benchmark-v2: + name: Benchmark v2 + runs-on: ${{ inputs.runner }} + if: | + (github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'run-benchmark')) || + (github.event_name == 'schedule') + container: + image: huggingface/transformers-pytorch-gpu + options: --gpus all --privileged --ipc host --shm-size "16gb" + steps: + - name: Get repo + uses: actions/checkout@v4 + with: + ref: ${{ inputs.commit_sha || github.sha }} + + - name: Install benchmark dependencies + run: | + python3 -m pip install -r benchmark_v2/requirements.txt + + - name: Reinstall transformers in edit mode + run: | + python3 -m pip uninstall -y transformers + python3 -m pip install -e ".[torch]" + + - name: Show installed libraries and their versions + run: | + python3 -m pip list + python3 -c "import torch; print(f'PyTorch version: {torch.__version__}')" + python3 -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}')" + python3 -c "import torch; print(f'CUDA device count: {torch.cuda.device_count()}')" || true + nvidia-smi || true + + - name: Run benchmark v2 + working-directory: benchmark_v2 + run: | + echo "Running benchmarks" + python3 run_benchmarks.py \ + --commit-id '${{ inputs.commit_sha || github.sha }}' \ + --upload-to-hub '${{ inputs.upload_to_hub || false}}' \ + --run-id '${{ inputs.run_id }}' \ + --benchmark-repo-id '${{ inputs.benchmark_repo_id}}' \ + --log-level INFO + env: + HF_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/benchmark_v2_a10_caller.yml b/.github/workflows/benchmark_v2_a10_caller.yml new file mode 100644 index 000000000000..30b5e8be78a5 --- /dev/null +++ b/.github/workflows/benchmark_v2_a10_caller.yml @@ -0,0 +1,20 @@ +name: Benchmark v2 Scheduled Runner - A10 Single-GPU + +on: + schedule: + # Run daily at 16:30 UTC + - cron: "30 16 * * *" + pull_request: + types: [ opened, labeled, reopened, synchronize ] + +jobs: + benchmark-v2-default: + name: Benchmark v2 - Default Models + uses: ./.github/workflows/benchmark_v2.yml + with: + runner: aws-g5-4xlarge-cache-use1-public-80 + commit_sha: ${{ github.sha }} + upload_to_hub: true + run_id: ${{ github.run_id }} + benchmark_repo_id: hf-internal-testing/transformers-daily-benchmarks + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/benchmark_v2_mi325_caller.yml b/.github/workflows/benchmark_v2_mi325_caller.yml new file mode 100644 index 000000000000..95fbeb5e5f6a --- /dev/null +++ b/.github/workflows/benchmark_v2_mi325_caller.yml @@ -0,0 +1,20 @@ +name: Benchmark v2 Scheduled Runner - MI325 Single-GPU + +on: + schedule: + # Run daily at 16:30 UTC + - cron: "30 16 * * *" + pull_request: + types: [ opened, labeled, reopened, synchronize ] + +jobs: + benchmark-v2-default: + name: Benchmark v2 - Default Models + uses: ./.github/workflows/benchmark_v2.yml + with: + runner: amd-mi325-ci-1gpu + commit_sha: ${{ github.sha }} + upload_to_hub: true + run_id: ${{ github.run_id }} + benchmark_repo_id: hf-internal-testing/transformers-daily-benchmarks + secrets: inherit \ No newline at end of file diff --git a/benchmark_v2/README.md b/benchmark_v2/README.md index 9a0102b387fc..1d34de6408c7 100644 --- a/benchmark_v2/README.md +++ b/benchmark_v2/README.md @@ -21,6 +21,36 @@ python run_benchmarks.py \ --num-tokens-to-generate 200 ``` +### Uploading Results to HuggingFace Dataset + +You can automatically upload benchmark results to a HuggingFace Dataset for tracking and analysis: + +```bash +# Upload to a public dataset with auto-generated run ID +python run_benchmarks.py --upload-to-hf username/benchmark-results + +# Upload with a custom run ID for easy identification +python run_benchmarks.py --upload-to-hf username/benchmark-results --run-id experiment_v1 +``` + +**Dataset Directory Structure:** +``` +dataset_name/ +├── 2025-01-15/ +│ ├── runs/ # Non-scheduled runs (manual, PR, etc.) +│ │ └── 123-1245151651/ # GitHub run number and ID +│ │ └── benchmark_results/ +│ │ ├── benchmark_summary_20250115_143022.json +│ │ └── model-name/ +│ │ └── model-name_benchmark_20250115_143022.json +│ └── benchmark_results_abc123de/ # Scheduled runs (daily CI) +│ ├── benchmark_summary_20250115_143022.json +│ └── model-name/ +│ └── model-name_benchmark_20250115_143022.json +└── 2025-01-16/ + └── ... +``` + ### Running Specific Benchmarks ```bash diff --git a/benchmark_v2/benches/llama.py b/benchmark_v2/benches/llama.py index 23427a8549c7..2349e75f1347 100644 --- a/benchmark_v2/benches/llama.py +++ b/benchmark_v2/benches/llama.py @@ -20,7 +20,6 @@ from benchmark_framework import ModelBenchmark -os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1" os.environ["TOKENIZERS_PARALLELISM"] = "1" torch.set_float32_matmul_precision("high") diff --git a/benchmark_v2/requirements.txt b/benchmark_v2/requirements.txt index a7a435958cf7..e4dcbb3eb7ef 100644 --- a/benchmark_v2/requirements.txt +++ b/benchmark_v2/requirements.txt @@ -3,4 +3,5 @@ psutil>=5.8.0 gpustat>=1.0.0 torch>=2.0.0 transformers>=4.30.0 -datasets>=2.10.0 \ No newline at end of file +datasets>=2.10.0 +huggingface_hub>=0.16.0 \ No newline at end of file diff --git a/benchmark_v2/run_benchmarks.py b/benchmark_v2/run_benchmarks.py index 26c816b9d16d..44f6515a2c30 100755 --- a/benchmark_v2/run_benchmarks.py +++ b/benchmark_v2/run_benchmarks.py @@ -24,6 +24,7 @@ import logging import os import sys +import uuid from datetime import datetime from pathlib import Path from typing import Any, Optional @@ -160,7 +161,12 @@ def run_single_benchmark( return None -def generate_summary_report(output_dir: str, benchmark_results: dict[str, Any], logger: logging.Logger) -> str: +def generate_summary_report( + output_dir: str, + benchmark_results: dict[str, Any], + logger: logging.Logger, + benchmark_run_uuid: Optional[str] = None, +) -> str: """Generate a summary report of all benchmark runs.""" timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") summary_file = os.path.join(output_dir, f"benchmark_summary_{timestamp}.json") @@ -168,6 +174,7 @@ def generate_summary_report(output_dir: str, benchmark_results: dict[str, Any], summary_data = { "run_metadata": { "timestamp": datetime.utcnow().isoformat(), + "benchmark_run_uuid": benchmark_run_uuid, "total_benchmarks": len(benchmark_results), "successful_benchmarks": len([r for r in benchmark_results.values() if r is not None]), "failed_benchmarks": len([r for r in benchmark_results.values() if r is None]), @@ -183,9 +190,115 @@ def generate_summary_report(output_dir: str, benchmark_results: dict[str, Any], return summary_file +def upload_results_to_hf_dataset( + output_dir: str, + summary_file: str, + dataset_name: str, + run_id: Optional[str] = None, + logger: Optional[logging.Logger] = None, +) -> Optional[str]: + """ + Upload benchmark results to a HuggingFace Dataset. + Based on upload_collated_report() from utils/collated_reports.py + Args: + output_dir: Local output directory containing results + summary_file: Path to the summary file + dataset_name: Name of the HuggingFace dataset to upload to + run_id: Unique run identifier (if None, will generate one) + logger: Logger instance + Returns: + The run_id used for the upload, None if upload failed + """ + if logger is None: + logger = logging.getLogger(__name__) + + import os + + from huggingface_hub import HfApi + + api = HfApi() + + if run_id is None: + github_run_number = os.getenv("GITHUB_RUN_NUMBER") + github_run_id = os.getenv("GITHUB_RUN_ID") + if github_run_number and github_run_id: + run_id = f"{github_run_number}-{github_run_id}" + + date_folder = datetime.now().strftime("%Y-%m-%d") + + github_event_name = os.getenv("GITHUB_EVENT_NAME") + if github_event_name != "schedule": + # Non-scheduled runs go under a runs subfolder + repo_path = f"{date_folder}/runs/{run_id}/benchmark_results" + else: + # Scheduled runs go directly under the date + repo_path = f"{date_folder}/{run_id}/benchmark_results" + + logger.info(f"Uploading benchmark results to dataset '{dataset_name}' at path '{repo_path}'") + + try: + # Get the authentication token (prioritize specific token, fallback to HF_TOKEN) + token = os.getenv("TRANSFORMERS_CI_RESULTS_UPLOAD_TOKEN") or os.getenv("HF_TOKEN") + + # Upload all files in the output directory + from pathlib import Path + + output_path = Path(output_dir) + + for file_path in output_path.rglob("*"): + if file_path.is_file(): + # Calculate relative path from output_dir + relative_path = file_path.relative_to(output_path) + path_in_repo = f"{repo_path}/{relative_path}" + + logger.debug(f"Uploading {file_path} to {path_in_repo}") + + api.upload_file( + path_or_fileobj=str(file_path), + path_in_repo=path_in_repo, + repo_id=dataset_name, + repo_type="dataset", + token=token, + commit_message=f"Upload benchmark results for run {run_id}", + ) + + logger.info( + f"Successfully uploaded results to: https://huggingface.co/datasets/{dataset_name}/tree/main/{repo_path}" + ) + + return run_id + + except Exception as upload_error: + logger.error(f"Failed to upload results: {upload_error}") + import traceback + + logger.debug(traceback.format_exc()) + return None + + def main(): """Main entry point for the benchmarking script.""" - parser = argparse.ArgumentParser(description="Run all benchmarks in the ./benches directory") + # Generate a unique UUID for this benchmark run + benchmark_run_uuid = str(uuid.uuid4())[:8] + + parser = argparse.ArgumentParser( + description="Run all benchmarks in the ./benches directory", + epilog=""" +Examples: + # Run all available benchmarks + python3 run_benchmarks.py + + # Run with specific model and upload to HuggingFace Dataset + python3 run_benchmarks.py --model-id meta-llama/Llama-2-7b-hf --upload-to-hf username/benchmark-results + + # Run with custom run ID and upload to HuggingFace Dataset + python3 run_benchmarks.py --run-id experiment_v1 --upload-to-hf org/benchmarks + + # Run only specific benchmarks with file logging + python3 run_benchmarks.py --include llama --enable-file-logging + """, # noqa: W293 + formatter_class=argparse.RawDescriptionHelpFormatter, + ) parser.add_argument( "--output-dir", @@ -228,20 +341,29 @@ def main(): parser.add_argument("--exclude", type=str, nargs="*", help="Exclude benchmarks matching these names") - parser.add_argument("--enable-mock", action="store_true", help="Enable mock benchmark (skipped by default)") - parser.add_argument("--enable-file-logging", action="store_true", help="Enable file logging (disabled by default)") parser.add_argument( "--commit-id", type=str, help="Git commit ID for metadata (if not provided, will auto-detect from git)" ) + parser.add_argument( + "--upload-to-hub", + type=str, + help="Upload results to HuggingFace Dataset (provide dataset name, e.g., 'username/benchmark-results')", + ) + + parser.add_argument( + "--run-id", type=str, help="Custom run ID for organizing results (if not provided, will generate a unique ID)" + ) + args = parser.parse_args() # Setup logging logger = setup_logging(args.log_level, args.enable_file_logging) logger.info("Starting benchmark discovery and execution") + logger.info(f"Benchmark run UUID: {benchmark_run_uuid}") logger.info(f"Output directory: {args.output_dir}") logger.info(f"Benches directory: {args.benches_dir}") @@ -286,9 +408,6 @@ def main(): if args.model_id: benchmark_kwargs["model_id"] = args.model_id - # Add enable_mock flag for mock benchmark - benchmark_kwargs["enable_mock"] = args.enable_mock - # Add commit_id if provided if args.commit_id: benchmark_kwargs["commit_id"] = args.commit_id @@ -306,7 +425,27 @@ def main(): successful_count += 1 # Generate summary report - summary_file = generate_summary_report(args.output_dir, benchmark_results, logger) + summary_file = generate_summary_report(args.output_dir, benchmark_results, logger, benchmark_run_uuid) + + # Upload results to HuggingFace Dataset if requested + upload_run_id = None + if args.upload_to_hub: + logger.info("=" * 60) + logger.info("UPLOADING TO HUGGINGFACE DATASET") + logger.info("=" * 60) + # Use provided run_id or fallback to benchmark run UUID + effective_run_id = args.run_id or benchmark_run_uuid + upload_run_id = upload_results_to_hf_dataset( + output_dir=args.output_dir, + summary_file=summary_file, + dataset_name=args.upload_to_hub, + run_id=effective_run_id, + logger=logger, + ) + if upload_run_id: + logger.info(f"Upload completed with run ID: {upload_run_id}") + else: + logger.warning("Upload failed - continuing with local results") # Final summary total_benchmarks = len(filtered_benchmarks) @@ -321,6 +460,16 @@ def main(): logger.info(f"Output directory: {args.output_dir}") logger.info(f"Summary report: {summary_file}") + if args.upload_to_hub: + if upload_run_id: + logger.info(f"HuggingFace Dataset: {args.upload_to_hub}") + logger.info(f"Run ID: {upload_run_id}") + logger.info( + f"View results: https://huggingface.co/datasets/{args.upload_to_hub}/tree/main/{datetime.now().strftime('%Y-%m-%d')}/runs/{upload_run_id}" + ) + else: + logger.warning("Upload to HuggingFace Dataset failed") + if failed_count > 0: logger.warning(f"{failed_count} benchmark(s) failed. Check logs for details.") return 1 From e0fb372151cb11819a757a0fb7fca65f93ac3342 Mon Sep 17 00:00:00 2001 From: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> Date: Fri, 19 Sep 2025 11:23:58 +0200 Subject: [PATCH 113/204] =?UTF-8?q?=F0=9F=94=B4[`Attention`]=20Bert-based?= =?UTF-8?q?=20Models=20Attention=20Refactor=20(#38301)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * clean start to bert refactor * some test fixes * style * fix last tests * be strict on positional embeddings, fixup according tests * cache support * more cache fixes, new causal API * simplify masks, fix tests for gen * flex attn, static cache support, round of fixes * ? * this time * style * fix flash attention tests, flex attention requires torch 2.7.x to work with multiple classes (as recompile strats force a size call which is wrongly interpreted before) * roberta * fixup sdpa remains * attention split, simplify args and kwargs, better typing * fix encoder decoder * fix test * modular roberta * albert * data2vectext, making it modular tomorrow * modular data2vec text * tmp disable * xmod + cache position fixes * whoops * electra + markuplm, small fixes * remove wrong copy * xlm_roberta + some embedding fixes * roberta prelayernorm * RemBert: remove copy, maybe doing it later * ernie * fix roberta offloading * camembert * copy fixes * bert generation + fixes on eager * xlm roberta xl * bridgetower (text) + seamlessv2 copy fixes * rocbert + small fixes * whoops * small round of fixups * NOTE: kernels didnt load with an earlier version, some fixup (needs another look bc cross deps) * the end of the tunnel? * fixup nllbmoe + style * we dont need this anymore * megatron bert is barely used, low prio skip for now * Modernize bert (template for others) NOTE: trying to push this through, might be overdue if not in time possible * check inputs for all others (if checkmarked) * fix bridgetower * style * fix encoder decoder (partially but cause found and fix also, just needs to be done for everything else) * proper fix for bert to force intermediate dict outputs * propagate to others * style * xlm roberta xl investigation, its the layernorm... * mobile bert * revert this, might cause issues with composed models * review * style --- .../models/albert/modeling_albert.py | 504 +++---- .../models/altclip/modeling_altclip.py | 69 +- .../models/autoformer/modeling_autoformer.py | 2 +- src/transformers/models/bart/modeling_bart.py | 6 +- src/transformers/models/bert/modeling_bert.py | 911 ++++++------ .../modeling_bert_generation.py | 700 +++++---- .../modeling_bigbird_pegasus.py | 4 +- .../models/biogpt/modeling_biogpt.py | 2 +- .../models/biogpt/modular_biogpt.py | 2 +- .../models/blenderbot/modeling_blenderbot.py | 6 +- .../modeling_blenderbot_small.py | 6 +- .../bridgetower/modeling_bridgetower.py | 774 ++++++---- .../models/camembert/modeling_camembert.py | 1304 ++++++++--------- .../models/camembert/modular_camembert.py | 544 +++++++ src/transformers/models/clap/modeling_clap.py | 69 +- .../data2vec/modeling_data2vec_audio.py | 2 +- .../models/data2vec/modeling_data2vec_text.py | 1037 +++++++------ .../models/data2vec/modular_data2vec_text.py | 622 ++++++++ src/transformers/models/dia/modeling_dia.py | 4 +- src/transformers/models/dia/modular_dia.py | 4 +- .../models/electra/modeling_electra.py | 816 ++++++----- .../modeling_encoder_decoder.py | 29 +- .../models/ernie/modeling_ernie.py | 1059 +++++++------ .../models/ernie/modular_ernie.py | 1012 +++++++++++++ .../models/hubert/modeling_hubert.py | 4 +- .../models/informer/modeling_informer.py | 2 +- .../models/informer/modular_informer.py | 2 +- .../models/kosmos2/modeling_kosmos2.py | 45 +- .../models/kosmos2_5/modeling_kosmos2_5.py | 47 +- src/transformers/models/lilt/modeling_lilt.py | 6 +- .../models/m2m_100/modeling_m2m_100.py | 49 +- .../models/marian/modeling_marian.py | 6 +- .../models/markuplm/modeling_markuplm.py | 44 +- .../models/mbart/modeling_mbart.py | 6 +- .../megatron_bert/modeling_megatron_bert.py | 2 +- .../models/mobilebert/modeling_mobilebert.py | 382 +++-- .../models/nllb_moe/modeling_nllb_moe.py | 53 +- .../models/pegasus/modeling_pegasus.py | 6 +- .../models/pegasus_x/modeling_pegasus_x.py | 6 +- .../models/plbart/modeling_plbart.py | 6 +- .../models/plbart/modular_plbart.py | 6 +- .../models/prophetnet/modeling_prophetnet.py | 2 + .../models/rembert/modeling_rembert.py | 4 +- .../models/roberta/modeling_roberta.py | 1003 ++++++------- .../models/roberta/modular_roberta.py | 800 ++++++++++ .../modeling_roberta_prelayernorm.py | 853 ++++++----- .../models/roc_bert/modeling_roc_bert.py | 852 ++++++----- .../seamless_m4t/modeling_seamless_m4t.py | 49 +- .../modeling_seamless_m4t_v2.py | 51 +- .../speech_to_text/modeling_speech_to_text.py | 2 +- .../models/tapas/modeling_tapas.py | 4 +- .../modeling_time_series_transformer.py | 2 +- .../models/unispeech/modeling_unispeech.py | 4 +- .../unispeech_sat/modeling_unispeech_sat.py | 4 +- .../models/wav2vec2/modeling_wav2vec2.py | 4 +- .../xlm_roberta/modeling_xlm_roberta.py | 1233 ++++++++-------- .../models/xlm_roberta/modular_xlm_roberta.py | 559 +++++++ .../xlm_roberta_xl/modeling_xlm_roberta_xl.py | 1233 ++++++++-------- .../xlm_roberta_xl/modular_xlm_roberta_xl.py | 777 ++++++++++ src/transformers/models/xmod/modeling_xmod.py | 843 ++++++----- tests/models/albert/test_modeling_albert.py | 7 +- tests/models/bert/test_modeling_bert.py | 199 ++- .../test_modeling_bert_generation.py | 132 +- .../data2vec/test_modeling_data2vec_text.py | 138 +- tests/models/electra/test_modeling_electra.py | 131 +- .../test_modeling_encoder_decoder.py | 7 +- tests/models/ernie/test_modeling_ernie.py | 125 ++ .../mobilebert/test_modeling_mobilebert.py | 6 +- tests/models/roberta/test_modeling_roberta.py | 137 +- .../test_modeling_roberta_prelayernorm.py | 133 +- .../models/roc_bert/test_modeling_roc_bert.py | 136 ++ tests/models/sam2/test_modeling_sam2.py | 10 +- .../test_modeling_vision_text_dual_encoder.py | 5 +- .../test_modeling_xlm_roberta_xl.py | 250 +++- tests/models/xmod/test_modeling_xmod.py | 135 +- tests/test_modeling_common.py | 26 +- 76 files changed, 13160 insertions(+), 6856 deletions(-) create mode 100644 src/transformers/models/camembert/modular_camembert.py create mode 100644 src/transformers/models/data2vec/modular_data2vec_text.py create mode 100644 src/transformers/models/ernie/modular_ernie.py create mode 100644 src/transformers/models/roberta/modular_roberta.py create mode 100644 src/transformers/models/xlm_roberta/modular_xlm_roberta.py create mode 100644 src/transformers/models/xlm_roberta_xl/modular_xlm_roberta_xl.py diff --git a/src/transformers/models/albert/modeling_albert.py b/src/transformers/models/albert/modeling_albert.py index c3d1dc540223..31caa335bb64 100755 --- a/src/transformers/models/albert/modeling_albert.py +++ b/src/transformers/models/albert/modeling_albert.py @@ -14,16 +14,15 @@ # limitations under the License. """PyTorch ALBERT model.""" -import math from dataclasses import dataclass -from typing import Optional, Union +from typing import Callable, Optional, Union import torch from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN -from ...modeling_attn_mask_utils import _prepare_4d_attention_mask_for_sdpa +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_outputs import ( BaseModelOutput, BaseModelOutputWithPooling, @@ -33,16 +32,22 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import ( apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer, ) -from ...utils import ModelOutput, auto_docstring, logging +from ...utils import ModelOutput, TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_albert import AlbertConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) @@ -69,33 +74,32 @@ def __init__(self, config: AlbertConfig): "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False ) - # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.forward def forward( self, input_ids: Optional[torch.LongTensor] = None, token_type_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - past_key_values_length: int = 0, ) -> torch.Tensor: if input_ids is not None: input_shape = input_ids.size() else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape if position_ids is None: - position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length] + position_ids = self.position_ids[:, :seq_length] # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -112,6 +116,65 @@ def forward( return embeddings +# Copied from transformers.models.bert.modeling_bert.eager_attention_forward +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + class AlbertAttention(nn.Module): def __init__(self, config: AlbertConfig): super().__init__() @@ -120,19 +183,22 @@ def __init__(self, config: AlbertConfig): f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads}" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.hidden_size = config.hidden_size self.attention_head_size = config.hidden_size // config.num_attention_heads self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 + + self.attention_dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.output_dropout = nn.Dropout(config.hidden_dropout_prob) self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) self.value = nn.Linear(config.hidden_size, self.all_head_size) - - self.attention_dropout = nn.Dropout(config.attention_probs_dropout_prob) - self.output_dropout = nn.Dropout(config.hidden_dropout_prob) self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.pruned_heads = set() @@ -141,6 +207,8 @@ def __init__(self, config: AlbertConfig): self.max_position_embeddings = config.max_position_embeddings self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) + self.is_causal = False + def prune_heads(self, heads: list[int]) -> None: if len(heads) == 0: return @@ -164,125 +232,45 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - output_attentions: bool = False, - ) -> Union[tuple[torch.Tensor], tuple[torch.Tensor, torch.Tensor]]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - key_layer = self.key(hidden_states) - value_layer = self.value(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 - ) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose(1, 2) - value_layer = value_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 - ) - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in BertModel forward() function) - attention_scores = attention_scores + attention_mask - - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - seq_length = hidden_states.size()[1] - position_ids_l = torch.arange(seq_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(seq_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.attention_dropout(attention_probs) - - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - - context_layer = torch.matmul(attention_probs, value_layer) - context_layer = context_layer.transpose(2, 1).flatten(2) - - projected_context_layer = self.dense(context_layer) - projected_context_layer_dropout = self.output_dropout(projected_context_layer) - layernormed_context_layer = self.LayerNorm(hidden_states + projected_context_layer_dropout) - return (layernormed_context_layer, attention_probs) if output_attentions else (layernormed_context_layer,) - - -class AlbertSdpaAttention(AlbertAttention): - def __init__(self, config): - super().__init__(config) - self.dropout_prob = config.attention_probs_dropout_prob - - def forward( - self, - hidden_states: torch.Tensor, - attention_mask: Optional[torch.FloatTensor] = None, - head_mask: Optional[torch.FloatTensor] = None, - output_attentions: bool = False, - ) -> Union[tuple[torch.Tensor], tuple[torch.Tensor, torch.Tensor]]: - if self.position_embedding_type != "absolute" or output_attentions: - logger.warning( - "AlbertSdpaAttention is used but `torch.nn.functional.scaled_dot_product_attention` does not support " - "non-absolute `position_embedding_type` or `output_attentions=True` . Falling back to " - "the eager attention implementation, but specifying the eager implementation will be required from " - "Transformers version v5.0.0 onwards. This warning can be removed using the argument " - '`attn_implementation="eager"` when loading the model.' - ) - return super().forward(hidden_states, attention_mask, output_attentions=output_attentions) - - batch_size, seq_len, _ = hidden_states.size() - query_layer = ( - self.query(hidden_states) - .view(batch_size, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) - key_layer = ( - self.key(hidden_states) - .view(batch_size, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) - value_layer = ( - self.value(hidden_states) - .view(batch_size, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) - - attention_output = torch.nn.functional.scaled_dot_product_attention( - query=query_layer, - key=key_layer, - value=value_layer, - attn_mask=attention_mask, - dropout_p=self.dropout_prob if self.training else 0.0, - is_causal=False, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=False, + **kwargs, ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attention_output = attention_output.transpose(1, 2) - attention_output = attention_output.reshape(batch_size, seq_len, self.all_head_size) - - projected_context_layer = self.dense(attention_output) - projected_context_layer_dropout = self.output_dropout(projected_context_layer) - layernormed_context_layer = self.LayerNorm(hidden_states + projected_context_layer_dropout) - return (layernormed_context_layer,) - + attn_output = self.dense(attn_output) + attn_output = self.output_dropout(attn_output) + attn_output = self.LayerNorm(hidden_states + attn_output) -ALBERT_ATTENTION_CLASSES = { - "eager": AlbertAttention, - "sdpa": AlbertSdpaAttention, -} + return attn_output, attn_weights class AlbertLayer(nn.Module): @@ -293,7 +281,7 @@ def __init__(self, config: AlbertConfig): self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 self.full_layer_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - self.attention = ALBERT_ATTENTION_CLASSES[config._attn_implementation](config) + self.attention = AlbertAttention(config) self.ffn = nn.Linear(config.hidden_size, config.intermediate_size) self.ffn_output = nn.Linear(config.intermediate_size, config.hidden_size) self.activation = ACT2FN[config.hidden_act] @@ -304,20 +292,18 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - output_attentions: bool = False, - output_hidden_states: bool = False, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor, torch.Tensor]: - attention_output = self.attention(hidden_states, attention_mask, head_mask, output_attentions) + attention_output, _ = self.attention(hidden_states, attention_mask, head_mask, **kwargs) ffn_output = apply_chunking_to_forward( self.ff_chunk, self.chunk_size_feed_forward, self.seq_len_dim, - attention_output[0], + attention_output, ) - hidden_states = self.full_layer_layer_norm(ffn_output + attention_output[0]) - - return (hidden_states,) + attention_output[1:] # add attentions if we output them + hidden_states = self.full_layer_layer_norm(ffn_output + attention_output) + return hidden_states def ff_chunk(self, attention_output: torch.Tensor) -> torch.Tensor: ffn_output = self.ffn(attention_output) @@ -337,28 +323,11 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - output_attentions: bool = False, - output_hidden_states: bool = False, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[Union[torch.Tensor, tuple[torch.Tensor]], ...]: - layer_hidden_states = () - layer_attentions = () - for layer_index, albert_layer in enumerate(self.albert_layers): - layer_output = albert_layer(hidden_states, attention_mask, head_mask[layer_index], output_attentions) - hidden_states = layer_output[0] - - if output_attentions: - layer_attentions = layer_attentions + (layer_output[1],) - - if output_hidden_states: - layer_hidden_states = layer_hidden_states + (hidden_states,) - - outputs = (hidden_states,) - if output_hidden_states: - outputs = outputs + (layer_hidden_states,) - if output_attentions: - outputs = outputs + (layer_attentions,) - return outputs # last-layer hidden state, (layer hidden states), (layer attentions) + hidden_states = albert_layer(hidden_states, attention_mask, head_mask[layer_index], **kwargs) + return hidden_states class AlbertTransformer(nn.Module): @@ -374,15 +343,10 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - output_attentions: bool = False, - output_hidden_states: bool = False, - return_dict: bool = True, + **kwargs: Unpack[TransformersKwargs], ) -> Union[BaseModelOutput, tuple]: hidden_states = self.embedding_hidden_mapping_in(hidden_states) - all_hidden_states = (hidden_states,) if output_hidden_states else None - all_attentions = () if output_attentions else None - head_mask = [None] * self.config.num_hidden_layers if head_mask is None else head_mask for i in range(self.config.num_hidden_layers): @@ -392,33 +356,28 @@ def forward( # Index of the hidden group group_idx = int(i / (self.config.num_hidden_layers / self.config.num_hidden_groups)) - layer_group_output = self.albert_layer_groups[group_idx]( + hidden_states = self.albert_layer_groups[group_idx]( hidden_states, attention_mask, head_mask[group_idx * layers_per_group : (group_idx + 1) * layers_per_group], - output_attentions, - output_hidden_states, + **kwargs, ) - hidden_states = layer_group_output[0] - - if output_attentions: - all_attentions = all_attentions + layer_group_output[-1] - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - return BaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) + return BaseModelOutput(last_hidden_state=hidden_states) @auto_docstring class AlbertPreTrainedModel(PreTrainedModel): - config: AlbertConfig + config_class = AlbertConfig base_model_prefix = "albert" + _supports_flash_attn = True _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": AlbertLayer, + "attentions": AlbertAttention, + } def _init_weights(self, module): """Initialize the weights.""" @@ -464,7 +423,7 @@ class AlbertForPreTrainingOutput(ModelOutput): @auto_docstring class AlbertModel(AlbertPreTrainedModel): - config: AlbertConfig + config_class = AlbertConfig base_model_prefix = "albert" def __init__(self, config: AlbertConfig, add_pooling_layer: bool = True): @@ -513,6 +472,7 @@ def _prune_heads(self, heads_to_prune: dict[int, list[int]]) -> None: inner_group_idx = int(layer - group_idx * self.config.inner_group_num) self.encoder.albert_layer_groups[group_idx].albert_layers[inner_group_idx].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -522,84 +482,59 @@ def forward( position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[BaseModelOutputWithPooling, tuple]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - if attention_mask is None: - attention_mask = torch.ones(input_shape, device=device) - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") embedding_output = self.embeddings( input_ids, position_ids=position_ids, token_type_ids=token_type_ids, inputs_embeds=inputs_embeds ) - use_sdpa_attention_mask = ( - self.attn_implementation == "sdpa" - and self.position_embedding_type == "absolute" - and head_mask is None - and not output_attentions - ) - - if use_sdpa_attention_mask: - extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - extended_attention_mask = attention_mask.unsqueeze(1).unsqueeze(2) - extended_attention_mask = extended_attention_mask.to(dtype=self.dtype) # fp16 compatibility - extended_attention_mask = (1.0 - extended_attention_mask) * torch.finfo(self.dtype).min + attention_mask = self._update_full_mask(attention_mask, embedding_output) head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) encoder_outputs = self.encoder( embedding_output, - extended_attention_mask, + attention_mask, head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + position_ids=position_ids, + **kwargs, ) sequence_output = encoder_outputs[0] pooled_output = self.pooler_activation(self.pooler(sequence_output[:, 0])) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] - return BaseModelOutputWithPooling( last_hidden_state=sequence_output, pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, ) + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_full_mask + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + @auto_docstring( custom_intro=""" @@ -629,6 +564,7 @@ def set_output_embeddings(self, new_embeddings: nn.Linear) -> None: def get_input_embeddings(self) -> nn.Embedding: return self.albert.embeddings.word_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -640,9 +576,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, sentence_order_label: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[AlbertForPreTrainingOutput, tuple]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -670,8 +604,6 @@ def forward( >>> prediction_logits = outputs.prediction_logits >>> sop_logits = outputs.sop_logits ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.albert( input_ids, attention_mask=attention_mask, @@ -679,9 +611,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output, pooled_output = outputs[:2] @@ -696,10 +627,6 @@ def forward( sentence_order_loss = loss_fct(sop_scores.view(-1, 2), sentence_order_label.view(-1)) total_loss = masked_lm_loss + sentence_order_loss - if not return_dict: - output = (prediction_scores, sop_scores) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return AlbertForPreTrainingOutput( loss=total_loss, prediction_logits=prediction_scores, @@ -775,6 +702,7 @@ def set_output_embeddings(self, new_embeddings: nn.Linear) -> None: def get_input_embeddings(self) -> nn.Embedding: return self.albert.embeddings.word_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -785,9 +713,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[MaskedLMOutput, tuple]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -824,8 +750,6 @@ def forward( 0.81 ``` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.albert( input_ids=input_ids, attention_mask=attention_mask, @@ -833,9 +757,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_outputs = outputs[0] @@ -846,10 +769,6 @@ def forward( loss_fct = CrossEntropyLoss() masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -877,6 +796,7 @@ def __init__(self, config: AlbertConfig): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -887,9 +807,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[SequenceClassifierOutput, tuple]: r""" labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): @@ -897,8 +815,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.albert( input_ids=input_ids, attention_mask=attention_mask, @@ -906,9 +822,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -939,10 +854,6 @@ def forward( loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return SequenceClassifierOutput( loss=loss, logits=logits, @@ -969,6 +880,7 @@ def __init__(self, config: AlbertConfig): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -979,16 +891,12 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[TokenClassifierOutput, tuple]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.albert( input_ids, attention_mask=attention_mask, @@ -996,9 +904,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1011,10 +918,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1035,6 +938,7 @@ def __init__(self, config: AlbertConfig): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1046,12 +950,8 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, start_positions: Optional[torch.LongTensor] = None, end_positions: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[AlbertForPreTrainingOutput, tuple]: - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.albert( input_ids=input_ids, attention_mask=attention_mask, @@ -1059,9 +959,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1088,10 +987,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, @@ -1113,6 +1008,7 @@ def __init__(self, config: AlbertConfig): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1123,9 +1019,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[AlbertForPreTrainingOutput, tuple]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1157,7 +1051,6 @@ def forward( num_choices-1]` where *num_choices* is the size of the second dimension of the input tensors. (see *input_ids* above) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1176,9 +1069,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1192,10 +1084,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, diff --git a/src/transformers/models/altclip/modeling_altclip.py b/src/transformers/models/altclip/modeling_altclip.py index 5cae61f12d7f..ec8031507d50 100755 --- a/src/transformers/models/altclip/modeling_altclip.py +++ b/src/transformers/models/altclip/modeling_altclip.py @@ -90,15 +90,11 @@ def to_tuple(self) -> tuple[Any]: # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->AltRoberta class AltRobertaEmbeddings(nn.Module): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ + """Construct the embeddings from word, position and token_type embeddings.""" - # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ def __init__(self, config): super().__init__() self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) - self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) @@ -112,37 +108,44 @@ def __init__(self, config): "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False ) - # End copy self.padding_idx = config.pad_token_id self.position_embeddings = nn.Embedding( config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx ) def forward( - self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: if position_ids is None: if input_ids is not None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) if input_ids is not None: input_shape = input_ids.size() else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -158,7 +161,8 @@ def forward( embeddings = self.dropout(embeddings) return embeddings - def create_position_ids_from_inputs_embeds(self, inputs_embeds): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -171,10 +175,26 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds): sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape) + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + class AltRobertaSelfAttention(nn.Module): def __init__(self, config, position_embedding_type=None): @@ -1366,21 +1386,4 @@ def forward( ) -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - __all__ = ["AltCLIPPreTrainedModel", "AltCLIPVisionModel", "AltCLIPTextModel", "AltCLIPModel"] diff --git a/src/transformers/models/autoformer/modeling_autoformer.py b/src/transformers/models/autoformer/modeling_autoformer.py index fe11fc4c4860..fc1f57aec0e7 100644 --- a/src/transformers/models/autoformer/modeling_autoformer.py +++ b/src/transformers/models/autoformer/modeling_autoformer.py @@ -873,7 +873,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/bart/modeling_bart.py b/src/transformers/models/bart/modeling_bart.py index 0a1f2451cff1..97e736520fe6 100755 --- a/src/transformers/models/bart/modeling_bart.py +++ b/src/transformers/models/bart/modeling_bart.py @@ -530,7 +530,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -567,7 +567,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -687,7 +687,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/bert/modeling_bert.py b/src/transformers/models/bert/modeling_bert.py index 186d13bb7541..384e34351ea7 100755 --- a/src/transformers/models/bert/modeling_bert.py +++ b/src/transformers/models/bert/modeling_bert.py @@ -15,19 +15,19 @@ # limitations under the License. """PyTorch BERT model.""" -import math import warnings from dataclasses import dataclass -from typing import Optional, Union +from typing import Callable, Optional, Union import torch from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin -from ...modeling_attn_mask_utils import _prepare_4d_attention_mask_for_sdpa, _prepare_4d_causal_attention_mask_for_sdpa +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -40,13 +40,18 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import ModelOutput, auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import ModelOutput, TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_bert import BertConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) @@ -83,7 +88,7 @@ def forward( else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape if position_ids is None: position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length] @@ -93,9 +98,10 @@ def forward( # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -112,18 +118,78 @@ def forward( return embeddings +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + class BertSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -138,215 +204,156 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 - ) - - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only bert can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) - - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in BertModel forward() function) - attention_scores = attention_scores + attention_mask + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - context_layer = torch.matmul(attention_probs, value_layer) +class BertCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + self.config = config - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 - return context_layer, attention_probs + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) -class BertSdpaSelfAttention(BertSelfAttention): - def __init__(self, config, position_embedding_type=None, layer_idx=None): - super().__init__(config, position_embedding_type=position_embedding_type, layer_idx=layer_idx) - self.dropout_prob = config.attention_probs_dropout_prob + self.is_causal = is_causal + self.layer_idx = layer_idx - # Adapted from BertSelfAttention - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, - attention_mask: Optional[torch.Tensor] = None, - head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, - cache_position: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - if self.position_embedding_type != "absolute" or output_attentions or head_mask is not None: - # TODO: Improve this warning with e.g. `model.config._attn_implementation = "manual"` once implemented. - logger.warning_once( - "BertSdpaSelfAttention is used but `torch.nn.functional.scaled_dot_product_attention` does not support " - "non-absolute `position_embedding_type` or `output_attentions=True` or `head_mask`. Falling back to " - "the manual attention implementation, but specifying the manual implementation will be required from " - "Transformers version v5.0.0 onwards. This warning can be removed using the argument " - '`attn_implementation="eager"` when loading the model.' - ) - return super().forward( - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states, - past_key_values, - output_attentions, - cache_position, - ) + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - bsz, tgt_len, _ = hidden_states.size() + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - query_layer = ( - self.query(hidden_states).view(bsz, -1, self.num_attention_heads, self.attention_head_size).transpose(1, 2) - ) + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - is_updated = False - is_cross_attention = encoder_hidden_states is not None - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_states from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values else: - key_layer = ( - self.key(current_states) - .view(bsz, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) - value_layer = ( - self.value(current_states) - .view(bsz, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx ) # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + past_key_value.is_updated[self.layer_idx] = True - # We dispatch to SDPA's Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment - # in SDPA to support both torch.compile's dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling. - # The tgt_len > 1 is necessary to match with AttentionMaskConverter.to_causal_4d that does not create - # a causal mask in case tgt_len == 1. - is_causal = self.is_decoder and not is_cross_attention and attention_mask is None and tgt_len > 1 + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - attn_output = torch.nn.functional.scaled_dot_product_attention( + attn_output, attn_weights = attention_interface( + self, query_layer, key_layer, value_layer, - attn_mask=attention_mask, - dropout_p=self.dropout_prob if self.training else 0.0, - is_causal=is_causal, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) - - attn_output = attn_output.transpose(1, 2) - attn_output = attn_output.reshape(bsz, tgt_len, self.all_head_size) - - return attn_output, None + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights class BertSelfOutput(nn.Module): @@ -363,19 +370,15 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -BERT_SELF_ATTENTION_CLASSES = { - "eager": BertSelfAttention, - "sdpa": BertSdpaSelfAttention, -} - - class BertAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = BERT_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = BertCrossAttention if is_cross_attention else BertSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = BertSelfOutput(config) self.pruned_heads = set() @@ -398,29 +401,29 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, + encoder_hidden_states=encoder_hidden_states, attention_mask=attention_mask, head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights class BertIntermediate(nn.Module): @@ -457,17 +460,22 @@ def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = BertAttention(config, layer_idx=layer_idx) + self.attention = BertAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = BertAttention(config, position_embedding_type="absolute", layer_idx=layer_idx) + self.crossattention = BertAttention( + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) self.intermediate = BertIntermediate(config) self.output = BertOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -475,20 +483,19 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -497,24 +504,21 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - outputs = (layer_output,) + outputs - - return outputs + return layer_output def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -523,11 +527,10 @@ def feed_forward_chunk(self, attention_output): class BertEncoder(nn.Module): - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config self.layer = nn.ModuleList([BertLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) - self.gradient_checkpointing = False def forward( self, @@ -538,77 +541,26 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and self.config.is_decoder and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - - if use_cache and self.config.is_decoder and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, # as a positional argument for gradient checkpointing encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_values, cache_position=cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) @@ -701,10 +653,18 @@ def forward(self, sequence_output, pooled_output): @auto_docstring class BertPreTrainedModel(PreTrainedModel): - config: BertConfig + config_class = BertConfig base_model_prefix = "bert" supports_gradient_checkpointing = True + _supports_flash_attn = True _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": BertLayer, + "attentions": BertSelfAttention, + "cross_attentions": BertCrossAttention, + } def _init_weights(self, module): """Initialize the weights""" @@ -770,13 +730,13 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = BertEmbeddings(config) self.encoder = BertEncoder(config) self.pooler = BertPooler(config) if add_pooling_layer else None - self.attn_implementation = config._attn_implementation self.position_embedding_type = config.position_embedding_type # Initialize weights and apply final processing @@ -796,6 +756,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -807,52 +768,40 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape + else: + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] + + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) embedding_output = self.embeddings( input_ids=input_ids, @@ -862,55 +811,16 @@ def forward( past_key_values_length=past_key_values_length, ) - if attention_mask is None: - attention_mask = torch.ones((batch_size, seq_length + past_key_values_length), device=device) - - use_sdpa_attention_masks = ( - self.attn_implementation == "sdpa" - and self.position_embedding_type == "absolute" - and head_mask is None - and not output_attentions + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, ) - # Expand the attention mask - if use_sdpa_attention_masks and attention_mask.dim() == 2: - # Expand the attention mask for SDPA. - # [bsz, seq_len] -> [bsz, 1, seq_len, seq_len] - if self.config.is_decoder: - extended_attention_mask = _prepare_4d_causal_attention_mask_for_sdpa( - attention_mask, - input_shape, - embedding_output, - past_key_values_length, - ) - else: - extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - - if use_sdpa_attention_masks and encoder_attention_mask.dim() == 2: - # Expand the attention mask for SDPA. - # [bsz, seq_len] -> [bsz, 1, seq_len, seq_len] - encoder_extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - encoder_attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) - else: - encoder_extended_attention_mask = None - # Prepare head mask if needed # 1.0 in head_mask indicate we keep the head # attention_probs has shape bsz x n_heads x N x N @@ -920,32 +830,137 @@ def forward( encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) - sequence_output = encoder_outputs[0] + sequence_output = encoder_outputs.last_hidden_state pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_full_mask + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_cross_attn_mask + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + @auto_docstring( custom_intro=""" @@ -972,6 +987,7 @@ def set_output_embeddings(self, new_embeddings): self.cls.predictions.decoder = new_embeddings self.cls.predictions.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -983,9 +999,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, next_sentence_label: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BertForPreTrainingOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1015,8 +1029,6 @@ def forward( >>> seq_relationship_logits = outputs.seq_relationship_logits ``` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.bert( input_ids, attention_mask=attention_mask, @@ -1024,9 +1036,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output, pooled_output = outputs[:2] @@ -1039,10 +1050,6 @@ def forward( next_sentence_loss = loss_fct(seq_relationship_score.view(-1, 2), next_sentence_label.view(-1)) total_loss = masked_lm_loss + next_sentence_loss - if not return_dict: - output = (prediction_scores, seq_relationship_score) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return BertForPreTrainingOutput( loss=total_loss, prediction_logits=prediction_scores, @@ -1079,6 +1086,7 @@ def set_output_embeddings(self, new_embeddings): self.cls.predictions.decoder = new_embeddings self.cls.predictions.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -1091,13 +1099,10 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, - **loss_kwargs, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1105,7 +1110,6 @@ def forward( `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -1120,10 +1124,9 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1131,11 +1134,7 @@ def forward( lm_loss = None if labels is not None: - lm_loss = self.loss_function(prediction_scores, labels, self.config.vocab_size, **loss_kwargs) - - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output + lm_loss = self.loss_function(prediction_scores, labels, self.config.vocab_size, **kwargs) return CausalLMOutputWithCrossAttentions( loss=lm_loss, @@ -1173,6 +1172,7 @@ def set_output_embeddings(self, new_embeddings): self.cls.predictions.decoder = new_embeddings self.cls.predictions.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -1185,9 +1185,7 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1195,9 +1193,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.bert( input_ids, attention_mask=attention_mask, @@ -1207,9 +1202,8 @@ def forward( inputs_embeds=inputs_embeds, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1220,10 +1214,6 @@ def forward( loss_fct = CrossEntropyLoss() # -100 index = padding token masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -1271,6 +1261,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1281,10 +1272,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], NextSentencePredictorOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): @@ -1321,8 +1309,6 @@ def forward( ) labels = kwargs.pop("next_sentence_label") - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.bert( input_ids, attention_mask=attention_mask, @@ -1330,9 +1316,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1344,10 +1329,6 @@ def forward( loss_fct = CrossEntropyLoss() next_sentence_loss = loss_fct(seq_relationship_scores.view(-1, 2), labels.view(-1)) - if not return_dict: - output = (seq_relationship_scores,) + outputs[2:] - return ((next_sentence_loss,) + output) if next_sentence_loss is not None else output - return NextSentencePredictorOutput( loss=next_sentence_loss, logits=seq_relationship_scores, @@ -1378,6 +1359,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1388,9 +1370,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): @@ -1398,8 +1378,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.bert( input_ids, attention_mask=attention_mask, @@ -1407,9 +1385,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1439,9 +1416,6 @@ def forward( elif self.config.problem_type == "multi_label_classification": loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output return SequenceClassifierOutput( loss=loss, @@ -1466,6 +1440,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1476,9 +1451,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1510,7 +1483,6 @@ def forward( num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1530,9 +1502,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1546,10 +1517,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1574,6 +1541,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1584,16 +1552,12 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.bert( input_ids, attention_mask=attention_mask, @@ -1601,9 +1565,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1616,10 +1579,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1640,6 +1599,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1651,12 +1611,8 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, start_positions: Optional[torch.Tensor] = None, end_positions: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.bert( input_ids, attention_mask=attention_mask, @@ -1664,9 +1620,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1693,10 +1648,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, diff --git a/src/transformers/models/bert_generation/modeling_bert_generation.py b/src/transformers/models/bert_generation/modeling_bert_generation.py index c1b09041cd74..8966adc1eb26 100755 --- a/src/transformers/models/bert_generation/modeling_bert_generation.py +++ b/src/transformers/models/bert_generation/modeling_bert_generation.py @@ -14,24 +14,35 @@ # limitations under the License. """PyTorch BERT model specific for generation.""" -import math -from typing import Optional, Union +from typing import Callable, Optional, Union import torch from torch import nn from ...activations import ACT2FN -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import BaseModelOutputWithPastAndCrossAttentions, CausalLMOutputWithCrossAttentions -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import ( + TransformersKwargs, + auto_docstring, + is_torch_flex_attn_available, + logging, +) +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_bert_generation import BertGenerationConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) @@ -50,19 +61,80 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states +# Copied from transformers.models.bert.modeling_bert.eager_attention_forward +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + # Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->BertGeneration class BertGenerationSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -77,126 +149,169 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only bert can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, + ) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 +# Copied from transformers.models.bert.modeling_bert.BertCrossAttention with Bert->BertGeneration +class BertGenerationCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + self.config = config - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 - ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in BertGenerationModel forward() function) - attention_scores = attention_scores + attention_mask + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + self.is_causal = is_causal + self.layer_idx = layer_idx - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask + def forward( + self, + hidden_states: torch.Tensor, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - context_layer = torch.matmul(attention_probs, value_layer) + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - return context_layer, attention_probs + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: + # reuse k,v, cross_attentions + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values + else: + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx + ) + # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls + past_key_value.is_updated[self.layer_idx] = True -BERT_GENERATION_SELF_ATTENTION_CLASSES = { - "eager": BertGenerationSelfAttention, -} + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights # Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->BertGeneration,BERT->BERT_GENERATION class BertGenerationAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = BERT_GENERATION_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = BertGenerationCrossAttention if is_cross_attention else BertGenerationSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = BertGenerationSelfOutput(config) self.pruned_heads = set() @@ -219,29 +334,29 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, + encoder_hidden_states=encoder_hidden_states, attention_mask=attention_mask, head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights # Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert->BertGeneration @@ -281,19 +396,22 @@ def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = BertGenerationAttention(config, layer_idx=layer_idx) + self.attention = BertGenerationAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") self.crossattention = BertGenerationAttention( - config, position_embedding_type="absolute", layer_idx=layer_idx + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, ) self.intermediate = BertGenerationIntermediate(config) self.output = BertGenerationOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -301,20 +419,19 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -323,24 +440,21 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - outputs = (layer_output,) + outputs - - return outputs + return layer_output def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -348,12 +462,13 @@ def feed_forward_chunk(self, attention_output): return layer_output +# Copied from transformers.models.bert.modeling_bert.BertEncoder class BertEncoder(nn.Module): - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config + # Ignore copy self.layer = nn.ModuleList([BertGenerationLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) - self.gradient_checkpointing = False def forward( self, @@ -364,76 +479,26 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - if use_cache and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, # as a positional argument for gradient checkpointing encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_values, cache_position=cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) @@ -475,9 +540,18 @@ def forward(self, input_ids=None, position_ids=None, inputs_embeds=None, past_ke @auto_docstring class BertGenerationPreTrainedModel(PreTrainedModel): - config: BertGenerationConfig + config_class = BertGenerationConfig base_model_prefix = "bert" supports_gradient_checkpointing = True + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": BertGenerationLayer, + "attentions": BertGenerationSelfAttention, + "cross_attentions": BertGenerationCrossAttention, + } def _init_weights(self, module): """Initialize the weights""" @@ -521,6 +595,7 @@ class BertGenerationEncoder(BertGenerationPreTrainedModel): def __init__(self, config): super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = BertGenerationEmbeddings(config) self.encoder = BertEncoder(config) @@ -542,6 +617,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -552,69 +628,40 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, # NOOP kwargs, for now - ) -> Union[tuple, BaseModelOutputWithPastAndCrossAttentions]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) + + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") - if attention_mask is None: - attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) - - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape else: - encoder_extended_attention_mask = None + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) embedding_output = self.embeddings( input_ids=input_ids, @@ -623,31 +670,155 @@ def forward( past_key_values_length=past_key_values_length, ) + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, + ) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) sequence_output = encoder_outputs[0] - if not return_dict: - return (sequence_output,) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=sequence_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + # Copied from transformers.models.bert.modeling_bert.BertModel._create_attention_masks + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_full_mask + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_cross_attn_mask + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + class BertGenerationOnlyLMHead(nn.Module): def __init__(self, config): @@ -696,6 +867,7 @@ def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings self.lm_head.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -707,12 +879,10 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, CausalLMOutputWithCrossAttentions]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -738,7 +908,6 @@ def forward( >>> prediction_logits = outputs.logits ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -752,9 +921,8 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + return_dict=True, **kwargs, ) @@ -770,10 +938,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[1:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, diff --git a/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py b/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py index 70644c8d3df2..04cc28e56bf9 100755 --- a/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py +++ b/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py @@ -1617,7 +1617,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -1738,7 +1738,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/biogpt/modeling_biogpt.py b/src/transformers/models/biogpt/modeling_biogpt.py index 8690082625a7..348bf2707584 100755 --- a/src/transformers/models/biogpt/modeling_biogpt.py +++ b/src/transformers/models/biogpt/modeling_biogpt.py @@ -375,7 +375,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None diff --git a/src/transformers/models/biogpt/modular_biogpt.py b/src/transformers/models/biogpt/modular_biogpt.py index 001c1de65756..accc1bdc7559 100644 --- a/src/transformers/models/biogpt/modular_biogpt.py +++ b/src/transformers/models/biogpt/modular_biogpt.py @@ -197,7 +197,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None diff --git a/src/transformers/models/blenderbot/modeling_blenderbot.py b/src/transformers/models/blenderbot/modeling_blenderbot.py index 3e25fad20d31..5cd138fe3180 100755 --- a/src/transformers/models/blenderbot/modeling_blenderbot.py +++ b/src/transformers/models/blenderbot/modeling_blenderbot.py @@ -495,7 +495,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -533,7 +533,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -654,7 +654,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py b/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py index e0e404f27cf8..1c1cf379d032 100755 --- a/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py +++ b/src/transformers/models/blenderbot_small/modeling_blenderbot_small.py @@ -488,7 +488,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -526,7 +526,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -647,7 +647,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/bridgetower/modeling_bridgetower.py b/src/transformers/models/bridgetower/modeling_bridgetower.py index 97fcc469a4c6..ff88a0a087d1 100644 --- a/src/transformers/models/bridgetower/modeling_bridgetower.py +++ b/src/transformers/models/bridgetower/modeling_bridgetower.py @@ -14,17 +14,18 @@ # limitations under the License. """PyTorch BridgeTower Model""" -import math from collections import OrderedDict from dataclasses import dataclass -from typing import Optional, Union +from typing import Callable, Optional, Union import torch from torch import nn from torch.nn import CrossEntropyLoss from ...activations import ACT2FN, QuickGELUActivation -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -33,13 +34,18 @@ ModelOutput, SequenceClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, logging, torch_int -from ...utils.deprecation import deprecate_kwarg +from ...utils import TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging, torch_int +from ...utils.generic import can_return_tuple from .configuration_bridgetower import BridgeTowerConfig, BridgeTowerTextConfig, BridgeTowerVisionConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) _TOKENIZER_FOR_DOC = "RobertaTokenizer" @@ -400,19 +406,80 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return pooled_output +# Copied from transformers.models.bert.modeling_bert.eager_attention_forward +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + # Copied from transformers.models.roberta.modeling_roberta.RobertaSelfAttention with Roberta->BridgeTower class BridgeTowerSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -427,126 +494,169 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only roberta can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, + ) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 +# Copied from transformers.models.roberta.modeling_roberta.RobertaCrossAttention with Roberta->BridgeTower +class BridgeTowerCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + self.config = config - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 - ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in BridgeTowerModel forward() function) - attention_scores = attention_scores + attention_mask + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + self.is_causal = is_causal + self.layer_idx = layer_idx - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask + def forward( + self, + hidden_states: torch.Tensor, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - context_layer = torch.matmul(attention_probs, value_layer) + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - return context_layer, attention_probs + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: + # reuse k,v, cross_attentions + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values + else: + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx + ) + # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls + past_key_value.is_updated[self.layer_idx] = True -BRIDGE_TOWER_SELF_ATTENTION_CLASSES = { - "eager": BridgeTowerSelfAttention, -} + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights # Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->BridgeTower,BERT->BRIDGE_TOWER class BridgeTowerAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = BRIDGE_TOWER_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = BridgeTowerCrossAttention if is_cross_attention else BridgeTowerSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = BridgeTowerSelfOutput(config) self.pruned_heads = set() @@ -569,29 +679,29 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, + encoder_hidden_states=encoder_hidden_states, attention_mask=attention_mask, head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights class BridgeTowerBertCrossLayer(nn.Module): @@ -599,14 +709,19 @@ def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = BridgeTowerAttention(config, layer_idx=layer_idx) + self.attention = BridgeTowerAttention(config, is_causal=True, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention - self.crossattention = BridgeTowerAttention(config, layer_idx=layer_idx) + self.crossattention = BridgeTowerAttention( + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) self.intermediate = BridgeTowerIntermediate(config) self.output = BridgeTowerOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states, @@ -614,43 +729,37 @@ def forward( attention_mask=None, head_mask=None, encoder_attention_mask=None, - past_key_values=None, - output_attentions=False, - cache_position=None, + past_key_value=None, + **kwargs: Unpack[TransformersKwargs], ): - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attention_outputs = self.attention( + self_attention_output, self_attn_weights = self.attention( hidden_states, attention_mask=attention_mask, head_mask=None, - output_attentions=output_attentions, - past_key_values=None, + past_key_value=None, + **kwargs, ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - # add self attentions if we output attention weights - outputs = self_attention_outputs[1:] + attention_output = self_attention_output - cross_attention_outputs = self.crossattention( + cross_attention_output, cross_attn_weights = self.crossattention( attention_output, - attention_mask=encoder_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + encoder_attention_mask=encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - # add cross attentions if we output attention weights - outputs = outputs + cross_attention_outputs[1:] + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - outputs = (layer_output,) + outputs - - return outputs + return ( + layer_output, + self_attn_weights, + cross_attn_weights, + ) def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -663,17 +772,23 @@ def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = BridgeTowerAttention(config, layer_idx=layer_idx) + self.attention = BridgeTowerAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = BridgeTowerAttention(config, position_embedding_type="absolute", layer_idx=layer_idx) + self.crossattention = BridgeTowerAttention( + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) self.intermediate = BridgeTowerIntermediate(config) self.output = BridgeTowerOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + # copied from transformers.models.bert.modeling_bert.BertLayer.forward def forward( self, hidden_states: torch.Tensor, @@ -681,26 +796,20 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 - self_attention_outputs = self.attention( + outputs = () + self_attention_output, self_attn_weights = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - - # if decoder, the last output is tuple of self-attn cache - if self.is_decoder: - outputs = self_attention_outputs[1:-1] - else: - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -709,22 +818,25 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, cross_attn_weights = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights + attention_output = cross_attention_output + outputs = (cross_attn_weights,) layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - return (layer_output,) + outputs + return outputs + ( + layer_output, + self_attn_weights, + ) def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -732,15 +844,14 @@ def feed_forward_chunk(self, attention_output): return layer_output -# Copied from transformers.models.roberta.modeling_roberta.RobertaEncoder with Roberta->BridgeTowerText +# copied from transformers.models.roberta.modeling_roberta.RobertaEncoder with Roberta->BridgeTowerText class BridgeTowerTextEncoder(nn.Module): - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config self.layer = nn.ModuleList( [BridgeTowerTextLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)] ) - self.gradient_checkpointing = False def forward( self, @@ -753,35 +864,14 @@ def forward( use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: all_hidden_states = () if output_hidden_states else None all_self_attentions = () if output_attentions else None all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and self.config.is_decoder and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - - if use_cache and self.config.is_decoder and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None layer_outputs = layer_module( @@ -790,9 +880,9 @@ def forward( layer_head_mask, encoder_hidden_states, # as a positional argument for gradient checkpointing encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_values, cache_position=cache_position, + **kwargs, ) hidden_states = layer_outputs[0] @@ -804,21 +894,9 @@ def forward( if output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, + past_key_values=past_key_values if use_cache else None, hidden_states=all_hidden_states, attentions=all_self_attentions, cross_attentions=all_cross_attentions, @@ -827,15 +905,11 @@ def forward( # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->BridgeTowerText class BridgeTowerTextEmbeddings(nn.Module): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ + """Construct the embeddings from word, position and token_type embeddings.""" - # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ def __init__(self, config): super().__init__() self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) - self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) @@ -849,37 +923,44 @@ def __init__(self, config): "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False ) - # End copy self.padding_idx = config.pad_token_id self.position_embeddings = nn.Embedding( config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx ) def forward( - self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: if position_ids is None: if input_ids is not None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) if input_ids is not None: input_shape = input_ids.size() else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -895,7 +976,8 @@ def forward( embeddings = self.dropout(embeddings) return embeddings - def create_position_ids_from_inputs_embeds(self, inputs_embeds): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -908,26 +990,25 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds): sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape) + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: + Args: + x: torch.Tensor x: - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx @auto_docstring @@ -1004,6 +1085,7 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = BridgeTowerTextEmbeddings(config) self.encoder = BridgeTowerTextEncoder(config) @@ -1027,7 +1109,11 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @can_return_tuple @auto_docstring + # NOTE: bridgetower with its multimodality has a more complicated scheme making records harder + # for now we skip the copies from bert but stay close to the original + # copied from transformers.models.bert.modeling_bert.BertModel.forward def forward( self, input_ids: Optional[torch.Tensor] = None, @@ -1038,77 +1124,54 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions output_hidden_states = ( output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - if attention_mask is None: - attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) - - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape else: - encoder_extended_attention_mask = None + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) embedding_output = self.embeddings( input_ids=input_ids, @@ -1117,24 +1180,43 @@ def forward( inputs_embeds=inputs_embeds, past_key_values_length=past_key_values_length, ) + + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, + ) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, output_attentions=output_attentions, output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) sequence_output = encoder_outputs[0] pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, @@ -1145,6 +1227,116 @@ def forward( cross_attentions=encoder_outputs.cross_attentions, ) + # Copied from transformers.models.bert.modeling_bert.BertModel._create_attention_masks + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_full_mask + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_cross_attn_mask + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + @auto_docstring( custom_intro=""" @@ -1181,10 +1373,10 @@ def __init__(self, config): ln.bias.data = self.vision_model.visual.ln_post.bias.data self.cross_modal_image_layers = nn.ModuleList( - [BridgeTowerBertCrossLayer(text_config, layer_idx=i) for i in range(config.num_hidden_layers)] + [BridgeTowerBertCrossLayer(text_config) for _ in range(config.num_hidden_layers)] ) self.cross_modal_text_layers = nn.ModuleList( - [BridgeTowerBertCrossLayer(text_config, layer_idx=i) for i in range(config.num_hidden_layers)] + [BridgeTowerBertCrossLayer(text_config) for _ in range(config.num_hidden_layers)] ) # Class token => Linear => Tanh diff --git a/src/transformers/models/camembert/modeling_camembert.py b/src/transformers/models/camembert/modeling_camembert.py index aa86eb18d652..dd882e60096f 100644 --- a/src/transformers/models/camembert/modeling_camembert.py +++ b/src/transformers/models/camembert/modeling_camembert.py @@ -1,3 +1,9 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/camembert/modular_camembert.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_camembert.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 # coding=utf-8 # Copyright 2019 Inria, Facebook AI Research and the HuggingFace Inc. team. # Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. @@ -13,19 +19,18 @@ # 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. -"""PyTorch CamemBERT model.""" -import math -from typing import Optional, Union +from typing import Callable, Optional, Union import torch -from torch import nn +import torch.nn as nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN, gelu -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin -from ...modeling_attn_mask_utils import _prepare_4d_attention_mask_for_sdpa, _prepare_4d_causal_attention_mask_for_sdpa +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -37,117 +42,93 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_camembert import CamembertConfig -logger = logging.get_logger(__name__) - - -# Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->Camembert -class CamembertEmbeddings(nn.Module): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ - - # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ - def __init__(self, config): - super().__init__() - self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) - self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) - self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask - self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - self.dropout = nn.Dropout(config.hidden_dropout_prob) - # position_ids (1, len position emb) is contiguous in memory and exported when serialized - self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") - self.register_buffer( - "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False - ) - self.register_buffer( - "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False - ) - # End copy - self.padding_idx = config.pad_token_id - self.position_embeddings = nn.Embedding( - config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx - ) +logger = logging.get_logger(__name__) - def forward( - self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): - if position_ids is None: - if input_ids is not None: - # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) - else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) - if input_ids is not None: - input_shape = input_ids.size() +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) else: - input_shape = inputs_embeds.size()[:-1] + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r - seq_length = input_shape[1] + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility - # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs - # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves - # issue #5664 - if token_type_ids is None: - if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key - if inputs_embeds is None: - inputs_embeds = self.word_embeddings(input_ids) - token_type_embeddings = self.token_type_embeddings(token_type_ids) + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling - embeddings = inputs_embeds + token_type_embeddings - if self.position_embedding_type == "absolute": - position_embeddings = self.position_embeddings(position_ids) - embeddings += position_embeddings - embeddings = self.LayerNorm(embeddings) - embeddings = self.dropout(embeddings) - return embeddings + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask - def create_position_ids_from_inputs_embeds(self, inputs_embeds): - """ - We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) - Args: - inputs_embeds: torch.Tensor + if head_mask is not None: + attn_weights = attn_weights * head_mask - Returns: torch.Tensor - """ - input_shape = inputs_embeds.size()[:-1] - sequence_length = input_shape[1] + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() - position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device - ) - return position_ids.unsqueeze(0).expand(input_shape) + return attn_output, attn_weights -# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfAttention with Roberta->Camembert class CamembertSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -162,219 +143,158 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 - ) - - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only camembert can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in CamembertModel forward() function) - attention_scores = attention_scores + attention_mask + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - context_layer = torch.matmul(attention_probs, value_layer) +class CamembertCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + self.config = config - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 - return context_layer, attention_probs + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) -# Copied from transformers.models.roberta.modeling_roberta.RobertaSdpaSelfAttention with Roberta->Camembert -class CamembertSdpaSelfAttention(CamembertSelfAttention): - def __init__(self, config, position_embedding_type=None, layer_idx=None): - super().__init__(config, position_embedding_type=position_embedding_type, layer_idx=layer_idx) - self.dropout_prob = config.attention_probs_dropout_prob + self.is_causal = is_causal + self.layer_idx = layer_idx - # Adapted from CamembertSelfAttention - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, - attention_mask: Optional[torch.Tensor] = None, - head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, - cache_position: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - if self.position_embedding_type != "absolute" or output_attentions or head_mask is not None: - # TODO: Improve this warning with e.g. `model.config._attn_implementation = "manual"` once implemented. - logger.warning_once( - "CamembertSdpaSelfAttention is used but `torch.nn.functional.scaled_dot_product_attention` does not support " - "non-absolute `position_embedding_type` or `output_attentions=True` or `head_mask`. Falling back to " - "the manual attention implementation, but specifying the manual implementation will be required from " - "Transformers version v5.0.0 onwards. This warning can be removed using the argument " - '`attn_implementation="eager"` when loading the model.' - ) - return super().forward( - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states, - past_key_values, - output_attentions, - cache_position, - ) + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - bsz, tgt_len, _ = hidden_states.size() + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - query_layer = ( - self.query(hidden_states).view(bsz, -1, self.num_attention_heads, self.attention_head_size).transpose(1, 2) - ) + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - is_updated = False - is_cross_attention = encoder_hidden_states is not None - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_states from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values else: - key_layer = ( - self.key(current_states) - .view(bsz, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) - value_layer = ( - self.value(current_states) - .view(bsz, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx ) # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + past_key_value.is_updated[self.layer_idx] = True - # We dispatch to SDPA's Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment - # in SDPA to support both torch.compile's dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling. - # The tgt_len > 1 is necessary to match with AttentionMaskConverter.to_causal_4d that does not create - # a causal mask in case tgt_len == 1. - is_causal = self.is_decoder and not is_cross_attention and attention_mask is None and tgt_len > 1 + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - attn_output = torch.nn.functional.scaled_dot_product_attention( + attn_output, attn_weights = attention_interface( + self, query_layer, key_layer, value_layer, - attn_mask=attention_mask, - dropout_p=self.dropout_prob if self.training else 0.0, - is_causal=is_causal, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights - attn_output = attn_output.transpose(1, 2) - attn_output = attn_output.reshape(bsz, tgt_len, self.all_head_size) - - return attn_output, None - -# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfOutput with Roberta->Camembert class CamembertSelfOutput(nn.Module): def __init__(self, config): super().__init__() @@ -389,20 +309,15 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -CAMEMBERT_SELF_ATTENTION_CLASSES = { - "eager": CamembertSelfAttention, - "sdpa": CamembertSdpaSelfAttention, -} - - -# Copied from transformers.models.roberta.modeling_roberta.RobertaAttention with Roberta->Camembert,ROBERTA->CAMEMBERT class CamembertAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = CAMEMBERT_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = CamembertCrossAttention if is_cross_attention else CamembertSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = CamembertSelfOutput(config) self.pruned_heads = set() @@ -425,32 +340,31 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, + encoder_hidden_states=encoder_hidden_states, attention_mask=attention_mask, head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights -# Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert->Roberta->Camembert class CamembertIntermediate(nn.Module): def __init__(self, config): super().__init__() @@ -466,7 +380,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return hidden_states -# Copied from transformers.models.bert.modeling_bert.BertOutput with Bert->Roberta->Camembert class CamembertOutput(nn.Module): def __init__(self, config): super().__init__() @@ -481,23 +394,27 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -# Copied from transformers.models.roberta.modeling_roberta.RobertaLayer with Roberta->Camembert class CamembertLayer(GradientCheckpointingLayer): def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = CamembertAttention(config, layer_idx=layer_idx) + self.attention = CamembertAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = CamembertAttention(config, position_embedding_type="absolute", layer_idx=layer_idx) + self.crossattention = CamembertAttention( + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) self.intermediate = CamembertIntermediate(config) self.output = CamembertOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -505,60 +422,224 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, + ) + attention_output = self_attention_output + + if self.is_decoder and encoder_hidden_states is not None: + if not hasattr(self, "crossattention"): + raise ValueError( + f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" + " by setting `config.add_cross_attention=True`" + ) + + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, + ) + attention_output = cross_attention_output + + layer_output = apply_chunking_to_forward( + self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + return layer_output + + def feed_forward_chunk(self, attention_output): + intermediate_output = self.intermediate(attention_output) + layer_output = self.output(intermediate_output, attention_output) + return layer_output + + +class CamembertLMHead(nn.Module): + """Camembert Head for masked language modeling.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + self.decoder = nn.Linear(config.hidden_size, config.vocab_size) + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + self.decoder.bias = self.bias + + def forward(self, features, **kwargs): + x = self.dense(features) + x = gelu(x) + x = self.layer_norm(x) + + # project back to size of vocabulary with bias + x = self.decoder(x) + + return x + + def _tie_weights(self): + # To tie those two weights if they get disconnected (on TPU or when the bias is resized) + # For accelerate compatibility and to not break backward compatibility + if self.decoder.bias.device.type == "meta": + self.decoder.bias = self.bias + else: + self.bias = self.decoder.bias + + +@auto_docstring +class CamembertPreTrainedModel(PreTrainedModel): + config_class = CamembertConfig + base_model_prefix = "roberta" + supports_gradient_checkpointing = True + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": CamembertLayer, + "attentions": CamembertSelfAttention, + "cross_attentions": CamembertCrossAttention, + } + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, CamembertLMHead): + module.bias.data.zero_() + + +class CamembertEmbeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) + + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + self.register_buffer( + "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False + ) + self.register_buffer( + "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False + ) + + self.padding_idx = config.pad_token_id + self.position_embeddings = nn.Embedding( + config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx + ) + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: + if position_ids is None: + if input_ids is not None: + # Create the position ids from the input token ids. Any padded tokens remain padded. + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) + else: + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) + + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + batch_size, seq_length = input_shape + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): + """ + We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. - if self.is_decoder and encoder_hidden_states is not None: - if not hasattr(self, "crossattention"): - raise ValueError( - f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" - " by setting `config.add_cross_attention=True`" - ) + Args: + inputs_embeds: torch.Tensor - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, - ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + Returns: torch.Tensor + """ + input_shape = inputs_embeds.size()[:-1] + sequence_length = input_shape[1] - layer_output = apply_chunking_to_forward( - self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output + position_ids = torch.arange( + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) - outputs = (layer_output,) + outputs + return position_ids.unsqueeze(0).expand(input_shape) - return outputs + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. - def feed_forward_chunk(self, attention_output): - intermediate_output = self.intermediate(attention_output) - layer_output = self.output(intermediate_output, attention_output) - return layer_output + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx -# Copied from transformers.models.roberta.modeling_roberta.RobertaEncoder with Roberta->Camembert class CamembertEncoder(nn.Module): - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config self.layer = nn.ModuleList([CamembertLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) - self.gradient_checkpointing = False def forward( self, @@ -569,81 +650,29 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and self.config.is_decoder and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - - if use_cache and self.config.is_decoder and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, # as a positional argument for gradient checkpointing encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_values, cache_position=cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) -# Copied from transformers.models.bert.modeling_bert.BertPooler class CamembertPooler(nn.Module): def __init__(self, config): super().__init__() @@ -659,106 +688,21 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return pooled_output -@auto_docstring -class CamembertPreTrainedModel(PreTrainedModel): - config: CamembertConfig - base_model_prefix = "roberta" - supports_gradient_checkpointing = True - _supports_sdpa = True - - # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights with BertLMPredictionHead->CamembertLMHead - def _init_weights(self, module): - """Initialize the weights""" - if isinstance(module, nn.Linear): - module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) - if module.bias is not None: - module.bias.data.zero_() - elif isinstance(module, nn.Embedding): - module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) - if module.padding_idx is not None: - module.weight.data[module.padding_idx].zero_() - elif isinstance(module, nn.LayerNorm): - module.bias.data.zero_() - module.weight.data.fill_(1.0) - elif isinstance(module, CamembertLMHead): - module.bias.data.zero_() - - -# Copied from transformers.models.roberta.modeling_roberta.RobertaClassificationHead with Roberta->Camembert -class CamembertClassificationHead(nn.Module): - """Head for sentence-level classification tasks.""" - - def __init__(self, config): - super().__init__() - self.dense = nn.Linear(config.hidden_size, config.hidden_size) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(classifier_dropout) - self.out_proj = nn.Linear(config.hidden_size, config.num_labels) - - def forward(self, features, **kwargs): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x) - x = self.dense(x) - x = torch.tanh(x) - x = self.dropout(x) - x = self.out_proj(x) - return x - - -# Copied from transformers.models.roberta.modeling_roberta.RobertaLMHead with Roberta->Camembert -class CamembertLMHead(nn.Module): - """Camembert Head for masked language modeling.""" - - def __init__(self, config): - super().__init__() - self.dense = nn.Linear(config.hidden_size, config.hidden_size) - self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - - self.decoder = nn.Linear(config.hidden_size, config.vocab_size) - self.bias = nn.Parameter(torch.zeros(config.vocab_size)) - self.decoder.bias = self.bias - - def forward(self, features, **kwargs): - x = self.dense(features) - x = gelu(x) - x = self.layer_norm(x) - - # project back to size of vocabulary with bias - x = self.decoder(x) - - return x - - def _tie_weights(self): - # To tie those two weights if they get disconnected (on TPU or when the bias is resized) - # For accelerate compatibility and to not break backward compatibility - if self.decoder.bias.device.type == "meta": - self.decoder.bias = self.bias - else: - self.bias = self.decoder.bias - - -@auto_docstring -class CamembertModel(CamembertPreTrainedModel): - """ - +@auto_docstring( + custom_intro=""" The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of - cross-attention is added between the self-attention layers, following the architecture described in *Attention is - all you need*_ by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz - Kaiser and Illia Polosukhin. + cross-attention is added between the self-attention layers, following the architecture described in [Attention is + all you need](https://huggingface.co/papers/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, + Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin. - To behave as a decoder the model needs to be initialized with the `is_decoder` argument of the configuration set to - `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and + To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set + to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. - - .. _*Attention is all you need*: https://huggingface.co/papers/1706.03762 - """ +) +class CamembertModel(CamembertPreTrainedModel): + _no_split_modules = ["CamembertEmbeddings", "CamembertLayer"] - _no_split_modules = [] - - # Copied from transformers.models.roberta.modeling_roberta.RobertaModel.__init__ with Roberta->Camembert def __init__(self, config, add_pooling_layer=True): r""" add_pooling_layer (bool, *optional*, defaults to `True`): @@ -766,13 +710,13 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = CamembertEmbeddings(config) self.encoder = CamembertEncoder(config) self.pooler = CamembertPooler(config) if add_pooling_layer else None - self.attn_implementation = config._attn_implementation self.position_embedding_type = config.position_embedding_type # Initialize weights and apply final processing @@ -792,8 +736,8 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring - # Copied from transformers.models.roberta.modeling_roberta.RobertaModel.forward def forward( self, input_ids: Optional[torch.Tensor] = None, @@ -804,52 +748,40 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape + else: + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] + + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) embedding_output = self.embeddings( input_ids=input_ids, @@ -859,55 +791,16 @@ def forward( past_key_values_length=past_key_values_length, ) - if attention_mask is None: - attention_mask = torch.ones((batch_size, seq_length + past_key_values_length), device=device) - - use_sdpa_attention_masks = ( - self.attn_implementation == "sdpa" - and self.position_embedding_type == "absolute" - and head_mask is None - and not output_attentions + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, ) - # Expand the attention mask - if use_sdpa_attention_masks and attention_mask.dim() == 2: - # Expand the attention mask for SDPA. - # [bsz, seq_len] -> [bsz, 1, seq_len, seq_len] - if self.config.is_decoder: - extended_attention_mask = _prepare_4d_causal_attention_mask_for_sdpa( - attention_mask, - input_shape, - embedding_output, - past_key_values_length, - ) - else: - extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - - if use_sdpa_attention_masks and encoder_attention_mask.dim() == 2: - # Expand the attention mask for SDPA. - # [bsz, seq_len] -> [bsz, 1, seq_len, seq_len] - encoder_extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - encoder_attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) - else: - encoder_extended_attention_mask = None - # Prepare head mask if needed # 1.0 in head_mask indicate we keep the head # attention_probs has shape bsz x n_heads x N x N @@ -917,35 +810,137 @@ def forward( encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) - sequence_output = encoder_outputs[0] + sequence_output = encoder_outputs.last_hidden_state pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + @auto_docstring -# Copied from transformers.models.roberta.modeling_roberta.RobertaForMaskedLM with Roberta->Camembert, ROBERTA->CAMEMBERT class CamembertForMaskedLM(CamembertPreTrainedModel): _tied_weights_keys = ["lm_head.decoder.weight", "lm_head.decoder.bias"] @@ -957,9 +952,9 @@ def __init__(self, config): "If you want to use `CamembertForMaskedLM` make sure `config.is_decoder=False` for " "bi-directional self-attention." ) + self.lm_head = CamembertLMHead(config) self.roberta = CamembertModel(config, add_pooling_layer=False) - self.lm_head = CamembertLMHead(config) # Initialize weights and apply final processing self.post_init() @@ -970,6 +965,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -982,9 +978,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1001,8 +995,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1012,9 +1004,8 @@ def forward( inputs_embeds=inputs_embeds, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] prediction_scores = self.lm_head(sequence_output) @@ -1026,10 +1017,6 @@ def forward( loss_fct = CrossEntropyLoss() masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -1038,25 +1025,47 @@ def forward( ) +class CamembertClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.out_proj = nn.Linear(config.hidden_size, config.num_labels) + + def forward(self, features, **kwargs): + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x) + x = self.dense(x) + x = torch.tanh(x) + x = self.dropout(x) + x = self.out_proj(x) + return x + + @auto_docstring( custom_intro=""" - CamemBERT Model transformer with a sequence classification/regression head on top (a linear layer on top of the + Camembert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled output) e.g. for GLUE tasks. """ ) -# Copied from transformers.models.roberta.modeling_roberta.RobertaForSequenceClassification with Roberta->Camembert, ROBERTA->CAMEMBERT class CamembertForSequenceClassification(CamembertPreTrainedModel): def __init__(self, config): super().__init__(config) self.num_labels = config.num_labels self.config = config + self.classifier = CamembertClassificationHead(config) self.roberta = CamembertModel(config, add_pooling_layer=False) - self.classifier = CamembertClassificationHead(config) # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1067,9 +1076,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1086,8 +1093,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1095,9 +1100,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] logits = self.classifier(sequence_output) @@ -1127,10 +1131,6 @@ def forward( loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return SequenceClassifierOutput( loss=loss, logits=logits, @@ -1140,18 +1140,18 @@ def forward( @auto_docstring -# Copied from transformers.models.roberta.modeling_roberta.RobertaForMultipleChoice with Roberta->Camembert, ROBERTA->CAMEMBERT class CamembertForMultipleChoice(CamembertPreTrainedModel): def __init__(self, config): super().__init__(config) - - self.roberta = CamembertModel(config) self.dropout = nn.Dropout(config.hidden_dropout_prob) self.classifier = nn.Linear(config.hidden_size, 1) + self.roberta = CamembertModel(config, add_pooling_layer=False) + # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1162,9 +1162,7 @@ def forward( position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1197,7 +1195,6 @@ def forward( is useful if you want more control over how to convert `input_ids` indices into associated vectors than the model's internal embedding lookup matrix. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1217,9 +1214,8 @@ def forward( attention_mask=flat_attention_mask, head_mask=head_mask, inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1234,10 +1230,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1247,22 +1239,22 @@ def forward( @auto_docstring -# Copied from transformers.models.roberta.modeling_roberta.RobertaForTokenClassification with Roberta->Camembert, ROBERTA->CAMEMBERT class CamembertForTokenClassification(CamembertPreTrainedModel): def __init__(self, config): super().__init__(config) self.num_labels = config.num_labels - - self.roberta = CamembertModel(config, add_pooling_layer=False) classifier_dropout = ( config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob ) self.dropout = nn.Dropout(classifier_dropout) self.classifier = nn.Linear(config.hidden_size, config.num_labels) + self.roberta = CamembertModel(config, add_pooling_layer=False) + # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1273,9 +1265,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1290,8 +1280,6 @@ def forward( labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1299,9 +1287,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1316,10 +1303,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1329,18 +1312,18 @@ def forward( @auto_docstring -# Copied from transformers.models.roberta.modeling_roberta.RobertaForQuestionAnswering with Roberta->Camembert, ROBERTA->CAMEMBERT class CamembertForQuestionAnswering(CamembertPreTrainedModel): def __init__(self, config): super().__init__(config) self.num_labels = config.num_labels + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) self.roberta = CamembertModel(config, add_pooling_layer=False) - self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1352,9 +1335,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, start_positions: Optional[torch.LongTensor] = None, end_positions: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1367,8 +1348,6 @@ def forward( [What are token type IDs?](../glossary#token-type-ids) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1376,9 +1355,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1405,10 +1383,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, @@ -1420,10 +1394,9 @@ def forward( @auto_docstring( custom_intro=""" - CamemBERT Model with a `language modeling` head on top for CLM fine-tuning. + Camembert Model with a `language modeling` head on top for CLM fine-tuning. """ ) -# Copied from transformers.models.roberta.modeling_roberta.RobertaForCausalLM with Roberta->Camembert, ROBERTA->CAMEMBERT, FacebookAI/roberta-base->almanach/camembert-base class CamembertForCausalLM(CamembertPreTrainedModel, GenerationMixin): _tied_weights_keys = ["lm_head.decoder.weight", "lm_head.decoder.bias"] @@ -1432,9 +1405,9 @@ def __init__(self, config): if not config.is_decoder: logger.warning("If you want to use `CamembertLMHeadModel` as a standalone, add `is_decoder=True.`") + self.lm_head = CamembertLMHead(config) self.roberta = CamembertModel(config, add_pooling_layer=False) - self.lm_head = CamembertLMHead(config) # Initialize weights and apply final processing self.post_init() @@ -1445,6 +1418,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -1457,12 +1431,10 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1495,7 +1467,6 @@ def forward( >>> prediction_logits = outputs.logits ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -1510,9 +1481,9 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1529,10 +1500,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, @@ -1543,23 +1510,6 @@ def forward( ) -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - __all__ = [ "CamembertForCausalLM", "CamembertForMaskedLM", diff --git a/src/transformers/models/camembert/modular_camembert.py b/src/transformers/models/camembert/modular_camembert.py new file mode 100644 index 000000000000..49b640a64680 --- /dev/null +++ b/src/transformers/models/camembert/modular_camembert.py @@ -0,0 +1,544 @@ +# coding=utf-8 +# Copyright 2019 Inria, Facebook AI Research and the HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# 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. +"""PyTorch CamemBERT model.""" + +from typing import Optional, Union + +import torch +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...modeling_outputs import ( + CausalLMOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring +from ...utils.generic import can_return_tuple +from ..roberta.modeling_roberta import ( + RobertaForCausalLM, + RobertaForMaskedLM, + RobertaForMultipleChoice, + RobertaForQuestionAnswering, + RobertaForSequenceClassification, + RobertaForTokenClassification, + RobertaModel, + RobertaPreTrainedModel, +) + + +class CamembertPreTrainedModel(RobertaPreTrainedModel): + base_model_prefix = "roberta" + + +class CamembertModel(RobertaModel): + pass + + +class CamembertForMaskedLM(RobertaForMaskedLM): + def __init__(self, config): + super().__init__(config) + del self.camembert + + self.roberta = CamembertModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + return_dict=True, + **kwargs, + ) + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + masked_lm_loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(prediction_scores.device) + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class CamembertForSequenceClassification(RobertaForSequenceClassification): + def __init__(self, config): + super().__init__(config) + del self.camembert + + self.roberta = CamembertModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + sequence_output = outputs[0] + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(logits.device) + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class CamembertForMultipleChoice(RobertaForMultipleChoice): + def __init__(self, config): + super().__init__(config) + del self.camembert + + self.roberta = CamembertModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: + r""" + input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + """ + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + flat_inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.roberta( + flat_input_ids, + position_ids=flat_position_ids, + token_type_ids=flat_token_type_ids, + attention_mask=flat_attention_mask, + head_mask=head_mask, + inputs_embeds=flat_inputs_embeds, + return_dict=True, + **kwargs, + ) + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(reshaped_logits.device) + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class CamembertForTokenClassification(RobertaForTokenClassification): + def __init__(self, config): + super().__init__(config) + del self.camembert + + self.roberta = CamembertModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(logits.device) + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class CamembertForQuestionAnswering(RobertaForQuestionAnswering): + def __init__(self, config): + super().__init__(config) + del self.camembert + + self.roberta = CamembertModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + start_positions: Optional[torch.LongTensor] = None, + end_positions: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class CamembertForCausalLM(RobertaForCausalLM): + def __init__(self, config): + super().__init__(config) + del self.camembert + + self.roberta = CamembertModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + + Example: + + ```python + >>> from transformers import AutoTokenizer, CamembertForCausalLM, AutoConfig + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("almanach/camembert-base") + >>> config = AutoConfig.from_pretrained("almanach/camembert-base") + >>> config.is_decoder = True + >>> model = CamembertForCausalLM.from_pretrained("almanach/camembert-base", config=config) + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> prediction_logits = outputs.logits + ```""" + if labels is not None: + use_cache = False + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + lm_loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(prediction_scores.device) + lm_loss = self.loss_function( + prediction_scores, + labels, + vocab_size=self.config.vocab_size, + **kwargs, + ) + + return CausalLMOutputWithCrossAttentions( + loss=lm_loss, + logits=prediction_scores, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +__all__ = [ + "CamembertForCausalLM", + "CamembertForMaskedLM", + "CamembertForMultipleChoice", + "CamembertForQuestionAnswering", + "CamembertForSequenceClassification", + "CamembertForTokenClassification", + "CamembertModel", + "CamembertPreTrainedModel", +] diff --git a/src/transformers/models/clap/modeling_clap.py b/src/transformers/models/clap/modeling_clap.py index b8983eecf035..33ad9463ff24 100644 --- a/src/transformers/models/clap/modeling_clap.py +++ b/src/transformers/models/clap/modeling_clap.py @@ -97,23 +97,6 @@ def window_reverse(windows, window_size, height, width): return windows -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - # contrastive loss function, adapted from # https://sachinruk.github.io/blog/pytorch/pytorch%20lightning/loss%20function/gpu/2021/03/07/CLIP.html#CLIP-loss-function def contrastive_loss(logits: torch.Tensor) -> torch.Tensor: @@ -997,15 +980,11 @@ def forward(self, hidden_states): # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->ClapText, persistent=False->persistent=True class ClapTextEmbeddings(nn.Module): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ + """Construct the embeddings from word, position and token_type embeddings.""" - # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ def __init__(self, config): super().__init__() self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) - self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) @@ -1019,37 +998,44 @@ def __init__(self, config): "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=True ) - # End copy self.padding_idx = config.pad_token_id self.position_embeddings = nn.Embedding( config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx ) def forward( - self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: if position_ids is None: if input_ids is not None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) if input_ids is not None: input_shape = input_ids.size() else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -1065,7 +1051,8 @@ def forward( embeddings = self.dropout(embeddings) return embeddings - def create_position_ids_from_inputs_embeds(self, inputs_embeds): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -1078,10 +1065,26 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds): sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape) + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + # Copied from transformers.models.align.modeling_align.eager_attention_forward def eager_attention_forward( diff --git a/src/transformers/models/data2vec/modeling_data2vec_audio.py b/src/transformers/models/data2vec/modeling_data2vec_audio.py index c9b3f01f42d4..60128f882dd3 100755 --- a/src/transformers/models/data2vec/modeling_data2vec_audio.py +++ b/src/transformers/models/data2vec/modeling_data2vec_audio.py @@ -430,7 +430,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/data2vec/modeling_data2vec_text.py b/src/transformers/models/data2vec/modeling_data2vec_text.py index 1d901908f818..0cba1f894003 100644 --- a/src/transformers/models/data2vec/modeling_data2vec_text.py +++ b/src/transformers/models/data2vec/modeling_data2vec_text.py @@ -1,3 +1,9 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/data2vec/modular_data2vec_text.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_data2vec_text.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 # coding=utf-8 # Copyright 2022 The HuggingFace Inc. team. # @@ -12,18 +18,18 @@ # 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. -"""PyTorch Data2VecText model.""" -import math -from typing import Optional, Union +from typing import Callable, Optional, Union import torch -from torch import nn +import torch.nn as nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN, gelu -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -35,30 +41,27 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_data2vec_text import Data2VecTextConfig -logger = logging.get_logger(__name__) +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask -_HIDDEN_STATES_START_POSITION = 2 +logger = logging.get_logger(__name__) -# Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->Data2VecText -class Data2VecTextForTextEmbeddings(nn.Module): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ +class Data2VecTextEmbeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" - # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ def __init__(self, config): super().__init__() self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) - self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) @@ -72,37 +75,44 @@ def __init__(self, config): "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False ) - # End copy self.padding_idx = config.pad_token_id self.position_embeddings = nn.Embedding( config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx ) def forward( - self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: if position_ids is None: if input_ids is not None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) if input_ids is not None: input_shape = input_ids.size() else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -118,7 +128,8 @@ def forward( embeddings = self.dropout(embeddings) return embeddings - def create_position_ids_from_inputs_embeds(self, inputs_embeds): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -131,24 +142,99 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds): sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape) + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + -# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfAttention with Roberta->Data2VecText class Data2VecTextSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -163,114 +249,158 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only data2vec_text can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, + ) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 +class Data2VecTextCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + self.config = config + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 - ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in Data2VecTextModel forward() function) - attention_scores = attention_scores + attention_mask + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) + self.is_causal = is_causal + self.layer_idx = layer_idx - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + def forward( + self, + hidden_states: torch.Tensor, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - context_layer = torch.matmul(attention_probs, value_layer) + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: + # reuse k,v, cross_attentions + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values + else: + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) - return context_layer, attention_probs + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx + ) + # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls + past_key_value.is_updated[self.layer_idx] = True + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights -# Copied from transformers.models.bert.modeling_bert.BertSelfOutput class Data2VecTextSelfOutput(nn.Module): def __init__(self, config): super().__init__() @@ -285,19 +415,15 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -DATA2VEC_TEXT_SELF_ATTENTION_CLASSES = { - "eager": Data2VecTextSelfAttention, -} - - -# Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->Data2VecText,BERT->DATA2VEC_TEXT class Data2VecTextAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = DATA2VEC_TEXT_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = Data2VecTextCrossAttention if is_cross_attention else Data2VecTextSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = Data2VecTextSelfOutput(config) self.pruned_heads = set() @@ -320,32 +446,31 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, + encoder_hidden_states=encoder_hidden_states, attention_mask=attention_mask, head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights -# Copied from transformers.models.bert.modeling_bert.BertIntermediate class Data2VecTextIntermediate(nn.Module): def __init__(self, config): super().__init__() @@ -361,7 +486,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return hidden_states -# Copied from transformers.models.bert.modeling_bert.BertOutput class Data2VecTextOutput(nn.Module): def __init__(self, config): super().__init__() @@ -376,25 +500,27 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -# Copied from transformers.models.bert.modeling_bert.BertLayer with Bert->Data2VecText class Data2VecTextLayer(GradientCheckpointingLayer): def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = Data2VecTextAttention(config, layer_idx=layer_idx) + self.attention = Data2VecTextAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") self.crossattention = Data2VecTextAttention( - config, position_embedding_type="absolute", layer_idx=layer_idx + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, ) self.intermediate = Data2VecTextIntermediate(config) self.output = Data2VecTextOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -402,20 +528,19 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -424,24 +549,21 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - outputs = (layer_output,) + outputs - - return outputs + return layer_output def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -449,13 +571,46 @@ def feed_forward_chunk(self, attention_output): return layer_output -# Copied from transformers.models.bert.modeling_bert.BertEncoder with Bert->Data2VecText +@auto_docstring +class Data2VecTextPreTrainedModel(PreTrainedModel): + config_class = Data2VecTextConfig + base_model_prefix = "data2vec_text" + supports_gradient_checkpointing = True + _no_split_modules = ["Data2VecTextForTextEmbeddings", "Data2VecTextLayer"] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": Data2VecTextLayer, + "attentions": Data2VecTextSelfAttention, + "cross_attentions": Data2VecTextCrossAttention, + } + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + if hasattr(module, "bias") and module.bias is not None: + module.bias.data.zero_() + if hasattr(module, "weight") and module.weight is not None: + module.weight.data.fill_(1.0) + + class Data2VecTextEncoder(nn.Module): - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config self.layer = nn.ModuleList([Data2VecTextLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) - self.gradient_checkpointing = False def forward( self, @@ -466,81 +621,29 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and self.config.is_decoder and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - - if use_cache and self.config.is_decoder and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, # as a positional argument for gradient checkpointing encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_values, cache_position=cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) -# Copied from transformers.models.bert.modeling_bert.BertPooler class Data2VecTextPooler(nn.Module): def __init__(self, config): super().__init__() @@ -556,46 +659,9 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return pooled_output -@auto_docstring -class Data2VecTextPreTrainedModel(PreTrainedModel): - config: Data2VecTextConfig - base_model_prefix = "data2vec_text" - supports_gradient_checkpointing = True - _no_split_modules = ["Data2VecTextForTextEmbeddings", "Data2VecTextLayer"] - - def _init_weights(self, module): - """Initialize the weights""" - if isinstance(module, nn.Linear): - module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) - if module.bias is not None: - module.bias.data.zero_() - elif isinstance(module, nn.Embedding): - module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) - if module.padding_idx is not None: - module.weight.data[module.padding_idx].zero_() - elif isinstance(module, nn.LayerNorm): - if hasattr(module, "bias") and module.bias is not None: - module.bias.data.zero_() - if hasattr(module, "weight") and module.weight is not None: - module.weight.data.fill_(1.0) - - @auto_docstring class Data2VecTextModel(Data2VecTextPreTrainedModel): - """ - - The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of - cross-attention is added between the self-attention layers, following the architecture described in *Attention is - all you need*_ by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz - Kaiser and Illia Polosukhin. - - To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set - to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and - `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. - - .. _*Attention is all you need*: https://huggingface.co/papers/1706.03762 - - """ + _no_split_modules = ["Data2VecTextEmbeddings", "Data2VecTextLayer"] def __init__(self, config, add_pooling_layer=True): r""" @@ -604,12 +670,15 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False - self.embeddings = Data2VecTextForTextEmbeddings(config) + self.embeddings = Data2VecTextEmbeddings(config) self.encoder = Data2VecTextEncoder(config) self.pooler = Data2VecTextPooler(config) if add_pooling_layer else None + self.position_embedding_type = config.position_embedding_type + # Initialize weights and apply final processing self.post_init() @@ -627,6 +696,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -638,77 +708,40 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - if attention_mask is None: - attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) - - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape else: - encoder_extended_attention_mask = None + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) embedding_output = self.embeddings( input_ids=input_ids, @@ -717,34 +750,208 @@ def forward( inputs_embeds=inputs_embeds, past_key_values_length=past_key_values_length, ) + + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, + ) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) - sequence_output = encoder_outputs[0] + sequence_output = encoder_outputs.last_hidden_state pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + + +class Data2VecTextLMHead(nn.Module): + """Data2VecText Head for masked language modeling.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + self.decoder = nn.Linear(config.hidden_size, config.vocab_size) + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + self.decoder.bias = self.bias + + def forward(self, features, **kwargs): + x = self.dense(features) + x = gelu(x) + x = self.layer_norm(x) + + # project back to size of vocabulary with bias + x = self.decoder(x) + + return x + + def _tie_weights(self): + # To tie those two weights if they get disconnected (on TPU or when the bias is resized) + # For accelerate compatibility and to not break backward compatibility + if self.decoder.bias.device.type == "meta": + self.decoder.bias = self.bias + else: + self.bias = self.decoder.bias + + +class Data2VecTextClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.out_proj = nn.Linear(config.hidden_size, config.num_labels) + + def forward(self, features, **kwargs): + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x) + x = self.dense(x) + x = torch.tanh(x) + x = self.dropout(x) + x = self.out_proj(x) + return x + @auto_docstring( custom_intro=""" @@ -772,6 +979,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -784,13 +992,10 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, - **kwargs, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, CausalLMOutputWithCrossAttentions]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -814,7 +1019,6 @@ def forward( >>> prediction_logits = outputs.logits ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -829,10 +1033,9 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -847,10 +1050,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, @@ -886,6 +1085,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -898,9 +1098,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, MaskedLMOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -908,8 +1106,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.data2vec_text( input_ids, attention_mask=attention_mask, @@ -919,9 +1115,8 @@ def forward( inputs_embeds=inputs_embeds, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] prediction_scores = self.lm_head(sequence_output) @@ -933,10 +1128,6 @@ def forward( labels = labels.to(prediction_scores.device) masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -945,38 +1136,6 @@ def forward( ) -# Copied from transformers.models.roberta.modeling_roberta.RobertaLMHead with Roberta->Data2VecText -class Data2VecTextLMHead(nn.Module): - """Data2VecText Head for masked language modeling.""" - - def __init__(self, config): - super().__init__() - self.dense = nn.Linear(config.hidden_size, config.hidden_size) - self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - - self.decoder = nn.Linear(config.hidden_size, config.vocab_size) - self.bias = nn.Parameter(torch.zeros(config.vocab_size)) - self.decoder.bias = self.bias - - def forward(self, features, **kwargs): - x = self.dense(features) - x = gelu(x) - x = self.layer_norm(x) - - # project back to size of vocabulary with bias - x = self.decoder(x) - - return x - - def _tie_weights(self): - # To tie those two weights if they get disconnected (on TPU or when the bias is resized) - # For accelerate compatibility and to not break backward compatibility - if self.decoder.bias.device.type == "meta": - self.decoder.bias = self.bias - else: - self.bias = self.decoder.bias - - @auto_docstring( custom_intro=""" Data2VecText Model transformer with a sequence classification/regression head on top (a linear layer on top of the @@ -995,6 +1154,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1005,9 +1165,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, SequenceClassifierOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): @@ -1015,8 +1173,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.data2vec_text( input_ids, attention_mask=attention_mask, @@ -1024,9 +1180,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] logits = self.classifier(sequence_output) @@ -1056,10 +1211,6 @@ def forward( loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return SequenceClassifierOutput( loss=loss, logits=logits, @@ -1080,6 +1231,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1090,9 +1242,7 @@ def forward( position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1124,7 +1274,6 @@ def forward( is useful if you want more control over how to convert `input_ids` indices into associated vectors than the model's internal embedding lookup matrix. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1144,9 +1293,8 @@ def forward( attention_mask=flat_attention_mask, head_mask=head_mask, inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1161,10 +1309,6 @@ def forward( labels = labels.to(reshaped_logits.device) loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1189,6 +1333,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1199,16 +1344,12 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, TokenClassifierOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.data2vec_text( input_ids, attention_mask=attention_mask, @@ -1216,9 +1357,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1233,10 +1373,6 @@ def forward( labels = labels.to(logits.device) loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1245,29 +1381,6 @@ def forward( ) -# Copied from transformers.models.roberta.modeling_roberta.RobertaClassificationHead with Roberta->Data2VecText -class Data2VecTextClassificationHead(nn.Module): - """Head for sentence-level classification tasks.""" - - def __init__(self, config): - super().__init__() - self.dense = nn.Linear(config.hidden_size, config.hidden_size) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(classifier_dropout) - self.out_proj = nn.Linear(config.hidden_size, config.num_labels) - - def forward(self, features, **kwargs): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x) - x = self.dense(x) - x = torch.tanh(x) - x = self.dropout(x) - x = self.out_proj(x) - return x - - @auto_docstring class Data2VecTextForQuestionAnswering(Data2VecTextPreTrainedModel): def __init__(self, config): @@ -1280,6 +1393,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1291,12 +1405,8 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, start_positions: Optional[torch.LongTensor] = None, end_positions: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, QuestionAnsweringModelOutput]: - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.data2vec_text( input_ids, attention_mask=attention_mask, @@ -1304,9 +1414,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1333,10 +1442,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, @@ -1346,22 +1451,6 @@ def forward( ) -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - __all__ = [ "Data2VecTextForCausalLM", "Data2VecTextForMaskedLM", diff --git a/src/transformers/models/data2vec/modular_data2vec_text.py b/src/transformers/models/data2vec/modular_data2vec_text.py new file mode 100644 index 000000000000..76a75671ecf8 --- /dev/null +++ b/src/transformers/models/data2vec/modular_data2vec_text.py @@ -0,0 +1,622 @@ +# coding=utf-8 +# Copyright 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. +"""PyTorch Data2VecText model.""" + +from typing import Optional, Union + +import torch +import torch.nn as nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...generation import GenerationMixin +from ...modeling_outputs import ( + CausalLMOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, logging +from ...utils.generic import can_return_tuple +from ..roberta.modeling_roberta import ( + RobertaClassificationHead, + RobertaCrossAttention, + RobertaEmbeddings, + RobertaLayer, + RobertaLMHead, + RobertaModel, + RobertaSelfAttention, +) +from .configuration_data2vec_text import Data2VecTextConfig + + +logger = logging.get_logger(__name__) + + +class Data2VecTextEmbeddings(RobertaEmbeddings): + pass + + +class Data2VecTextSelfAttention(RobertaSelfAttention): + pass + + +class Data2VecTextCrossAttention(RobertaCrossAttention): + pass + + +class Data2VecTextLayer(RobertaLayer): + pass + + +@auto_docstring +class Data2VecTextPreTrainedModel(PreTrainedModel): + config_class = Data2VecTextConfig + base_model_prefix = "data2vec_text" + supports_gradient_checkpointing = True + _no_split_modules = ["Data2VecTextForTextEmbeddings", "Data2VecTextLayer"] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": Data2VecTextLayer, + "attentions": Data2VecTextSelfAttention, + "cross_attentions": Data2VecTextCrossAttention, + } + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + if hasattr(module, "bias") and module.bias is not None: + module.bias.data.zero_() + if hasattr(module, "weight") and module.weight is not None: + module.weight.data.fill_(1.0) + + +@auto_docstring +class Data2VecTextModel(RobertaModel): + pass + + +class Data2VecTextLMHead(RobertaLMHead): + pass + + +class Data2VecTextClassificationHead(RobertaClassificationHead): + pass + + +@auto_docstring( + custom_intro=""" + Data2VecText Model with a `language modeling` head on top for CLM fine-tuning. + """ +) +class Data2VecTextForCausalLM(Data2VecTextPreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.decoder.weight", "lm_head.decoder.bias"] + + def __init__(self, config): + super().__init__(config) + + if not config.is_decoder: + logger.warning("If you want to use `Data2VecTextLMHeadModel` as a standalone, add `is_decoder=True.`") + + self.data2vec_text = Data2VecTextModel(config, add_pooling_layer=False) + self.lm_head = Data2VecTextLMHead(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.lm_head.decoder + + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, CausalLMOutputWithCrossAttentions]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + + Example: + + ```python + >>> from transformers import AutoTokenizer, Data2VecTextForCausalLM, Data2VecTextConfig + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/data2vec-text-base") + >>> config = Data2VecTextConfig.from_pretrained("facebook/data2vec-text-base") + >>> config.is_decoder = True + >>> model = Data2VecTextForCausalLM.from_pretrained("facebook/data2vec-text-base", config=config) + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> prediction_logits = outputs.logits + ```""" + if labels is not None: + use_cache = False + + outputs = self.data2vec_text( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + lm_loss = None + if labels is not None: + lm_loss = self.loss_function( + prediction_scores, + labels, + vocab_size=self.config.vocab_size, + **kwargs, + ) + + return CausalLMOutputWithCrossAttentions( + loss=lm_loss, + logits=prediction_scores, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +@auto_docstring +class Data2VecTextForMaskedLM(Data2VecTextPreTrainedModel): + _tied_weights_keys = ["lm_head.decoder.weight", "lm_head.decoder.bias"] + + def __init__(self, config): + super().__init__(config) + + if config.is_decoder: + logger.warning( + "If you want to use `Data2VecTextForMaskedLM` make sure `config.is_decoder=False` for " + "bi-directional self-attention." + ) + + self.data2vec_text = Data2VecTextModel(config, add_pooling_layer=False) + self.lm_head = Data2VecTextLMHead(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.lm_head.decoder + + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, MaskedLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + outputs = self.data2vec_text( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + return_dict=True, + **kwargs, + ) + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + masked_lm_loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + + labels = labels.to(prediction_scores.device) + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring( + custom_intro=""" + Data2VecText Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """ +) +class Data2VecTextForSequenceClassification(Data2VecTextPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + + self.data2vec_text = Data2VecTextModel(config, add_pooling_layer=False) + self.classifier = Data2VecTextClassificationHead(config) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + outputs = self.data2vec_text( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + sequence_output = outputs[0] + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + labels = labels.to(logits.device) + + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class Data2VecTextForMultipleChoice(Data2VecTextPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.data2vec_text = Data2VecTextModel(config) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, 1) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, MultipleChoiceModelOutput]: + r""" + input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + """ + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + flat_inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.data2vec_text( + flat_input_ids, + position_ids=flat_position_ids, + token_type_ids=flat_token_type_ids, + attention_mask=flat_attention_mask, + head_mask=head_mask, + inputs_embeds=flat_inputs_embeds, + return_dict=True, + **kwargs, + ) + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + + labels = labels.to(reshaped_logits.device) + loss = loss_fct(reshaped_logits, labels) + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class Data2VecTextForTokenClassification(Data2VecTextPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.data2vec_text = Data2VecTextModel(config, add_pooling_layer=False) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.data2vec_text( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + + labels = labels.to(logits.device) + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class Data2VecTextForQuestionAnswering(Data2VecTextPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.data2vec_text = Data2VecTextModel(config, add_pooling_layer=False) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + start_positions: Optional[torch.LongTensor] = None, + end_positions: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, QuestionAnsweringModelOutput]: + outputs = self.data2vec_text( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +__all__ = [ + "Data2VecTextForCausalLM", + "Data2VecTextForMaskedLM", + "Data2VecTextForMultipleChoice", + "Data2VecTextForQuestionAnswering", + "Data2VecTextForSequenceClassification", + "Data2VecTextForTokenClassification", + "Data2VecTextModel", + "Data2VecTextPreTrainedModel", +] diff --git a/src/transformers/models/dia/modeling_dia.py b/src/transformers/models/dia/modeling_dia.py index cf662b224aab..4626a37750c1 100644 --- a/src/transformers/models/dia/modeling_dia.py +++ b/src/transformers/models/dia/modeling_dia.py @@ -490,7 +490,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -684,7 +684,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/dia/modular_dia.py b/src/transformers/models/dia/modular_dia.py index f99d32a01d9c..398514cafe3f 100644 --- a/src/transformers/models/dia/modular_dia.py +++ b/src/transformers/models/dia/modular_dia.py @@ -305,7 +305,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -499,7 +499,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/electra/modeling_electra.py b/src/transformers/models/electra/modeling_electra.py index d3b47ea55b79..100e48034abb 100644 --- a/src/transformers/models/electra/modeling_electra.py +++ b/src/transformers/models/electra/modeling_electra.py @@ -14,7 +14,6 @@ # limitations under the License. """PyTorch ELECTRA model.""" -import math from dataclasses import dataclass from typing import Callable, Optional, Union @@ -23,8 +22,10 @@ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN, get_activation -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithCrossAttentions, @@ -36,13 +37,24 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import ModelOutput, auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import ( + ModelOutput, + TransformersKwargs, + auto_docstring, + is_torch_flex_attn_available, + logging, +) +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_electra import ElectraConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) @@ -81,7 +93,7 @@ def forward( else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape if position_ids is None: position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length] @@ -91,9 +103,10 @@ def forward( # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -110,19 +123,80 @@ def forward( return embeddings +# Copied from transformers.models.bert.modeling_bert.eager_attention_forward +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + # Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->Electra class ElectraSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -137,111 +211,157 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only bert can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, + ) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 +# Copied from transformers.models.bert.modeling_bert.BertCrossAttention with Bert->Electra +class ElectraCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + self.config = config - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 - ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in ElectraModel forward() function) - attention_scores = attention_scores + attention_mask + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) + self.is_causal = is_causal + self.layer_idx = layer_idx + + def forward( + self, + hidden_states: torch.Tensor, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - context_layer = torch.matmul(attention_probs, value_layer) + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: + # reuse k,v, cross_attentions + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values + else: + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx + ) + # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls + past_key_value.is_updated[self.layer_idx] = True - return context_layer, attention_probs + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights # Copied from transformers.models.bert.modeling_bert.BertSelfOutput @@ -259,19 +379,16 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -ELECTRA_SELF_ATTENTION_CLASSES = { - "eager": ElectraSelfAttention, -} - - # Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->Electra,BERT->ELECTRA class ElectraAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = ELECTRA_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = ElectraCrossAttention if is_cross_attention else ElectraSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = ElectraSelfOutput(config) self.pruned_heads = set() @@ -294,29 +411,29 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, + encoder_hidden_states=encoder_hidden_states, attention_mask=attention_mask, head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights # Copied from transformers.models.bert.modeling_bert.BertIntermediate @@ -356,17 +473,22 @@ def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = ElectraAttention(config, layer_idx=layer_idx) + self.attention = ElectraAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = ElectraAttention(config, position_embedding_type="absolute", layer_idx=layer_idx) + self.crossattention = ElectraAttention( + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) self.intermediate = ElectraIntermediate(config) self.output = ElectraOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -374,20 +496,19 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -396,24 +517,21 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - outputs = (layer_output,) + outputs - - return outputs + return layer_output def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -423,11 +541,10 @@ def feed_forward_chunk(self, attention_output): # Copied from transformers.models.bert.modeling_bert.BertEncoder with Bert->Electra class ElectraEncoder(nn.Module): - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config self.layer = nn.ModuleList([ElectraLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) - self.gradient_checkpointing = False def forward( self, @@ -438,77 +555,26 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and self.config.is_decoder and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - - if use_cache and self.config.is_decoder and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, # as a positional argument for gradient checkpointing encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_values, cache_position=cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) @@ -551,9 +617,18 @@ def forward(self, generator_hidden_states): @auto_docstring class ElectraPreTrainedModel(PreTrainedModel): - config: ElectraConfig + config_class = ElectraConfig base_model_prefix = "electra" supports_gradient_checkpointing = True + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": ElectraLayer, + "attentions": ElectraSelfAttention, + "cross_attentions": ElectraCrossAttention, + } def _init_weights(self, module): """Initialize the weights""" @@ -601,6 +676,7 @@ def __init__(self, config): self.encoder = ElectraEncoder(config) self.config = config + self.gradient_checkpointing = False # Initialize weights and apply final processing self.post_init() @@ -618,6 +694,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -629,89 +706,197 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[list[torch.FloatTensor]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithCrossAttentions]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] + if self.config.is_decoder: + use_cache = use_cache if use_cache is not None else self.config.use_cache else: - raise ValueError("You have to specify either input_ids or inputs_embeds") + use_cache = False - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - if attention_mask is None: - attention_mask = torch.ones(input_shape, device=device) - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) - - extended_attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape else: - encoder_extended_attention_mask = None + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] - head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) - hidden_states = self.embeddings( + embedding_output = self.embeddings( input_ids=input_ids, position_ids=position_ids, token_type_ids=token_type_ids, inputs_embeds=inputs_embeds, past_key_values_length=past_key_values_length, ) - if hasattr(self, "embeddings_project"): - hidden_states = self.embeddings_project(hidden_states) + embedding_output = self.embeddings_project(embedding_output) - hidden_states = self.encoder( - hidden_states, - attention_mask=extended_attention_mask, + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, + ) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + encoder_outputs = self.encoder( + embedding_output, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + position_ids=position_ids, + **kwargs, ) - return hidden_states + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() + + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=encoder_outputs.last_hidden_state, + past_key_values=encoder_outputs.past_key_values, + ) + + # Copied from transformers.models.bert.modeling_bert.BertModel._create_attention_masks + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_full_mask + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_cross_attn_mask + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask class ElectraClassificationHead(nn.Module): @@ -854,6 +1039,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -864,9 +1050,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): @@ -874,8 +1058,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - discriminator_hidden_states = self.electra( input_ids, attention_mask=attention_mask, @@ -883,9 +1065,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = discriminator_hidden_states[0] @@ -914,10 +1095,6 @@ def forward( loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + discriminator_hidden_states[1:] - return ((loss,) + output) if loss is not None else output - return SequenceClassifierOutput( loss=loss, logits=logits, @@ -942,6 +1119,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -952,9 +1130,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], ElectraForPreTrainingOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -987,8 +1163,6 @@ def forward( >>> predictions.squeeze().tolist() [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0] ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - discriminator_hidden_states = self.electra( input_ids, attention_mask=attention_mask, @@ -996,9 +1170,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) discriminator_sequence_output = discriminator_hidden_states[0] @@ -1015,10 +1188,6 @@ def forward( else: loss = loss_fct(logits.view(-1, discriminator_sequence_output.shape[1]), labels.float()) - if not return_dict: - output = (logits,) + discriminator_hidden_states[1:] - return ((loss,) + output) if loss is not None else output - return ElectraForPreTrainingOutput( loss=loss, logits=logits, @@ -1054,6 +1223,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, word_embeddings): self.generator_lm_head = word_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -1064,9 +1234,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1074,8 +1242,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - generator_hidden_states = self.electra( input_ids, attention_mask=attention_mask, @@ -1083,9 +1249,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) generator_sequence_output = generator_hidden_states[0] @@ -1098,10 +1263,6 @@ def forward( loss_fct = nn.CrossEntropyLoss() # -100 index = padding token loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + generator_hidden_states[1:] - return ((loss,) + output) if loss is not None else output - return MaskedLMOutput( loss=loss, logits=prediction_scores, @@ -1131,6 +1292,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1141,16 +1303,12 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - discriminator_hidden_states = self.electra( input_ids, attention_mask=attention_mask, @@ -1158,9 +1316,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) discriminator_sequence_output = discriminator_hidden_states[0] @@ -1172,10 +1329,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + discriminator_hidden_states[1:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1186,7 +1339,7 @@ def forward( @auto_docstring class ElectraForQuestionAnswering(ElectraPreTrainedModel): - config: ElectraConfig + config_class = ElectraConfig base_model_prefix = "electra" def __init__(self, config): @@ -1199,6 +1352,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1210,12 +1364,8 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, start_positions: Optional[torch.Tensor] = None, end_positions: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - discriminator_hidden_states = self.electra( input_ids, attention_mask=attention_mask, @@ -1223,8 +1373,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, + return_dict=True, + **kwargs, ) sequence_output = discriminator_hidden_states[0] @@ -1251,13 +1401,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = ( - start_logits, - end_logits, - ) + discriminator_hidden_states[1:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, @@ -1279,6 +1422,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1289,9 +1433,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1323,7 +1465,6 @@ def forward( num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1343,9 +1484,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = discriminator_hidden_states[0] @@ -1359,10 +1499,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + discriminator_hidden_states[1:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1397,6 +1533,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.generator_lm_head = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -1411,10 +1548,8 @@ def forward( labels: Optional[torch.Tensor] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1438,7 +1573,6 @@ def forward( >>> prediction_logits = outputs.logits ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -1453,9 +1587,9 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1470,10 +1604,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[1:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, diff --git a/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py b/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py index 55a736fd9034..37e3cb7a1d61 100644 --- a/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py +++ b/src/transformers/models/encoder_decoder/modeling_encoder_decoder.py @@ -28,6 +28,7 @@ from ...modeling_outputs import BaseModelOutput, Seq2SeqLMOutput from ...modeling_utils import PreTrainedModel from ...utils import auto_docstring, logging +from ...utils.generic import can_return_tuple from ..auto.configuration_auto import AutoConfig from ..auto.modeling_auto import AutoModel, AutoModelForCausalLM from .configuration_encoder_decoder import EncoderDecoderConfig @@ -339,6 +340,7 @@ def from_encoder_decoder_pretrained( config = EncoderDecoderConfig.from_encoder_decoder_configs(encoder.config, decoder.config, **kwargs) return cls(encoder=encoder, decoder=decoder, config=config) + @can_return_tuple @auto_docstring def forward( self, @@ -352,9 +354,7 @@ def forward( decoder_inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, **kwargs, ) -> Union[tuple, Seq2SeqLMOutput]: r""" @@ -411,24 +411,26 @@ def forward( >>> # generation >>> generated = model.generate(input_ids) ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict + # `record outputs` can rely on the absence of the kwarg to retrieve whether the config should be used or not + # Hence, we use this workaround to allow for defaults to work as expected + kwargs_shared = {key: kwargs[key] for key in ["output_attentions", "output_hidden_states"] if key in kwargs} kwargs_encoder = {argument: value for argument, value in kwargs.items() if not argument.startswith("decoder_")} + kwargs_encoder = kwargs_encoder | kwargs_shared kwargs_decoder = { argument[len("decoder_") :]: value for argument, value in kwargs.items() if argument.startswith("decoder_") } if "num_items_in_batch" in kwargs_encoder: kwargs_decoder["num_items_in_batch"] = kwargs_encoder.pop("num_items_in_batch", None) + kwargs_decoder = kwargs_decoder | kwargs_shared if encoder_outputs is None: encoder_outputs = self.encoder( input_ids=input_ids, attention_mask=attention_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, **kwargs_encoder, ) elif isinstance(encoder_outputs, tuple): @@ -457,11 +459,10 @@ def forward( encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=attention_mask, inputs_embeds=decoder_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, use_cache=use_cache, past_key_values=past_key_values, - return_dict=return_dict, + cache_position=cache_position, + return_dict=True, **kwargs_decoder, ) @@ -469,16 +470,10 @@ def forward( loss = None if labels is not None: warnings.warn(DEPRECATION_WARNING, FutureWarning) - logits = decoder_outputs.logits if return_dict else decoder_outputs[0] + logits = decoder_outputs.logits loss_fct = CrossEntropyLoss() loss = loss_fct(logits.reshape(-1, self.decoder.config.vocab_size), labels.view(-1)) - if not return_dict: - if loss is not None: - return (loss,) + decoder_outputs + encoder_outputs - else: - return decoder_outputs + encoder_outputs - return Seq2SeqLMOutput( loss=loss, logits=decoder_outputs.logits, diff --git a/src/transformers/models/ernie/modeling_ernie.py b/src/transformers/models/ernie/modeling_ernie.py index 4c7c33fd7e43..3e94cf71d1e6 100644 --- a/src/transformers/models/ernie/modeling_ernie.py +++ b/src/transformers/models/ernie/modeling_ernie.py @@ -1,3 +1,9 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/ernie/modular_ernie.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_ernie.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 # coding=utf-8 # Copyright 2022 The HuggingFace Inc. team. # @@ -12,20 +18,20 @@ # 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. -"""PyTorch ERNIE model.""" -import math import warnings from dataclasses import dataclass -from typing import Optional, Union +from typing import Callable, Optional, Union import torch -from torch import nn +import torch.nn as nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -38,13 +44,18 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import ModelOutput, auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import ModelOutput, TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_ernie import ErnieConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) @@ -56,9 +67,6 @@ def __init__(self, config): self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - self.use_task_id = config.use_task_id - if config.use_task_id: - self.task_type_embeddings = nn.Embedding(config.task_type_vocab_size, config.hidden_size) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.dropout = nn.Dropout(config.hidden_dropout_prob) @@ -71,6 +79,10 @@ def __init__(self, config): "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False ) + self.use_task_id = config.use_task_id + if config.use_task_id: + self.task_type_embeddings = nn.Embedding(config.task_type_vocab_size, config.hidden_size) + def forward( self, input_ids: Optional[torch.LongTensor] = None, @@ -85,7 +97,7 @@ def forward( else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape if position_ids is None: position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length] @@ -95,9 +107,10 @@ def forward( # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -122,19 +135,78 @@ def forward( return embeddings -# Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->Ernie +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + class ErnieSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -149,114 +221,158 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only ernie can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, + ) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 +class ErnieCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + self.config = config - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 - ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in ErnieModel forward() function) - attention_scores = attention_scores + attention_mask + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) + self.is_causal = is_causal + self.layer_idx = layer_idx - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + def forward( + self, + hidden_states: torch.Tensor, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - context_layer = torch.matmul(attention_probs, value_layer) + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: + # reuse k,v, cross_attentions + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values + else: + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx + ) + # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls + past_key_value.is_updated[self.layer_idx] = True - return context_layer, attention_probs + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights -# Copied from transformers.models.bert.modeling_bert.BertSelfOutput with Bert->Ernie class ErnieSelfOutput(nn.Module): def __init__(self, config): super().__init__() @@ -271,19 +387,15 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -ERNIE_SELF_ATTENTION_CLASSES = { - "eager": ErnieSelfAttention, -} - - -# Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->Ernie,BERT->ERNIE class ErnieAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = ERNIE_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = ErnieCrossAttention if is_cross_attention else ErnieSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = ErnieSelfOutput(config) self.pruned_heads = set() @@ -306,32 +418,31 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, + encoder_hidden_states=encoder_hidden_states, attention_mask=attention_mask, head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights -# Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert->Ernie class ErnieIntermediate(nn.Module): def __init__(self, config): super().__init__() @@ -347,7 +458,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return hidden_states -# Copied from transformers.models.bert.modeling_bert.BertOutput with Bert->Ernie class ErnieOutput(nn.Module): def __init__(self, config): super().__init__() @@ -362,23 +472,27 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -# Copied from transformers.models.bert.modeling_bert.BertLayer with Bert->Ernie class ErnieLayer(GradientCheckpointingLayer): def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = ErnieAttention(config, layer_idx=layer_idx) + self.attention = ErnieAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = ErnieAttention(config, position_embedding_type="absolute", layer_idx=layer_idx) + self.crossattention = ErnieAttention( + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) self.intermediate = ErnieIntermediate(config) self.output = ErnieOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -386,20 +500,19 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -408,24 +521,21 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - outputs = (layer_output,) + outputs - - return outputs + return layer_output def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -433,98 +543,6 @@ def feed_forward_chunk(self, attention_output): return layer_output -# Copied from transformers.models.bert.modeling_bert.BertEncoder with Bert->Ernie -class ErnieEncoder(nn.Module): - def __init__(self, config, layer_idx=None): - super().__init__() - self.config = config - self.layer = nn.ModuleList([ErnieLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) - self.gradient_checkpointing = False - - def forward( - self, - hidden_states: torch.Tensor, - attention_mask: Optional[torch.FloatTensor] = None, - head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, - cache_position: Optional[torch.Tensor] = None, - ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and self.config.is_decoder and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - - if use_cache and self.config.is_decoder and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_head_mask = head_mask[i] if head_mask is not None else None - - layer_outputs = layer_module( - hidden_states, - attention_mask, - layer_head_mask, - encoder_hidden_states, # as a positional argument for gradient checkpointing - encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, - ) - - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) - return BaseModelOutputWithPastAndCrossAttentions( - last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, - ) - - -# Copied from transformers.models.bert.modeling_bert.BertPooler with Bert->Ernie class ErniePooler(nn.Module): def __init__(self, config): super().__init__() @@ -540,7 +558,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return pooled_output -# Copied from transformers.models.bert.modeling_bert.BertPredictionHeadTransform with Bert->Ernie class ErniePredictionHeadTransform(nn.Module): def __init__(self, config): super().__init__() @@ -558,7 +575,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return hidden_states -# Copied from transformers.models.bert.modeling_bert.BertLMPredictionHead with Bert->Ernie class ErnieLMPredictionHead(nn.Module): def __init__(self, config): super().__init__() @@ -582,50 +598,64 @@ def forward(self, hidden_states): return hidden_states -# Copied from transformers.models.bert.modeling_bert.BertOnlyMLMHead with Bert->Ernie -class ErnieOnlyMLMHead(nn.Module): - def __init__(self, config): - super().__init__() - self.predictions = ErnieLMPredictionHead(config) - - def forward(self, sequence_output: torch.Tensor) -> torch.Tensor: - prediction_scores = self.predictions(sequence_output) - return prediction_scores - - -# Copied from transformers.models.bert.modeling_bert.BertOnlyNSPHead with Bert->Ernie -class ErnieOnlyNSPHead(nn.Module): +class ErnieEncoder(nn.Module): def __init__(self, config): super().__init__() - self.seq_relationship = nn.Linear(config.hidden_size, 2) - - def forward(self, pooled_output): - seq_relationship_score = self.seq_relationship(pooled_output) - return seq_relationship_score + self.config = config + self.layer = nn.ModuleList([ErnieLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: + for i, layer_module in enumerate(self.layer): + layer_head_mask = head_mask[i] if head_mask is not None else None -# Copied from transformers.models.bert.modeling_bert.BertPreTrainingHeads with Bert->Ernie -class ErniePreTrainingHeads(nn.Module): - def __init__(self, config): - super().__init__() - self.predictions = ErnieLMPredictionHead(config) - self.seq_relationship = nn.Linear(config.hidden_size, 2) + hidden_states = layer_module( + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, # as a positional argument for gradient checkpointing + encoder_attention_mask=encoder_attention_mask, + past_key_value=past_key_values, + cache_position=cache_position, + **kwargs, + ) - def forward(self, sequence_output, pooled_output): - prediction_scores = self.predictions(sequence_output) - seq_relationship_score = self.seq_relationship(pooled_output) - return prediction_scores, seq_relationship_score + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=past_key_values if use_cache else None, + ) @auto_docstring class ErniePreTrainedModel(PreTrainedModel): - config: ErnieConfig + config_class = ErnieConfig base_model_prefix = "ernie" supports_gradient_checkpointing = True + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": ErnieLayer, + "attentions": ErnieSelfAttention, + "cross_attentions": ErnieCrossAttention, + } def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() @@ -636,32 +666,8 @@ def _init_weights(self, module): elif isinstance(module, nn.LayerNorm): module.bias.data.zero_() module.weight.data.fill_(1.0) - - -@dataclass -@auto_docstring( - custom_intro=""" - Output type of [`ErnieForPreTraining`]. - """ -) -# Copied from transformers.models.bert.modeling_bert.BertForPreTrainingOutput with Bert->Ernie -class ErnieForPreTrainingOutput(ModelOutput): - r""" - loss (*optional*, returned when `labels` is provided, `torch.FloatTensor` of shape `(1,)`): - Total loss as the sum of the masked language modeling loss and the next sequence prediction - (classification) loss. - prediction_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): - Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). - seq_relationship_logits (`torch.FloatTensor` of shape `(batch_size, 2)`): - Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation - before SoftMax). - """ - - loss: Optional[torch.FloatTensor] = None - prediction_logits: Optional[torch.FloatTensor] = None - seq_relationship_logits: Optional[torch.FloatTensor] = None - hidden_states: Optional[tuple[torch.FloatTensor]] = None - attentions: Optional[tuple[torch.FloatTensor]] = None + elif isinstance(module, ErnieLMPredictionHead): + module.bias.data.zero_() @auto_docstring( @@ -673,10 +679,12 @@ class ErnieForPreTrainingOutput(ModelOutput): To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and + `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. """ ) class ErnieModel(ErniePreTrainedModel): - # Copied from transformers.models.clap.modeling_clap.ClapTextModel.__init__ with ClapText->Ernie + _no_split_modules = ["ErnieLayer"] + def __init__(self, config, add_pooling_layer=True): r""" add_pooling_layer (bool, *optional*, defaults to `True`): @@ -684,24 +692,24 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = ErnieEmbeddings(config) self.encoder = ErnieEncoder(config) self.pooler = ErniePooler(config) if add_pooling_layer else None + self.position_embedding_type = config.position_embedding_type + # Initialize weights and apply final processing self.post_init() - # Copied from transformers.models.bert.modeling_bert.BertModel.get_input_embeddings def get_input_embeddings(self): return self.embeddings.word_embeddings - # Copied from transformers.models.bert.modeling_bert.BertModel.set_input_embeddings def set_input_embeddings(self, value): self.embeddings.word_embeddings = value - # Copied from transformers.models.bert.modeling_bert.BertModel._prune_heads def _prune_heads(self, heads_to_prune): """ Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base @@ -710,6 +718,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -722,11 +731,10 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: r""" task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -735,17 +743,28 @@ def forward( assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, config.task_type_vocab_size-1] """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." + ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) + if input_ids is not None and inputs_embeds is not None: raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") elif input_ids is not None: @@ -759,39 +778,57 @@ def forward( batch_size, seq_length = input_shape device = input_ids.device if input_ids is not None else inputs_embeds.device - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() - ) + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) - if attention_mask is None: - attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + # specific to ernie + task_type_ids=task_type_ids, + inputs_embeds=inputs_embeds, + past_key_values_length=past_key_values_length, + ) - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) - - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) - else: - encoder_extended_attention_mask = None + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) # Prepare head mask if needed # 1.0 in head_mask indicate we keep the head @@ -800,41 +837,174 @@ def forward( # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - task_type_ids=task_type_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - ) encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) sequence_output = encoder_outputs[0] pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + + +@dataclass +@auto_docstring( + custom_intro=""" + Output type of [`ErnieForPreTraining`]. + """ +) +class ErnieForPreTrainingOutput(ModelOutput): + r""" + loss (*optional*, returned when `labels` is provided, `torch.FloatTensor` of shape `(1,)`): + Total loss as the sum of the masked language modeling loss and the next sequence prediction + (classification) loss. + prediction_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + seq_relationship_logits (`torch.FloatTensor` of shape `(batch_size, 2)`): + Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation + before SoftMax). + """ + + loss: Optional[torch.FloatTensor] = None + prediction_logits: Optional[torch.FloatTensor] = None + seq_relationship_logits: Optional[torch.FloatTensor] = None + hidden_states: Optional[tuple[torch.FloatTensor]] = None + attentions: Optional[tuple[torch.FloatTensor]] = None + + +class ErniePreTrainingHeads(nn.Module): + def __init__(self, config): + super().__init__() + self.predictions = ErnieLMPredictionHead(config) + self.seq_relationship = nn.Linear(config.hidden_size, 2) + + def forward(self, sequence_output, pooled_output): + prediction_scores = self.predictions(sequence_output) + seq_relationship_score = self.seq_relationship(pooled_output) + return prediction_scores, seq_relationship_score + @auto_docstring( custom_intro=""" @@ -845,7 +1015,6 @@ def forward( class ErnieForPreTraining(ErniePreTrainedModel): _tied_weights_keys = ["cls.predictions.decoder.bias", "cls.predictions.decoder.weight"] - # Copied from transformers.models.bert.modeling_bert.BertForPreTraining.__init__ with Bert->Ernie,bert->ernie def __init__(self, config): super().__init__(config) @@ -855,15 +1024,14 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() - # Copied from transformers.models.bert.modeling_bert.BertForPreTraining.get_output_embeddings def get_output_embeddings(self): return self.cls.predictions.decoder - # Copied from transformers.models.bert.modeling_bert.BertForPreTraining.set_output_embeddings def set_output_embeddings(self, new_embeddings): self.cls.predictions.decoder = new_embeddings self.cls.predictions.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -876,9 +1044,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, next_sentence_label: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], ErnieForPreTrainingOutput]: r""" task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -913,8 +1079,6 @@ def forward( >>> seq_relationship_logits = outputs.seq_relationship_logits ``` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.ernie( input_ids, attention_mask=attention_mask, @@ -923,9 +1087,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output, pooled_output = outputs[:2] @@ -938,10 +1101,6 @@ def forward( next_sentence_loss = loss_fct(seq_relationship_score.view(-1, 2), next_sentence_label.view(-1)) total_loss = masked_lm_loss + next_sentence_loss - if not return_dict: - output = (prediction_scores, seq_relationship_score) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return ErnieForPreTrainingOutput( loss=total_loss, prediction_logits=prediction_scores, @@ -951,6 +1110,16 @@ def forward( ) +class ErnieOnlyMLMHead(nn.Module): + def __init__(self, config): + super().__init__() + self.predictions = ErnieLMPredictionHead(config) + + def forward(self, sequence_output: torch.Tensor) -> torch.Tensor: + prediction_scores = self.predictions(sequence_output) + return prediction_scores + + @auto_docstring( custom_intro=""" Ernie Model with a `language modeling` head on top for CLM fine-tuning. @@ -959,7 +1128,6 @@ def forward( class ErnieForCausalLM(ErniePreTrainedModel, GenerationMixin): _tied_weights_keys = ["cls.predictions.decoder.bias", "cls.predictions.decoder.weight"] - # Copied from transformers.models.bert.modeling_bert.BertLMHeadModel.__init__ with BertLMHeadModel->ErnieForCausalLM,Bert->Ernie,bert->ernie def __init__(self, config): super().__init__(config) @@ -972,15 +1140,14 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() - # Copied from transformers.models.bert.modeling_bert.BertLMHeadModel.get_output_embeddings def get_output_embeddings(self): return self.cls.predictions.decoder - # Copied from transformers.models.bert.modeling_bert.BertLMHeadModel.set_output_embeddings def set_output_embeddings(self, new_embeddings): self.cls.predictions.decoder = new_embeddings self.cls.predictions.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -994,12 +1161,10 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[list[torch.Tensor]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: r""" task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1012,7 +1177,6 @@ def forward( `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -1028,9 +1192,9 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1045,10 +1209,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, @@ -1063,7 +1223,6 @@ def forward( class ErnieForMaskedLM(ErniePreTrainedModel): _tied_weights_keys = ["cls.predictions.decoder.bias", "cls.predictions.decoder.weight"] - # Copied from transformers.models.bert.modeling_bert.BertForMaskedLM.__init__ with Bert->Ernie,bert->ernie def __init__(self, config): super().__init__(config) @@ -1079,15 +1238,14 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() - # Copied from transformers.models.bert.modeling_bert.BertForMaskedLM.get_output_embeddings def get_output_embeddings(self): return self.cls.predictions.decoder - # Copied from transformers.models.bert.modeling_bert.BertForMaskedLM.set_output_embeddings def set_output_embeddings(self, new_embeddings): self.cls.predictions.decoder = new_embeddings self.cls.predictions.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -1101,9 +1259,7 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: r""" task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1116,9 +1272,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.ernie( input_ids, attention_mask=attention_mask, @@ -1129,9 +1282,8 @@ def forward( inputs_embeds=inputs_embeds, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1142,10 +1294,6 @@ def forward( loss_fct = CrossEntropyLoss() # -100 index = padding token masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -1153,7 +1301,6 @@ def forward( attentions=outputs.attentions, ) - # Copied from transformers.models.bert.modeling_bert.BertForMaskedLM.prepare_inputs_for_generation def prepare_inputs_for_generation(self, input_ids, attention_mask=None, **model_kwargs): input_shape = input_ids.shape effective_batch_size = input_shape[0] @@ -1179,13 +1326,22 @@ def can_generate(cls) -> bool: return False +class ErnieOnlyNSPHead(nn.Module): + def __init__(self, config): + super().__init__() + self.seq_relationship = nn.Linear(config.hidden_size, 2) + + def forward(self, pooled_output): + seq_relationship_score = self.seq_relationship(pooled_output) + return seq_relationship_score + + @auto_docstring( custom_intro=""" Ernie Model with a `next sentence prediction (classification)` head on top. """ ) class ErnieForNextSentencePrediction(ErniePreTrainedModel): - # Copied from transformers.models.bert.modeling_bert.BertForNextSentencePrediction.__init__ with Bert->Ernie,bert->ernie def __init__(self, config): super().__init__(config) @@ -1195,6 +1351,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1206,10 +1363,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], NextSentencePredictorOutput]: r""" task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1251,8 +1405,6 @@ def forward( ) labels = kwargs.pop("next_sentence_label") - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.ernie( input_ids, attention_mask=attention_mask, @@ -1261,9 +1413,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1275,10 +1426,6 @@ def forward( loss_fct = CrossEntropyLoss() next_sentence_loss = loss_fct(seq_relationship_scores.view(-1, 2), labels.view(-1)) - if not return_dict: - output = (seq_relationship_scores,) + outputs[2:] - return ((next_sentence_loss,) + output) if next_sentence_loss is not None else output - return NextSentencePredictorOutput( loss=next_sentence_loss, logits=seq_relationship_scores, @@ -1294,7 +1441,6 @@ def forward( """ ) class ErnieForSequenceClassification(ErniePreTrainedModel): - # Copied from transformers.models.bert.modeling_bert.BertForSequenceClassification.__init__ with Bert->Ernie,bert->ernie def __init__(self, config): super().__init__(config) self.num_labels = config.num_labels @@ -1310,6 +1456,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1321,9 +1468,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: r""" task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1336,8 +1481,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.ernie( input_ids, attention_mask=attention_mask, @@ -1346,9 +1489,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1378,9 +1520,6 @@ def forward( elif self.config.problem_type == "multi_label_classification": loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output return SequenceClassifierOutput( loss=loss, @@ -1392,7 +1531,6 @@ def forward( @auto_docstring class ErnieForMultipleChoice(ErniePreTrainedModel): - # Copied from transformers.models.bert.modeling_bert.BertForMultipleChoice.__init__ with Bert->Ernie,bert->ernie def __init__(self, config): super().__init__(config) @@ -1406,6 +1544,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1417,9 +1556,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1456,7 +1593,6 @@ def forward( num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1477,9 +1613,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1493,10 +1628,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1507,7 +1638,6 @@ def forward( @auto_docstring class ErnieForTokenClassification(ErniePreTrainedModel): - # Copied from transformers.models.bert.modeling_bert.BertForTokenClassification.__init__ with Bert->Ernie,bert->ernie def __init__(self, config): super().__init__(config) self.num_labels = config.num_labels @@ -1522,6 +1652,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1533,9 +1664,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: r""" task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1546,8 +1675,6 @@ def forward( labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.ernie( input_ids, attention_mask=attention_mask, @@ -1556,9 +1683,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1571,10 +1697,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1585,7 +1707,6 @@ def forward( @auto_docstring class ErnieForQuestionAnswering(ErniePreTrainedModel): - # Copied from transformers.models.bert.modeling_bert.BertForQuestionAnswering.__init__ with Bert->Ernie,bert->ernie def __init__(self, config): super().__init__(config) self.num_labels = config.num_labels @@ -1596,6 +1717,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1608,9 +1730,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, start_positions: Optional[torch.Tensor] = None, end_positions: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: r""" task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1619,8 +1739,6 @@ def forward( assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, config.task_type_vocab_size-1] """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.ernie( input_ids, attention_mask=attention_mask, @@ -1629,9 +1747,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1658,10 +1775,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, diff --git a/src/transformers/models/ernie/modular_ernie.py b/src/transformers/models/ernie/modular_ernie.py new file mode 100644 index 000000000000..30261966b3d0 --- /dev/null +++ b/src/transformers/models/ernie/modular_ernie.py @@ -0,0 +1,1012 @@ +# coding=utf-8 +# Copyright 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. +"""PyTorch ERNIE model.""" + +import warnings +from typing import Optional, Union + +import torch +import torch.nn as nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...cache_utils import Cache, EncoderDecoderCache +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa +from ...modeling_outputs import ( + BaseModelOutputWithPoolingAndCrossAttentions, + CausalLMOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + NextSentencePredictorOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs +from ..bert.modeling_bert import ( + BertCrossAttention, + BertEmbeddings, + BertEncoder, + BertForMaskedLM, + BertForMultipleChoice, + BertForNextSentencePrediction, + BertForPreTraining, + BertForPreTrainingOutput, + BertForQuestionAnswering, + BertForSequenceClassification, + BertForTokenClassification, + BertLayer, + BertLMHeadModel, + BertLMPredictionHead, + BertModel, + BertPooler, + BertSelfAttention, +) +from .configuration_ernie import ErnieConfig + + +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + +logger = logging.get_logger(__name__) + + +class ErnieEmbeddings(BertEmbeddings): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config): + super().__init__(config) + + self.use_task_id = config.use_task_id + if config.use_task_id: + self.task_type_embeddings = nn.Embedding(config.task_type_vocab_size, config.hidden_size) + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + task_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + batch_size, seq_length = input_shape + + if position_ids is None: + position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length] + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + + # add `task_type_id` for ERNIE model + if self.use_task_id: + if task_type_ids is None: + task_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + task_type_embeddings = self.task_type_embeddings(task_type_ids) + embeddings += task_type_embeddings + + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + +class ErnieSelfAttention(BertSelfAttention): + pass + + +class ErnieCrossAttention(BertCrossAttention): + pass + + +class ErnieLayer(BertLayer): + pass + + +class ErniePooler(BertPooler): + pass + + +class ErnieLMPredictionHead(BertLMPredictionHead): + pass + + +class ErnieEncoder(BertEncoder): + pass + + +@auto_docstring +class ErniePreTrainedModel(PreTrainedModel): + config_class = ErnieConfig + base_model_prefix = "ernie" + supports_gradient_checkpointing = True + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": ErnieLayer, + "attentions": ErnieSelfAttention, + "cross_attentions": ErnieCrossAttention, + } + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, ErnieLMPredictionHead): + module.bias.data.zero_() + + +class ErnieModel(BertModel): + _no_split_modules = ["ErnieLayer"] + + def __init__(self, config, add_pooling_layer=True): + super().__init__(self, config) + self.config = config + self.gradient_checkpointing = False + + self.embeddings = ErnieEmbeddings(config) + self.encoder = ErnieEncoder(config) + + self.pooler = ErniePooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + task_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: + r""" + task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Task type embedding is a special embedding to represent the characteristic of different tasks, such as + word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We + assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, + config.task_type_vocab_size-1] + """ + if self.config.is_decoder: + use_cache = use_cache if use_cache is not None else self.config.use_cache + else: + use_cache = False + + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." + ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + batch_size, seq_length = input_shape + device = input_ids.device if input_ids is not None else inputs_embeds.device + + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + # specific to ernie + task_type_ids=task_type_ids, + inputs_embeds=inputs_embeds, + past_key_values_length=past_key_values_length, + ) + + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + encoder_outputs = self.encoder( + embedding_output, + attention_mask=attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_ids=position_ids, + **kwargs, + ) + sequence_output = encoder_outputs[0] + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() + + return BaseModelOutputWithPoolingAndCrossAttentions( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + past_key_values=encoder_outputs.past_key_values, + ) + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_full_mask + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_cross_attn_mask + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + + +class ErnieForPreTrainingOutput(BertForPreTrainingOutput): + pass + + +class ErnieForPreTraining(BertForPreTraining): + _tied_weights_keys = ["cls.predictions.decoder.bias", "cls.predictions.decoder.weight"] + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + task_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + next_sentence_label: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], ErnieForPreTrainingOutput]: + r""" + task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Task type embedding is a special embedding to represent the characteristic of different tasks, such as + word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We + assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, + config.task_type_vocab_size-1] + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), + the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + next_sentence_label (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the next sequence prediction (classification) loss. Input should be a sequence + pair (see `input_ids` docstring) Indices should be in `[0, 1]`: + + - 0 indicates sequence B is a continuation of sequence A, + - 1 indicates sequence B is a random sequence. + + Example: + + ```python + >>> from transformers import AutoTokenizer, ErnieForPreTraining + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("nghuyong/ernie-1.0-base-zh") + >>> model = ErnieForPreTraining.from_pretrained("nghuyong/ernie-1.0-base-zh") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> prediction_logits = outputs.prediction_logits + >>> seq_relationship_logits = outputs.seq_relationship_logits + ``` + """ + outputs = self.ernie( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + task_type_ids=task_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output, pooled_output = outputs[:2] + prediction_scores, seq_relationship_score = self.cls(sequence_output, pooled_output) + + total_loss = None + if labels is not None and next_sentence_label is not None: + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + next_sentence_loss = loss_fct(seq_relationship_score.view(-1, 2), next_sentence_label.view(-1)) + total_loss = masked_lm_loss + next_sentence_loss + + return ErnieForPreTrainingOutput( + loss=total_loss, + prediction_logits=prediction_scores, + seq_relationship_logits=seq_relationship_score, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class ErnieForCausalLM(BertLMHeadModel): + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + task_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + past_key_values: Optional[list[torch.Tensor]] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: + r""" + task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Task type embedding is a special embedding to represent the characteristic of different tasks, such as + word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We + assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, + config.task_type_vocab_size-1] + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]` + """ + if labels is not None: + use_cache = False + + outputs = self.ernie( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + task_type_ids=task_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + prediction_scores = self.cls(sequence_output) + + lm_loss = None + if labels is not None: + lm_loss = self.loss_function( + prediction_scores, + labels, + vocab_size=self.config.vocab_size, + **kwargs, + ) + + return CausalLMOutputWithCrossAttentions( + loss=lm_loss, + logits=prediction_scores, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +class ErnieForMaskedLM(BertForMaskedLM): + _tied_weights_keys = ["cls.predictions.decoder.bias", "cls.predictions.decoder.weight"] + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + task_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: + r""" + task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Task type embedding is a special embedding to represent the characteristic of different tasks, such as + word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We + assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, + config.task_type_vocab_size-1] + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + outputs = self.ernie( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + task_type_ids=task_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + prediction_scores = self.cls(sequence_output) + + masked_lm_loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() # -100 index = padding token + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class ErnieForNextSentencePrediction(BertForNextSentencePrediction): + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + task_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], NextSentencePredictorOutput]: + r""" + task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Task type embedding is a special embedding to represent the characteristic of different tasks, such as + word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We + assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, + config.task_type_vocab_size-1] + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair + (see `input_ids` docstring). Indices should be in `[0, 1]`: + + - 0 indicates sequence B is a continuation of sequence A, + - 1 indicates sequence B is a random sequence. + + Example: + + ```python + >>> from transformers import AutoTokenizer, ErnieForNextSentencePrediction + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("nghuyong/ernie-1.0-base-zh") + >>> model = ErnieForNextSentencePrediction.from_pretrained("nghuyong/ernie-1.0-base-zh") + + >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced." + >>> next_sentence = "The sky is blue due to the shorter wavelength of blue light." + >>> encoding = tokenizer(prompt, next_sentence, return_tensors="pt") + + >>> outputs = model(**encoding, labels=torch.LongTensor([1])) + >>> logits = outputs.logits + >>> assert logits[0, 0] < logits[0, 1] # next sentence was random + ``` + """ + + if "next_sentence_label" in kwargs: + warnings.warn( + "The `next_sentence_label` argument is deprecated and will be removed in a future version, use" + " `labels` instead.", + FutureWarning, + ) + labels = kwargs.pop("next_sentence_label") + + outputs = self.ernie( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + task_type_ids=task_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + pooled_output = outputs[1] + + seq_relationship_scores = self.cls(pooled_output) + + next_sentence_loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + next_sentence_loss = loss_fct(seq_relationship_scores.view(-1, 2), labels.view(-1)) + + return NextSentencePredictorOutput( + loss=next_sentence_loss, + logits=seq_relationship_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class ErnieForSequenceClassification(BertForSequenceClassification): + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + task_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: + r""" + task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Task type embedding is a special embedding to represent the characteristic of different tasks, such as + word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We + assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, + config.task_type_vocab_size-1] + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + outputs = self.ernie( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + task_type_ids=task_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class ErnieForMultipleChoice(BertForMultipleChoice): + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + task_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: + r""" + input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + task_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Task type embedding is a special embedding to represent the characteristic of different tasks, such as + word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We + assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, + config.task_type_vocab_size-1] + position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + """ + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.ernie( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + task_type_ids=task_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class ErnieForTokenClassification(BertForTokenClassification): + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + task_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: + r""" + task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Task type embedding is a special embedding to represent the characteristic of different tasks, such as + word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We + assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, + config.task_type_vocab_size-1] + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.ernie( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + task_type_ids=task_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class ErnieForQuestionAnswering(BertForQuestionAnswering): + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + task_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + start_positions: Optional[torch.Tensor] = None, + end_positions: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: + r""" + task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Task type embedding is a special embedding to represent the characteristic of different tasks, such as + word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We + assign a `task_type_id` to each task and the `task_type_id` is in the range `[0, + config.task_type_vocab_size-1] + """ + outputs = self.ernie( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + task_type_ids=task_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +__all__ = [ + "ErnieForCausalLM", + "ErnieForMaskedLM", + "ErnieForMultipleChoice", + "ErnieForNextSentencePrediction", + "ErnieForPreTraining", + "ErnieForQuestionAnswering", + "ErnieForSequenceClassification", + "ErnieForTokenClassification", + "ErnieModel", + "ErniePreTrainedModel", +] diff --git a/src/transformers/models/hubert/modeling_hubert.py b/src/transformers/models/hubert/modeling_hubert.py index dfa53a2cf193..3588ca78e0d0 100755 --- a/src/transformers/models/hubert/modeling_hubert.py +++ b/src/transformers/models/hubert/modeling_hubert.py @@ -490,7 +490,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -658,7 +658,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/informer/modeling_informer.py b/src/transformers/models/informer/modeling_informer.py index b0fc4964a9ae..544fed9f1e51 100644 --- a/src/transformers/models/informer/modeling_informer.py +++ b/src/transformers/models/informer/modeling_informer.py @@ -269,7 +269,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/informer/modular_informer.py b/src/transformers/models/informer/modular_informer.py index aa6e2ad30a9f..157176c1fd38 100644 --- a/src/transformers/models/informer/modular_informer.py +++ b/src/transformers/models/informer/modular_informer.py @@ -110,7 +110,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/kosmos2/modeling_kosmos2.py b/src/transformers/models/kosmos2/modeling_kosmos2.py index 76acda9f0de9..d76107fcfe38 100644 --- a/src/transformers/models/kosmos2/modeling_kosmos2.py +++ b/src/transformers/models/kosmos2/modeling_kosmos2.py @@ -73,23 +73,6 @@ def _make_causal_mask( return mask[None, None, :, :].expand(bsz, 1, tgt_len, tgt_len + past_key_values_length) -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - @dataclass @auto_docstring( custom_intro=""" @@ -622,13 +605,15 @@ def forward( bsz, seq_len = input_ids.size() if position_ids is None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids( + position_ids = self.create_position_ids_from_input_ids( input_ids, self.padding_idx, past_key_values_length ).to(input_ids.device) else: bsz, seq_len = inputs_embeds.size()[:-1] if position_ids is None: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length) + position_ids = self.create_position_ids_from_inputs_embeds( + inputs_embeds, past_key_values_length, self.padding_idx + ) # expand embeddings if needed max_pos = self.padding_idx + 1 + seq_len + past_key_values_length @@ -637,8 +622,9 @@ def forward( return self.weights.index_select(0, position_ids.view(-1)).view(bsz, seq_len, self.weights.shape[-1]).detach() + @staticmethod # Copied from transformers.models.m2m_100.modeling_m2m_100.M2M100SinusoidalPositionalEmbedding.create_position_ids_from_inputs_embeds - def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_length): + def create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -651,10 +637,27 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_ sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape).contiguous() + past_key_values_length + @staticmethod + # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_input_ids + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + class KosmosTextAttention(nn.Module): """Multi-headed attention from 'Attention Is All You Need' paper""" diff --git a/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py b/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py index ad4910dcb8c1..b37233744da8 100644 --- a/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py +++ b/src/transformers/models/kosmos2_5/modeling_kosmos2_5.py @@ -78,23 +78,6 @@ def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min) -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - KOSMOS2_5_START_DOCSTRING = r""" This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads @@ -685,13 +668,15 @@ def forward( bsz, seq_len = input_ids.size() if position_ids is None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids( + position_ids = self.create_position_ids_from_input_ids( input_ids, self.padding_idx, past_key_values_length ).to(input_ids.device) else: bsz, seq_len = inputs_embeds.size()[:-1] if position_ids is None: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length) + position_ids = self.create_position_ids_from_inputs_embeds( + inputs_embeds, past_key_values_length, self.padding_idx + ) # expand embeddings if needed max_pos = self.padding_idx + 1 + seq_len + past_key_values_length @@ -700,8 +685,9 @@ def forward( return self.weights.index_select(0, position_ids.view(-1)).view(bsz, seq_len, self.weights.shape[-1]).detach() + @staticmethod # Copied from transformers.models.m2m_100.modeling_m2m_100.M2M100SinusoidalPositionalEmbedding.create_position_ids_from_inputs_embeds - def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_length): + def create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -714,10 +700,27 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_ sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape).contiguous() + past_key_values_length + @staticmethod + # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_input_ids + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + # Copied from transformers.models.kosmos2.modeling_kosmos2.Kosmos2TextFFN with Kosmos2->Kosmos2_5 class Kosmos2_5TextFFN(nn.Module): @@ -1617,7 +1620,7 @@ def prepare_inputs_for_generation( # cut input_ids if past_key_values is used if past_key_values is not None: - position_ids = create_position_ids_from_input_ids( + position_ids = Kosmos2_5TextSinusoidalPositionalEmbedding.create_position_ids_from_input_ids( input_ids, padding_idx=self.config.pad_token_id, past_key_values_length=0, diff --git a/src/transformers/models/lilt/modeling_lilt.py b/src/transformers/models/lilt/modeling_lilt.py index c486a494b48a..ac1e4d0544bf 100644 --- a/src/transformers/models/lilt/modeling_lilt.py +++ b/src/transformers/models/lilt/modeling_lilt.py @@ -479,12 +479,10 @@ def layout_feed_forward_chunk(self, attention_output): class LiltEncoder(nn.Module): - # Copied from transformers.models.bert.modeling_bert.BertEncoder.__init__ with Bert->Lilt - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config - self.layer = nn.ModuleList([LiltLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) - self.gradient_checkpointing = False + self.layer = nn.ModuleList([LiltLayer(config) for _ in range(config.num_hidden_layers)]) def forward( self, diff --git a/src/transformers/models/m2m_100/modeling_m2m_100.py b/src/transformers/models/m2m_100/modeling_m2m_100.py index 6015aa54d76b..e7b64e50a79a 100755 --- a/src/transformers/models/m2m_100/modeling_m2m_100.py +++ b/src/transformers/models/m2m_100/modeling_m2m_100.py @@ -72,17 +72,6 @@ def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start return shifted_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - # Copied from transformers.models.bart.modeling_bart.BartScaledWordEmbedding with Bart->M2M100 class M2M100ScaledWordEmbedding(nn.Embedding): """ @@ -146,12 +135,14 @@ def forward( if input_ids is not None: bsz, seq_len = input_ids.size() # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length).to( - input_ids.device - ) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ).to(input_ids.device) else: bsz, seq_len = inputs_embeds.size()[:-1] - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length) + position_ids = self.create_position_ids_from_inputs_embeds( + inputs_embeds, past_key_values_length, self.padding_idx + ) # expand embeddings if needed max_pos = self.padding_idx + 1 + seq_len + past_key_values_length @@ -160,7 +151,8 @@ def forward( return self.weights.index_select(0, position_ids.view(-1)).view(bsz, seq_len, self.weights.shape[-1]).detach() - def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_length): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -173,10 +165,27 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_ sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape).contiguous() + past_key_values_length + @staticmethod + # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_input_ids + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + # Copied from transformers.models.bart.modeling_bart.eager_attention_forward def eager_attention_forward( @@ -553,7 +562,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -591,7 +600,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -712,7 +721,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/marian/modeling_marian.py b/src/transformers/models/marian/modeling_marian.py index f5f567346412..24d056043fee 100755 --- a/src/transformers/models/marian/modeling_marian.py +++ b/src/transformers/models/marian/modeling_marian.py @@ -507,7 +507,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -545,7 +545,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -666,7 +666,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/markuplm/modeling_markuplm.py b/src/transformers/models/markuplm/modeling_markuplm.py index 61acac83b0f2..a0c6985b3da9 100755 --- a/src/transformers/models/markuplm/modeling_markuplm.py +++ b/src/transformers/models/markuplm/modeling_markuplm.py @@ -90,23 +90,6 @@ def forward(self, xpath_tags_seq=None, xpath_subs_seq=None): return xpath_embeddings -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - class MarkupLMEmbeddings(nn.Module): """Construct the embeddings from word, position and token_type embeddings.""" @@ -134,8 +117,9 @@ def __init__(self, config): config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx ) + @staticmethod # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_inputs_embeds - def create_position_ids_from_inputs_embeds(self, inputs_embeds): + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -148,10 +132,27 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds): sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape) + @staticmethod + # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_input_ids + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + def forward( self, input_ids=None, @@ -160,7 +161,6 @@ def forward( token_type_ids=None, position_ids=None, inputs_embeds=None, - past_key_values_length=0, ): if input_ids is not None: input_shape = input_ids.size() @@ -172,9 +172,9 @@ def forward( if position_ids is None: if input_ids is not None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + position_ids = self.create_position_ids_from_input_ids(input_ids, self.padding_idx) else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) if token_type_ids is None: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) diff --git a/src/transformers/models/mbart/modeling_mbart.py b/src/transformers/models/mbart/modeling_mbart.py index 55fad55a87ae..3a0eff585103 100755 --- a/src/transformers/models/mbart/modeling_mbart.py +++ b/src/transformers/models/mbart/modeling_mbart.py @@ -530,7 +530,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -568,7 +568,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -689,7 +689,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/megatron_bert/modeling_megatron_bert.py b/src/transformers/models/megatron_bert/modeling_megatron_bert.py index 8b8f842c2a2a..121ae19850ff 100755 --- a/src/transformers/models/megatron_bert/modeling_megatron_bert.py +++ b/src/transformers/models/megatron_bert/modeling_megatron_bert.py @@ -104,7 +104,7 @@ def forward( return embeddings -# Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->MegatronBert +# copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->MegatronBert class MegatronBertSelfAttention(nn.Module): def __init__(self, config, position_embedding_type=None, layer_idx=None): super().__init__() diff --git a/src/transformers/models/mobilebert/modeling_mobilebert.py b/src/transformers/models/mobilebert/modeling_mobilebert.py index 1d6c5f7c46f4..c44a24acbae9 100644 --- a/src/transformers/models/mobilebert/modeling_mobilebert.py +++ b/src/transformers/models/mobilebert/modeling_mobilebert.py @@ -20,16 +20,17 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import math import warnings from dataclasses import dataclass -from typing import Optional, Union +from typing import Callable, Optional, Union import torch from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa +from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutput, BaseModelOutputWithPooling, @@ -40,12 +41,18 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import ModelOutput, auto_docstring, logging +from ...utils import ModelOutput, TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_mobilebert import MobileBertConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) @@ -138,12 +145,45 @@ def forward( return embeddings +# Copied from transformers.models.bart.modeling_bart.eager_attention_forward +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + **kwargs, +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling + if attention_mask is not None: + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if head_mask is not None: + attn_weights = attn_weights * head_mask.view(1, -1, 1, 1) + + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + class MobileBertSelfAttention(nn.Module): def __init__(self, config): super().__init__() + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.true_hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.true_hidden_size, self.all_head_size) self.key = nn.Linear(config.true_hidden_size, self.all_head_size) @@ -152,6 +192,8 @@ def __init__(self, config): ) self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.is_causal = False + def forward( self, query_tensor: torch.Tensor, @@ -159,45 +201,33 @@ def forward( value_tensor: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = query_tensor.shape - query_layer = ( - self.query(query_tensor) - .view(batch_size, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) - key_layer = ( - self.key(key_tensor) - .view(batch_size, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) - value_layer = ( - self.value(value_tensor) - .view(batch_size, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) + input_shape = query_tensor.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(query_tensor).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(key_tensor).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(value_tensor).view(*hidden_shape).transpose(1, 2) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + **kwargs, ) - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in BertModel forward() function) - attention_scores = attention_scores + attention_mask - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - context_layer = torch.matmul(attention_probs, value_layer) - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) - outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) - return outputs + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights class MobileBertSelfOutput(nn.Module): @@ -250,21 +280,20 @@ def forward( layer_input: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_output, attn_weights = self.self( query_tensor, key_tensor, value_tensor, attention_mask, head_mask, - output_attentions, + **kwargs, ) # Run a linear projection of `hidden_size` then add a residual # with `layer_input`. - attention_output = self.output(self_outputs[0], layer_input) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, layer_input) + return attention_output, attn_weights class MobileBertIntermediate(nn.Module): @@ -392,7 +421,7 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return layer_outputs -class MobileBertLayer(nn.Module): +class MobileBertLayer(GradientCheckpointingLayer): def __init__(self, config): super().__init__() self.use_bottleneck = config.use_bottleneck @@ -411,48 +440,31 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: if self.use_bottleneck: query_tensor, key_tensor, value_tensor, layer_input = self.bottleneck(hidden_states) else: query_tensor, key_tensor, value_tensor, layer_input = [hidden_states] * 4 - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( query_tensor, key_tensor, value_tensor, layer_input, attention_mask, head_mask, - output_attentions=output_attentions, + **kwargs, ) - attention_output = self_attention_outputs[0] - s = (attention_output,) - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.num_feedforward_networks != 1: - for i, ffn_module in enumerate(self.ffn): + for ffn_module in self.ffn: attention_output = ffn_module(attention_output) - s += (attention_output,) intermediate_output = self.intermediate(attention_output) layer_output = self.output(intermediate_output, attention_output, hidden_states) - outputs = ( - (layer_output,) - + outputs - + ( - torch.tensor(1000), - query_tensor, - key_tensor, - value_tensor, - layer_input, - attention_output, - intermediate_output, - ) - + s - ) - return outputs + return layer_output class MobileBertEncoder(nn.Module): @@ -465,36 +477,16 @@ def forward( hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, BaseModelOutput]: - all_hidden_states = () if output_hidden_states else None - all_attentions = () if output_attentions else None for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, head_mask[i], - output_attentions, + **kwargs, ) - hidden_states = layer_outputs[0] - - if output_attentions: - all_attentions = all_attentions + (layer_outputs[1],) - - # Add last layer - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) - return BaseModelOutput( - last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions - ) + return BaseModelOutput(last_hidden_state=hidden_states) class MobileBertPooler(nn.Module): @@ -581,6 +573,15 @@ def forward(self, sequence_output: torch.Tensor, pooled_output: torch.Tensor) -> class MobileBertPreTrainedModel(PreTrainedModel): config: MobileBertConfig base_model_prefix = "mobilebert" + supports_gradient_checkpointing = True + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": MobileBertLayer, + "attentions": MobileBertSelfAttention, + } def _init_weights(self, module): """Initialize the weights""" @@ -637,6 +638,8 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False + self.embeddings = MobileBertEmbeddings(config) self.encoder = MobileBertEncoder(config) @@ -659,6 +662,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -668,36 +672,22 @@ def forward( position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - output_hidden_states: Optional[bool] = None, - output_attentions: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, BaseModelOutputWithPooling]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - device = input_ids.device if input_ids is not None else inputs_embeds.device + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") - if attention_mask is None: - attention_mask = torch.ones(input_shape, device=device) - if token_type_ids is None: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + ) - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) # Prepare head mask if needed # 1.0 in head_mask indicate we keep the head @@ -706,30 +696,43 @@ def forward( # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) - embedding_output = self.embeddings( - input_ids=input_ids, position_ids=position_ids, token_type_ids=token_type_ids, inputs_embeds=inputs_embeds - ) encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + **kwargs, ) sequence_output = encoder_outputs[0] pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] - return BaseModelOutputWithPooling( last_hidden_state=sequence_output, pooler_output=pooled_output, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, ) + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_full_mask + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + @auto_docstring( custom_intro=""" @@ -763,6 +766,7 @@ def resize_token_embeddings(self, new_num_tokens: Optional[int] = None) -> nn.Em return super().resize_token_embeddings(new_num_tokens=new_num_tokens) + @can_return_tuple @auto_docstring def forward( self, @@ -774,9 +778,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, next_sentence_label: Optional[torch.LongTensor] = None, - output_attentions: Optional[torch.FloatTensor] = None, - output_hidden_states: Optional[torch.FloatTensor] = None, - return_dict: Optional[torch.FloatTensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, MobileBertForPreTrainingOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -806,8 +808,6 @@ def forward( >>> prediction_logits = outputs.prediction_logits >>> seq_relationship_logits = outputs.seq_relationship_logits ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.mobilebert( input_ids, attention_mask=attention_mask, @@ -815,9 +815,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output, pooled_output = outputs[:2] prediction_scores, seq_relationship_score = self.cls(sequence_output, pooled_output) @@ -829,10 +828,6 @@ def forward( next_sentence_loss = loss_fct(seq_relationship_score.view(-1, 2), next_sentence_label.view(-1)) total_loss = masked_lm_loss + next_sentence_loss - if not return_dict: - output = (prediction_scores, seq_relationship_score) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return MobileBertForPreTrainingOutput( loss=total_loss, prediction_logits=prediction_scores, @@ -869,6 +864,7 @@ def resize_token_embeddings(self, new_num_tokens: Optional[int] = None) -> nn.Em ) return super().resize_token_embeddings(new_num_tokens=new_num_tokens) + @can_return_tuple @auto_docstring def forward( self, @@ -879,9 +875,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, MaskedLMOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -889,8 +883,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.mobilebert( input_ids, attention_mask=attention_mask, @@ -898,9 +890,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -911,10 +902,6 @@ def forward( loss_fct = CrossEntropyLoss() # -100 index = padding token masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -948,6 +935,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -958,10 +946,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, NextSentencePredictorOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): @@ -997,8 +982,6 @@ def forward( ) labels = kwargs.pop("next_sentence_label") - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.mobilebert( input_ids, attention_mask=attention_mask, @@ -1006,9 +989,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1019,10 +1001,6 @@ def forward( loss_fct = CrossEntropyLoss() next_sentence_loss = loss_fct(seq_relationship_score.view(-1, 2), labels.view(-1)) - if not return_dict: - output = (seq_relationship_score,) + outputs[2:] - return ((next_sentence_loss,) + output) if next_sentence_loss is not None else output - return NextSentencePredictorOutput( loss=next_sentence_loss, logits=seq_relationship_score, @@ -1054,6 +1032,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1064,9 +1043,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): @@ -1074,8 +1051,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.mobilebert( input_ids, attention_mask=attention_mask, @@ -1083,9 +1058,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1115,9 +1089,6 @@ def forward( elif self.config.problem_type == "multi_label_classification": loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output return SequenceClassifierOutput( loss=loss, @@ -1140,6 +1111,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1151,12 +1123,8 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, start_positions: Optional[torch.Tensor] = None, end_positions: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.mobilebert( input_ids, attention_mask=attention_mask, @@ -1164,9 +1132,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1193,10 +1160,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, @@ -1222,6 +1185,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1232,9 +1196,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1266,7 +1228,6 @@ def forward( num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1286,9 +1247,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1302,10 +1262,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1331,6 +1287,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1341,16 +1298,12 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.mobilebert( input_ids, attention_mask=attention_mask, @@ -1358,9 +1311,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1373,10 +1325,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, diff --git a/src/transformers/models/nllb_moe/modeling_nllb_moe.py b/src/transformers/models/nllb_moe/modeling_nllb_moe.py index f0131b6b999b..3fcbd936af9b 100644 --- a/src/transformers/models/nllb_moe/modeling_nllb_moe.py +++ b/src/transformers/models/nllb_moe/modeling_nllb_moe.py @@ -77,23 +77,6 @@ def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start return shifted_input_ids -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - def load_balancing_loss_func(router_probs: torch.Tensor, expert_indices: torch.Tensor) -> float: r""" Computes auxiliary load balancing loss as in Switch Transformer - implemented in Pytorch. @@ -150,7 +133,7 @@ def forward(self, input_ids: torch.Tensor): return super().forward(input_ids) * self.embed_scale -# Copied from transformers.models.m2m_100.modeling_m2m_100.M2M100SinusoidalPositionalEmbedding +# Copied from transformers.models.m2m_100.modeling_m2m_100.M2M100SinusoidalPositionalEmbedding with M2M100->NllbMoe class NllbMoeSinusoidalPositionalEmbedding(nn.Module): """This module produces sinusoidal positional embeddings of any length.""" @@ -200,12 +183,14 @@ def forward( if input_ids is not None: bsz, seq_len = input_ids.size() # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length).to( - input_ids.device - ) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ).to(input_ids.device) else: bsz, seq_len = inputs_embeds.size()[:-1] - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length) + position_ids = self.create_position_ids_from_inputs_embeds( + inputs_embeds, past_key_values_length, self.padding_idx + ) # expand embeddings if needed max_pos = self.padding_idx + 1 + seq_len + past_key_values_length @@ -214,7 +199,8 @@ def forward( return self.weights.index_select(0, position_ids.view(-1)).view(bsz, seq_len, self.weights.shape[-1]).detach() - def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_length): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -227,10 +213,27 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_ sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape).contiguous() + past_key_values_length + @staticmethod + # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_input_ids + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + class NllbMoeTop2Router(nn.Module): """ @@ -1059,7 +1062,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/pegasus/modeling_pegasus.py b/src/transformers/models/pegasus/modeling_pegasus.py index dc3a8005acac..09ea75c3b1fe 100755 --- a/src/transformers/models/pegasus/modeling_pegasus.py +++ b/src/transformers/models/pegasus/modeling_pegasus.py @@ -486,7 +486,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -524,7 +524,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -645,7 +645,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/pegasus_x/modeling_pegasus_x.py b/src/transformers/models/pegasus_x/modeling_pegasus_x.py index 231d6601d28a..b9ba1aca6d28 100755 --- a/src/transformers/models/pegasus_x/modeling_pegasus_x.py +++ b/src/transformers/models/pegasus_x/modeling_pegasus_x.py @@ -779,7 +779,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -817,7 +817,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -938,7 +938,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/plbart/modeling_plbart.py b/src/transformers/models/plbart/modeling_plbart.py index 60239bf9ac54..5c056be5ae89 100644 --- a/src/transformers/models/plbart/modeling_plbart.py +++ b/src/transformers/models/plbart/modeling_plbart.py @@ -88,7 +88,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -126,7 +126,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -247,7 +247,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/plbart/modular_plbart.py b/src/transformers/models/plbart/modular_plbart.py index 29c253144557..9ca406775eae 100644 --- a/src/transformers/models/plbart/modular_plbart.py +++ b/src/transformers/models/plbart/modular_plbart.py @@ -72,7 +72,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -110,7 +110,7 @@ def _update_causal_mask( ) return attention_mask - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: if attention_mask is not None and (attention_mask == 0.0).any(): return attention_mask return None @@ -231,7 +231,7 @@ def _update_cross_attn_mask( ): # expand encoder attention mask if encoder_hidden_states is not None and encoder_attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on diff --git a/src/transformers/models/prophetnet/modeling_prophetnet.py b/src/transformers/models/prophetnet/modeling_prophetnet.py index 260b0c698407..17517ca1209d 100644 --- a/src/transformers/models/prophetnet/modeling_prophetnet.py +++ b/src/transformers/models/prophetnet/modeling_prophetnet.py @@ -1662,6 +1662,7 @@ def forward( output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs, ) -> Union[tuple, ProphetNetSeq2SeqLMOutput]: r""" decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*): @@ -1864,6 +1865,7 @@ def forward( output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, + **kwargs, ) -> Union[tuple, ProphetNetDecoderLMOutput]: r""" cross_attn_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): diff --git a/src/transformers/models/rembert/modeling_rembert.py b/src/transformers/models/rembert/modeling_rembert.py index 3a1980885339..8e187421f152 100755 --- a/src/transformers/models/rembert/modeling_rembert.py +++ b/src/transformers/models/rembert/modeling_rembert.py @@ -262,7 +262,7 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - # Copied from transformers.models.bert.modeling_bert.BertAttention.forward + # copied from transformers.models.bert.modeling_bert.BertAttention.forward def forward( self, hidden_states: torch.Tensor, @@ -333,7 +333,7 @@ def __init__(self, config, layer_idx=None): self.intermediate = RemBertIntermediate(config) self.output = RemBertOutput(config) - # Copied from transformers.models.bert.modeling_bert.BertLayer.forward + # copied from transformers.models.bert.modeling_bert.BertLayer.forward def forward( self, hidden_states: torch.Tensor, diff --git a/src/transformers/models/roberta/modeling_roberta.py b/src/transformers/models/roberta/modeling_roberta.py index 2865460718c2..8810be00a0d0 100644 --- a/src/transformers/models/roberta/modeling_roberta.py +++ b/src/transformers/models/roberta/modeling_roberta.py @@ -1,3 +1,9 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/roberta/modular_roberta.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_roberta.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 # coding=utf-8 # Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. # Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. @@ -13,19 +19,18 @@ # 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. -"""PyTorch RoBERTa model.""" -import math -from typing import Optional, Union +from typing import Callable, Optional, Union import torch -from torch import nn +import torch.nn as nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN, gelu -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin -from ...modeling_attn_mask_utils import _prepare_4d_attention_mask_for_sdpa, _prepare_4d_causal_attention_mask_for_sdpa +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -37,26 +42,27 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_roberta import RobertaConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) class RobertaEmbeddings(nn.Module): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ + """Construct the embeddings from word, position and token_type embeddings.""" - # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ def __init__(self, config): super().__init__() self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) - self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) @@ -70,37 +76,44 @@ def __init__(self, config): "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False ) - # End copy self.padding_idx = config.pad_token_id self.position_embeddings = nn.Embedding( config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx ) def forward( - self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: if position_ids is None: if input_ids is not None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) if input_ids is not None: input_shape = input_ids.size() else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -116,7 +129,8 @@ def forward( embeddings = self.dropout(embeddings) return embeddings - def create_position_ids_from_inputs_embeds(self, inputs_embeds): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -129,24 +143,99 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds): sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape) + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + -# Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->Roberta class RobertaSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -161,219 +250,158 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 - ) - - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only roberta can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) - - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in RobertaModel forward() function) - attention_scores = attention_scores + attention_mask - - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - context_layer = torch.matmul(attention_probs, value_layer) +class RobertaCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + self.config = config - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 - return context_layer, attention_probs + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) -# Copied from transformers.models.bert.modeling_bert.BertSdpaSelfAttention with Bert->Roberta -class RobertaSdpaSelfAttention(RobertaSelfAttention): - def __init__(self, config, position_embedding_type=None, layer_idx=None): - super().__init__(config, position_embedding_type=position_embedding_type, layer_idx=layer_idx) - self.dropout_prob = config.attention_probs_dropout_prob + self.is_causal = is_causal + self.layer_idx = layer_idx - # Adapted from RobertaSelfAttention - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, - attention_mask: Optional[torch.Tensor] = None, - head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, - cache_position: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - if self.position_embedding_type != "absolute" or output_attentions or head_mask is not None: - # TODO: Improve this warning with e.g. `model.config._attn_implementation = "manual"` once implemented. - logger.warning_once( - "RobertaSdpaSelfAttention is used but `torch.nn.functional.scaled_dot_product_attention` does not support " - "non-absolute `position_embedding_type` or `output_attentions=True` or `head_mask`. Falling back to " - "the manual attention implementation, but specifying the manual implementation will be required from " - "Transformers version v5.0.0 onwards. This warning can be removed using the argument " - '`attn_implementation="eager"` when loading the model.' - ) - return super().forward( - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states, - past_key_values, - output_attentions, - cache_position, - ) - - bsz, tgt_len, _ = hidden_states.size() + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - query_layer = ( - self.query(hidden_states).view(bsz, -1, self.num_attention_heads, self.attention_head_size).transpose(1, 2) - ) + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - is_updated = False - is_cross_attention = encoder_hidden_states is not None - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_states from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values else: - key_layer = ( - self.key(current_states) - .view(bsz, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) - value_layer = ( - self.value(current_states) - .view(bsz, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx ) # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + past_key_value.is_updated[self.layer_idx] = True - # We dispatch to SDPA's Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment - # in SDPA to support both torch.compile's dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling. - # The tgt_len > 1 is necessary to match with AttentionMaskConverter.to_causal_4d that does not create - # a causal mask in case tgt_len == 1. - is_causal = self.is_decoder and not is_cross_attention and attention_mask is None and tgt_len > 1 + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - attn_output = torch.nn.functional.scaled_dot_product_attention( + attn_output, attn_weights = attention_interface( + self, query_layer, key_layer, value_layer, - attn_mask=attention_mask, - dropout_p=self.dropout_prob if self.training else 0.0, - is_causal=is_causal, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights - attn_output = attn_output.transpose(1, 2) - attn_output = attn_output.reshape(bsz, tgt_len, self.all_head_size) - - return attn_output, None - -# Copied from transformers.models.bert.modeling_bert.BertSelfOutput class RobertaSelfOutput(nn.Module): def __init__(self, config): super().__init__() @@ -388,20 +416,15 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -ROBERTA_SELF_ATTENTION_CLASSES = { - "eager": RobertaSelfAttention, - "sdpa": RobertaSdpaSelfAttention, -} - - -# Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->Roberta,BERT->ROBERTA class RobertaAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = ROBERTA_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = RobertaCrossAttention if is_cross_attention else RobertaSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = RobertaSelfOutput(config) self.pruned_heads = set() @@ -424,32 +447,31 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, + encoder_hidden_states=encoder_hidden_states, attention_mask=attention_mask, head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights -# Copied from transformers.models.bert.modeling_bert.BertIntermediate class RobertaIntermediate(nn.Module): def __init__(self, config): super().__init__() @@ -465,7 +487,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return hidden_states -# Copied from transformers.models.bert.modeling_bert.BertOutput class RobertaOutput(nn.Module): def __init__(self, config): super().__init__() @@ -480,23 +501,27 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -# Copied from transformers.models.bert.modeling_bert.BertLayer with Bert->Roberta class RobertaLayer(GradientCheckpointingLayer): def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = RobertaAttention(config, layer_idx=layer_idx) + self.attention = RobertaAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = RobertaAttention(config, position_embedding_type="absolute", layer_idx=layer_idx) + self.crossattention = RobertaAttention( + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) self.intermediate = RobertaIntermediate(config) self.output = RobertaOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -504,20 +529,19 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -526,24 +550,21 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - outputs = (layer_output,) + outputs - - return outputs + return layer_output def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -551,13 +572,44 @@ def feed_forward_chunk(self, attention_output): return layer_output -# Copied from transformers.models.bert.modeling_bert.BertEncoder with Bert->Roberta +@auto_docstring +class RobertaPreTrainedModel(PreTrainedModel): + config_class = RobertaConfig + base_model_prefix = "roberta" + supports_gradient_checkpointing = True + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": RobertaLayer, + "attentions": RobertaSelfAttention, + "cross_attentions": RobertaCrossAttention, + } + + # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights with BertLMPredictionHead->RobertaLMHead + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, RobertaLMHead): + module.bias.data.zero_() + + class RobertaEncoder(nn.Module): - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config self.layer = nn.ModuleList([RobertaLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) - self.gradient_checkpointing = False def forward( self, @@ -568,81 +620,29 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and self.config.is_decoder and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - - if use_cache and self.config.is_decoder and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, # as a positional argument for gradient checkpointing encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_values, cache_position=cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) -# Copied from transformers.models.bert.modeling_bert.BertPooler class RobertaPooler(nn.Module): def __init__(self, config): super().__init__() @@ -658,32 +658,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return pooled_output -@auto_docstring -class RobertaPreTrainedModel(PreTrainedModel): - config: RobertaConfig - base_model_prefix = "roberta" - supports_gradient_checkpointing = True - _no_split_modules = ["RobertaEmbeddings", "RobertaSelfAttention", "RobertaSdpaSelfAttention"] - _supports_sdpa = True - - # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights with BertLMPredictionHead->RobertaLMHead - def _init_weights(self, module): - """Initialize the weights""" - if isinstance(module, nn.Linear): - module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) - if module.bias is not None: - module.bias.data.zero_() - elif isinstance(module, nn.Embedding): - module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) - if module.padding_idx is not None: - module.weight.data[module.padding_idx].zero_() - elif isinstance(module, nn.LayerNorm): - module.bias.data.zero_() - module.weight.data.fill_(1.0) - elif isinstance(module, RobertaLMHead): - module.bias.data.zero_() - - @auto_docstring( custom_intro=""" The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of @@ -696,7 +670,6 @@ def _init_weights(self, module): `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. """ ) -# Copied from transformers.models.bert.modeling_bert.BertModel with Bert->Roberta, BERT->ROBERTA class RobertaModel(RobertaPreTrainedModel): _no_split_modules = ["RobertaEmbeddings", "RobertaLayer"] @@ -707,13 +680,13 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = RobertaEmbeddings(config) self.encoder = RobertaEncoder(config) self.pooler = RobertaPooler(config) if add_pooling_layer else None - self.attn_implementation = config._attn_implementation self.position_embedding_type = config.position_embedding_type # Initialize weights and apply final processing @@ -733,6 +706,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -744,52 +718,40 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape + else: + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] + + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) embedding_output = self.embeddings( input_ids=input_ids, @@ -799,55 +761,16 @@ def forward( past_key_values_length=past_key_values_length, ) - if attention_mask is None: - attention_mask = torch.ones((batch_size, seq_length + past_key_values_length), device=device) - - use_sdpa_attention_masks = ( - self.attn_implementation == "sdpa" - and self.position_embedding_type == "absolute" - and head_mask is None - and not output_attentions + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, ) - # Expand the attention mask - if use_sdpa_attention_masks and attention_mask.dim() == 2: - # Expand the attention mask for SDPA. - # [bsz, seq_len] -> [bsz, 1, seq_len, seq_len] - if self.config.is_decoder: - extended_attention_mask = _prepare_4d_causal_attention_mask_for_sdpa( - attention_mask, - input_shape, - embedding_output, - past_key_values_length, - ) - else: - extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - - if use_sdpa_attention_masks and encoder_attention_mask.dim() == 2: - # Expand the attention mask for SDPA. - # [bsz, seq_len] -> [bsz, 1, seq_len, seq_len] - encoder_extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - encoder_attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) - else: - encoder_extended_attention_mask = None - # Prepare head mask if needed # 1.0 in head_mask indicate we keep the head # attention_probs has shape bsz x n_heads x N x N @@ -857,32 +780,135 @@ def forward( encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) - sequence_output = encoder_outputs[0] + sequence_output = encoder_outputs.last_hidden_state pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + @auto_docstring( custom_intro=""" @@ -910,6 +936,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -922,12 +949,10 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -960,7 +985,6 @@ def forward( >>> prediction_logits = outputs.logits ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -975,9 +999,9 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -994,10 +1018,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, @@ -1033,6 +1053,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -1045,9 +1066,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1064,8 +1083,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1075,9 +1092,8 @@ def forward( inputs_embeds=inputs_embeds, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] prediction_scores = self.lm_head(sequence_output) @@ -1089,10 +1105,6 @@ def forward( loss_fct = CrossEntropyLoss() masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -1150,6 +1162,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1160,9 +1173,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1179,8 +1190,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1188,9 +1197,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] logits = self.classifier(sequence_output) @@ -1220,10 +1228,6 @@ def forward( loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return SequenceClassifierOutput( loss=loss, logits=logits, @@ -1244,6 +1248,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1254,9 +1259,7 @@ def forward( position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1289,7 +1292,6 @@ def forward( is useful if you want more control over how to convert `input_ids` indices into associated vectors than the model's internal embedding lookup matrix. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1309,9 +1311,8 @@ def forward( attention_mask=flat_attention_mask, head_mask=head_mask, inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1326,10 +1327,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1354,6 +1351,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1364,9 +1362,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1381,8 +1377,6 @@ def forward( labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1390,9 +1384,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1407,10 +1400,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1453,6 +1442,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1464,9 +1454,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, start_positions: Optional[torch.LongTensor] = None, end_positions: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1479,8 +1467,6 @@ def forward( [What are token type IDs?](../glossary#token-type-ids) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1488,9 +1474,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1517,10 +1502,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, @@ -1530,22 +1511,6 @@ def forward( ) -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - __all__ = [ "RobertaForCausalLM", "RobertaForMaskedLM", diff --git a/src/transformers/models/roberta/modular_roberta.py b/src/transformers/models/roberta/modular_roberta.py new file mode 100644 index 000000000000..e98eddf99bf5 --- /dev/null +++ b/src/transformers/models/roberta/modular_roberta.py @@ -0,0 +1,800 @@ +# coding=utf-8 +# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# 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. +"""PyTorch RoBERTa model.""" + +from typing import Optional, Union + +import torch +import torch.nn as nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import gelu +from ...generation import GenerationMixin +from ...modeling_outputs import ( + CausalLMOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, logging +from ...utils.generic import can_return_tuple +from ..bert.modeling_bert import BertCrossAttention, BertEmbeddings, BertLayer, BertModel, BertSelfAttention +from .configuration_roberta import RobertaConfig + + +logger = logging.get_logger(__name__) + + +class RobertaEmbeddings(BertEmbeddings): + def __init__(self, config): + super().__init__(config) + + del self.pad_token_id + del self.position_embeddings + + self.padding_idx = config.pad_token_id + self.position_embeddings = nn.Embedding( + config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx + ) + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ): + if position_ids is None: + if input_ids is not None: + # Create the position ids from the input token ids. Any padded tokens remain padded. + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) + else: + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) + + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + batch_size, seq_length = input_shape + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): + """ + We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. + + Args: + inputs_embeds: torch.Tensor + + Returns: torch.Tensor + """ + input_shape = inputs_embeds.size()[:-1] + sequence_length = input_shape[1] + + position_ids = torch.arange( + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + ) + return position_ids.unsqueeze(0).expand(input_shape) + + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + + +class RobertaSelfAttention(BertSelfAttention): + pass + + +class RobertaCrossAttention(BertCrossAttention): + pass + + +class RobertaLayer(BertLayer): + pass + + +@auto_docstring +class RobertaPreTrainedModel(PreTrainedModel): + config_class = RobertaConfig + base_model_prefix = "roberta" + supports_gradient_checkpointing = True + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": RobertaLayer, + "attentions": RobertaSelfAttention, + "cross_attentions": RobertaCrossAttention, + } + + # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights with BertLMPredictionHead->RobertaLMHead + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, RobertaLMHead): + module.bias.data.zero_() + + +class RobertaModel(BertModel): + def __init__(self, config, add_pooling_layer=True): + super().__init__(self, config) + + +@auto_docstring( + custom_intro=""" + RoBERTa Model with a `language modeling` head on top for CLM fine-tuning. + """ +) +class RobertaForCausalLM(RobertaPreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.decoder.weight", "lm_head.decoder.bias"] + + def __init__(self, config): + super().__init__(config) + + if not config.is_decoder: + logger.warning("If you want to use `RobertaLMHeadModel` as a standalone, add `is_decoder=True.`") + + self.roberta = RobertaModel(config, add_pooling_layer=False) + self.lm_head = RobertaLMHead(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.lm_head.decoder + + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + + Example: + + ```python + >>> from transformers import AutoTokenizer, RobertaForCausalLM, AutoConfig + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("FacebookAI/roberta-base") + >>> config = AutoConfig.from_pretrained("FacebookAI/roberta-base") + >>> config.is_decoder = True + >>> model = RobertaForCausalLM.from_pretrained("FacebookAI/roberta-base", config=config) + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> prediction_logits = outputs.logits + ```""" + if labels is not None: + use_cache = False + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + lm_loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(prediction_scores.device) + lm_loss = self.loss_function( + prediction_scores, + labels, + vocab_size=self.config.vocab_size, + **kwargs, + ) + + return CausalLMOutputWithCrossAttentions( + loss=lm_loss, + logits=prediction_scores, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +@auto_docstring +class RobertaForMaskedLM(RobertaPreTrainedModel): + _tied_weights_keys = ["lm_head.decoder.weight", "lm_head.decoder.bias"] + + def __init__(self, config): + super().__init__(config) + + if config.is_decoder: + logger.warning( + "If you want to use `RobertaForMaskedLM` make sure `config.is_decoder=False` for " + "bi-directional self-attention." + ) + + self.roberta = RobertaModel(config, add_pooling_layer=False) + self.lm_head = RobertaLMHead(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.lm_head.decoder + + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + return_dict=True, + **kwargs, + ) + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + masked_lm_loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(prediction_scores.device) + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class RobertaLMHead(nn.Module): + """Roberta Head for masked language modeling.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + self.decoder = nn.Linear(config.hidden_size, config.vocab_size) + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + self.decoder.bias = self.bias + + def forward(self, features, **kwargs): + x = self.dense(features) + x = gelu(x) + x = self.layer_norm(x) + + # project back to size of vocabulary with bias + x = self.decoder(x) + + return x + + def _tie_weights(self): + # To tie those two weights if they get disconnected (on TPU or when the bias is resized) + # For accelerate compatibility and to not break backward compatibility + if self.decoder.bias.device.type == "meta": + self.decoder.bias = self.bias + else: + self.bias = self.decoder.bias + + +@auto_docstring( + custom_intro=""" + RoBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """ +) +class RobertaForSequenceClassification(RobertaPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + + self.roberta = RobertaModel(config, add_pooling_layer=False) + self.classifier = RobertaClassificationHead(config) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + sequence_output = outputs[0] + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(logits.device) + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class RobertaForMultipleChoice(RobertaPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.roberta = RobertaModel(config) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, 1) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: + r""" + input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + """ + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + flat_inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.roberta( + flat_input_ids, + position_ids=flat_position_ids, + token_type_ids=flat_token_type_ids, + attention_mask=flat_attention_mask, + head_mask=head_mask, + inputs_embeds=flat_inputs_embeds, + return_dict=True, + **kwargs, + ) + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(reshaped_logits.device) + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class RobertaForTokenClassification(RobertaPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.roberta = RobertaModel(config, add_pooling_layer=False) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(logits.device) + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class RobertaClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.out_proj = nn.Linear(config.hidden_size, config.num_labels) + + def forward(self, features, **kwargs): + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x) + x = self.dense(x) + x = torch.tanh(x) + x = self.dropout(x) + x = self.out_proj(x) + return x + + +@auto_docstring +class RobertaForQuestionAnswering(RobertaPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.roberta = RobertaModel(config, add_pooling_layer=False) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + start_positions: Optional[torch.LongTensor] = None, + end_positions: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +__all__ = [ + "RobertaForCausalLM", + "RobertaForMaskedLM", + "RobertaForMultipleChoice", + "RobertaForQuestionAnswering", + "RobertaForSequenceClassification", + "RobertaForTokenClassification", + "RobertaModel", + "RobertaPreTrainedModel", +] diff --git a/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py b/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py index 5247c39b7553..0085992d2a9a 100644 --- a/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py +++ b/src/transformers/models/roberta_prelayernorm/modeling_roberta_prelayernorm.py @@ -15,16 +15,17 @@ # limitations under the License. """PyTorch RoBERTa-PreLayerNorm model.""" -import math -from typing import Optional, Union +from typing import Callable, Optional, Union import torch from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN, gelu -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -36,27 +37,28 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_roberta_prelayernorm import RobertaPreLayerNormConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->RobertaPreLayerNorm class RobertaPreLayerNormEmbeddings(nn.Module): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ + """Construct the embeddings from word, position and token_type embeddings.""" - # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ def __init__(self, config): super().__init__() self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) - self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) @@ -70,37 +72,44 @@ def __init__(self, config): "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False ) - # End copy self.padding_idx = config.pad_token_id self.position_embeddings = nn.Embedding( config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx ) def forward( - self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: if position_ids is None: if input_ids is not None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) if input_ids is not None: input_shape = input_ids.size() else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -116,7 +125,8 @@ def forward( embeddings = self.dropout(embeddings) return embeddings - def create_position_ids_from_inputs_embeds(self, inputs_embeds): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -129,24 +139,101 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds): sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape) + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + + +# Copied from transformers.models.bert.modeling_bert.eager_attention_forward +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + # Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->RobertaPreLayerNorm class RobertaPreLayerNormSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -161,111 +248,157 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only bert can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, + ) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 +# Copied from transformers.models.bert.modeling_bert.BertCrossAttention with Bert->RobertaPreLayerNorm +class RobertaPreLayerNormCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + self.config = config - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 - ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in RobertaPreLayerNormModel forward() function) - attention_scores = attention_scores + attention_mask + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) + self.is_causal = is_causal + self.layer_idx = layer_idx - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + def forward( + self, + hidden_states: torch.Tensor, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] + + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) + + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: + # reuse k,v, cross_attentions + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values + else: + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) - context_layer = torch.matmul(attention_probs, value_layer) + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx + ) + # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls + past_key_value.is_updated[self.layer_idx] = True - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - return context_layer, attention_probs + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights class RobertaPreLayerNormSelfOutput(nn.Module): @@ -282,10 +415,14 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to class RobertaPreLayerNormAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = RobertaPreLayerNormSelfAttention( - config, position_embedding_type=position_embedding_type, layer_idx=layer_idx + self.is_cross_attention = is_cross_attention + attention_class = RobertaPreLayerNormCrossAttention if is_cross_attention else RobertaPreLayerNormSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = RobertaPreLayerNormSelfOutput(config) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) @@ -310,30 +447,30 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[tuple[tuple[torch.FloatTensor]]] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: hidden_states_pre_layer_norm = self.LayerNorm(hidden_states) - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states_pre_layer_norm, - attention_mask, - head_mask, - encoder_hidden_states, - past_key_values, - output_attentions, - cache_position, + encoder_hidden_states=encoder_hidden_states, + attention_mask=attention_mask, + head_mask=head_mask, + past_key_value=past_key_value, + cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights class RobertaPreLayerNormIntermediate(nn.Module): @@ -372,19 +509,22 @@ def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = RobertaPreLayerNormAttention(config, layer_idx=layer_idx) + self.attention = RobertaPreLayerNormAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") self.crossattention = RobertaPreLayerNormAttention( - config, position_embedding_type="absolute", layer_idx=layer_idx + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, ) self.intermediate = RobertaPreLayerNormIntermediate(config) self.output = RobertaPreLayerNormOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -392,20 +532,19 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -414,24 +553,21 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - outputs = (layer_output,) + outputs - - return outputs + return layer_output def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -441,13 +577,12 @@ def feed_forward_chunk(self, attention_output): # Copied from transformers.models.bert.modeling_bert.BertEncoder with Bert->RobertaPreLayerNorm class RobertaPreLayerNormEncoder(nn.Module): - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config self.layer = nn.ModuleList( [RobertaPreLayerNormLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)] ) - self.gradient_checkpointing = False def forward( self, @@ -458,77 +593,26 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and self.config.is_decoder and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - - if use_cache and self.config.is_decoder and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, # as a positional argument for gradient checkpointing encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_values, cache_position=cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) @@ -550,10 +634,23 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: @auto_docstring class RobertaPreLayerNormPreTrainedModel(PreTrainedModel): - config: RobertaPreLayerNormConfig + config_class = RobertaPreLayerNormConfig base_model_prefix = "roberta_prelayernorm" supports_gradient_checkpointing = True - _no_split_modules = ["RobertaPreLayerNormEmbeddings", "RobertaPreLayerNormSelfAttention"] + _no_split_modules = [ + "RobertaPreLayerNormEmbeddings", + "RobertaPreLayerNormSelfAttention", + "RobertaPreLayerNormCrossAttention", + ] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": RobertaPreLayerNormLayer, + "attentions": RobertaPreLayerNormSelfAttention, + "cross_attentions": RobertaPreLayerNormCrossAttention, + } # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights with BertLMPredictionHead->RobertaPreLayerNormLMHead def _init_weights(self, module): @@ -596,6 +693,7 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = RobertaPreLayerNormEmbeddings(config) self.encoder = RobertaPreLayerNormEncoder(config) @@ -620,6 +718,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -631,11 +730,10 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[list[torch.FloatTensor]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -648,70 +746,35 @@ def forward( [What are token type IDs?](../glossary#token-type-ids) """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - if attention_mask is None: - attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) - - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape else: - encoder_extended_attention_mask = None + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) embedding_output = self.embeddings( input_ids=input_ids, @@ -720,34 +783,159 @@ def forward( inputs_embeds=inputs_embeds, past_key_values_length=past_key_values_length, ) + + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, + ) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) sequence_output = encoder_outputs[0] sequence_output = self.LayerNorm(sequence_output) pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + # Copied from transformers.models.bert.modeling_bert.BertModel._create_attention_masks + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_full_mask + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_cross_attn_mask + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + @auto_docstring( custom_intro=""" @@ -778,6 +966,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -790,12 +979,10 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -828,7 +1015,6 @@ def forward( >>> prediction_logits = outputs.logits ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -843,9 +1029,9 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -862,10 +1048,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, @@ -906,6 +1088,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring # Copied from transformers.models.roberta.modeling_roberta.RobertaForMaskedLM.forward with ROBERTA->ROBERTA_PRELAYERNORM,Roberta->RobertaPreLayerNorm,roberta->roberta_prelayernorm def forward( @@ -919,9 +1102,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -938,8 +1119,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta_prelayernorm( input_ids, attention_mask=attention_mask, @@ -949,9 +1128,8 @@ def forward( inputs_embeds=inputs_embeds, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] prediction_scores = self.lm_head(sequence_output) @@ -963,10 +1141,6 @@ def forward( loss_fct = CrossEntropyLoss() masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -1025,6 +1199,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring # Copied from transformers.models.roberta.modeling_roberta.RobertaForSequenceClassification.forward with roberta->roberta_prelayernorm def forward( @@ -1036,9 +1211,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1055,8 +1228,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta_prelayernorm( input_ids, attention_mask=attention_mask, @@ -1064,9 +1235,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] logits = self.classifier(sequence_output) @@ -1096,10 +1266,6 @@ def forward( loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return SequenceClassifierOutput( loss=loss, logits=logits, @@ -1121,6 +1287,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1131,9 +1298,7 @@ def forward( position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1166,7 +1331,6 @@ def forward( is useful if you want more control over how to convert `input_ids` indices into associated vectors than the model's internal embedding lookup matrix. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1186,9 +1350,8 @@ def forward( attention_mask=flat_attention_mask, head_mask=head_mask, inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1203,10 +1366,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1231,6 +1390,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring # Copied from transformers.models.roberta.modeling_roberta.RobertaForTokenClassification.forward with roberta->roberta_prelayernorm def forward( @@ -1242,9 +1402,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1259,8 +1417,6 @@ def forward( labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta_prelayernorm( input_ids, attention_mask=attention_mask, @@ -1268,9 +1424,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1285,10 +1440,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1332,6 +1483,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring # Copied from transformers.models.roberta.modeling_roberta.RobertaForQuestionAnswering.forward with roberta->roberta_prelayernorm def forward( @@ -1344,9 +1496,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, start_positions: Optional[torch.LongTensor] = None, end_positions: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1359,8 +1509,6 @@ def forward( [What are token type IDs?](../glossary#token-type-ids) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta_prelayernorm( input_ids, attention_mask=attention_mask, @@ -1368,9 +1516,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1397,10 +1544,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, @@ -1410,22 +1553,6 @@ def forward( ) -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - __all__ = [ "RobertaPreLayerNormForCausalLM", "RobertaPreLayerNormForMaskedLM", diff --git a/src/transformers/models/roc_bert/modeling_roc_bert.py b/src/transformers/models/roc_bert/modeling_roc_bert.py index 0b91af94bbaa..d7614e59c2d6 100644 --- a/src/transformers/models/roc_bert/modeling_roc_bert.py +++ b/src/transformers/models/roc_bert/modeling_roc_bert.py @@ -14,16 +14,17 @@ # limitations under the License. """PyTorch RoCBert model.""" -import math -from typing import Optional, Union +from typing import Callable, Optional, Union import torch from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -35,13 +36,18 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_roc_bert import RoCBertConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) @@ -104,7 +110,7 @@ def forward( else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape if position_ids is None: position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length] @@ -114,9 +120,10 @@ def forward( # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -174,19 +181,80 @@ def forward( return embedding_in +# Copied from transformers.models.bert.modeling_bert.eager_attention_forward +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + # Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->RoCBert class RoCBertSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -201,111 +269,157 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only bert can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, + ) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 +# Copied from transformers.models.bert.modeling_bert.BertCrossAttention with Bert->RoCBert +class RoCBertCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + self.config = config + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 - ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in RoCBertModel forward() function) - attention_scores = attention_scores + attention_mask + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) + self.is_causal = is_causal + self.layer_idx = layer_idx - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + def forward( + self, + hidden_states: torch.Tensor, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] + + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - context_layer = torch.matmul(attention_probs, value_layer) + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: + # reuse k,v, cross_attentions + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values + else: + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx + ) + # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls + past_key_value.is_updated[self.layer_idx] = True - return context_layer, attention_probs + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights # Copied from transformers.models.bert.modeling_bert.BertSelfOutput with Bert->RoCBert @@ -323,19 +437,16 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -ROC_BERT_SELF_ATTENTION_CLASSES = { - "eager": RoCBertSelfAttention, -} - - # Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->RoCBert,BERT->ROC_BERT class RoCBertAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = ROC_BERT_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = RoCBertCrossAttention if is_cross_attention else RoCBertSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = RoCBertSelfOutput(config) self.pruned_heads = set() @@ -358,29 +469,29 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, + encoder_hidden_states=encoder_hidden_states, attention_mask=attention_mask, head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights # Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert->RoCBert @@ -420,17 +531,22 @@ def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = RoCBertAttention(config, layer_idx=layer_idx) + self.attention = RoCBertAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = RoCBertAttention(config, position_embedding_type="absolute", layer_idx=layer_idx) + self.crossattention = RoCBertAttention( + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) self.intermediate = RoCBertIntermediate(config) self.output = RoCBertOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -438,20 +554,19 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -460,24 +575,21 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - outputs = (layer_output,) + outputs - - return outputs + return layer_output def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -487,11 +599,10 @@ def feed_forward_chunk(self, attention_output): # Copied from transformers.models.bert.modeling_bert.BertEncoder with Bert->RoCBert class RoCBertEncoder(nn.Module): - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config self.layer = nn.ModuleList([RoCBertLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) - self.gradient_checkpointing = False def forward( self, @@ -502,77 +613,26 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and self.config.is_decoder and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - - if use_cache and self.config.is_decoder and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, # as a positional argument for gradient checkpointing encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_values, cache_position=cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) @@ -647,9 +707,18 @@ def forward(self, sequence_output: torch.Tensor) -> torch.Tensor: @auto_docstring class RoCBertPreTrainedModel(PreTrainedModel): - config: RoCBertConfig + config_class = RoCBertConfig base_model_prefix = "roc_bert" supports_gradient_checkpointing = True + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": RoCBertLayer, + "attentions": RoCBertSelfAttention, + "cross_attentions": RoCBertCrossAttention, + } def _init_weights(self, module): """Initialize the weights""" @@ -682,7 +751,6 @@ def _init_weights(self, module): """ ) class RoCBertModel(RoCBertPreTrainedModel): - # Copied from transformers.models.clap.modeling_clap.ClapTextModel.__init__ with ClapText->RoCBert def __init__(self, config, add_pooling_layer=True): r""" add_pooling_layer (bool, *optional*, defaults to `True`): @@ -690,6 +758,7 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = RoCBertEmbeddings(config) self.encoder = RoCBertEncoder(config) @@ -728,6 +797,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -741,11 +811,10 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: r""" input_shape_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): @@ -763,70 +832,35 @@ def forward( [What are input IDs?](../glossary#input_pronunciation_ids) """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - if attention_mask is None: - attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) - - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape else: - encoder_extended_attention_mask = None + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] - # Prepare head mask if needed - # 1.0 in head_mask indicate we keep the head - # attention_probs has shape bsz x n_heads x N x N - # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] - # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] - head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) embedding_output = self.embeddings( input_ids=input_ids, @@ -837,33 +871,158 @@ def forward( inputs_embeds=inputs_embeds, past_key_values_length=past_key_values_length, ) + + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, + ) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) sequence_output = encoder_outputs[0] pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + # Copied from transformers.models.bert.modeling_bert.BertModel._create_attention_masks + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_full_mask + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_cross_attn_mask + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + @auto_docstring( custom_intro=""" @@ -891,6 +1050,7 @@ def set_output_embeddings(self, new_embeddings): self.cls.predictions.decoder = new_embeddings self.cls.predictions.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -912,10 +1072,7 @@ def forward( labels_input_pronunciation_ids: Optional[torch.Tensor] = None, labels_attention_mask: Optional[torch.Tensor] = None, labels_token_type_ids: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: r""" input_shape_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): @@ -996,8 +1153,6 @@ def forward( torch.Size([1, 11, 21128]) ``` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roc_bert( input_ids, input_shape_ids=input_shape_ids, @@ -1007,9 +1162,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output, pooled_output = outputs[:2] @@ -1033,7 +1187,6 @@ def forward( input_pronunciation_ids=labels_input_pronunciation_ids, attention_mask=labels_attention_mask, token_type_ids=labels_token_type_ids, - return_dict=return_dict, ) attack_output = self.roc_bert( attack_input_ids, @@ -1041,7 +1194,6 @@ def forward( input_pronunciation_ids=attack_input_pronunciation_ids, attention_mask=attack_attention_mask, token_type_ids=attack_token_type_ids, - return_dict=return_dict, ) labels_pooled_output = labels_output[1] @@ -1063,10 +1215,6 @@ def forward( else: loss = masked_lm_loss - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MaskedLMOutput( loss=loss, logits=prediction_scores, @@ -1104,6 +1252,7 @@ def set_output_embeddings(self, new_embeddings): self.cls.predictions.decoder = new_embeddings self.cls.predictions.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -1118,9 +1267,7 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: r""" input_shape_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): @@ -1163,8 +1310,6 @@ def forward( '.' ``` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roc_bert( input_ids, input_shape_ids=input_shape_ids, @@ -1176,9 +1321,8 @@ def forward( inputs_embeds=inputs_embeds, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1189,10 +1333,6 @@ def forward( loss_fct = CrossEntropyLoss() # -100 index = padding token masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -1227,6 +1367,14 @@ def prepare_inputs_for_generation( "attention_mask": attention_mask, } + @classmethod + def can_generate(cls) -> bool: + """ + Legacy correction: RoCBertForMaskedLM can't call `generate()` from `GenerationMixin`, even though it has a + `prepare_inputs_for_generation` method. + """ + return False + @auto_docstring( custom_intro=""" @@ -1258,6 +1406,7 @@ def set_output_embeddings(self, new_embeddings): self.cls.predictions.decoder = new_embeddings self.cls.predictions.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -1271,13 +1420,11 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[list[torch.Tensor]] = None, labels: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: r""" input_shape_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): @@ -1316,8 +1463,6 @@ def forward( >>> prediction_logits = outputs.logits ``` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roc_bert( input_ids, input_shape_ids=input_shape_ids, @@ -1331,9 +1476,9 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1348,10 +1493,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, @@ -1372,36 +1513,21 @@ def prepare_inputs_for_generation( ): # Overwritten -- `input_pronunciation_ids` - input_shape = input_ids.shape - - # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly - if attention_mask is None: - attention_mask = input_ids.new_ones(input_shape) + model_inputs = super().prepare_inputs_for_generation( + input_ids=input_ids, + past_key_values=past_key_values, + attention_mask=attention_mask, + **model_kwargs, + ) # cut decoder_input_ids if past_key_values is used if past_key_values is not None: - past_length = past_key_values.get_seq_length() - - # Some generation methods already pass only the last input ID - if input_ids.shape[1] > past_length: - remove_prefix_length = past_length - else: - # Default to old behavior: keep only final ID - remove_prefix_length = input_ids.shape[1] - 1 - - input_ids = input_ids[:, remove_prefix_length:] if input_shape_ids is not None: - input_shape_ids = input_shape_ids[:, -1:] + model_inputs["input_shape_ids"] = input_shape_ids[:, -1:] if input_pronunciation_ids is not None: - input_pronunciation_ids = input_pronunciation_ids[:, -1:] + model_inputs["input_pronunciation_ids"] = input_pronunciation_ids[:, -1:] - return { - "input_ids": input_ids, - "input_shape_ids": input_shape_ids, - "input_pronunciation_ids": input_pronunciation_ids, - "attention_mask": attention_mask, - "past_key_values": past_key_values, - } + return model_inputs @auto_docstring( @@ -1427,6 +1553,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1439,9 +1566,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: r""" input_shape_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): @@ -1463,8 +1588,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roc_bert( input_ids, input_shape_ids=input_shape_ids, @@ -1474,9 +1597,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1506,9 +1628,6 @@ def forward( elif self.config.problem_type == "multi_label_classification": loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output return SequenceClassifierOutput( loss=loss, @@ -1534,6 +1653,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1546,9 +1666,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1594,7 +1712,6 @@ def forward( num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1622,9 +1739,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1638,10 +1754,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1667,6 +1779,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1679,9 +1792,7 @@ def forward( head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, TokenClassifierOutput]: r""" input_shape_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): @@ -1701,8 +1812,6 @@ def forward( labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roc_bert( input_ids, input_shape_ids=input_shape_ids, @@ -1712,9 +1821,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1727,10 +1835,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1752,6 +1856,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1765,9 +1870,7 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, start_positions: Optional[torch.Tensor] = None, end_positions: Optional[torch.Tensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: r""" input_shape_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): @@ -1785,8 +1888,6 @@ def forward( [What are input IDs?](../glossary#input_pronunciation_ids) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roc_bert( input_ids, input_shape_ids=input_shape_ids, @@ -1796,9 +1897,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1825,10 +1925,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, diff --git a/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py b/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py index 5078d437e978..f9206cae9ae8 100755 --- a/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py +++ b/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py @@ -112,23 +112,6 @@ class SeamlessM4TGenerationOutput(ModelOutput): ############ UTILS ################ -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - # Copied from transformers.models.bart.modeling_bart.shift_tokens_right def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start_token_id: int): """ @@ -953,12 +936,14 @@ def forward( if input_ids is not None: bsz, seq_len = input_ids.size() # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length).to( - input_ids.device - ) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ).to(input_ids.device) else: bsz, seq_len = inputs_embeds.size()[:-1] - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length) + position_ids = self.create_position_ids_from_inputs_embeds( + inputs_embeds, past_key_values_length, self.padding_idx + ) # expand embeddings if needed max_pos = self.padding_idx + 1 + seq_len + past_key_values_length @@ -967,7 +952,8 @@ def forward( return self.weights.index_select(0, position_ids.view(-1)).view(bsz, seq_len, self.weights.shape[-1]).detach() - def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_length): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -980,10 +966,27 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_ sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape).contiguous() + past_key_values_length + @staticmethod + # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_input_ids + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + class SeamlessM4TAttention(nn.Module): """Multi-headed attention from 'Attention Is All You Need' paper""" diff --git a/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py b/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py index 7aa15cb84ddd..9d9cc95059a0 100644 --- a/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py +++ b/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py @@ -160,23 +160,6 @@ class SeamlessM4Tv2TextToUnitOutput(ModelOutput): ############ UTILS ################ -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - # Copied from transformers.models.bart.modeling_bart.shift_tokens_right def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start_token_id: int): """ @@ -775,7 +758,7 @@ def forward(self, input_ids: torch.Tensor): return super().forward(input_ids) * self.embed_scale -# Copied from transformers.models.m2m_100.modeling_m2m_100.M2M100SinusoidalPositionalEmbedding +# Copied from transformers.models.m2m_100.modeling_m2m_100.M2M100SinusoidalPositionalEmbedding with M2M100->SeamlessM4Tv2 class SeamlessM4Tv2SinusoidalPositionalEmbedding(nn.Module): """This module produces sinusoidal positional embeddings of any length.""" @@ -825,12 +808,14 @@ def forward( if input_ids is not None: bsz, seq_len = input_ids.size() # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length).to( - input_ids.device - ) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ).to(input_ids.device) else: bsz, seq_len = inputs_embeds.size()[:-1] - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length) + position_ids = self.create_position_ids_from_inputs_embeds( + inputs_embeds, past_key_values_length, self.padding_idx + ) # expand embeddings if needed max_pos = self.padding_idx + 1 + seq_len + past_key_values_length @@ -839,7 +824,8 @@ def forward( return self.weights.index_select(0, position_ids.view(-1)).view(bsz, seq_len, self.weights.shape[-1]).detach() - def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_length): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -852,10 +838,27 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds, past_key_values_ sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape).contiguous() + past_key_values_length + @staticmethod + # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_input_ids + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + class SeamlessM4Tv2Attention(nn.Module): """Multi-headed attention from 'Attention Is All You Need' paper""" diff --git a/src/transformers/models/speech_to_text/modeling_speech_to_text.py b/src/transformers/models/speech_to_text/modeling_speech_to_text.py index 8cfc99266041..bb2a8649ce9b 100755 --- a/src/transformers/models/speech_to_text/modeling_speech_to_text.py +++ b/src/transformers/models/speech_to_text/modeling_speech_to_text.py @@ -713,7 +713,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/tapas/modeling_tapas.py b/src/transformers/models/tapas/modeling_tapas.py index 2987e7ec7467..cedd1fabbb3f 100644 --- a/src/transformers/models/tapas/modeling_tapas.py +++ b/src/transformers/models/tapas/modeling_tapas.py @@ -292,7 +292,7 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - # Copied from transformers.models.bert.modeling_bert.BertAttention.forward + # Copied from transformers.models.rembert.modeling_rembert.RemBertAttention.forward def forward( self, hidden_states: torch.Tensor, @@ -363,7 +363,7 @@ def __init__(self, config, layer_idx=None): self.intermediate = TapasIntermediate(config) self.output = TapasOutput(config) - # Copied from transformers.models.bert.modeling_bert.BertLayer.forward + # Copied from transformers.models.rembert.modeling_rembert.RemBertLayer.forward def forward( self, hidden_states: torch.Tensor, diff --git a/src/transformers/models/time_series_transformer/modeling_time_series_transformer.py b/src/transformers/models/time_series_transformer/modeling_time_series_transformer.py index 9810eae30d5e..462656986711 100644 --- a/src/transformers/models/time_series_transformer/modeling_time_series_transformer.py +++ b/src/transformers/models/time_series_transformer/modeling_time_series_transformer.py @@ -660,7 +660,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/unispeech/modeling_unispeech.py b/src/transformers/models/unispeech/modeling_unispeech.py index 233653a36b39..ab0d77b5623e 100755 --- a/src/transformers/models/unispeech/modeling_unispeech.py +++ b/src/transformers/models/unispeech/modeling_unispeech.py @@ -522,7 +522,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -690,7 +690,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/unispeech_sat/modeling_unispeech_sat.py b/src/transformers/models/unispeech_sat/modeling_unispeech_sat.py index c1281f7955af..23fcd7c3227e 100755 --- a/src/transformers/models/unispeech_sat/modeling_unispeech_sat.py +++ b/src/transformers/models/unispeech_sat/modeling_unispeech_sat.py @@ -527,7 +527,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -695,7 +695,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/wav2vec2/modeling_wav2vec2.py b/src/transformers/models/wav2vec2/modeling_wav2vec2.py index d8c58a333e07..00f31596e688 100755 --- a/src/transformers/models/wav2vec2/modeling_wav2vec2.py +++ b/src/transformers/models/wav2vec2/modeling_wav2vec2.py @@ -760,7 +760,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to @@ -858,7 +858,7 @@ def _update_full_mask( inputs_embeds: torch.Tensor, ): if attention_mask is not None: - if self.config._attn_implementation == "flash_attention_2": + if "flash" in self.config._attn_implementation: attention_mask = attention_mask if 0 in attention_mask else None elif self.config._attn_implementation == "sdpa": # output_attentions=True & head_mask can not be supported when using SDPA, fall back to diff --git a/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py b/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py index 4e0fab16b429..60b14e35f781 100644 --- a/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py +++ b/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py @@ -1,3 +1,9 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/xlm_roberta/modular_xlm_roberta.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_xlm_roberta.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 # coding=utf-8 # Copyright 2019 Facebook AI Research and the HuggingFace Inc. team. # Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. @@ -13,19 +19,18 @@ # 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. -"""PyTorch XLM-RoBERTa model.""" -import math -from typing import Optional, Union +from typing import Callable, Optional, Union import torch -from torch import nn +import torch.nn as nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN, gelu -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin -from ...modeling_attn_mask_utils import _prepare_4d_attention_mask_for_sdpa, _prepare_4d_causal_attention_mask_for_sdpa +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -37,117 +42,93 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_xlm_roberta import XLMRobertaConfig -logger = logging.get_logger(__name__) - - -# Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->XLMRoberta -class XLMRobertaEmbeddings(nn.Module): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask - # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ - def __init__(self, config): - super().__init__() - self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) - self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) - self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - self.dropout = nn.Dropout(config.hidden_dropout_prob) - # position_ids (1, len position emb) is contiguous in memory and exported when serialized - self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") - self.register_buffer( - "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False - ) - self.register_buffer( - "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False - ) +logger = logging.get_logger(__name__) - # End copy - self.padding_idx = config.pad_token_id - self.position_embeddings = nn.Embedding( - config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx - ) - def forward( - self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): - if position_ids is None: - if input_ids is not None: - # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) - else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) - - if input_ids is not None: - input_shape = input_ids.size() +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) else: - input_shape = inputs_embeds.size()[:-1] + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r - seq_length = input_shape[1] + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility - # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs - # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves - # issue #5664 - if token_type_ids is None: - if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key - if inputs_embeds is None: - inputs_embeds = self.word_embeddings(input_ids) - token_type_embeddings = self.token_type_embeddings(token_type_ids) + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling - embeddings = inputs_embeds + token_type_embeddings - if self.position_embedding_type == "absolute": - position_embeddings = self.position_embeddings(position_ids) - embeddings += position_embeddings - embeddings = self.LayerNorm(embeddings) - embeddings = self.dropout(embeddings) - return embeddings + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask - def create_position_ids_from_inputs_embeds(self, inputs_embeds): - """ - We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) - Args: - inputs_embeds: torch.Tensor + if head_mask is not None: + attn_weights = attn_weights * head_mask - Returns: torch.Tensor - """ - input_shape = inputs_embeds.size()[:-1] - sequence_length = input_shape[1] + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() - position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device - ) - return position_ids.unsqueeze(0).expand(input_shape) + return attn_output, attn_weights -# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfAttention with Roberta->XLMRoberta class XLMRobertaSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -162,219 +143,158 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 - ) - - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only xlm_roberta can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True - - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in XLMRobertaModel forward() function) - attention_scores = attention_scores + attention_mask + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) - - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - context_layer = torch.matmul(attention_probs, value_layer) +class XLMRobertaCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + self.config = config - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 - return context_layer, attention_probs + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) -# Copied from transformers.models.roberta.modeling_roberta.RobertaSdpaSelfAttention with Roberta->XLMRoberta -class XLMRobertaSdpaSelfAttention(XLMRobertaSelfAttention): - def __init__(self, config, position_embedding_type=None, layer_idx=None): - super().__init__(config, position_embedding_type=position_embedding_type, layer_idx=layer_idx) - self.dropout_prob = config.attention_probs_dropout_prob + self.is_causal = is_causal + self.layer_idx = layer_idx - # Adapted from XLMRobertaSelfAttention - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, - attention_mask: Optional[torch.Tensor] = None, - head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, - cache_position: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - if self.position_embedding_type != "absolute" or output_attentions or head_mask is not None: - # TODO: Improve this warning with e.g. `model.config._attn_implementation = "manual"` once implemented. - logger.warning_once( - "XLMRobertaSdpaSelfAttention is used but `torch.nn.functional.scaled_dot_product_attention` does not support " - "non-absolute `position_embedding_type` or `output_attentions=True` or `head_mask`. Falling back to " - "the manual attention implementation, but specifying the manual implementation will be required from " - "Transformers version v5.0.0 onwards. This warning can be removed using the argument " - '`attn_implementation="eager"` when loading the model.' - ) - return super().forward( - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states, - past_key_values, - output_attentions, - cache_position, - ) + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - bsz, tgt_len, _ = hidden_states.size() + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - query_layer = ( - self.query(hidden_states).view(bsz, -1, self.num_attention_heads, self.attention_head_size).transpose(1, 2) - ) + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - is_updated = False - is_cross_attention = encoder_hidden_states is not None - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_states from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values else: - key_layer = ( - self.key(current_states) - .view(bsz, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) - value_layer = ( - self.value(current_states) - .view(bsz, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx ) # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + past_key_value.is_updated[self.layer_idx] = True - # We dispatch to SDPA's Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment - # in SDPA to support both torch.compile's dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling. - # The tgt_len > 1 is necessary to match with AttentionMaskConverter.to_causal_4d that does not create - # a causal mask in case tgt_len == 1. - is_causal = self.is_decoder and not is_cross_attention and attention_mask is None and tgt_len > 1 + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - attn_output = torch.nn.functional.scaled_dot_product_attention( + attn_output, attn_weights = attention_interface( + self, query_layer, key_layer, value_layer, - attn_mask=attention_mask, - dropout_p=self.dropout_prob if self.training else 0.0, - is_causal=is_causal, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights - attn_output = attn_output.transpose(1, 2) - attn_output = attn_output.reshape(bsz, tgt_len, self.all_head_size) - return attn_output, None - - -# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfOutput with Roberta->XLMRoberta class XLMRobertaSelfOutput(nn.Module): def __init__(self, config): super().__init__() @@ -389,20 +309,15 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -XLM_ROBERTA_SELF_ATTENTION_CLASSES = { - "eager": XLMRobertaSelfAttention, - "sdpa": XLMRobertaSdpaSelfAttention, -} - - -# Copied from transformers.models.roberta.modeling_roberta.RobertaAttention with Roberta->XLMRoberta,ROBERTA->XLM_ROBERTA class XLMRobertaAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = XLM_ROBERTA_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = XLMRobertaCrossAttention if is_cross_attention else XLMRobertaSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = XLMRobertaSelfOutput(config) self.pruned_heads = set() @@ -425,32 +340,31 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, + encoder_hidden_states=encoder_hidden_states, attention_mask=attention_mask, head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights -# Copied from transformers.models.roberta.modeling_roberta.RobertaIntermediate with Roberta->XLMRoberta class XLMRobertaIntermediate(nn.Module): def __init__(self, config): super().__init__() @@ -466,7 +380,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return hidden_states -# Copied from transformers.models.roberta.modeling_roberta.RobertaOutput with Roberta->XLMRoberta class XLMRobertaOutput(nn.Module): def __init__(self, config): super().__init__() @@ -481,23 +394,27 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to return hidden_states -# Copied from transformers.models.roberta.modeling_roberta.RobertaLayer with Roberta->XLMRoberta class XLMRobertaLayer(GradientCheckpointingLayer): def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = XLMRobertaAttention(config, layer_idx=layer_idx) + self.attention = XLMRobertaAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = XLMRobertaAttention(config, position_embedding_type="absolute", layer_idx=layer_idx) + self.crossattention = XLMRobertaAttention( + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) self.intermediate = XLMRobertaIntermediate(config) self.output = XLMRobertaOutput(config) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -505,20 +422,19 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -527,24 +443,21 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - outputs = (layer_output,) + outputs - - return outputs + return layer_output def feed_forward_chunk(self, attention_output): intermediate_output = self.intermediate(attention_output) @@ -552,13 +465,181 @@ def feed_forward_chunk(self, attention_output): return layer_output -# Copied from transformers.models.roberta.modeling_roberta.RobertaEncoder with Roberta->XLMRoberta +class XLMRobertaLMHead(nn.Module): + """XLMRoberta Head for masked language modeling.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + self.decoder = nn.Linear(config.hidden_size, config.vocab_size) + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + self.decoder.bias = self.bias + + def forward(self, features, **kwargs): + x = self.dense(features) + x = gelu(x) + x = self.layer_norm(x) + + # project back to size of vocabulary with bias + x = self.decoder(x) + + return x + + def _tie_weights(self): + # To tie those two weights if they get disconnected (on TPU or when the bias is resized) + # For accelerate compatibility and to not break backward compatibility + if self.decoder.bias.device.type == "meta": + self.decoder.bias = self.bias + else: + self.bias = self.decoder.bias + + +@auto_docstring +class XLMRobertaPreTrainedModel(PreTrainedModel): + config_class = XLMRobertaConfig + base_model_prefix = "roberta" + supports_gradient_checkpointing = True + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": XLMRobertaLayer, + "attentions": XLMRobertaSelfAttention, + "cross_attentions": XLMRobertaCrossAttention, + } + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, XLMRobertaLMHead): + module.bias.data.zero_() + + +class XLMRobertaEmbeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) + + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + self.register_buffer( + "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False + ) + self.register_buffer( + "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False + ) + + self.padding_idx = config.pad_token_id + self.position_embeddings = nn.Embedding( + config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx + ) + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: + if position_ids is None: + if input_ids is not None: + # Create the position ids from the input token ids. Any padded tokens remain padded. + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) + else: + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) + + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + batch_size, seq_length = input_shape + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): + """ + We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. + + Args: + inputs_embeds: torch.Tensor + + Returns: torch.Tensor + """ + input_shape = inputs_embeds.size()[:-1] + sequence_length = input_shape[1] + + position_ids = torch.arange( + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + ) + return position_ids.unsqueeze(0).expand(input_shape) + + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + + class XLMRobertaEncoder(nn.Module): - def __init__(self, config, layer_idx=None): + def __init__(self, config): super().__init__() self.config = config self.layer = nn.ModuleList([XLMRobertaLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) - self.gradient_checkpointing = False def forward( self, @@ -569,81 +650,29 @@ def forward( encoder_attention_mask: Optional[torch.FloatTensor] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and self.config.is_decoder and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - - if use_cache and self.config.is_decoder and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, # as a positional argument for gradient checkpointing encoder_attention_mask=encoder_attention_mask, - past_key_values=past_key_values, - output_attentions=output_attentions, + past_key_value=past_key_values, cache_position=cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) -# Copied from transformers.models.roberta.modeling_roberta.RobertaPooler with Roberta->XLMRoberta class XLMRobertaPooler(nn.Module): def __init__(self, config): super().__init__() @@ -660,34 +689,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: @auto_docstring -# Copied from transformers.models.roberta.modeling_roberta.RobertaPreTrainedModel with Roberta->XLMRoberta -class XLMRobertaPreTrainedModel(PreTrainedModel): - config: XLMRobertaConfig - base_model_prefix = "roberta" - supports_gradient_checkpointing = True - _no_split_modules = ["XLMRobertaEmbeddings", "XLMRobertaSelfAttention", "XLMRobertaSdpaSelfAttention"] - _supports_sdpa = True - - # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights with BertLMPredictionHead->XLMRobertaLMHead - def _init_weights(self, module): - """Initialize the weights""" - if isinstance(module, nn.Linear): - module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) - if module.bias is not None: - module.bias.data.zero_() - elif isinstance(module, nn.Embedding): - module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) - if module.padding_idx is not None: - module.weight.data[module.padding_idx].zero_() - elif isinstance(module, nn.LayerNorm): - module.bias.data.zero_() - module.weight.data.fill_(1.0) - elif isinstance(module, XLMRobertaLMHead): - module.bias.data.zero_() - - -@auto_docstring -# Copied from transformers.models.roberta.modeling_roberta.RobertaModel with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA class XLMRobertaModel(XLMRobertaPreTrainedModel): _no_split_modules = ["XLMRobertaEmbeddings", "XLMRobertaLayer"] @@ -698,13 +699,13 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = XLMRobertaEmbeddings(config) self.encoder = XLMRobertaEncoder(config) self.pooler = XLMRobertaPooler(config) if add_pooling_layer else None - self.attn_implementation = config._attn_implementation self.position_embedding_type = config.position_embedding_type # Initialize weights and apply final processing @@ -724,6 +725,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -735,52 +737,40 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape + else: + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] + + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) embedding_output = self.embeddings( input_ids=input_ids, @@ -790,55 +780,16 @@ def forward( past_key_values_length=past_key_values_length, ) - if attention_mask is None: - attention_mask = torch.ones((batch_size, seq_length + past_key_values_length), device=device) - - use_sdpa_attention_masks = ( - self.attn_implementation == "sdpa" - and self.position_embedding_type == "absolute" - and head_mask is None - and not output_attentions + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, ) - # Expand the attention mask - if use_sdpa_attention_masks and attention_mask.dim() == 2: - # Expand the attention mask for SDPA. - # [bsz, seq_len] -> [bsz, 1, seq_len, seq_len] - if self.config.is_decoder: - extended_attention_mask = _prepare_4d_causal_attention_mask_for_sdpa( - attention_mask, - input_shape, - embedding_output, - past_key_values_length, - ) - else: - extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - - if use_sdpa_attention_masks and encoder_attention_mask.dim() == 2: - # Expand the attention mask for SDPA. - # [bsz, seq_len] -> [bsz, 1, seq_len, seq_len] - encoder_extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - encoder_attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) - else: - encoder_extended_attention_mask = None - # Prepare head mask if needed # 1.0 in head_mask indicate we keep the head # attention_probs has shape bsz x n_heads x N x N @@ -848,39 +799,141 @@ def forward( encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) - sequence_output = encoder_outputs[0] + sequence_output = encoder_outputs.last_hidden_state pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + @auto_docstring( custom_intro=""" XLM-RoBERTa Model with a `language modeling` head on top for CLM fine-tuning. """ ) -# Copied from transformers.models.roberta.modeling_roberta.RobertaForCausalLM with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA class XLMRobertaForCausalLM(XLMRobertaPreTrainedModel, GenerationMixin): _tied_weights_keys = ["lm_head.decoder.weight", "lm_head.decoder.bias"] @@ -889,9 +942,9 @@ def __init__(self, config): if not config.is_decoder: logger.warning("If you want to use `XLMRobertaLMHeadModel` as a standalone, add `is_decoder=True.`") + self.lm_head = XLMRobertaLMHead(config) self.roberta = XLMRobertaModel(config, add_pooling_layer=False) - self.lm_head = XLMRobertaLMHead(config) # Initialize weights and apply final processing self.post_init() @@ -902,6 +955,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -914,12 +968,9 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -952,7 +1003,6 @@ def forward( >>> prediction_logits = outputs.logits ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -967,9 +1017,8 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -986,10 +1035,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, @@ -1001,7 +1046,6 @@ def forward( @auto_docstring -# Copied from transformers.models.roberta.modeling_roberta.RobertaForMaskedLM with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA class XLMRobertaForMaskedLM(XLMRobertaPreTrainedModel): _tied_weights_keys = ["lm_head.decoder.weight", "lm_head.decoder.bias"] @@ -1013,9 +1057,9 @@ def __init__(self, config): "If you want to use `XLMRobertaForMaskedLM` make sure `config.is_decoder=False` for " "bi-directional self-attention." ) + self.lm_head = XLMRobertaLMHead(config) self.roberta = XLMRobertaModel(config, add_pooling_layer=False) - self.lm_head = XLMRobertaLMHead(config) # Initialize weights and apply final processing self.post_init() @@ -1026,6 +1070,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -1038,9 +1083,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1057,8 +1100,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1068,9 +1109,8 @@ def forward( inputs_embeds=inputs_embeds, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] prediction_scores = self.lm_head(sequence_output) @@ -1082,10 +1122,6 @@ def forward( loss_fct = CrossEntropyLoss() masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -1094,37 +1130,27 @@ def forward( ) -# Copied from transformers.models.roberta.modeling_roberta.RobertaLMHead -class XLMRobertaLMHead(nn.Module): - """Roberta Head for masked language modeling.""" +class XLMRobertaClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" def __init__(self, config): super().__init__() self.dense = nn.Linear(config.hidden_size, config.hidden_size) - self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - - self.decoder = nn.Linear(config.hidden_size, config.vocab_size) - self.bias = nn.Parameter(torch.zeros(config.vocab_size)) - self.decoder.bias = self.bias + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.out_proj = nn.Linear(config.hidden_size, config.num_labels) def forward(self, features, **kwargs): - x = self.dense(features) - x = gelu(x) - x = self.layer_norm(x) - - # project back to size of vocabulary with bias - x = self.decoder(x) - + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x) + x = self.dense(x) + x = torch.tanh(x) + x = self.dropout(x) + x = self.out_proj(x) return x - def _tie_weights(self): - # To tie those two weights if they get disconnected (on TPU or when the bias is resized) - # For accelerate compatibility and to not break backward compatibility - if self.decoder.bias.device.type == "meta": - self.decoder.bias = self.bias - else: - self.bias = self.decoder.bias - @auto_docstring( custom_intro=""" @@ -1132,19 +1158,19 @@ def _tie_weights(self): pooled output) e.g. for GLUE tasks. """ ) -# Copied from transformers.models.roberta.modeling_roberta.RobertaForSequenceClassification with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA class XLMRobertaForSequenceClassification(XLMRobertaPreTrainedModel): def __init__(self, config): super().__init__(config) self.num_labels = config.num_labels self.config = config + self.classifier = XLMRobertaClassificationHead(config) self.roberta = XLMRobertaModel(config, add_pooling_layer=False) - self.classifier = XLMRobertaClassificationHead(config) # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1155,9 +1181,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1174,8 +1198,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1183,9 +1205,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] logits = self.classifier(sequence_output) @@ -1215,10 +1236,6 @@ def forward( loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return SequenceClassifierOutput( loss=loss, logits=logits, @@ -1228,18 +1245,18 @@ def forward( @auto_docstring -# Copied from transformers.models.roberta.modeling_roberta.RobertaForMultipleChoice with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA class XLMRobertaForMultipleChoice(XLMRobertaPreTrainedModel): def __init__(self, config): super().__init__(config) - - self.roberta = XLMRobertaModel(config) self.dropout = nn.Dropout(config.hidden_dropout_prob) self.classifier = nn.Linear(config.hidden_size, 1) + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1250,9 +1267,7 @@ def forward( position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1285,7 +1300,6 @@ def forward( is useful if you want more control over how to convert `input_ids` indices into associated vectors than the model's internal embedding lookup matrix. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1305,9 +1319,8 @@ def forward( attention_mask=flat_attention_mask, head_mask=head_mask, inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1322,10 +1335,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1335,22 +1344,22 @@ def forward( @auto_docstring -# Copied from transformers.models.roberta.modeling_roberta.RobertaForTokenClassification with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA class XLMRobertaForTokenClassification(XLMRobertaPreTrainedModel): def __init__(self, config): super().__init__(config) self.num_labels = config.num_labels - - self.roberta = XLMRobertaModel(config, add_pooling_layer=False) classifier_dropout = ( config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob ) self.dropout = nn.Dropout(classifier_dropout) self.classifier = nn.Linear(config.hidden_size, config.num_labels) + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1361,9 +1370,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1378,8 +1385,6 @@ def forward( labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1387,9 +1392,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1404,10 +1408,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1416,42 +1416,19 @@ def forward( ) -# Copied from transformers.models.roberta.modeling_roberta.RobertaClassificationHead with Roberta->XLMRoberta -class XLMRobertaClassificationHead(nn.Module): - """Head for sentence-level classification tasks.""" - - def __init__(self, config): - super().__init__() - self.dense = nn.Linear(config.hidden_size, config.hidden_size) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(classifier_dropout) - self.out_proj = nn.Linear(config.hidden_size, config.num_labels) - - def forward(self, features, **kwargs): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x) - x = self.dense(x) - x = torch.tanh(x) - x = self.dropout(x) - x = self.out_proj(x) - return x - - @auto_docstring -# Copied from transformers.models.roberta.modeling_roberta.RobertaForQuestionAnswering with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA class XLMRobertaForQuestionAnswering(XLMRobertaPreTrainedModel): def __init__(self, config): super().__init__(config) self.num_labels = config.num_labels + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) self.roberta = XLMRobertaModel(config, add_pooling_layer=False) - self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1463,9 +1440,7 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, start_positions: Optional[torch.LongTensor] = None, end_positions: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: r""" token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1478,8 +1453,6 @@ def forward( [What are token type IDs?](../glossary#token-type-ids) """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1487,9 +1460,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1516,10 +1488,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, @@ -1529,23 +1497,6 @@ def forward( ) -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - __all__ = [ "XLMRobertaForCausalLM", "XLMRobertaForMaskedLM", diff --git a/src/transformers/models/xlm_roberta/modular_xlm_roberta.py b/src/transformers/models/xlm_roberta/modular_xlm_roberta.py new file mode 100644 index 000000000000..510f522c93b2 --- /dev/null +++ b/src/transformers/models/xlm_roberta/modular_xlm_roberta.py @@ -0,0 +1,559 @@ +# coding=utf-8 +# Copyright 2019 Facebook AI Research and the HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# 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. +"""PyTorch XLM-RoBERTa model.""" + +from typing import Optional, Union + +import torch +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...modeling_outputs import ( + CausalLMOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring +from ...utils.generic import can_return_tuple +from ..roberta.modeling_roberta import ( + RobertaForCausalLM, + RobertaForMaskedLM, + RobertaForMultipleChoice, + RobertaForQuestionAnswering, + RobertaForSequenceClassification, + RobertaForTokenClassification, + RobertaModel, + RobertaPreTrainedModel, +) + + +@auto_docstring +class XLMRobertaPreTrainedModel(RobertaPreTrainedModel): + base_model_prefix = "roberta" + + +@auto_docstring +class XLMRobertaModel(RobertaModel): + pass + + +@auto_docstring( + custom_intro=""" + XLM-RoBERTa Model with a `language modeling` head on top for CLM fine-tuning. + """ +) +class XLMRobertaForCausalLM(RobertaForCausalLM): + def __init__(self, config): + super().__init__(config) + del self.xlm_roberta + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + + Example: + + ```python + >>> from transformers import AutoTokenizer, XLMRobertaForCausalLM, AutoConfig + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("FacebookAI/roberta-base") + >>> config = AutoConfig.from_pretrained("FacebookAI/roberta-base") + >>> config.is_decoder = True + >>> model = XLMRobertaForCausalLM.from_pretrained("FacebookAI/roberta-base", config=config) + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> prediction_logits = outputs.logits + ```""" + if labels is not None: + use_cache = False + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + lm_loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(prediction_scores.device) + lm_loss = self.loss_function( + prediction_scores, + labels, + vocab_size=self.config.vocab_size, + **kwargs, + ) + + return CausalLMOutputWithCrossAttentions( + loss=lm_loss, + logits=prediction_scores, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +@auto_docstring +class XLMRobertaForMaskedLM(RobertaForMaskedLM): + def __init__(self, config): + super().__init__(config) + del self.xlm_roberta + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + return_dict=True, + **kwargs, + ) + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + masked_lm_loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(prediction_scores.device) + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring( + custom_intro=""" + XLM-RoBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """ +) +class XLMRobertaForSequenceClassification(RobertaForSequenceClassification): + def __init__(self, config): + super().__init__(config) + del self.xlm_roberta + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + sequence_output = outputs[0] + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(logits.device) + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class XLMRobertaForMultipleChoice(RobertaForMultipleChoice): + def __init__(self, config): + super().__init__(config) + del self.xlm_roberta + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: + r""" + input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + """ + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + flat_inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.roberta( + flat_input_ids, + position_ids=flat_position_ids, + token_type_ids=flat_token_type_ids, + attention_mask=flat_attention_mask, + head_mask=head_mask, + inputs_embeds=flat_inputs_embeds, + return_dict=True, + **kwargs, + ) + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(reshaped_logits.device) + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class XLMRobertaForTokenClassification(RobertaForTokenClassification): + def __init__(self, config): + super().__init__(config) + del self.xlm_roberta + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(logits.device) + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class XLMRobertaForQuestionAnswering(RobertaForQuestionAnswering): + def __init__(self, config): + super().__init__(config) + del self.xlm_roberta + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + start_positions: Optional[torch.LongTensor] = None, + end_positions: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: + r""" + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value + >= 2. All the value in this tensor should be always < type_vocab_size. + + [What are token type IDs?](../glossary#token-type-ids) + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +__all__ = [ + "XLMRobertaForCausalLM", + "XLMRobertaForMaskedLM", + "XLMRobertaForMultipleChoice", + "XLMRobertaForQuestionAnswering", + "XLMRobertaForSequenceClassification", + "XLMRobertaForTokenClassification", + "XLMRobertaModel", + "XLMRobertaPreTrainedModel", +] diff --git a/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py b/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py index c07f9e9bf760..522d63aad884 100644 --- a/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py +++ b/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py @@ -1,3 +1,15 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/xlm_roberta_xl/modular_xlm_roberta_xl.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_xlm_roberta_xl.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. # coding=utf-8 # Copyright 2022 The HuggingFace Inc. team. # @@ -12,19 +24,18 @@ # 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. -"""PyTorch XLM RoBERTa xl,xxl model.""" -import math -from typing import Optional, Union +from typing import Callable, Optional, Union import torch -from torch import nn +import torch.nn as nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN, gelu -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin -from ...modeling_attn_mask_utils import _prepare_4d_attention_mask_for_sdpa, _prepare_4d_causal_attention_mask_for_sdpa +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -36,27 +47,28 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_xlm_roberta_xl import XLMRobertaXLConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) class XLMRobertaXLEmbeddings(nn.Module): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ + """Construct the embeddings from word, position and token_type embeddings.""" def __init__(self, config): super().__init__() self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) - self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) - self.dropout = nn.Dropout(config.hidden_dropout_prob) # position_ids (1, len position emb) is contiguous in memory and exported when serialized self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") @@ -67,37 +79,44 @@ def __init__(self, config): "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False ) - # End copy self.padding_idx = config.pad_token_id self.position_embeddings = nn.Embedding( config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx ) def forward( - self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: if position_ids is None: if input_ids is not None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) if input_ids is not None: input_shape = input_ids.size() else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -113,8 +132,8 @@ def forward( embeddings = self.dropout(embeddings) return embeddings - # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_inputs_embeds - def create_position_ids_from_inputs_embeds(self, inputs_embeds): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -127,24 +146,99 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds): sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape) + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + -# Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->XLMRobertaXL class XLMRobertaXLSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -159,216 +253,156 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 - ) - - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only xlm_roberta_xl can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) - - if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in XLMRobertaXLModel forward() function) - attention_scores = attention_scores + attention_mask - - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask - context_layer = torch.matmul(attention_probs, value_layer) +class XLMRobertaXLCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + self.config = config - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 - return context_layer, attention_probs + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) -# Copied from transformers.models.bert.modeling_bert.BertSdpaSelfAttention with Bert->XLMRobertaXL -class XLMRobertaXLSdpaSelfAttention(XLMRobertaXLSelfAttention): - def __init__(self, config, position_embedding_type=None, layer_idx=None): - super().__init__(config, position_embedding_type=position_embedding_type, layer_idx=layer_idx) - self.dropout_prob = config.attention_probs_dropout_prob + self.is_causal = is_causal + self.layer_idx = layer_idx - # Adapted from XLMRobertaXLSelfAttention - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, - attention_mask: Optional[torch.Tensor] = None, - head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, - cache_position: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - if self.position_embedding_type != "absolute" or output_attentions or head_mask is not None: - # TODO: Improve this warning with e.g. `model.config._attn_implementation = "manual"` once implemented. - logger.warning_once( - "XLMRobertaXLSdpaSelfAttention is used but `torch.nn.functional.scaled_dot_product_attention` does not support " - "non-absolute `position_embedding_type` or `output_attentions=True` or `head_mask`. Falling back to " - "the manual attention implementation, but specifying the manual implementation will be required from " - "Transformers version v5.0.0 onwards. This warning can be removed using the argument " - '`attn_implementation="eager"` when loading the model.' - ) - return super().forward( - hidden_states, - attention_mask, - head_mask, - encoder_hidden_states, - past_key_values, - output_attentions, - cache_position, - ) + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - bsz, tgt_len, _ = hidden_states.size() + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - query_layer = ( - self.query(hidden_states).view(bsz, -1, self.num_attention_heads, self.attention_head_size).transpose(1, 2) - ) - - is_updated = False - is_cross_attention = encoder_hidden_states is not None - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_states from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values else: - key_layer = ( - self.key(current_states) - .view(bsz, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) - value_layer = ( - self.value(current_states) - .view(bsz, -1, self.num_attention_heads, self.attention_head_size) - .transpose(1, 2) - ) + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx ) # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + past_key_value.is_updated[self.layer_idx] = True - # We dispatch to SDPA's Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment - # in SDPA to support both torch.compile's dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling. - # The tgt_len > 1 is necessary to match with AttentionMaskConverter.to_causal_4d that does not create - # a causal mask in case tgt_len == 1. - is_causal = self.is_decoder and not is_cross_attention and attention_mask is None and tgt_len > 1 + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - attn_output = torch.nn.functional.scaled_dot_product_attention( + attn_output, attn_weights = attention_interface( + self, query_layer, key_layer, value_layer, - attn_mask=attention_mask, - dropout_p=self.dropout_prob if self.training else 0.0, - is_causal=is_causal, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) - - attn_output = attn_output.transpose(1, 2) - attn_output = attn_output.reshape(bsz, tgt_len, self.all_head_size) - - return attn_output, None + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights class XLMRobertaXLSelfOutput(nn.Module): @@ -377,31 +411,28 @@ def __init__(self, config): self.dense = nn.Linear(config.hidden_size, config.hidden_size) self.dropout = nn.Dropout(config.hidden_dropout_prob) - def forward(self, hidden_states, input_tensor): + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: hidden_states = self.dense(hidden_states) hidden_states = self.dropout(hidden_states) hidden_states = hidden_states + input_tensor return hidden_states -XLMROBERTAXL_SELF_ATTENTION_CLASSES = { - "eager": XLMRobertaXLSelfAttention, - "sdpa": XLMRobertaXLSdpaSelfAttention, -} - - class XLMRobertaXLAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self_attn_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - self.self = XLMROBERTAXL_SELF_ATTENTION_CLASSES[config._attn_implementation]( - config, - position_embedding_type=position_embedding_type, - layer_idx=layer_idx, + self.is_cross_attention = is_cross_attention + attention_class = XLMRobertaXLCrossAttention if is_cross_attention else XLMRobertaXLSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx ) self.output = XLMRobertaXLSelfOutput(config) self.pruned_heads = set() + self.self_attn_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + def prune_heads(self, heads): if len(heads) == 0: return @@ -420,33 +451,43 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, - hidden_states, - attention_mask=None, - head_mask=None, - encoder_hidden_states=None, - past_key_values=None, - output_attentions=False, - cache_position=None, - ): + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[tuple[tuple[torch.FloatTensor]]] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: intermediate = self.self_attn_layer_norm(hidden_states) - self_outputs = self.self( + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( intermediate, - attention_mask, - head_mask, - encoder_hidden_states, - past_key_values, - output_attentions, - cache_position, + encoder_hidden_states=encoder_hidden_states, + attention_mask=attention_mask, + head_mask=head_mask, + past_key_value=past_key_value, + cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], hidden_states) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights + + +class XLMRobertaXLOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + + def forward(self, hidden_states, input_tensor): + hidden_states = self.dense(hidden_states) + hidden_states = hidden_states + input_tensor + return hidden_states -# Copied from transformers.models.bert.modeling_bert.BertIntermediate class XLMRobertaXLIntermediate(nn.Module): def __init__(self, config): super().__init__() @@ -462,57 +503,48 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return hidden_states -class XLMRobertaXLOutput(nn.Module): - def __init__(self, config): - super().__init__() - self.dense = nn.Linear(config.intermediate_size, config.hidden_size) - - def forward(self, hidden_states, input_tensor): - hidden_states = self.dense(hidden_states) - hidden_states = hidden_states + input_tensor - return hidden_states - - class XLMRobertaXLLayer(GradientCheckpointingLayer): def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = XLMRobertaXLAttention(config, layer_idx=layer_idx) + self.attention = XLMRobertaXLAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") self.crossattention = XLMRobertaXLAttention( - config, position_embedding_type="absolute", layer_idx=layer_idx + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, ) self.intermediate = XLMRobertaXLIntermediate(config) self.output = XLMRobertaXLOutput(config) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, - hidden_states, - attention_mask=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_values=None, - output_attentions=False, - cache_position=None, - ): - self_attention_outputs = self.attention( + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Cache] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -521,22 +553,21 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( - attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + cross_attention_output, _ = self.crossattention( + self_attention_output, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output layer_output = apply_chunking_to_forward( self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output ) - return (layer_output,) + outputs + return layer_output def feed_forward_chunk(self, attention_output): intermediate_output = self.LayerNorm(attention_output) @@ -551,116 +582,57 @@ def __init__(self, config): self.config = config self.layer = nn.ModuleList([XLMRobertaXLLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - self.gradient_checkpointing = False def forward( self, - hidden_states, - attention_mask=None, - head_mask=None, - encoder_hidden_states=None, - encoder_attention_mask=None, - past_key_values=None, - use_cache=None, - output_attentions=False, - output_hidden_states=False, - return_dict=True, - cache_position=None, - ): - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - if use_cache and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, attention_mask, layer_head_mask, - encoder_hidden_states, - encoder_attention_mask, - past_key_values, - output_attentions, - cache_position, + encoder_hidden_states, # as a positional argument for gradient checkpointing + encoder_attention_mask=encoder_attention_mask, + past_key_value=past_key_values, + cache_position=cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - + # Extra layernorm at the end (causes high fluctuations between different attentions) hidden_states = self.LayerNorm(hidden_states) - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) -# Copied from transformers.models.bert.modeling_bert.BertPooler -class XLMRobertaXLPooler(nn.Module): - def __init__(self, config): - super().__init__() - self.dense = nn.Linear(config.hidden_size, config.hidden_size) - self.activation = nn.Tanh() - - def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. - first_token_tensor = hidden_states[:, 0] - pooled_output = self.dense(first_token_tensor) - pooled_output = self.activation(pooled_output) - return pooled_output - - @auto_docstring class XLMRobertaXLPreTrainedModel(PreTrainedModel): - config: XLMRobertaXLConfig + config_class = XLMRobertaXLConfig base_model_prefix = "roberta" - _no_split_modules = ["XLMRobertaXLEmbeddings", "XLMRobertaXLLayer"] + supports_gradient_checkpointing = True + _supports_flash_attn = True _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": XLMRobertaXLLayer, + "attentions": XLMRobertaXLSelfAttention, + "cross_attentions": XLMRobertaXLCrossAttention, + } - # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights with BertLMPredictionHead->XLMRobertaXLLMHead def _init_weights(self, module): """Initialize the weights""" if isinstance(module, nn.Linear): @@ -678,8 +650,33 @@ def _init_weights(self, module): module.bias.data.zero_() -@auto_docstring -# Copied from transformers.models.bert.modeling_bert.BertModel with Bert->XLMRobertaXL, BERT->XLM_ROBERTA_XL +class XLMRobertaXLPooler(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.activation = nn.Tanh() + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(first_token_tensor) + pooled_output = self.activation(pooled_output) + return pooled_output + + +@auto_docstring( + custom_intro=""" + The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of + cross-attention is added between the self-attention layers, following the architecture described in [Attention is + all you need](https://huggingface.co/papers/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, + Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin. + + To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set + to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and + `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. + """ +) class XLMRobertaXLModel(XLMRobertaXLPreTrainedModel): _no_split_modules = ["XLMRobertaXLEmbeddings", "XLMRobertaXLLayer"] @@ -690,13 +687,13 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = XLMRobertaXLEmbeddings(config) self.encoder = XLMRobertaXLEncoder(config) self.pooler = XLMRobertaXLPooler(config) if add_pooling_layer else None - self.attn_implementation = config._attn_implementation self.position_embedding_type = config.position_embedding_type # Initialize weights and apply final processing @@ -716,6 +713,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -727,52 +725,40 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[Union[list[torch.FloatTensor], Cache]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] - else: - raise ValueError("You have to specify either input_ids or inputs_embeds") - - batch_size, seq_length = input_shape - device = input_ids.device if input_ids is not None else inputs_embeds.device - - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape + else: + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] + + seq_length = input_shape[1] + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) embedding_output = self.embeddings( input_ids=input_ids, @@ -782,55 +768,16 @@ def forward( past_key_values_length=past_key_values_length, ) - if attention_mask is None: - attention_mask = torch.ones((batch_size, seq_length + past_key_values_length), device=device) - - use_sdpa_attention_masks = ( - self.attn_implementation == "sdpa" - and self.position_embedding_type == "absolute" - and head_mask is None - and not output_attentions + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, ) - # Expand the attention mask - if use_sdpa_attention_masks and attention_mask.dim() == 2: - # Expand the attention mask for SDPA. - # [bsz, seq_len] -> [bsz, 1, seq_len, seq_len] - if self.config.is_decoder: - extended_attention_mask = _prepare_4d_causal_attention_mask_for_sdpa( - attention_mask, - input_shape, - embedding_output, - past_key_values_length, - ) - else: - extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - - if use_sdpa_attention_masks and encoder_attention_mask.dim() == 2: - # Expand the attention mask for SDPA. - # [bsz, seq_len] -> [bsz, 1, seq_len, seq_len] - encoder_extended_attention_mask = _prepare_4d_attention_mask_for_sdpa( - encoder_attention_mask, embedding_output.dtype, tgt_len=seq_length - ) - else: - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) - else: - encoder_extended_attention_mask = None - # Prepare head mask if needed # 1.0 in head_mask indicate we keep the head # attention_probs has shape bsz x n_heads x N x N @@ -840,32 +787,188 @@ def forward( encoder_outputs = self.encoder( embedding_output, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) - sequence_output = encoder_outputs[0] + sequence_output = encoder_outputs.last_hidden_state pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + + +class XLMRobertaXLLMHead(nn.Module): + """XLM-RoBERTa-XL Head for masked language modeling.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + self.decoder = nn.Linear(config.hidden_size, config.vocab_size) + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + self.decoder.bias = self.bias + + def forward(self, features, **kwargs): + x = self.dense(features) + x = gelu(x) + x = self.layer_norm(x) + + # project back to size of vocabulary with bias + x = self.decoder(x) + + return x + + def _tie_weights(self) -> None: + # For accelerate compatibility and to not break backward compatibility + if self.decoder.bias.device.type == "meta": + self.decoder.bias = self.bias + else: + # To tie those two weights if they get disconnected (on TPU or when the bias is resized) + self.bias = self.decoder.bias + + +class XLMRobertaXLClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.out_proj = nn.Linear(config.hidden_size, config.num_labels) + + def forward(self, features, **kwargs): + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x) + x = self.dense(x) + x = torch.tanh(x) + x = self.dropout(x) + x = self.out_proj(x) + return x + @auto_docstring( custom_intro=""" @@ -893,6 +996,7 @@ def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings self.lm_head.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -905,12 +1009,10 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, - **kwargs, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, CausalLMOutputWithCrossAttentions]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -933,7 +1035,6 @@ def forward( >>> prediction_logits = outputs.logits ``` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -948,9 +1049,9 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + cache_position=cache_position, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -965,10 +1066,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, @@ -978,53 +1075,6 @@ def forward( cross_attentions=outputs.cross_attentions, ) - def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): - # Overwritten -- model logic breaks when `inputs_embeds` are passed from this function - - input_shape = input_ids.shape - # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly - if attention_mask is None: - attention_mask = input_ids.new_ones(input_shape) - - # Create missing `position_ids` on the fly - position_ids = None - if model_kwargs.get("position_ids") is None: - position_ids = create_position_ids_from_input_ids( - input_ids, padding_idx=self.config.pad_token_id - ) # placed in kwargs for further processing (see below) - - # cut decoder_input_ids if past_key_values is used - if past_key_values is not None: - past_length = past_key_values.get_seq_length() - - # Some generation methods already pass only the last input ID - if input_ids.shape[1] > past_length: - remove_prefix_length = past_length - else: - # Default to old behavior: keep only final ID - remove_prefix_length = input_ids.shape[1] - 1 - - input_ids = input_ids[:, remove_prefix_length:] - if position_ids is not None: - position_ids = position_ids[:, remove_prefix_length:] - - model_inputs = { - "input_ids": input_ids, - "attention_mask": attention_mask, - "position_ids": position_ids, - "past_key_values": past_key_values, - } - - # They are calculated on the fly on XLMRobertaXLModel.forward() - model_kwargs.pop("token_type_ids", None) - - # Forward ALL kwargs that are uninitialized (e.g. `use_cache`). - for key, value in model_kwargs.items(): - if key not in model_inputs: - model_inputs[key] = value - - return model_inputs - @auto_docstring class XLMRobertaXLForMaskedLM(XLMRobertaXLPreTrainedModel): @@ -1051,6 +1101,7 @@ def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings self.lm_head.bias = new_embeddings.bias + @can_return_tuple @auto_docstring def forward( self, @@ -1063,9 +1114,7 @@ def forward( encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, MaskedLMOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1073,8 +1122,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1084,9 +1131,8 @@ def forward( inputs_embeds=inputs_embeds, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] prediction_scores = self.lm_head(sequence_output) @@ -1096,10 +1142,6 @@ def forward( loss_fct = CrossEntropyLoss() masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -1108,37 +1150,6 @@ def forward( ) -class XLMRobertaXLLMHead(nn.Module): - """XLM-RoBERTa-XL Head for masked language modeling.""" - - def __init__(self, config): - super().__init__() - self.dense = nn.Linear(config.hidden_size, config.hidden_size) - self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - - self.decoder = nn.Linear(config.hidden_size, config.vocab_size) - self.bias = nn.Parameter(torch.zeros(config.vocab_size)) - self.decoder.bias = self.bias - - def forward(self, features, **kwargs): - x = self.dense(features) - x = gelu(x) - x = self.layer_norm(x) - - # project back to size of vocabulary with bias - x = self.decoder(x) - - return x - - def _tie_weights(self) -> None: - # For accelerate compatibility and to not break backward compatibility - if self.decoder.bias.device.type == "meta": - self.decoder.bias = self.bias - else: - # To tie those two weights if they get disconnected (on TPU or when the bias is resized) - self.bias = self.decoder.bias - - @auto_docstring( custom_intro=""" XLM-RoBERTa-XL Model transformer with a sequence classification/regression head on top (a linear layer on top @@ -1156,6 +1167,7 @@ def __init__(self, config): self.init_weights() + @can_return_tuple @auto_docstring def forward( self, @@ -1166,9 +1178,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, SequenceClassifierOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): @@ -1176,8 +1186,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1185,9 +1193,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] logits = self.classifier(sequence_output) @@ -1215,10 +1222,6 @@ def forward( loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return SequenceClassifierOutput( loss=loss, logits=logits, @@ -1238,6 +1241,7 @@ def __init__(self, config): self.init_weights() + @can_return_tuple @auto_docstring def forward( self, @@ -1248,9 +1252,7 @@ def forward( position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1276,7 +1278,6 @@ def forward( is useful if you want more control over how to convert `input_ids` indices into associated vectors than the model's internal embedding lookup matrix. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1296,9 +1297,8 @@ def forward( attention_mask=flat_attention_mask, head_mask=head_mask, inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1311,10 +1311,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1338,6 +1334,7 @@ def __init__(self, config): self.init_weights() + @can_return_tuple @auto_docstring def forward( self, @@ -1348,16 +1345,12 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, TokenClassifierOutput]: r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1365,9 +1358,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1389,10 +1381,6 @@ def forward( else: loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1401,28 +1389,6 @@ def forward( ) -class XLMRobertaXLClassificationHead(nn.Module): - """Head for sentence-level classification tasks.""" - - def __init__(self, config): - super().__init__() - self.dense = nn.Linear(config.hidden_size, config.hidden_size) - classifier_dropout = ( - config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob - ) - self.dropout = nn.Dropout(classifier_dropout) - self.out_proj = nn.Linear(config.hidden_size, config.num_labels) - - def forward(self, features, **kwargs): - x = features[:, 0, :] # take token (equiv. to [CLS]) - x = self.dropout(x) - x = self.dense(x) - x = torch.tanh(x) - x = self.dropout(x) - x = self.out_proj(x) - return x - - @auto_docstring class XLMRobertaXLForQuestionAnswering(XLMRobertaXLPreTrainedModel): def __init__(self, config): @@ -1434,6 +1400,7 @@ def __init__(self, config): self.init_weights() + @can_return_tuple @auto_docstring def forward( self, @@ -1445,12 +1412,8 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, start_positions: Optional[torch.LongTensor] = None, end_positions: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple, QuestionAnsweringModelOutput]: - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, attention_mask=attention_mask, @@ -1458,9 +1421,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1487,10 +1449,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, @@ -1500,23 +1458,6 @@ def forward( ) -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - __all__ = [ "XLMRobertaXLForCausalLM", "XLMRobertaXLForMaskedLM", diff --git a/src/transformers/models/xlm_roberta_xl/modular_xlm_roberta_xl.py b/src/transformers/models/xlm_roberta_xl/modular_xlm_roberta_xl.py new file mode 100644 index 000000000000..d4937d424d31 --- /dev/null +++ b/src/transformers/models/xlm_roberta_xl/modular_xlm_roberta_xl.py @@ -0,0 +1,777 @@ +# coding=utf-8 +# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# coding=utf-8 +# Copyright 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. +"""PyTorch XLM RoBERTa xl,xxl model.""" + +from typing import Optional, Union + +import torch +import torch.nn as nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import gelu +from ...cache_utils import Cache +from ...generation import GenerationMixin +from ...modeling_outputs import ( + BaseModelOutputWithPastAndCrossAttentions, + CausalLMOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, logging +from ...utils.generic import can_return_tuple +from ..bert.modeling_bert import ( + BertAttention, + BertCrossAttention, + BertLayer, + BertModel, + BertSelfAttention, +) +from ..roberta.modeling_roberta import ( + RobertaClassificationHead, + RobertaEmbeddings, + RobertaPreTrainedModel, +) + + +logger = logging.get_logger(__name__) + + +class XLMRobertaXLEmbeddings(RobertaEmbeddings): + def __init__(self, config): + super().__init__(config) + del self.LayerNorm + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: + if position_ids is None: + if input_ids is not None: + # Create the position ids from the input token ids. Any padded tokens remain padded. + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) + else: + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) + + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + batch_size, seq_length = input_shape + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + + embeddings = self.dropout(embeddings) + return embeddings + + +class XLMRobertaXLSelfAttention(BertSelfAttention): + pass + + +class XLMRobertaXLCrossAttention(BertCrossAttention): + pass + + +class XLMRobertaXLSelfOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = hidden_states + input_tensor + return hidden_states + + +class XLMRobertaXLAttention(BertAttention): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): + super().__init__(config, position_embedding_type, is_causal, layer_idx, is_cross_attention) + del self.LayerNorm + + self.self_attn_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[tuple[tuple[torch.FloatTensor]]] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + intermediate = self.self_attn_layer_norm(hidden_states) + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( + intermediate, + encoder_hidden_states=encoder_hidden_states, + attention_mask=attention_mask, + head_mask=head_mask, + past_key_value=past_key_value, + cache_position=cache_position, + **kwargs, + ) + attention_output = self.output(attention_output, hidden_states) + return attention_output, attn_weights + + +class XLMRobertaXLOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + + def forward(self, hidden_states, input_tensor): + hidden_states = self.dense(hidden_states) + hidden_states = hidden_states + input_tensor + return hidden_states + + +class XLMRobertaXLLayer(BertLayer): + def __init__(self, config, layer_idx=None): + super().__init__(config, layer_idx) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def feed_forward_chunk(self, attention_output): + intermediate_output = self.LayerNorm(attention_output) + intermediate_output = self.intermediate(intermediate_output) + layer_output = self.output(intermediate_output, attention_output) + return layer_output + + +class XLMRobertaXLEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.layer = nn.ModuleList([XLMRobertaXLLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)]) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: + for i, layer_module in enumerate(self.layer): + layer_head_mask = head_mask[i] if head_mask is not None else None + + hidden_states = layer_module( + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, # as a positional argument for gradient checkpointing + encoder_attention_mask=encoder_attention_mask, + past_key_value=past_key_values, + cache_position=cache_position, + **kwargs, + ) + + # Extra layernorm at the end (causes high fluctuations between different attentions) + hidden_states = self.LayerNorm(hidden_states) + + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=past_key_values if use_cache else None, + ) + + +@auto_docstring +class XLMRobertaXLPreTrainedModel(RobertaPreTrainedModel): + base_model_prefix = "roberta" + + +class XLMRobertaXLModel(BertModel): + pass + + +class XLMRobertaXLLMHead(nn.Module): + """XLM-RoBERTa-XL Head for masked language modeling.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + self.decoder = nn.Linear(config.hidden_size, config.vocab_size) + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + self.decoder.bias = self.bias + + def forward(self, features, **kwargs): + x = self.dense(features) + x = gelu(x) + x = self.layer_norm(x) + + # project back to size of vocabulary with bias + x = self.decoder(x) + + return x + + def _tie_weights(self) -> None: + # For accelerate compatibility and to not break backward compatibility + if self.decoder.bias.device.type == "meta": + self.decoder.bias = self.bias + else: + # To tie those two weights if they get disconnected (on TPU or when the bias is resized) + self.bias = self.decoder.bias + + +class XLMRobertaXLClassificationHead(RobertaClassificationHead): + pass + + +@auto_docstring( + custom_intro=""" + XLM-RoBERTa-XL Model with a `language modeling` head on top for CLM fine-tuning. + """ +) +class XLMRobertaXLForCausalLM(XLMRobertaXLPreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.decoder.weight", "lm_head.decoder.bias"] + + def __init__(self, config): + super().__init__(config) + + if not config.is_decoder: + logger.warning("If you want to use `RobertaLMHeadModel` as a standalone, add `is_decoder=True.`") + + self.roberta = XLMRobertaXLModel(config, add_pooling_layer=False) + self.lm_head = XLMRobertaXLLMHead(config) + + self.init_weights() + + def get_output_embeddings(self): + return self.lm_head.decoder + + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + self.lm_head.bias = new_embeddings.bias + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, CausalLMOutputWithCrossAttentions]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + + Example: + + ```python + >>> from transformers import AutoTokenizer, RobertaForCausalLM, RobertaConfig + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("FacebookAI/roberta-base") + >>> config = RobertaConfig.from_pretrained("FacebookAI/roberta-base") + >>> config.is_decoder = True + >>> model = RobertaForCausalLM.from_pretrained("FacebookAI/roberta-base", config=config) + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + >>> prediction_logits = outputs.logits + ``` + """ + if labels is not None: + use_cache = False + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + lm_loss = None + if labels is not None: + lm_loss = self.loss_function( + prediction_scores, + labels, + vocab_size=self.config.vocab_size, + **kwargs, + ) + + return CausalLMOutputWithCrossAttentions( + loss=lm_loss, + logits=prediction_scores, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +@auto_docstring +class XLMRobertaXLForMaskedLM(XLMRobertaXLPreTrainedModel): + _tied_weights_keys = ["lm_head.decoder.weight", "lm_head.decoder.bias"] + + def __init__(self, config): + super().__init__(config) + + if config.is_decoder: + logger.warning( + "If you want to use `RobertaForMaskedLM` make sure `config.is_decoder=False` for " + "bi-directional self-attention." + ) + + self.roberta = XLMRobertaXLModel(config, add_pooling_layer=False) + self.lm_head = XLMRobertaXLLMHead(config) + + self.init_weights() + + def get_output_embeddings(self): + return self.lm_head.decoder + + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + self.lm_head.bias = new_embeddings.bias + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, MaskedLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + return_dict=True, + **kwargs, + ) + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + masked_lm_loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring( + custom_intro=""" + XLM-RoBERTa-XL Model transformer with a sequence classification/regression head on top (a linear layer on top + of the pooled output) e.g. for GLUE tasks. + """ +) +class XLMRobertaXLForSequenceClassification(XLMRobertaXLPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + + self.roberta = XLMRobertaXLModel(config, add_pooling_layer=False) + self.classifier = XLMRobertaXLClassificationHead(config) + + self.init_weights() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + sequence_output = outputs[0] + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class XLMRobertaXLForMultipleChoice(XLMRobertaXLPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.roberta = XLMRobertaXLModel(config) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, 1) + + self.init_weights() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, MultipleChoiceModelOutput]: + r""" + input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Indices can be obtained using [`AutoTokenizer`]. See + [`PreTrainedTokenizer.encode`] and [`PreTrainedTokenizer.__call__`] for details. [What are input + IDs?](../glossary#input-ids) + token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + [What are token type IDs?](../glossary#token-type-ids) + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. [What are position IDs?](../glossary#position-ids) + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + """ + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + flat_inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.roberta( + flat_input_ids, + position_ids=flat_position_ids, + token_type_ids=flat_token_type_ids, + attention_mask=flat_attention_mask, + head_mask=head_mask, + inputs_embeds=flat_inputs_embeds, + return_dict=True, + **kwargs, + ) + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class XLMRobertaXLForTokenClassification(XLMRobertaXLPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.roberta = XLMRobertaXLModel(config, add_pooling_layer=False) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + self.init_weights() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + # Only keep active parts of the loss + if attention_mask is not None: + active_loss = attention_mask.view(-1) == 1 + active_logits = logits.view(-1, self.num_labels) + active_labels = torch.where( + active_loss, labels.view(-1), torch.tensor(loss_fct.ignore_index).type_as(labels) + ) + loss = loss_fct(active_logits, active_labels) + else: + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@auto_docstring +class XLMRobertaXLForQuestionAnswering(XLMRobertaXLPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.roberta = XLMRobertaXLModel(config, add_pooling_layer=False) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + self.init_weights() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + start_positions: Optional[torch.LongTensor] = None, + end_positions: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, QuestionAnsweringModelOutput]: + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + return_dict=True, + **kwargs, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +__all__ = [ + "XLMRobertaXLForCausalLM", + "XLMRobertaXLForMaskedLM", + "XLMRobertaXLForMultipleChoice", + "XLMRobertaXLForQuestionAnswering", + "XLMRobertaXLForSequenceClassification", + "XLMRobertaXLForTokenClassification", + "XLMRobertaXLModel", + "XLMRobertaXLPreTrainedModel", +] diff --git a/src/transformers/models/xmod/modeling_xmod.py b/src/transformers/models/xmod/modeling_xmod.py index f7242a64d5d4..eaf1362d3664 100644 --- a/src/transformers/models/xmod/modeling_xmod.py +++ b/src/transformers/models/xmod/modeling_xmod.py @@ -14,16 +14,17 @@ # limitations under the License. """PyTorch X-MOD model.""" -import math -from typing import Optional, Union +from typing import Callable, Optional, Union import torch from torch import nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss from ...activations import ACT2FN, gelu -from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache +from ...cache_utils import Cache, EncoderDecoderCache from ...generation import GenerationMixin +from ...masking_utils import create_causal_mask +from ...modeling_attn_mask_utils import _prepare_4d_attention_mask, _prepare_4d_attention_mask_for_sdpa from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import ( BaseModelOutputWithPastAndCrossAttentions, @@ -35,27 +36,28 @@ SequenceClassifierOutput, TokenClassifierOutput, ) -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer -from ...utils import auto_docstring, logging -from ...utils.deprecation import deprecate_kwarg +from ...utils import TransformersKwargs, auto_docstring, is_torch_flex_attn_available, logging +from ...utils.generic import can_return_tuple, check_model_inputs from .configuration_xmod import XmodConfig +if is_torch_flex_attn_available(): + from ...integrations.flex_attention import make_flex_block_causal_mask + + logger = logging.get_logger(__name__) # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->Xmod class XmodEmbeddings(nn.Module): - """ - Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. - """ + """Construct the embeddings from word, position and token_type embeddings.""" - # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ def __init__(self, config): super().__init__() self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) - self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) @@ -69,37 +71,44 @@ def __init__(self, config): "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False ) - # End copy self.padding_idx = config.pad_token_id self.position_embeddings = nn.Embedding( config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx ) def forward( - self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 - ): + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: if position_ids is None: if input_ids is not None: # Create the position ids from the input token ids. Any padded tokens remain padded. - position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + position_ids = self.create_position_ids_from_input_ids( + input_ids, self.padding_idx, past_key_values_length + ) else: - position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx) if input_ids is not None: input_shape = input_ids.size() else: input_shape = inputs_embeds.size()[:-1] - seq_length = input_shape[1] + batch_size, seq_length = input_shape # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves # issue #5664 if token_type_ids is None: if hasattr(self, "token_type_ids"): - buffered_token_type_ids = self.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) - token_type_ids = buffered_token_type_ids_expanded + # NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0]) + buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1) + buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids) + token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length) else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) @@ -115,7 +124,8 @@ def forward( embeddings = self.dropout(embeddings) return embeddings - def create_position_ids_from_inputs_embeds(self, inputs_embeds): + @staticmethod + def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx): """ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. @@ -128,24 +138,101 @@ def create_position_ids_from_inputs_embeds(self, inputs_embeds): sequence_length = input_shape[1] position_ids = torch.arange( - self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device ) return position_ids.unsqueeze(0).expand(input_shape) + @staticmethod + def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx + + +# Copied from transformers.models.bert.modeling_bert.eager_attention_forward +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: Optional[float] = None, + dropout: float = 0.0, + head_mask: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], +): + if scaling is None: + scaling = query.size(-1) ** -0.5 + + # Take the dot product between "query" and "key" to get the raw attention scores. + attn_weights = torch.matmul(query, key.transpose(2, 3)) + + # Relative positional embeddings + if module.position_embedding_type == "relative_key" or module.position_embedding_type == "relative_key_query": + query_length, key_length = query.shape[2], key.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=query.device).view(-1, 1) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=query.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=query.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = module.distance_embedding(distance + module.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query.dtype) # fp16 compatibility + + if module.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + attn_weights = attn_weights + relative_position_scores + elif module.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key, positional_embedding) + attn_weights = attn_weights + relative_position_scores_query + relative_position_scores_key + + # Scaling is shifted in case of embeddings being relative + attn_weights = attn_weights * scaling + + if attention_mask is not None and attention_mask.ndim == 4: + attention_mask = attention_mask[:, :, :, : key.shape[-2]] + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + # Copied from transformers.models.roberta.modeling_roberta.RobertaSelfAttention with Roberta->Xmod class XmodSelfAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): super().__init__() if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): raise ValueError( f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " f"heads ({config.num_attention_heads})" ) + self.config = config self.num_attention_heads = config.num_attention_heads self.attention_head_size = int(config.hidden_size / config.num_attention_heads) self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 self.query = nn.Linear(config.hidden_size, self.all_head_size) self.key = nn.Linear(config.hidden_size, self.all_head_size) @@ -160,111 +247,157 @@ def __init__(self, config, position_embedding_type=None, layer_idx=None): self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) self.is_decoder = config.is_decoder + self.is_causal = is_causal self.layer_idx = layer_idx - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, - encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[Cache] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - batch_size, seq_length, _ = hidden_states.shape - query_layer = self.query(hidden_states) - query_layer = query_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + # get all proj + query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2) + key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2) + value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2) + + if past_key_value is not None: + # decoder-only roberta can have a simple dynamic cache for example + current_past_key_value = past_key_value + if isinstance(past_key_value, EncoderDecoderCache): + current_past_key_value = past_key_value.self_attention_cache + + # save all key/value_layer to cache to be re-used for fast auto-regressive generation + key_layer, value_layer = current_past_key_value.update( + key_layer, + value_layer, + self.layer_idx, + {"cache_position": cache_position}, + ) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights - is_updated = False - is_cross_attention = encoder_hidden_states is not None - if past_key_values is not None: - if isinstance(past_key_values, EncoderDecoderCache): - is_updated = past_key_values.is_updated.get(self.layer_idx) - if is_cross_attention: - # after the first generated id, we can subsequently re-use all key/value_layer from cache - curr_past_key_value = past_key_values.cross_attention_cache - else: - curr_past_key_value = past_key_values.self_attention_cache - else: - curr_past_key_value = past_key_values - current_states = encoder_hidden_states if is_cross_attention else hidden_states - if is_cross_attention and past_key_values is not None and is_updated: - # reuse k,v, cross_attentions - key_layer = curr_past_key_value.layers[self.layer_idx].keys - value_layer = curr_past_key_value.layers[self.layer_idx].values - else: - key_layer = self.key(current_states) - key_layer = key_layer.view(batch_size, -1, self.num_attention_heads, self.attention_head_size).transpose( - 1, 2 +# Copied from transformers.models.bert.modeling_bert.BertCrossAttention with Bert->Xmod +class XmodCrossAttention(nn.Module): + def __init__(self, config, position_embedding_type=None, is_causal=False, layer_idx=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" ) - value_layer = self.value(current_states) - value_layer = value_layer.view( - batch_size, -1, self.num_attention_heads, self.attention_head_size - ).transpose(1, 2) - - if past_key_values is not None: - # save all key/value_layer to cache to be re-used for fast auto-regressive generation - cache_position = cache_position if not is_cross_attention else None - key_layer, value_layer = curr_past_key_value.update( - key_layer, value_layer, self.layer_idx, {"cache_position": cache_position} - ) - # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls - if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache): - past_key_values.is_updated[self.layer_idx] = True + self.config = config + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.scaling = self.attention_head_size**-0.5 - # Take the dot product between "query" and "key" to get the raw attention scores. - attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": - query_length, key_length = query_layer.shape[2], key_layer.shape[2] - if past_key_values is not None: - position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( - -1, 1 - ) - else: - position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) - position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) - distance = position_ids_l - position_ids_r - - positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) - positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility - - if self.position_embedding_type == "relative_key": - relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores - elif self.position_embedding_type == "relative_key_query": - relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) - relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) - attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key - - attention_scores = attention_scores / math.sqrt(self.attention_head_size) - if attention_mask is not None: - # Apply the attention mask is (precomputed for all layers in XmodModel forward() function) - attention_scores = attention_scores + attention_mask + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) - # Normalize the attention scores to probabilities. - attention_probs = nn.functional.softmax(attention_scores, dim=-1) + self.is_causal = is_causal + self.layer_idx = layer_idx - # This is actually dropping out entire tokens to attend to, which might - # seem a bit unusual, but is taken from the original Transformer paper. - attention_probs = self.dropout(attention_probs) + def forward( + self, + hidden_states: torch.Tensor, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[EncoderDecoderCache] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + # determine input shapes + bsz, tgt_len = hidden_states.shape[:-1] + src_len = encoder_hidden_states.shape[1] - # Mask heads if we want to - if head_mask is not None: - attention_probs = attention_probs * head_mask + q_input_shape = (bsz, tgt_len, -1, self.attention_head_size) + kv_input_shape = (bsz, src_len, -1, self.attention_head_size) - context_layer = torch.matmul(attention_probs, value_layer) + # get query proj + query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2) - context_layer = context_layer.permute(0, 2, 1, 3).contiguous() - new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) - context_layer = context_layer.view(new_context_layer_shape) + is_updated = past_key_value.is_updated.get(self.layer_idx) if past_key_value is not None else False + if past_key_value is not None and is_updated: + # reuse k,v, cross_attentions + key_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].keys + value_layer = past_key_value.cross_attention_cache.layers[self.layer_idx].values + else: + key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) + value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2) - return context_layer, attention_probs + if past_key_value is not None: + # save all states to the cache + key_layer, value_layer = past_key_value.cross_attention_cache.update( + key_layer, value_layer, self.layer_idx + ) + # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls + past_key_value.is_updated[self.layer_idx] = True + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.position_embedding_type != "absolute": + raise ValueError( + f"You are using {self.config._attn_implementation} as attention type. However, non-absolute " + 'positional embeddings can not work with them. Please load the model with `attn_implementation="eager"`.' + ) + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout.p, + scaling=self.scaling, + head_mask=head_mask, + # only for relevant for non-absolute positional embeddings + use_cache=past_key_value is not None, + **kwargs, + ) + attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous() + return attn_output, attn_weights class XmodSelfOutput(nn.Module): @@ -283,9 +416,15 @@ def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> to class XmodAttention(nn.Module): - def __init__(self, config, position_embedding_type=None, layer_idx=None): + def __init__( + self, config, position_embedding_type=None, is_causal=False, layer_idx=None, is_cross_attention=False + ): super().__init__() - self.self = XmodSelfAttention(config, position_embedding_type=position_embedding_type, layer_idx=layer_idx) + self.is_cross_attention = is_cross_attention + attention_class = XmodCrossAttention if is_cross_attention else XmodSelfAttention + self.self = attention_class( + config, position_embedding_type=position_embedding_type, is_causal=is_causal, layer_idx=layer_idx + ) self.output = XmodSelfOutput(config) self.pruned_heads = set() self.pre_norm = config.pre_norm @@ -309,34 +448,37 @@ def prune_heads(self, heads): self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads self.pruned_heads = self.pruned_heads.union(heads) - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[tuple[tuple[torch.FloatTensor]]] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: residual = hidden_states if self.pre_norm: hidden_states = self.output.LayerNorm(hidden_states) - self_outputs = self.self( + + attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask + attention_output, attn_weights = self.self( hidden_states, - attention_mask, - head_mask, - encoder_hidden_states, - past_key_values, - output_attentions, - cache_position, + encoder_hidden_states=encoder_hidden_states, + attention_mask=attention_mask, + head_mask=head_mask, + past_key_value=past_key_value, + cache_position=cache_position, + **kwargs, ) - attention_output = self.output(self_outputs[0], residual) + attention_output = self.output(attention_output, residual) + if not self.pre_norm: attention_output = self.output.LayerNorm(attention_output) - outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them - return outputs + + return attention_output, attn_weights # Copied from transformers.models.roberta.modeling_roberta.RobertaIntermediate @@ -428,18 +570,23 @@ def __init__(self, config, layer_idx=None): super().__init__() self.chunk_size_feed_forward = config.chunk_size_feed_forward self.seq_len_dim = 1 - self.attention = XmodAttention(config, layer_idx=layer_idx) + self.attention = XmodAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) self.is_decoder = config.is_decoder self.add_cross_attention = config.add_cross_attention if self.add_cross_attention: if not self.is_decoder: raise ValueError(f"{self} should be used as a decoder model if cross attention is added") - self.crossattention = XmodAttention(config, position_embedding_type="absolute", layer_idx=layer_idx) + self.crossattention = XmodAttention( + config, + position_embedding_type="absolute", + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) self.intermediate = XmodIntermediate(config) self.output = XmodOutput(config) self.pre_norm = config.pre_norm - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( self, hidden_states: torch.Tensor, @@ -448,20 +595,19 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, - output_attentions: Optional[bool] = False, + past_key_value: Optional[tuple[tuple[torch.FloatTensor]]] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> tuple[torch.Tensor]: - self_attention_outputs = self.attention( + self_attention_output, _ = self.attention( hidden_states, - attention_mask=attention_mask, - head_mask=head_mask, - output_attentions=output_attentions, - past_key_values=past_key_values, + attention_mask, + head_mask, + past_key_value=past_key_value, cache_position=cache_position, + **kwargs, ) - attention_output = self_attention_outputs[0] - outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + attention_output = self_attention_output if self.is_decoder and encoder_hidden_states is not None: if not hasattr(self, "crossattention"): @@ -470,17 +616,16 @@ def forward( " by setting `config.add_cross_attention=True`" ) - cross_attention_outputs = self.crossattention( + cross_attention_output, _ = self.crossattention( attention_output, - attention_mask=encoder_attention_mask, - head_mask=head_mask, - encoder_hidden_states=encoder_hidden_states, - past_key_values=past_key_values, - output_attentions=output_attentions, - cache_position=cache_position, + None, # attention_mask + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value=past_key_value, + **kwargs, ) - attention_output = cross_attention_outputs[0] - outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights + attention_output = cross_attention_output residual = attention_output if self.pre_norm: @@ -494,7 +639,8 @@ def forward( layer_output = self.output(intermediate_output, residual, lang_ids) if not self.pre_norm: layer_output = self.output.LayerNorm(layer_output) - return (layer_output,) + outputs + + return layer_output def feed_forward_chunk(self, attention_output): return self.intermediate(attention_output) @@ -508,7 +654,6 @@ def __init__(self, config): self.is_pre_norm = config.pre_norm if self.is_pre_norm: self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) - self.gradient_checkpointing = False def forward( self, @@ -518,41 +663,15 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = False, - output_hidden_states: Optional[bool] = False, - return_dict: Optional[bool] = True, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: - if self.gradient_checkpointing and self.training: - if use_cache: - logger.warning_once( - "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." - ) - use_cache = False - - if use_cache and past_key_values is None: - past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config)) - if use_cache and isinstance(past_key_values, tuple): - logger.warning_once( - "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " - "You should pass an instance of `EncoderDecoderCache` instead, e.g. " - "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." - ) - past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) - - all_hidden_states = () if output_hidden_states else None - all_self_attentions = () if output_attentions else None - all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None - for i, layer_module in enumerate(self.layer): - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - layer_head_mask = head_mask[i] if head_mask is not None else None - layer_outputs = layer_module( + hidden_states = layer_module( hidden_states, lang_ids, attention_mask, @@ -560,40 +679,16 @@ def forward( encoder_hidden_states, encoder_attention_mask, past_key_values, - output_attentions, cache_position, + **kwargs, ) - hidden_states = layer_outputs[0] - if output_attentions: - all_self_attentions = all_self_attentions + (layer_outputs[1],) - if self.config.add_cross_attention: - all_cross_attentions = all_cross_attentions + (layer_outputs[2],) - if self.is_pre_norm: hidden_states = self.LayerNorm(hidden_states) - if output_hidden_states: - all_hidden_states = all_hidden_states + (hidden_states,) - - if not return_dict: - return tuple( - v - for v in [ - hidden_states, - past_key_values, - all_hidden_states, - all_self_attentions, - all_cross_attentions, - ] - if v is not None - ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, - past_key_values=past_key_values, - hidden_states=all_hidden_states, - attentions=all_self_attentions, - cross_attentions=all_cross_attentions, + past_key_values=past_key_values if use_cache else None, ) @@ -615,9 +710,19 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: @auto_docstring class XmodPreTrainedModel(PreTrainedModel): - config: XmodConfig + config_class = XmodConfig base_model_prefix = "roberta" supports_gradient_checkpointing = True + no_split_modules = ["XmodEmbeddings", "XmodSelfAttention", "XmodCrossAttention"] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": XmodLayer, + "attentions": XmodSelfAttention, + "cross_attentions": XmodCrossAttention, + } # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights with BertLMPredictionHead->XmodLMHead def _init_weights(self, module): @@ -681,7 +786,6 @@ def freeze_embeddings_and_language_adapters(self): """ ) class XmodModel(XmodPreTrainedModel): - # Copied from transformers.models.clap.modeling_clap.ClapTextModel.__init__ with ClapText->Xmod def __init__(self, config, add_pooling_layer=True): r""" add_pooling_layer (bool, *optional*, defaults to `True`): @@ -689,6 +793,7 @@ def __init__(self, config, add_pooling_layer=True): """ super().__init__(config) self.config = config + self.gradient_checkpointing = False self.embeddings = XmodEmbeddings(config) self.encoder = XmodEncoder(config) @@ -715,6 +820,7 @@ class PreTrainedModel for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) + @check_model_inputs @auto_docstring def forward( self, @@ -727,49 +833,47 @@ def forward( inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[list[torch.FloatTensor]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: r""" lang_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Indices of the language adapters that should be activated for each sample, respectively. Default: the index that corresponds to `self.config.default_language`. """ - output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions - output_hidden_states = ( - output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states - ) - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False - if input_ids is not None and inputs_embeds is not None: - raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") - elif input_ids is not None: - self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) - input_shape = input_ids.size() - elif inputs_embeds is not None: - input_shape = inputs_embeds.size()[:-1] + return_legacy_cache = False + if use_cache and not isinstance(past_key_values, Cache): + logger.warning_once( + "Passing a tuple of `past_key_values` is deprecated and will be removed in Transformers v4.58.0. " + "You should pass an instance of `EncoderDecoderCache` instead, e.g. " + "`past_key_values=EncoderDecoderCache.from_legacy_cache(past_key_values)`." + ) + return_legacy_cache = True + past_key_values = EncoderDecoderCache.from_legacy_cache(past_key_values) + + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if input_ids is not None: + device = input_ids.device + input_shape = input_ids.shape else: - raise ValueError("You have to specify either input_ids or inputs_embeds") + device = inputs_embeds.device + input_shape = inputs_embeds.shape[:-1] batch_size, seq_length = input_shape device = input_ids.device if input_ids is not None else inputs_embeds.device - past_key_values_length = 0 - if past_key_values is not None: - past_key_values_length = ( - past_key_values[0][0].shape[-2] - if not isinstance(past_key_values, Cache) - else past_key_values.get_seq_length() - ) + past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0 + if cache_position is None: + cache_position = torch.arange(past_key_values_length, past_key_values_length + seq_length, device=device) if lang_ids is None: if self.config.default_language is None: @@ -778,31 +882,23 @@ def forward( default_lang_id = adapter_languages.index(self.config.default_language) lang_ids = default_lang_id * torch.ones(batch_size, device=device) - if attention_mask is None: - attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + past_key_values_length=past_key_values_length, + ) - if token_type_ids is None: - if hasattr(self.embeddings, "token_type_ids"): - buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] - buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) - token_type_ids = buffered_token_type_ids_expanded - else: - token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) - - # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] - # ourselves in which case we just need to make it broadcastable to all heads. - extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) - - # If a 2D or 3D attention mask is provided for the cross-attention - # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] - if self.config.is_decoder and encoder_hidden_states is not None: - encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() - encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) - if encoder_attention_mask is None: - encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) - encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) - else: - encoder_extended_attention_mask = None + attention_mask, encoder_attention_mask = self._create_attention_masks( + input_shape=input_shape, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + embedding_output=embedding_output, + encoder_hidden_states=encoder_hidden_states, + cache_position=cache_position, + past_key_values=past_key_values, + ) # Prepare head mask if needed # 1.0 in head_mask indicate we keep the head @@ -811,42 +907,141 @@ def forward( # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) - embedding_output = self.embeddings( - input_ids=input_ids, - position_ids=position_ids, - token_type_ids=token_type_ids, - inputs_embeds=inputs_embeds, - past_key_values_length=past_key_values_length, - ) encoder_outputs = self.encoder( embedding_output, lang_ids=lang_ids, - attention_mask=extended_attention_mask, + attention_mask=attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_extended_attention_mask, + encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + position_ids=position_ids, + **kwargs, ) sequence_output = encoder_outputs[0] pooled_output = self.pooler(sequence_output) if self.pooler is not None else None - if not return_dict: - return (sequence_output, pooled_output) + encoder_outputs[1:] + if return_legacy_cache: + encoder_outputs.past_key_values = encoder_outputs.past_key_values.to_legacy_cache() return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, - hidden_states=encoder_outputs.hidden_states, - attentions=encoder_outputs.attentions, - cross_attentions=encoder_outputs.cross_attentions, ) + # Copied from transformers.models.bert.modeling_bert.BertModel._create_attention_masks + def _create_attention_masks( + self, + input_shape, + attention_mask, + encoder_attention_mask, + embedding_output, + encoder_hidden_states, + cache_position, + past_key_values, + ): + if attention_mask is not None and attention_mask.dim() == 2: + if self.config.is_decoder: + attention_mask = create_causal_mask( + config=self.config, + input_embeds=embedding_output, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + ) + else: + attention_mask = self._update_full_mask( + attention_mask, + embedding_output, + ) + elif attention_mask is not None and attention_mask.dim() == 3: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + if encoder_attention_mask is not None: + if encoder_attention_mask.dim() == 2: + encoder_attention_mask = self._update_cross_attn_mask( + encoder_hidden_states, + encoder_attention_mask, + embedding_output.shape[:2], + embedding_output, + ) + else: + if "flash" in self.config._attn_implementation or self.config._attn_implementation == "flex_attention": + raise ValueError( + "Passing attention mask with a 3D/4D shape does not work with type " + f"{self.config._attn_implementation} - please use either `sdpa` or `eager` instead." + ) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + + return attention_mask, encoder_attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_full_mask + def _update_full_mask( + self, + attention_mask: Union[torch.Tensor, None], + inputs_embeds: torch.Tensor, + ): + if attention_mask is not None: + if "flash" in self.config._attn_implementation: + attention_mask = attention_mask if 0 in attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & head_mask can not be supported when using SDPA, fall back to + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask_for_sdpa(attention_mask, inputs_embeds.dtype) + elif self.config._attn_implementation == "flex_attention": + if isinstance(attention_mask, torch.Tensor): + attention_mask = make_flex_block_causal_mask(attention_mask, is_causal=False) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _prepare_4d_attention_mask(attention_mask, inputs_embeds.dtype) + + return attention_mask + + # Copied from transformers.models.bart.modeling_bart.BartPreTrainedModel._update_cross_attn_mask + def _update_cross_attn_mask( + self, + encoder_hidden_states: Union[torch.Tensor, None], + encoder_attention_mask: Union[torch.Tensor, None], + input_shape: torch.Size, + inputs_embeds: torch.Tensor, + ): + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + if "flash" in self.config._attn_implementation: + encoder_attention_mask = encoder_attention_mask if 0 in encoder_attention_mask else None + elif self.config._attn_implementation == "sdpa": + # output_attentions=True & cross_attn_head_mask can not be supported when using SDPA, and we fall back on + # the manual implementation that requires a 4D causal mask in all cases. + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask_for_sdpa( + encoder_attention_mask, + inputs_embeds.dtype, + tgt_len=input_shape[-1], + ) + elif self.config._attn_implementation == "flex_attention": + if isinstance(encoder_attention_mask, torch.Tensor): + encoder_attention_mask = make_flex_block_causal_mask( + encoder_attention_mask, + query_length=input_shape[-1], + is_causal=False, + ) + else: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _prepare_4d_attention_mask( + encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1] + ) + + return encoder_attention_mask + @auto_docstring( custom_intro=""" @@ -877,6 +1072,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -890,13 +1086,10 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - past_key_values: Optional[Cache] = None, + past_key_values: Optional[tuple[tuple[torch.FloatTensor]]] = None, use_cache: Optional[bool] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, cache_position: Optional[torch.Tensor] = None, - **kwargs, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: r""" lang_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -924,7 +1117,6 @@ def forward( >>> prediction_logits = outputs.logits ```""" - return_dict = return_dict if return_dict is not None else self.config.use_return_dict if labels is not None: use_cache = False @@ -940,10 +1132,9 @@ def forward( encoder_attention_mask=encoder_attention_mask, past_key_values=past_key_values, use_cache=use_cache, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, cache_position=cache_position, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -958,10 +1149,6 @@ def forward( **kwargs, ) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((lm_loss,) + output) if lm_loss is not None else output - return CausalLMOutputWithCrossAttentions( loss=lm_loss, logits=prediction_scores, @@ -1000,6 +1187,7 @@ def get_output_embeddings(self): def set_output_embeddings(self, new_embeddings): self.lm_head.decoder = new_embeddings + @can_return_tuple @auto_docstring def forward( self, @@ -1013,9 +1201,7 @@ def forward( encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MaskedLMOutput]: r""" lang_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1026,8 +1212,6 @@ def forward( config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, lang_ids=lang_ids, @@ -1038,9 +1222,8 @@ def forward( inputs_embeds=inputs_embeds, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_attention_mask, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] prediction_scores = self.lm_head(sequence_output) @@ -1050,10 +1233,6 @@ def forward( loss_fct = CrossEntropyLoss() masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) - if not return_dict: - output = (prediction_scores,) + outputs[2:] - return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output - return MaskedLMOutput( loss=masked_lm_loss, logits=prediction_scores, @@ -1113,6 +1292,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1124,9 +1304,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], SequenceClassifierOutput]: r""" lang_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1137,8 +1315,6 @@ def forward( config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, lang_ids=lang_ids, @@ -1147,9 +1323,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] logits = self.classifier(sequence_output) @@ -1177,10 +1352,6 @@ def forward( loss_fct = BCEWithLogitsLoss() loss = loss_fct(logits, labels) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return SequenceClassifierOutput( loss=loss, logits=logits, @@ -1202,6 +1373,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1213,9 +1385,7 @@ def forward( position_ids: Optional[torch.LongTensor] = None, head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], MultipleChoiceModelOutput]: r""" input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`): @@ -1250,7 +1420,6 @@ def forward( is useful if you want more control over how to convert `input_ids` indices into associated vectors than the model's internal embedding lookup matrix. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None @@ -1272,9 +1441,8 @@ def forward( attention_mask=flat_attention_mask, head_mask=head_mask, inputs_embeds=flat_inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) pooled_output = outputs[1] @@ -1287,10 +1455,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(reshaped_logits, labels) - if not return_dict: - output = (reshaped_logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return MultipleChoiceModelOutput( loss=loss, logits=reshaped_logits, @@ -1316,6 +1480,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1327,9 +1492,7 @@ def forward( head_mask: Optional[torch.FloatTensor] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]: r""" lang_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): @@ -1338,8 +1501,6 @@ def forward( labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, lang_ids=lang_ids, @@ -1348,9 +1509,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1363,10 +1523,6 @@ def forward( loss_fct = CrossEntropyLoss() loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) - if not return_dict: - output = (logits,) + outputs[2:] - return ((loss,) + output) if loss is not None else output - return TokenClassifierOutput( loss=loss, logits=logits, @@ -1411,6 +1567,7 @@ def __init__(self, config): # Initialize weights and apply final processing self.post_init() + @can_return_tuple @auto_docstring def forward( self, @@ -1423,17 +1580,13 @@ def forward( inputs_embeds: Optional[torch.FloatTensor] = None, start_positions: Optional[torch.LongTensor] = None, end_positions: Optional[torch.LongTensor] = None, - output_attentions: Optional[bool] = None, - output_hidden_states: Optional[bool] = None, - return_dict: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], ) -> Union[tuple[torch.Tensor], QuestionAnsweringModelOutput]: r""" lang_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): Indices of the language adapters that should be activated for each sample, respectively. Default: the index that corresponds to `self.config.default_language`. """ - return_dict = return_dict if return_dict is not None else self.config.use_return_dict - outputs = self.roberta( input_ids, lang_ids=lang_ids, @@ -1442,9 +1595,8 @@ def forward( position_ids=position_ids, head_mask=head_mask, inputs_embeds=inputs_embeds, - output_attentions=output_attentions, - output_hidden_states=output_hidden_states, - return_dict=return_dict, + return_dict=True, + **kwargs, ) sequence_output = outputs[0] @@ -1471,10 +1623,6 @@ def forward( end_loss = loss_fct(end_logits, end_positions) total_loss = (start_loss + end_loss) / 2 - if not return_dict: - output = (start_logits, end_logits) + outputs[2:] - return ((total_loss,) + output) if total_loss is not None else output - return QuestionAnsweringModelOutput( loss=total_loss, start_logits=start_logits, @@ -1484,23 +1632,6 @@ def forward( ) -# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids -def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): - """ - Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols - are ignored. This is modified from fairseq's `utils.make_positions`. - - Args: - x: torch.Tensor x: - - Returns: torch.Tensor - """ - # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. - mask = input_ids.ne(padding_idx).int() - incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask - return incremental_indices.long() + padding_idx - - __all__ = [ "XmodForCausalLM", "XmodForMaskedLM", diff --git a/tests/models/albert/test_modeling_albert.py b/tests/models/albert/test_modeling_albert.py index eb857f3383c9..193143d7b46a 100644 --- a/tests/models/albert/test_modeling_albert.py +++ b/tests/models/albert/test_modeling_albert.py @@ -54,12 +54,12 @@ def __init__( use_labels=True, vocab_size=32, embedding_size=8, - hidden_size=12, + hidden_size=16, num_hidden_layers=2, # this needs to be the same as `num_hidden_layers`! num_hidden_groups=2, num_attention_heads=4, - intermediate_size=16, + intermediate_size=20, hidden_act="gelu", hidden_dropout_prob=0.1, attention_probs_dropout_prob=0.1, @@ -260,7 +260,7 @@ class AlbertModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): if is_torch_available() else {} ) - fx_compatible = True + fx_compatible = False # will not be maintained # special case for ForPreTraining model def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): @@ -311,6 +311,7 @@ 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 + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_model(*config_and_inputs) @slow diff --git a/tests/models/bert/test_modeling_bert.py b/tests/models/bert/test_modeling_bert.py index 8d33d9dc1b22..19094754f8bb 100644 --- a/tests/models/bert/test_modeling_bert.py +++ b/tests/models/bert/test_modeling_bert.py @@ -11,16 +11,16 @@ # 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. +import inspect +import tempfile import unittest import pytest from packaging import version from transformers import AutoTokenizer, BertConfig, is_torch_available -from transformers.cache_utils import EncoderDecoderCache from transformers.models.auto import get_values from transformers.testing_utils import ( - CaptureLogger, require_torch, slow, torch_device, @@ -46,7 +46,7 @@ BertForTokenClassification, BertLMHeadModel, BertModel, - logging, + DataCollatorWithFlattening, ) @@ -462,7 +462,7 @@ class BertModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin if is_torch_available() else {} ) - fx_compatible = True + fx_compatible = False # won't be maintained model_split_percents = [0.5, 0.8, 0.9] # special case for ForPreTraining model @@ -479,6 +479,12 @@ def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): ) return inputs_dict + # Overwriting to add `is_decoder` flag + def prepare_config_and_inputs_for_generate(self, batch_size=2): + config, inputs = super().prepare_config_and_inputs_for_generate(batch_size) + config.is_decoder = True + return config, inputs + def setUp(self): self.model_tester = BertModelTester(self) self.config_tester = ConfigTester(self, config_class=BertConfig, hidden_size=37) @@ -494,6 +500,7 @@ 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 + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_model(*config_and_inputs) def test_model_3d_mask_shapes(self): @@ -584,6 +591,7 @@ def test_decoder_model_past_with_large_inputs(self): def test_decoder_model_past_with_large_inputs_relative_pos_emb(self): config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() config_and_inputs[0].position_embedding_type = "relative_key" + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) def test_for_multiple_choice(self): @@ -610,38 +618,126 @@ def test_for_token_classification(self): config_and_inputs = self.model_tester.prepare_config_and_inputs() self.model_tester.create_and_check_for_token_classification(*config_and_inputs) - def test_for_warning_if_padding_and_no_attention_mask(self): - ( - config, - input_ids, - token_type_ids, - input_mask, - sequence_labels, - token_labels, - choice_labels, - ) = self.model_tester.prepare_config_and_inputs() - - # Set pad tokens in the input_ids - input_ids[0, 0] = config.pad_token_id - - # Check for warnings if the attention_mask is missing. - logger = logging.get_logger("transformers.modeling_utils") - # clear cache so we can test the warning is emitted (from `warning_once`). - logger.warning_once.cache_clear() - - with CaptureLogger(logger) as cl: - model = BertModel(config=config) - model.to(torch_device) - model.eval() - model(input_ids, attention_mask=None, token_type_ids=token_type_ids) - self.assertIn("We strongly recommend passing in an `attention_mask`", cl.out) - @slow def test_model_from_pretrained(self): model_name = "google-bert/bert-base-uncased" model = BertModel.from_pretrained(model_name) self.assertIsNotNone(model) + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Overwritten to account for the embeddings that rely on position ids. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + # Main difference to other models, we need to prepare position ids according to the attention mask + # as we use it to extract embeddings that rely on the correct position - naively increasing sequences do + # not suffice anymore atp. The solution here calculates an increasing sequences for all 1s and puts 0s else. + inputs_dict["position_ids"] = ((inputs_dict["attention_mask"] == 1).long().cumsum(dim=1) - 1) * ( + inputs_dict["attention_mask"] == 1 + ).long() + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + @require_torch class BertModelIntegrationTest(unittest.TestCase): @@ -660,7 +756,9 @@ def test_inference_no_head_absolute_embedding(self): @slow def test_inference_no_head_relative_embedding_key(self): - model = BertModel.from_pretrained("zhiheng-huang/bert-base-uncased-embedding-relative-key") + model = BertModel.from_pretrained( + "zhiheng-huang/bert-base-uncased-embedding-relative-key", attn_implementation="eager" + ) input_ids = torch.tensor([[0, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 2]]) attention_mask = torch.tensor([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) with torch.no_grad(): @@ -675,7 +773,9 @@ def test_inference_no_head_relative_embedding_key(self): @slow def test_inference_no_head_relative_embedding_key_query(self): - model = BertModel.from_pretrained("zhiheng-huang/bert-base-uncased-embedding-relative-key-query") + model = BertModel.from_pretrained( + "zhiheng-huang/bert-base-uncased-embedding-relative-key-query", attn_implementation="eager" + ) input_ids = torch.tensor([[0, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 2]]) attention_mask = torch.tensor([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) with torch.no_grad(): @@ -688,41 +788,6 @@ def test_inference_no_head_relative_embedding_key_query(self): torch.testing.assert_close(output[:, 1:4, 1:4], expected_slice, rtol=1e-4, atol=1e-4) - def test_sdpa_ignored_mask(self): - pkv = [] - - model = BertModel.from_pretrained("hf-internal-testing/tiny-random-BertModel", attn_implementation="eager") - model_sdpa = BertModel.from_pretrained("hf-internal-testing/tiny-random-BertModel", attn_implementation="sdpa") - - model = model.eval() - model_sdpa = model_sdpa.eval() - - for _ in range(model.config.num_hidden_layers): - num_heads = model.config.num_attention_heads - head_dim = model.config.hidden_size // model.config.num_attention_heads - pkv.append([torch.rand(1, num_heads, 3, head_dim), torch.rand(1, num_heads, 3, head_dim)]) - - tokenizer = AutoTokenizer.from_pretrained("hf-internal-testing/tiny-random-BertModel") - inp = tokenizer("I am in Paris and", return_tensors="pt") - - del inp["attention_mask"] - - with torch.no_grad(): - res_eager = model(**inp) - res_sdpa = model_sdpa(**inp) - self.assertTrue( - torch.allclose(res_eager.last_hidden_state, res_sdpa.last_hidden_state, atol=1e-5, rtol=1e-4) - ) - - # Case where query length != kv_length. Note that model needs to be a decoder so we can use cache - model.config.is_decoder = True - model_sdpa.config.is_decoder = True - res_eager = model(**inp, past_key_values=EncoderDecoderCache.from_legacy_cache(pkv), use_cache=True) - res_sdpa = model_sdpa(**inp, past_key_values=EncoderDecoderCache.from_legacy_cache(pkv), use_cache=True) - self.assertTrue( - torch.allclose(res_eager.last_hidden_state, res_sdpa.last_hidden_state, atol=1e-5, rtol=1e-4) - ) - @slow @pytest.mark.torch_export_test def test_export(self): diff --git a/tests/models/bert_generation/test_modeling_bert_generation.py b/tests/models/bert_generation/test_modeling_bert_generation.py index e639f31073a4..eecb9205df3e 100644 --- a/tests/models/bert_generation/test_modeling_bert_generation.py +++ b/tests/models/bert_generation/test_modeling_bert_generation.py @@ -13,6 +13,8 @@ # limitations under the License. +import inspect +import tempfile import unittest from transformers import BertGenerationConfig, is_torch_available @@ -27,7 +29,7 @@ if is_torch_available(): import torch - from transformers import BertGenerationDecoder, BertGenerationEncoder + from transformers import BertGenerationDecoder, BertGenerationEncoder, DataCollatorWithFlattening class BertGenerationEncoderTester: @@ -248,6 +250,12 @@ class BertGenerationEncoderTest(ModelTesterMixin, GenerationTesterMixin, Pipelin else {} ) + # Overwriting to add `is_decoder` flag + def prepare_config_and_inputs_for_generate(self, batch_size=2): + config, inputs = super().prepare_config_and_inputs_for_generate(batch_size) + config.is_decoder = True + return config, inputs + def setUp(self): self.model_tester = BertGenerationEncoderTester(self) self.config_tester = ConfigTester(self, config_class=BertGenerationConfig, hidden_size=37) @@ -302,12 +310,128 @@ def test_model_from_pretrained(self): model = BertGenerationEncoder.from_pretrained("google/bert_for_seq_generation_L-24_bbc_encoder") self.assertIsNotNone(model) + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Overwritten to account for the embeddings that rely on position ids. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + # Main difference to other models, we need to prepare position ids according to the attention mask + # as we use it to extract embeddings that rely on the correct position - naively increasing sequences do + # not suffice anymore atp. The solution here calculates an increasing sequences for all 1s and puts 0s else. + inputs_dict["position_ids"] = ((inputs_dict["attention_mask"] == 1).long().cumsum(dim=1) - 1) * ( + inputs_dict["attention_mask"] == 1 + ).long() + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + @require_torch class BertGenerationEncoderIntegrationTest(unittest.TestCase): @slow def test_inference_no_head_absolute_embedding(self): - model = BertGenerationEncoder.from_pretrained("google/bert_for_seq_generation_L-24_bbc_encoder") + model = BertGenerationEncoder.from_pretrained( + "google/bert_for_seq_generation_L-24_bbc_encoder", attn_implementation="eager" + ) input_ids = torch.tensor([[101, 7592, 1010, 2026, 3899, 2003, 10140, 102]]) with torch.no_grad(): output = model(input_ids)[0] @@ -323,7 +447,9 @@ def test_inference_no_head_absolute_embedding(self): class BertGenerationDecoderIntegrationTest(unittest.TestCase): @slow def test_inference_no_head_absolute_embedding(self): - model = BertGenerationDecoder.from_pretrained("google/bert_for_seq_generation_L-24_bbc_encoder") + model = BertGenerationDecoder.from_pretrained( + "google/bert_for_seq_generation_L-24_bbc_encoder", attn_implementation="eager" + ) input_ids = torch.tensor([[101, 7592, 1010, 2026, 3899, 2003, 10140, 102]]) with torch.no_grad(): output = model(input_ids)[0] diff --git a/tests/models/data2vec/test_modeling_data2vec_text.py b/tests/models/data2vec/test_modeling_data2vec_text.py index acb18b3d8e89..59f86c88cd6c 100644 --- a/tests/models/data2vec/test_modeling_data2vec_text.py +++ b/tests/models/data2vec/test_modeling_data2vec_text.py @@ -13,6 +13,8 @@ # limitations under the License. """Testing suite for the PyTorch Data2VecAudio model.""" +import inspect +import tempfile import unittest from tests.test_modeling_common import floats_tensor, ids_tensor, random_attention_mask @@ -36,11 +38,9 @@ Data2VecTextForSequenceClassification, Data2VecTextForTokenClassification, Data2VecTextModel, + DataCollatorWithFlattening, ) - from transformers.models.data2vec.modeling_data2vec_text import ( - Data2VecTextForTextEmbeddings, - create_position_ids_from_input_ids, - ) + from transformers.models.data2vec.modeling_data2vec_text import Data2VecTextEmbeddings class Data2VecTextModelTester: @@ -387,6 +387,12 @@ class Data2VecTextModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTes ) model_split_percents = [0.5, 0.9] + # Overwriting to add `is_decoder` flag + def prepare_config_and_inputs_for_generate(self, batch_size=2): + config, inputs = super().prepare_config_and_inputs_for_generate(batch_size) + config.is_decoder = True + return config, inputs + def setUp(self): self.model_tester = Data2VecTextModelTester(self) self.config_tester = ConfigTester(self, config_class=Data2VecTextConfig, hidden_size=37) @@ -402,6 +408,7 @@ 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 + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_model(*config_and_inputs) def test_model_as_decoder(self): @@ -446,6 +453,7 @@ def test_decoder_model_past_with_large_inputs(self): def test_decoder_model_past_with_large_inputs_relative_pos_emb(self): config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() config_and_inputs[0].position_embedding_type = "relative_key" + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) def test_for_masked_lm(self): @@ -477,14 +485,14 @@ def test_create_position_ids_respects_padding_index(self): first available non-padding position index is Data2VecTextForTextEmbeddings.padding_idx + 1 """ config = self.model_tester.prepare_config_and_inputs()[0] - model = Data2VecTextForTextEmbeddings(config=config) + model = Data2VecTextEmbeddings(config=config) input_ids = torch.as_tensor([[12, 31, 13, model.padding_idx]]) expected_positions = torch.as_tensor( [[0 + model.padding_idx + 1, 1 + model.padding_idx + 1, 2 + model.padding_idx + 1, model.padding_idx]] ) - position_ids = create_position_ids_from_input_ids(input_ids, model.padding_idx) + position_ids = Data2VecTextEmbeddings.create_position_ids_from_input_ids(input_ids, model.padding_idx) self.assertEqual(position_ids.shape, expected_positions.shape) self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) @@ -495,7 +503,7 @@ def test_create_position_ids_from_inputs_embeds(self): first available non-padding position index is Data2VecTextForTextEmbeddings.padding_idx + 1 """ config = self.model_tester.prepare_config_and_inputs()[0] - embeddings = Data2VecTextForTextEmbeddings(config=config) + embeddings = Data2VecTextEmbeddings(config=config) inputs_embeds = torch.empty(2, 4, 30) expected_single_positions = [ @@ -505,10 +513,124 @@ def test_create_position_ids_from_inputs_embeds(self): 3 + embeddings.padding_idx + 1, ] expected_positions = torch.as_tensor([expected_single_positions, expected_single_positions]) - position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds, embeddings.padding_idx) self.assertEqual(position_ids.shape, expected_positions.shape) self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Overwritten to account for the embeddings that rely on position ids. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + # Main difference to other models, we need to prepare position ids according to the attention mask + # as we use it to extract embeddings that rely on the correct position - naively increasing sequences do + # not suffice anymore atp. The solution here calculates an increasing sequences for all 1s and puts 0s else. + inputs_dict["position_ids"] = ((inputs_dict["attention_mask"] == 1).long().cumsum(dim=1) - 1) * ( + inputs_dict["attention_mask"] == 1 + ).long() + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + @require_torch class Data2VecTextModelIntegrationTest(TestCasePlus): diff --git a/tests/models/electra/test_modeling_electra.py b/tests/models/electra/test_modeling_electra.py index 7d451ff6378a..3a1823cc8c01 100644 --- a/tests/models/electra/test_modeling_electra.py +++ b/tests/models/electra/test_modeling_electra.py @@ -13,12 +13,15 @@ # limitations under the License. +import inspect +import tempfile import unittest from transformers import ElectraConfig, is_torch_available from transformers.models.auto import get_values 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, floats_tensor, ids_tensor, random_attention_mask from ...test_pipeline_mixin import PipelineTesterMixin @@ -29,6 +32,7 @@ from transformers import ( MODEL_FOR_PRETRAINING_MAPPING, + DataCollatorWithFlattening, ElectraForCausalLM, ElectraForMaskedLM, ElectraForMultipleChoice, @@ -373,7 +377,7 @@ def prepare_config_and_inputs_for_common(self): @require_torch -class ElectraModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): +class ElectraModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): all_model_classes = ( ( ElectraModel, @@ -388,8 +392,6 @@ class ElectraModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase) if is_torch_available() else () ) - # Doesn't run generation tests. There are interface mismatches when using `generate` -- TODO @gante - all_generative_model_classes = () pipeline_model_mapping = ( { "feature-extraction": ElectraModel, @@ -403,7 +405,13 @@ class ElectraModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase) if is_torch_available() else {} ) - fx_compatible = True + fx_compatible = False # won't be maintained + + # Overwriting to add `is_decoder` flag + def prepare_config_and_inputs_for_generate(self, batch_size=2): + config, inputs = super().prepare_config_and_inputs_for_generate(batch_size) + config.is_decoder = True + return config, inputs # special case for ForPreTraining model def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): @@ -435,6 +443,7 @@ def test_electra_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 + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_electra_model(*config_and_inputs) def test_for_masked_lm(self): @@ -471,6 +480,120 @@ def test_for_causal_lm(self): config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() self.model_tester.create_and_check_electra_for_causal_lm(*config_and_inputs) + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Overwritten to account for the embeddings that rely on position ids. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + # Main difference to other models, we need to prepare position ids according to the attention mask + # as we use it to extract embeddings that rely on the correct position - naively increasing sequences do + # not suffice anymore atp. The solution here calculates an increasing sequences for all 1s and puts 0s else. + inputs_dict["position_ids"] = ((inputs_dict["attention_mask"] == 1).long().cumsum(dim=1) - 1) * ( + inputs_dict["attention_mask"] == 1 + ).long() + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + @require_torch class ElectraModelIntegrationTest(unittest.TestCase): diff --git a/tests/models/encoder_decoder/test_modeling_encoder_decoder.py b/tests/models/encoder_decoder/test_modeling_encoder_decoder.py index 3d39e973637d..a6b12a9f65ae 100644 --- a/tests/models/encoder_decoder/test_modeling_encoder_decoder.py +++ b/tests/models/encoder_decoder/test_modeling_encoder_decoder.py @@ -807,11 +807,14 @@ def test_relative_position_embeds(self): encoder_config = config_and_inputs["config"] decoder_config = config_and_inputs["decoder_config"] + encoder_config._attn_implementation = "eager" + decoder_config._attn_implementation = "eager" encoder_config.position_embedding_type = "relative_key_query" decoder_config.position_embedding_type = "relative_key_query" - config = EncoderDecoderConfig.from_encoder_decoder_configs(encoder_config, decoder_config) - model = EncoderDecoderModel(config).eval().to(torch_device) + encoder_model, decoder_model = self.get_encoder_decoder_model(encoder_config, decoder_config) + model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model).eval().to(torch_device) + model.config._attn_implementation = "eager" # model config -> won't work logits = model( input_ids=config_and_inputs["input_ids"], decoder_input_ids=config_and_inputs["decoder_input_ids"] diff --git a/tests/models/ernie/test_modeling_ernie.py b/tests/models/ernie/test_modeling_ernie.py index 86500deeda50..a500a32e3236 100644 --- a/tests/models/ernie/test_modeling_ernie.py +++ b/tests/models/ernie/test_modeling_ernie.py @@ -11,6 +11,8 @@ # 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. +import inspect +import tempfile import unittest from transformers import ErnieConfig, is_torch_available @@ -28,6 +30,7 @@ from transformers import ( MODEL_FOR_PRETRAINING_MAPPING, + DataCollatorWithFlattening, ErnieForCausalLM, ErnieForMaskedLM, ErnieForMultipleChoice, @@ -454,6 +457,12 @@ class ErnieModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixi ) fx_compatible = False + # Overwriting to add `is_decoder` flag + def prepare_config_and_inputs_for_generate(self, batch_size=2): + config, inputs = super().prepare_config_and_inputs_for_generate(batch_size) + config.is_decoder = True + return config, inputs + # special case for ForPreTraining model def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) @@ -483,6 +492,7 @@ 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 + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_model(*config_and_inputs) def test_model_as_decoder(self): @@ -535,6 +545,7 @@ def test_decoder_model_past_with_large_inputs(self): def test_decoder_model_past_with_large_inputs_relative_pos_emb(self): config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() config_and_inputs[0].position_embedding_type = "relative_key" + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) def test_for_multiple_choice(self): @@ -566,3 +577,117 @@ def test_model_from_pretrained(self): model_name = "nghuyong/ernie-1.0-base-zh" model = ErnieModel.from_pretrained(model_name) self.assertIsNotNone(model) + + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Overwritten to account for the embeddings that rely on position ids. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + # Main difference to other models, we need to prepare position ids according to the attention mask + # as we use it to extract embeddings that rely on the correct position - naively increasing sequences do + # not suffice anymore atp. The solution here calculates an increasing sequences for all 1s and puts 0s else. + inputs_dict["position_ids"] = ((inputs_dict["attention_mask"] == 1).long().cumsum(dim=1) - 1) * ( + inputs_dict["attention_mask"] == 1 + ).long() + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) diff --git a/tests/models/mobilebert/test_modeling_mobilebert.py b/tests/models/mobilebert/test_modeling_mobilebert.py index 72bc842ec9c8..db2215696fd7 100644 --- a/tests/models/mobilebert/test_modeling_mobilebert.py +++ b/tests/models/mobilebert/test_modeling_mobilebert.py @@ -283,7 +283,7 @@ class MobileBertModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCa if is_torch_available() else {} ) - fx_compatible = True + fx_compatible = False # won't be maintained # special case for ForPreTraining model def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): @@ -361,7 +361,9 @@ def _long_tensor(tok_lst): class MobileBertModelIntegrationTests(unittest.TestCase): @slow def test_inference_no_head(self): - model = MobileBertModel.from_pretrained("google/mobilebert-uncased").to(torch_device) + model = MobileBertModel.from_pretrained("google/mobilebert-uncased", attn_implementation="eager").to( + torch_device + ) input_ids = _long_tensor([[101, 7110, 1005, 1056, 2023, 11333, 17413, 1029, 102]]) with torch.no_grad(): output = model(input_ids)[0] diff --git a/tests/models/roberta/test_modeling_roberta.py b/tests/models/roberta/test_modeling_roberta.py index 5001438e4c6e..009e9dfc22c1 100644 --- a/tests/models/roberta/test_modeling_roberta.py +++ b/tests/models/roberta/test_modeling_roberta.py @@ -12,7 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. - +import inspect +import tempfile import unittest import pytest @@ -30,6 +31,7 @@ import torch from transformers import ( + DataCollatorWithFlattening, RobertaForCausalLM, RobertaForMaskedLM, RobertaForMultipleChoice, @@ -38,10 +40,7 @@ RobertaForTokenClassification, RobertaModel, ) - from transformers.models.roberta.modeling_roberta import ( - RobertaEmbeddings, - create_position_ids_from_input_ids, - ) + from transformers.models.roberta.modeling_roberta import RobertaEmbeddings from transformers.pytorch_utils import is_torch_greater_or_equal_than_2_4 ROBERTA_TINY = "sshleifer/tiny-distilroberta-base" @@ -394,9 +393,15 @@ class RobertaModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMi if is_torch_available() else {} ) - fx_compatible = True + fx_compatible = False # won't be maintained model_split_percents = [0.5, 0.8, 0.9] + # Overwriting to add `is_decoder` flag + def prepare_config_and_inputs_for_generate(self, batch_size=2): + config, inputs = super().prepare_config_and_inputs_for_generate(batch_size) + config.is_decoder = True + return config, inputs + def setUp(self): self.model_tester = RobertaModelTester(self) self.config_tester = ConfigTester(self, config_class=RobertaConfig, hidden_size=37) @@ -412,6 +417,7 @@ 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 + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_model(*config_and_inputs) def test_model_as_decoder(self): @@ -456,6 +462,7 @@ def test_decoder_model_past_with_large_inputs(self): def test_decoder_model_past_with_large_inputs_relative_pos_emb(self): config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() config_and_inputs[0].position_embedding_type = "relative_key" + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) def test_for_masked_lm(self): @@ -494,7 +501,7 @@ def test_create_position_ids_respects_padding_index(self): [[0 + model.padding_idx + 1, 1 + model.padding_idx + 1, 2 + model.padding_idx + 1, model.padding_idx]] ) - position_ids = create_position_ids_from_input_ids(input_ids, model.padding_idx) + position_ids = RobertaEmbeddings.create_position_ids_from_input_ids(input_ids, model.padding_idx) self.assertEqual(position_ids.shape, expected_positions.shape) self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) @@ -515,10 +522,124 @@ def test_create_position_ids_from_inputs_embeds(self): 3 + embeddings.padding_idx + 1, ] expected_positions = torch.as_tensor([expected_single_positions, expected_single_positions]) - position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds, embeddings.padding_idx) self.assertEqual(position_ids.shape, expected_positions.shape) self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Overwritten to account for the embeddings that rely on position ids. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + # Main difference to other models, we need to prepare position ids according to the attention mask + # as we use it to extract embeddings that rely on the correct position - naively increasing sequences do + # not suffice anymore atp. The solution here calculates an increasing sequences for all 1s and puts 0s else. + inputs_dict["position_ids"] = ((inputs_dict["attention_mask"] == 1).long().cumsum(dim=1) - 1) * ( + inputs_dict["attention_mask"] == 1 + ).long() + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + @require_torch class RobertaModelIntegrationTest(TestCasePlus): diff --git a/tests/models/roberta_prelayernorm/test_modeling_roberta_prelayernorm.py b/tests/models/roberta_prelayernorm/test_modeling_roberta_prelayernorm.py index 7bb0de874d9e..7605be9e2c84 100644 --- a/tests/models/roberta_prelayernorm/test_modeling_roberta_prelayernorm.py +++ b/tests/models/roberta_prelayernorm/test_modeling_roberta_prelayernorm.py @@ -13,6 +13,8 @@ # limitations under the License. +import inspect +import tempfile import unittest from transformers import RobertaPreLayerNormConfig, is_torch_available @@ -28,6 +30,7 @@ import torch from transformers import ( + DataCollatorWithFlattening, RobertaPreLayerNormForCausalLM, RobertaPreLayerNormForMaskedLM, RobertaPreLayerNormForMultipleChoice, @@ -36,10 +39,7 @@ RobertaPreLayerNormForTokenClassification, RobertaPreLayerNormModel, ) - from transformers.models.roberta_prelayernorm.modeling_roberta_prelayernorm import ( - RobertaPreLayerNormEmbeddings, - create_position_ids_from_input_ids, - ) + from transformers.models.roberta_prelayernorm.modeling_roberta_prelayernorm import RobertaPreLayerNormEmbeddings # Copied from tests.models.roberta.test_modeling_roberta.RobertaModelTester with Roberta->RobertaPreLayerNorm @@ -393,6 +393,12 @@ class RobertaPreLayerNormModelTest(ModelTesterMixin, GenerationTesterMixin, Pipe fx_compatible = False model_split_percents = [0.5, 0.8, 0.9] + # Overwriting to add `is_decoder` flag + def prepare_config_and_inputs_for_generate(self, batch_size=2): + config, inputs = super().prepare_config_and_inputs_for_generate(batch_size) + config.is_decoder = True + return config, inputs + # Copied from tests.models.roberta.test_modeling_roberta.RobertaModelTest.setUp with Roberta->RobertaPreLayerNorm def setUp(self): self.model_tester = RobertaPreLayerNormModelTester(self) @@ -412,6 +418,7 @@ 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 + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_model(*config_and_inputs) # Copied from tests.models.roberta.test_modeling_roberta.RobertaModelTest.test_model_as_decoder @@ -498,7 +505,7 @@ def test_create_position_ids_respects_padding_index(self): [[0 + model.padding_idx + 1, 1 + model.padding_idx + 1, 2 + model.padding_idx + 1, model.padding_idx]] ) - position_ids = create_position_ids_from_input_ids(input_ids, model.padding_idx) + position_ids = RobertaPreLayerNormEmbeddings.create_position_ids_from_input_ids(input_ids, model.padding_idx) self.assertEqual(position_ids.shape, expected_positions.shape) self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) @@ -520,10 +527,124 @@ def test_create_position_ids_from_inputs_embeds(self): 3 + embeddings.padding_idx + 1, ] expected_positions = torch.as_tensor([expected_single_positions, expected_single_positions]) - position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds, embeddings.padding_idx) self.assertEqual(position_ids.shape, expected_positions.shape) self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Overwritten to account for the embeddings that rely on position ids. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + # Main difference to other models, we need to prepare position ids according to the attention mask + # as we use it to extract embeddings that rely on the correct position - naively increasing sequences do + # not suffice anymore atp. The solution here calculates an increasing sequences for all 1s and puts 0s else. + inputs_dict["position_ids"] = ((inputs_dict["attention_mask"] == 1).long().cumsum(dim=1) - 1) * ( + inputs_dict["attention_mask"] == 1 + ).long() + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + @require_torch class RobertaPreLayerNormModelIntegrationTest(TestCasePlus): diff --git a/tests/models/roc_bert/test_modeling_roc_bert.py b/tests/models/roc_bert/test_modeling_roc_bert.py index 55babab54b51..23a6017168a3 100644 --- a/tests/models/roc_bert/test_modeling_roc_bert.py +++ b/tests/models/roc_bert/test_modeling_roc_bert.py @@ -13,6 +13,8 @@ # limitations under the License. """Testing suite for the PyTorch RoCBert model.""" +import inspect +import tempfile import unittest from transformers import RoCBertConfig, is_torch_available @@ -29,6 +31,7 @@ from transformers import ( MODEL_FOR_PRETRAINING_MAPPING, + DataCollatorWithFlattening, RoCBertForCausalLM, RoCBertForMaskedLM, RoCBertForMultipleChoice, @@ -583,6 +586,12 @@ def is_pipeline_test_to_skip( return False + # Overwriting to add `is_decoder` flag + def prepare_config_and_inputs_for_generate(self, batch_size=2): + config, inputs = super().prepare_config_and_inputs_for_generate(batch_size) + config.is_decoder = True + return config, inputs + # special case for ForPreTraining model def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) @@ -624,6 +633,7 @@ 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 + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_model(*config_and_inputs) def test_for_masked_lm(self): @@ -641,6 +651,7 @@ def test_decoder_model_past_with_large_inputs(self): def test_decoder_model_past_with_large_inputs_relative_pos_emb(self): config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() config_and_inputs[0].position_embedding_type = "relative_key" + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) def test_for_question_answering(self): @@ -700,6 +711,131 @@ def test_model_from_pretrained(self): model = RoCBertModel.from_pretrained(model_name) self.assertIsNotNone(model) + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Overwritten to account for the embeddings that rely on position ids. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + # Main difference to other models, we need to prepare position ids according to the attention mask + # as we use it to extract embeddings that rely on the correct position - naively increasing sequences do + # not suffice anymore atp. The solution here calculates an increasing sequences for all 1s and puts 0s else. + inputs_dict["position_ids"] = ((inputs_dict["attention_mask"] == 1).long().cumsum(dim=1) - 1) * ( + inputs_dict["attention_mask"] == 1 + ).long() + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + + def flash_attn_inference_equivalence( + self, attn_implementation: str, padding_side: str, atol: float = 4e-2, rtol: float = 4e-2 + ): + super().flash_attn_inference_equivalence( + attn_implementation, + padding_side, + # relaxing the tolerance here + atol=6e-2, + rtol=4e-2, + ) + @require_torch class RoCBertModelIntegrationTest(unittest.TestCase): diff --git a/tests/models/sam2/test_modeling_sam2.py b/tests/models/sam2/test_modeling_sam2.py index a6584f034064..a19c6a13d220 100644 --- a/tests/models/sam2/test_modeling_sam2.py +++ b/tests/models/sam2/test_modeling_sam2.py @@ -608,7 +608,9 @@ def test_sdpa_can_dispatch_composite_models(self): raise ValueError("The eager model should not have SDPA attention layers") # Override as Sam2Model doesn't have hidden states - def flash_attn_inference_equivalence(self, attn_implementation: str, padding_side: str): + def flash_attn_inference_equivalence( + self, attn_implementation: str, padding_side: str, atol: float = 4e-2, rtol: float = 4e-2 + ): r""" Tests the equivalence between the eager and flash attention implementations. This test is only for inference and runs with `dtype=torch.bfloat16`. @@ -661,7 +663,7 @@ def flash_attn_inference_equivalence(self, attn_implementation: str, padding_sid logits = outputs.vision_hidden_states[-1] logits_fa = outputs_fa.vision_hidden_states[-1] - assert torch.allclose(logits_fa, logits, atol=4e-2, rtol=4e-2) + assert torch.allclose(logits_fa, logits, atol=atol, rtol=rtol) if model.config.is_encoder_decoder: other_inputs = { @@ -688,13 +690,13 @@ def flash_attn_inference_equivalence(self, attn_implementation: str, padding_sid logits_fa = outputs_fa.vision_hidden_states[-1] if padding_side == "left": - assert torch.allclose(logits_fa[1:], logits[1:], atol=4e-2, rtol=4e-2) + assert torch.allclose(logits_fa[1:], logits[1:], atol=atol, rtol=rtol) # check with inference + dropout model.train() _ = model_fa(dummy_input, **other_inputs) else: - assert torch.allclose(logits_fa[:-1], logits[:-1], atol=4e-2, rtol=4e-2) + assert torch.allclose(logits_fa[:-1], logits[:-1], atol=atol, rtol=rtol) # Override as difference slightly higher than the threshold def test_batching_equivalence(self, atol=5e-4, rtol=5e-4): diff --git a/tests/models/vision_text_dual_encoder/test_modeling_vision_text_dual_encoder.py b/tests/models/vision_text_dual_encoder/test_modeling_vision_text_dual_encoder.py index aef0d98bbdfa..e6d0a66c961b 100644 --- a/tests/models/vision_text_dual_encoder/test_modeling_vision_text_dual_encoder.py +++ b/tests/models/vision_text_dual_encoder/test_modeling_vision_text_dual_encoder.py @@ -135,8 +135,8 @@ def check_vision_text_output_attention( self, text_config, input_ids, attention_mask, vision_config, pixel_values=None, **kwargs ): # The backbones don't support dynamic attention setting, so we manually change it. FIXME; when bert is refactored - vision_config._attn_implementation = "eager" text_config._attn_implementation = "eager" + vision_config._attn_implementation = "eager" vision_model, text_model = self.get_vision_text_model(vision_config, text_config) model = VisionTextDualEncoderModel(vision_model=vision_model, text_model=text_model) model.to(torch_device) @@ -285,6 +285,9 @@ def get_pretrained_model_and_inputs(self): def check_vision_text_output_attention( self, text_config, input_ids, attention_mask, vision_config, pixel_values=None, **kwargs ): + # The backbones don't support dynamic attention setting, so we manually change it. FIXME; when bert is refactored + text_config._attn_implementation = "eager" + vision_config._attn_implementation = "eager" vision_model, text_model = self.get_vision_text_model(vision_config, text_config) model = VisionTextDualEncoderModel(vision_model=vision_model, text_model=text_model) model.to(torch_device) diff --git a/tests/models/xlm_roberta_xl/test_modeling_xlm_roberta_xl.py b/tests/models/xlm_roberta_xl/test_modeling_xlm_roberta_xl.py index 543f4ef841de..6ab20ba5feb0 100644 --- a/tests/models/xlm_roberta_xl/test_modeling_xlm_roberta_xl.py +++ b/tests/models/xlm_roberta_xl/test_modeling_xlm_roberta_xl.py @@ -13,6 +13,8 @@ # limitations under the License. +import inspect +import tempfile import unittest from transformers import XLMRobertaXLConfig, is_torch_available @@ -28,6 +30,7 @@ import torch from transformers import ( + DataCollatorWithFlattening, XLMRobertaXLForCausalLM, XLMRobertaXLForMaskedLM, XLMRobertaXLForMultipleChoice, @@ -36,10 +39,7 @@ XLMRobertaXLForTokenClassification, XLMRobertaXLModel, ) - from transformers.models.xlm_roberta_xl.modeling_xlm_roberta_xl import ( - XLMRobertaXLEmbeddings, - create_position_ids_from_input_ids, - ) + from transformers.models.xlm_roberta_xl.modeling_xlm_roberta_xl import XLMRobertaXLEmbeddings class XLMRobertaXLModelTester: @@ -403,6 +403,12 @@ def is_pipeline_test_to_skip( return False + # Overwriting to add `is_decoder` flag + def prepare_config_and_inputs_for_generate(self, batch_size=2): + config, inputs = super().prepare_config_and_inputs_for_generate(batch_size) + config.is_decoder = True + return config, inputs + def setUp(self): self.model_tester = XLMRobertaXLModelTester(self) self.config_tester = ConfigTester(self, config_class=XLMRobertaXLConfig, hidden_size=37) @@ -418,6 +424,7 @@ 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 + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_model(*config_and_inputs) def test_model_as_decoder(self): @@ -462,6 +469,7 @@ def test_decoder_model_past_with_large_inputs(self): def test_decoder_model_past_with_large_inputs_relative_pos_emb(self): config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() config_and_inputs[0].position_embedding_type = "relative_key" + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) def test_for_masked_lm(self): @@ -494,7 +502,7 @@ def test_create_position_ids_respects_padding_index(self): [[0 + model.padding_idx + 1, 1 + model.padding_idx + 1, 2 + model.padding_idx + 1, model.padding_idx]] ) - position_ids = create_position_ids_from_input_ids(input_ids, model.padding_idx) + position_ids = XLMRobertaXLEmbeddings.create_position_ids_from_input_ids(input_ids, model.padding_idx) self.assertEqual(position_ids.shape, expected_positions.shape) self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) @@ -515,10 +523,240 @@ def test_create_position_ids_from_inputs_embeds(self): 3 + embeddings.padding_idx + 1, ] expected_positions = torch.as_tensor([expected_single_positions, expected_single_positions]) - position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds, embeddings.padding_idx) self.assertEqual(position_ids.shape, expected_positions.shape) self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Overwritten to account for the embeddings that rely on position ids. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + # Main difference to other models, we need to prepare position ids according to the attention mask + # as we use it to extract embeddings that rely on the correct position - naively increasing sequences do + # not suffice anymore atp. The solution here calculates an increasing sequences for all 1s and puts 0s else. + inputs_dict["position_ids"] = ((inputs_dict["attention_mask"] == 1).long().cumsum(dim=1) - 1) * ( + inputs_dict["attention_mask"] == 1 + ).long() + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + + def flash_attn_inference_equivalence( + self, attn_implementation: str, padding_side: str, atol: float = 4e-2, rtol: float = 4e-2 + ): + r""" + Overwritten to enforce decoder behavior as the model is very easily influenced + by slight changes in the mask. One major reason for the high fluctuations is + the extra layernom at the end of the model which shifts the logits a lot. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.is_decoder = True + model = model_class(config) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model_fa = model_class.from_pretrained( + tmpdirname, torch_dtype=torch.bfloat16, attn_implementation=attn_implementation + ) + model_fa.to(torch_device) + + model = model_class.from_pretrained(tmpdirname, torch_dtype=torch.bfloat16) + model.to(torch_device) + + dummy_input = inputs_dict[model.main_input_name][:1] + if dummy_input.dtype in [torch.float32, torch.float16]: + dummy_input = dummy_input.to(torch.bfloat16) + + dummy_attention_mask = inputs_dict.get("attention_mask", None) + + if dummy_attention_mask is not None: + dummy_attention_mask = dummy_attention_mask[:1] + if padding_side == "left": + dummy_attention_mask[:, 1:] = 1 + dummy_attention_mask[:, :1] = 0 + else: + dummy_attention_mask[:, :-1] = 1 + dummy_attention_mask[:, -1:] = 0 + + # no attention mask + processed_inputs = { + model.main_input_name: dummy_input, + "output_hidden_states": True, + } + if model.config.is_encoder_decoder: + processed_inputs["decoder_input_ids"] = inputs_dict.get("decoder_input_ids", dummy_input)[:1] + + prepared_inputs = self._prepare_for_class(processed_inputs, model_class) + prepared_inputs = { + k: v.to(torch_device) if isinstance(v, torch.Tensor) else v for k, v in prepared_inputs.items() + } + + outputs = model(**prepared_inputs) + outputs_fa = model_fa(**prepared_inputs) + + logits = ( + outputs.hidden_states[-1] + if not model.config.is_encoder_decoder + else outputs.decoder_hidden_states[-1] + ) + logits_fa = ( + outputs_fa.hidden_states[-1] + if not model.config.is_encoder_decoder + else outputs_fa.decoder_hidden_states[-1] + ) + + assert torch.allclose(logits_fa, logits, atol=atol, rtol=rtol) + + # with attention mask + if dummy_attention_mask is not None: + processed_inputs["attention_mask"] = dummy_attention_mask + if model.config.is_encoder_decoder: + processed_inputs["decoder_attention_mask"] = dummy_attention_mask + + prepared_inputs = self._prepare_for_class(processed_inputs, model_class) + prepared_inputs = { + k: v.to(torch_device) if isinstance(v, torch.Tensor) else v for k, v in prepared_inputs.items() + } + + outputs = model(**prepared_inputs) + outputs_fa = model_fa(**prepared_inputs) + + logits = ( + outputs.hidden_states[-1] + if not model.config.is_encoder_decoder + else outputs.decoder_hidden_states[-1] + ) + logits_fa = ( + outputs_fa.hidden_states[-1] + if not model.config.is_encoder_decoder + else outputs_fa.decoder_hidden_states[-1] + ) + + if padding_side == "left": + assert torch.allclose(logits_fa[1:], logits[1:], atol=atol, rtol=rtol) + + # check with inference + dropout + model.train() + _ = model_fa(**prepared_inputs) + else: + assert torch.allclose(logits_fa[:-1], logits[:-1], atol=atol, rtol=rtol) + + @unittest.skip("XLM Roberta XL has some higher fluctuations, skipping for now (norm issue)") + def test_flash_attn_2_inference_equivalence_right_padding(self): + pass + + @unittest.skip("XLM Roberta XL doesn't work for some reason, FIXME") + def test_eager_padding_matches_padding_free_with_position_ids(self): + pass + + @unittest.skip("XLM Roberta XL doesn't work for some reason, FIXME") + def test_sdpa_padding_matches_padding_free_with_position_ids(self): + pass + @require_torch class XLMRobertaModelXLIntegrationTest(unittest.TestCase): diff --git a/tests/models/xmod/test_modeling_xmod.py b/tests/models/xmod/test_modeling_xmod.py index 8a0c90cd1fce..298c7ad3a27b 100644 --- a/tests/models/xmod/test_modeling_xmod.py +++ b/tests/models/xmod/test_modeling_xmod.py @@ -11,6 +11,8 @@ # 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. +import inspect +import tempfile import unittest from transformers import XLMRobertaTokenizer, is_torch_available @@ -26,6 +28,7 @@ import torch from transformers import ( + DataCollatorWithFlattening, XmodConfig, XmodForCausalLM, XmodForMaskedLM, @@ -35,7 +38,7 @@ XmodForTokenClassification, XmodModel, ) - from transformers.models.xmod.modeling_xmod import XmodEmbeddings, create_position_ids_from_input_ids + from transformers.models.xmod.modeling_xmod import XmodEmbeddings class XmodModelTester: @@ -398,6 +401,12 @@ def is_pipeline_test_to_skip( return False + # Overwriting to add `is_decoder` flag + def prepare_config_and_inputs_for_generate(self, batch_size=2): + config, inputs = super().prepare_config_and_inputs_for_generate(batch_size) + config.is_decoder = True + return config, inputs + def setUp(self): self.model_tester = XmodModelTester(self) self.config_tester = ConfigTester(self, config_class=XmodConfig, hidden_size=37) @@ -413,6 +422,7 @@ 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 + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_model(*config_and_inputs) def test_model_as_decoder(self): @@ -457,6 +467,7 @@ def test_decoder_model_past_with_large_inputs(self): def test_decoder_model_past_with_large_inputs_relative_pos_emb(self): config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() config_and_inputs[0].position_embedding_type = "relative_key" + config_and_inputs[0]._attn_implementation = "eager" self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) def test_for_masked_lm(self): @@ -489,7 +500,7 @@ def test_create_position_ids_respects_padding_index(self): [[0 + model.padding_idx + 1, 1 + model.padding_idx + 1, 2 + model.padding_idx + 1, model.padding_idx]] ) - position_ids = create_position_ids_from_input_ids(input_ids, model.padding_idx) + position_ids = XmodEmbeddings.create_position_ids_from_input_ids(input_ids, model.padding_idx) self.assertEqual(position_ids.shape, expected_positions.shape) self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) @@ -510,7 +521,7 @@ def test_create_position_ids_from_inputs_embeds(self): 3 + embeddings.padding_idx + 1, ] expected_positions = torch.as_tensor([expected_single_positions, expected_single_positions]) - position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds) + position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds, embeddings.padding_idx) self.assertEqual(position_ids.shape, expected_positions.shape) self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) @@ -530,6 +541,120 @@ def test_freeze_embeddings_and_language_adapters(self): num_trainable_params_after = sum(p.numel() for p in model.parameters() if p.requires_grad) self.assertLess(num_trainable_params_after, num_trainable_params_before) + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + """ + Overwritten to account for the embeddings that rely on position ids. + """ + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + max_new_tokens = 30 + support_flag = { + "sdpa": "_supports_sdpa", + "flash_attention_2": "_supports_flash_attn", + "flash_attention_3": "_supports_flash_attn", + } + + for model_class in self.all_generative_model_classes: + if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]): + self.skipTest(f"{model_class.__name__} does not support {attn_implementation}") + + # can't infer if new attn mask API is supported by assume that only model with attention backend support it + if not model_class._supports_attention_backend: + self.skipTest(f"{model_class.__name__} does not support new attention mask API") + + if model_class._is_stateful: # non-transformer models most probably have no packing support + self.skipTest(f"{model_class.__name__} doesn't support packing!") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.is_encoder_decoder: + self.skipTest("Model is an encoder-decoder") + + if 0 not in inputs_dict.get("attention_mask", []) or "attention_mask" not in inputs_dict: + self.skipTest("Model dummy inputs should contain padding in their attention mask") + + if "input_ids" not in inputs_dict or inputs_dict["input_ids"].ndim != 2: + self.skipTest("Model dummy inputs should contain text input ids") + + # make sure that all models have enough positions for generation + dummy_input_ids = inputs_dict["input_ids"] + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input_ids.shape[1] + 1 + + model = model_class(config) + if "position_ids" not in inspect.signature(model.forward).parameters: + self.skipTest("Model does not support position_ids") + + if (not fa_kwargs) and "position_ids" not in inspect.signature(model.forward).parameters: + continue # this model doesn't accept position ids as input + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # Drop all keys except for the minimal set. Hard to manipulate with multimodals/head_mask/etc + inputs_dict = {k: v for k, v in inputs_dict.items() if k in ["input_ids", "attention_mask"]} + + # Ensure left padding, to adapt for some models + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + dummy_input_ids[~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + # Main difference to other models, we need to prepare position ids according to the attention mask + # as we use it to extract embeddings that rely on the correct position - naively increasing sequences do + # not suffice anymore atp. The solution here calculates an increasing sequences for all 1s and puts 0s else. + inputs_dict["position_ids"] = ((inputs_dict["attention_mask"] == 1).long().cumsum(dim=1) - 1) * ( + inputs_dict["attention_mask"] == 1 + ).long() + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + if fa_kwargs: + # flatten + features = [ + {"input_ids": i[a.bool()].tolist()} for i, a in zip(dummy_input_ids, dummy_attention_mask) + ] + + # add position_ids + fa_kwargs + data_collator = DataCollatorWithFlattening(return_tensors="pt", return_flash_attn_kwargs=True) + batch = data_collator(features) + padfree_inputs_dict = { + k: t.to(torch_device) if torch.is_tensor(t) else t for k, t in batch.items() + } + else: + # create packed position_ids + position_ids = ( + torch.cat([torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()]) + .long() + .unsqueeze(0) + .to(torch_device) + ) + padfree_inputs_dict = { + "input_ids": dummy_input_ids[dummy_attention_mask.bool()].unsqueeze(0), + "position_ids": position_ids, + } + + # We need to do simple forward without cache in order to trigger packed SDPA/flex/eager attention path + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[dummy_attention_mask.bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + @require_sentencepiece @require_tokenizers @@ -669,8 +794,8 @@ def test_end_to_end_mask_fill(self): padded_sentence = tokenizer.decode(predictions_padded[0], skip_special_tokens=True) expected_output_sentence = [ - "Hello, my dog is a little girl.", - "Hi everyone!", + "Hello, my dog is a little girl .", + "Hi everyone !", ] self.assertListEqual(expected_output_sentence, batch_out_sentence) self.assertListEqual(batch_out_sentence, [non_padded_sentence, padded_sentence]) diff --git a/tests/test_modeling_common.py b/tests/test_modeling_common.py index 188c7517d54c..8d6325bfe0a0 100755 --- a/tests/test_modeling_common.py +++ b/tests/test_modeling_common.py @@ -616,7 +616,7 @@ def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): for k, v in inputs_dict.items() } elif model_class.__name__ in get_values(MODEL_FOR_AUDIO_XVECTOR_MAPPING_NAMES): - inputs_dict.pop("attention_mask") + inputs_dict.pop("attention_mask", None) elif model_class.__name__ == MODEL_FOR_PRETRAINING_MAPPING_NAMES["hiera"]: config = self.model_tester.get_config() mask_spatial_shape = [ @@ -1757,6 +1757,7 @@ def test_head_pruning(self): inputs_dict["output_attentions"] = True config.output_hidden_states = False + config._attn_implementation = "eager" model = model_class(config=config) model.to(torch_device) model.eval() @@ -1791,6 +1792,7 @@ def test_head_pruning_save_load_from_pretrained(self): inputs_dict["output_attentions"] = True config.output_hidden_states = False + config._attn_implementation = "eager" model = model_class(config=config) model.to(torch_device) model.eval() @@ -1829,6 +1831,7 @@ def test_head_pruning_save_load_from_config_init(self): inputs_dict["output_attentions"] = True config.output_hidden_states = False + config._attn_implementation = "eager" heads_to_prune = { 0: list(range(1, self.model_tester.num_attention_heads)), @@ -1865,6 +1868,7 @@ def test_head_pruning_integration(self): inputs_dict["output_attentions"] = True config.output_hidden_states = False + config._attn_implementation = "eager" heads_to_prune = {1: [1, 2]} config.pruned_heads = heads_to_prune @@ -3398,7 +3402,9 @@ def test_model_is_small(self): f"{model_class} is too big for the common tests ({num_params})! It should have 1M max." ) - def flash_attn_inference_equivalence(self, attn_implementation: str, padding_side: str): + def flash_attn_inference_equivalence( + self, attn_implementation: str, padding_side: str, atol: float = 4e-2, rtol: float = 4e-2 + ): r""" Tests the equivalence between the eager and flash attention implementations. This test is only for inference and runs with `dtype=torch.bfloat16`. @@ -3476,6 +3482,16 @@ def flash_attn_inference_equivalence(self, attn_implementation: str, padding_sid if model.config.is_encoder_decoder: second_inputs["decoder_attention_mask"] = dummy_attention_mask + # Use prepare for class to account for special attributes (e.g. in QnA models) + first_inputs = self._prepare_for_class(first_inputs, model_class) + first_inputs = { + k: v.to(torch_device) if isinstance(v, torch.Tensor) else v for k, v in first_inputs.items() + } + second_inputs = self._prepare_for_class(second_inputs, model_class) + second_inputs = { + k: v.to(torch_device) if isinstance(v, torch.Tensor) else v for k, v in second_inputs.items() + } + model = model_class.from_pretrained( tmpdirname, dtype=torch.bfloat16, attn_implementation="eager", device_map=torch_device ) @@ -3523,14 +3539,14 @@ def flash_attn_inference_equivalence(self, attn_implementation: str, padding_sid ) # Check the results - torch.testing.assert_close(logits_1_eager, logits_1_fa, atol=4e-2, rtol=4e-2) + torch.testing.assert_close(logits_1_eager, logits_1_fa, atol=atol, rtol=rtol) if padding_side == "left": - torch.testing.assert_close(logits_2_eager[1:], logits_2_fa[1:], atol=4e-2, rtol=4e-2) + torch.testing.assert_close(logits_2_eager[1:], logits_2_fa[1:], atol=atol, rtol=rtol) # Check it can run in training mode model.train() _ = model(**second_inputs) else: - torch.testing.assert_close(logits_2_eager[:-1], logits_2_fa[:-1], atol=4e-2, rtol=4e-2) + torch.testing.assert_close(logits_2_eager[:-1], logits_2_fa[:-1], atol=atol, rtol=rtol) # In this case, the test should appear as skipped, not successful if not _has_run_at_least_one_model: From 0dbfde2a67926c6d6d47c20ac3351e28acb944b6 Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Fri, 19 Sep 2025 11:28:34 +0200 Subject: [PATCH 114/204] Remove [[autodoc]] refs to TF/Flax objects (#40996) * remove refs * more --- docs/source/ja/internal/generation_utils.md | 117 --------------- docs/source/ja/internal/modeling_utils.md | 27 ---- docs/source/ja/main_classes/model.md | 16 --- docs/source/ja/main_classes/output.md | 132 ----------------- .../source/ja/main_classes/text_generation.md | 11 -- docs/source/ja/model_doc/albert.md | 80 ----------- docs/source/ja/model_doc/auto.md | 134 ----------------- docs/source/ja/model_doc/bart.md | 48 ------- docs/source/ja/model_doc/beit.md | 17 --- docs/source/ja/model_doc/bert.md | 108 -------------- docs/source/ja/model_doc/big_bird.md | 43 ------ docs/source/ja/model_doc/blenderbot-small.md | 24 ---- docs/source/ja/model_doc/blenderbot.md | 23 --- docs/source/ja/model_doc/blip.md | 34 ----- docs/source/ja/model_doc/bloom.md | 13 -- docs/source/ja/model_doc/camembert.md | 31 ---- docs/source/ja/model_doc/clip.md | 45 ------ docs/source/ja/model_doc/convbert.md | 33 ----- docs/source/ja/model_doc/convnext.md | 13 -- docs/source/ja/model_doc/convnextv2.md | 11 -- docs/source/ja/model_doc/ctrl.md | 18 --- docs/source/ja/model_doc/cvt.md | 13 -- docs/source/ja/model_doc/data2vec.md | 18 --- docs/source/ja/model_doc/deberta-v2.md | 38 ----- docs/source/ja/model_doc/deberta.md | 33 ----- docs/source/ja/model_doc/deit.md | 23 --- docs/source/ko/internal/generation_utils.md | 119 --------------- docs/source/ko/internal/modeling_utils.md | 28 ---- docs/source/ko/main_classes/model.md | 16 --- docs/source/ko/main_classes/output.md | 131 ----------------- .../source/ko/main_classes/text_generation.md | 10 -- docs/source/ko/model_doc/albert.md | 65 --------- docs/source/ko/model_doc/auto.md | 136 ------------------ docs/source/ko/model_doc/bart.md | 53 ------- docs/source/ko/model_doc/bert.md | 108 -------------- docs/source/ko/model_doc/blip.md | 34 ----- docs/source/ko/model_doc/clip.md | 45 ------ docs/source/ko/model_doc/convbert.md | 33 ----- docs/source/ko/model_doc/deberta-v2.md | 38 ----- docs/source/ko/model_doc/deberta.md | 33 ----- docs/source/ko/model_doc/electra.md | 83 ----------- docs/source/ko/model_doc/encoder-decoder.md | 18 --- docs/source/ko/model_doc/esm.md | 23 --- docs/source/ko/model_doc/gemma.md | 10 -- docs/source/ko/model_doc/gpt2.md | 46 ------ docs/source/ko/model_doc/marian.md | 26 ---- docs/source/ko/model_doc/mistral.md | 25 ---- docs/source/ko/model_doc/openai-gpt.md | 25 ---- docs/source/ko/model_doc/rag.md | 20 --- docs/source/ko/model_doc/roberta.md | 76 ---------- docs/source/ko/model_doc/swin.md | 18 --- docs/source/ko/model_doc/vit.md | 26 ---- docs/source/ko/model_doc/whisper.md | 28 ---- docs/source/zh/internal/generation_utils.md | 118 --------------- docs/source/zh/internal/modeling_utils.md | 27 ---- docs/source/zh/main_classes/model.md | 13 -- docs/source/zh/main_classes/output.md | 134 +---------------- .../source/zh/main_classes/text_generation.md | 13 +- docs/source/zh/model_doc/bert.md | 100 +------------ 59 files changed, 3 insertions(+), 2778 deletions(-) diff --git a/docs/source/ja/internal/generation_utils.md b/docs/source/ja/internal/generation_utils.md index 4b29c125373d..eb88a63b3e42 100644 --- a/docs/source/ja/internal/generation_utils.md +++ b/docs/source/ja/internal/generation_utils.md @@ -75,36 +75,6 @@ generation_output[:2] [[autodoc]] generation.GenerateBeamEncoderDecoderOutput -### TensorFlow - -[[autodoc]] generation.TFGreedySearchEncoderDecoderOutput - -[[autodoc]] generation.TFGreedySearchDecoderOnlyOutput - -[[autodoc]] generation.TFSampleEncoderDecoderOutput - -[[autodoc]] generation.TFSampleDecoderOnlyOutput - -[[autodoc]] generation.TFBeamSearchEncoderDecoderOutput - -[[autodoc]] generation.TFBeamSearchDecoderOnlyOutput - -[[autodoc]] generation.TFBeamSampleEncoderDecoderOutput - -[[autodoc]] generation.TFBeamSampleDecoderOnlyOutput - -[[autodoc]] generation.TFContrastiveSearchEncoderDecoderOutput - -[[autodoc]] generation.TFContrastiveSearchDecoderOnlyOutput - -### FLAX - -[[autodoc]] generation.FlaxSampleOutput - -[[autodoc]] generation.FlaxGreedySearchOutput - -[[autodoc]] generation.FlaxBeamSearchOutput - ## LogitsProcessor [`LogitsProcessor`] を使用して、言語モデルのヘッドの予測スコアを変更できます。 @@ -196,93 +166,6 @@ generation_output[:2] [[autodoc]] WhisperTimeStampLogitsProcessor - __call__ -### TensorFlow - -[[autodoc]] TFForcedBOSTokenLogitsProcessor - - __call__ - -[[autodoc]] TFForcedEOSTokenLogitsProcessor - - __call__ - -[[autodoc]] TFForceTokensLogitsProcessor - - __call__ - -[[autodoc]] TFLogitsProcessor - - __call__ - -[[autodoc]] TFLogitsProcessorList - - __call__ - -[[autodoc]] TFLogitsWarper - - __call__ - -[[autodoc]] TFMinLengthLogitsProcessor - - __call__ - -[[autodoc]] TFNoBadWordsLogitsProcessor - - __call__ - -[[autodoc]] TFNoRepeatNGramLogitsProcessor - - __call__ - -[[autodoc]] TFRepetitionPenaltyLogitsProcessor - - __call__ - -[[autodoc]] TFSuppressTokensAtBeginLogitsProcessor - - __call__ - -[[autodoc]] TFSuppressTokensLogitsProcessor - - __call__ - -[[autodoc]] TFTemperatureLogitsWarper - - __call__ - -[[autodoc]] TFTopKLogitsWarper - - __call__ - -[[autodoc]] TFTopPLogitsWarper - - __call__ - -### FLAX - -[[autodoc]] FlaxForcedBOSTokenLogitsProcessor - - __call__ - -[[autodoc]] FlaxForcedEOSTokenLogitsProcessor - - __call__ - -[[autodoc]] FlaxForceTokensLogitsProcessor - - __call__ - -[[autodoc]] FlaxLogitsProcessor - - __call__ - -[[autodoc]] FlaxLogitsProcessorList - - __call__ - -[[autodoc]] FlaxLogitsWarper - - __call__ - -[[autodoc]] FlaxMinLengthLogitsProcessor - - __call__ - -[[autodoc]] FlaxSuppressTokensAtBeginLogitsProcessor - - __call__ - -[[autodoc]] FlaxSuppressTokensLogitsProcessor - - __call__ - -[[autodoc]] FlaxTemperatureLogitsWarper - - __call__ - -[[autodoc]] FlaxTopKLogitsWarper - - __call__ - -[[autodoc]] FlaxTopPLogitsWarper - - __call__ - -[[autodoc]] FlaxWhisperTimeStampLogitsProcessor - - __call__ ## StoppingCriteria diff --git a/docs/source/ja/internal/modeling_utils.md b/docs/source/ja/internal/modeling_utils.md index 6e8335623a01..7e906e87d7f9 100644 --- a/docs/source/ja/internal/modeling_utils.md +++ b/docs/source/ja/internal/modeling_utils.md @@ -37,30 +37,3 @@ rendered properly in your Markdown viewer. [[autodoc]] pytorch_utils.prune_linear_layer -## TensorFlow custom layers - -[[autodoc]] modeling_tf_utils.TFConv1D - -[[autodoc]] modeling_tf_utils.TFSequenceSummary - -## TensorFlow loss functions - -[[autodoc]] modeling_tf_utils.TFCausalLanguageModelingLoss - -[[autodoc]] modeling_tf_utils.TFMaskedLanguageModelingLoss - -[[autodoc]] modeling_tf_utils.TFMultipleChoiceLoss - -[[autodoc]] modeling_tf_utils.TFQuestionAnsweringLoss - -[[autodoc]] modeling_tf_utils.TFSequenceClassificationLoss - -[[autodoc]] modeling_tf_utils.TFTokenClassificationLoss - -## TensorFlow Helper Functions - -[[autodoc]] modeling_tf_utils.get_initializer - -[[autodoc]] modeling_tf_utils.keras_serializable - -[[autodoc]] modeling_tf_utils.shape_list diff --git a/docs/source/ja/main_classes/model.md b/docs/source/ja/main_classes/model.md index b98d3ac952cf..21b3b0777823 100644 --- a/docs/source/ja/main_classes/model.md +++ b/docs/source/ja/main_classes/model.md @@ -124,22 +124,6 @@ Pytorch の設計により、この機能は浮動小数点 dtype でのみ使 [[autodoc]] modeling_utils.ModuleUtilsMixin -## TFPreTrainedModel - -[[autodoc]] TFPreTrainedModel - - push_to_hub - - all - -## TFModelUtilsMixin - -[[autodoc]] modeling_tf_utils.TFModelUtilsMixin - -## FlaxPreTrainedModel - -[[autodoc]] FlaxPreTrainedModel - - push_to_hub - - all - ## Pushing to the Hub [[autodoc]] utils.PushToHubMixin diff --git a/docs/source/ja/main_classes/output.md b/docs/source/ja/main_classes/output.md index beb9dcbb4423..b42ed844c65d 100644 --- a/docs/source/ja/main_classes/output.md +++ b/docs/source/ja/main_classes/output.md @@ -187,135 +187,3 @@ outputs[:2] ## SampleTSPredictionOutput [[autodoc]] modeling_outputs.SampleTSPredictionOutput - -## TFBaseModelOutput - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutput - -## TFBaseModelOutputWithPooling - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPooling - -## TFBaseModelOutputWithPoolingAndCrossAttentions - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPoolingAndCrossAttentions - -## TFBaseModelOutputWithPast - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPast - -## TFBaseModelOutputWithPastAndCrossAttentions - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPastAndCrossAttentions - -## TFSeq2SeqModelOutput - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqModelOutput - -## TFCausalLMOutput - -[[autodoc]] modeling_tf_outputs.TFCausalLMOutput - -## TFCausalLMOutputWithCrossAttentions - -[[autodoc]] modeling_tf_outputs.TFCausalLMOutputWithCrossAttentions - -## TFCausalLMOutputWithPast - -[[autodoc]] modeling_tf_outputs.TFCausalLMOutputWithPast - -## TFMaskedLMOutput - -[[autodoc]] modeling_tf_outputs.TFMaskedLMOutput - -## TFSeq2SeqLMOutput - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqLMOutput - -## TFNextSentencePredictorOutput - -[[autodoc]] modeling_tf_outputs.TFNextSentencePredictorOutput - -## TFSequenceClassifierOutput - -[[autodoc]] modeling_tf_outputs.TFSequenceClassifierOutput - -## TFSeq2SeqSequenceClassifierOutput - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqSequenceClassifierOutput - -## TFMultipleChoiceModelOutput - -[[autodoc]] modeling_tf_outputs.TFMultipleChoiceModelOutput - -## TFTokenClassifierOutput - -[[autodoc]] modeling_tf_outputs.TFTokenClassifierOutput - -## TFQuestionAnsweringModelOutput - -[[autodoc]] modeling_tf_outputs.TFQuestionAnsweringModelOutput - -## TFSeq2SeqQuestionAnsweringModelOutput - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqQuestionAnsweringModelOutput - -## FlaxBaseModelOutput - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutput - -## FlaxBaseModelOutputWithPast - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutputWithPast - -## FlaxBaseModelOutputWithPooling - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutputWithPooling - -## FlaxBaseModelOutputWithPastAndCrossAttentions - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutputWithPastAndCrossAttentions - -## FlaxSeq2SeqModelOutput - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqModelOutput - -## FlaxCausalLMOutputWithCrossAttentions - -[[autodoc]] modeling_flax_outputs.FlaxCausalLMOutputWithCrossAttentions - -## FlaxMaskedLMOutput - -[[autodoc]] modeling_flax_outputs.FlaxMaskedLMOutput - -## FlaxSeq2SeqLMOutput - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqLMOutput - -## FlaxNextSentencePredictorOutput - -[[autodoc]] modeling_flax_outputs.FlaxNextSentencePredictorOutput - -## FlaxSequenceClassifierOutput - -[[autodoc]] modeling_flax_outputs.FlaxSequenceClassifierOutput - -## FlaxSeq2SeqSequenceClassifierOutput - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqSequenceClassifierOutput - -## FlaxMultipleChoiceModelOutput - -[[autodoc]] modeling_flax_outputs.FlaxMultipleChoiceModelOutput - -## FlaxTokenClassifierOutput - -[[autodoc]] modeling_flax_outputs.FlaxTokenClassifierOutput - -## FlaxQuestionAnsweringModelOutput - -[[autodoc]] modeling_flax_outputs.FlaxQuestionAnsweringModelOutput - -## FlaxSeq2SeqQuestionAnsweringModelOutput - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqQuestionAnsweringModelOutput diff --git a/docs/source/ja/main_classes/text_generation.md b/docs/source/ja/main_classes/text_generation.md index 18477d97e626..570f0659c90c 100644 --- a/docs/source/ja/main_classes/text_generation.md +++ b/docs/source/ja/main_classes/text_generation.md @@ -43,14 +43,3 @@ rendered properly in your Markdown viewer. [[autodoc]] generation.GenerationMixin - generate - compute_transition_scores - -## TFGenerationMixin - -[[autodoc]] generation.TFGenerationMixin - - generate - - compute_transition_scores - -## FlaxGenerationMixin - -[[autodoc]] generation.FlaxGenerationMixin - - generate diff --git a/docs/source/ja/model_doc/albert.md b/docs/source/ja/model_doc/albert.md index 7824f2459991..b81723f1910d 100644 --- a/docs/source/ja/model_doc/albert.md +++ b/docs/source/ja/model_doc/albert.md @@ -73,8 +73,6 @@ ALBERTモデルは、「[ALBERT: A Lite BERT for Self-supervised Learning of Lan [[autodoc]] models.albert.modeling_albert.AlbertForPreTrainingOutput -[[autodoc]] models.albert.modeling_tf_albert.TFAlbertForPreTrainingOutput - @@ -113,81 +111,3 @@ ALBERTモデルは、「[ALBERT: A Lite BERT for Self-supervised Learning of Lan - forward - - - -## TFAlbertModel - -[[autodoc]] TFAlbertModel - - call - -## TFAlbertForPreTraining - -[[autodoc]] TFAlbertForPreTraining - - call - -## TFAlbertForMaskedLM - -[[autodoc]] TFAlbertForMaskedLM - - call - -## TFAlbertForSequenceClassification - -[[autodoc]] TFAlbertForSequenceClassification - - call - -## TFAlbertForMultipleChoice - -[[autodoc]] TFAlbertForMultipleChoice - - call - -## TFAlbertForTokenClassification - -[[autodoc]] TFAlbertForTokenClassification - - call - -## TFAlbertForQuestionAnswering - -[[autodoc]] TFAlbertForQuestionAnswering - - call - - - - -## FlaxAlbertModel - -[[autodoc]] FlaxAlbertModel - - __call__ - -## FlaxAlbertForPreTraining - -[[autodoc]] FlaxAlbertForPreTraining - - __call__ - -## FlaxAlbertForMaskedLM - -[[autodoc]] FlaxAlbertForMaskedLM - - __call__ - -## FlaxAlbertForSequenceClassification - -[[autodoc]] FlaxAlbertForSequenceClassification - - __call__ - -## FlaxAlbertForMultipleChoice - -[[autodoc]] FlaxAlbertForMultipleChoice - - __call__ - -## FlaxAlbertForTokenClassification - -[[autodoc]] FlaxAlbertForTokenClassification - - __call__ - -## FlaxAlbertForQuestionAnswering - -[[autodoc]] FlaxAlbertForQuestionAnswering - - __call__ - - - diff --git a/docs/source/ja/model_doc/auto.md b/docs/source/ja/model_doc/auto.md index 27030a264f57..1a36d2c9bb12 100644 --- a/docs/source/ja/model_doc/auto.md +++ b/docs/source/ja/model_doc/auto.md @@ -77,14 +77,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModel -### TFAutoModel - -[[autodoc]] TFAutoModel - -### FlaxAutoModel - -[[autodoc]] FlaxAutoModel - ## Generic pretraining classes 以下の自動クラスは、事前学習ヘッドを持つモデルをインスタンス化するために利用可能です。 @@ -93,14 +85,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForPreTraining -### TFAutoModelForPreTraining - -[[autodoc]] TFAutoModelForPreTraining - -### FlaxAutoModelForPreTraining - -[[autodoc]] FlaxAutoModelForPreTraining - ## Natural Language Processing 以下の自動クラスは、次の自然言語処理タスクに利用可能です。 @@ -109,114 +93,43 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForCausalLM -### TFAutoModelForCausalLM - -[[autodoc]] TFAutoModelForCausalLM - -### FlaxAutoModelForCausalLM - -[[autodoc]] FlaxAutoModelForCausalLM - ### AutoModelForMaskedLM [[autodoc]] AutoModelForMaskedLM -### TFAutoModelForMaskedLM - -[[autodoc]] TFAutoModelForMaskedLM - -### FlaxAutoModelForMaskedLM - -[[autodoc]] FlaxAutoModelForMaskedLM ### AutoModelForMaskGeneration [[autodoc]] AutoModelForMaskGeneration -### TFAutoModelForMaskGeneration - -[[autodoc]] TFAutoModelForMaskGeneration - ### AutoModelForSeq2SeqLM [[autodoc]] AutoModelForSeq2SeqLM -### TFAutoModelForSeq2SeqLM - -[[autodoc]] TFAutoModelForSeq2SeqLM - -### FlaxAutoModelForSeq2SeqLM - -[[autodoc]] FlaxAutoModelForSeq2SeqLM - ### AutoModelForSequenceClassification [[autodoc]] AutoModelForSequenceClassification -### TFAutoModelForSequenceClassification - -[[autodoc]] TFAutoModelForSequenceClassification - -### FlaxAutoModelForSequenceClassification - -[[autodoc]] FlaxAutoModelForSequenceClassification - ### AutoModelForMultipleChoice [[autodoc]] AutoModelForMultipleChoice -### TFAutoModelForMultipleChoice - -[[autodoc]] TFAutoModelForMultipleChoice - -### FlaxAutoModelForMultipleChoice - -[[autodoc]] FlaxAutoModelForMultipleChoice - ### AutoModelForNextSentencePrediction [[autodoc]] AutoModelForNextSentencePrediction -### TFAutoModelForNextSentencePrediction - -[[autodoc]] TFAutoModelForNextSentencePrediction - -### FlaxAutoModelForNextSentencePrediction - -[[autodoc]] FlaxAutoModelForNextSentencePrediction - ### AutoModelForTokenClassification [[autodoc]] AutoModelForTokenClassification -### TFAutoModelForTokenClassification - -[[autodoc]] TFAutoModelForTokenClassification - -### FlaxAutoModelForTokenClassification - -[[autodoc]] FlaxAutoModelForTokenClassification - ### AutoModelForQuestionAnswering [[autodoc]] AutoModelForQuestionAnswering -### TFAutoModelForQuestionAnswering - -[[autodoc]] TFAutoModelForQuestionAnswering - -### FlaxAutoModelForQuestionAnswering - -[[autodoc]] FlaxAutoModelForQuestionAnswering - ### AutoModelForTextEncoding [[autodoc]] AutoModelForTextEncoding -### TFAutoModelForTextEncoding - -[[autodoc]] TFAutoModelForTextEncoding - ## Computer vision 以下の自動クラスは、次のコンピュータービジョンタスクに利用可能です。 @@ -229,14 +142,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForImageClassification -### TFAutoModelForImageClassification - -[[autodoc]] TFAutoModelForImageClassification - -### FlaxAutoModelForImageClassification - -[[autodoc]] FlaxAutoModelForImageClassification - ### AutoModelForVideoClassification [[autodoc]] AutoModelForVideoClassification @@ -245,10 +150,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForMaskedImageModeling -### TFAutoModelForMaskedImageModeling - -[[autodoc]] TFAutoModelForMaskedImageModeling - ### AutoModelForObjectDetection [[autodoc]] AutoModelForObjectDetection @@ -265,10 +166,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForSemanticSegmentation -### TFAutoModelForSemanticSegmentation - -[[autodoc]] TFAutoModelForSemanticSegmentation - ### AutoModelForInstanceSegmentation [[autodoc]] AutoModelForInstanceSegmentation @@ -281,10 +178,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForZeroShotImageClassification -### TFAutoModelForZeroShotImageClassification - -[[autodoc]] TFAutoModelForZeroShotImageClassification - ### AutoModelForZeroShotObjectDetection [[autodoc]] AutoModelForZeroShotObjectDetection @@ -299,10 +192,6 @@ AutoModel.register(NewModelConfig, NewModel) ### AutoModelForAudioFrameClassification -[[autodoc]] TFAutoModelForAudioClassification - -### TFAutoModelForAudioFrameClassification - [[autodoc]] AutoModelForAudioFrameClassification ### AutoModelForCTC @@ -313,14 +202,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForSpeechSeq2Seq -### TFAutoModelForSpeechSeq2Seq - -[[autodoc]] TFAutoModelForSpeechSeq2Seq - -### FlaxAutoModelForSpeechSeq2Seq - -[[autodoc]] FlaxAutoModelForSpeechSeq2Seq - ### AutoModelForAudioXVector [[autodoc]] AutoModelForAudioXVector @@ -341,18 +222,10 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForTableQuestionAnswering -### TFAutoModelForTableQuestionAnswering - -[[autodoc]] TFAutoModelForTableQuestionAnswering - ### AutoModelForDocumentQuestionAnswering [[autodoc]] AutoModelForDocumentQuestionAnswering -### TFAutoModelForDocumentQuestionAnswering - -[[autodoc]] TFAutoModelForDocumentQuestionAnswering - ### AutoModelForVisualQuestionAnswering [[autodoc]] AutoModelForVisualQuestionAnswering @@ -361,13 +234,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForVision2Seq -### TFAutoModelForVision2Seq - -[[autodoc]] TFAutoModelForVision2Seq - -### FlaxAutoModelForVision2Seq - -[[autodoc]] FlaxAutoModelForVision2Seq ### AutoModelForImageTextToText diff --git a/docs/source/ja/model_doc/bart.md b/docs/source/ja/model_doc/bart.md index 4584f4815017..ee584b8013e0 100644 --- a/docs/source/ja/model_doc/bart.md +++ b/docs/source/ja/model_doc/bart.md @@ -173,51 +173,3 @@ BART を始めるのに役立つ公式 Hugging Face およびコミュニティ [[autodoc]] BartForCausalLM - forward - -## TFBartModel - -[[autodoc]] TFBartModel - - call - -## TFBartForConditionalGeneration - -[[autodoc]] TFBartForConditionalGeneration - - call - -## TFBartForSequenceClassification - -[[autodoc]] TFBartForSequenceClassification - - call - -## FlaxBartModel - -[[autodoc]] FlaxBartModel - - __call__ - - encode - - decode - -## FlaxBartForConditionalGeneration - -[[autodoc]] FlaxBartForConditionalGeneration - - __call__ - - encode - - decode - -## FlaxBartForSequenceClassification - -[[autodoc]] FlaxBartForSequenceClassification - - __call__ - - encode - - decode - -## FlaxBartForQuestionAnswering - -[[autodoc]] FlaxBartForQuestionAnswering - - __call__ - - encode - - decode - -## FlaxBartForCausalLM - -[[autodoc]] FlaxBartForCausalLM - - __call__ diff --git a/docs/source/ja/model_doc/beit.md b/docs/source/ja/model_doc/beit.md index 21ccc28c68e2..cd92b041c8b1 100644 --- a/docs/source/ja/model_doc/beit.md +++ b/docs/source/ja/model_doc/beit.md @@ -89,8 +89,6 @@ BEiT の使用を開始するのに役立つ公式 Hugging Face およびコミ [[autodoc]] models.beit.modeling_beit.BeitModelOutputWithPooling -[[autodoc]] models.beit.modeling_flax_beit.FlaxBeitModelOutputWithPooling - ## BeitConfig [[autodoc]] BeitConfig @@ -132,18 +130,3 @@ BEiT の使用を開始するのに役立つ公式 Hugging Face およびコミ [[autodoc]] BeitForSemanticSegmentation - forward - -## FlaxBeitModel - -[[autodoc]] FlaxBeitModel - - __call__ - -## FlaxBeitForMaskedImageModeling - -[[autodoc]] FlaxBeitForMaskedImageModeling - - __call__ - -## FlaxBeitForImageClassification - -[[autodoc]] FlaxBeitForImageClassification - - __call__ diff --git a/docs/source/ja/model_doc/bert.md b/docs/source/ja/model_doc/bert.md index e0367dcd46eb..306b894db219 100644 --- a/docs/source/ja/model_doc/bert.md +++ b/docs/source/ja/model_doc/bert.md @@ -146,23 +146,12 @@ BERT を始めるのに役立つ公式 Hugging Face およびコミュニティ [[autodoc]] BertTokenizerFast - - -## TFBertTokenizer - -[[autodoc]] TFBertTokenizer - - ## Bert specific outputs [[autodoc]] models.bert.modeling_bert.BertForPreTrainingOutput -[[autodoc]] models.bert.modeling_tf_bert.TFBertForPreTrainingOutput - -[[autodoc]] models.bert.modeling_flax_bert.FlaxBertForPreTrainingOutput - @@ -212,101 +201,4 @@ BERT を始めるのに役立つ公式 Hugging Face およびコミュニティ - forward - - -## TFBertModel - -[[autodoc]] TFBertModel - - call - -## TFBertForPreTraining - -[[autodoc]] TFBertForPreTraining - - call - -## TFBertModelLMHeadModel - -[[autodoc]] TFBertLMHeadModel - - call - -## TFBertForMaskedLM - -[[autodoc]] TFBertForMaskedLM - - call - -## TFBertForNextSentencePrediction - -[[autodoc]] TFBertForNextSentencePrediction - - call - -## TFBertForSequenceClassification - -[[autodoc]] TFBertForSequenceClassification - - call - -## TFBertForMultipleChoice - -[[autodoc]] TFBertForMultipleChoice - - call - -## TFBertForTokenClassification - -[[autodoc]] TFBertForTokenClassification - - call - -## TFBertForQuestionAnswering - -[[autodoc]] TFBertForQuestionAnswering - - call - - - - - -## FlaxBertModel - -[[autodoc]] FlaxBertModel - - __call__ - -## FlaxBertForPreTraining - -[[autodoc]] FlaxBertForPreTraining - - __call__ - -## FlaxBertForCausalLM - -[[autodoc]] FlaxBertForCausalLM - - __call__ - -## FlaxBertForMaskedLM - -[[autodoc]] FlaxBertForMaskedLM - - __call__ - -## FlaxBertForNextSentencePrediction - -[[autodoc]] FlaxBertForNextSentencePrediction - - __call__ - -## FlaxBertForSequenceClassification - -[[autodoc]] FlaxBertForSequenceClassification - - __call__ - -## FlaxBertForMultipleChoice - -[[autodoc]] FlaxBertForMultipleChoice - - __call__ - -## FlaxBertForTokenClassification - -[[autodoc]] FlaxBertForTokenClassification - - __call__ - -## FlaxBertForQuestionAnswering - -[[autodoc]] FlaxBertForQuestionAnswering - - __call__ - - \ No newline at end of file diff --git a/docs/source/ja/model_doc/big_bird.md b/docs/source/ja/model_doc/big_bird.md index d5f4f9d282ea..cec7cdf5f319 100644 --- a/docs/source/ja/model_doc/big_bird.md +++ b/docs/source/ja/model_doc/big_bird.md @@ -129,48 +129,5 @@ BigBird は、質問応答や要約などのさまざまな NLP タスクのパ - forward - - -## FlaxBigBirdModel - -[[autodoc]] FlaxBigBirdModel - - __call__ - -## FlaxBigBirdForPreTraining - -[[autodoc]] FlaxBigBirdForPreTraining - - __call__ - -## FlaxBigBirdForCausalLM - -[[autodoc]] FlaxBigBirdForCausalLM - - __call__ - -## FlaxBigBirdForMaskedLM - -[[autodoc]] FlaxBigBirdForMaskedLM - - __call__ - -## FlaxBigBirdForSequenceClassification - -[[autodoc]] FlaxBigBirdForSequenceClassification - - __call__ - -## FlaxBigBirdForMultipleChoice - -[[autodoc]] FlaxBigBirdForMultipleChoice - - __call__ - -## FlaxBigBirdForTokenClassification - -[[autodoc]] FlaxBigBirdForTokenClassification - - __call__ - -## FlaxBigBirdForQuestionAnswering - -[[autodoc]] FlaxBigBirdForQuestionAnswering - - __call__ - - diff --git a/docs/source/ja/model_doc/blenderbot-small.md b/docs/source/ja/model_doc/blenderbot-small.md index 97455bddf806..cdfad5272f59 100644 --- a/docs/source/ja/model_doc/blenderbot-small.md +++ b/docs/source/ja/model_doc/blenderbot-small.md @@ -84,27 +84,3 @@ Blender チャットボット モデルは、[Recipes for building an open-domai [[autodoc]] BlenderbotSmallForCausalLM - forward - -## TFBlenderbotSmallModel - -[[autodoc]] TFBlenderbotSmallModel - - call - -## TFBlenderbotSmallForConditionalGeneration - -[[autodoc]] TFBlenderbotSmallForConditionalGeneration - - call - -## FlaxBlenderbotSmallModel - -[[autodoc]] FlaxBlenderbotSmallModel - - __call__ - - encode - - decode - -## FlaxBlenderbotForConditionalGeneration - -[[autodoc]] FlaxBlenderbotSmallForConditionalGeneration - - __call__ - - encode - - decode diff --git a/docs/source/ja/model_doc/blenderbot.md b/docs/source/ja/model_doc/blenderbot.md index f2a03e69c987..5c7aef5a5240 100644 --- a/docs/source/ja/model_doc/blenderbot.md +++ b/docs/source/ja/model_doc/blenderbot.md @@ -107,26 +107,3 @@ Blender チャットボット モデルは、[Recipes for building an open-domai [[autodoc]] BlenderbotForCausalLM - forward -## TFBlenderbotModel - -[[autodoc]] TFBlenderbotModel - - call - -## TFBlenderbotForConditionalGeneration - -[[autodoc]] TFBlenderbotForConditionalGeneration - - call - -## FlaxBlenderbotModel - -[[autodoc]] FlaxBlenderbotModel - - __call__ - - encode - - decode - -## FlaxBlenderbotForConditionalGeneration - -[[autodoc]] FlaxBlenderbotForConditionalGeneration - - __call__ - - encode - - decode diff --git a/docs/source/ja/model_doc/blip.md b/docs/source/ja/model_doc/blip.md index e93c740883ab..4cba6d0c936b 100644 --- a/docs/source/ja/model_doc/blip.md +++ b/docs/source/ja/model_doc/blip.md @@ -102,38 +102,4 @@ BLIP は、次のようなさまざまなマルチモーダル タスクを実 - forward - - -## TFBlipModel - -[[autodoc]] TFBlipModel - - call - - get_text_features - - get_image_features - -## TFBlipTextModel - -[[autodoc]] TFBlipTextModel - - call - -## TFBlipVisionModel - -[[autodoc]] TFBlipVisionModel - - call - -## TFBlipForConditionalGeneration - -[[autodoc]] TFBlipForConditionalGeneration - - call - -## TFBlipForImageTextRetrieval - -[[autodoc]] TFBlipForImageTextRetrieval - - call - -## TFBlipForQuestionAnswering - -[[autodoc]] TFBlipForQuestionAnswering - - call - \ No newline at end of file diff --git a/docs/source/ja/model_doc/bloom.md b/docs/source/ja/model_doc/bloom.md index f7cb66ab9532..159802882467 100644 --- a/docs/source/ja/model_doc/bloom.md +++ b/docs/source/ja/model_doc/bloom.md @@ -91,17 +91,4 @@ BLOOM を使い始めるのに役立つ公式 Hugging Face およびコミュニ - forward - - -## FlaxBloomModel - -[[autodoc]] FlaxBloomModel - - __call__ - -## FlaxBloomForCausalLM - -[[autodoc]] FlaxBloomForCausalLM - - __call__ - - diff --git a/docs/source/ja/model_doc/camembert.md b/docs/source/ja/model_doc/camembert.md index 382077613dd1..c0d6a4fdb7f0 100644 --- a/docs/source/ja/model_doc/camembert.md +++ b/docs/source/ja/model_doc/camembert.md @@ -101,35 +101,4 @@ Bi-direction Encoders for Transformers (BERT) のフランス語版である Cam [[autodoc]] CamembertForQuestionAnswering - - -## TFCamembertModel - -[[autodoc]] TFCamembertModel - -## TFCamembertForCasualLM - -[[autodoc]] TFCamembertForCausalLM - -## TFCamembertForMaskedLM - -[[autodoc]] TFCamembertForMaskedLM - -## TFCamembertForSequenceClassification - -[[autodoc]] TFCamembertForSequenceClassification - -## TFCamembertForMultipleChoice - -[[autodoc]] TFCamembertForMultipleChoice - -## TFCamembertForTokenClassification - -[[autodoc]] TFCamembertForTokenClassification - -## TFCamembertForQuestionAnswering - -[[autodoc]] TFCamembertForQuestionAnswering - - diff --git a/docs/source/ja/model_doc/clip.md b/docs/source/ja/model_doc/clip.md index 6b21dbd14395..3e785a2b310e 100644 --- a/docs/source/ja/model_doc/clip.md +++ b/docs/source/ja/model_doc/clip.md @@ -177,49 +177,4 @@ CLIP を使い始めるのに役立つ公式 Hugging Face およびコミュニ - forward - - -## TFCLIPModel - -[[autodoc]] TFCLIPModel - - call - - get_text_features - - get_image_features - -## TFCLIPTextModel - -[[autodoc]] TFCLIPTextModel - - call - -## TFCLIPVisionModel - -[[autodoc]] TFCLIPVisionModel - - call - - - - -## FlaxCLIPModel - -[[autodoc]] FlaxCLIPModel - - __call__ - - get_text_features - - get_image_features - -## FlaxCLIPTextModel - -[[autodoc]] FlaxCLIPTextModel - - __call__ - -## FlaxCLIPTextModelWithProjection - -[[autodoc]] FlaxCLIPTextModelWithProjection - - __call__ - -## FlaxCLIPVisionModel - -[[autodoc]] FlaxCLIPVisionModel - - __call__ - - diff --git a/docs/source/ja/model_doc/convbert.md b/docs/source/ja/model_doc/convbert.md index c581b715db96..5112a64366ff 100644 --- a/docs/source/ja/model_doc/convbert.md +++ b/docs/source/ja/model_doc/convbert.md @@ -109,37 +109,4 @@ ConvBERT トレーニングのヒントは BERT のヒントと似ています - forward - - -## TFConvBertModel - -[[autodoc]] TFConvBertModel - - call - -## TFConvBertForMaskedLM - -[[autodoc]] TFConvBertForMaskedLM - - call - -## TFConvBertForSequenceClassification - -[[autodoc]] TFConvBertForSequenceClassification - - call - -## TFConvBertForMultipleChoice - -[[autodoc]] TFConvBertForMultipleChoice - - call - -## TFConvBertForTokenClassification - -[[autodoc]] TFConvBertForTokenClassification - - call - -## TFConvBertForQuestionAnswering - -[[autodoc]] TFConvBertForQuestionAnswering - - call - - diff --git a/docs/source/ja/model_doc/convnext.md b/docs/source/ja/model_doc/convnext.md index 336f27709d40..a733b0923c29 100644 --- a/docs/source/ja/model_doc/convnext.md +++ b/docs/source/ja/model_doc/convnext.md @@ -83,17 +83,4 @@ ConvNeXT の使用を開始するのに役立つ公式 Hugging Face およびコ - forward - - -## TFConvNextModel - -[[autodoc]] TFConvNextModel - - call - -## TFConvNextForImageClassification - -[[autodoc]] TFConvNextForImageClassification - - call - - \ No newline at end of file diff --git a/docs/source/ja/model_doc/convnextv2.md b/docs/source/ja/model_doc/convnextv2.md index cadd5e8ca0bf..cf80bcd63bbf 100644 --- a/docs/source/ja/model_doc/convnextv2.md +++ b/docs/source/ja/model_doc/convnextv2.md @@ -55,14 +55,3 @@ ConvNeXt V2 の使用を開始するのに役立つ公式 Hugging Face および [[autodoc]] ConvNextV2ForImageClassification - forward - -## TFConvNextV2Model - -[[autodoc]] TFConvNextV2Model - - call - - -## TFConvNextV2ForImageClassification - -[[autodoc]] TFConvNextV2ForImageClassification - - call diff --git a/docs/source/ja/model_doc/ctrl.md b/docs/source/ja/model_doc/ctrl.md index 508a0d2e432a..260649ef01a3 100644 --- a/docs/source/ja/model_doc/ctrl.md +++ b/docs/source/ja/model_doc/ctrl.md @@ -92,22 +92,4 @@ CTRL モデルは、Nitish Shirish Keskar*、Bryan McCann*、Lav R. Varshney、C - forward - - -## TFCTRLModel - -[[autodoc]] TFCTRLModel - - call - -## TFCTRLLMHeadModel - -[[autodoc]] TFCTRLLMHeadModel - - call - -## TFCTRLForSequenceClassification - -[[autodoc]] TFCTRLForSequenceClassification - - call - - diff --git a/docs/source/ja/model_doc/cvt.md b/docs/source/ja/model_doc/cvt.md index ba092732986d..86f54afafee9 100644 --- a/docs/source/ja/model_doc/cvt.md +++ b/docs/source/ja/model_doc/cvt.md @@ -71,18 +71,5 @@ CvT を始めるのに役立つ公式 Hugging Face およびコミュニティ ( - forward - - -## TFCvtModel - -[[autodoc]] TFCvtModel - - call - -## TFCvtForImageClassification - -[[autodoc]] TFCvtForImageClassification - - call - - diff --git a/docs/source/ja/model_doc/data2vec.md b/docs/source/ja/model_doc/data2vec.md index b5267aae35b6..53f389223d1f 100644 --- a/docs/source/ja/model_doc/data2vec.md +++ b/docs/source/ja/model_doc/data2vec.md @@ -166,22 +166,4 @@ Data2Vec の使用を開始するのに役立つ公式 Hugging Face およびコ - forward - - -## TFData2VecVisionModel - -[[autodoc]] TFData2VecVisionModel - - call - -## TFData2VecVisionForImageClassification - -[[autodoc]] TFData2VecVisionForImageClassification - - call - -## TFData2VecVisionForSemanticSegmentation - -[[autodoc]] TFData2VecVisionForSemanticSegmentation - - call - - diff --git a/docs/source/ja/model_doc/deberta-v2.md b/docs/source/ja/model_doc/deberta-v2.md index 279dae3610ab..0054b6ad3dbf 100644 --- a/docs/source/ja/model_doc/deberta-v2.md +++ b/docs/source/ja/model_doc/deberta-v2.md @@ -124,44 +124,6 @@ v2 の新機能: - forward - - -## TFDebertaV2Model - -[[autodoc]] TFDebertaV2Model - - call - -## TFDebertaV2PreTrainedModel - -[[autodoc]] TFDebertaV2PreTrainedModel - - call - -## TFDebertaV2ForMaskedLM - -[[autodoc]] TFDebertaV2ForMaskedLM - - call - -## TFDebertaV2ForSequenceClassification - -[[autodoc]] TFDebertaV2ForSequenceClassification - - call - -## TFDebertaV2ForTokenClassification - -[[autodoc]] TFDebertaV2ForTokenClassification - - call - -## TFDebertaV2ForQuestionAnswering - -[[autodoc]] TFDebertaV2ForQuestionAnswering - - call - -## TFDebertaV2ForMultipleChoice - -[[autodoc]] TFDebertaV2ForMultipleChoice - - call - - diff --git a/docs/source/ja/model_doc/deberta.md b/docs/source/ja/model_doc/deberta.md index 8a9440a91f00..1a7ae534911a 100644 --- a/docs/source/ja/model_doc/deberta.md +++ b/docs/source/ja/model_doc/deberta.md @@ -127,38 +127,5 @@ DeBERTa を使い始めるのに役立つ公式 Hugging Face およびコミュ - forward - - -## TFDebertaModel - -[[autodoc]] TFDebertaModel - - call - -## TFDebertaPreTrainedModel - -[[autodoc]] TFDebertaPreTrainedModel - - call - -## TFDebertaForMaskedLM - -[[autodoc]] TFDebertaForMaskedLM - - call - -## TFDebertaForSequenceClassification - -[[autodoc]] TFDebertaForSequenceClassification - - call - -## TFDebertaForTokenClassification - -[[autodoc]] TFDebertaForTokenClassification - - call - -## TFDebertaForQuestionAnswering - -[[autodoc]] TFDebertaForQuestionAnswering - - call - - diff --git a/docs/source/ja/model_doc/deit.md b/docs/source/ja/model_doc/deit.md index ba769dcf0dbf..3332d3f16738 100644 --- a/docs/source/ja/model_doc/deit.md +++ b/docs/source/ja/model_doc/deit.md @@ -127,27 +127,4 @@ DeiT を始めるのに役立つ公式 Hugging Face およびコミュニティ - forward - - -## TFDeiTModel - -[[autodoc]] TFDeiTModel - - call - -## TFDeiTForMaskedImageModeling - -[[autodoc]] TFDeiTForMaskedImageModeling - - call - -## TFDeiTForImageClassification - -[[autodoc]] TFDeiTForImageClassification - - call - -## TFDeiTForImageClassificationWithTeacher - -[[autodoc]] TFDeiTForImageClassificationWithTeacher - - call - - \ No newline at end of file diff --git a/docs/source/ko/internal/generation_utils.md b/docs/source/ko/internal/generation_utils.md index d97dfb2ae6f3..01a9e6f2b935 100644 --- a/docs/source/ko/internal/generation_utils.md +++ b/docs/source/ko/internal/generation_utils.md @@ -68,36 +68,6 @@ generation_output[:2] [[autodoc]] generation.GenerateBeamEncoderDecoderOutput -### TensorFlow [[transformers.generation.TFGreedySearchEncoderDecoderOutput]] - -[[autodoc]] generation.TFGreedySearchEncoderDecoderOutput - -[[autodoc]] generation.TFGreedySearchDecoderOnlyOutput - -[[autodoc]] generation.TFSampleEncoderDecoderOutput - -[[autodoc]] generation.TFSampleDecoderOnlyOutput - -[[autodoc]] generation.TFBeamSearchEncoderDecoderOutput - -[[autodoc]] generation.TFBeamSearchDecoderOnlyOutput - -[[autodoc]] generation.TFBeamSampleEncoderDecoderOutput - -[[autodoc]] generation.TFBeamSampleDecoderOnlyOutput - -[[autodoc]] generation.TFContrastiveSearchEncoderDecoderOutput - -[[autodoc]] generation.TFContrastiveSearchDecoderOnlyOutput - -### FLAX [[transformers.generation.FlaxSampleOutput]] - -[[autodoc]] generation.FlaxSampleOutput - -[[autodoc]] generation.FlaxGreedySearchOutput - -[[autodoc]] generation.FlaxBeamSearchOutput - ## LogitsProcessor [[logitsprocessor]] [`LogitsProcessor`]는 생성 중 언어 모델 헤드의 예측 점수를 수정하는 데 사용됩니다. @@ -194,95 +164,6 @@ generation_output[:2] [[autodoc]] WatermarkLogitsProcessor - __call__ - -### TensorFlow [[transformers.TFForcedBOSTokenLogitsProcessor]] - -[[autodoc]] TFForcedBOSTokenLogitsProcessor - - __call__ - -[[autodoc]] TFForcedEOSTokenLogitsProcessor - - __call__ - -[[autodoc]] TFForceTokensLogitsProcessor - - __call__ - -[[autodoc]] TFLogitsProcessor - - __call__ - -[[autodoc]] TFLogitsProcessorList - - __call__ - -[[autodoc]] TFLogitsWarper - - __call__ - -[[autodoc]] TFMinLengthLogitsProcessor - - __call__ - -[[autodoc]] TFNoBadWordsLogitsProcessor - - __call__ - -[[autodoc]] TFNoRepeatNGramLogitsProcessor - - __call__ - -[[autodoc]] TFRepetitionPenaltyLogitsProcessor - - __call__ - -[[autodoc]] TFSuppressTokensAtBeginLogitsProcessor - - __call__ - -[[autodoc]] TFSuppressTokensLogitsProcessor - - __call__ - -[[autodoc]] TFTemperatureLogitsWarper - - __call__ - -[[autodoc]] TFTopKLogitsWarper - - __call__ - -[[autodoc]] TFTopPLogitsWarper - - __call__ - -### FLAX [[transformers.FlaxForcedBOSTokenLogitsProcessor]] - -[[autodoc]] FlaxForcedBOSTokenLogitsProcessor - - __call__ - -[[autodoc]] FlaxForcedEOSTokenLogitsProcessor - - __call__ - -[[autodoc]] FlaxForceTokensLogitsProcessor - - __call__ - -[[autodoc]] FlaxLogitsProcessor - - __call__ - -[[autodoc]] FlaxLogitsProcessorList - - __call__ - -[[autodoc]] FlaxLogitsWarper - - __call__ - -[[autodoc]] FlaxMinLengthLogitsProcessor - - __call__ - -[[autodoc]] FlaxSuppressTokensAtBeginLogitsProcessor - - __call__ - -[[autodoc]] FlaxSuppressTokensLogitsProcessor - - __call__ - -[[autodoc]] FlaxTemperatureLogitsWarper - - __call__ - -[[autodoc]] FlaxTopKLogitsWarper - - __call__ - -[[autodoc]] FlaxTopPLogitsWarper - - __call__ - -[[autodoc]] FlaxWhisperTimeStampLogitsProcessor - - __call__ - ## StoppingCriteria [[transformers.StoppingCriteria]] [`StoppingCriteria`]는 생성이 언제 멈출지를 결정하는 데 사용됩니다 (EOS 토큰 외). 이 기능은 PyTorch 구현에만 제공됩니다. diff --git a/docs/source/ko/internal/modeling_utils.md b/docs/source/ko/internal/modeling_utils.md index f84ae30cd6f5..d51408ae2bad 100644 --- a/docs/source/ko/internal/modeling_utils.md +++ b/docs/source/ko/internal/modeling_utils.md @@ -36,31 +36,3 @@ rendered properly in your Markdown viewer. [[autodoc]] pytorch_utils.prune_conv1d_layer [[autodoc]] pytorch_utils.prune_linear_layer - -## TensorFlow 사용자 정의 레이어 [[transformers.modeling_tf_utils.TFConv1D]] - -[[autodoc]] modeling_tf_utils.TFConv1D - -[[autodoc]] modeling_tf_utils.TFSequenceSummary - -## TensorFlow 손실 함수 [[transformers.modeling_tf_utils.TFCausalLanguageModelingLoss]] - -[[autodoc]] modeling_tf_utils.TFCausalLanguageModelingLoss - -[[autodoc]] modeling_tf_utils.TFMaskedLanguageModelingLoss - -[[autodoc]] modeling_tf_utils.TFMultipleChoiceLoss - -[[autodoc]] modeling_tf_utils.TFQuestionAnsweringLoss - -[[autodoc]] modeling_tf_utils.TFSequenceClassificationLoss - -[[autodoc]] modeling_tf_utils.TFTokenClassificationLoss - -## TensorFlow 도우미 함수 [[transformers.modeling_tf_utils.get_initializer]] - -[[autodoc]] modeling_tf_utils.get_initializer - -[[autodoc]] modeling_tf_utils.keras_serializable - -[[autodoc]] modeling_tf_utils.shape_list diff --git a/docs/source/ko/main_classes/model.md b/docs/source/ko/main_classes/model.md index 71a9768deee1..67a8ba535fda 100644 --- a/docs/source/ko/main_classes/model.md +++ b/docs/source/ko/main_classes/model.md @@ -43,22 +43,6 @@ rendered properly in your Markdown viewer. [[autodoc]] modeling_utils.ModuleUtilsMixin -## TFPreTrainedModel - -[[autodoc]] TFPreTrainedModel - - push_to_hub - - all - -## TFModelUtilsMixin - -[[autodoc]] modeling_tf_utils.TFModelUtilsMixin - -## FlaxPreTrainedModel - -[[autodoc]] FlaxPreTrainedModel - - push_to_hub - - all - ## 허브에 저장하기 [[autodoc]] utils.PushToHubMixin diff --git a/docs/source/ko/main_classes/output.md b/docs/source/ko/main_classes/output.md index e65a2c2c3590..c383a522a1aa 100644 --- a/docs/source/ko/main_classes/output.md +++ b/docs/source/ko/main_classes/output.md @@ -181,134 +181,3 @@ outputs[:2] [[autodoc]] modeling_outputs.SampleTSPredictionOutput -## TFBaseModelOutput[[transformers.modeling_outputs.TFBaseModelOutput]] - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutput - -## TFBaseModelOutputWithPooling[[transformers.modeling_tf_outputs.TFBaseModelOutputWithPooling]] - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPooling - -## TFBaseModelOutputWithPoolingAndCrossAttentions[[transformers.modeling_tf_outputs.TFBaseModelOutputWithPoolingAndCrossAttentions]] - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPoolingAndCrossAttentions - -## TFBaseModelOutputWithPast[[transformers.modeling_tf_outputs.TFBaseModelOutputWithPast]] - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPast - -## TFBaseModelOutputWithPastAndCrossAttentions[[transformers.modeling_tf_outputs.TFBaseModelOutputWithPastAndCrossAttentions]] - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPastAndCrossAttentions - -## TFSeq2SeqModelOutput[[transformers.modeling_tf_outputs.TFSeq2SeqModelOutput]] - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqModelOutput - -## TFCausalLMOutput[[transformers.modeling_tf_outputs.TFCausalLMOutput]] - -[[autodoc]] modeling_tf_outputs.TFCausalLMOutput - -## TFCausalLMOutputWithCrossAttentions[[transformers.modeling_tf_outputs.TFCausalLMOutputWithCrossAttentions]] - -[[autodoc]] modeling_tf_outputs.TFCausalLMOutputWithCrossAttentions - -## TFCausalLMOutputWithPast[[transformers.modeling_tf_outputs.TFCausalLMOutputWithPast]] - -[[autodoc]] modeling_tf_outputs.TFCausalLMOutputWithPast - -## TFMaskedLMOutput[[transformers.modeling_tf_outputs.TFMaskedLMOutput]] - -[[autodoc]] modeling_tf_outputs.TFMaskedLMOutput - -## TFSeq2SeqLMOutput[[transformers.modeling_tf_outputs.TFSeq2SeqLMOutput]] - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqLMOutput - -## TFNextSentencePredictorOutput[[transformers.modeling_tf_outputs.TFNextSentencePredictorOutput]] - -[[autodoc]] modeling_tf_outputs.TFNextSentencePredictorOutput - -## TFSequenceClassifierOutput[[transformers.modeling_tf_outputs.TFSequenceClassifierOutput]] - -[[autodoc]] modeling_tf_outputs.TFSequenceClassifierOutput - -## TFSeq2SeqSequenceClassifierOutput[[transformers.modeling_tf_outputs.TFSeq2SeqSequenceClassifierOutput]] - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqSequenceClassifierOutput - -## TFMultipleChoiceModelOutput[[transformers.modeling_tf_outputs.TFMultipleChoiceModelOutput]] - -[[autodoc]] modeling_tf_outputs.TFMultipleChoiceModelOutput - -## TFTokenClassifierOutput[[transformers.modeling_tf_outputs.TFTokenClassifierOutput]] - -[[autodoc]] modeling_tf_outputs.TFTokenClassifierOutput - -## TFQuestionAnsweringModelOutput[[transformers.modeling_tf_outputs.TFQuestionAnsweringModelOutput]] - -[[autodoc]] modeling_tf_outputs.TFQuestionAnsweringModelOutput - -## TFSeq2SeqQuestionAnsweringModelOutput[[transformers.modeling_tf_outputs.TFSeq2SeqQuestionAnsweringModelOutput]] - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqQuestionAnsweringModelOutput - -## FlaxBaseModelOutput[[transformers.modeling_flax_outputs.FlaxBaseModelOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutput - -## FlaxBaseModelOutputWithPast[[transformers.modeling_flax_outputs.FlaxBaseModelOutputWithPast]] - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutputWithPast - -## FlaxBaseModelOutputWithPooling[[transformers.modeling_flax_outputs.FlaxBaseModelOutputWithPooling]] - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutputWithPooling - -## FlaxBaseModelOutputWithPastAndCrossAttentions[[transformers.modeling_flax_outputs.FlaxBaseModelOutputWithPastAndCrossAttentions]] - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutputWithPastAndCrossAttentions - -## FlaxSeq2SeqModelOutput[[transformers.modeling_flax_outputs.FlaxSeq2SeqModelOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqModelOutput - -## FlaxCausalLMOutputWithCrossAttentions[[transformers.modeling_flax_outputs.FlaxCausalLMOutputWithCrossAttentions]] - -[[autodoc]] modeling_flax_outputs.FlaxCausalLMOutputWithCrossAttentions - -## FlaxMaskedLMOutput[[transformers.modeling_flax_outputs.FlaxMaskedLMOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxMaskedLMOutput - -## FlaxSeq2SeqLMOutput[[transformers.modeling_flax_outputs.FlaxSeq2SeqLMOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqLMOutput - -## FlaxNextSentencePredictorOutput[[transformers.modeling_flax_outputs.FlaxNextSentencePredictorOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxNextSentencePredictorOutput - -## FlaxSequenceClassifierOutput[[transformers.modeling_flax_outputs.FlaxSequenceClassifierOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxSequenceClassifierOutput - -## FlaxSeq2SeqSequenceClassifierOutput[[transformers.modeling_flax_outputs.FlaxSeq2SeqSequenceClassifierOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqSequenceClassifierOutput - -## FlaxMultipleChoiceModelOutput[[transformers.modeling_flax_outputs.FlaxMultipleChoiceModelOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxMultipleChoiceModelOutput - -## FlaxTokenClassifierOutput[[transformers.modeling_flax_outputs.FlaxTokenClassifierOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxTokenClassifierOutput - -## FlaxQuestionAnsweringModelOutput[[transformers.modeling_flax_outputs.FlaxQuestionAnsweringModelOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxQuestionAnsweringModelOutput - -## FlaxSeq2SeqQuestionAnsweringModelOutput[[transformers.modeling_flax_outputs.FlaxSeq2SeqQuestionAnsweringModelOutput]] - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqQuestionAnsweringModelOutput diff --git a/docs/source/ko/main_classes/text_generation.md b/docs/source/ko/main_classes/text_generation.md index 917d995e6ec1..f220939b0daf 100644 --- a/docs/source/ko/main_classes/text_generation.md +++ b/docs/source/ko/main_classes/text_generation.md @@ -44,13 +44,3 @@ rendered properly in your Markdown viewer. - generate - compute_transition_scores -## TFGenerationMixin [[transformers.TFGenerationMixin]] - -[[autodoc]] generation.TFGenerationMixin - - generate - - compute_transition_scores - -## FlaxGenerationMixin [[transformers.FlaxGenerationMixin]] - -[[autodoc]] generation.FlaxGenerationMixin - - generate diff --git a/docs/source/ko/model_doc/albert.md b/docs/source/ko/model_doc/albert.md index 7e2bc2f46328..2ca79a721d60 100644 --- a/docs/source/ko/model_doc/albert.md +++ b/docs/source/ko/model_doc/albert.md @@ -163,8 +163,6 @@ echo -e "Plants create [MASK] through a process known as photosynthesis." | tran [[autodoc]] models.albert.modeling_albert.AlbertForPreTrainingOutput -[[autodoc]] models.albert.modeling_tf_albert.TFAlbertForPreTrainingOutput - @@ -197,67 +195,4 @@ echo -e "Plants create [MASK] through a process known as photosynthesis." | tran [[autodoc]] AlbertForQuestionAnswering - forward - - - -## TFAlbertModel[[tfalbertmodel]] - -[[autodoc]] TFAlbertModel - call - -## TFAlbertForPreTraining[[tfalbertforpretraining]] - -[[autodoc]] TFAlbertForPreTraining - call - -## TFAlbertForMaskedLM[[tfalbertformaskedlm]] - -[[autodoc]] TFAlbertForMaskedLM - call - -## TFAlbertForSequenceClassification[[tfalbertforsequenceclassification]] - -[[autodoc]] TFAlbertForSequenceClassification - call - -## TFAlbertForMultipleChoice[[tfalbertformultiplechoice]] - -[[autodoc]] TFAlbertForMultipleChoice - call - -## TFAlbertForTokenClassification[[tfalbertfortokenclassification]] - -[[autodoc]] TFAlbertForTokenClassification - call - -## TFAlbertForQuestionAnswering[[tfalbertforquestionanswering]] - -[[autodoc]] TFAlbertForQuestionAnswering - call - - - - -## FlaxAlbertModel[[flaxalbertmodel]] - -[[autodoc]] FlaxAlbertModel - **call** - -## FlaxAlbertForPreTraining[[flaxalbertforpretraining]] - -[[autodoc]] FlaxAlbertForPreTraining - **call** - -## FlaxAlbertForMaskedLM[[flaxalbertformaskedlm]] - -[[autodoc]] FlaxAlbertForMaskedLM - **call** - -## FlaxAlbertForSequenceClassification[[flaxalbertforsequenceclassification]] - -[[autodoc]] FlaxAlbertForSequenceClassification - **call** - -## FlaxAlbertForMultipleChoice[[flaxalbertformultiplechoice]] - -[[autodoc]] FlaxAlbertForMultipleChoice - **call** - -## FlaxAlbertForTokenClassification[[flaxalbertfortokenclassification]] - -[[autodoc]] FlaxAlbertForTokenClassification - **call** - -## FlaxAlbertForQuestionAnswering[[flaxalbertforquestionanswering]] - -[[autodoc]] FlaxAlbertForQuestionAnswering - **call** - - diff --git a/docs/source/ko/model_doc/auto.md b/docs/source/ko/model_doc/auto.md index 45c2f917a42c..f928b1904553 100644 --- a/docs/source/ko/model_doc/auto.md +++ b/docs/source/ko/model_doc/auto.md @@ -78,14 +78,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModel -### TFAutoModel[[transformers.TFAutoModel]] - -[[autodoc]] TFAutoModel - -### FlaxAutoModel[[transformers.FlaxAutoModel]] - -[[autodoc]] FlaxAutoModel - ## 일반적인 사전 학습 클래스[[generic-pretraining-classes]] 다음 자동 클래스들은 사전 훈련 헤드가 포함된 모델을 인스턴스화하는 데 사용할 수 있습니다. @@ -94,14 +86,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForPreTraining -### TFAutoModelForPreTraining[[transformers.TFAutoModelForPreTraining]] - -[[autodoc]] TFAutoModelForPreTraining - -### FlaxAutoModelForPreTraining[[transformers.FlaxAutoModelForPreTraining]] - -[[autodoc]] FlaxAutoModelForPreTraining - ## 자연어 처리[[natural-language-processing]] 다음 자동 클래스들은 아래의 자연어 처리 작업에 사용할 수 있습니다. @@ -110,114 +94,42 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForCausalLM -### TFAutoModelForCausalLM[[transformers.TFAutoModelForCausalLM]] - -[[autodoc]] TFAutoModelForCausalLM - -### FlaxAutoModelForCausalLM[[transformers.FlaxAutoModelForCausalLM]] - -[[autodoc]] FlaxAutoModelForCausalLM - ### AutoModelForMaskedLM[[transformers.AutoModelForMaskedLM]] [[autodoc]] AutoModelForMaskedLM -### TFAutoModelForMaskedLM[[transformers.TFAutoModelForMaskedLM]] - -[[autodoc]] TFAutoModelForMaskedLM - -### FlaxAutoModelForMaskedLM[[transformers.FlaxAutoModelForMaskedLM]] - -[[autodoc]] FlaxAutoModelForMaskedLM - ### AutoModelForMaskGeneration[[transformers.AutoModelForMaskGeneration]] [[autodoc]] AutoModelForMaskGeneration -### TFAutoModelForMaskGeneration[[transformers.TFAutoModelForMaskGeneration]] - -[[autodoc]] TFAutoModelForMaskGeneration - ### AutoModelForSeq2SeqLM[[transformers.AutoModelForSeq2SeqLM]] [[autodoc]] AutoModelForSeq2SeqLM -### TFAutoModelForSeq2SeqLM[[transformers.TFAutoModelForSeq2SeqLM]] - -[[autodoc]] TFAutoModelForSeq2SeqLM - -### FlaxAutoModelForSeq2SeqLM[[transformers.FlaxAutoModelForSeq2SeqLM]] - -[[autodoc]] FlaxAutoModelForSeq2SeqLM - ### AutoModelForSequenceClassification[[transformers.AutoModelForSequenceClassification]] [[autodoc]] AutoModelForSequenceClassification -### TFAutoModelForSequenceClassification[[transformers.TFAutoModelForSequenceClassification]] - -[[autodoc]] TFAutoModelForSequenceClassification - -### FlaxAutoModelForSequenceClassification[[transformers.FlaxAutoModelForSequenceClassification]] - -[[autodoc]] FlaxAutoModelForSequenceClassification - ### AutoModelForMultipleChoice[[transformers.AutoModelForMultipleChoice]] [[autodoc]] AutoModelForMultipleChoice -### TFAutoModelForMultipleChoice[[transformers.TFAutoModelForMultipleChoice]] - -[[autodoc]] TFAutoModelForMultipleChoice - -### FlaxAutoModelForMultipleChoice[[transformers.FlaxAutoModelForMultipleChoice]] - -[[autodoc]] FlaxAutoModelForMultipleChoice - ### AutoModelForNextSentencePrediction[[transformers.AutoModelForNextSentencePrediction]] [[autodoc]] AutoModelForNextSentencePrediction -### TFAutoModelForNextSentencePrediction[[transformers.TFAutoModelForNextSentencePrediction]] - -[[autodoc]] TFAutoModelForNextSentencePrediction - -### FlaxAutoModelForNextSentencePrediction[[transformers.FlaxAutoModelForNextSentencePrediction]] - -[[autodoc]] FlaxAutoModelForNextSentencePrediction - ### AutoModelForTokenClassification[[transformers.AutoModelForTokenClassification]] [[autodoc]] AutoModelForTokenClassification -### TFAutoModelForTokenClassification[[transformers.TFAutoModelForTokenClassification]] - -[[autodoc]] TFAutoModelForTokenClassification - -### FlaxAutoModelForTokenClassification[[transformers.FlaxAutoModelForTokenClassification]] - -[[autodoc]] FlaxAutoModelForTokenClassification - ### AutoModelForQuestionAnswering[[transformers.AutoModelForQuestionAnswering]] [[autodoc]] AutoModelForQuestionAnswering -### TFAutoModelForQuestionAnswering[[transformers.TFAutoModelForQuestionAnswering]] - -[[autodoc]] TFAutoModelForQuestionAnswering - -### FlaxAutoModelForQuestionAnswering[[transformers.FlaxAutoModelForQuestionAnswering]] - -[[autodoc]] FlaxAutoModelForQuestionAnswering - ### AutoModelForTextEncoding[[transformers.AutoModelForTextEncoding]] [[autodoc]] AutoModelForTextEncoding -### TFAutoModelForTextEncoding[[transformers.TFAutoModelForTextEncoding]] - -[[autodoc]] TFAutoModelForTextEncoding - ## 컴퓨터 비전[[computer-vision]] 다음 자동 클래스들은 아래의 컴퓨터 비전 작업에 사용할 수 있습니다. @@ -230,14 +142,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForImageClassification -### TFAutoModelForImageClassification[[transformers.TFAutoModelForImageClassification]] - -[[autodoc]] TFAutoModelForImageClassification - -### FlaxAutoModelForImageClassification[[transformers.FlaxAutoModelForImageClassification]] - -[[autodoc]] FlaxAutoModelForImageClassification - ### AutoModelForVideoClassification[[transformers.AutoModelForVideoClassification]] [[autodoc]] AutoModelForVideoClassification @@ -250,10 +154,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForMaskedImageModeling -### TFAutoModelForMaskedImageModeling[[transformers.TFAutoModelForMaskedImageModeling]] - -[[autodoc]] TFAutoModelForMaskedImageModeling - ### AutoModelForObjectDetection[[transformers.AutoModelForObjectDetection]] [[autodoc]] AutoModelForObjectDetection @@ -270,10 +170,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForSemanticSegmentation -### TFAutoModelForSemanticSegmentation[[transformers.TFAutoModelForSemanticSegmentation]] - -[[autodoc]] TFAutoModelForSemanticSegmentation - ### AutoModelForInstanceSegmentation[[transformers.AutoModelForInstanceSegmentation]] [[autodoc]] AutoModelForInstanceSegmentation @@ -286,10 +182,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForZeroShotImageClassification -### TFAutoModelForZeroShotImageClassification[[transformers.TFAutoModelForZeroShotImageClassification]] - -[[autodoc]] TFAutoModelForZeroShotImageClassification - ### AutoModelForZeroShotObjectDetection[[transformers.AutoModelForZeroShotObjectDetection]] [[autodoc]] AutoModelForZeroShotObjectDetection @@ -302,10 +194,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForAudioClassification -### TFAutoModelForAudioClassification[[transformers.TFAutoModelForAudioClassification]] - -[[autodoc]] TFAutoModelForAudioClassification - ### AutoModelForAudioFrameClassification[[transformers.AutoModelForAudioFrameClassification]] [[autodoc]] AutoModelForAudioFrameClassification @@ -318,14 +206,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForSpeechSeq2Seq -### TFAutoModelForSpeechSeq2Seq[[transformers.TFAutoModelForSpeechSeq2Seq]] - -[[autodoc]] TFAutoModelForSpeechSeq2Seq - -### FlaxAutoModelForSpeechSeq2Seq[[transformers.FlaxAutoModelForSpeechSeq2Seq]] - -[[autodoc]] FlaxAutoModelForSpeechSeq2Seq - ### AutoModelForAudioXVector[[transformers.AutoModelForAudioXVector]] [[autodoc]] AutoModelForAudioXVector @@ -346,18 +226,10 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForTableQuestionAnswering -### TFAutoModelForTableQuestionAnswering[[transformers.TFAutoModelForTableQuestionAnswering]] - -[[autodoc]] TFAutoModelForTableQuestionAnswering - ### AutoModelForDocumentQuestionAnswering[[transformers.AutoModelForDocumentQuestionAnswering]] [[autodoc]] AutoModelForDocumentQuestionAnswering -### TFAutoModelForDocumentQuestionAnswering[[transformers.TFAutoModelForDocumentQuestionAnswering]] - -[[autodoc]] TFAutoModelForDocumentQuestionAnswering - ### AutoModelForVisualQuestionAnswering[[transformers.AutoModelForVisualQuestionAnswering]] [[autodoc]] AutoModelForVisualQuestionAnswering @@ -366,14 +238,6 @@ AutoModel.register(NewModelConfig, NewModel) [[autodoc]] AutoModelForVision2Seq -### TFAutoModelForVision2Seq[[transformers.TFAutoModelForVision2Seq]] - -[[autodoc]] TFAutoModelForVision2Seq - -### FlaxAutoModelForVision2Seq[[transformers.FlaxAutoModelForVision2Seq]] - -[[autodoc]] FlaxAutoModelForVision2Seq - ## Time Series ### AutoModelForTimeSeriesPrediction[[transformers.AutoModelForTimeSeriesPrediction]] diff --git a/docs/source/ko/model_doc/bart.md b/docs/source/ko/model_doc/bart.md index 86d97b13103e..6e76a78484e3 100644 --- a/docs/source/ko/model_doc/bart.md +++ b/docs/source/ko/model_doc/bart.md @@ -158,59 +158,6 @@ BART를 시작하는 데 도움이 되는 Hugging Face와 community 자료 목 - forward - - -## TFBartModel[[transformers.TFBartModel]] - -[[autodoc]] TFBartModel - - call - -## TFBartForConditionalGeneration[[transformers.TFBartForConditionalGeneration]] - -[[autodoc]] TFBartForConditionalGeneration - - call - -## TFBartForSequenceClassification[[transformers.TFBartForSequenceClassification]] - -[[autodoc]] TFBartForSequenceClassification - - call - - - - -## FlaxBartModel[[transformers.FlaxBartModel]] - -[[autodoc]] FlaxBartModel - - __call__ - - encode - - decode - -## FlaxBartForConditionalGeneration[[transformers.FlaxBartForConditionalGeneration]] - -[[autodoc]] FlaxBartForConditionalGeneration - - __call__ - - encode - - decode - -## FlaxBartForSequenceClassification[[transformers.FlaxBartForSequenceClassification]] - -[[autodoc]] FlaxBartForSequenceClassification - - __call__ - - encode - - decode - -## FlaxBartForQuestionAnswering[[transformers.FlaxBartForQuestionAnswering]] - -[[autodoc]] FlaxBartForQuestionAnswering - - __call__ - - encode - - decode - -## FlaxBartForCausalLM[[transformers.FlaxBartForCausalLM]] - -[[autodoc]] FlaxBartForCausalLM - - __call__ - diff --git a/docs/source/ko/model_doc/bert.md b/docs/source/ko/model_doc/bert.md index 28aee583c0cb..b08c81459a02 100644 --- a/docs/source/ko/model_doc/bert.md +++ b/docs/source/ko/model_doc/bert.md @@ -172,24 +172,12 @@ BERT를 시작하는 데 도움이 되는 Hugging Face와 community 자료 목 [[autodoc]] BertTokenizerFast - - -## TFBertTokenizer - -[[autodoc]] TFBertTokenizer - - ## Bert specific outputs [[autodoc]] models.bert.modeling_bert.BertForPreTrainingOutput -[[autodoc]] models.bert.modeling_tf_bert.TFBertForPreTrainingOutput - -[[autodoc]] models.bert.modeling_flax_bert.FlaxBertForPreTrainingOutput - - @@ -239,102 +227,6 @@ BERT를 시작하는 데 도움이 되는 Hugging Face와 community 자료 목 - forward - - -## TFBertModel - -[[autodoc]] TFBertModel - - call - -## TFBertForPreTraining - -[[autodoc]] TFBertForPreTraining - - call - -## TFBertModelLMHeadModel - -[[autodoc]] TFBertLMHeadModel - - call - -## TFBertForMaskedLM - -[[autodoc]] TFBertForMaskedLM - - call - -## TFBertForNextSentencePrediction - -[[autodoc]] TFBertForNextSentencePrediction - - call - -## TFBertForSequenceClassification - -[[autodoc]] TFBertForSequenceClassification - - call - -## TFBertForMultipleChoice - -[[autodoc]] TFBertForMultipleChoice - - call - -## TFBertForTokenClassification - -[[autodoc]] TFBertForTokenClassification - - call - -## TFBertForQuestionAnswering - -[[autodoc]] TFBertForQuestionAnswering - - call - - - - -## FlaxBertModel - -[[autodoc]] FlaxBertModel - - __call__ - -## FlaxBertForPreTraining - -[[autodoc]] FlaxBertForPreTraining - - __call__ - -## FlaxBertForCausalLM - -[[autodoc]] FlaxBertForCausalLM - - __call__ - -## FlaxBertForMaskedLM - -[[autodoc]] FlaxBertForMaskedLM - - __call__ - -## FlaxBertForNextSentencePrediction - -[[autodoc]] FlaxBertForNextSentencePrediction - - __call__ - -## FlaxBertForSequenceClassification - -[[autodoc]] FlaxBertForSequenceClassification - - __call__ - -## FlaxBertForMultipleChoice - -[[autodoc]] FlaxBertForMultipleChoice - - __call__ - -## FlaxBertForTokenClassification - -[[autodoc]] FlaxBertForTokenClassification - - __call__ - -## FlaxBertForQuestionAnswering - -[[autodoc]] FlaxBertForQuestionAnswering - - __call__ - - diff --git a/docs/source/ko/model_doc/blip.md b/docs/source/ko/model_doc/blip.md index 6b5a4e8abc2d..8e88884a793a 100644 --- a/docs/source/ko/model_doc/blip.md +++ b/docs/source/ko/model_doc/blip.md @@ -99,38 +99,4 @@ BLIP은 여러 멀티모달 작업을 수행할 수 있는 모델입니다: - forward - - -## TFBlipModel[[transformers.TFBlipModel]] - -[[autodoc]] TFBlipModel - - call - - get_text_features - - get_image_features - -## TFBlipTextModel[[transformers.TFBlipTextModel]] - -[[autodoc]] TFBlipTextModel - - call - -## TFBlipVisionModel[[transformers.TFBlipVisionModel]] - -[[autodoc]] TFBlipVisionModel - - call - -## TFBlipForConditionalGeneration[[transformers.TFBlipForConditionalGeneration]] - -[[autodoc]] TFBlipForConditionalGeneration - - call - -## TFBlipForImageTextRetrieval[[transformers.TFBlipForImageTextRetrieval]] - -[[autodoc]] TFBlipForImageTextRetrieval - - call - -## TFBlipForQuestionAnswering[[transformers.TFBlipForQuestionAnswering]] - -[[autodoc]] TFBlipForQuestionAnswering - - call - diff --git a/docs/source/ko/model_doc/clip.md b/docs/source/ko/model_doc/clip.md index d5af5a24f397..b9517cea17df 100644 --- a/docs/source/ko/model_doc/clip.md +++ b/docs/source/ko/model_doc/clip.md @@ -270,49 +270,4 @@ CLIP을 시작하는 데 도움이 되는 Hugging Face와 community 자료 목 - forward - - -## TFCLIPModel[[transformers.TFCLIPModel]] - -[[autodoc]] TFCLIPModel - - call - - get_text_features - - get_image_features - -## TFCLIPTextModel[[transformers.TFCLIPTextModel]] - -[[autodoc]] TFCLIPTextModel - - call - -## TFCLIPVisionModel[[transformers.TFCLIPVisionModel]] - -[[autodoc]] TFCLIPVisionModel - - call - - - - -## FlaxCLIPModel[[transformers.FlaxCLIPModel]] - -[[autodoc]] FlaxCLIPModel - - __call__ - - get_text_features - - get_image_features - -## FlaxCLIPTextModel[[transformers.FlaxCLIPTextModel]] - -[[autodoc]] FlaxCLIPTextModel - - __call__ - -## FlaxCLIPTextModelWithProjection[[transformers.FlaxCLIPTextModelWithProjection]] - -[[autodoc]] FlaxCLIPTextModelWithProjection - - __call__ - -## FlaxCLIPVisionModel[[transformers.FlaxCLIPVisionModel]] - -[[autodoc]] FlaxCLIPVisionModel - - __call__ - - diff --git a/docs/source/ko/model_doc/convbert.md b/docs/source/ko/model_doc/convbert.md index c4f0d2ace252..6bbac5b42272 100644 --- a/docs/source/ko/model_doc/convbert.md +++ b/docs/source/ko/model_doc/convbert.md @@ -99,37 +99,4 @@ ConvBERT 훈련 팁은 BERT와 유사합니다. 사용 팁은 [BERT 문서](bert - forward - - -## TFConvBertModel [[transformers.TFConvBertModel]] - -[[autodoc]] TFConvBertModel - - call - -## TFConvBertForMaskedLM [[transformers.TFConvBertForMaskedLM]] - -[[autodoc]] TFConvBertForMaskedLM - - call - -## TFConvBertForSequenceClassification [[transformers.TFConvBertForSequenceClassification]] - -[[autodoc]] TFConvBertForSequenceClassification - - call - -## TFConvBertForMultipleChoice [[transformers.TFConvBertForMultipleChoice]] - -[[autodoc]] TFConvBertForMultipleChoice - - call - -## TFConvBertForTokenClassification [[transformers.TFConvBertForTokenClassification]] - -[[autodoc]] TFConvBertForTokenClassification - - call - -## TFConvBertForQuestionAnswering [[transformers.TFConvBertForQuestionAnswering]] - -[[autodoc]] TFConvBertForQuestionAnswering - - call - - diff --git a/docs/source/ko/model_doc/deberta-v2.md b/docs/source/ko/model_doc/deberta-v2.md index bb7bed1434cd..254b183a5736 100644 --- a/docs/source/ko/model_doc/deberta-v2.md +++ b/docs/source/ko/model_doc/deberta-v2.md @@ -106,42 +106,4 @@ v2의 새로운 점: - forward - - -## TFDebertaV2Model - -[[autodoc]] TFDebertaV2Model - - call - -## TFDebertaV2PreTrainedModel - -[[autodoc]] TFDebertaV2PreTrainedModel - - call - -## TFDebertaV2ForMaskedLM - -[[autodoc]] TFDebertaV2ForMaskedLM - - call - -## TFDebertaV2ForSequenceClassification - -[[autodoc]] TFDebertaV2ForSequenceClassification - - call - -## TFDebertaV2ForTokenClassification - -[[autodoc]] TFDebertaV2ForTokenClassification - - call - -## TFDebertaV2ForQuestionAnswering - -[[autodoc]] TFDebertaV2ForQuestionAnswering - - call - -## TFDebertaV2ForMultipleChoice - -[[autodoc]] TFDebertaV2ForMultipleChoice - - call - - diff --git a/docs/source/ko/model_doc/deberta.md b/docs/source/ko/model_doc/deberta.md index b471c9327ae1..b76912197f1e 100644 --- a/docs/source/ko/model_doc/deberta.md +++ b/docs/source/ko/model_doc/deberta.md @@ -115,38 +115,5 @@ DeBERTa를 시작하는 데 도움이 되는 Hugging Face와 community 자료 - forward - - -## TFDebertaModel[[transformers.TFDebertaModel]] - -[[autodoc]] TFDebertaModel - - call - -## TFDebertaPreTrainedModel[[transformers.TFDebertaPreTrainedModel]] - -[[autodoc]] TFDebertaPreTrainedModel - - call - -## TFDebertaForMaskedLM[[transformers.TFDebertaForMaskedLM]] - -[[autodoc]] TFDebertaForMaskedLM - - call - -## TFDebertaForSequenceClassification[[transformers.TFDebertaForSequenceClassification]] - -[[autodoc]] TFDebertaForSequenceClassification - - call - -## TFDebertaForTokenClassification[[transformers.TFDebertaForTokenClassification]] - -[[autodoc]] TFDebertaForTokenClassification - - call - -## TFDebertaForQuestionAnswering[[transformers.TFDebertaForQuestionAnswering]] - -[[autodoc]] TFDebertaForQuestionAnswering - - call - - diff --git a/docs/source/ko/model_doc/electra.md b/docs/source/ko/model_doc/electra.md index d7bee11db701..e9e1879e13dc 100644 --- a/docs/source/ko/model_doc/electra.md +++ b/docs/source/ko/model_doc/electra.md @@ -66,8 +66,6 @@ Generators](https://openreview.net/pdf?id=r1xMH1BtvB) 논문에서 제안되었 [[autodoc]] models.electra.modeling_electra.ElectraForPreTrainingOutput -[[autodoc]] models.electra.modeling_tf_electra.TFElectraForPreTrainingOutput - @@ -112,85 +110,4 @@ Generators](https://openreview.net/pdf?id=r1xMH1BtvB) 논문에서 제안되었 - forward - - -## TFElectraModel - -[[autodoc]] TFElectraModel - - call - -## TFElectraForPreTraining - -[[autodoc]] TFElectraForPreTraining - - call - -## TFElectraForMaskedLM - -[[autodoc]] TFElectraForMaskedLM - - call - -## TFElectraForSequenceClassification - -[[autodoc]] TFElectraForSequenceClassification - - call - -## TFElectraForMultipleChoice - -[[autodoc]] TFElectraForMultipleChoice - - call - -## TFElectraForTokenClassification - -[[autodoc]] TFElectraForTokenClassification - - call - -## TFElectraForQuestionAnswering - -[[autodoc]] TFElectraForQuestionAnswering - - call - - - - -## FlaxElectraModel - -[[autodoc]] FlaxElectraModel - - __call__ - -## FlaxElectraForPreTraining - -[[autodoc]] FlaxElectraForPreTraining - - __call__ - -## FlaxElectraForCausalLM - -[[autodoc]] FlaxElectraForCausalLM - - __call__ - -## FlaxElectraForMaskedLM - -[[autodoc]] FlaxElectraForMaskedLM - - __call__ - -## FlaxElectraForSequenceClassification - -[[autodoc]] FlaxElectraForSequenceClassification - - __call__ - -## FlaxElectraForMultipleChoice - -[[autodoc]] FlaxElectraForMultipleChoice - - __call__ - -## FlaxElectraForTokenClassification - -[[autodoc]] FlaxElectraForTokenClassification - - __call__ - -## FlaxElectraForQuestionAnswering - -[[autodoc]] FlaxElectraForQuestionAnswering - - __call__ - - diff --git a/docs/source/ko/model_doc/encoder-decoder.md b/docs/source/ko/model_doc/encoder-decoder.md index 60982cb4554c..9cea74aac10c 100644 --- a/docs/source/ko/model_doc/encoder-decoder.md +++ b/docs/source/ko/model_doc/encoder-decoder.md @@ -146,22 +146,4 @@ nearly 800 thousand customers were affected by the shutoffs. the aim is to reduc - from_encoder_decoder_pretrained - - -## TFEncoderDecoderModel - -[[autodoc]] TFEncoderDecoderModel - - call - - from_encoder_decoder_pretrained - - - - -## FlaxEncoderDecoderModel - -[[autodoc]] FlaxEncoderDecoderModel - - __call__ - - from_encoder_decoder_pretrained - - diff --git a/docs/source/ko/model_doc/esm.md b/docs/source/ko/model_doc/esm.md index 6ea1191dabe0..89640d1366c4 100644 --- a/docs/source/ko/model_doc/esm.md +++ b/docs/source/ko/model_doc/esm.md @@ -89,27 +89,4 @@ ESMFold는 [Matt](https://huggingface.co/Rocketknight1)와 [Sylvain](https://hug - forward - - -## TFEsmModel [[transformers.TFEsmModel]] - -[[autodoc]] TFEsmModel - - call - -## TFEsmForMaskedLM [[transformers.TFEsmForMaskedLM]] - -[[autodoc]] TFEsmForMaskedLM - - call - -## TFEsmForSequenceClassification [[transformers.TFEsmForSequenceClassification]] - -[[autodoc]] TFEsmForSequenceClassification - - call - -## TFEsmForTokenClassification [[transformers.TFEsmForTokenClassification]] - -[[autodoc]] TFEsmForTokenClassification - - call - - diff --git a/docs/source/ko/model_doc/gemma.md b/docs/source/ko/model_doc/gemma.md index 25fe6f1c7729..2b2297eea56f 100644 --- a/docs/source/ko/model_doc/gemma.md +++ b/docs/source/ko/model_doc/gemma.md @@ -64,13 +64,3 @@ Gemma 모델은 6조 토큰으로 학습되었으며, 2b와 7b의 두 가지 버 [[autodoc]] GemmaForTokenClassification - forward - -## FlaxGemmaModel [[transformers.FlaxGemmaModel]] - -[[autodoc]] FlaxGemmaModel - - __call__ - -## FlaxGemmaForCausalLM [[transformers.FlaxGemmaForCausalLM]] - -[[autodoc]] FlaxGemmaForCausalLM - - __call__ diff --git a/docs/source/ko/model_doc/gpt2.md b/docs/source/ko/model_doc/gpt2.md index 53596bb9824d..56650243f9fa 100644 --- a/docs/source/ko/model_doc/gpt2.md +++ b/docs/source/ko/model_doc/gpt2.md @@ -136,8 +136,6 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True)) [[autodoc]] models.gpt2.modeling_gpt2.GPT2DoubleHeadsModelOutput -[[autodoc]] models.gpt2.modeling_tf_gpt2.TFGPT2DoubleHeadsModelOutput - @@ -172,48 +170,4 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True)) - forward - - -## TFGPT2Model - -[[autodoc]] TFGPT2Model - - call - -## TFGPT2LMHeadModel - -[[autodoc]] TFGPT2LMHeadModel - - call - -## TFGPT2DoubleHeadsModel - -[[autodoc]] TFGPT2DoubleHeadsModel - - call - -## TFGPT2ForSequenceClassification - -[[autodoc]] TFGPT2ForSequenceClassification - - call - -## TFSequenceClassifierOutputWithPast - -[[autodoc]] modeling_tf_outputs.TFSequenceClassifierOutputWithPast - -## TFGPT2Tokenizer - -[[autodoc]] TFGPT2Tokenizer - - - - -## FlaxGPT2Model - -[[autodoc]] FlaxGPT2Model - - __call__ - -## FlaxGPT2LMHeadModel - -[[autodoc]] FlaxGPT2LMHeadModel - - __call__ - - \ No newline at end of file diff --git a/docs/source/ko/model_doc/marian.md b/docs/source/ko/model_doc/marian.md index 79a9641401d0..c978e2df6df0 100644 --- a/docs/source/ko/model_doc/marian.md +++ b/docs/source/ko/model_doc/marian.md @@ -188,30 +188,4 @@ GROUP_MEMBERS = { - forward - - -## TFMarianModel - -[[autodoc]] TFMarianModel - - call - -## TFMarianMTModel - -[[autodoc]] TFMarianMTModel - - call - - - - -## FlaxMarianModel - -[[autodoc]] FlaxMarianModel - - __call__ - -## FlaxMarianMTModel - -[[autodoc]] FlaxMarianMTModel - - __call__ - - diff --git a/docs/source/ko/model_doc/mistral.md b/docs/source/ko/model_doc/mistral.md index a05f00a4233f..74de49f5df79 100644 --- a/docs/source/ko/model_doc/mistral.md +++ b/docs/source/ko/model_doc/mistral.md @@ -206,28 +206,3 @@ pip install -U flash-attn --no-build-isolation [[autodoc]] MistralForTokenClassification - forward - -## FlaxMistralModel[[transformers.FlaxMistralModel]] - -[[autodoc]] FlaxMistralModel - - __call__ - -## FlaxMistralForCausalLM[[transformers.FlaxMistralForCausalLM]] - -[[autodoc]] FlaxMistralForCausalLM - - __call__ - -## TFMistralModel[[transformers.TFMistralModel]] - -[[autodoc]] TFMistralModel - - call - -## TFMistralForCausalLM[[transformers.TFMistralForCausalLM]] - -[[autodoc]] TFMistralForCausalLM - - call - -## TFMistralForSequenceClassification[[transformers.TFMistralForSequenceClassification]] - -[[autodoc]] TFMistralForSequenceClassification - - call diff --git a/docs/source/ko/model_doc/openai-gpt.md b/docs/source/ko/model_doc/openai-gpt.md index 7e8f57c743bf..679bf0783c81 100644 --- a/docs/source/ko/model_doc/openai-gpt.md +++ b/docs/source/ko/model_doc/openai-gpt.md @@ -97,8 +97,6 @@ OpenAI GPT를 시작하는 데 도움이 되는 공식 Hugging Face 및 커뮤 [[autodoc]] models.openai.modeling_openai.OpenAIGPTDoubleHeadsModelOutput -[[autodoc]] models.openai.modeling_tf_openai.TFOpenAIGPTDoubleHeadsModelOutput - @@ -123,27 +121,4 @@ OpenAI GPT를 시작하는 데 도움이 되는 공식 Hugging Face 및 커뮤 - forward - - -## TFOpenAIGPTModel [[transformers.TFOpenAIGPTModel]] - -[[autodoc]] TFOpenAIGPTModel - - call - -## TFOpenAIGPTLMHeadModel [[transformers.TFOpenAIGPTLMHeadModel]] - -[[autodoc]] TFOpenAIGPTLMHeadModel - - call - -## TFOpenAIGPTDoubleHeadsModel [[transformers.TFOpenAIGPTDoubleHeadsModel]] - -[[autodoc]] TFOpenAIGPTDoubleHeadsModel - - call - -## TFOpenAIGPTForSequenceClassification [[transformers.TFOpenAIGPTForSequenceClassification]] - -[[autodoc]] TFOpenAIGPTForSequenceClassification - - call - - diff --git a/docs/source/ko/model_doc/rag.md b/docs/source/ko/model_doc/rag.md index 0610eaa553bf..cb670a54ee9a 100644 --- a/docs/source/ko/model_doc/rag.md +++ b/docs/source/ko/model_doc/rag.md @@ -77,24 +77,4 @@ rendered properly in your Markdown viewer. - generate - - -## TFRagModel [[transformers.TFRagModel]] - -[[autodoc]] TFRagModel - - call - -## TFRagSequenceForGeneration [[transformers.TFRagSequenceForGeneration]] - -[[autodoc]] TFRagSequenceForGeneration - - call - - generate - -## TFRagTokenForGeneration [[transformers.TFRagTokenForGeneration]] - -[[autodoc]] TFRagTokenForGeneration - - call - - generate - - diff --git a/docs/source/ko/model_doc/roberta.md b/docs/source/ko/model_doc/roberta.md index e17d7df90c99..6588ff62e264 100644 --- a/docs/source/ko/model_doc/roberta.md +++ b/docs/source/ko/model_doc/roberta.md @@ -151,80 +151,4 @@ RoBERTa를 처음 다룰 때 도움이 되는 Hugging Face 공식 자료와 커 - forward - - -## TFRobertaModel - -[[autodoc]] TFRobertaModel - - call - -## TFRobertaForCausalLM - -[[autodoc]] TFRobertaForCausalLM - - call - -## TFRobertaForMaskedLM - -[[autodoc]] TFRobertaForMaskedLM - - call - -## TFRobertaForSequenceClassification - -[[autodoc]] TFRobertaForSequenceClassification - - call - -## TFRobertaForMultipleChoice - -[[autodoc]] TFRobertaForMultipleChoice - - call - -## TFRobertaForTokenClassification - -[[autodoc]] TFRobertaForTokenClassification - - call - -## TFRobertaForQuestionAnswering - -[[autodoc]] TFRobertaForQuestionAnswering - - call - - - - -## FlaxRobertaModel - -[[autodoc]] FlaxRobertaModel - - __call__ - -## FlaxRobertaForCausalLM - -[[autodoc]] FlaxRobertaForCausalLM - - __call__ - -## FlaxRobertaForMaskedLM - -[[autodoc]] FlaxRobertaForMaskedLM - - __call__ - -## FlaxRobertaForSequenceClassification - -[[autodoc]] FlaxRobertaForSequenceClassification - - __call__ - -## FlaxRobertaForMultipleChoice - -[[autodoc]] FlaxRobertaForMultipleChoice - - __call__ - -## FlaxRobertaForTokenClassification - -[[autodoc]] FlaxRobertaForTokenClassification - - __call__ - -## FlaxRobertaForQuestionAnswering - -[[autodoc]] FlaxRobertaForQuestionAnswering - - __call__ - - diff --git a/docs/source/ko/model_doc/swin.md b/docs/source/ko/model_doc/swin.md index ba1088210fea..48ffdcc9cb2b 100644 --- a/docs/source/ko/model_doc/swin.md +++ b/docs/source/ko/model_doc/swin.md @@ -74,22 +74,4 @@ Swin Transformer의 사용을 도울 수 있는 Hugging Face 및 커뮤니티( - forward - - -## TFSwinModel [[transformers.TFSwinModel]] - -[[autodoc]] TFSwinModel - - call - -## TFSwinForMaskedImageModeling [[transformers.TFSwinForMaskedImageModeling]] - -[[autodoc]] TFSwinForMaskedImageModeling - - call - -## TFSwinForImageClassification [[transformers.TFSwinForImageClassification]] - -[[autodoc]] transformers.TFSwinForImageClassification - - call - - \ No newline at end of file diff --git a/docs/source/ko/model_doc/vit.md b/docs/source/ko/model_doc/vit.md index e02740f5fff3..7d6d54093a66 100644 --- a/docs/source/ko/model_doc/vit.md +++ b/docs/source/ko/model_doc/vit.md @@ -143,30 +143,4 @@ ViT의 추론 및 커스텀 데이터에 대한 미세 조정과 관련된 데 - forward - - -## TFViTModel [[transformers.TFViTModel]] - -[[autodoc]] TFViTModel - - call - -## TFViTForImageClassification [[transformers.TFViTForImageClassification]] - -[[autodoc]] TFViTForImageClassification - - call - - - - -## FlaxVitModel [[transformers.FlaxViTModel]] - -[[autodoc]] FlaxViTModel - - __call__ - -## FlaxViTForImageClassification [[transformers.FlaxViTForImageClassification]] - -[[autodoc]] FlaxViTForImageClassification - - __call__ - - \ No newline at end of file diff --git a/docs/source/ko/model_doc/whisper.md b/docs/source/ko/model_doc/whisper.md index f48bae1e60f5..fc3fb51f51a6 100644 --- a/docs/source/ko/model_doc/whisper.md +++ b/docs/source/ko/model_doc/whisper.md @@ -98,31 +98,3 @@ python src/transformers/models/whisper/convert_openai_to_hf.py --checkpoint_path [[autodoc]] WhisperForAudioClassification - forward - - -## TFWhisperModel [[tfwhispermodel]] - -[[autodoc]] TFWhisperModel - - call - -## TFWhisperForConditionalGeneration [[tfwhisperforconditionalgeneration]] - -[[autodoc]] TFWhisperForConditionalGeneration - - call - - -## FlaxWhisperModel [[flaxwhispermodel]] - -[[autodoc]] FlaxWhisperModel - - __call__ - -## FlaxWhisperForConditionalGeneration [[flaxwhisperforconditionalgeneration]] - -[[autodoc]] FlaxWhisperForConditionalGeneration - - __call__ - -## FlaxWhisperForAudioClassification [[flaxwhisperforaudioclassification]] - -[[autodoc]] FlaxWhisperForAudioClassification - - __call__ - diff --git a/docs/source/zh/internal/generation_utils.md b/docs/source/zh/internal/generation_utils.md index e7b821f93ecd..282202cb79e1 100644 --- a/docs/source/zh/internal/generation_utils.md +++ b/docs/source/zh/internal/generation_utils.md @@ -69,36 +69,6 @@ generation_output[:2] [[autodoc]] generation.GenerateBeamEncoderDecoderOutput -### TensorFlow - -[[autodoc]] generation.TFGreedySearchEncoderDecoderOutput - -[[autodoc]] generation.TFGreedySearchDecoderOnlyOutput - -[[autodoc]] generation.TFSampleEncoderDecoderOutput - -[[autodoc]] generation.TFSampleDecoderOnlyOutput - -[[autodoc]] generation.TFBeamSearchEncoderDecoderOutput - -[[autodoc]] generation.TFBeamSearchDecoderOnlyOutput - -[[autodoc]] generation.TFBeamSampleEncoderDecoderOutput - -[[autodoc]] generation.TFBeamSampleDecoderOnlyOutput - -[[autodoc]] generation.TFContrastiveSearchEncoderDecoderOutput - -[[autodoc]] generation.TFContrastiveSearchDecoderOnlyOutput - -### FLAX - -[[autodoc]] generation.FlaxSampleOutput - -[[autodoc]] generation.FlaxGreedySearchOutput - -[[autodoc]] generation.FlaxBeamSearchOutput - ## LogitsProcessor [`LogitsProcessor`] 可以用于修改语言模型头的预测分数以进行生成 @@ -190,94 +160,6 @@ generation_output[:2] [[autodoc]] WhisperTimeStampLogitsProcessor - __call__ -### TensorFlow - -[[autodoc]] TFForcedBOSTokenLogitsProcessor - - __call__ - -[[autodoc]] TFForcedEOSTokenLogitsProcessor - - __call__ - -[[autodoc]] TFForceTokensLogitsProcessor - - __call__ - -[[autodoc]] TFLogitsProcessor - - __call__ - -[[autodoc]] TFLogitsProcessorList - - __call__ - -[[autodoc]] TFLogitsWarper - - __call__ - -[[autodoc]] TFMinLengthLogitsProcessor - - __call__ - -[[autodoc]] TFNoBadWordsLogitsProcessor - - __call__ - -[[autodoc]] TFNoRepeatNGramLogitsProcessor - - __call__ - -[[autodoc]] TFRepetitionPenaltyLogitsProcessor - - __call__ - -[[autodoc]] TFSuppressTokensAtBeginLogitsProcessor - - __call__ - -[[autodoc]] TFSuppressTokensLogitsProcessor - - __call__ - -[[autodoc]] TFTemperatureLogitsWarper - - __call__ - -[[autodoc]] TFTopKLogitsWarper - - __call__ - -[[autodoc]] TFTopPLogitsWarper - - __call__ - -### FLAX - -[[autodoc]] FlaxForcedBOSTokenLogitsProcessor - - __call__ - -[[autodoc]] FlaxForcedEOSTokenLogitsProcessor - - __call__ - -[[autodoc]] FlaxForceTokensLogitsProcessor - - __call__ - -[[autodoc]] FlaxLogitsProcessor - - __call__ - -[[autodoc]] FlaxLogitsProcessorList - - __call__ - -[[autodoc]] FlaxLogitsWarper - - __call__ - -[[autodoc]] FlaxMinLengthLogitsProcessor - - __call__ - -[[autodoc]] FlaxSuppressTokensAtBeginLogitsProcessor - - __call__ - -[[autodoc]] FlaxSuppressTokensLogitsProcessor - - __call__ - -[[autodoc]] FlaxTemperatureLogitsWarper - - __call__ - -[[autodoc]] FlaxTopKLogitsWarper - - __call__ - -[[autodoc]] FlaxTopPLogitsWarper - - __call__ - -[[autodoc]] FlaxWhisperTimeStampLogitsProcessor - - __call__ - ## StoppingCriteria 可以使用[`StoppingCriteria`]来更改停止生成的时间(除了EOS token以外的方法)。请注意,这仅适用于我们的PyTorch实现。 diff --git a/docs/source/zh/internal/modeling_utils.md b/docs/source/zh/internal/modeling_utils.md index 2cc62711c717..d83df64dff33 100644 --- a/docs/source/zh/internal/modeling_utils.md +++ b/docs/source/zh/internal/modeling_utils.md @@ -37,30 +37,3 @@ rendered properly in your Markdown viewer. [[autodoc]] pytorch_utils.prune_linear_layer -## TensorFlow自定义层 - -[[autodoc]] modeling_tf_utils.TFConv1D - -[[autodoc]] modeling_tf_utils.TFSequenceSummary - -## TensorFlow loss 函数 - -[[autodoc]] modeling_tf_utils.TFCausalLanguageModelingLoss - -[[autodoc]] modeling_tf_utils.TFMaskedLanguageModelingLoss - -[[autodoc]] modeling_tf_utils.TFMultipleChoiceLoss - -[[autodoc]] modeling_tf_utils.TFQuestionAnsweringLoss - -[[autodoc]] modeling_tf_utils.TFSequenceClassificationLoss - -[[autodoc]] modeling_tf_utils.TFTokenClassificationLoss - -## TensorFlow帮助函数 - -[[autodoc]] modeling_tf_utils.get_initializer - -[[autodoc]] modeling_tf_utils.keras_serializable - -[[autodoc]] modeling_tf_utils.shape_list diff --git a/docs/source/zh/main_classes/model.md b/docs/source/zh/main_classes/model.md index dd9fb57b15c6..323b534640c1 100644 --- a/docs/source/zh/main_classes/model.md +++ b/docs/source/zh/main_classes/model.md @@ -107,19 +107,6 @@ model = AutoModel.from_config(config) [[autodoc]] modeling_utils.ModuleUtilsMixin -TFPreTrainedModel -[[autodoc]] TFPreTrainedModel - - push_to_hub - - all - -## TFModelUtilsMixin -[[autodoc]] modeling_tf_utils.TFModelUtilsMixin - -FlaxPreTrainedModel -[[autodoc]] FlaxPreTrainedModel - - push_to_hub - - all - ## 推送到 Hub [[autodoc]] utils.PushToHubMixin diff --git a/docs/source/zh/main_classes/output.md b/docs/source/zh/main_classes/output.md index f4d5c3c6941d..23af6da6fbee 100644 --- a/docs/source/zh/main_classes/output.md +++ b/docs/source/zh/main_classes/output.md @@ -174,136 +174,4 @@ outputs[:2] ## SampleTSPredictionOutput -[[autodoc]] modeling_outputs.SampleTSPredictionOutput - -## TFBaseModelOutput - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutput - -## TFBaseModelOutputWithPooling - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPooling - -## TFBaseModelOutputWithPoolingAndCrossAttentions - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPoolingAndCrossAttentions - -## TFBaseModelOutputWithPast - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPast - -## TFBaseModelOutputWithPastAndCrossAttentions - -[[autodoc]] modeling_tf_outputs.TFBaseModelOutputWithPastAndCrossAttentions - -## TFSeq2SeqModelOutput - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqModelOutput - -## TFCausalLMOutput - -[[autodoc]] modeling_tf_outputs.TFCausalLMOutput - -## TFCausalLMOutputWithCrossAttentions - -[[autodoc]] modeling_tf_outputs.TFCausalLMOutputWithCrossAttentions - -## TFCausalLMOutputWithPast - -[[autodoc]] modeling_tf_outputs.TFCausalLMOutputWithPast - -## TFMaskedLMOutput - -[[autodoc]] modeling_tf_outputs.TFMaskedLMOutput - -## TFSeq2SeqLMOutput - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqLMOutput - -## TFNextSentencePredictorOutput - -[[autodoc]] modeling_tf_outputs.TFNextSentencePredictorOutput - -## TFSequenceClassifierOutput - -[[autodoc]] modeling_tf_outputs.TFSequenceClassifierOutput - -## TFSeq2SeqSequenceClassifierOutput - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqSequenceClassifierOutput - -## TFMultipleChoiceModelOutput - -[[autodoc]] modeling_tf_outputs.TFMultipleChoiceModelOutput - -## TFTokenClassifierOutput - -[[autodoc]] modeling_tf_outputs.TFTokenClassifierOutput - -## TFQuestionAnsweringModelOutput - -[[autodoc]] modeling_tf_outputs.TFQuestionAnsweringModelOutput - -## TFSeq2SeqQuestionAnsweringModelOutput - -[[autodoc]] modeling_tf_outputs.TFSeq2SeqQuestionAnsweringModelOutput - -## FlaxBaseModelOutput - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutput - -## FlaxBaseModelOutputWithPast - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutputWithPast - -## FlaxBaseModelOutputWithPooling - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutputWithPooling - -## FlaxBaseModelOutputWithPastAndCrossAttentions - -[[autodoc]] modeling_flax_outputs.FlaxBaseModelOutputWithPastAndCrossAttentions - -## FlaxSeq2SeqModelOutput - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqModelOutput - -## FlaxCausalLMOutputWithCrossAttentions - -[[autodoc]] modeling_flax_outputs.FlaxCausalLMOutputWithCrossAttentions - -## FlaxMaskedLMOutput - -[[autodoc]] modeling_flax_outputs.FlaxMaskedLMOutput - -## FlaxSeq2SeqLMOutput - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqLMOutput - -## FlaxNextSentencePredictorOutput - -[[autodoc]] modeling_flax_outputs.FlaxNextSentencePredictorOutput - -## FlaxSequenceClassifierOutput - -[[autodoc]] modeling_flax_outputs.FlaxSequenceClassifierOutput - -## FlaxSeq2SeqSequenceClassifierOutput - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqSequenceClassifierOutput - -## FlaxMultipleChoiceModelOutput - -[[autodoc]] modeling_flax_outputs.FlaxMultipleChoiceModelOutput - -## FlaxTokenClassifierOutput - -[[autodoc]] modeling_flax_outputs.FlaxTokenClassifierOutput - -## FlaxQuestionAnsweringModelOutput - -[[autodoc]] modeling_flax_outputs.FlaxQuestionAnsweringModelOutput - -## FlaxSeq2SeqQuestionAnsweringModelOutput - -[[autodoc]] modeling_flax_outputs.FlaxSeq2SeqQuestionAnsweringModelOutput +[[autodoc]] modeling_outputs.SampleTSPredictionOutput \ No newline at end of file diff --git a/docs/source/zh/main_classes/text_generation.md b/docs/source/zh/main_classes/text_generation.md index 22e31b63c14e..5e7426fa8441 100644 --- a/docs/source/zh/main_classes/text_generation.md +++ b/docs/source/zh/main_classes/text_generation.md @@ -37,15 +37,4 @@ rendered properly in your Markdown viewer. [[autodoc]] generation.GenerationMixin - generate - - compute_transition_scores - -## TFGenerationMixin - -[[autodoc]] generation.TFGenerationMixin - - generate - - compute_transition_scores - -## FlaxGenerationMixin - -[[autodoc]] generation.FlaxGenerationMixin - - generate + - compute_transition_scores \ No newline at end of file diff --git a/docs/source/zh/model_doc/bert.md b/docs/source/zh/model_doc/bert.md index a3356e0bf2d4..3877fcafe4de 100644 --- a/docs/source/zh/model_doc/bert.md +++ b/docs/source/zh/model_doc/bert.md @@ -155,104 +155,6 @@ echo -e "Plants create [MASK] through a process known as photosynthesis." | tran [[autodoc]] BertForQuestionAnswering - forward -## TFBertTokenizer - -[[autodoc]] TFBertTokenizer - -## TFBertModel - -[[autodoc]] TFBertModel - - call - -## TFBertForPreTraining - -[[autodoc]] TFBertForPreTraining - - call - -## TFBertModelLMHeadModel - -[[autodoc]] TFBertLMHeadModel - - call - -## TFBertForMaskedLM - -[[autodoc]] TFBertForMaskedLM - - call - -## TFBertForNextSentencePrediction - -[[autodoc]] TFBertForNextSentencePrediction - - call - -## TFBertForSequenceClassification - -[[autodoc]] TFBertForSequenceClassification - - call - -## TFBertForMultipleChoice - -[[autodoc]] TFBertForMultipleChoice - - call - -## TFBertForTokenClassification - -[[autodoc]] TFBertForTokenClassification - - call - -## TFBertForQuestionAnswering - -[[autodoc]] TFBertForQuestionAnswering - - call - -## FlaxBertModel - -[[autodoc]] FlaxBertModel - - __call__ - -## FlaxBertForPreTraining - -[[autodoc]] FlaxBertForPreTraining - - __call__ - -## FlaxBertForCausalLM - -[[autodoc]] FlaxBertForCausalLM - - __call__ - -## FlaxBertForMaskedLM - -[[autodoc]] FlaxBertForMaskedLM - - __call__ - -## FlaxBertForNextSentencePrediction - -[[autodoc]] FlaxBertForNextSentencePrediction - - __call__ - -## FlaxBertForSequenceClassification - -[[autodoc]] FlaxBertForSequenceClassification - - __call__ - -## FlaxBertForMultipleChoice - -[[autodoc]] FlaxBertForMultipleChoice - - __call__ - -## FlaxBertForTokenClassification - -[[autodoc]] FlaxBertForTokenClassification - - __call__ - -## FlaxBertForQuestionAnswering - -[[autodoc]] FlaxBertForQuestionAnswering - - __call__ - ## Bert specific outputs -[[autodoc]] models.bert.modeling_bert.BertForPreTrainingOutput - -[[autodoc]] models.bert.modeling_tf_bert.TFBertForPreTrainingOutput - -[[autodoc]] models.bert.modeling_flax_bert.FlaxBertForPreTrainingOutput \ No newline at end of file +[[autodoc]] models.bert.modeling_bert.BertForPreTrainingOutput \ No newline at end of file From 46922b31f22355d76e24276ac9b0d45c6637f2ba Mon Sep 17 00:00:00 2001 From: Benjamin Bossan Date: Fri, 19 Sep 2025 11:39:21 +0200 Subject: [PATCH 115/204] ENH: Enable readline support for transformers chat (#40911) ENH Enable readline support for chat This small change enables GNU readline support for the transformers chat command. This includes, among others: - advanced navigation and editing: ctrl + a ctrl + e alt + b alt + f ctrl + k alt + d etc. - navigate and search history: arrow up/down ctrl + p ctrl + n ctrl + r - undo: ctrl + _ - clear screen: ctrl + l Implementation Although it may look strange, just importing readline is enough to enable it in Python, see: https://docs.python.org/3/library/functions.html#input As readline is not available on some platforms (https://docs.python.org/3/library/readline.html), the import is guarded. Readline should work on Linux, MacOS, and with WSL, I'm not sure about Windows though. Ideally, someone can give it a try. It's possible that Windows users would have to install pyreadline (https://pypi.org/project/pyreadline3/). --- src/transformers/commands/chat.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/transformers/commands/chat.py b/src/transformers/commands/chat.py index 70ee41c0c514..37f606d00dd5 100644 --- a/src/transformers/commands/chat.py +++ b/src/transformers/commands/chat.py @@ -40,6 +40,12 @@ from transformers.utils import is_rich_available, is_torch_available +try: + import readline # noqa importing this enables GNU readline capabilities +except ImportError: + # some platforms may not support readline: https://docs.python.org/3/library/readline.html + pass + if platform.system() != "Windows": import pwd From dbc0952d4e52b80508de3d54f0267c78c42001dc Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Fri, 19 Sep 2025 11:45:07 +0200 Subject: [PATCH 116/204] [testing] test `num_hidden_layers` being small in model tester (#40992) fix Co-authored-by: ydshieh --- .../aya_vision/test_modeling_aya_vision.py | 2 +- tests/models/bamba/test_modeling_bamba.py | 2 +- tests/models/bitnet/test_modeling_bitnet.py | 2 +- tests/models/bros/test_modeling_bros.py | 2 +- tests/models/cohere/test_modeling_cohere.py | 2 +- .../test_modeling_cohere2_vision.py | 2 +- .../deepseek_v3/test_modeling_deepseek_v3.py | 2 +- tests/models/eomt/test_modeling_eomt.py | 2 +- tests/models/falcon/test_modeling_falcon.py | 2 +- .../falcon_h1/test_modeling_falcon_h1.py | 2 +- .../models/got_ocr2/test_modeling_got_ocr2.py | 2 +- tests/models/idefics/test_modeling_idefics.py | 4 +- .../models/idefics2/test_modeling_idefics2.py | 2 +- .../models/idefics3/test_modeling_idefics3.py | 2 +- .../models/internvl/test_modeling_internvl.py | 2 +- .../test_modeling_longcat_flash.py | 4 +- tests/models/lxmert/test_modeling_lxmert.py | 2 +- tests/models/mllama/test_modeling_mllama.py | 4 +- .../pop2piano/test_modeling_pop2piano.py | 2 +- .../test_modeling_qwen2_5_omni.py | 2 +- .../qwen2_5_vl/test_modeling_qwen2_5_vl.py | 2 +- .../models/qwen2_vl/test_modeling_qwen2_vl.py | 2 +- .../models/qwen3_vl/test_modeling_qwen3_vl.py | 2 +- .../test_modeling_qwen3_vl_moe.py | 2 +- .../models/reformer/test_modeling_reformer.py | 2 +- tests/models/smolvlm/test_modeling_smolvlm.py | 2 +- tests/models/udop/test_modeling_udop.py | 4 +- tests/models/vitpose/test_modeling_vitpose.py | 2 +- .../test_modeling_vitpose_backbone.py | 2 +- tests/models/vjepa2/test_modeling_vjepa2.py | 2 +- tests/models/xlnet/test_modeling_xlnet.py | 2 +- tests/test_modeling_common.py | 39 +++++++++++++++++++ 32 files changed, 74 insertions(+), 35 deletions(-) diff --git a/tests/models/aya_vision/test_modeling_aya_vision.py b/tests/models/aya_vision/test_modeling_aya_vision.py index 8911d39ec10c..b4a2f345b895 100644 --- a/tests/models/aya_vision/test_modeling_aya_vision.py +++ b/tests/models/aya_vision/test_modeling_aya_vision.py @@ -71,7 +71,7 @@ def __init__( "vocab_size": 99, "hidden_size": 128, "intermediate_size": 37, - "num_hidden_layers": 4, + "num_hidden_layers": 2, "num_attention_heads": 4, "output_channels": 64, "hidden_act": "silu", diff --git a/tests/models/bamba/test_modeling_bamba.py b/tests/models/bamba/test_modeling_bamba.py index c2e7c435dbfa..06f99fc1c6ac 100644 --- a/tests/models/bamba/test_modeling_bamba.py +++ b/tests/models/bamba/test_modeling_bamba.py @@ -73,7 +73,7 @@ def __init__( use_labels=True, vocab_size=99, hidden_size=32, - num_hidden_layers=4, + num_hidden_layers=2, num_attention_heads=4, num_key_value_heads=2, intermediate_size=64, diff --git a/tests/models/bitnet/test_modeling_bitnet.py b/tests/models/bitnet/test_modeling_bitnet.py index 75d885ba4d51..19bc0c45eb2e 100644 --- a/tests/models/bitnet/test_modeling_bitnet.py +++ b/tests/models/bitnet/test_modeling_bitnet.py @@ -49,7 +49,7 @@ def __init__( use_input_mask=True, vocab_size=99, hidden_size=64, - num_hidden_layers=5, + num_hidden_layers=2, num_attention_heads=4, num_key_value_heads=2, intermediate_size=37, diff --git a/tests/models/bros/test_modeling_bros.py b/tests/models/bros/test_modeling_bros.py index 3a80497cafc6..8f3f5957e02e 100644 --- a/tests/models/bros/test_modeling_bros.py +++ b/tests/models/bros/test_modeling_bros.py @@ -49,7 +49,7 @@ def __init__( use_labels=True, vocab_size=99, hidden_size=64, - num_hidden_layers=5, + num_hidden_layers=2, num_attention_heads=4, intermediate_size=37, hidden_act="gelu", diff --git a/tests/models/cohere/test_modeling_cohere.py b/tests/models/cohere/test_modeling_cohere.py index 427a7f447d74..436d1f9d4226 100644 --- a/tests/models/cohere/test_modeling_cohere.py +++ b/tests/models/cohere/test_modeling_cohere.py @@ -54,7 +54,7 @@ def __init__( use_labels=True, vocab_size=99, hidden_size=32, - num_hidden_layers=4, + num_hidden_layers=2, num_attention_heads=4, intermediate_size=37, hidden_act="gelu", diff --git a/tests/models/cohere2_vision/test_modeling_cohere2_vision.py b/tests/models/cohere2_vision/test_modeling_cohere2_vision.py index 7a12c2ad9fca..776b2b254f17 100644 --- a/tests/models/cohere2_vision/test_modeling_cohere2_vision.py +++ b/tests/models/cohere2_vision/test_modeling_cohere2_vision.py @@ -65,7 +65,7 @@ def __init__( "vocab_size": 99, "hidden_size": 128, "intermediate_size": 37, - "num_hidden_layers": 4, + "num_hidden_layers": 2, "num_attention_heads": 4, "output_channels": 64, "hidden_act": "silu", diff --git a/tests/models/deepseek_v3/test_modeling_deepseek_v3.py b/tests/models/deepseek_v3/test_modeling_deepseek_v3.py index 9ed521509408..62bb9c999958 100644 --- a/tests/models/deepseek_v3/test_modeling_deepseek_v3.py +++ b/tests/models/deepseek_v3/test_modeling_deepseek_v3.py @@ -65,7 +65,7 @@ def __init__( hidden_size=32, intermediate_size=37, moe_intermediate_size=12, - num_hidden_layers=5, + num_hidden_layers=2, num_attention_heads=4, num_key_value_heads=4, n_shared_experts=1, diff --git a/tests/models/eomt/test_modeling_eomt.py b/tests/models/eomt/test_modeling_eomt.py index 1c92692f2795..f0d4a7c1fa9e 100644 --- a/tests/models/eomt/test_modeling_eomt.py +++ b/tests/models/eomt/test_modeling_eomt.py @@ -47,7 +47,7 @@ def __init__( num_labels=4, hidden_size=8, num_attention_heads=2, - num_hidden_layers=4, + num_hidden_layers=2, ): self.parent = parent self.batch_size = batch_size diff --git a/tests/models/falcon/test_modeling_falcon.py b/tests/models/falcon/test_modeling_falcon.py index f15b86d425f1..14e160fe594f 100644 --- a/tests/models/falcon/test_modeling_falcon.py +++ b/tests/models/falcon/test_modeling_falcon.py @@ -208,7 +208,7 @@ def test_falcon_alibi_sdpa_matches_eager(self): config = FalconConfig( vocab_size=1000, hidden_size=64, - num_hidden_layers=3, + num_hidden_layers=2, num_attention_heads=4, new_decoder_architecture=True, alibi=True, diff --git a/tests/models/falcon_h1/test_modeling_falcon_h1.py b/tests/models/falcon_h1/test_modeling_falcon_h1.py index cc78f7bf7c1d..3e475ef70802 100644 --- a/tests/models/falcon_h1/test_modeling_falcon_h1.py +++ b/tests/models/falcon_h1/test_modeling_falcon_h1.py @@ -55,7 +55,7 @@ def __init__( use_labels=True, vocab_size=99, hidden_size=32, - num_hidden_layers=4, + num_hidden_layers=2, num_attention_heads=4, num_key_value_heads=2, intermediate_size=64, diff --git a/tests/models/got_ocr2/test_modeling_got_ocr2.py b/tests/models/got_ocr2/test_modeling_got_ocr2.py index 59577106b069..3ece8d3aabaf 100644 --- a/tests/models/got_ocr2/test_modeling_got_ocr2.py +++ b/tests/models/got_ocr2/test_modeling_got_ocr2.py @@ -59,7 +59,7 @@ def __init__( "vocab_size": 99, "hidden_size": 128, "intermediate_size": 37, - "num_hidden_layers": 4, + "num_hidden_layers": 2, "num_attention_heads": 4, "num_key_value_heads": 2, "output_channels": 64, diff --git a/tests/models/idefics/test_modeling_idefics.py b/tests/models/idefics/test_modeling_idefics.py index 2cf220fd6dfd..5539d6a0b075 100644 --- a/tests/models/idefics/test_modeling_idefics.py +++ b/tests/models/idefics/test_modeling_idefics.py @@ -67,7 +67,7 @@ def __init__( use_labels=True, vocab_size=99, hidden_size=32, - num_hidden_layers=5, + num_hidden_layers=2, num_attention_heads=4, intermediate_size=37, hidden_act="gelu", @@ -85,7 +85,7 @@ def __init__( vision_patch_size=2, vision_image_size=30, vision_num_attention_heads=4, - vision_num_hidden_layers=5, + vision_num_hidden_layers=2, vision_intermediate_size=37, perceiver_qk_layer_norms_perceiver=False, perceiver_resampler_depth=2, diff --git a/tests/models/idefics2/test_modeling_idefics2.py b/tests/models/idefics2/test_modeling_idefics2.py index a500d8bf4946..6603f3604e0b 100644 --- a/tests/models/idefics2/test_modeling_idefics2.py +++ b/tests/models/idefics2/test_modeling_idefics2.py @@ -86,7 +86,7 @@ def __init__( "vocab_size": 100, "hidden_size": 64, "intermediate_size": 56, - "num_hidden_layers": 3, + "num_hidden_layers": 2, "num_attention_heads": 2, "num_key_value_heads": 2, "hidden_act": "silu", diff --git a/tests/models/idefics3/test_modeling_idefics3.py b/tests/models/idefics3/test_modeling_idefics3.py index b4434f34b81c..fe05eda8c0fb 100644 --- a/tests/models/idefics3/test_modeling_idefics3.py +++ b/tests/models/idefics3/test_modeling_idefics3.py @@ -74,7 +74,7 @@ def __init__( "vocab_size": 100, "hidden_size": 64, "intermediate_size": 56, - "num_hidden_layers": 3, + "num_hidden_layers": 2, "num_attention_heads": 2, "num_key_value_heads": 2, "hidden_act": "silu", diff --git a/tests/models/internvl/test_modeling_internvl.py b/tests/models/internvl/test_modeling_internvl.py index 297dc6cffe85..8704fccb6a1c 100644 --- a/tests/models/internvl/test_modeling_internvl.py +++ b/tests/models/internvl/test_modeling_internvl.py @@ -74,7 +74,7 @@ def __init__( "vocab_size": 99, "hidden_size": 128, "intermediate_size": 37, - "num_hidden_layers": 4, + "num_hidden_layers": 2, "num_attention_heads": 4, "num_key_value_heads": 2, "output_channels": 64, diff --git a/tests/models/longcat_flash/test_modeling_longcat_flash.py b/tests/models/longcat_flash/test_modeling_longcat_flash.py index bc52e890ce0a..ecfda972339d 100644 --- a/tests/models/longcat_flash/test_modeling_longcat_flash.py +++ b/tests/models/longcat_flash/test_modeling_longcat_flash.py @@ -60,7 +60,7 @@ def __init__( hidden_size=144, ffn_hidden_size=288, expert_ffn_hidden_size=48, - num_layers=2, + num_layers=1, # We have `self.num_hidden_layers = 2 * num_layers` in the body. See `LongcatFlashConfig`. num_attention_heads=8, num_key_value_heads=8, kv_lora_rank=16, @@ -96,7 +96,7 @@ def __init__( self.expert_ffn_hidden_size = expert_ffn_hidden_size self.num_layers = num_layers self.num_hidden_layers = 2 * num_layers # for compatibility - self.expected_num_hidden_layers = 3 # embedding + 2 layers + self.expected_num_hidden_layers = 2 # embedding + 2 layers self.num_attention_heads = num_attention_heads self.num_key_value_heads = num_key_value_heads self.kv_lora_rank = kv_lora_rank diff --git a/tests/models/lxmert/test_modeling_lxmert.py b/tests/models/lxmert/test_modeling_lxmert.py index 033fcc0605d6..3d9a88d561ce 100644 --- a/tests/models/lxmert/test_modeling_lxmert.py +++ b/tests/models/lxmert/test_modeling_lxmert.py @@ -59,7 +59,7 @@ def __init__( num_object_labels=16, num_attr_labels=4, num_visual_features=10, - l_layers=2, + l_layers=1, x_layers=1, r_layers=1, visual_feat_dim=128, diff --git a/tests/models/mllama/test_modeling_mllama.py b/tests/models/mllama/test_modeling_mllama.py index ca5579ecb058..0d151602ffce 100644 --- a/tests/models/mllama/test_modeling_mllama.py +++ b/tests/models/mllama/test_modeling_mllama.py @@ -145,7 +145,7 @@ def __init__( "model_type": "mllama", "vocab_size": 99, "hidden_size": 32, - "num_hidden_layers": 4, + "num_hidden_layers": 2, "num_attention_heads": 4, "num_key_value_heads": 4, "intermediate_size": 37, @@ -166,7 +166,7 @@ def __init__( "intermediate_layers_indices": [0], "vision_output_dim": 32, "projection_dim": 32, - "num_hidden_layers": 6, + "num_hidden_layers": 2, "num_global_layers": 2, "num_attention_heads": 4, "intermediate_size": 37, diff --git a/tests/models/pop2piano/test_modeling_pop2piano.py b/tests/models/pop2piano/test_modeling_pop2piano.py index 0a4a773faac2..91e25f6093b2 100644 --- a/tests/models/pop2piano/test_modeling_pop2piano.py +++ b/tests/models/pop2piano/test_modeling_pop2piano.py @@ -57,7 +57,7 @@ def __init__( use_attention_mask=True, use_labels=True, hidden_size=64, - num_hidden_layers=5, + num_hidden_layers=2, num_attention_heads=4, d_ff=37, relative_attention_num_buckets=8, diff --git a/tests/models/qwen2_5_omni/test_modeling_qwen2_5_omni.py b/tests/models/qwen2_5_omni/test_modeling_qwen2_5_omni.py index 32ebdd0ab036..61fa18153902 100644 --- a/tests/models/qwen2_5_omni/test_modeling_qwen2_5_omni.py +++ b/tests/models/qwen2_5_omni/test_modeling_qwen2_5_omni.py @@ -99,7 +99,7 @@ def __init__( "vocab_size": 99, "hidden_size": 32, "intermediate_size": 37, - "num_hidden_layers": 4, + "num_hidden_layers": 2, "num_attention_heads": 4, "num_key_value_heads": 2, "hidden_act": "silu", diff --git a/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py b/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py index 650f8b05d3b1..d90dff9f13ff 100644 --- a/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py +++ b/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py @@ -85,7 +85,7 @@ def __init__( max_window_layers=3, model_type="qwen2_5_vl", num_attention_heads=4, - num_hidden_layers=4, + num_hidden_layers=2, num_key_value_heads=2, rope_theta=10000, tie_word_embeddings=True, diff --git a/tests/models/qwen2_vl/test_modeling_qwen2_vl.py b/tests/models/qwen2_vl/test_modeling_qwen2_vl.py index ef109fb7cca7..37f315b5dc38 100644 --- a/tests/models/qwen2_vl/test_modeling_qwen2_vl.py +++ b/tests/models/qwen2_vl/test_modeling_qwen2_vl.py @@ -79,7 +79,7 @@ def __init__( max_window_layers=3, model_type="qwen2_vl", num_attention_heads=4, - num_hidden_layers=4, + num_hidden_layers=2, num_key_value_heads=2, rope_theta=10000, tie_word_embeddings=True, diff --git a/tests/models/qwen3_vl/test_modeling_qwen3_vl.py b/tests/models/qwen3_vl/test_modeling_qwen3_vl.py index 35031bf542aa..6074efecf4a9 100644 --- a/tests/models/qwen3_vl/test_modeling_qwen3_vl.py +++ b/tests/models/qwen3_vl/test_modeling_qwen3_vl.py @@ -61,7 +61,7 @@ def __init__( "max_position_embeddings": 512, "model_type": "qwen3_vl", "num_attention_heads": 4, - "num_hidden_layers": 4, + "num_hidden_layers": 2, "num_key_value_heads": 2, "rope_theta": 10000, "tie_word_embeddings": True, diff --git a/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py b/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py index adae69a81fa8..411845fcbfa5 100644 --- a/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py +++ b/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py @@ -61,7 +61,7 @@ def __init__( "model_type": "qwen3_vl_moe", "num_attention_heads": 4, "num_key_value_heads": 2, - "num_hidden_layers": 4, + "num_hidden_layers": 2, "moe_intermediate_size": 16, "num_experts_per_tok": 4, "num_experts": 8, diff --git a/tests/models/reformer/test_modeling_reformer.py b/tests/models/reformer/test_modeling_reformer.py index 8f2b1cdc9957..48df1559e991 100644 --- a/tests/models/reformer/test_modeling_reformer.py +++ b/tests/models/reformer/test_modeling_reformer.py @@ -83,7 +83,7 @@ def __init__( axial_pos_embds=True, axial_pos_shape=[4, 8], axial_pos_embds_dim=[16, 16], - attn_layers=["local", "local", "local", "local"], + attn_layers=["local", "local"], pad_token_id=0, eos_token_id=2, scope=None, diff --git a/tests/models/smolvlm/test_modeling_smolvlm.py b/tests/models/smolvlm/test_modeling_smolvlm.py index 6a3c8c5fa346..7856afd2c9eb 100644 --- a/tests/models/smolvlm/test_modeling_smolvlm.py +++ b/tests/models/smolvlm/test_modeling_smolvlm.py @@ -77,7 +77,7 @@ def __init__( "vocab_size": 100, "hidden_size": 64, "intermediate_size": 56, - "num_hidden_layers": 3, + "num_hidden_layers": 2, "num_attention_heads": 2, "num_key_value_heads": 2, "hidden_act": "silu", diff --git a/tests/models/udop/test_modeling_udop.py b/tests/models/udop/test_modeling_udop.py index 3ec5df33d2b9..4e6aa707ee20 100644 --- a/tests/models/udop/test_modeling_udop.py +++ b/tests/models/udop/test_modeling_udop.py @@ -55,7 +55,7 @@ def __init__( use_attention_mask=True, use_labels=True, hidden_size=32, - num_hidden_layers=5, + num_hidden_layers=2, num_attention_heads=4, d_ff=37, relative_attention_num_buckets=32, @@ -425,7 +425,7 @@ def __init__( is_training=False, use_attention_mask=True, hidden_size=32, - num_hidden_layers=5, + num_hidden_layers=2, decoder_layers=2, num_attention_heads=4, d_ff=37, diff --git a/tests/models/vitpose/test_modeling_vitpose.py b/tests/models/vitpose/test_modeling_vitpose.py index 7cb92e10f005..d5dddc74a3bc 100644 --- a/tests/models/vitpose/test_modeling_vitpose.py +++ b/tests/models/vitpose/test_modeling_vitpose.py @@ -51,7 +51,7 @@ def __init__( is_training=True, use_labels=True, hidden_size=32, - num_hidden_layers=5, + num_hidden_layers=2, num_attention_heads=4, intermediate_size=37, hidden_act="gelu", diff --git a/tests/models/vitpose_backbone/test_modeling_vitpose_backbone.py b/tests/models/vitpose_backbone/test_modeling_vitpose_backbone.py index 5a35795a7495..6f8ee5eb9ed4 100644 --- a/tests/models/vitpose_backbone/test_modeling_vitpose_backbone.py +++ b/tests/models/vitpose_backbone/test_modeling_vitpose_backbone.py @@ -44,7 +44,7 @@ def __init__( is_training=True, use_labels=True, hidden_size=32, - num_hidden_layers=5, + num_hidden_layers=2, num_attention_heads=4, intermediate_size=37, hidden_act="gelu", diff --git a/tests/models/vjepa2/test_modeling_vjepa2.py b/tests/models/vjepa2/test_modeling_vjepa2.py index 1d0004122ab4..c61cb72bc0a0 100644 --- a/tests/models/vjepa2/test_modeling_vjepa2.py +++ b/tests/models/vjepa2/test_modeling_vjepa2.py @@ -61,7 +61,7 @@ def __init__( patch_size=16, num_channels=3, hidden_size=32, - num_hidden_layers=4, + num_hidden_layers=2, num_attention_heads=2, num_frames=2, mlp_ratio=1, diff --git a/tests/models/xlnet/test_modeling_xlnet.py b/tests/models/xlnet/test_modeling_xlnet.py index ae0e2b9d56df..9f1fb24d17c7 100644 --- a/tests/models/xlnet/test_modeling_xlnet.py +++ b/tests/models/xlnet/test_modeling_xlnet.py @@ -80,7 +80,7 @@ def __init__( self.hidden_size = 32 self.num_attention_heads = 4 self.d_inner = 128 - self.num_hidden_layers = 5 + self.num_hidden_layers = 3 self.type_sequence_label_size = 2 self.bi_data = False self.same_length = False diff --git a/tests/test_modeling_common.py b/tests/test_modeling_common.py index 8d6325bfe0a0..1a12f9e4608e 100755 --- a/tests/test_modeling_common.py +++ b/tests/test_modeling_common.py @@ -674,6 +674,45 @@ def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): return inputs_dict + def test_num_layers_is_small(self): + # TODO (if possible): Avoid exceptional cases, especially for `OwlViT`. + # ⛔ DO NOT edit this list (unless there is really nothing to tweak in the model tester class and approved by the reviewer) ⛔! + exceptional_num_hidden_layers = { + # TODO: There might be some way to fix + "FunnelModelTest": 5, + "FunnelBaseModelTest": 4, + "GroupViTVisionModelTest": 12, + "OwlViTModelTest": 12, + "OwlViTTextModelTest": 12, + "OwlViTForObjectDetectionTest": 12, + "Owlv2ModelTest": 12, + "Owlv2TextModelTest": 12, + "Owlv2ForObjectDetectionTest": 12, + "SamHQModelTest": 12, + "Swin2SRModelTest": 3, + "XLNetModelTest": 3, + "DPTModelTest": 4, # `test_modeling_dpt_hybrid.py`: not able to get it work after change `num_hidden_layers` and `neck_hidden_sizes` + # Nothing we can't do + "Gemma3nTextModelTest": 4, # need to test KV shared layer for both types: `full_attention` and `sliding_attention` + "BeitModelTest": 4, # BeitForSemanticSegmentation requires config.out_indices to be a list of 4 integers + "ZambaModelTest": 5, # The minimum number to test beyond the initial ["mamba", "mamba", "hybrid"] in `ZambaConfig._layers_block_type` + } + target_num_hidden_layers = exceptional_num_hidden_layers.get(type(self).__name__, 2) + + if hasattr(self.model_tester, "num_hidden_layers") and isinstance(self.model_tester.num_hidden_layers, int): + assert self.model_tester.num_hidden_layers <= target_num_hidden_layers + + if hasattr(self.model_tester, "vision_config") and "num_hidden_layers" in self.model_tester.vision_config: + if isinstance(self.model_tester.vision_config, dict): + assert self.model_tester.vision_config["num_hidden_layers"] <= target_num_hidden_layers + else: + assert self.model_tester.vision_config.num_hidden_layers <= target_num_hidden_layers + if hasattr(self.model_tester, "text_config") and "num_hidden_layers" in self.model_tester.text_config: + if isinstance(self.model_tester.text_config, dict): + assert self.model_tester.text_config["num_hidden_layers"] <= target_num_hidden_layers + else: + assert self.model_tester.text_config.num_hidden_layers <= target_num_hidden_layers + def test_save_load(self): def check_save_load(out1, out2): # make sure we don't have nans From 17be25b16bb4cd6930d572b142e529ba15f76092 Mon Sep 17 00:00:00 2001 From: Ita Zaporozhets <31893021+itazap@users.noreply.github.com> Date: Fri, 19 Sep 2025 11:55:55 +0200 Subject: [PATCH 117/204] blt wip (#38579) * blt wip * cpu version * cpu friendly with full entropy model (real time patching) * adding config file instead of args file * enable MPS * refactoring unused code * single config class in config file * inherit from PreTrainedModel * refactor LMTransformer --> BLTPatcher * add conversion script * load from new checkpoing with form_pretrained * fixed demo from_pretrained * clean up * clean a few comments * cleanup folder * clean up dir * cleaned up modeling further * rename classes * adding transformers Attention class and RotaryEmbedding class * exchanged blt modules for transformers modules: attention, rotary_emb, create_causal_mask, etc * seperate out patcher config, update modeling and conversion script * rename vars to be more transformers-like * rm unused functions * adding cross attention from transformers * pass arg * rename weights * updated conversion script * overwritten commit! fixing PR * apply feedback * adding BLTRMSNorm like Llama * add repeat_kv and eager_attention_forward copied from * BLTMLP identical to MllamTextMLP * clean up some args' * more like mllama, but busier inits * BLTTransformerLayer config * decoder, encoder, global configs * wip working on modular file * cleaning up patch and configs * clean up patcher helpers * clean up patcher helpers further * clean up * some config renaming * clean up unused configs * clean up configs * clean up configs * update modular * clean * update demo * config more like mllama, seperated subconfigs from subdicts * read from config instead of self args * update demo file * model weights to causal lm weights * missed file * added tied weights keys * BLTForCausalLM * adding files after add-new-model-like * update demo * working on tests * first running integration tests * added integration tests * adding tokenization tests, integration tests, and cleaned up tokenization file, + ruff * tokenizer clean up * modular file * fixing rebase * ruff * adding correct basemodel output and updating config with checkpoint vals (for testing) * BLTModelTests git status * enabling inputs_embeds, although won't be equal to input_ids since need ids for patching logic * fix sdpa == causal tests * fix small model test and some gradient checkpointing * skip training GC tests * fix test * updated modular * update modular * ruff * adding modular + modeling * modular * more modern is_casual check * cleaning up modular * more modular reduction * ruff * modular fix * fix styling * return 2 * return 2 * fix some tests * fix bltcrossattention after modular break * some fixes / feedback * try cache generate fix * try cache generate fix * fix generate tests * attn_impl workaround * refactoring to use recent TransformersKwargs changes * fix hidden_states shape test * refactor to new outputs * simplify outputs a bit * rm unneeded decoderlayer overwriting * rename blt * forgot tokenizer test renamed * Reorder * Reorder * working on modular * updates from modular * new modular * ruff and such * update pretrainedmodel modular * using cohere2 apply_rotary_pos_emb * small changes * apply feedback r2 * fix cross_attention * apply more feedback * update modeling fix * load submodules from pretrainedmodel * set initializer_range to subconfigs * rm cross_attnetion_states pass when not needed * add 7b projection layer support * check repo * make copies * lost cohere2 rotate_half * ruff * copies? * don't tie weights for submodules * tie weights setting * check docstrings * apply feedback * rebase * rebased modeling * update docs * applying feedback * few more fixes * fix can_record_outputs * fast tokenizer * no more modulelist * tok auto * rm tokenizersss * fix docs * ruff * fix after rebase * fix test, configs are not subscriptable --------- Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: Lysandre Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co Co-authored-by: ita.zaporozhets@huggingface.co --- docs/source/en/_toctree.yml | 2 + docs/source/en/model_doc/blt.md | 97 ++ src/transformers/models/__init__.py | 1 + .../models/auto/configuration_auto.py | 2 + src/transformers/models/auto/modeling_auto.py | 2 + .../models/auto/tokenization_auto.py | 1 + src/transformers/models/blt/__init__.py | 28 + .../models/blt/configuration_blt.py | 423 ++++++ .../models/blt/convert_blt_weights_to_hf.py | 487 ++++++ src/transformers/models/blt/modeling_blt.py | 1306 +++++++++++++++++ src/transformers/models/blt/modular_blt.py | 1008 +++++++++++++ tests/causal_lm_tester.py | 2 +- tests/models/blt/__init__.py | 0 tests/models/blt/test_modeling_blt.py | 561 +++++++ utils/check_docstrings.py | 4 + utils/check_repo.py | 11 + 16 files changed, 3934 insertions(+), 1 deletion(-) create mode 100644 docs/source/en/model_doc/blt.md create mode 100644 src/transformers/models/blt/__init__.py create mode 100644 src/transformers/models/blt/configuration_blt.py create mode 100644 src/transformers/models/blt/convert_blt_weights_to_hf.py create mode 100644 src/transformers/models/blt/modeling_blt.py create mode 100644 src/transformers/models/blt/modular_blt.py create mode 100644 tests/models/blt/__init__.py create mode 100644 tests/models/blt/test_modeling_blt.py diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index 61fea5a26ae7..6fdc16bcfce1 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -407,6 +407,8 @@ title: Blenderbot Small - local: model_doc/bloom title: BLOOM + - local: model_doc/blt + title: BLT - local: model_doc/bort title: BORT - local: model_doc/byt5 diff --git a/docs/source/en/model_doc/blt.md b/docs/source/en/model_doc/blt.md new file mode 100644 index 000000000000..0289f77ac901 --- /dev/null +++ b/docs/source/en/model_doc/blt.md @@ -0,0 +1,97 @@ + + +
+
+ PyTorch + Flax + FlashAttention + SDPA +
+
+ +# Byte Lantet Transformer (BLT) + +## Overview + +The BLT model was proposed in [Byte Latent Transformer: Patches Scale Better Than Tokens]() by Artidoro Pagnoni, Ram Pasunuru, Pedro Rodriguez, John Nguyen, Benjamin Muller, Margaret Li1, Chunting Zhou, Lili Yu, Jason Weston, Luke Zettlemoyer, Gargi Ghosh, Mike Lewis, Ari Holtzman†, Srinivasan Iyer. +BLT is a byte-level LLM that achieves tokenization-level performance through entropy-based dynamic patching. + +The abstract from the paper is the following: + +*We introduce the Byte Latent Transformer (BLT), a new byte-level LLM architecture that, for the first time, matches tokenization-based LLM performance at scale with significant improvements in inference +efficiency and robustness. BLT encodes bytes into dynamically sized patches, which serve as the primary units of computation. Patches are segmented based on the entropy of the next byte, allocating +more compute and model capacity where increased data complexity demands it. We present the first flop controlled scaling study of byte-level models up to 8B parameters and 4T training bytes. Our results demonstrate the feasibility of scaling models trained on raw bytes without a fixed vocabulary. Both training and inference efficiency improve due to dynamically selecting long patches when data is predictable, along with qualitative improvements on reasoning and long tail generalization. Overall, for fixed inference costs, BLT shows significantly better scaling than tokenization-based models, by simultaneously growing both patch and model size.* + +## Usage Tips: + +- **Dual Model Architecture**: BLT consists of two separate trained models: + - **Patcher (Entropy Model)**: A smaller transformer model that predicts byte-level entropy to determine patch boundaries and segment input. + - **Main Transformer Model**: The primary model that processes the patches through a Local Encoder, Global Transformer, and Local Decoder. + +- **Dynamic Patching**: The model uses entropy-based dynamic patching where: + - High-entropy regions (complex data) get shorter patches with more computational attention + - Low-entropy regions (predictable data) get longer patches for efficiency + - This allows the model to allocate compute resources where they're most needed + +- **Local Encoder**: Processes byte sequences with cross-attention to patch embeddings +- **Global Transformer**: Processes patch-level representations with full attention across patches +- **Local Decoder**: Generates output with cross-attention back to the original byte sequence + +- **Byte-Level Tokenizer**: Unlike traditional tokenizers that use learned vocabularies, BLT's tokenizer simply converts text to UTF-8 bytes and maps each byte to a token ID. There is no need for a vocabulary. + +The model can be loaded via: + + + +```python +import torch +from transformers import AutoTokenizer, AutoModelForCausalLM + +tokenizer = AutoTokenizer.from_pretrained("itazap/blt-1b-hf") +model = AutoModelForCausalLM.from_pretrained( + "itazap/blt-1b-hf", + device_map="auto", +) + +inputs = tokenizer(prompt, return_tensors="pt").to(model.device) + +prompt = "my name is" +generated_ids = model.generate( + **inputs, max_new_tokens=NUM_TOKENS_TO_GENERATE, do_sample=False, use_cache=False +) + +print(tokenizer.decode(generated_ids[0])) +``` + + + +This model was contributed by [itazap](https://huggingface.co/). +The original code can be found [here](). + + +## BltConfig + +[[autodoc]] BltConfig + +[[autodoc]] BltModel + - forward + +## BltForCausalLM + +[[autodoc]] BltForCausalLM + - forward diff --git a/src/transformers/models/__init__.py b/src/transformers/models/__init__.py index c32c8a795488..f0939b089977 100644 --- a/src/transformers/models/__init__.py +++ b/src/transformers/models/__init__.py @@ -48,6 +48,7 @@ from .blip import * from .blip_2 import * from .bloom import * + from .blt import * from .bridgetower import * from .bros import * from .byt5 import * diff --git a/src/transformers/models/auto/configuration_auto.py b/src/transformers/models/auto/configuration_auto.py index 06023f09c9d8..ec6ce58f7994 100644 --- a/src/transformers/models/auto/configuration_auto.py +++ b/src/transformers/models/auto/configuration_auto.py @@ -65,6 +65,7 @@ ("blip-2", "Blip2Config"), ("blip_2_qformer", "Blip2QFormerConfig"), ("bloom", "BloomConfig"), + ("blt", "BltConfig"), ("bridgetower", "BridgeTowerConfig"), ("bros", "BrosConfig"), ("camembert", "CamembertConfig"), @@ -490,6 +491,7 @@ ("blip-2", "BLIP-2"), ("blip_2_qformer", "BLIP-2 QFormer"), ("bloom", "BLOOM"), + ("blt", "Blt"), ("bort", "BORT"), ("bridgetower", "BridgeTower"), ("bros", "BROS"), diff --git a/src/transformers/models/auto/modeling_auto.py b/src/transformers/models/auto/modeling_auto.py index 025a7a1f90a0..3d0ee2e9fcbd 100644 --- a/src/transformers/models/auto/modeling_auto.py +++ b/src/transformers/models/auto/modeling_auto.py @@ -72,6 +72,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("blip-2", "Blip2Model"), ("blip_2_qformer", "Blip2QFormerModel"), ("bloom", "BloomModel"), + ("blt", "BltModel"), ("bridgetower", "BridgeTowerModel"), ("bros", "BrosModel"), ("camembert", "CamembertModel"), @@ -633,6 +634,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("blenderbot", "BlenderbotForCausalLM"), ("blenderbot-small", "BlenderbotSmallForCausalLM"), ("bloom", "BloomForCausalLM"), + ("blt", "BltForCausalLM"), ("camembert", "CamembertForCausalLM"), ("code_llama", "LlamaForCausalLM"), ("codegen", "CodeGenForCausalLM"), diff --git a/src/transformers/models/auto/tokenization_auto.py b/src/transformers/models/auto/tokenization_auto.py index 7858ae587946..52726fd6200a 100644 --- a/src/transformers/models/auto/tokenization_auto.py +++ b/src/transformers/models/auto/tokenization_auto.py @@ -105,6 +105,7 @@ ("blip", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), ("blip-2", ("GPT2Tokenizer", "GPT2TokenizerFast" if is_tokenizers_available() else None)), ("bloom", (None, "BloomTokenizerFast" if is_tokenizers_available() else None)), + ("blt", (None, "PreTrainedTokenizerFast" if is_tokenizers_available() else None)), ("bridgetower", ("RobertaTokenizer", "RobertaTokenizerFast" if is_tokenizers_available() else None)), ("bros", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), ("byt5", ("ByT5Tokenizer", None)), diff --git a/src/transformers/models/blt/__init__.py b/src/transformers/models/blt/__init__.py new file mode 100644 index 000000000000..703b81ecdd09 --- /dev/null +++ b/src/transformers/models/blt/__init__.py @@ -0,0 +1,28 @@ +# Copyright 2025 The HuggingFace Team. All rights reserved. +# +# 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. +from typing import TYPE_CHECKING + +from ...utils import _LazyModule +from ...utils.import_utils import define_import_structure + + +if TYPE_CHECKING: + from .configuration_blt import * + from .modeling_blt import * + from .tokenization_blt import * +else: + import sys + + _file = globals()["__file__"] + sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__) diff --git a/src/transformers/models/blt/configuration_blt.py b/src/transformers/models/blt/configuration_blt.py new file mode 100644 index 000000000000..0bc6718e5bd1 --- /dev/null +++ b/src/transformers/models/blt/configuration_blt.py @@ -0,0 +1,423 @@ +# coding=utf-8 +# Copyright 2025 The HuggingFace Inc. team. All rights reserved. +# +# 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. +"""Blt model configuration""" + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + + +class BltLocalEncoderConfig(PretrainedConfig): + """ + Configuration class for the Blt Local Encoder component. + """ + + model_type = "blt_local_encoder" + + def __init__( + self, + vocab_size=260, + cross_attn_all_layers=False, + cross_attn_k=2, + hidden_size_global=2048, + hidden_size=1024, + num_attention_heads=16, + num_key_value_heads=None, + num_hidden_layers=1, + rms_norm_eps=1e-5, + dropout=0.0, + max_position_embeddings=24576, + rope_theta=500000.0, + rope_scaling=None, + hidden_act="silu", + intermediate_size=2816, + initializer_range=0.02, + **kwargs, + ): + self.vocab_size = vocab_size + self.cross_attn_all_layers = cross_attn_all_layers + self.cross_attn_k = cross_attn_k + self.hidden_size_global = hidden_size_global + self.hidden_size = hidden_size + self.num_attention_heads = num_attention_heads + self.num_key_value_heads = num_key_value_heads or num_attention_heads + self.head_dim = hidden_size // num_attention_heads + self.intermediate_size = intermediate_size or int(8 * hidden_size / 3) + self.num_hidden_layers = num_hidden_layers + self.rms_norm_eps = rms_norm_eps + self.dropout = dropout + self.max_position_embeddings = max_position_embeddings + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self.hidden_act = hidden_act + self.initializer_range = initializer_range + + # Remove tie_word_embeddings from kwargs to avoid duplicate parameter error + kwargs.pop("tie_word_embeddings", None) + super().__init__(**kwargs, tie_word_embeddings=False) + + +class BltLocalDecoderConfig(PretrainedConfig): + """ + Configuration class for the Blt Local Decoder component. + """ + + model_type = "blt_local_decoder" + + def __init__( + self, + vocab_size=260, + cross_attn_all_layers=True, + cross_attn_k=2, + hidden_size_global=2048, + hidden_size=1024, + num_attention_heads=16, + num_key_value_heads=None, + num_hidden_layers=9, + rms_norm_eps=1e-5, + dropout=0.0, + max_position_embeddings=24576, + rope_theta=500000.0, + rope_scaling=None, + hidden_act="silu", + intermediate_size=2816, + initializer_range=0.02, + **kwargs, + ): + self.vocab_size = vocab_size + self.cross_attn_all_layers = cross_attn_all_layers + self.cross_attn_k = cross_attn_k + self.hidden_size_global = hidden_size_global + self.hidden_size = hidden_size + self.num_attention_heads = num_attention_heads + self.num_key_value_heads = num_key_value_heads or num_attention_heads + self.head_dim = hidden_size // num_attention_heads + self.intermediate_size = intermediate_size or int(8 * hidden_size / 3) + self.num_hidden_layers = num_hidden_layers + self.rms_norm_eps = rms_norm_eps + self.dropout = dropout + self.max_position_embeddings = max_position_embeddings + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self.hidden_act = hidden_act + self.initializer_range = initializer_range + + # Remove tie_word_embeddings from kwargs to avoid duplicate parameter error + kwargs.pop("tie_word_embeddings", None) + super().__init__(**kwargs, tie_word_embeddings=False) + + +class BltGlobalTransformerConfig(PretrainedConfig): + """ + Configuration class for the Blt Global Transformer component. + """ + + model_type = "blt_global_transformer" + + def __init__( + self, + hidden_size=2048, + num_attention_heads=16, + num_key_value_heads=None, + num_hidden_layers=25, + rms_norm_eps=1e-5, + dropout=0.0, + max_position_embeddings=4096, + rope_theta=500000.0, + rope_scaling=None, + hidden_act="silu", + intermediate_size=5632, + initializer_range=0.02, + **kwargs, + ): + self.hidden_size = hidden_size + self.num_attention_heads = num_attention_heads + self.num_key_value_heads = num_key_value_heads or num_attention_heads + self.head_dim = hidden_size // num_attention_heads + self.intermediate_size = intermediate_size or int(8 * hidden_size / 3) + self.num_hidden_layers = num_hidden_layers + self.rms_norm_eps = rms_norm_eps + self.dropout = dropout + self.max_position_embeddings = max_position_embeddings + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self.hidden_act = hidden_act + self.initializer_range = initializer_range + + # Remove tie_word_embeddings from kwargs to avoid duplicate parameter error + kwargs.pop("tie_word_embeddings", None) + super().__init__(**kwargs, tie_word_embeddings=False) + + +class BltPatcherConfig(PretrainedConfig): + r""" + Configuration class for the Blt Patcher/Entropy model component. + + Args: + vocab_size (`int`, *optional*, defaults to 260): + Vocabulary size of the Blt patcher model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling the patcher model. + hidden_size (`int`, *optional*, defaults to 768): + Dimension of the hidden representations. + num_hidden_layers (`int`, *optional*, defaults to 14): + Number of hidden layers in the Transformer decoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer decoder. + num_key_value_heads (`int`, *optional*): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to + `num_attention_heads`. + max_position_embeddings (`int`, *optional*, defaults to 8192): + The maximum sequence length that this model might ever be used with. + rms_norm_eps (`float`, *optional*, defaults to 1e-05): + The epsilon used by the rms normalization layers. + dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period of the RoPE embeddings. + intermediate_size (`int`, *optional*, defaults to 2048): + Dimension of the MLP representations. + rope_scaling (`dict`, *optional*): + Dictionary containing the RoPE scaling configuration. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + """ + + model_type = "blt_patcher" + + def __init__( + self, + vocab_size=260, + hidden_size=768, + num_hidden_layers=14, + num_attention_heads=12, + num_key_value_heads=None, + max_position_embeddings=8192, + rms_norm_eps=1e-5, + dropout=0.0, + rope_theta=10000.0, + intermediate_size=2048, + rope_scaling=None, + initializer_range=0.02, + **kwargs, + ): + 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.head_dim = hidden_size // num_attention_heads + self.num_key_value_heads = num_key_value_heads if num_key_value_heads is not None else num_attention_heads + self.max_position_embeddings = max_position_embeddings + self.rms_norm_eps = rms_norm_eps + self.dropout = dropout + self.rope_theta = rope_theta + self.hidden_act = "silu" # Blt uses silu activation + self.intermediate_size = intermediate_size or int(8 * self.hidden_size / 3) + self.rope_scaling = rope_scaling + self.initializer_range = initializer_range + + # Remove tie_word_embeddings from kwargs to avoid duplicate parameter error + kwargs.pop("tie_word_embeddings", None) + super().__init__(**kwargs, tie_word_embeddings=False) + + +class BltConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`BltModel`]. It is used to instantiate a + Blt model according to the specified arguments, defining the model 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 260): + Vocabulary size of the Blt model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`BltModel`]. + max_position_embeddings (`int`, *optional*, defaults to 4096): + The maximum sequence length that this model might ever be used with. + patch_in_forward (`bool`, *optional*, defaults to `True`): + Whether to perform patching during the forward pass. + patch_size (`int`, *optional*, defaults to 4): + Size of the patches used in the patching mechanism. + patching_mode (`str`, *optional*, defaults to `"entropy"`): + The mode used for patching, such as entropy-based patching. + patching_threshold (`float`, *optional*, defaults to 1.34): + Threshold value used for determining when to apply patches. + patching_batch_size (`int`, *optional*, defaults to 1): + Batch size used during the patching process. + max_patch_length (`int`, *optional*): + Maximum length of patches that can be generated. + cross_attn_k (`int`, *optional*, defaults to 2): + Number of cross-attention heads used in the model. + encoder_hash_byte_group_size (`list`, *optional*): + List of byte group sizes used in the encoder hash function. + encoder_hash_byte_group_vocab (`int`, *optional*, defaults to 500002): + Vocabulary size for the encoder hash byte groups. + encoder_hash_byte_group_nb_functions (`int`, *optional*, defaults to 1): + Number of hash functions used in the encoder byte grouping. + patcher_config (`BltPatcherConfig`, *optional*): + Configuration for the patcher component of the model. + encoder_config (`BltLocalEncoderConfig`, *optional*): + Configuration for the local encoder component of the model. + decoder_config (`BltLocalDecoderConfig`, *optional*): + Configuration for the local decoder component of the model. + global_config (`BltGlobalTransformerConfig`, *optional*): + Configuration for the global transformer component of the model. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether to tie weight embeddings. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rope_theta (`float`, *optional*, defaults to 500000.0): + The base period of the RoPE embeddings. + rope_scaling (`dict`, *optional*): + Dictionary containing the RoPE scaling configuration. + + ```python + >>> from transformers import BltModel, BltConfig + + >>> # Initializing a Blt configuration + >>> configuration = BltConfig() + + >>> # Initializing a model from the configuration + >>> model = BltModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ``` + + Checkpoint: [facebook/blt](https://huggingface.co/facebook/blt) + """ + + model_type = "blt" + keys_to_ignore_at_inference = ["past_key_values"] + sub_configs = { + "patcher_config": BltPatcherConfig, + "encoder_config": BltLocalEncoderConfig, + "decoder_config": BltLocalDecoderConfig, + "global_config": BltGlobalTransformerConfig, + } + + def __init__( + self, + vocab_size=260, + max_position_embeddings=4096, + patch_in_forward=True, + patch_size=4, + patching_mode="entropy", + patching_threshold=1.335442066192627, + patching_batch_size=1, + max_patch_length=None, + cross_attn_k=2, + encoder_hash_byte_group_size=None, + encoder_hash_byte_group_vocab=500002, + encoder_hash_byte_group_nb_functions=1, + patcher_config=None, + encoder_config=None, + decoder_config=None, + global_config=None, + tie_word_embeddings=False, + initializer_range=0.02, + rope_theta=500000.0, + rope_scaling=None, + **kwargs, + ): + # Basic model configuration + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.initializer_range = initializer_range + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + + # Patching configuration + self.patch_in_forward = patch_in_forward + self.patch_size = patch_size + self.patching_mode = patching_mode + self.patching_threshold = patching_threshold + self.patching_batch_size = patching_batch_size + self.max_patch_length = max_patch_length + self.patching_device = kwargs.get("patching_device", "cuda") + self.realtime_patching = kwargs.get("realtime_patching", True) + self.patching_threshold_add = kwargs.get("patching_threshold_add") + self.monotonicity = kwargs.get("monotonicity", False) + + # Cross attention configurations + self.cross_attn_k = cross_attn_k + + # Encoder configurations + self.encoder_hash_byte_group_size = encoder_hash_byte_group_size or [3, 4, 5, 6, 7, 8] + self.encoder_hash_byte_group_vocab = encoder_hash_byte_group_vocab + self.encoder_hash_byte_group_nb_functions = encoder_hash_byte_group_nb_functions + + # Initialize component configurations + if patcher_config is None: + self.patcher_config = BltPatcherConfig(initializer_range=initializer_range) + logger.info("patcher_config is None, using default Blt patcher config") + elif isinstance(patcher_config, dict): + patcher_config.setdefault("initializer_range", initializer_range) + self.patcher_config = BltPatcherConfig(**patcher_config) + elif isinstance(patcher_config, BltPatcherConfig): + self.patcher_config = patcher_config + + if encoder_config is None: + self.encoder_config = BltLocalEncoderConfig(initializer_range=initializer_range) + logger.info("encoder_config is None, using default Blt encoder config") + elif isinstance(encoder_config, dict): + encoder_config.setdefault("initializer_range", initializer_range) + self.encoder_config = BltLocalEncoderConfig(**encoder_config) + elif isinstance(encoder_config, BltLocalEncoderConfig): + self.encoder_config = encoder_config + + if decoder_config is None: + self.decoder_config = BltLocalDecoderConfig(initializer_range=initializer_range) + logger.info("decoder_config is None, using default Blt decoder config") + elif isinstance(decoder_config, dict): + decoder_config.setdefault("initializer_range", initializer_range) + self.decoder_config = BltLocalDecoderConfig(**decoder_config) + elif isinstance(decoder_config, BltLocalDecoderConfig): + self.decoder_config = decoder_config + + if global_config is None: + self.global_config = BltGlobalTransformerConfig(initializer_range=initializer_range) + logger.info("global_config is None, using default Blt global config") + elif isinstance(global_config, dict): + global_config.setdefault("initializer_range", initializer_range) + self.global_config = BltGlobalTransformerConfig(**global_config) + elif isinstance(global_config, BltGlobalTransformerConfig): + self.global_config = global_config + + # Determine if token embedding projection is needed based on dimension mismatch (7b) + encoder_cross_output_size = self.encoder_config.hidden_size * self.cross_attn_k + self.global_config.encoder_cross_output_size = ( + encoder_cross_output_size if encoder_cross_output_size != self.global_config.hidden_size else None + ) + + # Remove tie_word_embeddings from kwargs to avoid duplicate parameter error + kwargs.pop("tie_word_embeddings", None) + super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs) + + +__all__ = [ + "BltConfig", + "BltPatcherConfig", + "BltLocalEncoderConfig", + "BltLocalDecoderConfig", + "BltGlobalTransformerConfig", +] diff --git a/src/transformers/models/blt/convert_blt_weights_to_hf.py b/src/transformers/models/blt/convert_blt_weights_to_hf.py new file mode 100644 index 000000000000..f9decff3a1f8 --- /dev/null +++ b/src/transformers/models/blt/convert_blt_weights_to_hf.py @@ -0,0 +1,487 @@ +import argparse +import json +import logging +import os +from typing import Any, Optional + +import torch +from huggingface_hub import hf_hub_download, upload_folder +from safetensors.torch import load_file, save_file +from tokenizers import Tokenizer, decoders, pre_tokenizers, processors +from tokenizers.models import BPE + +from transformers import PreTrainedTokenizerFast +from transformers.convert_slow_tokenizer import bytes_to_unicode +from transformers.utils import logging as transformers_logging + + +logger = transformers_logging.get_logger(__name__) +transformers_logging.set_verbosity_info() + + +def merge_configurations(config_path: str, entropy_params_path: str) -> dict[str, Any]: + logger.info("Merging configurations") + + with open(config_path, "r") as f: + main_config = json.load(f) + + with open(entropy_params_path, "r") as f: + entropy_data = json.load(f) + + entropy_model_params = entropy_data.get("entropy_model", {}) + patcher_args = entropy_data.get("data", {}).get("patcher_args", {}) + + unified_config = main_config.copy()["args"] + + for key in ["vocab_size", "dim", "n_layers", "n_heads", "max_seqlen"]: + if key in unified_config and not isinstance(unified_config[key], int): + unified_config[key] = int(unified_config[key]) + + patch_size = patcher_args.get("patch_size", 8) + if isinstance(patch_size, float): + patch_size = int(patch_size) + + # Create patcher config + patcher_hidden_size = int(entropy_model_params.get("dim", 512)) + patcher_multiple_of = int(entropy_model_params.get("multiple_of", 256)) + patcher_intermediate_size = patcher_multiple_of * ( + (int(8 * patcher_hidden_size / 3) + patcher_multiple_of - 1) // patcher_multiple_of + ) + + patcher_config = { + "vocab_size": int(entropy_model_params.get("vocab_size", 256)), + "hidden_size": patcher_hidden_size, + "num_hidden_layers": int(entropy_model_params.get("n_layers", 8)), + "num_attention_heads": int(entropy_model_params.get("n_heads", 8)), + "num_key_value_heads": int(entropy_model_params.get("n_kv_heads")) + if entropy_model_params.get("n_kv_heads") is not None + else None, + "max_position_embeddings": int(entropy_model_params.get("max_seqlen", 1024)), + "norm_eps": entropy_model_params.get("norm_eps", 1e-5), + "dropout": entropy_model_params.get("dropout", 0.0), + "rope_theta": entropy_model_params.get("rope_theta", 10000.0), + "attn_impl": entropy_model_params.get("attn_impl", "sdpa"), + "attn_bias_type": entropy_model_params.get("attn_bias_type", "causal"), + "intermediate_size": patcher_intermediate_size, + } + + # Create encoder config + encoder_hidden_size = unified_config.get("dim_local_encoder", 1024) + encoder_multiple_of = unified_config.get("multiple_of", 256) + encoder_intermediate_size = encoder_multiple_of * ( + (int(8 * encoder_hidden_size / 3) + encoder_multiple_of - 1) // encoder_multiple_of + ) + + encoder_config = { + "vocab_size": unified_config.get("vocab_size", 256), + "cross_attn_all_layers": unified_config.get("cross_attn_all_layers_encoder", False), + "cross_attn_k": unified_config.get("cross_attn_k", 2), + "hidden_size_global": unified_config.get("dim_global", 2048), + "pm_size": unified_config.get("pm_size", 0), + "hidden_size": encoder_hidden_size, + "num_attention_heads": unified_config.get("n_heads_local_encoder", 16), + "num_key_value_heads": unified_config.get("n_kv_heads"), + "num_hidden_layers": unified_config.get("n_layers_local_encoder", 1), + "norm_eps": unified_config.get("norm_eps", 1e-5), + "dropout": unified_config.get("dropout", 0.0), + "max_position_embeddings": unified_config.get("max_encoder_seq_length") + or unified_config.get("max_seqlen", 1024), + "rope_theta": unified_config.get("rope_theta", 10000.0), + "rope_scaling": {"rope_type": "default"}, + "hidden_act": unified_config.get("hidden_act", "silu"), + "_attn_implementation": unified_config.get("_attn_implementation", "sdpa"), + "intermediate_size": encoder_intermediate_size, + } + + # Create decoder config + decoder_hidden_size = unified_config.get("dim_local_decoder", 1024) + decoder_multiple_of = unified_config.get("multiple_of", 256) + decoder_intermediate_size = decoder_multiple_of * ( + (int(8 * decoder_hidden_size / 3) + decoder_multiple_of - 1) // decoder_multiple_of + ) + + decoder_config = { + "vocab_size": unified_config.get("vocab_size", 256), + "cross_attn_all_layers": unified_config.get("cross_attn_all_layers_decoder", False), + "cross_attn_k": unified_config.get("cross_attn_k", 2), + "hidden_size_global": unified_config.get("dim_global", 2048), + "hidden_size": decoder_hidden_size, + "num_attention_heads": unified_config.get("n_heads_local_decoder", 16), + "num_key_value_heads": unified_config.get("n_kv_heads"), + "num_hidden_layers": unified_config.get("n_layers_local_decoder", 9), + "norm_eps": unified_config.get("norm_eps", 1e-5), + "dropout": unified_config.get("dropout", 0.0), + "max_position_embeddings": unified_config.get("max_encoder_seq_length") + or unified_config.get("max_seqlen", 1024), + "rope_theta": unified_config.get("rope_theta", 10000.0), + "rope_scaling": {"rope_type": "default"}, + "hidden_act": unified_config.get("hidden_act", "silu"), + "_attn_implementation": unified_config.get("_attn_implementation", "sdpa"), + "intermediate_size": decoder_intermediate_size, + } + + # Create global transformer config + global_hidden_size = unified_config.get("dim_global", 2048) + global_multiple_of = unified_config.get("multiple_of", 256) + global_intermediate_size = global_multiple_of * ( + (int(8 * global_hidden_size / 3) + global_multiple_of - 1) // global_multiple_of + ) + + global_config = { + "hidden_size": global_hidden_size, + "num_attention_heads": unified_config.get("n_heads_global", 16), + "num_key_value_heads": unified_config.get("n_kv_heads_global"), + "num_hidden_layers": unified_config.get("n_layers_global", 25), + "norm_eps": unified_config.get("norm_eps", 1e-5), + "dropout": unified_config.get("dropout", 0.0), + "max_position_embeddings": unified_config.get("max_seqlen", 1024), + "rope_theta": unified_config.get("rope_theta", 10000.0), + "rope_scaling": {"rope_type": "default"}, + "hidden_act": unified_config.get("hidden_act", "silu"), + "_attn_implementation": unified_config.get("_attn_implementation", "sdpa"), + "intermediate_size": global_intermediate_size, + } + + # Create main config with sub-configs + main_config_dict = { + "model_type": "blt", + "vocab_size": unified_config.get("vocab_size", 256), + "max_position_embeddings": unified_config.get("max_seqlen", 1024), + "patch_in_forward": True, + "realtime_patching": True, + "patching_mode": "entropy", + "patch_size": patch_size, + "patching_threshold": patcher_args.get("threshold", 0.5), + "patching_threshold_add": patcher_args.get("threshold_add", 0.0), + "max_patch_length": patcher_args.get("max_patch_length"), + "patching_batch_size": patcher_args.get("patching_batch_size", 1), + "patching_device": patcher_args.get("patching_device", "cuda"), + "monotonicity": patcher_args.get("monotonicity", False), + "cross_attn_k": unified_config.get("cross_attn_k", 2), + "encoder_hash_byte_group_size": unified_config.get("encoder_hash_byte_group_size"), + "encoder_hash_byte_group_vocab": unified_config.get("encoder_hash_byte_group_vocab", 30000), + "encoder_hash_byte_group_nb_functions": unified_config.get("encoder_hash_byte_group_nb_functions", 3), + "pm_size": unified_config.get("pm_size", 0), + "patcher_config": patcher_config, + "encoder_config": encoder_config, + "decoder_config": decoder_config, + "global_config": global_config, + } + + main_config_dict["tie_word_embeddings"] = False + + logger.info(f"Merged configuration with {len(main_config_dict)} parameters") + return main_config_dict + + +def apply_weight_mapping(state_dict: dict[str, torch.Tensor]) -> dict[str, torch.Tensor]: + component_mappings = { + ".attention.": ".self_attn.", + ".feed_forward.": ".mlp.", + ".attention_norm.": ".input_layernorm.", + ".ffn_norm.": ".post_attention_layernorm.", + ".tok_embeddings.": ".embed_tokens.", + ".cross_attn_norm_q.": ".q_norm.", + ".cross_attn_norm_kv.": ".k_norm.", + ".w1.": ".gate_proj.", + ".w2.": ".down_proj.", + ".w3.": ".up_proj.", + ".wq.": ".q_proj.", + ".wk.": ".k_proj.", + ".wv.": ".v_proj.", + ".wo.": ".o_proj.", + ".output.": ".lm_head.", + } + + new_state_dict = {} + + for old_key, tensor in state_dict.items(): + new_key = old_key + + for old_pattern, new_pattern in component_mappings.items(): + if old_pattern in new_key: + new_key = new_key.replace(old_pattern, new_pattern) + + new_state_dict[new_key] = tensor + + return new_state_dict + + +def convert_hash_embeddings_to_fused( + unified_weights: dict[str, torch.Tensor], config: dict[str, Any] +) -> dict[str, torch.Tensor]: + """Convert ModuleList hash embeddings to nn.embedding format""" + original_keys_format = [ + key + for key in unified_weights.keys() + if "encoder_hash_tok_embedding." in key and ".weight" in key and key.split(".")[-2].isdigit() + ] + + num_embeddings = config.get("encoder_hash_byte_group_nb_functions", 1) * len( + config.get("encoder_hash_byte_group_size", [3, 4, 5, 6, 7, 8]) + ) + vocab_size = config.get("encoder_hash_byte_group_vocab", 500002) + hidden_size = config.get("encoder_config", {}).get("hidden_size", 1024) + + fused_weight = torch.zeros(vocab_size * num_embeddings, hidden_size) + + sorted_keys = sorted(original_keys_format, key=lambda k: int(k.split(".")[-2])) + + for i, old_key in enumerate(sorted_keys): + start_idx = i * vocab_size + end_idx = (i + 1) * vocab_size + fused_weight[start_idx:end_idx] = unified_weights[old_key] + logger.info(f"Copied {old_key} to indices {start_idx}:{end_idx}") + del unified_weights[old_key] + + fused_key = "model.encoder_hash_tok_embedding.weight" + unified_weights[fused_key] = fused_weight + + return unified_weights + + +def merge_weights(weights_path: str, entropy_weights_path: str) -> dict[str, torch.Tensor]: + main_weights = load_file(weights_path) + + entropy_weights = torch.load(entropy_weights_path, map_location="cpu", weights_only=True) + + if "model" in entropy_weights: + entropy_weights = entropy_weights["model"] + elif "state_dict" in entropy_weights: + entropy_weights = entropy_weights["state_dict"] + + unified_weights = main_weights.copy() + + for key, tensor in entropy_weights.items(): + patcher_key = f"patcher.{key}" + unified_weights[patcher_key] = tensor + + unified_weights = apply_weight_mapping(unified_weights) + + decoder_lm_head_key = "local_decoder.lm_head.weight" + top_lm_head_key = "lm_head.weight" + unified_weights[top_lm_head_key] = unified_weights[decoder_lm_head_key] + del unified_weights[decoder_lm_head_key] + + prefixed_weights = {} + for key, tensor in unified_weights.items(): + if key == top_lm_head_key: + prefixed_weights[key] = tensor + elif not key.startswith("model."): + prefixed_weights[f"model.{key}"] = tensor + else: + prefixed_weights[key] = tensor + + unified_weights = prefixed_weights + + return unified_weights + + +def create_tokenizer_config(output_dir: str, config: dict[str, Any]): + tokenizer_config = { + "tokenizer_class": "PreTrainedTokenizerFast", + "vocab_size": config.get("vocab_size", 256), + "model_max_length": config.get("max_seqlen", 1024), + "model_input_names": ["input_ids", "attention_mask"], + "add_bos_token": True, + "add_eos_token": True, + "bos_token": "", + "eos_token": "", + "pad_token": "", + "unk_token": "", + } + + tokenizer_path = os.path.join(output_dir, "tokenizer_config.json") + with open(tokenizer_path, "w") as f: + json.dump(tokenizer_config, f, indent=2) + + +def create_tokenizer_json(output_dir: str, config: dict[str, Any]): + byte_encoder = bytes_to_unicode() + + vocab: dict[str, int] = {} + vocab[""] = 0 + vocab[""] = 1 + vocab[""] = 2 + vocab[""] = 3 + + offset = 4 + for byte_val, unicode_char in byte_encoder.items(): + vocab[unicode_char] = byte_val + offset + + backend = Tokenizer( + BPE(vocab=vocab, merges=[], continuing_subword_prefix="", end_of_word_suffix="", fuse_unk=False) + ) + backend.pre_tokenizer = pre_tokenizers.ByteLevel(add_prefix_space=False) + backend.decoder = decoders.ByteLevel() + + bos = config.get("bos_token", "") + backend.post_processor = processors.TemplateProcessing( + single=f"{bos}:0 $A:0", + pair=f"{bos}:0 $A:0 $B:1", + special_tokens=[(bos, 1)], + ) + + tokenizer = PreTrainedTokenizerFast( + tokenizer_object=backend, + bos_token=config.get("bos_token", ""), + eos_token=config.get("eos_token", ""), + pad_token=config.get("pad_token", ""), + unk_token=config.get("unk_token", ""), + ) + + tokenizer.add_bos_token = bool(config.get("add_bos_token", True)) + tokenizer.add_eos_token = bool(config.get("add_eos_token", True)) + + tokenizer.save_pretrained(output_dir) + logger.info(f"Saved tokenizer.json to {os.path.join(output_dir, 'tokenizer.json')}") + + +def push_to_hub( + local_dir: str, + repo_id: str, + commit_message: str = "Upload converted Blt model", + private: bool = False, + token: Optional[str] = None, +) -> None: + try: + upload_folder( + folder_path=local_dir, + repo_id=repo_id, + commit_message=commit_message, + repo_type="model", + token=token, + ) + logger.info(f"Successfully pushed model to {repo_id}") + + except Exception as e: + logger.error(f"Failed to push model to Hub: {e}") + raise + + +def convert_hf_blt_to_unified( + model_id: str, + output_dir: str, + config_name: str = "config.json", + weights_name: str = "model.bin", + cache_dir: Optional[str] = None, + push_to_hub_repo: Optional[str] = None, + hub_private: bool = False, + hub_token: Optional[str] = None, +) -> None: + # Download model files + config_path = hf_hub_download(repo_id=model_id, filename="config.json", cache_dir=cache_dir) + weights_path = hf_hub_download(repo_id=model_id, filename="model.safetensors", cache_dir=cache_dir) + entropy_params_path = hf_hub_download(repo_id=model_id, filename="entropy_model/params.json", cache_dir=cache_dir) + entropy_weights_path = hf_hub_download( + repo_id=model_id, filename="entropy_model/consolidated.pth", cache_dir=cache_dir + ) + + unified_config = merge_configurations(config_path, entropy_params_path) + unified_weights = merge_weights(weights_path, entropy_weights_path) + + unified_weights = convert_hash_embeddings_to_fused(unified_weights, unified_config) + + os.makedirs(output_dir, exist_ok=True) + + config_path = os.path.join(output_dir, config_name) + with open(config_path, "w") as f: + json.dump(unified_config, f, indent=2) + + if weights_name.endswith(".bin"): + weights_name = weights_name.replace(".bin", ".safetensors") + + weights_path = os.path.join(output_dir, weights_name) + save_file(unified_weights, weights_path) + + create_tokenizer_json(output_dir=output_dir, config=unified_config) + + create_tokenizer_config(output_dir, unified_config) + + logger.info(f"Conversion completed, model saved to: {output_dir}") + + if push_to_hub_repo: + push_to_hub( + local_dir=output_dir, + repo_id=push_to_hub_repo, + commit_message="Upload Blt model converted", + private=hub_private, + token=hub_token, + ) + + +def main(): + parser = argparse.ArgumentParser( + description="Convert Blt models from HuggingFace Hub format to unified format", + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + + parser.add_argument( + "--model_id", + type=str, + default="facebook/blt-7b", + ) + parser.add_argument( + "--output_dir", + type=str, + default="./blt_converted", + ) + parser.add_argument( + "--config_name", + type=str, + default="config.json", + ) + parser.add_argument( + "--weights_name", + type=str, + default="model.bin", + ) + parser.add_argument( + "--cache_dir", + type=str, + default=None, + ) + parser.add_argument( + "--debug", + action="store_true", + default=True, + ) + parser.add_argument( + "--push_to_hub", + type=str, + default=None, + ) + parser.add_argument( + "--hub_private", + action="store_true", + default=False, + ) + parser.add_argument( + "--hub_token", + type=str, + default="hf_token", + ) + + args = parser.parse_args() + + transformers_logging.set_verbosity_debug() + logging.basicConfig(level=logging.DEBUG) + + try: + convert_hf_blt_to_unified( + model_id=args.model_id, + output_dir=args.output_dir, + config_name=args.config_name, + weights_name=args.weights_name, + cache_dir=args.cache_dir, + push_to_hub_repo=False, # args.push_to_hub, + hub_private=args.hub_private, + hub_token=args.hub_token, + ) + except Exception as e: + logger.error(f"Conversion failed: {e}") + raise + + +if __name__ == "__main__": + main() diff --git a/src/transformers/models/blt/modeling_blt.py b/src/transformers/models/blt/modeling_blt.py new file mode 100644 index 000000000000..e1639d4e3e2b --- /dev/null +++ b/src/transformers/models/blt/modeling_blt.py @@ -0,0 +1,1306 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/blt/modular_blt.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_blt.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 HuggingFace Inc. team. All rights reserved. +# +# 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. + +from typing import Callable, Optional, Union + +import torch +import torch.distributions +import torch.nn as nn +import torch.nn.functional as F + +from ...activations import ACT2FN +from ...cache_utils import Cache, DynamicCache +from ...generation import GenerationMixin +from ...masking_utils import create_causal_mask +from ...modeling_flash_attention_utils import FlashAttentionKwargs +from ...modeling_layers import GradientCheckpointingLayer +from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple +from ...utils.deprecation import deprecate_kwarg +from ...utils.generic import OutputRecorder, check_model_inputs +from .configuration_blt import ( + BltConfig, + BltGlobalTransformerConfig, + BltLocalDecoderConfig, + BltLocalEncoderConfig, + BltPatcherConfig, +) + + +class BltMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + # Ignore copy + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +class BltRMSNorm(nn.Module): + def __init__(self, hidden_size, eps=1e-6): + """ + BltRMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states): + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return self.weight * hidden_states.to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +class BltRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: BltConfig, device=None): + super().__init__() + # BC: "rope_type" was originally "type" + if hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): + self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type")) + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1) + position_ids_expanded = position_ids[:, None, :].float() + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2) + emb = torch.repeat_interleave(freqs, 2, dim=-1) # diff from Llama: we interleave() instead of cat() + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + +# Modified from transformers.models.llama.modeling_llama.LlamaDecoderLayer +class BltTransformerLayer(GradientCheckpointingLayer): + def __init__(self, config, layer_idx: int): + super().__init__() + self.hidden_size = config.hidden_size + + self.self_attn = BltSelfAttention(config=config, layer_idx=layer_idx) + self.mlp = BltMLP(config) + self.input_layernorm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + self.layer_idx = layer_idx + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + cross_attention_states: Optional[torch.Tensor] = None, + cross_attention_mask: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + full_text_row_masked_out_mask: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, # necessary, but kept here for BC + **kwargs: Unpack[FlashAttentionKwargs], + ) -> tuple[torch.FloatTensor, Optional[tuple[torch.FloatTensor, torch.FloatTensor]]]: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`, *optional*): + attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1, + query_sequence_length, key_sequence_length)` if default attention is used. + + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + past_key_values (`Cache`, *optional*): cached past key and value projection states + cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): + Indices depicting the position of the input sequence tokens in the sequence + position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): + Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`, + with `head_dim` being the embedding dimension of each attention head. + kwargs (`dict`, *optional*): + Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code + into the model + """ + residual = hidden_states + + hidden_states = self.input_layernorm(hidden_states) + + # Self Attention + hidden_states, self_attn_weights = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + hidden_states + + return hidden_states + + +def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor: + """ + This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, + num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim) + """ + batch, num_key_value_heads, slen, head_dim = hidden_states.shape + if n_rep == 1: + return hidden_states + hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim) + return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim) + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: float, + dropout: float = 0.0, + **kwargs: Unpack[TransformersKwargs], +): + key_states = repeat_kv(key, module.num_key_value_groups) + value_states = repeat_kv(value, module.num_key_value_groups) + + attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling + if attention_mask is not None: + causal_mask = attention_mask[:, :, :, : key_states.shape[-2]] + attn_weights = attn_weights + causal_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + attn_output = torch.matmul(attn_weights, value_states) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + +def rotate_half(x): + # Split and rotate. Note that this function is different from e.g. Llama. + x1 = x[..., ::2] + x2 = x[..., 1::2] + rot_x = torch.stack([-x2, x1], dim=-1).flatten(-2) + return rot_x + + +def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1): + """Applies Rotary Position Embedding to the query and key tensors. + + Args: + q (`torch.Tensor`): The query tensor. + k (`torch.Tensor`): The key tensor. + cos (`torch.Tensor`): The cosine part of the rotary embedding. + sin (`torch.Tensor`): The sine part of the rotary embedding. + position_ids (`torch.Tensor`, *optional*): + Deprecated and unused. + unsqueeze_dim (`int`, *optional*, defaults to 1): + The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and + sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note + that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and + k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes + cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have + the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. + Returns: + `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. + """ + cos = cos.unsqueeze(unsqueeze_dim) + sin = sin.unsqueeze(unsqueeze_dim) + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + return q_embed, k_embed + + +class BltSelfAttention(nn.Module): + def __init__(self, config: BltConfig, layer_idx: int): + super().__init__() + self.config = config + self.num_heads = config.num_attention_heads + self.dropout = config.dropout + self.hidden_size = config.hidden_size + self.num_key_value_heads = config.num_key_value_heads + self.head_dim = config.hidden_size // self.num_heads + self.num_key_value_groups = self.num_heads // self.num_key_value_heads + self.scaling = self.head_dim**-0.5 + self.rope_theta = config.rope_theta + self.layer_idx = layer_idx + + self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False) + self.k_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=False) + self.v_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=False) + self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=False) + self.is_causal = True + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + position_embeddings: torch.Tensor, + use_cache: bool = False, + past_key_values=None, + cache_position=None, + **kwargs, + ): + bsz, q_len, _ = hidden_states.size() + + query_states = self.q_proj(hidden_states) + key_states = self.k_proj(hidden_states) + value_states = self.v_proj(hidden_states) + + query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2) + key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2) + value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(bsz, q_len, -1).contiguous() + attn_output = self.o_proj(attn_output) + + return attn_output, attn_weights + + +class BltCrossAttention(nn.Module): + """Cross-attention module for Blt, following transformers style""" + + def __init__(self, config: BltConfig, layer_idx: int, hidden_size: Optional[int] = None): + super().__init__() + self.config = config + self.num_heads = self.config.num_attention_heads + self.num_key_value_heads = self.config.num_key_value_heads + self.dropout = config.dropout + self.hidden_size = config.hidden_size + self.head_dim = config.hidden_size // self.num_heads + self.layer_idx = layer_idx + self.num_key_value_groups = self.num_heads // self.num_key_value_heads + self.scaling = self.head_dim**-0.5 + + self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False) + self.k_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=False) + self.v_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=False) + self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=False) + self.q_norm = BltRMSNorm(self.hidden_size, eps=config.rms_norm_eps) + self.k_norm = BltRMSNorm(self.hidden_size, eps=config.rms_norm_eps) + self.is_causal = False + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + cross_attention_states: Optional[torch.Tensor] = None, + past_key_values: Optional[Cache] = None, + attention_mask: Optional[torch.Tensor] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + bsz, q_len, _ = hidden_states.size() + query_states = self.q_norm(hidden_states) + query_states = self.q_proj(query_states) + query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2) + + if cross_attention_states is not None: + cross_attention_states = self.k_norm(cross_attention_states) + key_states = self.k_proj(cross_attention_states) + value_states = self.v_proj(cross_attention_states) + key_states = key_states.view(bsz, -1, self.num_key_value_heads, self.head_dim).transpose(1, 2) + value_states = value_states.view(bsz, -1, self.num_key_value_heads, self.head_dim).transpose(1, 2) + if past_key_values is not None: + key_states, value_states = past_key_values.update( + key_states, value_states, self.layer_idx, {"cache_position": cache_position} + ) + elif cache_position[0] != 0: + key_states, value_states = ( + past_key_values.layers[self.layer_idx].keys, + past_key_values.layers[self.layer_idx].values, + ) + else: + raise ValueError( + "Cross attention layer can't find neither `cross_attn_states` nor cached values for key/values!" + ) + attention_interface: Callable = eager_attention_forward + + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.dropout, + scaling=self.scaling, + **kwargs, + ) + attn_output = attn_output.reshape(bsz, q_len, -1).contiguous() + attn_output = self.o_proj(attn_output) + attn_output = attn_output + hidden_states + return attn_output, attn_weights + + +@auto_docstring +class BltPreTrainedModel(PreTrainedModel): + config: BltConfig + base_model_prefix = "" + supports_gradient_checkpointing = True + _no_split_modules = ["BltTransformerLayer"] + _can_compile_fullgraph = False # static cache cannot have different shapes for each layer + _supports_sdpa = True + _supports_flash_attn = True + _supports_flex_attn = True + _supports_attention_backend = False + _can_record_outputs = { + "hidden_states": OutputRecorder(BltTransformerLayer, index=0, layer_name="local_decoder"), + "attentions": OutputRecorder(BltSelfAttention, index=1, layer_name="local_decoder"), + } + + +class BltLocalEncoder(BltPreTrainedModel): + config: BltLocalEncoderConfig + _can_record_outputs = { + "encoder_attentions": OutputRecorder(BltSelfAttention, index=1, layer_name="local_encoder"), + } + + def __init__(self, config: BltLocalEncoderConfig): + super().__init__(config) + self.gradient_checkpointing = False + self.config = config + self.layers = nn.ModuleList( + [BltTransformerLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = BltRotaryEmbedding(config=config) + self.patch_embedding_projection = nn.Linear( + in_features=config.hidden_size, + out_features=config.hidden_size * config.cross_attn_k, + bias=False, + ) + self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size) + self.cross_attn_layers = nn.ModuleList() + layers_to_add = config.num_hidden_layers if config.cross_attn_all_layers else 1 + for layer_idx in range(layers_to_add): + self.cross_attn_layers.append( + BltCrossAttention(config=config, layer_idx=layer_idx, hidden_size=config.hidden_size) + ) + + self.post_init() + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + patch_embeds: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + num_patches: Optional[int] = None, + patch_ids: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ): + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + batch_size = inputs_embeds.shape[0] + hidden_states = F.dropout(inputs_embeds, p=self.config.dropout, training=self.training) + + if position_ids is None: + position_ids = ( + torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device).unsqueeze(0).expand(batch_size, -1) + ) + + position_embeddings = self.rotary_emb(hidden_states, position_ids) + hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training) + + for idx, layer in enumerate(self.layers): + hidden_states = layer( + hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + past_key_values=past_key_values, + cache_position=cache_position, + **kwargs, + ) + if idx == len(self.layers) - 1 or self.config.cross_attn_all_layers: + patch_embeds = self.patch_reduce(hidden_states, num_patches, patch_ids) + patch_embeds = self.patch_embedding_projection(patch_embeds) + patch_embeds = patch_embeds.reshape( + batch_size, patch_embeds.shape[1] * self.config.cross_attn_k, self.config.hidden_size + ) + layer_idx = idx if self.config.cross_attn_all_layers else 0 + cross_attention_output, _ = self.cross_attn_layers[layer_idx]( + hidden_states=patch_embeds, + cross_attention_states=hidden_states, + attention_mask=encoder_attention_mask, + **kwargs, + ) + patch_embeds = patch_embeds + cross_attention_output + encoder_cross_states = patch_embeds + return hidden_states, encoder_cross_states + + def patch_reduce(self, hidden_states, max_num_patches, patch_ids): + """ + Reduce variable length patches to single embedding per patch + Note: this works with variable number of patches for different sequences in the batch + It handles variable length patches by assuming that patch_lengths will be 0 for any + extra patches on the *right*. Since there can be a variable number of patches + this function also return the number of patches for each sequence in the batch. + Any embeddings on the right that are not allocated to a patch + (i.e. if the sum(patch_lengths[i]) < seq_len for any i) + will be sent to a dummy patch, which is trimmed before returning. + """ + batch_size = hidden_states.shape[0] + embedding_dim = hidden_states.shape[-1] + + patch_ids = patch_ids.unsqueeze(-1).expand(-1, -1, hidden_states.shape[-1]) + + reduced_embeddings = torch.zeros( + (batch_size, max_num_patches, embedding_dim), dtype=hidden_states.dtype, device=hidden_states.device + ) + + reduced_embeddings = reduced_embeddings.scatter_reduce( + src=hidden_states, + dim=1, + index=patch_ids, + reduce="amax", + include_self=False, + ) + reduced_embeddings = reduced_embeddings[:, :max_num_patches, :] + + return reduced_embeddings + + +class BltLocalDecoder(BltPreTrainedModel): + config: BltLocalDecoderConfig + + def __init__(self, config: BltLocalDecoderConfig): + super().__init__(config) + self.gradient_checkpointing = False + self.config = config + self.cross_attn_decoder = True + self.layers = nn.ModuleList( + [BltTransformerLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = BltRotaryEmbedding(config=config) + self.patch_embedding_projection = nn.Linear( + in_features=config.hidden_size_global, + out_features=config.hidden_size * config.cross_attn_k, + bias=False, + ) + self.norm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.cross_attn_layers = nn.ModuleList() + layers_to_add = config.num_hidden_layers if config.cross_attn_all_layers else 1 + for layer_idx in range(layers_to_add): + self.cross_attn_layers.append( + BltCrossAttention(config=config, layer_idx=layer_idx, hidden_size=config.hidden_size) + ) + + self.post_init() + + @check_model_inputs + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + patch_embeds: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ): + batch_size = inputs_embeds.shape[0] + hidden_states = inputs_embeds + patch_embeds = self.patch_embedding_projection(patch_embeds) + patch_embeds = patch_embeds.reshape( + batch_size, patch_embeds.shape[1] * self.config.cross_attn_k, self.config.hidden_size + ) + + if patch_embeds is not None and not self.cross_attn_decoder: + hidden_states = hidden_states + patch_embeds + + if position_ids is None: + position_ids = ( + torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device).unsqueeze(0).expand(batch_size, -1) + ) + + position_embeddings = self.rotary_emb(hidden_states, position_ids) + hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training) + + for i, layer in enumerate(self.layers): + if i == 0 or self.config.cross_attn_all_layers: + cross_attention_output, _ = self.cross_attn_layers[i]( + hidden_states=hidden_states, + cross_attention_states=patch_embeds, + attention_mask=encoder_attention_mask, + **kwargs, + ) + hidden_states = hidden_states + cross_attention_output + hidden_states = layer( + hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + past_key_values=past_key_values, + cache_position=cache_position, + **kwargs, + ) + logits = self.norm(hidden_states) + return logits + + +class BltGlobalTransformer(BltPreTrainedModel): + config: BltGlobalTransformerConfig + _can_record_outputs = { + "global_attentions": OutputRecorder(BltSelfAttention, index=1, layer_name="global_transformer"), + } + + def __init__(self, config: BltGlobalTransformerConfig): + super().__init__(config) + self.config = config + self.layers = nn.ModuleList() + for layer_idx in range(config.num_hidden_layers): + self.layers.append(BltTransformerLayer(config, layer_idx)) + self.rotary_emb = BltRotaryEmbedding(config=config) + + # Create token embedding projection (use nn.Identity() when no projection needed) + if getattr(config, "encoder_cross_output_size", None) is not None: + self.token_embedding_projection = nn.Linear( + config.encoder_cross_output_size, config.hidden_size, bias=False + ) + else: + self.token_embedding_projection = nn.Identity() + + self.post_init() + + def forward( + self, + input_embeds: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ): + batch_size, seq_len, _ = input_embeds.shape + hidden_states = self.token_embedding_projection(input_embeds) + hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training) + if position_ids is None: + position_ids = ( + torch.arange(input_embeds.shape[1], device=input_embeds.device).unsqueeze(0).expand(batch_size, -1) + ) + position_embeddings = self.rotary_emb(hidden_states, position_ids) + for i, layer in enumerate(self.layers): + hidden_states = layer( + hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + past_key_values=past_key_values, + cache_position=cache_position, + **kwargs, + ) + return hidden_states + + +def process_patch_lengths(patch_lengths: torch.Tensor, max_patch_length: Optional[int]) -> torch.Tensor: + """ + Splits patch lengths into smaller segments if they exceed `max_patch_length`. + Pads the result to uniform length across the batch. + + Args: + patch_lengths (torch.Tensor): [batch_size, num_patches] tensor of patch lengths. + max_patch_length (int, optional): Maximum allowed length per patch. + + Returns: + torch.Tensor: [batch_size, max_len] tensor of split and padded patch lengths. + """ + if max_patch_length is None: + return patch_lengths + + batch_size = patch_lengths.size(0) + processed = [] + + for seq in patch_lengths: + splits = [] + for length in seq[seq > 0]: + length = length.item() + full_chunks, remainder = divmod(length, max_patch_length) + splits.extend([max_patch_length] * full_chunks) + if remainder: + splits.append(remainder) + processed.append(splits) + + # Find max length to pad to + max_len = max(len(splits) for splits in processed) + padded = torch.zeros((batch_size, max_len), dtype=patch_lengths.dtype, device=patch_lengths.device) + + for i, splits in enumerate(processed): + if splits: + padded[i, : len(splits)] = torch.tensor(splits, dtype=patch_lengths.dtype, device=patch_lengths.device) + + # Trim zero columns + if (padded != 0).any(dim=0).sum() < padded.shape[1]: + last_nonzero = (padded != 0).any(dim=0).nonzero().max().item() + 1 + padded = padded[:, :last_nonzero] + + return padded + + +class BltPatcher(BltPreTrainedModel): + config: BltPatcherConfig + + def __init__(self, config: BltPatcherConfig): + super().__init__(config) + self.rotary_emb = BltRotaryEmbedding(config=self.config) + self.layers = nn.ModuleList() + for layer_idx in range(self.config.num_hidden_layers): + self.layers.append(BltTransformerLayer(self.config, layer_idx)) + self.embed_tokens = nn.Embedding(self.config.vocab_size, self.config.hidden_size) + self.norm = BltRMSNorm(self.config.hidden_size, eps=self.config.rms_norm_eps) + self.lm_head = nn.Linear( + self.config.hidden_size, + self.config.vocab_size, + bias=False, + ) + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + patch_size: Optional[int] = None, + threshold: Optional[float] = None, + max_patch_length: Optional[int] = None, + **kwargs: Unpack[TransformersKwargs], + ): + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if use_cache and past_key_values is None: + past_key_values = DynamicCache() + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + causal_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + hidden_states = inputs_embeds + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for layer in self.layers: + hidden_states = layer(hidden_states, position_embeddings=position_embeddings, attention_mask=causal_mask) + + logits = self.lm_head(self.norm(hidden_states)) + prediction_entropies = torch.distributions.Categorical(logits=logits).entropy() + + batch_size, sequence_length = inputs_embeds.shape[:2] + if patch_size is not None: + patch_lengths = self.patch_lengths_from_entropies( + entropies=prediction_entropies, + sequence_length=sequence_length, + patch_size=patch_size, + threshold=threshold, + ) + else: + patch_lengths = torch.ones( + (batch_size, sequence_length), dtype=inputs_embeds.dtype, device=inputs_embeds.device + ) + patch_lengths = process_patch_lengths(patch_lengths, max_patch_length) + return prediction_entropies, patch_lengths, logits + + @staticmethod + def patch_lengths_from_entropies( + entropies, + sequence_length, + patch_size=None, + threshold=None, + ): + """ + Computes patch lengths from token entropies. + + Depending on whether a threshold is provided, the function uses either: + - Thresholding the entropy values (when `threshold` is set). + """ + + batch_size = entropies.shape[0] + + # Always include token 0 and 1 as starting tokens + init_tokens = ( + torch.tensor([0, 1], dtype=torch.long, device=entropies.device).unsqueeze(0).repeat(batch_size, 1) + ) + offset = init_tokens.shape[1] + + # Ignore first token entropy (BOS) + entropies = entropies[:, 1:] + + # Threshold the entropy values to define patch start points + patch_mask = entropies > threshold + + seq_len = patch_mask.shape[1] + + # Create patch IDs (token indices), and add a sentinel to ensure alignment + token_indices = torch.arange(seq_len, device=entropies.device).unsqueeze(0).expand(batch_size, -1) + sentinel = torch.full_like(token_indices, seq_len) + padded_indices = torch.cat([token_indices, sentinel], dim=1) + + # Pad mask with inverse to align sentinel correctly + padded_mask = torch.cat([patch_mask, ~patch_mask], dim=1) + + # Select indices where mask is True + patch_starts = padded_indices[padded_mask].reshape(batch_size, seq_len) + max_valid_patches = patch_mask.sum(dim=1).max() + patch_starts = patch_starts[:, :max_valid_patches] + + # Offset patch starts to account for the two initial tokens + patch_start_ids = torch.cat((init_tokens, patch_starts + offset), dim=1) + + # Compute patch end positions by shifting start positions + last_token = torch.full_like(patch_start_ids[:, :1], sequence_length - 1) + patch_ends = torch.cat((patch_start_ids[:, 1:] - 1, last_token), dim=1) + + patch_lengths = patch_ends - patch_start_ids + 1 + + return patch_lengths + + +def rolling_polynomial_hash(token_tensor, prime: int = 1000000007): + """ + A polynomial rolling hash algorithm that converts sequences + of tokens into hash values. The hash is computed as: + hash = (token_0 * prime^0 + token_1 * prime^1 + ... + token_n * prime^n) + + The rolling hash allows the model to efficiently + identify and encode recurring byte-level patterns in the input text. + + Args: + token_tensor (torch.Tensor): [batch_size, seq_len, group_size] containing token IDs to hash + prime (int): Prime number used as the base for the polynomial hash. + + Returns: + torch.Tensor: Hash values of shape [batch_size, seq_len] where each value + represents the hash of the corresponding token group + + Example: + >>> tokens = torch.tensor([[1, 2, 3], [4, 5, 6]]) + >>> hashes = rolling_polynomial_hash(tokens, prime=31) + >>> # hash[0] = 1*31^0 + 2*31^1 + 3*31^2 + >>> # hash[1] = 4*31^0 + 5*31^1 + 6*31^2 + """ + prime_tensor = torch.tensor(prime, dtype=torch.int64, device=token_tensor.device) + powers = torch.arange(token_tensor.shape[-1], device=token_tensor.device) + prime_powers = prime_tensor**powers + return torch.sum(token_tensor * prime_powers, dim=-1) + + +def byte_group_hash_function( + token_ids: torch.Tensor, group_size: int = 2, prime: int = 1000000007, max_hash: int = 30000 +): + """Hash token groups and map to range [0, max_hash].""" + with torch.no_grad(): + batch_size, seq_len = token_ids.shape + # Add padding for sliding window + padding = torch.zeros(batch_size, group_size - 1, dtype=torch.int64, device=token_ids.device) + padded_tokens = torch.cat([padding, token_ids], dim=1) + + # Create sliding windows and compute hashes + windows = padded_tokens.unfold(1, group_size, 1) + hashes = rolling_polynomial_hash(windows, prime) + hash_values = hashes % max_hash + + return hash_values + + +def compute_hash_embeddings( + local_encoder_tokens: torch.Tensor, + local_encoder, + encoder_hash_tok_embedding: nn.Embedding, + encoder_hash_byte_group_nb_functions: int, + encoder_hash_byte_group_size: list, + encoder_hash_byte_group_vocab: int, +) -> torch.Tensor: + """Compute token embeddings enhanced with hash-based embeddings.""" + # Available primes for hash functions + primes = [ + 1000000007, + 5915587277, + 1500450271, + 3267000013, + 5754853343, + 4093082899, + 9576890767, + 3628273133, + 2860486313, + 5463458053, + 3367900313, + ] + + embeddings = local_encoder.embed_tokens(local_encoder_tokens) + embedding_idx = 0 + for func_nb in range(encoder_hash_byte_group_nb_functions): + prime = primes[func_nb % len(primes)] # Cycle through primes if more functions than primes + for group_size in encoder_hash_byte_group_size: + hash_ids = byte_group_hash_function(local_encoder_tokens, group_size, prime, encoder_hash_byte_group_vocab) + # Apply offset to get the correct slice of the fused embedding + offset_hash_ids = hash_ids + embedding_idx * encoder_hash_byte_group_vocab + embeddings += encoder_hash_tok_embedding(offset_hash_ids) + embedding_idx += 1 + + return embeddings + + +def _prepare_patch_cross_attention_mask( + patch_ids: torch.Tensor, + num_patches: int, + sequence_length: int, + patches_as_queries: bool = False, + cross_attn_k: int = 1, + dtype: torch.dtype = torch.float32, +) -> tuple[torch.Tensor, torch.Tensor]: + """ + Prepare cross-attention mask for patch-based attention, following mllama's robust approach. + + This function creates masks that control which patches can attend to which other patches, + with support for query/key role swapping and cross-attention multipliers. + + Args: + patch_ids (torch.Tensor): Tensor of shape [batch_size, seq_len] containing patch ids. + num_patches (int): Total number of patches. + sequence_length (int): Length of the sequence. + patches_as_queries (bool): If True, patches are used as queries, otherwise as keys. + cross_attn_k (int): Cross-attention multiplier for repeating patches. + dtype (torch.dtype): Data type for the output mask. + + Returns: + Tuple[torch.Tensor, torch.Tensor]: + - cross_attention_mask: 4D tensor [batch_size, 1, q_len, kv_len] + """ + batch_size, seq_len = patch_ids.shape + device = patch_ids.device + + # Determine query and key lengths based on configuration + if patches_as_queries: + q_len = num_patches * cross_attn_k + kv_len = sequence_length + # Create patch-to-sequence mapping + q_patch_ids = ( + torch.arange(num_patches, device=device) + .unsqueeze(0) + .unsqueeze(-1) + .expand(batch_size, num_patches, seq_len) + ) + kv_patch_ids = patch_ids.unsqueeze(1).expand(batch_size, num_patches, seq_len) + else: + q_len = sequence_length + kv_len = num_patches * cross_attn_k + # Create sequence-to-patch mapping + q_patch_ids = patch_ids.unsqueeze(-1).expand(batch_size, seq_len, num_patches) + kv_patch_ids = ( + torch.arange(num_patches, device=device).unsqueeze(0).unsqueeze(0).expand(batch_size, seq_len, num_patches) + ) + + # Create base attention mask - boolean mask where True means "should attend" + # Exact patch matching + cross_attention_mask = q_patch_ids == kv_patch_ids + + # Handle cross_attn_k multiplier by repeating along appropriate dimension + repeat_dim = 1 if patches_as_queries else -1 + cross_attention_mask = cross_attention_mask.repeat_interleave(cross_attn_k, dim=repeat_dim) + + # Validate dimensions + expected_shape = (batch_size, q_len, kv_len) + if cross_attention_mask.shape != expected_shape: + raise ValueError( + f"Cross attention mask shape {cross_attention_mask.shape} doesn't match expected {expected_shape}" + ) + + # Reshape so it can be used by attn module - add head dimension + cross_attention_mask = cross_attention_mask.unsqueeze(1) # [batch_size, 1, q_len, kv_len] + + # Invert the mask (following mllama pattern exactly) + # True -> 0.0 (attend), False -> 1.0 (will become -inf) + inverted_cross_attn_mask = 1.0 - cross_attention_mask.to(dtype) + cross_attention_mask = inverted_cross_attn_mask.masked_fill( + inverted_cross_attn_mask.to(torch.bool), torch.finfo(dtype).min + ) + + return cross_attention_mask + + +class BltModel(BltPreTrainedModel): + def __init__(self, config: BltConfig): + super().__init__(config) + self.gradient_checkpointing = False + + self.config = config + self.local_encoder = BltLocalEncoder(config.encoder_config) + self.global_transformer = BltGlobalTransformer(config.global_config) + self.local_decoder = BltLocalDecoder(config.decoder_config) + num_embeddings = config.encoder_hash_byte_group_nb_functions * len(config.encoder_hash_byte_group_size) + total_vocab_size = config.encoder_hash_byte_group_vocab * num_embeddings + self.encoder_hash_tok_embedding = nn.Embedding(total_vocab_size, config.encoder_config.hidden_size) + if self.config.patch_in_forward: + self.patcher = BltPatcher(config.patcher_config) + self.patcher.eval() + for param in self.patcher.parameters(): + param.requires_grad = False + else: + self.patcher = None + self.post_init() + + @check_model_inputs + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + patch_lengths: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> BaseModelOutputWithPast: + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + # Extract input embeddings as early as possible + if inputs_embeds is not None: + encoder_embeds = inputs_embeds + batch_size, sequence_length, _ = inputs_embeds.shape + else: + batch_size, sequence_length = input_ids.shape + encoder_embeds = compute_hash_embeddings( + input_ids, + self.local_encoder, + self.encoder_hash_tok_embedding, + self.config.encoder_hash_byte_group_nb_functions, + self.config.encoder_hash_byte_group_size, + self.config.encoder_hash_byte_group_vocab, + ) + + if patch_lengths is None: + if self.config.patching_mode == "entropy" and self.patcher is not None: + if input_ids is None: + raise ValueError("input_ids is required for entropy-based patching") + _, patch_lengths, _ = self.patcher( + input_ids, + patch_size=self.config.patch_size, + threshold=self.config.patching_threshold, + max_patch_length=self.config.max_patch_length, + patching_batch_size=self.config.patching_batch_size, + device=input_ids.device, + ) + else: + device = input_ids.device if input_ids is not None else inputs_embeds.device + dtype = input_ids.dtype if input_ids is not None else inputs_embeds.dtype + patch_lengths = process_patch_lengths( + torch.ones((batch_size, sequence_length + 1), dtype=dtype, device=device), + self.config.max_patch_length, + ) + patch_ids = self._patch_ids_from_lengths(patch_lengths, sequence_length) + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + encoder_embeds.shape[1], device=encoder_embeds.device + ) + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + causal_mask = create_causal_mask( + config=self.config, + input_embeds=encoder_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + cross_attn_mask_enc = _prepare_patch_cross_attention_mask( + patch_ids, patch_lengths.shape[1], sequence_length, True, self.config.cross_attn_k, encoder_embeds.dtype + ) + encoder_hidden_states, encoder_cross_states = self.local_encoder( + input_ids=input_ids, + inputs_embeds=encoder_embeds, + attention_mask=causal_mask, + position_ids=position_ids, + encoder_attention_mask=cross_attn_mask_enc, + num_patches=patch_lengths.shape[1], + patch_ids=patch_ids, + **kwargs, + ) + encoder_cross_states = encoder_cross_states.view(batch_size, patch_lengths.shape[1], -1) + global_cache_position = torch.arange(0, encoder_cross_states.shape[1], device=encoder_cross_states.device) + global_position_ids = global_cache_position.unsqueeze(0) + global_causal_mask = create_causal_mask( + config=self.config, + input_embeds=encoder_cross_states, + attention_mask=None, + cache_position=global_cache_position, + past_key_values=None, + position_ids=None, + ) + + global_hidden_states = self.global_transformer( + input_embeds=encoder_cross_states, + attention_mask=global_causal_mask, + position_ids=global_position_ids, + **kwargs, + ) + decoder_patch_ids = self._patch_ids_from_lengths(patch_lengths[:, 1:], sequence_length) + cross_attn_mask_dec = _prepare_patch_cross_attention_mask( + decoder_patch_ids, + patch_lengths.shape[1], + sequence_length, + False, + self.config.cross_attn_k, + encoder_embeds.dtype, + ) + output = self.local_decoder( + input_ids=input_ids, + inputs_embeds=encoder_hidden_states, + patch_embeds=global_hidden_states, + attention_mask=causal_mask, + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + encoder_attention_mask=cross_attn_mask_dec, + **kwargs, + ) + return BaseModelOutputWithPast( + last_hidden_state=output, + past_key_values=past_key_values, + ) + + def get_input_embeddings(self): + return self.local_encoder.embed_tokens + + def set_input_embeddings(self, value): + self.local_encoder.embed_tokens = value + + def _patch_ids_from_lengths(self, patch_lengths: torch.Tensor, seq_len: int) -> torch.Tensor: + batch_size = patch_lengths.shape[0] + patch_starts = torch.cat( + [ + torch.zeros(batch_size, 1, dtype=patch_lengths.dtype, device=patch_lengths.device), + patch_lengths.cumsum(dim=-1)[:, :-1], + ], + dim=-1, + ) + token_positions = torch.arange(seq_len, device=patch_lengths.device) + return (patch_starts.unsqueeze(1) <= token_positions.unsqueeze(0).unsqueeze(-1)).sum(dim=-1) - 1 + + +@auto_docstring( + custom_intro=""" + The Blt Text Model with a language modeling head on top. + """ +) +class BltForCausalLM(BltPreTrainedModel, GenerationMixin): + config: BltConfig + _can_compile_fullgraph = False + base_model_prefix = "model" + _tied_weights_keys = ["lm_head.weight"] + + def __init__(self, config: BltConfig): + super().__init__(config.get_text_config()) + self.text_config = config.get_text_config() + self.vocab_size = config.vocab_size + self.model = BltModel(config) + self.lm_head = nn.Linear(config.decoder_config.hidden_size, config.vocab_size, bias=False) + + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + cross_attention_states: Optional[torch.LongTensor] = None, # Keep for compatibility + cross_attention_mask: Optional[torch.LongTensor] = None, + full_text_row_masked_out_mask: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + past_key_values: Optional[Union[Cache, list[torch.FloatTensor]]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, CausalLMOutputWithPast]: + r""" + cross_attention_states (`torch.FloatTensor`, *optional*): + Output of the vision model, used for cross-attention. This tensor contains the processed image features that + the language model will attend to. + cross_attention_mask (`torch.Tensor` of shape `(batch_size, seq_length, max_num_images, max_num_tiles)`, *optional*): + Cross-attention mask to control the interaction between text tokens and image tiles. + This 4D tensor defines which image tiles each text token should attend to. + + For each text token (in seq_length): + - 1 indicates the token **should attend** to the corresponding image tile + - 0 indicates the token **should not attend** to the corresponding image tile + full_text_row_masked_out_mask (`tuple[torch.Tensor, torch.Tensor]`, *optional*): + A tuple containing two tensors that mask out rows in the cross-attention mechanism: + - The first tensor has shape `(batch_size, 1, seq_length, 1)` and contains values of 0 or 1. + A value of 0 indicates that the corresponding text token's entire row in the cross-attention + matrix should be masked out (all image tokens ignored). + - The second tensor has the same shape and is used internally to apply the masking during + the forward pass of cross-attention layers. + This mask is derived from the cross_attention_mask and is used to handle cases where a text token + should not attend to any image token. + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + + Example: + + ```python + >>> from transformers import AutoTokenizer, BltForCausalLM + + >>> model = BltForCausalLM.from_pretrained("Llama-3.2-11B-Vision") + >>> tokenizer = AutoTokenizer.from_pretrained("Llama-3.2-11B-Vision") + + >>> prompt = "If I had to write a haiku, it would be:" + >>> inputs = tokenizer(prompt, return_tensors="pt") + + >>> # Generate + >>> generate_ids = model.generate(inputs.input_ids, max_length=40, do_sample=True, temperature=0.6) + >>> result = tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] + >>> print(result) + If I had to write a haiku, it would be: "Snowflakes gently fall" - simple, yet peaceful. + I love the idea of snowflakes gently falling, each one + ``` + """ + # Call parent forward but exclude cross_attention_states from model call + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + cross_attention_mask=cross_attention_mask, + full_text_row_masked_out_mask=full_text_row_masked_out_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs.last_hidden_state + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]).float() + + loss = None + if labels is not None: + loss = self.loss_function(logits, labels, self.vocab_size, **kwargs) + + return CausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +__all__ = ["BltPreTrainedModel", "BltModel", "BltPatcher", "BltForCausalLM"] diff --git a/src/transformers/models/blt/modular_blt.py b/src/transformers/models/blt/modular_blt.py new file mode 100644 index 000000000000..0b04966d97fe --- /dev/null +++ b/src/transformers/models/blt/modular_blt.py @@ -0,0 +1,1008 @@ +# coding=utf-8 +# Copyright 2025 HuggingFace Inc. team. All rights reserved. +# +# 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. +"""Blt modular model, inheriting from Mllama where appropriate.""" + +from typing import Callable, Optional, Union + +import torch +import torch.distributions +import torch.nn as nn +import torch.nn.functional as F + +from ...cache_utils import Cache, DynamicCache +from ...masking_utils import create_causal_mask +from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, logging +from ...utils.generic import OutputRecorder, check_model_inputs +from ..cohere2.modeling_cohere2 import ( + Cohere2RotaryEmbedding, + rotate_half, # noqa: F401 +) +from ..mllama.modeling_mllama import ( + MllamaForCausalLM, + MllamaPreTrainedModel, + MllamaSelfAttentionDecoderLayer, + MllamaTextCrossAttention, + MllamaTextMLP, + MllamaTextRMSNorm, + MllamaTextSelfAttention, + eager_attention_forward, +) +from .configuration_blt import ( + BltConfig, + BltGlobalTransformerConfig, + BltLocalDecoderConfig, + BltLocalEncoderConfig, + BltPatcherConfig, +) + + +logger = logging.get_logger(__name__) + + +def rolling_polynomial_hash(token_tensor, prime: int = 1000000007): + """ + A polynomial rolling hash algorithm that converts sequences + of tokens into hash values. The hash is computed as: + hash = (token_0 * prime^0 + token_1 * prime^1 + ... + token_n * prime^n) + + The rolling hash allows the model to efficiently + identify and encode recurring byte-level patterns in the input text. + + Args: + token_tensor (torch.Tensor): [batch_size, seq_len, group_size] containing token IDs to hash + prime (int): Prime number used as the base for the polynomial hash. + + Returns: + torch.Tensor: Hash values of shape [batch_size, seq_len] where each value + represents the hash of the corresponding token group + + Example: + >>> tokens = torch.tensor([[1, 2, 3], [4, 5, 6]]) + >>> hashes = rolling_polynomial_hash(tokens, prime=31) + >>> # hash[0] = 1*31^0 + 2*31^1 + 3*31^2 + >>> # hash[1] = 4*31^0 + 5*31^1 + 6*31^2 + """ + prime_tensor = torch.tensor(prime, dtype=torch.int64, device=token_tensor.device) + powers = torch.arange(token_tensor.shape[-1], device=token_tensor.device) + prime_powers = prime_tensor**powers + return torch.sum(token_tensor * prime_powers, dim=-1) + + +def byte_group_hash_function( + token_ids: torch.Tensor, group_size: int = 2, prime: int = 1000000007, max_hash: int = 30000 +): + """Hash token groups and map to range [0, max_hash].""" + with torch.no_grad(): + batch_size, seq_len = token_ids.shape + # Add padding for sliding window + padding = torch.zeros(batch_size, group_size - 1, dtype=torch.int64, device=token_ids.device) + padded_tokens = torch.cat([padding, token_ids], dim=1) + + # Create sliding windows and compute hashes + windows = padded_tokens.unfold(1, group_size, 1) + hashes = rolling_polynomial_hash(windows, prime) + hash_values = hashes % max_hash + + return hash_values + + +def compute_hash_embeddings( + local_encoder_tokens: torch.Tensor, + local_encoder, + encoder_hash_tok_embedding: nn.Embedding, + encoder_hash_byte_group_nb_functions: int, + encoder_hash_byte_group_size: list, + encoder_hash_byte_group_vocab: int, +) -> torch.Tensor: + """Compute token embeddings enhanced with hash-based embeddings.""" + # Available primes for hash functions + primes = [ + 1000000007, + 5915587277, + 1500450271, + 3267000013, + 5754853343, + 4093082899, + 9576890767, + 3628273133, + 2860486313, + 5463458053, + 3367900313, + ] + + embeddings = local_encoder.embed_tokens(local_encoder_tokens) + embedding_idx = 0 + for func_nb in range(encoder_hash_byte_group_nb_functions): + prime = primes[func_nb % len(primes)] # Cycle through primes if more functions than primes + for group_size in encoder_hash_byte_group_size: + hash_ids = byte_group_hash_function(local_encoder_tokens, group_size, prime, encoder_hash_byte_group_vocab) + # Apply offset to get the correct slice of the fused embedding + offset_hash_ids = hash_ids + embedding_idx * encoder_hash_byte_group_vocab + embeddings += encoder_hash_tok_embedding(offset_hash_ids) + embedding_idx += 1 + + return embeddings + + +def _prepare_patch_cross_attention_mask( + patch_ids: torch.Tensor, + num_patches: int, + sequence_length: int, + patches_as_queries: bool = False, + cross_attn_k: int = 1, + dtype: torch.dtype = torch.float32, +) -> tuple[torch.Tensor, torch.Tensor]: + """ + Prepare cross-attention mask for patch-based attention, following mllama's robust approach. + + This function creates masks that control which patches can attend to which other patches, + with support for query/key role swapping and cross-attention multipliers. + + Args: + patch_ids (torch.Tensor): Tensor of shape [batch_size, seq_len] containing patch ids. + num_patches (int): Total number of patches. + sequence_length (int): Length of the sequence. + patches_as_queries (bool): If True, patches are used as queries, otherwise as keys. + cross_attn_k (int): Cross-attention multiplier for repeating patches. + dtype (torch.dtype): Data type for the output mask. + + Returns: + Tuple[torch.Tensor, torch.Tensor]: + - cross_attention_mask: 4D tensor [batch_size, 1, q_len, kv_len] + """ + batch_size, seq_len = patch_ids.shape + device = patch_ids.device + + # Determine query and key lengths based on configuration + if patches_as_queries: + q_len = num_patches * cross_attn_k + kv_len = sequence_length + # Create patch-to-sequence mapping + q_patch_ids = ( + torch.arange(num_patches, device=device) + .unsqueeze(0) + .unsqueeze(-1) + .expand(batch_size, num_patches, seq_len) + ) + kv_patch_ids = patch_ids.unsqueeze(1).expand(batch_size, num_patches, seq_len) + else: + q_len = sequence_length + kv_len = num_patches * cross_attn_k + # Create sequence-to-patch mapping + q_patch_ids = patch_ids.unsqueeze(-1).expand(batch_size, seq_len, num_patches) + kv_patch_ids = ( + torch.arange(num_patches, device=device).unsqueeze(0).unsqueeze(0).expand(batch_size, seq_len, num_patches) + ) + + # Create base attention mask - boolean mask where True means "should attend" + # Exact patch matching + cross_attention_mask = q_patch_ids == kv_patch_ids + + # Handle cross_attn_k multiplier by repeating along appropriate dimension + repeat_dim = 1 if patches_as_queries else -1 + cross_attention_mask = cross_attention_mask.repeat_interleave(cross_attn_k, dim=repeat_dim) + + # Validate dimensions + expected_shape = (batch_size, q_len, kv_len) + if cross_attention_mask.shape != expected_shape: + raise ValueError( + f"Cross attention mask shape {cross_attention_mask.shape} doesn't match expected {expected_shape}" + ) + + # Reshape so it can be used by attn module - add head dimension + cross_attention_mask = cross_attention_mask.unsqueeze(1) # [batch_size, 1, q_len, kv_len] + + # Invert the mask (following mllama pattern exactly) + # True -> 0.0 (attend), False -> 1.0 (will become -inf) + inverted_cross_attn_mask = 1.0 - cross_attention_mask.to(dtype) + cross_attention_mask = inverted_cross_attn_mask.masked_fill( + inverted_cross_attn_mask.to(torch.bool), torch.finfo(dtype).min + ) + + return cross_attention_mask + + +def process_patch_lengths(patch_lengths: torch.Tensor, max_patch_length: Optional[int]) -> torch.Tensor: + """ + Splits patch lengths into smaller segments if they exceed `max_patch_length`. + Pads the result to uniform length across the batch. + + Args: + patch_lengths (torch.Tensor): [batch_size, num_patches] tensor of patch lengths. + max_patch_length (int, optional): Maximum allowed length per patch. + + Returns: + torch.Tensor: [batch_size, max_len] tensor of split and padded patch lengths. + """ + if max_patch_length is None: + return patch_lengths + + batch_size = patch_lengths.size(0) + processed = [] + + for seq in patch_lengths: + splits = [] + for length in seq[seq > 0]: + length = length.item() + full_chunks, remainder = divmod(length, max_patch_length) + splits.extend([max_patch_length] * full_chunks) + if remainder: + splits.append(remainder) + processed.append(splits) + + # Find max length to pad to + max_len = max(len(splits) for splits in processed) + padded = torch.zeros((batch_size, max_len), dtype=patch_lengths.dtype, device=patch_lengths.device) + + for i, splits in enumerate(processed): + if splits: + padded[i, : len(splits)] = torch.tensor(splits, dtype=patch_lengths.dtype, device=patch_lengths.device) + + # Trim zero columns + if (padded != 0).any(dim=0).sum() < padded.shape[1]: + last_nonzero = (padded != 0).any(dim=0).nonzero().max().item() + 1 + padded = padded[:, :last_nonzero] + + return padded + + +class BltMLP(MllamaTextMLP): + pass + + +class BltRMSNorm(MllamaTextRMSNorm): + pass + + +class BltRotaryEmbedding(Cohere2RotaryEmbedding): + pass + + +class BltTransformerLayer(MllamaSelfAttentionDecoderLayer): + def __init__(self, config, layer_idx: int): + super().__init__() + + self.self_attn = BltSelfAttention(config=config, layer_idx=layer_idx) + self.mlp = BltMLP(config) + self.input_layernorm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + +class BltSelfAttention(MllamaTextSelfAttention): + def __init__(self, config: BltConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.is_causal = True + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + position_embeddings: torch.Tensor, + use_cache: bool = False, + past_key_values=None, + cache_position=None, + **kwargs, + ): + return super().forward( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_embeddings=position_embeddings, + use_cache=use_cache, + past_key_values=past_key_values, + cache_position=cache_position, + **kwargs, + ) + + +class BltCrossAttention(MllamaTextCrossAttention): + """Cross-attention module for Blt, following transformers style""" + + def __init__(self, config: BltConfig, layer_idx: int, hidden_size: Optional[int] = None): + super().__init__() + self.is_causal = False + self.q_norm = BltRMSNorm(self.hidden_size, eps=config.rms_norm_eps) + self.k_norm = BltRMSNorm(self.hidden_size, eps=config.rms_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + cross_attention_states: Optional[torch.Tensor] = None, + past_key_values: Optional[Cache] = None, + attention_mask: Optional[torch.Tensor] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ): + bsz, q_len, _ = hidden_states.size() + query_states = self.q_norm(hidden_states) + query_states = self.q_proj(query_states) + query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2) + + if cross_attention_states is not None: + cross_attention_states = self.k_norm(cross_attention_states) + key_states = self.k_proj(cross_attention_states) + value_states = self.v_proj(cross_attention_states) + key_states = key_states.view(bsz, -1, self.num_key_value_heads, self.head_dim).transpose(1, 2) + value_states = value_states.view(bsz, -1, self.num_key_value_heads, self.head_dim).transpose(1, 2) + if past_key_values is not None: + key_states, value_states = past_key_values.update( + key_states, value_states, self.layer_idx, {"cache_position": cache_position} + ) + elif cache_position[0] != 0: + key_states, value_states = ( + past_key_values.layers[self.layer_idx].keys, + past_key_values.layers[self.layer_idx].values, + ) + else: + raise ValueError( + "Cross attention layer can't find neither `cross_attn_states` nor cached values for key/values!" + ) + attention_interface: Callable = eager_attention_forward + + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.dropout, + scaling=self.scaling, + **kwargs, + ) + attn_output = attn_output.reshape(bsz, q_len, -1).contiguous() + attn_output = self.o_proj(attn_output) + attn_output = attn_output + hidden_states + return attn_output, attn_weights + + +@auto_docstring +class BltPreTrainedModel(MllamaPreTrainedModel): + config: BltConfig + _supports_attention_backend = False + _no_split_modules = ["BltTransformerLayer"] + _can_record_outputs = { + "hidden_states": OutputRecorder(BltTransformerLayer, index=0, layer_name="local_decoder"), + "attentions": OutputRecorder(BltSelfAttention, index=1, layer_name="local_decoder"), + } + + def _init_weights(self, module): + raise AttributeError("No need to inherit it!") + + def _update_causal_mask(self, module): + raise AttributeError("No need to inherit it!") + + def _prepare_4d_causal_attention_mask_with_cache_position(self, module): + raise AttributeError("No need to inherit it!") + + +class BltLocalEncoder(BltPreTrainedModel): + config: BltLocalEncoderConfig + _can_record_outputs = { + "encoder_attentions": OutputRecorder(BltSelfAttention, index=1, layer_name="local_encoder"), + } + + def __init__(self, config: BltLocalEncoderConfig): + super().__init__(config) + self.gradient_checkpointing = False + self.config = config + self.layers = nn.ModuleList( + [BltTransformerLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = BltRotaryEmbedding(config=config) + self.patch_embedding_projection = nn.Linear( + in_features=config.hidden_size, + out_features=config.hidden_size * config.cross_attn_k, + bias=False, + ) + self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size) + self.cross_attn_layers = nn.ModuleList() + layers_to_add = config.num_hidden_layers if config.cross_attn_all_layers else 1 + for layer_idx in range(layers_to_add): + self.cross_attn_layers.append( + BltCrossAttention(config=config, layer_idx=layer_idx, hidden_size=config.hidden_size) + ) + + self.post_init() + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + patch_embeds: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + num_patches: Optional[int] = None, + patch_ids: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ): + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + batch_size = inputs_embeds.shape[0] + hidden_states = F.dropout(inputs_embeds, p=self.config.dropout, training=self.training) + + if position_ids is None: + position_ids = ( + torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device).unsqueeze(0).expand(batch_size, -1) + ) + + position_embeddings = self.rotary_emb(hidden_states, position_ids) + hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training) + + for idx, layer in enumerate(self.layers): + hidden_states = layer( + hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + past_key_values=past_key_values, + cache_position=cache_position, + **kwargs, + ) + if idx == len(self.layers) - 1 or self.config.cross_attn_all_layers: + patch_embeds = self.patch_reduce(hidden_states, num_patches, patch_ids) + patch_embeds = self.patch_embedding_projection(patch_embeds) + patch_embeds = patch_embeds.reshape( + batch_size, patch_embeds.shape[1] * self.config.cross_attn_k, self.config.hidden_size + ) + layer_idx = idx if self.config.cross_attn_all_layers else 0 + cross_attention_output, _ = self.cross_attn_layers[layer_idx]( + hidden_states=patch_embeds, + cross_attention_states=hidden_states, + attention_mask=encoder_attention_mask, + **kwargs, + ) + patch_embeds = patch_embeds + cross_attention_output + encoder_cross_states = patch_embeds + return hidden_states, encoder_cross_states + + def patch_reduce(self, hidden_states, max_num_patches, patch_ids): + """ + Reduce variable length patches to single embedding per patch + Note: this works with variable number of patches for different sequences in the batch + It handles variable length patches by assuming that patch_lengths will be 0 for any + extra patches on the *right*. Since there can be a variable number of patches + this function also return the number of patches for each sequence in the batch. + Any embeddings on the right that are not allocated to a patch + (i.e. if the sum(patch_lengths[i]) < seq_len for any i) + will be sent to a dummy patch, which is trimmed before returning. + """ + batch_size = hidden_states.shape[0] + embedding_dim = hidden_states.shape[-1] + + patch_ids = patch_ids.unsqueeze(-1).expand(-1, -1, hidden_states.shape[-1]) + + reduced_embeddings = torch.zeros( + (batch_size, max_num_patches, embedding_dim), dtype=hidden_states.dtype, device=hidden_states.device + ) + + reduced_embeddings = reduced_embeddings.scatter_reduce( + src=hidden_states, + dim=1, + index=patch_ids, + reduce="amax", + include_self=False, + ) + reduced_embeddings = reduced_embeddings[:, :max_num_patches, :] + + return reduced_embeddings + + +class BltLocalDecoder(BltPreTrainedModel): + config: BltLocalDecoderConfig + + def __init__(self, config: BltLocalDecoderConfig): + super().__init__(config) + self.gradient_checkpointing = False + self.config = config + self.cross_attn_decoder = True + self.layers = nn.ModuleList( + [BltTransformerLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = BltRotaryEmbedding(config=config) + self.patch_embedding_projection = nn.Linear( + in_features=config.hidden_size_global, + out_features=config.hidden_size * config.cross_attn_k, + bias=False, + ) + self.norm = BltRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.cross_attn_layers = nn.ModuleList() + layers_to_add = config.num_hidden_layers if config.cross_attn_all_layers else 1 + for layer_idx in range(layers_to_add): + self.cross_attn_layers.append( + BltCrossAttention(config=config, layer_idx=layer_idx, hidden_size=config.hidden_size) + ) + + self.post_init() + + @check_model_inputs + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + patch_embeds: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + **kwargs: Unpack[TransformersKwargs], + ): + batch_size = inputs_embeds.shape[0] + hidden_states = inputs_embeds + patch_embeds = self.patch_embedding_projection(patch_embeds) + patch_embeds = patch_embeds.reshape( + batch_size, patch_embeds.shape[1] * self.config.cross_attn_k, self.config.hidden_size + ) + + if patch_embeds is not None and not self.cross_attn_decoder: + hidden_states = hidden_states + patch_embeds + + if position_ids is None: + position_ids = ( + torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device).unsqueeze(0).expand(batch_size, -1) + ) + + position_embeddings = self.rotary_emb(hidden_states, position_ids) + hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training) + + for i, layer in enumerate(self.layers): + if i == 0 or self.config.cross_attn_all_layers: + cross_attention_output, _ = self.cross_attn_layers[i]( + hidden_states=hidden_states, + cross_attention_states=patch_embeds, + attention_mask=encoder_attention_mask, + **kwargs, + ) + hidden_states = hidden_states + cross_attention_output + hidden_states = layer( + hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + past_key_values=past_key_values, + cache_position=cache_position, + **kwargs, + ) + logits = self.norm(hidden_states) + return logits + + +class BltGlobalTransformer(BltPreTrainedModel): + config: BltGlobalTransformerConfig + _can_record_outputs = { + "global_attentions": OutputRecorder(BltSelfAttention, index=1, layer_name="global_transformer"), + } + + def __init__(self, config: BltGlobalTransformerConfig): + super().__init__(config) + self.config = config + self.layers = nn.ModuleList() + for layer_idx in range(config.num_hidden_layers): + self.layers.append(BltTransformerLayer(config, layer_idx)) + self.rotary_emb = BltRotaryEmbedding(config=config) + + # Create token embedding projection (use nn.Identity() when no projection needed) + if getattr(config, "encoder_cross_output_size", None) is not None: + self.token_embedding_projection = nn.Linear( + config.encoder_cross_output_size, config.hidden_size, bias=False + ) + else: + self.token_embedding_projection = nn.Identity() + + self.post_init() + + def forward( + self, + input_embeds: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ): + batch_size, seq_len, _ = input_embeds.shape + hidden_states = self.token_embedding_projection(input_embeds) + hidden_states = F.dropout(hidden_states, p=self.config.dropout, training=self.training) + if position_ids is None: + position_ids = ( + torch.arange(input_embeds.shape[1], device=input_embeds.device).unsqueeze(0).expand(batch_size, -1) + ) + position_embeddings = self.rotary_emb(hidden_states, position_ids) + for i, layer in enumerate(self.layers): + hidden_states = layer( + hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + past_key_values=past_key_values, + cache_position=cache_position, + **kwargs, + ) + return hidden_states + + +class BltPatcher(BltPreTrainedModel): + config: BltPatcherConfig + + def __init__(self, config: BltPatcherConfig): + super().__init__(config) + self.rotary_emb = BltRotaryEmbedding(config=self.config) + self.layers = nn.ModuleList() + for layer_idx in range(self.config.num_hidden_layers): + self.layers.append(BltTransformerLayer(self.config, layer_idx)) + self.embed_tokens = nn.Embedding(self.config.vocab_size, self.config.hidden_size) + self.norm = BltRMSNorm(self.config.hidden_size, eps=self.config.rms_norm_eps) + self.lm_head = nn.Linear( + self.config.hidden_size, + self.config.vocab_size, + bias=False, + ) + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + patch_size: Optional[int] = None, + threshold: Optional[float] = None, + max_patch_length: Optional[int] = None, + **kwargs: Unpack[TransformersKwargs], + ): + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if use_cache and past_key_values is None: + past_key_values = DynamicCache() + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + causal_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + hidden_states = inputs_embeds + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for layer in self.layers: + hidden_states = layer(hidden_states, position_embeddings=position_embeddings, attention_mask=causal_mask) + + logits = self.lm_head(self.norm(hidden_states)) + prediction_entropies = torch.distributions.Categorical(logits=logits).entropy() + + batch_size, sequence_length = inputs_embeds.shape[:2] + if patch_size is not None: + patch_lengths = self.patch_lengths_from_entropies( + entropies=prediction_entropies, + sequence_length=sequence_length, + patch_size=patch_size, + threshold=threshold, + ) + else: + patch_lengths = torch.ones( + (batch_size, sequence_length), dtype=inputs_embeds.dtype, device=inputs_embeds.device + ) + patch_lengths = process_patch_lengths(patch_lengths, max_patch_length) + return prediction_entropies, patch_lengths, logits + + @staticmethod + def patch_lengths_from_entropies( + entropies, + sequence_length, + patch_size=None, + threshold=None, + ): + """ + Computes patch lengths from token entropies. + + Depending on whether a threshold is provided, the function uses either: + - Thresholding the entropy values (when `threshold` is set). + """ + + batch_size = entropies.shape[0] + + # Always include token 0 and 1 as starting tokens + init_tokens = ( + torch.tensor([0, 1], dtype=torch.long, device=entropies.device).unsqueeze(0).repeat(batch_size, 1) + ) + offset = init_tokens.shape[1] + + # Ignore first token entropy (BOS) + entropies = entropies[:, 1:] + + # Threshold the entropy values to define patch start points + patch_mask = entropies > threshold + + seq_len = patch_mask.shape[1] + + # Create patch IDs (token indices), and add a sentinel to ensure alignment + token_indices = torch.arange(seq_len, device=entropies.device).unsqueeze(0).expand(batch_size, -1) + sentinel = torch.full_like(token_indices, seq_len) + padded_indices = torch.cat([token_indices, sentinel], dim=1) + + # Pad mask with inverse to align sentinel correctly + padded_mask = torch.cat([patch_mask, ~patch_mask], dim=1) + + # Select indices where mask is True + patch_starts = padded_indices[padded_mask].reshape(batch_size, seq_len) + max_valid_patches = patch_mask.sum(dim=1).max() + patch_starts = patch_starts[:, :max_valid_patches] + + # Offset patch starts to account for the two initial tokens + patch_start_ids = torch.cat((init_tokens, patch_starts + offset), dim=1) + + # Compute patch end positions by shifting start positions + last_token = torch.full_like(patch_start_ids[:, :1], sequence_length - 1) + patch_ends = torch.cat((patch_start_ids[:, 1:] - 1, last_token), dim=1) + + patch_lengths = patch_ends - patch_start_ids + 1 + + return patch_lengths + + +class BltModel(BltPreTrainedModel): + def __init__(self, config: BltConfig): + super().__init__(config) + self.gradient_checkpointing = False + + self.config = config + self.local_encoder = BltLocalEncoder(config.encoder_config) + self.global_transformer = BltGlobalTransformer(config.global_config) + self.local_decoder = BltLocalDecoder(config.decoder_config) + num_embeddings = config.encoder_hash_byte_group_nb_functions * len(config.encoder_hash_byte_group_size) + total_vocab_size = config.encoder_hash_byte_group_vocab * num_embeddings + self.encoder_hash_tok_embedding = nn.Embedding(total_vocab_size, config.encoder_config.hidden_size) + if self.config.patch_in_forward: + self.patcher = BltPatcher(config.patcher_config) + self.patcher.eval() + for param in self.patcher.parameters(): + param.requires_grad = False + else: + self.patcher = None + self.post_init() + + @check_model_inputs + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + patch_lengths: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> BaseModelOutputWithPast: + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + # Extract input embeddings as early as possible + if inputs_embeds is not None: + encoder_embeds = inputs_embeds + batch_size, sequence_length, _ = inputs_embeds.shape + else: + batch_size, sequence_length = input_ids.shape + encoder_embeds = compute_hash_embeddings( + input_ids, + self.local_encoder, + self.encoder_hash_tok_embedding, + self.config.encoder_hash_byte_group_nb_functions, + self.config.encoder_hash_byte_group_size, + self.config.encoder_hash_byte_group_vocab, + ) + + if patch_lengths is None: + if self.config.patching_mode == "entropy" and self.patcher is not None: + if input_ids is None: + raise ValueError("input_ids is required for entropy-based patching") + _, patch_lengths, _ = self.patcher( + input_ids, + patch_size=self.config.patch_size, + threshold=self.config.patching_threshold, + max_patch_length=self.config.max_patch_length, + patching_batch_size=self.config.patching_batch_size, + device=input_ids.device, + ) + else: + device = input_ids.device if input_ids is not None else inputs_embeds.device + dtype = input_ids.dtype if input_ids is not None else inputs_embeds.dtype + patch_lengths = process_patch_lengths( + torch.ones((batch_size, sequence_length + 1), dtype=dtype, device=device), + self.config.max_patch_length, + ) + patch_ids = self._patch_ids_from_lengths(patch_lengths, sequence_length) + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + encoder_embeds.shape[1], device=encoder_embeds.device + ) + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + causal_mask = create_causal_mask( + config=self.config, + input_embeds=encoder_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + cross_attn_mask_enc = _prepare_patch_cross_attention_mask( + patch_ids, patch_lengths.shape[1], sequence_length, True, self.config.cross_attn_k, encoder_embeds.dtype + ) + encoder_hidden_states, encoder_cross_states = self.local_encoder( + input_ids=input_ids, + inputs_embeds=encoder_embeds, + attention_mask=causal_mask, + position_ids=position_ids, + encoder_attention_mask=cross_attn_mask_enc, + num_patches=patch_lengths.shape[1], + patch_ids=patch_ids, + **kwargs, + ) + encoder_cross_states = encoder_cross_states.view(batch_size, patch_lengths.shape[1], -1) + global_cache_position = torch.arange(0, encoder_cross_states.shape[1], device=encoder_cross_states.device) + global_position_ids = global_cache_position.unsqueeze(0) + global_causal_mask = create_causal_mask( + config=self.config, + input_embeds=encoder_cross_states, + attention_mask=None, + cache_position=global_cache_position, + past_key_values=None, + position_ids=None, + ) + + global_hidden_states = self.global_transformer( + input_embeds=encoder_cross_states, + attention_mask=global_causal_mask, + position_ids=global_position_ids, + **kwargs, + ) + decoder_patch_ids = self._patch_ids_from_lengths(patch_lengths[:, 1:], sequence_length) + cross_attn_mask_dec = _prepare_patch_cross_attention_mask( + decoder_patch_ids, + patch_lengths.shape[1], + sequence_length, + False, + self.config.cross_attn_k, + encoder_embeds.dtype, + ) + output = self.local_decoder( + input_ids=input_ids, + inputs_embeds=encoder_hidden_states, + patch_embeds=global_hidden_states, + attention_mask=causal_mask, + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + encoder_attention_mask=cross_attn_mask_dec, + **kwargs, + ) + return BaseModelOutputWithPast( + last_hidden_state=output, + past_key_values=past_key_values, + ) + + def get_input_embeddings(self): + return self.local_encoder.embed_tokens + + def set_input_embeddings(self, value): + self.local_encoder.embed_tokens = value + + def _patch_ids_from_lengths(self, patch_lengths: torch.Tensor, seq_len: int) -> torch.Tensor: + batch_size = patch_lengths.shape[0] + patch_starts = torch.cat( + [ + torch.zeros(batch_size, 1, dtype=patch_lengths.dtype, device=patch_lengths.device), + patch_lengths.cumsum(dim=-1)[:, :-1], + ], + dim=-1, + ) + token_positions = torch.arange(seq_len, device=patch_lengths.device) + return (patch_starts.unsqueeze(1) <= token_positions.unsqueeze(0).unsqueeze(-1)).sum(dim=-1) - 1 + + +class BltForCausalLM(MllamaForCausalLM): + config: BltConfig + _can_compile_fullgraph = False + base_model_prefix = "model" + _tied_weights_keys = ["lm_head.weight"] + + def __init__(self, config: BltConfig): + super().__init__(config) + self.vocab_size = config.vocab_size + self.model = BltModel(config) + self.lm_head = nn.Linear(config.decoder_config.hidden_size, config.vocab_size, bias=False) + self.post_init() + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + cross_attention_states: Optional[torch.LongTensor] = None, # Keep for compatibility + cross_attention_mask: Optional[torch.LongTensor] = None, + full_text_row_masked_out_mask: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + past_key_values: Optional[Union[Cache, list[torch.FloatTensor]]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs: Unpack[TransformersKwargs], + ) -> Union[tuple, CausalLMOutputWithPast]: + # Call parent forward but exclude cross_attention_states from model call + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + cross_attention_mask=cross_attention_mask, + full_text_row_masked_out_mask=full_text_row_masked_out_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs.last_hidden_state + slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep + logits = self.lm_head(hidden_states[:, slice_indices, :]).float() + + loss = None + if labels is not None: + loss = self.loss_function(logits, labels, self.vocab_size, **kwargs) + + return CausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +__all__ = [ + "BltPreTrainedModel", + "BltModel", + "BltPatcher", + "BltForCausalLM", +] diff --git a/tests/causal_lm_tester.py b/tests/causal_lm_tester.py index 8600f1dc265e..4757d4b69c6c 100644 --- a/tests/causal_lm_tester.py +++ b/tests/causal_lm_tester.py @@ -497,7 +497,7 @@ def _config_supports_rope_scaling(config: PretrainedConfig) -> bool: # Has rope_theta (and no rope_scaling) -> probably an older model, but should support rope scaling as well main_config_has_rope = hasattr(config, "rope_scaling") or hasattr(config, "rope_theta") sub_config_has_rope = any( - hasattr(config[sub_config], "rope_scaling") or hasattr(config[sub_config], "rope_theta") + hasattr(getattr(config, sub_config), "rope_scaling") or hasattr(getattr(config, sub_config), "rope_theta") for sub_config in config.sub_configs.keys() ) return main_config_has_rope or sub_config_has_rope diff --git a/tests/models/blt/__init__.py b/tests/models/blt/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/models/blt/test_modeling_blt.py b/tests/models/blt/test_modeling_blt.py new file mode 100644 index 000000000000..dc4703974781 --- /dev/null +++ b/tests/models/blt/test_modeling_blt.py @@ -0,0 +1,561 @@ +# Copyright 2025 The HuggingFace Inc. team. All rights reserved. +# +# 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 Blt model.""" + +import unittest + +import pytest +from parameterized import parameterized + +from transformers import AutoTokenizer, is_torch_available, set_seed +from transformers.testing_utils import ( + cleanup, + require_read_token, + require_torch, + require_torch_accelerator, + require_torch_bf16, + slow, + torch_device, +) + +from ...causal_lm_tester import CausalLMModelTest, CausalLMModelTester +from ...test_modeling_common import ( + TEST_EAGER_MATCHES_SDPA_INFERENCE_PARAMETERIZATION, + _test_eager_matches_sdpa_inference, + ids_tensor, +) + + +if is_torch_available(): + import torch + + from transformers import BltConfig, BltForCausalLM, BltModel +from transformers.models.blt.modeling_blt import BltRotaryEmbedding + + +class BltModelTester(CausalLMModelTester): + if is_torch_available(): + config_class = BltConfig + base_model_class = BltModel + causal_lm_class = BltForCausalLM + + def __init__( + self, + parent, + ignore_index=-100, + seq_length=7, + is_training=True, + ): + super().__init__(parent) + self.parent = parent + self.ignore_index = ignore_index + self.seq_length = seq_length + self.is_training = is_training + self.batch_size = 3 + + # Common parameters for all configs + self.hidden_size = 16 + self.num_hidden_layers = 1 + self.num_attention_heads = 2 + self.num_key_value_heads = 2 + self.intermediate_size = 32 + self.hidden_act = "silu" + self.max_position_embeddings = 32 + self.vocab_size = 32 + self.rope_theta = 500000.0 + self.rope_scaling = {"rope_type": "default"} + self.rms_norm_eps = 1e-5 + self.dropout = 0.0 + self.encoder_hash_byte_group_size = [2, 3] + self.encoder_hash_byte_group_vocab = 64 + self.encoder_hash_byte_group_nb_functions = 1 + # Common parameters for all configs + self.patcher_config = { + "hidden_size": self.hidden_size, + "num_hidden_layers": self.num_hidden_layers, + "num_attention_heads": self.num_attention_heads, + "num_key_value_heads": self.num_key_value_heads, + "intermediate_size": self.intermediate_size, + "max_position_embeddings": self.max_position_embeddings, + "rope_theta": self.rope_theta, + "rope_scaling": self.rope_scaling, + "hidden_act": self.hidden_act, + "rms_norm_eps": self.rms_norm_eps, + "dropout": self.dropout, + } + + self.encoder_config = { + "hidden_size": self.hidden_size, + "num_hidden_layers": self.num_hidden_layers, + "num_attention_heads": self.num_attention_heads, + "num_key_value_heads": self.num_key_value_heads, + "intermediate_size": self.intermediate_size, + "max_position_embeddings": self.max_position_embeddings, + "rope_theta": self.rope_theta, + "rope_scaling": self.rope_scaling, + "hidden_act": self.hidden_act, + "rms_norm_eps": self.rms_norm_eps, + "dropout": self.dropout, + } + + self.decoder_config = { + "vocab_size": self.vocab_size, + "hidden_size": self.hidden_size, + "hidden_size_global": self.hidden_size * 2, # Must match global transformer output size + "num_hidden_layers": self.num_hidden_layers, + "num_attention_heads": self.num_attention_heads, + "num_key_value_heads": self.num_key_value_heads, + "intermediate_size": self.intermediate_size, + "max_position_embeddings": self.max_position_embeddings, + "rope_theta": self.rope_theta, + "rope_scaling": self.rope_scaling, + "hidden_act": self.hidden_act, + "rms_norm_eps": self.rms_norm_eps, + "dropout": self.dropout, + } + + self.global_config = { + "hidden_size": self.hidden_size * 2, # Double the hidden size for global transformer + "num_hidden_layers": self.num_hidden_layers, + "num_attention_heads": self.num_attention_heads, + "num_key_value_heads": self.num_key_value_heads, + "intermediate_size": self.intermediate_size, + "max_position_embeddings": self.max_position_embeddings, + "rope_theta": self.rope_theta, + "rope_scaling": self.rope_scaling, + "hidden_act": self.hidden_act, + "rms_norm_eps": self.rms_norm_eps, + "dropout": self.dropout, + } + + self.num_hidden_layers = self.encoder_config["num_hidden_layers"] + + def get_config(self): + config = BltConfig( + vocab_size=self.vocab_size, + max_position_embeddings=self.max_position_embeddings, + patch_in_forward=False, # Disable patching for tests + patch_size=4, + patching_mode="entropy", + patching_threshold=1.335442066192627, + patching_batch_size=1, + max_patch_length=None, + cross_attn_k=2, + encoder_hash_byte_group_size=self.encoder_hash_byte_group_size, + encoder_hash_byte_group_vocab=self.encoder_hash_byte_group_vocab, + encoder_hash_byte_group_nb_functions=self.encoder_hash_byte_group_nb_functions, + patcher_config=self.patcher_config, + encoder_config=self.encoder_config, + decoder_config=self.decoder_config, + global_config=self.global_config, + rope_scaling=self.rope_scaling, + tie_word_embeddings=False, + ) + + config.num_attention_heads = config.decoder_config.num_attention_heads + config.num_hidden_layers = config.encoder_config.num_hidden_layers + config.hidden_size = config.decoder_config.hidden_size + + return config + + +@require_torch +class BltModelTest(CausalLMModelTest, unittest.TestCase): + all_model_classes = ( + ( + BltModel, + BltForCausalLM, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": BltModel, + "text-generation": BltForCausalLM, + } + if is_torch_available() + else {} + ) + test_headmasking = False + test_pruning = False + fx_compatible = False + model_tester_class = BltModelTester + rotary_embedding_layer = BltRotaryEmbedding # Enables RoPE tests if set + + # Need to use `0.8` instead of `0.9` for `test_cpu_offload` + # This is because we are hitting edge cases with the causal_mask buffer + model_split_percents = [0.5, 0.7, 0.8] + + # used in `test_torch_compile_for_training` + _torch_compile_train_cls = BltForCausalLM if is_torch_available() else None + + @pytest.mark.generate + @parameterized.expand([("greedy", 1), ("beam search", 2)]) + @unittest.skip( + "Blt requires real token IDs for its hash-based embedding computation, making inputs_embeds generation incompatible with identical outputs" + ) + def test_generate_from_inputs_embeds(self, _, num_beams): + pass + + @pytest.mark.generate + @unittest.skip( + "Blt requires real token IDs for its hash-based embedding computation, making inputs_embeds generation incompatible with identical outputs" + ) + def test_inputs_embeds_matches_input_ids(self): + pass + + @parameterized.expand(TEST_EAGER_MATCHES_SDPA_INFERENCE_PARAMETERIZATION) + def test_eager_matches_sdpa_inference( + self, + name, + torch_dtype, + padding_side, + use_attention_mask, + output_attentions, + enable_kernels, + ): + "We need to relax a bit the `atols` for fp32 here due to the altup projections" + atols = { + ("cpu", False, torch.float32): 2e-2, # this was relaxed + ("cpu", False, torch.float16): 5e-3, + ("cpu", False, torch.bfloat16): 1e-2, + ("cpu", True, torch.float32): 2e-2, # this was relaxed + ("cpu", True, torch.float16): 5e-3, + ("cpu", True, torch.bfloat16): 1e-2, + ("cuda", False, torch.float32): 2e-2, # this was relaxed + ("cuda", False, torch.bfloat16): 1e-2, + ("cuda", False, torch.float16): 5e-3, + ("cuda", True, torch.float32): 2e-2, # this was relaxed + ("cuda", True, torch.bfloat16): 1e-2, + ("cuda", True, torch.float16): 5e-3, + } + _test_eager_matches_sdpa_inference( + self, name, torch_dtype, padding_side, use_attention_mask, output_attentions, enable_kernels, atols=atols + ) + + @parameterized.expand([("linear",), ("dynamic",), ("yarn",)]) + def test_model_rope_scaling_from_config(self, scaling_type): + """Override rope scaling from config test to handle Blt's sub-config structure.""" + if self.rotary_embedding_layer is None: + self.skipTest("Rotary embedding layer not set") + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + short_input = ids_tensor([1, 10], config.vocab_size) + long_input = ids_tensor([1, int(config.max_position_embeddings * 1.5)], config.vocab_size) + + set_seed(42) # Fixed seed at init time so the two models get the same random weights + original_model = self.model_tester_class.base_model_class(config) + original_model.to(torch_device) + original_model.eval() + original_short_output = original_model(short_input).last_hidden_state + original_long_output = original_model(long_input).last_hidden_state + + set_seed(42) # Fixed seed at init time so the two models get the same random weights + config.rope_scaling = {"rope_type": scaling_type, "factor": 10.0} + # Propagate rope_scaling to sub-configs for Blt + config.encoder_config.rope_scaling = config.rope_scaling + config.decoder_config.rope_scaling = config.rope_scaling + config.global_config.rope_scaling = config.rope_scaling + config.patcher_config.rope_scaling = config.rope_scaling + + scaled_model = self.model_tester_class.base_model_class(config) + scaled_model.to(torch_device) + scaled_model.eval() + scaled_short_output = scaled_model(short_input).last_hidden_state + scaled_long_output = scaled_model(long_input).last_hidden_state + + # Dynamic scaling does not change the RoPE embeddings until it receives an input longer than the original + # maximum sequence length, so the outputs for the short input should match. + if scaling_type == "dynamic": + torch.testing.assert_close(original_short_output, scaled_short_output, rtol=1e-5, atol=1e-5) + else: + self.assertFalse(torch.allclose(original_short_output, scaled_short_output, atol=1e-5)) + + self.assertFalse(torch.allclose(original_long_output, scaled_long_output, atol=1e-5)) + + @unittest.skip(reason="Decoder cannot keep gradients") + def test_flex_attention_with_grads(): + pass + + +@require_torch_accelerator +class BltIntegrationTest(unittest.TestCase): + def tearDown(self): + # TODO (joao): automatic compilation, i.e. compilation when `cache_implementation="static"` is used, leaves + # some memory allocated in the cache, which means some object is not being released properly. This causes some + # unoptimal memory usage, e.g. after certain tests a 7B model in FP16 no longer fits in a 24GB GPU. + # Investigate the root cause. + cleanup(torch_device, gc_collect=False) + + @slow + @require_read_token + def test_model(self): + NUM_TOKENS_TO_GENERATE = 200 + EXPECTED_TEXT = "my name is alex and i am a student at the university of michigan. i am a senior majoring in computer science and minoring in mathematics. i am also a member of the michigan math club and the michigan computer s" + + prompt = "my name is" + + model = BltForCausalLM.from_pretrained("itazap/blt-1b-hf", device_map="auto", attn_implementation="sdpa") + + tokenizer = AutoTokenizer.from_pretrained("itazap/blt-1b-hf") + + inputs = tokenizer(prompt, return_tensors="pt").to(model.device) + + generated_ids = model.generate( + **inputs, max_new_tokens=NUM_TOKENS_TO_GENERATE, do_sample=False, use_cache=False + ) + + output_text = tokenizer.decode(generated_ids[0], skip_special_tokens=True) + self.assertEqual(output_text, EXPECTED_TEXT) + + @slow + @require_read_token + def test_model_logits(self): + EXPECTED_OUTPUT = torch.tensor( + [ + [ + -10.4948, + -10.7065, + -6.1813, + -10.5545, + -10.3428, + -9.1493, + -8.4937, + -8.6382, + -9.2159, + -9.5907, + -9.3679, + -8.4184, + -9.0655, + -3.4436, + 2.9616, + -10.3157, + -6.3723, + -6.0133, + -9.7100, + -9.2128, + -8.8064, + -9.8179, + -9.7516, + -9.4681, + -9.7715, + -9.4897, + -9.0491, + -9.8098, + -9.4648, + -9.3294, + ], + [ + -13.3010, + -13.1910, + -5.7230, + -13.2895, + -13.4864, + -8.7140, + -7.0275, + -7.0182, + -10.1362, + -10.3762, + -9.9086, + -7.8049, + -8.8660, + -5.2711, + -3.5778, + -12.5346, + -9.1609, + -6.7925, + -10.3717, + -9.2650, + -10.6393, + -11.4807, + -11.2128, + -10.9615, + -10.5806, + -10.8873, + -11.0651, + -11.3471, + -10.5437, + -9.9688, + ], + ] + ).to(torch_device) + + input_ids = [1, 42, 21, 12, 43, 23, 1, 4] + + model = BltForCausalLM.from_pretrained("itazap/blt-1b-hf", attn_implementation="sdpa", device_map="auto") + + with torch.no_grad(): + output = model(torch.tensor([input_ids]).to(torch_device))[0] + + torch.testing.assert_close(EXPECTED_OUTPUT, output[0, :2, :30], rtol=1e-4, atol=1e-4) + + @slow + @require_read_token + @require_torch_bf16 + def test_model_bf16(self): + """Test Blt model with bfloat16 precision.""" + NUM_TOKENS_TO_GENERATE = 200 + EXPECTED_TEXT = "my name is alex and i am a student at the university of michigan. i am a senior majoring in computer science and minoring in mathematics. i am also a member of the michigan math club and the michigan computer s" + + prompt = "my name is" + + model = BltForCausalLM.from_pretrained( + "itazap/blt-1b-hf", device_map="auto", attn_implementation="sdpa", torch_dtype=torch.bfloat16 + ) + + tokenizer = AutoTokenizer.from_pretrained("itazap/blt-1b-hf") + + inputs = tokenizer(prompt, return_tensors="pt").to(model.device) + + generated_ids = model.generate( + **inputs, max_new_tokens=NUM_TOKENS_TO_GENERATE, do_sample=False, use_cache=False + ) + + output_text = tokenizer.decode(generated_ids[0], skip_special_tokens=True) + self.assertEqual(output_text, EXPECTED_TEXT) + + @slow + @require_read_token + @require_torch_bf16 + def test_model_logits_bf16(self): + """Test Blt model logits with bfloat16 precision.""" + + EXPECTED_OUTPUT = torch.tensor( + [ + [ + -10.5000, + -10.6875, + -6.1875, + -10.5625, + -10.3125, + -9.1875, + -8.5000, + -8.6875, + -9.1875, + -9.5625, + -9.3750, + -8.5000, + -9.0625, + -3.4219, + 2.9531, + -10.3125, + -6.4062, + -6.0000, + -9.6875, + -9.1875, + -8.8125, + -9.8125, + -9.7500, + -9.4375, + -9.8125, + -9.5000, + -9.0000, + -9.8125, + -9.4375, + -9.3125, + ], + [ + -13.2500, + -13.1875, + -5.6875, + -13.3125, + -13.5000, + -8.7500, + -7.0625, + -7.0312, + -10.1250, + -10.3750, + -9.8750, + -7.8438, + -8.8750, + -5.2812, + -3.5625, + -12.5000, + -9.1875, + -6.8125, + -10.3750, + -9.3125, + -10.6250, + -11.5000, + -11.2500, + -11.0000, + -10.5625, + -10.8750, + -11.0625, + -11.3750, + -10.5625, + -10.0000, + ], + ] + ).to(torch_device) + + input_ids = [1, 42, 21, 12, 43, 23, 1, 4] + + model = BltForCausalLM.from_pretrained( + "itazap/blt-1b-hf", device_map="auto", attn_implementation="sdpa", torch_dtype=torch.bfloat16 + ) + + with torch.no_grad(): + output = model(torch.tensor([input_ids]).to(torch_device))[0] + + torch.testing.assert_close(EXPECTED_OUTPUT, output[0, :2, :30], rtol=1e-3, atol=1e-3) + + @slow + @require_read_token + def test_model_eager(self): + """Test Blt model with bfloat16 precision using eager attention implementation.""" + NUM_TOKENS_TO_GENERATE = 200 + EXPECTED_TEXT = "my name is alex and i am a student at the university of michigan. i am a senior majoring in computer science and minoring in mathematics. i am also a member of the michigan math club and the michigan computer s" + + prompt = "my name is" + + model = BltForCausalLM.from_pretrained("itazap/blt-1b-hf", device_map="auto", attn_implementation="eager") + + tokenizer = AutoTokenizer.from_pretrained("itazap/blt-1b-hf") + + inputs = tokenizer(prompt, return_tensors="pt").to(model.device) + + generated_ids = model.generate( + **inputs, max_new_tokens=NUM_TOKENS_TO_GENERATE, do_sample=False, use_cache=False + ) + + output_text = tokenizer.decode(generated_ids[0], skip_special_tokens=True) + self.assertEqual(output_text, EXPECTED_TEXT) + + @slow + @require_read_token + @require_torch_bf16 + def test_model_bf16_static_cache(self): + """Test Blt model with bfloat16 precision and static cache.""" + NUM_TOKENS_TO_GENERATE = 200 + EXPECTED_TEXT = "my name is alex and i am a student at the university of michigan. i am a senior majoring in computer science and minoring in mathematics. i am also a member of the michigan math club and the michigan computer s" + + prompt = "my name is" + + model = BltForCausalLM.from_pretrained( + "itazap/blt-1b-hf", device_map="auto", attn_implementation="sdpa", torch_dtype=torch.bfloat16 + ) + + model.generation_config.cache_implementation = "static" + + tokenizer = AutoTokenizer.from_pretrained("itazap/blt-1b-hf") + + inputs = tokenizer(prompt, return_tensors="pt").to(model.device) + + generated_ids = model.generate( + **inputs, max_new_tokens=NUM_TOKENS_TO_GENERATE, do_sample=False, use_cache=False + ) + + output_text = tokenizer.decode(generated_ids[0], skip_special_tokens=True) + self.assertEqual(output_text, EXPECTED_TEXT) diff --git a/utils/check_docstrings.py b/utils/check_docstrings.py index 754a86941d93..37bc980e745c 100644 --- a/utils/check_docstrings.py +++ b/utils/check_docstrings.py @@ -128,6 +128,8 @@ "BlipVisionConfig", "BloomConfig", "BloomTokenizerFast", + "BLTConfig", + "BLTPatcherConfig", "BridgeTowerTextConfig", "BridgeTowerVisionConfig", "BrosModel", @@ -460,6 +462,8 @@ "ZeroShotImageClassificationPipeline", "ZeroShotObjectDetectionPipeline", "Llama4TextConfig", + "BltConfig", + "BltPatcherConfig", } # In addition to the objects above, we also ignore objects with certain prefixes. If you add an item to the list # below, make sure to add a comment explaining why. diff --git a/utils/check_repo.py b/utils/check_repo.py index e92ac6f3b7eb..29bd3dfc3586 100644 --- a/utils/check_repo.py +++ b/utils/check_repo.py @@ -96,6 +96,9 @@ "Glm4vVisionModel", "Glm4vMoeVisionModel", "EvollaSaProtPreTrainedModel", + "BltLocalEncoder", # Building part of bigger (tested) model. Tested implicitly through BLTForCausalLM. + "BltLocalDecoder", # Building part of bigger (tested) model. Tested implicitly through BLTForCausalLM. + "BltGlobalTransformer", # Building part of bigger (tested) model. Tested implicitly through BLTForCausalLM. "Ovis2VisionModel", ] @@ -170,6 +173,10 @@ "CsmDepthDecoderForCausalLM", # Building part of bigger (tested) model. Tested implicitly through CsmForConditionalGenerationIntegrationTest. "CsmDepthDecoderModel", # Building part of bigger (tested) model. Tested implicitly through CsmForConditionalGenerationIntegrationTest. "CsmBackboneModel", # Building part of bigger (tested) model. Tested implicitly through CsmForConditionalGenerationIntegrationTest. + "BltPatcher", # Building part of bigger (tested) model. Tested implicitly through BLTForCausalLM. + "BltLocalEncoder", # Building part of bigger (tested) model. Tested implicitly through BLTForCausalLM. + "BltLocalDecoder", # Building part of bigger (tested) model. Tested implicitly through BLTForCausalLM. + "BltGlobalTransformer", # Building part of bigger (tested) model. Tested implicitly through BLTForCausalLM. "Florence2VisionBackbone", # Building part of bigger (tested) model. Tested implicitly through Florence2ForConditionalGeneration. ] ) @@ -360,6 +367,7 @@ "CsmDepthDecoderModel", # Building part of a bigger model "CsmDepthDecoderForCausalLM", # Building part of a bigger model "CsmForConditionalGeneration", # Building part of a bigger model + "BltPatcher", # Building part of a bigger model, tested implicitly through BltForCausalLM "Florence2VisionBackbone", # Building part of a bigger model ] @@ -1006,6 +1014,9 @@ def ignore_undocumented(name: str) -> bool: # MMBT model does not really work. if name.startswith("MMBT"): return True + # BLT models are internal building blocks, tested implicitly through BltForCausalLM + if name.startswith("Blt"): + return True if name in SHOULD_HAVE_THEIR_OWN_PAGE: return True return False From 4a17be0ab40a1e642f31310490aa73a5d94430ae Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Fri, 19 Sep 2025 12:04:12 +0100 Subject: [PATCH 118/204] [docs] rm stray tf/flax autodocs references (#40999) rm tf references --- .github/workflows/build_documentation.yml | 2 +- docs/source/ja/main_classes/data_collator.md | 3 - .../ja/main_classes/optimizer_schedules.md | 16 - docs/source/ko/main_classes/data_collator.md | 4 - .../ko/main_classes/optimizer_schedules.md | 16 - docs/source/ms/_toctree.yml | 674 ------------------ docs/source/ms/index.md | 464 ------------ docs/source/te/_toctree.yml | 6 - docs/source/te/index.md | 298 -------- docs/source/te/quicktour.md | 557 --------------- docs/source/tr/_toctree.yml | 4 - docs/source/tr/index.md | 295 -------- docs/source/zh/main_classes/data_collator.md | 3 - .../zh/main_classes/optimizer_schedules.md | 16 - 14 files changed, 1 insertion(+), 2357 deletions(-) delete mode 100644 docs/source/ms/_toctree.yml delete mode 100644 docs/source/ms/index.md delete mode 100644 docs/source/te/_toctree.yml delete mode 100644 docs/source/te/index.md delete mode 100644 docs/source/te/quicktour.md delete mode 100644 docs/source/tr/_toctree.yml delete mode 100644 docs/source/tr/index.md diff --git a/.github/workflows/build_documentation.yml b/.github/workflows/build_documentation.yml index c55638ded149..ae67046435fd 100644 --- a/.github/workflows/build_documentation.yml +++ b/.github/workflows/build_documentation.yml @@ -16,7 +16,7 @@ jobs: commit_sha: ${{ github.sha }} package: transformers notebook_folder: transformers_doc - languages: ar de en es fr hi it ko pt tr zh ja te + languages: ar de en es fr hi it ja ko pt zh custom_container: huggingface/transformers-doc-builder secrets: token: ${{ secrets.HUGGINGFACE_PUSH }} diff --git a/docs/source/ja/main_classes/data_collator.md b/docs/source/ja/main_classes/data_collator.md index c37f1aeef4d1..9e89b719e705 100644 --- a/docs/source/ja/main_classes/data_collator.md +++ b/docs/source/ja/main_classes/data_collator.md @@ -49,19 +49,16 @@ rendered properly in your Markdown viewer. [[autodoc]] data.data_collator.DataCollatorForLanguageModeling - numpy_mask_tokens - - tf_mask_tokens - torch_mask_tokens ## DataCollatorForWholeWordMask [[autodoc]] data.data_collator.DataCollatorForWholeWordMask - numpy_mask_tokens - - tf_mask_tokens - torch_mask_tokens ## DataCollatorForPermutationLanguageModeling [[autodoc]] data.data_collator.DataCollatorForPermutationLanguageModeling - numpy_mask_tokens - - tf_mask_tokens - torch_mask_tokens diff --git a/docs/source/ja/main_classes/optimizer_schedules.md b/docs/source/ja/main_classes/optimizer_schedules.md index cd6dada007cb..780b9394ec08 100644 --- a/docs/source/ja/main_classes/optimizer_schedules.md +++ b/docs/source/ja/main_classes/optimizer_schedules.md @@ -26,12 +26,6 @@ rendered properly in your Markdown viewer. [[autodoc]] Adafactor -## AdamWeightDecay (TensorFlow) - -[[autodoc]] AdamWeightDecay - -[[autodoc]] create_optimizer - ## Schedules ### Learning Rate Schedules (Pytorch) @@ -61,13 +55,3 @@ rendered properly in your Markdown viewer. [[autodoc]] get_polynomial_decay_schedule_with_warmup [[autodoc]] get_inverse_sqrt_schedule - -### Warmup (TensorFlow) - -[[autodoc]] WarmUp - -## Gradient Strategies - -### GradientAccumulator (TensorFlow) - -[[autodoc]] GradientAccumulator diff --git a/docs/source/ko/main_classes/data_collator.md b/docs/source/ko/main_classes/data_collator.md index 0e677c7d8979..e631b79ab2f6 100644 --- a/docs/source/ko/main_classes/data_collator.md +++ b/docs/source/ko/main_classes/data_collator.md @@ -43,24 +43,20 @@ rendered properly in your Markdown viewer. [[autodoc]] data.data_collator.DataCollatorForLanguageModeling - numpy_mask_tokens - - tf_mask_tokens - torch_mask_tokens ## DataCollatorForWholeWordMask[[transformers.DataCollatorForWholeWordMask]] [[autodoc]] data.data_collator.DataCollatorForWholeWordMask - numpy_mask_tokens - - tf_mask_tokens - torch_mask_tokens ## DataCollatorForPermutationLanguageModeling[[transformers.DataCollatorForPermutationLanguageModeling]] [[autodoc]] data.data_collator.DataCollatorForPermutationLanguageModeling - numpy_mask_tokens - - tf_mask_tokens - torch_mask_tokens ## DataCollatorWithFlatteningtransformers.DataCollatorWithFlattening [[autodoc]] data.data_collator.DataCollatorWithFlattening - diff --git a/docs/source/ko/main_classes/optimizer_schedules.md b/docs/source/ko/main_classes/optimizer_schedules.md index 24e1009e8274..a11acc12ef0e 100644 --- a/docs/source/ko/main_classes/optimizer_schedules.md +++ b/docs/source/ko/main_classes/optimizer_schedules.md @@ -27,12 +27,6 @@ rendered properly in your Markdown viewer. [[autodoc]] Adafactor -## AdamWeightDecay (TensorFlow)[[transformers.AdamWeightDecay]] - -[[autodoc]] AdamWeightDecay - -[[autodoc]] create_optimizer - ## 스케줄[[schedules]] ### 학습률 스케줄 (PyTorch)[[transformers.SchedulerType]] @@ -64,13 +58,3 @@ rendered properly in your Markdown viewer. [[autodoc]] get_inverse_sqrt_schedule [[autodoc]] get_wsd_schedule - -### 웜업 (TensorFlow)[[transformers.WarmUp]] - -[[autodoc]] WarmUp - -## 그래디언트 전략[[gradient-strategies]] - -### GradientAccumulator (TensorFlow)[[transformers.GradientAccumulator]] - -[[autodoc]] GradientAccumulator diff --git a/docs/source/ms/_toctree.yml b/docs/source/ms/_toctree.yml deleted file mode 100644 index 05d4829437b9..000000000000 --- a/docs/source/ms/_toctree.yml +++ /dev/null @@ -1,674 +0,0 @@ -- sections: - - local: index - title: 🤗 Transformers - - local: quicktour - title: Lawatan cepat - - local: installation - title: Pemasangan - title: Mulakan -- sections: - - local: pipeline_tutorial - title: Jalankan inferens dengan saluran paip - - local: autoclass_tutorial - title: Tulis kod mudah alih dengan AutoClass - - local: preprocessing - title: Praproses data - - local: training - title: Perhalusi model yang telah dilatih - - local: run_scripts - title: Latih dengan skrip - - local: accelerate - title: Sediakan latihan yang diedarkan dengan 🤗 Accelerate - - local: model_sharing - title: Kongsi model anda - title: Tutorials -- sections: - - sections: - - local: tasks/sequence_classification - title: Klasifikasi teks - - local: tasks/token_classification - title: Klasifikasi token - - local: tasks/question_answering - title: Soalan menjawab - - local: tasks/language_modeling - title: Pemodelan bahasa sebab-akibat - - local: tasks/masked_language_modeling - title: Pemodelan bahasa Masked - - local: tasks/translation - title: Terjemahan - - local: tasks/summarization - title: Rumusan - - local: tasks/multiple_choice - title: Pilihan - title: Natural Language Processing - isExpanded: false - - sections: - - local: tasks/audio_classification - title: Klasifikasi audio - - local: tasks/asr - title: Pengecaman pertuturan automatik - title: Audio - isExpanded: false - - sections: - - local: tasks/image_classification - title: Klasifikasi imej - - local: tasks/semantic_segmentation - title: Segmentasi semantik - - local: tasks/video_classification - title: Klasifikasi video - - local: tasks/object_detection - title: Pengesanan objek - - local: tasks/zero_shot_object_detection - title: Pengesanan objek Zero-Shot - - local: tasks/zero_shot_image_classification - title: Klasifikasi imej tangkapan Zero-Shot - - local: tasks/monocular_depth_estimation - title: Anggaran kedalaman - title: Visi komputer - isExpanded: false - - sections: - - local: tasks/image_captioning - title: Kapsyen imej - - local: tasks/document_question_answering - title: Menjawab Soalan Dokumen - - local: tasks/text-to-speech - title: Teks kepada ucapan - title: Multimodal - isExpanded: false - title: Panduan Tugasan -- sections: - - local: fast_tokenizers - title: Gunakan tokenizer cepat dari 🤗 Tokenizers - - local: multilingual - title: Jalankan inferens dengan model berbilang bahasa - - local: generation_strategies - title: Sesuaikan strategi penjanaan teks - - local: create_a_model - title: Gunakan API khusus model - - local: custom_models - title: Kongsi model tersuai - - local: sagemaker - title: Jalankan latihan di Amazon SageMaker - - local: serialization - title: Eksport ke ONNX - - local: torchscript - title: Eksport ke TorchScript - - local: Buku nota dengan contoh - title: Notebooks with examples - - local: Sumber komuniti - title: Community resources - - local: Sumber komuniti - title: Custom Tools and Prompts - - local: Alat dan Gesaan Tersuai - title: Selesaikan masalah - title: Panduan Developer -- sections: - - local: performance - title: Gambaran keseluruhan - - local: perf_train_gpu_one - title: Latihan pada satu GPU - - local: perf_train_gpu_many - title: Latihan pada banyak GPU - - local: perf_train_cpu - title: Latihan mengenai CPU - - local: perf_train_cpu_many - title: Latihan pada banyak CPU - - local: perf_train_tpu - title: Latihan mengenai TPU - - local: perf_train_special - title: Latihan mengenai Perkakasan Khusus - - local: perf_infer_cpu - title: Inferens pada CPU - - local: perf_infer_gpu_one - title: Inferens pada satu GPU - - local: perf_infer_gpu_many - title: Inferens pada banyak GPUs - - local: perf_infer_special - title: Inferens pada Perkakasan Khusus - - local: perf_hardware - title: Perkakasan tersuai untuk latihan - - local: big_models - title: Menghidupkan model besar - - local: debugging - title: Penyahpepijatan - - local: hpo_train - title: Carian Hiperparameter menggunakan API Pelatih - title: Prestasi dan kebolehskalaan -- sections: - - local: contributing - title: Bagaimana untuk menyumbang kepada transformer? - - local: add_new_model - title: Bagaimana untuk menambah model pada 🤗 Transformers? - - local: add_new_pipeline - title: Bagaimana untuk menambah saluran paip ke 🤗 Transformers? - - local: testing - title: Ujian - - local: pr_checks - title: Menyemak Permintaan Tarik - title: Sumbangkan - -- sections: - - local: philosophy - title: Falsafah - - local: glossary - title: Glosari - - local: task_summary - title: Apa 🤗 Transformers boleh buat - - local: tasks_explained - title: Bagaimana 🤗 Transformers menyelesaikan tugasan - - local: model_summary - title: Keluarga model Transformer - - local: tokenizer_summary - title: Ringkasan tokenizer - - local: attention - title: Mekanisme perhatian - - local: pad_truncation - title: Padding dan pemotongan - - local: bertology - title: BERTology - - local: perplexity - title: Kekeliruan model panjang tetap - - local: pipeline_webserver - title: Saluran paip untuk inferens pelayan web - title: Panduan konsep -- sections: - - sections: - - local: model_doc/auto - title: Kelas Auto - - local: main_classes/callback - title: Panggilan balik - - local: main_classes/configuration - title: Configuration - - local: main_classes/data_collator - title: Data Collator - - local: main_classes/logging - title: Logging - - local: main_classes/model - title: Models - - local: main_classes/text_generation - title: Text Generation - - local: main_classes/onnx - title: ONNX - - local: main_classes/optimizer_schedules - title: Optimization - - local: main_classes/output - title: Model outputs - - local: main_classes/pipelines - title: Pipelines - - local: main_classes/processors - title: Processors - - local: main_classes/quantization - title: Quantization - - local: main_classes/tokenizer - title: Tokenizer - - local: main_classes/trainer - title: Trainer - - local: main_classes/deepspeed - title: DeepSpeed Integration - - local: main_classes/feature_extractor - title: Feature Extractor - - local: main_classes/image_processor - title: Image Processor - title: Main Classes - - sections: - - isExpanded: false - sections: - - local: model_doc/albert - title: ALBERT - - local: model_doc/bart - title: BART - - local: model_doc/barthez - title: BARThez - - local: model_doc/bartpho - title: BARTpho - - local: model_doc/bert - title: BERT - - local: model_doc/bert-generation - title: BertGeneration - - local: model_doc/bert-japanese - title: BertJapanese - - local: model_doc/bertweet - title: Bertweet - - local: model_doc/big_bird - title: BigBird - - local: model_doc/bigbird_pegasus - title: BigBirdPegasus - - local: model_doc/biogpt - title: BioGpt - - local: model_doc/blenderbot - title: Blenderbot - - local: model_doc/blenderbot-small - title: Blenderbot Small - - local: model_doc/bloom - title: BLOOM - - local: model_doc/bort - title: BORT - - local: model_doc/byt5 - title: ByT5 - - local: model_doc/camembert - title: CamemBERT - - local: model_doc/canine - title: CANINE - - local: model_doc/codegen - title: CodeGen - - local: model_doc/convbert - title: ConvBERT - - local: model_doc/cpm - title: CPM - - local: model_doc/cpmant - title: CPMANT - - local: model_doc/ctrl - title: CTRL - - local: model_doc/deberta - title: DeBERTa - - local: model_doc/deberta-v2 - title: DeBERTa-v2 - - local: model_doc/dialogpt - title: DialoGPT - - local: model_doc/distilbert - title: DistilBERT - - local: model_doc/dpr - title: DPR - - local: model_doc/electra - title: ELECTRA - - local: model_doc/encoder-decoder - title: Encoder Decoder Models - - local: model_doc/ernie - title: ERNIE - - local: model_doc/ernie_m - title: ErnieM - - local: model_doc/esm - title: ESM - - local: model_doc/flan-t5 - title: FLAN-T5 - - local: model_doc/flan-ul2 - title: FLAN-UL2 - - local: model_doc/flaubert - title: FlauBERT - - local: model_doc/fnet - title: FNet - - local: model_doc/fsmt - title: FSMT - - local: model_doc/funnel - title: Funnel Transformer - - local: model_doc/openai-gpt - title: GPT - - local: model_doc/gpt_neo - title: GPT Neo - - local: model_doc/gpt_neox - title: GPT NeoX - - local: model_doc/gpt_neox_japanese - title: GPT NeoX Japanese - - local: model_doc/gptj - title: GPT-J - - local: model_doc/gpt2 - title: GPT2 - - local: model_doc/gpt_bigcode - title: GPTBigCode - - local: model_doc/gptsan-japanese - title: GPTSAN Japanese - - local: model_doc/gpt-sw3 - title: GPTSw3 - - local: model_doc/herbert - title: HerBERT - - local: model_doc/ibert - title: I-BERT - - local: model_doc/jukebox - title: Jukebox - - local: model_doc/led - title: LED - - local: model_doc/llama - title: LLaMA - - local: model_doc/longformer - title: Longformer - - local: model_doc/longt5 - title: LongT5 - - local: model_doc/luke - title: LUKE - - local: model_doc/m2m_100 - title: M2M100 - - local: model_doc/marian - title: MarianMT - - local: model_doc/markuplm - title: MarkupLM - - local: model_doc/mbart - title: MBart and MBart-50 - - local: model_doc/mega - title: MEGA - - local: model_doc/megatron-bert - title: MegatronBERT - - local: model_doc/megatron_gpt2 - title: MegatronGPT2 - - local: model_doc/mluke - title: mLUKE - - local: model_doc/mobilebert - title: MobileBERT - - local: model_doc/mpnet - title: MPNet - - local: model_doc/mt5 - title: MT5 - - local: model_doc/mvp - title: MVP - - local: model_doc/nezha - title: NEZHA - - local: model_doc/nllb - title: NLLB - - local: model_doc/nllb-moe - title: NLLB-MoE - - local: model_doc/nystromformer - title: Nyströmformer - - local: model_doc/open-llama - title: Open-Llama - - local: model_doc/opt - title: OPT - - local: model_doc/pegasus - title: Pegasus - - local: model_doc/pegasus_x - title: PEGASUS-X - - local: model_doc/phobert - title: PhoBERT - - local: model_doc/plbart - title: PLBart - - local: model_doc/prophetnet - title: ProphetNet - - local: model_doc/qdqbert - title: QDQBert - - local: model_doc/rag - title: RAG - - local: model_doc/realm - title: REALM - - local: model_doc/reformer - title: Reformer - - local: model_doc/rembert - title: RemBERT - - local: model_doc/retribert - title: RetriBERT - - local: model_doc/roberta - title: RoBERTa - - local: model_doc/roberta-prelayernorm - title: RoBERTa-PreLayerNorm - - local: model_doc/roc_bert - title: RoCBert - - local: model_doc/roformer - title: RoFormer - - local: model_doc/rwkv - title: RWKV - - local: model_doc/splinter - title: Splinter - - local: model_doc/squeezebert - title: SqueezeBERT - - local: model_doc/switch_transformers - title: SwitchTransformers - - local: model_doc/t5 - title: T5 - - local: model_doc/t5v1.1 - title: T5v1.1 - - local: model_doc/tapex - title: TAPEX - - local: model_doc/transfo-xl - title: Transformer XL - - local: model_doc/ul2 - title: UL2 - - local: model_doc/xmod - title: X-MOD - - local: model_doc/xglm - title: XGLM - - local: model_doc/xlm - title: XLM - - local: model_doc/xlm-prophetnet - title: XLM-ProphetNet - - local: model_doc/xlm-roberta - title: XLM-RoBERTa - - local: model_doc/xlm-roberta-xl - title: XLM-RoBERTa-XL - - local: model_doc/xlm-v - title: XLM-V - - local: model_doc/xlnet - title: XLNet - - local: model_doc/yoso - title: YOSO - title: Text models - - isExpanded: false - sections: - - local: model_doc/beit - title: BEiT - - local: model_doc/bit - title: BiT - - local: model_doc/conditional_detr - title: Conditional DETR - - local: model_doc/convnext - title: ConvNeXT - - local: model_doc/convnextv2 - title: ConvNeXTV2 - - local: model_doc/cvt - title: CvT - - local: model_doc/deformable_detr - title: Deformable DETR - - local: model_doc/deit - title: DeiT - - local: model_doc/deta - title: DETA - - local: model_doc/detr - title: DETR - - local: model_doc/dinat - title: DiNAT - - local: model_doc/dit - title: DiT - - local: model_doc/dpt - title: DPT - - local: model_doc/efficientformer - title: EfficientFormer - - local: model_doc/efficientnet - title: EfficientNet - - local: model_doc/focalnet - title: FocalNet - - local: model_doc/glpn - title: GLPN - - local: model_doc/imagegpt - title: ImageGPT - - local: model_doc/levit - title: LeViT - - local: model_doc/mask2former - title: Mask2Former - - local: model_doc/maskformer - title: MaskFormer - - local: model_doc/mobilenet_v1 - title: MobileNetV1 - - local: model_doc/mobilenet_v2 - title: MobileNetV2 - - local: model_doc/mobilevit - title: MobileViT - - local: model_doc/nat - title: NAT - - local: model_doc/poolformer - title: PoolFormer - - local: model_doc/regnet - title: RegNet - - local: model_doc/resnet - title: ResNet - - local: model_doc/segformer - title: SegFormer - - local: model_doc/swiftformer - title: SwiftFormer - - local: model_doc/swin - title: Swin Transformer - - local: model_doc/swinv2 - title: Swin Transformer V2 - - local: model_doc/swin2sr - title: Swin2SR - - local: model_doc/table-transformer - title: Table Transformer - - local: model_doc/timesformer - title: TimeSformer - - local: model_doc/upernet - title: UperNet - - local: model_doc/van - title: VAN - - local: model_doc/videomae - title: VideoMAE - - local: model_doc/vit - title: Vision Transformer (ViT) - - local: model_doc/vit_hybrid - title: ViT Hybrid - - local: model_doc/vit_mae - title: ViTMAE - - local: model_doc/vit_msn - title: ViTMSN - - local: model_doc/yolos - title: YOLOS - title: Vision models - - isExpanded: false - sections: - - local: model_doc/audio-spectrogram-transformer - title: Audio Spectrogram Transformer - - local: model_doc/clap - title: CLAP - - local: model_doc/hubert - title: Hubert - - local: model_doc/mctct - title: MCTCT - - local: model_doc/sew - title: SEW - - local: model_doc/sew-d - title: SEW-D - - local: model_doc/speech_to_text - title: Speech2Text - - local: model_doc/speech_to_text_2 - title: Speech2Text2 - - local: model_doc/speecht5 - title: SpeechT5 - - local: model_doc/unispeech - title: UniSpeech - - local: model_doc/unispeech-sat - title: UniSpeech-SAT - - local: model_doc/wav2vec2 - title: Wav2Vec2 - - local: model_doc/wav2vec2-conformer - title: Wav2Vec2-Conformer - - local: model_doc/wav2vec2_phoneme - title: Wav2Vec2Phoneme - - local: model_doc/wavlm - title: WavLM - - local: model_doc/whisper - title: Whisper - - local: model_doc/xls_r - title: XLS-R - - local: model_doc/xlsr_wav2vec2 - title: XLSR-Wav2Vec2 - title: Audio models - - isExpanded: false - sections: - - local: model_doc/align - title: ALIGN - - local: model_doc/altclip - title: AltCLIP - - local: model_doc/blip - title: BLIP - - local: model_doc/blip-2 - title: BLIP-2 - - local: model_doc/bridgetower - title: BridgeTower - - local: model_doc/chinese_clip - title: Chinese-CLIP - - local: model_doc/clip - title: CLIP - - local: model_doc/clipseg - title: CLIPSeg - - local: model_doc/data2vec - title: Data2Vec - - local: model_doc/deplot - title: DePlot - - local: model_doc/donut - title: Donut - - local: model_doc/flava - title: FLAVA - - local: model_doc/git - title: GIT - - local: model_doc/groupvit - title: GroupViT - - local: model_doc/layoutlm - title: LayoutLM - - local: model_doc/layoutlmv2 - title: LayoutLMV2 - - local: model_doc/layoutlmv3 - title: LayoutLMV3 - - local: model_doc/layoutxlm - title: LayoutXLM - - local: model_doc/lilt - title: LiLT - - local: model_doc/lxmert - title: LXMERT - - local: model_doc/matcha - title: MatCha - - local: model_doc/mgp-str - title: MGP-STR - - local: model_doc/oneformer - title: OneFormer - - local: model_doc/owlvit - title: OWL-ViT - - local: model_doc/perceiver - title: Perceiver - - local: model_doc/pix2struct - title: Pix2Struct - - local: model_doc/sam - title: Segment Anything - - local: model_doc/speech-encoder-decoder - title: Speech Encoder Decoder Models - - local: model_doc/tapas - title: TAPAS - - local: model_doc/trocr - title: TrOCR - - local: model_doc/tvlt - title: TVLT - - local: model_doc/vilt - title: ViLT - - local: model_doc/vision-encoder-decoder - title: Vision Encoder Decoder Models - - local: model_doc/vision-text-dual-encoder - title: Vision Text Dual Encoder - - local: model_doc/visual_bert - title: VisualBERT - - local: model_doc/xclip - title: X-CLIP - title: Multimodal models - - isExpanded: false - sections: - - local: model_doc/decision_transformer - title: Decision Transformer - - local: model_doc/trajectory_transformer - title: Trajectory Transformer - title: Reinforcement learning models - - isExpanded: false - sections: - - local: model_doc/informer - title: Informer - - local: model_doc/time_series_transformer - title: Time Series Transformer - title: Time series models - - isExpanded: false - sections: - - local: model_doc/graphormer - title: Graphormer - title: Graph models - title: Models - - sections: - - local: internal/modeling_utils - title: Custom Layers and Utilities - - local: internal/pipelines_utils - title: Utilities for pipelines - - local: internal/tokenization_utils - title: Utilities for Tokenizers - - local: internal/trainer_utils - title: Utilities for Trainer - - local: internal/generation_utils - title: Utilities for Generation - - local: internal/image_processing_utils - title: Utilities for Image Processors - - local: internal/audio_utils - title: Utilities for Audio processing - - local: internal/file_utils - title: General Utilities - - local: internal/time_series_utils - title: Utilities for Time Series - title: Internal Helpers - title: API diff --git a/docs/source/ms/index.md b/docs/source/ms/index.md deleted file mode 100644 index e54b6aa574c6..000000000000 --- a/docs/source/ms/index.md +++ /dev/null @@ -1,464 +0,0 @@ - - -# 🤗 Transformers - -Pembelajaran Mesin terkini untuk [PyTorch](https://pytorch.org/), [TensorFlow](https://www.tensorflow.org/), dan [JAX](https://jax.readthedocs.io/en/latest/). - -🤗 Transformers menyediakan API dan alatan untuk memuat turun dan melatih model pra-latihan terkini dengan mudah. Menggunakan model terlatih boleh mengurangkan kos pengiraan anda, jejak karbon dan menjimatkan masa serta sumber yang diperlukan untuk melatih model dari awal. Model ini menyokong tugas biasa dalam modaliti yang berbeza, seperti: - -📝 **Natural Language Processing**: klasifikasi teks, pengecaman entiti bernama, menjawab soalan, pemodelan bahasa, ringkasan, terjemahan, pilihan berganda dan penjanaan teks.
-🖼️ **Computer Vision**: pengelasan imej, pengesanan objek dan pembahagian.
-🗣️ **Audio**: pengecaman pertuturan automatik dan klasifikasi audio.
-🐙 **Multimodal**: jawapan soalan jadual, pengecaman aksara optik, pengekstrakan maklumat daripada dokumen yang diimbas, klasifikasi video dan jawapan soalan visual. - -🤗 Transformer menyokong kebolehoperasian rangka kerja antara PyTorch, TensorFlow, and JAX. Ini memberikan fleksibiliti untuk menggunakan rangka kerja yang berbeza pada setiap peringkat kehidupan model; latih model dalam tiga baris kod dalam satu rangka kerja, dan muatkannya untuk inferens dalam rangka kerja yang lain. Model juga boleh dieksport ke format seperti ONNX. - -Sertai komuniti yang semakin berkembang di [Hub](https://huggingface.co/models), [forum](https://discuss.huggingface.co/), atau [Discord](https://discord.com/invite/JfAtkvEtRb) hari ini! - -## Jika anda sedang mencari sokongan tersuai daripada pasukan Hugging Face - - - HuggingFace Expert Acceleration Program - - -## Kandungan - -Dokumentasi disusun kepada lima bahagian: - -- **MULAKAN** menyediakan lawatan pantas ke perpustakaan dan arahan pemasangan untuk bangun dan berjalan. -- **TUTORIAL** ialah tempat yang bagus untuk bermula jika anda seorang pemula. Bahagian ini akan membantu anda memperoleh kemahiran asas yang anda perlukan untuk mula menggunakan perpustakaan. -- **PANDUAN CARA-CARA** menunjukkan kepada anda cara untuk mencapai matlamat tertentu, seperti memperhalusi model terlatih untuk pemodelan bahasa atau cara menulis dan berkongsi model tersuai. -- **PANDUAN KONSEP** menawarkan lebih banyak perbincangan dan penjelasan tentang konsep dan idea asas di sebalik model, tugasan dan falsafah reka bentuk 🤗 Transformers. -- **API** menerangkan semua kelas dan fungsi: - - - **KELAS UTAMA** memperincikan kelas yang paling penting seperti konfigurasi, model, tokenizer dan saluran paip. - - **MODEL** memperincikan kelas dan fungsi yang berkaitan dengan setiap model yang dilaksanakan dalam perpustakaan. - - **PEMBANTU DALAMAN** memperincikan kelas utiliti dan fungsi yang digunakan secara dalaman. - -### Model yang disokong - - - -1. **[ALBERT](model_doc/albert)** (from Google Research and the Toyota Technological Institute at Chicago) released with the paper [ALBERT: A Lite BERT for Self-supervised Learning of Language Representations](https://huggingface.co/papers/1909.11942), by Zhenzhong Lan, Mingda Chen, Sebastian Goodman, Kevin Gimpel, Piyush Sharma, Radu Soricut. -1. **[ALIGN](model_doc/align)** (from Google Research) released with the paper [Scaling Up Visual and Vision-Language Representation Learning With Noisy Text Supervision](https://huggingface.co/papers/2102.05918) by Chao Jia, Yinfei Yang, Ye Xia, Yi-Ting Chen, Zarana Parekh, Hieu Pham, Quoc V. Le, Yunhsuan Sung, Zhen Li, Tom Duerig. -1. **[AltCLIP](model_doc/altclip)** (from BAAI) released with the paper [AltCLIP: Altering the Language Encoder in CLIP for Extended Language Capabilities](https://huggingface.co/papers/2211.06679) by Chen, Zhongzhi and Liu, Guang and Zhang, Bo-Wen and Ye, Fulong and Yang, Qinghong and Wu, Ledell. -1. **[Audio Spectrogram Transformer](model_doc/audio-spectrogram-transformer)** (from MIT) released with the paper [AST: Audio Spectrogram Transformer](https://huggingface.co/papers/2104.01778) by Yuan Gong, Yu-An Chung, James Glass. -1. **[Autoformer](model_doc/autoformer)** (from Tsinghua University) released with the paper [Autoformer: Decomposition Transformers with Auto-Correlation for Long-Term Series Forecasting](https://huggingface.co/papers/2106.13008) by Haixu Wu, Jiehui Xu, Jianmin Wang, Mingsheng Long. -1. **[BART](model_doc/bart)** (from Facebook) released with the paper [BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension](https://huggingface.co/papers/1910.13461) by Mike Lewis, Yinhan Liu, Naman Goyal, Marjan Ghazvininejad, Abdelrahman Mohamed, Omer Levy, Ves Stoyanov and Luke Zettlemoyer. -1. **[BARThez](model_doc/barthez)** (from École polytechnique) released with the paper [BARThez: a Skilled Pretrained French Sequence-to-Sequence Model](https://huggingface.co/papers/2010.12321) by Moussa Kamal Eddine, Antoine J.-P. Tixier, Michalis Vazirgiannis. -1. **[BARTpho](model_doc/bartpho)** (from VinAI Research) released with the paper [BARTpho: Pre-trained Sequence-to-Sequence Models for Vietnamese](https://huggingface.co/papers/2109.09701) by Nguyen Luong Tran, Duong Minh Le and Dat Quoc Nguyen. -1. **[BEiT](model_doc/beit)** (from Microsoft) released with the paper [BEiT: BERT Pre-Training of Image Transformers](https://huggingface.co/papers/2106.08254) by Hangbo Bao, Li Dong, Furu Wei. -1. **[BERT](model_doc/bert)** (from Google) released with the paper [BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding](https://huggingface.co/papers/1810.04805) by Jacob Devlin, Ming-Wei Chang, Kenton Lee and Kristina Toutanova. -1. **[BERT For Sequence Generation](model_doc/bert-generation)** (from Google) released with the paper [Leveraging Pre-trained Checkpoints for Sequence Generation Tasks](https://huggingface.co/papers/1907.12461) by Sascha Rothe, Shashi Narayan, Aliaksei Severyn. -1. **[BERTweet](model_doc/bertweet)** (from VinAI Research) released with the paper [BERTweet: A pre-trained language model for English Tweets](https://aclanthology.org/2020.emnlp-demos.2/) by Dat Quoc Nguyen, Thanh Vu and Anh Tuan Nguyen. -1. **[BigBird-Pegasus](model_doc/bigbird_pegasus)** (from Google Research) released with the paper [Big Bird: Transformers for Longer Sequences](https://huggingface.co/papers/2007.14062) by Manzil Zaheer, Guru Guruganesh, Avinava Dubey, Joshua Ainslie, Chris Alberti, Santiago Ontanon, Philip Pham, Anirudh Ravula, Qifan Wang, Li Yang, Amr Ahmed. -1. **[BigBird-RoBERTa](model_doc/big_bird)** (from Google Research) released with the paper [Big Bird: Transformers for Longer Sequences](https://huggingface.co/papers/2007.14062) by Manzil Zaheer, Guru Guruganesh, Avinava Dubey, Joshua Ainslie, Chris Alberti, Santiago Ontanon, Philip Pham, Anirudh Ravula, Qifan Wang, Li Yang, Amr Ahmed. -1. **[BioGpt](model_doc/biogpt)** (from Microsoft Research AI4Science) released with the paper [BioGPT: generative pre-trained transformer for biomedical text generation and mining](https://academic.oup.com/bib/advance-article/doi/10.1093/bib/bbac409/6713511?guestAccessKey=a66d9b5d-4f83-4017-bb52-405815c907b9) by Renqian Luo, Liai Sun, Yingce Xia, Tao Qin, Sheng Zhang, Hoifung Poon and Tie-Yan Liu. -1. **[BiT](model_doc/bit)** (from Google AI) released with the paper [Big Transfer (BiT): General Visual Representation Learning](https://huggingface.co/papers/1912.11370) by Alexander Kolesnikov, Lucas Beyer, Xiaohua Zhai, Joan Puigcerver, Jessica Yung, Sylvain Gelly, Neil Houlsby. -1. **[Blenderbot](model_doc/blenderbot)** (from Facebook) released with the paper [Recipes for building an open-domain chatbot](https://huggingface.co/papers/2004.13637) by Stephen Roller, Emily Dinan, Naman Goyal, Da Ju, Mary Williamson, Yinhan Liu, Jing Xu, Myle Ott, Kurt Shuster, Eric M. Smith, Y-Lan Boureau, Jason Weston. -1. **[BlenderbotSmall](model_doc/blenderbot-small)** (from Facebook) released with the paper [Recipes for building an open-domain chatbot](https://huggingface.co/papers/2004.13637) by Stephen Roller, Emily Dinan, Naman Goyal, Da Ju, Mary Williamson, Yinhan Liu, Jing Xu, Myle Ott, Kurt Shuster, Eric M. Smith, Y-Lan Boureau, Jason Weston. -1. **[BLIP](model_doc/blip)** (from Salesforce) released with the paper [BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation](https://huggingface.co/papers/2201.12086) by Junnan Li, Dongxu Li, Caiming Xiong, Steven Hoi. -1. **[BLIP-2](model_doc/blip-2)** (from Salesforce) released with the paper [BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models](https://huggingface.co/papers/2301.12597) by Junnan Li, Dongxu Li, Silvio Savarese, Steven Hoi. -1. **[BLOOM](model_doc/bloom)** (from BigScience workshop) released by the [BigScience Workshop](https://bigscience.huggingface.co/). -1. **[BORT](model_doc/bort)** (from Alexa) released with the paper [Optimal Subarchitecture Extraction For BERT](https://huggingface.co/papers/2010.10499) by Adrian de Wynter and Daniel J. Perry. -1. **[BridgeTower](model_doc/bridgetower)** (from Harbin Institute of Technology/Microsoft Research Asia/Intel Labs) released with the paper [BridgeTower: Building Bridges Between Encoders in Vision-Language Representation Learning](https://huggingface.co/papers/2206.08657) by Xiao Xu, Chenfei Wu, Shachar Rosenman, Vasudev Lal, Wanxiang Che, Nan Duan. -1. **[Bros](model_doc/bros)** (from NAVER) released with the paper [BROS: A Pre-trained Language Model Focusing on Text and Layout for Better Key Information Extraction from Documents](https://huggingface.co/papers/2108.04539) by Teakgyu Hong, Donghyun Kim, Mingi Ji, Wonseok Hwang, Daehyun Nam, Sungrae Park. -1. **[ByT5](model_doc/byt5)** (from Google Research) released with the paper [ByT5: Towards a token-free future with pre-trained byte-to-byte models](https://huggingface.co/papers/2105.13626) by Linting Xue, Aditya Barua, Noah Constant, Rami Al-Rfou, Sharan Narang, Mihir Kale, Adam Roberts, Colin Raffel. -1. **[CamemBERT](model_doc/camembert)** (from Inria/Facebook/Sorbonne) released with the paper [CamemBERT: a Tasty French Language Model](https://huggingface.co/papers/1911.03894) by Louis Martin*, Benjamin Muller*, Pedro Javier Ortiz Suárez*, Yoann Dupont, Laurent Romary, Éric Villemonte de la Clergerie, Djamé Seddah and Benoît Sagot. -1. **[CANINE](model_doc/canine)** (from Google Research) released with the paper [CANINE: Pre-training an Efficient Tokenization-Free Encoder for Language Representation](https://huggingface.co/papers/2103.06874) by Jonathan H. Clark, Dan Garrette, Iulia Turc, John Wieting. -1. **[Chinese-CLIP](model_doc/chinese_clip)** (from OFA-Sys) released with the paper [Chinese CLIP: Contrastive Vision-Language Pretraining in Chinese](https://huggingface.co/papers/2211.01335) by An Yang, Junshu Pan, Junyang Lin, Rui Men, Yichang Zhang, Jingren Zhou, Chang Zhou. -1. **[CLAP](model_doc/clap)** (from LAION-AI) released with the paper [Large-scale Contrastive Language-Audio Pretraining with Feature Fusion and Keyword-to-Caption Augmentation](https://huggingface.co/papers/2211.06687) by Yusong Wu, Ke Chen, Tianyu Zhang, Yuchen Hui, Taylor Berg-Kirkpatrick, Shlomo Dubnov. -1. **[CLIP](model_doc/clip)** (from OpenAI) released with the paper [Learning Transferable Visual Models From Natural Language Supervision](https://huggingface.co/papers/2103.00020) by Alec Radford, Jong Wook Kim, Chris Hallacy, Aditya Ramesh, Gabriel Goh, Sandhini Agarwal, Girish Sastry, Amanda Askell, Pamela Mishkin, Jack Clark, Gretchen Krueger, Ilya Sutskever. -1. **[CLIPSeg](model_doc/clipseg)** (from University of Göttingen) released with the paper [Image Segmentation Using Text and Image Prompts](https://huggingface.co/papers/2112.10003) by Timo Lüddecke and Alexander Ecker. -1. **[CodeGen](model_doc/codegen)** (from Salesforce) released with the paper [A Conversational Paradigm for Program Synthesis](https://huggingface.co/papers/2203.13474) by Erik Nijkamp, Bo Pang, Hiroaki Hayashi, Lifu Tu, Huan Wang, Yingbo Zhou, Silvio Savarese, Caiming Xiong. -1. **[Conditional DETR](model_doc/conditional_detr)** (from Microsoft Research Asia) released with the paper [Conditional DETR for Fast Training Convergence](https://huggingface.co/papers/2108.06152) by Depu Meng, Xiaokang Chen, Zejia Fan, Gang Zeng, Houqiang Li, Yuhui Yuan, Lei Sun, Jingdong Wang. -1. **[ConvBERT](model_doc/convbert)** (from YituTech) released with the paper [ConvBERT: Improving BERT with Span-based Dynamic Convolution](https://huggingface.co/papers/2008.02496) by Zihang Jiang, Weihao Yu, Daquan Zhou, Yunpeng Chen, Jiashi Feng, Shuicheng Yan. -1. **[ConvNeXT](model_doc/convnext)** (from Facebook AI) released with the paper [A ConvNet for the 2020s](https://huggingface.co/papers/2201.03545) by Zhuang Liu, Hanzi Mao, Chao-Yuan Wu, Christoph Feichtenhofer, Trevor Darrell, Saining Xie. -1. **[ConvNeXTV2](model_doc/convnextv2)** (from Facebook AI) released with the paper [ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders](https://huggingface.co/papers/2301.00808) by Sanghyun Woo, Shoubhik Debnath, Ronghang Hu, Xinlei Chen, Zhuang Liu, In So Kweon, Saining Xie. -1. **[CPM](model_doc/cpm)** (from Tsinghua University) released with the paper [CPM: A Large-scale Generative Chinese Pre-trained Language Model](https://huggingface.co/papers/2012.00413) by Zhengyan Zhang, Xu Han, Hao Zhou, Pei Ke, Yuxian Gu, Deming Ye, Yujia Qin, Yusheng Su, Haozhe Ji, Jian Guan, Fanchao Qi, Xiaozhi Wang, Yanan Zheng, Guoyang Zeng, Huanqi Cao, Shengqi Chen, Daixuan Li, Zhenbo Sun, Zhiyuan Liu, Minlie Huang, Wentao Han, Jie Tang, Juanzi Li, Xiaoyan Zhu, Maosong Sun. -1. **[CPM-Ant](model_doc/cpmant)** (from OpenBMB) released by the [OpenBMB](https://www.openbmb.org/). -1. **[CTRL](model_doc/ctrl)** (from Salesforce) released with the paper [CTRL: A Conditional Transformer Language Model for Controllable Generation](https://huggingface.co/papers/1909.05858) by Nitish Shirish Keskar*, Bryan McCann*, Lav R. Varshney, Caiming Xiong and Richard Socher. -1. **[CvT](model_doc/cvt)** (from Microsoft) released with the paper [CvT: Introducing Convolutions to Vision Transformers](https://huggingface.co/papers/2103.15808) by Haiping Wu, Bin Xiao, Noel Codella, Mengchen Liu, Xiyang Dai, Lu Yuan, Lei Zhang. -1. **[Data2Vec](model_doc/data2vec)** (from Facebook) released with the paper [Data2Vec: A General Framework for Self-supervised Learning in Speech, Vision and Language](https://huggingface.co/papers/2202.03555) by Alexei Baevski, Wei-Ning Hsu, Qiantong Xu, Arun Babu, Jiatao Gu, Michael Auli. -1. **[DeBERTa](model_doc/deberta)** (from Microsoft) released with the paper [DeBERTa: Decoding-enhanced BERT with Disentangled Attention](https://huggingface.co/papers/2006.03654) by Pengcheng He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen. -1. **[DeBERTa-v2](model_doc/deberta-v2)** (from Microsoft) released with the paper [DeBERTa: Decoding-enhanced BERT with Disentangled Attention](https://huggingface.co/papers/2006.03654) by Pengcheng He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen. -1. **[Decision Transformer](model_doc/decision_transformer)** (from Berkeley/Facebook/Google) released with the paper [Decision Transformer: Reinforcement Learning via Sequence Modeling](https://huggingface.co/papers/2106.01345) by Lili Chen, Kevin Lu, Aravind Rajeswaran, Kimin Lee, Aditya Grover, Michael Laskin, Pieter Abbeel, Aravind Srinivas, Igor Mordatch. -1. **[Deformable DETR](model_doc/deformable_detr)** (from SenseTime Research) released with the paper [Deformable DETR: Deformable Transformers for End-to-End Object Detection](https://huggingface.co/papers/2010.04159) by Xizhou Zhu, Weijie Su, Lewei Lu, Bin Li, Xiaogang Wang, Jifeng Dai. -1. **[DeiT](model_doc/deit)** (from Facebook) released with the paper [Training data-efficient image transformers & distillation through attention](https://huggingface.co/papers/2012.12877) by Hugo Touvron, Matthieu Cord, Matthijs Douze, Francisco Massa, Alexandre Sablayrolles, Hervé Jégou. -1. **[DePlot](model_doc/deplot)** (from Google AI) released with the paper [DePlot: One-shot visual language reasoning by plot-to-table translation](https://huggingface.co/papers/2212.10505) by Fangyu Liu, Julian Martin Eisenschlos, Francesco Piccinno, Syrine Krichene, Chenxi Pang, Kenton Lee, Mandar Joshi, Wenhu Chen, Nigel Collier, Yasemin Altun. -1. **[DETA](model_doc/deta)** (from The University of Texas at Austin) released with the paper [NMS Strikes Back](https://huggingface.co/papers/2212.06137) by Jeffrey Ouyang-Zhang, Jang Hyun Cho, Xingyi Zhou, Philipp Krähenbühl. -1. **[DETR](model_doc/detr)** (from Facebook) released with the paper [End-to-End Object Detection with Transformers](https://huggingface.co/papers/2005.12872) by Nicolas Carion, Francisco Massa, Gabriel Synnaeve, Nicolas Usunier, Alexander Kirillov, Sergey Zagoruyko. -1. **[DialoGPT](model_doc/dialogpt)** (from Microsoft Research) released with the paper [DialoGPT: Large-Scale Generative Pre-training for Conversational Response Generation](https://huggingface.co/papers/1911.00536) by Yizhe Zhang, Siqi Sun, Michel Galley, Yen-Chun Chen, Chris Brockett, Xiang Gao, Jianfeng Gao, Jingjing Liu, Bill Dolan. -1. **[DiNAT](model_doc/dinat)** (from SHI Labs) released with the paper [Dilated Neighborhood Attention Transformer](https://huggingface.co/papers/2209.15001) by Ali Hassani and Humphrey Shi. -1. **[DistilBERT](model_doc/distilbert)** (from HuggingFace), released together with the paper [DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter](https://huggingface.co/papers/1910.01108) by Victor Sanh, Lysandre Debut and Thomas Wolf. The same method has been applied to compress GPT2 into [DistilGPT2](https://github.com/huggingface/transformers-research-projects/tree/main/distillation), RoBERTa into [DistilRoBERTa](https://github.com/huggingface/transformers-research-projects/tree/main/distillation), Multilingual BERT into [DistilmBERT](https://github.com/huggingface/transformers-research-projects/tree/main/distillation) and a German version of DistilBERT. -1. **[DiT](model_doc/dit)** (from Microsoft Research) released with the paper [DiT: Self-supervised Pre-training for Document Image Transformer](https://huggingface.co/papers/2203.02378) by Junlong Li, Yiheng Xu, Tengchao Lv, Lei Cui, Cha Zhang, Furu Wei. -1. **[Donut](model_doc/donut)** (from NAVER), released together with the paper [OCR-free Document Understanding Transformer](https://huggingface.co/papers/2111.15664) by Geewook Kim, Teakgyu Hong, Moonbin Yim, Jeongyeon Nam, Jinyoung Park, Jinyeong Yim, Wonseok Hwang, Sangdoo Yun, Dongyoon Han, Seunghyun Park. -1. **[DPR](model_doc/dpr)** (from Facebook) released with the paper [Dense Passage Retrieval for Open-Domain Question Answering](https://huggingface.co/papers/2004.04906) by Vladimir Karpukhin, Barlas Oğuz, Sewon Min, Patrick Lewis, Ledell Wu, Sergey Edunov, Danqi Chen, and Wen-tau Yih. -1. **[DPT](master/model_doc/dpt)** (from Intel Labs) released with the paper [Vision Transformers for Dense Prediction](https://huggingface.co/papers/2103.13413) by René Ranftl, Alexey Bochkovskiy, Vladlen Koltun. -1. **[EfficientFormer](model_doc/efficientformer)** (from Snap Research) released with the paper [EfficientFormer: Vision Transformers at MobileNetSpeed](https://huggingface.co/papers/2206.01191) by Yanyu Li, Geng Yuan, Yang Wen, Ju Hu, Georgios Evangelidis, Sergey Tulyakov, Yanzhi Wang, Jian Ren. -1. **[EfficientNet](model_doc/efficientnet)** (from Google Brain) released with the paper [EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks](https://huggingface.co/papers/1905.11946) by Mingxing Tan, Quoc V. Le. -1. **[ELECTRA](model_doc/electra)** (from Google Research/Stanford University) released with the paper [ELECTRA: Pre-training text encoders as discriminators rather than generators](https://huggingface.co/papers/2003.10555) by Kevin Clark, Minh-Thang Luong, Quoc V. Le, Christopher D. Manning. -1. **[EncoderDecoder](model_doc/encoder-decoder)** (from Google Research) released with the paper [Leveraging Pre-trained Checkpoints for Sequence Generation Tasks](https://huggingface.co/papers/1907.12461) by Sascha Rothe, Shashi Narayan, Aliaksei Severyn. -1. **[ERNIE](model_doc/ernie)** (from Baidu) released with the paper [ERNIE: Enhanced Representation through Knowledge Integration](https://huggingface.co/papers/1904.09223) by Yu Sun, Shuohuan Wang, Yukun Li, Shikun Feng, Xuyi Chen, Han Zhang, Xin Tian, Danxiang Zhu, Hao Tian, Hua Wu. -1. **[ErnieM](model_doc/ernie_m)** (from Baidu) released with the paper [ERNIE-M: Enhanced Multilingual Representation by Aligning Cross-lingual Semantics with Monolingual Corpora](https://huggingface.co/papers/2012.15674) by Xuan Ouyang, Shuohuan Wang, Chao Pang, Yu Sun, Hao Tian, Hua Wu, Haifeng Wang. -1. **[ESM](model_doc/esm)** (from Meta AI) are transformer protein language models. **ESM-1b** was released with the paper [Biological structure and function emerge from scaling unsupervised learning to 250 million protein sequences](https://www.pnas.org/content/118/15/e2016239118) by Alexander Rives, Joshua Meier, Tom Sercu, Siddharth Goyal, Zeming Lin, Jason Liu, Demi Guo, Myle Ott, C. Lawrence Zitnick, Jerry Ma, and Rob Fergus. **ESM-1v** was released with the paper [Language models enable zero-shot prediction of the effects of mutations on protein function](https://doi.org/10.1101/2021.07.09.450648) by Joshua Meier, Roshan Rao, Robert Verkuil, Jason Liu, Tom Sercu and Alexander Rives. **ESM-2 and ESMFold** were released with the paper [Language models of protein sequences at the scale of evolution enable accurate structure prediction](https://doi.org/10.1101/2022.07.20.500902) by Zeming Lin, Halil Akin, Roshan Rao, Brian Hie, Zhongkai Zhu, Wenting Lu, Allan dos Santos Costa, Maryam Fazel-Zarandi, Tom Sercu, Sal Candido, Alexander Rives. -1. **[FLAN-T5](model_doc/flan-t5)** (from Google AI) released in the repository [google-research/t5x](https://github.com/google-research/t5x/blob/main/docs/models.md#flan-t5-checkpoints) by Hyung Won Chung, Le Hou, Shayne Longpre, Barret Zoph, Yi Tay, William Fedus, Eric Li, Xuezhi Wang, Mostafa Dehghani, Siddhartha Brahma, Albert Webson, Shixiang Shane Gu, Zhuyun Dai, Mirac Suzgun, Xinyun Chen, Aakanksha Chowdhery, Sharan Narang, Gaurav Mishra, Adams Yu, Vincent Zhao, Yanping Huang, Andrew Dai, Hongkun Yu, Slav Petrov, Ed H. Chi, Jeff Dean, Jacob Devlin, Adam Roberts, Denny Zhou, Quoc V. Le, and Jason Wei -1. **[FLAN-UL2](model_doc/flan-ul2)** (from Google AI) released in the repository [google-research/t5x](https://github.com/google-research/t5x/blob/main/docs/models.md#flan-ul2-checkpoints) by Hyung Won Chung, Le Hou, Shayne Longpre, Barret Zoph, Yi Tay, William Fedus, Eric Li, Xuezhi Wang, Mostafa Dehghani, Siddhartha Brahma, Albert Webson, Shixiang Shane Gu, Zhuyun Dai, Mirac Suzgun, Xinyun Chen, Aakanksha Chowdhery, Sharan Narang, Gaurav Mishra, Adams Yu, Vincent Zhao, Yanping Huang, Andrew Dai, Hongkun Yu, Slav Petrov, Ed H. Chi, Jeff Dean, Jacob Devlin, Adam Roberts, Denny Zhou, Quoc V. Le, and Jason Wei -1. **[FlauBERT](model_doc/flaubert)** (from CNRS) released with the paper [FlauBERT: Unsupervised Language Model Pre-training for French](https://huggingface.co/papers/1912.05372) by Hang Le, Loïc Vial, Jibril Frej, Vincent Segonne, Maximin Coavoux, Benjamin Lecouteux, Alexandre Allauzen, Benoît Crabbé, Laurent Besacier, Didier Schwab. -1. **[FLAVA](model_doc/flava)** (from Facebook AI) released with the paper [FLAVA: A Foundational Language And Vision Alignment Model](https://huggingface.co/papers/2112.04482) by Amanpreet Singh, Ronghang Hu, Vedanuj Goswami, Guillaume Couairon, Wojciech Galuba, Marcus Rohrbach, and Douwe Kiela. -1. **[FNet](model_doc/fnet)** (from Google Research) released with the paper [FNet: Mixing Tokens with Fourier Transforms](https://huggingface.co/papers/2105.03824) by James Lee-Thorp, Joshua Ainslie, Ilya Eckstein, Santiago Ontanon. -1. **[FocalNet](model_doc/focalnet)** (from Microsoft Research) released with the paper [Focal Modulation Networks](https://huggingface.co/papers/2203.11926) by Jianwei Yang, Chunyuan Li, Xiyang Dai, Lu Yuan, Jianfeng Gao. -1. **[Funnel Transformer](model_doc/funnel)** (from CMU/Google Brain) released with the paper [Funnel-Transformer: Filtering out Sequential Redundancy for Efficient Language Processing](https://huggingface.co/papers/2006.03236) by Zihang Dai, Guokun Lai, Yiming Yang, Quoc V. Le. -1. **[GIT](model_doc/git)** (from Microsoft Research) released with the paper [GIT: A Generative Image-to-text Transformer for Vision and Language](https://huggingface.co/papers/2205.14100) by Jianfeng Wang, Zhengyuan Yang, Xiaowei Hu, Linjie Li, Kevin Lin, Zhe Gan, Zicheng Liu, Ce Liu, Lijuan Wang. -1. **[GLPN](model_doc/glpn)** (from KAIST) released with the paper [Global-Local Path Networks for Monocular Depth Estimation with Vertical CutDepth](https://huggingface.co/papers/2201.07436) by Doyeon Kim, Woonghyun Ga, Pyungwhan Ahn, Donggyu Joo, Sehwan Chun, Junmo Kim. -1. **[GPT](model_doc/openai-gpt)** (from OpenAI) released with the paper [Improving Language Understanding by Generative Pre-Training](https://openai.com/research/language-unsupervised/) by Alec Radford, Karthik Narasimhan, Tim Salimans and Ilya Sutskever. -1. **[GPT Neo](model_doc/gpt_neo)** (from EleutherAI) released in the repository [EleutherAI/gpt-neo](https://github.com/EleutherAI/gpt-neo) by Sid Black, Stella Biderman, Leo Gao, Phil Wang and Connor Leahy. -1. **[GPT NeoX](model_doc/gpt_neox)** (from EleutherAI) released with the paper [GPT-NeoX-20B: An Open-Source Autoregressive Language Model](https://huggingface.co/papers/2204.06745) by Sid Black, Stella Biderman, Eric Hallahan, Quentin Anthony, Leo Gao, Laurence Golding, Horace He, Connor Leahy, Kyle McDonell, Jason Phang, Michael Pieler, USVSN Sai Prashanth, Shivanshu Purohit, Laria Reynolds, Jonathan Tow, Ben Wang, Samuel Weinbach -1. **[GPT NeoX Japanese](model_doc/gpt_neox_japanese)** (from ABEJA) released by Shinya Otani, Takayoshi Makabe, Anuj Arora, and Kyo Hattori. -1. **[GPT-2](model_doc/gpt2)** (from OpenAI) released with the paper [Language Models are Unsupervised Multitask Learners](https://openai.com/research/better-language-models/) by Alec Radford, Jeffrey Wu, Rewon Child, David Luan, Dario Amodei and Ilya Sutskever. -1. **[GPT-J](model_doc/gptj)** (from EleutherAI) released in the repository [kingoflolz/mesh-transformer-jax](https://github.com/kingoflolz/mesh-transformer-jax/) by Ben Wang and Aran Komatsuzaki. -1. **[GPT-Sw3](model_doc/gpt-sw3)** (from AI-Sweden) released with the paper [Lessons Learned from GPT-SW3: Building the First Large-Scale Generative Language Model for Swedish](http://www.lrec-conf.org/proceedings/lrec2022/pdf/2022.lrec-1.376.pdf) by Ariel Ekgren, Amaru Cuba Gyllensten, Evangelia Gogoulou, Alice Heiman, Severine Verlinden, Joey Öhman, Fredrik Carlsson, Magnus Sahlgren. -1. **[GPTBigCode](model_doc/gpt_bigcode)** (from BigCode) released with the paper [SantaCoder: don't reach for the stars!](https://huggingface.co/papers/2301.03988) by Loubna Ben Allal, Raymond Li, Denis Kocetkov, Chenghao Mou, Christopher Akiki, Carlos Munoz Ferrandis, Niklas Muennighoff, Mayank Mishra, Alex Gu, Manan Dey, Logesh Kumar Umapathi, Carolyn Jane Anderson, Yangtian Zi, Joel Lamy Poirier, Hailey Schoelkopf, Sergey Troshin, Dmitry Abulkhanov, Manuel Romero, Michael Lappert, Francesco De Toni, Bernardo García del Río, Qian Liu, Shamik Bose, Urvashi Bhattacharyya, Terry Yue Zhuo, Ian Yu, Paulo Villegas, Marco Zocca, Sourab Mangrulkar, David Lansky, Huu Nguyen, Danish Contractor, Luis Villa, Jia Li, Dzmitry Bahdanau, Yacine Jernite, Sean Hughes, Daniel Fried, Arjun Guha, Harm de Vries, Leandro von Werra. -1. **[GPTSAN-japanese](model_doc/gptsan-japanese)** released in the repository [tanreinama/GPTSAN](https://github.com/tanreinama/GPTSAN/blob/main/report/model.md) by Toshiyuki Sakamoto(tanreinama). -1. **[Graphormer](model_doc/graphormer)** (from Microsoft) released with the paper [Do Transformers Really Perform Bad for Graph Representation?](https://huggingface.co/papers/2106.05234) by Chengxuan Ying, Tianle Cai, Shengjie Luo, Shuxin Zheng, Guolin Ke, Di He, Yanming Shen, Tie-Yan Liu. -1. **[GroupViT](model_doc/groupvit)** (from UCSD, NVIDIA) released with the paper [GroupViT: Semantic Segmentation Emerges from Text Supervision](https://huggingface.co/papers/2202.11094) by Jiarui Xu, Shalini De Mello, Sifei Liu, Wonmin Byeon, Thomas Breuel, Jan Kautz, Xiaolong Wang. -1. **[Hubert](model_doc/hubert)** (from Facebook) released with the paper [HuBERT: Self-Supervised Speech Representation Learning by Masked Prediction of Hidden Units](https://huggingface.co/papers/2106.07447) by Wei-Ning Hsu, Benjamin Bolte, Yao-Hung Hubert Tsai, Kushal Lakhotia, Ruslan Salakhutdinov, Abdelrahman Mohamed. -1. **[I-BERT](model_doc/ibert)** (from Berkeley) released with the paper [I-BERT: Integer-only BERT Quantization](https://huggingface.co/papers/2101.01321) by Sehoon Kim, Amir Gholami, Zhewei Yao, Michael W. Mahoney, Kurt Keutzer. -1. **[ImageGPT](model_doc/imagegpt)** (from OpenAI) released with the paper [Generative Pretraining from Pixels](https://openai.com/blog/image-gpt/) by Mark Chen, Alec Radford, Rewon Child, Jeffrey Wu, Heewoo Jun, David Luan, Ilya Sutskever. -1. **[Informer](model_doc/informer)** (from Beihang University, UC Berkeley, Rutgers University, SEDD Company) released with the paper [Informer: Beyond Efficient Transformer for Long Sequence Time-Series Forecasting](https://huggingface.co/papers/2012.07436) by Haoyi Zhou, Shanghang Zhang, Jieqi Peng, Shuai Zhang, Jianxin Li, Hui Xiong, and Wancai Zhang. -1. **[Jukebox](model_doc/jukebox)** (from OpenAI) released with the paper [Jukebox: A Generative Model for Music](https://huggingface.co/papers/2005.00341) by Prafulla Dhariwal, Heewoo Jun, Christine Payne, Jong Wook Kim, Alec Radford, Ilya Sutskever. -1. **[LayoutLM](model_doc/layoutlm)** (from Microsoft Research Asia) released with the paper [LayoutLM: Pre-training of Text and Layout for Document Image Understanding](https://huggingface.co/papers/1912.13318) by Yiheng Xu, Minghao Li, Lei Cui, Shaohan Huang, Furu Wei, Ming Zhou. -1. **[LayoutLMv2](model_doc/layoutlmv2)** (from Microsoft Research Asia) released with the paper [LayoutLMv2: Multi-modal Pre-training for Visually-Rich Document Understanding](https://huggingface.co/papers/2012.14740) by Yang Xu, Yiheng Xu, Tengchao Lv, Lei Cui, Furu Wei, Guoxin Wang, Yijuan Lu, Dinei Florencio, Cha Zhang, Wanxiang Che, Min Zhang, Lidong Zhou. -1. **[LayoutLMv3](model_doc/layoutlmv3)** (from Microsoft Research Asia) released with the paper [LayoutLMv3: Pre-training for Document AI with Unified Text and Image Masking](https://huggingface.co/papers/2204.08387) by Yupan Huang, Tengchao Lv, Lei Cui, Yutong Lu, Furu Wei. -1. **[LayoutXLM](model_doc/layoutxlm)** (from Microsoft Research Asia) released with the paper [LayoutXLM: Multimodal Pre-training for Multilingual Visually-rich Document Understanding](https://huggingface.co/papers/2104.08836) by Yiheng Xu, Tengchao Lv, Lei Cui, Guoxin Wang, Yijuan Lu, Dinei Florencio, Cha Zhang, Furu Wei. -1. **[LED](model_doc/led)** (from AllenAI) released with the paper [Longformer: The Long-Document Transformer](https://huggingface.co/papers/2004.05150) by Iz Beltagy, Matthew E. Peters, Arman Cohan. -1. **[LeViT](model_doc/levit)** (from Meta AI) released with the paper [LeViT: A Vision Transformer in ConvNet's Clothing for Faster Inference](https://huggingface.co/papers/2104.01136) by Ben Graham, Alaaeldin El-Nouby, Hugo Touvron, Pierre Stock, Armand Joulin, Hervé Jégou, Matthijs Douze. -1. **[LiLT](model_doc/lilt)** (from South China University of Technology) released with the paper [LiLT: A Simple yet Effective Language-Independent Layout Transformer for Structured Document Understanding](https://huggingface.co/papers/2202.13669) by Jiapeng Wang, Lianwen Jin, Kai Ding. -1. **[LLaMA](model_doc/llama)** (from The FAIR team of Meta AI) released with the paper [LLaMA: Open and Efficient Foundation Language Models](https://huggingface.co/papers/2302.13971) by Hugo Touvron, Thibaut Lavril, Gautier Izacard, Xavier Martinet, Marie-Anne Lachaux, Timothée Lacroix, Baptiste Rozière, Naman Goyal, Eric Hambro, Faisal Azhar, Aurelien Rodriguez, Armand Joulin, Edouard Grave, Guillaume Lample. -1. **[Longformer](model_doc/longformer)** (from AllenAI) released with the paper [Longformer: The Long-Document Transformer](https://huggingface.co/papers/2004.05150) by Iz Beltagy, Matthew E. Peters, Arman Cohan. -1. **[LongT5](model_doc/longt5)** (from Google AI) released with the paper [LongT5: Efficient Text-To-Text Transformer for Long Sequences](https://huggingface.co/papers/2112.07916) by Mandy Guo, Joshua Ainslie, David Uthus, Santiago Ontanon, Jianmo Ni, Yun-Hsuan Sung, Yinfei Yang. -1. **[LUKE](model_doc/luke)** (from Studio Ousia) released with the paper [LUKE: Deep Contextualized Entity Representations with Entity-aware Self-attention](https://huggingface.co/papers/2010.01057) by Ikuya Yamada, Akari Asai, Hiroyuki Shindo, Hideaki Takeda, Yuji Matsumoto. -1. **[LXMERT](model_doc/lxmert)** (from UNC Chapel Hill) released with the paper [LXMERT: Learning Cross-Modality Encoder Representations from Transformers for Open-Domain Question Answering](https://huggingface.co/papers/1908.07490) by Hao Tan and Mohit Bansal. -1. **[M-CTC-T](model_doc/mctct)** (from Facebook) released with the paper [Pseudo-Labeling For Massively Multilingual Speech Recognition](https://huggingface.co/papers/2111.00161) by Loren Lugosch, Tatiana Likhomanenko, Gabriel Synnaeve, and Ronan Collobert. -1. **[M2M100](model_doc/m2m_100)** (from Facebook) released with the paper [Beyond English-Centric Multilingual Machine Translation](https://huggingface.co/papers/2010.11125) by Angela Fan, Shruti Bhosale, Holger Schwenk, Zhiyi Ma, Ahmed El-Kishky, Siddharth Goyal, Mandeep Baines, Onur Celebi, Guillaume Wenzek, Vishrav Chaudhary, Naman Goyal, Tom Birch, Vitaliy Liptchinsky, Sergey Edunov, Edouard Grave, Michael Auli, Armand Joulin. -1. **[MarianMT](model_doc/marian)** Machine translation models trained using [OPUS](http://opus.nlpl.eu/) data by Jörg Tiedemann. The [Marian Framework](https://marian-nmt.github.io/) is being developed by the Microsoft Translator Team. -1. **[MarkupLM](model_doc/markuplm)** (from Microsoft Research Asia) released with the paper [MarkupLM: Pre-training of Text and Markup Language for Visually-rich Document Understanding](https://huggingface.co/papers/2110.08518) by Junlong Li, Yiheng Xu, Lei Cui, Furu Wei. -1. **[Mask2Former](model_doc/mask2former)** (from FAIR and UIUC) released with the paper [Masked-attention Mask Transformer for Universal Image Segmentation](https://huggingface.co/papers/2112.01527) by Bowen Cheng, Ishan Misra, Alexander G. Schwing, Alexander Kirillov, Rohit Girdhar. -1. **[MaskFormer](model_doc/maskformer)** (from Meta and UIUC) released with the paper [Per-Pixel Classification is Not All You Need for Semantic Segmentation](https://huggingface.co/papers/2107.06278) by Bowen Cheng, Alexander G. Schwing, Alexander Kirillov. -1. **[MatCha](model_doc/matcha)** (from Google AI) released with the paper [MatCha: Enhancing Visual Language Pretraining with Math Reasoning and Chart Derendering](https://huggingface.co/papers/2212.09662) by Fangyu Liu, Francesco Piccinno, Syrine Krichene, Chenxi Pang, Kenton Lee, Mandar Joshi, Yasemin Altun, Nigel Collier, Julian Martin Eisenschlos. -1. **[mBART](model_doc/mbart)** (from Facebook) released with the paper [Multilingual Denoising Pre-training for Neural Machine Translation](https://huggingface.co/papers/2001.08210) by Yinhan Liu, Jiatao Gu, Naman Goyal, Xian Li, Sergey Edunov, Marjan Ghazvininejad, Mike Lewis, Luke Zettlemoyer. -1. **[mBART-50](model_doc/mbart)** (from Facebook) released with the paper [Multilingual Translation with Extensible Multilingual Pretraining and Finetuning](https://huggingface.co/papers/2008.00401) by Yuqing Tang, Chau Tran, Xian Li, Peng-Jen Chen, Naman Goyal, Vishrav Chaudhary, Jiatao Gu, Angela Fan. -1. **[MEGA](model_doc/mega)** (from Meta/USC/CMU/SJTU) released with the paper [Mega: Moving Average Equipped Gated Attention](https://huggingface.co/papers/2209.10655) by Xuezhe Ma, Chunting Zhou, Xiang Kong, Junxian He, Liangke Gui, Graham Neubig, Jonathan May, and Luke Zettlemoyer. -1. **[Megatron-BERT](model_doc/megatron-bert)** (from NVIDIA) released with the paper [Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism](https://huggingface.co/papers/1909.08053) by Mohammad Shoeybi, Mostofa Patwary, Raul Puri, Patrick LeGresley, Jared Casper and Bryan Catanzaro. -1. **[Megatron-GPT2](model_doc/megatron_gpt2)** (from NVIDIA) released with the paper [Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism](https://huggingface.co/papers/1909.08053) by Mohammad Shoeybi, Mostofa Patwary, Raul Puri, Patrick LeGresley, Jared Casper and Bryan Catanzaro. -1. **[MGP-STR](model_doc/mgp-str)** (from Alibaba Research) released with the paper [Multi-Granularity Prediction for Scene Text Recognition](https://huggingface.co/papers/2209.03592) by Peng Wang, Cheng Da, and Cong Yao. -1. **[mLUKE](model_doc/mluke)** (from Studio Ousia) released with the paper [mLUKE: The Power of Entity Representations in Multilingual Pretrained Language Models](https://huggingface.co/papers/2110.08151) by Ryokan Ri, Ikuya Yamada, and Yoshimasa Tsuruoka. -1. **[MobileBERT](model_doc/mobilebert)** (from CMU/Google Brain) released with the paper [MobileBERT: a Compact Task-Agnostic BERT for Resource-Limited Devices](https://huggingface.co/papers/2004.02984) by Zhiqing Sun, Hongkun Yu, Xiaodan Song, Renjie Liu, Yiming Yang, and Denny Zhou. -1. **[MobileNetV1](model_doc/mobilenet_v1)** (from Google Inc.) released with the paper [MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications](https://huggingface.co/papers/1704.04861) by Andrew G. Howard, Menglong Zhu, Bo Chen, Dmitry Kalenichenko, Weijun Wang, Tobias Weyand, Marco Andreetto, Hartwig Adam. -1. **[MobileNetV2](model_doc/mobilenet_v2)** (from Google Inc.) released with the paper [MobileNetV2: Inverted Residuals and Linear Bottlenecks](https://huggingface.co/papers/1801.04381) by Mark Sandler, Andrew Howard, Menglong Zhu, Andrey Zhmoginov, Liang-Chieh Chen. -1. **[MobileViT](model_doc/mobilevit)** (from Apple) released with the paper [MobileViT: Light-weight, General-purpose, and Mobile-friendly Vision Transformer](https://huggingface.co/papers/2110.02178) by Sachin Mehta and Mohammad Rastegari. -1. **[MPNet](model_doc/mpnet)** (from Microsoft Research) released with the paper [MPNet: Masked and Permuted Pre-training for Language Understanding](https://huggingface.co/papers/2004.09297) by Kaitao Song, Xu Tan, Tao Qin, Jianfeng Lu, Tie-Yan Liu. -1. **[MT5](model_doc/mt5)** (from Google AI) released with the paper [mT5: A massively multilingual pre-trained text-to-text transformer](https://huggingface.co/papers/2010.11934) by Linting Xue, Noah Constant, Adam Roberts, Mihir Kale, Rami Al-Rfou, Aditya Siddhant, Aditya Barua, Colin Raffel. -1. **[MVP](model_doc/mvp)** (from RUC AI Box) released with the paper [MVP: Multi-task Supervised Pre-training for Natural Language Generation](https://huggingface.co/papers/2206.12131) by Tianyi Tang, Junyi Li, Wayne Xin Zhao and Ji-Rong Wen. -1. **[NAT](model_doc/nat)** (from SHI Labs) released with the paper [Neighborhood Attention Transformer](https://huggingface.co/papers/2204.07143) by Ali Hassani, Steven Walton, Jiachen Li, Shen Li, and Humphrey Shi. -1. **[Nezha](model_doc/nezha)** (from Huawei Noah’s Ark Lab) released with the paper [NEZHA: Neural Contextualized Representation for Chinese Language Understanding](https://huggingface.co/papers/1909.00204) by Junqiu Wei, Xiaozhe Ren, Xiaoguang Li, Wenyong Huang, Yi Liao, Yasheng Wang, Jiashu Lin, Xin Jiang, Xiao Chen and Qun Liu. -1. **[NLLB](model_doc/nllb)** (from Meta) released with the paper [No Language Left Behind: Scaling Human-Centered Machine Translation](https://huggingface.co/papers/2207.04672) by the NLLB team. -1. **[NLLB-MOE](model_doc/nllb-moe)** (from Meta) released with the paper [No Language Left Behind: Scaling Human-Centered Machine Translation](https://huggingface.co/papers/2207.04672) by the NLLB team. -1. **[Nyströmformer](model_doc/nystromformer)** (from the University of Wisconsin - Madison) released with the paper [Nyströmformer: A Nyström-Based Algorithm for Approximating Self-Attention](https://huggingface.co/papers/2102.03902) by Yunyang Xiong, Zhanpeng Zeng, Rudrasis Chakraborty, Mingxing Tan, Glenn Fung, Yin Li, Vikas Singh. -1. **[OneFormer](model_doc/oneformer)** (from SHI Labs) released with the paper [OneFormer: One Transformer to Rule Universal Image Segmentation](https://huggingface.co/papers/2211.06220) by Jitesh Jain, Jiachen Li, MangTik Chiu, Ali Hassani, Nikita Orlov, Humphrey Shi. -1. **[OpenLlama](model_doc/open-llama)** (from [s-JoL](https://huggingface.co/s-JoL)) released on GitHub (now removed). -1. **[OPT](master/model_doc/opt)** (from Meta AI) released with the paper [OPT: Open Pre-trained Transformer Language Models](https://huggingface.co/papers/2205.01068) by Susan Zhang, Stephen Roller, Naman Goyal, Mikel Artetxe, Moya Chen, Shuohui Chen et al. -1. **[OWL-ViT](model_doc/owlvit)** (from Google AI) released with the paper [Simple Open-Vocabulary Object Detection with Vision Transformers](https://huggingface.co/papers/2205.06230) by Matthias Minderer, Alexey Gritsenko, Austin Stone, Maxim Neumann, Dirk Weissenborn, Alexey Dosovitskiy, Aravindh Mahendran, Anurag Arnab, Mostafa Dehghani, Zhuoran Shen, Xiao Wang, Xiaohua Zhai, Thomas Kipf, and Neil Houlsby. -1. **[Pegasus](model_doc/pegasus)** (from Google) released with the paper [PEGASUS: Pre-training with Extracted Gap-sentences for Abstractive Summarization](https://huggingface.co/papers/1912.08777) by Jingqing Zhang, Yao Zhao, Mohammad Saleh and Peter J. Liu. -1. **[PEGASUS-X](model_doc/pegasus_x)** (from Google) released with the paper [Investigating Efficiently Extending Transformers for Long Input Summarization](https://huggingface.co/papers/2208.04347) by Jason Phang, Yao Zhao, and Peter J. Liu. -1. **[Perceiver IO](model_doc/perceiver)** (from Deepmind) released with the paper [Perceiver IO: A General Architecture for Structured Inputs & Outputs](https://huggingface.co/papers/2107.14795) by Andrew Jaegle, Sebastian Borgeaud, Jean-Baptiste Alayrac, Carl Doersch, Catalin Ionescu, David Ding, Skanda Koppula, Daniel Zoran, Andrew Brock, Evan Shelhamer, Olivier Hénaff, Matthew M. Botvinick, Andrew Zisserman, Oriol Vinyals, João Carreira. -1. **[PhoBERT](model_doc/phobert)** (from VinAI Research) released with the paper [PhoBERT: Pre-trained language models for Vietnamese](https://www.aclweb.org/anthology/2020.findings-emnlp.92/) by Dat Quoc Nguyen and Anh Tuan Nguyen. -1. **[Pix2Struct](model_doc/pix2struct)** (from Google) released with the paper [Pix2Struct: Screenshot Parsing as Pretraining for Visual Language Understanding](https://huggingface.co/papers/2210.03347) by Kenton Lee, Mandar Joshi, Iulia Turc, Hexiang Hu, Fangyu Liu, Julian Eisenschlos, Urvashi Khandelwal, Peter Shaw, Ming-Wei Chang, Kristina Toutanova. -1. **[PLBart](model_doc/plbart)** (from UCLA NLP) released with the paper [Unified Pre-training for Program Understanding and Generation](https://huggingface.co/papers/2103.06333) by Wasi Uddin Ahmad, Saikat Chakraborty, Baishakhi Ray, Kai-Wei Chang. -1. **[PoolFormer](model_doc/poolformer)** (from Sea AI Labs) released with the paper [MetaFormer is Actually What You Need for Vision](https://huggingface.co/papers/2111.11418) by Yu, Weihao and Luo, Mi and Zhou, Pan and Si, Chenyang and Zhou, Yichen and Wang, Xinchao and Feng, Jiashi and Yan, Shuicheng. -1. **[ProphetNet](model_doc/prophetnet)** (from Microsoft Research) released with the paper [ProphetNet: Predicting Future N-gram for Sequence-to-Sequence Pre-training](https://huggingface.co/papers/2001.04063) by Yu Yan, Weizhen Qi, Yeyun Gong, Dayiheng Liu, Nan Duan, Jiusheng Chen, Ruofei Zhang and Ming Zhou. -1. **[QDQBert](model_doc/qdqbert)** (from NVIDIA) released with the paper [Integer Quantization for Deep Learning Inference: Principles and Empirical Evaluation](https://huggingface.co/papers/2004.09602) by Hao Wu, Patrick Judd, Xiaojie Zhang, Mikhail Isaev and Paulius Micikevicius. -1. **[RAG](model_doc/rag)** (from Facebook) released with the paper [Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks](https://huggingface.co/papers/2005.11401) by Patrick Lewis, Ethan Perez, Aleksandara Piktus, Fabio Petroni, Vladimir Karpukhin, Naman Goyal, Heinrich Küttler, Mike Lewis, Wen-tau Yih, Tim Rocktäschel, Sebastian Riedel, Douwe Kiela. -1. **[REALM](model_doc/realm.html)** (from Google Research) released with the paper [REALM: Retrieval-Augmented Language Model Pre-Training](https://huggingface.co/papers/2002.08909) by Kelvin Guu, Kenton Lee, Zora Tung, Panupong Pasupat and Ming-Wei Chang. -1. **[Reformer](model_doc/reformer)** (from Google Research) released with the paper [Reformer: The Efficient Transformer](https://huggingface.co/papers/2001.04451) by Nikita Kitaev, Łukasz Kaiser, Anselm Levskaya. -1. **[RegNet](model_doc/regnet)** (from META Platforms) released with the paper [Designing Network Design Space](https://huggingface.co/papers/2003.13678) by Ilija Radosavovic, Raj Prateek Kosaraju, Ross Girshick, Kaiming He, Piotr Dollár. -1. **[RemBERT](model_doc/rembert)** (from Google Research) released with the paper [Rethinking embedding coupling in pre-trained language models](https://huggingface.co/papers/2010.12821) by Hyung Won Chung, Thibault Févry, Henry Tsai, M. Johnson, Sebastian Ruder. -1. **[ResNet](model_doc/resnet)** (from Microsoft Research) released with the paper [Deep Residual Learning for Image Recognition](https://huggingface.co/papers/1512.03385) by Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun. -1. **[RoBERTa](model_doc/roberta)** (from Facebook), released together with the paper [RoBERTa: A Robustly Optimized BERT Pretraining Approach](https://huggingface.co/papers/1907.11692) by Yinhan Liu, Myle Ott, Naman Goyal, Jingfei Du, Mandar Joshi, Danqi Chen, Omer Levy, Mike Lewis, Luke Zettlemoyer, Veselin Stoyanov. -1. **[RoBERTa-PreLayerNorm](model_doc/roberta-prelayernorm)** (from Facebook) released with the paper [fairseq: A Fast, Extensible Toolkit for Sequence Modeling](https://huggingface.co/papers/1904.01038) by Myle Ott, Sergey Edunov, Alexei Baevski, Angela Fan, Sam Gross, Nathan Ng, David Grangier, Michael Auli. -1. **[RoCBert](model_doc/roc_bert)** (from WeChatAI) released with the paper [RoCBert: Robust Chinese Bert with Multimodal Contrastive Pretraining](https://aclanthology.org/2022.acl-long.65.pdf) by HuiSu, WeiweiShi, XiaoyuShen, XiaoZhou, TuoJi, JiaruiFang, JieZhou. -1. **[RoFormer](model_doc/roformer)** (from ZhuiyiTechnology), released together with the paper [RoFormer: Enhanced Transformer with Rotary Position Embedding](https://huggingface.co/papers/2104.09864) by Jianlin Su and Yu Lu and Shengfeng Pan and Bo Wen and Yunfeng Liu. -1. **[RWKV](model_doc/rwkv)** (from Bo Peng), released on [this repo](https://github.com/BlinkDL/RWKV-LM) by Bo Peng. -1. **[SegFormer](model_doc/segformer)** (from NVIDIA) released with the paper [SegFormer: Simple and Efficient Design for Semantic Segmentation with Transformers](https://huggingface.co/papers/2105.15203) by Enze Xie, Wenhai Wang, Zhiding Yu, Anima Anandkumar, Jose M. Alvarez, Ping Luo. -1. **[Segment Anything](model_doc/sam)** (from Meta AI) released with the paper [Segment Anything](https://huggingface.co/papers/2304.02643) by Alexander Kirillov, Eric Mintun, Nikhila Ravi, Hanzi Mao, Chloe Rolland, Laura Gustafson, Tete Xiao, Spencer Whitehead, Alex Berg, Wan-Yen Lo, Piotr Dollar, Ross Girshick. -1. **[SEW](model_doc/sew)** (from ASAPP) released with the paper [Performance-Efficiency Trade-offs in Unsupervised Pre-training for Speech Recognition](https://huggingface.co/papers/2109.06870) by Felix Wu, Kwangyoun Kim, Jing Pan, Kyu Han, Kilian Q. Weinberger, Yoav Artzi. -1. **[SEW-D](model_doc/sew_d)** (from ASAPP) released with the paper [Performance-Efficiency Trade-offs in Unsupervised Pre-training for Speech Recognition](https://huggingface.co/papers/2109.06870) by Felix Wu, Kwangyoun Kim, Jing Pan, Kyu Han, Kilian Q. Weinberger, Yoav Artzi. -1. **[SpeechT5](model_doc/speecht5)** (from Microsoft Research) released with the paper [SpeechT5: Unified-Modal Encoder-Decoder Pre-Training for Spoken Language Processing](https://huggingface.co/papers/2110.07205) by Junyi Ao, Rui Wang, Long Zhou, Chengyi Wang, Shuo Ren, Yu Wu, Shujie Liu, Tom Ko, Qing Li, Yu Zhang, Zhihua Wei, Yao Qian, Jinyu Li, Furu Wei. -1. **[SpeechToTextTransformer](model_doc/speech_to_text)** (from Facebook), released together with the paper [fairseq S2T: Fast Speech-to-Text Modeling with fairseq](https://huggingface.co/papers/2010.05171) by Changhan Wang, Yun Tang, Xutai Ma, Anne Wu, Dmytro Okhonko, Juan Pino. -1. **[SpeechToTextTransformer2](model_doc/speech_to_text_2)** (from Facebook), released together with the paper [Large-Scale Self- and Semi-Supervised Learning for Speech Translation](https://huggingface.co/papers/2104.06678) by Changhan Wang, Anne Wu, Juan Pino, Alexei Baevski, Michael Auli, Alexis Conneau. -1. **[Splinter](model_doc/splinter)** (from Tel Aviv University), released together with the paper [Few-Shot Question Answering by Pretraining Span Selection](https://huggingface.co/papers/2101.00438) by Ori Ram, Yuval Kirstain, Jonathan Berant, Amir Globerson, Omer Levy. -1. **[SqueezeBERT](model_doc/squeezebert)** (from Berkeley) released with the paper [SqueezeBERT: What can computer vision teach NLP about efficient neural networks?](https://huggingface.co/papers/2006.11316) by Forrest N. Iandola, Albert E. Shaw, Ravi Krishna, and Kurt W. Keutzer. -1. **[SwiftFormer](model_doc/swiftformer)** (from MBZUAI) released with the paper [SwiftFormer: Efficient Additive Attention for Transformer-based Real-time Mobile Vision Applications](https://huggingface.co/papers/2303.15446) by Abdelrahman Shaker, Muhammad Maaz, Hanoona Rasheed, Salman Khan, Ming-Hsuan Yang, Fahad Shahbaz Khan. -1. **[Swin Transformer](model_doc/swin)** (from Microsoft) released with the paper [Swin Transformer: Hierarchical Vision Transformer using Shifted Windows](https://huggingface.co/papers/2103.14030) by Ze Liu, Yutong Lin, Yue Cao, Han Hu, Yixuan Wei, Zheng Zhang, Stephen Lin, Baining Guo. -1. **[Swin Transformer V2](model_doc/swinv2)** (from Microsoft) released with the paper [Swin Transformer V2: Scaling Up Capacity and Resolution](https://huggingface.co/papers/2111.09883) by Ze Liu, Han Hu, Yutong Lin, Zhuliang Yao, Zhenda Xie, Yixuan Wei, Jia Ning, Yue Cao, Zheng Zhang, Li Dong, Furu Wei, Baining Guo. -1. **[Swin2SR](model_doc/swin2sr)** (from University of Würzburg) released with the paper [Swin2SR: SwinV2 Transformer for Compressed Image Super-Resolution and Restoration](https://huggingface.co/papers/2209.11345) by Marcos V. Conde, Ui-Jin Choi, Maxime Burchi, Radu Timofte. -1. **[SwitchTransformers](model_doc/switch_transformers)** (from Google) released with the paper [Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity](https://huggingface.co/papers/2101.03961) by William Fedus, Barret Zoph, Noam Shazeer. -1. **[T5](model_doc/t5)** (from Google AI) released with the paper [Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer](https://huggingface.co/papers/1910.10683) by Colin Raffel and Noam Shazeer and Adam Roberts and Katherine Lee and Sharan Narang and Michael Matena and Yanqi Zhou and Wei Li and Peter J. Liu. -1. **[T5v1.1](model_doc/t5v1.1)** (from Google AI) released in the repository [google-research/text-to-text-transfer-transformer](https://github.com/google-research/text-to-text-transfer-transformer/blob/main/released_checkpoints.md#t511) by Colin Raffel and Noam Shazeer and Adam Roberts and Katherine Lee and Sharan Narang and Michael Matena and Yanqi Zhou and Wei Li and Peter J. Liu. -1. **[Table Transformer](model_doc/table-transformer)** (from Microsoft Research) released with the paper [PubTables-1M: Towards Comprehensive Table Extraction From Unstructured Documents](https://huggingface.co/papers/2110.00061) by Brandon Smock, Rohith Pesala, Robin Abraham. -1. **[TAPAS](model_doc/tapas)** (from Google AI) released with the paper [TAPAS: Weakly Supervised Table Parsing via Pre-training](https://huggingface.co/papers/2004.02349) by Jonathan Herzig, Paweł Krzysztof Nowak, Thomas Müller, Francesco Piccinno and Julian Martin Eisenschlos. -1. **[TAPEX](model_doc/tapex)** (from Microsoft Research) released with the paper [TAPEX: Table Pre-training via Learning a Neural SQL Executor](https://huggingface.co/papers/2107.07653) by Qian Liu, Bei Chen, Jiaqi Guo, Morteza Ziyadi, Zeqi Lin, Weizhu Chen, Jian-Guang Lou. -1. **[Time Series Transformer](model_doc/time_series_transformer)** (from HuggingFace). -1. **[TimeSformer](model_doc/timesformer)** (from Facebook) released with the paper [Is Space-Time Attention All You Need for Video Understanding?](https://huggingface.co/papers/2102.05095) by Gedas Bertasius, Heng Wang, Lorenzo Torresani. -1. **[Trajectory Transformer](model_doc/trajectory_transformers)** (from the University of California at Berkeley) released with the paper [Offline Reinforcement Learning as One Big Sequence Modeling Problem](https://huggingface.co/papers/2106.02039) by Michael Janner, Qiyang Li, Sergey Levine -1. **[Transformer-XL](model_doc/transfo-xl)** (from Google/CMU) released with the paper [Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context](https://huggingface.co/papers/1901.02860) by Zihang Dai*, Zhilin Yang*, Yiming Yang, Jaime Carbonell, Quoc V. Le, Ruslan Salakhutdinov. -1. **[TrOCR](model_doc/trocr)** (from Microsoft), released together with the paper [TrOCR: Transformer-based Optical Character Recognition with Pre-trained Models](https://huggingface.co/papers/2109.10282) by Minghao Li, Tengchao Lv, Lei Cui, Yijuan Lu, Dinei Florencio, Cha Zhang, Zhoujun Li, Furu Wei. -1. **[TVLT](model_doc/tvlt)** (from UNC Chapel Hill) released with the paper [TVLT: Textless Vision-Language Transformer](https://huggingface.co/papers/2209.14156) by Zineng Tang, Jaemin Cho, Yixin Nie, Mohit Bansal. -1. **[TVP](model_doc/tvp)** (from Intel) released with the paper [Text-Visual Prompting for Efficient 2D Temporal Video Grounding](https://huggingface.co/papers/2303.04995) by Yimeng Zhang, Xin Chen, Jinghan Jia, Sijia Liu, Ke Ding. -1. **[UL2](model_doc/ul2)** (from Google Research) released with the paper [Unifying Language Learning Paradigms](https://huggingface.co/papers/2205.05131v1) by Yi Tay, Mostafa Dehghani, Vinh Q. Tran, Xavier Garcia, Dara Bahri, Tal Schuster, Huaixiu Steven Zheng, Neil Houlsby, Donald Metzler -1. **[UniSpeech](model_doc/unispeech)** (from Microsoft Research) released with the paper [UniSpeech: Unified Speech Representation Learning with Labeled and Unlabeled Data](https://huggingface.co/papers/2101.07597) by Chengyi Wang, Yu Wu, Yao Qian, Kenichi Kumatani, Shujie Liu, Furu Wei, Michael Zeng, Xuedong Huang. -1. **[UniSpeechSat](model_doc/unispeech-sat)** (from Microsoft Research) released with the paper [UNISPEECH-SAT: UNIVERSAL SPEECH REPRESENTATION LEARNING WITH SPEAKER AWARE PRE-TRAINING](https://huggingface.co/papers/2110.05752) by Sanyuan Chen, Yu Wu, Chengyi Wang, Zhengyang Chen, Zhuo Chen, Shujie Liu, Jian Wu, Yao Qian, Furu Wei, Jinyu Li, Xiangzhan Yu. -1. **[UPerNet](model_doc/upernet)** (from Peking University) released with the paper [Unified Perceptual Parsing for Scene Understanding](https://huggingface.co/papers/1807.10221) by Tete Xiao, Yingcheng Liu, Bolei Zhou, Yuning Jiang, Jian Sun. -1. **[VAN](model_doc/van)** (from Tsinghua University and Nankai University) released with the paper [Visual Attention Network](https://huggingface.co/papers/2202.09741) by Meng-Hao Guo, Cheng-Ze Lu, Zheng-Ning Liu, Ming-Ming Cheng, Shi-Min Hu. -1. **[VideoMAE](model_doc/videomae)** (from Multimedia Computing Group, Nanjing University) released with the paper [VideoMAE: Masked Autoencoders are Data-Efficient Learners for Self-Supervised Video Pre-Training](https://huggingface.co/papers/2203.12602) by Zhan Tong, Yibing Song, Jue Wang, Limin Wang. -1. **[ViLT](model_doc/vilt)** (from NAVER AI Lab/Kakao Enterprise/Kakao Brain) released with the paper [ViLT: Vision-and-Language Transformer Without Convolution or Region Supervision](https://huggingface.co/papers/2102.03334) by Wonjae Kim, Bokyung Son, Ildoo Kim. -1. **[Vision Transformer (ViT)](model_doc/vit)** (from Google AI) released with the paper [An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale](https://huggingface.co/papers/2010.11929) by Alexey Dosovitskiy, Lucas Beyer, Alexander Kolesnikov, Dirk Weissenborn, Xiaohua Zhai, Thomas Unterthiner, Mostafa Dehghani, Matthias Minderer, Georg Heigold, Sylvain Gelly, Jakob Uszkoreit, Neil Houlsby. -1. **[VisualBERT](model_doc/visual_bert)** (from UCLA NLP) released with the paper [VisualBERT: A Simple and Performant Baseline for Vision and Language](https://huggingface.co/papers/1908.03557) by Liunian Harold Li, Mark Yatskar, Da Yin, Cho-Jui Hsieh, Kai-Wei Chang. -1. **[ViT Hybrid](model_doc/vit_hybrid)** (from Google AI) released with the paper [An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale](https://huggingface.co/papers/2010.11929) by Alexey Dosovitskiy, Lucas Beyer, Alexander Kolesnikov, Dirk Weissenborn, Xiaohua Zhai, Thomas Unterthiner, Mostafa Dehghani, Matthias Minderer, Georg Heigold, Sylvain Gelly, Jakob Uszkoreit, Neil Houlsby. -1. **[ViTMAE](model_doc/vit_mae)** (from Meta AI) released with the paper [Masked Autoencoders Are Scalable Vision Learners](https://huggingface.co/papers/2111.06377) by Kaiming He, Xinlei Chen, Saining Xie, Yanghao Li, Piotr Dollár, Ross Girshick. -1. **[ViTMSN](model_doc/vit_msn)** (from Meta AI) released with the paper [Masked Siamese Networks for Label-Efficient Learning](https://huggingface.co/papers/2204.07141) by Mahmoud Assran, Mathilde Caron, Ishan Misra, Piotr Bojanowski, Florian Bordes, Pascal Vincent, Armand Joulin, Michael Rabbat, Nicolas Ballas. -1. **[Wav2Vec2](model_doc/wav2vec2)** (from Facebook AI) released with the paper [wav2vec 2.0: A Framework for Self-Supervised Learning of Speech Representations](https://huggingface.co/papers/2006.11477) by Alexei Baevski, Henry Zhou, Abdelrahman Mohamed, Michael Auli. -1. **[Wav2Vec2-Conformer](model_doc/wav2vec2-conformer)** (from Facebook AI) released with the paper [FAIRSEQ S2T: Fast Speech-to-Text Modeling with FAIRSEQ](https://huggingface.co/papers/2010.05171) by Changhan Wang, Yun Tang, Xutai Ma, Anne Wu, Sravya Popuri, Dmytro Okhonko, Juan Pino. -1. **[Wav2Vec2Phoneme](model_doc/wav2vec2_phoneme)** (from Facebook AI) released with the paper [Simple and Effective Zero-shot Cross-lingual Phoneme Recognition](https://huggingface.co/papers/2109.11680) by Qiantong Xu, Alexei Baevski, Michael Auli. -1. **[WavLM](model_doc/wavlm)** (from Microsoft Research) released with the paper [WavLM: Large-Scale Self-Supervised Pre-Training for Full Stack Speech Processing](https://huggingface.co/papers/2110.13900) by Sanyuan Chen, Chengyi Wang, Zhengyang Chen, Yu Wu, Shujie Liu, Zhuo Chen, Jinyu Li, Naoyuki Kanda, Takuya Yoshioka, Xiong Xiao, Jian Wu, Long Zhou, Shuo Ren, Yanmin Qian, Yao Qian, Jian Wu, Michael Zeng, Furu Wei. -1. **[Whisper](model_doc/whisper)** (from OpenAI) released with the paper [Robust Speech Recognition via Large-Scale Weak Supervision](https://cdn.openai.com/papers/whisper.pdf) by Alec Radford, Jong Wook Kim, Tao Xu, Greg Brockman, Christine McLeavey, Ilya Sutskever. -1. **[X-CLIP](model_doc/xclip)** (from Microsoft Research) released with the paper [Expanding Language-Image Pretrained Models for General Video Recognition](https://huggingface.co/papers/2208.02816) by Bolin Ni, Houwen Peng, Minghao Chen, Songyang Zhang, Gaofeng Meng, Jianlong Fu, Shiming Xiang, Haibin Ling. -1. **[X-MOD](model_doc/xmod)** (from Meta AI) released with the paper [Lifting the Curse of Multilinguality by Pre-training Modular Transformers](http://dx.doi.org/10.18653/v1/2022.naacl-main.255) by Jonas Pfeiffer, Naman Goyal, Xi Lin, Xian Li, James Cross, Sebastian Riedel, Mikel Artetxe. -1. **[XGLM](model_doc/xglm)** (From Facebook AI) released with the paper [Few-shot Learning with Multilingual Language Models](https://huggingface.co/papers/2112.10668) by Xi Victoria Lin, Todor Mihaylov, Mikel Artetxe, Tianlu Wang, Shuohui Chen, Daniel Simig, Myle Ott, Naman Goyal, Shruti Bhosale, Jingfei Du, Ramakanth Pasunuru, Sam Shleifer, Punit Singh Koura, Vishrav Chaudhary, Brian O'Horo, Jeff Wang, Luke Zettlemoyer, Zornitsa Kozareva, Mona Diab, Veselin Stoyanov, Xian Li. -1. **[XLM](model_doc/xlm)** (from Facebook) released together with the paper [Cross-lingual Language Model Pretraining](https://huggingface.co/papers/1901.07291) by Guillaume Lample and Alexis Conneau. -1. **[XLM-ProphetNet](model_doc/xlm-prophetnet)** (from Microsoft Research) released with the paper [ProphetNet: Predicting Future N-gram for Sequence-to-Sequence Pre-training](https://huggingface.co/papers/2001.04063) by Yu Yan, Weizhen Qi, Yeyun Gong, Dayiheng Liu, Nan Duan, Jiusheng Chen, Ruofei Zhang and Ming Zhou. -1. **[XLM-RoBERTa](model_doc/xlm-roberta)** (from Facebook AI), released together with the paper [Unsupervised Cross-lingual Representation Learning at Scale](https://huggingface.co/papers/1911.02116) by Alexis Conneau*, Kartikay Khandelwal*, Naman Goyal, Vishrav Chaudhary, Guillaume Wenzek, Francisco Guzmán, Edouard Grave, Myle Ott, Luke Zettlemoyer and Veselin Stoyanov. -1. **[XLM-RoBERTa-XL](model_doc/xlm-roberta-xl)** (from Facebook AI), released together with the paper [Larger-Scale Transformers for Multilingual Masked Language Modeling](https://huggingface.co/papers/2105.00572) by Naman Goyal, Jingfei Du, Myle Ott, Giri Anantharaman, Alexis Conneau. -1. **[XLM-V](model_doc/xlm-v)** (from Meta AI) released with the paper [XLM-V: Overcoming the Vocabulary Bottleneck in Multilingual Masked Language Models](https://huggingface.co/papers/2301.10472) by Davis Liang, Hila Gonen, Yuning Mao, Rui Hou, Naman Goyal, Marjan Ghazvininejad, Luke Zettlemoyer, Madian Khabsa. -1. **[XLNet](model_doc/xlnet)** (from Google/CMU) released with the paper [​XLNet: Generalized Autoregressive Pretraining for Language Understanding](https://huggingface.co/papers/1906.08237) by Zhilin Yang*, Zihang Dai*, Yiming Yang, Jaime Carbonell, Ruslan Salakhutdinov, Quoc V. Le. -1. **[XLS-R](model_doc/xls_r)** (from Facebook AI) released with the paper [XLS-R: Self-supervised Cross-lingual Speech Representation Learning at Scale](https://huggingface.co/papers/2111.09296) by Arun Babu, Changhan Wang, Andros Tjandra, Kushal Lakhotia, Qiantong Xu, Naman Goyal, Kritika Singh, Patrick von Platen, Yatharth Saraf, Juan Pino, Alexei Baevski, Alexis Conneau, Michael Auli. -1. **[XLSR-Wav2Vec2](model_doc/xlsr_wav2vec2)** (from Facebook AI) released with the paper [Unsupervised Cross-Lingual Representation Learning For Speech Recognition](https://huggingface.co/papers/2006.13979) by Alexis Conneau, Alexei Baevski, Ronan Collobert, Abdelrahman Mohamed, Michael Auli. -1. **[YOLOS](model_doc/yolos)** (from Huazhong University of Science & Technology) released with the paper [You Only Look at One Sequence: Rethinking Transformer in Vision through Object Detection](https://huggingface.co/papers/2106.00666) by Yuxin Fang, Bencheng Liao, Xinggang Wang, Jiemin Fang, Jiyang Qi, Rui Wu, Jianwei Niu, Wenyu Liu. -1. **[YOSO](model_doc/yoso)** (from the University of Wisconsin - Madison) released with the paper [You Only Sample (Almost) Once: Linear Cost Self-Attention Via Bernoulli Sampling](https://huggingface.co/papers/2111.09714) by Zhanpeng Zeng, Yunyang Xiong, Sathya N. Ravi, Shailesh Acharya, Glenn Fung, Vikas Singh. - - -### Rangka kerja yang disokong - -Jadual di bawah mewakili sokongan semasa dalam perpustakaan untuk setiap model tersebut, sama ada model tersebut mempunyai Python -tokenizer (dipanggil ""lambat""). Tokenizer ""pantas"" yang disokong oleh perpustakaan Tokenizers 🤗, sama ada mereka mempunyai sokongan dalam Jax (melalui -Flax), PyTorch, dan/atau TensorFlow. - - - -| Model | Tokenizer slow | Tokenizer fast | PyTorch support | TensorFlow support | Flax Support | -|:-----------------------------:|:--------------:|:--------------:|:---------------:|:------------------:|:------------:| -| ALBERT | ✅ | ✅ | ✅ | ✅ | ✅ | -| ALIGN | ❌ | ❌ | ✅ | ❌ | ❌ | -| AltCLIP | ❌ | ❌ | ✅ | ❌ | ❌ | -| Audio Spectrogram Transformer | ❌ | ❌ | ✅ | ❌ | ❌ | -| Autoformer | ❌ | ❌ | ✅ | ❌ | ❌ | -| BART | ✅ | ✅ | ✅ | ✅ | ✅ | -| BEiT | ❌ | ❌ | ✅ | ❌ | ✅ | -| BERT | ✅ | ✅ | ✅ | ✅ | ✅ | -| Bert Generation | ✅ | ❌ | ✅ | ❌ | ❌ | -| BigBird | ✅ | ✅ | ✅ | ❌ | ✅ | -| BigBird-Pegasus | ❌ | ❌ | ✅ | ❌ | ❌ | -| BioGpt | ✅ | ❌ | ✅ | ❌ | ❌ | -| BiT | ❌ | ❌ | ✅ | ❌ | ❌ | -| Blenderbot | ✅ | ✅ | ✅ | ✅ | ✅ | -| BlenderbotSmall | ✅ | ✅ | ✅ | ✅ | ✅ | -| BLIP | ❌ | ❌ | ✅ | ✅ | ❌ | -| BLIP-2 | ❌ | ❌ | ✅ | ❌ | ❌ | -| BLOOM | ❌ | ✅ | ✅ | ❌ | ❌ | -| BridgeTower | ❌ | ❌ | ✅ | ❌ | ❌ | -| Bros | ✅ | ✅ | ✅ | ❌ | ❌ | -| CamemBERT | ✅ | ✅ | ✅ | ✅ | ❌ | -| CANINE | ✅ | ❌ | ✅ | ❌ | ❌ | -| Chinese-CLIP | ❌ | ❌ | ✅ | ❌ | ❌ | -| CLAP | ❌ | ❌ | ✅ | ❌ | ❌ | -| CLIP | ✅ | ✅ | ✅ | ✅ | ✅ | -| CLIPSeg | ❌ | ❌ | ✅ | ❌ | ❌ | -| CodeGen | ✅ | ✅ | ✅ | ❌ | ❌ | -| Conditional DETR | ❌ | ❌ | ✅ | ❌ | ❌ | -| ConvBERT | ✅ | ✅ | ✅ | ✅ | ❌ | -| ConvNeXT | ❌ | ❌ | ✅ | ✅ | ❌ | -| ConvNeXTV2 | ❌ | ❌ | ✅ | ❌ | ❌ | -| CPM-Ant | ✅ | ❌ | ✅ | ❌ | ❌ | -| CTRL | ✅ | ❌ | ✅ | ✅ | ❌ | -| CvT | ❌ | ❌ | ✅ | ✅ | ❌ | -| Data2VecAudio | ❌ | ❌ | ✅ | ❌ | ❌ | -| Data2VecText | ❌ | ❌ | ✅ | ❌ | ❌ | -| Data2VecVision | ❌ | ❌ | ✅ | ✅ | ❌ | -| DeBERTa | ✅ | ✅ | ✅ | ✅ | ❌ | -| DeBERTa-v2 | ✅ | ✅ | ✅ | ✅ | ❌ | -| Decision Transformer | ❌ | ❌ | ✅ | ❌ | ❌ | -| Deformable DETR | ❌ | ❌ | ✅ | ❌ | ❌ | -| DeiT | ❌ | ❌ | ✅ | ✅ | ❌ | -| DETA | ❌ | ❌ | ✅ | ❌ | ❌ | -| DETR | ❌ | ❌ | ✅ | ❌ | ❌ | -| DiNAT | ❌ | ❌ | ✅ | ❌ | ❌ | -| DistilBERT | ✅ | ✅ | ✅ | ✅ | ✅ | -| DonutSwin | ❌ | ❌ | ✅ | ❌ | ❌ | -| DPR | ✅ | ✅ | ✅ | ✅ | ❌ | -| DPT | ❌ | ❌ | ✅ | ❌ | ❌ | -| EfficientFormer | ❌ | ❌ | ✅ | ✅ | ❌ | -| EfficientNet | ❌ | ❌ | ✅ | ❌ | ❌ | -| ELECTRA | ✅ | ✅ | ✅ | ✅ | ✅ | -| Encoder decoder | ❌ | ❌ | ✅ | ✅ | ✅ | -| ERNIE | ❌ | ❌ | ✅ | ❌ | ❌ | -| ErnieM | ✅ | ❌ | ✅ | ❌ | ❌ | -| ESM | ✅ | ❌ | ✅ | ✅ | ❌ | -| FairSeq Machine-Translation | ✅ | ❌ | ✅ | ❌ | ❌ | -| FlauBERT | ✅ | ❌ | ✅ | ✅ | ❌ | -| FLAVA | ❌ | ❌ | ✅ | ❌ | ❌ | -| FNet | ✅ | ✅ | ✅ | ❌ | ❌ | -| FocalNet | ❌ | ❌ | ✅ | ❌ | ❌ | -| Funnel Transformer | ✅ | ✅ | ✅ | ✅ | ❌ | -| GIT | ❌ | ❌ | ✅ | ❌ | ❌ | -| GLPN | ❌ | ❌ | ✅ | ❌ | ❌ | -| GPT Neo | ❌ | ❌ | ✅ | ❌ | ✅ | -| GPT NeoX | ❌ | ✅ | ✅ | ❌ | ❌ | -| GPT NeoX Japanese | ✅ | ❌ | ✅ | ❌ | ❌ | -| GPT-J | ❌ | ❌ | ✅ | ✅ | ✅ | -| GPT-Sw3 | ✅ | ✅ | ✅ | ✅ | ✅ | -| GPTBigCode | ❌ | ❌ | ✅ | ❌ | ❌ | -| GPTSAN-japanese | ✅ | ❌ | ✅ | ❌ | ❌ | -| Graphormer | ❌ | ❌ | ✅ | ❌ | ❌ | -| GroupViT | ❌ | ❌ | ✅ | ✅ | ❌ | -| Hubert | ❌ | ❌ | ✅ | ✅ | ❌ | -| I-BERT | ❌ | ❌ | ✅ | ❌ | ❌ | -| ImageGPT | ❌ | ❌ | ✅ | ❌ | ❌ | -| Informer | ❌ | ❌ | ✅ | ❌ | ❌ | -| Jukebox | ✅ | ❌ | ✅ | ❌ | ❌ | -| LayoutLM | ✅ | ✅ | ✅ | ✅ | ❌ | -| LayoutLMv2 | ✅ | ✅ | ✅ | ❌ | ❌ | -| LayoutLMv3 | ✅ | ✅ | ✅ | ✅ | ❌ | -| LED | ✅ | ✅ | ✅ | ✅ | ❌ | -| LeViT | ❌ | ❌ | ✅ | ❌ | ❌ | -| LiLT | ❌ | ❌ | ✅ | ❌ | ❌ | -| LLaMA | ✅ | ✅ | ✅ | ❌ | ❌ | -| Longformer | ✅ | ✅ | ✅ | ✅ | ❌ | -| LongT5 | ❌ | ❌ | ✅ | ❌ | ✅ | -| LUKE | ✅ | ❌ | ✅ | ❌ | ❌ | -| LXMERT | ✅ | ✅ | ✅ | ✅ | ❌ | -| M-CTC-T | ❌ | ❌ | ✅ | ❌ | ❌ | -| M2M100 | ✅ | ❌ | ✅ | ❌ | ❌ | -| Marian | ✅ | ❌ | ✅ | ✅ | ✅ | -| MarkupLM | ✅ | ✅ | ✅ | ❌ | ❌ | -| Mask2Former | ❌ | ❌ | ✅ | ❌ | ❌ | -| MaskFormer | ❌ | ❌ | ✅ | ❌ | ❌ | -| MaskFormerSwin | ❌ | ❌ | ❌ | ❌ | ❌ | -| mBART | ✅ | ✅ | ✅ | ✅ | ✅ | -| MEGA | ❌ | ❌ | ✅ | ❌ | ❌ | -| Megatron-BERT | ❌ | ❌ | ✅ | ❌ | ❌ | -| MGP-STR | ✅ | ❌ | ✅ | ❌ | ❌ | -| MobileBERT | ✅ | ✅ | ✅ | ✅ | ❌ | -| MobileNetV1 | ❌ | ❌ | ✅ | ❌ | ❌ | -| MobileNetV2 | ❌ | ❌ | ✅ | ❌ | ❌ | -| MobileViT | ❌ | ❌ | ✅ | ✅ | ❌ | -| MPNet | ✅ | ✅ | ✅ | ✅ | ❌ | -| MT5 | ✅ | ✅ | ✅ | ✅ | ✅ | -| MVP | ✅ | ✅ | ✅ | ❌ | ❌ | -| NAT | ❌ | ❌ | ✅ | ❌ | ❌ | -| Nezha | ❌ | ❌ | ✅ | ❌ | ❌ | -| NLLB-MOE | ❌ | ❌ | ✅ | ❌ | ❌ | -| Nyströmformer | ❌ | ❌ | ✅ | ❌ | ❌ | -| OneFormer | ❌ | ❌ | ✅ | ❌ | ❌ | -| OpenAI GPT | ✅ | ✅ | ✅ | ✅ | ❌ | -| OpenAI GPT-2 | ✅ | ✅ | ✅ | ✅ | ✅ | -| OpenLlama | ❌ | ❌ | ✅ | ❌ | ❌ | -| OPT | ❌ | ❌ | ✅ | ✅ | ✅ | -| OWL-ViT | ❌ | ❌ | ✅ | ❌ | ❌ | -| Pegasus | ✅ | ✅ | ✅ | ✅ | ✅ | -| PEGASUS-X | ❌ | ❌ | ✅ | ❌ | ❌ | -| Perceiver | ✅ | ❌ | ✅ | ❌ | ❌ | -| Pix2Struct | ❌ | ❌ | ✅ | ❌ | ❌ | -| PLBart | ✅ | ❌ | ✅ | ❌ | ❌ | -| PoolFormer | ❌ | ❌ | ✅ | ❌ | ❌ | -| ProphetNet | ✅ | ❌ | ✅ | ❌ | ❌ | -| QDQBert | ❌ | ❌ | ✅ | ❌ | ❌ | -| RAG | ✅ | ❌ | ✅ | ✅ | ❌ | -| REALM | ✅ | ✅ | ✅ | ❌ | ❌ | -| Reformer | ✅ | ✅ | ✅ | ❌ | ❌ | -| RegNet | ❌ | ❌ | ✅ | ✅ | ✅ | -| RemBERT | ✅ | ✅ | ✅ | ✅ | ❌ | -| ResNet | ❌ | ❌ | ✅ | ✅ | ✅ | -| RetriBERT | ✅ | ✅ | ✅ | ❌ | ❌ | -| RoBERTa | ✅ | ✅ | ✅ | ✅ | ✅ | -| RoBERTa-PreLayerNorm | ❌ | ❌ | ✅ | ✅ | ✅ | -| RoCBert | ✅ | ❌ | ✅ | ❌ | ❌ | -| RoFormer | ✅ | ✅ | ✅ | ✅ | ✅ | -| RWKV | ❌ | ❌ | ✅ | ❌ | ❌ | -| SAM | ❌ | ❌ | ✅ | ✅ | ❌ | -| SegFormer | ❌ | ❌ | ✅ | ✅ | ❌ | -| SEW | ❌ | ❌ | ✅ | ❌ | ❌ | -| SEW-D | ❌ | ❌ | ✅ | ❌ | ❌ | -| Speech Encoder decoder | ❌ | ❌ | ✅ | ❌ | ✅ | -| Speech2Text | ✅ | ❌ | ✅ | ✅ | ❌ | -| Speech2Text2 | ✅ | ❌ | ❌ | ❌ | ❌ | -| SpeechT5 | ✅ | ❌ | ✅ | ❌ | ❌ | -| Splinter | ✅ | ✅ | ✅ | ❌ | ❌ | -| SqueezeBERT | ✅ | ✅ | ✅ | ❌ | ❌ | -| SwiftFormer | ❌ | ❌ | ✅ | ❌ | ❌ | -| Swin Transformer | ❌ | ❌ | ✅ | ✅ | ❌ | -| Swin Transformer V2 | ❌ | ❌ | ✅ | ❌ | ❌ | -| Swin2SR | ❌ | ❌ | ✅ | ❌ | ❌ | -| SwitchTransformers | ❌ | ❌ | ✅ | ❌ | ❌ | -| T5 | ✅ | ✅ | ✅ | ✅ | ✅ | -| Table Transformer | ❌ | ❌ | ✅ | ❌ | ❌ | -| TAPAS | ✅ | ❌ | ✅ | ✅ | ❌ | -| Time Series Transformer | ❌ | ❌ | ✅ | ❌ | ❌ | -| TimeSformer | ❌ | ❌ | ✅ | ❌ | ❌ | -| Trajectory Transformer | ❌ | ❌ | ✅ | ❌ | ❌ | -| Transformer-XL | ✅ | ❌ | ✅ | ✅ | ❌ | -| TrOCR | ❌ | ❌ | ✅ | ❌ | ❌ | -| TVLT | ❌ | ❌ | ✅ | ❌ | ❌ | -| TVP | ❌ | ❌ | ✅ | ❌ | ❌ | -| UniSpeech | ❌ | ❌ | ✅ | ❌ | ❌ | -| UniSpeechSat | ❌ | ❌ | ✅ | ❌ | ❌ | -| UPerNet | ❌ | ❌ | ✅ | ❌ | ❌ | -| VAN | ❌ | ❌ | ✅ | ❌ | ❌ | -| VideoMAE | ❌ | ❌ | ✅ | ❌ | ❌ | -| ViLT | ❌ | ❌ | ✅ | ❌ | ❌ | -| Vision Encoder decoder | ❌ | ❌ | ✅ | ✅ | ✅ | -| VisionTextDualEncoder | ❌ | ❌ | ✅ | ✅ | ✅ | -| VisualBERT | ❌ | ❌ | ✅ | ❌ | ❌ | -| ViT | ❌ | ❌ | ✅ | ✅ | ✅ | -| ViT Hybrid | ❌ | ❌ | ✅ | ❌ | ❌ | -| ViTMAE | ❌ | ❌ | ✅ | ✅ | ❌ | -| ViTMSN | ❌ | ❌ | ✅ | ❌ | ❌ | -| Wav2Vec2 | ✅ | ❌ | ✅ | ✅ | ✅ | -| Wav2Vec2-Conformer | ❌ | ❌ | ✅ | ❌ | ❌ | -| WavLM | ❌ | ❌ | ✅ | ❌ | ❌ | -| Whisper | ✅ | ✅ | ✅ | ✅ | ✅ | -| X-CLIP | ❌ | ❌ | ✅ | ❌ | ❌ | -| X-MOD | ❌ | ❌ | ✅ | ❌ | ❌ | -| XGLM | ✅ | ✅ | ✅ | ✅ | ✅ | -| XLM | ✅ | ❌ | ✅ | ✅ | ❌ | -| XLM-ProphetNet | ✅ | ❌ | ✅ | ❌ | ❌ | -| XLM-RoBERTa | ✅ | ✅ | ✅ | ✅ | ✅ | -| XLM-RoBERTa-XL | ❌ | ❌ | ✅ | ❌ | ❌ | -| XLNet | ✅ | ✅ | ✅ | ✅ | ❌ | -| YOLOS | ❌ | ❌ | ✅ | ❌ | ❌ | -| YOSO | ❌ | ❌ | ✅ | ❌ | ❌ | - - diff --git a/docs/source/te/_toctree.yml b/docs/source/te/_toctree.yml deleted file mode 100644 index 5e6b45eb472f..000000000000 --- a/docs/source/te/_toctree.yml +++ /dev/null @@ -1,6 +0,0 @@ -- sections: - - local: index - title: 🤗 Transformers - - local: quicktour - title: త్వరిత పర్యటన - title: ప్రారంభించడానికి diff --git a/docs/source/te/index.md b/docs/source/te/index.md deleted file mode 100644 index 3e23f8f5eb13..000000000000 --- a/docs/source/te/index.md +++ /dev/null @@ -1,298 +0,0 @@ - - -[పైటోర్చ్](https://pytorch.org/), [టెన్సర్‌ఫ్లో](https://www.tensorflow.org/), మరియు [జాక్స్](https://jax.readthedocs.io/en/latest/) కోసం స్థితి-కలాన యంత్ర అభ్యాసం. - -🤗 ట్రాన్స్ఫార్మర్స్ అభివృద్ధిస్తున్నది API మరియు ఉపకరణాలు, పూర్వ-చేతన మోడల్లను సులభంగా డౌన్లోడ్ మరియు శిక్షణ చేయడానికి అవసరమైన సమయం, వనరులు, మరియు వస్తువులను నుంచి మోడల్ను శీర్షికం నుంచి ప్రశిక్షించడం వరకు దేవాయనం చేస్తుంది. ఈ మోడల్లు విభిన్న మోడాలిటీలలో సాధారణ పనులకు మద్దతు చేస్తాయి, వంటివి: - -📝 **ప్రాకృతిక భాష ప్రక్రియ**: వచన వర్గీకరణ, పేరుల యొక్క యెంటిటీ గుర్తువు, ప్రశ్న సంవాద, భాషా రచన, సంక్షేపణ, అనువాదం, అనేక ప్రకారాలు, మరియు వచన సృష్టి.
-🖼️ **కంప్యూటర్ విషయం**: చిత్రం వర్గీకరణ, వస్త్రం గుర్తువు, మరియు విభజన.
-🗣️ **ఆడియో**: స్వయంచలన ప్రసంగాన్ని గుర్తుచేసేందుకు, ఆడియో వర్గీకరణ.
-🐙 **బహుమూలిక**: పట్టి ప్రశ్న సంవాద, ఆప్టికల్ సిఫర్ గుర్తువు, డాక్యుమెంట్లు స్క్యాన్ చేసినంతగా సమాచార పొందడం, వీడియో వర్గీకరణ, మరియు దృశ్య ప్రశ్న సంవాద. - -🤗 ట్రాన్స్ఫార్మర్స్ పైన మద్దతు చేస్తుంది పైన తొలగించడానికి పైన పైన పైన ప్రోగ్రామ్లో మోడల్ను శిక్షించండి, మరియు అన్ని ప్రాథమిక యొక్కడా ఇన్‌ఫరెన్స్ కోసం లోడ్ చేయండి. మో - -డల్లు కూడా ప్రొడక్షన్ వాతావరణాలలో వాడుకోవడానికి ONNX మరియు TorchScript వంటి ఆకృతులకు ఎగుమతి చేయవచ్చు. - -ఈరువులకు [హబ్](https://huggingface.co/models), [ఫోరం](https://discuss.huggingface.co/), లేదా [డిస్కార్డ్](https://discord.com/invite/JfAtkvEtRb) లో ఈ పెద్ద సముదాయంలో చేరండి! - -## మీరు హగ్గింగ్ ఫేస్ టీమ్ నుండి అనుకూల మద్దతు కోసం చూస్తున్నట్లయితే - - - HuggingFace Expert Acceleration Program - - -## విషయాలు - -డాక్యుమెంటేషన్ ఐదు విభాగాలుగా నిర్వహించబడింది: - -- **ప్రారంభించండి** లైబ్రరీ యొక్క శీఘ్ర పర్యటన మరియు రన్నింగ్ కోసం ఇన్‌స్టాలేషన్ సూచనలను అందిస్తుంది. -- **ట్యుటోరియల్స్** మీరు అనుభవశూన్యుడు అయితే ప్రారంభించడానికి గొప్ప ప్రదేశం. మీరు లైబ్రరీని ఉపయోగించడం ప్రారంభించడానికి అవసరమైన ప్రాథమిక నైపుణ్యాలను పొందడానికి ఈ విభాగం మీకు సహాయం చేస్తుంది. -- **హౌ-టు-గైడ్‌లు** లాంగ్వేజ్ మోడలింగ్ కోసం ప్రిట్రైన్డ్ మోడల్‌ని ఫైన్‌ట్యూన్ చేయడం లేదా కస్టమ్ మోడల్‌ను ఎలా వ్రాయాలి మరియు షేర్ చేయాలి వంటి నిర్దిష్ట లక్ష్యాన్ని ఎలా సాధించాలో మీకు చూపుతాయి. -- **కాన్సెప్చువల్ గైడ్స్** మోడల్‌లు, టాస్క్‌లు మరియు 🤗 ట్రాన్స్‌ఫార్మర్ల డిజైన్ ఫిలాసఫీ వెనుక ఉన్న అంతర్లీన భావనలు మరియు ఆలోచనల గురించి మరింత చర్చ మరియు వివరణను అందిస్తుంది. -- **API** అన్ని తరగతులు మరియు విధులను వివరిస్తుంది: - - - **ప్రధాన తరగతులు** కాన్ఫిగరేషన్, మోడల్, టోకెనైజర్ మరియు పైప్‌లైన్ వంటి అత్యంత ముఖ్యమైన తరగతులను వివరిస్తుంది. - - **మోడల్స్** లైబ్రరీలో అమలు చేయబడిన ప్రతి మోడల్‌కు సంబంధించిన తరగతులు మరియు విధులను వివరిస్తుంది. - - **అంతర్గత సహాయకులు** అంతర్గతంగా ఉపయోగించే యుటిలిటీ క్లాస్‌లు మరియు ఫంక్షన్‌ల వివరాలు. - -## మద్దతు ఉన్న నమూనాలు మరియు ఫ్రేమ్‌వర్క్‌లు - -దిగువన ఉన్న పట్టిక ఆ ప్రతి మోడల్‌కు పైథాన్ కలిగి ఉన్నా లైబ్రరీలో ప్రస్తుత మద్దతును సూచిస్తుంది -టోకెనైజర్ ("నెమ్మదిగా" అని పిలుస్తారు). Jax (ద్వారా -ఫ్లాక్స్), పైటార్చ్ మరియు/లేదా టెన్సర్‌ఫ్లో. - - - -| Model | PyTorch support | TensorFlow support | Flax Support | -|:------------------------------------------------------------------------:|:---------------:|:------------------:|:------------:| -| [ALBERT](model_doc/albert) | ✅ | ✅ | ✅ | -| [ALIGN](model_doc/align) | ✅ | ❌ | ❌ | -| [AltCLIP](model_doc/altclip) | ✅ | ❌ | ❌ | -| [Audio Spectrogram Transformer](model_doc/audio-spectrogram-transformer) | ✅ | ❌ | ❌ | -| [Autoformer](model_doc/autoformer) | ✅ | ❌ | ❌ | -| [Bark](model_doc/bark) | ✅ | ❌ | ❌ | -| [BART](model_doc/bart) | ✅ | ✅ | ✅ | -| [BARThez](model_doc/barthez) | ✅ | ✅ | ✅ | -| [BARTpho](model_doc/bartpho) | ✅ | ✅ | ✅ | -| [BEiT](model_doc/beit) | ✅ | ❌ | ✅ | -| [BERT](model_doc/bert) | ✅ | ✅ | ✅ | -| [Bert Generation](model_doc/bert-generation) | ✅ | ❌ | ❌ | -| [BertJapanese](model_doc/bert-japanese) | ✅ | ✅ | ✅ | -| [BERTweet](model_doc/bertweet) | ✅ | ✅ | ✅ | -| [BigBird](model_doc/big_bird) | ✅ | ❌ | ✅ | -| [BigBird-Pegasus](model_doc/bigbird_pegasus) | ✅ | ❌ | ❌ | -| [BioGpt](model_doc/biogpt) | ✅ | ❌ | ❌ | -| [BiT](model_doc/bit) | ✅ | ❌ | ❌ | -| [Blenderbot](model_doc/blenderbot) | ✅ | ✅ | ✅ | -| [BlenderbotSmall](model_doc/blenderbot-small) | ✅ | ✅ | ✅ | -| [BLIP](model_doc/blip) | ✅ | ✅ | ❌ | -| [BLIP-2](model_doc/blip-2) | ✅ | ❌ | ❌ | -| [BLOOM](model_doc/bloom) | ✅ | ❌ | ✅ | -| [BORT](model_doc/bort) | ✅ | ✅ | ✅ | -| [BridgeTower](model_doc/bridgetower) | ✅ | ❌ | ❌ | -| [BROS](model_doc/bros) | ✅ | ❌ | ❌ | -| [ByT5](model_doc/byt5) | ✅ | ✅ | ✅ | -| [CamemBERT](model_doc/camembert) | ✅ | ✅ | ❌ | -| [CANINE](model_doc/canine) | ✅ | ❌ | ❌ | -| [Chinese-CLIP](model_doc/chinese_clip) | ✅ | ❌ | ❌ | -| [CLAP](model_doc/clap) | ✅ | ❌ | ❌ | -| [CLIP](model_doc/clip) | ✅ | ✅ | ✅ | -| [CLIPSeg](model_doc/clipseg) | ✅ | ❌ | ❌ | -| [CodeGen](model_doc/codegen) | ✅ | ❌ | ❌ | -| [CodeLlama](model_doc/code_llama) | ✅ | ❌ | ❌ | -| [Conditional DETR](model_doc/conditional_detr) | ✅ | ❌ | ❌ | -| [ConvBERT](model_doc/convbert) | ✅ | ✅ | ❌ | -| [ConvNeXT](model_doc/convnext) | ✅ | ✅ | ❌ | -| [ConvNeXTV2](model_doc/convnextv2) | ✅ | ❌ | ❌ | -| [CPM](model_doc/cpm) | ✅ | ✅ | ✅ | -| [CPM-Ant](model_doc/cpmant) | ✅ | ❌ | ❌ | -| [CTRL](model_doc/ctrl) | ✅ | ✅ | ❌ | -| [CvT](model_doc/cvt) | ✅ | ✅ | ❌ | -| [Data2VecAudio](model_doc/data2vec) | ✅ | ❌ | ❌ | -| [Data2VecText](model_doc/data2vec) | ✅ | ❌ | ❌ | -| [Data2VecVision](model_doc/data2vec) | ✅ | ✅ | ❌ | -| [DeBERTa](model_doc/deberta) | ✅ | ✅ | ❌ | -| [DeBERTa-v2](model_doc/deberta-v2) | ✅ | ✅ | ❌ | -| [Decision Transformer](model_doc/decision_transformer) | ✅ | ❌ | ❌ | -| [Deformable DETR](model_doc/deformable_detr) | ✅ | ❌ | ❌ | -| [DeiT](model_doc/deit) | ✅ | ✅ | ❌ | -| [DePlot](model_doc/deplot) | ✅ | ❌ | ❌ | -| [DETA](model_doc/deta) | ✅ | ❌ | ❌ | -| [DETR](model_doc/detr) | ✅ | ❌ | ❌ | -| [DialoGPT](model_doc/dialogpt) | ✅ | ✅ | ✅ | -| [DiNAT](model_doc/dinat) | ✅ | ❌ | ❌ | -| [DINOv2](model_doc/dinov2) | ✅ | ❌ | ❌ | -| [DistilBERT](model_doc/distilbert) | ✅ | ✅ | ✅ | -| [DiT](model_doc/dit) | ✅ | ❌ | ✅ | -| [DonutSwin](model_doc/donut) | ✅ | ❌ | ❌ | -| [DPR](model_doc/dpr) | ✅ | ✅ | ❌ | -| [DPT](model_doc/dpt) | ✅ | ❌ | ❌ | -| [EfficientFormer](model_doc/efficientformer) | ✅ | ✅ | ❌ | -| [EfficientNet](model_doc/efficientnet) | ✅ | ❌ | ❌ | -| [ELECTRA](model_doc/electra) | ✅ | ✅ | ✅ | -| [EnCodec](model_doc/encodec) | ✅ | ❌ | ❌ | -| [Encoder decoder](model_doc/encoder-decoder) | ✅ | ✅ | ✅ | -| [ERNIE](model_doc/ernie) | ✅ | ❌ | ❌ | -| [ErnieM](model_doc/ernie_m) | ✅ | ❌ | ❌ | -| [ESM](model_doc/esm) | ✅ | ✅ | ❌ | -| [FairSeq Machine-Translation](model_doc/fsmt) | ✅ | ❌ | ❌ | -| [Falcon](model_doc/falcon) | ✅ | ❌ | ❌ | -| [FLAN-T5](model_doc/flan-t5) | ✅ | ✅ | ✅ | -| [FLAN-UL2](model_doc/flan-ul2) | ✅ | ✅ | ✅ | -| [FlauBERT](model_doc/flaubert) | ✅ | ✅ | ❌ | -| [FLAVA](model_doc/flava) | ✅ | ❌ | ❌ | -| [FNet](model_doc/fnet) | ✅ | ❌ | ❌ | -| [FocalNet](model_doc/focalnet) | ✅ | ❌ | ❌ | -| [Funnel Transformer](model_doc/funnel) | ✅ | ✅ | ❌ | -| [GIT](model_doc/git) | ✅ | ❌ | ❌ | -| [GLPN](model_doc/glpn) | ✅ | ❌ | ❌ | -| [GPT Neo](model_doc/gpt_neo) | ✅ | ❌ | ✅ | -| [GPT NeoX](model_doc/gpt_neox) | ✅ | ❌ | ❌ | -| [GPT NeoX Japanese](model_doc/gpt_neox_japanese) | ✅ | ❌ | ❌ | -| [GPT-J](model_doc/gptj) | ✅ | ✅ | ✅ | -| [GPT-Sw3](model_doc/gpt-sw3) | ✅ | ✅ | ✅ | -| [GPTBigCode](model_doc/gpt_bigcode) | ✅ | ❌ | ❌ | -| [GPTSAN-japanese](model_doc/gptsan-japanese) | ✅ | ❌ | ❌ | -| [Graphormer](model_doc/graphormer) | ✅ | ❌ | ❌ | -| [GroupViT](model_doc/groupvit) | ✅ | ✅ | ❌ | -| [HerBERT](model_doc/herbert) | ✅ | ✅ | ✅ | -| [Hubert](model_doc/hubert) | ✅ | ✅ | ❌ | -| [I-BERT](model_doc/ibert) | ✅ | ❌ | ❌ | -| [IDEFICS](model_doc/idefics) | ✅ | ❌ | ❌ | -| [ImageGPT](model_doc/imagegpt) | ✅ | ❌ | ❌ | -| [Informer](model_doc/informer) | ✅ | ❌ | ❌ | -| [InstructBLIP](model_doc/instructblip) | ✅ | ❌ | ❌ | -| [Jukebox](model_doc/jukebox) | ✅ | ❌ | ❌ | -| [LayoutLM](model_doc/layoutlm) | ✅ | ✅ | ❌ | -| [LayoutLMv2](model_doc/layoutlmv2) | ✅ | ❌ | ❌ | -| [LayoutLMv3](model_doc/layoutlmv3) | ✅ | ✅ | ❌ | -| [LayoutXLM](model_doc/layoutxlm) | ✅ | ❌ | ❌ | -| [LED](model_doc/led) | ✅ | ✅ | ❌ | -| [LeViT](model_doc/levit) | ✅ | ❌ | ❌ | -| [LiLT](model_doc/lilt) | ✅ | ❌ | ❌ | -| [LLaMA](model_doc/llama) | ✅ | ❌ | ❌ | -| [Llama2](model_doc/llama2) | ✅ | ❌ | ❌ | -| [Longformer](model_doc/longformer) | ✅ | ✅ | ❌ | -| [LongT5](model_doc/longt5) | ✅ | ❌ | ✅ | -| [LUKE](model_doc/luke) | ✅ | ❌ | ❌ | -| [LXMERT](model_doc/lxmert) | ✅ | ✅ | ❌ | -| [M-CTC-T](model_doc/mctct) | ✅ | ❌ | ❌ | -| [M2M100](model_doc/m2m_100) | ✅ | ❌ | ❌ | -| [Marian](model_doc/marian) | ✅ | ✅ | ✅ | -| [MarkupLM](model_doc/markuplm) | ✅ | ❌ | ❌ | -| [Mask2Former](model_doc/mask2former) | ✅ | ❌ | ❌ | -| [MaskFormer](model_doc/maskformer) | ✅ | ❌ | ❌ | -| [MatCha](model_doc/matcha) | ✅ | ❌ | ❌ | -| [mBART](model_doc/mbart) | ✅ | ✅ | ✅ | -| [mBART-50](model_doc/mbart50) | ✅ | ✅ | ✅ | -| [MEGA](model_doc/mega) | ✅ | ❌ | ❌ | -| [Megatron-BERT](model_doc/megatron-bert) | ✅ | ❌ | ❌ | -| [Megatron-GPT2](model_doc/megatron_gpt2) | ✅ | ✅ | ✅ | -| [MGP-STR](model_doc/mgp-str) | ✅ | ❌ | ❌ | -| [Mistral](model_doc/mistral) | ✅ | ❌ | ❌ | -| [mLUKE](model_doc/mluke) | ✅ | ❌ | ❌ | -| [MMS](model_doc/mms) | ✅ | ✅ | ✅ | -| [MobileBERT](model_doc/mobilebert) | ✅ | ✅ | ❌ | -| [MobileNetV1](model_doc/mobilenet_v1) | ✅ | ❌ | ❌ | -| [MobileNetV2](model_doc/mobilenet_v2) | ✅ | ❌ | ❌ | -| [MobileViT](model_doc/mobilevit) | ✅ | ✅ | ❌ | -| [MobileViTV2](model_doc/mobilevitv2) | ✅ | ❌ | ❌ | -| [MPNet](model_doc/mpnet) | ✅ | ✅ | ❌ | -| [MPT](model_doc/mpt) | ✅ | ❌ | ❌ | -| [MRA](model_doc/mra) | ✅ | ❌ | ❌ | -| [MT5](model_doc/mt5) | ✅ | ✅ | ✅ | -| [MusicGen](model_doc/musicgen) | ✅ | ❌ | ❌ | -| [MVP](model_doc/mvp) | ✅ | ❌ | ❌ | -| [NAT](model_doc/nat) | ✅ | ❌ | ❌ | -| [Nezha](model_doc/nezha) | ✅ | ❌ | ❌ | -| [NLLB](model_doc/nllb) | ✅ | ❌ | ❌ | -| [NLLB-MOE](model_doc/nllb-moe) | ✅ | ❌ | ❌ | -| [Nougat](model_doc/nougat) | ✅ | ✅ | ✅ | -| [Nyströmformer](model_doc/nystromformer) | ✅ | ❌ | ❌ | -| [OneFormer](model_doc/oneformer) | ✅ | ❌ | ❌ | -| [OpenAI GPT](model_doc/openai-gpt) | ✅ | ✅ | ❌ | -| [OpenAI GPT-2](model_doc/gpt2) | ✅ | ✅ | ✅ | -| [OpenLlama](model_doc/open-llama) | ✅ | ❌ | ❌ | -| [OPT](model_doc/opt) | ✅ | ✅ | ✅ | -| [OWL-ViT](model_doc/owlvit) | ✅ | ❌ | ❌ | -| [Pegasus](model_doc/pegasus) | ✅ | ✅ | ✅ | -| [PEGASUS-X](model_doc/pegasus_x) | ✅ | ❌ | ❌ | -| [Perceiver](model_doc/perceiver) | ✅ | ❌ | ❌ | -| [Persimmon](model_doc/persimmon) | ✅ | ❌ | ❌ | -| [PhoBERT](model_doc/phobert) | ✅ | ✅ | ✅ | -| [Pix2Struct](model_doc/pix2struct) | ✅ | ❌ | ❌ | -| [PLBart](model_doc/plbart) | ✅ | ❌ | ❌ | -| [PoolFormer](model_doc/poolformer) | ✅ | ❌ | ❌ | -| [Pop2Piano](model_doc/pop2piano) | ✅ | ❌ | ❌ | -| [ProphetNet](model_doc/prophetnet) | ✅ | ❌ | ❌ | -| [PVT](model_doc/pvt) | ✅ | ❌ | ❌ | -| [QDQBert](model_doc/qdqbert) | ✅ | ❌ | ❌ | -| [RAG](model_doc/rag) | ✅ | ✅ | ❌ | -| [REALM](model_doc/realm) | ✅ | ❌ | ❌ | -| [Reformer](model_doc/reformer) | ✅ | ❌ | ❌ | -| [RegNet](model_doc/regnet) | ✅ | ✅ | ✅ | -| [RemBERT](model_doc/rembert) | ✅ | ✅ | ❌ | -| [ResNet](model_doc/resnet) | ✅ | ✅ | ✅ | -| [RetriBERT](model_doc/retribert) | ✅ | ❌ | ❌ | -| [RoBERTa](model_doc/roberta) | ✅ | ✅ | ✅ | -| [RoBERTa-PreLayerNorm](model_doc/roberta-prelayernorm) | ✅ | ✅ | ✅ | -| [RoCBert](model_doc/roc_bert) | ✅ | ❌ | ❌ | -| [RoFormer](model_doc/roformer) | ✅ | ✅ | ✅ | -| [RWKV](model_doc/rwkv) | ✅ | ❌ | ❌ | -| [SAM](model_doc/sam) | ✅ | ✅ | ❌ | -| [SegFormer](model_doc/segformer) | ✅ | ✅ | ❌ | -| [SEW](model_doc/sew) | ✅ | ❌ | ❌ | -| [SEW-D](model_doc/sew-d) | ✅ | ❌ | ❌ | -| [Speech Encoder decoder](model_doc/speech-encoder-decoder) | ✅ | ❌ | ✅ | -| [Speech2Text](model_doc/speech_to_text) | ✅ | ✅ | ❌ | -| [SpeechT5](model_doc/speecht5) | ✅ | ❌ | ❌ | -| [Splinter](model_doc/splinter) | ✅ | ❌ | ❌ | -| [SqueezeBERT](model_doc/squeezebert) | ✅ | ❌ | ❌ | -| [SwiftFormer](model_doc/swiftformer) | ✅ | ❌ | ❌ | -| [Swin Transformer](model_doc/swin) | ✅ | ✅ | ❌ | -| [Swin Transformer V2](model_doc/swinv2) | ✅ | ❌ | ❌ | -| [Swin2SR](model_doc/swin2sr) | ✅ | ❌ | ❌ | -| [SwitchTransformers](model_doc/switch_transformers) | ✅ | ❌ | ❌ | -| [T5](model_doc/t5) | ✅ | ✅ | ✅ | -| [T5v1.1](model_doc/t5v1.1) | ✅ | ✅ | ✅ | -| [Table Transformer](model_doc/table-transformer) | ✅ | ❌ | ❌ | -| [TAPAS](model_doc/tapas) | ✅ | ✅ | ❌ | -| [TAPEX](model_doc/tapex) | ✅ | ✅ | ✅ | -| [Time Series Transformer](model_doc/time_series_transformer) | ✅ | ❌ | ❌ | -| [TimeSformer](model_doc/timesformer) | ✅ | ❌ | ❌ | -| [Trajectory Transformer](model_doc/trajectory_transformer) | ✅ | ❌ | ❌ | -| [Transformer-XL](model_doc/transfo-xl) | ✅ | ✅ | ❌ | -| [TrOCR](model_doc/trocr) | ✅ | ❌ | ❌ | -| [TVLT](model_doc/tvlt) | ✅ | ❌ | ❌ | -| [UL2](model_doc/ul2) | ✅ | ✅ | ✅ | -| [UMT5](model_doc/umt5) | ✅ | ❌ | ❌ | -| [UniSpeech](model_doc/unispeech) | ✅ | ❌ | ❌ | -| [UniSpeechSat](model_doc/unispeech-sat) | ✅ | ❌ | ❌ | -| [UPerNet](model_doc/upernet) | ✅ | ❌ | ❌ | -| [VAN](model_doc/van) | ✅ | ❌ | ❌ | -| [VideoMAE](model_doc/videomae) | ✅ | ❌ | ❌ | -| [ViLT](model_doc/vilt) | ✅ | ❌ | ❌ | -| [Vision Encoder decoder](model_doc/vision-encoder-decoder) | ✅ | ✅ | ✅ | -| [VisionTextDualEncoder](model_doc/vision-text-dual-encoder) | ✅ | ✅ | ✅ | -| [VisualBERT](model_doc/visual_bert) | ✅ | ❌ | ❌ | -| [ViT](model_doc/vit) | ✅ | ✅ | ✅ | -| [ViT Hybrid](model_doc/vit_hybrid) | ✅ | ❌ | ❌ | -| [VitDet](model_doc/vitdet) | ✅ | ❌ | ❌ | -| [ViTMAE](model_doc/vit_mae) | ✅ | ✅ | ❌ | -| [ViTMatte](model_doc/vitmatte) | ✅ | ❌ | ❌ | -| [ViTMSN](model_doc/vit_msn) | ✅ | ❌ | ❌ | -| [VITS](model_doc/vits) | ✅ | ❌ | ❌ | -| [ViViT](model_doc/vivit) | ✅ | ❌ | ❌ | -| [Wav2Vec2](model_doc/wav2vec2) | ✅ | ✅ | ✅ | -| [Wav2Vec2-Conformer](model_doc/wav2vec2-conformer) | ✅ | ❌ | ❌ | -| [Wav2Vec2Phoneme](model_doc/wav2vec2_phoneme) | ✅ | ✅ | ✅ | -| [WavLM](model_doc/wavlm) | ✅ | ❌ | ❌ | -| [Whisper](model_doc/whisper) | ✅ | ✅ | ✅ | -| [X-CLIP](model_doc/xclip) | ✅ | ❌ | ❌ | -| [X-MOD](model_doc/xmod) | ✅ | ❌ | ❌ | -| [XGLM](model_doc/xglm) | ✅ | ✅ | ✅ | -| [XLM](model_doc/xlm) | ✅ | ✅ | ❌ | -| [XLM-ProphetNet](model_doc/xlm-prophetnet) | ✅ | ❌ | ❌ | -| [XLM-RoBERTa](model_doc/xlm-roberta) | ✅ | ✅ | ✅ | -| [XLM-RoBERTa-XL](model_doc/xlm-roberta-xl) | ✅ | ❌ | ❌ | -| [XLM-V](model_doc/xlm-v) | ✅ | ✅ | ✅ | -| [XLNet](model_doc/xlnet) | ✅ | ✅ | ❌ | -| [XLS-R](model_doc/xls_r) | ✅ | ✅ | ✅ | -| [XLSR-Wav2Vec2](model_doc/xlsr_wav2vec2) | ✅ | ✅ | ✅ | -| [YOLOS](model_doc/yolos) | ✅ | ❌ | ❌ | -| [YOSO](model_doc/yoso) | ✅ | ❌ | ❌ | - - diff --git a/docs/source/te/quicktour.md b/docs/source/te/quicktour.md deleted file mode 100644 index 6045b673d2d3..000000000000 --- a/docs/source/te/quicktour.md +++ /dev/null @@ -1,557 +0,0 @@ - - -# శీఘ్ర పర్యటన - -[[ఓపెన్-ఇన్-కోలాబ్]] - -🤗 ట్రాన్స్‌ఫార్మర్‌లతో లేచి పరుగెత్తండి! మీరు డెవలపర్ అయినా లేదా రోజువారీ వినియోగదారు అయినా, ఈ శీఘ్ర పర్యటన మీకు ప్రారంభించడానికి సహాయం చేస్తుంది మరియు [`pipeline`] అనుమితి కోసం ఎలా ఉపయోగించాలో మీకు చూపుతుంది, [AutoClass](./model_doc/auto) తో ప్రీట్రైన్డ్ మోడల్ మరియు ప్రిప్రాసెసర్/ ఆటో, మరియు PyTorch లేదా TensorFlowతో మోడల్‌కు త్వరగా శిక్షణ ఇవ్వండి. మీరు ఒక అనుభవశూన్యుడు అయితే, ఇక్కడ పరిచయం చేయబడిన భావనల గురించి మరింత లోతైన వివరణల కోసం మా ట్యుటోరియల్స్ లేదా [course](https://huggingface.co/course/chapter1/1)ని తనిఖీ చేయమని మేము సిఫార్సు చేస్తున్నాము. - -మీరు ప్రారంభించడానికి ముందు, మీరు అవసరమైన అన్ని లైబ్రరీలను ఇన్‌స్టాల్ చేశారని నిర్ధారించుకోండి: - -```bash -!pip install transformers datasets evaluate accelerate -``` - -మీరు మీ ప్రాధాన్య యంత్ర అభ్యాస ఫ్రేమ్‌వర్క్‌ను కూడా ఇన్‌స్టాల్ చేయాలి: - - - - -```bash -pip install torch -``` - - - -```bash -pip install tensorflow -``` - - - -## పైప్‌లైన్ - - - -[`pipeline`] అనుమితి కోసం ముందుగా శిక్షణ పొందిన నమూనాను ఉపయోగించడానికి సులభమైన మరియు వేగవంతమైన మార్గం. మీరు వివిధ పద్ధతులలో అనేక పనుల కోసం [`pipeline`] వెలుపల ఉపయోగించవచ్చు, వాటిలో కొన్ని క్రింది పట్టికలో చూపబడ్డాయి: - - - - -అందుబాటులో ఉన్న పనుల పూర్తి జాబితా కోసం, [పైప్‌లైన్ API సూచన](./main_classes/pipelines)ని తనిఖీ చేయండి. - - - -Here is the translation in Telugu: - -| **పని** | **వివరణ** | **మోడాలిటీ** | **పైప్‌లైన్ ఐడెంటిఫైయర్** | -|------------------------------|--------------------------------------------------------------------------------------------------------|-----------------|------------------------------------------| -| వచన వర్గీకరణు | కొన్ని వచనాల అంతా ఒక లేబుల్‌ను కొడి | NLP | pipeline(task=“sentiment-analysis”) | -| వచన సృష్టి | ప్రమ్పుటం కలిగినంత వచనం సృష్టించండి | NLP | pipeline(task=“text-generation”) | -| సంక్షేపణ | వచనం లేదా పత్రం కొరకు సంక్షేపణ తయారుచేసండి | NLP | pipeline(task=“summarization”) | -| చిత్రం వర్గీకరణు | చిత్రంలో ఒక లేబుల్‌ను కొడి | కంప్యూటర్ విషయం | pipeline(task=“image-classification”) | -| చిత్రం విభజన | ఒక చిత్రంలో ప్రతి వ్యక్తిగత పిక్సల్‌ను ఒక లేబుల్‌గా నమోదు చేయండి (సెమాంటిక్, పానొప్టిక్, మరియు ఇన్స్టన్స్ విభజనలను మద్దతు చేస్తుంది) | కంప్యూటర్ విషయం | pipeline(task=“image-segmentation”) | -| వస్త్రం గుర్తువు | ఒక చిత్రంలో పదాల యొక్క బౌండింగ్ బాక్స్‌లను మరియు వస్త్రాల వర్గాలను అంచనా చేయండి | కంప్యూటర్ విషయం | pipeline(task=“object-detection”) | -| ఆడియో గుర్తువు | కొన్ని ఆడియో డేటానికి ఒక లేబుల్‌ను కొడి | ఆడియో | pipeline(task=“audio-classification”) | -| స్వయంచలన ప్రసంగ గుర్తువు | ప్రసంగాన్ని వచనంగా వర్ణించండి | ఆడియో | pipeline(task=“automatic-speech-recognition”) | -| దృశ్య ప్రశ్న సంవాదం | వచనం మరియు ప్రశ్నను నమోదు చేసిన చిత్రంతో ప్రశ్నకు సమాధానం ఇవ్వండి | బహుమూలిక | pipeline(task=“vqa”) | -| పత్రం ప్రశ్న సంవాదం | ప్రశ్నను పత్రం లేదా డాక్యుమెంట్‌తో సమాధానం ఇవ్వండి | బహుమూలిక | pipeline(task="document-question-answering") | -| చిత్రం వ్రాసాయింగ్ | కొన్ని చిత్రానికి పిటియార్లను సృష్టించండి | బహుమూలిక | pipeline(task="image-to-text") | - - -[`pipeline`] యొక్క ఉదాహరణను సృష్టించడం ద్వారా మరియు మీరు దానిని ఉపయోగించాలనుకుంటున్న పనిని పేర్కొనడం ద్వారా ప్రారంభించండి. ఈ గైడ్‌లో, మీరు సెంటిమెంట్ విశ్లేషణ కోసం [`pipeline`]ని ఉదాహరణగా ఉపయోగిస్తారు: - -```py ->>> from transformers import pipeline - ->>> classifier = pipeline("sentiment-analysis") -``` - -సెంటిమెంట్ విశ్లేషణ కోసం [`pipeline`] డిఫాల్ట్ [ప్రీట్రైన్డ్ మోడల్](https://huggingface.co/distilbert/distilbert-base-uncased-finetuned-sst-2-english) మరియు టోకెనైజర్‌ని డౌన్‌లోడ్ చేస్తుంది మరియు కాష్ చేస్తుంది. ఇప్పుడు మీరు మీ లక్ష్య వచనంలో `classifier`ని ఉపయోగించవచ్చు: - -```py ->>> classifier("We are very happy to show you the 🤗 Transformers library.") -[{'label': 'POSITIVE', 'score': 0.9998}] -``` - -మీరు ఒకటి కంటే ఎక్కువ ఇన్‌పుట్‌లను కలిగి ఉంటే, నిఘంటువుల జాబితాను అందించడానికి మీ ఇన్‌పుట్‌లను జాబితాగా [`pipeline`]కి పంపండి: - -```py ->>> results = classifier(["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."]) ->>> for result in results: -... print(f"label: {result['label']}, with score: {round(result['score'], 4)}") -label: POSITIVE, with score: 0.9998 -label: NEGATIVE, with score: 0.5309 -``` - -[`pipeline`] మీకు నచ్చిన ఏదైనా పని కోసం మొత్తం డేటాసెట్‌ను కూడా పునరావృతం చేయగలదు. ఈ ఉదాహరణ కోసం, స్వయంచాలక ప్రసంగ గుర్తింపును మన పనిగా ఎంచుకుందాం: - -```py ->>> import torch ->>> from transformers import pipeline - ->>> speech_recognizer = pipeline("automatic-speech-recognition", model="facebook/wav2vec2-base-960h") -``` - -మీరు మళ్లీ మళ్లీ చెప్పాలనుకుంటున్న ఆడియో డేటాసెట్‌ను లోడ్ చేయండి (మరిన్ని వివరాల కోసం 🤗 డేటాసెట్‌లు [త్వరిత ప్రారంభం](https://huggingface.co/docs/datasets/quickstart#audio) చూడండి. ఉదాహరణకు, [MInDS-14](https://huggingface.co/datasets/PolyAI/minds14) డేటాసెట్‌ను లోడ్ చేయండి: - -```py ->>> from datasets import load_dataset, Audio - ->>> dataset = load_dataset("PolyAI/minds14", name="en-US", split="train") # doctest: +IGNORE_RESULT -``` - -డేటాసెట్ యొక్క నమూనా రేటు నమూనాతో సరిపోలుతుందని మీరు నిర్ధారించుకోవాలి -రేటు [`facebook/wav2vec2-base-960h`](https://huggingface.co/facebook/wav2vec2-base-960h) దీనిపై శిక్షణ పొందింది: - -```py ->>> dataset = dataset.cast_column("audio", Audio(sampling_rate=speech_recognizer.feature_extractor.sampling_rate)) -``` - -`"ఆడియో"` కాలమ్‌కి కాల్ చేస్తున్నప్పుడు ఆడియో ఫైల్‌లు స్వయంచాలకంగా లోడ్ చేయబడతాయి మరియు మళ్లీ నమూనా చేయబడతాయి. -మొదటి 4 నమూనాల నుండి ముడి వేవ్‌ఫార్మ్ శ్రేణులను సంగ్రహించి, పైప్‌లైన్‌కు జాబితాగా పాస్ చేయండి: - -```py ->>> result = speech_recognizer(dataset[:4]["audio"]) ->>> print([d["text"] for d in result]) -['I WOULD LIKE TO SET UP A JOINT ACCOUNT WITH MY PARTNER HOW DO I PROCEED WITH DOING THAT', "FONDERING HOW I'D SET UP A JOIN TO HELL T WITH MY WIFE AND WHERE THE AP MIGHT BE", "I I'D LIKE TOY SET UP A JOINT ACCOUNT WITH MY PARTNER I'M NOT SEEING THE OPTION TO DO IT ON THE APSO I CALLED IN TO GET SOME HELP CAN I JUST DO IT OVER THE PHONE WITH YOU AND GIVE YOU THE INFORMATION OR SHOULD I DO IT IN THE AP AN I'M MISSING SOMETHING UQUETTE HAD PREFERRED TO JUST DO IT OVER THE PHONE OF POSSIBLE THINGS", 'HOW DO I FURN A JOINA COUT'] -``` - -ఇన్‌పుట్‌లు పెద్దగా ఉన్న పెద్ద డేటాసెట్‌ల కోసం (స్పీచ్ లేదా విజన్ వంటివి), మెమరీలోని అన్ని ఇన్‌పుట్‌లను లోడ్ చేయడానికి మీరు జాబితాకు బదులుగా జెనరేటర్‌ను పాస్ చేయాలనుకుంటున్నారు. మరింత సమాచారం కోసం [పైప్‌లైన్ API సూచన](./main_classes/pipelines)ని చూడండి. - -### పైప్‌లైన్‌లో మరొక మోడల్ మరియు టోకెనైజర్‌ని ఉపయోగించండి - -[`pipeline`] [Hub](https://huggingface.co/models) నుండి ఏదైనా మోడల్‌ను కలిగి ఉంటుంది, దీని వలన ఇతర వినియోగ-కేసుల కోసం [`pipeline`]ని సులభంగా స్వీకరించవచ్చు. ఉదాహరణకు, మీరు ఫ్రెంచ్ టెక్స్ట్‌ను హ్యాండిల్ చేయగల మోడల్ కావాలనుకుంటే, తగిన మోడల్ కోసం ఫిల్టర్ చేయడానికి హబ్‌లోని ట్యాగ్‌లను ఉపయోగించండి. అగ్ర ఫిల్టర్ చేసిన ఫలితం మీరు ఫ్రెంచ్ టెక్స్ట్ కోసం ఉపయోగించగల సెంటిమెంట్ విశ్లేషణ కోసం ఫైన్‌ట్యూన్ చేయబడిన బహుభాషా [BERT మోడల్](https://huggingface.co/nlptown/bert-base-multilingual-uncased-sentiment)ని అందిస్తుంది: - -```py ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" -``` - - - -ముందుగా శిక్షణ పొందిన మోడల్‌ను లోడ్ చేయడానికి [`AutoModelForSequenceClassification`] మరియు [`AutoTokenizer`]ని ఉపయోగించండి మరియు దాని అనుబంధిత టోకెనైజర్ (తదుపరి విభాగంలో `AutoClass`పై మరిన్ని): - -```py ->>> from transformers import AutoTokenizer, AutoModelForSequenceClassification - ->>> model = AutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - - -ముందుగా శిక్షణ పొందిన మోడల్‌ను లోడ్ చేయడానికి [`TFAutoModelForSequenceClassification`] మరియు [`AutoTokenizer`]ని ఉపయోగించండి మరియు దాని అనుబంధిత టోకెనైజర్ (తదుపరి విభాగంలో `TFAutoClass`పై మరిన్ని): - -```py ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - - - -[`pipeline`]లో మోడల్ మరియు టోకెనైజర్‌ను పేర్కొనండి మరియు ఇప్పుడు మీరు ఫ్రెంచ్ టెక్స్ట్‌పై `క్లాసిఫైయర్`ని వర్తింపజేయవచ్చు: - -```py ->>> classifier = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer) ->>> classifier("Nous sommes très heureux de vous présenter la bibliothèque 🤗 Transformers.") -[{'label': '5 stars', 'score': 0.7273}] -``` - -మీరు మీ వినియోగ-కేస్ కోసం మోడల్‌ను కనుగొనలేకపోతే, మీరు మీ డేటాపై ముందుగా శిక్షణ పొందిన మోడల్‌ను చక్కగా మార్చాలి. ఎలాగో తెలుసుకోవడానికి మా [ఫైన్‌ట్యూనింగ్ ట్యుటోరియల్](./training)ని చూడండి. చివరగా, మీరు మీ ప్రీట్రైన్డ్ మోడల్‌ని ఫైన్‌ట్యూన్ చేసిన తర్వాత, దయచేసి అందరి కోసం మెషిన్ లెర్నింగ్‌ని డెమోక్రటైజ్ చేయడానికి హబ్‌లోని సంఘంతో మోడల్‌ను [షేరింగ్](./model_sharing) పరిగణించండి! 🤗 - -## AutoClass - - - -హుడ్ కింద, మీరు పైన ఉపయోగించిన [`pipeline`]కి శక్తిని అందించడానికి [`AutoModelForSequenceClassification`] మరియు [`AutoTokenizer`] తరగతులు కలిసి పని చేస్తాయి. ఒక [AutoClass](./model_doc/auto) అనేది ముందుగా శిక్షణ పొందిన మోడల్ యొక్క ఆర్కిటెక్చర్‌ను దాని పేరు లేదా మార్గం నుండి స్వయంచాలకంగా తిరిగి పొందే సత్వరమార్గం. మీరు మీ టాస్క్ కోసం తగిన `ఆటోక్లాస్`ని మాత్రమే ఎంచుకోవాలి మరియు ఇది అనుబంధిత ప్రీప్రాసెసింగ్ క్లాస్. - -మునుపటి విభాగం నుండి ఉదాహరణకి తిరిగి వెళ్లి, [`pipeline`] ఫలితాలను ప్రతిబింబించడానికి మీరు `ఆటోక్లాస్`ని ఎలా ఉపయోగించవచ్చో చూద్దాం. - -### AutoTokenizer - -ఒక మోడల్‌కు ఇన్‌పుట్‌లుగా సంఖ్యల శ్రేణిలో వచనాన్ని ప్రీప్రాసెసింగ్ చేయడానికి టోకెనైజర్ బాధ్యత వహిస్తుంది. పదాన్ని ఎలా విభజించాలి మరియు ఏ స్థాయిలో పదాలను విభజించాలి ([tokenizer సారాంశం](./tokenizer_summary)లో టోకనైజేషన్ గురించి మరింత తెలుసుకోండి) సహా టోకనైజేషన్ ప్రక్రియను నియంత్రించే అనేక నియమాలు ఉన్నాయి. గుర్తుంచుకోవలసిన ముఖ్యమైన విషయం ఏమిటంటే, మీరు మోడల్‌కు ముందే శిక్షణ పొందిన అదే టోకనైజేషన్ నియమాలను ఉపయోగిస్తున్నారని నిర్ధారించుకోవడానికి మీరు అదే మోడల్ పేరుతో టోకెనైజర్‌ను తక్షణం చేయాలి. - -[`AutoTokenizer`]తో టోకెనైజర్‌ను లోడ్ చేయండి: - -```py ->>> from transformers import AutoTokenizer - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - -మీ వచనాన్ని టోకెనైజర్‌కు పంపండి: - -```py ->>> encoding = tokenizer("We are very happy to show you the 🤗 Transformers library.") ->>> print(encoding) -{'input_ids': [101, 11312, 10320, 12495, 19308, 10114, 11391, 10855, 10103, 100, 58263, 13299, 119, 102], - 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]} -``` - -టోకెనైజర్ వీటిని కలిగి ఉన్న నిఘంటువుని అందిస్తుంది: - -* [input_ids](./glossary#input-ids): మీ టోకెన్‌ల సంఖ్యాపరమైన ప్రాతినిధ్యం. -* [అటెన్షన్_మాస్క్](./glossary#attention-mask): ఏ టోకెన్‌లకు హాజరు కావాలో సూచిస్తుంది. - -ఒక టోకెనైజర్ ఇన్‌పుట్‌ల జాబితాను కూడా ఆమోదించగలదు మరియు ఏకరీతి పొడవుతో బ్యాచ్‌ను తిరిగి ఇవ్వడానికి టెక్స్ట్‌ను ప్యాడ్ చేసి కత్తిరించవచ్చు: - - - - -```py ->>> pt_batch = tokenizer( -... ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="pt", -... ) -``` - - - -```py ->>> tf_batch = tokenizer( -... ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="tf", -... ) -``` - - - - - -టోకనైజేషన్ గురించి మరిన్ని వివరాల కోసం [ప్రీప్రాసెస్](./preprocessing) ట్యుటోరియల్‌ని చూడండి మరియు ఇమేజ్, ఆడియో మరియు మల్టీమోడల్ ఇన్‌పుట్‌లను ప్రీప్రాసెస్ చేయడానికి [`AutoImageProcessor`], [`AutoFeatureExtractor`] మరియు [`AutoProcessor`] ఎలా ఉపయోగించాలి. - - - -### AutoModel - - - -🤗 ట్రాన్స్‌ఫార్మర్లు ప్రీట్రైన్డ్ ఇన్‌స్టాన్స్‌లను లోడ్ చేయడానికి సులభమైన మరియు ఏకీకృత మార్గాన్ని అందిస్తాయి. దీని అర్థం మీరు [`AutoTokenizer`]ని లోడ్ చేసినట్లుగా [`AutoModel`]ని లోడ్ చేయవచ్చు. టాస్క్ కోసం సరైన [`AutoModel`]ని ఎంచుకోవడం మాత్రమే తేడా. టెక్స్ట్ (లేదా సీక్వెన్స్) వర్గీకరణ కోసం, మీరు [`AutoModelForSequenceClassification`]ని లోడ్ చేయాలి: - - -```py ->>> from transformers import AutoModelForSequenceClassification - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> pt_model = AutoModelForSequenceClassification.from_pretrained(model_name) -``` - - - -[`AutoModel`] క్లాస్ ద్వారా సపోర్ట్ చేసే టాస్క్‌ల కోసం [టాస్క్ సారాంశం](./task_summary)ని చూడండి. - - - -ఇప్పుడు మీ ప్రీప్రాసెస్ చేయబడిన బ్యాచ్ ఇన్‌పుట్‌లను నేరుగా మోడల్‌కి పంపండి. మీరు `**`ని జోడించడం ద్వారా నిఘంటువుని అన్‌ప్యాక్ చేయాలి: - -```py ->>> pt_outputs = pt_model(**pt_batch) -``` - -మోడల్ తుది యాక్టివేషన్‌లను `logits` లక్షణంలో అవుట్‌పుట్ చేస్తుంది. సంభావ్యతలను తిరిగి పొందడానికి సాఫ్ట్‌మాక్స్ ఫంక్షన్‌ను `logits` కు వర్తింపజేయండి: - - -```py ->>> from torch import nn - ->>> pt_predictions = nn.functional.softmax(pt_outputs.logits, dim=-1) ->>> print(pt_predictions) -tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], - [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) -``` - - - -🤗 ట్రాన్స్‌ఫార్మర్లు ప్రీట్రైన్డ్ ఇన్‌స్టాన్స్‌లను లోడ్ చేయడానికి సులభమైన మరియు ఏకీకృత మార్గాన్ని అందిస్తాయి. మీరు [`AutoTokenizer`]ని లోడ్ చేసినట్లుగా మీరు [`TFAutoModel`]ని లోడ్ చేయవచ్చని దీని అర్థం. టాస్క్ కోసం సరైన [`TFAutoModel`]ని ఎంచుకోవడం మాత్రమే తేడా. టెక్స్ట్ (లేదా సీక్వెన్స్) వర్గీకరణ కోసం, మీరు [`TFAutoModelForSequenceClassification`]ని లోడ్ చేయాలి: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name) -``` - - - -[`AutoModel`] క్లాస్ ద్వారా సపోర్ట్ చేసే టాస్క్‌ల కోసం [టాస్క్ సారాంశం](./task_summary)ని చూడండి. - - - -ఇప్పుడు మీ ప్రీప్రాసెస్ చేయబడిన బ్యాచ్ ఇన్‌పుట్‌లను నేరుగా మోడల్‌కి పంపండి. మీరు టెన్సర్‌లను ఇలా పాస్ చేయవచ్చు: - -```py ->>> tf_outputs = tf_model(tf_batch) -``` - -మోడల్ తుది యాక్టివేషన్‌లను `logits` లక్షణంలో అవుట్‌పుట్ చేస్తుంది. సంభావ్యతలను తిరిగి పొందడానికి సాఫ్ట్‌మాక్స్ ఫంక్షన్‌ను `logits`కు వర్తింపజేయండి: - -```py ->>> import tensorflow as tf - ->>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1) ->>> tf_predictions # doctest: +IGNORE_RESULT -``` - - - - - -అన్ని 🤗 ట్రాన్స్‌ఫార్మర్స్ మోడల్‌లు (PyTorch లేదా TensorFlow) తుది యాక్టివేషన్‌కు *ముందు* టెన్సర్‌లను అవుట్‌పుట్ చేస్తాయి -ఫంక్షన్ (softmax వంటిది) ఎందుకంటే చివరి యాక్టివేషన్ ఫంక్షన్ తరచుగా నష్టంతో కలిసిపోతుంది. మోడల్ అవుట్‌పుట్‌లు ప్రత్యేక డేటాక్లాస్‌లు కాబట్టి వాటి లక్షణాలు IDEలో స్వయంచాలకంగా పూర్తి చేయబడతాయి. మోడల్ అవుట్‌పుట్‌లు టుపుల్ లేదా డిక్షనరీ లాగా ప్రవర్తిస్తాయి (మీరు పూర్ణాంకం, స్లైస్ లేదా స్ట్రింగ్‌తో ఇండెక్స్ చేయవచ్చు) ఈ సందర్భంలో, ఏదీ లేని గుణాలు విస్మరించబడతాయి. - - - -### మోడల్‌ను సేవ్ చేయండి - - - -మీ మోడల్ చక్కగా ట్యూన్ చేయబడిన తర్వాత, మీరు దానిని [`PreTrainedModel.save_pretrained`]ని ఉపయోగించి దాని టోకెనైజర్‌తో సేవ్ చేయవచ్చు: - -```py ->>> pt_save_directory = "./pt_save_pretrained" ->>> tokenizer.save_pretrained(pt_save_directory) # doctest: +IGNORE_RESULT ->>> pt_model.save_pretrained(pt_save_directory) -``` - -మీరు మోడల్‌ని మళ్లీ ఉపయోగించడానికి సిద్ధంగా ఉన్నప్పుడు, దాన్ని [`PreTrainedModel.from_pretrained`]తో రీలోడ్ చేయండి: - -```py ->>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") -``` - - -మీ మోడల్ చక్కగా ట్యూన్ చేయబడిన తర్వాత, మీరు దానిని [`TFPreTrainedModel.save_pretrained`]ని ఉపయోగించి దాని టోకెనైజర్‌తో సేవ్ చేయవచ్చు: - -```py ->>> tf_save_directory = "./tf_save_pretrained" ->>> tokenizer.save_pretrained(tf_save_directory) # doctest: +IGNORE_RESULT ->>> tf_model.save_pretrained(tf_save_directory) -``` -మీరు మోడల్‌ని మళ్లీ ఉపయోగించడానికి సిద్ధంగా ఉన్నప్పుడు, దాన్ని [`TFPreTrainedModel.from_pretrained`]తో రీలోడ్ చేయండి: - -```py ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained") -``` - - - -ఒక ప్రత్యేకించి అద్భుతమైన 🤗 ట్రాన్స్‌ఫార్మర్స్ ఫీచర్ మోడల్‌ను సేవ్ చేయగల సామర్థ్యం మరియు దానిని PyTorch లేదా TensorFlow మోడల్‌గా రీలోడ్ చేయగలదు. `from_pt` లేదా `from_tf` పరామితి మోడల్‌ను ఒక ఫ్రేమ్‌వర్క్ నుండి మరొక ఫ్రేమ్‌వర్క్‌కి మార్చగలదు: - - - - -```py ->>> from transformers import AutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory) ->>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) -``` - - - -```py ->>> from transformers import TFAutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory) ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) -``` - - - -## కస్టమ్ మోడల్ బిల్డ్స్ -మోడల్ ఎలా నిర్మించబడుతుందో మార్చడానికి మీరు మోడల్ కాన్ఫిగరేషన్ క్లాస్‌ని సవరించవచ్చు. దాచిన లేయర్‌లు లేదా అటెన్షన్ హెడ్‌ల సంఖ్య వంటి మోడల్ లక్షణాలను కాన్ఫిగరేషన్ నిర్దేశిస్తుంది. మీరు కస్టమ్ కాన్ఫిగరేషన్ క్లాస్ నుండి మోడల్‌ను ప్రారంభించినప్పుడు మీరు మొదటి నుండి ప్రారంభిస్తారు. మోడల్ అట్రిబ్యూట్‌లు యాదృచ్ఛికంగా ప్రారంభించబడ్డాయి మరియు అర్థవంతమైన ఫలితాలను పొందడానికి మీరు మోడల్‌ను ఉపయోగించే ముందు దానికి శిక్షణ ఇవ్వాలి. - -[`AutoConfig`]ని దిగుమతి చేయడం ద్వారా ప్రారంభించండి, ఆపై మీరు సవరించాలనుకుంటున్న ప్రీట్రైన్డ్ మోడల్‌ను లోడ్ చేయండి. [`AutoConfig.from_pretrained`]లో, మీరు అటెన్షన్ హెడ్‌ల సంఖ్య వంటి మీరు మార్చాలనుకుంటున్న లక్షణాన్ని పేర్కొనవచ్చు: - -```py ->>> from transformers import AutoConfig - ->>> my_config = AutoConfig.from_pretrained("distilbert/distilbert-base-uncased", n_heads=12) -``` - - - -[`AutoModel.from_config`]తో మీ అనుకూల కాన్ఫిగరేషన్ నుండి మోడల్‌ను సృష్టించండి: - -```py ->>> from transformers import AutoModel - ->>> my_model = AutoModel.from_config(my_config) -``` - - -[`TFAutoModel.from_config`]తో మీ అనుకూల కాన్ఫిగరేషన్ నుండి మోడల్‌ను సృష్టించండి: - -```py ->>> from transformers import TFAutoModel - ->>> my_model = TFAutoModel.from_config(my_config) -``` - - - -అనుకూల కాన్ఫిగరేషన్‌లను రూపొందించడం గురించి మరింత సమాచారం కోసం [కస్టమ్ ఆర్కిటెక్చర్‌ని సృష్టించండి](./create_a_model) గైడ్‌ను చూడండి. - -## శిక్షకుడు - పైటార్చ్ ఆప్టిమైజ్ చేసిన శిక్షణ లూప్ - -అన్ని మోడల్‌లు ప్రామాణికమైన [`torch.nn.Module`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) కాబట్టి మీరు వాటిని ఏదైనా సాధారణ శిక్షణ లూప్‌లో ఉపయోగించవచ్చు. మీరు మీ స్వంత శిక్షణ లూప్‌ను వ్రాయగలిగినప్పటికీ, 🤗 ట్రాన్స్‌ఫార్మర్లు PyTorch కోసం [`ట్రైనర్`] తరగతిని అందజేస్తాయి, ఇందులో ప్రాథమిక శిక్షణ లూప్ ఉంటుంది మరియు పంపిణీ చేయబడిన శిక్షణ, మిశ్రమ ఖచ్చితత్వం మరియు మరిన్ని వంటి ఫీచర్‌ల కోసం అదనపు కార్యాచరణను జోడిస్తుంది. - -మీ విధిని బట్టి, మీరు సాధారణంగా కింది పారామితులను [`ట్రైనర్`]కి పంపుతారు: - -1. మీరు [`PreTrainedModel`] లేదా [`torch.nn.Module`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module)తో ప్రారంభిస్తారు: - ```py - >>> from transformers import AutoModelForSequenceClassification - - >>> model = AutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") - ``` - -2. [`TrainingArguments`] మీరు నేర్చుకునే రేటు, బ్యాచ్ పరిమాణం మరియు శిక్షణ పొందవలసిన యుగాల సంఖ్య వంటి మార్చగల మోడల్ హైపర్‌పారామీటర్‌లను కలిగి ఉంది. మీరు ఎలాంటి శిక్షణా వాదనలను పేర్కొనకుంటే డిఫాల్ట్ విలువలు ఉపయోగించబడతాయి: - - ```py - >>> from transformers import TrainingArguments - - >>> training_args = TrainingArguments( - ... output_dir="path/to/save/folder/", - ... learning_rate=2e-5, - ... per_device_train_batch_size=8, - ... per_device_eval_batch_size=8, - ... num_train_epochs=2, - ... ) - ``` - -3. టోకెనైజర్, ఇమేజ్ ప్రాసెసర్, ఫీచర్ ఎక్స్‌ట్రాక్టర్ లేదా ప్రాసెసర్ వంటి ప్రీప్రాసెసింగ్ క్లాస్‌ని లోడ్ చేయండి: - ```py - >>> from transformers import AutoTokenizer - - >>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased") - ``` - -4. డేటాసెట్‌ను లోడ్ చేయండి: - - ```py - >>> from datasets import load_dataset - - >>> dataset = load_dataset("rotten_tomatoes") # doctest: +IGNORE_RESULT - ``` - -5. డేటాసెట్‌ను టోకనైజ్ చేయడానికి ఒక ఫంక్షన్‌ను సృష్టించండి: - - ```py - >>> def tokenize_dataset(dataset): - ... return tokenizer(dataset["text"]) - ``` - - ఆపై దానిని [`~datasets.Dataset.map`]తో మొత్తం డేటాసెట్‌లో వర్తింపజేయండి: - - ```py - >>> dataset = dataset.map(tokenize_dataset, batched=True) - ``` - -6. మీ డేటాసెట్ నుండి ఉదాహరణల సమూహాన్ని సృష్టించడానికి [`DataCollatorWithPadding`]: - - ```py - >>> from transformers import DataCollatorWithPadding - - >>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer) - ``` - -ఇప్పుడు ఈ తరగతులన్నింటినీ [`Trainer`]లో సేకరించండి: - -```py ->>> from transformers import Trainer - ->>> trainer = Trainer( -... model=model, -... args=training_args, -... train_dataset=dataset["train"], -... eval_dataset=dataset["test"], -... processing_class=tokenizer, -... data_collator=data_collator, -... ) # doctest: +SKIP -``` - -మీరు సిద్ధంగా ఉన్నప్పుడు, శిక్షణను ప్రారంభించడానికి [`~Trainer.train`]కి కాల్ చేయండి: - -```py ->>> trainer.train() # doctest: +SKIP -``` - - - -సీక్వెన్స్-టు-సీక్వెన్స్ మోడల్‌ని ఉపయోగించే - అనువాదం లేదా సారాంశం వంటి పనుల కోసం, బదులుగా [`Seq2SeqTrainer`] మరియు [`Seq2SeqTrainingArguments`] తరగతులను ఉపయోగించండి. - - - -మీరు [`Trainer`] లోపల ఉన్న పద్ధతులను ఉపవర్గీకరించడం ద్వారా శిక్షణ లూప్ ప్రవర్తనను అనుకూలీకరించవచ్చు. ఇది లాస్ ఫంక్షన్, ఆప్టిమైజర్ మరియు షెడ్యూలర్ వంటి లక్షణాలను అనుకూలీకరించడానికి మిమ్మల్ని అనుమతిస్తుంది. ఉపవర్గీకరించబడే పద్ధతుల కోసం [`Trainer`] సూచనను పరిశీలించండి. - -శిక్షణ లూప్‌ను అనుకూలీకరించడానికి మరొక మార్గం [కాల్‌బ్యాక్‌లు](./main_classes/callback). మీరు ఇతర లైబ్రరీలతో అనుసంధానం చేయడానికి కాల్‌బ్యాక్‌లను ఉపయోగించవచ్చు మరియు పురోగతిపై నివేదించడానికి శిక్షణ లూప్‌ను తనిఖీ చేయవచ్చు లేదా శిక్షణను ముందుగానే ఆపవచ్చు. శిక్షణ లూప్‌లోనే కాల్‌బ్యాక్‌లు దేనినీ సవరించవు. లాస్ ఫంక్షన్ వంటివాటిని అనుకూలీకరించడానికి, మీరు బదులుగా [`Trainer`]ని ఉపవర్గం చేయాలి. - -## TensorFlowతో శిక్షణ పొందండి - -అన్ని మోడల్‌లు ప్రామాణికమైన [`tf.keras.Model`](https://www.tensorflow.org/api_docs/python/tf/keras/Model) కాబట్టి వాటిని [Keras]తో TensorFlowలో శిక్షణ పొందవచ్చు(https: //keras.io/) API. 🤗 ట్రాన్స్‌ఫార్మర్‌లు మీ డేటాసెట్‌ని సులభంగా `tf.data.Dataset`గా లోడ్ చేయడానికి [`~TFPreTrainedModel.prepare_tf_dataset`] పద్ధతిని అందజేస్తుంది కాబట్టి మీరు వెంటనే Keras' [`compile`](https://keras.io/api/models/model_training_apis/#compile-method) మరియు [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) పద్ధతులు. - -1. మీరు [`TFPreTrainedModel`] లేదా [`tf.keras.Model`](https://www.tensorflow.org/api_docs/python/tf/keras/Model)తో ప్రారంభిస్తారు: - ```py - >>> from transformers import TFAutoModelForSequenceClassification - - >>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") - ``` - -2. టోకెనైజర్, ఇమేజ్ ప్రాసెసర్, ఫీచర్ ఎక్స్‌ట్రాక్టర్ లేదా ప్రాసెసర్ వంటి ప్రీప్రాసెసింగ్ క్లాస్‌ని లోడ్ చేయండి: - - ```py - >>> from transformers import AutoTokenizer - - >>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased") - ``` - -3. డేటాసెట్‌ను టోకనైజ్ చేయడానికి ఒక ఫంక్షన్‌ను సృష్టించండి: - - ```py - >>> def tokenize_dataset(dataset): - ... return tokenizer(dataset["text"]) # doctest: +SKIP - ``` - -4. [`~datasets.Dataset.map`]తో మొత్తం డేటాసెట్‌పై టోకెనైజర్‌ని వర్తింపజేయి, ఆపై డేటాసెట్ మరియు టోకెనైజర్‌ను [`~TFPreTrainedModel.prepare_tf_dataset`]కి పంపండి. మీరు కావాలనుకుంటే బ్యాచ్ పరిమాణాన్ని కూడా మార్చవచ్చు మరియు డేటాసెట్‌ను ఇక్కడ షఫుల్ చేయవచ్చు: - ```py - >>> dataset = dataset.map(tokenize_dataset) # doctest: +SKIP - >>> tf_dataset = model.prepare_tf_dataset( - ... dataset["train"], batch_size=16, shuffle=True, tokenizer=tokenizer - ... ) # doctest: +SKIP - ``` - -5. మీరు సిద్ధంగా ఉన్నప్పుడు, శిక్షణను ప్రారంభించడానికి మీరు `కంపైల్` మరియు `ఫిట్`కి కాల్ చేయవచ్చు. ట్రాన్స్‌ఫార్మర్స్ మోడల్స్ అన్నీ డిఫాల్ట్ టాస్క్-సంబంధిత లాస్ ఫంక్షన్‌ని కలిగి ఉన్నాయని గుర్తుంచుకోండి, కాబట్టి మీరు కోరుకునే వరకు మీరు ఒకదానిని పేర్కొనవలసిన అవసరం లేదు: - - ```py - >>> from tensorflow.keras.optimizers import Adam - - >>> model.compile(optimizer=Adam(3e-5)) # No loss argument! - >>> model.fit(tf_dataset) # doctest: +SKIP - ``` - -## తరవాత ఏంటి? - -ఇప్పుడు మీరు 🤗 ట్రాన్స్‌ఫార్మర్స్ త్వరిత పర్యటనను పూర్తి చేసారు, మా గైడ్‌లను తనిఖీ చేయండి మరియు అనుకూల మోడల్‌ను వ్రాయడం, టాస్క్ కోసం మోడల్‌ను చక్కగా తీర్చిదిద్దడం మరియు స్క్రిప్ట్‌తో మోడల్‌కు శిక్షణ ఇవ్వడం వంటి మరింత నిర్దిష్టమైన పనులను ఎలా చేయాలో తెలుసుకోండి. 🤗 ట్రాన్స్‌ఫార్మర్స్ కోర్ కాన్సెప్ట్‌ల గురించి మరింత తెలుసుకోవడానికి మీకు ఆసక్తి ఉంటే, ఒక కప్పు కాఫీ తాగి, మా కాన్సెప్టువల్ గైడ్‌లను చూడండి! diff --git a/docs/source/tr/_toctree.yml b/docs/source/tr/_toctree.yml deleted file mode 100644 index 8401da6e4eb0..000000000000 --- a/docs/source/tr/_toctree.yml +++ /dev/null @@ -1,4 +0,0 @@ -- sections: - - local: index - title: 🤗 Transformers - title: Get started \ No newline at end of file diff --git a/docs/source/tr/index.md b/docs/source/tr/index.md deleted file mode 100644 index 1b2c665e169d..000000000000 --- a/docs/source/tr/index.md +++ /dev/null @@ -1,295 +0,0 @@ - - -# 🤗 Transformers - -[PyTorch](https://pytorch.org/), [TensorFlow](https://www.tensorflow.org/) ve [JAX](https://jax.readthedocs.io/en/latest/) için son teknoloji makine öğrenimi. - -🤗 Transformers, güncel önceden eğitilmiş (pretrained) modelleri indirmenizi ve eğitmenizi kolaylaştıran API'ler ve araçlar sunar. Önceden eğitilmiş modeller kullanarak, hesaplama maliyetlerinizi ve karbon ayak izinizi azaltabilir, ve sıfırdan bir modeli eğitmek için gereken zaman ve kaynaklardan tasarruf edebilirsiniz. Bu modeller farklı modalitelerde ortak görevleri destekler. Örneğin: - -📝 **Doğal Dil İşleme**: metin sınıflandırma, adlandırılmış varlık tanıma, soru cevaplama, dil modelleme, özetleme, çeviri, çoktan seçmeli ve metin oluşturma.
-🖼️ **Bilgisayarlı Görü**: görüntü sınıflandırma, nesne tespiti ve bölümleme (segmentation).
-🗣️ **Ses**: otomatik konuşma tanıma ve ses sınıflandırma.
-🐙 **Çoklu Model**: tablo soru cevaplama, optik karakter tanıma, taranmış belgelerden bilgi çıkarma, video sınıflandırma ve görsel soru cevaplama. - -🤗 Transformers, PyTorch, TensorFlow ve JAX arasında çerçeve (framework) uyumluluğu sağlar. Bu, bir modelin yaşam döngüsünün her aşamasında farklı bir çerçeve kullanma esnekliği sunar; bir çerçevede üç satır kodla bir modeli eğitebilir ve başka bir çerçevede tahminleme için kullanabilirsiniz. Modeller ayrıca üretim ortamlarında kullanılmak üzere ONNX ve TorchScript gibi bir formata aktarılabilir. - -Büyüyen topluluğa [Hub](https://huggingface.co/models), [Forum](https://discuss.huggingface.co/) veya [Discord](https://discord.com/invite/JfAtkvEtRb) üzerinden katılabilirsiniz! - -## Hugging Face ekibinden özel destek arıyorsanız - - - HuggingFace Uzman Hızlandırma Programı - - -## İçindekiler - -Dokümantasyon, beş bölüme ayrılmıştır: - -- **BAŞLARKEN**, kütüphanenin hızlı bir turunu ve çalışmaya başlamak için kurulum talimatlarını sağlar. -- **ÖĞRETİCİLER**, başlangıç yapmak için harika bir yerdir. Bu bölüm, kütüphane kullanmaya başlamak için ihtiyacınız olan temel becerileri kazanmanıza yardımcı olacaktır. -- **NASIL YAPILIR KILAVUZLARI**, önceden eğitilmiş bir modele dil modellemesi için ince ayar (fine-tuning) yapmak veya özel bir model yazmak, ve paylaşmak gibi belirli bir hedefe nasıl ulaşılacağını gösterir. -- **KAVRAMSAL REHBERLER**, modellerin, görevlerin ve 🤗 Transformers tasarım felsefesinin temel kavramları ve fikirleri hakkında daha fazla tartışma ve açıklama sunar. -- **API** tüm sınıfları (class) ve fonksiyonları (functions) açıklar: - - - **ANA SINIFLAR**, yapılandırma, model, tokenizer ve pipeline gibi en önemli sınıfları (classes) ayrıntılandırır. - - **MODELLER**, kütüphanede kullanılan her modelle ilgili sınıfları ve fonksiyonları detaylı olarak inceler. - - **DAHİLİ YARDIMCILAR**, kullanılan yardımcı sınıfları ve fonksiyonları detaylı olarak inceler. - -## Desteklenen Modeller ve Çerçeveler - -Aşağıdaki tablo, her bir model için kütüphanede yer alan mevcut desteği temsil etmektedir. Her bir model için bir Python tokenizer'ına ("slow" olarak adlandırılır) sahip olup olmadıkları, 🤗 Tokenizers kütüphanesi tarafından desteklenen hızlı bir tokenizer'a sahip olup olmadıkları, Jax (Flax aracılığıyla), PyTorch ve/veya TensorFlow'da destek olup olmadıklarını göstermektedir. - - - -| Model | PyTorch support | TensorFlow support | Flax Support | -|:------------------------------------------------------------------------:|:---------------:|:------------------:|:------------:| -| [ALBERT](model_doc/albert) | ✅ | ✅ | ✅ | -| [ALIGN](model_doc/align) | ✅ | ❌ | ❌ | -| [AltCLIP](model_doc/altclip) | ✅ | ❌ | ❌ | -| [Audio Spectrogram Transformer](model_doc/audio-spectrogram-transformer) | ✅ | ❌ | ❌ | -| [Autoformer](model_doc/autoformer) | ✅ | ❌ | ❌ | -| [Bark](model_doc/bark) | ✅ | ❌ | ❌ | -| [BART](model_doc/bart) | ✅ | ✅ | ✅ | -| [BARThez](model_doc/barthez) | ✅ | ✅ | ✅ | -| [BARTpho](model_doc/bartpho) | ✅ | ✅ | ✅ | -| [BEiT](model_doc/beit) | ✅ | ❌ | ✅ | -| [BERT](model_doc/bert) | ✅ | ✅ | ✅ | -| [Bert Generation](model_doc/bert-generation) | ✅ | ❌ | ❌ | -| [BertJapanese](model_doc/bert-japanese) | ✅ | ✅ | ✅ | -| [BERTweet](model_doc/bertweet) | ✅ | ✅ | ✅ | -| [BigBird](model_doc/big_bird) | ✅ | ❌ | ✅ | -| [BigBird-Pegasus](model_doc/bigbird_pegasus) | ✅ | ❌ | ❌ | -| [BioGpt](model_doc/biogpt) | ✅ | ❌ | ❌ | -| [BiT](model_doc/bit) | ✅ | ❌ | ❌ | -| [Blenderbot](model_doc/blenderbot) | ✅ | ✅ | ✅ | -| [BlenderbotSmall](model_doc/blenderbot-small) | ✅ | ✅ | ✅ | -| [BLIP](model_doc/blip) | ✅ | ✅ | ❌ | -| [BLIP-2](model_doc/blip-2) | ✅ | ❌ | ❌ | -| [BLOOM](model_doc/bloom) | ✅ | ❌ | ✅ | -| [BORT](model_doc/bort) | ✅ | ✅ | ✅ | -| [BridgeTower](model_doc/bridgetower) | ✅ | ❌ | ❌ | -| [BROS](model_doc/bros) | ✅ | ❌ | ❌ | -| [ByT5](model_doc/byt5) | ✅ | ✅ | ✅ | -| [CamemBERT](model_doc/camembert) | ✅ | ✅ | ❌ | -| [CANINE](model_doc/canine) | ✅ | ❌ | ❌ | -| [Chinese-CLIP](model_doc/chinese_clip) | ✅ | ❌ | ❌ | -| [CLAP](model_doc/clap) | ✅ | ❌ | ❌ | -| [CLIP](model_doc/clip) | ✅ | ✅ | ✅ | -| [CLIPSeg](model_doc/clipseg) | ✅ | ❌ | ❌ | -| [CodeGen](model_doc/codegen) | ✅ | ❌ | ❌ | -| [CodeLlama](model_doc/code_llama) | ✅ | ❌ | ❌ | -| [Conditional DETR](model_doc/conditional_detr) | ✅ | ❌ | ❌ | -| [ConvBERT](model_doc/convbert) | ✅ | ✅ | ❌ | -| [ConvNeXT](model_doc/convnext) | ✅ | ✅ | ❌ | -| [ConvNeXTV2](model_doc/convnextv2) | ✅ | ❌ | ❌ | -| [CPM](model_doc/cpm) | ✅ | ✅ | ✅ | -| [CPM-Ant](model_doc/cpmant) | ✅ | ❌ | ❌ | -| [CTRL](model_doc/ctrl) | ✅ | ✅ | ❌ | -| [CvT](model_doc/cvt) | ✅ | ✅ | ❌ | -| [Data2VecAudio](model_doc/data2vec) | ✅ | ❌ | ❌ | -| [Data2VecText](model_doc/data2vec) | ✅ | ❌ | ❌ | -| [Data2VecVision](model_doc/data2vec) | ✅ | ✅ | ❌ | -| [DeBERTa](model_doc/deberta) | ✅ | ✅ | ❌ | -| [DeBERTa-v2](model_doc/deberta-v2) | ✅ | ✅ | ❌ | -| [Decision Transformer](model_doc/decision_transformer) | ✅ | ❌ | ❌ | -| [Deformable DETR](model_doc/deformable_detr) | ✅ | ❌ | ❌ | -| [DeiT](model_doc/deit) | ✅ | ✅ | ❌ | -| [DePlot](model_doc/deplot) | ✅ | ❌ | ❌ | -| [DETA](model_doc/deta) | ✅ | ❌ | ❌ | -| [DETR](model_doc/detr) | ✅ | ❌ | ❌ | -| [DialoGPT](model_doc/dialogpt) | ✅ | ✅ | ✅ | -| [DiNAT](model_doc/dinat) | ✅ | ❌ | ❌ | -| [DINOv2](model_doc/dinov2) | ✅ | ❌ | ❌ | -| [DistilBERT](model_doc/distilbert) | ✅ | ✅ | ✅ | -| [DiT](model_doc/dit) | ✅ | ❌ | ✅ | -| [DonutSwin](model_doc/donut) | ✅ | ❌ | ❌ | -| [DPR](model_doc/dpr) | ✅ | ✅ | ❌ | -| [DPT](model_doc/dpt) | ✅ | ❌ | ❌ | -| [EfficientFormer](model_doc/efficientformer) | ✅ | ✅ | ❌ | -| [EfficientNet](model_doc/efficientnet) | ✅ | ❌ | ❌ | -| [ELECTRA](model_doc/electra) | ✅ | ✅ | ✅ | -| [EnCodec](model_doc/encodec) | ✅ | ❌ | ❌ | -| [Encoder decoder](model_doc/encoder-decoder) | ✅ | ✅ | ✅ | -| [ERNIE](model_doc/ernie) | ✅ | ❌ | ❌ | -| [ErnieM](model_doc/ernie_m) | ✅ | ❌ | ❌ | -| [ESM](model_doc/esm) | ✅ | ✅ | ❌ | -| [FairSeq Machine-Translation](model_doc/fsmt) | ✅ | ❌ | ❌ | -| [Falcon](model_doc/falcon) | ✅ | ❌ | ❌ | -| [FLAN-T5](model_doc/flan-t5) | ✅ | ✅ | ✅ | -| [FLAN-UL2](model_doc/flan-ul2) | ✅ | ✅ | ✅ | -| [FlauBERT](model_doc/flaubert) | ✅ | ✅ | ❌ | -| [FLAVA](model_doc/flava) | ✅ | ❌ | ❌ | -| [FNet](model_doc/fnet) | ✅ | ❌ | ❌ | -| [FocalNet](model_doc/focalnet) | ✅ | ❌ | ❌ | -| [Funnel Transformer](model_doc/funnel) | ✅ | ✅ | ❌ | -| [Fuyu](model_doc/fuyu) | ✅ | ❌ | ❌ | -| [GIT](model_doc/git) | ✅ | ❌ | ❌ | -| [GLPN](model_doc/glpn) | ✅ | ❌ | ❌ | -| [GPT Neo](model_doc/gpt_neo) | ✅ | ❌ | ✅ | -| [GPT NeoX](model_doc/gpt_neox) | ✅ | ❌ | ❌ | -| [GPT NeoX Japanese](model_doc/gpt_neox_japanese) | ✅ | ❌ | ❌ | -| [GPT-J](model_doc/gptj) | ✅ | ✅ | ✅ | -| [GPT-Sw3](model_doc/gpt-sw3) | ✅ | ✅ | ✅ | -| [GPTBigCode](model_doc/gpt_bigcode) | ✅ | ❌ | ❌ | -| [GPTSAN-japanese](model_doc/gptsan-japanese) | ✅ | ❌ | ❌ | -| [Graphormer](model_doc/graphormer) | ✅ | ❌ | ❌ | -| [GroupViT](model_doc/groupvit) | ✅ | ✅ | ❌ | -| [HerBERT](model_doc/herbert) | ✅ | ✅ | ✅ | -| [Hubert](model_doc/hubert) | ✅ | ✅ | ❌ | -| [I-BERT](model_doc/ibert) | ✅ | ❌ | ❌ | -| [IDEFICS](model_doc/idefics) | ✅ | ❌ | ❌ | -| [ImageGPT](model_doc/imagegpt) | ✅ | ❌ | ❌ | -| [Informer](model_doc/informer) | ✅ | ❌ | ❌ | -| [InstructBLIP](model_doc/instructblip) | ✅ | ❌ | ❌ | -| [Jukebox](model_doc/jukebox) | ✅ | ❌ | ❌ | -| [LayoutLM](model_doc/layoutlm) | ✅ | ✅ | ❌ | -| [LayoutLMv2](model_doc/layoutlmv2) | ✅ | ❌ | ❌ | -| [LayoutLMv3](model_doc/layoutlmv3) | ✅ | ✅ | ❌ | -| [LayoutXLM](model_doc/layoutxlm) | ✅ | ❌ | ❌ | -| [LED](model_doc/led) | ✅ | ✅ | ❌ | -| [LeViT](model_doc/levit) | ✅ | ❌ | ❌ | -| [LiLT](model_doc/lilt) | ✅ | ❌ | ❌ | -| [LLaMA](model_doc/llama) | ✅ | ❌ | ❌ | -| [Llama2](model_doc/llama2) | ✅ | ❌ | ❌ | -| [Longformer](model_doc/longformer) | ✅ | ✅ | ❌ | -| [LongT5](model_doc/longt5) | ✅ | ❌ | ✅ | -| [LUKE](model_doc/luke) | ✅ | ❌ | ❌ | -| [LXMERT](model_doc/lxmert) | ✅ | ✅ | ❌ | -| [M-CTC-T](model_doc/mctct) | ✅ | ❌ | ❌ | -| [M2M100](model_doc/m2m_100) | ✅ | ❌ | ❌ | -| [Marian](model_doc/marian) | ✅ | ✅ | ✅ | -| [MarkupLM](model_doc/markuplm) | ✅ | ❌ | ❌ | -| [Mask2Former](model_doc/mask2former) | ✅ | ❌ | ❌ | -| [MaskFormer](model_doc/maskformer) | ✅ | ❌ | ❌ | -| [MatCha](model_doc/matcha) | ✅ | ❌ | ❌ | -| [mBART](model_doc/mbart) | ✅ | ✅ | ✅ | -| [mBART-50](model_doc/mbart50) | ✅ | ✅ | ✅ | -| [MEGA](model_doc/mega) | ✅ | ❌ | ❌ | -| [Megatron-BERT](model_doc/megatron-bert) | ✅ | ❌ | ❌ | -| [Megatron-GPT2](model_doc/megatron_gpt2) | ✅ | ✅ | ✅ | -| [MGP-STR](model_doc/mgp-str) | ✅ | ❌ | ❌ | -| [Mistral](model_doc/mistral) | ✅ | ❌ | ❌ | -| [mLUKE](model_doc/mluke) | ✅ | ❌ | ❌ | -| [MMS](model_doc/mms) | ✅ | ✅ | ✅ | -| [MobileBERT](model_doc/mobilebert) | ✅ | ✅ | ❌ | -| [MobileNetV1](model_doc/mobilenet_v1) | ✅ | ❌ | ❌ | -| [MobileNetV2](model_doc/mobilenet_v2) | ✅ | ❌ | ❌ | -| [MobileViT](model_doc/mobilevit) | ✅ | ✅ | ❌ | -| [MobileViTV2](model_doc/mobilevitv2) | ✅ | ❌ | ❌ | -| [MPNet](model_doc/mpnet) | ✅ | ✅ | ❌ | -| [MPT](model_doc/mpt) | ✅ | ❌ | ❌ | -| [MRA](model_doc/mra) | ✅ | ❌ | ❌ | -| [MT5](model_doc/mt5) | ✅ | ✅ | ✅ | -| [MusicGen](model_doc/musicgen) | ✅ | ❌ | ❌ | -| [MVP](model_doc/mvp) | ✅ | ❌ | ❌ | -| [NAT](model_doc/nat) | ✅ | ❌ | ❌ | -| [Nezha](model_doc/nezha) | ✅ | ❌ | ❌ | -| [NLLB](model_doc/nllb) | ✅ | ❌ | ❌ | -| [NLLB-MOE](model_doc/nllb-moe) | ✅ | ❌ | ❌ | -| [Nougat](model_doc/nougat) | ✅ | ✅ | ✅ | -| [Nyströmformer](model_doc/nystromformer) | ✅ | ❌ | ❌ | -| [OneFormer](model_doc/oneformer) | ✅ | ❌ | ❌ | -| [OpenAI GPT](model_doc/openai-gpt) | ✅ | ✅ | ❌ | -| [OpenAI GPT-2](model_doc/gpt2) | ✅ | ✅ | ✅ | -| [OpenLlama](model_doc/open-llama) | ✅ | ❌ | ❌ | -| [OPT](model_doc/opt) | ✅ | ✅ | ✅ | -| [OWL-ViT](model_doc/owlvit) | ✅ | ❌ | ❌ | -| [OWLv2](model_doc/owlv2) | ✅ | ❌ | ❌ | -| [Pegasus](model_doc/pegasus) | ✅ | ✅ | ✅ | -| [PEGASUS-X](model_doc/pegasus_x) | ✅ | ❌ | ❌ | -| [Perceiver](model_doc/perceiver) | ✅ | ❌ | ❌ | -| [Persimmon](model_doc/persimmon) | ✅ | ❌ | ❌ | -| [PhoBERT](model_doc/phobert) | ✅ | ✅ | ✅ | -| [Pix2Struct](model_doc/pix2struct) | ✅ | ❌ | ❌ | -| [PLBart](model_doc/plbart) | ✅ | ❌ | ❌ | -| [PoolFormer](model_doc/poolformer) | ✅ | ❌ | ❌ | -| [Pop2Piano](model_doc/pop2piano) | ✅ | ❌ | ❌ | -| [ProphetNet](model_doc/prophetnet) | ✅ | ❌ | ❌ | -| [PVT](model_doc/pvt) | ✅ | ❌ | ❌ | -| [QDQBert](model_doc/qdqbert) | ✅ | ❌ | ❌ | -| [RAG](model_doc/rag) | ✅ | ✅ | ❌ | -| [REALM](model_doc/realm) | ✅ | ❌ | ❌ | -| [Reformer](model_doc/reformer) | ✅ | ❌ | ❌ | -| [RegNet](model_doc/regnet) | ✅ | ✅ | ✅ | -| [RemBERT](model_doc/rembert) | ✅ | ✅ | ❌ | -| [ResNet](model_doc/resnet) | ✅ | ✅ | ✅ | -| [RetriBERT](model_doc/retribert) | ✅ | ❌ | ❌ | -| [RoBERTa](model_doc/roberta) | ✅ | ✅ | ✅ | -| [RoBERTa-PreLayerNorm](model_doc/roberta-prelayernorm) | ✅ | ✅ | ✅ | -| [RoCBert](model_doc/roc_bert) | ✅ | ❌ | ❌ | -| [RoFormer](model_doc/roformer) | ✅ | ✅ | ✅ | -| [RWKV](model_doc/rwkv) | ✅ | ❌ | ❌ | -| [SAM](model_doc/sam) | ✅ | ✅ | ❌ | -| [SeamlessM4T](model_doc/seamless_m4t) | ✅ | ❌ | ❌ | -| [SegFormer](model_doc/segformer) | ✅ | ✅ | ❌ | -| [SEW](model_doc/sew) | ✅ | ❌ | ❌ | -| [SEW-D](model_doc/sew-d) | ✅ | ❌ | ❌ | -| [Speech Encoder decoder](model_doc/speech-encoder-decoder) | ✅ | ❌ | ✅ | -| [Speech2Text](model_doc/speech_to_text) | ✅ | ✅ | ❌ | -| [SpeechT5](model_doc/speecht5) | ✅ | ❌ | ❌ | -| [Splinter](model_doc/splinter) | ✅ | ❌ | ❌ | -| [SqueezeBERT](model_doc/squeezebert) | ✅ | ❌ | ❌ | -| [SwiftFormer](model_doc/swiftformer) | ✅ | ❌ | ❌ | -| [Swin Transformer](model_doc/swin) | ✅ | ✅ | ❌ | -| [Swin Transformer V2](model_doc/swinv2) | ✅ | ❌ | ❌ | -| [Swin2SR](model_doc/swin2sr) | ✅ | ❌ | ❌ | -| [SwitchTransformers](model_doc/switch_transformers) | ✅ | ❌ | ❌ | -| [T5](model_doc/t5) | ✅ | ✅ | ✅ | -| [T5v1.1](model_doc/t5v1.1) | ✅ | ✅ | ✅ | -| [Table Transformer](model_doc/table-transformer) | ✅ | ❌ | ❌ | -| [TAPAS](model_doc/tapas) | ✅ | ✅ | ❌ | -| [TAPEX](model_doc/tapex) | ✅ | ✅ | ✅ | -| [Time Series Transformer](model_doc/time_series_transformer) | ✅ | ❌ | ❌ | -| [TimeSformer](model_doc/timesformer) | ✅ | ❌ | ❌ | -| [Trajectory Transformer](model_doc/trajectory_transformer) | ✅ | ❌ | ❌ | -| [Transformer-XL](model_doc/transfo-xl) | ✅ | ✅ | ❌ | -| [TrOCR](model_doc/trocr) | ✅ | ❌ | ❌ | -| [TVLT](model_doc/tvlt) | ✅ | ❌ | ❌ | -| [UL2](model_doc/ul2) | ✅ | ✅ | ✅ | -| [UMT5](model_doc/umt5) | ✅ | ❌ | ❌ | -| [UniSpeech](model_doc/unispeech) | ✅ | ❌ | ❌ | -| [UniSpeechSat](model_doc/unispeech-sat) | ✅ | ❌ | ❌ | -| [UPerNet](model_doc/upernet) | ✅ | ❌ | ❌ | -| [VAN](model_doc/van) | ✅ | ❌ | ❌ | -| [VideoMAE](model_doc/videomae) | ✅ | ❌ | ❌ | -| [ViLT](model_doc/vilt) | ✅ | ❌ | ❌ | -| [Vision Encoder decoder](model_doc/vision-encoder-decoder) | ✅ | ✅ | ✅ | -| [VisionTextDualEncoder](model_doc/vision-text-dual-encoder) | ✅ | ✅ | ✅ | -| [VisualBERT](model_doc/visual_bert) | ✅ | ❌ | ❌ | -| [ViT](model_doc/vit) | ✅ | ✅ | ✅ | -| [ViT Hybrid](model_doc/vit_hybrid) | ✅ | ❌ | ❌ | -| [VitDet](model_doc/vitdet) | ✅ | ❌ | ❌ | -| [ViTMAE](model_doc/vit_mae) | ✅ | ✅ | ❌ | -| [ViTMatte](model_doc/vitmatte) | ✅ | ❌ | ❌ | -| [ViTMSN](model_doc/vit_msn) | ✅ | ❌ | ❌ | -| [VITS](model_doc/vits) | ✅ | ❌ | ❌ | -| [ViViT](model_doc/vivit) | ✅ | ❌ | ❌ | -| [Wav2Vec2](model_doc/wav2vec2) | ✅ | ✅ | ✅ | -| [Wav2Vec2-Conformer](model_doc/wav2vec2-conformer) | ✅ | ❌ | ❌ | -| [Wav2Vec2Phoneme](model_doc/wav2vec2_phoneme) | ✅ | ✅ | ✅ | -| [WavLM](model_doc/wavlm) | ✅ | ❌ | ❌ | -| [Whisper](model_doc/whisper) | ✅ | ✅ | ✅ | -| [X-CLIP](model_doc/xclip) | ✅ | ❌ | ❌ | -| [X-MOD](model_doc/xmod) | ✅ | ❌ | ❌ | -| [XGLM](model_doc/xglm) | ✅ | ✅ | ✅ | -| [XLM](model_doc/xlm) | ✅ | ✅ | ❌ | -| [XLM-ProphetNet](model_doc/xlm-prophetnet) | ✅ | ❌ | ❌ | -| [XLM-RoBERTa](model_doc/xlm-roberta) | ✅ | ✅ | ✅ | -| [XLM-RoBERTa-XL](model_doc/xlm-roberta-xl) | ✅ | ❌ | ❌ | -| [XLM-V](model_doc/xlm-v) | ✅ | ✅ | ✅ | -| [XLNet](model_doc/xlnet) | ✅ | ✅ | ❌ | -| [XLS-R](model_doc/xls_r) | ✅ | ✅ | ✅ | -| [XLSR-Wav2Vec2](model_doc/xlsr_wav2vec2) | ✅ | ✅ | ✅ | -| [YOLOS](model_doc/yolos) | ✅ | ❌ | ❌ | -| [YOSO](model_doc/yoso) | ✅ | ❌ | ❌ | - - diff --git a/docs/source/zh/main_classes/data_collator.md b/docs/source/zh/main_classes/data_collator.md index d947b53ea14c..473281878f0a 100644 --- a/docs/source/zh/main_classes/data_collator.md +++ b/docs/source/zh/main_classes/data_collator.md @@ -47,19 +47,16 @@ Data collators是一个对象,通过使用数据集元素列表作为输入来 [[autodoc]] data.data_collator.DataCollatorForLanguageModeling - numpy_mask_tokens - - tf_mask_tokens - torch_mask_tokens ## DataCollatorForWholeWordMask [[autodoc]] data.data_collator.DataCollatorForWholeWordMask - numpy_mask_tokens - - tf_mask_tokens - torch_mask_tokens ## DataCollatorForPermutationLanguageModeling [[autodoc]] data.data_collator.DataCollatorForPermutationLanguageModeling - numpy_mask_tokens - - tf_mask_tokens - torch_mask_tokens diff --git a/docs/source/zh/main_classes/optimizer_schedules.md b/docs/source/zh/main_classes/optimizer_schedules.md index 4fb45540abb9..6aa17d523f5f 100644 --- a/docs/source/zh/main_classes/optimizer_schedules.md +++ b/docs/source/zh/main_classes/optimizer_schedules.md @@ -26,12 +26,6 @@ rendered properly in your Markdown viewer. [[autodoc]] Adafactor -## AdamWeightDecay (TensorFlow) - -[[autodoc]] AdamWeightDecay - -[[autodoc]] create_optimizer - ## Schedules ### Learning Rate Schedules (Pytorch) @@ -61,13 +55,3 @@ rendered properly in your Markdown viewer. [[autodoc]] get_polynomial_decay_schedule_with_warmup [[autodoc]] get_inverse_sqrt_schedule - -### Warmup (TensorFlow) - -[[autodoc]] WarmUp - -## Gradient Strategies - -### GradientAccumulator (TensorFlow) - -[[autodoc]] GradientAccumulator From e08f64cc3ebf6b9edeba0ae7c75ddd273b8a1be1 Mon Sep 17 00:00:00 2001 From: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> Date: Fri, 19 Sep 2025 14:15:36 +0200 Subject: [PATCH 119/204] [`RMSNorm`] Fix rms norm init for models that center around 1 (#40796) * fix * fixup inits * oops * fixup gemma * fixup modular order * how does this keep happen lol * vaultgemma is new i forgot * remove init check --- .../models/gemma/modeling_gemma.py | 7 ++ .../models/gemma/modular_gemma.py | 16 ++++ .../models/gemma2/modeling_gemma2.py | 79 ++++++++++--------- .../models/gemma2/modular_gemma2.py | 10 +++ .../models/gemma3/modeling_gemma3.py | 3 + .../models/gemma3/modular_gemma3.py | 3 + .../models/qwen3_next/modeling_qwen3_next.py | 3 + .../models/qwen3_next/modular_qwen3_next.py | 3 + .../modeling_recurrent_gemma.py | 3 +- .../models/t5gemma/modeling_t5gemma.py | 3 + .../models/t5gemma/modular_t5gemma.py | 3 + .../models/vaultgemma/modeling_vaultgemma.py | 7 ++ 12 files changed, 103 insertions(+), 37 deletions(-) diff --git a/src/transformers/models/gemma/modeling_gemma.py b/src/transformers/models/gemma/modeling_gemma.py index 5f72f27d9382..04d27b309a40 100644 --- a/src/transformers/models/gemma/modeling_gemma.py +++ b/src/transformers/models/gemma/modeling_gemma.py @@ -322,6 +322,13 @@ class GemmaPreTrainedModel(PreTrainedModel): "attentions": GemmaAttention, } + def _init_weights(self, module): + super()._init_weights(module) + + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) + if "RMSNorm" in module.__class__.__name__: + module.weight.data.zero_() + @auto_docstring class GemmaModel(GemmaPreTrainedModel): diff --git a/src/transformers/models/gemma/modular_gemma.py b/src/transformers/models/gemma/modular_gemma.py index 00dfb9edbcf7..94c3820de79c 100644 --- a/src/transformers/models/gemma/modular_gemma.py +++ b/src/transformers/models/gemma/modular_gemma.py @@ -23,6 +23,7 @@ from ...configuration_utils import PretrainedConfig from ...masking_utils import create_causal_mask from ...modeling_outputs import BaseModelOutputWithPast +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...tokenization_utils import AddedToken, PreTrainedTokenizer from ...utils import TransformersKwargs, logging @@ -32,6 +33,8 @@ LlamaForTokenClassification, LlamaMLP, LlamaModel, + LlamaPreTrainedModel, + LlamaRotaryEmbedding, ) from ..llama.tokenization_llama import LlamaTokenizer @@ -361,6 +364,19 @@ def __init__(self, config): self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) +class GemmaRotaryEmbedding(LlamaRotaryEmbedding): + pass + + +class GemmaPreTrainedModel(LlamaPreTrainedModel): + def _init_weights(self, module): + PreTrainedModel._init_weights(self, module) + + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) + if "RMSNorm" in module.__class__.__name__: + module.weight.data.zero_() + + class GemmaModel(LlamaModel): def forward( self, diff --git a/src/transformers/models/gemma2/modeling_gemma2.py b/src/transformers/models/gemma2/modeling_gemma2.py index 3d088cfc52cf..ec2f1521ef85 100644 --- a/src/transformers/models/gemma2/modeling_gemma2.py +++ b/src/transformers/models/gemma2/modeling_gemma2.py @@ -83,6 +83,42 @@ def forward(self, x): return down_proj +class Gemma2RotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: Gemma2Config, device=None): + super().__init__() + # BC: "rope_type" was originally "type" + if hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): + self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type")) + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device) + position_ids_expanded = position_ids[:, None, :].float() + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + def rotate_half(x): """Rotates half the hidden dims of the input.""" x1 = x[..., : x.shape[-1] // 2] @@ -299,42 +335,6 @@ def forward( return outputs -class Gemma2RotaryEmbedding(nn.Module): - inv_freq: torch.Tensor # fix linting for `register_buffer` - - def __init__(self, config: Gemma2Config, device=None): - super().__init__() - # BC: "rope_type" was originally "type" - if hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): - self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type")) - else: - self.rope_type = "default" - self.max_seq_len_cached = config.max_position_embeddings - self.original_max_seq_len = config.max_position_embeddings - - self.config = config - self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] - - inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) - self.register_buffer("inv_freq", inv_freq, persistent=False) - self.original_inv_freq = self.inv_freq - - @torch.no_grad() - @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) - def forward(self, x, position_ids): - inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device) - position_ids_expanded = position_ids[:, None, :].float() - - device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" - with torch.autocast(device_type=device_type, enabled=False): # Force float32 - freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2) - emb = torch.cat((freqs, freqs), dim=-1) - cos = emb.cos() * self.attention_scaling - sin = emb.sin() * self.attention_scaling - - return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) - - @auto_docstring class Gemma2PreTrainedModel(PreTrainedModel): config: Gemma2Config @@ -353,6 +353,13 @@ class Gemma2PreTrainedModel(PreTrainedModel): "attentions": Gemma2Attention, } + def _init_weights(self, module): + super()._init_weights(module) + + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) + if "RMSNorm" in module.__class__.__name__: + module.weight.data.zero_() + @auto_docstring class Gemma2Model(Gemma2PreTrainedModel): diff --git a/src/transformers/models/gemma2/modular_gemma2.py b/src/transformers/models/gemma2/modular_gemma2.py index c7e34e4abed4..add7e6c0989b 100644 --- a/src/transformers/models/gemma2/modular_gemma2.py +++ b/src/transformers/models/gemma2/modular_gemma2.py @@ -36,7 +36,9 @@ GemmaForTokenClassification, GemmaMLP, GemmaModel, + GemmaPreTrainedModel, GemmaRMSNorm, + GemmaRotaryEmbedding, apply_rotary_pos_emb, repeat_kv, ) @@ -212,6 +214,10 @@ def __init__(self, config): self.act_fn = ACT2FN[config.hidden_activation] +class Gemma2RotaryEmbedding(GemmaRotaryEmbedding): + pass + + def eager_attention_forward( module: nn.Module, query: torch.Tensor, @@ -363,6 +369,10 @@ def forward( return outputs +class Gemma2PreTrainedModel(GemmaPreTrainedModel): + pass + + class Gemma2Model(GemmaModel): def __init__(self, config: Gemma2Config): super().__init__(config) diff --git a/src/transformers/models/gemma3/modeling_gemma3.py b/src/transformers/models/gemma3/modeling_gemma3.py index 7a91db1905f7..4536ec7f69f7 100644 --- a/src/transformers/models/gemma3/modeling_gemma3.py +++ b/src/transformers/models/gemma3/modeling_gemma3.py @@ -434,6 +434,9 @@ def _init_weights(self, module): super()._init_weights(module) if isinstance(module, Gemma3MultiModalProjector): module.mm_input_projection_weight.data.zero_() + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) + elif "RMSNorm" in module.__class__.__name__: + module.weight.data.zero_() def _bidirectional_window_overlay(sliding_window: int) -> Callable[[int, int, int, int], bool]: diff --git a/src/transformers/models/gemma3/modular_gemma3.py b/src/transformers/models/gemma3/modular_gemma3.py index d10d01f55759..8afbf566c061 100644 --- a/src/transformers/models/gemma3/modular_gemma3.py +++ b/src/transformers/models/gemma3/modular_gemma3.py @@ -526,6 +526,9 @@ def _init_weights(self, module): PreTrainedModel._init_weights(self, module) if isinstance(module, Gemma3MultiModalProjector): module.mm_input_projection_weight.data.zero_() + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) + elif "RMSNorm" in module.__class__.__name__: + module.weight.data.zero_() def _bidirectional_window_overlay(sliding_window: int) -> Callable[[int, int, int, int], bool]: diff --git a/src/transformers/models/qwen3_next/modeling_qwen3_next.py b/src/transformers/models/qwen3_next/modeling_qwen3_next.py index 7d2b60d943e2..21e5d4f9819c 100644 --- a/src/transformers/models/qwen3_next/modeling_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modeling_qwen3_next.py @@ -970,6 +970,9 @@ def _init_weights(self, module): if isinstance(module, Qwen3NextGatedDeltaNet): module.dt_bias.data.fill_(1.0) module.A_log.data.uniform_(0, 16).log_() + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) + elif isinstance(module, Qwen3NextRMSNorm): + module.weight.data.zero_() class Qwen3NextModel(Qwen3NextPreTrainedModel): diff --git a/src/transformers/models/qwen3_next/modular_qwen3_next.py b/src/transformers/models/qwen3_next/modular_qwen3_next.py index e141e229eedf..9e92ecf312c3 100644 --- a/src/transformers/models/qwen3_next/modular_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modular_qwen3_next.py @@ -709,6 +709,9 @@ def _init_weights(self, module): if isinstance(module, Qwen3NextGatedDeltaNet): module.dt_bias.data.fill_(1.0) module.A_log.data.uniform_(0, 16).log_() + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) + elif isinstance(module, Qwen3NextRMSNorm): + module.weight.data.zero_() class Qwen3NextModel(Qwen3NextPreTrainedModel): diff --git a/src/transformers/models/recurrent_gemma/modeling_recurrent_gemma.py b/src/transformers/models/recurrent_gemma/modeling_recurrent_gemma.py index d7d1ce33e8f0..88364515459a 100644 --- a/src/transformers/models/recurrent_gemma/modeling_recurrent_gemma.py +++ b/src/transformers/models/recurrent_gemma/modeling_recurrent_gemma.py @@ -556,8 +556,9 @@ def _init_weights(self, module): if module.padding_idx is not None: module.weight.data[module.padding_idx].zero_() + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) elif isinstance(module, RecurrentGemmaRMSNorm): - module.weight.data.fill_(1.0) + module.weight.data.zero_() def _setup_cache(self, config, batch, device, dtype): layers = getattr(self, "model", self).layers diff --git a/src/transformers/models/t5gemma/modeling_t5gemma.py b/src/transformers/models/t5gemma/modeling_t5gemma.py index ba023447c2bc..b6be86e9cdd7 100644 --- a/src/transformers/models/t5gemma/modeling_t5gemma.py +++ b/src/transformers/models/t5gemma/modeling_t5gemma.py @@ -611,6 +611,9 @@ def _init_weights(self, module): if not self.config.tie_word_embeddings: scale = module.out_proj.weight.shape[0] ** -0.5 module.out_proj.weight.data.normal_(mean=0.0, std=std * scale) + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) + elif "RMSNorm" in module.__class__.__name__: + module.weight.data.zero_() def _shift_right(self, input_ids): """ diff --git a/src/transformers/models/t5gemma/modular_t5gemma.py b/src/transformers/models/t5gemma/modular_t5gemma.py index 4ac42d99239c..d358a51d0e68 100644 --- a/src/transformers/models/t5gemma/modular_t5gemma.py +++ b/src/transformers/models/t5gemma/modular_t5gemma.py @@ -491,6 +491,9 @@ def _init_weights(self, module): if not self.config.tie_word_embeddings: scale = module.out_proj.weight.shape[0] ** -0.5 module.out_proj.weight.data.normal_(mean=0.0, std=std * scale) + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) + elif "RMSNorm" in module.__class__.__name__: + module.weight.data.zero_() def _shift_right(self, input_ids): """ diff --git a/src/transformers/models/vaultgemma/modeling_vaultgemma.py b/src/transformers/models/vaultgemma/modeling_vaultgemma.py index c70a7a83fa9c..eaad6c5335a4 100644 --- a/src/transformers/models/vaultgemma/modeling_vaultgemma.py +++ b/src/transformers/models/vaultgemma/modeling_vaultgemma.py @@ -342,6 +342,13 @@ class VaultGemmaPreTrainedModel(PreTrainedModel): "attentions": VaultGemmaAttention, } + def _init_weights(self, module): + super()._init_weights(module) + + # We initialize with 0s to be 1 centered as the RMSNorm here does (1 + weight) + if "RMSNorm" in module.__class__.__name__: + module.weight.data.zero_() + @auto_docstring class VaultGemmaModel(VaultGemmaPreTrainedModel): From 40dcb51220ca3827a1c55ab3d6dea1fadfb9d73d Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Fri, 19 Sep 2025 14:51:05 +0200 Subject: [PATCH 120/204] Make `EfficientLoFTRModelTest` faster (#41000) * fix * fix * fix --------- Co-authored-by: ydshieh --- .../efficientloftr/test_modeling_efficientloftr.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/models/efficientloftr/test_modeling_efficientloftr.py b/tests/models/efficientloftr/test_modeling_efficientloftr.py index be428c3b4ffa..4ea8a4d823c5 100644 --- a/tests/models/efficientloftr/test_modeling_efficientloftr.py +++ b/tests/models/efficientloftr/test_modeling_efficientloftr.py @@ -46,18 +46,18 @@ def __init__( self, parent, batch_size=2, - image_width=80, - image_height=60, - stage_num_blocks: list[int] = [1, 1, 1], - out_features: list[int] = [32, 32, 128], - stage_stride: list[int] = [2, 1, 2], + image_width=6, # need to be a multiple of `stage_stride[0] * stage_stride[1]` + image_height=4, # need to be a multiple of `stage_stride[0] * stage_stride[1]` + stage_num_blocks: list[int] = [1, 1], + out_features: list[int] = [16, 16], # need to be >= 2 to make `config.fine_fusion_dims > 0` + stage_stride: list[int] = [2, 1], q_aggregation_kernel_size: int = 1, kv_aggregation_kernel_size: int = 1, q_aggregation_stride: int = 1, kv_aggregation_stride: int = 1, num_attention_layers: int = 2, num_attention_heads: int = 8, - hidden_size: int = 128, + hidden_size: int = 16, coarse_matching_threshold: float = 0.0, fine_kernel_size: int = 2, coarse_matching_border_removal: int = 0, From 85702fd6a82c2a9feaf14e85fd586e3b69cf2290 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Fri, 19 Sep 2025 21:18:38 +0800 Subject: [PATCH 121/204] Fix typoes in src and tests (#40845) Signed-off-by: Yuanyuan Chen --- .../generation/continuous_batching/cache.py | 4 +-- .../models/big_bird/modeling_big_bird.py | 8 ++--- .../modeling_bigbird_pegasus.py | 8 ++--- .../models/cpmant/modeling_cpmant.py | 12 +++---- .../models/gemma3/convert_gemma3_weights.py | 6 ++-- src/transformers/models/git/modeling_git.py | 4 +-- .../models/groupvit/modeling_groupvit.py | 4 +-- .../imagegpt/image_processing_imagegpt.py | 2 +- .../image_processing_kosmos2_5_fast.py | 2 +- ...eature_extraction_kyutai_speech_to_text.py | 2 +- .../modeling_kyutai_speech_to_text.py | 2 +- .../modular_kyutai_speech_to_text.py | 4 +-- .../models/oneformer/modeling_oneformer.py | 4 +-- .../image_processing_perception_lm_fast.py | 2 +- .../configuration_phi4_multimodal.py | 6 ++-- .../modeling_phi4_multimodal.py | 6 ++-- .../modular_phi4_multimodal.py | 12 +++---- .../rwkv/convert_rwkv_checkpoint_to_hf.py | 4 +-- .../seamless_m4t/modeling_seamless_m4t.py | 6 ++-- .../modeling_seamless_m4t_v2.py | 6 ++-- .../models/voxtral/processing_voxtral.py | 6 ++-- src/transformers/utils/generic.py | 2 +- src/transformers/utils/metrics.py | 2 +- tests/models/bloom/test_modeling_bloom.py | 2 +- tests/models/clipseg/test_modeling_clipseg.py | 2 +- tests/models/codegen/test_modeling_codegen.py | 4 +-- tests/models/cohere2/test_modeling_cohere2.py | 2 +- tests/models/csm/test_modeling_csm.py | 8 ++--- .../deepseek_v3/test_modeling_deepseek_v3.py | 4 ++- .../distilbert/test_modeling_distilbert.py | 2 +- tests/models/evolla/test_modeling_evolla.py | 8 ++--- tests/models/gemma3/test_modeling_gemma3.py | 4 +-- .../test_modeling_granite_speech.py | 4 +-- .../models/kosmos2/test_processing_kosmos2.py | 2 +- .../test_modeling_kyutai_speech_to_text.py | 4 +-- .../test_tokenization_layoutlmv3.py | 6 ++-- tests/models/m2m_100/test_modeling_m2m_100.py | 2 +- tests/models/mllama/test_processing_mllama.py | 32 ++++++++++++++----- .../modernbert/test_modeling_modernbert.py | 2 +- .../test_modeling_phi4_multimodal.py | 2 +- tests/models/vit_mae/test_modeling_vit_mae.py | 2 +- tests/test_configuration_common.py | 2 +- tests/utils/test_add_new_model_like.py | 4 +-- utils/check_copies.py | 2 +- 44 files changed, 116 insertions(+), 98 deletions(-) diff --git a/src/transformers/generation/continuous_batching/cache.py b/src/transformers/generation/continuous_batching/cache.py index 05de093f661f..8d6e057be84a 100644 --- a/src/transformers/generation/continuous_batching/cache.py +++ b/src/transformers/generation/continuous_batching/cache.py @@ -79,7 +79,7 @@ class PagedAttentionCache: layer group, and the shape of the cache tensor is `[num_blocks * block_size, num_heads, head_size]`. Grouping layers into groups is useful because when we allocate one block to a group N, the block allocated is the - same for all layers in group N, equivalently it is allocated accross all cache tensors. This allows us to + same for all layers in group N, equivalently it is allocated across all cache tensors. This allows us to efficiently allocate and free blocks, and to efficiently read and write key and value states. For instance, imagine we have 8 blocks of cache and a model with two layer groups: a full-attention group with 3 @@ -349,7 +349,7 @@ class PagedAttentionMemoryHandler: The memory footprint consists of three main components: - Cache memory: the space needed to store the cache tensors: 2 * layer_group_size * [num_pages, page_size] * cache_dtype - - Activation memory: the space temporarly taken by the largest activation during the model forward pass: + - Activation memory: the space temporarily taken by the largest activation during the model forward pass: peak_activation_per_token * max_tokens_per_batch * activation_dtype_size - Static tensors: the space taken by the input/output buffers and metadata tensors for batch processing, sum of: - inputs_ids + outputs_ids + position_ids + logits_indices: 4 * max_tokens_per_batch * int32_size diff --git a/src/transformers/models/big_bird/modeling_big_bird.py b/src/transformers/models/big_bird/modeling_big_bird.py index 69dc11a7cb69..a25c412e688a 100755 --- a/src/transformers/models/big_bird/modeling_big_bird.py +++ b/src/transformers/models/big_bird/modeling_big_bird.py @@ -1108,14 +1108,14 @@ def _get_single_block_row_attention( if block_id == to_end_block_id - 2: illegal_blocks.append(1) - selected_random_blokcs = [] + selected_random_blocks = [] for i in range(to_end_block_id - to_start_block_id): if perm_block[i] not in illegal_blocks: - selected_random_blokcs.append(perm_block[i]) - if len(selected_random_blokcs) == num_rand_blocks: + selected_random_blocks.append(perm_block[i]) + if len(selected_random_blocks) == num_rand_blocks: break - return np.array(selected_random_blokcs, dtype=np.int32) + return np.array(selected_random_blocks, dtype=np.int32) # Copied from transformers.models.bert.modeling_bert.BertSelfOutput with Bert->BigBird diff --git a/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py b/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py index 04cc28e56bf9..e36e4b06dbef 100755 --- a/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py +++ b/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py @@ -1086,14 +1086,14 @@ def _get_single_block_row_attention( if block_id == to_end_block_id - 2: illegal_blocks.append(1) - selected_random_blokcs = [] + selected_random_blocks = [] for i in range(to_end_block_id - to_start_block_id): if perm_block[i] not in illegal_blocks: - selected_random_blokcs.append(perm_block[i]) - if len(selected_random_blokcs) == num_rand_blocks: + selected_random_blocks.append(perm_block[i]) + if len(selected_random_blocks) == num_rand_blocks: break - return np.array(selected_random_blokcs, dtype=np.int32) + return np.array(selected_random_blocks, dtype=np.int32) class BigBirdPegasusEncoderAttention(nn.Module): diff --git a/src/transformers/models/cpmant/modeling_cpmant.py b/src/transformers/models/cpmant/modeling_cpmant.py index 1930cc0e8793..15881a64eb37 100755 --- a/src/transformers/models/cpmant/modeling_cpmant.py +++ b/src/transformers/models/cpmant/modeling_cpmant.py @@ -351,7 +351,7 @@ def forward( output_hidden_states: Optional[bool] = None, past_key_values: Optional[Cache] = None, use_cache: Optional[bool] = None, - cache_postion: Optional[torch.Tensor] = None, + cache_position: Optional[torch.Tensor] = None, ): """ Args: @@ -492,16 +492,16 @@ def _position_bucket(self, relative_position, num_buckets=32, max_distance=128): relative_position = torch.abs(relative_position) max_exact = num_buckets // 2 is_small = relative_position < max_exact - relative_postion_if_large = max_exact + ( + relative_position_if_large = max_exact + ( torch.log(relative_position.float() / max_exact) / math.log(max_distance / max_exact) * (num_buckets - max_exact) ).to(torch.int32) - relative_postion_if_large = torch.min( - relative_postion_if_large, - torch.full_like(relative_postion_if_large, num_buckets - 1), + relative_position_if_large = torch.min( + relative_position_if_large, + torch.full_like(relative_position_if_large, num_buckets - 1), ) - relative_buckets += torch.where(is_small, relative_position.to(torch.int32), relative_postion_if_large) + relative_buckets += torch.where(is_small, relative_position.to(torch.int32), relative_position_if_large) return relative_buckets diff --git a/src/transformers/models/gemma3/convert_gemma3_weights.py b/src/transformers/models/gemma3/convert_gemma3_weights.py index 8d7a21219197..aefd9648d3fe 100644 --- a/src/transformers/models/gemma3/convert_gemma3_weights.py +++ b/src/transformers/models/gemma3/convert_gemma3_weights.py @@ -439,9 +439,9 @@ def convert_transformer_weights( decoder_block_start = path.find(_TRANSFORMER_DECODER_BLOCK) decoder_block_offset = decoder_block_start + _TRANSFORMER_DECODER_BLOCK_LEN decoder_block_path = path[decoder_block_offset:] - next_path_seperator_idx = decoder_block_path.find("/") - layer_idx = decoder_block_path[:next_path_seperator_idx] - decoder_block_path = decoder_block_path[next_path_seperator_idx:] + next_path_separator_idx = decoder_block_path.find("/") + layer_idx = decoder_block_path[:next_path_separator_idx] + decoder_block_path = decoder_block_path[next_path_separator_idx:] base_path = f"language_model.model.layers.{layer_idx}" diff --git a/src/transformers/models/git/modeling_git.py b/src/transformers/models/git/modeling_git.py index b98d2b1c231c..82a1d5e451ca 100644 --- a/src/transformers/models/git/modeling_git.py +++ b/src/transformers/models/git/modeling_git.py @@ -950,7 +950,7 @@ def __init__(self, config): self.visual_projection = GitProjection(config) if config.num_image_with_embedding is not None: - self.img_temperal_embedding = nn.ParameterList( + self.img_temporal_embedding = nn.ParameterList( nn.Parameter(torch.zeros(1, 1, config.vision_config.hidden_size)) for _ in range(config.num_image_with_embedding) ) @@ -1115,7 +1115,7 @@ def forward( visual_features_frame = self.image_encoder( pixel_values[:, frame_idx, :, :], interpolate_pos_encoding=interpolate_pos_encoding ).last_hidden_state - visual_features_frame += self.img_temperal_embedding[frame_idx] + visual_features_frame += self.img_temporal_embedding[frame_idx] visual_features.append(visual_features_frame) # finally, concatenate all features along sequence dimension diff --git a/src/transformers/models/groupvit/modeling_groupvit.py b/src/transformers/models/groupvit/modeling_groupvit.py index 65fdaaa784d3..598845750da2 100644 --- a/src/transformers/models/groupvit/modeling_groupvit.py +++ b/src/transformers/models/groupvit/modeling_groupvit.py @@ -74,7 +74,7 @@ def gumbel_softmax(logits: torch.Tensor, tau: float = 1, hard: bool = False, dim y_hard = torch.zeros_like(logits, memory_format=torch.legacy_contiguous_format).scatter_(dim, index, 1.0) ret = y_hard - y_soft.detach() + y_soft else: - # Reparametrization trick. + # Reparameterization trick. ret = y_soft return ret @@ -662,7 +662,7 @@ def forward( attn_weights = nn.functional.softmax(attn_weights, dim=-1) if output_attentions: - # this operation is a bit akward, but it's required to + # this operation is a bit awkward, but it's required to # make sure that attn_weights keeps its gradient. # In order to do so, attn_weights have to reshaped # twice and have to be reused in the following diff --git a/src/transformers/models/imagegpt/image_processing_imagegpt.py b/src/transformers/models/imagegpt/image_processing_imagegpt.py index 97086ed45e07..ee8fe04771b7 100644 --- a/src/transformers/models/imagegpt/image_processing_imagegpt.py +++ b/src/transformers/models/imagegpt/image_processing_imagegpt.py @@ -242,7 +242,7 @@ def preprocess( raise ValueError("Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, or torch.Tensor") # Here, normalize() is using a constant factor to divide pixel values. - # hence, the method does not need iamge_mean and image_std. + # hence, the method does not need image_mean and image_std. validate_preprocess_arguments( do_resize=do_resize, size=size, diff --git a/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py b/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py index c539288d9913..028ccf6bf8a2 100644 --- a/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py +++ b/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py @@ -34,7 +34,7 @@ # Similar to transformers.models.pix2struct.image_processing_pix2struct.torch_extract_patches but dealing with a batch of images directly. def torch_extract_patches(image_tensor, patch_height, patch_width): """ - Utiliy function to extract patches from a given tensor representing a batch of images. Returns a tensor of shape + Utility function to extract patches from a given tensor representing a batch of images. Returns a tensor of shape (batch_size, `rows`, `columns`, `num_channels` x `patch_height` x `patch_width`). Args: diff --git a/src/transformers/models/kyutai_speech_to_text/feature_extraction_kyutai_speech_to_text.py b/src/transformers/models/kyutai_speech_to_text/feature_extraction_kyutai_speech_to_text.py index fa0ce5e11ded..8fa8f0a78875 100644 --- a/src/transformers/models/kyutai_speech_to_text/feature_extraction_kyutai_speech_to_text.py +++ b/src/transformers/models/kyutai_speech_to_text/feature_extraction_kyutai_speech_to_text.py @@ -203,7 +203,7 @@ def __call__( if padding: padded_inputs["padding_mask"] = padded_inputs.pop("attention_mask") - # now let's padd left and right + # now let's pad left and right pad_left = int(self.audio_silence_prefix_seconds * self.sampling_rate) pad_right = int((self.audio_delay_seconds + 1.0) * self.sampling_rate) padded_inputs["input_values"] = np.pad( diff --git a/src/transformers/models/kyutai_speech_to_text/modeling_kyutai_speech_to_text.py b/src/transformers/models/kyutai_speech_to_text/modeling_kyutai_speech_to_text.py index 9eba7e163670..77c636570d58 100644 --- a/src/transformers/models/kyutai_speech_to_text/modeling_kyutai_speech_to_text.py +++ b/src/transformers/models/kyutai_speech_to_text/modeling_kyutai_speech_to_text.py @@ -1078,7 +1078,7 @@ def __init__(self, config): self.codec_model = AutoModel.from_config(config.codec_config) # we are in an edge case where for the codec_model self.can_generate is False, setting self.codec_model.generation_config to None - # yet the codec_model needs a generation config to initalize it's cache for streaming inference + # yet the codec_model needs a generation config to initialize it's cache for streaming inference # we therefore initialize a generation config for the codec model self.codec_model.generation_config = GenerationConfig.from_model_config(config.codec_config) diff --git a/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py b/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py index 16e8f6cd6dcb..af8c182f226e 100644 --- a/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py +++ b/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py @@ -182,7 +182,7 @@ def __call__( if padding: padded_inputs["padding_mask"] = padded_inputs.pop("attention_mask") - # now let's padd left and right + # now let's pad left and right pad_left = int(self.audio_silence_prefix_seconds * self.sampling_rate) pad_right = int((self.audio_delay_seconds + 1.0) * self.sampling_rate) padded_inputs["input_values"] = np.pad( @@ -258,7 +258,7 @@ def __init__(self, config): self.codec_model = AutoModel.from_config(config.codec_config) # we are in an edge case where for the codec_model self.can_generate is False, setting self.codec_model.generation_config to None - # yet the codec_model needs a generation config to initalize it's cache for streaming inference + # yet the codec_model needs a generation config to initialize it's cache for streaming inference # we therefore initialize a generation config for the codec model self.codec_model.generation_config = GenerationConfig.from_model_config(config.codec_config) diff --git a/src/transformers/models/oneformer/modeling_oneformer.py b/src/transformers/models/oneformer/modeling_oneformer.py index a5336f6fc490..dc44ad67f71f 100644 --- a/src/transformers/models/oneformer/modeling_oneformer.py +++ b/src/transformers/models/oneformer/modeling_oneformer.py @@ -2882,7 +2882,7 @@ def forward( Task inputs. Task inputs can be obtained using [`AutoImageProcessor`]. See [`OneFormerProcessor.__call__`] for details. text_inputs (`list[torch.Tensor]`, *optional*): - Tensor fof shape `(num_queries, sequence_length)` to be fed to a model + Tensor of shape `(num_queries, sequence_length)` to be fed to a model Example: @@ -3068,7 +3068,7 @@ def forward( Task inputs. Task inputs can be obtained using [`AutoImageProcessor`]. See [`OneFormerProcessor.__call__`] for details. text_inputs (`list[torch.Tensor]`, *optional*): - Tensor fof shape `(num_queries, sequence_length)` to be fed to a model + Tensor of shape `(num_queries, sequence_length)` to be fed to a model mask_labels (`list[torch.Tensor]`, *optional*): List of mask labels of shape `(num_labels, height, width)` to be fed to a model class_labels (`list[torch.LongTensor]`, *optional*): diff --git a/src/transformers/models/perception_lm/image_processing_perception_lm_fast.py b/src/transformers/models/perception_lm/image_processing_perception_lm_fast.py index be55c39572d5..c26132a48439 100644 --- a/src/transformers/models/perception_lm/image_processing_perception_lm_fast.py +++ b/src/transformers/models/perception_lm/image_processing_perception_lm_fast.py @@ -190,7 +190,7 @@ def _fit_image_to_canvas(self, img_width: int, img_height: int, tile_size: int): target_width=n_w * tile_size, target_height=n_h * tile_size, ) - # Llama3V dynamic tiling. Priortize biggest canvas. + # Llama3V dynamic tiling. Prioritize biggest canvas. if (scale < 1.0 and (image_width_height[0] >= optimal_image_width_height[0])) or ( scale >= 1.0 and (image_width_height[1] >= optimal_image_width_height[1]) ): diff --git a/src/transformers/models/phi4_multimodal/configuration_phi4_multimodal.py b/src/transformers/models/phi4_multimodal/configuration_phi4_multimodal.py index 3b6c2ca1d979..3c1fdb8b0a8c 100644 --- a/src/transformers/models/phi4_multimodal/configuration_phi4_multimodal.py +++ b/src/transformers/models/phi4_multimodal/configuration_phi4_multimodal.py @@ -137,7 +137,7 @@ class Phi4MultimodalAudioConfig(PretrainedConfig): The dropout ratio. ext_pw_out_channel (`int`, *optional*, defaults to 1024): Number of out channels in the point-wise conv modules. - depthwise_seperable_out_channel (`int`, *optional*, defaults to 1024): + depthwise_separable_out_channel (`int`, *optional*, defaults to 1024): Number of out channels in the depth-wise separable conv modules. depthwise_multiplier (`int`, *optional*, defaults to 1): Input size multiplier for the depth-wise separable conv modules. @@ -190,7 +190,7 @@ def __init__( left_chunk: int = 18, dropout_rate: float = 0.0, ext_pw_out_channel: int = 1024, - depthwise_seperable_out_channel: int = 1024, + depthwise_separable_out_channel: int = 1024, depthwise_multiplier: int = 1, kernel_size: int = 3, conv_activation: str = "swish", @@ -217,7 +217,7 @@ def __init__( self.num_blocks = num_blocks self.dropout_rate = dropout_rate self.ext_pw_out_channel = ext_pw_out_channel - self.depthwise_seperable_out_channel = depthwise_seperable_out_channel + self.depthwise_separable_out_channel = depthwise_separable_out_channel self.depthwise_multiplier = depthwise_multiplier self.kernel_size = kernel_size self.conv_activation = conv_activation diff --git a/src/transformers/models/phi4_multimodal/modeling_phi4_multimodal.py b/src/transformers/models/phi4_multimodal/modeling_phi4_multimodal.py index 349f2e02e2f2..ad2ef3e07124 100644 --- a/src/transformers/models/phi4_multimodal/modeling_phi4_multimodal.py +++ b/src/transformers/models/phi4_multimodal/modeling_phi4_multimodal.py @@ -746,7 +746,7 @@ def forward( return attn_output -class Phi4MultimodalAudioDepthWiseSeperableConv1d(nn.Module): +class Phi4MultimodalAudioDepthWiseSeparableConv1d(nn.Module): def __init__(self, config: Phi4MultimodalAudioConfig, padding: int = 0): super().__init__() self.dw_conv = nn.Conv1d( @@ -758,7 +758,7 @@ def __init__(self, config: Phi4MultimodalAudioConfig, padding: int = 0): groups=config.hidden_size, ) self.pw_conv = nn.Conv1d( - config.hidden_size * config.depthwise_multiplier, config.depthwise_seperable_out_channel, 1, 1, 0 + config.hidden_size * config.depthwise_multiplier, config.depthwise_separable_out_channel, 1, 1, 0 ) def forward(self, hidden_states): @@ -794,7 +794,7 @@ def __init__(self, config: Phi4MultimodalAudioConfig): self.layer_norm = nn.LayerNorm(config.hidden_size) self.glu = Phi4MultimodalAudioGluPointWiseConv(config) - self.dw_sep_conv_1d = Phi4MultimodalAudioDepthWiseSeperableConv1d(config, padding=config.kernel_size - 1) + self.dw_sep_conv_1d = Phi4MultimodalAudioDepthWiseSeparableConv1d(config, padding=config.kernel_size - 1) self.act = ACT2FN[config.conv_activation] self.ext_pw_conv_1d = nn.Conv1d(config.hidden_size, config.ext_pw_out_channel, kernel_size=1, stride=1) self.dropout = nn.Dropout(config.dropout_rate) diff --git a/src/transformers/models/phi4_multimodal/modular_phi4_multimodal.py b/src/transformers/models/phi4_multimodal/modular_phi4_multimodal.py index ea226e4e1981..0514136cad85 100644 --- a/src/transformers/models/phi4_multimodal/modular_phi4_multimodal.py +++ b/src/transformers/models/phi4_multimodal/modular_phi4_multimodal.py @@ -174,7 +174,7 @@ class Phi4MultimodalAudioConfig(PretrainedConfig): The dropout ratio. ext_pw_out_channel (`int`, *optional*, defaults to 1024): Number of out channels in the point-wise conv modules. - depthwise_seperable_out_channel (`int`, *optional*, defaults to 1024): + depthwise_separable_out_channel (`int`, *optional*, defaults to 1024): Number of out channels in the depth-wise separable conv modules. depthwise_multiplier (`int`, *optional*, defaults to 1): Input size multiplier for the depth-wise separable conv modules. @@ -227,7 +227,7 @@ def __init__( left_chunk: int = 18, dropout_rate: float = 0.0, ext_pw_out_channel: int = 1024, - depthwise_seperable_out_channel: int = 1024, + depthwise_separable_out_channel: int = 1024, depthwise_multiplier: int = 1, kernel_size: int = 3, conv_activation: str = "swish", @@ -254,7 +254,7 @@ def __init__( self.num_blocks = num_blocks self.dropout_rate = dropout_rate self.ext_pw_out_channel = ext_pw_out_channel - self.depthwise_seperable_out_channel = depthwise_seperable_out_channel + self.depthwise_separable_out_channel = depthwise_separable_out_channel self.depthwise_multiplier = depthwise_multiplier self.kernel_size = kernel_size self.conv_activation = conv_activation @@ -930,7 +930,7 @@ def forward( return attn_output -class Phi4MultimodalAudioDepthWiseSeperableConv1d(nn.Module): +class Phi4MultimodalAudioDepthWiseSeparableConv1d(nn.Module): def __init__(self, config: Phi4MultimodalAudioConfig, padding: int = 0): super().__init__() self.dw_conv = nn.Conv1d( @@ -942,7 +942,7 @@ def __init__(self, config: Phi4MultimodalAudioConfig, padding: int = 0): groups=config.hidden_size, ) self.pw_conv = nn.Conv1d( - config.hidden_size * config.depthwise_multiplier, config.depthwise_seperable_out_channel, 1, 1, 0 + config.hidden_size * config.depthwise_multiplier, config.depthwise_separable_out_channel, 1, 1, 0 ) def forward(self, hidden_states): @@ -978,7 +978,7 @@ def __init__(self, config: Phi4MultimodalAudioConfig): self.layer_norm = nn.LayerNorm(config.hidden_size) self.glu = Phi4MultimodalAudioGluPointWiseConv(config) - self.dw_sep_conv_1d = Phi4MultimodalAudioDepthWiseSeperableConv1d(config, padding=config.kernel_size - 1) + self.dw_sep_conv_1d = Phi4MultimodalAudioDepthWiseSeparableConv1d(config, padding=config.kernel_size - 1) self.act = ACT2FN[config.conv_activation] self.ext_pw_conv_1d = nn.Conv1d(config.hidden_size, config.ext_pw_out_channel, kernel_size=1, stride=1) self.dropout = nn.Dropout(config.dropout_rate) diff --git a/src/transformers/models/rwkv/convert_rwkv_checkpoint_to_hf.py b/src/transformers/models/rwkv/convert_rwkv_checkpoint_to_hf.py index 87d35db22363..33044a4d1271 100644 --- a/src/transformers/models/rwkv/convert_rwkv_checkpoint_to_hf.py +++ b/src/transformers/models/rwkv/convert_rwkv_checkpoint_to_hf.py @@ -36,7 +36,7 @@ "14B": 40, } -HIDEN_SIZE_MAPPING = { +HIDDEN_SIZE_MAPPING = { "169M": 768, "430M": 1024, "1B5": 2048, @@ -106,7 +106,7 @@ def convert_rmkv_checkpoint_to_hf_format( config = RwkvConfig( vocab_size=vocab_size, num_hidden_layers=NUM_HIDDEN_LAYERS_MAPPING[size], - hidden_size=HIDEN_SIZE_MAPPING[size], + hidden_size=HIDDEN_SIZE_MAPPING[size], ) config.save_pretrained(output_dir) diff --git a/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py b/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py index f9206cae9ae8..0c4f1118d30f 100755 --- a/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py +++ b/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py @@ -2190,7 +2190,7 @@ def __init__(self, config): kernel_size=kernel_size, padding=(kernel_size - 1) // 2, ) - self.activation_fuction = nn.ReLU() + self.activation_function = nn.ReLU() self.ln1 = nn.LayerNorm(embed_dim) self.dropout_module = nn.Dropout(p=var_pred_dropout) self.conv2 = nn.Conv1d( @@ -2205,10 +2205,10 @@ def __init__(self, config): def forward(self, hidden_states: Tensor) -> Tensor: # Input: B x T x C; Output: B x T hidden_states = self.conv1(hidden_states.transpose(1, 2)) - hidden_states = self.activation_fuction(hidden_states).transpose(1, 2) + hidden_states = self.activation_function(hidden_states).transpose(1, 2) hidden_states = self.dropout_module(self.ln1(hidden_states)) hidden_states = self.conv2(hidden_states.transpose(1, 2)) - hidden_states = self.activation_fuction(hidden_states).transpose(1, 2) + hidden_states = self.activation_function(hidden_states).transpose(1, 2) hidden_states = self.dropout_module(self.ln2(hidden_states)) return self.proj(hidden_states).squeeze(dim=2) diff --git a/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py b/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py index 9d9cc95059a0..352dc20011af 100644 --- a/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py +++ b/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py @@ -2383,7 +2383,7 @@ def __init__(self, embed_dim, hidden_dim, kernel_size, var_pred_dropout): kernel_size=kernel_size, padding="same", ) - self.activation_fuction = nn.ReLU() + self.activation_function = nn.ReLU() self.ln1 = nn.LayerNorm(hidden_dim) self.dropout_module = nn.Dropout(p=var_pred_dropout) self.conv2 = nn.Conv1d( @@ -2400,12 +2400,12 @@ def forward(self, hidden_states: Tensor, padding_mask: Optional[Tensor] = None) if padding_mask is not None: hidden_states = hidden_states.masked_fill(~padding_mask.bool().unsqueeze(-1), 0.0) hidden_states = self.conv1(hidden_states.transpose(1, 2)) - hidden_states = self.activation_fuction(hidden_states).transpose(1, 2) + hidden_states = self.activation_function(hidden_states).transpose(1, 2) hidden_states = self.dropout_module(self.ln1(hidden_states)) if padding_mask is not None: hidden_states = hidden_states.masked_fill(~padding_mask.bool().unsqueeze(-1), 0.0) hidden_states = self.conv2(hidden_states.transpose(1, 2)) - hidden_states = self.activation_fuction(hidden_states).transpose(1, 2) + hidden_states = self.activation_function(hidden_states).transpose(1, 2) hidden_states = self.dropout_module(self.ln2(hidden_states)) return self.proj(hidden_states).squeeze(dim=2) diff --git a/src/transformers/models/voxtral/processing_voxtral.py b/src/transformers/models/voxtral/processing_voxtral.py index 1166c9636307..1b812ba60a4b 100644 --- a/src/transformers/models/voxtral/processing_voxtral.py +++ b/src/transformers/models/voxtral/processing_voxtral.py @@ -88,7 +88,7 @@ def __init__( super().__init__(feature_extractor, tokenizer) - def _retreive_input_features(self, audio, max_source_positions, **kwargs): + def _retrieve_input_features(self, audio, max_source_positions, **kwargs): """ Handles specific logic of Voxtral expected input features: audio arrays should be padded to next multiple of 480000 (duration is a multiple of 30s), see VoxtralProcessorKwargs' default audio_kwargs. Then mel input features are extracted and stacked along batch dimension, splitting into chunks of max_source_positions. @@ -222,7 +222,7 @@ def apply_chat_template( data = dict(encoded_instruct_inputs) if audio is not None: max_source_positions = audio_kwargs.pop("max_source_positions") - data["input_features"] = self._retreive_input_features(audio, max_source_positions, **audio_kwargs) + data["input_features"] = self._retrieve_input_features(audio, max_source_positions, **audio_kwargs) return BatchFeature(data=data, tensor_type=return_tensors) @@ -421,7 +421,7 @@ def apply_transcription_request( # extract the input features max_source_positions = audio_kwargs.pop("max_source_positions") - data["input_features"] = self._retreive_input_features( + data["input_features"] = self._retrieve_input_features( audio_arrays, max_source_positions, **audio_kwargs ) diff --git a/src/transformers/utils/generic.py b/src/transformers/utils/generic.py index ef5e356bcd1c..451b98193d43 100644 --- a/src/transformers/utils/generic.py +++ b/src/transformers/utils/generic.py @@ -850,7 +850,7 @@ def wrapper(self, *args, **kwargs): } # We let cross attentions to be saved separately because some models add `cross-attn` layer - # when certain condtions are met. Let's output cross attention if attentions are requested (for BC) + # when certain conditions are met. Let's output cross attention if attentions are requested (for BC) if "output_attentions" in recordable_keys: recordable_keys["output_cross_attentions"] = recordable_keys["output_attentions"] diff --git a/src/transformers/utils/metrics.py b/src/transformers/utils/metrics.py index 62b41995a6d9..33623b385ce3 100644 --- a/src/transformers/utils/metrics.py +++ b/src/transformers/utils/metrics.py @@ -339,7 +339,7 @@ def record_kv_cache_memory_metrics(self, cache) -> None: page_size = cache.head_dim * cache.num_key_value_heads page_mem_in_bytes = page_size * cache.dtype.itemsize # When a block is allocated, it is for both K and V, so we multiply by 2 - # It's also allocated accross all cache tensors, so we multiply by the nb of tensors: len(cache.key_cache) + # It's also allocated across all cache tensors, so we multiply by the nb of tensors: len(cache.key_cache) block_mem_in_bytes = 2 * len(cache.key_cache) * cache.block_size * page_mem_in_bytes # Retrieve the number of used and free blocks diff --git a/tests/models/bloom/test_modeling_bloom.py b/tests/models/bloom/test_modeling_bloom.py index 9480aac9ae94..e8cdd43ff5f7 100644 --- a/tests/models/bloom/test_modeling_bloom.py +++ b/tests/models/bloom/test_modeling_bloom.py @@ -446,7 +446,7 @@ def test_batch_generation(self): @slow @require_torch_accelerator - def test_batch_generation_padd(self): + def test_batch_generation_padding(self): path_560m = "bigscience/bloom-560m" model = BloomForCausalLM.from_pretrained(path_560m, use_cache=True, revision="gs555750").to(torch_device) model = model.eval() diff --git a/tests/models/clipseg/test_modeling_clipseg.py b/tests/models/clipseg/test_modeling_clipseg.py index 08a21f9dcf3b..788a60021a88 100644 --- a/tests/models/clipseg/test_modeling_clipseg.py +++ b/tests/models/clipseg/test_modeling_clipseg.py @@ -393,7 +393,7 @@ def create_and_check_model(self, config, input_ids, attention_mask, pixel_values result.logits_per_text.shape, (self.text_model_tester.batch_size, self.vision_model_tester.batch_size) ) - def create_and_check_model_for_image_segmentation(self, config, input_ids, attention_maks, pixel_values): + def create_and_check_model_for_image_segmentation(self, config, input_ids, attention_mask, pixel_values): model = CLIPSegForImageSegmentation(config).to(torch_device).eval() with torch.no_grad(): result = model(input_ids, pixel_values) diff --git a/tests/models/codegen/test_modeling_codegen.py b/tests/models/codegen/test_modeling_codegen.py index ee16a5347ad6..5f97cfad359d 100644 --- a/tests/models/codegen/test_modeling_codegen.py +++ b/tests/models/codegen/test_modeling_codegen.py @@ -379,7 +379,7 @@ def test_batch_generation(self): model.config.pad_token_id = model.config.eos_token_id # use different length sentences to test batching - sentences = ["def hellow_world():", "def greet(name):"] + sentences = ["def hello_world():", "def greet(name):"] inputs = tokenizer(sentences, return_tensors="pt", padding=True) input_ids = inputs["input_ids"].to(torch_device) @@ -415,7 +415,7 @@ def test_batch_generation(self): padded_sentence = tokenizer.decode(output_padded[0], skip_special_tokens=True) expected_output_sentence = [ - 'def hellow_world():\n print("Hello World")\n\nhellow_world()', + 'def hello_world():\n print("Hello World")\n\nhellow_world()', 'def greet(name):\n print(f"Hello {name}")\n\ng', ] self.assertListEqual(expected_output_sentence, batch_out_sentence) diff --git a/tests/models/cohere2/test_modeling_cohere2.py b/tests/models/cohere2/test_modeling_cohere2.py index cdb78895e866..4619c7a7f19d 100644 --- a/tests/models/cohere2/test_modeling_cohere2.py +++ b/tests/models/cohere2/test_modeling_cohere2.py @@ -241,7 +241,7 @@ def test_generation_beyond_sliding_window(self, attn_implementation: str): self.skipTest("FlashAttention2 is required for this test.") if torch_device == "xpu" and attn_implementation == "flash_attention_2": - self.skipTest(reason="Intel XPU doesn't support falsh_attention_2 as of now.") + self.skipTest(reason="Intel XPU doesn't support flash_attention_2 as of now.") model_id = "CohereForAI/c4ai-command-r7b-12-2024" EXPECTED_COMPLETIONS = [ diff --git a/tests/models/csm/test_modeling_csm.py b/tests/models/csm/test_modeling_csm.py index 19e0beb39cb9..204ef79831f3 100644 --- a/tests/models/csm/test_modeling_csm.py +++ b/tests/models/csm/test_modeling_csm.py @@ -362,7 +362,7 @@ def _load_conversation(self): def test_1b_model_integration_generate(self): """ Tests the generated tokens match the ones from the original model implementation. - Such tokens are to be retreived using https://gist.github.com/eustlb/d25577a357ddcf8f4a8cd0d00baca551, which is a script that infers the original model. + Such tokens are to be retrieved using https://gist.github.com/eustlb/d25577a357ddcf8f4a8cd0d00baca551, which is a script that infers the original model. """ processor = AutoProcessor.from_pretrained(self.model_checkpoint) prompt = "<|begin_of_text|>[0]What are you working on?<|end_of_text|><|AUDIO|><|audio_eos|><|begin_of_text|>[1]I'm figuring out my budget.<|end_of_text|>" @@ -406,7 +406,7 @@ def test_1b_model_integration_generate(self): def test_1b_model_integration_generate_no_audio(self): """ Tests the generated tokens match the ones from the original model implementation. - Such tokens are to be retreived using https://gist.github.com/eustlb/aed822f765e928b9612e01b0d8836d69, which is a script that infers the original model. + Such tokens are to be retrieved using https://gist.github.com/eustlb/aed822f765e928b9612e01b0d8836d69, which is a script that infers the original model. """ processor = AutoProcessor.from_pretrained(self.model_checkpoint) @@ -467,7 +467,7 @@ def test_1b_model_integration_generate_no_audio(self): def test_1b_model_integration_generate_multiple_audio(self): """ Test the generated tokens match the ones from the original model implementation. - Such tokens are to be retreived using https://gist.github.com/eustlb/0c94de002e1325abb61d32217f74c0f8, which is a script that infers the original model. + Such tokens are to be retrieved using https://gist.github.com/eustlb/0c94de002e1325abb61d32217f74c0f8, which is a script that infers the original model. """ processor = AutoProcessor.from_pretrained(self.model_checkpoint) @@ -526,7 +526,7 @@ def test_1b_model_integration_generate_multiple_audio(self): def test_1b_model_integration_generate_batched(self): """ Test the generated tokens match the ones from the original model implementation. - Such tokens are to be retreived using https://gist.github.com/eustlb/bcc532b53161bc31da3d66cb07ae193f, which is a script that infers the original model. + Such tokens are to be retrieved using https://gist.github.com/eustlb/bcc532b53161bc31da3d66cb07ae193f, which is a script that infers the original model. """ processor = AutoProcessor.from_pretrained(self.model_checkpoint) diff --git a/tests/models/deepseek_v3/test_modeling_deepseek_v3.py b/tests/models/deepseek_v3/test_modeling_deepseek_v3.py index 62bb9c999958..df97dc4a0af4 100644 --- a/tests/models/deepseek_v3/test_modeling_deepseek_v3.py +++ b/tests/models/deepseek_v3/test_modeling_deepseek_v3.py @@ -326,7 +326,9 @@ def test_model_rope_scaling(self): long_input_length = int(config.max_position_embeddings * 1.5) # Inputs - x = torch.randn(1, dtype=torch.float32, device=torch_device) # used exlusively to get the dtype and the device + x = torch.randn( + 1, dtype=torch.float32, device=torch_device + ) # used exclusively to get the dtype and the device position_ids_short = torch.arange(short_input_length, dtype=torch.long, device=torch_device) position_ids_short = position_ids_short.unsqueeze(0) position_ids_long = torch.arange(long_input_length, dtype=torch.long, device=torch_device) diff --git a/tests/models/distilbert/test_modeling_distilbert.py b/tests/models/distilbert/test_modeling_distilbert.py index db90233b438a..a22d229a0405 100644 --- a/tests/models/distilbert/test_modeling_distilbert.py +++ b/tests/models/distilbert/test_modeling_distilbert.py @@ -383,7 +383,7 @@ def test_flash_attn_2_inference_equivalence_right_padding(self): @require_torch -class DistilBertModelIntergrationTest(unittest.TestCase): +class DistilBertModelIntegrationTest(unittest.TestCase): @slow def test_inference_no_head_absolute_embedding(self): model = DistilBertModel.from_pretrained("distilbert-base-uncased") diff --git a/tests/models/evolla/test_modeling_evolla.py b/tests/models/evolla/test_modeling_evolla.py index 50574c7c5096..b518c0db956d 100644 --- a/tests/models/evolla/test_modeling_evolla.py +++ b/tests/models/evolla/test_modeling_evolla.py @@ -257,7 +257,7 @@ def test_generate_multiple_proteins(self): def test_saprot_output(self): config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() config.return_dict = True - protein_informations = { + protein_information = { "input_ids": inputs_dict["protein_input_ids"], "attention_mask": inputs_dict["protein_attention_mask"], } @@ -267,13 +267,13 @@ def test_saprot_output(self): model = model_class(config) model.to(torch_device) model.eval() - protein_encoder_outputs = model.protein_encoder.model(**protein_informations, return_dict=True) + protein_encoder_outputs = model.protein_encoder.model(**protein_information, return_dict=True) print(model_class, protein_encoder_outputs) def test_protein_encoder_output(self): config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() config.return_dict = True - protein_informations = { + protein_information = { "input_ids": inputs_dict["protein_input_ids"], "attention_mask": inputs_dict["protein_attention_mask"], } @@ -283,7 +283,7 @@ def test_protein_encoder_output(self): model = model_class(config) model.to(torch_device) model.eval() - protein_encoder_outputs = model.protein_encoder(**protein_informations, return_dict=True) + protein_encoder_outputs = model.protein_encoder(**protein_information, return_dict=True) print(model_class, protein_encoder_outputs) def test_single_forward(self): diff --git a/tests/models/gemma3/test_modeling_gemma3.py b/tests/models/gemma3/test_modeling_gemma3.py index ddef6e0d6bc1..95c33187eb7c 100644 --- a/tests/models/gemma3/test_modeling_gemma3.py +++ b/tests/models/gemma3/test_modeling_gemma3.py @@ -814,8 +814,8 @@ def test_dynamic_sliding_window_is_default(self): prompt = "What is the capital of France?" model_inputs = tokenizer(prompt, return_tensors="pt").to(model.device) - foward_outputs = model(**model_inputs) - self.assertIn("DynamicSlidingWindowLayer", str(foward_outputs.past_key_values)) + forward_outputs = model(**model_inputs) + self.assertIn("DynamicSlidingWindowLayer", str(forward_outputs.past_key_values)) generate_outputs = model.generate( **model_inputs, max_new_tokens=2, do_sample=False, return_dict_in_generate=True diff --git a/tests/models/granite_speech/test_modeling_granite_speech.py b/tests/models/granite_speech/test_modeling_granite_speech.py index 1ea1f73b4344..adb925934548 100644 --- a/tests/models/granite_speech/test_modeling_granite_speech.py +++ b/tests/models/granite_speech/test_modeling_granite_speech.py @@ -127,7 +127,7 @@ def __init__( self.audio_token_index = audio_token_index self.tie_word_embeddings = tie_word_embeddings self.initializer_range = initializer_range - self.has_lora_adapater = has_lora_adapter + self.has_lora_adapter = has_lora_adapter self.downsample_rate = downsample_rate self.window_size = window_size self.is_training = is_training @@ -152,7 +152,7 @@ def get_config(self): audio_token_index=self.audio_token_index, tie_word_embeddings=self.tie_word_embeddings, initializer_range=self.initializer_range, - has_lora_adapter=self.has_lora_adapater, + has_lora_adapter=self.has_lora_adapter, ) def prepare_config_and_inputs(self): diff --git a/tests/models/kosmos2/test_processing_kosmos2.py b/tests/models/kosmos2/test_processing_kosmos2.py index d167ad4ebe57..c2c98882ef02 100644 --- a/tests/models/kosmos2/test_processing_kosmos2.py +++ b/tests/models/kosmos2/test_processing_kosmos2.py @@ -97,7 +97,7 @@ def get_image_processor(self, **kwargs): def tearDownClass(cls): shutil.rmtree(cls.tmpdirname, ignore_errors=True) - def test_image_procesor_load_save_reload(self): + def test_image_processor_load_save_reload(self): # make sure load from Hub repo. -> save -> reload locally work image_processor = CLIPImageProcessor.from_pretrained("microsoft/kosmos-2-patch14-224") with TemporaryDirectory() as tmp_dir: diff --git a/tests/models/kyutai_speech_to_text/test_modeling_kyutai_speech_to_text.py b/tests/models/kyutai_speech_to_text/test_modeling_kyutai_speech_to_text.py index b7c4537006dd..8325c0f699ed 100644 --- a/tests/models/kyutai_speech_to_text/test_modeling_kyutai_speech_to_text.py +++ b/tests/models/kyutai_speech_to_text/test_modeling_kyutai_speech_to_text.py @@ -717,7 +717,7 @@ def test_generation(self): reproduce test expected outputs using original codebase: https://gist.github.com/eustlb/7a9aa6139d11e0103c6b65bac103da52 DISCLAIMER: we are testing for pretty short inputs. Indeed, reproducing correct expected outputs for longer is not possible - as implementation choices (qkv matrix in one linear for original code vs three for hf) create growing divergence with context lenght, + as implementation choices (qkv matrix in one linear for original code vs three for hf) create growing divergence with context length, ultimately giving different outputs. """ processor = KyutaiSpeechToTextProcessor.from_pretrained(self.model_checkpoint) @@ -747,7 +747,7 @@ def test_generation_batched(self): reproduce test expected outputs using original codebase: https://gist.github.com/eustlb/b58c217c75124d405ec1c13877c7ece8 DISCLAIMER: we are testing for pretty short inputs. Indeed, reproducing correct expected outputs for longer is not possible - as implementation choices (qkv matrix in one linear for original code vs three for hf) create growing divergence with context lenght, + as implementation choices (qkv matrix in one linear for original code vs three for hf) create growing divergence with context length, ultimately giving different outputs. """ processor = KyutaiSpeechToTextProcessor.from_pretrained(self.model_checkpoint) diff --git a/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py b/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py index 729a7f4034f7..5ca0499805ef 100644 --- a/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py +++ b/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py @@ -1697,11 +1697,11 @@ def test_added_token_with_space_before(self): words_without_space = tokens_to_add + list(tokenizer_s.added_tokens_encoder.keys()) boxes = [[i, i, i, i] for i in range(len(words_with_space))] - tokens_to_add_formated = [ + tokens_to_add_formatted = [ AddedToken(token, rstrip=True, lstrip=True, single_word=False) for token in tokens_to_add ] - tokenizer_s.add_tokens(tokens_to_add_formated) - tokenizer_f.add_tokens(tokens_to_add_formated) + tokenizer_s.add_tokens(tokens_to_add_formatted) + tokenizer_f.add_tokens(tokens_to_add_formatted) ids_s = tokenizer_s(words_with_space, boxes=boxes).input_ids ids_f = tokenizer_f(words_with_space, boxes=boxes).input_ids diff --git a/tests/models/m2m_100/test_modeling_m2m_100.py b/tests/models/m2m_100/test_modeling_m2m_100.py index 20cd88baa534..32c5edd3071f 100644 --- a/tests/models/m2m_100/test_modeling_m2m_100.py +++ b/tests/models/m2m_100/test_modeling_m2m_100.py @@ -117,7 +117,7 @@ def prepare_config_and_inputs(self): # all pad tokens have pos id = 2 and rest are between 2..seq_length # and the seq_length here is seq_length - num_pad_tokens # but when using past, there is no way of knowing if the past input ids had - # pad tokens in them, which results in incorrect seq_lenth and which in turn results in + # pad tokens in them, which results in incorrect seq_length and which in turn results in # position_ids being off by num_pad_tokens in past input input_ids = input_ids.clamp(self.pad_token_id + 1) decoder_input_ids = decoder_input_ids.clamp(self.pad_token_id + 1) diff --git a/tests/models/mllama/test_processing_mllama.py b/tests/models/mllama/test_processing_mllama.py index be1472496823..e9acdddcd0c3 100644 --- a/tests/models/mllama/test_processing_mllama.py +++ b/tests/models/mllama/test_processing_mllama.py @@ -274,12 +274,14 @@ def test_process_interleaved_images_prompts_image_splitting(self): [self.image_token_id, self.bos_token_id, 2028, 374, 264, 1296, 11914, 13], [self.bos_token_id, 2028, 374, 264, 1296, 11914, 13, self.image_token_id, self.image_token_id, 2028, 374, 264, 1296, 11914, 13], ] - # fmt: onn + # fmt: on images = [[self.image1], [self.image1, self.image2]] inputs = processor(text=text, images=images, padding=True, size={"width": 256, "height": 256}) self.assertEqual(inputs["pixel_values"].shape, (2, 2, 4, 3, 256, 256)) - for input_ids_i, attention_mask_i, expected_ids_i in zip(inputs["input_ids"], inputs["attention_mask"], expected_ids): + for input_ids_i, attention_mask_i, expected_ids_i in zip( + inputs["input_ids"], inputs["attention_mask"], expected_ids + ): pad_ids = [id for id, m in zip(input_ids_i, attention_mask_i) if m == 0] input_ids = [id for id, m in zip(input_ids_i, attention_mask_i) if m == 1] self.assertEqual(input_ids, expected_ids_i) @@ -291,24 +293,38 @@ def test_process_interleaved_images_prompts_image_splitting(self): # Check that only first tile of first sample is attended to all text tokens first_sample_mask = cross_attention_mask[0].copy() first_image_first_tile_attention = first_sample_mask[:, :1, :1] # text tokens, images, tiles - self.assertTrue(np.all(first_image_first_tile_attention == 1), f"Cross attention mask is not all ones: {first_image_first_tile_attention}") + self.assertTrue( + np.all(first_image_first_tile_attention == 1), + f"Cross attention mask is not all ones: {first_image_first_tile_attention}", + ) # zero out first tile of first image first_image_first_tile_attention[:, :1, :1] = 0 - self.assertTrue(np.all(first_image_first_tile_attention == 0), f"Cross attention mask is not all zeros: {first_image_first_tile_attention}") + self.assertTrue( + np.all(first_image_first_tile_attention == 0), + f"Cross attention mask is not all zeros: {first_image_first_tile_attention}", + ) # second sample second_sample_mask = cross_attention_mask[1].copy() first_image_first_tile_attention = second_sample_mask[7:, :1, :1] # text tokens, images, tiles - self.assertTrue(np.all(first_image_first_tile_attention == 1), f"Cross attention mask is not all ones: {first_image_first_tile_attention}") + self.assertTrue( + np.all(first_image_first_tile_attention == 1), + f"Cross attention mask is not all ones: {first_image_first_tile_attention}", + ) second_image_two_tiles_attention = second_sample_mask[8:, 1:2, :2] # text tokens, images, tiles - self.assertTrue(np.all(second_image_two_tiles_attention == 1), f"Cross attention mask is not all ones: {second_image_two_tiles_attention}") + self.assertTrue( + np.all(second_image_two_tiles_attention == 1), + f"Cross attention mask is not all ones: {second_image_two_tiles_attention}", + ) # zero out both images masks second_sample_mask[7:, :1, :1] = 0 second_sample_mask[8:, 1:2, :2] = 0 - self.assertTrue(np.all(second_sample_mask == 0), f"Cross attention mask is not all zeros: {second_sample_mask}") + self.assertTrue( + np.all(second_sample_mask == 0), f"Cross attention mask is not all zeros: {second_sample_mask}" + ) def test_process_interleaved_images_prompts_image_error(self): text = [ @@ -406,6 +422,6 @@ def test_special_mm_token_truncation(self): max_length=3, ) - @unittest.skip("Mllama can't process inouts with no image ttogether with multimodal inputs") + @unittest.skip("Mllama can't process inputs with no image ttogether with multimodal inputs") def test_processor_text_has_no_visual(self): pass diff --git a/tests/models/modernbert/test_modeling_modernbert.py b/tests/models/modernbert/test_modeling_modernbert.py index 2a9c63089819..b1f0ce468a38 100644 --- a/tests/models/modernbert/test_modeling_modernbert.py +++ b/tests/models/modernbert/test_modeling_modernbert.py @@ -402,7 +402,7 @@ def test_saved_config_excludes_reference_compile(self): @require_flash_attn @require_torch_gpu @pytest.mark.flash_attn_test - def test_flash_attention_dispatches_by_defaul(self): + def test_flash_attention_dispatches_by_default(self): "ModernBert should dispatch to FA2 by default, not SDPA" config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: diff --git a/tests/models/phi4_multimodal/test_modeling_phi4_multimodal.py b/tests/models/phi4_multimodal/test_modeling_phi4_multimodal.py index 84dbf95301c1..b8e3232dc005 100644 --- a/tests/models/phi4_multimodal/test_modeling_phi4_multimodal.py +++ b/tests/models/phi4_multimodal/test_modeling_phi4_multimodal.py @@ -85,7 +85,7 @@ def __init__( hidden_size=32, num_attention_heads=8, intermediate_size=48, - depthwise_seperable_out_channel=128, + depthwise_separable_out_channel=128, nemo_conv_channels=128, initializer_range=1e-5, ), diff --git a/tests/models/vit_mae/test_modeling_vit_mae.py b/tests/models/vit_mae/test_modeling_vit_mae.py index b28d4711d589..689256de2d0d 100644 --- a/tests/models/vit_mae/test_modeling_vit_mae.py +++ b/tests/models/vit_mae/test_modeling_vit_mae.py @@ -328,7 +328,7 @@ def test_initialization(self): for model_class in self.all_model_classes: model = model_class(config=configs_no_init) for name, param in model.named_parameters(): - # This is an excepton in the module, it's initialized with xavier_uniform without using initializer_range + # This is an exception in the module, it's initialized with xavier_uniform without using initializer_range if name.endswith("patch_embeddings.projection.weight"): continue if param.requires_grad: diff --git a/tests/test_configuration_common.py b/tests/test_configuration_common.py index f7836dca6db3..4bf85697c4cc 100644 --- a/tests/test_configuration_common.py +++ b/tests/test_configuration_common.py @@ -160,7 +160,7 @@ def create_and_test_config_from_pretrained_custom_kwargs(self): for composite configs. We should overwrite only the requested keys, keeping all values of the subconfig that are loaded from the checkpoint. """ - # Check only composite configs. We can't know which attributes each type fo config has so check + # Check only composite configs. We can't know which attributes each type of config has so check # only text config because we are sure that all text configs have a `vocab_size` config = self.config_class(**self.inputs_dict) if config.get_text_config() is config or not hasattr(self.parent.model_tester, "get_config"): diff --git a/tests/utils/test_add_new_model_like.py b/tests/utils/test_add_new_model_like.py index dffe71897806..5ba84bab5501 100644 --- a/tests/utils/test_add_new_model_like.py +++ b/tests/utils/test_add_new_model_like.py @@ -481,7 +481,7 @@ def test_phi4_with_all_processors(self): Phi4MultimodalAudioAttention, Phi4MultimodalAudioConformerEncoderLayer, Phi4MultimodalAudioConvModule, - Phi4MultimodalAudioDepthWiseSeperableConv1d, + Phi4MultimodalAudioDepthWiseSeparableConv1d, Phi4MultimodalAudioEmbedding, Phi4MultimodalAudioGluPointWiseConv, Phi4MultimodalAudioMeanVarianceNormLayer, @@ -567,7 +567,7 @@ class MyTest2AudioAttention(Phi4MultimodalAudioAttention): pass - class MyTest2AudioDepthWiseSeperableConv1d(Phi4MultimodalAudioDepthWiseSeperableConv1d): + class MyTest2AudioDepthWiseSeparableConv1d(Phi4MultimodalAudioDepthWiseSeparableConv1d): pass diff --git a/utils/check_copies.py b/utils/check_copies.py index 56530dab8829..2bb00776af98 100644 --- a/utils/check_copies.py +++ b/utils/check_copies.py @@ -504,7 +504,7 @@ def find_code_and_splits(object_name: str, base_path: str, buffer: Optional[dict code (`str`): The object's code. code_splits (`List[Tuple[str, int, int]]`): - `code` splitted into blocks. See `split_code_into_blocks`. + `code` split into blocks. See `split_code_into_blocks`. """ if buffer is None: buffer = {} From d471b2e8a1e855ded62dd014f60a42e1ffdee305 Mon Sep 17 00:00:00 2001 From: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com> Date: Fri, 19 Sep 2025 09:47:28 -0400 Subject: [PATCH 122/204] Fix more dates in model cards and wrong modalities in _toctree.yml (#40955) * Fix model cards and modalities in toctree * fix new models --- docs/source/en/_toctree.yml | 28 ++++++++--------- docs/source/en/model_doc/bert-generation.md | 1 + docs/source/en/model_doc/flex_olmo.md | 2 +- docs/source/en/model_doc/hunyuan_v1_dense.md | 1 + docs/source/en/model_doc/hunyuan_v1_moe.md | 1 + docs/source/en/model_doc/lfm2_vl.md | 1 + docs/source/en/model_doc/longcat_flash.md | 5 ++- docs/source/en/model_doc/ministral.md | 1 + docs/source/en/model_doc/olmo3.md | 11 ++++--- docs/source/en/model_doc/ovis2.md | 1 + docs/source/en/model_doc/qwen3_next.md | 12 ++++--- docs/source/en/model_doc/qwen3_vl.md | 2 +- docs/source/en/model_doc/qwen3_vl_moe.md | 2 +- docs/source/en/model_doc/seed_oss.md | 33 +++++++++++--------- docs/source/en/model_doc/vaultgemma.md | 3 +- 15 files changed, 58 insertions(+), 46 deletions(-) diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index 6fdc16bcfce1..be97cf6d7c36 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -439,6 +439,8 @@ title: DeBERTa - local: model_doc/deberta-v2 title: DeBERTa-v2 + - local: model_doc/deepseek_v2 + title: DeepSeek-V2 - local: model_doc/deepseek_v3 title: DeepSeek-V3 - local: model_doc/dialogpt @@ -763,12 +765,6 @@ title: D-FINE - local: model_doc/dab-detr title: DAB-DETR - - local: model_doc/deepseek_v2 - title: DeepSeek-V2 - - local: model_doc/deepseek_vl - title: DeepseekVL - - local: model_doc/deepseek_vl_hybrid - title: DeepseekVLHybrid - local: model_doc/deformable_detr title: Deformable DETR - local: model_doc/deit @@ -851,10 +847,16 @@ title: RT-DETR - local: model_doc/rt_detr_v2 title: RT-DETRv2 + - local: model_doc/sam2 + title: SAM2 - local: model_doc/segformer title: SegFormer - local: model_doc/seggpt title: SegGpt + - local: model_doc/sam + title: Segment Anything + - local: model_doc/sam_hq + title: Segment Anything High Quality - local: model_doc/superglue title: SuperGlue - local: model_doc/superpoint @@ -977,6 +979,8 @@ title: XLSR-Wav2Vec2 title: Audio models - sections: + - local: model_doc/sam2_video + title: SAM2 Video - local: model_doc/timesformer title: TimeSformer - local: model_doc/vjepa2 @@ -1021,6 +1025,10 @@ title: ColQwen2 - local: model_doc/data2vec title: Data2Vec + - local: model_doc/deepseek_vl + title: DeepseekVL + - local: model_doc/deepseek_vl_hybrid + title: DeepseekVLHybrid - local: model_doc/deplot title: DePlot - local: model_doc/donut @@ -1139,14 +1147,6 @@ title: Qwen3VL - local: model_doc/qwen3_vl_moe title: Qwen3VLMoe - - local: model_doc/sam2 - title: SAM2 - - local: model_doc/sam2_video - title: SAM2 Video - - local: model_doc/sam - title: Segment Anything - - local: model_doc/sam_hq - title: Segment Anything High Quality - local: model_doc/shieldgemma2 title: ShieldGemma2 - local: model_doc/siglip diff --git a/docs/source/en/model_doc/bert-generation.md b/docs/source/en/model_doc/bert-generation.md index 38cbe2137eb7..b5be3458db7d 100644 --- a/docs/source/en/model_doc/bert-generation.md +++ b/docs/source/en/model_doc/bert-generation.md @@ -13,6 +13,7 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on 2019-07-29 and added to Hugging Face Transformers on 2020-11-16.*
diff --git a/docs/source/en/model_doc/flex_olmo.md b/docs/source/en/model_doc/flex_olmo.md index b771fe526d06..418a660b6d23 100644 --- a/docs/source/en/model_doc/flex_olmo.md +++ b/docs/source/en/model_doc/flex_olmo.md @@ -16,7 +16,7 @@ limitations under the License. ⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be rendered properly in your Markdown viewer. --> -*This model was released on 2025-07-09 and added to Hugging Face Transformers on 2025-09-15.* +*This model was released on 2025-07-09 and added to Hugging Face Transformers on 2025-09-18.*
PyTorch diff --git a/docs/source/en/model_doc/hunyuan_v1_dense.md b/docs/source/en/model_doc/hunyuan_v1_dense.md index f87ca422c8ed..520c68b7fd9d 100644 --- a/docs/source/en/model_doc/hunyuan_v1_dense.md +++ b/docs/source/en/model_doc/hunyuan_v1_dense.md @@ -13,6 +13,7 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on {release_date} and added to Hugging Face Transformers on 2025-08-22.* # HunYuanDenseV1 diff --git a/docs/source/en/model_doc/hunyuan_v1_moe.md b/docs/source/en/model_doc/hunyuan_v1_moe.md index c66846cc0881..36a53742715d 100644 --- a/docs/source/en/model_doc/hunyuan_v1_moe.md +++ b/docs/source/en/model_doc/hunyuan_v1_moe.md @@ -13,6 +13,7 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on {release_date} and added to Hugging Face Transformers on 2025-08-22.* # HunYuanMoEV1 diff --git a/docs/source/en/model_doc/lfm2_vl.md b/docs/source/en/model_doc/lfm2_vl.md index 1607e3066905..3a93a8189a70 100644 --- a/docs/source/en/model_doc/lfm2_vl.md +++ b/docs/source/en/model_doc/lfm2_vl.md @@ -13,6 +13,7 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on {release_date} and added to Hugging Face Transformers on 2025-09-18.*
PyTorch diff --git a/docs/source/en/model_doc/longcat_flash.md b/docs/source/en/model_doc/longcat_flash.md index b2c2d7a00646..d9a9a4a7f603 100644 --- a/docs/source/en/model_doc/longcat_flash.md +++ b/docs/source/en/model_doc/longcat_flash.md @@ -16,8 +16,7 @@ limitations under the License. ⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be rendered properly in your Markdown viewer. --> -*This model was released on 2025-09-01 and added to Hugging Face Transformers on 2025-09-15.* - +*This model was released on 2025-09-01 and added to Hugging Face Transformers on 2025-09-17.* # LongCatFlash @@ -70,7 +69,7 @@ outputs = model.generate(inputs, max_new_tokens=30) print(tokenizer.batch_decode(outputs)) ``` -To run with TP, you will need torchrun: +To run with TP, you will need torchrun: ```bash torchrun --nproc_per_node=8 --nnodes=2 --node_rank=0 | 1 --rdzv-id --rdzv-backend c10d --rdzv-endpoint $NODE_ID:$NODE_PORT --log-dir ./logs_longcat launch_longcat.py diff --git a/docs/source/en/model_doc/ministral.md b/docs/source/en/model_doc/ministral.md index 07692c6163e5..13b6f3d6c04b 100644 --- a/docs/source/en/model_doc/ministral.md +++ b/docs/source/en/model_doc/ministral.md @@ -13,6 +13,7 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on {release_date} and added to Hugging Face Transformers on 2025-09-11.*
diff --git a/docs/source/en/model_doc/olmo3.md b/docs/source/en/model_doc/olmo3.md index e320181925ca..8e88a175d463 100644 --- a/docs/source/en/model_doc/olmo3.md +++ b/docs/source/en/model_doc/olmo3.md @@ -16,7 +16,8 @@ limitations under the License. ⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be rendered properly in your Markdown viewer. --> -*This model was released on {release_date} and added to Hugging Face Transformers on 2025-09-08.* +*This model was released on {release_date} and added to Hugging Face Transformers on 2025-09-16.* +
PyTorch @@ -46,7 +47,7 @@ pipe = pipeline( dtype=torch.bfloat16, device=0, ) - + result = pipe("Plants create energy through a process known as") print(result) ``` @@ -119,11 +120,11 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ## Notes -- Load specific intermediate checkpoints by adding the `revision` parameter to [`~PreTrainedModel.from_pretrained`]. +- Load specific intermediate checkpoints by adding the `revision` parameter to [`~PreTrainedModel.from_pretrained`]. ```py from transformers import AutoModelForCausalLM - + model = AutoModelForCausalLM.from_pretrained("allenai/TBA", revision="stage1-step140000-tokens294B") ``` @@ -144,4 +145,4 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ## Olmo3PreTrainedModel [[autodoc]] Olmo3PreTrainedModel - - forward \ No newline at end of file + - forward diff --git a/docs/source/en/model_doc/ovis2.md b/docs/source/en/model_doc/ovis2.md index ab1d761f19ed..342e34ef7a1b 100644 --- a/docs/source/en/model_doc/ovis2.md +++ b/docs/source/en/model_doc/ovis2.md @@ -13,6 +13,7 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on 2024-05-31 and added to Hugging Face Transformers on 2025-08-18.* # Ovis2 diff --git a/docs/source/en/model_doc/qwen3_next.md b/docs/source/en/model_doc/qwen3_next.md index f2e003182ee7..737934136099 100644 --- a/docs/source/en/model_doc/qwen3_next.md +++ b/docs/source/en/model_doc/qwen3_next.md @@ -13,18 +13,20 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> +*This model was released on {release_date} and added to Hugging Face Transformers on 2025-09-10.* + ## Overview -The Qwen3-Next series represents our next-generation foundation models, optimized for extreme context length and large-scale parameter efficiency. +The Qwen3-Next series represents our next-generation foundation models, optimized for extreme context length and large-scale parameter efficiency. The series introduces a suite of architectural innovations designed to maximize performance while minimizing computational cost: -- **Hybrid Attention**: Replaces standard attention with the combination of **Gated DeltaNet** and **Gated Attention**, enabling efficient context modeling. +- **Hybrid Attention**: Replaces standard attention with the combination of **Gated DeltaNet** and **Gated Attention**, enabling efficient context modeling. - **High-Sparsity MoE**: Achieves an extreme low activation ratio as 1:50 in MoE layers — drastically reducing FLOPs per token while preserving model capacity. - **Multi-Token Prediction(MTP)**: Boosts pretraining model performance, and accelerates inference. -- **Other Optimizations**: Includes techniques such as **zero-centered and weight-decayed layernorm**, **Gated Attention**, and other stabilizing enhancements for robust training. +- **Other Optimizations**: Includes techniques such as **zero-centered and weight-decayed layernorm**, **Gated Attention**, and other stabilizing enhancements for robust training. Built on this architecture, we trained and open-sourced Qwen3-Next-80B-A3B — 80B total parameters, only 3B active — achieving extreme sparsity and efficiency. -Despite its ultra-efficiency, it outperforms Qwen3-32B on downstream tasks — while requiring **less than 1/10 of the training cost**. +Despite its ultra-efficiency, it outperforms Qwen3-32B on downstream tasks — while requiring **less than 1/10 of the training cost**. Moreover, it delivers over **10x higher inference throughput** than Qwen3-32B when handling contexts longer than 32K tokens. For more details, please visit our blog [Qwen3-Next](qwen3_next) ([blog post](https://qwenlm.github.io/blog/qwen3_next/)). @@ -60,7 +62,7 @@ generated_ids = model.generate( **model_inputs, max_new_tokens=512 ) -output_ids = generated_ids[0][len(model_inputs.input_ids[0]):].tolist() +output_ids = generated_ids[0][len(model_inputs.input_ids[0]):].tolist() content = tokenizer.decode(output_ids, skip_special_tokens=True) diff --git a/docs/source/en/model_doc/qwen3_vl.md b/docs/source/en/model_doc/qwen3_vl.md index 9e90363a1eba..c939d5da3cd9 100644 --- a/docs/source/en/model_doc/qwen3_vl.md +++ b/docs/source/en/model_doc/qwen3_vl.md @@ -13,7 +13,7 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> -*This model was released on None and added to Hugging Face Transformers on 2025-08-16.* +*This model was released on None and added to Hugging Face Transformers on 2025-09-15.*
diff --git a/docs/source/en/model_doc/qwen3_vl_moe.md b/docs/source/en/model_doc/qwen3_vl_moe.md index 76d046efff2d..6e27adf915d3 100644 --- a/docs/source/en/model_doc/qwen3_vl_moe.md +++ b/docs/source/en/model_doc/qwen3_vl_moe.md @@ -13,7 +13,7 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> -*This model was released on None and added to Hugging Face Transformers on 2025-08-17.* +*This model was released on None and added to Hugging Face Transformers on 2025-09-15.*
diff --git a/docs/source/en/model_doc/seed_oss.md b/docs/source/en/model_doc/seed_oss.md index 0f0dacb2be90..dbcddcb5f2c7 100644 --- a/docs/source/en/model_doc/seed_oss.md +++ b/docs/source/en/model_doc/seed_oss.md @@ -1,17 +1,20 @@ - + +*This model was released on {release_date} and added to Hugging Face Transformers on 2025-08-22.* # SeedOss @@ -54,4 +57,4 @@ To be released with the official model launch. ## SeedOssForQuestionAnswering [[autodoc]] SeedOssForQuestionAnswering - - forward \ No newline at end of file + - forward diff --git a/docs/source/en/model_doc/vaultgemma.md b/docs/source/en/model_doc/vaultgemma.md index c9eb36124fca..94d28cc8afe2 100644 --- a/docs/source/en/model_doc/vaultgemma.md +++ b/docs/source/en/model_doc/vaultgemma.md @@ -16,6 +16,7 @@ limitations under the License. ⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be rendered properly in your Markdown viewer. --> +*This model was released on {release_date} and added to Hugging Face Transformers on 2025-09-12.* # VaultGemma @@ -30,7 +31,7 @@ sequence length. VaultGemma was trained from scratch with sequence-level differential privacy (DP). Its training data includes the same mixture as the [Gemma 2 models](https://huggingface.co/collections/google/gemma-2-release-667d6600fd5220e7b967f315), consisting of a number of documents of varying lengths. Additionally, it is trained using -[DP stochastic gradient descent (DP-SGD)](https://arxiv.org/abs/1607.00133) and provides a +[DP stochastic gradient descent (DP-SGD)](https://huggingface.co/papers/1607.00133) and provides a (ε ≤ 2.0, δ ≤ 1.1e-10)-sequence-level DP guarantee, where a sequence consists of 1024 consecutive tokens extracted from heterogeneous data sources. Specifically, the privacy unit of the guarantee is for the sequences after sampling and packing of the mixture. From ae88512bc026d106adc91af27939e9fa34ea881a Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Fri, 19 Sep 2025 21:50:26 +0800 Subject: [PATCH 123/204] RUFF fix on CI scripts (#40805) Signed-off-by: Yuanyuan Chen --- .circleci/create_circleci_config.py | 23 +++++++++++------------ .circleci/parse_test_outputs.py | 3 ++- .github/scripts/assign_reviewers.py | 8 +++++--- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.circleci/create_circleci_config.py b/.circleci/create_circleci_config.py index aff69510d636..1e39aa4751a5 100644 --- a/.circleci/create_circleci_config.py +++ b/.circleci/create_circleci_config.py @@ -16,10 +16,9 @@ import argparse import copy import os -import random from dataclasses import dataclass -from typing import Any, Dict, List, Optional -import glob +from typing import Any, Optional + import yaml @@ -82,15 +81,15 @@ def to_dict(self): @dataclass class CircleCIJob: name: str - additional_env: Dict[str, Any] = None - docker_image: List[Dict[str, str]] = None - install_steps: List[str] = None + additional_env: dict[str, Any] = None + docker_image: list[dict[str, str]] = None + install_steps: list[str] = None marker: Optional[str] = None parallelism: Optional[int] = 0 pytest_num_workers: int = 8 - pytest_options: Dict[str, Any] = None + pytest_options: dict[str, Any] = None resource_class: Optional[str] = "xlarge" - tests_to_run: Optional[List[str]] = None + tests_to_run: Optional[list[str]] = None num_test_files_per_worker: Optional[int] = 10 # This should be only used for doctest job! command_timeout: Optional[int] = None @@ -149,7 +148,7 @@ def to_dict(self): # Examples special case: we need to download NLTK files in advance to avoid cuncurrency issues timeout_cmd = f"timeout {self.command_timeout} " if self.command_timeout else "" marker_cmd = f"-m '{self.marker}'" if self.marker is not None else "" - junit_flags = f" -p no:warning -o junit_family=xunit1 --junitxml=test-results/junit.xml" + junit_flags = " -p no:warning -o junit_family=xunit1 --junitxml=test-results/junit.xml" joined_flaky_patterns = "|".join(FLAKY_TEST_FAILURE_PATTERNS) repeat_on_failure_flags = f"--reruns 5 --reruns-delay 2 --only-rerun '({joined_flaky_patterns})'" parallel = f' << pipeline.parameters.{self.job_name}_parallelism >> ' @@ -200,9 +199,9 @@ def to_dict(self): fi""" }, }, - {"run": {"name": "Expand to show skipped tests", "when": "always", "command": f"python3 .circleci/parse_test_outputs.py --file tests_output.txt --skip"}}, - {"run": {"name": "Failed tests: show reasons", "when": "always", "command": f"python3 .circleci/parse_test_outputs.py --file tests_output.txt --fail"}}, - {"run": {"name": "Errors", "when": "always", "command": f"python3 .circleci/parse_test_outputs.py --file tests_output.txt --errors"}}, + {"run": {"name": "Expand to show skipped tests", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --skip"}}, + {"run": {"name": "Failed tests: show reasons", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --fail"}}, + {"run": {"name": "Errors", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --errors"}}, {"store_test_results": {"path": "test-results"}}, {"store_artifacts": {"path": "test-results/junit.xml"}}, {"store_artifacts": {"path": "reports"}}, diff --git a/.circleci/parse_test_outputs.py b/.circleci/parse_test_outputs.py index a69da1a3eafb..c58447155859 100644 --- a/.circleci/parse_test_outputs.py +++ b/.circleci/parse_test_outputs.py @@ -1,5 +1,6 @@ -import re import argparse +import re + def parse_pytest_output(file_path): skipped_tests = {} diff --git a/.github/scripts/assign_reviewers.py b/.github/scripts/assign_reviewers.py index 02966204ea32..18567203596f 100644 --- a/.github/scripts/assign_reviewers.py +++ b/.github/scripts/assign_reviewers.py @@ -13,14 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os -import github import json -from github import Github +import os import re from collections import Counter from pathlib import Path +import github +from github import Github + + def pattern_to_regex(pattern): if pattern.startswith("/"): start_anchor = True From c52a158fac0f1ff89e5f7abf04628cafca0b6243 Mon Sep 17 00:00:00 2001 From: Marc Sun <57196510+SunMarc@users.noreply.github.com> Date: Fri, 19 Sep 2025 16:14:44 +0200 Subject: [PATCH 124/204] fix dict like init for ModelOutput (#41002) * fix dict like init * style --- src/transformers/utils/generic.py | 2 ++ tests/utils/test_generic.py | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/transformers/utils/generic.py b/src/transformers/utils/generic.py index 451b98193d43..1606443ccece 100644 --- a/src/transformers/utils/generic.py +++ b/src/transformers/utils/generic.py @@ -318,6 +318,8 @@ def __post_init__(self): # if we provided an iterator as first field and the iterator is a (key, value) iterator # set the associated fields if first_field_iterator: + # reset first field to None + setattr(self, class_fields[0].name, None) for idx, element in enumerate(iterator): if not isinstance(element, (list, tuple)) or len(element) != 2 or not isinstance(element[0], str): if idx == 0: diff --git a/tests/utils/test_generic.py b/tests/utils/test_generic.py index 77e7cdba7c2c..f09d8653adf4 100644 --- a/tests/utils/test_generic.py +++ b/tests/utils/test_generic.py @@ -19,7 +19,7 @@ import pytest from transformers.configuration_utils import PretrainedConfig -from transformers.modeling_outputs import BaseModelOutput +from transformers.modeling_outputs import BaseModelOutput, CausalLMOutputWithPast from transformers.testing_utils import require_torch from transformers.utils import ( can_return_tuple, @@ -139,6 +139,19 @@ def test_to_py_obj_torch(self): self.assertTrue(to_py_obj([t1, t2]) == [x1, x2]) + def test_model_output_subclass(self): + # testing with “dict-like init” case + out = CausalLMOutputWithPast({"logits": torch.ones(2, 3, 4)}) + self.assertTrue(out["logits"] is not None) + self.assertTrue(out.loss is None) + self.assertTrue(len(out.to_tuple()) == 1) + + # testing with dataclass init case + out = CausalLMOutputWithPast(logits=torch.ones(2, 3, 4)) + self.assertTrue(out["logits"] is not None) + self.assertTrue(out.loss is None) + self.assertTrue(len(out.to_tuple()) == 1) + class ValidationDecoratorTester(unittest.TestCase): def test_cases_no_warning(self): From 425b2b4918f2af2f93f13fa4594b4348b3b78d63 Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Fri, 19 Sep 2025 15:36:12 +0100 Subject: [PATCH 125/204] =?UTF-8?q?=F0=9F=9A=A8=20[v5]=20remove=20generate?= =?UTF-8?q?=20output=20retrocompatibility=20aliases=20(#40998)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove old type aliases --- src/transformers/generation/__init__.py | 20 -------------------- src/transformers/generation/utils.py | 22 ---------------------- tests/generation/test_utils.py | 24 ------------------------ 3 files changed, 66 deletions(-) diff --git a/src/transformers/generation/__init__.py b/src/transformers/generation/__init__.py index 2cf4007a0192..a7bb6c113fee 100644 --- a/src/transformers/generation/__init__.py +++ b/src/transformers/generation/__init__.py @@ -101,16 +101,6 @@ ] _import_structure["utils"] = [ "GenerationMixin", - "GreedySearchEncoderDecoderOutput", - "GreedySearchDecoderOnlyOutput", - "SampleEncoderDecoderOutput", - "SampleDecoderOnlyOutput", - "BeamSearchEncoderDecoderOutput", - "BeamSearchDecoderOnlyOutput", - "BeamSampleEncoderDecoderOutput", - "BeamSampleDecoderOnlyOutput", - "ContrastiveSearchEncoderDecoderOutput", - "ContrastiveSearchDecoderOnlyOutput", "GenerateBeamDecoderOnlyOutput", "GenerateBeamEncoderDecoderOutput", "GenerateDecoderOnlyOutput", @@ -196,21 +186,11 @@ validate_stopping_criteria, ) from .utils import ( - BeamSampleDecoderOnlyOutput, - BeamSampleEncoderDecoderOutput, - BeamSearchDecoderOnlyOutput, - BeamSearchEncoderDecoderOutput, - ContrastiveSearchDecoderOnlyOutput, - ContrastiveSearchEncoderDecoderOutput, GenerateBeamDecoderOnlyOutput, GenerateBeamEncoderDecoderOutput, GenerateDecoderOnlyOutput, GenerateEncoderDecoderOutput, GenerationMixin, - GreedySearchDecoderOnlyOutput, - GreedySearchEncoderDecoderOutput, - SampleDecoderOnlyOutput, - SampleEncoderDecoderOutput, ) from .watermarking import ( BayesianDetectorConfig, diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index 845e723e95f7..71fb097297f6 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -330,28 +330,6 @@ class GenerateBeamEncoderDecoderOutput(ModelOutput): past_key_values: Optional[Cache] = None -# TODO (joao): remove the equivalent classes and typing shortcuts below in v5 -# Equivalent classes (kept for retrocompatibility purposes) -GreedySearchDecoderOnlyOutput = GenerateDecoderOnlyOutput -ContrastiveSearchDecoderOnlyOutput = GenerateDecoderOnlyOutput -SampleDecoderOnlyOutput = GenerateDecoderOnlyOutput - -ContrastiveSearchEncoderDecoderOutput = GenerateEncoderDecoderOutput -GreedySearchEncoderDecoderOutput = GenerateEncoderDecoderOutput -SampleEncoderDecoderOutput = GenerateEncoderDecoderOutput - -BeamSearchDecoderOnlyOutput = GenerateBeamDecoderOnlyOutput -BeamSampleDecoderOnlyOutput = GenerateBeamDecoderOnlyOutput - -BeamSearchEncoderDecoderOutput = GenerateBeamEncoderDecoderOutput -BeamSampleEncoderDecoderOutput = GenerateBeamEncoderDecoderOutput - -GreedySearchOutput = Union[GreedySearchEncoderDecoderOutput, GreedySearchDecoderOnlyOutput] -SampleOutput = Union[SampleEncoderDecoderOutput, SampleDecoderOnlyOutput] -BeamSearchOutput = Union[BeamSearchEncoderDecoderOutput, BeamSearchDecoderOnlyOutput] -BeamSampleOutput = Union[BeamSampleEncoderDecoderOutput, BeamSampleDecoderOnlyOutput] -ContrastiveSearchOutput = Union[ContrastiveSearchEncoderDecoderOutput, ContrastiveSearchDecoderOnlyOutput] - # Typing shortcuts GenerateNonBeamOutput = Union[GenerateDecoderOnlyOutput, GenerateEncoderDecoderOutput] GenerateBeamOutput = Union[GenerateBeamDecoderOnlyOutput, GenerateBeamEncoderDecoderOutput] diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index b8931c9988f6..c86dedd04d10 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -84,10 +84,6 @@ StaticCache, ) from transformers.generation import ( - BeamSampleDecoderOnlyOutput, - BeamSampleEncoderDecoderOutput, - BeamSearchDecoderOnlyOutput, - BeamSearchEncoderDecoderOutput, CompileConfig, GenerateBeamDecoderOnlyOutput, GenerateBeamEncoderDecoderOutput, @@ -95,14 +91,10 @@ GenerateEncoderDecoderOutput, GenerationConfig, GenerationMixin, - GreedySearchDecoderOnlyOutput, - GreedySearchEncoderDecoderOutput, LogitsProcessorList, MaxLengthCriteria, MinLengthLogitsProcessor, PromptLookupCandidateGenerator, - SampleDecoderOnlyOutput, - SampleEncoderDecoderOutput, StoppingCriteria, StoppingCriteriaList, SynthIDTextWatermarkingConfig, @@ -364,15 +356,11 @@ def test_greedy_generate_dict_outputs(self): if model.config.is_encoder_decoder: self.assertTrue(output_generate.sequences.shape[1] == self.max_new_tokens + 1) self.assertIsInstance(output_generate, GenerateEncoderDecoderOutput) - # Retrocompatibility check - self.assertIsInstance(output_generate, GreedySearchEncoderDecoderOutput) else: self.assertTrue( output_generate.sequences.shape[1] == self.max_new_tokens + inputs_dict["input_ids"].shape[1] ) self.assertIsInstance(output_generate, GenerateDecoderOnlyOutput) - # Retrocompatibility check - self.assertIsInstance(output_generate, GreedySearchDecoderOnlyOutput) self._check_generate_outputs(output_generate, model.config) @@ -446,15 +434,11 @@ def test_sample_generate_dict_output(self): if model.config.is_encoder_decoder: self.assertTrue(output_generate.sequences.shape[1] == self.max_new_tokens + 1) self.assertIsInstance(output_generate, GenerateEncoderDecoderOutput) - # Retrocompatibility check - self.assertIsInstance(output_generate, SampleEncoderDecoderOutput) else: self.assertTrue( output_generate.sequences.shape[1] == self.max_new_tokens + inputs_dict["input_ids"].shape[1] ) self.assertIsInstance(output_generate, GenerateDecoderOnlyOutput) - # Retrocompatibility check - self.assertIsInstance(output_generate, SampleDecoderOnlyOutput) self._check_generate_outputs(output_generate, model.config, num_return_sequences=2) @@ -496,15 +480,11 @@ def test_beam_search_generate_dict_output(self): if model.config.is_encoder_decoder: self.assertTrue(output_generate.sequences.shape[1] == self.max_new_tokens + 1) self.assertIsInstance(output_generate, GenerateBeamEncoderDecoderOutput) - # Retrocompatibility check - self.assertIsInstance(output_generate, BeamSearchEncoderDecoderOutput) else: self.assertTrue( output_generate.sequences.shape[1] == self.max_new_tokens + inputs_dict["input_ids"].shape[1] ) self.assertIsInstance(output_generate, GenerateBeamDecoderOnlyOutput) - # Retrocompatibility check - self.assertIsInstance(output_generate, BeamSearchDecoderOnlyOutput) self._check_generate_outputs( output_generate, @@ -625,15 +605,11 @@ def test_beam_sample_generate_dict_output(self): if model.config.is_encoder_decoder: self.assertTrue(output_generate.sequences.shape[1] == self.max_new_tokens + 1) self.assertIsInstance(output_generate, GenerateBeamEncoderDecoderOutput) - # Retrocompatibility check - self.assertIsInstance(output_generate, BeamSampleEncoderDecoderOutput) else: self.assertTrue( output_generate.sequences.shape[1] == self.max_new_tokens + inputs_dict["input_ids"].shape[1] ) self.assertIsInstance(output_generate, GenerateBeamDecoderOnlyOutput) - # Retrocompatibility check - self.assertIsInstance(output_generate, BeamSampleDecoderOnlyOutput) self._check_generate_outputs( output_generate, From 4e05e80d09ddf12057f9dc4383e3f135c5586a9b Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Fri, 19 Sep 2025 15:36:26 +0100 Subject: [PATCH 126/204] [tests] update `test_left_padding_compatibility` (and minimize overwrites) (#40980) * update test (and overwrites) * better test comment * 0 as a default for --- tests/generation/test_utils.py | 110 ++++++++++++------ tests/models/bamba/test_modeling_bamba.py | 83 +------------ tests/models/blip_2/test_modeling_blip_2.py | 84 ------------- .../falcon_h1/test_modeling_falcon_h1.py | 84 +------------ tests/models/idefics/test_modeling_idefics.py | 89 +++++--------- .../models/imagegpt/test_modeling_imagegpt.py | 4 - .../test_modeling_instructblip.py | 89 -------------- .../test_modeling_instructblipvideo.py | 89 -------------- tests/models/kosmos2/test_modeling_kosmos2.py | 65 +++-------- .../kosmos2_5/test_modeling_kosmos2_5.py | 67 +++-------- .../test_modeling_kyutai_speech_to_text.py | 86 +------------- tests/models/mllama/test_modeling_mllama.py | 19 +++ tests/models/moshi/test_modeling_moshi.py | 72 ++++-------- .../qwen2_audio/test_modeling_qwen2_audio.py | 1 + tests/models/voxtral/test_modeling_voxtral.py | 2 +- tests/models/zamba/test_modeling_zamba.py | 45 ------- tests/models/zamba2/test_modeling_zamba2.py | 45 ------- 17 files changed, 190 insertions(+), 844 deletions(-) diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index c86dedd04d10..dcca71df7c2f 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -23,6 +23,7 @@ import unittest import warnings from pathlib import Path +from typing import Optional import numpy as np import pytest @@ -903,32 +904,44 @@ def test_prompt_lookup_decoding_stops_at_eos(self): self.assertTrue(output_prompt_lookup.shape[-1] == 10) @pytest.mark.generate - def test_left_padding_compatibility(self): - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 + def test_left_padding_compatibility( + self, unpadded_custom_inputs: Optional[dict] = None, padded_custom_inputs: Optional[dict] = None + ): + """ + Tests that adding left-padding yields the same logits as the original input. Exposes arguments for custom + inputs for overwrites, to prevent full rewrites of the test when all we need is model-specific input handling. - # First, filter out models that don't support left padding - # - The model must have generative capabilities - if len(self.all_generative_model_classes) == 0: - self.skipTest(reason="No generative architecture available for this model.") + ! If you overwrite this test, make sure to document why you need to overwrite it ! - # - The model must support padding + NOTE: left-padding results in small numerical differences. This is expected. + See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 + + Args: + unpadded_custom_inputs (`dict`, *optional*): + Used in test overwrites. Custom inputs to add/overwrite over the default test inputs. + padded_custom_inputs (`dict`, *optional*): + Used in test overwrites. Custom inputs to add/overwrite over the padded test input handcrafted in this + test. Commonly used e.g. with multimodal cross attention masks. + """ + + # First, filter out models that don't support left padding + # 1. The model must support padding if not self.has_attentions: self.skipTest(reason="This model doesn't support padding.") - - # - The model must be a decoder-only architecture (encoder-based architectures use right-padding) + # 2. [encoder-decoder] The model must be a decoder-only architecture. Encoder-based architectures can use + # right-padding in their (encoder) inputs. Encoder-decoder may use left-padding on their decoder inputs + # [TODO: lift this restriction? technically, we can test padding the decoder inputs.] decoder_only_classes = [] for model_class in self.all_generative_model_classes: config, _ = self.prepare_config_and_inputs_for_generate() - if config.get_text_config(decoder=True).is_encoder_decoder: + if config.is_encoder_decoder: continue else: decoder_only_classes.append(model_class) if len(decoder_only_classes) == 0: self.skipTest(reason="No decoder-only architecture available for this model.") - - # - Decoder-only architectures derived from encoder-decoder models could support it in theory, but we haven't - # added support for it yet. We skip these models for now. + # 3. [old models] Decoder-only architectures derived from encoder-decoder models could support it in theory, + # but we haven't added support for it yet. We skip these models for now. has_encoder_attributes = any( attr_name for attr_name in config.to_dict() @@ -939,48 +952,73 @@ def test_left_padding_compatibility(self): reason="The decoder-only derived from encoder-decoder models are not expected to support left-padding." ) - # Then, test left-padding - def _prepare_model_kwargs(input_ids, attention_mask, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} + # Now we can start testing + unpadded_custom_inputs = unpadded_custom_inputs or {} + padded_custom_inputs = padded_custom_inputs or {} + + def _prepare_model_kwargs(model_inputs, signature): + model_kwargs = {"input_ids": model_inputs["input_ids"], "attention_mask": model_inputs["attention_mask"]} if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) + position_ids = torch.cumsum(model_inputs["attention_mask"], dim=-1) - 1 + position_ids.masked_fill_(model_inputs["attention_mask"] == 0, 1) model_kwargs["position_ids"] = position_ids if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[1], device=torch_device) + cache_position = torch.arange(model_inputs["input_ids"].shape[1], device=torch_device) model_kwargs["cache_position"] = cache_position + # forward all other inputs, if they are in the signature + model_kwargs.update({k: v for k, v in model_inputs.items() if k not in model_kwargs and k in signature}) return model_kwargs for model_class in decoder_only_classes: config, inputs_dict = self.prepare_config_and_inputs_for_generate() - input_ids = inputs_dict["input_ids"] - attention_mask = inputs_dict.get("attention_mask") - if attention_mask is None: - attention_mask = torch.ones_like(input_ids) - model = model_class(config).to(torch_device).eval() signature = inspect.signature(model.forward).parameters.keys() - # no cache as some models require special cache classes to be init outside forward + # No cache to simplify the test (some models need careful init) model.generation_config.use_cache = False + inputs_dict.update(unpadded_custom_inputs) + # special case: an inexistent `attention_mask` is a full mask + inputs_dict["attention_mask"] = inputs_dict.get("attention_mask", None) + if inputs_dict["attention_mask"] is None: + inputs_dict["attention_mask"] = torch.ones_like(inputs_dict["input_ids"]) - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, signature) - next_logits_wo_padding = model(**model_kwargs).logits[:, -1, :] + # Get output logits from inputs without padding + model_kwargs_wo_padding = _prepare_model_kwargs(inputs_dict, signature) + next_logits_wo_padding = model(**model_kwargs_wo_padding).logits[:, -1, :] - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) + # Prepare padding on common inputs (pad length 32) + input_ids = inputs_dict["input_ids"] + attention_mask = inputs_dict["attention_mask"] + token_type_ids = inputs_dict.get("token_type_ids", None) + pad_token_id = getattr(config.get_text_config(decoder=True), "pad_token_id", None) or 0 pad_size = (input_ids.shape[0], 32, *input_ids.shape[2:]) padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id padded_input_ids = torch.cat((padding, input_ids), dim=1) padded_attention_mask = torch.cat( (torch.zeros(pad_size[:2], dtype=input_ids.dtype, device=torch_device), attention_mask), dim=1 ) - model_kwargs = _prepare_model_kwargs(padded_input_ids, padded_attention_mask, signature) - next_logits_with_padding = model(**model_kwargs).logits[:, -1, :] + if token_type_ids is not None: + padded_token_type_ids = torch.cat( + ( + # Assumption: `0` is a good default value for padding token type ids + torch.zeros(pad_size[:2], dtype=input_ids.dtype, device=torch_device), + token_type_ids, + ), + dim=1, + ) + else: + padded_token_type_ids = None + + # Get output logits from inputs with left-padding (pad length 32) + padded_inputs_dict = copy.deepcopy(inputs_dict) + padded_inputs_dict["input_ids"] = padded_input_ids + padded_inputs_dict["attention_mask"] = padded_attention_mask + if padded_token_type_ids is not None: + padded_inputs_dict["token_type_ids"] = padded_token_type_ids + padded_inputs_dict.update(padded_custom_inputs) + + model_kwargs_with_padding = _prepare_model_kwargs(padded_inputs_dict, signature) + next_logits_with_padding = model(**model_kwargs_with_padding).logits[:, -1, :] # They should result in very similar logits torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=1e-5, atol=1e-5) diff --git a/tests/models/bamba/test_modeling_bamba.py b/tests/models/bamba/test_modeling_bamba.py index 06f99fc1c6ac..10eaf0efe2c3 100644 --- a/tests/models/bamba/test_modeling_bamba.py +++ b/tests/models/bamba/test_modeling_bamba.py @@ -438,88 +438,11 @@ def test_batching_equivalence(self): super().test_batching_equivalence() self.model_tester.use_input_mask = orig - # essentially the same test in test_utils, just adjustment for rtol for this model @pytest.mark.generate def test_left_padding_compatibility(self): - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 - - # First, filter out models that don't support left padding - # - The model must have generative capabilities - if len(self.all_generative_model_classes) == 0: - self.skipTest(reason="No generative architecture available for this model.") - - # - The model must support padding - if not self.has_attentions: - self.skipTest(reason="This model doesn't support padding.") - - # - The model must be a decoder-only architecture (encoder-based architectures use right-padding) - decoder_only_classes = [] - for model_class in self.all_generative_model_classes: - config, _ = self.prepare_config_and_inputs_for_generate() - if config.is_encoder_decoder: - continue - else: - decoder_only_classes.append(model_class) - if len(decoder_only_classes) == 0: - self.skipTest(reason="No decoder-only architecture available for this model.") - - # - Decoder-only architectures derived from encoder-decoder models could support it in theory, but we haven't - # added support for it yet. We skip these models for now. - has_encoder_attributes = any( - attr_name - for attr_name in config.to_dict() - if attr_name.startswith("encoder") and attr_name != "encoder_no_repeat_ngram_size" - ) - if has_encoder_attributes: - self.skipTest( - reason="The decoder-only derived from encoder-decoder models are not expected to support left-padding." - ) - - # Then, test left-padding - def _prepare_model_kwargs(input_ids, attention_mask, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[-1], device=torch_device) - model_kwargs["cache_position"] = cache_position - return model_kwargs - - for model_class in decoder_only_classes: - config, inputs_dict = self.prepare_config_and_inputs_for_generate() - input_ids = inputs_dict["input_ids"] - - # - for left padding we absolutely need to use an all ones - # attention mask, so we do not use the one in inputs_dict - attention_mask = torch.ones_like(input_ids) - - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # no cache as some models require special cache classes to be init outside forward - model.generation_config.use_cache = False - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, signature) - next_logits_wo_padding = model(**model_kwargs).logits[:, -1, :] - - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - model_kwargs = _prepare_model_kwargs(padded_input_ids, padded_attention_mask, signature) - next_logits_with_padding = model(**model_kwargs).logits[:, -1, :] - - # They should result in very similar logits - torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=1e-5, atol=1e-5) + # TODO: document why a random attention mask causes this test to fail, but a full mask doesn't + unpadded_custom_inputs = {"attention_mask": None} + super().test_left_padding_compatibility(unpadded_custom_inputs=unpadded_custom_inputs) @unittest.skip( "Bamba requires additionally specifying position_ids, seq_idx, and FlashAttentionKwargs for padding-free training." diff --git a/tests/models/blip_2/test_modeling_blip_2.py b/tests/models/blip_2/test_modeling_blip_2.py index 0b3ab74d519c..5667b1a3fe19 100644 --- a/tests/models/blip_2/test_modeling_blip_2.py +++ b/tests/models/blip_2/test_modeling_blip_2.py @@ -19,7 +19,6 @@ import unittest import numpy as np -import pytest import requests from parameterized import parameterized @@ -597,89 +596,6 @@ def _check_generate_outputs(self, output, config, use_cache=False, num_return_se output, config, use_cache=use_cache, num_return_sequences=num_return_sequences, num_beams=num_beams ) - # overwrite because BLIP2 cannot generate only from input ids, and requires pixel values in all cases to be present - @pytest.mark.generate - def test_left_padding_compatibility(self): - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 - - # First, filter out models that don't support left padding - # - The model must have generative capabilities - if len(self.all_generative_model_classes) == 0: - self.skipTest(reason="No generative architecture available for this model.") - - # - The model must support padding - if not self.has_attentions: - self.skipTest(reason="This model doesn't support padding.") - - # - The model must be a decoder-only architecture (encoder-based architectures use right-padding) - decoder_only_classes = [] - for model_class in self.all_generative_model_classes: - config, _ = self.prepare_config_and_inputs_for_generate() - if config.is_encoder_decoder: - continue - else: - decoder_only_classes.append(model_class) - if len(decoder_only_classes) == 0: - self.skipTest(reason="No decoder-only architecture available for this model.") - - # - Decoder-only architectures derived from encoder-decoder models could support it in theory, but we haven't - # added support for it yet. We skip these models for now. - has_encoder_attributes = any( - attr_name - for attr_name in config.to_dict() - if attr_name.startswith("encoder") and attr_name != "encoder_no_repeat_ngram_size" - ) - if has_encoder_attributes: - self.skipTest( - reason="The decoder-only derived from encoder-decoder models are not expected to support left-padding." - ) - - # Then, test left-padding - def _prepare_model_kwargs(input_ids, attention_mask, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[-1], device=torch_device) - model_kwargs["cache_position"] = cache_position - return model_kwargs - - for model_class in decoder_only_classes: - config, inputs_dict = self.prepare_config_and_inputs_for_generate() - input_ids = inputs_dict["input_ids"] - attention_mask = inputs_dict.get("attention_mask") - pixel_values = inputs_dict["pixel_values"] - if attention_mask is None: - attention_mask = torch.ones_like(input_ids) - - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # no cache as some models require special cache classes to be init outside forward - model.generation_config.use_cache = False - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, signature) - next_logits_wo_padding = model(**model_kwargs, pixel_values=pixel_values).logits[:, -1, :] - - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - model_kwargs = _prepare_model_kwargs(padded_input_ids, padded_attention_mask, signature) - next_logits_with_padding = model(**model_kwargs, pixel_values=pixel_values).logits[:, -1, :] - - # They should result in very similar logits - torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=1e-5, atol=1e-5) - # this class is based on `T5ModelTester` found in tests/models/t5/test_modeling_t5.py class Blip2TextModelTester: diff --git a/tests/models/falcon_h1/test_modeling_falcon_h1.py b/tests/models/falcon_h1/test_modeling_falcon_h1.py index 3e475ef70802..e5050df20901 100644 --- a/tests/models/falcon_h1/test_modeling_falcon_h1.py +++ b/tests/models/falcon_h1/test_modeling_falcon_h1.py @@ -14,7 +14,6 @@ # limitations under the License. """Testing suite for the PyTorch FalconH1 model.""" -import inspect import unittest import pytest @@ -413,88 +412,11 @@ def test_batching_equivalence(self): super().test_batching_equivalence() self.model_tester.use_input_mask = orig - # essentially the same test in test_utils, just adjustment for rtol for this model @pytest.mark.generate def test_left_padding_compatibility(self): - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 - - # First, filter out models that don't support left padding - # - The model must have generative capabilities - if len(self.all_generative_model_classes) == 0: - self.skipTest(reason="No generative architecture available for this model.") - - # - The model must support padding - if not self.has_attentions: - self.skipTest(reason="This model doesn't support padding.") - - # - The model must be a decoder-only architecture (encoder-based architectures use right-padding) - decoder_only_classes = [] - for model_class in self.all_generative_model_classes: - config, _ = self.prepare_config_and_inputs_for_generate() - if config.is_encoder_decoder: - continue - else: - decoder_only_classes.append(model_class) - if len(decoder_only_classes) == 0: - self.skipTest(reason="No decoder-only architecture available for this model.") - - # - Decoder-only architectures derived from encoder-decoder models could support it in theory, but we haven't - # added support for it yet. We skip these models for now. - has_encoder_attributes = any( - attr_name - for attr_name in config.to_dict() - if attr_name.startswith("encoder") and attr_name != "encoder_no_repeat_ngram_size" - ) - if has_encoder_attributes: - self.skipTest( - reason="The decoder-only derived from encoder-decoder models are not expected to support left-padding." - ) - - # Then, test left-padding - def _prepare_model_kwargs(input_ids, attention_mask, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[-1], device=torch_device) - model_kwargs["cache_position"] = cache_position - return model_kwargs - - for model_class in decoder_only_classes: - config, inputs_dict = self.prepare_config_and_inputs_for_generate() - input_ids = inputs_dict["input_ids"] - - # - for left padding we absolutely need to use an all ones - # attention mask, so we do not use the one in inputs_dict - attention_mask = torch.ones_like(input_ids) - - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # no cache as some models require special cache classes to be init outside forward - model.generation_config.use_cache = False - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, signature) - next_logits_wo_padding = model(**model_kwargs).logits[:, -1, :] - - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - model_kwargs = _prepare_model_kwargs(padded_input_ids, padded_attention_mask, signature) - next_logits_with_padding = model(**model_kwargs).logits[:, -1, :] - - # They should result in very similar logits - torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=1e-5, atol=1e-5) + # TODO: document why a random attention mask causes this test to fail, but a full mask doesn't + unpadded_custom_inputs = {"attention_mask": None} + super().test_left_padding_compatibility(unpadded_custom_inputs=unpadded_custom_inputs) @slow diff --git a/tests/models/idefics/test_modeling_idefics.py b/tests/models/idefics/test_modeling_idefics.py index 5539d6a0b075..a517d69e18a6 100644 --- a/tests/models/idefics/test_modeling_idefics.py +++ b/tests/models/idefics/test_modeling_idefics.py @@ -13,7 +13,6 @@ # limitations under the License. """Testing suite for the PyTorch Idefics model.""" -import inspect import unittest from functools import cached_property @@ -327,7 +326,6 @@ class IdeficsModelTest(ModelTesterMixin, PipelineTesterMixin, GenerationTesterMi test_pruning = False test_headmasking = False test_torchscript = False - has_attentions = False # only supports SDOA and thus no attention probs returned def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) @@ -594,6 +592,33 @@ def test_generate_from_random_inputs_embeds( ): pass + @pytest.mark.generate + def test_left_padding_compatibility(self): + # Overwrite -- Idefics needs to prepare `image_attention_mask`, and it must be padded accordingly + _, inputs_dict = self.prepare_config_and_inputs_for_generate() + input_ids = inputs_dict["input_ids"] + image_attention_mask = inputs_dict["image_attention_mask"] + + pad_size_img = (input_ids.shape[0], 32, image_attention_mask.shape[-1]) + extra_img_mask = torch.zeros(pad_size_img, dtype=image_attention_mask.dtype, device=torch_device) + padded_image_attention_mask = torch.cat([extra_img_mask, image_attention_mask], dim=1) + + # `image_attention_mask` is randomly generated in `prepare_config_and_inputs_for_generate`, and it must match + # its padded version for the test to be valid -- we need to pass both + unpadded_custom_inputs = {"image_attention_mask": image_attention_mask} + padded_custom_inputs = {"image_attention_mask": padded_image_attention_mask} + super().test_left_padding_compatibility( + unpadded_custom_inputs=unpadded_custom_inputs, padded_custom_inputs=padded_custom_inputs + ) + + @unittest.skip(reason="Idefics can't do text-only inference (test filters non-text inputs)") + def test_eager_padding_matches_padding_free_with_position_ids(self): + pass + + @unittest.skip(reason="Idefics can't do text-only inference (test filters non-text inputs)") + def test_sdpa_padding_matches_padding_free_with_position_ids(self): + pass + @require_torch class IdeficsForVisionText2TextTest(IdeficsModelTest, GenerationTesterMixin, unittest.TestCase): @@ -613,66 +638,6 @@ def test_eager_matches_sdpa_inference( ): pass - @pytest.mark.generate - def test_left_padding_compatibility(self): - """Overwrite because IDEFICS needs image attention mask to be also padded""" - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 - - def _prepare_model_kwargs(input_ids, attention_mask, image_attention_mask, signature): - model_kwargs = { - "input_ids": input_ids, - "attention_mask": attention_mask, - "image_attention_mask": image_attention_mask, - } - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[-1], device=torch_device) - model_kwargs["cache_position"] = cache_position - return model_kwargs - - for model_class in self.all_generative_model_classes: - config, inputs_dict = self.prepare_config_and_inputs_for_generate() - input_ids = inputs_dict.pop("input_ids") - attention_mask = inputs_dict.pop("attention_mask") - if attention_mask is None: - attention_mask = torch.ones_like(input_ids) - image_attention_mask = inputs_dict.pop("image_attention_mask", None) - - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # no cache as some models require special cache classes to be init outside forward - model.generation_config.use_cache = False - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, image_attention_mask, signature) - next_logits_wo_padding = model(**model_kwargs, **inputs_dict).logits[:, -1, :] - - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - - pad_size_img = (input_ids.shape[0], 32, image_attention_mask.shape[-1]) - extra_img_mask = torch.zeros(pad_size_img, dtype=image_attention_mask.dtype, device=torch_device) - padded_image_attention_mask = torch.cat([extra_img_mask, image_attention_mask], dim=1) - model_kwargs = _prepare_model_kwargs( - padded_input_ids, padded_attention_mask, padded_image_attention_mask, signature - ) - next_logits_with_padding = model(**model_kwargs, **inputs_dict).logits[:, -1, :] - - # They should result in very similar logits - torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=1e-5, atol=1e-5) - @pytest.mark.generate def test_generate_continue_from_past_key_values(self): """Overwrite because IDEFICS needs image attention mask to be also processed""" diff --git a/tests/models/imagegpt/test_modeling_imagegpt.py b/tests/models/imagegpt/test_modeling_imagegpt.py index 1c10ed0797db..9a43671ad975 100644 --- a/tests/models/imagegpt/test_modeling_imagegpt.py +++ b/tests/models/imagegpt/test_modeling_imagegpt.py @@ -316,10 +316,6 @@ def test_forward_signature(self): expected_arg_names = ["input_ids"] self.assertListEqual(arg_names[:1], expected_arg_names) - @unittest.skip(reason="The model doesn't support left padding") # and it's not used enough to be worth fixing :) - def test_left_padding_compatibility(self): - pass - @unittest.skip(reason="Model inputs don't fit test pattern") # and it's not used enough to be worth fixing :) def test_past_key_values_format(self): pass diff --git a/tests/models/instructblip/test_modeling_instructblip.py b/tests/models/instructblip/test_modeling_instructblip.py index 3ce58e4cb24a..17a54da482a2 100644 --- a/tests/models/instructblip/test_modeling_instructblip.py +++ b/tests/models/instructblip/test_modeling_instructblip.py @@ -18,7 +18,6 @@ import unittest import numpy as np -import pytest import requests from transformers import ( @@ -566,94 +565,6 @@ def _check_generate_outputs(self, output, config, use_cache=False, num_return_se output, config, use_cache=use_cache, num_return_sequences=num_return_sequences, num_beams=num_beams ) - # overwrite because InstructBLIP cannot generate only from input ids, and requires `pixel` values and `qformer_input_ids` in all cases to be present - @pytest.mark.generate - def test_left_padding_compatibility(self): - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 - - # First, filter out models that don't support left padding - # - The model must have generative capabilities - if len(self.all_generative_model_classes) == 0: - self.skipTest(reason="No generative architecture available for this model.") - - # - The model must support padding - if not self.has_attentions: - self.skipTest(reason="This model doesn't support padding.") - - # - The model must be a decoder-only architecture (encoder-based architectures use right-padding) - decoder_only_classes = [] - for model_class in self.all_generative_model_classes: - config, _ = self.prepare_config_and_inputs_for_generate() - if config.is_encoder_decoder: - continue - else: - decoder_only_classes.append(model_class) - if len(decoder_only_classes) == 0: - self.skipTest(reason="No decoder-only architecture available for this model.") - - # - Decoder-only architectures derived from encoder-decoder models could support it in theory, but we haven't - # added support for it yet. We skip these models for now. - has_encoder_attributes = any( - attr_name - for attr_name in config.to_dict() - if attr_name.startswith("encoder") and attr_name != "encoder_no_repeat_ngram_size" - ) - if has_encoder_attributes: - self.skipTest( - reason="The decoder-only derived from encoder-decoder models are not expected to support left-padding." - ) - - # Then, test left-padding - def _prepare_model_kwargs(input_ids, attention_mask, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[-1], device=torch_device) - model_kwargs["cache_position"] = cache_position - return model_kwargs - - for model_class in decoder_only_classes: - config, inputs_dict = self.prepare_config_and_inputs_for_generate() - input_ids = inputs_dict["input_ids"] - attention_mask = inputs_dict.get("attention_mask") - pixel_values = inputs_dict["pixel_values"] - qformer_input_ids = inputs_dict["qformer_input_ids"] - if attention_mask is None: - attention_mask = torch.ones_like(input_ids) - - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # no cache as some models require special cache classes to be init outside forward - model.generation_config.use_cache = False - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, signature) - next_logits_wo_padding = model( - **model_kwargs, pixel_values=pixel_values, qformer_input_ids=qformer_input_ids - ).logits[:, -1, :] - - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - model_kwargs = _prepare_model_kwargs(padded_input_ids, padded_attention_mask, signature) - next_logits_with_padding = model( - **model_kwargs, pixel_values=pixel_values, qformer_input_ids=qformer_input_ids - ).logits[:, -1, :] - - # They should result in very similar logits - torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=1e-5, atol=1e-5) - def test_sdpa_can_dispatch_composite_models(self): """ Tests if composite models dispatch correctly on SDPA/eager when requested so when loading the model. diff --git a/tests/models/instructblipvideo/test_modeling_instructblipvideo.py b/tests/models/instructblipvideo/test_modeling_instructblipvideo.py index a91d31082da9..d6336c8c6840 100644 --- a/tests/models/instructblipvideo/test_modeling_instructblipvideo.py +++ b/tests/models/instructblipvideo/test_modeling_instructblipvideo.py @@ -18,7 +18,6 @@ import unittest import numpy as np -import pytest from huggingface_hub import hf_hub_download from transformers import ( @@ -578,94 +577,6 @@ def _check_generate_outputs(self, output, config, use_cache=False, num_return_se output, config, use_cache=use_cache, num_return_sequences=num_return_sequences, num_beams=num_beams ) - # overwrite because InstructBLIPVideo cannot generate only from input ids, and requires `pixel` values and `qformer_input_ids` in all cases to be present - @pytest.mark.generate - def test_left_padding_compatibility(self): - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 - - # First, filter out models that don't support left padding - # - The model must have generative capabilities - if len(self.all_generative_model_classes) == 0: - self.skipTest(reason="No generative architecture available for this model.") - - # - The model must support padding - if not self.has_attentions: - self.skipTest(reason="This model doesn't support padding.") - - # - The model must be a decoder-only architecture (encoder-based architectures use right-padding) - decoder_only_classes = [] - for model_class in self.all_generative_model_classes: - config, _ = self.prepare_config_and_inputs_for_generate() - if config.is_encoder_decoder: - continue - else: - decoder_only_classes.append(model_class) - if len(decoder_only_classes) == 0: - self.skipTest(reason="No decoder-only architecture available for this model.") - - # - Decoder-only architectures derived from encoder-decoder models could support it in theory, but we haven't - # added support for it yet. We skip these models for now. - has_encoder_attributes = any( - attr_name - for attr_name in config.to_dict() - if attr_name.startswith("encoder") and attr_name != "encoder_no_repeat_ngram_size" - ) - if has_encoder_attributes: - self.skipTest( - reason="The decoder-only derived from encoder-decoder models are not expected to support left-padding." - ) - - # Then, test left-padding - def _prepare_model_kwargs(input_ids, attention_mask, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[-1], device=torch_device) - model_kwargs["cache_position"] = cache_position - return model_kwargs - - for model_class in decoder_only_classes: - config, inputs_dict = self.prepare_config_and_inputs_for_generate() - input_ids = inputs_dict["input_ids"] - attention_mask = inputs_dict.get("attention_mask") - pixel_values = inputs_dict["pixel_values"] - qformer_input_ids = inputs_dict["qformer_input_ids"] - if attention_mask is None: - attention_mask = torch.ones_like(input_ids) - - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # no cache as some models require special cache classes to be init outside forward - model.generation_config.use_cache = False - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, signature) - next_logits_wo_padding = model( - **model_kwargs, pixel_values=pixel_values, qformer_input_ids=qformer_input_ids - ).logits[:, -1, :] - - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - model_kwargs = _prepare_model_kwargs(padded_input_ids, padded_attention_mask, signature) - next_logits_with_padding = model( - **model_kwargs, pixel_values=pixel_values, qformer_input_ids=qformer_input_ids - ).logits[:, -1, :] - - # They should result in very similar logits - torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=1e-5, atol=1e-5) - def test_sdpa_can_dispatch_composite_models(self): """ Tests if composite models dispatch correctly on SDPA/eager when requested so when loading the model. diff --git a/tests/models/kosmos2/test_modeling_kosmos2.py b/tests/models/kosmos2/test_modeling_kosmos2.py index ac16e62c55f3..38a769229952 100644 --- a/tests/models/kosmos2/test_modeling_kosmos2.py +++ b/tests/models/kosmos2/test_modeling_kosmos2.py @@ -481,57 +481,24 @@ def test_sdpa_padding_matches_padding_free_with_position_ids(self): @pytest.mark.generate def test_left_padding_compatibility(self): - # Overwrite because Kosmos-2 need to pad pixel values and pad image-attn-mask - - def _prepare_model_kwargs(input_ids, attention_mask, pad_size, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[-1], device=torch_device) - model_kwargs["cache_position"] = cache_position - if "image_embeds_position_mask" in signature: - image_embeds_position_mask = torch.zeros_like(input_ids) - image_embeds_position_mask[:, (pad_size + 1) : pad_size + 1 + self.model_tester.latent_query_num] = 1 - model_kwargs["image_embeds_position_mask"] = image_embeds_position_mask - return model_kwargs + # Overwrite -- kosmos2 needs to prepare `image_embeds_position_mask`, and it must be padded accordingly + _, inputs_dict = self.prepare_config_and_inputs_for_generate() + input_ids = inputs_dict["input_ids"] - for model_class in self.all_generative_model_classes: - config, inputs_dict = self.prepare_config_and_inputs_for_generate() - input_ids = inputs_dict["input_ids"] - pixel_values = inputs_dict["pixel_values"] - attention_mask = inputs_dict.get("attention_mask") - if attention_mask is None: - attention_mask = torch.ones_like(input_ids) - - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # no cache as some models require special cache classes to be init outside forward - model.generation_config.use_cache = False - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, pad_size=0, signature=signature) - next_logits_wo_padding = model(**model_kwargs, pixel_values=pixel_values).logits[:, -1, :] - - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - model_kwargs = _prepare_model_kwargs( - padded_input_ids, padded_attention_mask, pad_size=32, signature=signature + def _prepare_image_embeds_position_mask(input_ids, pad_size): + image_embeds_position_mask = torch.zeros( + input_ids.shape[0], input_ids.shape[1] + pad_size, device=torch_device, dtype=input_ids.dtype ) - next_logits_with_padding = model(**model_kwargs, pixel_values=pixel_values).logits[:, -1, :] - - # They should result in very similar logits - torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=1e-3, atol=1e-3) + image_embeds_position_mask[:, (pad_size + 1) : pad_size + 1 + self.model_tester.latent_query_num] = 1 + return image_embeds_position_mask + + # `image_embeds_position_mask` is randomly generated in `prepare_config_and_inputs_for_generate`, and it must + # match its padded version for the test to be valid -- we need to pass both + unpadded_custom_inputs = {"image_embeds_position_mask": _prepare_image_embeds_position_mask(input_ids, 0)} + padded_custom_inputs = {"image_embeds_position_mask": _prepare_image_embeds_position_mask(input_ids, 32)} + super().test_left_padding_compatibility( + unpadded_custom_inputs=unpadded_custom_inputs, padded_custom_inputs=padded_custom_inputs + ) @slow def test_model_from_pretrained(self): diff --git a/tests/models/kosmos2_5/test_modeling_kosmos2_5.py b/tests/models/kosmos2_5/test_modeling_kosmos2_5.py index c2a18cb5b690..b3155915b03d 100644 --- a/tests/models/kosmos2_5/test_modeling_kosmos2_5.py +++ b/tests/models/kosmos2_5/test_modeling_kosmos2_5.py @@ -570,57 +570,24 @@ def test_generate_from_inputs_embeds(self): @pytest.mark.generate def test_left_padding_compatibility(self): - # Overwrite because Kosmos-2.5 need to pad pixel values and pad image-attn-mask - - def _prepare_model_kwargs(input_ids, attention_mask, pad_size, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[-1], device=torch_device) - model_kwargs["cache_position"] = cache_position - if "image_embeds_position_mask" in signature: - image_embeds_position_mask = torch.zeros_like(input_ids) - image_embeds_position_mask[:, (pad_size + 1) : pad_size + 1 + self.model_tester.latent_query_num] = 1 - model_kwargs["image_embeds_position_mask"] = image_embeds_position_mask - return model_kwargs - - for model_class in self.all_generative_model_classes: - config, inputs_dict = self.prepare_config_and_inputs_for_generate() - input_ids = inputs_dict["input_ids"] - flattened_patches = inputs_dict["flattened_patches"] - attention_mask = inputs_dict.get("attention_mask") - if attention_mask is None: - attention_mask = torch.ones_like(input_ids) - - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # no cache as some models require special cache classes to be init outside forward - model.generation_config.use_cache = False - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, pad_size=0, signature=signature) - next_logits_wo_padding = model(**model_kwargs, flattened_patches=flattened_patches).logits[:, -1, :] - - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - model_kwargs = _prepare_model_kwargs( - padded_input_ids, padded_attention_mask, pad_size=32, signature=signature - ) - next_logits_with_padding = model(**model_kwargs, flattened_patches=flattened_patches).logits[:, -1, :] + # Overwrite -- Kosmos-2.5 needs to prepare `image_embeds_position_mask`, and it must be padded accordingly + _, inputs_dict = self.prepare_config_and_inputs_for_generate() + input_ids = inputs_dict["input_ids"] - # They should result in very similar logits - self.assertTrue(torch.allclose(next_logits_wo_padding, next_logits_with_padding, atol=1e-3)) + def _prepare_image_embeds_position_mask(input_ids, pad_size): + image_embeds_position_mask = torch.zeros( + input_ids.shape[0], input_ids.shape[1] + pad_size, device=torch_device, dtype=input_ids.dtype + ) + image_embeds_position_mask[:, (pad_size + 1) : pad_size + 1 + self.model_tester.latent_query_num] = 1 + return image_embeds_position_mask + + # `image_embeds_position_mask` is randomly generated in `prepare_config_and_inputs_for_generate`, and it must + # match its padded version for the test to be valid -- we need to pass both + unpadded_custom_inputs = {"image_embeds_position_mask": _prepare_image_embeds_position_mask(input_ids, 0)} + padded_custom_inputs = {"image_embeds_position_mask": _prepare_image_embeds_position_mask(input_ids, 32)} + super().test_left_padding_compatibility( + unpadded_custom_inputs=unpadded_custom_inputs, padded_custom_inputs=padded_custom_inputs + ) @require_vision diff --git a/tests/models/kyutai_speech_to_text/test_modeling_kyutai_speech_to_text.py b/tests/models/kyutai_speech_to_text/test_modeling_kyutai_speech_to_text.py index 8325c0f699ed..c7ab9f9dc6dd 100644 --- a/tests/models/kyutai_speech_to_text/test_modeling_kyutai_speech_to_text.py +++ b/tests/models/kyutai_speech_to_text/test_modeling_kyutai_speech_to_text.py @@ -14,7 +14,6 @@ """Testing suite for the PyTorch Moshi ASR model.""" import gc -import inspect import tempfile import unittest @@ -361,86 +360,11 @@ def test_disk_offload_safetensors(self): @pytest.mark.generate def test_left_padding_compatibility(self): - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 - - # First, filter out models that don't support left padding - # - The model must have generative capabilities - if len(self.all_generative_model_classes) == 0: - self.skipTest(reason="No generative architecture available for this model.") - - # - The model must support padding - if not self.has_attentions: - self.skipTest(reason="This model doesn't support padding.") - - # - The model must be a decoder-only architecture (encoder-based architectures use right-padding) - decoder_only_classes = [] - for model_class in self.all_generative_model_classes: - config, _ = self.prepare_config_and_inputs_for_generate() - if config.is_encoder_decoder: - continue - else: - decoder_only_classes.append(model_class) - if len(decoder_only_classes) == 0: - self.skipTest(reason="No decoder-only architecture available for this model.") - - # - Decoder-only architectures derived from encoder-decoder models could support it in theory, but we haven't - # added support for it yet. We skip these models for now. - has_encoder_attributes = any( - attr_name - for attr_name in config.to_dict() - if attr_name.startswith("encoder") and attr_name != "encoder_no_repeat_ngram_size" - ) - if has_encoder_attributes: - self.skipTest( - reason="The decoder-only derived from encoder-decoder models are not expected to support left-padding." - ) - - # Then, test left-padding - def _prepare_model_kwargs(input_ids, attention_mask, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[1], device=torch_device) - model_kwargs["cache_position"] = cache_position - return model_kwargs - - for model_class in decoder_only_classes: - config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() - input_ids = inputs_dict["input_ids"] - attention_mask = inputs_dict.get("attention_mask") - if attention_mask is None: - attention_mask = torch.ones_like(input_ids) - - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # no cache as some models require special cache classes to be init outside forward - model.generation_config.use_cache = False - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, signature) - next_logits_wo_padding = model(**model_kwargs).logits[:, -1, :] - - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) - pad_size = (input_ids.shape[0], 32, *input_ids.shape[2:]) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat( - (torch.zeros(pad_size[:2], dtype=input_ids.dtype, device=torch_device), attention_mask), dim=1 - ) - model_kwargs = _prepare_model_kwargs(padded_input_ids, padded_attention_mask, signature) - next_logits_with_padding = model(**model_kwargs).logits[:, -1, :] - - # They should result in very similar logits - torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=1e-5, atol=1e-5) + # TODO: this tester has non-standard input monkey-patching in `prepare_config_and_inputs_for_generate`, + # and the test fails with the monkey-patched test inputs (bad shapes for the test) ☠️ The base inputs work + # fine, though. + unpadded_custom_inputs = self.model_tester.prepare_config_and_inputs_for_common()[1] + super().test_left_padding_compatibility(unpadded_custom_inputs=unpadded_custom_inputs) def test_generate_continue_from_past_key_values(self): # Tests that we can continue generating from past key values, returned from a previous `generate` call diff --git a/tests/models/mllama/test_modeling_mllama.py b/tests/models/mllama/test_modeling_mllama.py index 0d151602ffce..2330684d0d71 100644 --- a/tests/models/mllama/test_modeling_mllama.py +++ b/tests/models/mllama/test_modeling_mllama.py @@ -505,6 +505,25 @@ def test_generate_text_only_with_cache(self): model.generate(input_ids, use_cache=True) + @pytest.mark.generate + def test_left_padding_compatibility(self): + # Overwrite -- mllama needs to prepare `cross_attention_mask`, and it must be padded accordingly + _, inputs_dict = self.prepare_config_and_inputs_for_generate() + input_ids = inputs_dict["input_ids"] + cross_attention_mask = inputs_dict["cross_attention_mask"] + + pad_cross_attn_size = (input_ids.shape[0], 32, *cross_attention_mask.shape[2:]) + extra_cross_attn_mask = torch.zeros(pad_cross_attn_size, dtype=cross_attention_mask.dtype, device=torch_device) + padded_cross_attention_mask = torch.cat([extra_cross_attn_mask, cross_attention_mask], dim=1) + + # `cross_attention_mask` is randomly generated in `prepare_config_and_inputs_for_generate`, and it must match + # its padded version for the test to be valid -- we need to pass both + unpadded_custom_inputs = {"cross_attention_mask": cross_attention_mask} + padded_custom_inputs = {"cross_attention_mask": padded_cross_attention_mask} + super().test_left_padding_compatibility( + unpadded_custom_inputs=unpadded_custom_inputs, padded_custom_inputs=padded_custom_inputs + ) + @require_torch class MllamaForConditionalGenerationIntegrationTest(unittest.TestCase): diff --git a/tests/models/moshi/test_modeling_moshi.py b/tests/models/moshi/test_modeling_moshi.py index 21f56e1bc56d..d4815a140d69 100644 --- a/tests/models/moshi/test_modeling_moshi.py +++ b/tests/models/moshi/test_modeling_moshi.py @@ -629,54 +629,30 @@ def test_sdpa_can_compile_dynamic(self): @pytest.mark.generate def test_left_padding_compatibility(self): - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 - - # Then, test left-padding - - for model_class in self.all_generative_model_classes: - config, input_ids, attention_mask, input_dict = self._get_input_ids_and_config() - model = model_class(config).to(torch_device).eval() - - # no cache as some models require special cache classes to be init outside forward - model.generation_config.use_cache = False - - # Without padding - next_logits_wo_padding = model(input_ids=input_ids, attention_mask=attention_mask, **input_dict).logits[ - :, -1, : - ] - - # With left-padding (length 32) - # can hardcode pad_token to be 0 as we'll do attn masking anyway - pad_token_id = ( - config.get_text_config().pad_token_id if config.get_text_config().pad_token_id is not None else 0 - ) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - - padding = ( - torch.ones( - (pad_size[0], self.model_tester.num_codebooks, 32), dtype=input_ids.dtype, device=torch_device - ) - * config.audio_vocab_size - ) - padded_moshi_audio_codes = torch.cat((padding, input_dict["moshi_audio_codes"]), dim=2) - padded_user_audio_codes = torch.cat((padding, input_dict["user_audio_codes"]), dim=2) - - model_kwargs = { - "input_ids": padded_input_ids, - "attention_mask": padded_attention_mask, - "moshi_audio_codes": padded_moshi_audio_codes, - "user_audio_codes": padded_user_audio_codes, - } - - next_logits_with_padding = model(**model_kwargs).logits[:, -1, :] - - # They should result in very similar logits - torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=1e-5, atol=1e-5) + # Overwrite -- Moshi needs to prepare the audio codes, and they must be padded accordingly + config, inputs_dict = self.prepare_config_and_inputs_for_generate() + input_ids = inputs_dict["input_ids"] + moshi_audio_codes = inputs_dict["moshi_audio_codes"] + user_audio_codes = inputs_dict["user_audio_codes"] + + pad_size = (input_ids.shape[0], 32) + padding = ( + torch.ones((pad_size[0], self.model_tester.num_codebooks, 32), dtype=input_ids.dtype, device=torch_device) + * config.audio_vocab_size + ) + padded_moshi_audio_codes = torch.cat((padding, moshi_audio_codes), dim=2) + padded_user_audio_codes = torch.cat((padding, user_audio_codes), dim=2) + + # the audio codes are randomly generated in `prepare_config_and_inputs_for_generate`, and they must match + # their padded version for the test to be valid -- we need to pass both + unpadded_custom_inputs = {"moshi_audio_codes": moshi_audio_codes, "user_audio_codes": user_audio_codes} + padded_custom_inputs = { + "moshi_audio_codes": padded_moshi_audio_codes, + "user_audio_codes": padded_user_audio_codes, + } + super().test_left_padding_compatibility( + unpadded_custom_inputs=unpadded_custom_inputs, padded_custom_inputs=padded_custom_inputs + ) @slow @is_flaky(max_attempts=5, description="flaky on some models.") diff --git a/tests/models/qwen2_audio/test_modeling_qwen2_audio.py b/tests/models/qwen2_audio/test_modeling_qwen2_audio.py index b1f809892c8f..538353fee44d 100644 --- a/tests/models/qwen2_audio/test_modeling_qwen2_audio.py +++ b/tests/models/qwen2_audio/test_modeling_qwen2_audio.py @@ -63,6 +63,7 @@ def __init__( "use_labels": True, "use_mrope": False, "vocab_size": 99, + "pad_token_id": 1, # can't be the same as the audio token id }, is_training=True, audio_config={ diff --git a/tests/models/voxtral/test_modeling_voxtral.py b/tests/models/voxtral/test_modeling_voxtral.py index 123bec730f4e..d6662ebd5532 100644 --- a/tests/models/voxtral/test_modeling_voxtral.py +++ b/tests/models/voxtral/test_modeling_voxtral.py @@ -59,7 +59,7 @@ def __init__( "use_mrope": False, "vocab_size": 99, "head_dim": 8, - "pad_token_id": 0, + "pad_token_id": 1, # can't be the same as the audio token id }, is_training=True, audio_config={ diff --git a/tests/models/zamba/test_modeling_zamba.py b/tests/models/zamba/test_modeling_zamba.py index b601b280558b..070e84733092 100644 --- a/tests/models/zamba/test_modeling_zamba.py +++ b/tests/models/zamba/test_modeling_zamba.py @@ -480,51 +480,6 @@ def _get_input_ids_and_config(self): ) = config_and_inputs return config, input_ids, input_mask - def test_left_padding_compatibility(self): - r""" - Overriding the test_left_padding_compatibility test as the mamba layers accentuate the numerical differences - effect of the left padding discussed in the issue in the note. Using a more permissive tolerance value. - """ - import inspect - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 - - # First, filter out models that don't support left padding - generative and decoder-only. - # Zamba is a decoder-only architecture - decoder_only_classes = self.all_generative_model_classes - - # Then, test left-padding - def _prepare_model_kwargs(input_ids, attention_mask, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[-1], device=torch_device) - model_kwargs["cache_position"] = cache_position - return model_kwargs - - for model_class in decoder_only_classes: - config, input_ids, attention_mask = self._get_input_ids_and_config() - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, signature) - next_logits_wo_padding = model(**model_kwargs).logits[:, -1, :] - - # With left-padding (length 32) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * config.pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - model_kwargs = _prepare_model_kwargs(padded_input_ids, padded_attention_mask, signature) - next_logits_with_padding = model(**model_kwargs).logits[:, -1, :] - - # They should result in very similar logits - torch.testing.assert_close(next_logits_wo_padding, next_logits_with_padding, rtol=3e-3, atol=3e-3) - @require_flash_attn @require_torch_gpu @require_bitsandbytes diff --git a/tests/models/zamba2/test_modeling_zamba2.py b/tests/models/zamba2/test_modeling_zamba2.py index c6921297d6e7..99c6f5fc53d9 100644 --- a/tests/models/zamba2/test_modeling_zamba2.py +++ b/tests/models/zamba2/test_modeling_zamba2.py @@ -499,51 +499,6 @@ def _get_input_ids_and_config(self): ) = config_and_inputs return config, input_ids, input_mask - def test_left_padding_compatibility(self): - r""" - Overriding the test_left_padding_compatibility test as the mamba layers accentuate the numerical differences - effect of the left padding discussed in the issue in the note. Using a more permissive tolerance value. - """ - import inspect - # NOTE: left-padding results in small numerical differences. This is expected. - # See https://github.com/huggingface/transformers/issues/25420#issuecomment-1775317535 - - # First, filter out models that don't support left padding - generative and decoder-only. - # Zamba2 is a decoder-only architecture - decoder_only_classes = self.all_generative_model_classes - - # Then, test left-padding - def _prepare_model_kwargs(input_ids, attention_mask, signature): - model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} - if "position_ids" in signature: - position_ids = torch.cumsum(attention_mask, dim=-1) - 1 - position_ids.masked_fill_(attention_mask == 0, 1) - model_kwargs["position_ids"] = position_ids - if "cache_position" in signature: - cache_position = torch.arange(input_ids.shape[-1], device=torch_device) - model_kwargs["cache_position"] = cache_position - return model_kwargs - - for model_class in decoder_only_classes: - config, input_ids, attention_mask = self._get_input_ids_and_config() - model = model_class(config).to(torch_device).eval() - signature = inspect.signature(model.forward).parameters.keys() - - # Without padding - model_kwargs = _prepare_model_kwargs(input_ids, attention_mask, signature) - next_logits_wo_padding = model(**model_kwargs).logits[:, -1, :] - - # With left-padding (length 32) - pad_size = (input_ids.shape[0], 32) - padding = torch.ones(pad_size, dtype=input_ids.dtype, device=torch_device) * config.pad_token_id - padded_input_ids = torch.cat((padding, input_ids), dim=1) - padded_attention_mask = torch.cat((torch.zeros_like(padding), attention_mask), dim=1) - model_kwargs = _prepare_model_kwargs(padded_input_ids, padded_attention_mask, signature) - next_logits_with_padding = model(**model_kwargs).logits[:, -1, :] - - # They should result in very similar logits - self.assertTrue(torch.allclose(next_logits_wo_padding, next_logits_with_padding, atol=3e-3)) - @require_flash_attn @require_torch_gpu @require_bitsandbytes From 387fb9a8fedcbb594eb504040aa8bd5be69f96b6 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Fri, 19 Sep 2025 16:38:12 +0200 Subject: [PATCH 127/204] Patch more `unittest.case.TestCase.assertXXX` methods (#41008) fix Co-authored-by: ydshieh --- src/transformers/testing_utils.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/transformers/testing_utils.py b/src/transformers/testing_utils.py index b66d92f69026..32732560bb37 100644 --- a/src/transformers/testing_utils.py +++ b/src/transformers/testing_utils.py @@ -3732,6 +3732,18 @@ def patch_testing_methods_to_collect_info(): _patch_with_call_info(torch.testing, "assert_close", _parse_call_info, target_args=("actual", "expected")) _patch_with_call_info(unittest.case.TestCase, "assertEqual", _parse_call_info, target_args=("first", "second")) + _patch_with_call_info(unittest.case.TestCase, "assertListEqual", _parse_call_info, target_args=("list1", "list2")) + _patch_with_call_info( + unittest.case.TestCase, "assertTupleEqual", _parse_call_info, target_args=("tuple1", "tuple2") + ) + _patch_with_call_info(unittest.case.TestCase, "assertSetEqual", _parse_call_info, target_args=("set1", "set1")) + _patch_with_call_info(unittest.case.TestCase, "assertDictEqual", _parse_call_info, target_args=("d1", "d2")) + _patch_with_call_info(unittest.case.TestCase, "assertIn", _parse_call_info, target_args=("member", "container")) + _patch_with_call_info(unittest.case.TestCase, "assertNotIn", _parse_call_info, target_args=("member", "container")) + _patch_with_call_info(unittest.case.TestCase, "assertLess", _parse_call_info, target_args=("a", "b")) + _patch_with_call_info(unittest.case.TestCase, "assertLessEqual", _parse_call_info, target_args=("a", "b")) + _patch_with_call_info(unittest.case.TestCase, "assertGreater", _parse_call_info, target_args=("a", "b")) + _patch_with_call_info(unittest.case.TestCase, "assertGreaterEqual", _parse_call_info, target_args=("a", "b")) def torchrun(script: str, nproc_per_node: int, is_torchrun: bool = True, env: Optional[dict] = None): From e1c13bc9bb5afcde02a6481ad2b465662f56a052 Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Fri, 19 Sep 2025 15:40:27 +0100 Subject: [PATCH 128/204] =?UTF-8?q?=F0=9F=9A=A8=20[v5]=20remove=20deprecat?= =?UTF-8?q?ed=20entry=20point=20(#40997)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove old entry point * update references to transformers-cli --- docs/source/en/llm_tutorial.md | 2 +- docs/source/en/model_doc/bamba.md | 2 +- docs/source/en/model_doc/bart.md | 2 +- docs/source/en/model_doc/bertweet.md | 2 +- docs/source/en/model_doc/big_bird.md | 2 +- docs/source/en/model_doc/bigbird_pegasus.md | 4 +- docs/source/en/model_doc/biogpt.md | 12 ++-- docs/source/en/model_doc/byt5.md | 4 +- docs/source/en/model_doc/canine.md | 8 +-- docs/source/en/model_doc/cohere2.md | 20 +++--- docs/source/en/model_doc/deberta-v2.md | 2 +- docs/source/en/model_doc/encoder-decoder.md | 2 +- docs/source/en/model_doc/flex_olmo.md | 8 +-- docs/source/en/model_doc/gpt_neo.md | 2 +- docs/source/en/model_doc/granite.md | 8 +-- docs/source/en/model_doc/led.md | 4 +- docs/source/en/model_doc/mamba2.md | 18 +++--- docs/source/en/model_doc/olmo2.md | 8 +-- docs/source/en/model_doc/olmo3.md | 2 +- docs/source/en/model_doc/pegasus.md | 2 +- docs/source/en/model_doc/pegasus_x.md | 4 +- docs/source/en/model_doc/roberta.md | 2 +- docs/source/en/model_doc/roc_bert.md | 4 +- docs/source/en/model_doc/roformer.md | 2 +- docs/source/en/model_doc/xlm-roberta-xl.md | 64 +++++++++---------- docs/source/en/model_doc/xlm-roberta.md | 2 +- docs/source/en/model_doc/xlm.md | 2 +- docs/source/zh/model_doc/bert.md | 6 +- setup.py | 1 - src/transformers/commands/transformers_cli.py | 9 --- 30 files changed, 99 insertions(+), 111 deletions(-) diff --git a/docs/source/en/llm_tutorial.md b/docs/source/en/llm_tutorial.md index a08f57426b6a..0f4f91d30a67 100644 --- a/docs/source/en/llm_tutorial.md +++ b/docs/source/en/llm_tutorial.md @@ -23,7 +23,7 @@ Text generation is the most popular application for large language models (LLMs) In Transformers, the [`~GenerationMixin.generate`] API handles text generation, and it is available for all models with generative capabilities. This guide will show you the basics of text generation with [`~GenerationMixin.generate`] and some common pitfalls to avoid. > [!TIP] -> You can also chat with a model directly from the command line. ([reference](./conversations.md#transformers-cli)) +> You can also chat with a model directly from the command line. ([reference](./conversations.md#transformers)) > ```shell > transformers chat Qwen/Qwen2.5-0.5B-Instruct > ``` diff --git a/docs/source/en/model_doc/bamba.md b/docs/source/en/model_doc/bamba.md index 54aceb11f699..893162083dd8 100644 --- a/docs/source/en/model_doc/bamba.md +++ b/docs/source/en/model_doc/bamba.md @@ -72,7 +72,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ```bash -echo "Plants create energy through a process known as" | transformers-cli run --task text-generation --model ibm-ai-platform/Bamba-9B-v2 --device 0 +echo "Plants create energy through a process known as" | transformers run --task text-generation --model ibm-ai-platform/Bamba-9B-v2 --device 0 ``` diff --git a/docs/source/en/model_doc/bart.md b/docs/source/en/model_doc/bart.md index b0252ea92311..d1eeafb82b23 100644 --- a/docs/source/en/model_doc/bart.md +++ b/docs/source/en/model_doc/bart.md @@ -79,7 +79,7 @@ print(f"The predicted token is: {predicted_token}") ```bash -echo -e "Plants create through a process known as photosynthesis." | transformers-cli run --task fill-mask --model facebook/bart-large --device 0 +echo -e "Plants create through a process known as photosynthesis." | transformers run --task fill-mask --model facebook/bart-large --device 0 ``` diff --git a/docs/source/en/model_doc/bertweet.md b/docs/source/en/model_doc/bertweet.md index 4dffe29168d3..6488e197d212 100644 --- a/docs/source/en/model_doc/bertweet.md +++ b/docs/source/en/model_doc/bertweet.md @@ -81,7 +81,7 @@ print(f"The predicted token is: {predicted_token}") ```bash -echo -e "Plants create through a process known as photosynthesis." | transformers-cli run --task fill-mask --model vinai/bertweet-base --device 0 +echo -e "Plants create through a process known as photosynthesis." | transformers run --task fill-mask --model vinai/bertweet-base --device 0 ``` diff --git a/docs/source/en/model_doc/big_bird.md b/docs/source/en/model_doc/big_bird.md index 2d3b6d545faf..5e431c6883d0 100644 --- a/docs/source/en/model_doc/big_bird.md +++ b/docs/source/en/model_doc/big_bird.md @@ -79,7 +79,7 @@ print(f"The predicted token is: {predicted_token}") ```bash -!echo -e "Plants create [MASK] through a process known as photosynthesis." | transformers-cli run --task fill-mask --model google/bigbird-roberta-base --device 0 +!echo -e "Plants create [MASK] through a process known as photosynthesis." | transformers run --task fill-mask --model google/bigbird-roberta-base --device 0 ``` diff --git a/docs/source/en/model_doc/bigbird_pegasus.md b/docs/source/en/model_doc/bigbird_pegasus.md index cae1e8f779d4..fe3241ed7ab6 100644 --- a/docs/source/en/model_doc/bigbird_pegasus.md +++ b/docs/source/en/model_doc/bigbird_pegasus.md @@ -78,10 +78,10 @@ output = model.generate(**input_ids, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` - + ```bash -echo -e "Plants are among the most remarkable and essential life forms on Earth, possessing a unique ability to produce their own food through a process known as photosynthesis. This complex biochemical process is fundamental not only to plant life but to virtually all life on the planet. Through photosynthesis, plants capture energy from sunlight using a green pigment called chlorophyll, which is located in specialized cell structures called chloroplasts." | transformers-cli run --task summarization --model google/bigbird-pegasus-large-arxiv --device 0 +echo -e "Plants are among the most remarkable and essential life forms on Earth, possessing a unique ability to produce their own food through a process known as photosynthesis. This complex biochemical process is fundamental not only to plant life but to virtually all life on the planet. Through photosynthesis, plants capture energy from sunlight using a green pigment called chlorophyll, which is located in specialized cell structures called chloroplasts." | transformers run --task summarization --model google/bigbird-pegasus-large-arxiv --device 0 ``` diff --git a/docs/source/en/model_doc/biogpt.md b/docs/source/en/model_doc/biogpt.md index 60b84f015122..4676a440c751 100644 --- a/docs/source/en/model_doc/biogpt.md +++ b/docs/source/en/model_doc/biogpt.md @@ -71,7 +71,7 @@ inputs = tokenizer(input_text, return_tensors="pt").to(model.device) with torch.no_grad(): generated_ids = model.generate(**inputs, max_length=50) - + output = tokenizer.decode(generated_ids[0], skip_special_tokens=True) print(output) ``` @@ -80,7 +80,7 @@ print(output) ```bash -echo -e "Ibuprofen is best used for" | transformers-cli run --task text-generation --model microsoft/biogpt --device 0 +echo -e "Ibuprofen is best used for" | transformers run --task text-generation --model microsoft/biogpt --device 0 ``` @@ -103,7 +103,7 @@ bnb_config = BitsAndBytesConfig( tokenizer = AutoTokenizer.from_pretrained("microsoft/BioGPT-Large") model = AutoModelForCausalLM.from_pretrained( - "microsoft/BioGPT-Large", + "microsoft/BioGPT-Large", quantization_config=bnb_config, dtype=torch.bfloat16, device_map="auto" @@ -112,7 +112,7 @@ model = AutoModelForCausalLM.from_pretrained( input_text = "Ibuprofen is best used for" inputs = tokenizer(input_text, return_tensors="pt").to(model.device) with torch.no_grad(): - generated_ids = model.generate(**inputs, max_length=50) + generated_ids = model.generate(**inputs, max_length=50) output = tokenizer.decode(generated_ids[0], skip_special_tokens=True) print(output) ``` @@ -125,7 +125,7 @@ print(output) ```py from transformers import AutoModelForCausalLM - + model = AutoModelForCausalLM.from_pretrained( "microsoft/biogpt", attn_implementation="eager" @@ -163,4 +163,4 @@ print(output) ## BioGptForSequenceClassification [[autodoc]] BioGptForSequenceClassification - - forward \ No newline at end of file + - forward diff --git a/docs/source/en/model_doc/byt5.md b/docs/source/en/model_doc/byt5.md index ffe2a76567f4..1c9239e4892a 100644 --- a/docs/source/en/model_doc/byt5.md +++ b/docs/source/en/model_doc/byt5.md @@ -70,10 +70,10 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` - + ```bash -echo -e "translate English to French: Life is beautiful." | transformers-cli run --task text2text-generation --model google/byt5-small --device 0 +echo -e "translate English to French: Life is beautiful." | transformers run --task text2text-generation --model google/byt5-small --device 0 ``` diff --git a/docs/source/en/model_doc/canine.md b/docs/source/en/model_doc/canine.md index e1d8bb7f7f68..4e46e943c8e9 100644 --- a/docs/source/en/model_doc/canine.md +++ b/docs/source/en/model_doc/canine.md @@ -42,7 +42,7 @@ from transformers import pipeline pipeline = pipeline( task="feature-extraction", model="google/canine-c", - device=0, + device=0, ) pipeline("Plant create energy through a process known as photosynthesis.") @@ -60,7 +60,7 @@ model = AutoModel.from_pretrained("google/canine-c") text = "Plant create energy through a process known as photosynthesis." input_ids = torch.tensor([[ord(char) for char in text]]) -outputs = model(input_ids) +outputs = model(input_ids) pooled_output = outputs.pooler_output sequence_output = outputs.last_hidden_state ``` @@ -69,7 +69,7 @@ sequence_output = outputs.last_hidden_state ```bash -echo -e "Plant create energy through a process known as photosynthesis." | transformers-cli run --task feature-extraction --model google/canine-c --device 0 +echo -e "Plant create energy through a process known as photosynthesis." | transformers run --task feature-extraction --model google/canine-c --device 0 ``` @@ -81,7 +81,7 @@ echo -e "Plant create energy through a process known as photosynthesis." | trans ```py from transformers import AutoTokenizer, AutoModel - + tokenizer = AutoTokenizer("google/canine-c") inputs = ["Life is like a box of chocolates.", "You never know what you gonna get."] encoding = tokenizer(inputs, padding="longest", truncation=True, return_tensors="pt") diff --git a/docs/source/en/model_doc/cohere2.md b/docs/source/en/model_doc/cohere2.md index bcfa05e98d19..b1edcf8c8517 100644 --- a/docs/source/en/model_doc/cohere2.md +++ b/docs/source/en/model_doc/cohere2.md @@ -45,7 +45,7 @@ import torch from transformers import pipeline pipeline = pipeline( - task="text-generation", + task="text-generation", model="CohereLabs/c4ai-command-r7b-12-2024", dtype=torch.float16, device_map=0 @@ -66,9 +66,9 @@ from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("CohereLabs/c4ai-command-r7b-12-2024") model = AutoModelForCausalLM.from_pretrained( - "CohereLabs/c4ai-command-r7b-12-2024", - dtype=torch.float16, - device_map="auto", + "CohereLabs/c4ai-command-r7b-12-2024", + dtype=torch.float16, + device_map="auto", attn_implementation="sdpa" ) @@ -90,7 +90,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ```bash # pip install -U flash-attn --no-build-isolation -transformers-cli chat CohereLabs/c4ai-command-r7b-12-2024 --dtype auto --attn_implementation flash_attention_2 +transformers chat CohereLabs/c4ai-command-r7b-12-2024 --dtype auto --attn_implementation flash_attention_2 ``` @@ -107,10 +107,10 @@ from transformers import BitsAndBytesConfig, AutoTokenizer, AutoModelForCausalLM bnb_config = BitsAndBytesConfig(load_in_4bit=True) tokenizer = AutoTokenizer.from_pretrained("CohereLabs/c4ai-command-r7b-12-2024") model = AutoModelForCausalLM.from_pretrained( - "CohereLabs/c4ai-command-r7b-12-2024", - dtype=torch.float16, - device_map="auto", - quantization_config=bnb_config, + "CohereLabs/c4ai-command-r7b-12-2024", + dtype=torch.float16, + device_map="auto", + quantization_config=bnb_config, attn_implementation="sdpa" ) @@ -141,5 +141,3 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) [[autodoc]] Cohere2ForCausalLM - forward - - diff --git a/docs/source/en/model_doc/deberta-v2.md b/docs/source/en/model_doc/deberta-v2.md index 7fc8bcdc5226..7c92cd6cb9d3 100644 --- a/docs/source/en/model_doc/deberta-v2.md +++ b/docs/source/en/model_doc/deberta-v2.md @@ -84,7 +84,7 @@ print(f"Predicted label: {predicted_label}") ```bash -echo -e "DeBERTa-v2 is great at understanding context!" | transformers-cli run --task fill-mask --model microsoft/deberta-v2-xlarge-mnli --device 0 +echo -e "DeBERTa-v2 is great at understanding context!" | transformers run --task fill-mask --model microsoft/deberta-v2-xlarge-mnli --device 0 ``` diff --git a/docs/source/en/model_doc/encoder-decoder.md b/docs/source/en/model_doc/encoder-decoder.md index 33346a153524..58361f55eb17 100644 --- a/docs/source/en/model_doc/encoder-decoder.md +++ b/docs/source/en/model_doc/encoder-decoder.md @@ -71,7 +71,7 @@ print(tokenizer.decode(summary[0], skip_special_tokens=True)) ```bash -echo -e "Plants create energy through a process known as photosynthesis. This involves capturing sunlight and converting carbon dioxide and water into glucose and oxygen." | transformers-cli run --task summarization --model "patrickvonplaten/bert2bert-cnn_dailymail-fp16" --device 0 +echo -e "Plants create energy through a process known as photosynthesis. This involves capturing sunlight and converting carbon dioxide and water into glucose and oxygen." | transformers run --task summarization --model "patrickvonplaten/bert2bert-cnn_dailymail-fp16" --device 0 ``` diff --git a/docs/source/en/model_doc/flex_olmo.md b/docs/source/en/model_doc/flex_olmo.md index 418a660b6d23..49ad1b255270 100644 --- a/docs/source/en/model_doc/flex_olmo.md +++ b/docs/source/en/model_doc/flex_olmo.md @@ -27,7 +27,7 @@ limitations under the License. # FlexOlmo -[FlexOlmo](https://huggingface.co/papers/2507.07024) is a new class of language models (LMs) that supports (1) distributed training without data sharing, where different model parameters are independently trained on closed datasets, and (2) data-flexible inference, where these parameters along with their associated data can be flexibly included or excluded from model inferences with no further training. FlexOlmo employs a mixture-of-experts (MoE) architecture where each expert is trained independently on closed datasets and later integrated through a new domain-informed routing without any joint training. FlexOlmo is trained on FlexMix, a corpus we curate comprising publicly available datasets alongside seven domain-specific sets, representing realistic approximations of closed sets. +[FlexOlmo](https://huggingface.co/papers/2507.07024) is a new class of language models (LMs) that supports (1) distributed training without data sharing, where different model parameters are independently trained on closed datasets, and (2) data-flexible inference, where these parameters along with their associated data can be flexibly included or excluded from model inferences with no further training. FlexOlmo employs a mixture-of-experts (MoE) architecture where each expert is trained independently on closed datasets and later integrated through a new domain-informed routing without any joint training. FlexOlmo is trained on FlexMix, a corpus we curate comprising publicly available datasets alongside seven domain-specific sets, representing realistic approximations of closed sets. You can find all the original FlexOlmo checkpoints under the [FlexOlmo](https://huggingface.co/collections/allenai/flexolmo-68471177a386b6e20a54c55f) collection. @@ -49,7 +49,7 @@ pipe = pipeline( dtype=torch.bfloat16, device=0, ) - + result = pipe("Plants create energy through a process known as") print(result) ``` @@ -81,7 +81,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ```bash -echo -e "Plants create energy through a process known as" | transformers-cli run --task text-generation --model allenai/FlexOlmo-7x7B-1T --device 0 +echo -e "Plants create energy through a process known as" | transformers run --task text-generation --model allenai/FlexOlmo-7x7B-1T --device 0 ``` @@ -136,4 +136,4 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ## FlexOlmoPreTrainedModel [[autodoc]] FlexOlmoPreTrainedModel - - forward \ No newline at end of file + - forward diff --git a/docs/source/en/model_doc/gpt_neo.md b/docs/source/en/model_doc/gpt_neo.md index f3de04d0e550..de48bce65085 100644 --- a/docs/source/en/model_doc/gpt_neo.md +++ b/docs/source/en/model_doc/gpt_neo.md @@ -65,7 +65,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ```bash -echo -e "Hello, I'm a language model" | transformers-cli run --task text-generation --model EleutherAI/gpt-neo-1.3B --device 0 +echo -e "Hello, I'm a language model" | transformers run --task text-generation --model EleutherAI/gpt-neo-1.3B --device 0 ``` diff --git a/docs/source/en/model_doc/granite.md b/docs/source/en/model_doc/granite.md index 3f99caf7f685..fce23a3c3493 100644 --- a/docs/source/en/model_doc/granite.md +++ b/docs/source/en/model_doc/granite.md @@ -59,8 +59,8 @@ from transformers import AutoModelForCausalLM, AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("ibm-granite/granite-3.3-2b-base") model = AutoModelForCausalLM.from_pretrained( - "ibm-granite/granite-3.3-2b-base", - dtype=torch.bfloat16, + "ibm-granite/granite-3.3-2b-base", + dtype=torch.bfloat16, device_map="auto", attn_implementation="sdpa" ) @@ -73,7 +73,7 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True)) ```python -echo -e "Explain quantum computing simply." | transformers-cli run --task text-generation --model ibm-granite/granite-3.3-8b-instruct --device 0 +echo -e "Explain quantum computing simply." | transformers run --task text-generation --model ibm-granite/granite-3.3-8b-instruct --device 0 ``` @@ -110,7 +110,7 @@ outputs = model.generate(**inputs, max_length=50, cache_implementation="static") print(tokenizer.decode(outputs[0], skip_special_tokens=True)) ``` - + ## GraniteConfig [[autodoc]] GraniteConfig diff --git a/docs/source/en/model_doc/led.md b/docs/source/en/model_doc/led.md index 8a732ae85cff..4acc6a639797 100644 --- a/docs/source/en/model_doc/led.md +++ b/docs/source/en/model_doc/led.md @@ -84,10 +84,10 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` - + ```bash -!echo -e "Plants are among the most remarkable and essential life forms on Earth, possessing a unique ability to produce their own food through a process known as photosynthesis. This complex biochemical process is fundamental not only to plant life but to virtually all life on the planet. Through photosynthesis, plants capture energy from sunlight using a green pigment called chlorophyll, which is located in specialized cell structures called chloroplasts." | transformers-cli run --task summarization --model allenai/led-base-16384 --device 0 +!echo -e "Plants are among the most remarkable and essential life forms on Earth, possessing a unique ability to produce their own food through a process known as photosynthesis. This complex biochemical process is fundamental not only to plant life but to virtually all life on the planet. Through photosynthesis, plants capture energy from sunlight using a green pigment called chlorophyll, which is located in specialized cell structures called chloroplasts." | transformers run --task summarization --model allenai/led-base-16384 --device 0 ``` diff --git a/docs/source/en/model_doc/mamba2.md b/docs/source/en/model_doc/mamba2.md index f8532f3cfbe6..547e959634e3 100644 --- a/docs/source/en/model_doc/mamba2.md +++ b/docs/source/en/model_doc/mamba2.md @@ -52,14 +52,14 @@ pipeline("Plants create energy through a process known as") ```python -import torch -from transformers import AutoModelForCausalLM, AutoTokenizer +import torch +from transformers import AutoModelForCausalLM, AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("mistralai/Mamba-Codestral-7B-v0.1") -model = AutoModelForCausalLM.from_pretrained("mistralai/Mamba-Codestral-7B-v0.1", dtype=torch.bfloat16, device_map="auto") -input_ids = tokenizer("Plants create energy through a process known as", return_tensors="pt").to(model.device) +model = AutoModelForCausalLM.from_pretrained("mistralai/Mamba-Codestral-7B-v0.1", dtype=torch.bfloat16, device_map="auto") +input_ids = tokenizer("Plants create energy through a process known as", return_tensors="pt").to(model.device) -output = model.generate(**input_ids) +output = model.generate(**input_ids) print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` @@ -67,7 +67,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ```bash -echo -e "Plants create energy through a process known as" | transformers-cli run --task text-generation --model mistralai/Mamba-Codestral-7B-v0.1 --device 0 +echo -e "Plants create energy through a process known as" | transformers run --task text-generation --model mistralai/Mamba-Codestral-7B-v0.1 --device 0 ``` @@ -97,14 +97,14 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) - `cuda_kernels_forward` uses the original CUDA kernels if they're available in your environment. It is slower during prefill because it requires a "warmup run" due to the higher CPU overhead (see [these](https://github.com/state-spaces/mamba/issues/389#issuecomment-2171755306) [comments](https://github.com/state-spaces/mamba/issues/355#issuecomment-2147597457) for more details). - There are no positional embeddings in this model, but there is an `attention_mask` and a specific logic to mask out hidden states in two places in the case of batched generation (see this [comment](https://github.com/state-spaces/mamba/issues/66#issuecomment-1863563829) for more details). This (and the addition of the reimplemented Mamba 2 kernels) results in a slight discrepancy between batched and cached generation. - -- The SSM algorithm heavily relies on tensor contractions, which have matmul equivalents but the order of operations is slightly different. This makes the difference greater at smaller precisions. + +- The SSM algorithm heavily relies on tensor contractions, which have matmul equivalents but the order of operations is slightly different. This makes the difference greater at smaller precisions. - Hidden states that correspond to padding tokens is shutdown in 2 places and is mostly tested with left-padding. Right-padding propagates noise down the line and is not guaranteed to yield satisfactory results. `tokenizer.padding_side = "left"` ensures you are using the correct padding side. - The example below demonstrates how to fine-tune Mamba 2 with [PEFT](https://huggingface.co/docs/peft). -```python +```python from datasets import load_dataset from peft import LoraConfig from trl import SFTConfig, SFTTrainer diff --git a/docs/source/en/model_doc/olmo2.md b/docs/source/en/model_doc/olmo2.md index 158909c085c3..bf582bc2ef54 100644 --- a/docs/source/en/model_doc/olmo2.md +++ b/docs/source/en/model_doc/olmo2.md @@ -46,7 +46,7 @@ pipe = pipeline( dtype=torch.float16, device=0, ) - + result = pipe("Plants create energy through a process known as") print(result) ``` @@ -78,7 +78,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ```bash -echo -e "Plants create energy through a process known as" | transformers-cli run --task text-generation --model allenai/OLMo-2-0425-1B --device 0 +echo -e "Plants create energy through a process known as" | transformers run --task text-generation --model allenai/OLMo-2-0425-1B --device 0 ``` @@ -121,11 +121,11 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) - OLMo2 uses RMSNorm instead of standard layer norm. The RMSNorm is applied to attention queries and keys, and it is applied after the attention and feedforward layers rather than before. - OLMo2 requires Transformers v4.48 or higher. -- Load specific intermediate checkpoints by adding the `revision` parameter to [`~PreTrainedModel.from_pretrained`]. +- Load specific intermediate checkpoints by adding the `revision` parameter to [`~PreTrainedModel.from_pretrained`]. ```py from transformers import AutoModelForCausalLM - + model = AutoModelForCausalLM.from_pretrained("allenai/OLMo-2-0425-1B", revision="stage1-step140000-tokens294B") ``` diff --git a/docs/source/en/model_doc/olmo3.md b/docs/source/en/model_doc/olmo3.md index 8e88a175d463..ecf384ee7cc0 100644 --- a/docs/source/en/model_doc/olmo3.md +++ b/docs/source/en/model_doc/olmo3.md @@ -79,7 +79,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ```bash -echo -e "Plants create energy through a process known as" | transformers-cli run --task text-generation --model allenai/TBA --device 0 +echo -e "Plants create energy through a process known as" | transformers run --task text-generation --model allenai/TBA --device 0 ``` diff --git a/docs/source/en/model_doc/pegasus.md b/docs/source/en/model_doc/pegasus.md index 9b92bda82a47..94b42eb9e7f9 100644 --- a/docs/source/en/model_doc/pegasus.md +++ b/docs/source/en/model_doc/pegasus.md @@ -82,7 +82,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ```bash -echo -e "Plants are remarkable organisms that produce their own food using a method called photosynthesis. This process involves converting sunlight, carbon dioxide, and water into glucose, which provides energy for growth. Plants play a crucial role in sustaining life on Earth by generating oxygen and serving as the foundation of most ecosystems." | transformers-cli run --task summarization --model google/pegasus-xsum --device 0 +echo -e "Plants are remarkable organisms that produce their own food using a method called photosynthesis. This process involves converting sunlight, carbon dioxide, and water into glucose, which provides energy for growth. Plants play a crucial role in sustaining life on Earth by generating oxygen and serving as the foundation of most ecosystems." | transformers run --task summarization --model google/pegasus-xsum --device 0 ``` diff --git a/docs/source/en/model_doc/pegasus_x.md b/docs/source/en/model_doc/pegasus_x.md index 791618c67d30..4f048e5496cb 100644 --- a/docs/source/en/model_doc/pegasus_x.md +++ b/docs/source/en/model_doc/pegasus_x.md @@ -79,10 +79,10 @@ output = model.generate(**input_ids, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` - + ```bash -echo -e "Plants are among the most remarkable and essential life forms on Earth, possessing a unique ability to produce their own food through a process known as photosynthesis. This complex biochemical process is fundamental not only to plant life but to virtually all life on the planet. Through photosynthesis, plants capture energy from sunlight using a green pigment called chlorophyll, which is located in specialized cell structures called chloroplasts." | transformers-cli run --task summarization --model google/pegasus-x-large --device 0 +echo -e "Plants are among the most remarkable and essential life forms on Earth, possessing a unique ability to produce their own food through a process known as photosynthesis. This complex biochemical process is fundamental not only to plant life but to virtually all life on the planet. Through photosynthesis, plants capture energy from sunlight using a green pigment called chlorophyll, which is located in specialized cell structures called chloroplasts." | transformers run --task summarization --model google/pegasus-x-large --device 0 ``` diff --git a/docs/source/en/model_doc/roberta.md b/docs/source/en/model_doc/roberta.md index da393646442a..580ff09e72c9 100644 --- a/docs/source/en/model_doc/roberta.md +++ b/docs/source/en/model_doc/roberta.md @@ -83,7 +83,7 @@ print(f"The predicted token is: {predicted_token}") ```bash -echo -e "Plants create through a process known as photosynthesis." | transformers-cli run --task fill-mask --model FacebookAI/roberta-base --device 0 +echo -e "Plants create through a process known as photosynthesis." | transformers run --task fill-mask --model FacebookAI/roberta-base --device 0 ``` diff --git a/docs/source/en/model_doc/roc_bert.md b/docs/source/en/model_doc/roc_bert.md index e8b0ededd603..3430f3369076 100644 --- a/docs/source/en/model_doc/roc_bert.md +++ b/docs/source/en/model_doc/roc_bert.md @@ -29,7 +29,7 @@ You can find all the original RoCBert checkpoints under the [weiweishi](https:// > [!TIP] > This model was contributed by [weiweishi](https://huggingface.co/weiweishi). -> +> > Click on the RoCBert models in the right sidebar for more examples of how to apply RoCBert to different Chinese language tasks. The example below demonstrates how to predict the [MASK] token with [`Pipeline`], [`AutoModel`], and from the command line. @@ -82,7 +82,7 @@ print(f"The predicted token is: {predicted_token}") ```bash -echo -e "這家餐廳的拉麵是我[MASK]過的最好的拉麵之" | transformers-cli run --task fill-mask --model weiweishi/roc-bert-base-zh --device 0 +echo -e "這家餐廳的拉麵是我[MASK]過的最好的拉麵之" | transformers run --task fill-mask --model weiweishi/roc-bert-base-zh --device 0 ``` diff --git a/docs/source/en/model_doc/roformer.md b/docs/source/en/model_doc/roformer.md index 313ed71f38fa..c892988e449e 100644 --- a/docs/source/en/model_doc/roformer.md +++ b/docs/source/en/model_doc/roformer.md @@ -75,7 +75,7 @@ print(decoded) ```bash -echo -e "水在零度时会[MASK]" | transformers-cli run --task fill-mask --model junnyu/roformer_chinese_base --device 0 +echo -e "水在零度时会[MASK]" | transformers run --task fill-mask --model junnyu/roformer_chinese_base --device 0 ``` diff --git a/docs/source/en/model_doc/xlm-roberta-xl.md b/docs/source/en/model_doc/xlm-roberta-xl.md index 988107fdacc6..8ae33e8b286a 100644 --- a/docs/source/en/model_doc/xlm-roberta-xl.md +++ b/docs/source/en/model_doc/xlm-roberta-xl.md @@ -37,43 +37,43 @@ The example below demonstrates how to predict the `` token with [`Pipeline ```python -import torch -from transformers import pipeline - -pipeline = pipeline( - task="fill-mask", - model="facebook/xlm-roberta-xl", - dtype=torch.float16, - device=0 -) -pipeline("Bonjour, je suis un modèle .") +import torch +from transformers import pipeline + +pipeline = pipeline( + task="fill-mask", + model="facebook/xlm-roberta-xl", + dtype=torch.float16, + device=0 +) +pipeline("Bonjour, je suis un modèle .") ``` ```python -import torch -from transformers import AutoModelForMaskedLM, AutoTokenizer - -tokenizer = AutoTokenizer.from_pretrained( - "facebook/xlm-roberta-xl", -) -model = AutoModelForMaskedLM.from_pretrained( - "facebook/xlm-roberta-xl", - dtype=torch.float16, - device_map="auto", - attn_implementation="sdpa" -) -inputs = tokenizer("Bonjour, je suis un modèle .", return_tensors="pt").to(model.device) - -with torch.no_grad(): - outputs = model(**inputs) - predictions = outputs.logits - -masked_index = torch.where(inputs['input_ids'] == tokenizer.mask_token_id)[1] -predicted_token_id = predictions[0, masked_index].argmax(dim=-1) -predicted_token = tokenizer.decode(predicted_token_id) +import torch +from transformers import AutoModelForMaskedLM, AutoTokenizer + +tokenizer = AutoTokenizer.from_pretrained( + "facebook/xlm-roberta-xl", +) +model = AutoModelForMaskedLM.from_pretrained( + "facebook/xlm-roberta-xl", + dtype=torch.float16, + device_map="auto", + attn_implementation="sdpa" +) +inputs = tokenizer("Bonjour, je suis un modèle .", return_tensors="pt").to(model.device) + +with torch.no_grad(): + outputs = model(**inputs) + predictions = outputs.logits + +masked_index = torch.where(inputs['input_ids'] == tokenizer.mask_token_id)[1] +predicted_token_id = predictions[0, masked_index].argmax(dim=-1) +predicted_token = tokenizer.decode(predicted_token_id) print(f"The predicted token is: {predicted_token}") ``` @@ -82,7 +82,7 @@ print(f"The predicted token is: {predicted_token}") ```bash -echo -e "Plants create through a process known as photosynthesis." | transformers-cli run --task fill-mask --model facebook/xlm-roberta-xl --device 0 +echo -e "Plants create through a process known as photosynthesis." | transformers run --task fill-mask --model facebook/xlm-roberta-xl --device 0 ``` diff --git a/docs/source/en/model_doc/xlm-roberta.md b/docs/source/en/model_doc/xlm-roberta.md index a662742c2674..65468a786a07 100644 --- a/docs/source/en/model_doc/xlm-roberta.md +++ b/docs/source/en/model_doc/xlm-roberta.md @@ -85,7 +85,7 @@ print(f"The predicted token is: {predicted_token}") ```bash -echo -e "Plants create through a process known as photosynthesis." | transformers-cli run --task fill-mask --model FacebookAI/xlm-roberta-base --device 0 +echo -e "Plants create through a process known as photosynthesis." | transformers run --task fill-mask --model FacebookAI/xlm-roberta-base --device 0 ``` diff --git a/docs/source/en/model_doc/xlm.md b/docs/source/en/model_doc/xlm.md index dc51fa4be4cd..b4d84c791f5a 100644 --- a/docs/source/en/model_doc/xlm.md +++ b/docs/source/en/model_doc/xlm.md @@ -77,7 +77,7 @@ print(f"Predicted token: {predicted_token}") ```bash -echo -e "Plants create through a process known as photosynthesis." | transformers-cli run --task fill-mask --model FacebookAI/xlm-mlm-en-2048 --device 0 +echo -e "Plants create through a process known as photosynthesis." | transformers run --task fill-mask --model FacebookAI/xlm-mlm-en-2048 --device 0 ``` diff --git a/docs/source/zh/model_doc/bert.md b/docs/source/zh/model_doc/bert.md index 3877fcafe4de..482e70627048 100644 --- a/docs/source/zh/model_doc/bert.md +++ b/docs/source/zh/model_doc/bert.md @@ -81,10 +81,10 @@ print(f"The predicted token is: {predicted_token}") ``` - + ```bash -echo -e "Plants create [MASK] through a process known as photosynthesis." | transformers-cli run --task fill-mask --model google-bert/bert-base-uncased --device 0 +echo -e "Plants create [MASK] through a process known as photosynthesis." | transformers run --task fill-mask --model google-bert/bert-base-uncased --device 0 ``` @@ -157,4 +157,4 @@ echo -e "Plants create [MASK] through a process known as photosynthesis." | tran ## Bert specific outputs -[[autodoc]] models.bert.modeling_bert.BertForPreTrainingOutput \ No newline at end of file +[[autodoc]] models.bert.modeling_bert.BertForPreTrainingOutput diff --git a/setup.py b/setup.py index d6e69d3b83c5..10bac3c7707f 100644 --- a/setup.py +++ b/setup.py @@ -439,7 +439,6 @@ def run(self): entry_points={ "console_scripts": [ "transformers=transformers.commands.transformers_cli:main", - "transformers-cli=transformers.commands.transformers_cli:main_cli", ] }, python_requires=">=3.9.0", diff --git a/src/transformers/commands/transformers_cli.py b/src/transformers/commands/transformers_cli.py index 1a283a1c512c..7d5f3b6fb383 100644 --- a/src/transformers/commands/transformers_cli.py +++ b/src/transformers/commands/transformers_cli.py @@ -12,7 +12,6 @@ # 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. -import warnings from transformers import HfArgumentParser from transformers.commands.add_fast_image_processor import AddFastImageProcessorCommand @@ -24,14 +23,6 @@ from transformers.commands.serving import ServeCommand -def main_cli(): - warnings.warn( - "`transformers-cli` is deprecated in favour of `transformers` directly and will be removed in v5.", - DeprecationWarning, - ) - main() - - def main(): parser = HfArgumentParser(prog="Transformers CLI tool", usage="transformers []") commands_parser = parser.add_subparsers(help="transformers command helpers") From 9896a3f7c7091d4b253c6febbe31fcfdb99ce289 Mon Sep 17 00:00:00 2001 From: StevenBucaille Date: Fri, 19 Sep 2025 11:41:22 -0400 Subject: [PATCH 129/204] =?UTF-8?q?=F0=9F=9A=A8=20[lightglue]=20fix:=20mat?= =?UTF-8?q?ches=20order=20changed=20because=20of=20early=20stopped=20indic?= =?UTF-8?q?es=20(#40859)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: bug that made early stop change order of matches * fix: applied code suggestion Co-authored-by: Pavel Iakubovskii * fix: applied code suggestion to modular * fix: integration tests --------- Co-authored-by: Pavel Iakubovskii --- .../models/lightglue/modeling_lightglue.py | 4 ++ .../models/lightglue/modular_lightglue.py | 4 ++ .../lightglue/test_modeling_lightglue.py | 52 ++++++++++++++----- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/transformers/models/lightglue/modeling_lightglue.py b/src/transformers/models/lightglue/modeling_lightglue.py index fd460e54d393..8e9faa3e4e04 100644 --- a/src/transformers/models/lightglue/modeling_lightglue.py +++ b/src/transformers/models/lightglue/modeling_lightglue.py @@ -628,6 +628,10 @@ def _concat_early_stopped_outputs( matching_scores, ): early_stops_indices = torch.stack(early_stops_indices) + # Rearrange tensors to have the same order as the input batch + ids = torch.arange(early_stops_indices.shape[0]) + order_indices = early_stops_indices[ids] + early_stops_indices = early_stops_indices[order_indices] matches, final_pruned_keypoints_indices = ( pad_sequence(tensor, batch_first=True, padding_value=-1) for tensor in [matches, final_pruned_keypoints_indices] diff --git a/src/transformers/models/lightglue/modular_lightglue.py b/src/transformers/models/lightglue/modular_lightglue.py index 64c36f21fef9..29441344c9cd 100644 --- a/src/transformers/models/lightglue/modular_lightglue.py +++ b/src/transformers/models/lightglue/modular_lightglue.py @@ -786,6 +786,10 @@ def _concat_early_stopped_outputs( matching_scores, ): early_stops_indices = torch.stack(early_stops_indices) + # Rearrange tensors to have the same order as the input batch + ids = torch.arange(early_stops_indices.shape[0]) + order_indices = early_stops_indices[ids] + early_stops_indices = early_stops_indices[order_indices] matches, final_pruned_keypoints_indices = ( pad_sequence(tensor, batch_first=True, padding_value=-1) for tensor in [matches, final_pruned_keypoints_indices] diff --git a/tests/models/lightglue/test_modeling_lightglue.py b/tests/models/lightglue/test_modeling_lightglue.py index 17276f1cdefd..9342b9a58fb8 100644 --- a/tests/models/lightglue/test_modeling_lightglue.py +++ b/tests/models/lightglue/test_modeling_lightglue.py @@ -331,24 +331,13 @@ def test_inference(self): predicted_matches_values1 = outputs.matches[1, 0, 10:30] predicted_matching_scores_values1 = outputs.matching_scores[1, 0, 10:30] - expected_number_of_matches0 = 140 + expected_number_of_matches0 = 866 expected_matches_values0 = torch.tensor( - [14, -1, -1, 15, 17, 13, -1, -1, -1, -1, -1, -1, 5, -1, -1, 19, -1, 10, -1, 11], - dtype=torch.int64, - device=torch_device, - ) - expected_matching_scores_values0 = torch.tensor( - [0.3796, 0, 0, 0.3772, 0.4439, 0.2411, 0, 0, 0.0032, 0, 0, 0, 0.2997, 0, 0, 0.6762, 0, 0.8826, 0, 0.5583], - device=torch_device, - ) - - expected_number_of_matches1 = 866 - expected_matches_values1 = torch.tensor( [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], dtype=torch.int64, device=torch_device, ) - expected_matching_scores_values1 = torch.tensor( + expected_matching_scores_values0 = torch.tensor( [ 0.6188,0.7817,0.5686,0.9353,0.9801,0.9193,0.8632,0.9111,0.9821,0.5496, 0.9906,0.8682,0.9679,0.9914,0.9318,0.1910,0.9669,0.3240,0.9971,0.9923, @@ -356,6 +345,17 @@ def test_inference(self): device=torch_device ) # fmt:skip + expected_number_of_matches1 = 140 + expected_matches_values1 = torch.tensor( + [14, -1, -1, 15, 17, 13, -1, -1, -1, -1, -1, -1, 5, -1, -1, 19, -1, 10, -1, 11], + dtype=torch.int64, + device=torch_device, + ) + expected_matching_scores_values1 = torch.tensor( + [0.3796, 0, 0, 0.3772, 0.4439, 0.2411, 0, 0, 0.0032, 0, 0, 0, 0.2997, 0, 0, 0.6762, 0, 0.8826, 0, 0.5583], + device=torch_device, + ) + # expected_early_stopping_layer = 2 # predicted_early_stopping_layer = torch.max(outputs.prune[1]).item() # self.assertEqual(predicted_early_stopping_layer, expected_early_stopping_layer) @@ -375,7 +375,6 @@ def test_inference(self): Such CUDA inconsistencies can be found [here](https://github.com/huggingface/transformers/pull/33200/files#r1785980300) """ - self.assertTrue(abs(predicted_number_of_matches0 - expected_number_of_matches0) < 4) self.assertTrue(abs(predicted_number_of_matches1 - expected_number_of_matches1) < 4) self.assertTrue( @@ -590,3 +589,28 @@ def test_inference_without_early_stop_and_keypoint_pruning(self): ) self.assertTrue(torch.sum(predicted_matches_values0 != expected_matches_values0) < 4) self.assertTrue(torch.sum(predicted_matches_values1 != expected_matches_values1) < 4) + + @slow + def test_inference_order_with_early_stop(self): + model = LightGlueForKeypointMatching.from_pretrained( + "ETH-CVG/lightglue_superpoint", attn_implementation="eager" + ).to(torch_device) + preprocessor = self.default_image_processor + images = prepare_imgs() + # [[image2, image0], [image1, image1]] -> [[image2, image0], [image2, image0], [image1, image1]] + images = [images[0]] + images # adding a 3rd pair to test batching with early stopping + inputs = preprocessor(images=images, return_tensors="pt").to(torch_device) + with torch.no_grad(): + outputs = model(**inputs, output_hidden_states=True, output_attentions=True) + + predicted_number_of_matches_pair0 = torch.sum(outputs.matches[0][0] != -1).item() + predicted_number_of_matches_pair1 = torch.sum(outputs.matches[1][0] != -1).item() + predicted_number_of_matches_pair2 = torch.sum(outputs.matches[2][0] != -1).item() + + # pair 0 and 1 are the same, so should have the same number of matches + # pair 2 is [image1, image1] so should have more matches than first two pairs + # This ensures that early stopping does not affect the order of the outputs + # See : https://huggingface.co/ETH-CVG/lightglue_superpoint/discussions/6 + # The bug made the pairs switch order when early stopping was activated + self.assertTrue(predicted_number_of_matches_pair0 == predicted_number_of_matches_pair1) + self.assertTrue(predicted_number_of_matches_pair0 < predicted_number_of_matches_pair2) From b16b1561f2098bd77877df43ff493962975c4cc4 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Fri, 19 Sep 2025 18:43:46 +0200 Subject: [PATCH 130/204] Fix `PhimoeIntegrationTest` (#41007) * fix * fix * fix * fix * fix --------- Co-authored-by: ydshieh --- tests/models/phimoe/test_modeling_phimoe.py | 81 +++++++++++++++------ 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/tests/models/phimoe/test_modeling_phimoe.py b/tests/models/phimoe/test_modeling_phimoe.py index 46714244a14b..ac6fa3c2672a 100644 --- a/tests/models/phimoe/test_modeling_phimoe.py +++ b/tests/models/phimoe/test_modeling_phimoe.py @@ -14,12 +14,14 @@ """Testing suite for the PyTorch PhiMoE model.""" +import copy import unittest from parameterized import parameterized from transformers import PhimoeConfig, StaticCache, is_torch_available from transformers.testing_utils import ( + cleanup, require_torch, slow, torch_device, @@ -130,31 +132,47 @@ def test_model_rope_scaling_from_config(self, scaling_type): @slow @require_torch class PhimoeIntegrationTest(unittest.TestCase): - def test_model_phimoe_instruct_logits(self): - input_ids = { - "input_ids": torch.tensor( - [[1212, 318, 281, 1672, 2643, 290, 428, 318, 257, 1332]], dtype=torch.long, device=torch_device + model = None + + @classmethod + def get_model(cls): + if cls.model is None: + cls.model = PhimoeForCausalLM.from_pretrained( + "microsoft/Phi-3.5-MoE-instruct", dtype="auto", device_map="auto" ) - } + return cls.model + + @classmethod + def tearDownClass(cls): + del cls.model + cleanup(torch_device, gc_collect=True) + + def setUp(self): + cleanup(torch_device, gc_collect=True) + + def tearDown(self): + cleanup(torch_device, gc_collect=True) - model = PhimoeForCausalLM.from_pretrained("microsoft/Phi-3.5-MoE-instruct").to(torch_device) + def test_model_phimoe_instruct_logits(self): + input_ids = {"input_ids": torch.tensor([[1212, 318, 281, 1672]], dtype=torch.long, device=torch_device)} + + model = self.get_model() model.eval() - output = model(**input_ids).logits + with torch.no_grad(): + output = model(**input_ids).logits - EXPECTED_OUTPUT = torch.tensor([[-3.5312, -2.5000, -1.2734, 0.3555, -0.7578, -0.4727, 0.5977, -0.4316, - 0.2256, -1.2188, -1.6797, 0.9961, 3.7656, 11.3125, -1.3828, -4.8438, - -5.7500, -1.9375, 0.7227, -0.3438, -0.2100, -0.4277, -0.0444, -0.5352, - -0.6406, -0.1016, -0.4258, -1.0234, 0.4297, -0.6250], - [-0.9883, 0.1455, -0.4902, 2.3594, 0.7031, 3.1406, 0.4375, 0.2559, - 0.6172, -2.1094, -1.3359, 2.5938, 4.9062, 10.8125, -0.1094, 1.5781, - -4.9375, 0.7148, -0.0972, 1.7656, -0.0801, 0.2217, 0.1875, -0.4629, - 1.5781, 0.3535, 0.0874, 0.6836, -0.0518, -1.2969]]).to(torch_device) # fmt: skip + EXPECTED_OUTPUT = torch.tensor( + [ + [-3.4844, -2.4531, -1.1719, 0.6055, -0.4922, -0.1001, 0.8086, -0.2422, 0.3477, -1.0078], + [-0.9766, 0.1631, -0.5508, 2.3594, 0.7031, 3.1719, 0.4141, 0.2305, 0.6055, -2.1250], + ] + ).to(device=torch_device, dtype=output.dtype) # fmt: skip - torch.testing.assert_close(EXPECTED_OUTPUT, output[0, :2, :30], rtol=1e-4, atol=1e-4) + torch.testing.assert_close(output[0, :2, :10], EXPECTED_OUTPUT, rtol=1e-4, atol=1e-4) def test_phimoe_instruct_generation(self): - model = PhimoeForCausalLM.from_pretrained("microsoft/Phi-3.5-MoE-instruct") + model = self.get_model() tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3.5-MoE-instruct") messages = [ @@ -166,17 +184,29 @@ def test_phimoe_instruct_generation(self): ] inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt") - outputs = model.generate(inputs, max_new_tokens=32) + outputs = model.generate(inputs, max_new_tokens=30) output_text = tokenizer.batch_decode(outputs) EXPECTED_OUTPUT = [ - "<|system|> You are a helpful digital assistant. Please provide safe, ethical and accurate information to the user.<|end|><|user|> Can you provide ways to eat combinations of bananas and dragonfruits?<|end|><|assistant|> Certainly! Bananas and dragonfruits are both delicious and nutritious fruits that can be combined in various ways to create tast" + "<|system|> You are a helpful digital assistant. Please provide safe, ethical and accurate information to the user.<|end|><|user|> Can you provide ways to eat combinations of bananas and dragonfruits?<|end|><|assistant|> Certainly! Bananas and dragonfruits are both delicious and nutritious fruits that can be combined in various ways to create", ] - self.assertListEqual(output_text, EXPECTED_OUTPUT) def test_phimoe_instruct_with_static_cache(self): - model = PhimoeForCausalLM.from_pretrained("microsoft/Phi-3.5-MoE-instruct") + model = self.get_model() + # Can't run with the real checkpoint, even if offloaded. Let's just use a tiny dummy one + config = copy.deepcopy(model.config) + config.num_hidden_layers = 2 + # make `head_dim = 128` + config.hidden_size = 512 + config.num_attention_heads = 4 + config.num_key_value_heads = 1 + config.intermediate_size = 512 + config.max_position_embeddinqgs = 64 + config.num_local_experts = 4 + torch.manual_seed(42) + model = PhimoeForCausalLM(config).to(torch_device) + model.eval() tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3.5-MoE-instruct") messages = [ @@ -186,14 +216,17 @@ def test_phimoe_instruct_with_static_cache(self): }, {"role": "user", "content": "Can you provide ways to eat combinations of bananas and dragonfruits?"}, ] - inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt") + inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt").to( + torch_device + ) - response_tokens = PhimoeMiniWithStaticCache.generate(model, inputs, 64) + response_tokens = PhimoeMiniWithStaticCache.generate(model, inputs, max_seq_len=30) output_text = tokenizer.batch_decode(torch.tensor([response_tokens], dtype=torch.long, device=torch_device)) + # This is dummy outputs. We actually check if it could run with static cache, not the output quality. EXPECTED_OUTPUT = [ - "<|system|> You are a helpful digital assistant. Please provide safe, ethical and accurate information to the user.<|end|><|user|> Can you provide ways to eat combinations of bananas and dragonfruits?<|end|><|assistant|> Certainly! Bananas and dragonfruits are both delicious and nutritious fruits that can" + "<|system|> You are a helpful digital assistant. Please provide safe, ethical and accurate information to the user.<|end|><|user|> Can you provide ways to eat combinations of bananas and dragonfruits?<|end|><|assistant|> awards" ] self.assertListEqual(output_text, EXPECTED_OUTPUT) From 002d85355fe24363f6e214b637681cfa9d91f846 Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Fri, 19 Sep 2025 18:54:26 +0200 Subject: [PATCH 131/204] Fix Glm4v test (#41011) fix --- tests/models/glm4v_moe/test_modeling_glm4v_moe.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/models/glm4v_moe/test_modeling_glm4v_moe.py b/tests/models/glm4v_moe/test_modeling_glm4v_moe.py index 995b3c0723db..1881fffa9dd9 100644 --- a/tests/models/glm4v_moe/test_modeling_glm4v_moe.py +++ b/tests/models/glm4v_moe/test_modeling_glm4v_moe.py @@ -297,6 +297,7 @@ def test_inputs_embeds_matches_input_ids(self): @require_torch +@slow class Glm4vMoeIntegrationTest(unittest.TestCase): model = None @@ -310,7 +311,8 @@ def get_model(cls): @classmethod def tearDownClass(cls): - del cls.model + if hasattr(cls, "model"): + del cls.model cleanup(torch_device, gc_collect=True) def setUp(self): @@ -364,7 +366,6 @@ def setUp(self): def tearDown(self): cleanup(torch_device, gc_collect=True) - @slow def test_small_model_integration_test(self): inputs = self.processor.apply_chat_template( self.message, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt" @@ -386,7 +387,6 @@ def test_small_model_integration_test(self): ) torch.testing.assert_close(expected_pixel_slice, inputs.pixel_values[:6, :3], atol=1e-4, rtol=1e-4) - @slow def test_small_model_integration_test_batch(self): model = self.get_model() batch_messages = [self.message, self.message2, self.message_wo_image] @@ -414,7 +414,6 @@ def test_small_model_integration_test_batch(self): EXPECTED_DECODED_TEXT, ) - @slow def test_small_model_integration_test_with_video(self): processor = AutoProcessor.from_pretrained("zai-org/GLM-4.5V", max_image_size={"longest_edge": 50176}) model = self.get_model() @@ -437,7 +436,6 @@ def test_small_model_integration_test_with_video(self): ) @run_first - @slow @require_flash_attn @require_torch_gpu def test_small_model_integration_test_batch_flashatt2(self): From 0f598ff7d6c822ea992e17c8375b13658bf89220 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Fri, 19 Sep 2025 21:55:46 +0200 Subject: [PATCH 132/204] Update after #41007 (#41014) * fix * fix --------- Co-authored-by: ydshieh --- tests/models/phimoe/test_modeling_phimoe.py | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/tests/models/phimoe/test_modeling_phimoe.py b/tests/models/phimoe/test_modeling_phimoe.py index ac6fa3c2672a..ba6b1d50be71 100644 --- a/tests/models/phimoe/test_modeling_phimoe.py +++ b/tests/models/phimoe/test_modeling_phimoe.py @@ -14,7 +14,6 @@ """Testing suite for the PyTorch PhiMoE model.""" -import copy import unittest from parameterized import parameterized @@ -59,6 +58,7 @@ def forward( past_key_values=self.cache, ).logits + @torch.no_grad() @staticmethod def generate(model: PhimoeForCausalLM, prompt_tokens: torch.LongTensor, max_seq_len: int) -> list[int]: model = PhimoeMiniWithStaticCache(model, 1, max_seq_len + prompt_tokens.shape[-1]) @@ -194,19 +194,6 @@ def test_phimoe_instruct_generation(self): def test_phimoe_instruct_with_static_cache(self): model = self.get_model() - # Can't run with the real checkpoint, even if offloaded. Let's just use a tiny dummy one - config = copy.deepcopy(model.config) - config.num_hidden_layers = 2 - # make `head_dim = 128` - config.hidden_size = 512 - config.num_attention_heads = 4 - config.num_key_value_heads = 1 - config.intermediate_size = 512 - config.max_position_embeddinqgs = 64 - config.num_local_experts = 4 - torch.manual_seed(42) - model = PhimoeForCausalLM(config).to(torch_device) - model.eval() tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3.5-MoE-instruct") messages = [ @@ -221,12 +208,9 @@ def test_phimoe_instruct_with_static_cache(self): ) response_tokens = PhimoeMiniWithStaticCache.generate(model, inputs, max_seq_len=30) - output_text = tokenizer.batch_decode(torch.tensor([response_tokens], dtype=torch.long, device=torch_device)) - # This is dummy outputs. We actually check if it could run with static cache, not the output quality. EXPECTED_OUTPUT = [ - "<|system|> You are a helpful digital assistant. Please provide safe, ethical and accurate information to the user.<|end|><|user|> Can you provide ways to eat combinations of bananas and dragonfruits?<|end|><|assistant|> awards" + "<|system|> You are a helpful digital assistant. Please provide safe, ethical and accurate information to the user.<|end|><|user|> Can you provide ways to eat combinations of bananas and dragonfruits?<|end|><|assistant|> C" ] - self.assertListEqual(output_text, EXPECTED_OUTPUT) From 00aa6c74c34dfa713e34ebb42a911234657ee872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Hadnagy?= Date: Sat, 20 Sep 2025 10:53:56 +0200 Subject: [PATCH 133/204] Fix benchmark runner argument name (#41012) --- .github/workflows/benchmark_v2.yml | 8 +------- .github/workflows/benchmark_v2_a10_caller.yml | 1 - .github/workflows/benchmark_v2_mi325_caller.yml | 1 - 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/benchmark_v2.yml b/.github/workflows/benchmark_v2.yml index 350ad0144101..a2c25908d129 100644 --- a/.github/workflows/benchmark_v2.yml +++ b/.github/workflows/benchmark_v2.yml @@ -12,11 +12,6 @@ on: required: false type: string default: '' - upload_to_hub: - description: 'Uploading results to a HuggingFace Dataset' - required: false - type: string - default: 'false' run_id: description: 'Custom run ID for organizing results (auto-generated if not provided)' required: false @@ -74,9 +69,8 @@ jobs: echo "Running benchmarks" python3 run_benchmarks.py \ --commit-id '${{ inputs.commit_sha || github.sha }}' \ - --upload-to-hub '${{ inputs.upload_to_hub || false}}' \ --run-id '${{ inputs.run_id }}' \ - --benchmark-repo-id '${{ inputs.benchmark_repo_id}}' \ + --upload-to-hub '${{ inputs.benchmark_repo_id}}' \ --log-level INFO env: HF_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/benchmark_v2_a10_caller.yml b/.github/workflows/benchmark_v2_a10_caller.yml index 30b5e8be78a5..6d4f6ad7fe9a 100644 --- a/.github/workflows/benchmark_v2_a10_caller.yml +++ b/.github/workflows/benchmark_v2_a10_caller.yml @@ -14,7 +14,6 @@ jobs: with: runner: aws-g5-4xlarge-cache-use1-public-80 commit_sha: ${{ github.sha }} - upload_to_hub: true run_id: ${{ github.run_id }} benchmark_repo_id: hf-internal-testing/transformers-daily-benchmarks secrets: inherit \ No newline at end of file diff --git a/.github/workflows/benchmark_v2_mi325_caller.yml b/.github/workflows/benchmark_v2_mi325_caller.yml index 95fbeb5e5f6a..9ed387aee2ef 100644 --- a/.github/workflows/benchmark_v2_mi325_caller.yml +++ b/.github/workflows/benchmark_v2_mi325_caller.yml @@ -14,7 +14,6 @@ jobs: with: runner: amd-mi325-ci-1gpu commit_sha: ${{ github.sha }} - upload_to_hub: true run_id: ${{ github.run_id }} benchmark_repo_id: hf-internal-testing/transformers-daily-benchmarks secrets: inherit \ No newline at end of file From ceefb5400b1637e7876cd36251fea984b3314752 Mon Sep 17 00:00:00 2001 From: BakerBunker <17872844+BakerBunker@users.noreply.github.com> Date: Sun, 21 Sep 2025 16:46:27 -0500 Subject: [PATCH 134/204] Adding support for Qwen3Omni (#41025) * Add Qwen3Omni * make fix-copies, import properly * nit * fix wrong setup. Why was audio_token_id renamed ? * upds * more processing fixes * yup * fix more generation tests * down to 1? * fix import issue * style, update check repo * up * fix quality at my best * final quality? * fix doc building * FINAL COMMIT: SKIP IMPORTANT BUT FAILING TESTS FOR MERGE * SKIP THE TEMPLATE ONE --------- Co-authored-by: lvyuanjun.lyj Co-authored-by: Arthur --- docs/source/en/_toctree.yml | 2 + docs/source/en/model_doc/qwen3_omni_moe.md | 414 ++ src/transformers/models/__init__.py | 1 + .../models/auto/configuration_auto.py | 2 + src/transformers/models/auto/modeling_auto.py | 1 + .../models/auto/processing_auto.py | 1 + .../models/auto/tokenization_auto.py | 1 + .../models/auto/video_processing_auto.py | 1 + .../qwen2_5_omni/processing_qwen2_5_omni.py | 8 +- .../models/qwen3_omni_moe/__init__.py | 28 + .../configuration_qwen3_omni_moe.py | 1250 +++++ .../qwen3_omni_moe/modeling_qwen3_omni_moe.py | 4067 +++++++++++++++++ .../qwen3_omni_moe/modular_qwen3_omni_moe.py | 2779 +++++++++++ .../processing_qwen3_omni_moe.py | 360 ++ tests/models/qwen3_omni_moe/__init__.py | 0 .../test_modeling_qwen3_omni_moe.py | 878 ++++ .../test_processing_qwen3_omni_moe.py | 602 +++ tests/test_modeling_common.py | 1 + utils/check_docstrings.py | 1 + utils/check_repo.py | 18 + 20 files changed, 10411 insertions(+), 4 deletions(-) create mode 100644 docs/source/en/model_doc/qwen3_omni_moe.md create mode 100644 src/transformers/models/qwen3_omni_moe/__init__.py create mode 100644 src/transformers/models/qwen3_omni_moe/configuration_qwen3_omni_moe.py create mode 100644 src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py create mode 100644 src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py create mode 100644 src/transformers/models/qwen3_omni_moe/processing_qwen3_omni_moe.py create mode 100644 tests/models/qwen3_omni_moe/__init__.py create mode 100644 tests/models/qwen3_omni_moe/test_modeling_qwen3_omni_moe.py create mode 100644 tests/models/qwen3_omni_moe/test_processing_qwen3_omni_moe.py diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index be97cf6d7c36..c690bddf36a0 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -1143,6 +1143,8 @@ title: Qwen2Audio - local: model_doc/qwen2_vl title: Qwen2VL + - local: model_doc/qwen3_omni_moe + title: Qwen3-Omni-MoE - local: model_doc/qwen3_vl title: Qwen3VL - local: model_doc/qwen3_vl_moe diff --git a/docs/source/en/model_doc/qwen3_omni_moe.md b/docs/source/en/model_doc/qwen3_omni_moe.md new file mode 100644 index 000000000000..04d77534f649 --- /dev/null +++ b/docs/source/en/model_doc/qwen3_omni_moe.md @@ -0,0 +1,414 @@ + +*This model was released on 2025-03-26 and added to Hugging Face Transformers on 2025-04-14.* + +# Qwen2.5-Omni + +
+PyTorch +FlashAttention +SDPA +
+ +## Overview + +The [Qwen2.5-Omni](https://qwenlm.github.io/blog/qwen2.5-omni/) model is a unified multiple modalities model proposed in [Qwen2.5-Omni Technical Report](https://huggingface.co/papers/2503.20215) from Qwen team, Alibaba Group. + +The abstract from the technical report is the following: + +*We present Qwen2.5-Omni, an end-to-end multimodal model designed to perceive diverse modalities, including text, images, audio, and video, while simultaneously generating text and natural speech responses in a streaming manner. To enable the streaming of multimodal information inputs, both audio and visual encoders utilize a block-wise processing approach. This strategy effectively decouples the handling of long sequences of multimodal data, assigning the perceptual responsibilities to the multimodal encoder and entrusting the modeling of extended sequences to a large language model. Such a division of labor enhances the fusion of different modalities via the shared attention mechanism. To synchronize the timestamps of video inputs with audio, we organized the audio and video sequentially in an interleaved manner and propose a novel position embedding approach, named TMRoPE (Time-aligned Multimodal RoPE). To concurrently generate text and speech while avoiding interference between the two modalities, we propose Thinker-Talker architecture. In this framework, Thinker functions as a large language model tasked with text generation, while Talker is a dual-track autoregressive model that directly utilizes the hidden representations from the Thinker to produce audio tokens as output. Both the Thinker and Talker models are designed to be trained and inferred in an end-to-end manner. For decoding audio tokens in a streaming manner, we introduce a sliding-window DiT that restricts the receptive field, aiming to reduce the initial package delay. Qwen2.5-Omni outperforms the similarly sized Qwen2-VL and Qwen2-Audio in both image and audio capabilities. Furthermore, Qwen2.5-Omni achieves state-of-the-art performance on multimodal benchmarks like Omni-Bench. Notably, Qwen2.5-Omni is the first open-source model to achieve a level of performance in end-to-end speech instruction following that is comparable to its capabilities with text inputs, as evidenced by benchmarks such as MMLU and GSM8K. As for speech generation, Qwen2.5-Omni’s streaming Talker outperform most existing streaming and non-streaming alternatives in robustness and naturalness.* + + + +## Notes + +- Use [`Qwen2_5OmniForConditionalGeneration`] to generate audio and text output. To generate only one output type, use [`Qwen2_5OmniThinkerForConditionalGeneration`] for text-only and [`Qwen2_5OmniTalkersForConditionalGeneration`] for audio-only outputs. +- Audio generation with [`Qwen2_5OmniForConditionalGeneration`] supports only single batch size at the moment. +- In case out out-of-memory errors hwen working with video input, decrease `processor.max_pixels`. By default the maximum is set to a very arge value and high resolution visuals will not be resized, unless resolution exceeds `processor.max_pixels`. +- The processor has its own [`~ProcessorMixin.apply_chat_template`] method to convert chat messages to model inputs. + + +## Usage example + +`Qwen2.5-Omni` can be found on the [Huggingface Hub](https://huggingface.co/Qwen). + +### Single Media inference + +The model can accept text, images, audio and videos as input. Here's an example code for inference. + +```python +import soundfile as sf +from transformers import Qwen2_5OmniForConditionalGeneration, Qwen2_5OmniProcessor + +model = Qwen2_5OmniForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", + dtype="auto", + device_map="auto" +) +processor = Qwen2_5OmniProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B") + +conversations = [ + { + "role": "system", + "content": [ + {"type": "text", "text": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech."} + ], + }, + { + "role": "user", + "content": [ + {"type": "video", "video": "/path/to/video.mp4"}, + {"type": "text", "text": "What cant you hear and see in this video?"}, + ], + }, +] + +inputs = processor.apply_chat_template( + conversations, + load_audio_from_video=True, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", + video_fps=1, + + # kwargs to be passed to `Qwen2-5-OmniProcessor` + padding=True, + use_audio_in_video=True, +).to(model.device) + +# Generation params for audio or text can be different and have to be prefixed with `thinker_` or `talker_` +text_ids, audio = model.generate(**inputs, use_audio_in_video=True, thinker_do_sample=False, talker_do_sample=True) +text = processor.batch_decode(text_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False) + +sf.write( + "output.wav", + audio.reshape(-1).detach().cpu().numpy(), + samplerate=24000, +) +print(text) +``` + +### Text-only generation + +To generate only text output and save compute by not loading the audio generation model, we can use `Qwen2_5OmniThinkerForConditionalGeneration` model. + +```python +from transformers import Qwen2_5OmniThinkerForConditionalGeneration, Qwen2_5OmniProcessor + +model = Qwen2_5OmniThinkerForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", + dtype="auto", + device_map="auto", +) +processor = Qwen2_5OmniProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B") + +conversations = [ + { + "role": "system", + "content": [ + {"type": "text", "text": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech."} + ], + }, + { + "role": "user", + "content": [ + {"type": "video", "video": "/path/to/video.mp4"}, + {"type": "text", "text": "What cant you hear and see in this video?"}, + ], + }, +] + +inputs = processor.apply_chat_template( + conversations, + load_audio_from_video=True, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", + video_fps=1, + + # kwargs to be passed to `Qwen2-5-OmniProcessor` + padding=True, + use_audio_in_video=True, +).to(model.device) + + +text_ids = model.generate(**inputs, use_audio_in_video=True) +text = processor.batch_decode(text_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False) + +sf.write( + "output.wav", + audio.reshape(-1).detach().cpu().numpy(), + samplerate=24000, +) +print(text) +``` + +### Batch Mixed Media Inference + +The model can batch inputs composed of mixed samples of various types such as text, images, audio and videos as input when using `Qwen2_5OmniThinkerForConditionalGeneration` model. Here is an example. + +```python +import soundfile as sf +from transformers import Qwen2_5OmniForConditionalGeneration, Qwen2_5OmniProcessor + +model = Qwen2_5OmniForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", + dtype="auto", + device_map="auto" +) +processor = Qwen2_5OmniProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B") + +# Conversation with video only +conversation1 = [ + { + "role": "system", + "content": [ + {"type": "text", "text": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech."} + ], + }, + { + "role": "user", + "content": [ + {"type": "video", "path": "/path/to/video.mp4"}, + ] + } +] + +# Conversation with audio only +conversation2 = [ + { + "role": "system", + "content": [ + {"type": "text", "text": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech."} + ], + }, + { + "role": "user", + "content": [ + {"type": "audio", "path": "/path/to/audio.wav"}, + ] + } +] + +# Conversation with pure text +conversation3 = [ + { + "role": "system", + "content": [ + {"type": "text", "text": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech."} + ], + }, + { + "role": "user", + "content": [{"type": "text", "text": "who are you?"}], + } +] + + +# Conversation with mixed media +conversation4 = [ + { + "role": "system", + "content": [ + {"type": "text", "text": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech."} + ], + }, + { + "role": "user", + "content": [ + {"type": "image", "path": "/path/to/image.jpg"}, + {"type": "video", "path": "/path/to/video.mp4"}, + {"type": "audio", "path": "/path/to/audio.wav"}, + {"type": "text", "text": "What are the elements can you see and hear in these medias?"}, + ], + } +] + +conversations = [conversation1, conversation2, conversation3, conversation4] + +inputs = processor.apply_chat_template( + conversations, + load_audio_from_video=True, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", + video_fps=1, + + # kwargs to be passed to `Qwen2-5-OmniProcessor` + padding=True, + use_audio_in_video=True, +).to(model.thinker.device) + +text_ids = model.generate(**inputs, use_audio_in_video=True) +text = processor.batch_decode(text_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False) + +print(text) +``` + +### Usage Tips + +#### Image Resolution trade-off + +The model supports a wide range of resolution inputs. By default, it uses the native resolution for input, but higher resolutions can enhance performance at the cost of more computation. Users can set the minimum and maximum number of pixels to achieve an optimal configuration for their needs. + +```python +min_pixels = 128*28*28 +max_pixels = 768*28*28 +processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B", min_pixels=min_pixels, max_pixels=max_pixels) +``` + +#### Prompt for audio output +If users need audio output, the system prompt must be set as "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech.", otherwise the audio output may not work as expected. +``` +{ + "role": "system", + "content": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech.", +} +``` + +#### Use audio output or not + +The model supports both text and audio outputs, if users do not need audio outputs, they can set `enable_audio_output` in the `from_pretrained` function. This option will save about `~2GB` of GPU memory but the `return_audio` option for `generate` function will only allow to be set at `False`. +```python +model = Qwen2_5OmniForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", + dtype="auto", + device_map="auto", + enable_audio_output=False, +) +``` + +In order to obtain a flexible experience, we recommend that users set `enable_audio_output` at `True` when initializing the model through `from_pretrained` function, and then decide whether to return audio when `generate` function is called. When `return_audio` is set to `False`, the model will only return text outputs to get text responses faster. + +```python +model = Qwen2_5OmniForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", + dtype="auto", + device_map="auto", + enable_audio_output=True, +) +... +text_ids = model.generate(**inputs, return_audio=False) +``` + +#### Change voice type of output audio +Qwen2.5-Omni supports the ability to change the voice of the output audio. Users can use the `spk` parameter of `generate` function to specify the voice type. The `"Qwen/Qwen2.5-Omni-7B"` checkpoint support two voice types: `Chelsie` and `Ethan`, while `Chelsie` is a female voice and `Ethan` is a male voice. By default, if `spk` is not specified, the default voice type is `Chelsie`. + +```python +text_ids, audio = model.generate(**inputs, spk="Chelsie") +``` + +```python +text_ids, audio = model.generate(**inputs, spk="Ethan") +``` + +#### Flash-Attention 2 to speed up generation + +First, make sure to install the latest version of Flash Attention 2: + +```bash +pip install -U flash-attn --no-build-isolation +``` + +Also, you should have hardware that is compatible with FlashAttention 2. Read more about it in the official documentation of the [flash attention repository](https://github.com/Dao-AILab/flash-attention). FlashAttention-2 can only be used when a model is loaded in `torch.float16` or `torch.bfloat16`. + +To load and run a model using FlashAttention-2, add `attn_implementation="flash_attention_2"` when loading the model: + +```python +from transformers import Qwen2_5OmniForConditionalGeneration + +model = Qwen2_5OmniForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", + device_map="auto", + dtype=torch.bfloat16, + attn_implementation="flash_attention_2", +) +``` + + + +## Qwen3OmniMoeConfig + +[[autodoc]] Qwen3OmniMoeConfig + +## Qwen3OmniMoeThinkerConfig + +[[autodoc]] Qwen3OmniMoeThinkerConfig + +## Qwen3OmniMoeTalkerConfig + +[[autodoc]] Qwen3OmniMoeTalkerConfig + +## Qwen3OmniMoeForConditionalGeneration + +[[autodoc]] Qwen3OmniMoeForConditionalGeneration + +## Qwen3OmniMoeThinkerTextModel + +[[autodoc]] Qwen3OmniMoeThinkerTextModel + +## Qwen3OmniMoeThinkerForConditionalGeneration + +[[autodoc]] Qwen3OmniMoeThinkerForConditionalGeneration + +## Qwen3OmniMoeTalkerForConditionalGeneration + +[[autodoc]] Qwen3OmniMoeTalkerForConditionalGeneration + +## Qwen3OmniMoePreTrainedModel + +[[autodoc]] Qwen3OmniMoePreTrainedModel + +## Qwen3OmniMoePreTrainedModelForConditionalGeneration + +[[autodoc]] Qwen3OmniMoePreTrainedModelForConditionalGeneration + +## Qwen3OmniMoeTalkerModel + +[[autodoc]] Qwen3OmniMoeTalkerModel + +## Qwen3OmniMoeThinkerTextPreTrainedModel + +[[autodoc]] Qwen3OmniMoeThinkerTextPreTrainedModel + +## Qwen3OmniMoeProcessor + +[[autodoc]] Qwen3OmniMoeProcessor + +## Qwen3OmniMoeCode2Wav + +[[autodoc]] Qwen3OmniMoeCode2Wav + +## Qwen3OmniMoeCode2WavDecoderBlock + +[[autodoc]] Qwen3OmniMoeCode2WavDecoderBlock + +## Qwen3OmniMoeCode2WavTransformerModel + +[[autodoc]] Qwen3OmniMoeCode2WavTransformerModel + +## Qwen3OmniMoeTalkerCodePredictorModel + +[[autodoc]] Qwen3OmniMoeTalkerCodePredictorModel + +## Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration + +[[autodoc]] Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration + + diff --git a/src/transformers/models/__init__.py b/src/transformers/models/__init__.py index f0939b089977..1eb2b905ca4c 100644 --- a/src/transformers/models/__init__.py +++ b/src/transformers/models/__init__.py @@ -283,6 +283,7 @@ from .qwen3 import * from .qwen3_moe import * from .qwen3_next import * + from .qwen3_omni_moe import * from .qwen3_vl import * from .qwen3_vl_moe import * from .rag import * diff --git a/src/transformers/models/auto/configuration_auto.py b/src/transformers/models/auto/configuration_auto.py index ec6ce58f7994..0ee87f723d60 100644 --- a/src/transformers/models/auto/configuration_auto.py +++ b/src/transformers/models/auto/configuration_auto.py @@ -330,6 +330,7 @@ ("qwen3", "Qwen3Config"), ("qwen3_moe", "Qwen3MoeConfig"), ("qwen3_next", "Qwen3NextConfig"), + ("qwen3_omni_moe", "Qwen3OmniMoeConfig"), ("qwen3_vl", "Qwen3VLConfig"), ("qwen3_vl_moe", "Qwen3VLMoeConfig"), ("qwen3_vl_moe_text", "Qwen3VLMoeTextConfig"), @@ -779,6 +780,7 @@ ("qwen3", "Qwen3"), ("qwen3_moe", "Qwen3MoE"), ("qwen3_next", "Qwen3Next"), + ("qwen3_omni_moe", "Qwen3OmniMoE"), ("qwen3_vl", "Qwen3VL"), ("qwen3_vl_moe", "Qwen3VLMoe"), ("qwen3_vl_moe_text", "Qwen3VLMoe"), diff --git a/src/transformers/models/auto/modeling_auto.py b/src/transformers/models/auto/modeling_auto.py index 3d0ee2e9fcbd..01036e76222b 100644 --- a/src/transformers/models/auto/modeling_auto.py +++ b/src/transformers/models/auto/modeling_auto.py @@ -1654,6 +1654,7 @@ class _BaseModelWithGenerate(PreTrainedModel, GenerationMixin): ("musicgen", "MusicgenForConditionalGeneration"), ("musicgen_melody", "MusicgenMelodyForConditionalGeneration"), ("qwen2_5_omni", "Qwen2_5OmniForConditionalGeneration"), + ("qwen3_omni_moe", "Qwen3OmniMoeForConditionalGeneration"), ("seamless_m4t", "SeamlessM4TForTextToSpeech"), ("seamless_m4t_v2", "SeamlessM4Tv2ForTextToSpeech"), ("vits", "VitsModel"), diff --git a/src/transformers/models/auto/processing_auto.py b/src/transformers/models/auto/processing_auto.py index c455c6850844..2b1ca09bb8df 100644 --- a/src/transformers/models/auto/processing_auto.py +++ b/src/transformers/models/auto/processing_auto.py @@ -121,6 +121,7 @@ ("qwen2_5_vl", "Qwen2_5_VLProcessor"), ("qwen2_audio", "Qwen2AudioProcessor"), ("qwen2_vl", "Qwen2VLProcessor"), + ("qwen3_omni_moe", "Qwen3OmniMoeProcessor"), ("qwen3_vl", "Qwen3VLProcessor"), ("qwen3_vl_moe", "Qwen3VLProcessor"), ("sam", "SamProcessor"), diff --git a/src/transformers/models/auto/tokenization_auto.py b/src/transformers/models/auto/tokenization_auto.py index 52726fd6200a..c79bb7167b9a 100644 --- a/src/transformers/models/auto/tokenization_auto.py +++ b/src/transformers/models/auto/tokenization_auto.py @@ -586,6 +586,7 @@ "Qwen2TokenizerFast" if is_tokenizers_available() else None, ), ), + ("qwen3_omni_moe", ("Qwen2Tokenizer", "Qwen2TokenizerFast" if is_tokenizers_available() else None)), ("qwen3_vl", ("Qwen2Tokenizer", "Qwen2TokenizerFast" if is_tokenizers_available() else None)), ("qwen3_vl_moe", ("Qwen2Tokenizer", "Qwen2TokenizerFast" if is_tokenizers_available() else None)), ("rag", ("RagTokenizer", None)), diff --git a/src/transformers/models/auto/video_processing_auto.py b/src/transformers/models/auto/video_processing_auto.py index 551de914626e..84bbc8e6fdb1 100644 --- a/src/transformers/models/auto/video_processing_auto.py +++ b/src/transformers/models/auto/video_processing_auto.py @@ -56,6 +56,7 @@ ("qwen2_5_omni", "Qwen2VLVideoProcessor"), ("qwen2_5_vl", "Qwen2VLVideoProcessor"), ("qwen2_vl", "Qwen2VLVideoProcessor"), + ("qwen3_omni_moe", "Qwen2VLVideoProcessor"), ("qwen3_vl", "Qwen3VLVideoProcessor"), ("qwen3_vl_moe", "Qwen3VLVideoProcessor"), ("sam2_video", "Sam2VideoVideoProcessor"), diff --git a/src/transformers/models/qwen2_5_omni/processing_qwen2_5_omni.py b/src/transformers/models/qwen2_5_omni/processing_qwen2_5_omni.py index 45d8cacddeb2..3d9d5f1066ef 100644 --- a/src/transformers/models/qwen2_5_omni/processing_qwen2_5_omni.py +++ b/src/transformers/models/qwen2_5_omni/processing_qwen2_5_omni.py @@ -31,10 +31,10 @@ class Qwen2_5_OmniVideosKwargs(VideosKwargs): - fps: Optional[list[Union[int, float]]] = None - use_audio_in_video: Optional[bool] = None - seconds_per_chunk: Optional[float] = None - position_id_per_seconds: Optional[int] = None + fps: Optional[list[Union[int, float]]] + use_audio_in_video: Optional[bool] + seconds_per_chunk: Optional[float] + position_id_per_seconds: Optional[int] min_pixels: Optional[int] max_pixels: Optional[int] patch_size: Optional[int] diff --git a/src/transformers/models/qwen3_omni_moe/__init__.py b/src/transformers/models/qwen3_omni_moe/__init__.py new file mode 100644 index 000000000000..bd9da3809533 --- /dev/null +++ b/src/transformers/models/qwen3_omni_moe/__init__.py @@ -0,0 +1,28 @@ +# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved. +# +# 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. +from typing import TYPE_CHECKING + +from ...utils import _LazyModule +from ...utils.import_utils import define_import_structure + + +if TYPE_CHECKING: + from .configuration_qwen3_omni_moe import * + from .modeling_qwen3_omni_moe import * + from .processing_qwen3_omni_moe import * +else: + import sys + + _file = globals()["__file__"] + sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__) diff --git a/src/transformers/models/qwen3_omni_moe/configuration_qwen3_omni_moe.py b/src/transformers/models/qwen3_omni_moe/configuration_qwen3_omni_moe.py new file mode 100644 index 000000000000..8eefcc595261 --- /dev/null +++ b/src/transformers/models/qwen3_omni_moe/configuration_qwen3_omni_moe.py @@ -0,0 +1,1250 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_qwen3_omni_moe.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 The Qwen team, Alibaba Group and the HuggingFace Inc. team. All rights reserved. +# +# +# 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. +from ...configuration_utils import PretrainedConfig, layer_type_validation +from ...modeling_rope_utils import rope_config_validation +from ...utils import logging + + +logger = logging.get_logger(__name__) + + +class Qwen3OmniMoeAudioEncoderConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3OmniMoeAudioEncoder`]. It is used to instantiate a + Qwen2.5-Omni-Thinker audio encoder according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the audio encoder of the Qwen2-Audio + architecture. + + e.g. [Qwen/Qwen2.5-Omni-7B](https://huggingface.co/Qwen/Qwen2.5-Omni-7B) + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + num_mel_bins (`int`, *optional*, defaults to 128): + Number of mel features used per input features. Should correspond to the value used in the + `Qwen3OmniMoeProcessor` class. + encoder_layers (`int`, *optional*, defaults to 32): + Number of encoder layers. + encoder_attention_heads (`int`, *optional*, defaults to 20): + Number of attention heads for each attention layer in the Transformer encoder. + encoder_ffn_dim (`int`, *optional*, defaults to 5120): + Dimensionality of the "intermediate" (often named feed-forward) layer in encoder. + d_model (`int`, *optional*, defaults to 1280): + Dimensionality of the layers. + dropout (`float`, *optional*, defaults to 0.0): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + activation_function (`str`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + activation_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for activations inside the fully connected layer. + scale_embedding (`bool`, *optional*, defaults to `False`): + Scale embeddings by diving by sqrt(d_model). + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + max_source_positions (`int`, *optional*, defaults to 1500): + The maximum sequence length of log-mel filter-bank features that this model might ever be used with. + n_window (`int`, *optional*, defaults to 100): + The chunk for conv and flash attn in AudioEncoder. + output_dim (`int`, *optional*, defaults to 3584): + The output dimension of AudioEncoder. + + Example: + + ```python + >>> from transformers import Qwen3OmniMoeAudioEncoderConfig, Qwen3OmniMoeAudioEncoder + + >>> # Initializing a Qwen3OmniMoeAudioEncoderConfig + >>> configuration = Qwen3OmniMoeAudioEncoderConfig() + + >>> # Initializing a Qwen3OmniMoeAudioEncoder (with random weights) + >>> model = Qwen3OmniMoeAudioEncoder(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_omni_moe_audio_encoder" + + def __init__( + self, + num_mel_bins=128, + encoder_layers=32, + encoder_attention_heads=20, + encoder_ffn_dim=5120, + d_model=1280, + dropout=0, + attention_dropout=0, + activation_function="gelu", + activation_dropout=0, + scale_embedding=False, + initializer_range=0.02, + max_source_positions=1500, + n_window=100, + output_dim=3584, + n_window_infer=400, + conv_chunksize=500, + downsample_hidden_size=480, + **kwargs, + ): + super().__init__(**kwargs) + + self.num_mel_bins = num_mel_bins + self.d_model = d_model + self.encoder_layers = encoder_layers + self.encoder_attention_heads = encoder_attention_heads + self.encoder_ffn_dim = encoder_ffn_dim + self.dropout = dropout + self.attention_dropout = attention_dropout + self.activation_function = activation_function + self.activation_dropout = activation_dropout + self.num_hidden_layers = encoder_layers + self.initializer_range = initializer_range + self.scale_embedding = scale_embedding # scale factor will be sqrt(d_model) if True + self.max_source_positions = max_source_positions + self.n_window = n_window + self.output_dim = output_dim + self.n_window_infer = n_window_infer + self.conv_chunksize = conv_chunksize + self.downsample_hidden_size = downsample_hidden_size + + +class Qwen3OmniMoeVisionEncoderConfig(PretrainedConfig): + model_type = "qwen3_omni_moe_vision_encoder" + base_config_key = "vision_config" + + def __init__( + self, + depth=27, + hidden_size=1152, + hidden_act="gelu_pytorch_tanh", + intermediate_size=4304, + num_heads=16, + in_channels=3, + patch_size=16, + spatial_merge_size=2, + temporal_patch_size=2, + out_hidden_size=3584, + num_position_embeddings=2304, + deepstack_visual_indexes=[8, 16, 24], + initializer_range=0.02, + **kwargs, + ): + super().__init__(**kwargs) + + self.depth = depth + self.hidden_size = hidden_size + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.num_heads = num_heads + self.in_channels = in_channels + self.patch_size = patch_size + self.spatial_merge_size = spatial_merge_size + self.temporal_patch_size = temporal_patch_size + self.out_hidden_size = out_hidden_size + self.num_position_embeddings = num_position_embeddings + self.initializer_range = initializer_range + self.deepstack_visual_indexes = deepstack_visual_indexes + + +class Qwen3OmniMoeTextConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3OmniMoeTextModel`]. It is used to instantiate a + Qwen3OmniMoeText model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of [Qwen/Qwen3-15B-A2B](https://huggingface.co/Qwen/Qwen3-15B-A2B). + + 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 151936): + Vocabulary size of the Qwen3OmniMoeText model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`Qwen3OmniMoeTextModel`] + hidden_size (`int`, *optional*, defaults to 2048): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 6144): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 24): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 32): + Number of attention heads for each attention layer in the Transformer encoder. + num_key_value_heads (`int`, *optional*, defaults to 4): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to `32`. + + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 32768): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether the model's input and output word embeddings should be tied. + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period of the RoPE embeddings. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type + and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value + accordingly. + Expected contents: + `rope_type` (`str`): + The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope', + 'llama3'], with 'default' being the original RoPE implementation. + `factor` (`float`, *optional*): + Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In + most scaling types, a `factor` of x will enable the model to handle sequences of length x * + original maximum pre-trained length. + `original_max_position_embeddings` (`int`, *optional*): + Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during + pretraining. + `attention_factor` (`float`, *optional*): + Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention + computation. If unspecified, it defaults to value recommended by the implementation, using the + `factor` field to infer the suggested value. + `beta_fast` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear + ramp function. If unspecified, it defaults to 32. + `beta_slow` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear + ramp function. If unspecified, it defaults to 1. + `short_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to short contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `long_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to long contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `low_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE + `high_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + use_sliding_window (`bool`, *optional*, defaults to `False`): + Whether to use sliding window attention. + sliding_window (`int`, *optional*, defaults to 4096): + Sliding window attention (SWA) window size. If not specified, will default to `4096`. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + decoder_sparse_step (`int`, *optional*, defaults to 1): + The frequency of the MoE layer. + moe_intermediate_size (`int`, *optional*, defaults to 768): + Intermediate size of the routed expert. + num_experts_per_tok (`int`, *optional*, defaults to 8): + Number of selected experts. + num_experts (`int`, *optional*, defaults to 128): + Number of routed experts. + norm_topk_prob (`bool`, *optional*, defaults to `False`): + Whether to normalize the topk probabilities. + output_router_logits (`bool`, *optional*, defaults to `False`): + Whether or not the router logits should be returned by the model. Enabling this will also + allow the model to output the auxiliary loss, including load balancing loss and router z-loss. + router_aux_loss_coef (`float`, *optional*, defaults to 0.001): + The aux loss factor for the total loss. + mlp_only_layers (`list[int]`, *optional*, defaults to `[]`): + Indicate which layers use Qwen3OmniMoeTextMLP rather than Qwen3OmniMoeTextSparseMoeBlock + The list contains layer index, from 0 to num_layers-1 if we have num_layers layers + If `mlp_only_layers` is empty, `decoder_sparse_step` is used to determine the sparsity. + + ```python + >>> from transformers import Qwen3OmniMoeTextModel, Qwen3OmniMoeTextConfig + + >>> # Initializing a Qwen3OmniMoeText style configuration + >>> configuration = Qwen3OmniMoeTextConfig() + + >>> # Initializing a model from the Qwen3-15B-A2B" style configuration + >>> model = Qwen3OmniMoeTextModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_omni_moe_text" + keys_to_ignore_at_inference = ["past_key_values"] + + # Default tensor parallel plan for base model `Qwen3OmniMoeText` + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise", + "layers.*.self_attn.k_proj": "colwise", + "layers.*.self_attn.v_proj": "colwise", + "layers.*.self_attn.o_proj": "rowwise", + "layers.*.mlp.experts.*.gate_proj": "colwise", + "layers.*.mlp.experts.*.up_proj": "colwise", + "layers.*.mlp.experts.*.down_proj": "rowwise", + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=3584, + hidden_size=2048, + intermediate_size=18944, + num_hidden_layers=28, + num_attention_heads=28, + num_key_value_heads=4, + hidden_act="silu", + max_position_embeddings=32768, + initializer_range=0.02, + rms_norm_eps=1e-6, + use_cache=True, + tie_word_embeddings=False, + rope_theta=1000000.0, + rope_scaling=None, + attention_bias=False, + sliding_window=None, + attention_dropout=0, + decoder_sparse_step=1, + moe_intermediate_size=768, + num_experts_per_tok=8, + num_experts=128, + norm_topk_prob=True, + output_router_logits=False, + router_aux_loss_coef=0.001, + mlp_only_layers=None, + **kwargs, + ): + super().__init__( + tie_word_embeddings=tie_word_embeddings, + **kwargs, + ) + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.sliding_window = sliding_window + + self.num_key_value_heads = num_key_value_heads + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + # Validate the correctness of rotary position embeddings parameters + # BC: if there is a 'type' field, move it to 'rope_type'. + if self.rope_scaling is not None and "type" in self.rope_scaling: + self.rope_scaling["rope_type"] = self.rope_scaling["type"] + rope_config_validation(self) + + # MoE arguments + self.decoder_sparse_step = decoder_sparse_step + self.moe_intermediate_size = moe_intermediate_size + self.num_experts_per_tok = num_experts_per_tok + self.num_experts = num_experts + self.norm_topk_prob = norm_topk_prob + self.output_router_logits = output_router_logits + self.router_aux_loss_coef = router_aux_loss_coef + self.mlp_only_layers = [] if mlp_only_layers is None else mlp_only_layers + + +class Qwen3OmniMoeThinkerConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3OmniMoeThinker`]. It is used to instantiate a + Qwen3-Omni-Thinker 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 thinker component of the Qwen3-Omni + architecture. + + e.g. [Qwen/Qwen3-Omni-7B](https://huggingface.co/Qwen/Qwen3-Omni-7B) + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + audio_config (`dict`, *optional*): + The config dictionary of the audio backbone. + vision_config (`dict`, *optional*): + The config dictionary of the vision backbone. + text_config (`dict`, *optional*): + The config dictionary of the text backbone. + audio_token_id (`int`, *optional*, defaults to 151646): + The audio token id to encode the audio prompt. + image_token_id (`int`, *optional*, defaults to 151655): + The image token id to encode the image prompt. + video_token_id (`int`, *optional*, defaults to 151656): + The video token id to encode the video prompt. + position_id_per_seconds (`int`, *optional*, defaults to 25): + The increment of position id per second. + audio_start_token_id (`int`, *optional*, defaults to 151647): + The audio start token id to encode the audio prompt. + user_token_id (`int`, *optional*, defaults to 872): + The user token id to encode the user token. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + + Example: + + ```python + >>> from transformers import Qwen3OmniMoeThinkerModel, Qwen3OmniMoeThinkerConfig + + >>> # Initializing a default Qwen3OmniMoeThinkerConfig + >>> configuration = Qwen3OmniMoeThinkerConfig() + + >>> # Initializing a model (with random weights) from the default configuration + >>> model = Qwen3OmniMoeThinkerModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_omni_moe_thinker" + attribute_map = { + "image_token_id": "image_token_index", + "video_token_id": "video_token_index", + "audio_token_id": "audio_token_index", + } + sub_configs = { + "audio_config": Qwen3OmniMoeAudioEncoderConfig, + "vision_config": Qwen3OmniMoeVisionEncoderConfig, + "text_config": Qwen3OmniMoeTextConfig, + } + + def __init__( + self, + audio_config=None, + vision_config=None, + text_config=None, + audio_token_id=151646, + image_token_id=151655, + video_token_id=151656, + position_id_per_seconds=25, + audio_start_token_id=151647, + user_token_id=872, + initializer_range=0.02, + **kwargs, + ): + super().__init__(**kwargs) + self.user_token_id = user_token_id + self.position_id_per_seconds = position_id_per_seconds + self.audio_start_token_id = audio_start_token_id + self.initializer_range = initializer_range + + if isinstance(vision_config, dict): + vision_config = Qwen3OmniMoeVisionEncoderConfig(**vision_config) + elif vision_config is None: + vision_config = Qwen3OmniMoeVisionEncoderConfig() + self.vision_config = vision_config + + if isinstance(audio_config, dict): + audio_config = Qwen3OmniMoeAudioEncoderConfig(**audio_config) + elif audio_config is None: + audio_config = Qwen3OmniMoeAudioEncoderConfig() + self.audio_config = audio_config + + if isinstance(text_config, dict): + text_config = Qwen3OmniMoeTextConfig(**text_config) + elif text_config is None: + text_config = Qwen3OmniMoeTextConfig() + self.text_config = text_config + self.audio_token_id = audio_token_id + self.image_token_id = image_token_id + self.video_token_id = video_token_id + + +class Qwen3OmniMoeTalkerCodePredictorConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3OmniMoeTalkerCodePredictorModel`]. It is used to instantiate a + Qwen3OmniMoeTalkerCodePredictor model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of + Qwen3OmniMoeTalkerCodePredictor-8B [Qwen/Qwen3OmniMoeTalkerCodePredictor-8B](https://huggingface.co/Qwen/Qwen3OmniMoeTalkerCodePredictor-8B). + + 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 151936): + Vocabulary size of the Qwen3OmniMoeTalkerCodePredictor model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`Qwen3OmniMoeTalkerCodePredictorModel`] + hidden_size (`int`, *optional*, defaults to 4096): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 22016): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 32): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 32): + Number of attention heads for each attention layer in the Transformer encoder. + num_key_value_heads (`int`, *optional*, defaults to 32): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to `32`. + head_dim (`int`, *optional*, defaults to 128): + The attention head dimension. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 32768): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether the model's input and output word embeddings should be tied. + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period of the RoPE embeddings. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type + and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value + accordingly. + Expected contents: + `rope_type` (`str`): + The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope', + 'llama3'], with 'default' being the original RoPE implementation. + `factor` (`float`, *optional*): + Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In + most scaling types, a `factor` of x will enable the model to handle sequences of length x * + original maximum pre-trained length. + `original_max_position_embeddings` (`int`, *optional*): + Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during + pretraining. + `attention_factor` (`float`, *optional*): + Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention + computation. If unspecified, it defaults to value recommended by the implementation, using the + `factor` field to infer the suggested value. + `beta_fast` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear + ramp function. If unspecified, it defaults to 32. + `beta_slow` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear + ramp function. If unspecified, it defaults to 1. + `short_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to short contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `long_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to long contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `low_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE + `high_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + use_sliding_window (`bool`, *optional*, defaults to `False`): + Whether to use sliding window attention. + sliding_window (`int`, *optional*, defaults to 4096): + Sliding window attention (SWA) window size. If not specified, will default to `4096`. + max_window_layers (`int`, *optional*, defaults to 28): + The number of layers using full attention. The first `max_window_layers` layers will use full attention, while any + additional layer afterwards will use SWA (Sliding Window Attention). + layer_types (`list`, *optional*): + Attention pattern for each layer. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + + ```python + >>> from transformers import Qwen3OmniMoeTalkerCodePredictorModel, Qwen3OmniMoeTalkerCodePredictorConfig + + >>> # Initializing a Qwen3OmniMoeTalkerCodePredictor style configuration + >>> configuration = Qwen3OmniMoeTalkerCodePredictorConfig() + + >>> # Initializing a model from the Qwen3OmniMoeTalkerCodePredictor-8B style configuration + >>> model = Qwen3OmniMoeTalkerCodePredictorModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_omni_moe_talker_code_predictor" + keys_to_ignore_at_inference = ["past_key_values"] + + # Default tensor parallel plan for base model `Qwen3OmniMoeTalkerCodePredictor` + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise", + "layers.*.self_attn.k_proj": "colwise", + "layers.*.self_attn.v_proj": "colwise", + "layers.*.self_attn.o_proj": "rowwise", + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=2048, + hidden_size=1024, + intermediate_size=3072, + num_hidden_layers=5, + num_attention_heads=16, + num_key_value_heads=8, + head_dim=128, + hidden_act="silu", + max_position_embeddings=32768, + initializer_range=0.02, + rms_norm_eps=0.000001, + use_cache=True, + tie_word_embeddings=False, + rope_theta=10000, + rope_scaling=None, + attention_bias=False, + sliding_window=None, + layer_types=None, + attention_dropout=0, + num_code_groups=32, + **kwargs, + ): + super().__init__( + tie_word_embeddings=tie_word_embeddings, + **kwargs, + ) + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.sliding_window = sliding_window + + # for backward compatibility + if num_key_value_heads is None: + num_key_value_heads = num_attention_heads + + self.num_key_value_heads = num_key_value_heads + self.head_dim = head_dim + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + # Validate the correctness of rotary position embeddings parameters + # BC: if there is a 'type' field, move it to 'rope_type'. + if self.rope_scaling is not None and "type" in self.rope_scaling: + self.rope_scaling["rope_type"] = self.rope_scaling["type"] + rope_config_validation(self) + + self.layer_types = layer_types + if self.layer_types is None: + self.layer_types = [ + "sliding_attention" + if self.sliding_window is not None and i >= self.max_window_layers + else "full_attention" + for i in range(self.num_hidden_layers) + ] + layer_type_validation(self.layer_types, self.num_hidden_layers) + self.num_code_groups = num_code_groups + + +class Qwen3OmniMoeTalkerTextConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3OmniMoeTalkerTextModel`]. It is used to instantiate a + Qwen3OmniMoeTalkerText model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of [Qwen/Qwen3-15B-A2B](https://huggingface.co/Qwen/Qwen3-15B-A2B). + + 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 151936): + Vocabulary size of the Qwen3OmniMoeTalkerText model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`Qwen3OmniMoeTalkerTextModel`] + hidden_size (`int`, *optional*, defaults to 2048): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 6144): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 24): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 32): + Number of attention heads for each attention layer in the Transformer encoder. + num_key_value_heads (`int`, *optional*, defaults to 4): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to `32`. + + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in the decoder. + max_position_embeddings (`int`, *optional*, defaults to 32768): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + tie_word_embeddings (`bool`, *optional*, defaults to `False`): + Whether the model's input and output word embeddings should be tied. + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period of the RoPE embeddings. + rope_scaling (`Dict`, *optional*): + Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type + and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value + accordingly. + Expected contents: + `rope_type` (`str`): + The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope', + 'llama3'], with 'default' being the original RoPE implementation. + `factor` (`float`, *optional*): + Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In + most scaling types, a `factor` of x will enable the model to handle sequences of length x * + original maximum pre-trained length. + `original_max_position_embeddings` (`int`, *optional*): + Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during + pretraining. + `attention_factor` (`float`, *optional*): + Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention + computation. If unspecified, it defaults to value recommended by the implementation, using the + `factor` field to infer the suggested value. + `beta_fast` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear + ramp function. If unspecified, it defaults to 32. + `beta_slow` (`float`, *optional*): + Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear + ramp function. If unspecified, it defaults to 1. + `short_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to short contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `long_factor` (`list[float]`, *optional*): + Only used with 'longrope'. The scaling factor to be applied to long contexts (< + `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden + size divided by the number of attention heads divided by 2 + `low_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE + `high_freq_factor` (`float`, *optional*): + Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + use_sliding_window (`bool`, *optional*, defaults to `False`): + Whether to use sliding window attention. + sliding_window (`int`, *optional*, defaults to 4096): + Sliding window attention (SWA) window size. If not specified, will default to `4096`. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + decoder_sparse_step (`int`, *optional*, defaults to 1): + The frequency of the MoE layer. + moe_intermediate_size (`int`, *optional*, defaults to 768): + Intermediate size of the routed expert. + num_experts_per_tok (`int`, *optional*, defaults to 8): + Number of selected experts. + num_experts (`int`, *optional*, defaults to 128): + Number of routed experts. + norm_topk_prob (`bool`, *optional*, defaults to `False`): + Whether to normalize the topk probabilities. + output_router_logits (`bool`, *optional*, defaults to `False`): + Whether or not the router logits should be returned by the model. Enabling this will also + allow the model to output the auxiliary loss, including load balancing loss and router z-loss. + router_aux_loss_coef (`float`, *optional*, defaults to 0.001): + The aux loss factor for the total loss. + mlp_only_layers (`list[int]`, *optional*, defaults to `[]`): + Indicate which layers use Qwen3OmniMoeTalkerTextMLP rather than Qwen3OmniMoeTalkerTextSparseMoeBlock + The list contains layer index, from 0 to num_layers-1 if we have num_layers layers + If `mlp_only_layers` is empty, `decoder_sparse_step` is used to determine the sparsity. + + ```python + >>> from transformers import Qwen3OmniMoeTalkerTextModel, Qwen3OmniMoeTalkerTextConfig + + >>> # Initializing a Qwen3OmniMoeTalkerText style configuration + >>> configuration = Qwen3OmniMoeTalkerTextConfig() + + >>> # Initializing a model from the Qwen3-15B-A2B" style configuration + >>> model = Qwen3OmniMoeTalkerTextModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_omni_moe_talker_text" + keys_to_ignore_at_inference = ["past_key_values"] + + # Default tensor parallel plan for base model `Qwen3OmniMoeTalkerText` + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise", + "layers.*.self_attn.k_proj": "colwise", + "layers.*.self_attn.v_proj": "colwise", + "layers.*.self_attn.o_proj": "rowwise", + "layers.*.mlp.experts.*.gate_proj": "colwise", + "layers.*.mlp.experts.*.up_proj": "colwise", + "layers.*.mlp.experts.*.down_proj": "rowwise", + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=3072, + hidden_size=1024, + intermediate_size=2048, + num_hidden_layers=20, + num_attention_heads=16, + num_key_value_heads=2, + hidden_act="silu", + max_position_embeddings=32768, + initializer_range=0.02, + rms_norm_eps=0.000001, + use_cache=True, + tie_word_embeddings=False, + rope_theta=10000, + rope_scaling=None, + attention_bias=False, + sliding_window=None, + attention_dropout=0, + decoder_sparse_step=1, + moe_intermediate_size=384, + num_experts_per_tok=8, + num_experts=128, + norm_topk_prob=False, + output_router_logits=False, + router_aux_loss_coef=0.001, + mlp_only_layers=None, + **kwargs, + ): + super().__init__( + tie_word_embeddings=tie_word_embeddings, + **kwargs, + ) + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.sliding_window = sliding_window + + self.num_key_value_heads = num_key_value_heads + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.rope_theta = rope_theta + self.rope_scaling = rope_scaling + self.attention_bias = attention_bias + self.attention_dropout = attention_dropout + # Validate the correctness of rotary position embeddings parameters + # BC: if there is a 'type' field, move it to 'rope_type'. + if self.rope_scaling is not None and "type" in self.rope_scaling: + self.rope_scaling["rope_type"] = self.rope_scaling["type"] + rope_config_validation(self) + + # MoE arguments + self.decoder_sparse_step = decoder_sparse_step + self.moe_intermediate_size = moe_intermediate_size + self.num_experts_per_tok = num_experts_per_tok + self.num_experts = num_experts + self.norm_topk_prob = norm_topk_prob + self.output_router_logits = output_router_logits + self.router_aux_loss_coef = router_aux_loss_coef + self.mlp_only_layers = [] if mlp_only_layers is None else mlp_only_layers + + +class Qwen3OmniMoeTalkerConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3OmniMoeTalker`]. It is used to instantiate a + Qwen3-Omni multi-modal talker model capable of handling text, audio, and vision modalities in a unified architecture. + The model integrates a text decoder with a code predictor for autoregressive generation of both semantic and acoustic + tokens, enabling speech and multimodal content generation. This configuration wraps sub-configurations for the text and + code predictor components, allowing modular setup and initialization. + + e.g. [Qwen/Qwen3-Omni-7B](https://huggingface.co/Qwen/Qwen3-Omni-7B) + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + code_predictor_config (`dict`, *optional*): + A dictionary of configuration parameters used to initialize a [`Qwen3OmniMoeTalkerCodePredictorConfig`]. + If not provided, defaults will be used. + text_config (`dict`, *optional*): + A dictionary of configuration parameters used to initialize a [`Qwen3OmniMoeTalkerTextConfig`]. + If not provided, defaults will be used. + num_code_groups (`int`, *optional*, defaults to 32): + Number of codebook groups used in the predicted acoustic token sequence, corresponding to multi-codebook VQ representation. + thinker_hidden_size (`int`, *optional*, defaults to 2048): + Hidden dimension size of the thinker module used for intermediate reasoning or latent planning before audio generation. + codec_eos_token_id (`int`, *optional*, defaults to 4198): + Token ID representing the end-of-speech token in the codec-generated sequence. + accept_hidden_layer (`int`, *optional*, defaults to 18): + Index of the hidden layer whose output is used for accepting or refining generated tokens during think-and-speak process. + codec_nothink_id (`int`, *optional*, defaults to 4203): + Token ID indicating no thinking step is required during generation. + codec_think_bos_id (`int`, *optional*, defaults to 4204): + Token ID marking the beginning of a thinking sequence. + codec_think_eos_id (`int`, *optional*, defaults to 4205): + Token ID marking the end of a thinking sequence. + codec_pad_id (`int`, *optional*, defaults to 4196): + Padding token ID used in codec input sequences. + codec_bos_id (`int`, *optional*, defaults to 4197): + Beginning-of-speech token ID in codec sequences. + audio_token_id (`int`, *optional*, defaults to 151646): + Special token ID used to indicate the position of audio tokens in the input sequence. + image_token_id (`int`, *optional*, defaults to 151655): + Special token ID used to represent image inputs in the multimodal context. + video_token_id (`int`, *optional*, defaults to 151656): + Special token ID used to represent video inputs. + vision_start_token_id (`int`, *optional*, defaults to 151652): + Token ID indicating the start of a visual input sequence (e.g., image or video embeddings). + position_id_per_seconds (`int`, *optional*, defaults to 25): + Number of position IDs allocated per second of audio content, used for temporal alignment in generation. + audio_start_token_id (`int`, *optional*, defaults to 151669): + Token ID that indicates the start of an audio generation segment in the output. + speaker_id (`dict`, *optional*): + Speaker name to speaker id dict. + + Example: + + ```python + >>> from transformers import Qwen3OmniMoeTalkerConfig, Qwen3OmniMoeTalker + + >>> # Initialize a Qwen3OmniMoeTalkerConfig with default sub-configurations + >>> config = Qwen3OmniMoeTalkerConfig( + ... num_code_groups=32, + ... thinker_hidden_size=2048, + ... ) + + >>> # Initialize the full Qwen3-Omni Talker model + >>> model = Qwen3OmniMoeTalker(config) + + >>> # Access the model configuration + >>> config = model.config + >>> print(config.text_config) # Access text decoder configuration + >>> print(config.code_predictor_config) # Access code predictor configuration + ```""" + + sub_configs = { + "code_predictor_config": Qwen3OmniMoeTalkerCodePredictorConfig, + "text_config": Qwen3OmniMoeTalkerTextConfig, + } + + def __init__( + self, + code_predictor_config=None, + text_config=None, + num_code_groups=32, + thinker_hidden_size=2048, + codec_eos_token_id=4198, + accept_hidden_layer=18, + codec_nothink_id=4203, + codec_think_bos_id=4204, + codec_think_eos_id=4205, + codec_pad_id=4196, + codec_bos_id=4197, + audio_token_id=151646, + image_token_id=151655, + video_token_id=151656, + vision_start_token_id=151652, + position_id_per_seconds=25, + audio_start_token_id=151669, + speaker_id=None, + **kwargs, + ): + super().__init__(**kwargs) + if code_predictor_config is None: + code_predictor_config = {} + self.code_predictor_config = Qwen3OmniMoeTalkerCodePredictorConfig() + logger.info("code_predictor_config is None. Initializing code_predictor_config model with default values") + elif isinstance(code_predictor_config, Qwen3OmniMoeTalkerCodePredictorConfig): + self.code_predictor_config = code_predictor_config + else: + self.code_predictor_config = Qwen3OmniMoeTalkerCodePredictorConfig(**code_predictor_config) + + if text_config is None: + text_config = {} + self.text_config = Qwen3OmniMoeTalkerTextConfig() + logger.info("talker text_config is None. Initializing talker text model with default values") + elif isinstance(text_config, Qwen3OmniMoeTalkerTextConfig): + self.text_config = text_config + else: + self.text_config = Qwen3OmniMoeTalkerTextConfig(**text_config) + self.num_code_groups = num_code_groups + self.thinker_hidden_size = thinker_hidden_size + self.codec_eos_token_id = codec_eos_token_id + self.accept_hidden_layer = accept_hidden_layer + self.codec_nothink_id = codec_nothink_id + self.codec_think_bos_id = codec_think_bos_id + self.codec_think_eos_id = codec_think_eos_id + self.codec_pad_id = codec_pad_id + self.codec_bos_id = codec_bos_id + self.audio_token_id = audio_token_id + self.image_token_id = image_token_id + self.video_token_id = video_token_id + self.position_id_per_seconds = position_id_per_seconds + self.audio_start_token_id = audio_start_token_id + self.vision_start_token_id = vision_start_token_id + self.speaker_id = speaker_id + + +class Qwen3OmniMoeCode2WavConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3OmniMoeCode2WavConfig`]. It is used to instantiate a + Qwen3-Omni code-to-waveform decoder, responsible for converting discrete audio codes into high-fidelity waveforms. + The configuration defines the architecture of the decoder, including parameters for vector quantization, autoregressive modeling, + and upsampling layers. + + e.g. [Qwen/Qwen3-Omni-7B](https://huggingface.co/Qwen/Qwen3-Omni-7B) + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + codebook_size (`int`, *optional*, defaults to 2048): + Number of entries in each residual codebook used for acoustic token quantization. + hidden_size (`int`, *optional*, defaults to 1024): + Dimensionality of the hidden states and embeddings in the autoregressive transformer decoder. + max_position_embeddings (`int`, *optional*, defaults to 8000): + Maximum sequence length that the autoregressive decoder can handle. Determines positional embedding size. + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period for rotary position embeddings (RoPE) applied to attention layers. + num_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the decoder. + num_key_value_heads (`int`, *optional*, defaults to 16): + Number of key and value attention heads used in grouped-query attention (if applicable). + attention_bias (`bool`, *optional*, defaults to `False`): + Whether to use bias in the attention projection layers. + sliding_window (`int`, *optional*, defaults to 72): + Window size for local attention mechanism, limiting attention context to improve efficiency. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the feed-forward (intermediate) layer in each transformer block. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function used in the feed-forward layers. Supports `"silu"`, `"relu"`, `"gelu"`, etc. + layer_scale_initial_scale (`float`, *optional*, defaults to 0.01): + Initial value for LayerScale applied in transformer blocks, helping stabilize training. + rms_norm_eps (`float`, *optional*, defaults to 1e-5): + Epsilon value for RMS normalization layers to prevent division by zero. + num_hidden_layers (`int`, *optional*, defaults to 8): + Number of transformer blocks in the autoregressive decoder. + num_quantizers (`int`, *optional*, defaults to 16): + Number of residual vector quantizers used in the vocoder for fine-grained audio reconstruction. + upsample_rates (`Tuple[int]`, *optional*, defaults to `(8, 5, 4, 3)`): + Rate at which features are upsampled in the final waveform synthesis stage. + upsampling_ratios (`Tuple[int]`, *optional*, defaults to `(2, 2)`): + Ratios used in transposed convolutional layers to progressively upsample feature maps to waveform. + decoder_dim (`int`, *optional*, defaults to 1536): + Final dimensionality of the decoder's output before waveform generation. + attention_dropout (`float`, *optional*, defaults to 0.0): + Dropout probability applied to attention weights in the decoder. + + Example: + + ```python + >>> from transformers import Qwen3OmniMoeCode2WavConfig, Qwen3OmniMoeCode2WavModel + + >>> # Initializing a default Qwen3OmniMoeCode2WavConfig + >>> config = Qwen3OmniMoeCode2WavConfig() + + >>> # Initializing the Code2Wav model with the configuration + >>> model = Qwen3OmniMoeCode2WavModel(config) + + >>> # Accessing configuration + >>> config = model.config + ```""" + + def __init__( + self, + codebook_size=2048, + hidden_size=1024, + max_position_embeddings=8000, + rope_theta=10000, + num_attention_heads=16, + num_key_value_heads=16, + attention_bias=False, + sliding_window=72, + intermediate_size=3072, + hidden_act="silu", + layer_scale_initial_scale=0.01, + rms_norm_eps=1e-5, + num_hidden_layers=8, + num_quantizers=16, + upsample_rates=(8, 5, 4, 3), + upsampling_ratios=(2, 2), + decoder_dim=1536, + attention_dropout=0.0, + **kwargs, + ): + super().__init__(**kwargs) + self.codebook_size = codebook_size + self.hidden_size = hidden_size + self.max_position_embeddings = max_position_embeddings + self.rope_theta = rope_theta + self.num_attention_heads = num_attention_heads + self.num_key_value_heads = num_key_value_heads + self.attention_bias = attention_bias + self.sliding_window = sliding_window + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.layer_scale_initial_scale = layer_scale_initial_scale + self.rms_norm_eps = rms_norm_eps + self.num_hidden_layers = num_hidden_layers + self.num_quantizers = num_quantizers + self.upsample_rates = upsample_rates + self.upsampling_ratios = upsampling_ratios + self.decoder_dim = decoder_dim + self.attention_dropout = attention_dropout + + @property + def layer_types(self): + """ + All layer in code2wav should be sliding attention + """ + return ["sliding_attention"] * self.num_hidden_layers + + +class Qwen3OmniMoeConfig(PretrainedConfig): + """ + This is the configuration class to store the configuration of a [`Qwen3OmniMoeForConditionalGeneration`]. It is used to instantiate a Qwen3Omni + model according to the specified sub-models configurations, defining the model architecture. + + Instantiating a configuration with the defaults will yield a similar configuration to that of the + [Qwen/Qwen2.5-Omni-7B](https://huggingface.co/Qwen/Qwen2.5-Omni-7B) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + thinker_config (`dict`, *optional*): Configuration of the underlying thinker sub-model. + talker_config (`dict`, *optional*): Configuration of the underlying talker sub-model. + code2wav_config (`dict`, *optional*): Configuration of the underlying code2wav sub-model. + enable_audio_output (`bool`, *optional*, defaults to `True`): Whether enable audio output and load talker and code2wav module. + + Example: + + ```python + >>> from transformers import ( + ... Qwen3OmniMoeThinkerConfig, + ... Qwen3OmniMoeTalkerConfig, + ... Qwen3OmniMoeCode2WavConfig, + ... Qwen3OmniMoeForConditionalGeneration, + ... Qwen3OmniMoeConfig, + ... ) + + >>> # Initializing a Qwen3OmniMoe style configuration + >>> configuration = Qwen3OmniMoeConfig() + + >>> # Initializing a model from the configuration + >>> model = Qwen3OmniMoeForConditionalGeneration(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_omni_moe" + sub_configs = { + "thinker_config": Qwen3OmniMoeThinkerConfig, + "talker_config": Qwen3OmniMoeTalkerConfig, + "code2wav_config": Qwen3OmniMoeCode2WavConfig, + } + + def __init__( + self, + thinker_config=None, + talker_config=None, + code2wav_config=None, + enable_audio_output=True, + im_start_token_id=151644, + im_end_token_id=151645, + tts_pad_token_id=151671, + tts_bos_token_id=151672, + tts_eos_token_id=151673, + system_token_id=8948, + user_token_id=872, + assistant_token_id=77091, + **kwargs, + ): + super().__init__(**kwargs) + if thinker_config is None: + thinker_config = {} + logger.info("thinker_config is None. Initializing thinker model with default values") + + if talker_config is None: + talker_config = {} + logger.info("talker_config is None. Initializing talker model with default values") + + if code2wav_config is None: + code2wav_config = {} + logger.info("code2wav_config is None. Initializing code2wav model with default values") + + self.thinker_config = Qwen3OmniMoeThinkerConfig(**thinker_config) + self.talker_config = Qwen3OmniMoeTalkerConfig(**talker_config) + self.code2wav_config = Qwen3OmniMoeCode2WavConfig(**code2wav_config) + self.enable_audio_output = enable_audio_output + self.im_start_token_id = im_start_token_id + self.im_end_token_id = im_end_token_id + self.tts_pad_token_id = tts_pad_token_id + self.tts_bos_token_id = tts_bos_token_id + self.tts_eos_token_id = tts_eos_token_id + self.system_token_id = system_token_id + self.user_token_id = user_token_id + self.assistant_token_id = assistant_token_id + + def get_text_config(self, decoder=False) -> "PretrainedConfig": + """ + Returns the config that is meant to be used with text IO. On most models, it is the original config instance + itself. On specific composite models, it is under a set of valid names. + + Args: + decoder (`Optional[bool]`, *optional*, defaults to `False`): + If set to `True`, then only search for decoder config names. + """ + # Overridden for deeply nested config like Qwen2-Omni. We don't have any omni model + # except for Qwen yet. This has to be generalized if more deeply nested configs are + # added. NOTE: currently method used only by vLLM + return self.thinker_config.get_text_config() + + +__all__ = ["Qwen3OmniMoeConfig", "Qwen3OmniMoeThinkerConfig", "Qwen3OmniMoeTalkerConfig"] diff --git a/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py b/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py new file mode 100644 index 000000000000..2ddc4d656530 --- /dev/null +++ b/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py @@ -0,0 +1,4067 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_qwen3_omni_moe.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 The Qwen team, Alibaba Group and the HuggingFace Inc. team. All rights reserved. +# +# +# 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. + +import math +from dataclasses import dataclass +from typing import Callable, Optional, Union + +import numpy as np +import torch +from torch import nn +from torch.nn import Parameter +from torch.nn import functional as F + +from ...activations import ACT2FN +from ...cache_utils import Cache, DynamicCache +from ...generation import GenerationMixin +from ...integrations import use_kernel_forward_from_hub +from ...masking_utils import create_causal_mask, create_sliding_window_causal_mask +from ...modeling_flash_attention_utils import FlashAttentionKwargs +from ...modeling_layers import GradientCheckpointingLayer +from ...modeling_outputs import ( + BaseModelOutput, + BaseModelOutputWithPast, + CausalLMOutputWithPast, + MoeCausalLMOutputWithPast, + MoeModelOutputWithPast, +) +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...processing_utils import Unpack +from ...utils import auto_docstring, can_return_tuple +from ...utils.deprecation import deprecate_kwarg +from ...utils.generic import OutputRecorder, TransformersKwargs, check_model_inputs +from .configuration_qwen3_omni_moe import ( + Qwen3OmniMoeAudioEncoderConfig, + Qwen3OmniMoeCode2WavConfig, + Qwen3OmniMoeConfig, + Qwen3OmniMoeTalkerCodePredictorConfig, + Qwen3OmniMoeTalkerConfig, + Qwen3OmniMoeTalkerTextConfig, + Qwen3OmniMoeTextConfig, + Qwen3OmniMoeThinkerConfig, + Qwen3OmniMoeVisionEncoderConfig, +) + + +@auto_docstring +class Qwen3OmniMoePreTrainedModel(PreTrainedModel): + config: Qwen3OmniMoeConfig + base_model_prefix = "model" + supports_gradient_checkpointing = True + _no_split_modules = ["Qwen3OmniMoeDecoderLayer", "Qwen3OmniMoeVisionBlock"] + _skip_keys_device_placement = "past_key_values" + _supports_flash_attn = True + _supports_sdpa = True + _can_compile_fullgraph = False + _supports_attention_backend = True + + +def _get_feat_extract_output_lengths(input_lengths): + """ + Computes the output length of the convolutional layers and the output length of the audio encoder + """ + + input_lengths_leave = input_lengths % 100 + feat_lengths = (input_lengths_leave - 1) // 2 + 1 + output_lengths = ((feat_lengths - 1) // 2 + 1 - 1) // 2 + 1 + (input_lengths // 100) * 13 + return output_lengths + + +class Qwen3OmniMoePreTrainedModelForConditionalGeneration(Qwen3OmniMoePreTrainedModel): + def _prepare_4d_causal_attention_mask_with_cache_position( + self, + attention_mask: torch.Tensor, + sequence_length: int, + target_length: int, + dtype: torch.dtype, + device: torch.device, + min_dtype: float, + cache_position: torch.Tensor, + batch_size: int, + ): + """ + Creates a causal 4D mask of shape `(batch_size, 1, query_length, key_value_length)` from a 2D mask of shape + `(batch_size, key_value_length)`, or if the input `attention_mask` is already 4D, do nothing. + + Args: + attention_mask (`torch.Tensor`): + A 2D attention mask of shape `(batch_size, key_value_length)` or a 4D attention mask of shape `(batch_size, 1, query_length, key_value_length)`. + sequence_length (`int`): + The sequence length being processed. + target_length (`int`): + The target length: when generating with static cache, the mask should be as long as the static cache, to account for the 0 padding, the part of the cache that is not filled yet. + dtype (`torch.dtype`): + The dtype to use for the 4D attention mask. + device (`torch.device`): + The device to place the 4D attention mask on. + min_dtype (`float`): + The minimum value representable with the dtype `dtype`. + cache_position (`torch.Tensor`): + Indices depicting the position of the input sequence tokens in the sequence. + batch_size (`torch.Tensor`): + Batch size. + """ + if attention_mask is not None and attention_mask.dim() == 4: + # In this case we assume that the mask comes already in inverted form and requires no inversion or slicing. + causal_mask = attention_mask + else: + causal_mask = torch.full( + (sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=device + ) + if sequence_length != 1: + causal_mask = torch.triu(causal_mask, diagonal=1) + causal_mask *= torch.arange(target_length, device=device) > cache_position.reshape(-1, 1) + causal_mask = causal_mask[None, None, :, :].expand(batch_size, 1, -1, -1) + if attention_mask is not None: + causal_mask = causal_mask.clone() # copy to contiguous memory for in-place edit + mask_length = attention_mask.shape[-1] + padding_mask = causal_mask[:, :, :, :mask_length] + attention_mask[:, None, None, :] + padding_mask = padding_mask == 0 + causal_mask[:, :, :, :mask_length] = causal_mask[:, :, :, :mask_length].masked_fill( + padding_mask, min_dtype + ) + + return causal_mask + + def get_llm_pos_ids_for_vision( + self, + start_idx: int, + vision_idx: int, + spatial_merge_size: int, + t_index: list[torch.Tensor], + grid_hs: list[torch.Tensor], + grid_ws: list[torch.Tensor], + ): + llm_pos_ids_list = [] + llm_grid_h = grid_hs[vision_idx] // spatial_merge_size + llm_grid_w = grid_ws[vision_idx] // spatial_merge_size + h_index = torch.arange(llm_grid_h).view(1, -1, 1).expand(len(t_index), -1, llm_grid_w).flatten().float() + w_index = torch.arange(llm_grid_w).view(1, 1, -1).expand(len(t_index), llm_grid_h, -1).flatten().float() + t_index = torch.Tensor(t_index).view(-1, 1).expand(-1, llm_grid_h * llm_grid_w).flatten().float() + _llm_pos_ids = torch.stack([t_index, h_index, w_index]) + llm_pos_ids_list.append(_llm_pos_ids + start_idx) + llm_pos_ids = torch.cat(llm_pos_ids_list, dim=1) + return llm_pos_ids + + def get_chunked_index( + self, token_indices: torch.Tensor, tokens_per_chunk: int, remove_index: int + ) -> list[tuple[int, int]]: + """ + Splits token index list into chunks based on token value ranges. + + Given a list of token indices, returns a list of (start, end) index tuples representing + slices of the list where the token values fall within successive ranges of `t_ntoken_per_chunk`. + + For example, if `t_ntoken_per_chunk` is 1000, the function will create chunks such that: + - the first chunk contains token values < 1000, + - the second chunk contains values >= 1000 and < 2000, and so on. + + Parameters: + token_indices (`torch.Tensor` of shape `(seq_len, )`): A monotonically increasing list of + token index values. + t_ntoken_per_chunk (`int`): Number of tokens per chunk (used as the chunk size threshold). + remove_index (`int`) An index id to subtract from `token_indices` before chunking + + Returns: + `list[tuple[int, int]]`: A list of tuples, each representing the start (inclusive) + and end (exclusive) indices of a chunk in `token_indices`. + """ + + def _iter(): + i, start_idx = 0, 0 # skip bos token + current_chunk = 1 + while i < len(token_indices): # skip eos token + if token_indices[i] - remove_index >= current_chunk * tokens_per_chunk: + yield (start_idx, i) + start_idx = i + current_chunk += 1 + i += 1 + yield (start_idx, len(token_indices)) + + return list(_iter()) + + def get_rope_index( + self, + input_ids: Optional[torch.LongTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + use_audio_in_video: bool = False, + audio_seqlens: Optional[torch.LongTensor] = None, + second_per_grids: Optional[torch.Tensor] = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + """ + Calculate the 3D rope index based on image and video's temporal, height and width in LLM. + + Explanation: + Each embedding sequence contains vision embedding and text embedding or just contains text embedding. + + For pure text embedding sequence, the rotary position embedding has no difference with modern LLMs. + Examples: + input_ids: [T T T T T], here T is for text. + temporal position_ids: [0, 1, 2, 3, 4] + height position_ids: [0, 1, 2, 3, 4] + width position_ids: [0, 1, 2, 3, 4] + + For vision and text embedding sequence, we calculate 3D rotary position embedding for vision part + and 1D rotary position embedding for text part. + Examples: + Temporal (Time): 3 patches, representing different segments of the video in time. + Height: 2 patches, dividing each frame vertically. + Width: 2 patches, dividing each frame horizontally. + We also have some important parameters: + fps (Frames Per Second): The video's frame rate, set to 1. This means one frame is processed each second. + tokens_per_second: This is a crucial parameter. It dictates how many "time-steps" or "temporal tokens" are conceptually packed into a one-second interval of the video. In this case, we have 25 tokens per second. So each second of the video will be represented with 25 separate time points. It essentially defines the temporal granularity. + temporal_patch_size: The number of frames that compose one temporal patch. Here, it's 2 frames. + interval: The step size for the temporal position IDs, calculated as tokens_per_second * temporal_patch_size / fps. In this case, 25 * 2 / 1 = 50. This means that each temporal patch will be have a difference of 50 in the temporal position IDs. + input_ids: [V V V V V V V V V V V V T T T T T], here V is for vision. + vision temporal position_ids: [0, 0, 0, 0, 50, 50, 50, 50, 100, 100, 100, 100] + vision height position_ids: [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1] + vision width position_ids: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] + text temporal position_ids: [101, 102, 103, 104, 105] + text height position_ids: [101, 102, 103, 104, 105] + text width position_ids: [101, 102, 103, 104, 105] + Here we calculate the text start position_ids as the max vision position_ids plus 1. + + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + use_audio_in_video (`bool`, *optional*): + If set to `True`, use the audio in video. + audio_seqlens (`torch.LongTensor` of shape `(num_audios)`, *optional*): + The length of feature shape of each audio in LLM. + second_per_grids (`torch.LongTensor` of shape `(num_videos)`, *optional*): + The time interval (in seconds) for each grid along the temporal dimension in the 3D position IDs. + + Returns: + position_ids (`torch.LongTensor` of shape `(3, batch_size, sequence_length)`) + mrope_position_deltas (`torch.Tensor` of shape `(batch_size)`) + """ + spatial_merge_size = self.spatial_merge_size + image_token_id = self.config.image_token_id + video_token_id = self.config.video_token_id + audio_token_id = self.config.audio_token_id + vision_start_token_id = self.config.vision_start_token_id + audio_start_token_id = self.config.audio_start_token_id + position_id_per_seconds = self.config.position_id_per_seconds + + mrope_position_deltas = [] + if input_ids is not None and (image_grid_thw is not None or video_grid_thw is not None): + total_input_ids = input_ids + if attention_mask is not None: + attention_mask = attention_mask == 1 + position_ids = torch.zeros( + 3, + input_ids.shape[0], + input_ids.shape[1], + dtype=torch.float, + device=input_ids.device, + ) + image_idx, video_idx, audio_idx = 0, 0, 0 + for i, input_ids in enumerate(total_input_ids): + if attention_mask is not None: + input_ids = input_ids[attention_mask[i]] + image_nums, video_nums, audio_nums = 0, 0, 0 + vision_start_indices = torch.argwhere(input_ids == vision_start_token_id).squeeze(1) + vision_tokens = input_ids[vision_start_indices + 1] + audio_nums = torch.sum(input_ids == audio_start_token_id) + image_nums = (vision_tokens == image_token_id).sum() + video_nums = ( + (vision_tokens == audio_start_token_id).sum() + if use_audio_in_video + else (vision_tokens == video_token_id).sum() + ) + input_tokens = input_ids.tolist() + llm_pos_ids_list: list = [] + st = 0 + remain_images, remain_videos, remain_audios = image_nums, video_nums, audio_nums + multimodal_nums = ( + image_nums + audio_nums if use_audio_in_video else image_nums + video_nums + audio_nums + ) + for _ in range(multimodal_nums): + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + if (image_token_id in input_tokens or video_token_id in input_tokens) and ( + remain_videos > 0 or remain_images > 0 + ): + ed_vision_start = input_tokens.index(vision_start_token_id, st) + else: + ed_vision_start = len(input_tokens) + 1 + if audio_token_id in input_tokens and remain_audios > 0: + ed_audio_start = input_tokens.index(audio_start_token_id, st) + else: + ed_audio_start = len(input_tokens) + 1 + min_ed = min(ed_vision_start, ed_audio_start) + + text_len = min_ed - st + if text_len != 0: + llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx) + st_idx += text_len + # Audio in Video + if min_ed == ed_vision_start and ed_vision_start + 1 == ed_audio_start: + bos_len, eos_len = 2, 2 + else: + bos_len, eos_len = 1, 1 + llm_pos_ids_list.append(torch.arange(bos_len).view(1, -1).expand(3, -1) + st_idx) + st_idx += bos_len + # Audio Only + if min_ed == ed_audio_start: + audio_len = _get_feat_extract_output_lengths(audio_seqlens[audio_idx]) + llm_pos_ids = torch.arange(audio_len).view(1, -1).expand(3, -1) + st_idx + llm_pos_ids_list.append(llm_pos_ids) + + st += int(text_len + bos_len + audio_len + eos_len) + audio_idx += 1 + remain_audios -= 1 + + # Image Only + elif min_ed == ed_vision_start and input_ids[ed_vision_start + 1] == image_token_id: + grid_t = image_grid_thw[image_idx][0] + grid_hs = image_grid_thw[:, 1] + grid_ws = image_grid_thw[:, 2] + t_index = (torch.arange(grid_t) * 1 * position_id_per_seconds).float() + llm_pos_ids = self.get_llm_pos_ids_for_vision( + st_idx, image_idx, spatial_merge_size, t_index, grid_hs, grid_ws + ) + image_len = image_grid_thw[image_idx].prod() // (spatial_merge_size**2) + llm_pos_ids_list.append(llm_pos_ids) + + st += int(text_len + bos_len + image_len + eos_len) + image_idx += 1 + remain_images -= 1 + + # Video Only + elif min_ed == ed_vision_start and input_ids[ed_vision_start + 1] == video_token_id: + grid_t = video_grid_thw[video_idx][0] + grid_hs = video_grid_thw[:, 1] + grid_ws = video_grid_thw[:, 2] + t_index = ( + torch.arange(grid_t) * second_per_grids[video_idx].cpu().float() * position_id_per_seconds + ).float() + llm_pos_ids = self.get_llm_pos_ids_for_vision( + st_idx, video_idx, spatial_merge_size, t_index, grid_hs, grid_ws + ) + video_len = video_grid_thw[video_idx].prod() // (spatial_merge_size**2) + llm_pos_ids_list.append(llm_pos_ids) + + st += int(text_len + bos_len + video_len + eos_len) + video_idx += 1 + remain_videos -= 1 + + # Audio in Video + elif min_ed == ed_vision_start and ed_vision_start + 1 == ed_audio_start: + audio_len = _get_feat_extract_output_lengths(audio_seqlens[audio_idx]) + audio_llm_pos_ids = torch.arange(audio_len).view(1, -1).expand(3, -1) + st_idx + grid_t = video_grid_thw[video_idx][0] + grid_hs = video_grid_thw[:, 1] + grid_ws = video_grid_thw[:, 2] + + t_index = ( + torch.arange(grid_t) * second_per_grids[video_idx].cpu().float() * position_id_per_seconds + ).float() + video_llm_pos_ids = self.get_llm_pos_ids_for_vision( + st_idx, video_idx, spatial_merge_size, t_index, grid_hs, grid_ws + ) + video_data_index, audio_data_index = 0, 0 + while ( + video_data_index < video_llm_pos_ids.shape[-1] + and audio_data_index < audio_llm_pos_ids.shape[-1] + ): + if video_llm_pos_ids[0][video_data_index] <= audio_llm_pos_ids[0][audio_data_index]: + llm_pos_ids_list.append(video_llm_pos_ids[:, video_data_index : video_data_index + 1]) + video_data_index += 1 + else: + llm_pos_ids_list.append(audio_llm_pos_ids[:, audio_data_index : audio_data_index + 1]) + audio_data_index += 1 + if video_data_index < video_llm_pos_ids.shape[-1]: + llm_pos_ids_list.append( + video_llm_pos_ids[:, video_data_index : video_llm_pos_ids.shape[-1]] + ) + if audio_data_index < audio_llm_pos_ids.shape[-1]: + llm_pos_ids_list.append( + audio_llm_pos_ids[:, audio_data_index : audio_llm_pos_ids.shape[-1]] + ) + video_len = video_grid_thw[video_idx].prod() // (spatial_merge_size**2) + + st += int(text_len + bos_len + audio_len + video_len + eos_len) + + audio_idx += 1 + video_idx += 1 + remain_videos -= 1 + remain_audios -= 1 + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + llm_pos_ids_list.append(torch.arange(eos_len).view(1, -1).expand(3, -1) + st_idx) + + if st < len(input_tokens): + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + text_len = len(input_tokens) - st + llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx) + + llm_positions = torch.cat([item.float() for item in llm_pos_ids_list], dim=1).reshape(3, -1) + + position_ids[..., i, attention_mask[i] == 1] = llm_positions.to(position_ids.device) + mrope_position_deltas.append(llm_positions.max() + 1 - len(input_ids)) + mrope_position_deltas = torch.tensor(mrope_position_deltas, device=input_ids.device).unsqueeze(1) + + return position_ids, mrope_position_deltas + else: + position_ids = attention_mask.float().cumsum(-1) - 1 + position_ids.masked_fill_(attention_mask == 0, 1) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1).to(attention_mask.device) + max_position_ids = position_ids.max(0, keepdim=False)[0].max(-1, keepdim=True)[0] + mrope_position_deltas = max_position_ids + 1 - torch.sum(attention_mask, dim=-1, keepdim=True) + + return position_ids, mrope_position_deltas + + +def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor: + """ + This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, + num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim) + """ + batch, num_key_value_heads, slen, head_dim = hidden_states.shape + if n_rep == 1: + return hidden_states + hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim) + return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim) + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: float, + dropout: float = 0.0, + **kwargs, +): + key_states = repeat_kv(key, module.num_key_value_groups) + value_states = repeat_kv(value, module.num_key_value_groups) + + attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling + if attention_mask is not None: + causal_mask = attention_mask[:, :, :, : key_states.shape[-2]] + attn_weights = attn_weights + causal_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype) + attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training) + attn_output = torch.matmul(attn_weights, value_states) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + +class Qwen3OmniMoeAudioAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config): + super().__init__() + self.embed_dim = config.d_model + self.num_heads = config.encoder_attention_heads + self.dropout = config.attention_dropout + self.head_dim = self.embed_dim // self.num_heads + self.num_key_value_groups = 1 # needed for eager attention + self.config = config + + if (self.head_dim * self.num_heads) != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {self.num_heads})." + ) + self.scaling = self.head_dim**-0.5 + self.attention_dropout = 0.0 + self.is_decoder = False + self.is_causal = False + self.k_proj = nn.Linear(self.embed_dim, self.embed_dim, bias=True) + self.v_proj = nn.Linear(self.embed_dim, self.embed_dim, bias=True) + self.q_proj = nn.Linear(self.embed_dim, self.embed_dim, bias=True) + self.out_proj = nn.Linear(self.embed_dim, self.embed_dim, bias=True) + + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + **kwargs, + ) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + + seq_length, _ = hidden_states.size() + + query_states = self.q_proj(hidden_states).reshape(seq_length, self.num_heads, -1) + key_states = self.k_proj(hidden_states).reshape(seq_length, self.num_heads, -1) + value_states = self.v_proj(hidden_states).reshape(seq_length, self.num_heads, -1) + + query_states = query_states.transpose(0, 1).unsqueeze(0) + key_states = key_states.transpose(0, 1).unsqueeze(0) + value_states = value_states.transpose(0, 1).unsqueeze(0) + max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max() + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, _ = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask=attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + cu_seq_lens_q=cu_seqlens, # pass cu seq lens for FA2 + cu_seq_lens_k=cu_seqlens, + max_length_q=max_seqlen, + max_length_k=max_seqlen, + is_causal=False, + **kwargs, + ) + + attn_output = attn_output.reshape(seq_length, -1).contiguous() + attn_output = self.out_proj(attn_output) + + return attn_output + + +class Qwen3OmniMoeAudioEncoderLayer(GradientCheckpointingLayer): + def __init__(self, config: Qwen3OmniMoeAudioEncoderConfig): + super().__init__() + self.embed_dim = config.d_model + self.self_attn = Qwen3OmniMoeAudioAttention(config) + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + self.fc1 = nn.Linear(self.embed_dim, config.encoder_ffn_dim) + self.fc2 = nn.Linear(config.encoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + **kwargs, + ) -> torch.Tensor: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + layer_head_mask (`torch.FloatTensor`): mask for attention heads in a given layer of size + `(encoder_attention_heads,)`. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + hidden_states = self.self_attn( + hidden_states=hidden_states, + cu_seqlens=cu_seqlens, + attention_mask=attention_mask, + **kwargs, + ) + hidden_states = residual + hidden_states + residual = hidden_states + hidden_states = self.final_layer_norm(hidden_states) + hidden_states = self.fc1(hidden_states) + hidden_states = self.activation_fn(hidden_states) + hidden_states = self.fc2(hidden_states) + hidden_states = residual + hidden_states + + if hidden_states.dtype == torch.float16: + clamp_value = torch.finfo(hidden_states.dtype).max - 1000 + hidden_states = torch.clamp(hidden_states, min=-clamp_value, max=clamp_value) + + outputs = (hidden_states,) + + return outputs + + +class SinusoidsPositionEmbedding(nn.Module): + def __init__(self, length, channels, max_timescale=10000): + super().__init__() + if channels % 2 != 0: + raise ValueError("SinusoidsPositionEmbedding needs even channels input") + log_timescale_increment = np.log(max_timescale) / (channels // 2 - 1) + inv_timescales = torch.exp(-log_timescale_increment * torch.arange(channels // 2).float()) + scaled_time = torch.arange(length)[:, np.newaxis] * inv_timescales[np.newaxis, :] + self.register_buffer( + "positional_embedding", + torch.cat([torch.sin(scaled_time), torch.cos(scaled_time)], dim=1), + persistent=False, + ) + + def forward(self, seqlen: int): + return self.positional_embedding[:seqlen, :] + + +@auto_docstring( + custom_intro=""" + Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a + [`Qwen3OmniMoeAudioEncoderLayer`]. + """ +) +class Qwen3OmniMoeAudioEncoder(Qwen3OmniMoePreTrainedModel): + config: Qwen3OmniMoeAudioEncoderConfig + main_input_name = "input_features" + _no_split_modules = ["Qwen3OmniMoeAudioEncoderLayer"] + _supports_sdpa = True + + def __init__(self, config: Qwen3OmniMoeAudioEncoderConfig): + super().__init__(config) + self.dropout = config.dropout + + embed_dim = config.d_model + self.num_mel_bins = config.num_mel_bins + self.max_source_positions = config.max_source_positions + self.embed_scale = math.sqrt(embed_dim) if config.scale_embedding else 1.0 + self.n_window = config.n_window + self.positional_embedding = SinusoidsPositionEmbedding(self.max_source_positions, embed_dim) + self.layers = nn.ModuleList([Qwen3OmniMoeAudioEncoderLayer(config) for _ in range(config.encoder_layers)]) + self.ln_post = nn.LayerNorm(config.d_model) + self.gradient_checkpointing = False + self.conv2d1 = nn.Conv2d(1, config.downsample_hidden_size, 3, 2, padding=1) + self.conv2d2 = nn.Conv2d(config.downsample_hidden_size, config.downsample_hidden_size, 3, 2, padding=1) + self.conv2d3 = nn.Conv2d(config.downsample_hidden_size, config.downsample_hidden_size, 3, 2, padding=1) + self.conv_out = nn.Linear( + config.downsample_hidden_size * ((((config.num_mel_bins + 1) // 2 + 1) // 2 + 1) // 2), + config.d_model, + bias=False, + ) + self.proj1 = nn.Linear(config.d_model, config.d_model) + self.act = ACT2FN[config.activation_function] + self.proj2 = nn.Linear(config.d_model, config.output_dim) + self.n_window_infer = self.config.n_window_infer + self.conv_chunksize = self.config.conv_chunksize + # Initialize weights and apply final processing + self.post_init() + + def _freeze_parameters(self): + for param in self.parameters(): + param.requires_grad = False + self._requires_grad = False + + def get_input_embeddings(self) -> nn.Module: + return self.conv1 + + def set_input_embeddings(self, value: nn.Module): + self.conv1 = value + + def _prepare_attention_mask(self, inputs_tensor: torch.Tensor, cu_seqlens: torch.Tensor) -> torch.Tensor: + # Flash Attention 2 doesn't need a 4D mask and relies on `cu_seqlens/max_seqlen` + # NOTE: the created attention masl only approximates the ragged FA2 attention by + # allowing bidirectional attention within `cu_seqlens` blocks, and not attending between + # blocks. Though it will not be a 100% match for FA2's `varlen` path + if self.config._attn_implementation == "flash_attention_2": + return None + + seq_length = inputs_tensor.shape[0] + attention_mask = torch.full( + [1, 1, seq_length, seq_length], + torch.finfo(inputs_tensor.dtype).min, + device=inputs_tensor.device, + dtype=inputs_tensor.dtype, + ) + for i in range(1, len(cu_seqlens)): + attention_mask[..., cu_seqlens[i - 1] : cu_seqlens[i], cu_seqlens[i - 1] : cu_seqlens[i]] = 0 + return attention_mask + + @auto_docstring + def forward( + self, + input_features, + feature_lens=None, + aftercnn_lens=None, + ): + r""" + feature_lens (`torch.LongTensor` of shape `(batch_size,)`): + mel length + aftercnn_lens (`torch.LongTensor` of shape `(batch_size,)`): + mel length after cnn + """ + aftercnn_lens = _get_feat_extract_output_lengths(feature_lens) + chunk_num = torch.ceil(feature_lens / (self.n_window * 2)).long() + + chunk_lengths = torch.tensor( + [self.n_window * 2] * chunk_num.sum(), + dtype=torch.long, + device=feature_lens.device, + ) + tail_chunk_index = F.pad(chunk_num, (1, 0), value=-1).cumsum(0)[1:] + chunk_lengths[tail_chunk_index] = feature_lens % (self.n_window * 2) + chunk_lengths[chunk_lengths == 0] = self.n_window * 2 + + chunk_list = input_features.T.split(chunk_lengths.tolist(), dim=0) + padded_feature = nn.utils.rnn.pad_sequence(chunk_list, batch_first=True).transpose(1, 2) + feature_lens_after_cnn = _get_feat_extract_output_lengths(chunk_lengths) + padded_mask_after_cnn = nn.utils.rnn.pad_sequence( + [torch.ones(length, dtype=torch.bool, device=padded_feature.device) for length in feature_lens_after_cnn], + batch_first=True, + ) + padded_feature = padded_feature.unsqueeze(1) + # Split to chunk to avoid OOM during convolution + padded_embeds = [] + for chunk in padded_feature.split(self.conv_chunksize, dim=0): + padded_embed = F.gelu(self.conv2d1(chunk)) + padded_embed = F.gelu(self.conv2d2(padded_embed)) + padded_embed = F.gelu(self.conv2d3(padded_embed)) + padded_embeds.append(padded_embed) + padded_embed = torch.cat(padded_embeds, dim=0) + b, c, f, t = padded_embed.size() + padded_embed = self.conv_out(padded_embed.permute(0, 3, 1, 2).contiguous().view(b, t, c * f)) + + positional_embedding = ( + self.positional_embedding.positional_embedding[: padded_embed.shape[1], :] + .unsqueeze(0) + .to(padded_embed.dtype) + ) + padded_embed = padded_embed + positional_embedding + hidden_states = padded_embed[padded_mask_after_cnn] + cu_chunk_lens = [0] + window_aftercnn = padded_mask_after_cnn.shape[-1] * (self.n_window_infer // (self.n_window * 2)) + for cnn_len in aftercnn_lens: + cu_chunk_lens += [window_aftercnn] * (cnn_len // window_aftercnn) + remainder = cnn_len % window_aftercnn + if remainder != 0: + cu_chunk_lens += [remainder] + cu_seqlens = torch.tensor(cu_chunk_lens, device=aftercnn_lens.device).cumsum(-1, dtype=torch.int32) + + for encoder_layer in self.layers: + layer_outputs = encoder_layer( + hidden_states, + cu_seqlens, + ) + + hidden_states = layer_outputs[0] + + hidden_states = self.ln_post(hidden_states) + hidden_states = self.proj1(hidden_states) + hidden_states = self.act(hidden_states) + hidden_states = self.proj2(hidden_states) + return BaseModelOutput(last_hidden_state=hidden_states) + + def padded_and_mask_function(self, tensor_list, tensor_len, padding_value=0, padding_side="right"): + """ + Pads a sequence of tensors to their maximum length on indicated `padding_side`. + Then prepares a mask so that pad tokens are not attended to. + """ + max_len = tensor_len.max() + dim = tensor_list[0].shape[0] + padded_tensor = torch.full( + size=(len(tensor_list), dim, max_len), + fill_value=padding_value, + dtype=self.dtype, + device=tensor_list[0].device, + ) + + batch_mask = torch.zeros( + (len(tensor_len), max_len), + dtype=torch.long, + device=padded_tensor.device, + ) + for i, length in enumerate(tensor_len): + batch_mask[i, :length] = 1 + padded_tensor[i, :, :length] = tensor_list[i] + + feature_lens_after_cnn = (tensor_len - 1) // 2 + 1 + max_len_after_cnn = feature_lens_after_cnn.max() + batch_mask_after_cnn = torch.zeros( + (len(tensor_len), max_len_after_cnn), + dtype=torch.long, + device=padded_tensor.device, + ) + for i, length in enumerate(feature_lens_after_cnn): + batch_mask_after_cnn[i, :length] = 1 + return ( + padded_tensor, + batch_mask.unsqueeze(1), + batch_mask_after_cnn.bool(), + ) + + # Ignore copy + def _get_feat_extract_output_lengths(self, input_lengths: torch.LongTensor): + """ + Computes the output length of the convolutional layers and the output length of the audio encoder + """ + input_lengths = (input_lengths - 1) // 2 + 1 + output_lengths = (input_lengths - 2) // 2 + 1 + return input_lengths, output_lengths + + +def rotate_half(x): + """Rotates half the hidden dims of the input.""" + x1 = x[..., : x.shape[-1] // 2] + x2 = x[..., x.shape[-1] // 2 :] + return torch.cat((-x2, x1), dim=-1) + + +def apply_rotary_pos_emb_vision( + q: torch.Tensor, k: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor +) -> tuple[torch.Tensor, torch.Tensor]: + orig_q_dtype = q.dtype + orig_k_dtype = k.dtype + q, k = q.float(), k.float() + cos, sin = cos.unsqueeze(-2).float(), sin.unsqueeze(-2).float() + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + q_embed = q_embed.to(orig_q_dtype) + k_embed = k_embed.to(orig_k_dtype) + return q_embed, k_embed + + +class Qwen3OmniMoeVisionAttention(nn.Module): + def __init__(self, config: Qwen3OmniMoeVisionEncoderConfig) -> None: + super().__init__() + self.dim = config.hidden_size + self.num_heads = config.num_heads + self.head_dim = self.dim // self.num_heads + self.num_key_value_groups = 1 # needed for eager attention + self.qkv = nn.Linear(self.dim, self.dim * 3, bias=True) + self.proj = nn.Linear(self.dim, self.dim) + self.scaling = self.head_dim**-0.5 + self.config = config + self.attention_dropout = 0.0 + self.is_causal = False + + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: torch.Tensor, + rotary_pos_emb: Optional[torch.Tensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + **kwargs, + ) -> torch.Tensor: + seq_length = hidden_states.shape[0] + query_states, key_states, value_states = ( + self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0) + ) + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb_vision(query_states, key_states, cos, sin) + + query_states = query_states.transpose(0, 1).unsqueeze(0) + key_states = key_states.transpose(0, 1).unsqueeze(0) + value_states = value_states.transpose(0, 1).unsqueeze(0) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + if self.config._attn_implementation == "flash_attention_2": + # Flash Attention 2: Use cu_seqlens for variable length attention + max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max() + attn_output, _ = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + cu_seq_lens_q=cu_seqlens, + cu_seq_lens_k=cu_seqlens, + max_length_q=max_seqlen, + max_length_k=max_seqlen, + is_causal=False, + **kwargs, + ) + else: + # Other implementations: Process each chunk separately + lengths = cu_seqlens[1:] - cu_seqlens[:-1] + splits = [ + torch.split(tensor, lengths.tolist(), dim=2) for tensor in (query_states, key_states, value_states) + ] + + attn_outputs = [ + attention_interface( + self, + q, + k, + v, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + is_causal=False, + **kwargs, + )[0] + for q, k, v in zip(*splits) + ] + attn_output = torch.cat(attn_outputs, dim=1) + + attn_output = attn_output.reshape(seq_length, -1).contiguous() + attn_output = self.proj(attn_output) + return attn_output + + +class Qwen3OmniMoeVisionPatchMerger(nn.Module): + def __init__(self, config: Qwen3OmniMoeVisionEncoderConfig, use_postshuffle_norm=False) -> None: + super().__init__() + self.hidden_size = config.hidden_size * (config.spatial_merge_size**2) + self.use_postshuffle_norm = use_postshuffle_norm + self.ln_q = nn.LayerNorm(self.hidden_size if use_postshuffle_norm else config.hidden_size, eps=1e-6) + self.mlp = nn.ModuleList( + [ + nn.Linear(self.hidden_size, self.hidden_size), + nn.GELU(), + nn.Linear(self.hidden_size, config.out_hidden_size), + ] + ) + + def forward(self, hidden: torch.Tensor) -> torch.Tensor: + hidden = self.ln_q(hidden.view(-1, self.hidden_size) if self.use_postshuffle_norm else hidden).view( + -1, self.hidden_size + ) + for layer in self.mlp: + hidden = layer(hidden) + return hidden + + +class Qwen3OmniMoeVisionMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.linear_fc1 = nn.Linear(self.hidden_size, self.intermediate_size, bias=True) + self.linear_fc2 = nn.Linear(self.intermediate_size, self.hidden_size, bias=True) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, hidden_state): + return self.linear_fc2(self.act_fn(self.linear_fc1(hidden_state))) + + +class Qwen3OmniMoeVisionPatchEmbed(nn.Module): + def __init__(self, config) -> None: + super().__init__() + self.patch_size = config.patch_size + self.temporal_patch_size = config.temporal_patch_size + self.in_channels = config.in_channels + self.embed_dim = config.hidden_size + + kernel_size = [self.temporal_patch_size, self.patch_size, self.patch_size] + self.proj = nn.Conv3d(self.in_channels, self.embed_dim, kernel_size=kernel_size, stride=kernel_size, bias=True) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + target_dtype = self.proj.weight.dtype + hidden_states = hidden_states.view( + -1, self.in_channels, self.temporal_patch_size, self.patch_size, self.patch_size + ) + hidden_states = self.proj(hidden_states.to(dtype=target_dtype)).view(-1, self.embed_dim) + return hidden_states + + +class Qwen3OmniMoeVisionRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, dim: int, theta: float = 10000.0) -> None: + super().__init__() + inv_freq = 1.0 / (theta ** (torch.arange(0, dim, 2, dtype=torch.float) / dim)) + self.register_buffer("inv_freq", inv_freq, persistent=False) + + def forward(self, seqlen: int) -> torch.Tensor: + seq = torch.arange(seqlen, device=self.inv_freq.device, dtype=self.inv_freq.dtype) + freqs = torch.outer(seq, self.inv_freq) + return freqs + + +class Qwen3OmniMoeVisionBlock(GradientCheckpointingLayer): + def __init__(self, config, attn_implementation: str = "sdpa") -> None: + super().__init__() + self.norm1 = nn.LayerNorm(config.hidden_size, eps=1e-6) + self.norm2 = nn.LayerNorm(config.hidden_size, eps=1e-6) + self.attn = Qwen3OmniMoeVisionAttention(config=config) + self.mlp = Qwen3OmniMoeVisionMLP(config=config) + + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: torch.Tensor, + rotary_pos_emb: Optional[torch.Tensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, + **kwargs, + ) -> torch.Tensor: + hidden_states = hidden_states + self.attn( + self.norm1(hidden_states), + cu_seqlens=cu_seqlens, + rotary_pos_emb=rotary_pos_emb, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = hidden_states + self.mlp(self.norm2(hidden_states)) + return hidden_states + + +class Qwen3OmniMoeVisionEncoder(Qwen3OmniMoePreTrainedModel): + config: Qwen3OmniMoeVisionEncoderConfig + _no_split_modules = ["Qwen3OmniMoeVisionBlock"] + + def __init__(self, config, *inputs, **kwargs) -> None: + super().__init__(config, *inputs, **kwargs) + self.merger_list = nn.ModuleList( + [ + Qwen3OmniMoeVisionPatchMerger( + config=config, + use_postshuffle_norm=True, + ) + for _ in range(len(config.deepstack_visual_indexes)) + ] + ) + self.spatial_merge_size = config.spatial_merge_size + self.patch_size = config.patch_size + self.spatial_merge_unit = self.spatial_merge_size * self.spatial_merge_size + + self.patch_embed = Qwen3OmniMoeVisionPatchEmbed( + config=config, + ) + + self.pos_embed = nn.Embedding(config.num_position_embeddings, config.hidden_size) + self.num_grid_per_side = int(config.num_position_embeddings**0.5) + + head_dim = config.hidden_size // config.num_heads + self.rotary_pos_emb = Qwen3OmniMoeVisionRotaryEmbedding(head_dim // 2) + + self.blocks = nn.ModuleList([Qwen3OmniMoeVisionBlock(config) for _ in range(config.depth)]) + self.merger = Qwen3OmniMoeVisionPatchMerger( + config=config, + use_postshuffle_norm=False, + ) + + self.deepstack_visual_indexes = config.deepstack_visual_indexes + + self.gradient_checkpointing = False + + def rot_pos_emb(self, grid_thw: torch.Tensor) -> torch.Tensor: + merge_size = self.spatial_merge_size + + max_hw = int(grid_thw[:, 1:].max().item()) + freq_table = self.rotary_pos_emb(max_hw) # (max_hw, dim // 2) + device = freq_table.device + + total_tokens = int(torch.prod(grid_thw, dim=1).sum().item()) + pos_ids = torch.empty((total_tokens, 2), dtype=torch.long, device=device) + + offset = 0 + for num_frames, height, width in grid_thw: + merged_h, merged_w = height // merge_size, width // merge_size + + block_rows = torch.arange(merged_h, device=device) # block row indices + block_cols = torch.arange(merged_w, device=device) # block col indices + intra_row = torch.arange(merge_size, device=device) # intra-block row offsets + intra_col = torch.arange(merge_size, device=device) # intra-block col offsets + + # Compute full-resolution positions + row_idx = block_rows[:, None, None, None] * merge_size + intra_row[None, None, :, None] + col_idx = block_cols[None, :, None, None] * merge_size + intra_col[None, None, None, :] + + row_idx = row_idx.expand(merged_h, merged_w, merge_size, merge_size).reshape(-1) + col_idx = col_idx.expand(merged_h, merged_w, merge_size, merge_size).reshape(-1) + + coords = torch.stack((row_idx, col_idx), dim=-1) + + if num_frames > 1: + coords = coords.repeat(num_frames, 1) + + num_tokens = coords.shape[0] + pos_ids[offset : offset + num_tokens] = coords + offset += num_tokens + + embeddings = freq_table[pos_ids] # lookup rotary embeddings + embeddings = embeddings.flatten(1) + return embeddings + + def fast_pos_embed_interpolate(self, grid_thw): + grid_ts, grid_hs, grid_ws = grid_thw[:, 0], grid_thw[:, 1], grid_thw[:, 2] + + idx_list = [[] for _ in range(4)] + weight_list = [[] for _ in range(4)] + + for t, h, w in zip(grid_ts, grid_hs, grid_ws): + h_idxs = torch.linspace(0, self.num_grid_per_side - 1, h) + w_idxs = torch.linspace(0, self.num_grid_per_side - 1, w) + + h_idxs_floor = h_idxs.int() + w_idxs_floor = w_idxs.int() + h_idxs_ceil = (h_idxs.int() + 1).clip(max=self.num_grid_per_side - 1) + w_idxs_ceil = (w_idxs.int() + 1).clip(max=self.num_grid_per_side - 1) + + dh = h_idxs - h_idxs_floor + dw = w_idxs - w_idxs_floor + + base_h = h_idxs_floor * self.num_grid_per_side + base_h_ceil = h_idxs_ceil * self.num_grid_per_side + + indices = [ + (base_h[None].T + w_idxs_floor[None]).flatten(), + (base_h[None].T + w_idxs_ceil[None]).flatten(), + (base_h_ceil[None].T + w_idxs_floor[None]).flatten(), + (base_h_ceil[None].T + w_idxs_ceil[None]).flatten(), + ] + + weights = [ + ((1 - dh)[None].T * (1 - dw)[None]).flatten(), + ((1 - dh)[None].T * dw[None]).flatten(), + (dh[None].T * (1 - dw)[None]).flatten(), + (dh[None].T * dw[None]).flatten(), + ] + + for i in range(4): + idx_list[i].extend(indices[i].tolist()) + weight_list[i].extend(weights[i].tolist()) + + idx_tensor = torch.tensor(idx_list, dtype=torch.long, device=self.pos_embed.weight.device) + weight_tensor = torch.tensor( + weight_list, dtype=self.pos_embed.weight.dtype, device=self.pos_embed.weight.device + ) + pos_embeds = self.pos_embed(idx_tensor) * weight_tensor[:, :, None] + patch_pos_embeds = pos_embeds[0] + pos_embeds[1] + pos_embeds[2] + pos_embeds[3] + + patch_pos_embeds = patch_pos_embeds.split([h * w for h, w in zip(grid_hs, grid_ws)]) + + patch_pos_embeds_permute = [] + merge_size = self.config.spatial_merge_size + for pos_embed, t, h, w in zip(patch_pos_embeds, grid_ts, grid_hs, grid_ws): + pos_embed = pos_embed.repeat(t, 1) + pos_embed = ( + pos_embed.view(t, h // merge_size, merge_size, w // merge_size, merge_size, -1) + .permute(0, 1, 3, 2, 4, 5) + .flatten(0, 4) + ) + patch_pos_embeds_permute.append(pos_embed) + patch_pos_embeds = torch.cat(patch_pos_embeds_permute) + return patch_pos_embeds + + def forward(self, hidden_states: torch.Tensor, grid_thw: torch.Tensor, **kwargs) -> torch.Tensor: + """ + Args: + hidden_states (`torch.Tensor` of shape `(seq_len, hidden_size)`): + The final hidden states of the model. + grid_thw (`torch.Tensor` of shape `(num_images_or_videos, 3)`): + The temporal, height and width of feature shape of each image in LLM. + + Returns: + `torch.Tensor`: hidden_states. + """ + hidden_states = self.patch_embed(hidden_states) + + pos_embeds = self.fast_pos_embed_interpolate(grid_thw) + hidden_states = hidden_states + pos_embeds + + rotary_pos_emb = self.rot_pos_emb(grid_thw) + + seq_len, _ = hidden_states.size() + hidden_states = hidden_states.reshape(seq_len, -1) + rotary_pos_emb = rotary_pos_emb.reshape(seq_len, -1) + emb = torch.cat((rotary_pos_emb, rotary_pos_emb), dim=-1) + position_embeddings = (emb.cos(), emb.sin()) + + cu_seqlens = torch.repeat_interleave(grid_thw[:, 1] * grid_thw[:, 2], grid_thw[:, 0]).cumsum( + dim=0, + # Select dtype based on the following factors: + # - FA2 requires that cu_seqlens_q must have dtype int32 + # - torch.onnx.export requires that cu_seqlens_q must have same dtype as grid_thw + # See https://github.com/huggingface/transformers/pull/34852 for more information + dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32, + ) + cu_seqlens = F.pad(cu_seqlens, (1, 0), value=0) + + deepstack_feature_lists = [] + for layer_num, blk in enumerate(self.blocks): + hidden_states = blk( + hidden_states, + cu_seqlens=cu_seqlens, + position_embeddings=position_embeddings, + **kwargs, + ) + if layer_num in self.deepstack_visual_indexes: + deepstack_feature = self.deepstack_merger_list[self.deepstack_visual_indexes.index(layer_num)]( + hidden_states + ) + deepstack_feature_lists.append(deepstack_feature) + + hidden_states = self.merger(hidden_states) + + return hidden_states, deepstack_feature_lists + + @property + def deepstack_merger_list(self): + return self.merger_list + + +class Qwen3OmniMoeThinkerTextRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: Qwen3OmniMoeTextConfig, device=None): + super().__init__() + if hasattr(config, "rope_scaling") and config.rope_scaling is not None: + self.rope_type = config.rope_scaling.get("rope_type", "default") + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + self.mrope_section = config.rope_scaling.get("mrope_section", [24, 20, 20]) + + def apply_interleaved_mrope(self, freqs, mrope_section): + """Apply interleaved MRoPE to 3D rotary embeddings. + Reorganizes frequency layout from chunked [TTT...HHH...WWW] to + interleaved [THTHWHTHW...TT], preserving frequency continuity. + args: + x: (3, bs, seq_len, head_dim // 2) + mrope_section: (3,) + returns: + x_t: (bs, seq_len, head_dim // 2) + """ + freqs_t = freqs[0] # just overwrite the first dimension T + for dim, offset in enumerate((1, 2), start=1): # H, W + length = mrope_section[dim] * 3 + idx = slice(offset, length, 3) + freqs_t[..., idx] = freqs[dim, ..., idx] + return freqs_t + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + # In contrast to other models, Qwen3OmniMoeThinker has different position ids for the grids + # So we expand the inv_freq to shape (3, ...) + if position_ids.ndim == 2: + position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1) + inv_freq_expanded = self.inv_freq[None, None, :, None].float().expand(3, position_ids.shape[1], -1, 1) + position_ids_expanded = position_ids[:, :, None, :].float() # shape (3, bs, 1, positions) + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(2, 3) + freqs = self.apply_interleaved_mrope(freqs, self.mrope_section) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + +class Qwen3OmniMoeThinkerTextMLP(nn.Module): + def __init__(self, config, intermediate_size=None): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = intermediate_size if intermediate_size is not None else config.intermediate_size + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +class Qwen3OmniMoeThinkerTextSparseMoeBlock(nn.Module): + def __init__(self, config): + super().__init__() + self.num_experts = config.num_experts + self.top_k = config.num_experts_per_tok + self.norm_topk_prob = config.norm_topk_prob + + # gating + self.gate = nn.Linear(config.hidden_size, config.num_experts, bias=False) + self.experts = nn.ModuleList( + [ + Qwen3OmniMoeThinkerTextMLP(config, intermediate_size=config.moe_intermediate_size) + for _ in range(self.num_experts) + ] + ) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + """ """ + batch_size, sequence_length, hidden_dim = hidden_states.shape + hidden_states = hidden_states.view(-1, hidden_dim) + # router_logits: (batch * sequence_length, n_experts) + router_logits = self.gate(hidden_states) + + routing_weights = F.softmax(router_logits, dim=1, dtype=torch.float) + routing_weights, selected_experts = torch.topk(routing_weights, self.top_k, dim=-1) + if self.norm_topk_prob: # only diff with mixtral sparse moe block! + routing_weights /= routing_weights.sum(dim=-1, keepdim=True) + # we cast back to the input dtype + routing_weights = routing_weights.to(hidden_states.dtype) + + final_hidden_states = torch.zeros( + (batch_size * sequence_length, hidden_dim), dtype=hidden_states.dtype, device=hidden_states.device + ) + + # One hot encode the selected experts to create an expert mask + # this will be used to easily index which expert is going to be sollicitated + expert_mask = torch.nn.functional.one_hot(selected_experts, num_classes=self.num_experts).permute(2, 1, 0) + + # Loop over all available experts in the model and perform the computation on each expert + expert_hit = torch.greater(expert_mask.sum(dim=(-1, -2)), 0).nonzero() + for expert_idx in expert_hit: + expert_layer = self.experts[expert_idx] + idx, top_x = torch.where(expert_mask[expert_idx].squeeze(0)) + + # Index the correct hidden states and compute the expert hidden state for + # the current expert. We need to make sure to multiply the output hidden + # states by `routing_weights` on the corresponding tokens (top-1 and top-2) + current_state = hidden_states[None, top_x].reshape(-1, hidden_dim) + current_hidden_states = expert_layer(current_state) * routing_weights[top_x, idx, None] + + # However `index_add_` only support torch tensors for indexing so we'll use + # the `top_x` tensor here. + final_hidden_states.index_add_(0, top_x, current_hidden_states.to(hidden_states.dtype)) + final_hidden_states = final_hidden_states.reshape(batch_size, sequence_length, hidden_dim) + return final_hidden_states, router_logits + + +@use_kernel_forward_from_hub("RMSNorm") +class Qwen3OmniMoeThinkerTextRMSNorm(nn.Module): + def __init__(self, hidden_size, eps=1e-6): + """ + Qwen3OmniMoeThinkerTextRMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states): + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return self.weight * hidden_states.to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1): + """Applies Rotary Position Embedding to the query and key tensors. + + Args: + q (`torch.Tensor`): The query tensor. + k (`torch.Tensor`): The key tensor. + cos (`torch.Tensor`): The cosine part of the rotary embedding. + sin (`torch.Tensor`): The sine part of the rotary embedding. + position_ids (`torch.Tensor`, *optional*): + Deprecated and unused. + unsqueeze_dim (`int`, *optional*, defaults to 1): + The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and + sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note + that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and + k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes + cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have + the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. + Returns: + `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. + """ + cos = cos.unsqueeze(unsqueeze_dim) + sin = sin.unsqueeze(unsqueeze_dim) + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + return q_embed, k_embed + + +class Qwen3OmniMoeThinkerTextAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config, layer_idx): + super().__init__() + self.config = config + self.layer_idx = layer_idx + self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) + self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads + self.scaling = self.head_dim**-0.5 + self.attention_dropout = config.attention_dropout + self.is_causal = True + + self.q_proj = nn.Linear( + config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias + ) + self.k_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.v_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.o_proj = nn.Linear( + config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias + ) + self.q_norm = Qwen3OmniMoeThinkerTextRMSNorm( + self.head_dim, eps=config.rms_norm_eps + ) # unlike olmo, only on the head dim! + self.k_norm = Qwen3OmniMoeThinkerTextRMSNorm( + self.head_dim, eps=config.rms_norm_eps + ) # thus post q_norm does not need reshape + self.sliding_window = None + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor]]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + sliding_window=self.sliding_window, # diff with Llama + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class Qwen3OmniMoeThinkerTextDecoderLayer(GradientCheckpointingLayer): + def __init__(self, config, layer_idx): + super().__init__() + self.hidden_size = config.hidden_size + self.self_attn = Qwen3OmniMoeThinkerTextAttention(config, layer_idx) + + if (layer_idx not in config.mlp_only_layers) and ( + config.num_experts > 0 and (layer_idx + 1) % config.decoder_sparse_step == 0 + ): + self.mlp = Qwen3OmniMoeThinkerTextSparseMoeBlock(config) + else: + self.mlp = Qwen3OmniMoeThinkerTextMLP(config, intermediate_size=config.intermediate_size) + + self.input_layernorm = Qwen3OmniMoeThinkerTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = Qwen3OmniMoeThinkerTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> torch.FloatTensor: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`, *optional*): attention mask of size + `(batch, sequence_length)` where padding elements are indicated by 0. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_router_logits (`bool`, *optional*): + Whether or not to return the logits of all the routers. They are useful for computing the router loss, + and should not be returned during inference. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + past_key_values (`Cache`, *optional*): cached past key and value projection states + cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): + Indices depicting the position of the input sequence tokens in the sequence. + position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): + Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`, + with `head_dim` being the embedding dimension of each attention head. + kwargs (`dict`, *optional*): + Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code + into the model + """ + residual = hidden_states + + hidden_states = self.input_layernorm(hidden_states) + + # Self Attention + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + **kwargs, + ) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + # For the MoE layers, we need to unpack + if isinstance(hidden_states, tuple): + hidden_states, _ = hidden_states + hidden_states = residual + hidden_states + + return hidden_states + + +@auto_docstring +class Qwen3OmniMoeThinkerTextPreTrainedModel(PreTrainedModel): + config = Qwen3OmniMoeTextConfig + base_model_prefix = "model" + supports_gradient_checkpointing = True + _no_split_modules = ["Qwen3OmniMoeThinkerTextDecoderLayer"] + _skip_keys_device_placement = ["past_key_values"] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + _can_compile_fullgraph = False # MoE models don't work with torch.compile (`torch.where(condition)` not supported) + _supports_attention_backend = True + _can_record_outputs = { + "router_logits": OutputRecorder(Qwen3OmniMoeThinkerTextSparseMoeBlock, index=1), + "hidden_states": Qwen3OmniMoeThinkerTextDecoderLayer, + "attentions": Qwen3OmniMoeThinkerTextAttention, + } + config_class = Qwen3OmniMoeTextConfig + + +@use_kernel_forward_from_hub("RMSNorm") +class Qwen3OmniMoeTextRMSNorm(nn.Module): + def __init__(self, hidden_size, eps=1e-6): + """ + Qwen3OmniMoeTextRMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states): + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return self.weight * hidden_states.to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +@auto_docstring( + custom_intro=( + "Text part of Qwen3OmniMoeThinker, " + "not a pure text-only model, as DeepStack integrates visual features into the early hidden states." + ) +) +class Qwen3OmniMoeThinkerTextModel(Qwen3OmniMoePreTrainedModel): + config: Qwen3OmniMoeTextConfig + _no_split_modules = ["Qwen3OmniMoeThinkerTextDecoderLayer"] + config_class = Qwen3OmniMoeTextConfig + _can_record_outputs = { + "hidden_states": Qwen3OmniMoeThinkerTextDecoderLayer, + "attentions": Qwen3OmniMoeThinkerTextAttention, + "router_logits": OutputRecorder(Qwen3OmniMoeThinkerTextSparseMoeBlock, index=1), + } + + def __init__(self, config: Qwen3OmniMoeTextConfig): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + + self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx) + self.layers = nn.ModuleList( + [Qwen3OmniMoeThinkerTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = Qwen3OmniMoeTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = Qwen3OmniMoeThinkerTextRotaryEmbedding(config) + self.gradient_checkpointing = False + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + # args for deepstack + visual_pos_masks: Optional[torch.Tensor] = None, + deepstack_visual_embeds: Optional[list[torch.Tensor]] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> Union[tuple, BaseModelOutputWithPast]: + r""" + visual_pos_masks (`torch.Tensor` of shape `(batch_size, seqlen)`, *optional*): + The mask of the visual positions. + deepstack_visual_embeds (`list[torch.Tensor]`, *optional*): + The deepstack visual embeddings. The shape is (num_layers, visual_seqlen, embed_dim). + The feature is extracted from the different visual encoder layers, and fed to the decoder + hidden states. It's from the paper DeepStack(https://arxiv.org/abs/2406.04334). + """ + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + # torch.jit.trace() doesn't support cache objects in the output + if use_cache and past_key_values is None and not torch.jit.is_tracing(): + past_key_values = DynamicCache(config=self.config) + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + # the hard coded `3` is for temporal, height and width. + if position_ids is None: + position_ids = cache_position.view(1, 1, -1).expand(3, inputs_embeds.shape[0], -1) + elif position_ids.ndim == 2: + position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1) + + if position_ids.ndim == 3 and position_ids.shape[0] == 4: + text_position_ids = position_ids[0] + position_ids = position_ids[1:] + else: + text_position_ids = position_ids[0] + + attention_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=text_position_ids, + ) + + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + # decoder layers + for layer_idx, decoder_layer in enumerate(self.layers): + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + position_ids=text_position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = layer_outputs + + # add visual features to the hidden states of first several layers + if deepstack_visual_embeds is not None and layer_idx in range(len(deepstack_visual_embeds)): + hidden_states = self._deepstack_process( + hidden_states, + visual_pos_masks, + deepstack_visual_embeds[layer_idx], + ) + + hidden_states = self.norm(hidden_states) + + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) + + def _deepstack_process( + self, hidden_states: torch.Tensor, visual_pos_masks: torch.Tensor, visual_embeds: torch.Tensor + ): + visual_pos_masks = visual_pos_masks.to(hidden_states.device) + visual_embeds = visual_embeds.to(hidden_states.device, hidden_states.dtype) + local_this = hidden_states[visual_pos_masks, :].clone() + visual_embeds + hidden_states[visual_pos_masks, :] = local_this + return hidden_states + + +@dataclass +class Qwen3OmniMoeThinkerCausalLMOutputWithPast(MoeCausalLMOutputWithPast): + r""" + Args: + rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*): + The rope index difference between sequence length and multimodal rope. + """ + + rope_deltas: Optional[torch.LongTensor] = None + + +def load_balancing_loss_func( + gate_logits: Union[torch.Tensor, tuple[torch.Tensor], None], + num_experts: Optional[int] = None, + top_k=2, + attention_mask: Optional[torch.Tensor] = None, +) -> Union[torch.Tensor, int]: + r""" + Computes auxiliary load balancing loss as in Switch Transformer - implemented in Pytorch. + + See Switch Transformer (https://huggingface.co/papers/2101.03961) for more details. This function implements the loss + function presented in equations (4) - (6) of the paper. It aims at penalizing cases where the routing between + experts is too unbalanced. + + Args: + gate_logits: + Logits from the `gate`, should be a tuple of model.config.num_hidden_layers tensors of + shape [batch_size X sequence_length, num_experts]. + num_experts: + Number of experts + top_k: + The number of experts to route per-token, can be also interpreted as the `top-k` routing + parameter. + attention_mask (`torch.Tensor`, *optional*): + The attention_mask used in forward function + shape [batch_size X sequence_length] if not None. + + Returns: + The auxiliary loss. + """ + if gate_logits is None or not isinstance(gate_logits, tuple): + return 0 + + if isinstance(gate_logits, tuple): + compute_device = gate_logits[0].device + concatenated_gate_logits = torch.cat([layer_gate.to(compute_device) for layer_gate in gate_logits], dim=0) + + routing_weights = torch.nn.functional.softmax(concatenated_gate_logits, dim=-1) + + _, selected_experts = torch.topk(routing_weights, top_k, dim=-1) + + expert_mask = torch.nn.functional.one_hot(selected_experts, num_experts) + + if attention_mask is None: + # Compute the percentage of tokens routed to each experts + tokens_per_expert = torch.mean(expert_mask.float(), dim=0) + + # Compute the average probability of routing to these experts + router_prob_per_expert = torch.mean(routing_weights, dim=0) + else: + batch_size, sequence_length = attention_mask.shape + num_hidden_layers = concatenated_gate_logits.shape[0] // (batch_size * sequence_length) + + # Compute the mask that masks all padding tokens as 0 with the same shape of expert_mask + expert_attention_mask = ( + attention_mask[None, :, :, None, None] + .expand((num_hidden_layers, batch_size, sequence_length, top_k, num_experts)) + .reshape(-1, top_k, num_experts) + .to(compute_device) + ) + + # Compute the percentage of tokens routed to each experts + tokens_per_expert = torch.sum(expert_mask.float() * expert_attention_mask, dim=0) / torch.sum( + expert_attention_mask, dim=0 + ) + + # Compute the mask that masks all padding tokens as 0 with the same shape of tokens_per_expert + router_per_expert_attention_mask = ( + attention_mask[None, :, :, None] + .expand((num_hidden_layers, batch_size, sequence_length, num_experts)) + .reshape(-1, num_experts) + .to(compute_device) + ) + + # Compute the average probability of routing to these experts + router_prob_per_expert = torch.sum(routing_weights * router_per_expert_attention_mask, dim=0) / torch.sum( + router_per_expert_attention_mask, dim=0 + ) + + overall_loss = torch.sum(tokens_per_expert * router_prob_per_expert.unsqueeze(0)) + return overall_loss * num_experts + + +@auto_docstring( + custom_intro=""" + The Qwen2.5OmniThinker model which consists of a audio backbone and a language model. + """ +) +class Qwen3OmniMoeThinkerForConditionalGeneration( + Qwen3OmniMoePreTrainedModelForConditionalGeneration, GenerationMixin +): + config: Qwen3OmniMoeThinkerConfig + base_model_prefix = "thinker" + _tied_weights_keys = ["model.embed_tokens.weight", "lm_head.weight"] + _no_split_modules = [ + "Qwen3OmniMoeAudioEncoderLayer", + "Qwen3OmniMoeThinkerTextDecoderLayer", + ] + _can_record_outputs = { + "hidden_states": Qwen3OmniMoeThinkerTextDecoderLayer, + "attentions": Qwen3OmniMoeThinkerTextAttention, + "router_logits": OutputRecorder(Qwen3OmniMoeThinkerTextSparseMoeBlock, index=1), + } + + def __init__(self, config): + super().__init__(config) + self.audio_tower = Qwen3OmniMoeAudioEncoder._from_config(config.audio_config) + self.visual = Qwen3OmniMoeVisionEncoder._from_config(config.vision_config) + self.vocab_size = config.text_config.vocab_size + self.model = Qwen3OmniMoeThinkerTextModel._from_config(config.text_config) + self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False) + self.pad_token_id = self.config.pad_token_id if self.config.pad_token_id is not None else -1 + self.spatial_merge_size = config.vision_config.spatial_merge_size + self.rope_deltas = None + self.num_experts = config.text_config.num_experts + self.num_experts_per_tok = config.text_config.num_experts_per_tok + self.post_init() + + def get_input_embeddings(self): + return self.model.get_input_embeddings() + + def set_input_embeddings(self, value): + self.model.set_input_embeddings(value) + + def get_video_features( + self, pixel_values_videos: torch.FloatTensor, video_grid_thw: Optional[torch.LongTensor] = None + ): + """ + Encodes videos into continuous embeddings that can be forwarded to the language model. + + Args: + pixel_values_videos (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`): + The tensors corresponding to the input videos. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + """ + pixel_values_videos = pixel_values_videos.type(self.visual.dtype) + video_embeds = self.visual(pixel_values_videos, grid_thw=video_grid_thw) + return video_embeds + + def get_image_features(self, pixel_values: torch.FloatTensor, image_grid_thw: Optional[torch.LongTensor] = None): + """ + Encodes images into continuous embeddings that can be forwarded to the language model. + + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`): + The tensors corresponding to the input images. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + """ + pixel_values = pixel_values.type(self.visual.dtype) + image_embeds = self.visual(pixel_values, grid_thw=image_grid_thw) + return image_embeds + + def get_audio_features( + self, + input_features: torch.FloatTensor, + feature_attention_mask: Optional[torch.LongTensor] = None, + audio_feature_lengths: Optional[torch.LongTensor] = None, + ): + """ + Encodes audios into continuous embeddings that can be forwarded to the language model. + + Args: + input_features (`torch.FloatTensor`): + The tensors corresponding to the input audios. + feature_attention_mask (`torch.LongTensor`, *optional*): + Mask to avoid performing attention on padding feature indices. Mask values selected in `[0, 1]`: + audio_feature_lengths (`torch.LongTensor` of shape `(num_audios)`, *optional*): + The length of feature shape of each audio in LLM. + """ + if feature_attention_mask is not None: + audio_feature_lengths = torch.sum(feature_attention_mask, dim=1) + input_features = input_features.permute(0, 2, 1)[feature_attention_mask.bool()].permute(1, 0) + else: + audio_feature_lengths = None + + feature_lens = audio_feature_lengths if audio_feature_lengths is not None else feature_attention_mask.sum(-1) + audio_outputs = self.audio_tower( + input_features, + feature_lens=feature_lens, + ) + audio_features = audio_outputs.last_hidden_state + + return audio_features + + def get_placeholder_mask( + self, + input_ids: torch.LongTensor, + inputs_embeds: torch.FloatTensor, + image_features: Optional[torch.FloatTensor] = None, + video_features: Optional[torch.FloatTensor] = None, + ): + """ + Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is + equal to the length of multimodal features. If the lengths are different, an error is raised. + """ + if input_ids is None: + special_image_mask = inputs_embeds == self.get_input_embeddings()( + torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + special_image_mask = special_image_mask.all(-1) + special_video_mask = inputs_embeds == self.get_input_embeddings()( + torch.tensor(self.config.video_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + special_video_mask = special_video_mask.all(-1) + special_audio_mask = ( + inputs_embeds + == self.get_input_embeddings()( + torch.tensor(self.config.audio_token_id, dtype=torch.long, device=inputs_embeds.device) + ) + ).all(-1) + else: + special_image_mask = input_ids == self.config.image_token_id + special_video_mask = input_ids == self.config.video_token_id + special_audio_mask = input_ids == self.config.audio_token_id + + n_image_tokens = special_image_mask.sum() + special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device) + if image_features is not None and inputs_embeds[special_image_mask].numel() != image_features.numel(): + raise ValueError( + f"Image features and image tokens do not match: tokens: {n_image_tokens}, features {image_features.shape[0]}" + ) + + n_video_tokens = special_video_mask.sum() + special_video_mask = special_video_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device) + if video_features is not None and inputs_embeds[special_video_mask].numel() != video_features.numel(): + raise ValueError( + f"Videos features and image tokens do not match: tokens: {n_video_tokens}, features {video_features.shape[0]}" + ) + + special_audio_mask = special_audio_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device) + return special_image_mask, special_video_mask, special_audio_mask + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids=None, + input_features=None, + pixel_values=None, + pixel_values_videos=None, + image_grid_thw=None, + video_grid_thw=None, + attention_mask=None, + feature_attention_mask=None, + audio_feature_lengths=None, + position_ids=None, + past_key_values=None, + inputs_embeds=None, + rope_deltas=None, + labels=None, + use_cache=None, + output_router_logits: Optional[bool] = None, + use_audio_in_video=None, + cache_position=None, + video_second_per_grid=None, + **kwargs, + ) -> Union[tuple, Qwen3OmniMoeThinkerCausalLMOutputWithPast]: + r""" + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + feature_attention_mask (`torch.Tensor` of shape `(batch_size, feature_sequence_length)`, *optional*): + Mask to avoid performing attention on padding feature indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + audio_feature_lengths (`torch.LongTensor` of shape `(num_audios)`, *optional*): + The length of feature shape of each audio in LLM. + rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*): + The rope index difference between sequence length and multimodal rope. + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + use_audio_in_video (`bool`, *optional*): + Whether or not use audio track in video, should same as the parameter in `process_audio_info`. + video_second_per_grid (`torch.LongTensor` of shape `(num_videos)`, *optional*): + Number of seconds per grid for each video, used for temporal feature mapping. + + Example: + + ```python + >>> from io import BytesIO + >>> from urllib.request import urlopen + >>> import librosa + >>> from qwen_vl_utils import process_vision_info + >>> from transformers import Qwen3OmniMoeProcessor, Qwen3OmniMoeThinkerForConditionalGeneration + + >>> thinker = Qwen3OmniMoeThinkerForConditionalGeneration.from_pretrained("Qwen/Qwen2.5-Omni-7B") + >>> processor = Qwen3OmniMoeProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B") + + >>> conversations = [ + >>> {'role': 'system', 'content': 'You are a helpful voice chat bot, and please respond to me in a casual conversation manner using random voice.'}, + >>> {"role": "user", "content": [ + >>> {"type": "image", "image_url": "https://www.ilankelman.org/stopsigns/australia.jpg"}, + >>> {"type": "audio", "audio_url": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/glass-breaking-151256.mp3"}, + >>> ]}, + >>> ] + + >>> text = processor.apply_chat_template(conversation, add_generation_prompt=True, tokenize=False) + >>> audios = [ librosa.load(BytesIO(urlopen( conversations[1]['content'][1]['audio_url'] ).read()), sr=self.processor.feature_extractor.sampling_rate) ] + >>> images, videos = process_vision_info(conversations) + >>> inputs = processor(text=text, audios=audios, images=images, videos=videos, return_tensors="pt", padding=True) + + >>> # Generate + >>> inputs['use_audio_in_video'] = `True` or `False` + >>> generation = thinker.generate(**inputs, max_new_tokens=2048) + >>> generate_ids = generation[:, inputs.input_ids.size(1):] + + >>> response = processor.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] + ```""" + output_router_logits = ( + output_router_logits if output_router_logits is not None else self.config.text_config.output_router_logits + ) + + if inputs_embeds is None: + # 1. Extract the input embeddings + inputs_embeds = self.get_input_embeddings()(input_ids) + + visual_embeds_multiscale = None + visual_pos_masks = None + # 2. Merge text , audios , image and video + if input_features is not None: + audio_features = self.get_audio_features( + input_features, + feature_attention_mask=feature_attention_mask, + audio_feature_lengths=audio_feature_lengths, + ) + audio_features = audio_features.to(inputs_embeds.device, inputs_embeds.dtype) + _, _, audio_mask = self.get_placeholder_mask(input_ids, inputs_embeds=inputs_embeds) + inputs_embeds = inputs_embeds.masked_scatter(audio_mask, audio_features) + + if pixel_values is not None: + image_embeds, image_embeds_multiscale = self.get_image_features(pixel_values, image_grid_thw) + image_embeds = image_embeds.to(inputs_embeds.device, inputs_embeds.dtype) + image_mask, _, _ = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, image_features=image_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds) + + visual_pos_masks = image_mask + visual_embeds_multiscale = image_embeds_multiscale + + if pixel_values_videos is not None: + video_embeds, video_embeds_multiscale = self.get_video_features(pixel_values_videos, video_grid_thw) + + video_embeds = video_embeds.to(inputs_embeds.device, inputs_embeds.dtype) + _, video_mask, _ = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, video_features=video_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter(video_mask, video_embeds) + + if visual_embeds_multiscale is None: + visual_embeds_multiscale = video_embeds_multiscale + visual_pos_masks = video_mask + else: + visual_pos_masks = video_mask | image_mask + visual_embeds_multiscale_joint = () + image_mask_joint = image_mask[visual_pos_masks] + video_mask_joint = video_mask[visual_pos_masks] + for img_embed, vid_embed in zip(visual_embeds_multiscale, video_embeds_multiscale): + embed_joint = img_embed.new_zeros(visual_pos_masks.sum(), img_embed.shape[-1]) + embed_joint[image_mask_joint, :] = img_embed + embed_joint[video_mask_joint, :] = vid_embed + visual_embeds_multiscale_joint = visual_embeds_multiscale_joint + (embed_joint,) + visual_embeds_multiscale = visual_embeds_multiscale_joint + + if feature_attention_mask is not None: + audio_feature_lengths = torch.sum(feature_attention_mask, dim=1) + else: + audio_feature_lengths = None + + if attention_mask is not None and position_ids is None: + if ( + cache_position is None + or (cache_position is not None and cache_position[0] == 0) + or self.rope_deltas is None + ): + delta0 = (1 - attention_mask).sum(dim=-1).unsqueeze(1) + position_ids, rope_deltas = self.get_rope_index( + input_ids, + image_grid_thw, + video_grid_thw, + attention_mask, + use_audio_in_video, + audio_feature_lengths, + video_second_per_grid, + ) + rope_deltas = rope_deltas - delta0 + self.rope_deltas = rope_deltas + else: + batch_size, seq_length = input_ids.shape + delta = cache_position[0] + self.rope_deltas if cache_position is not None else 0 + position_ids = torch.arange(seq_length, device=input_ids.device) + position_ids = position_ids.view(1, -1).expand(batch_size, -1) + position_ids = position_ids.add(delta) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1) + + outputs = self.model( + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_router_logits=output_router_logits, + cache_position=cache_position, + deepstack_visual_embeds_multiscale=visual_embeds_multiscale, + visual_pos_masks=visual_pos_masks, + **kwargs, + ) + + hidden_states = outputs[0] + logits = self.lm_head(hidden_states) + + loss = None + if labels is not None: + loss = self.loss_function( + logits=logits, labels=labels, vocab_size=self.config.get_text_config().vocab_size + ) + + aux_loss = None + if output_router_logits: + aux_loss = load_balancing_loss_func( + outputs.router_logits, + self.num_experts, + self.num_experts_per_tok, + attention_mask, + ) + if labels is not None: + loss += self.router_aux_loss_coef * aux_loss.to(loss.device) # make sure to reside in the same device + + return Qwen3OmniMoeThinkerCausalLMOutputWithPast( + loss=loss, + logits=logits, + aux_loss=aux_loss, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + past_key_values=outputs.past_key_values, + rope_deltas=self.rope_deltas, + ) + + def prepare_inputs_for_generation( + self, + input_ids, + past_key_values=None, + attention_mask=None, + inputs_embeds=None, + cache_position=None, + position_ids=None, + use_cache=True, + pixel_values=None, + pixel_values_videos=None, + image_grid_thw=None, + video_grid_thw=None, + input_features=None, + feature_attention_mask=None, + use_audio_in_video=False, + video_second_per_grid=None, + **kwargs, + ): + model_inputs = super().prepare_inputs_for_generation( + input_ids, + past_key_values=past_key_values, + attention_mask=attention_mask, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + position_ids=position_ids, + use_cache=use_cache, + pixel_values=pixel_values, + pixel_values_videos=pixel_values_videos, + image_grid_thw=image_grid_thw, + video_grid_thw=video_grid_thw, + input_features=input_features, + feature_attention_mask=feature_attention_mask, + use_audio_in_video=use_audio_in_video, + video_second_per_grid=video_second_per_grid, + **kwargs, + ) + + model_inputs["position_ids"] = None + + if cache_position[0] != 0: + model_inputs["pixel_values"] = None + model_inputs["pixel_values_videos"] = None + model_inputs["input_features"] = None + + return model_inputs + + +class Qwen3OmniMoeTalkerResizeMLP(nn.Module): + def __init__(self, config: Qwen3OmniMoeTalkerConfig): + super().__init__() + self.linear_fc1 = nn.Linear(config.thinker_hidden_size, config.text_config.intermediate_size, bias=True) + self.linear_fc2 = nn.Linear(config.text_config.intermediate_size, config.text_config.hidden_size, bias=True) + self.act_fn = ACT2FN[config.text_config.hidden_act] + + def forward(self, hidden_state): + return self.linear_fc2(self.act_fn(self.linear_fc1(hidden_state))) + + +@dataclass +class Qwen3OmniMoeTalkerCodePredictorOutputWithPast(CausalLMOutputWithPast): + r""" + generation_steps (`int`, *optional*) + Current generation step of code predictor model. + """ + + generation_steps: Optional[int] = None + + +@use_kernel_forward_from_hub("RMSNorm") +class Qwen3OmniMoeRMSNorm(nn.Module): + def __init__(self, hidden_size, eps: float = 1e-6) -> None: + """ + Qwen3OmniMoeRMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return self.weight * hidden_states.to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +class Qwen3OmniMoeTalkerCodePredictorAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: Qwen3OmniMoeConfig, layer_idx: int): + super().__init__() + self.config = config + self.layer_idx = layer_idx + self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) + self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads + self.scaling = self.head_dim**-0.5 + self.attention_dropout = config.attention_dropout + self.is_causal = True + + self.q_proj = nn.Linear( + config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias + ) + self.k_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.v_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.o_proj = nn.Linear( + config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias + ) + self.q_norm = Qwen3OmniMoeRMSNorm(self.head_dim, eps=config.rms_norm_eps) # unlike olmo, only on the head dim! + self.k_norm = Qwen3OmniMoeRMSNorm( + self.head_dim, eps=config.rms_norm_eps + ) # thus post q_norm does not need reshape + self.sliding_window = config.sliding_window if config.layer_types[layer_idx] == "sliding_attention" else None + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor]]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + sliding_window=self.sliding_window, # diff with Llama + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class Qwen3OmniMoeMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +class Qwen3OmniMoeTalkerCodePredictorDecoderLayer(GradientCheckpointingLayer): + def __init__(self, config, layer_idx): + super().__init__() + self.hidden_size = config.hidden_size + self.self_attn = Qwen3OmniMoeTalkerCodePredictorAttention(config=config, layer_idx=layer_idx) + + self.mlp = Qwen3OmniMoeMLP(config) + self.input_layernorm = Qwen3OmniMoeRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = Qwen3OmniMoeRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.attention_type = config.layer_types[layer_idx] + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, # necessary, but kept here for BC + **kwargs: Unpack[TransformersKwargs], + ) -> torch.Tensor: + residual = hidden_states + hidden_states = self.input_layernorm(hidden_states) + # Self Attention + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + hidden_states + return hidden_states + + +class Qwen3OmniMoeRotaryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: Qwen3OmniMoeConfig, device=None): + super().__init__() + # BC: "rope_type" was originally "type" + if hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): + self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type")) + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device) + position_ids_expanded = position_ids[:, None, :].float() + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + +@auto_docstring +class Qwen3OmniMoeTalkerCodePredictorModel(Qwen3OmniMoePreTrainedModel): + config_class = Qwen3OmniMoeTalkerCodePredictorConfig + base_model_prefix = "talker.code_predictor.model" + _can_record_outputs = { + "attentions": Qwen3OmniMoeTalkerCodePredictorAttention, + "hidden_states": Qwen3OmniMoeTalkerCodePredictorDecoderLayer, + } + + def __init__(self, config: Qwen3OmniMoeTalkerCodePredictorConfig): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + self.layers = nn.ModuleList( + [ + Qwen3OmniMoeTalkerCodePredictorDecoderLayer(config, layer_idx) + for layer_idx in range(config.num_hidden_layers) + ] + ) + self.norm = Qwen3OmniMoeRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = Qwen3OmniMoeRotaryEmbedding(config=config) + self.gradient_checkpointing = False + self.has_sliding_layers = "sliding_attention" in self.config.layer_types + self.codec_embedding = nn.ModuleList( + [nn.Embedding(config.vocab_size, config.hidden_size) for _ in range(config.num_code_groups - 1)] + ) + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> BaseModelOutputWithPast: + if input_ids is not None: + raise ValueError("`input_ids` is expected to be `None`") + + if use_cache and past_key_values is None: + past_key_values = DynamicCache(config=self.config) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + # It may already have been prepared by e.g. `generate` + if not isinstance(causal_mask_mapping := attention_mask, dict): + # Prepare mask arguments + mask_kwargs = { + "config": self.config, + "input_embeds": inputs_embeds, + "attention_mask": attention_mask, + "cache_position": cache_position, + "past_key_values": past_key_values, + "position_ids": position_ids, + } + # Create the masks + causal_mask_mapping = { + "full_attention": create_causal_mask(**mask_kwargs), + } + + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for decoder_layer in self.layers[: self.config.num_hidden_layers]: + hidden_states = decoder_layer( + hidden_states, + attention_mask=causal_mask_mapping[decoder_layer.attention_type], + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values if use_cache else None, + ) + + def get_input_embeddings(self): + return self.codec_embedding + + +@auto_docstring +class Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration(Qwen3OmniMoePreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.weight"] + _tp_plan = {"lm_head": "colwise_rep"} + _pp_plan = {"lm_head": (["hidden_states"], ["logits"])} + config_class = Qwen3OmniMoeTalkerCodePredictorConfig + base_model_prefix = "talker.code_predictor" + _can_record_outputs = { + "attentions": Qwen3OmniMoeTalkerCodePredictorAttention, + "hidden_states": Qwen3OmniMoeTalkerCodePredictorDecoderLayer, + } + + def __init__(self, config: Qwen3OmniMoeTalkerCodePredictorConfig): + super().__init__(config) + self.model = Qwen3OmniMoeTalkerCodePredictorModel._from_config(config) + self.vocab_size = config.vocab_size + self.lm_head = nn.ModuleList( + [nn.Linear(config.hidden_size, config.vocab_size, bias=False) for _ in range(config.num_code_groups - 1)] + ) + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids=None, + attention_mask=None, + position_ids=None, + past_key_values=None, + inputs_embeds=None, + labels=None, + use_cache=None, + cache_position=None, + generation_steps=None, + **kwargs, + ) -> CausalLMOutputWithPast: + r""" + Args: + generation_steps (`int`): + generation step of code predictor, 0..num_code_groups-1 + """ + + # Prefill stage + if inputs_embeds is not None and inputs_embeds.shape[1] > 1: + generation_steps = inputs_embeds.shape[1] - 2 # hidden & layer 0 + # Generation stage + else: + inputs_embeds = self.model.get_input_embeddings()[generation_steps - 1](input_ids) + + # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn) + outputs: BaseModelOutputWithPast = self.model( + input_ids=None, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs.last_hidden_state + logits = self.lm_head[generation_steps](hidden_states) + + loss = None + if labels is not None: + loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs) + + return Qwen3OmniMoeTalkerCodePredictorOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + generation_steps=generation_steps + 1, + ) + + def get_input_embeddings(self): + return self.model.get_input_embeddings() + + def _update_model_kwargs_for_generation(self, outputs, model_kwargs, is_encoder_decoder=False, num_new_tokens=1): + model_kwargs = super()._update_model_kwargs_for_generation( + outputs, model_kwargs, is_encoder_decoder, num_new_tokens + ) + model_kwargs["generation_steps"] = outputs.generation_steps + return model_kwargs + + +@dataclass +class Qwen3OmniMoeTalkerOutputWithPast(MoeCausalLMOutputWithPast): + r""" + Args: + generation_step (`int`, *optional*): + Current generation step, used to track which `trailing_text_hidden` should be used. + """ + + generation_step: Optional[int] = None + + +class Qwen3OmniMoeTalkerRotaryEmbedding(Qwen3OmniMoeThinkerTextRotaryEmbedding): + pass + + +class Qwen3OmniMoeTalkerTextMLP(nn.Module): + def __init__(self, config, intermediate_size=None): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = intermediate_size if intermediate_size is not None else config.intermediate_size + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +class Qwen3OmniMoeTalkerTextSparseMoeBlock(nn.Module): + def __init__(self, config): + super().__init__() + self.num_experts = config.num_experts + self.top_k = config.num_experts_per_tok + self.norm_topk_prob = config.norm_topk_prob + + # gating + self.gate = nn.Linear(config.hidden_size, config.num_experts, bias=False) + self.experts = nn.ModuleList( + [ + Qwen3OmniMoeTalkerTextMLP(config, intermediate_size=config.moe_intermediate_size) + for _ in range(self.num_experts) + ] + ) + + self.shared_expert = Qwen3OmniMoeTalkerTextMLP( + config, intermediate_size=config.shared_expert_intermediate_size + ) + self.shared_expert_gate = torch.nn.Linear(config.hidden_size, 1, bias=False) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + """ """ + batch_size, sequence_length, hidden_dim = hidden_states.shape + hidden_states = hidden_states.view(-1, hidden_dim) + # router_logits: (batch * sequence_length, n_experts) + router_logits = self.gate(hidden_states) + + routing_weights = F.softmax(router_logits, dim=1, dtype=torch.float) + routing_weights, selected_experts = torch.topk(routing_weights, self.top_k, dim=-1) + if self.norm_topk_prob: + routing_weights /= routing_weights.sum(dim=-1, keepdim=True) + # we cast back to the input dtype + routing_weights = routing_weights.to(hidden_states.dtype) + + final_hidden_states = torch.zeros( + (batch_size * sequence_length, hidden_dim), dtype=hidden_states.dtype, device=hidden_states.device + ) + + # One hot encode the selected experts to create an expert mask + # this will be used to easily index which expert is going to be sollicitated + expert_mask = torch.nn.functional.one_hot(selected_experts, num_classes=self.num_experts).permute(2, 1, 0) + + # Loop over all available experts in the model and perform the computation on each expert + expert_hit = torch.greater(expert_mask.sum(dim=(-1, -2)), 0).nonzero() + for expert_idx in expert_hit: + expert_layer = self.experts[expert_idx] + idx, top_x = torch.where(expert_mask[expert_idx].squeeze(0)) + + # Index the correct hidden states and compute the expert hidden state for + # the current expert. We need to make sure to multiply the output hidden + # states by `routing_weights` on the corresponding tokens (top-1 and top-2) + current_state = hidden_states[None, top_x].reshape(-1, hidden_dim) + current_hidden_states = expert_layer(current_state) * routing_weights[top_x, idx, None] + + # However `index_add_` only support torch tensors for indexing so we'll use + # the `top_x` tensor here. + final_hidden_states.index_add_(0, top_x, current_hidden_states.to(hidden_states.dtype)) + + shared_expert_output = self.shared_expert(hidden_states) + shared_expert_output = F.sigmoid(self.shared_expert_gate(hidden_states)) * shared_expert_output + + final_hidden_states = final_hidden_states + shared_expert_output + + final_hidden_states = final_hidden_states.reshape(batch_size, sequence_length, hidden_dim) + return final_hidden_states, router_logits + + +class Qwen3OmniMoeTalkerDecoderLayer(GradientCheckpointingLayer): + def __init__(self, config, layer_idx): + super().__init__() + self.hidden_size = config.hidden_size + self.self_attn = Qwen3OmniMoeThinkerTextAttention(config, layer_idx) + + if (layer_idx not in config.mlp_only_layers) and ( + config.num_experts > 0 and (layer_idx + 1) % config.decoder_sparse_step == 0 + ): + self.mlp = Qwen3OmniMoeThinkerTextSparseMoeBlock(config) + else: + self.mlp = Qwen3OmniMoeThinkerTextMLP(config, intermediate_size=config.intermediate_size) + + self.input_layernorm = Qwen3OmniMoeThinkerTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = Qwen3OmniMoeThinkerTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.mlp = Qwen3OmniMoeTalkerTextSparseMoeBlock(config) + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> torch.FloatTensor: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`, *optional*): attention mask of size + `(batch, sequence_length)` where padding elements are indicated by 0. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_router_logits (`bool`, *optional*): + Whether or not to return the logits of all the routers. They are useful for computing the router loss, + and should not be returned during inference. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + past_key_values (`Cache`, *optional*): cached past key and value projection states + cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): + Indices depicting the position of the input sequence tokens in the sequence. + position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*): + Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`, + with `head_dim` being the embedding dimension of each attention head. + kwargs (`dict`, *optional*): + Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code + into the model + """ + residual = hidden_states + + hidden_states = self.input_layernorm(hidden_states) + + # Self Attention + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + **kwargs, + ) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + # For the MoE layers, we need to unpack + if isinstance(hidden_states, tuple): + hidden_states, _ = hidden_states + hidden_states = residual + hidden_states + + return hidden_states + + +@auto_docstring( + custom_intro=( + "Text part of Qwen3OmniMoe, " + "not a pure text-only model, as DeepStack integrates visual features into the early hidden states." + ) +) +class Qwen3OmniMoeTalkerModel(Qwen3OmniMoePreTrainedModel): + config: Qwen3OmniMoeTextConfig + _no_split_modules = ["Qwen3OmniMoeTalkerDecoderLayer"] + config_class = Qwen3OmniMoeTalkerTextConfig + base_model_prefix = "talker.model" + _can_record_outputs = { + "hidden_states": Qwen3OmniMoeTalkerDecoderLayer, + "attentions": Qwen3OmniMoeThinkerTextAttention, + "router_logits": OutputRecorder(Qwen3OmniMoeTalkerTextSparseMoeBlock, index=1), + } + + def __init__(self, config: Qwen3OmniMoeTalkerTextConfig): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + self.layers = nn.ModuleList( + [Qwen3OmniMoeTalkerDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = Qwen3OmniMoeTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = Qwen3OmniMoeTalkerRotaryEmbedding(config) + self.gradient_checkpointing = False + self.codec_embedding = nn.Embedding(config.vocab_size, config.hidden_size) + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + # args for deepstack + visual_pos_masks: Optional[torch.Tensor] = None, + deepstack_visual_embeds: Optional[list[torch.Tensor]] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> Union[tuple, BaseModelOutputWithPast]: + r""" + visual_pos_masks (`torch.Tensor` of shape `(batch_size, seqlen)`, *optional*): + The mask of the visual positions. + deepstack_visual_embeds (`list[torch.Tensor]`, *optional*): + The deepstack visual embeddings. The shape is (num_layers, visual_seqlen, embed_dim). + The feature is extracted from the different visual encoder layers, and fed to the decoder + hidden states. It's from the paper DeepStack(https://arxiv.org/abs/2406.04334). + """ + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + # torch.jit.trace() doesn't support cache objects in the output + if use_cache and past_key_values is None and not torch.jit.is_tracing(): + past_key_values = DynamicCache(config=self.config) + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + # the hard coded `3` is for temporal, height and width. + if position_ids is None: + position_ids = cache_position.view(1, 1, -1).expand(3, inputs_embeds.shape[0], -1) + elif position_ids.ndim == 2: + position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1) + + if position_ids.ndim == 3 and position_ids.shape[0] == 4: + text_position_ids = position_ids[0] + position_ids = position_ids[1:] + else: + text_position_ids = position_ids[0] + + attention_mask = create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=text_position_ids, + ) + + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + # decoder layers + for layer_idx, decoder_layer in enumerate(self.layers): + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + position_ids=text_position_ids, + past_key_values=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = layer_outputs + + # add visual features to the hidden states of first several layers + if deepstack_visual_embeds is not None and layer_idx in range(len(deepstack_visual_embeds)): + hidden_states = self._deepstack_process( + hidden_states, + visual_pos_masks, + deepstack_visual_embeds[layer_idx], + ) + + hidden_states = self.norm(hidden_states) + + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) + + def _deepstack_process( + self, hidden_states: torch.Tensor, visual_pos_masks: torch.Tensor, visual_embeds: torch.Tensor + ): + visual_pos_masks = visual_pos_masks.to(hidden_states.device) + visual_embeds = visual_embeds.to(hidden_states.device, hidden_states.dtype) + local_this = hidden_states[visual_pos_masks, :].clone() + visual_embeds + hidden_states[visual_pos_masks, :] = local_this + return hidden_states + + def get_input_embeddings(self): + return self.codec_embedding + + +@auto_docstring +class Qwen3OmniMoeTalkerForConditionalGeneration(Qwen3OmniMoeThinkerTextPreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.weight"] + _tp_plan = {"lm_head": "colwise_rep"} + _pp_plan = {"lm_head": (["hidden_states"], ["logits"])} + config_class = Qwen3OmniMoeTalkerConfig + base_model_prefix = "talker" + _no_split_modules = ["Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration"] + _can_record_outputs = { + "attentions": Qwen3OmniMoeThinkerTextAttention, + "router_logits": OutputRecorder(Qwen3OmniMoeTalkerTextSparseMoeBlock, index=1), + } + + def __init__(self, config: Qwen3OmniMoeTalkerConfig): + super().__init__(config) + self.model = Qwen3OmniMoeTalkerModel._from_config(config.text_config) + self.vocab_size = config.text_config.vocab_size + self.router_aux_loss_coef = config.text_config.router_aux_loss_coef + self.num_experts = config.text_config.num_experts + self.num_experts_per_tok = config.text_config.num_experts_per_tok + self.text_projection = Qwen3OmniMoeTalkerResizeMLP(config) + self.hidden_projection = Qwen3OmniMoeTalkerResizeMLP(config) + self.codec_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False) + self.code_predictor = Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration._from_config( + config=config.code_predictor_config + ) + self.rope_deltas = None + self.spatial_merge_size = self.config.spatial_merge_size + + # Initialize weights and apply final processing + self.post_init() + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids=None, + attention_mask=None, + use_audio_in_video=None, + audio_feature_lengths=None, + video_second_per_grid=None, + image_grid_thw=None, + video_grid_thw=None, + position_ids=None, + past_key_values=None, + inputs_embeds=None, + labels=None, + use_cache=None, + output_router_logits=None, + cache_position=None, + residual_codes=None, + trailing_text_hidden=None, + tts_pad_embed=None, + generation_step=None, + talker_input_ids=None, + **kwargs, + ) -> MoeCausalLMOutputWithPast: + r""" + Args: + use_audio_in_video (`bool`, *optional*): + If set to `True`, use the audio in video. + audio_feature_lengths (`torch.LongTensor` of shape `(num_audios)`, *optional*): + The length of feature shape of each audio in LLM. + video_second_per_grid (`torch.LongTensor` of shape `(num_videos)`, *optional*): + Number of seconds per grid for each video, used for temporal feature mapping. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + residual_codes (`torch.Tensor`): + The predicted residual codes of previous step. + trailing_text_hidden (`torch.Tensor`): + Text hidden states from thinker after the first token. + tts_pad_embed (`torch.Tensor`): + Embedding tensor of `tts_pad_token_id`. + generation_step (`int`): + Generation step since prefill, used to sync with `trailing_text_hidden`. + talker_input_ids (`torch.Tensor`): + Input ids from thinker, used to compute 3d RoPE. + """ + # Prefill + if inputs_embeds is not None and inputs_embeds.shape[1] > 1: + generation_step = -1 + residual_codes = None + if attention_mask is not None: + if ( + cache_position is None + or (cache_position is not None and cache_position[0] == 0) + or self.rope_deltas is None + ): + delta0 = (1 - attention_mask).sum(dim=-1).unsqueeze(1) + position_ids, rope_deltas = self.get_rope_index( + talker_input_ids, + image_grid_thw, + video_grid_thw, + attention_mask, + use_audio_in_video, + audio_feature_lengths, + video_second_per_grid, + ) + rope_deltas = rope_deltas - delta0 + self.rope_deltas = rope_deltas + else: + batch_size, seq_length = input_ids.shape + delta = cache_position[0] + self.rope_deltas if cache_position is not None else 0 + position_ids = torch.arange(seq_length, device=input_ids.device) + position_ids = position_ids.view(1, -1).expand(batch_size, -1) + position_ids = position_ids.add(delta) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1) + + outputs: MoeModelOutputWithPast = self.model( + input_ids=None, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_router_logits=output_router_logits, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs.last_hidden_state + logits = self.codec_head(hidden_states) + + loss = None + if labels is not None: + loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs) + + aux_loss = None + if output_router_logits: + aux_loss = load_balancing_loss_func( + outputs.router_logits, + self.num_experts, + self.num_experts_per_tok, + attention_mask, + ) + if labels is not None: + loss += self.router_aux_loss_coef * aux_loss.to(loss.device) # make sure to reside in the same device + + return Qwen3OmniMoeTalkerOutputWithPast( + loss=loss, + logits=logits, + aux_loss=aux_loss, + past_key_values=outputs.past_key_values, + hidden_states=( + outputs.hidden_states, + residual_codes, + ), # TODO: hack here to take residual codes out, need refactor. + generation_step=generation_step + 1, + ) + + # Should inherit from PretrainedModel, but cannot inherit multiple classes in modular + def get_rope_index( + self, + input_ids: Optional[torch.LongTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + use_audio_in_video: bool = False, + audio_seqlens: Optional[torch.LongTensor] = None, + second_per_grids: Optional[torch.Tensor] = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + return Qwen3OmniMoePreTrainedModelForConditionalGeneration.get_rope_index( + self, + input_ids, + image_grid_thw, + video_grid_thw, + attention_mask, + use_audio_in_video, + audio_seqlens, + second_per_grids, + ) + + def get_llm_pos_ids_for_vision( + self, + start_idx: int, + vision_idx: int, + spatial_merge_size: int, + t_index: list[torch.Tensor], + grid_hs: list[torch.Tensor], + grid_ws: list[torch.Tensor], + ): + return Qwen3OmniMoePreTrainedModelForConditionalGeneration.get_llm_pos_ids_for_vision( + self, start_idx, vision_idx, spatial_merge_size, t_index, grid_hs, grid_ws + ) + + def get_input_embeddings(self): + return self.model.get_input_embeddings() + + def _update_model_kwargs_for_generation(self, outputs, model_kwargs, is_encoder_decoder=False, num_new_tokens=1): + model_kwargs = super()._update_model_kwargs_for_generation( + outputs, model_kwargs, is_encoder_decoder, num_new_tokens + ) + model_kwargs["hidden_states"] = outputs.hidden_states + model_kwargs["generation_step"] = outputs.generation_step + return model_kwargs + + def prepare_inputs_for_generation( + self, input_ids, past_key_values=None, attention_mask=None, inputs_embeds=None, cache_position=None, **kwargs + ): + hidden_states = kwargs.pop("hidden_states", None) + inputs = super().prepare_inputs_for_generation( + input_ids, past_key_values, attention_mask, inputs_embeds, cache_position, **kwargs + ) + # Decode stage + # TODO(raushan, gante): Refactor this part to a utility function + if cache_position[0] != 0: + input_ids = input_ids[:, -1:] + generation_step = kwargs.get("generation_step") + trailing_text_hidden = kwargs.get("trailing_text_hidden") + tts_pad_embed = kwargs.get("tts_pad_embed") + last_id_hidden = self.get_input_embeddings()(input_ids) + + past_hidden = hidden_states[0][-1][:, -1:].to(last_id_hidden.device) # hidden, last layer, last token + predictor_result = self.code_predictor.generate( + inputs_embeds=torch.cat((past_hidden, last_id_hidden), dim=1), + max_new_tokens=self.config.num_code_groups - 1, + do_sample=True, + top_k=50, + top_p=0.8, + output_hidden_states=True, + return_dict_in_generate=True, + ) + residual_codes = torch.cat((input_ids, predictor_result.sequences.to(input_ids.device)), dim=-1) + + mid_residual_hiddens = [hid[0].to(last_id_hidden.device) for hid in predictor_result.hidden_states[1:]] + last_residual_hidden = self.code_predictor.get_input_embeddings()[-1]( + predictor_result.sequences[..., -1:] + ).to(last_id_hidden.device) + codec_hiddens = torch.cat( + [last_id_hidden] + mid_residual_hiddens + [last_residual_hidden], + dim=1, + ) + inputs_embeds = codec_hiddens.sum(1, keepdim=True) + + if generation_step < trailing_text_hidden.shape[1]: + inputs_embeds = inputs_embeds + trailing_text_hidden[:, generation_step].unsqueeze(1).to( + inputs_embeds.device + ) + else: + inputs_embeds = inputs_embeds + tts_pad_embed.to(inputs_embeds.device) + inputs["inputs_embeds"] = inputs_embeds + inputs["residual_codes"] = residual_codes + return inputs + + +class Qwen3OmniMoeCausalConvNet(nn.Module): + def __init__( + self, + in_channels, + out_channels, + kernel_size, + dilation=1, + stride=1, + groups=1, + ): + super().__init__() + self.conv = nn.Conv1d( + in_channels, + out_channels, + kernel_size, + stride=stride, + dilation=dilation, + groups=groups, + ) + self.stride = stride + self.kernel_size = (kernel_size - 1) * dilation + 1 + self.dilation = dilation + self.padding = self.kernel_size - self.stride + + def _get_extra_padding_for_conv1d(self, hidden_state: torch.Tensor) -> int: + length = hidden_state.shape[-1] + n_frames = (length - self.kernel_size + self.padding) / self.stride + 1 + ideal_length = (math.ceil(n_frames) - 1) * self.stride + (self.kernel_size - self.padding) + return ideal_length - length + + def forward(self, hidden_state): + extra_padding = self._get_extra_padding_for_conv1d(hidden_state) + hidden_state = F.pad(hidden_state, (self.padding, extra_padding), mode="constant", value=0) + return self.conv(hidden_state).contiguous() + + +class Qwen3OmniMoeCausalTransConvNet(nn.Module): + def __init__(self, in_channels, out_channels, kernel_size, stride=1): + super().__init__() + self.conv = nn.ConvTranspose1d(in_channels, out_channels, kernel_size, stride=stride) + + pad = kernel_size - stride + self.left_pad = math.ceil(pad) + self.right_pad = pad = self.left_pad + + def forward(self, hidden_state): + hidden_state = self.conv(hidden_state) + hidden_state = hidden_state[..., self.left_pad : hidden_state.shape[-1] - self.right_pad] + return hidden_state.contiguous() + + +class Qwen3OmniMoeConvNeXtBlock(nn.Module): + def __init__(self, dim: int): + super().__init__() + self.dwconv = Qwen3OmniMoeCausalConvNet( + dim, + dim, + kernel_size=7, + groups=dim, + dilation=1, + ) + self.norm = nn.LayerNorm(dim, eps=1e-6) + self.pwconv1 = nn.Linear(dim, 4 * dim) + self.act = nn.GELU() + self.pwconv2 = nn.Linear(4 * dim, dim) + self.gamma = nn.Parameter(1e-6 * torch.ones(dim)) + + def forward(self, hidden_states): + input = hidden_states + + hidden_states = self.dwconv(hidden_states) + hidden_states = hidden_states.permute(0, 2, 1) + hidden_states = self.norm(hidden_states) + hidden_states = self.pwconv1(hidden_states) + hidden_states = self.act(hidden_states) + hidden_states = self.pwconv2(hidden_states) + + hidden_states = self.gamma * hidden_states + + hidden_states = hidden_states.permute(0, 2, 1) + + hidden_states = input + hidden_states + + return hidden_states + + +class Qwen3OmniMoeCode2WavRotatoryEmbedding(nn.Module): + inv_freq: torch.Tensor # fix linting for `register_buffer` + + def __init__(self, config: Qwen3OmniMoeConfig, device=None): + super().__init__() + # BC: "rope_type" was originally "type" + if hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): + self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type")) + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device) + position_ids_expanded = position_ids[:, None, :].float() + + device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu" + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + +class Qwen3OmniMoeCode2WavAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: Qwen3OmniMoeCode2WavConfig, layer_idx): + super().__init__() + self.config = config + self.layer_idx = layer_idx + self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) + self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads + self.scaling = self.head_dim**-0.5 + self.attention_dropout = config.attention_dropout + self.is_causal = True + + self.q_proj = nn.Linear( + config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias + ) + self.k_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.v_proj = nn.Linear( + config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias + ) + self.o_proj = nn.Linear( + config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias + ) + self.q_norm = nn.Identity() + self.k_norm = nn.Identity() + self.sliding_window = config.sliding_window + + @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_values: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[FlashAttentionKwargs], + ) -> tuple[torch.Tensor, Optional[torch.Tensor]]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) + + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + sliding_window=self.sliding_window, # diff with Llama + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +class Qwen3OmniMoeCode2WavMlp(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) + self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +@use_kernel_forward_from_hub("RMSNorm") +class Qwen3OmniMoeCode2WavRMSNorm(nn.Module): + def __init__(self, hidden_size, eps: float = 1e-6) -> None: + """ + Qwen3OmniMoeCode2WavRMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return self.weight * hidden_states.to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +class Qwen3OmniMoeCode2WavLayerScale(nn.Module): + """Layer scale from [Touvron et al 2021] (https://huggingface.co/papers/2103.17239). + This rescales diagonally the residual outputs close to 0, with a learnt scale. + """ + + def __init__(self, config): + super().__init__() + channels = config.hidden_size + initial_scale = config.layer_scale_initial_scale + self.scale = nn.Parameter(torch.full((channels,), initial_scale, requires_grad=True)) + + def forward(self, x: torch.Tensor): + return self.scale * x + + +class Qwen3OmniMoeCode2WavTransformerLayer(GradientCheckpointingLayer): + def __init__(self, config: Qwen3OmniMoeCode2WavConfig, layer_idx): + super().__init__() + self.hidden_size = config.hidden_size + self.self_attn = Qwen3OmniMoeCode2WavAttention(config, layer_idx) + self.mlp = Qwen3OmniMoeCode2WavMlp(config) + self.input_layernorm = Qwen3OmniMoeCode2WavRMSNorm(config.hidden_size, config.rms_norm_eps) + self.post_attention_layernorm = Qwen3OmniMoeCode2WavRMSNorm(config.hidden_size, config.rms_norm_eps) + self.self_attn_layer_scale = Qwen3OmniMoeCode2WavLayerScale(config) + self.mlp_layer_scale = Qwen3OmniMoeCode2WavLayerScale(config) + self.attention_type = "sliding_attention" + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + **kwargs, + ) -> tuple[torch.FloatTensor, Optional[tuple[torch.FloatTensor, torch.FloatTensor]]]: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`, *optional*): + attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1, + query_sequence_length, key_sequence_length)` if default attention is used. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): + Indices depicting the position of the input sequence tokens in the sequence + kwargs (`dict`, *optional*): + Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code + into the model + """ + residual = hidden_states + + hidden_states = self.input_layernorm(hidden_states) + + # Self Attention + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + hidden_states = residual + self.self_attn_layer_scale(hidden_states) + + # Fully Connected + residual = hidden_states + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + self.mlp_layer_scale(hidden_states) + + return hidden_states + + +@auto_docstring +class Qwen3OmniMoeCode2WavTransformerModel(Qwen3OmniMoePreTrainedModel): + _can_record_outputs = { + "hidden_states": Qwen3OmniMoeCode2WavTransformerLayer, + "attentions": Qwen3OmniMoeCode2WavAttention, + } + + def __init__(self, config: Qwen3OmniMoeCode2WavConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [Qwen3OmniMoeCode2WavTransformerLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = Qwen3OmniMoeRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = Qwen3OmniMoeRotaryEmbedding(config=config) + self.gradient_checkpointing = False + self.has_sliding_layers = "sliding_attention" in self.config.layer_types + self.window_size = config.sliding_window + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids=None, + attention_mask=None, + position_ids=None, + past_key_values=None, + inputs_embeds=None, + use_cache=None, + cache_position=None, + **kwargs, + ) -> BaseModelOutputWithPast: + if input_ids is not None: + raise ValueError("input_ids is not expected") + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if use_cache and past_key_values is None: + past_key_values = DynamicCache(config=self.config) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + # It may already have been prepared by e.g. `generate` + if not isinstance(causal_mask_mapping := attention_mask, dict): + # Prepare mask arguments + mask_kwargs = { + "config": self.config, + "input_embeds": inputs_embeds, + "attention_mask": attention_mask, + "cache_position": cache_position, + "past_key_values": past_key_values, + "position_ids": position_ids, + } + # Create the masks + causal_mask_mapping = { + "full_attention": create_causal_mask(**mask_kwargs), + } + # The sliding window alternating layers are not always activated depending on the config + if self.has_sliding_layers: + causal_mask_mapping["sliding_attention"] = create_sliding_window_causal_mask(**mask_kwargs) + + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for decoder_layer in self.layers[: self.config.num_hidden_layers]: + hidden_states = decoder_layer( + hidden_states, + attention_mask=causal_mask_mapping[decoder_layer.attention_type], + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values if use_cache else None, + ) + + +class SnakeBeta(nn.Module): + """ + A modified Snake function which uses separate parameters for the magnitude of the periodic components + Shape: + - Input: (B, C, T) + - Output: (B, C, T), same shape as the input + Parameters: + - alpha - trainable parameter that controls frequency + - beta - trainable parameter that controls magnitude + References: + - This activation function is a modified version based on this paper by Liu Ziyin, Tilman Hartwig, Masahito Ueda: + https://huggingface.co/papers/2006.08195 + """ + + def __init__(self, in_features, alpha=1.0): + super().__init__() + self.in_features = in_features + + # initialize alpha + self.alpha = Parameter(torch.zeros(in_features) * alpha) + self.beta = Parameter(torch.zeros(in_features) * alpha) + + self.no_div_by_zero = 0.000000001 + + def forward(self, hidden_states): + """ + Forward pass of the function. + Applies the function to the input elementwise. + SnakeBeta ∶= x + 1/b * sin^2 (xa) + """ + alpha = self.alpha.unsqueeze(0).unsqueeze(-1) # line up with x to [B, C, T] + beta = self.beta.unsqueeze(0).unsqueeze(-1) + alpha = torch.exp(alpha) + beta = torch.exp(beta) + hidden_states = hidden_states + (1.0 / (beta + self.no_div_by_zero)) * torch.pow( + torch.sin(hidden_states * alpha), 2 + ) + + return hidden_states + + +class Qwen3OmniMoeCode2WavDecoderResidualUnit(nn.Module): + def __init__(self, dim: int = 16, dilation: int = 1): + super().__init__() + + self.act1 = SnakeBeta(dim) + self.conv1 = Qwen3OmniMoeCausalConvNet(dim, dim, kernel_size=7, dilation=dilation) + self.act2 = SnakeBeta(dim) + self.conv2 = Qwen3OmniMoeCausalConvNet(dim, dim, kernel_size=1) + + def forward(self, hidden_state): + residual = hidden_state + + hidden_state = self.act1(hidden_state) + hidden_state = self.conv1(hidden_state) + hidden_state = self.act2(hidden_state) + hidden_state = self.conv2(hidden_state) + return hidden_state + residual + + +class Qwen3OmniMoeCode2WavDecoderBlock(Qwen3OmniMoePreTrainedModel): + def __init__(self, config: Qwen3OmniMoeCode2WavConfig, layer_idx): + super().__init__(config) + in_dim = config.decoder_dim // 2**layer_idx + out_dim = config.decoder_dim // 2 ** (layer_idx + 1) + upsample_rate = config.upsample_rates[layer_idx] + + block = [ + SnakeBeta(in_dim), + Qwen3OmniMoeCausalTransConvNet(in_dim, out_dim, 2 * upsample_rate, upsample_rate), + ] + + for dilation in (1, 3, 9): + block.append(Qwen3OmniMoeCode2WavDecoderResidualUnit(out_dim, dilation)) + + self.block = nn.ModuleList(block) + + def forward(self, hidden): + for block in self.block: + hidden = block(hidden) + return hidden + + +class Qwen3OmniMoeCode2Wav(Qwen3OmniMoePreTrainedModel): + def __init__(self, config: Qwen3OmniMoeCode2WavConfig): + super().__init__(config) + self.total_upsample = np.prod(config.upsample_rates + config.upsampling_ratios) + self.pre_transformer = Qwen3OmniMoeCode2WavTransformerModel._from_config(config) + self.code_embedding = nn.Embedding(config.codebook_size * config.num_quantizers, config.hidden_size) + self.register_buffer( + "code_offset", torch.arange(config.num_quantizers).view(1, -1, 1) * config.codebook_size, persistent=False + ) + + upsample = [] + for factor in config.upsampling_ratios: + upsample.append( + nn.ModuleList( + [ + Qwen3OmniMoeCausalTransConvNet(config.hidden_size, config.hidden_size, factor, factor), + Qwen3OmniMoeConvNeXtBlock(config.hidden_size), + ] + ) + ) + self.upsample = nn.ModuleList(upsample) + + decoder = [Qwen3OmniMoeCausalConvNet(config.hidden_size, config.decoder_dim, 7)] + for i in range(len(config.upsample_rates)): + decoder.append(Qwen3OmniMoeCode2WavDecoderBlock(config, i)) + output_dim = config.decoder_dim // 2 ** len(config.upsample_rates) + decoder += [ + SnakeBeta(output_dim), + Qwen3OmniMoeCausalConvNet(output_dim, 1, 7), + ] + self.decoder = nn.ModuleList(decoder) + + self.post_init() + + def forward(self, codes): + if codes.shape[1] != self.config.num_quantizers: + raise ValueError(f"Expected {self.config.num_quantizers} layer of codes, got {codes.shape[1]}") + hidden = self.code_embedding(codes + self.code_offset).mean(1) + hidden = self.pre_transformer(inputs_embeds=hidden).last_hidden_state + hidden = hidden.permute(0, 2, 1) + for blocks in self.upsample: + for block in blocks: + hidden = block(hidden) + wav = hidden + for block in self.decoder: + wav = block(wav) + return wav.clamp(min=-1, max=1) + + def chunked_decode(self, codes, chunk_size=300, left_context_size=25): + wavs = [] + start_index = 0 + while start_index < codes.shape[-1]: + end_index = min(start_index + chunk_size, codes.shape[-1]) + context_size = left_context_size if start_index - left_context_size > 0 else start_index + codes_chunk = codes[..., start_index - context_size : end_index] + wav_chunk = self(codes_chunk) + wavs.append(wav_chunk[..., context_size * self.total_upsample :]) + start_index = end_index + return torch.cat(wavs, dim=-1) + + +class Qwen3OmniMoeForConditionalGeneration(Qwen3OmniMoePreTrainedModel, GenerationMixin): + config_class = Qwen3OmniMoeConfig + + def __init__(self, config: Qwen3OmniMoeConfig): + super().__init__(config) + + self.thinker = Qwen3OmniMoeThinkerForConditionalGeneration._from_config(config.thinker_config) + self.has_talker = config.enable_audio_output + if self.has_talker: + self.enable_talker() + self.post_init() + + def enable_talker(self): + self.talker = Qwen3OmniMoeTalkerForConditionalGeneration._from_config(self.config.talker_config) + self.code2wav = Qwen3OmniMoeCode2Wav._from_config(self.config.code2wav_config) + + def disable_talker(self): + if hasattr(self, "talker"): + del self.talker + if hasattr(self, "code2wav"): + del self.code2wav + self.has_talker = False + + def _get_talker_user_parts( + self, im_start_index, segment_end_index, multimodal_mask, thinker_hidden, thinker_embed + ): + user_talker_part = torch.empty( + (1, segment_end_index - im_start_index, self.config.talker_config.text_config.hidden_size), + device=self.talker.device, + dtype=self.talker.dtype, + ) + + user_mm_mask = multimodal_mask[:, im_start_index:segment_end_index] + + # Multimodal data exists + if user_mm_mask.any(): + user_thinker_hidden_mm = thinker_hidden[:, im_start_index:segment_end_index][user_mm_mask] + mm_hidden = self.talker.hidden_projection(user_thinker_hidden_mm).to(self.talker.device) + user_talker_part[user_mm_mask] = mm_hidden + user_thinker_embed = thinker_embed[:, im_start_index:segment_end_index][~user_mm_mask] + user_text_hidden = self.talker.text_projection(user_thinker_embed).to(self.talker.device) + user_talker_part[~user_mm_mask] = user_text_hidden + return user_talker_part + + def _get_talker_assistant_parts( + self, im_start_index, segment_end_index, speaker_id, thinker_embed, tts_pad_embed, tts_bos_embed, tts_eos_embed + ): + assistant_hidden = self.talker.text_projection(thinker_embed[:, im_start_index:segment_end_index]).to( + self.talker.device + ) # [1 t d] + assistant_text_hidden = torch.cat( + ( + assistant_hidden[:, :3], + tts_pad_embed.expand(-1, 4, -1), + tts_bos_embed, + assistant_hidden[:, 3:4], # First text + ), + dim=1, + ) + codec_special_tokens = torch.tensor( + [ + [ + self.config.talker_config.codec_nothink_id, + self.config.talker_config.codec_think_bos_id, + self.config.talker_config.codec_think_eos_id, + speaker_id, + self.config.talker_config.codec_pad_id, + self.config.talker_config.codec_bos_id, + ] + ], + device=self.talker.device, + dtype=torch.long, + ) + assistant_codec_hidden = torch.cat( + ( + torch.zeros( + (1, 3, self.config.talker_config.text_config.hidden_size), + device=self.talker.device, + dtype=self.talker.dtype, + ), + self.talker.get_input_embeddings()(codec_special_tokens).to(self.talker.device), + ), + dim=1, + ) + trailing_text_hidden = torch.cat( + ( + assistant_hidden[:, 4:], + tts_eos_embed, + ), + dim=1, + ) + + input_embeds = assistant_text_hidden + assistant_codec_hidden + input_ids = torch.full( + (1, assistant_text_hidden.shape[1]), + fill_value=self.config.tts_pad_token_id, + dtype=torch.long, + device=assistant_text_hidden.device, + ) + return input_embeds, input_ids, trailing_text_hidden + + @torch.no_grad() + def generate( + self, + input_ids: Optional[torch.Tensor] = None, + speaker: str = "Ethan", + use_audio_in_video: bool = False, + return_audio: Optional[bool] = None, + thinker_max_new_tokens: int = 1024, + thinker_eos_token_id: int = 151645, + talker_max_new_tokens: int = 4096, + talker_do_sample: bool = True, + talker_top_k: int = 50, + talker_top_p: float = 1.0, + talker_temperature: float = 0.9, + talker_repetition_penalty: float = 1.05, + **kwargs, + ): + if return_audio and not self.has_talker: + raise ValueError( + "Cannot use talker when talker module not initialized. Use `enable_talker` method or set enable_talker in config to enable talker." + ) + if return_audio is None: + return_audio = self.has_talker + + shared_kwargs = {"use_audio_in_video": use_audio_in_video} + thinker_kwargs = { + "max_new_tokens": thinker_max_new_tokens, + "eos_token_id": thinker_eos_token_id, + } + + talker_kwargs = {} + token2wav_kwargs = {} + if return_audio: + speaker_id = self.config.talker_config.speaker_id.get(speaker.lower()) + if speaker_id is None: + raise NotImplementedError(f"Speaker {speaker} not implemented") + if input_ids.shape[0] != 1: + raise NotImplementedError("Qwen3-Omni currently does not support batched inference with audio output") + talker_supppressed_tokens = [ + i + for i in range( + self.config.talker_config.text_config.vocab_size - 1024, + self.config.talker_config.text_config.vocab_size, + ) + if i not in (self.config.talker_config.codec_eos_token_id,) + ] # Suppress additional special tokens, should not be predicted + talker_kwargs = { + "max_new_tokens": talker_max_new_tokens, + "do_sample": talker_do_sample, + "top_k": talker_top_k, + "top_p": talker_top_p, + "temperature": talker_temperature, + "eos_token_id": self.config.talker_config.codec_eos_token_id, + "repetition_penalty": talker_repetition_penalty, + "suppress_tokens": talker_supppressed_tokens, + "output_hidden_states": True, + "return_dict_in_generate": True, + } + token2wav_kwargs = {} + + for key, value in kwargs.items(): + if key.startswith("thinker_"): + thinker_kwargs[key[len("thinker_") :]] = value + elif key.startswith("talker_"): + talker_kwargs[key[len("talker_") :]] = value + elif key.startswith("token2wav_"): + token2wav_kwargs[key[len("token2wav_") :]] = value + # Process special input values + elif key == "feature_attention_mask": + thinker_kwargs[key] = value + talker_kwargs["audio_feature_lengths"] = torch.sum(value, dim=1) + elif key in ("input_features", "attention_mask"): + thinker_kwargs[key] = value + # Put other key to shared kwargs + else: + shared_kwargs[key] = value + + # Merge kwargs + for key, value in shared_kwargs.items(): + if key not in thinker_kwargs: + thinker_kwargs[key] = value + if key not in talker_kwargs and key in ["image_grid_thw", "video_grid_thw", "video_second_per_grid"]: + talker_kwargs[key] = value + if key not in token2wav_kwargs: + token2wav_kwargs[key] = value + + # 1. Generate from thinker module + generate_audio = return_audio and self.has_talker + if generate_audio: + thinker_kwargs["output_hidden_states"] = True + thinker_kwargs["return_dict_in_generate"] = True + + thinker_result = self.thinker.generate(input_ids=input_ids, **thinker_kwargs) + + if not generate_audio: + return thinker_result, None + + # 2. Prepare talker input + thinker_embed = torch.cat([hidden_states[0] for hidden_states in thinker_result.hidden_states], dim=1).to( + self.talker.device + ) # [1 t d] + thinker_hidden = torch.cat( + [ + hidden_states[self.config.talker_config.accept_hidden_layer] + for hidden_states in thinker_result.hidden_states + ], + dim=1, + ).to(self.talker.device) # [1 t d] + im_start_indexes = torch.cat( + ( + torch.nonzero(input_ids[0] == self.config.im_start_token_id).squeeze(), + torch.tensor([thinker_result.sequences.shape[-1]], device=input_ids.device, dtype=input_ids.dtype), + ), + dim=-1, + ).to(self.talker.device) # Shape [n_starts + 1]; Take batch 0 since batched inference is not supported here. + multimodal_mask = ( + (thinker_result.sequences == self.config.thinker_config.audio_token_id) | + (thinker_result.sequences == self.config.thinker_config.image_token_id) | + (thinker_result.sequences == self.config.thinker_config.video_token_id) + ).to(self.talker.device) # [1 t] # fmt: skip + + talker_special_tokens = torch.tensor( + [[self.config.tts_bos_token_id, self.config.tts_eos_token_id, self.config.tts_pad_token_id]], + device=self.thinker.device, + dtype=input_ids.dtype, + ) + tts_bos_embed, tts_eos_embed, tts_pad_embed = ( + self.talker.text_projection(self.thinker.get_input_embeddings()(talker_special_tokens)) + .to(self.talker.device) + .chunk(3, dim=1) + ) # 3 * [1 1 d] + + talker_input_embeds = [] # [1 t d] + talker_input_ids = [] + # For every chatml parts + for i in range(len(im_start_indexes) - 1): + im_start_index = im_start_indexes[i] + segment_end_index = im_start_indexes[i + 1] + role_token = input_ids[0][im_start_index + 1] + # Talker should ignore thinker system prompt + if role_token == self.config.system_token_id: + continue + # Talker takes word embeddings for tokens and hidden state from `accept_hidden_layer` for multimodal inputs + elif role_token == self.config.user_token_id: + talker_user_part = self._get_talker_user_parts( + im_start_index, segment_end_index, multimodal_mask, thinker_hidden, thinker_embed + ) + talker_input_embeds.append(talker_user_part) + talker_input_ids.append(thinker_result.sequences[:, im_start_index:segment_end_index]) + # Take assistant output (for now) + elif role_token == self.config.assistant_token_id and i == len(im_start_indexes) - 2: + talker_assistant_embeds, talker_assistant_ids, trailing_text_hidden = self._get_talker_assistant_parts( + im_start_index, + segment_end_index, + speaker_id, + thinker_embed, + tts_pad_embed, + tts_bos_embed, + tts_eos_embed, + ) + talker_input_embeds.append(talker_assistant_embeds) + talker_input_ids.append(talker_assistant_ids) + # History assistant output (ignore for now) + elif role_token == self.config.assistant_token_id and i != len(im_start_indexes) - 2: + continue + else: + raise AssertionError("Expect role id after <|im_start|> (assistant, user, system)") + talker_input_embed = torch.cat([embed.to(self.talker.device) for embed in talker_input_embeds], dim=1) + talker_input_id = torch.cat([embed.to(self.talker.device) for embed in talker_input_ids], dim=1) + talker_result = self.talker.generate( + inputs_embeds=talker_input_embed, + trailing_text_hidden=trailing_text_hidden, + tts_pad_embed=tts_pad_embed, + talker_input_ids=talker_input_id, # Not use input_ids to prevent repetation penalty out of bound + **talker_kwargs, + ) + talker_codes = ( + torch.stack([hid[-1] for hid in talker_result.hidden_states if hid[-1] is not None], dim=1) + .transpose(1, 2) + .to(self.code2wav.device) + ) + talker_wavs = self.code2wav.chunked_decode(talker_codes, chunk_size=300, left_context_size=25) + + return thinker_result, talker_wavs.float() + + +__all__ = [ + "Qwen3OmniMoeForConditionalGeneration", + "Qwen3OmniMoeThinkerTextModel", + "Qwen3OmniMoeThinkerForConditionalGeneration", + "Qwen3OmniMoeTalkerForConditionalGeneration", + "Qwen3OmniMoePreTrainedModel", + "Qwen3OmniMoePreTrainedModelForConditionalGeneration", + "Qwen3OmniMoeTalkerModel", + "Qwen3OmniMoeThinkerTextPreTrainedModel", + "Qwen3OmniMoeCode2Wav", + "Qwen3OmniMoeCode2WavDecoderBlock", + "Qwen3OmniMoeCode2WavTransformerModel", + "Qwen3OmniMoeTalkerCodePredictorModel", + "Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration", +] diff --git a/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py b/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py new file mode 100644 index 000000000000..8a7ba792f846 --- /dev/null +++ b/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py @@ -0,0 +1,2779 @@ +# coding=utf-8 +# Copyright 2025 The Qwen team, Alibaba Group and the HuggingFace Inc. team. All rights reserved. +# +# +# 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. +"""PyTorch Qwen3Omni model (Audio, Image, Video).""" + +import math +import re +from dataclasses import dataclass +from typing import Optional, Union + +import numpy as np +import torch +from torch import nn +from torch.nn import functional as F + +from ...activations import ACT2FN +from ...audio_utils import AudioInput +from ...cache_utils import Cache, DynamicCache +from ...configuration_utils import PretrainedConfig +from ...feature_extraction_utils import BatchFeature +from ...generation import GenerationMixin +from ...image_utils import ImageInput +from ...masking_utils import create_causal_mask +from ...modeling_layers import GradientCheckpointingLayer +from ...modeling_outputs import ( + BaseModelOutput, + BaseModelOutputWithPast, + CausalLMOutputWithPast, + MoeCausalLMOutputWithPast, + MoeModelOutputWithPast, +) +from ...processing_utils import ProcessorMixin, Unpack +from ...tokenization_utils_base import TextInput +from ...utils import auto_docstring, can_return_tuple, logging +from ...utils.generic import OutputRecorder, TransformersKwargs, check_model_inputs +from ...video_utils import VideoInput, make_batched_videos +from ..mimi.modeling_mimi import MimiLayerScale +from ..qwen2_5_omni.configuration_qwen2_5_omni import ( + Qwen2_5OmniAudioEncoderConfig, + Qwen2_5OmniThinkerConfig, +) +from ..qwen2_5_omni.modeling_qwen2_5_omni import ( + Qwen2_5OmniAudioAttention, + Qwen2_5OmniAudioEncoder, + Qwen2_5OmniPreTrainedModel, + Qwen2_5OmniPreTrainedModelForConditionalGeneration, + Qwen2_5OmniThinkerForConditionalGeneration, + SnakeBeta, +) +from ..qwen2_5_omni.processing_qwen2_5_omni import Qwen2_5OmniProcessor, Qwen2_5OmniProcessorKwargs +from ..qwen2_moe.modeling_qwen2_moe import Qwen2MoeSparseMoeBlock +from ..qwen3.configuration_qwen3 import Qwen3Config +from ..qwen3.modeling_qwen3 import ( + Qwen3Attention, + Qwen3DecoderLayer, + Qwen3ForCausalLM, + Qwen3MLP, + Qwen3Model, + Qwen3RMSNorm, + Qwen3RotaryEmbedding, +) +from ..qwen3_moe.configuration_qwen3_moe import Qwen3MoeConfig +from ..qwen3_moe.modeling_qwen3_moe import ( + Qwen3MoeAttention, + Qwen3MoeDecoderLayer, + Qwen3MoeForCausalLM, + Qwen3MoeMLP, + Qwen3MoePreTrainedModel, + Qwen3MoeSparseMoeBlock, + load_balancing_loss_func, +) +from ..qwen3_vl_moe.configuration_qwen3_vl_moe import Qwen3VLMoeVisionConfig +from ..qwen3_vl_moe.modeling_qwen3_vl_moe import ( + Qwen3VLMoeTextModel, + Qwen3VLMoeTextRotaryEmbedding, + Qwen3VLMoeVisionAttention, + Qwen3VLMoeVisionModel, +) + + +logger = logging.get_logger(__name__) + + +def _get_feat_extract_output_lengths(input_lengths): + """ + Computes the output length of the convolutional layers and the output length of the audio encoder + """ + + input_lengths_leave = input_lengths % 100 + feat_lengths = (input_lengths_leave - 1) // 2 + 1 + output_lengths = ((feat_lengths - 1) // 2 + 1 - 1) // 2 + 1 + (input_lengths // 100) * 13 + return output_lengths + + +class Qwen3OmniMoeAudioEncoderConfig(Qwen2_5OmniAudioEncoderConfig): + def __init__( + self, + num_mel_bins=128, + encoder_layers=32, + encoder_attention_heads=20, + encoder_ffn_dim=5120, + d_model=1280, + dropout=0, + attention_dropout=0, + activation_function="gelu", + activation_dropout=0, + scale_embedding=False, + initializer_range=0.02, + max_source_positions=1500, + n_window=100, + output_dim=3584, + n_window_infer=400, + conv_chunksize=500, + downsample_hidden_size=480, + **kwargs, + ): + super().__init__( + num_mel_bins, + encoder_layers, + encoder_attention_heads, + encoder_ffn_dim, + d_model, + dropout, + attention_dropout, + activation_function, + activation_dropout, + scale_embedding, + initializer_range, + max_source_positions, + n_window, + output_dim, + **kwargs, + ) + self.n_window_infer = n_window_infer + self.conv_chunksize = conv_chunksize + self.downsample_hidden_size = downsample_hidden_size + + +class Qwen3OmniMoeVisionEncoderConfig(Qwen3VLMoeVisionConfig): + pass + + +class Qwen3OmniMoeTextConfig(Qwen3MoeConfig): + def __init__( + self, + vocab_size=3584, + hidden_size=2048, + intermediate_size=18944, + num_hidden_layers=28, + num_attention_heads=28, + num_key_value_heads=4, + hidden_act="silu", + max_position_embeddings=32768, + initializer_range=0.02, + rms_norm_eps=1e-6, + use_cache=True, + tie_word_embeddings=False, + rope_theta=1000000.0, + rope_scaling=None, + attention_bias=False, + sliding_window=None, + attention_dropout=0, + decoder_sparse_step=1, + moe_intermediate_size=768, + num_experts_per_tok=8, + num_experts=128, + norm_topk_prob=True, + output_router_logits=False, + router_aux_loss_coef=0.001, + mlp_only_layers=None, + **kwargs, + ): + super().__init__( + vocab_size, + hidden_size, + intermediate_size, + num_hidden_layers, + num_attention_heads, + num_key_value_heads, + hidden_act, + max_position_embeddings, + initializer_range, + rms_norm_eps, + use_cache, + tie_word_embeddings, + rope_theta, + rope_scaling, + attention_bias, + False, + sliding_window, + attention_dropout, + decoder_sparse_step, + moe_intermediate_size, + num_experts_per_tok, + num_experts, + norm_topk_prob, + output_router_logits, + router_aux_loss_coef, + mlp_only_layers, + **kwargs, + ) + del self.use_sliding_window + self.sliding_window = sliding_window + + +class Qwen3OmniMoeThinkerConfig(Qwen2_5OmniThinkerConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3OmniMoeThinker`]. It is used to instantiate a + Qwen3-Omni-Thinker 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 thinker component of the Qwen3-Omni + architecture. + + e.g. [Qwen/Qwen3-Omni-7B](https://huggingface.co/Qwen/Qwen3-Omni-7B) + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + audio_config (`dict`, *optional*): + The config dictionary of the audio backbone. + vision_config (`dict`, *optional*): + The config dictionary of the vision backbone. + text_config (`dict`, *optional*): + The config dictionary of the text backbone. + audio_token_id (`int`, *optional*, defaults to 151646): + The audio token id to encode the audio prompt. + image_token_id (`int`, *optional*, defaults to 151655): + The image token id to encode the image prompt. + video_token_id (`int`, *optional*, defaults to 151656): + The video token id to encode the video prompt. + position_id_per_seconds (`int`, *optional*, defaults to 25): + The increment of position id per second. + audio_start_token_id (`int`, *optional*, defaults to 151647): + The audio start token id to encode the audio prompt. + user_token_id (`int`, *optional*, defaults to 872): + The user token id to encode the user token. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + + Example: + + ```python + >>> from transformers import Qwen3OmniMoeThinkerModel, Qwen3OmniMoeThinkerConfig + + >>> # Initializing a default Qwen3OmniMoeThinkerConfig + >>> configuration = Qwen3OmniMoeThinkerConfig() + + >>> # Initializing a model (with random weights) from the default configuration + >>> model = Qwen3OmniMoeThinkerModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + def __init__( + self, + audio_config=None, + vision_config=None, + text_config=None, + audio_token_id=151646, + image_token_id=151655, + video_token_id=151656, + position_id_per_seconds=25, + audio_start_token_id=151647, + user_token_id=872, + initializer_range=0.02, + **kwargs, + ): + super().__init__( + audio_config, + vision_config, + text_config, + None, + None, + None, + position_id_per_seconds, + None, + audio_start_token_id, + None, + user_token_id, + initializer_range, + **kwargs, + ) + del self.seconds_per_chunk + del self.audio_token_index + del self.image_token_index + del self.video_token_index + del self.audio_end_token_id + self.audio_token_id = audio_token_id + self.image_token_id = image_token_id + self.video_token_id = video_token_id + + +class Qwen3OmniMoeTalkerCodePredictorConfig(Qwen3Config): + def __init__( + self, + vocab_size=2048, + hidden_size=1024, + intermediate_size=3072, + num_hidden_layers=5, + num_attention_heads=16, + num_key_value_heads=8, + head_dim=128, + hidden_act="silu", + max_position_embeddings=32768, + initializer_range=0.02, + rms_norm_eps=0.000001, + use_cache=True, + tie_word_embeddings=False, + rope_theta=10000, + rope_scaling=None, + attention_bias=False, + sliding_window=None, + layer_types=None, + attention_dropout=0, + num_code_groups=32, + **kwargs, + ): + super().__init__( + vocab_size, + hidden_size, + intermediate_size, + num_hidden_layers, + num_attention_heads, + num_key_value_heads, + head_dim, + hidden_act, + max_position_embeddings, + initializer_range, + rms_norm_eps, + use_cache, + tie_word_embeddings, + rope_theta, + rope_scaling, + attention_bias, + False, + sliding_window, + None, + layer_types, + attention_dropout, + **kwargs, + ) + del self.use_sliding_window + del self.max_window_layers + self.sliding_window = sliding_window + self.num_code_groups = num_code_groups + + +class Qwen3OmniMoeTalkerTextConfig(Qwen3MoeConfig): + def __init__( + self, + vocab_size=3072, + hidden_size=1024, + intermediate_size=2048, + num_hidden_layers=20, + num_attention_heads=16, + num_key_value_heads=2, + hidden_act="silu", + max_position_embeddings=32768, + initializer_range=0.02, + rms_norm_eps=0.000001, + use_cache=True, + tie_word_embeddings=False, + rope_theta=10000, + rope_scaling=None, + attention_bias=False, + sliding_window=None, + attention_dropout=0, + decoder_sparse_step=1, + moe_intermediate_size=384, + num_experts_per_tok=8, + num_experts=128, + norm_topk_prob=False, + output_router_logits=False, + router_aux_loss_coef=0.001, + mlp_only_layers=None, + **kwargs, + ): + super().__init__( + vocab_size, + hidden_size, + intermediate_size, + num_hidden_layers, + num_attention_heads, + num_key_value_heads, + hidden_act, + max_position_embeddings, + initializer_range, + rms_norm_eps, + use_cache, + tie_word_embeddings, + rope_theta, + rope_scaling, + attention_bias, + False, + sliding_window, + attention_dropout, + decoder_sparse_step, + moe_intermediate_size, + num_experts_per_tok, + num_experts, + norm_topk_prob, + output_router_logits, + router_aux_loss_coef, + mlp_only_layers, + **kwargs, + ) + del self.use_sliding_window + self.sliding_window = sliding_window + + +class Qwen3OmniMoeTalkerConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3OmniMoeTalker`]. It is used to instantiate a + Qwen3-Omni multi-modal talker model capable of handling text, audio, and vision modalities in a unified architecture. + The model integrates a text decoder with a code predictor for autoregressive generation of both semantic and acoustic + tokens, enabling speech and multimodal content generation. This configuration wraps sub-configurations for the text and + code predictor components, allowing modular setup and initialization. + + e.g. [Qwen/Qwen3-Omni-7B](https://huggingface.co/Qwen/Qwen3-Omni-7B) + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + code_predictor_config (`dict`, *optional*): + A dictionary of configuration parameters used to initialize a [`Qwen3OmniMoeTalkerCodePredictorConfig`]. + If not provided, defaults will be used. + text_config (`dict`, *optional*): + A dictionary of configuration parameters used to initialize a [`Qwen3OmniMoeTalkerTextConfig`]. + If not provided, defaults will be used. + num_code_groups (`int`, *optional*, defaults to 32): + Number of codebook groups used in the predicted acoustic token sequence, corresponding to multi-codebook VQ representation. + thinker_hidden_size (`int`, *optional*, defaults to 2048): + Hidden dimension size of the thinker module used for intermediate reasoning or latent planning before audio generation. + codec_eos_token_id (`int`, *optional*, defaults to 4198): + Token ID representing the end-of-speech token in the codec-generated sequence. + accept_hidden_layer (`int`, *optional*, defaults to 18): + Index of the hidden layer whose output is used for accepting or refining generated tokens during think-and-speak process. + codec_nothink_id (`int`, *optional*, defaults to 4203): + Token ID indicating no thinking step is required during generation. + codec_think_bos_id (`int`, *optional*, defaults to 4204): + Token ID marking the beginning of a thinking sequence. + codec_think_eos_id (`int`, *optional*, defaults to 4205): + Token ID marking the end of a thinking sequence. + codec_pad_id (`int`, *optional*, defaults to 4196): + Padding token ID used in codec input sequences. + codec_bos_id (`int`, *optional*, defaults to 4197): + Beginning-of-speech token ID in codec sequences. + audio_token_id (`int`, *optional*, defaults to 151646): + Special token ID used to indicate the position of audio tokens in the input sequence. + image_token_id (`int`, *optional*, defaults to 151655): + Special token ID used to represent image inputs in the multimodal context. + video_token_id (`int`, *optional*, defaults to 151656): + Special token ID used to represent video inputs. + vision_start_token_id (`int`, *optional*, defaults to 151652): + Token ID indicating the start of a visual input sequence (e.g., image or video embeddings). + position_id_per_seconds (`int`, *optional*, defaults to 25): + Number of position IDs allocated per second of audio content, used for temporal alignment in generation. + audio_start_token_id (`int`, *optional*, defaults to 151669): + Token ID that indicates the start of an audio generation segment in the output. + speaker_id (`dict`, *optional*): + Speaker name to speaker id dict. + + Example: + + ```python + >>> from transformers import Qwen3OmniMoeTalkerConfig, Qwen3OmniMoeTalker + + >>> # Initialize a Qwen3OmniMoeTalkerConfig with default sub-configurations + >>> config = Qwen3OmniMoeTalkerConfig( + ... num_code_groups=32, + ... thinker_hidden_size=2048, + ... ) + + >>> # Initialize the full Qwen3-Omni Talker model + >>> model = Qwen3OmniMoeTalker(config) + + >>> # Access the model configuration + >>> config = model.config + >>> print(config.text_config) # Access text decoder configuration + >>> print(config.code_predictor_config) # Access code predictor configuration + ```""" + + sub_configs = { + "code_predictor_config": Qwen3OmniMoeTalkerCodePredictorConfig, + "text_config": Qwen3OmniMoeTalkerTextConfig, + } + + def __init__( + self, + code_predictor_config=None, + text_config=None, + num_code_groups=32, + thinker_hidden_size=2048, + codec_eos_token_id=4198, + accept_hidden_layer=18, + codec_nothink_id=4203, + codec_think_bos_id=4204, + codec_think_eos_id=4205, + codec_pad_id=4196, + codec_bos_id=4197, + audio_token_id=151646, + image_token_id=151655, + video_token_id=151656, + vision_start_token_id=151652, + position_id_per_seconds=25, + audio_start_token_id=151669, + speaker_id=None, + **kwargs, + ): + super().__init__(**kwargs) + if code_predictor_config is None: + code_predictor_config = {} + self.code_predictor_config = Qwen3OmniMoeTalkerCodePredictorConfig() + logger.info("code_predictor_config is None. Initializing code_predictor_config model with default values") + elif isinstance(code_predictor_config, Qwen3OmniMoeTalkerCodePredictorConfig): + self.code_predictor_config = code_predictor_config + else: + self.code_predictor_config = Qwen3OmniMoeTalkerCodePredictorConfig(**code_predictor_config) + + if text_config is None: + text_config = {} + self.text_config = Qwen3OmniMoeTalkerTextConfig() + logger.info("talker text_config is None. Initializing talker text model with default values") + elif isinstance(text_config, Qwen3OmniMoeTalkerTextConfig): + self.text_config = text_config + else: + self.text_config = Qwen3OmniMoeTalkerTextConfig(**text_config) + self.num_code_groups = num_code_groups + self.thinker_hidden_size = thinker_hidden_size + self.codec_eos_token_id = codec_eos_token_id + self.accept_hidden_layer = accept_hidden_layer + self.codec_nothink_id = codec_nothink_id + self.codec_think_bos_id = codec_think_bos_id + self.codec_think_eos_id = codec_think_eos_id + self.codec_pad_id = codec_pad_id + self.codec_bos_id = codec_bos_id + self.audio_token_id = audio_token_id + self.image_token_id = image_token_id + self.video_token_id = video_token_id + self.position_id_per_seconds = position_id_per_seconds + self.audio_start_token_id = audio_start_token_id + self.vision_start_token_id = vision_start_token_id + self.speaker_id = speaker_id + + +class Qwen3OmniMoeCode2WavConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Qwen3OmniMoeCode2WavConfig`]. It is used to instantiate a + Qwen3-Omni code-to-waveform decoder, responsible for converting discrete audio codes into high-fidelity waveforms. + The configuration defines the architecture of the decoder, including parameters for vector quantization, autoregressive modeling, + and upsampling layers. + + e.g. [Qwen/Qwen3-Omni-7B](https://huggingface.co/Qwen/Qwen3-Omni-7B) + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + codebook_size (`int`, *optional*, defaults to 2048): + Number of entries in each residual codebook used for acoustic token quantization. + hidden_size (`int`, *optional*, defaults to 1024): + Dimensionality of the hidden states and embeddings in the autoregressive transformer decoder. + max_position_embeddings (`int`, *optional*, defaults to 8000): + Maximum sequence length that the autoregressive decoder can handle. Determines positional embedding size. + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period for rotary position embeddings (RoPE) applied to attention layers. + num_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the decoder. + num_key_value_heads (`int`, *optional*, defaults to 16): + Number of key and value attention heads used in grouped-query attention (if applicable). + attention_bias (`bool`, *optional*, defaults to `False`): + Whether to use bias in the attention projection layers. + sliding_window (`int`, *optional*, defaults to 72): + Window size for local attention mechanism, limiting attention context to improve efficiency. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the feed-forward (intermediate) layer in each transformer block. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function used in the feed-forward layers. Supports `"silu"`, `"relu"`, `"gelu"`, etc. + layer_scale_initial_scale (`float`, *optional*, defaults to 0.01): + Initial value for LayerScale applied in transformer blocks, helping stabilize training. + rms_norm_eps (`float`, *optional*, defaults to 1e-5): + Epsilon value for RMS normalization layers to prevent division by zero. + num_hidden_layers (`int`, *optional*, defaults to 8): + Number of transformer blocks in the autoregressive decoder. + num_quantizers (`int`, *optional*, defaults to 16): + Number of residual vector quantizers used in the vocoder for fine-grained audio reconstruction. + upsample_rates (`Tuple[int]`, *optional*, defaults to `(8, 5, 4, 3)`): + Rate at which features are upsampled in the final waveform synthesis stage. + upsampling_ratios (`Tuple[int]`, *optional*, defaults to `(2, 2)`): + Ratios used in transposed convolutional layers to progressively upsample feature maps to waveform. + decoder_dim (`int`, *optional*, defaults to 1536): + Final dimensionality of the decoder's output before waveform generation. + attention_dropout (`float`, *optional*, defaults to 0.0): + Dropout probability applied to attention weights in the decoder. + + Example: + + ```python + >>> from transformers import Qwen3OmniMoeCode2WavConfig, Qwen3OmniMoeCode2WavModel + + >>> # Initializing a default Qwen3OmniMoeCode2WavConfig + >>> config = Qwen3OmniMoeCode2WavConfig() + + >>> # Initializing the Code2Wav model with the configuration + >>> model = Qwen3OmniMoeCode2WavModel(config) + + >>> # Accessing configuration + >>> config = model.config + ```""" + + def __init__( + self, + codebook_size=2048, + hidden_size=1024, + max_position_embeddings=8000, + rope_theta=10000, + num_attention_heads=16, + num_key_value_heads=16, + attention_bias=False, + sliding_window=72, + intermediate_size=3072, + hidden_act="silu", + layer_scale_initial_scale=0.01, + rms_norm_eps=1e-5, + num_hidden_layers=8, + num_quantizers=16, + upsample_rates=(8, 5, 4, 3), + upsampling_ratios=(2, 2), + decoder_dim=1536, + attention_dropout=0.0, + **kwargs, + ): + super().__init__(**kwargs) + self.codebook_size = codebook_size + self.hidden_size = hidden_size + self.max_position_embeddings = max_position_embeddings + self.rope_theta = rope_theta + self.num_attention_heads = num_attention_heads + self.num_key_value_heads = num_key_value_heads + self.attention_bias = attention_bias + self.sliding_window = sliding_window + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.layer_scale_initial_scale = layer_scale_initial_scale + self.rms_norm_eps = rms_norm_eps + self.num_hidden_layers = num_hidden_layers + self.num_quantizers = num_quantizers + self.upsample_rates = upsample_rates + self.upsampling_ratios = upsampling_ratios + self.decoder_dim = decoder_dim + self.attention_dropout = attention_dropout + + @property + def layer_types(self): + """ + All layer in code2wav should be sliding attention + """ + return ["sliding_attention"] * self.num_hidden_layers + + +class Qwen3OmniMoeConfig(PretrainedConfig): + """ + This is the configuration class to store the configuration of a [`Qwen3OmniMoeForConditionalGeneration`]. It is used to instantiate a Qwen3Omni + model according to the specified sub-models configurations, defining the model architecture. + + Instantiating a configuration with the defaults will yield a similar configuration to that of the + [Qwen/Qwen2.5-Omni-7B](https://huggingface.co/Qwen/Qwen2.5-Omni-7B) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + thinker_config (`dict`, *optional*): Configuration of the underlying thinker sub-model. + talker_config (`dict`, *optional*): Configuration of the underlying talker sub-model. + code2wav_config (`dict`, *optional*): Configuration of the underlying code2wav sub-model. + enable_audio_output (`bool`, *optional*, defaults to `True`): Whether enable audio output and load talker and code2wav module. + + Example: + + ```python + >>> from transformers import ( + ... Qwen3OmniMoeThinkerConfig, + ... Qwen3OmniMoeTalkerConfig, + ... Qwen3OmniMoeCode2WavConfig, + ... Qwen3OmniMoeForConditionalGeneration, + ... Qwen3OmniMoeConfig, + ... ) + + >>> # Initializing a Qwen3OmniMoe style configuration + >>> configuration = Qwen3OmniMoeConfig() + + >>> # Initializing a model from the configuration + >>> model = Qwen3OmniMoeForConditionalGeneration(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "qwen3_omni_moe" + sub_configs = { + "thinker_config": Qwen3OmniMoeThinkerConfig, + "talker_config": Qwen3OmniMoeTalkerConfig, + "code2wav_config": Qwen3OmniMoeCode2WavConfig, + } + + def __init__( + self, + thinker_config=None, + talker_config=None, + code2wav_config=None, + enable_audio_output=True, + im_start_token_id=151644, + im_end_token_id=151645, + tts_pad_token_id=151671, + tts_bos_token_id=151672, + tts_eos_token_id=151673, + system_token_id=8948, + user_token_id=872, + assistant_token_id=77091, + **kwargs, + ): + super().__init__(**kwargs) + if thinker_config is None: + thinker_config = {} + logger.info("thinker_config is None. Initializing thinker model with default values") + + if talker_config is None: + talker_config = {} + logger.info("talker_config is None. Initializing talker model with default values") + + if code2wav_config is None: + code2wav_config = {} + logger.info("code2wav_config is None. Initializing code2wav model with default values") + + self.thinker_config = Qwen3OmniMoeThinkerConfig(**thinker_config) + self.talker_config = Qwen3OmniMoeTalkerConfig(**talker_config) + self.code2wav_config = Qwen3OmniMoeCode2WavConfig(**code2wav_config) + self.enable_audio_output = enable_audio_output + self.im_start_token_id = im_start_token_id + self.im_end_token_id = im_end_token_id + self.tts_pad_token_id = tts_pad_token_id + self.tts_bos_token_id = tts_bos_token_id + self.tts_eos_token_id = tts_eos_token_id + self.system_token_id = system_token_id + self.user_token_id = user_token_id + self.assistant_token_id = assistant_token_id + + def get_text_config(self, decoder=False) -> "PretrainedConfig": + """ + Returns the config that is meant to be used with text IO. On most models, it is the original config instance + itself. On specific composite models, it is under a set of valid names. + + Args: + decoder (`Optional[bool]`, *optional*, defaults to `False`): + If set to `True`, then only search for decoder config names. + """ + # Overridden for deeply nested config like Qwen2-Omni. We don't have any omni model + # except for Qwen yet. This has to be generalized if more deeply nested configs are + # added. NOTE: currently method used only by vLLM + return self.thinker_config.get_text_config() + + +class Qwen3OmniMoePreTrainedModel(Qwen2_5OmniPreTrainedModel): + pass + + +class Qwen3OmniMoePreTrainedModelForConditionalGeneration(Qwen2_5OmniPreTrainedModelForConditionalGeneration): + def get_llm_pos_ids_for_vision( + self, + start_idx: int, + vision_idx: int, + spatial_merge_size: int, + t_index: list[torch.Tensor], + grid_hs: list[torch.Tensor], + grid_ws: list[torch.Tensor], + ): + llm_pos_ids_list = [] + llm_grid_h = grid_hs[vision_idx] // spatial_merge_size + llm_grid_w = grid_ws[vision_idx] // spatial_merge_size + h_index = torch.arange(llm_grid_h).view(1, -1, 1).expand(len(t_index), -1, llm_grid_w).flatten().float() + w_index = torch.arange(llm_grid_w).view(1, 1, -1).expand(len(t_index), llm_grid_h, -1).flatten().float() + t_index = torch.Tensor(t_index).view(-1, 1).expand(-1, llm_grid_h * llm_grid_w).flatten().float() + _llm_pos_ids = torch.stack([t_index, h_index, w_index]) + llm_pos_ids_list.append(_llm_pos_ids + start_idx) + llm_pos_ids = torch.cat(llm_pos_ids_list, dim=1) + return llm_pos_ids + + def get_rope_index( + self, + input_ids: Optional[torch.LongTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + use_audio_in_video: bool = False, + audio_seqlens: Optional[torch.LongTensor] = None, + second_per_grids: Optional[torch.Tensor] = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + """ + Calculate the 3D rope index based on image and video's temporal, height and width in LLM. + + Explanation: + Each embedding sequence contains vision embedding and text embedding or just contains text embedding. + + For pure text embedding sequence, the rotary position embedding has no difference with modern LLMs. + Examples: + input_ids: [T T T T T], here T is for text. + temporal position_ids: [0, 1, 2, 3, 4] + height position_ids: [0, 1, 2, 3, 4] + width position_ids: [0, 1, 2, 3, 4] + + For vision and text embedding sequence, we calculate 3D rotary position embedding for vision part + and 1D rotary position embedding for text part. + Examples: + Temporal (Time): 3 patches, representing different segments of the video in time. + Height: 2 patches, dividing each frame vertically. + Width: 2 patches, dividing each frame horizontally. + We also have some important parameters: + fps (Frames Per Second): The video's frame rate, set to 1. This means one frame is processed each second. + tokens_per_second: This is a crucial parameter. It dictates how many "time-steps" or "temporal tokens" are conceptually packed into a one-second interval of the video. In this case, we have 25 tokens per second. So each second of the video will be represented with 25 separate time points. It essentially defines the temporal granularity. + temporal_patch_size: The number of frames that compose one temporal patch. Here, it's 2 frames. + interval: The step size for the temporal position IDs, calculated as tokens_per_second * temporal_patch_size / fps. In this case, 25 * 2 / 1 = 50. This means that each temporal patch will be have a difference of 50 in the temporal position IDs. + input_ids: [V V V V V V V V V V V V T T T T T], here V is for vision. + vision temporal position_ids: [0, 0, 0, 0, 50, 50, 50, 50, 100, 100, 100, 100] + vision height position_ids: [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1] + vision width position_ids: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] + text temporal position_ids: [101, 102, 103, 104, 105] + text height position_ids: [101, 102, 103, 104, 105] + text width position_ids: [101, 102, 103, 104, 105] + Here we calculate the text start position_ids as the max vision position_ids plus 1. + + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + use_audio_in_video (`bool`, *optional*): + If set to `True`, use the audio in video. + audio_seqlens (`torch.LongTensor` of shape `(num_audios)`, *optional*): + The length of feature shape of each audio in LLM. + second_per_grids (`torch.LongTensor` of shape `(num_videos)`, *optional*): + The time interval (in seconds) for each grid along the temporal dimension in the 3D position IDs. + + Returns: + position_ids (`torch.LongTensor` of shape `(3, batch_size, sequence_length)`) + mrope_position_deltas (`torch.Tensor` of shape `(batch_size)`) + """ + spatial_merge_size = self.spatial_merge_size + image_token_id = self.config.image_token_id + video_token_id = self.config.video_token_id + audio_token_id = self.config.audio_token_id + vision_start_token_id = self.config.vision_start_token_id + audio_start_token_id = self.config.audio_start_token_id + position_id_per_seconds = self.config.position_id_per_seconds + + mrope_position_deltas = [] + if input_ids is not None and (image_grid_thw is not None or video_grid_thw is not None): + total_input_ids = input_ids + if attention_mask is not None: + attention_mask = attention_mask == 1 + position_ids = torch.zeros( + 3, + input_ids.shape[0], + input_ids.shape[1], + dtype=torch.float, + device=input_ids.device, + ) + image_idx, video_idx, audio_idx = 0, 0, 0 + for i, input_ids in enumerate(total_input_ids): + if attention_mask is not None: + input_ids = input_ids[attention_mask[i]] + image_nums, video_nums, audio_nums = 0, 0, 0 + vision_start_indices = torch.argwhere(input_ids == vision_start_token_id).squeeze(1) + vision_tokens = input_ids[vision_start_indices + 1] + audio_nums = torch.sum(input_ids == audio_start_token_id) + image_nums = (vision_tokens == image_token_id).sum() + video_nums = ( + (vision_tokens == audio_start_token_id).sum() + if use_audio_in_video + else (vision_tokens == video_token_id).sum() + ) + input_tokens = input_ids.tolist() + llm_pos_ids_list: list = [] + st = 0 + remain_images, remain_videos, remain_audios = image_nums, video_nums, audio_nums + multimodal_nums = ( + image_nums + audio_nums if use_audio_in_video else image_nums + video_nums + audio_nums + ) + for _ in range(multimodal_nums): + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + if (image_token_id in input_tokens or video_token_id in input_tokens) and ( + remain_videos > 0 or remain_images > 0 + ): + ed_vision_start = input_tokens.index(vision_start_token_id, st) + else: + ed_vision_start = len(input_tokens) + 1 + if audio_token_id in input_tokens and remain_audios > 0: + ed_audio_start = input_tokens.index(audio_start_token_id, st) + else: + ed_audio_start = len(input_tokens) + 1 + min_ed = min(ed_vision_start, ed_audio_start) + + text_len = min_ed - st + if text_len != 0: + llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx) + st_idx += text_len + # Audio in Video + if min_ed == ed_vision_start and ed_vision_start + 1 == ed_audio_start: + bos_len, eos_len = 2, 2 + else: + bos_len, eos_len = 1, 1 + llm_pos_ids_list.append(torch.arange(bos_len).view(1, -1).expand(3, -1) + st_idx) + st_idx += bos_len + # Audio Only + if min_ed == ed_audio_start: + audio_len = _get_feat_extract_output_lengths(audio_seqlens[audio_idx]) + llm_pos_ids = torch.arange(audio_len).view(1, -1).expand(3, -1) + st_idx + llm_pos_ids_list.append(llm_pos_ids) + + st += int(text_len + bos_len + audio_len + eos_len) + audio_idx += 1 + remain_audios -= 1 + + # Image Only + elif min_ed == ed_vision_start and input_ids[ed_vision_start + 1] == image_token_id: + grid_t = image_grid_thw[image_idx][0] + grid_hs = image_grid_thw[:, 1] + grid_ws = image_grid_thw[:, 2] + t_index = (torch.arange(grid_t) * 1 * position_id_per_seconds).float() + llm_pos_ids = self.get_llm_pos_ids_for_vision( + st_idx, image_idx, spatial_merge_size, t_index, grid_hs, grid_ws + ) + image_len = image_grid_thw[image_idx].prod() // (spatial_merge_size**2) + llm_pos_ids_list.append(llm_pos_ids) + + st += int(text_len + bos_len + image_len + eos_len) + image_idx += 1 + remain_images -= 1 + + # Video Only + elif min_ed == ed_vision_start and input_ids[ed_vision_start + 1] == video_token_id: + grid_t = video_grid_thw[video_idx][0] + grid_hs = video_grid_thw[:, 1] + grid_ws = video_grid_thw[:, 2] + t_index = ( + torch.arange(grid_t) * second_per_grids[video_idx].cpu().float() * position_id_per_seconds + ).float() + llm_pos_ids = self.get_llm_pos_ids_for_vision( + st_idx, video_idx, spatial_merge_size, t_index, grid_hs, grid_ws + ) + video_len = video_grid_thw[video_idx].prod() // (spatial_merge_size**2) + llm_pos_ids_list.append(llm_pos_ids) + + st += int(text_len + bos_len + video_len + eos_len) + video_idx += 1 + remain_videos -= 1 + + # Audio in Video + elif min_ed == ed_vision_start and ed_vision_start + 1 == ed_audio_start: + audio_len = _get_feat_extract_output_lengths(audio_seqlens[audio_idx]) + audio_llm_pos_ids = torch.arange(audio_len).view(1, -1).expand(3, -1) + st_idx + grid_t = video_grid_thw[video_idx][0] + grid_hs = video_grid_thw[:, 1] + grid_ws = video_grid_thw[:, 2] + + t_index = ( + torch.arange(grid_t) * second_per_grids[video_idx].cpu().float() * position_id_per_seconds + ).float() + video_llm_pos_ids = self.get_llm_pos_ids_for_vision( + st_idx, video_idx, spatial_merge_size, t_index, grid_hs, grid_ws + ) + video_data_index, audio_data_index = 0, 0 + while ( + video_data_index < video_llm_pos_ids.shape[-1] + and audio_data_index < audio_llm_pos_ids.shape[-1] + ): + if video_llm_pos_ids[0][video_data_index] <= audio_llm_pos_ids[0][audio_data_index]: + llm_pos_ids_list.append(video_llm_pos_ids[:, video_data_index : video_data_index + 1]) + video_data_index += 1 + else: + llm_pos_ids_list.append(audio_llm_pos_ids[:, audio_data_index : audio_data_index + 1]) + audio_data_index += 1 + if video_data_index < video_llm_pos_ids.shape[-1]: + llm_pos_ids_list.append( + video_llm_pos_ids[:, video_data_index : video_llm_pos_ids.shape[-1]] + ) + if audio_data_index < audio_llm_pos_ids.shape[-1]: + llm_pos_ids_list.append( + audio_llm_pos_ids[:, audio_data_index : audio_llm_pos_ids.shape[-1]] + ) + video_len = video_grid_thw[video_idx].prod() // (spatial_merge_size**2) + + st += int(text_len + bos_len + audio_len + video_len + eos_len) + + audio_idx += 1 + video_idx += 1 + remain_videos -= 1 + remain_audios -= 1 + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + llm_pos_ids_list.append(torch.arange(eos_len).view(1, -1).expand(3, -1) + st_idx) + + if st < len(input_tokens): + st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0 + text_len = len(input_tokens) - st + llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx) + + llm_positions = torch.cat([item.float() for item in llm_pos_ids_list], dim=1).reshape(3, -1) + + position_ids[..., i, attention_mask[i] == 1] = llm_positions.to(position_ids.device) + mrope_position_deltas.append(llm_positions.max() + 1 - len(input_ids)) + mrope_position_deltas = torch.tensor(mrope_position_deltas, device=input_ids.device).unsqueeze(1) + + return position_ids, mrope_position_deltas + else: + position_ids = attention_mask.float().cumsum(-1) - 1 + position_ids.masked_fill_(attention_mask == 0, 1) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1).to(attention_mask.device) + max_position_ids = position_ids.max(0, keepdim=False)[0].max(-1, keepdim=True)[0] + mrope_position_deltas = max_position_ids + 1 - torch.sum(attention_mask, dim=-1, keepdim=True) + + return position_ids, mrope_position_deltas + + +class Qwen3OmniMoeAudioAttention(Qwen2_5OmniAudioAttention): + def __init__(self, config): + super().__init__(config) + self.k_proj = nn.Linear(self.embed_dim, self.embed_dim, bias=True) + + +class Qwen3OmniMoeAudioEncoder(Qwen2_5OmniAudioEncoder): + def __init__(self, config: Qwen3OmniMoeAudioEncoderConfig): + super().__init__(config) + del self.proj + del self.avg_pooler + del self.audio_bos_eos_token + del self.conv1 + del self.conv2 + self.conv2d1 = nn.Conv2d(1, config.downsample_hidden_size, 3, 2, padding=1) + self.conv2d2 = nn.Conv2d(config.downsample_hidden_size, config.downsample_hidden_size, 3, 2, padding=1) + self.conv2d3 = nn.Conv2d(config.downsample_hidden_size, config.downsample_hidden_size, 3, 2, padding=1) + self.conv_out = nn.Linear( + config.downsample_hidden_size * ((((config.num_mel_bins + 1) // 2 + 1) // 2 + 1) // 2), + config.d_model, + bias=False, + ) + self.proj1 = nn.Linear(config.d_model, config.d_model) + self.act = ACT2FN[config.activation_function] + self.proj2 = nn.Linear(config.d_model, config.output_dim) + self.n_window_infer = self.config.n_window_infer + self.conv_chunksize = self.config.conv_chunksize + + def forward( + self, + input_features, + feature_lens=None, + aftercnn_lens=None, + ): + aftercnn_lens = _get_feat_extract_output_lengths(feature_lens) + chunk_num = torch.ceil(feature_lens / (self.n_window * 2)).long() + + chunk_lengths = torch.tensor( + [self.n_window * 2] * chunk_num.sum(), + dtype=torch.long, + device=feature_lens.device, + ) + tail_chunk_index = F.pad(chunk_num, (1, 0), value=-1).cumsum(0)[1:] + chunk_lengths[tail_chunk_index] = feature_lens % (self.n_window * 2) + chunk_lengths[chunk_lengths == 0] = self.n_window * 2 + + chunk_list = input_features.T.split(chunk_lengths.tolist(), dim=0) + padded_feature = nn.utils.rnn.pad_sequence(chunk_list, batch_first=True).transpose(1, 2) + feature_lens_after_cnn = _get_feat_extract_output_lengths(chunk_lengths) + padded_mask_after_cnn = nn.utils.rnn.pad_sequence( + [torch.ones(length, dtype=torch.bool, device=padded_feature.device) for length in feature_lens_after_cnn], + batch_first=True, + ) + padded_feature = padded_feature.unsqueeze(1) + # Split to chunk to avoid OOM during convolution + padded_embeds = [] + for chunk in padded_feature.split(self.conv_chunksize, dim=0): + padded_embed = F.gelu(self.conv2d1(chunk)) + padded_embed = F.gelu(self.conv2d2(padded_embed)) + padded_embed = F.gelu(self.conv2d3(padded_embed)) + padded_embeds.append(padded_embed) + padded_embed = torch.cat(padded_embeds, dim=0) + b, c, f, t = padded_embed.size() + padded_embed = self.conv_out(padded_embed.permute(0, 3, 1, 2).contiguous().view(b, t, c * f)) + + positional_embedding = ( + self.positional_embedding.positional_embedding[: padded_embed.shape[1], :] + .unsqueeze(0) + .to(padded_embed.dtype) + ) + padded_embed = padded_embed + positional_embedding + hidden_states = padded_embed[padded_mask_after_cnn] + cu_chunk_lens = [0] + window_aftercnn = padded_mask_after_cnn.shape[-1] * (self.n_window_infer // (self.n_window * 2)) + for cnn_len in aftercnn_lens: + cu_chunk_lens += [window_aftercnn] * (cnn_len // window_aftercnn) + remainder = cnn_len % window_aftercnn + if remainder != 0: + cu_chunk_lens += [remainder] + cu_seqlens = torch.tensor(cu_chunk_lens, device=aftercnn_lens.device).cumsum(-1, dtype=torch.int32) + + for encoder_layer in self.layers: + layer_outputs = encoder_layer( + hidden_states, + cu_seqlens, + ) + + hidden_states = layer_outputs[0] + + hidden_states = self.ln_post(hidden_states) + hidden_states = self.proj1(hidden_states) + hidden_states = self.act(hidden_states) + hidden_states = self.proj2(hidden_states) + return BaseModelOutput(last_hidden_state=hidden_states) + + +class Qwen3OmniMoeVisionAttention(Qwen3VLMoeVisionAttention): + def __init__(self, config: Qwen3OmniMoeVisionEncoderConfig): + super().__init__(config) + + +class Qwen3OmniMoeVisionPatchMerger(nn.Module): + def __init__(self, config: Qwen3OmniMoeVisionEncoderConfig, use_postshuffle_norm=False) -> None: + super().__init__() + self.hidden_size = config.hidden_size * (config.spatial_merge_size**2) + self.use_postshuffle_norm = use_postshuffle_norm + self.ln_q = nn.LayerNorm(self.hidden_size if use_postshuffle_norm else config.hidden_size, eps=1e-6) + self.mlp = nn.ModuleList( + [ + nn.Linear(self.hidden_size, self.hidden_size), + nn.GELU(), + nn.Linear(self.hidden_size, config.out_hidden_size), + ] + ) + + def forward(self, hidden: torch.Tensor) -> torch.Tensor: + hidden = self.ln_q(hidden.view(-1, self.hidden_size) if self.use_postshuffle_norm else hidden).view( + -1, self.hidden_size + ) + for layer in self.mlp: + hidden = layer(hidden) + return hidden + + +class Qwen3OmniMoeVisionEncoder(Qwen3VLMoeVisionModel): + config: Qwen3OmniMoeVisionEncoderConfig + _no_split_modules = ["Qwen3OmniMoeVisionBlock"] + + def __init__(self, config, *inputs, **kwargs): + self.merger_list = nn.ModuleList( + [ + Qwen3OmniMoeVisionPatchMerger( + config=config, + use_postshuffle_norm=True, + ) + for _ in range(len(config.deepstack_visual_indexes)) + ] + ) + super().__init__(config, *inputs, **kwargs) + del self.deepstack_merger_list + + @property + def deepstack_merger_list(self): + return self.merger_list + + +class Qwen3OmniMoeThinkerTextRotaryEmbedding(Qwen3VLMoeTextRotaryEmbedding): + pass + + +class Qwen3OmniMoeThinkerTextSparseMoeBlock(Qwen3MoeSparseMoeBlock): + pass + + +class Qwen3OmniMoeThinkerTextAttention(Qwen3MoeAttention): + def __init__(self, config, layer_idx): + super().__init__(config, layer_idx) + self.sliding_window = None + + +class Qwen3OmniMoeThinkerTextDecoderLayer(Qwen3MoeDecoderLayer): + def __init__(self, config, layer_idx): + super().__init__(config, layer_idx) + self.self_attn = Qwen3OmniMoeThinkerTextAttention(config, layer_idx) + + +class Qwen3OmniMoeThinkerTextPreTrainedModel(Qwen3MoePreTrainedModel): + config_class = Qwen3OmniMoeTextConfig + config = Qwen3OmniMoeTextConfig + + +class Qwen3OmniMoeThinkerTextModel(Qwen3VLMoeTextModel): + config_class = Qwen3OmniMoeTextConfig + _can_record_outputs = { + "hidden_states": Qwen3OmniMoeThinkerTextDecoderLayer, + "attentions": Qwen3OmniMoeThinkerTextAttention, + "router_logits": OutputRecorder(Qwen3OmniMoeThinkerTextSparseMoeBlock, index=1), + } + + def __init__(self, config: Qwen3OmniMoeTextConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [Qwen3OmniMoeThinkerTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = Qwen3OmniMoeThinkerTextRotaryEmbedding(config) + + +@dataclass +class Qwen3OmniMoeThinkerCausalLMOutputWithPast(MoeCausalLMOutputWithPast): + r""" + Args: + rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*): + The rope index difference between sequence length and multimodal rope. + """ + + rope_deltas: Optional[torch.LongTensor] = None + + +class Qwen3OmniMoeThinkerForConditionalGeneration(Qwen2_5OmniThinkerForConditionalGeneration): + _no_split_modules = [ + "Qwen3OmniMoeAudioEncoderLayer", + "Qwen3OmniMoeThinkerTextDecoderLayer", + ] + _can_record_outputs = { + "hidden_states": Qwen3OmniMoeThinkerTextDecoderLayer, + "attentions": Qwen3OmniMoeThinkerTextAttention, + "router_logits": OutputRecorder(Qwen3OmniMoeThinkerTextSparseMoeBlock, index=1), + } + + def __init__(self, config): + super().__init__(config) + self.num_experts = config.text_config.num_experts + self.num_experts_per_tok = config.text_config.num_experts_per_tok + + def get_audio_features( + self, + input_features: torch.FloatTensor, + feature_attention_mask: Optional[torch.LongTensor] = None, + audio_feature_lengths: Optional[torch.LongTensor] = None, + ): + """ + Encodes audios into continuous embeddings that can be forwarded to the language model. + + Args: + input_features (`torch.FloatTensor`): + The tensors corresponding to the input audios. + feature_attention_mask (`torch.LongTensor`, *optional*): + Mask to avoid performing attention on padding feature indices. Mask values selected in `[0, 1]`: + audio_feature_lengths (`torch.LongTensor` of shape `(num_audios)`, *optional*): + The length of feature shape of each audio in LLM. + """ + if feature_attention_mask is not None: + audio_feature_lengths = torch.sum(feature_attention_mask, dim=1) + input_features = input_features.permute(0, 2, 1)[feature_attention_mask.bool()].permute(1, 0) + else: + audio_feature_lengths = None + + feature_lens = audio_feature_lengths if audio_feature_lengths is not None else feature_attention_mask.sum(-1) + audio_outputs = self.audio_tower( + input_features, + feature_lens=feature_lens, + ) + audio_features = audio_outputs.last_hidden_state + + return audio_features + + @can_return_tuple + @auto_docstring + def forward( + self, + input_ids=None, + input_features=None, + pixel_values=None, + pixel_values_videos=None, + image_grid_thw=None, + video_grid_thw=None, + attention_mask=None, + feature_attention_mask=None, + audio_feature_lengths=None, + position_ids=None, + past_key_values=None, + inputs_embeds=None, + rope_deltas=None, + labels=None, + use_cache=None, + output_router_logits: Optional[bool] = None, + use_audio_in_video=None, + cache_position=None, + video_second_per_grid=None, + **kwargs, + ) -> Union[tuple, Qwen3OmniMoeThinkerCausalLMOutputWithPast]: + output_router_logits = ( + output_router_logits if output_router_logits is not None else self.config.text_config.output_router_logits + ) + + if inputs_embeds is None: + # 1. Extract the input embeddings + inputs_embeds = self.get_input_embeddings()(input_ids) + + visual_embeds_multiscale = None + visual_pos_masks = None + # 2. Merge text , audios , image and video + if input_features is not None: + audio_features = self.get_audio_features( + input_features, + feature_attention_mask=feature_attention_mask, + audio_feature_lengths=audio_feature_lengths, + ) + audio_features = audio_features.to(inputs_embeds.device, inputs_embeds.dtype) + _, _, audio_mask = self.get_placeholder_mask(input_ids, inputs_embeds=inputs_embeds) + inputs_embeds = inputs_embeds.masked_scatter(audio_mask, audio_features) + + if pixel_values is not None: + image_embeds, image_embeds_multiscale = self.get_image_features(pixel_values, image_grid_thw) + image_embeds = image_embeds.to(inputs_embeds.device, inputs_embeds.dtype) + image_mask, _, _ = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, image_features=image_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds) + + visual_pos_masks = image_mask + visual_embeds_multiscale = image_embeds_multiscale + + if pixel_values_videos is not None: + video_embeds, video_embeds_multiscale = self.get_video_features(pixel_values_videos, video_grid_thw) + + video_embeds = video_embeds.to(inputs_embeds.device, inputs_embeds.dtype) + _, video_mask, _ = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, video_features=video_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter(video_mask, video_embeds) + + if visual_embeds_multiscale is None: + visual_embeds_multiscale = video_embeds_multiscale + visual_pos_masks = video_mask + else: + visual_pos_masks = video_mask | image_mask + visual_embeds_multiscale_joint = () + image_mask_joint = image_mask[visual_pos_masks] + video_mask_joint = video_mask[visual_pos_masks] + for img_embed, vid_embed in zip(visual_embeds_multiscale, video_embeds_multiscale): + embed_joint = img_embed.new_zeros(visual_pos_masks.sum(), img_embed.shape[-1]) + embed_joint[image_mask_joint, :] = img_embed + embed_joint[video_mask_joint, :] = vid_embed + visual_embeds_multiscale_joint = visual_embeds_multiscale_joint + (embed_joint,) + visual_embeds_multiscale = visual_embeds_multiscale_joint + + if feature_attention_mask is not None: + audio_feature_lengths = torch.sum(feature_attention_mask, dim=1) + else: + audio_feature_lengths = None + + if attention_mask is not None and position_ids is None: + if ( + cache_position is None + or (cache_position is not None and cache_position[0] == 0) + or self.rope_deltas is None + ): + delta0 = (1 - attention_mask).sum(dim=-1).unsqueeze(1) + position_ids, rope_deltas = self.get_rope_index( + input_ids, + image_grid_thw, + video_grid_thw, + attention_mask, + use_audio_in_video, + audio_feature_lengths, + video_second_per_grid, + ) + rope_deltas = rope_deltas - delta0 + self.rope_deltas = rope_deltas + else: + batch_size, seq_length = input_ids.shape + delta = cache_position[0] + self.rope_deltas if cache_position is not None else 0 + position_ids = torch.arange(seq_length, device=input_ids.device) + position_ids = position_ids.view(1, -1).expand(batch_size, -1) + position_ids = position_ids.add(delta) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1) + + outputs = self.model( + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_router_logits=output_router_logits, + cache_position=cache_position, + deepstack_visual_embeds_multiscale=visual_embeds_multiscale, + visual_pos_masks=visual_pos_masks, + **kwargs, + ) + + hidden_states = outputs[0] + logits = self.lm_head(hidden_states) + + loss = None + if labels is not None: + loss = self.loss_function( + logits=logits, labels=labels, vocab_size=self.config.get_text_config().vocab_size + ) + + aux_loss = None + if output_router_logits: + aux_loss = load_balancing_loss_func( + outputs.router_logits, + self.num_experts, + self.num_experts_per_tok, + attention_mask, + ) + if labels is not None: + loss += self.router_aux_loss_coef * aux_loss.to(loss.device) # make sure to reside in the same device + + return Qwen3OmniMoeThinkerCausalLMOutputWithPast( + loss=loss, + logits=logits, + aux_loss=aux_loss, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + past_key_values=outputs.past_key_values, + rope_deltas=self.rope_deltas, + ) + + +class Qwen3OmniMoeTalkerResizeMLP(nn.Module): + def __init__(self, config: Qwen3OmniMoeTalkerConfig): + super().__init__() + self.linear_fc1 = nn.Linear(config.thinker_hidden_size, config.text_config.intermediate_size, bias=True) + self.linear_fc2 = nn.Linear(config.text_config.intermediate_size, config.text_config.hidden_size, bias=True) + self.act_fn = ACT2FN[config.text_config.hidden_act] + + def forward(self, hidden_state): + return self.linear_fc2(self.act_fn(self.linear_fc1(hidden_state))) + + +@dataclass +class Qwen3OmniMoeTalkerCodePredictorOutputWithPast(CausalLMOutputWithPast): + r""" + generation_steps (`int`, *optional*) + Current generation step of code predictor model. + """ + + generation_steps: Optional[int] = None + + +class Qwen3OmniMoeTalkerCodePredictorAttention(Qwen3Attention): + pass + + +class Qwen3OmniMoeTalkerCodePredictorDecoderLayer(Qwen3DecoderLayer): + def __init__(self, config, layer_idx): + super().__init__(config, layer_idx) + self.self_attn = Qwen3OmniMoeTalkerCodePredictorAttention(config=config, layer_idx=layer_idx) + + +class Qwen3OmniMoeTalkerCodePredictorModel(Qwen3Model): + config_class = Qwen3OmniMoeTalkerCodePredictorConfig + base_model_prefix = "talker.code_predictor.model" + _can_record_outputs = { + "attentions": Qwen3OmniMoeTalkerCodePredictorAttention, + "hidden_states": Qwen3OmniMoeTalkerCodePredictorDecoderLayer, + } + + def __init__(self, config: Qwen3OmniMoeTalkerCodePredictorConfig): + super().__init__(config) + del self.embed_tokens + self.layers = nn.ModuleList( + [ + Qwen3OmniMoeTalkerCodePredictorDecoderLayer(config, layer_idx) + for layer_idx in range(config.num_hidden_layers) + ] + ) + self.codec_embedding = nn.ModuleList( + [nn.Embedding(config.vocab_size, config.hidden_size) for _ in range(config.num_code_groups - 1)] + ) + + def get_input_embeddings(self): + return self.codec_embedding + + @check_model_inputs + @auto_docstring + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> BaseModelOutputWithPast: + if input_ids is not None: + raise ValueError("`input_ids` is expected to be `None`") + + if use_cache and past_key_values is None: + past_key_values = DynamicCache(config=self.config) + + if cache_position is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + cache_position = torch.arange( + past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device + ) + + if position_ids is None: + position_ids = cache_position.unsqueeze(0) + + # It may already have been prepared by e.g. `generate` + if not isinstance(causal_mask_mapping := attention_mask, dict): + # Prepare mask arguments + mask_kwargs = { + "config": self.config, + "input_embeds": inputs_embeds, + "attention_mask": attention_mask, + "cache_position": cache_position, + "past_key_values": past_key_values, + "position_ids": position_ids, + } + # Create the masks + causal_mask_mapping = { + "full_attention": create_causal_mask(**mask_kwargs), + } + + hidden_states = inputs_embeds + + # create position embeddings to be shared across the decoder layers + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for decoder_layer in self.layers[: self.config.num_hidden_layers]: + hidden_states = decoder_layer( + hidden_states, + attention_mask=causal_mask_mapping[decoder_layer.attention_type], + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values if use_cache else None, + ) + + +class Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration(Qwen3ForCausalLM): + config_class = Qwen3OmniMoeTalkerCodePredictorConfig + base_model_prefix = "talker.code_predictor" + _can_record_outputs = { + "attentions": Qwen3OmniMoeTalkerCodePredictorAttention, + "hidden_states": Qwen3OmniMoeTalkerCodePredictorDecoderLayer, + } + + def __init__(self, config: Qwen3OmniMoeTalkerCodePredictorConfig): + super().__init__(config) + self.model = Qwen3OmniMoeTalkerCodePredictorModel._from_config(config) + self.lm_head = nn.ModuleList( + [nn.Linear(config.hidden_size, config.vocab_size, bias=False) for _ in range(config.num_code_groups - 1)] + ) + + def get_input_embeddings(self): + return self.model.get_input_embeddings() + + def forward( + self, + input_ids=None, + attention_mask=None, + position_ids=None, + past_key_values=None, + inputs_embeds=None, + labels=None, + use_cache=None, + cache_position=None, + generation_steps=None, + **kwargs, + ): + r""" + Args: + generation_steps (`int`): + generation step of code predictor, 0..num_code_groups-1 + """ + + # Prefill stage + if inputs_embeds is not None and inputs_embeds.shape[1] > 1: + generation_steps = inputs_embeds.shape[1] - 2 # hidden & layer 0 + # Generation stage + else: + inputs_embeds = self.model.get_input_embeddings()[generation_steps - 1](input_ids) + + # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn) + outputs: BaseModelOutputWithPast = self.model( + input_ids=None, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs.last_hidden_state + logits = self.lm_head[generation_steps](hidden_states) + + loss = None + if labels is not None: + loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs) + + return Qwen3OmniMoeTalkerCodePredictorOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + generation_steps=generation_steps + 1, + ) + + def _update_model_kwargs_for_generation(self, outputs, model_kwargs, is_encoder_decoder=False, num_new_tokens=1): + model_kwargs = super()._update_model_kwargs_for_generation( + outputs, model_kwargs, is_encoder_decoder, num_new_tokens + ) + model_kwargs["generation_steps"] = outputs.generation_steps + return model_kwargs + + +@dataclass +class Qwen3OmniMoeTalkerOutputWithPast(MoeCausalLMOutputWithPast): + r""" + Args: + generation_step (`int`, *optional*): + Current generation step, used to track which `trailing_text_hidden` should be used. + """ + + generation_step: Optional[int] = None + + +class Qwen3OmniMoeTalkerRotaryEmbedding(Qwen3OmniMoeThinkerTextRotaryEmbedding): + pass + + +class Qwen3OmniMoeTalkerTextMLP(Qwen3MoeMLP): + pass + + +class Qwen3OmniMoeTalkerTextSparseMoeBlock(Qwen2MoeSparseMoeBlock): + pass + + +class Qwen3OmniMoeTalkerDecoderLayer(Qwen3MoeDecoderLayer): + def __init__(self, config, layer_idx): + super().__init__(config, layer_idx) + self.self_attn = Qwen3OmniMoeThinkerTextAttention(config, layer_idx) + self.mlp = Qwen3OmniMoeTalkerTextSparseMoeBlock(config) + + +class Qwen3OmniMoeTalkerModel(Qwen3VLMoeTextModel): + config_class = Qwen3OmniMoeTalkerTextConfig + base_model_prefix = "talker.model" + _no_split_modules = ["Qwen3OmniMoeTalkerDecoderLayer"] + _can_record_outputs = { + "hidden_states": Qwen3OmniMoeTalkerDecoderLayer, + "attentions": Qwen3OmniMoeThinkerTextAttention, + "router_logits": OutputRecorder(Qwen3OmniMoeTalkerTextSparseMoeBlock, index=1), + } + + def __init__(self, config: Qwen3OmniMoeTalkerTextConfig): + super().__init__(config) + del self.embed_tokens + self.codec_embedding = nn.Embedding(config.vocab_size, config.hidden_size) + self.layers = nn.ModuleList( + [Qwen3OmniMoeTalkerDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = Qwen3OmniMoeTalkerRotaryEmbedding(config) + + def get_input_embeddings(self): + return self.codec_embedding + + +class Qwen3OmniMoeTalkerForConditionalGeneration(Qwen3MoeForCausalLM): + config_class = Qwen3OmniMoeTalkerConfig + base_model_prefix = "talker" + _no_split_modules = ["Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration"] + _can_record_outputs = { + "attentions": Qwen3OmniMoeThinkerTextAttention, + "router_logits": OutputRecorder(Qwen3OmniMoeTalkerTextSparseMoeBlock, index=1), + } + + def __init__(self, config: Qwen3OmniMoeTalkerConfig): + super().__init__(config) + del self.lm_head + self.model = Qwen3OmniMoeTalkerModel._from_config(config.text_config) + self.text_projection = Qwen3OmniMoeTalkerResizeMLP(config) + self.hidden_projection = Qwen3OmniMoeTalkerResizeMLP(config) + self.codec_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False) + self.code_predictor = Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration._from_config( + config=config.code_predictor_config + ) + self.rope_deltas = None + self.spatial_merge_size = self.config.spatial_merge_size + self.vocab_size = config.text_config.vocab_size + self.router_aux_loss_coef = config.text_config.router_aux_loss_coef + self.num_experts = config.text_config.num_experts + self.num_experts_per_tok = config.text_config.num_experts_per_tok + + # Should inherit from PretrainedModel, but cannot inherit multiple classes in modular + def get_rope_index( + self, + input_ids: Optional[torch.LongTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + use_audio_in_video: bool = False, + audio_seqlens: Optional[torch.LongTensor] = None, + second_per_grids: Optional[torch.Tensor] = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + return Qwen3OmniMoePreTrainedModelForConditionalGeneration.get_rope_index( + self, + input_ids, + image_grid_thw, + video_grid_thw, + attention_mask, + use_audio_in_video, + audio_seqlens, + second_per_grids, + ) + + def get_llm_pos_ids_for_vision( + self, + start_idx: int, + vision_idx: int, + spatial_merge_size: int, + t_index: list[torch.Tensor], + grid_hs: list[torch.Tensor], + grid_ws: list[torch.Tensor], + ): + return Qwen3OmniMoePreTrainedModelForConditionalGeneration.get_llm_pos_ids_for_vision( + self, start_idx, vision_idx, spatial_merge_size, t_index, grid_hs, grid_ws + ) + + def get_input_embeddings(self): + return self.model.get_input_embeddings() + + def forward( + self, + input_ids=None, + attention_mask=None, + use_audio_in_video=None, + audio_feature_lengths=None, + video_second_per_grid=None, + image_grid_thw=None, + video_grid_thw=None, + position_ids=None, + past_key_values=None, + inputs_embeds=None, + labels=None, + use_cache=None, + output_router_logits=None, + cache_position=None, + residual_codes=None, + trailing_text_hidden=None, + tts_pad_embed=None, + generation_step=None, + talker_input_ids=None, + **kwargs, + ): + r""" + Args: + use_audio_in_video (`bool`, *optional*): + If set to `True`, use the audio in video. + audio_feature_lengths (`torch.LongTensor` of shape `(num_audios)`, *optional*): + The length of feature shape of each audio in LLM. + video_second_per_grid (`torch.LongTensor` of shape `(num_videos)`, *optional*): + Number of seconds per grid for each video, used for temporal feature mapping. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + residual_codes (`torch.Tensor`): + The predicted residual codes of previous step. + trailing_text_hidden (`torch.Tensor`): + Text hidden states from thinker after the first token. + tts_pad_embed (`torch.Tensor`): + Embedding tensor of `tts_pad_token_id`. + generation_step (`int`): + Generation step since prefill, used to sync with `trailing_text_hidden`. + talker_input_ids (`torch.Tensor`): + Input ids from thinker, used to compute 3d RoPE. + """ + # Prefill + if inputs_embeds is not None and inputs_embeds.shape[1] > 1: + generation_step = -1 + residual_codes = None + if attention_mask is not None: + if ( + cache_position is None + or (cache_position is not None and cache_position[0] == 0) + or self.rope_deltas is None + ): + delta0 = (1 - attention_mask).sum(dim=-1).unsqueeze(1) + position_ids, rope_deltas = self.get_rope_index( + talker_input_ids, + image_grid_thw, + video_grid_thw, + attention_mask, + use_audio_in_video, + audio_feature_lengths, + video_second_per_grid, + ) + rope_deltas = rope_deltas - delta0 + self.rope_deltas = rope_deltas + else: + batch_size, seq_length = input_ids.shape + delta = cache_position[0] + self.rope_deltas if cache_position is not None else 0 + position_ids = torch.arange(seq_length, device=input_ids.device) + position_ids = position_ids.view(1, -1).expand(batch_size, -1) + position_ids = position_ids.add(delta) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1) + + outputs: MoeModelOutputWithPast = self.model( + input_ids=None, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_router_logits=output_router_logits, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs.last_hidden_state + logits = self.codec_head(hidden_states) + + loss = None + if labels is not None: + loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs) + + aux_loss = None + if output_router_logits: + aux_loss = load_balancing_loss_func( + outputs.router_logits, + self.num_experts, + self.num_experts_per_tok, + attention_mask, + ) + if labels is not None: + loss += self.router_aux_loss_coef * aux_loss.to(loss.device) # make sure to reside in the same device + + return Qwen3OmniMoeTalkerOutputWithPast( + loss=loss, + logits=logits, + aux_loss=aux_loss, + past_key_values=outputs.past_key_values, + hidden_states=( + outputs.hidden_states, + residual_codes, + ), # TODO: hack here to take residual codes out, need refactor. + generation_step=generation_step + 1, + ) + + def _update_model_kwargs_for_generation(self, outputs, model_kwargs, is_encoder_decoder=False, num_new_tokens=1): + model_kwargs = super()._update_model_kwargs_for_generation( + outputs, model_kwargs, is_encoder_decoder, num_new_tokens + ) + model_kwargs["hidden_states"] = outputs.hidden_states + model_kwargs["generation_step"] = outputs.generation_step + return model_kwargs + + def prepare_inputs_for_generation( + self, input_ids, past_key_values=None, attention_mask=None, inputs_embeds=None, cache_position=None, **kwargs + ): + hidden_states = kwargs.pop("hidden_states", None) + inputs = super().prepare_inputs_for_generation( + input_ids, past_key_values, attention_mask, inputs_embeds, cache_position, **kwargs + ) + # Decode stage + # TODO(raushan, gante): Refactor this part to a utility function + if cache_position[0] != 0: + input_ids = input_ids[:, -1:] + generation_step = kwargs.get("generation_step") + trailing_text_hidden = kwargs.get("trailing_text_hidden") + tts_pad_embed = kwargs.get("tts_pad_embed") + last_id_hidden = self.get_input_embeddings()(input_ids) + + past_hidden = hidden_states[0][-1][:, -1:].to(last_id_hidden.device) # hidden, last layer, last token + predictor_result = self.code_predictor.generate( + inputs_embeds=torch.cat((past_hidden, last_id_hidden), dim=1), + max_new_tokens=self.config.num_code_groups - 1, + do_sample=True, + top_k=50, + top_p=0.8, + output_hidden_states=True, + return_dict_in_generate=True, + ) + residual_codes = torch.cat((input_ids, predictor_result.sequences.to(input_ids.device)), dim=-1) + + mid_residual_hiddens = [hid[0].to(last_id_hidden.device) for hid in predictor_result.hidden_states[1:]] + last_residual_hidden = self.code_predictor.get_input_embeddings()[-1]( + predictor_result.sequences[..., -1:] + ).to(last_id_hidden.device) + codec_hiddens = torch.cat( + [last_id_hidden] + mid_residual_hiddens + [last_residual_hidden], + dim=1, + ) + inputs_embeds = codec_hiddens.sum(1, keepdim=True) + + if generation_step < trailing_text_hidden.shape[1]: + inputs_embeds = inputs_embeds + trailing_text_hidden[:, generation_step].unsqueeze(1).to( + inputs_embeds.device + ) + else: + inputs_embeds = inputs_embeds + tts_pad_embed.to(inputs_embeds.device) + inputs["inputs_embeds"] = inputs_embeds + inputs["residual_codes"] = residual_codes + return inputs + + +class Qwen3OmniMoeCausalConvNet(nn.Module): + def __init__( + self, + in_channels, + out_channels, + kernel_size, + dilation=1, + stride=1, + groups=1, + ): + super().__init__() + self.conv = nn.Conv1d( + in_channels, + out_channels, + kernel_size, + stride=stride, + dilation=dilation, + groups=groups, + ) + self.stride = stride + self.kernel_size = (kernel_size - 1) * dilation + 1 + self.dilation = dilation + self.padding = self.kernel_size - self.stride + + def _get_extra_padding_for_conv1d(self, hidden_state: torch.Tensor) -> int: + length = hidden_state.shape[-1] + n_frames = (length - self.kernel_size + self.padding) / self.stride + 1 + ideal_length = (math.ceil(n_frames) - 1) * self.stride + (self.kernel_size - self.padding) + return ideal_length - length + + def forward(self, hidden_state): + extra_padding = self._get_extra_padding_for_conv1d(hidden_state) + hidden_state = F.pad(hidden_state, (self.padding, extra_padding), mode="constant", value=0) + return self.conv(hidden_state).contiguous() + + +class Qwen3OmniMoeCausalTransConvNet(nn.Module): + def __init__(self, in_channels, out_channels, kernel_size, stride=1): + super().__init__() + self.conv = nn.ConvTranspose1d(in_channels, out_channels, kernel_size, stride=stride) + + pad = kernel_size - stride + self.left_pad = math.ceil(pad) + self.right_pad = pad = self.left_pad + + def forward(self, hidden_state): + hidden_state = self.conv(hidden_state) + hidden_state = hidden_state[..., self.left_pad : hidden_state.shape[-1] - self.right_pad] + return hidden_state.contiguous() + + +class Qwen3OmniMoeConvNeXtBlock(nn.Module): + def __init__(self, dim: int): + super().__init__() + self.dwconv = Qwen3OmniMoeCausalConvNet( + dim, + dim, + kernel_size=7, + groups=dim, + dilation=1, + ) + self.norm = nn.LayerNorm(dim, eps=1e-6) + self.pwconv1 = nn.Linear(dim, 4 * dim) + self.act = nn.GELU() + self.pwconv2 = nn.Linear(4 * dim, dim) + self.gamma = nn.Parameter(1e-6 * torch.ones(dim)) + + def forward(self, hidden_states): + input = hidden_states + + hidden_states = self.dwconv(hidden_states) + hidden_states = hidden_states.permute(0, 2, 1) + hidden_states = self.norm(hidden_states) + hidden_states = self.pwconv1(hidden_states) + hidden_states = self.act(hidden_states) + hidden_states = self.pwconv2(hidden_states) + + hidden_states = self.gamma * hidden_states + + hidden_states = hidden_states.permute(0, 2, 1) + + hidden_states = input + hidden_states + + return hidden_states + + +class Qwen3OmniMoeCode2WavRotatoryEmbedding(Qwen3RotaryEmbedding): + pass + + +class Qwen3OmniMoeCode2WavAttention(Qwen3Attention): + def __init__(self, config: Qwen3OmniMoeCode2WavConfig, layer_idx): + super().__init__(config, layer_idx) + self.q_norm = nn.Identity() + self.k_norm = nn.Identity() + self.sliding_window = config.sliding_window + + +class Qwen3OmniMoeCode2WavMlp(Qwen3MLP): + pass + + +class Qwen3OmniMoeCode2WavRMSNorm(Qwen3RMSNorm): + pass + + +class Qwen3OmniMoeCode2WavLayerScale(MimiLayerScale): + pass + + +class Qwen3OmniMoeCode2WavTransformerLayer(GradientCheckpointingLayer): + def __init__(self, config: Qwen3OmniMoeCode2WavConfig, layer_idx): + super().__init__() + self.hidden_size = config.hidden_size + self.self_attn = Qwen3OmniMoeCode2WavAttention(config, layer_idx) + self.mlp = Qwen3OmniMoeCode2WavMlp(config) + self.input_layernorm = Qwen3OmniMoeCode2WavRMSNorm(config.hidden_size, config.rms_norm_eps) + self.post_attention_layernorm = Qwen3OmniMoeCode2WavRMSNorm(config.hidden_size, config.rms_norm_eps) + self.self_attn_layer_scale = Qwen3OmniMoeCode2WavLayerScale(config) + self.mlp_layer_scale = Qwen3OmniMoeCode2WavLayerScale(config) + self.attention_type = "sliding_attention" + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + **kwargs, + ) -> tuple[torch.FloatTensor, Optional[tuple[torch.FloatTensor, torch.FloatTensor]]]: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`, *optional*): + attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1, + query_sequence_length, key_sequence_length)` if default attention is used. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + past_key_values (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states + cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*): + Indices depicting the position of the input sequence tokens in the sequence + kwargs (`dict`, *optional*): + Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code + into the model + """ + residual = hidden_states + + hidden_states = self.input_layernorm(hidden_states) + + # Self Attention + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + hidden_states = residual + self.self_attn_layer_scale(hidden_states) + + # Fully Connected + residual = hidden_states + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + self.mlp_layer_scale(hidden_states) + + return hidden_states + + +class Qwen3OmniMoeCode2WavTransformerModel(Qwen3Model): + _can_record_outputs = { + "hidden_states": Qwen3OmniMoeCode2WavTransformerLayer, + "attentions": Qwen3OmniMoeCode2WavAttention, + } + + def __init__(self, config: Qwen3OmniMoeCode2WavConfig): + super().__init__(config) + del self.vocab_size + del self.padding_idx + del self.embed_tokens + self.window_size = config.sliding_window + self.layers = nn.ModuleList( + [Qwen3OmniMoeCode2WavTransformerLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + + def forward( + self, + input_ids=None, + attention_mask=None, + position_ids=None, + past_key_values=None, + inputs_embeds=None, + use_cache=None, + cache_position=None, + **kwargs, + ): + if input_ids is not None: + raise ValueError("input_ids is not expected") + return super().forward( + input_ids, + attention_mask, + position_ids, + past_key_values, + inputs_embeds, + use_cache, + cache_position, + **kwargs, + ) + + +class SnakeBeta(SnakeBeta): + pass + + +class Qwen3OmniMoeCode2WavDecoderResidualUnit(nn.Module): + def __init__(self, dim: int = 16, dilation: int = 1): + super().__init__() + + self.act1 = SnakeBeta(dim) + self.conv1 = Qwen3OmniMoeCausalConvNet(dim, dim, kernel_size=7, dilation=dilation) + self.act2 = SnakeBeta(dim) + self.conv2 = Qwen3OmniMoeCausalConvNet(dim, dim, kernel_size=1) + + def forward(self, hidden_state): + residual = hidden_state + + hidden_state = self.act1(hidden_state) + hidden_state = self.conv1(hidden_state) + hidden_state = self.act2(hidden_state) + hidden_state = self.conv2(hidden_state) + return hidden_state + residual + + +class Qwen3OmniMoeCode2WavDecoderBlock(Qwen3OmniMoePreTrainedModel): + def __init__(self, config: Qwen3OmniMoeCode2WavConfig, layer_idx): + super().__init__(config) + in_dim = config.decoder_dim // 2**layer_idx + out_dim = config.decoder_dim // 2 ** (layer_idx + 1) + upsample_rate = config.upsample_rates[layer_idx] + + block = [ + SnakeBeta(in_dim), + Qwen3OmniMoeCausalTransConvNet(in_dim, out_dim, 2 * upsample_rate, upsample_rate), + ] + + for dilation in (1, 3, 9): + block.append(Qwen3OmniMoeCode2WavDecoderResidualUnit(out_dim, dilation)) + + self.block = nn.ModuleList(block) + + def forward(self, hidden): + for block in self.block: + hidden = block(hidden) + return hidden + + +class Qwen3OmniMoeCode2Wav(Qwen3OmniMoePreTrainedModel): + def __init__(self, config: Qwen3OmniMoeCode2WavConfig): + super().__init__(config) + self.total_upsample = np.prod(config.upsample_rates + config.upsampling_ratios) + self.pre_transformer = Qwen3OmniMoeCode2WavTransformerModel._from_config(config) + self.code_embedding = nn.Embedding(config.codebook_size * config.num_quantizers, config.hidden_size) + self.register_buffer( + "code_offset", torch.arange(config.num_quantizers).view(1, -1, 1) * config.codebook_size, persistent=False + ) + + upsample = [] + for factor in config.upsampling_ratios: + upsample.append( + nn.ModuleList( + [ + Qwen3OmniMoeCausalTransConvNet(config.hidden_size, config.hidden_size, factor, factor), + Qwen3OmniMoeConvNeXtBlock(config.hidden_size), + ] + ) + ) + self.upsample = nn.ModuleList(upsample) + + decoder = [Qwen3OmniMoeCausalConvNet(config.hidden_size, config.decoder_dim, 7)] + for i in range(len(config.upsample_rates)): + decoder.append(Qwen3OmniMoeCode2WavDecoderBlock(config, i)) + output_dim = config.decoder_dim // 2 ** len(config.upsample_rates) + decoder += [ + SnakeBeta(output_dim), + Qwen3OmniMoeCausalConvNet(output_dim, 1, 7), + ] + self.decoder = nn.ModuleList(decoder) + + self.post_init() + + def forward(self, codes): + if codes.shape[1] != self.config.num_quantizers: + raise ValueError(f"Expected {self.config.num_quantizers} layer of codes, got {codes.shape[1]}") + hidden = self.code_embedding(codes + self.code_offset).mean(1) + hidden = self.pre_transformer(inputs_embeds=hidden).last_hidden_state + hidden = hidden.permute(0, 2, 1) + for blocks in self.upsample: + for block in blocks: + hidden = block(hidden) + wav = hidden + for block in self.decoder: + wav = block(wav) + return wav.clamp(min=-1, max=1) + + def chunked_decode(self, codes, chunk_size=300, left_context_size=25): + wavs = [] + start_index = 0 + while start_index < codes.shape[-1]: + end_index = min(start_index + chunk_size, codes.shape[-1]) + context_size = left_context_size if start_index - left_context_size > 0 else start_index + codes_chunk = codes[..., start_index - context_size : end_index] + wav_chunk = self(codes_chunk) + wavs.append(wav_chunk[..., context_size * self.total_upsample :]) + start_index = end_index + return torch.cat(wavs, dim=-1) + + +class Qwen3OmniMoeForConditionalGeneration(Qwen3OmniMoePreTrainedModel, GenerationMixin): + config_class = Qwen3OmniMoeConfig + + def __init__(self, config: Qwen3OmniMoeConfig): + super().__init__(config) + + self.thinker = Qwen3OmniMoeThinkerForConditionalGeneration._from_config(config.thinker_config) + self.has_talker = config.enable_audio_output + if self.has_talker: + self.enable_talker() + self.post_init() + + def enable_talker(self): + self.talker = Qwen3OmniMoeTalkerForConditionalGeneration._from_config(self.config.talker_config) + self.code2wav = Qwen3OmniMoeCode2Wav._from_config(self.config.code2wav_config) + + def disable_talker(self): + if hasattr(self, "talker"): + del self.talker + if hasattr(self, "code2wav"): + del self.code2wav + self.has_talker = False + + def _get_talker_user_parts( + self, im_start_index, segment_end_index, multimodal_mask, thinker_hidden, thinker_embed + ): + user_talker_part = torch.empty( + (1, segment_end_index - im_start_index, self.config.talker_config.text_config.hidden_size), + device=self.talker.device, + dtype=self.talker.dtype, + ) + + user_mm_mask = multimodal_mask[:, im_start_index:segment_end_index] + + # Multimodal data exists + if user_mm_mask.any(): + user_thinker_hidden_mm = thinker_hidden[:, im_start_index:segment_end_index][user_mm_mask] + mm_hidden = self.talker.hidden_projection(user_thinker_hidden_mm).to(self.talker.device) + user_talker_part[user_mm_mask] = mm_hidden + user_thinker_embed = thinker_embed[:, im_start_index:segment_end_index][~user_mm_mask] + user_text_hidden = self.talker.text_projection(user_thinker_embed).to(self.talker.device) + user_talker_part[~user_mm_mask] = user_text_hidden + return user_talker_part + + def _get_talker_assistant_parts( + self, im_start_index, segment_end_index, speaker_id, thinker_embed, tts_pad_embed, tts_bos_embed, tts_eos_embed + ): + assistant_hidden = self.talker.text_projection(thinker_embed[:, im_start_index:segment_end_index]).to( + self.talker.device + ) # [1 t d] + assistant_text_hidden = torch.cat( + ( + assistant_hidden[:, :3], + tts_pad_embed.expand(-1, 4, -1), + tts_bos_embed, + assistant_hidden[:, 3:4], # First text + ), + dim=1, + ) + codec_special_tokens = torch.tensor( + [ + [ + self.config.talker_config.codec_nothink_id, + self.config.talker_config.codec_think_bos_id, + self.config.talker_config.codec_think_eos_id, + speaker_id, + self.config.talker_config.codec_pad_id, + self.config.talker_config.codec_bos_id, + ] + ], + device=self.talker.device, + dtype=torch.long, + ) + assistant_codec_hidden = torch.cat( + ( + torch.zeros( + (1, 3, self.config.talker_config.text_config.hidden_size), + device=self.talker.device, + dtype=self.talker.dtype, + ), + self.talker.get_input_embeddings()(codec_special_tokens).to(self.talker.device), + ), + dim=1, + ) + trailing_text_hidden = torch.cat( + ( + assistant_hidden[:, 4:], + tts_eos_embed, + ), + dim=1, + ) + + input_embeds = assistant_text_hidden + assistant_codec_hidden + input_ids = torch.full( + (1, assistant_text_hidden.shape[1]), + fill_value=self.config.tts_pad_token_id, + dtype=torch.long, + device=assistant_text_hidden.device, + ) + return input_embeds, input_ids, trailing_text_hidden + + @torch.no_grad() + def generate( + self, + input_ids: Optional[torch.Tensor] = None, + speaker: str = "Ethan", + use_audio_in_video: bool = False, + return_audio: Optional[bool] = None, + thinker_max_new_tokens: int = 1024, + thinker_eos_token_id: int = 151645, + talker_max_new_tokens: int = 4096, + talker_do_sample: bool = True, + talker_top_k: int = 50, + talker_top_p: float = 1.0, + talker_temperature: float = 0.9, + talker_repetition_penalty: float = 1.05, + **kwargs, + ): + if return_audio and not self.has_talker: + raise ValueError( + "Cannot use talker when talker module not initialized. Use `enable_talker` method or set enable_talker in config to enable talker." + ) + if return_audio is None: + return_audio = self.has_talker + + shared_kwargs = {"use_audio_in_video": use_audio_in_video} + thinker_kwargs = { + "max_new_tokens": thinker_max_new_tokens, + "eos_token_id": thinker_eos_token_id, + } + + talker_kwargs = {} + token2wav_kwargs = {} + if return_audio: + speaker_id = self.config.talker_config.speaker_id.get(speaker.lower()) + if speaker_id is None: + raise NotImplementedError(f"Speaker {speaker} not implemented") + if input_ids.shape[0] != 1: + raise NotImplementedError("Qwen3-Omni currently does not support batched inference with audio output") + talker_supppressed_tokens = [ + i + for i in range( + self.config.talker_config.text_config.vocab_size - 1024, + self.config.talker_config.text_config.vocab_size, + ) + if i not in (self.config.talker_config.codec_eos_token_id,) + ] # Suppress additional special tokens, should not be predicted + talker_kwargs = { + "max_new_tokens": talker_max_new_tokens, + "do_sample": talker_do_sample, + "top_k": talker_top_k, + "top_p": talker_top_p, + "temperature": talker_temperature, + "eos_token_id": self.config.talker_config.codec_eos_token_id, + "repetition_penalty": talker_repetition_penalty, + "suppress_tokens": talker_supppressed_tokens, + "output_hidden_states": True, + "return_dict_in_generate": True, + } + token2wav_kwargs = {} + + for key, value in kwargs.items(): + if key.startswith("thinker_"): + thinker_kwargs[key[len("thinker_") :]] = value + elif key.startswith("talker_"): + talker_kwargs[key[len("talker_") :]] = value + elif key.startswith("token2wav_"): + token2wav_kwargs[key[len("token2wav_") :]] = value + # Process special input values + elif key == "feature_attention_mask": + thinker_kwargs[key] = value + talker_kwargs["audio_feature_lengths"] = torch.sum(value, dim=1) + elif key in ("input_features", "attention_mask"): + thinker_kwargs[key] = value + # Put other key to shared kwargs + else: + shared_kwargs[key] = value + + # Merge kwargs + for key, value in shared_kwargs.items(): + if key not in thinker_kwargs: + thinker_kwargs[key] = value + if key not in talker_kwargs and key in ["image_grid_thw", "video_grid_thw", "video_second_per_grid"]: + talker_kwargs[key] = value + if key not in token2wav_kwargs: + token2wav_kwargs[key] = value + + # 1. Generate from thinker module + generate_audio = return_audio and self.has_talker + if generate_audio: + thinker_kwargs["output_hidden_states"] = True + thinker_kwargs["return_dict_in_generate"] = True + + thinker_result = self.thinker.generate(input_ids=input_ids, **thinker_kwargs) + + if not generate_audio: + return thinker_result, None + + # 2. Prepare talker input + thinker_embed = torch.cat([hidden_states[0] for hidden_states in thinker_result.hidden_states], dim=1).to( + self.talker.device + ) # [1 t d] + thinker_hidden = torch.cat( + [ + hidden_states[self.config.talker_config.accept_hidden_layer] + for hidden_states in thinker_result.hidden_states + ], + dim=1, + ).to(self.talker.device) # [1 t d] + im_start_indexes = torch.cat( + ( + torch.nonzero(input_ids[0] == self.config.im_start_token_id).squeeze(), + torch.tensor([thinker_result.sequences.shape[-1]], device=input_ids.device, dtype=input_ids.dtype), + ), + dim=-1, + ).to(self.talker.device) # Shape [n_starts + 1]; Take batch 0 since batched inference is not supported here. + multimodal_mask = ( + (thinker_result.sequences == self.config.thinker_config.audio_token_id) | + (thinker_result.sequences == self.config.thinker_config.image_token_id) | + (thinker_result.sequences == self.config.thinker_config.video_token_id) + ).to(self.talker.device) # [1 t] # fmt: skip + + talker_special_tokens = torch.tensor( + [[self.config.tts_bos_token_id, self.config.tts_eos_token_id, self.config.tts_pad_token_id]], + device=self.thinker.device, + dtype=input_ids.dtype, + ) + tts_bos_embed, tts_eos_embed, tts_pad_embed = ( + self.talker.text_projection(self.thinker.get_input_embeddings()(talker_special_tokens)) + .to(self.talker.device) + .chunk(3, dim=1) + ) # 3 * [1 1 d] + + talker_input_embeds = [] # [1 t d] + talker_input_ids = [] + # For every chatml parts + for i in range(len(im_start_indexes) - 1): + im_start_index = im_start_indexes[i] + segment_end_index = im_start_indexes[i + 1] + role_token = input_ids[0][im_start_index + 1] + # Talker should ignore thinker system prompt + if role_token == self.config.system_token_id: + continue + # Talker takes word embeddings for tokens and hidden state from `accept_hidden_layer` for multimodal inputs + elif role_token == self.config.user_token_id: + talker_user_part = self._get_talker_user_parts( + im_start_index, segment_end_index, multimodal_mask, thinker_hidden, thinker_embed + ) + talker_input_embeds.append(talker_user_part) + talker_input_ids.append(thinker_result.sequences[:, im_start_index:segment_end_index]) + # Take assistant output (for now) + elif role_token == self.config.assistant_token_id and i == len(im_start_indexes) - 2: + talker_assistant_embeds, talker_assistant_ids, trailing_text_hidden = self._get_talker_assistant_parts( + im_start_index, + segment_end_index, + speaker_id, + thinker_embed, + tts_pad_embed, + tts_bos_embed, + tts_eos_embed, + ) + talker_input_embeds.append(talker_assistant_embeds) + talker_input_ids.append(talker_assistant_ids) + # History assistant output (ignore for now) + elif role_token == self.config.assistant_token_id and i != len(im_start_indexes) - 2: + continue + else: + raise AssertionError("Expect role id after <|im_start|> (assistant, user, system)") + talker_input_embed = torch.cat([embed.to(self.talker.device) for embed in talker_input_embeds], dim=1) + talker_input_id = torch.cat([embed.to(self.talker.device) for embed in talker_input_ids], dim=1) + talker_result = self.talker.generate( + inputs_embeds=talker_input_embed, + trailing_text_hidden=trailing_text_hidden, + tts_pad_embed=tts_pad_embed, + talker_input_ids=talker_input_id, # Not use input_ids to prevent repetation penalty out of bound + **talker_kwargs, + ) + talker_codes = ( + torch.stack([hid[-1] for hid in talker_result.hidden_states if hid[-1] is not None], dim=1) + .transpose(1, 2) + .to(self.code2wav.device) + ) + talker_wavs = self.code2wav.chunked_decode(talker_codes, chunk_size=300, left_context_size=25) + + return thinker_result, talker_wavs.float() + + +class Qwen3OmniMoeProcessorKwargs(Qwen2_5OmniProcessorKwargs): + _defaults = { + "text_kwargs": { + "padding": False, + "padding_side": "left", + }, + "videos_kwargs": { + "seconds_per_chunk": 2.0, + "position_id_per_seconds": 13.0, + "use_audio_in_video": False, + "size": { + "shortest_edge": 128 * 32 * 32, + "longest_edge": 768 * 32 * 32, + }, + }, + "audio_kwargs": { + "sampling_rate": 16000, + "padding": True, + "return_attention_mask": True, + }, + } + + +class Qwen3OmniMoeProcessor(Qwen2_5OmniProcessor, ProcessorMixin): + def replace_multimodal_special_tokens( + self, + text, + audio_lengths, + image_grid_thw, + video_grid_thw, + video_second_per_grid, + use_audio_in_video, + position_id_per_seconds, + seconds_per_chunk, + ): + # Extend mm token length + merge_length_image = self.image_processor.merge_size**2 + merge_length_video = self.video_processor.merge_size**2 + + processed_text = [] + for sample in text: + positions = [] + special_tokens = [re.escape(tok) for tok in [self.audio_token, self.image_token, self.video_token]] + pattern = "|".join(special_tokens) + positions = sorted([(match.start(), match.group()) for match in re.finditer(pattern, sample)]) + positions.sort(key=lambda x: x[0]) + + for _, special_token in positions: + if special_token == self.audio_token: + sample = sample.replace(self.audio_token, "<|audio_placeholder|>" * next(audio_lengths), 1) + elif special_token == self.image_token: + image_seq_length = next(image_grid_thw).prod() // merge_length_image + sample = sample.replace(self.image_token, "<|image_placeholder|>" * image_seq_length, 1) + elif special_token == self.video_token: + if not use_audio_in_video: + video_seq_length = next(video_grid_thw).prod() // merge_length_video + sample = sample.replace(self.video_token, "<|video_placeholder|>" * video_seq_length, 1) + else: + audio_token_indices = np.arange(next(audio_lengths)) + curr_video_grid_thw = next(video_grid_thw) + height = curr_video_grid_thw[1] // self.video_processor.merge_size + width = curr_video_grid_thw[2] // self.video_processor.merge_size + video_token_indices = np.arange(curr_video_grid_thw[0]).reshape(-1, 1, 1) + video_token_indices = np.broadcast_to( + video_token_indices, (video_token_indices.shape[0], height, width) + ).reshape(-1) + video_token_indices = ( + video_token_indices * next(video_second_per_grid) * position_id_per_seconds + ) + + video_data_index, audio_data_index = 0, 0 + placeholder_string = self.vision_bos_token + self.audio_bos_token + while video_data_index < len(video_token_indices) and audio_data_index < len( + audio_token_indices + ): + if video_token_indices[video_data_index] <= audio_token_indices[audio_data_index]: + placeholder_string += "<|video_placeholder|>" + video_data_index += 1 + else: + placeholder_string += "<|audio_placeholder|>" + audio_data_index += 1 + if video_data_index < len(video_token_indices): + placeholder_string += "<|video_placeholder|>" * ( + len(video_token_indices) - video_data_index + ) + if audio_data_index < len(audio_token_indices): + placeholder_string += "<|audio_placeholder|>" * ( + len(audio_token_indices) - audio_data_index + ) + placeholder_string += self.audio_eos_token + self.vision_eos_token + sample = sample.replace( + self.vision_bos_token + self.video_token + self.vision_eos_token, + placeholder_string, + 1, + ) + + sample = sample.replace("<|audio_placeholder|>", self.audio_token) + sample = sample.replace("<|image_placeholder|>", self.image_token) + sample = sample.replace("<|video_placeholder|>", self.video_token) + processed_text.append(sample) + return processed_text + + def __call__( + self, + text: TextInput = None, + images: ImageInput = None, + videos: VideoInput = None, + audio: AudioInput = None, + **kwargs, + ): + """ + Main method to prepare for the model one or several sequences(s) and audio(s). This method forwards the `text` + and `kwargs` arguments to Qwen2TokenizerFast's [`~Qwen2TokenizerFast.__call__`] if `text` is not `None` to encode + the text. To prepare the audio(s), this method forwards the `audio` and `kwargs` arguments to + WhisperFeatureExtractor's [`~WhisperFeatureExtractor.__call__`] if `audio` is not `None`. To prepare the vision inputs, + this method forwards the `vision_infos` and `kwargs` arguments to Qwen2VLImageProcessor's [`~Qwen2VLImageProcessor.__call__`] + if `vision_infos` is not `None`. Please refer to the doctsring + of the above two methods for more information. + + Args: + text (`str`, `List[str]`, `List[List[str]]`): + The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings + (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set + `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + images (`PIL.Image.Image`, `np.ndarray`, `torch.Tensor`, `List[PIL.Image.Image]`, `List[np.ndarray]`, `List[torch.Tensor]`): + The image or batch of images to be prepared. Each image can be a PIL image, NumPy array or PyTorch + tensor. Both channels-first and channels-last formats are supported. + videos (`np.ndarray`, `torch.Tensor`, `List[np.ndarray]`, `List[torch.Tensor]`): + The image or batch of videos to be prepared. Each video can be a 4D NumPy array or PyTorch + tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. + audio (`np.ndarray`, `List[np.ndarray]`): + The audio or batch of audio to be prepared. Each audio can be a NumPy array. + """ + + if text is None: + raise ValueError("You need to specify either a `text` input to process.") + + output_kwargs = self._merge_kwargs( + Qwen3OmniMoeProcessorKwargs, + tokenizer_init_kwargs=self.tokenizer.init_kwargs, + **kwargs, + ) + + seconds_per_chunk = output_kwargs["videos_kwargs"].pop("seconds_per_chunk") + position_id_per_seconds = output_kwargs["videos_kwargs"].pop("position_id_per_seconds") + use_audio_in_video = output_kwargs["videos_kwargs"].pop("use_audio_in_video") + fps = output_kwargs["videos_kwargs"].get("fps", 1.0) + + if audio is not None: + output_kwargs["audio_kwargs"]["padding"] = True # Setting to True to avoid default truncation + audio_inputs = self.feature_extractor(audio, **output_kwargs["audio_kwargs"]) + audio_inputs["feature_attention_mask"] = audio_inputs.pop( + "attention_mask" + ) # rename feature_attention_mask to prevent conflicts later on + audio_inputs["input_features"] = audio_inputs.pop( + "input_features" + ) # rename input_features to prevent conflicts later on + audio_lengths = iter(_get_feat_extract_output_lengths(audio_inputs["feature_attention_mask"].sum(-1))) + else: + audio_inputs = {} + audio_lengths = iter([]) + + if images is not None: + images_inputs = self.image_processor(images=images, videos=None, **output_kwargs["images_kwargs"]) + image_grid_thw = iter(images_inputs["image_grid_thw"]) + else: + images_inputs = {} + image_grid_thw = iter([]) + + if videos is not None: + videos = make_batched_videos(videos) + videos_inputs = self.video_processor(images=None, videos=videos, **output_kwargs["videos_kwargs"]) + fps = [fps] * len(videos) + videos_inputs["video_second_per_grid"] = [ + self.video_processor.temporal_patch_size / fps[i] for i in range(len(fps)) + ] + video_grid_thw = iter(videos_inputs["video_grid_thw"]) + video_second_per_grid = iter(videos_inputs["video_second_per_grid"]) + else: + videos_inputs = {} + video_grid_thw = iter([]) + video_second_per_grid = iter([]) + + if not isinstance(text, list): + text = [text] + + text = self.replace_multimodal_special_tokens( + text, + audio_lengths, + image_grid_thw, + video_grid_thw, + video_second_per_grid=video_second_per_grid, + use_audio_in_video=use_audio_in_video, + position_id_per_seconds=position_id_per_seconds, + seconds_per_chunk=seconds_per_chunk, + ) + + texts_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"]) + + return BatchFeature( + data={**texts_inputs, **images_inputs, **videos_inputs, **audio_inputs}, + tensor_type=kwargs.get("return_tensors"), + ) + + def apply_chat_template(self, conversations, chat_template=None, **kwargs): + return ProcessorMixin.apply_chat_template(self, conversations, chat_template, **kwargs) + + +__all__ = [ + "Qwen3OmniMoeConfig", + "Qwen3OmniMoeThinkerConfig", + "Qwen3OmniMoeTalkerConfig", + "Qwen3OmniMoeForConditionalGeneration", + "Qwen3OmniMoeThinkerTextModel", + "Qwen3OmniMoeThinkerForConditionalGeneration", + "Qwen3OmniMoeTalkerForConditionalGeneration", + "Qwen3OmniMoePreTrainedModel", + "Qwen3OmniMoePreTrainedModelForConditionalGeneration", + "Qwen3OmniMoeTalkerModel", + "Qwen3OmniMoeThinkerTextPreTrainedModel", + "Qwen3OmniMoeProcessor", + "Qwen3OmniMoeCode2Wav", + "Qwen3OmniMoeCode2WavDecoderBlock", + "Qwen3OmniMoeCode2WavTransformerModel", + "Qwen3OmniMoeTalkerCodePredictorModel", + "Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration", +] diff --git a/src/transformers/models/qwen3_omni_moe/processing_qwen3_omni_moe.py b/src/transformers/models/qwen3_omni_moe/processing_qwen3_omni_moe.py new file mode 100644 index 000000000000..f0506bf6930b --- /dev/null +++ b/src/transformers/models/qwen3_omni_moe/processing_qwen3_omni_moe.py @@ -0,0 +1,360 @@ +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# This file was automatically generated from src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py. +# Do NOT edit this file manually as any edits will be overwritten by the generation of +# the file from the modular. If any change should be done, please apply the change to the +# modular_qwen3_omni_moe.py file directly. One of our CI enforces this. +# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 +# coding=utf-8 +# Copyright 2025 The Qwen team, Alibaba Group and the HuggingFace Inc. team. All rights reserved. +# +# +# 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. +import re +from typing import Optional, Union + +import numpy as np + +from ...audio_utils import AudioInput +from ...feature_extraction_utils import BatchFeature +from ...image_utils import ImageInput +from ...processing_utils import ImagesKwargs, ProcessingKwargs, ProcessorMixin, VideosKwargs +from ...tokenization_utils_base import TextInput +from ...video_utils import VideoInput, make_batched_videos + + +class Qwen3OmniMoeVideosKwargs(VideosKwargs): + fps: Optional[list[Union[int, float]]] + use_audio_in_video: Optional[bool] + seconds_per_chunk: Optional[float] + position_id_per_seconds: Optional[int] + min_pixels: Optional[int] + max_pixels: Optional[int] + patch_size: Optional[int] + temporal_patch_size: Optional[int] + merge_size: Optional[int] + + +class Qwen3OmniMoeImagesKwargs(ImagesKwargs): + min_pixels: Optional[int] + max_pixels: Optional[int] + patch_size: Optional[int] + temporal_patch_size: Optional[int] + merge_size: Optional[int] + + +class Qwen3OmniMoeProcessorKwargs(ProcessingKwargs, total=False): + videos_kwargs: Qwen3OmniMoeVideosKwargs + images_kwargs: Qwen3OmniMoeImagesKwargs + _defaults = { + "text_kwargs": { + "padding": False, + "padding_side": "left", + }, + "videos_kwargs": { + "seconds_per_chunk": 2.0, + "position_id_per_seconds": 13.0, + "use_audio_in_video": False, + "size": { + "shortest_edge": 128 * 32 * 32, + "longest_edge": 768 * 32 * 32, + }, + }, + "audio_kwargs": { + "sampling_rate": 16000, + "padding": True, + "return_attention_mask": True, + }, + } + + +def _get_feat_extract_output_lengths(input_lengths): + """ + Computes the output length of the convolutional layers and the output length of the audio encoder + """ + + input_lengths_leave = input_lengths % 100 + feat_lengths = (input_lengths_leave - 1) // 2 + 1 + output_lengths = ((feat_lengths - 1) // 2 + 1 - 1) // 2 + 1 + (input_lengths // 100) * 13 + return output_lengths + + +class Qwen3OmniMoeProcessor(ProcessorMixin): + r""" + Constructs a Qwen2.5Omni processor. + [`Qwen3OmniMoeProcessor`] offers all the functionalities of [`Qwen2VLImageProcessor`], [`WhisperFeatureExtractor`], and [`Qwen2TokenizerFast`]. See the + [`~Qwen3OmniMoeProcessor.__call__`] and [`~Qwen3OmniMoeProcessor.decode`] for more information. + + Args: + image_processor ([`Qwen2VLImageProcessor`], *optional*): + The image processor. + video_processor ([`Qwen2VLVideoProcessor`], *optional*): + The video processor. + feature_extractor ([`WhisperFeatureExtractor`], *optional*): + The audio feature extractor. + tokenizer ([`Qwen2TokenizerFast`], *optional*): + The text tokenizer. + chat_template (`Optional[str]`, *optional*): + The Jinja template to use for formatting the conversation. If not provided, the default chat template is used. + """ + + attributes = ["image_processor", "video_processor", "feature_extractor", "tokenizer"] + image_processor_class = "AutoImageProcessor" + video_processor_class = "AutoVideoProcessor" + feature_extractor_class = "WhisperFeatureExtractor" + tokenizer_class = ("Qwen2Tokenizer", "Qwen2TokenizerFast") + + def __init__( + self, image_processor=None, video_processor=None, feature_extractor=None, tokenizer=None, chat_template=None + ): + super().__init__(image_processor, video_processor, feature_extractor, tokenizer, chat_template=chat_template) + self.image_token = self.tokenizer.image_token + self.audio_token = self.tokenizer.audio_token + self.video_token = self.tokenizer.video_token + self.vision_bos_token = self.tokenizer.vision_bos_token + self.vision_eos_token = self.tokenizer.vision_eos_token + self.audio_bos_token = self.tokenizer.audio_bos_token + self.audio_eos_token = self.tokenizer.audio_eos_token + + def __call__( + self, + text: TextInput = None, + images: ImageInput = None, + videos: VideoInput = None, + audio: AudioInput = None, + **kwargs, + ) -> BatchFeature: + """ + Main method to prepare for the model one or several sequences(s) and audio(s). This method forwards the `text` + and `kwargs` arguments to Qwen2TokenizerFast's [`~Qwen2TokenizerFast.__call__`] if `text` is not `None` to encode + the text. To prepare the audio(s), this method forwards the `audio` and `kwargs` arguments to + WhisperFeatureExtractor's [`~WhisperFeatureExtractor.__call__`] if `audio` is not `None`. To prepare the vision inputs, + this method forwards the `vision_infos` and `kwargs` arguments to Qwen2VLImageProcessor's [`~Qwen2VLImageProcessor.__call__`] + if `vision_infos` is not `None`. Please refer to the doctsring + of the above two methods for more information. + + Args: + text (`str`, `List[str]`, `List[List[str]]`): + The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings + (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set + `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + images (`PIL.Image.Image`, `np.ndarray`, `torch.Tensor`, `List[PIL.Image.Image]`, `List[np.ndarray]`, `List[torch.Tensor]`): + The image or batch of images to be prepared. Each image can be a PIL image, NumPy array or PyTorch + tensor. Both channels-first and channels-last formats are supported. + videos (`np.ndarray`, `torch.Tensor`, `List[np.ndarray]`, `List[torch.Tensor]`): + The image or batch of videos to be prepared. Each video can be a 4D NumPy array or PyTorch + tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. + audio (`np.ndarray`, `List[np.ndarray]`): + The audio or batch of audio to be prepared. Each audio can be a NumPy array. + """ + + if text is None: + raise ValueError("You need to specify either a `text` input to process.") + + output_kwargs = self._merge_kwargs( + Qwen3OmniMoeProcessorKwargs, + tokenizer_init_kwargs=self.tokenizer.init_kwargs, + **kwargs, + ) + + seconds_per_chunk = output_kwargs["videos_kwargs"].pop("seconds_per_chunk") + position_id_per_seconds = output_kwargs["videos_kwargs"].pop("position_id_per_seconds") + use_audio_in_video = output_kwargs["videos_kwargs"].pop("use_audio_in_video") + fps = output_kwargs["videos_kwargs"].get("fps", 1.0) + + if audio is not None: + output_kwargs["audio_kwargs"]["padding"] = True # Setting to True to avoid default truncation + audio_inputs = self.feature_extractor(audio, **output_kwargs["audio_kwargs"]) + audio_inputs["feature_attention_mask"] = audio_inputs.pop( + "attention_mask" + ) # rename feature_attention_mask to prevent conflicts later on + audio_inputs["input_features"] = audio_inputs.pop( + "input_features" + ) # rename input_features to prevent conflicts later on + audio_lengths = iter(_get_feat_extract_output_lengths(audio_inputs["feature_attention_mask"].sum(-1))) + else: + audio_inputs = {} + audio_lengths = iter([]) + + if images is not None: + images_inputs = self.image_processor(images=images, videos=None, **output_kwargs["images_kwargs"]) + image_grid_thw = iter(images_inputs["image_grid_thw"]) + else: + images_inputs = {} + image_grid_thw = iter([]) + + if videos is not None: + videos = make_batched_videos(videos) + videos_inputs = self.video_processor(images=None, videos=videos, **output_kwargs["videos_kwargs"]) + fps = [fps] * len(videos) + videos_inputs["video_second_per_grid"] = [ + self.video_processor.temporal_patch_size / fps[i] for i in range(len(fps)) + ] + video_grid_thw = iter(videos_inputs["video_grid_thw"]) + video_second_per_grid = iter(videos_inputs["video_second_per_grid"]) + else: + videos_inputs = {} + video_grid_thw = iter([]) + video_second_per_grid = iter([]) + + if not isinstance(text, list): + text = [text] + + text = self.replace_multimodal_special_tokens( + text, + audio_lengths, + image_grid_thw, + video_grid_thw, + video_second_per_grid=video_second_per_grid, + use_audio_in_video=use_audio_in_video, + position_id_per_seconds=position_id_per_seconds, + seconds_per_chunk=seconds_per_chunk, + ) + + texts_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"]) + + return BatchFeature( + data={**texts_inputs, **images_inputs, **videos_inputs, **audio_inputs}, + tensor_type=kwargs.get("return_tensors"), + ) + + def replace_multimodal_special_tokens( + self, + text, + audio_lengths, + image_grid_thw, + video_grid_thw, + video_second_per_grid, + use_audio_in_video, + position_id_per_seconds, + seconds_per_chunk, + ): + # Extend mm token length + merge_length_image = self.image_processor.merge_size**2 + merge_length_video = self.video_processor.merge_size**2 + + processed_text = [] + for sample in text: + positions = [] + special_tokens = [re.escape(tok) for tok in [self.audio_token, self.image_token, self.video_token]] + pattern = "|".join(special_tokens) + positions = sorted([(match.start(), match.group()) for match in re.finditer(pattern, sample)]) + positions.sort(key=lambda x: x[0]) + + for _, special_token in positions: + if special_token == self.audio_token: + sample = sample.replace(self.audio_token, "<|audio_placeholder|>" * next(audio_lengths), 1) + elif special_token == self.image_token: + image_seq_length = next(image_grid_thw).prod() // merge_length_image + sample = sample.replace(self.image_token, "<|image_placeholder|>" * image_seq_length, 1) + elif special_token == self.video_token: + if not use_audio_in_video: + video_seq_length = next(video_grid_thw).prod() // merge_length_video + sample = sample.replace(self.video_token, "<|video_placeholder|>" * video_seq_length, 1) + else: + audio_token_indices = np.arange(next(audio_lengths)) + curr_video_grid_thw = next(video_grid_thw) + height = curr_video_grid_thw[1] // self.video_processor.merge_size + width = curr_video_grid_thw[2] // self.video_processor.merge_size + video_token_indices = np.arange(curr_video_grid_thw[0]).reshape(-1, 1, 1) + video_token_indices = np.broadcast_to( + video_token_indices, (video_token_indices.shape[0], height, width) + ).reshape(-1) + video_token_indices = ( + video_token_indices * next(video_second_per_grid) * position_id_per_seconds + ) + + video_data_index, audio_data_index = 0, 0 + placeholder_string = self.vision_bos_token + self.audio_bos_token + while video_data_index < len(video_token_indices) and audio_data_index < len( + audio_token_indices + ): + if video_token_indices[video_data_index] <= audio_token_indices[audio_data_index]: + placeholder_string += "<|video_placeholder|>" + video_data_index += 1 + else: + placeholder_string += "<|audio_placeholder|>" + audio_data_index += 1 + if video_data_index < len(video_token_indices): + placeholder_string += "<|video_placeholder|>" * ( + len(video_token_indices) - video_data_index + ) + if audio_data_index < len(audio_token_indices): + placeholder_string += "<|audio_placeholder|>" * ( + len(audio_token_indices) - audio_data_index + ) + placeholder_string += self.audio_eos_token + self.vision_eos_token + sample = sample.replace( + self.vision_bos_token + self.video_token + self.vision_eos_token, + placeholder_string, + 1, + ) + + sample = sample.replace("<|audio_placeholder|>", self.audio_token) + sample = sample.replace("<|image_placeholder|>", self.image_token) + sample = sample.replace("<|video_placeholder|>", self.video_token) + processed_text.append(sample) + return processed_text + + def get_chunked_index(self, token_indices: np.ndarray, tokens_per_chunk: int) -> list[tuple[int, int]]: + """ + Splits token index list into chunks based on token value ranges. + + Given a list of token indices, returns a list of (start, end) index tuples representing + slices of the list where the token values fall within successive ranges of `t_ntoken_per_chunk`. + + For example, if `t_ntoken_per_chunk` is 1000, the function will create chunks such that: + - the first chunk contains token values < 1000, + - the second chunk contains values >= 1000 and < 2000, and so on. + + Parameters: + token_indices (`np.ndarray`): A monotonically increasing list of token index values. + t_ntoken_per_chunk (`int`): Number of tokens per chunk (used as the chunk size threshold). + + Returns: + `list[tuple[int, int]]`: A list of tuples, each representing the start (inclusive) + and end (exclusive) indices of a chunk in `token_indices`. + """ + + def _iter(): + i, start_idx = 0, 0 # skip bos token + current_chunk = 1 + while i < len(token_indices): # skip eos token + if token_indices[i] >= current_chunk * tokens_per_chunk: + yield (start_idx, i) + start_idx = i + current_chunk += 1 + i += 1 + yield (start_idx, len(token_indices)) + + return list(_iter()) + + def apply_chat_template(self, conversations, chat_template=None, **kwargs): + return super().apply_chat_template(conversations, chat_template, **kwargs) + + @property + def model_input_names(self): + tokenizer_input_names = self.tokenizer.model_input_names + feature_extractor_input_names = self.feature_extractor.model_input_names + image_processor_input_names = self.image_processor.model_input_names + return list( + dict.fromkeys( + tokenizer_input_names + + feature_extractor_input_names + + image_processor_input_names + + ["feature_attention_mask"] + + ["video_second_per_grid"] + ) + ) + + +__all__ = ["Qwen3OmniMoeProcessor"] diff --git a/tests/models/qwen3_omni_moe/__init__.py b/tests/models/qwen3_omni_moe/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/models/qwen3_omni_moe/test_modeling_qwen3_omni_moe.py b/tests/models/qwen3_omni_moe/test_modeling_qwen3_omni_moe.py new file mode 100644 index 000000000000..c0870bceda8d --- /dev/null +++ b/tests/models/qwen3_omni_moe/test_modeling_qwen3_omni_moe.py @@ -0,0 +1,878 @@ +# coding=utf-8 +# Copyright 2025 The Qwen team, Alibaba Group and the HuggingFace Inc. team. All rights reserved. +# +# +# 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 Qwen2.5-Omni model.""" + +import tempfile +import unittest +from io import BytesIO +from urllib.request import urlopen + +import librosa +import pytest +import requests + +from transformers import ( + AutoProcessor, + Qwen3OmniMoeForConditionalGeneration, + Qwen3OmniMoeThinkerConfig, + Qwen3OmniMoeThinkerForConditionalGeneration, + is_torch_available, + is_vision_available, +) +from transformers.testing_utils import ( + Expectations, + cleanup, + require_flash_attn, + require_torch, + require_torch_gpu, + slow, + torch_device, +) + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + floats_tensor, + ids_tensor, +) + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + +class Qwen3OmniMoeThinkerForConditionalGenerationTester: + def __init__( + self, + parent, + batch_size=3, + feat_seq_length=30, + num_channels=3, + image_size=16, + seq_length=39, + audio_token_id=1, + image_token_id=2, + video_token_id=3, + position_id_per_seconds=13, + seconds_per_chunk=2, + audio_start_token_id=4, + audio_end_token_id=5, + user_token_id=6, + vision_start_token_id=7, + vision_end_token_id=8, + initializer_range=0.02, + ): + self.parent = parent + self.vision_config = { + "depth": 2, + "embed_dim": 32, + "hidden_act": "quick_gelu", + "hidden_size": 32, + "out_hidden_size": 32, + "intermediate_size": 24, + "mlp_ratio": 4, + "num_heads": 4, + "patch_size": 16, + "spatial_merge_size": 1, + "temporal_patch_size": 2, + "initializer_range": 0.02, + "deepstack_visual_indexes": [1], + } + self.audio_config = { + "model_type": "qwen_omni_thinker_audio_encoder", + "d_model": 32, + "encoder_attention_heads": 4, + "encoder_ffn_dim": 32, + "encoder_layers": 2, + "num_mel_bins": 20, + "max_source_positions": 1500, + "initializer_range": 0.02, + "n_window": 50, + "output_dim": 32, + "n_window_infer": 100, + } + self.text_config = { + "rope_scaling": { + "mrope_section": [1, 1, 2], + "rope_type": "default", + "type": "default", + "interleaved": True, + }, + "vocab_size": 99, + "hidden_size": 32, + "intermediate_size": 37, + "num_hidden_layers": 4, + "num_attention_heads": 4, + "num_key_value_heads": 2, + "hidden_act": "silu", + "max_position_embeddings": 1024, + "rms_norm_eps": 1e-06, + "use_cache": True, + "tie_word_embeddings": False, + "rope_theta": 1000000.0, + "use_sliding_window": False, + "sliding_window": 50, + "max_window_layers": 3, + "attention_dropout": 0.0, + "pad_token_id": 0, + "initializer_range": 0.02, + "moe_intermediate_size": 32, + "num_experts_per_tok": 2, + "num_experts": 8, + "decoder_sparse_step": 1, + } + self.audio_token_id = audio_token_id + self.image_token_id = image_token_id + self.video_token_id = video_token_id + self.position_id_per_seconds = position_id_per_seconds + self.seconds_per_chunk = seconds_per_chunk + self.audio_start_token_id = audio_start_token_id + self.audio_end_token_id = audio_end_token_id + self.vision_start_token_id = vision_start_token_id + self.vision_end_token_id = vision_end_token_id + self.user_token_id = user_token_id + self.initializer_range = initializer_range + self.batch_size = batch_size + self.feat_seq_length = feat_seq_length + self.num_channels = num_channels + self.image_size = image_size + self.seq_length = seq_length + self.is_training = False + + # Used from `self.model_tester` by common model tests + self.num_hidden_layers = self.text_config["num_hidden_layers"] + self.hidden_size = self.text_config["hidden_size"] + self.num_attention_heads = self.text_config["num_attention_heads"] + self.vocab_size = self.text_config["vocab_size"] + + def get_config(self): + return Qwen3OmniMoeThinkerConfig( + audio_config=self.audio_config, + vision_config=self.vision_config, + text_config=self.text_config, + audio_token_id=self.audio_token_id, + image_token_id=self.image_token_id, + video_token_id=self.video_token_id, + position_id_per_seconds=self.position_id_per_seconds, + seconds_per_chunk=self.seconds_per_chunk, + audio_start_token_id=self.audio_start_token_id, + audio_end_token_id=self.audio_end_token_id, + vision_start_token_id=self.vision_start_token_id, + vision_end_token_id=self.vision_end_token_id, + user_token_id=self.user_token_id, + initializer_range=self.initializer_range, + ) + + def prepare_config_and_inputs(self): + config = self.get_config() + patch_size = config.vision_config.patch_size + temporal_patch_size = config.vision_config.temporal_patch_size + pixel_values = floats_tensor( + [ + self.batch_size * (self.image_size**2) // (patch_size**2), + self.num_channels * (patch_size**2) * temporal_patch_size, + ] + ) + pixel_grid_thw = torch.LongTensor( + [[1, self.image_size / patch_size, self.image_size / patch_size]] * self.batch_size + ).to(pixel_values.device) + input_features_values = floats_tensor( + [self.batch_size, self.audio_config["num_mel_bins"], self.feat_seq_length] + ) + feature_attention_mask = torch.ones([self.batch_size, self.feat_seq_length], dtype=torch.long).to(torch_device) + return config, pixel_values, pixel_grid_thw, input_features_values, feature_attention_mask + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, pixel_grid_thw, input_features_values, feature_attention_mask = config_and_inputs + input_ids = ids_tensor([self.batch_size, self.seq_length], config.get_text_config().vocab_size - 3) + 3 + attention_mask = torch.ones(input_ids.shape, dtype=torch.long).to(torch_device) + + # Make sure no other tokens are set to special, to prevetn flakiness + tokens_to_replace = torch.tensor( + [ + config.image_token_id, + config.audio_token_id, + config.audio_start_token_id, + config.audio_end_token_id, + config.vision_start_token_id, + config.vision_end_token_id, + ], + device=input_ids.device, + ) + input_ids[torch.isin(input_ids, tokens_to_replace)] = config.text_config.pad_token_id + + attention_mask[:, :1] = 0 + + # Audio token placeholders should be wrapped in start and end token ids + audio_feat_length = (((self.feat_seq_length - 1) // 2 + 1 - 1) // 2 + 1 - 1) // 2 + 1 + input_ids[:, 1] = config.audio_start_token_id + input_ids[:, 2 : (2 + audio_feat_length)] = config.audio_token_id + input_ids[:, 2 + audio_feat_length] = config.audio_end_token_id + + # Image token placeholders should be wrapped in start and end token ids + input_ids[:, -4:-1] = torch.tensor( + [config.vision_start_token_id, config.image_token_id, config.vision_end_token_id] + ) + inputs_dict = { + "input_features": input_features_values, + "feature_attention_mask": feature_attention_mask, + "input_ids": input_ids, + "attention_mask": attention_mask, + "image_grid_thw": pixel_grid_thw, + "pixel_values": pixel_values, + } + return config, inputs_dict + + def create_and_check_qwenomnithinker_model_fp16_forward(self, config, input_ids, pixel_values, attention_mask): + model = Qwen3OmniMoeThinkerForConditionalGeneration(config=config) + model.to(torch_device) + model.eval() + with torch.autocast(device_type=torch_device, dtype=torch.float16): + logits = model( + input_ids=input_ids, + attention_mask=attention_mask, + pixel_values=pixel_values.to(torch.bfloat16), + return_dict=True, + )["logits"] + self.parent.assertFalse(torch.isnan(logits).any().item()) + + +@require_torch +class Qwen2_5OmniThinkerForConditionalGenerationModelTest(ModelTesterMixin, GenerationTesterMixin, unittest.TestCase): + """ + Model tester for `Qwen2_5OmniThinkerForConditionalGeneration`. + """ + + all_model_classes = (Qwen3OmniMoeThinkerForConditionalGeneration,) if is_torch_available() else () + all_generative_model_classes = (Qwen3OmniMoeThinkerForConditionalGeneration,) if is_torch_available() else () + test_pruning = False + test_head_masking = False + _is_composite = True + model_split_percents = [0.5, 0.9] + + def setUp(self): + self.model_tester = Qwen3OmniMoeThinkerForConditionalGenerationTester(self) + self.config_tester = ConfigTester(self, config_class=Qwen3OmniMoeThinkerConfig, has_text_modality=False) + + @unittest.skip(reason="Cpu not yet supported because in QwenOmniThinker models") + def test_disk_offload_bin(self): + pass + + @unittest.skip(reason="Disk offload bin not yet supported because in QwenOmniThinker models") + def test_cpu_offload(self): + pass + + @unittest.skip(reason="Disk offload safetensors not yet supported because in QwenOmniThinker models") + def test_disk_offload_safetensors(self): + pass + + @unittest.skip(reason="Correct missing keys not yet supported because in QwenOmniThinker models") + def test_correct_missing_keys(self): + pass + + @unittest.skip(reason="Compile not yet supported because in QwenOmniThinker models") + @pytest.mark.torch_compile_test + def test_sdpa_can_compile_dynamic(self): + pass + + @unittest.skip(reason="Sdpa dispatch not yet supported because in QwenOmniThinker models") + def test_sdpa_can_dispatch_on_flash(self): + pass + + @unittest.skip(reason="QwenOmniThinker does not support output_hidden_states test") + def test_model_outputs_equivalence(self): + pass + + @unittest.skip(reason="Don't have time to investigate at time of merge") + def test_eager_padding_matches_padding_free_with_position_ids(self): + pass + + def test_sdpa_can_dispatch_composite_models(self): + # overwrite because Qwen2 is audio+text model (not vision+text) + if not self.has_attentions: + self.skipTest(reason="Model architecture does not support attentions") + + if not self._is_composite: + self.skipTest(f"{self.all_model_classes[0].__name__} does not support SDPA") + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + model = model_class(config) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model_sdpa = model_class.from_pretrained(tmpdirname) + model_sdpa = model_sdpa.eval().to(torch_device) + + text_attn = "sdpa" if model.model._supports_sdpa else "eager" + audio_attn = "sdpa" if model.audio_tower._supports_sdpa else "eager" + vision_attn = "sdpa" if model.visual._supports_sdpa else "eager" + # `None` as it is the requested one which will be assigned to each sub-config + # Sub-model will dispatch to SDPA if it can (checked below that `SDPA` layers are present) + self.assertTrue(model_sdpa.config._attn_implementation == "sdpa") + self.assertTrue(model.model.config._attn_implementation == text_attn) + self.assertTrue(model.audio_tower.config._attn_implementation == audio_attn) + self.assertTrue(model.visual.config._attn_implementation == vision_attn) + + model_eager = model_class.from_pretrained(tmpdirname, attn_implementation="eager") + model_eager = model_eager.eval().to(torch_device) + self.assertTrue(model_eager.config._attn_implementation == "eager") + self.assertTrue(model_eager.model.config._attn_implementation == "eager") + self.assertTrue(model_eager.audio_tower.config._attn_implementation == "eager") + self.assertTrue(model_eager.visual.config._attn_implementation == "eager") + + for name, submodule in model_eager.named_modules(): + class_name = submodule.__class__.__name__ + if "SdpaAttention" in class_name or "SdpaSelfAttention" in class_name: + raise ValueError("The eager model should not have SDPA attention layers") + + def attention_mask_padding_matches_padding_free_with_position_ids( + self, attn_implementation: str, fa_kwargs: bool = False + ): + max_new_tokens = 30 + for model_class in self.all_generative_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + dummy_input = inputs_dict[model_class.main_input_name] + if dummy_input.dtype in [torch.float32, torch.float16]: + dummy_input = dummy_input.to(torch.bfloat16) + + # make sure that all models have enough positions for generation + if hasattr(config, "max_position_embeddings"): + config.max_position_embeddings = max_new_tokens + dummy_input.shape[1] + 1 + + model = model_class(config) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + if 0 in inputs_dict["attention_mask"][:, -1]: + inputs_dict["attention_mask"] = inputs_dict["attention_mask"].flip(1) + dummy_attention_mask = inputs_dict["attention_mask"] + inputs_dict["input_ids"][~dummy_attention_mask.bool()] = config.get_text_config().pad_token_id + + model = ( + model_class.from_pretrained( + tmpdirname, + dtype=torch.bfloat16, + attn_implementation=attn_implementation, + ) + .to(torch_device) + .eval() + ) + + # flatten + padfree_inputs_dict = { + "input_features": inputs_dict["input_features"], + "feature_attention_mask": inputs_dict["feature_attention_mask"], + "pixel_values": inputs_dict["pixel_values"], + "image_grid_thw": inputs_dict["image_grid_thw"], + "input_ids": inputs_dict["input_ids"][dummy_attention_mask.bool()].unsqueeze(0), + } + + # add position_ids + vision_position_ids, deltas = model.get_rope_index( + input_ids=inputs_dict["input_ids"], + image_grid_thw=inputs_dict["image_grid_thw"], + attention_mask=inputs_dict["attention_mask"], + audio_seqlens=torch.sum(inputs_dict["feature_attention_mask"], dim=1), + ) # [3, bs, padded-seq-len] + vision_padfree_positions = vision_position_ids[:, dummy_attention_mask.bool()].view( + 3, -1 + ) # [3, bs*padfree-len] + text_padfree_positions = torch.cat( + [torch.arange(length) for length in dummy_attention_mask.sum(1).tolist()] + ) # [1, bs*padfree-len] + text_padfree_positions = text_padfree_positions.long().unsqueeze(0).to(torch_device) + padfree_inputs_dict["position_ids"] = torch.cat([text_padfree_positions, vision_padfree_positions])[ + :, None, : + ] + + if fa_kwargs: + cu_seq_lens = [0] + dummy_attention_mask.sum(1).tolist() + cu_seq_lens = torch.tensor(cu_seq_lens, device=torch_device) + max_length = cu_seq_lens.diff().max().item() + padfree_inputs_dict.update( + { + "cu_seq_lens_q": cu_seq_lens.cumsum(-1).to(dtype=torch.int32), + "cu_seq_lens_k": cu_seq_lens.cumsum(-1).to(dtype=torch.int32), + "max_length_q": max_length, + "max_length_k": max_length, + } + ) + + res_padded = model(**inputs_dict, use_cache=False) + res_padfree = model(**padfree_inputs_dict, use_cache=False) + + logits_padded = res_padded.logits[inputs_dict["attention_mask"].bool()] + logits_padfree = res_padfree.logits[0] + + # acceptable numerical instability + tol = torch.finfo(torch.bfloat16).eps + torch.testing.assert_close(logits_padded, logits_padfree, rtol=tol, atol=tol) + + @unittest.skip("Cannot do contrastive generation, has custom `generate()`") + def test_contrastive_generate(self): + pass + + @unittest.skip("Cannot do contrastive generation, has custom `generate()`") + def test_contrastive_generate_dict_outputs_use_cache(self): + pass + + @unittest.skip("Cannot do contrastive generation, has custom `generate()`") + def test_contrastive_generate_low_memory(self): + pass + + @unittest.skip("Cannot generate from inputs embeds") + def test_generate_from_inputs_embeds_with_static_cache(self): + pass + + # TODO (joao, raushan): there are multiple standardization issues in this model that prevent this test from + # passing, fix me + @unittest.skip("Cannot handle 4D attention mask") + @pytest.mark.torch_compile_test + def test_generate_compile_model_forward_fullgraph(self): + pass + + @unittest.skip( + "There seems to be something wrong with the config, that does not play well with this test. TODO fix me" + ) + def test_save_load(self): + pass + + @unittest.skip("Cannot handle 4D attention mask") + def test_generate_compilation_all_outputs(self): + pass + + @unittest.skip("In a rush to merge, cannot investigate now") + def test_sdpa_padding_matches_padding_free_with_position_ids(self): + pass + + @unittest.skip("Cannot handle 4D attention mask") + def test_generate_with_static_cache(self): + pass + + @unittest.skip("Cannot handle 4D attention mask") + def test_custom_4d_attention_mask(self): + pass + + @unittest.skip("We don't really care about this one, test is not that slow") + def test_model_is_small(self): + pass + + @unittest.skip("FIXME this is important, but in a rush to merge, cannot investigate now") + def test_get_rope_index_video_with_audio(self): + image_grid_thw = torch.empty((0, 3), dtype=torch.long) + + # 3 * 2 * 2 = 12 video tokens + video_grid_thw = torch.tensor([[3, 2, 2]], dtype=torch.long) + + # num_audio_tokens = ((audio_seqlen - 1) // 2 + 1 - 2) // 2 + 1 + # i.e.: 300 audio_seqlen -> 75 audio tokens + audio_seqlens = torch.tensor([300], dtype=torch.long) + + second_per_grids = torch.tensor([1.0], dtype=torch.float) + + use_audio_in_video = True + + # fmt: off + expected_position_ids = torch.tensor([ + [[ + 0, 1, # text + 2, 2, # vision_bos + audio_bos + + # video chunk + 3, 3, 3, 3, + 28, 28, 28, 28, + + # audio chunk + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, + + # video chunk + 53, 53, 53, 53, + + # audio chunk + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + + 78, 78, # audio_eos + vision_eos + 79, 80, # text + ]], + [[ + 0, 1, # text + 2, 2, # vision_bos + audio_bos + + # video chunk + 3, 3, 4, 4, + 3, 3, 4, 4, + + # audio chunk + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, + + # video chunk + 3, 3, 4, 4, + + # audio chunk + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + + 78, 78, # audio_eos + vision_eos + 79, 80, # text + ]], + [[ + 0, 1, # text + 2, 2, # vision_bos + audio_bos + + # video chunk + 3, 4, 3, 4, + 3, 4, 3, 4, + + # audio chunk + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, + + # video chunk + 3, 4, 3, 4, + + # audio chunk + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + + 78, 78, # audio_eos + vision_eos + 79, 80, # text + ]], + ], dtype=torch.long) + # fmt: on + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + input_ids = torch.tensor( + [ + [ + 100, + 101, + ] + + [ + config.vision_start_token_id, + config.audio_start_token_id, + ] + # 1st chunk: 8 video tokens, 50 audio tokens + + [config.video_token_id] * 2 * 2 * 2 + + [config.audio_token_id] * 50 + + + # 2nd chunk: 4 video tokens, 25 audio tokens + [config.video_token_id] * 1 * 2 * 2 + + [config.audio_token_id] * 25 + + [ + config.audio_end_token_id, + config.vision_end_token_id, + ] + + [ + 102, + 103, + ] + ], + dtype=torch.long, + ) + + model = model_class(config) + + position_ids, mrope_position_deltas = model.get_rope_index( + input_ids=input_ids, + image_grid_thw=image_grid_thw, + video_grid_thw=video_grid_thw, + attention_mask=None, + use_audio_in_video=use_audio_in_video, + audio_seqlens=audio_seqlens, + second_per_grids=second_per_grids, + ) + + self.assertTrue(torch.equal(position_ids, expected_position_ids)) + + +@require_torch +class Qwen2_5OmniModelIntegrationTest(unittest.TestCase): + def setUp(self): + self.processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B") + self.audio_url = "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/glass-breaking-151256.mp3" + self.audio_url_additional = ( + "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/f2641_0_throatclearing.wav" + ) + self.image_url = "https://qianwen-res.oss-accelerate-overseas.aliyuncs.com/Qwen2-VL/demo_small.jpg" + self.messages = [ + { + "role": "user", + "content": [ + {"type": "audio", "audio_url": self.audio_url}, + {"type": "image", "image_url": self.image_url}, + {"type": "text", "text": "What's that sound and what kind of dog is this?"}, + ], + } + ] + + self.raw_audio, _ = librosa.load( + BytesIO(urlopen(self.audio_url).read()), sr=self.processor.feature_extractor.sampling_rate + ) + self.raw_audio_additional, _ = librosa.load( + BytesIO(urlopen(self.audio_url_additional).read()), sr=self.processor.feature_extractor.sampling_rate + ) + self.raw_image = Image.open(requests.get(self.image_url, stream=True).raw) + + def tearDown(self): + cleanup(torch_device, gc_collect=True) + + @slow + def test_small_model_integration_test(self): + model = Qwen3OmniMoeForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", dtype=torch.bfloat16, device_map="auto" + ) + + text = self.processor.apply_chat_template(self.messages, tokenize=False, add_generation_prompt=True) + inputs = self.processor( + text=text, audio=[self.raw_audio], images=[self.raw_image], return_tensors="pt", padding=True + ).to(torch.bfloat16) + + expected_input_ids = torch.tensor( + [ + 151644, + 8948, + 198, + 2610, + 525, + 264, + 10950, + 17847, + 13, + 151645, + 198, + 151644, + 872, + 198, + 151647, + 151646, + 151646, + ] + ) + assert torch.allclose(expected_input_ids, inputs.input_ids[0][:17], atol=3e-3) + + expected_pixel_slice = torch.tensor( + [ + [0.8792, 0.8792, 0.9084], + [1.1858, 1.1858, 1.2296], + [1.2004, 1.2004, 1.2150], + [1.4340, 1.4340, 1.4194], + [1.3902, 1.4048, 1.4194], + [1.5216, 1.5362, 1.5362], + ], + dtype=torch.bfloat16, + device="cpu", + ) + assert torch.allclose(expected_pixel_slice, inputs.pixel_values[:6, :3], atol=3e-3) + + # verify generation + inputs = inputs.to(torch_device) + + output = model.generate( + **inputs, thinker_temperature=0, thinker_do_sample=False, return_audio=False, thinker_max_new_tokens=20 + ) + + EXPECTED_DECODED_TEXT = Expectations({ + ("cuda", (8, 6)): "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is glass shattering, and the dog is a Labrador Retriever.", + ("rocm", (9, 4)): "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is glass shattering, and the dog is a Labrador Retriever.", + }).get_expectation() # fmt: skip + + decoded_text = self.processor.decode(output[0], skip_special_tokens=True) + self.assertEqual(decoded_text, EXPECTED_DECODED_TEXT) + + @slow + def test_small_model_integration_test_batch(self): + model = Qwen3OmniMoeForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", dtype=torch.bfloat16, device_map="auto" + ) + text = self.processor.apply_chat_template(self.messages, tokenize=False, add_generation_prompt=True) + inputs = self.processor( + text=[text] * 2, + audio=[self.raw_audio, self.raw_audio], + images=[self.raw_image, self.raw_image], + return_tensors="pt", + padding=True, + ).to(torch_device, dtype=torch.bfloat16) + + output = model.generate( + **inputs, thinker_temperature=0, thinker_do_sample=False, return_audio=False, thinker_max_new_tokens=20 + ) + + EXPECTED_DECODED_TEXTS = Expectations( + { + ("cuda", 7) : [ + "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is of glass shattering, and the dog in the picture is a Labrador Retriever", + "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is of glass shattering, and the dog in the picture is a Labrador Retriever", + ], + ("cuda", 8): [ + "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is glass shattering, and the dog is a Labrador Retriever.", + "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is glass shattering, and the dog is a Labrador Retriever.", + ], + ("rocm", (9, 4)): [ + "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is glass shattering, and the dog is a Labrador Retriever.", + "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is glass shattering, and the dog is a Labrador Retriever.", + ], + } + ).get_expectation() # fmt: skip + + decoded_texts = self.processor.batch_decode(output, skip_special_tokens=True) + self.assertEqual(decoded_texts, EXPECTED_DECODED_TEXTS) + + @slow + def test_small_model_integration_test_multiturn(self): + model = Qwen3OmniMoeForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", dtype=torch.bfloat16, device_map="auto" + ) + + messages = [ + self.messages[0], + { + "role": "assistant", + "content": [ + { + "type": "text", + "text": "The sound is glass shattering, and the dog appears to be a Labrador Retriever.", + } + ], + }, + { + "role": "user", + "content": [ + {"type": "audio", "audio_url": self.audio_url_additional}, + {"type": "text", "text": "How about this one?"}, + ], + }, + ] + + text = self.processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) + inputs = self.processor( + text=text, + audio=[self.raw_audio, self.raw_audio_additional], + images=[self.raw_image], + return_tensors="pt", + padding=True, + ).to(torch_device, dtype=torch.bfloat16) + + output = model.generate( + **inputs, thinker_temperature=0, thinker_do_sample=False, return_audio=False, thinker_max_new_tokens=20 + ) + + EXPECTED_DECODED_TEXT = "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is glass shattering, and the dog appears to be a Labrador Retriever.\nuser\nHow about this one?\nassistant\nThe sound is a cough." + + self.assertEqual( + self.processor.decode(output[0], skip_special_tokens=True), + EXPECTED_DECODED_TEXT, + ) + + @slow + def test_small_model_integration_test_w_audio(self): + model = Qwen3OmniMoeForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", dtype=torch.bfloat16, device_map="auto" + ) + audio_url = "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/guess_age_gender.wav" + + messages = [ + { + "role": "system", + "content": [ + { + "type": "text", + "text": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech.", + } + ], + }, + { + "role": "user", + "content": [{"type": "audio", "audio": audio_url}], + }, + ] + audio, _ = librosa.load(BytesIO(urlopen(audio_url).read()), sr=self.processor.feature_extractor.sampling_rate) + + text = self.processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) + inputs = self.processor(text=text, audio=[audio], return_tensors="pt", padding=True).to( + torch_device, dtype=torch.bfloat16 + ) + + output = model.generate( + **inputs, + thinker_temperature=0, + thinker_do_sample=False, + thinker_max_new_tokens=20, + talker_max_new_tokens=10, + ) + + EXPECTED_DECODED_TEXTS = Expectations( + { + ("cuda", 7): "system\nYou are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech.\nuser\n\nassistant\nWell, I can try. But it's not always that accurate. I might be able to make", + ("cuda", 8): "system\nYou are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech.\nuser\n\nassistant\nWell, I can't really guess your age and gender just from your voice. There are so many", + } + ) # fmt: skip + EXPECTED_DECODED_TEXT = EXPECTED_DECODED_TEXTS.get_expectation() + + self.assertEqual( + self.processor.decode(output[0][0], skip_special_tokens=True), + EXPECTED_DECODED_TEXT, + ) + self.assertFalse(torch.isnan(output[1]).any().item()) + + @slow + @require_flash_attn + @require_torch_gpu + def test_small_model_integration_test_batch_flashatt2(self): + model = Qwen3OmniMoeForConditionalGeneration.from_pretrained( + "Qwen/Qwen2.5-Omni-7B", + dtype=torch.bfloat16, + attn_implementation="flash_attention_2", + device_map="auto", + ) + text = self.processor.apply_chat_template(self.messages, tokenize=False, add_generation_prompt=True) + inputs = self.processor( + text=[text, text], + audio=[self.raw_audio, self.raw_audio], + images=[self.raw_image, self.raw_image], + return_tensors="pt", + padding=True, + ).to(torch_device) + + output = model.generate(**inputs, thinker_temperature=0, thinker_do_sample=False, return_audio=False) + + EXPECTED_DECODED_TEXT = Expectations({ + ("cuda", None): "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is glass shattering, and the dog appears to be a Labrador Retriever.", + ("cuda", (8, 6)): "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is glass shattering, and the dog is a Labrador Retriever.", + ("rocm", (9, 4)): "system\nYou are a helpful assistant.\nuser\nWhat's that sound and what kind of dog is this?\nassistant\nThe sound is glass shattering, and the dog is a Labrador Retriever.", + }).get_expectation() # fmt: skip + + decoded_texts = self.processor.batch_decode(output, skip_special_tokens=True) + self.assertEqual(decoded_texts[0], EXPECTED_DECODED_TEXT) + self.assertEqual(decoded_texts[1], EXPECTED_DECODED_TEXT) diff --git a/tests/models/qwen3_omni_moe/test_processing_qwen3_omni_moe.py b/tests/models/qwen3_omni_moe/test_processing_qwen3_omni_moe.py new file mode 100644 index 000000000000..baaf22bd7831 --- /dev/null +++ b/tests/models/qwen3_omni_moe/test_processing_qwen3_omni_moe.py @@ -0,0 +1,602 @@ +# coding=utf-8 +# Copyright 2025 The Qwen team, Alibaba Group and the HuggingFace Inc. team. All rights reserved. +# +# +# 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. +import inspect +import shutil +import tempfile +import unittest + +import numpy as np +import pytest +from huggingface_hub import hf_hub_download +from parameterized import parameterized + +from transformers import ( + AutoProcessor, + Qwen2TokenizerFast, + Qwen3OmniMoeProcessor, + WhisperFeatureExtractor, +) +from transformers.testing_utils import ( + require_av, + require_librosa, + require_torch, + require_torchaudio, + require_torchvision, + require_vision, +) +from transformers.utils import is_torch_available, is_vision_available + +from ...test_processing_common import ProcessorTesterMixin, url_to_local_path + + +if is_torch_available(): + import torch + +if is_vision_available(): + from transformers import Qwen2VLImageProcessorFast + + +@require_vision +@require_torch +@require_torchaudio +@require_torchvision +class Qwen3OmniMoeProcessorTest(ProcessorTesterMixin, unittest.TestCase): + processor_class = Qwen3OmniMoeProcessor + + # text + audio kwargs testing + @require_torch + def test_tokenizer_defaults_preserved_by_kwargs_audio(self): + if "feature_extractor" not in self.processor_class.attributes: + self.skipTest(f"feature_extractor attribute not present in {self.processor_class}") + feature_extractor = self.get_component("feature_extractor") + if hasattr(self, "get_tokenizer"): + tokenizer = self.get_tokenizer(max_length=800, padding="max_length") + elif hasattr(self, "get_component"): + tokenizer = self.get_component("tokenizer", max_length=800, padding="max_length") + else: + self.assertTrue(False, "Processor doesn't have get_tokenizer or get_component defined") + if not tokenizer.pad_token: + tokenizer.pad_token = "[TEST_PAD]" + if "image_processor" not in self.processor_class.attributes: + self.skipTest(f"image_processor attribute not present in {self.processor_class}") + image_processor = self.get_component("image_processor") + video_processor = self.get_component("video_processor") + processor = self.processor_class( + tokenizer=tokenizer, + video_processor=video_processor, + feature_extractor=feature_extractor, + image_processor=image_processor, + ) + self.skip_processor_without_typed_kwargs(processor) + input_str = "lower newer" + raw_speech = self.prepare_audio_inputs() + inputs = processor(text=input_str, audio=raw_speech, return_tensors="pt") + if "input_ids" in inputs: + self.assertEqual(len(inputs["input_ids"][0]), 800) + elif "labels" in inputs: + self.assertEqual(len(inputs["labels"][0]), 800) + + @require_torch + @require_vision + def test_structured_kwargs_audio_nested(self): + if "feature_extractor" not in self.processor_class.attributes: + self.skipTest(f"feature_extractor attribute not present in {self.processor_class}") + feature_extractor = self.get_component("feature_extractor") + if hasattr(self, "get_tokenizer"): + tokenizer = self.get_tokenizer() + elif hasattr(self, "get_component"): + tokenizer = self.get_component("tokenizer") + if not tokenizer.pad_token: + tokenizer.pad_token = "[TEST_PAD]" + if "image_processor" not in self.processor_class.attributes: + self.skipTest(f"image_processor attribute not present in {self.processor_class}") + image_processor = self.get_component("image_processor") + video_processor = self.get_component("video_processor") + processor = self.processor_class( + tokenizer=tokenizer, + video_processor=video_processor, + feature_extractor=feature_extractor, + image_processor=image_processor, + ) + self.skip_processor_without_typed_kwargs(processor) + + input_str = ["lower newer"] + raw_speech = self.prepare_audio_inputs() + + # Define the kwargs for each modality + all_kwargs = { + "common_kwargs": {"return_tensors": "pt"}, + "audio_kwargs": {"max_length": 800}, + } + + inputs = processor(text=input_str, audio=raw_speech, **all_kwargs) + if "input_ids" in inputs: + self.assertEqual(len(inputs["input_ids"][0]), 2) + elif "labels" in inputs: + self.assertEqual(len(inputs["labels"][0]), 2) + + @require_torch + def test_unstructured_kwargs_audio(self): + if "feature_extractor" not in self.processor_class.attributes: + self.skipTest(f"feature_extractor attribute not present in {self.processor_class}") + feature_extractor = self.get_component("feature_extractor") + if hasattr(self, "get_tokenizer"): + tokenizer = self.get_tokenizer(max_length=117) + elif hasattr(self, "get_component"): + tokenizer = self.get_component("tokenizer", max_length=117) + if not tokenizer.pad_token: + tokenizer.pad_token = "[TEST_PAD]" + if "image_processor" not in self.processor_class.attributes: + self.skipTest(f"image_processor attribute not present in {self.processor_class}") + image_processor = self.get_component("image_processor") + video_processor = self.get_component("video_processor") + processor = self.processor_class( + tokenizer=tokenizer, + video_processor=video_processor, + feature_extractor=feature_extractor, + image_processor=image_processor, + ) + self.skip_processor_without_typed_kwargs(processor) + + input_str = "lower newer" + raw_speech = self.prepare_audio_inputs() + inputs = processor( + text=input_str, + audio=raw_speech, + return_tensors="pt", + padding="max_length", + max_length=800, + ) + + if "input_ids" in inputs: + self.assertEqual(len(inputs["input_ids"][0]), 800) + elif "labels" in inputs: + self.assertEqual(len(inputs["labels"][0]), 800) + + @require_torch + def test_doubly_passed_kwargs_audio(self): + if "feature_extractor" not in self.processor_class.attributes: + self.skipTest(f"feature_extractor attribute not present in {self.processor_class}") + feature_extractor = self.get_component("feature_extractor") + if hasattr(self, "get_tokenizer"): + tokenizer = self.get_tokenizer() + elif hasattr(self, "get_component"): + tokenizer = self.get_component("tokenizer") + if not tokenizer.pad_token: + tokenizer.pad_token = "[TEST_PAD]" + if "image_processor" not in self.processor_class.attributes: + self.skipTest(f"image_processor attribute not present in {self.processor_class}") + image_processor = self.get_component("image_processor") + video_processor = self.get_component("video_processor") + _ = self.processor_class( + tokenizer=tokenizer, + video_processor=video_processor, + feature_extractor=feature_extractor, + image_processor=image_processor, + ) # Why delete test? TODO: raushan double check tests after cleaning model + + @require_torch + def test_kwargs_overrides_default_tokenizer_kwargs_audio(self): + if "feature_extractor" not in self.processor_class.attributes: + self.skipTest(f"feature_extractor attribute not present in {self.processor_class}") + feature_extractor = self.get_component("feature_extractor") + if hasattr(self, "get_tokenizer"): + tokenizer = self.get_tokenizer(max_length=117) + elif hasattr(self, "get_component"): + tokenizer = self.get_component("tokenizer", max_length=117) + if not tokenizer.pad_token: + tokenizer.pad_token = "[TEST_PAD]" + if "image_processor" not in self.processor_class.attributes: + self.skipTest(f"image_processor attribute not present in {self.processor_class}") + image_processor = self.get_component("image_processor") + video_processor = self.get_component("video_processor") + _ = self.processor_class( + tokenizer=tokenizer, + video_processor=video_processor, + feature_extractor=feature_extractor, + image_processor=image_processor, + ) + + @classmethod + def setUpClass(cls): + cls.tmpdirname = tempfile.mkdtemp() + processor = Qwen3OmniMoeProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B") + processor.save_pretrained(cls.tmpdirname) + + def get_tokenizer(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs).tokenizer + + def get_image_processor(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs).image_processor + + def get_video_processor(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs).video_processor + + def get_feature_extractor(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs).feature_extractor + + def get_processor(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs) + + @classmethod + def tearDownClass(cls): + shutil.rmtree(cls.tmpdirname, ignore_errors=True) + + def prepare_audio_inputs(self): + """This function prepares a list of numpy audios.""" + audio_inputs = [np.random.rand(160000) * 2 - 1] * 3 # batch-size=3 + return audio_inputs + + def test_save_load_pretrained_default(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + feature_extractor = self.get_feature_extractor() + video_processor = self.get_video_processor() + processor = self.processor_class( + tokenizer=tokenizer, + video_processor=video_processor, + feature_extractor=feature_extractor, + image_processor=image_processor, + ) + + processor.save_pretrained(self.tmpdirname) + processor = Qwen3OmniMoeProcessor.from_pretrained(self.tmpdirname, use_fast=True) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer.get_vocab()) + self.assertEqual(processor.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor.to_json_string()) + self.assertIsInstance(processor.tokenizer, Qwen2TokenizerFast) + self.assertIsInstance(processor.image_processor, Qwen2VLImageProcessorFast) + self.assertIsInstance(processor.feature_extractor, WhisperFeatureExtractor) + + def test_image_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + feature_extractor = self.get_feature_extractor() + video_processor = self.get_video_processor() + processor = self.processor_class( + tokenizer=tokenizer, + video_processor=video_processor, + feature_extractor=feature_extractor, + image_processor=image_processor, + ) + + image_input = self.prepare_image_inputs() + + input_image_proc = image_processor(image_input, return_tensors="pt") + input_processor = processor(images=image_input, text="dummy", return_tensors="pt") + + for key in input_image_proc: + self.assertAlmostEqual(input_image_proc[key].sum(), input_processor[key].sum(), delta=1e-2) + + def test_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + feature_extractor = self.get_feature_extractor() + video_processor = self.get_video_processor() + processor = self.processor_class( + tokenizer=tokenizer, + video_processor=video_processor, + feature_extractor=feature_extractor, + image_processor=image_processor, + ) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + audio_input = self.prepare_audio_inputs() + inputs = processor(text=input_str, images=image_input, audio=audio_input) + keys = list(inputs.keys()) + self.assertListEqual( + keys, + [ + "input_ids", + "attention_mask", + "pixel_values", + "image_grid_thw", + "feature_attention_mask", + "input_features", + ], + ) + + # test if it raises when no input is passed + with pytest.raises(ValueError): + processor() + + # test if it raises when no text is passed + with pytest.raises(ValueError): + processor(images=image_input) + + @require_torch + def _test_apply_chat_template( + self, + modality: str, + batch_size: int, + return_tensors: str, + input_name: str, + processor_name: str, + input_data: list[str], + ): + processor = self.get_processor() + if processor.chat_template is None: + self.skipTest("Processor has no chat template") + + if processor_name not in self.processor_class.attributes: + self.skipTest(f"{processor_name} attribute not present in {self.processor_class}") + + batch_messages = [ + [ + { + "role": "user", + "content": [{"type": "text", "text": "Describe this."}], + }, + ] + ] * batch_size + + # Test that jinja can be applied + formatted_prompt = processor.apply_chat_template(batch_messages, add_generation_prompt=True, tokenize=False) + self.assertEqual(len(formatted_prompt), batch_size) + + # Test that tokenizing with template and directly with `self.tokenizer` gives same output + formatted_prompt_tokenized = processor.apply_chat_template( + batch_messages, add_generation_prompt=True, tokenize=True, return_tensors=return_tensors + ) + add_special_tokens = True + if processor.tokenizer.bos_token is not None and formatted_prompt[0].startswith(processor.tokenizer.bos_token): + add_special_tokens = False + tok_output = processor.tokenizer( + formatted_prompt, return_tensors=return_tensors, add_special_tokens=add_special_tokens + ) + expected_output = tok_output.input_ids + self.assertListEqual(expected_output.tolist(), formatted_prompt_tokenized.tolist()) + + # Test that kwargs passed to processor's `__call__` are actually used + tokenized_prompt_100 = processor.apply_chat_template( + batch_messages, + add_generation_prompt=True, + tokenize=True, + padding="max_length", + truncation=True, + return_tensors=return_tensors, + max_length=100, + ) + self.assertEqual(len(tokenized_prompt_100[0]), 100) + + # Test that `return_dict=True` returns text related inputs in the dict + out_dict_text = processor.apply_chat_template( + batch_messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors=return_tensors, + ) + self.assertTrue(all(key in out_dict_text for key in ["input_ids", "attention_mask"])) + self.assertEqual(len(out_dict_text["input_ids"]), batch_size) + self.assertEqual(len(out_dict_text["attention_mask"]), batch_size) + + # Test that with modality URLs and `return_dict=True`, we get modality inputs in the dict + for idx, url in enumerate(input_data[:batch_size]): + batch_messages[idx][0]["content"] = [batch_messages[idx][0]["content"][0], {"type": modality, "url": url}] + + out_dict = processor.apply_chat_template( + batch_messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors=return_tensors, + num_frames=2, # by default no more than 2 frames, otherwise too slow + ) + input_name = getattr(self, input_name) + self.assertTrue(input_name in out_dict) + self.assertEqual(len(out_dict["input_ids"]), batch_size) + self.assertEqual(len(out_dict["attention_mask"]), batch_size) + + if modality == "video": + # qwen pixels don't scale with bs same way as other models, calculate expected video token count based on video_grid_thw + expected_video_token_count = 0 + for thw in out_dict["video_grid_thw"]: + expected_video_token_count += thw[0] * thw[1] * thw[2] + mm_len = expected_video_token_count + elif modality == "audio": + mm_len = batch_size + else: + mm_len = batch_size * 1200 + self.assertEqual(len(out_dict[input_name]), mm_len) + + return_tensor_to_type = {"pt": torch.Tensor, "np": np.ndarray, None: list} + for k in out_dict: + self.assertIsInstance(out_dict[k], return_tensor_to_type[return_tensors]) + + @unittest.skip("Skipping but this one is important, should be fixed ASAP") + @parameterized.expand([(1, "pt"), (2, "pt")]) + def test_apply_chat_template_image(self, batch_size: int, return_tensors: str): + pass + + @require_av + def test_apply_chat_template_video_frame_sampling(self): + processor = self.get_processor() + if processor.chat_template is None: + self.skipTest("Processor has no chat template") + + signature = inspect.signature(processor.__call__) + if "videos" not in {*signature.parameters.keys()} or ( + signature.parameters.get("videos") is not None + and signature.parameters["videos"].annotation == inspect._empty + ): + self.skipTest("Processor doesn't accept videos at input") + + messages = [ + [ + { + "role": "user", + "content": [ + {"type": "text", "text": "What is shown in this video?"}, + ], + }, + ] + ] + + formatted_prompt = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=False) + self.assertEqual(len(formatted_prompt), 1) + + formatted_prompt_tokenized = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=True) + expected_output = processor.tokenizer(formatted_prompt, return_tensors=None).input_ids + self.assertListEqual(expected_output, formatted_prompt_tokenized) + + out_dict = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=True, return_dict=True) + self.assertListEqual(list(out_dict.keys()), ["input_ids", "attention_mask"]) + + # Add video URL for return dict and load with `num_frames` arg + messages[0][0]["content"].append( + { + "type": "video", + "url": url_to_local_path( + "https://huggingface.co/datasets/raushan-testing-hf/videos-test/resolve/main/Big_Buck_Bunny_720_10s_10MB.mp4" + ), + } + ) + num_frames = 3 + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + num_frames=num_frames, + ) + self.assertTrue(self.videos_input_name in out_dict_with_video) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 9568) + + # Load with `fps` arg + fps = 1 + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + fps=fps, + ) + self.assertTrue(self.videos_input_name in out_dict_with_video) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 23920) + + # Load with `fps` and `num_frames` args, should raise an error + with self.assertRaises(ValueError): + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + fps=fps, + num_frames=num_frames, + ) + + # Load without any arg should load the whole video + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + ) + self.assertTrue(self.videos_input_name in out_dict_with_video) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 717600) + + # Load video as a list of frames (i.e. images). NOTE: each frame should have same size + # because we assume they come from one video + messages[0][0]["content"][-1] = { + "type": "video", + "url": [ + "https://www.ilankelman.org/stopsigns/australia.jpg", + "https://www.ilankelman.org/stopsigns/australia.jpg", + ], + } + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + ) + self.assertTrue(self.videos_input_name in out_dict_with_video) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 11408) + + # When the inputs are frame URLs/paths we expect that those are already + # sampled and will raise an error is asked to sample again. + with self.assertRaises(ValueError): + out_dict_with_video = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + do_sample_frames=True, + num_frames=num_frames, + ) + + @require_librosa + @require_av + def test_chat_template_audio_from_video(self): + processor = self.get_processor() + if processor.chat_template is None: + self.skipTest("Processor has no chat template") + + signature = inspect.signature(processor.__call__) + if "videos" not in {*signature.parameters.keys()} or ( + signature.parameters.get("videos") is not None + and signature.parameters["videos"].annotation == inspect._empty + ): + self.skipTest(f"{self.processor_class} does not support video inputs") + + if "feature_extractor" not in self.processor_class.attributes: + self.skipTest(f"feature_extractor attribute not present in {self.processor_class}") + + video_file_path = hf_hub_download( + repo_id="raushan-testing-hf/videos-test", filename="sample_demo_1.mp4", repo_type="dataset" + ) + messages = [ + { + "role": "user", + "content": [ + {"type": "video", "path": video_file_path}, + {"type": "text", "text": "Which of these animals is making the sound?"}, + ], + }, + { + "role": "assistant", + "content": [{"type": "text", "text": "It is a cow."}], + }, + { + "role": "user", + "content": [ + {"type": "text", "text": "Tell me all about this animal."}, + ], + }, + ] + + formatted_prompt = processor.apply_chat_template([messages], add_generation_prompt=True, tokenize=False) + self.assertEqual(len(formatted_prompt), 1) # batch size=1 + + out_dict = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", + load_audio_from_video=True, + ) + self.assertTrue(self.audio_input_name in out_dict) + self.assertTrue(self.videos_input_name in out_dict) + + # should always have input_ids and attention_mask + self.assertEqual(len(out_dict["input_ids"]), 1) # batch-size=1 + self.assertEqual(len(out_dict["attention_mask"]), 1) # batch-size=1 + self.assertEqual(len(out_dict[self.audio_input_name]), 1) # 1 audio in the conversation + self.assertEqual(len(out_dict[self.videos_input_name]), 145912) # 1 video in the conversation diff --git a/tests/test_modeling_common.py b/tests/test_modeling_common.py index 1a12f9e4608e..d0b967578732 100755 --- a/tests/test_modeling_common.py +++ b/tests/test_modeling_common.py @@ -688,6 +688,7 @@ def test_num_layers_is_small(self): "Owlv2ModelTest": 12, "Owlv2TextModelTest": 12, "Owlv2ForObjectDetectionTest": 12, + "Qwen2_5OmniThinkerForConditionalGenerationModelTest": 4, "SamHQModelTest": 12, "Swin2SRModelTest": 3, "XLNetModelTest": 3, diff --git a/utils/check_docstrings.py b/utils/check_docstrings.py index 37bc980e745c..eff3f6865925 100644 --- a/utils/check_docstrings.py +++ b/utils/check_docstrings.py @@ -81,6 +81,7 @@ OBJECTS_TO_IGNORE = { "ApertusConfig", "Mxfp4Config", + "Qwen3OmniMoeConfig", "Exaone4Config", "SmolLM3Config", "Gemma3nVisionConfig", diff --git a/utils/check_repo.py b/utils/check_repo.py index 29bd3dfc3586..207be57f1b62 100644 --- a/utils/check_repo.py +++ b/utils/check_repo.py @@ -157,6 +157,16 @@ "Qwen2_5OmniToken2WavModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntergrationTest. "Qwen2_5OmniToken2WavDiTModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntergrationTest. "Qwen2_5OmniToken2WavBigVGANModel", # Building part of bigger (tested) model. Tested implicitly through Qwen2_5OmniModelIntergrationTest. + "Qwen3OmniMoeCode2Wav", # Building part of bigger (tested) model. Tested implicitly through Qwen3OmniMoeForConditionalGenerationIntegrationTest. + "Qwen3OmniMoeCode2WavDecoderBlock", + "Qwen3OmniMoeText2Wav", # Building part of bigger (tested) model. Tested implicitly through Qwen3OmniMoeForConditionalGenerationIntegrationTest. + "Qwen3OmniMoeTalkerCodePredictorModel", # Building part of bigger (tested) model. Tested implicitly through Qwen3OmniMoeForConditionalGenerationIntegrationTest. + "Qwen3OmniMoeCode2WavTransformerModel", + "Qwen3OmniMoeTalkerForConditionalGeneration", + "Qwen3OmniMoeTalkerModel", + "Qwen3OmniMoeThinkerTextModel", + "Qwen3OmniMoeForConditionalGeneration", # Bigger model tested through Qwen3OmniMoeForConditionalGenerationIntegrationTest. + "Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration", # Building part of bigger (tested) model. Tested implicitly through Qwen3OmniMoeForConditionalGenerationIntegrationTest. "MllamaTextModel", # Building part of bigger (tested) model. # TODO: add tests "MllamaVisionModel", # Building part of bigger (tested) model. # TODO: add tests "Llama4TextModel", # Building part of bigger (tested) model. # TODO: add tests @@ -369,6 +379,14 @@ "CsmForConditionalGeneration", # Building part of a bigger model "BltPatcher", # Building part of a bigger model, tested implicitly through BltForCausalLM "Florence2VisionBackbone", # Building part of a bigger model + "Qwen3OmniMoeCode2Wav", # Building part of a bigger model + "Qwen3OmniMoeCode2WavTransformerModel", # Building part of a bigger model + "Qwen3OmniMoeTalkerCodePredictorModel", # Building part of a bigger model + "Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration", # Building part of a bigger model + "Qwen3OmniMoeTalkerForConditionalGeneration", # Building part of a bigger model + "Qwen3OmniMoeTalkerModel", # Building part of a bigger model + "Qwen3OmniMoeThinkerForConditionalGeneration", # Building part of a bigger model + "Qwen3OmniMoeThinkerTextModel", # Building part of a bigger model ] From 2f2d1935489c8f85bce4b537101fd1657bc2fd82 Mon Sep 17 00:00:00 2001 From: Ayush Date: Mon, 22 Sep 2025 15:17:34 +0530 Subject: [PATCH 135/204] Making compute_loss_func always take priority in Trainer (#40632) * logger warn, if-else logic improved * redundant if condition fix --- src/transformers/trainer.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/transformers/trainer.py b/src/transformers/trainer.py index 24e1730608d2..272f69610a97 100755 --- a/src/transformers/trainer.py +++ b/src/transformers/trainer.py @@ -4115,16 +4115,27 @@ def compute_loss( if self.args.past_index >= 0: self._past = outputs[self.args.past_index] - if labels is not None: + # User-defined compute_loss function + if self.compute_loss_func is not None: + if labels is None: + logger.warning( + "Trainer: `compute_loss_func` is defined but `labels=None`. " + "Your custom loss function will still be called with labels=None. " + ) + loss = self.compute_loss_func( + outputs, + labels, + num_items_in_batch=num_items_in_batch, + ) + # Default HF loss handling (label smoothing) if no custom loss function + elif labels is not None: unwrapped_model = self.accelerator.unwrap_model(model) - if _is_peft_model(unwrapped_model): - model_name = unwrapped_model.base_model.model._get_name() - else: - model_name = unwrapped_model._get_name() - # User-defined compute_loss function - if self.compute_loss_func is not None: - loss = self.compute_loss_func(outputs, labels, num_items_in_batch=num_items_in_batch) - elif model_name in MODEL_FOR_CAUSAL_LM_MAPPING_NAMES.values(): + model_name = ( + unwrapped_model.base_model.model._get_name() + if _is_peft_model(unwrapped_model) + else unwrapped_model._get_name() + ) + if model_name in MODEL_FOR_CAUSAL_LM_MAPPING_NAMES.values(): loss = self.label_smoother(outputs, labels, shift_labels=True) else: loss = self.label_smoother(outputs, labels) From 21031f59c0cfbbe9fad74f65594a668d056aedb0 Mon Sep 17 00:00:00 2001 From: BakerBunker <17872844+BakerBunker@users.noreply.github.com> Date: Mon, 22 Sep 2025 05:06:59 -0500 Subject: [PATCH 136/204] Modify Qwen3Omni parameter name since VL changed it (#41045) Modify parameter name since VL changed it Co-authored-by: lvyuanjun.lyj --- .../models/qwen3_omni_moe/modeling_qwen3_omni_moe.py | 7 +++---- .../models/qwen3_omni_moe/modular_qwen3_omni_moe.py | 6 +++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py b/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py index 2ddc4d656530..1172ebf90919 100644 --- a/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py +++ b/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py @@ -1722,9 +1722,8 @@ def forward( past_key_values=past_key_values, ) - def _deepstack_process( - self, hidden_states: torch.Tensor, visual_pos_masks: torch.Tensor, visual_embeds: torch.Tensor - ): + def _deepstack_process(self, hidden_states, visual_pos_masks, visual_embeds): + visual_pos_masks = visual_pos_masks[..., 0] visual_pos_masks = visual_pos_masks.to(hidden_states.device) visual_embeds = visual_embeds.to(hidden_states.device, hidden_states.dtype) local_this = hidden_states[visual_pos_masks, :].clone() + visual_embeds @@ -2151,7 +2150,7 @@ def forward( use_cache=use_cache, output_router_logits=output_router_logits, cache_position=cache_position, - deepstack_visual_embeds_multiscale=visual_embeds_multiscale, + deepstack_visual_embeds=visual_embeds_multiscale, visual_pos_masks=visual_pos_masks, **kwargs, ) diff --git a/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py b/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py index 8a7ba792f846..4d1c30f0a4c3 100644 --- a/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py +++ b/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py @@ -1228,6 +1228,10 @@ def __init__(self, config: Qwen3OmniMoeTextConfig): ) self.rotary_emb = Qwen3OmniMoeThinkerTextRotaryEmbedding(config) + def _deepstack_process(self, hidden_states, visual_pos_masks, visual_embeds): + visual_pos_masks = visual_pos_masks[..., 0] + return super()._deepstack_process(hidden_states, visual_pos_masks, visual_embeds) + @dataclass class Qwen3OmniMoeThinkerCausalLMOutputWithPast(MoeCausalLMOutputWithPast): @@ -1408,7 +1412,7 @@ def forward( use_cache=use_cache, output_router_logits=output_router_logits, cache_position=cache_position, - deepstack_visual_embeds_multiscale=visual_embeds_multiscale, + deepstack_visual_embeds=visual_embeds_multiscale, visual_pos_masks=visual_pos_masks, **kwargs, ) From 17f5a926d61758c2e08a15ffa9eeb3def5db859d Mon Sep 17 00:00:00 2001 From: Raushan Turganbay Date: Mon, 22 Sep 2025 12:28:11 +0200 Subject: [PATCH 137/204] Fix Qwen video tests (#41049) fix test --- .../models/qwen2_5_omni/processing_qwen2_5_omni.py | 6 ++++-- .../models/qwen2_vl/video_processing_qwen2_vl.py | 8 ++------ .../models/qwen3_omni_moe/modular_qwen3_omni_moe.py | 4 ++-- .../qwen3_omni_moe/processing_qwen3_omni_moe.py | 4 ++-- tests/models/internvl/test_processing_internvl.py | 4 ++-- .../qwen2_5_omni/test_processing_qwen2_5_omni.py | 2 ++ .../qwen2_vl/test_video_processing_qwen2_vl.py | 9 --------- .../qwen3_omni_moe/test_processing_qwen3_omni_moe.py | 12 +++++++----- tests/models/qwen3_vl/test_processing_qwen3_vl.py | 2 +- 9 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/transformers/models/qwen2_5_omni/processing_qwen2_5_omni.py b/src/transformers/models/qwen2_5_omni/processing_qwen2_5_omni.py index 3d9d5f1066ef..5fcbb0c535f9 100644 --- a/src/transformers/models/qwen2_5_omni/processing_qwen2_5_omni.py +++ b/src/transformers/models/qwen2_5_omni/processing_qwen2_5_omni.py @@ -62,8 +62,10 @@ class Qwen2_5OmniProcessorKwargs(ProcessingKwargs, total=False): "seconds_per_chunk": 2.0, "position_id_per_seconds": 25, "use_audio_in_video": False, - "min_pixels": 128 * 28 * 28, - "max_pixels": 768 * 28 * 28, + "size": { + "shortest_edge": 128 * 28 * 28, + "longest_edge": 768 * 28 * 28, + }, }, "audio_kwargs": { "sampling_rate": 16000, diff --git a/src/transformers/models/qwen2_vl/video_processing_qwen2_vl.py b/src/transformers/models/qwen2_vl/video_processing_qwen2_vl.py index ba87909740a8..3fb020443f35 100644 --- a/src/transformers/models/qwen2_vl/video_processing_qwen2_vl.py +++ b/src/transformers/models/qwen2_vl/video_processing_qwen2_vl.py @@ -186,7 +186,6 @@ def sample_frames( def _preprocess( self, videos: list["torch.Tensor"], - do_convert_rgb: bool, do_resize: bool, size: SizeDict, interpolation: Optional["F.InterpolationMode"], @@ -195,13 +194,10 @@ def _preprocess( do_normalize: bool, image_mean: Optional[Union[float, list[float]]], image_std: Optional[Union[float, list[float]]], - min_pixels: Optional[int] = None, - max_pixels: Optional[int] = None, patch_size: Optional[int] = None, temporal_patch_size: Optional[int] = None, merge_size: Optional[int] = None, return_tensors: Optional[Union[str, TensorType]] = None, - device: Optional["torch.Tensor"] = None, **kwargs, ): # Group videos by size for batched resizing @@ -215,8 +211,8 @@ def _preprocess( height, width, factor=patch_size * merge_size, - min_pixels=min_pixels, - max_pixels=max_pixels, + min_pixels=size["shortest_edge"], + max_pixels=size["longest_edge"], ) stacked_videos = self.resize( image=stacked_videos, diff --git a/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py b/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py index 4d1c30f0a4c3..28347f03a6aa 100644 --- a/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py +++ b/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py @@ -2717,7 +2717,7 @@ def __call__( audio_lengths = iter([]) if images is not None: - images_inputs = self.image_processor(images=images, videos=None, **output_kwargs["images_kwargs"]) + images_inputs = self.image_processor(images=images, **output_kwargs["images_kwargs"]) image_grid_thw = iter(images_inputs["image_grid_thw"]) else: images_inputs = {} @@ -2725,7 +2725,7 @@ def __call__( if videos is not None: videos = make_batched_videos(videos) - videos_inputs = self.video_processor(images=None, videos=videos, **output_kwargs["videos_kwargs"]) + videos_inputs = self.video_processor(videos=videos, **output_kwargs["videos_kwargs"]) fps = [fps] * len(videos) videos_inputs["video_second_per_grid"] = [ self.video_processor.temporal_patch_size / fps[i] for i in range(len(fps)) diff --git a/src/transformers/models/qwen3_omni_moe/processing_qwen3_omni_moe.py b/src/transformers/models/qwen3_omni_moe/processing_qwen3_omni_moe.py index f0506bf6930b..86041fc3de16 100644 --- a/src/transformers/models/qwen3_omni_moe/processing_qwen3_omni_moe.py +++ b/src/transformers/models/qwen3_omni_moe/processing_qwen3_omni_moe.py @@ -186,7 +186,7 @@ def __call__( audio_lengths = iter([]) if images is not None: - images_inputs = self.image_processor(images=images, videos=None, **output_kwargs["images_kwargs"]) + images_inputs = self.image_processor(images=images, **output_kwargs["images_kwargs"]) image_grid_thw = iter(images_inputs["image_grid_thw"]) else: images_inputs = {} @@ -194,7 +194,7 @@ def __call__( if videos is not None: videos = make_batched_videos(videos) - videos_inputs = self.video_processor(images=None, videos=videos, **output_kwargs["videos_kwargs"]) + videos_inputs = self.video_processor(videos=videos, **output_kwargs["videos_kwargs"]) fps = [fps] * len(videos) videos_inputs["video_second_per_grid"] = [ self.video_processor.temporal_patch_size / fps[i] for i in range(len(fps)) diff --git a/tests/models/internvl/test_processing_internvl.py b/tests/models/internvl/test_processing_internvl.py index 76e91a50d3ed..6a510c89aafa 100644 --- a/tests/models/internvl/test_processing_internvl.py +++ b/tests/models/internvl/test_processing_internvl.py @@ -219,7 +219,7 @@ def test_apply_chat_template_video_frame_sampling(self): { "type": "video", "url": url_to_local_path( - "https://huggingface.co/datasets/raushan-testing-hf/videos-test/resolve/main/Big_Buck_Bunny_720_10s_10MB.mp4" + "https://huggingface.co/datasets/raushan-testing-hf/videos-test/resolve/main/tiny_video.mp4" ), }, {"type": "text", "text": "What is shown in this video?"}, @@ -251,7 +251,7 @@ def test_apply_chat_template_video_frame_sampling(self): return_tensors="pt", ) self.assertTrue(self.videos_input_name in out_dict_with_video) - self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 300) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 11) # Load video as a list of frames (i.e. images). NOTE: each frame should have same size # because we assume they come from one video diff --git a/tests/models/qwen2_5_omni/test_processing_qwen2_5_omni.py b/tests/models/qwen2_5_omni/test_processing_qwen2_5_omni.py index a75ce0c3bbda..c988e2d72917 100644 --- a/tests/models/qwen2_5_omni/test_processing_qwen2_5_omni.py +++ b/tests/models/qwen2_5_omni/test_processing_qwen2_5_omni.py @@ -213,6 +213,8 @@ def test_kwargs_overrides_default_tokenizer_kwargs_audio(self): def setUpClass(cls): cls.tmpdirname = tempfile.mkdtemp() processor = Qwen2_5OmniProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B") + processor.image_processor.size = {"shortest_edge": 28 * 28, "longest_edge": 56 * 56} + processor.video_processor.size = {"shortest_edge": 28 * 28, "longest_edge": 56 * 56} processor.save_pretrained(cls.tmpdirname) def get_tokenizer(self, **kwargs): diff --git a/tests/models/qwen2_vl/test_video_processing_qwen2_vl.py b/tests/models/qwen2_vl/test_video_processing_qwen2_vl.py index a9e800734712..4d6026a06289 100644 --- a/tests/models/qwen2_vl/test_video_processing_qwen2_vl.py +++ b/tests/models/qwen2_vl/test_video_processing_qwen2_vl.py @@ -48,8 +48,6 @@ def __init__( max_resolution=80, do_resize=True, size=None, - do_center_crop=True, - crop_size=None, do_normalize=True, image_mean=OPENAI_CLIP_MEAN, image_std=OPENAI_CLIP_STD, @@ -61,7 +59,6 @@ def __init__( merge_size=2, ): size = size if size is not None else {"shortest_edge": 20} - crop_size = crop_size if crop_size is not None else {"height": 18, "width": 18} self.parent = parent self.batch_size = batch_size self.num_frames = num_frames @@ -70,8 +67,6 @@ def __init__( self.max_resolution = max_resolution self.do_resize = do_resize self.size = size - self.do_center_crop = do_center_crop - self.crop_size = crop_size self.do_normalize = do_normalize self.image_mean = image_mean self.image_std = image_std @@ -85,8 +80,6 @@ def __init__( def prepare_video_processor_dict(self): return { "do_resize": self.do_resize, - "do_center_crop": self.do_center_crop, - "crop_size": self.crop_size, "do_normalize": self.do_normalize, "image_mean": self.image_mean, "image_std": self.image_std, @@ -149,8 +142,6 @@ def test_video_processor_properties(self): video_processing = self.fast_video_processing_class(**self.video_processor_dict) self.assertTrue(hasattr(video_processing, "do_resize")) self.assertTrue(hasattr(video_processing, "size")) - self.assertTrue(hasattr(video_processing, "do_center_crop")) - self.assertTrue(hasattr(video_processing, "center_crop")) self.assertTrue(hasattr(video_processing, "do_normalize")) self.assertTrue(hasattr(video_processing, "image_mean")) self.assertTrue(hasattr(video_processing, "image_std")) diff --git a/tests/models/qwen3_omni_moe/test_processing_qwen3_omni_moe.py b/tests/models/qwen3_omni_moe/test_processing_qwen3_omni_moe.py index baaf22bd7831..4c370e9286ed 100644 --- a/tests/models/qwen3_omni_moe/test_processing_qwen3_omni_moe.py +++ b/tests/models/qwen3_omni_moe/test_processing_qwen3_omni_moe.py @@ -214,6 +214,8 @@ def test_kwargs_overrides_default_tokenizer_kwargs_audio(self): def setUpClass(cls): cls.tmpdirname = tempfile.mkdtemp() processor = Qwen3OmniMoeProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B") + processor.image_processor.size = {"shortest_edge": 28 * 28, "longest_edge": 56 * 56} + processor.video_processor.size = {"shortest_edge": 28 * 28, "longest_edge": 56 * 56} processor.save_pretrained(cls.tmpdirname) def get_tokenizer(self, **kwargs): @@ -463,7 +465,7 @@ def test_apply_chat_template_video_frame_sampling(self): { "type": "video", "url": url_to_local_path( - "https://huggingface.co/datasets/raushan-testing-hf/videos-test/resolve/main/Big_Buck_Bunny_720_10s_10MB.mp4" + "https://huggingface.co/datasets/raushan-testing-hf/videos-test/resolve/main/tiny_video.mp4" ), } ) @@ -476,7 +478,7 @@ def test_apply_chat_template_video_frame_sampling(self): num_frames=num_frames, ) self.assertTrue(self.videos_input_name in out_dict_with_video) - self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 9568) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 7728) # Load with `fps` arg fps = 1 @@ -488,7 +490,7 @@ def test_apply_chat_template_video_frame_sampling(self): fps=fps, ) self.assertTrue(self.videos_input_name in out_dict_with_video) - self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 23920) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 7728) # Load with `fps` and `num_frames` args, should raise an error with self.assertRaises(ValueError): @@ -509,7 +511,7 @@ def test_apply_chat_template_video_frame_sampling(self): return_dict=True, ) self.assertTrue(self.videos_input_name in out_dict_with_video) - self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 717600) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 23184) # Load video as a list of frames (i.e. images). NOTE: each frame should have same size # because we assume they come from one video @@ -527,7 +529,7 @@ def test_apply_chat_template_video_frame_sampling(self): return_dict=True, ) self.assertTrue(self.videos_input_name in out_dict_with_video) - self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 11408) + self.assertEqual(len(out_dict_with_video[self.videos_input_name]), 7600) # When the inputs are frame URLs/paths we expect that those are already # sampled and will raise an error is asked to sample again. diff --git a/tests/models/qwen3_vl/test_processing_qwen3_vl.py b/tests/models/qwen3_vl/test_processing_qwen3_vl.py index 87636dcf607d..d6d1938ccd57 100644 --- a/tests/models/qwen3_vl/test_processing_qwen3_vl.py +++ b/tests/models/qwen3_vl/test_processing_qwen3_vl.py @@ -302,7 +302,7 @@ def test_apply_chat_template_video_frame_sampling(self): # Add video URL for return dict and load with `num_frames` arg messages[0][0]["content"][0] = { "type": "video", - "url": "https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_10MB.mp4", + "url": "https://huggingface.co/datasets/raushan-testing-hf/videos-test/resolve/main/tiny_video.mp4", } num_frames = 3 out_dict_with_video = processor.apply_chat_template( From 2e074060995f07e15c29f6d01bd08d4a95f50322 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Mon, 22 Sep 2025 12:45:31 +0200 Subject: [PATCH 138/204] [testing] Fix `qwen2_audio` (#41018) * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix --------- Co-authored-by: ydshieh --- .../qwen2_audio/test_modeling_qwen2_audio.py | 64 +++++++++---------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/tests/models/qwen2_audio/test_modeling_qwen2_audio.py b/tests/models/qwen2_audio/test_modeling_qwen2_audio.py index 538353fee44d..4d26443f63d6 100644 --- a/tests/models/qwen2_audio/test_modeling_qwen2_audio.py +++ b/tests/models/qwen2_audio/test_modeling_qwen2_audio.py @@ -198,6 +198,7 @@ def test_sdpa_can_dispatch_composite_models(self): @require_torch class Qwen2AudioForConditionalGenerationIntegrationTest(unittest.TestCase): def setUp(self): + cleanup(torch_device, gc_collect=True) self.processor = AutoProcessor.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct") def tearDown(self): @@ -206,7 +207,9 @@ def tearDown(self): @slow def test_small_model_integration_test_single(self): # Let' s make sure we test the preprocessing to replace what is used - model = Qwen2AudioForConditionalGeneration.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct") + model = Qwen2AudioForConditionalGeneration.from_pretrained( + "Qwen/Qwen2-Audio-7B-Instruct", device_map=torch_device, dtype=torch.float16 + ) url = "https://huggingface.co/datasets/raushan-testing-hf/audio-test/resolve/main/glass-breaking-151256.mp3" messages = [ @@ -223,47 +226,35 @@ def test_small_model_integration_test_single(self): formatted_prompt = self.processor.apply_chat_template(messages, add_generation_prompt=True) - inputs = self.processor(text=formatted_prompt, audios=[raw_audio], return_tensors="pt", padding=True) + inputs = self.processor(text=formatted_prompt, audio=[raw_audio], return_tensors="pt", padding=True).to( + torch_device + ) + torch.manual_seed(42) output = model.generate(**inputs, max_new_tokens=32) # fmt: off - EXPECTED_INPUT_IDS = torch.tensor([[ - 151644, 8948, 198, 2610, 525, 264, 10950, 17847, 13, 151645, 198, 151644, 872, 198, 14755, 220, 16, 25, 220, 151647, - *[151646] * 101, - 151648, 198, 3838, 594, 429, 5112, 30, 151645, 198, 151644, 77091, 198, - ]]) - # fmt: on - self.assertTrue(torch.equal(inputs["input_ids"], EXPECTED_INPUT_IDS)) - - EXPECTED_DECODED_TEXT = ( - "<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\nAudio 1: <|audio_bos|>" - + "<|AUDIO|>" * 101 - + "<|audio_eos|>\nWhat's that sound?<|im_end|>\n<|im_start|>assistant\nIt is the sound of glass breaking.<|im_end|>" + EXPECTED_INPUT_IDS = torch.tensor( + [[151644, 8948, 198, 2610, 525, 264, 10950, 17847, 13, 151645, 198, 151644, 872, 198, 14755, 220, 16, 25, 220, 151647, *[151646] * 101 , 151648, 198, 3838, 594, 429, 5112, 30, 151645, 198, 151644, 77091, 198]], + device=torch_device ) + # fmt: on + torch.testing.assert_close(inputs["input_ids"], EXPECTED_INPUT_IDS) + # fmt: off + EXPECTED_DECODED_TEXT = "<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\nAudio 1: <|audio_bos|>" + "<|AUDIO|>" * 101 + "<|audio_eos|>\nWhat's that sound?<|im_end|>\n<|im_start|>assistant\nIt is the sound of glass breaking.<|im_end|>" + # fmt: on self.assertEqual( self.processor.decode(output[0], skip_special_tokens=False), EXPECTED_DECODED_TEXT, ) - # test the error when incorrect number of audio tokens - # fmt: off - inputs["input_ids"] = torch.tensor([[ - 151644, 8948, 198, 2610, 525, 264, 10950, 17847, 13, 151645, 198, 151644, 872, 198, 14755, 220, 16, 25, 220, 151647, - *[151646] * 200, - 151648, 198, 3838, 594, 429, 5112, 30, 151645, 198, 151644, 77091, 198, - ]]) - # fmt: on - with self.assertRaisesRegex( - ValueError, "Audio features and audio tokens do not match: tokens: 200, features 101" - ): - model.generate(**inputs, max_new_tokens=32) - @slow def test_small_model_integration_test_batch(self): # Let' s make sure we test the preprocessing to replace what is used - model = Qwen2AudioForConditionalGeneration.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct") + model = Qwen2AudioForConditionalGeneration.from_pretrained( + "Qwen/Qwen2-Audio-7B-Instruct", device_map=torch_device, dtype=torch.float16 + ) conversation1 = [ { @@ -322,23 +313,27 @@ def test_small_model_integration_test_batch(self): )[0] ) - inputs = self.processor(text=text, audios=audios, return_tensors="pt", padding=True) + inputs = self.processor(text=text, audio=audios, return_tensors="pt", padding=True).to(torch_device) + torch.manual_seed(42) output = model.generate(**inputs, max_new_tokens=32) EXPECTED_DECODED_TEXT = [ "system\nYou are a helpful assistant.\nuser\nAudio 1: \nWhat's that sound?\nassistant\nIt is the sound of glass shattering.\nuser\nAudio 2: \nWhat can you hear?\nassistant\ncough and throat clearing.", "system\nYou are a helpful assistant.\nuser\nAudio 1: \nWhat does the person say?\nassistant\nThe original content of this audio is: 'Mister Quiller is the apostle of the middle classes and we are glad to welcome his gospel.'", ] + self.assertEqual( self.processor.batch_decode(output, skip_special_tokens=True), EXPECTED_DECODED_TEXT, ) @slow - def test_small_model_integration_test_multiturn(self): + def test_small_model_integration_test_multiurn(self): # Let' s make sure we test the preprocessing to replace what is used - model = Qwen2AudioForConditionalGeneration.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct") + model = Qwen2AudioForConditionalGeneration.from_pretrained( + "Qwen/Qwen2-Audio-7B-Instruct", device_map=torch_device, dtype=torch.float16 + ) messages = [ {"role": "system", "content": "You are a helpful assistant."}, @@ -379,12 +374,15 @@ def test_small_model_integration_test_multiturn(self): )[0] ) - inputs = self.processor(text=formatted_prompt, audios=audios, return_tensors="pt", padding=True) + inputs = self.processor(text=formatted_prompt, audio=audios, return_tensors="pt", padding=True).to( + torch_device + ) + torch.manual_seed(42) output = model.generate(**inputs, max_new_tokens=32, top_k=1) EXPECTED_DECODED_TEXT = [ - "system\nYou are a helpful assistant.\nuser\nAudio 1: \nWhat's that sound?\nassistant\nIt is the sound of glass shattering.\nuser\nAudio 2: \nHow about this one?\nassistant\nThroat clearing.", + "system\nYou are a helpful assistant.\nuser\nAudio 1: \nWhat's that sound?\nassistant\nIt is the sound of glass shattering.\nuser\nAudio 2: \nHow about this one?\nassistant\nThroat clearing." ] self.assertEqual( self.processor.batch_decode(output, skip_special_tokens=True), From 73f63799e83ff7a004ab5dbddc7d8e2610ee0a85 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 22 Sep 2025 19:29:07 +0800 Subject: [PATCH 139/204] Fix typing of tuples (#41028) * Fix tuple typing Signed-off-by: Yuanyuan Chen * More fixes Signed-off-by: Yuanyuan Chen * More fixes Signed-off-by: Yuanyuan Chen --------- Signed-off-by: Yuanyuan Chen --- src/transformers/image_processing_utils_fast.py | 2 +- src/transformers/image_transforms.py | 2 +- src/transformers/modeling_outputs.py | 2 +- src/transformers/modeling_utils.py | 2 +- src/transformers/onnx/config.py | 4 ++-- src/transformers/pipelines/base.py | 11 ++--------- src/transformers/tokenization_mistral_common.py | 2 +- src/transformers/tokenization_utils_base.py | 10 +++++----- src/transformers/tokenization_utils_fast.py | 4 ++-- src/transformers/utils/backbone_utils.py | 4 ++-- src/transformers/utils/generic.py | 2 +- 11 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/transformers/image_processing_utils_fast.py b/src/transformers/image_processing_utils_fast.py index 3eaa22cdb690..ef872b6c172c 100644 --- a/src/transformers/image_processing_utils_fast.py +++ b/src/transformers/image_processing_utils_fast.py @@ -131,7 +131,7 @@ def max_across_indices(values: Iterable[Any]) -> list[Any]: return [max(values_i) for values_i in zip(*values)] -def get_max_height_width(images: list["torch.Tensor"]) -> tuple[int]: +def get_max_height_width(images: list["torch.Tensor"]) -> tuple[int, ...]: """ Get the maximum height and width across all images in a batch. """ diff --git a/src/transformers/image_transforms.py b/src/transformers/image_transforms.py index 2aba3d549719..6d234ef37e5b 100644 --- a/src/transformers/image_transforms.py +++ b/src/transformers/image_transforms.py @@ -245,7 +245,7 @@ def get_size_with_aspect_ratio(image_size, size, max_size=None) -> tuple[int, in # Logic adapted from torchvision resizing logic: https://github.com/pytorch/vision/blob/511924c1ced4ce0461197e5caa64ce5b9e558aab/torchvision/transforms/functional.py#L366 def get_resize_output_image_size( input_image: np.ndarray, - size: Union[int, tuple[int, int], list[int], tuple[int]], + size: Union[int, tuple[int, int], list[int], tuple[int, ...]], default_to_square: bool = True, max_size: Optional[int] = None, input_data_format: Optional[Union[str, ChannelDimension]] = None, diff --git a/src/transformers/modeling_outputs.py b/src/transformers/modeling_outputs.py index 597e20b28ca8..1747f6fa477b 100755 --- a/src/transformers/modeling_outputs.py +++ b/src/transformers/modeling_outputs.py @@ -1651,7 +1651,7 @@ class Seq2SeqTSPredictionOutput(ModelOutput): """ loss: Optional[torch.FloatTensor] = None - params: Optional[tuple[torch.FloatTensor]] = None + params: Optional[tuple[torch.FloatTensor, ...]] = None past_key_values: Optional[EncoderDecoderCache] = None decoder_hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None decoder_attentions: Optional[tuple[torch.FloatTensor, ...]] = None diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index 31783d041fe4..a132a763ca05 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -1644,7 +1644,7 @@ def create_extended_attention_mask_for_decoder(input_shape, attention_mask, devi def get_extended_attention_mask( self, attention_mask: Tensor, - input_shape: tuple[int], + input_shape: tuple[int, ...], device: Optional[torch.device] = None, dtype: Optional[torch.dtype] = None, ) -> Tensor: diff --git a/src/transformers/onnx/config.py b/src/transformers/onnx/config.py index 46c9d32b7341..b3edad05327f 100644 --- a/src/transformers/onnx/config.py +++ b/src/transformers/onnx/config.py @@ -608,7 +608,7 @@ def outputs(self) -> Mapping[str, Mapping[int, str]]: return common_outputs @property - def num_layers(self) -> tuple[int]: + def num_layers(self) -> tuple[int, ...]: try: num_layers = super().num_layers num_layers = (num_layers, num_layers) @@ -624,7 +624,7 @@ def num_layers(self) -> tuple[int]: return num_layers @property - def num_attention_heads(self) -> tuple[int]: + def num_attention_heads(self) -> tuple[int, ...]: try: num_attention_heads = super().num_attention_heads num_attention_heads = (num_attention_heads, num_attention_heads) diff --git a/src/transformers/pipelines/base.py b/src/transformers/pipelines/base.py index 61c0aff4e029..20f32d994461 100644 --- a/src/transformers/pipelines/base.py +++ b/src/transformers/pipelines/base.py @@ -56,20 +56,13 @@ GenericTensor = Union[list["GenericTensor"], "torch.Tensor"] -if is_torch_available(): +if is_torch_available() or TYPE_CHECKING: import torch from torch.utils.data import DataLoader, Dataset from ..modeling_utils import PreTrainedModel - - # Re-export for backward compatibility - from .pt_utils import KeyDataset else: Dataset = None - KeyDataset = None - -if TYPE_CHECKING: - from ..modeling_utils import PreTrainedModel logger = logging.get_logger(__name__) @@ -200,7 +193,7 @@ def inner(items): def load_model( model, config: AutoConfig, - model_classes: Optional[tuple[type]] = None, + model_classes: Optional[tuple[type, ...]] = None, task: Optional[str] = None, **model_kwargs, ): diff --git a/src/transformers/tokenization_mistral_common.py b/src/transformers/tokenization_mistral_common.py index 90d3b673e20e..0b67041bfccc 100644 --- a/src/transformers/tokenization_mistral_common.py +++ b/src/transformers/tokenization_mistral_common.py @@ -1819,7 +1819,7 @@ def save_pretrained( repo_url: Optional[str] = None, organization: Optional[str] = None, **kwargs, - ) -> tuple[str]: + ) -> tuple[str, ...]: """ Save the full tokenizer state. diff --git a/src/transformers/tokenization_utils_base.py b/src/transformers/tokenization_utils_base.py index 36a99d66e23d..1264fb2392c8 100644 --- a/src/transformers/tokenization_utils_base.py +++ b/src/transformers/tokenization_utils_base.py @@ -2420,7 +2420,7 @@ def save_pretrained( filename_prefix: Optional[str] = None, push_to_hub: bool = False, **kwargs, - ) -> tuple[str]: + ) -> tuple[str, ...]: """ Save the full tokenizer state. @@ -2585,10 +2585,10 @@ def save_pretrained( def _save_pretrained( self, save_directory: Union[str, os.PathLike], - file_names: tuple[str], + file_names: tuple[str, ...], legacy_format: Optional[bool] = None, filename_prefix: Optional[str] = None, - ) -> tuple[str]: + ) -> tuple[str, ...]: """ Save a tokenizer using the slow-tokenizer/legacy format: vocabulary + added tokens. @@ -2617,7 +2617,7 @@ def _save_pretrained( return file_names + vocab_files + (added_tokens_file,) - def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> tuple[str]: + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> tuple[str, ...]: """ Save only the vocabulary of the tokenizer (vocabulary + added tokens). @@ -2631,7 +2631,7 @@ def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = An optional prefix to add to the named of the saved files. Returns: - `Tuple(str)`: Paths to the files saved. + `tuple(str)`: Paths to the files saved. """ raise NotImplementedError diff --git a/src/transformers/tokenization_utils_fast.py b/src/transformers/tokenization_utils_fast.py index 22c63f10da0c..fe4873d61b37 100644 --- a/src/transformers/tokenization_utils_fast.py +++ b/src/transformers/tokenization_utils_fast.py @@ -695,10 +695,10 @@ def _decode( def _save_pretrained( self, save_directory: Union[str, os.PathLike], - file_names: tuple[str], + file_names: tuple[str, ...], legacy_format: Optional[bool] = None, filename_prefix: Optional[str] = None, - ) -> tuple[str]: + ) -> tuple[str, ...]: """ Save a tokenizer using the slow-tokenizer/legacy format: vocabulary + added tokens as well as in a unique JSON file containing {config + vocab + added-tokens}. diff --git a/src/transformers/utils/backbone_utils.py b/src/transformers/utils/backbone_utils.py index 29b20a813ba6..d2f6277282d9 100644 --- a/src/transformers/utils/backbone_utils.py +++ b/src/transformers/utils/backbone_utils.py @@ -76,7 +76,7 @@ def verify_out_features_out_indices( def _align_output_features_output_indices( out_features: Optional[list[str]], - out_indices: Optional[Union[list[int], tuple[int]]], + out_indices: Optional[Union[list[int], tuple[int, ...]]], stage_names: list[str], ): """ @@ -284,7 +284,7 @@ def out_indices(self): return self._out_indices @out_indices.setter - def out_indices(self, out_indices: Union[tuple[int], list[int]]): + def out_indices(self, out_indices: Union[tuple[int, ...], list[int]]): """ Set the out_indices attribute. This will also update the out_features attribute to match the new out_indices. """ diff --git a/src/transformers/utils/generic.py b/src/transformers/utils/generic.py index 1606443ccece..994ab6a6b888 100644 --- a/src/transformers/utils/generic.py +++ b/src/transformers/utils/generic.py @@ -380,7 +380,7 @@ def __reduce__(self): args = tuple(getattr(self, field.name) for field in fields(self)) return callable, args, *remaining - def to_tuple(self) -> tuple[Any]: + def to_tuple(self) -> tuple: """ Convert self to a tuple containing all the attributes/keys that are not `None`. """ From a945d26793a88ced9f626b0b08398cfb58cf46c5 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 22 Sep 2025 19:30:39 +0800 Subject: [PATCH 140/204] Remove optax (#41030) Remove optax dep Signed-off-by: Yuanyuan Chen --- setup.py | 1 - src/transformers/dependency_versions_table.py | 1 - 2 files changed, 2 deletions(-) diff --git a/setup.py b/setup.py index 10bac3c7707f..d1ed91461f47 100644 --- a/setup.py +++ b/setup.py @@ -132,7 +132,6 @@ "opencv-python", "optimum-benchmark>=0.3.0", "optuna", - "optax>=0.0.8,<=0.1.4", "pandas<2.3.0", # `datasets` requires `pandas` while `pandas==2.3.0` has issues with CircleCI on 2025/06/05 "packaging>=20.0", "parameterized>=0.9", # older version of parameterized cause pytest collection to fail on .expand diff --git a/src/transformers/dependency_versions_table.py b/src/transformers/dependency_versions_table.py index 28a9f84b92a8..8170b459d438 100644 --- a/src/transformers/dependency_versions_table.py +++ b/src/transformers/dependency_versions_table.py @@ -41,7 +41,6 @@ "opencv-python": "opencv-python", "optimum-benchmark": "optimum-benchmark>=0.3.0", "optuna": "optuna", - "optax": "optax>=0.0.8,<=0.1.4", "pandas": "pandas<2.3.0", "packaging": "packaging>=20.0", "parameterized": "parameterized>=0.9", From 755a1e5ad1ad11dc55e78a842f6feb0471f00627 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 22 Sep 2025 19:31:46 +0800 Subject: [PATCH 141/204] Fix typos in English/Chinese documentation (#41031) * Fix typos and formatting in English docs Signed-off-by: Yuanyuan Chen * Fix typos and formatting in Chinese docs Signed-off-by: Yuanyuan Chen --------- Signed-off-by: Yuanyuan Chen --- docs/source/en/run_scripts.md | 2 +- docs/source/en/video_processors.md | 5 ++--- docs/source/zh/main_classes/deepspeed.md | 2 +- docs/source/zh/pipeline_tutorial.md | 2 +- docs/source/zh/tasks/asr.md | 4 ++-- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/source/en/run_scripts.md b/docs/source/en/run_scripts.md index c3a4787575c0..ef32bf26ee02 100644 --- a/docs/source/en/run_scripts.md +++ b/docs/source/en/run_scripts.md @@ -104,7 +104,7 @@ torchrun \ ... ``` -PyTorch supports TPUs, hardware designed to accelerate performance, through the [PyTorch/XLA](https://github.com/pytorch/xla/blob/master/README.md) package. Launch the `xla_spawn.py` script and use `num _cores` to set the number of TPU cores to train with. +PyTorch supports TPUs, hardware designed to accelerate performance, through the [PyTorch/XLA](https://github.com/pytorch/xla/blob/master/README.md) package. Launch the `xla_spawn.py` script and use `num_cores` to set the number of TPU cores to train with. ```bash python xla_spawn.py --num_cores 8 pytorch/summarization/run_summarization.py \ diff --git a/docs/source/en/video_processors.md b/docs/source/en/video_processors.md index 4f44914c8cfc..2b26d9f9fc7f 100644 --- a/docs/source/en/video_processors.md +++ b/docs/source/en/video_processors.md @@ -14,17 +14,16 @@ rendered properly in your Markdown viewer. --> - # Video Processor -A **Video Processor** is a utility responsible for preparing input features for video models, as well as handling the post-processing of their outputs. It provides transformations such as resizing, normalization, and conversion into PyTorch. +A **Video Processor** is a utility responsible for preparing input features for video models, as well as handling the post-processing of their outputs. It provides transformations such as resizing, normalization, and conversion into PyTorch. The video processor extends the functionality of image processors by allowing the models to handle videos with a distinct set of arguments compared to images. It serves as the bridge between raw video data and the model, ensuring that input features are optimized for the VLM. Use [`~BaseVideoProcessor.from_pretrained`] to load a video processors configuration (image size, whether to normalize and rescale, etc.) from a video model on the Hugging Face [Hub](https://hf.co) or local directory. The configuration for each pretrained model should be saved in a [video_preprocessor_config.json] file but older models might have the config saved in [preprocessor_config.json](https://huggingface.co/llava-hf/llava-onevision-qwen2-0.5b-ov-hf/blob/main/preprocessor_config.json) file. Note that the latter is less preferred and will be removed in the future. +## Usage Example -### Usage Example Here's an example of how to load a video processor with [`llava-hf/llava-onevision-qwen2-0.5b-ov-hf`](https://huggingface.co/llava-hf/llava-onevision-qwen2-0.5b-ov-hf) model: ```python diff --git a/docs/source/zh/main_classes/deepspeed.md b/docs/source/zh/main_classes/deepspeed.md index 7cdf3b62e427..a8863896235f 100644 --- a/docs/source/zh/main_classes/deepspeed.md +++ b/docs/source/zh/main_classes/deepspeed.md @@ -236,7 +236,7 @@ deepspeed --num_gpus=1 examples/pytorch/translation/run_translation.py \ } ``` -这会启用`optimizer offload `和一些其他重要功能。您可以尝试不同的buffer大小,有关详细信息,请参见下面的讨论。 +这会启用`optimizer offload`和一些其他重要功能。您可以尝试不同的buffer大小,有关详细信息,请参见下面的讨论。 关于这种启用类型的实际使用示例,请参阅 [此帖](https://github.com/huggingface/transformers/issues/8771#issuecomment-759176685)。 diff --git a/docs/source/zh/pipeline_tutorial.md b/docs/source/zh/pipeline_tutorial.md index 92fbcbba31e4..7c497c6f1c65 100644 --- a/docs/source/zh/pipeline_tutorial.md +++ b/docs/source/zh/pipeline_tutorial.md @@ -306,5 +306,5 @@ pipe = pipeline(model="facebook/opt-1.3b", device_map="auto", model_kwargs={"loa output = pipe("This is a cool example!", do_sample=True, top_p=0.95) ``` -请注意,您可以将`checkpoint `替换为任何支持大模型加载的Hugging Face模型,比如BLOOM! +请注意,您可以将`checkpoint`替换为任何支持大模型加载的Hugging Face模型,比如BLOOM! diff --git a/docs/source/zh/tasks/asr.md b/docs/source/zh/tasks/asr.md index 3b66888bc107..228ba55c0d0e 100644 --- a/docs/source/zh/tasks/asr.md +++ b/docs/source/zh/tasks/asr.md @@ -83,7 +83,7 @@ DatasetDict({ }) ``` -虽然数据集包含 `lang_id `和 `english_transcription` 等许多有用的信息,但在本指南中, +虽然数据集包含 `lang_id` 和 `english_transcription` 等许多有用的信息,但在本指南中, 您将专注于 `audio` 和 `transcription`。使用 [`~datasets.Dataset.remove_columns`] 方法删除其他列: ```py @@ -167,7 +167,7 @@ Wav2Vec2 分词器仅训练了大写字符,因此您需要确保文本与分 它还会动态地将您的文本和标签填充到其批次中最长元素的长度(而不是整个数据集),以使它们具有统一的长度。 虽然可以通过在 `tokenizer` 函数中设置 `padding=True` 来填充文本,但动态填充更有效。 -与其他数据整理器不同,这个特定的数据整理器需要对 `input_values` 和 `labels `应用不同的填充方法: +与其他数据整理器不同,这个特定的数据整理器需要对 `input_values` 和 `labels` 应用不同的填充方法: ```py >>> import torch From 586c4878269458453292659fd1acd18370708cf8 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 22 Sep 2025 20:18:24 +0800 Subject: [PATCH 142/204] Use torch.autocast (#40975) * Use torch.autocast Signed-off-by: Yuanyuan Chen * Format code Signed-off-by: Yuanyuan Chen --------- Signed-off-by: Yuanyuan Chen --- src/transformers/models/esm/modeling_esmfold.py | 4 ++-- src/transformers/models/oneformer/modeling_oneformer.py | 3 +-- src/transformers/trainer.py | 5 +---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/transformers/models/esm/modeling_esmfold.py b/src/transformers/models/esm/modeling_esmfold.py index dbff29fade87..7bc1f0dbdc70 100644 --- a/src/transformers/models/esm/modeling_esmfold.py +++ b/src/transformers/models/esm/modeling_esmfold.py @@ -293,7 +293,7 @@ def __init__(self, c_in, eps=1e-5): def forward(self, x): d = x.dtype if d is torch.bfloat16 and not is_deepspeed_initialized(): - with torch.cuda.amp.autocast(enabled=False): + with torch.autocast(device_type="cuda", enabled=False): out = nn.functional.layer_norm(x, self.c_in, self.weight.to(dtype=d), self.bias.to(dtype=d), self.eps) else: out = nn.functional.layer_norm(x, self.c_in, self.weight, self.bias, self.eps) @@ -308,7 +308,7 @@ def softmax_no_cast(t: torch.Tensor, dim: int = -1) -> torch.Tensor: """ d = t.dtype if d is torch.bfloat16 and not is_deepspeed_initialized(): - with torch.cuda.amp.autocast(enabled=False): + with torch.autocast(device_type="cuda", enabled=False): s = torch.nn.functional.softmax(t, dim=dim) else: s = torch.nn.functional.softmax(t, dim=dim) diff --git a/src/transformers/models/oneformer/modeling_oneformer.py b/src/transformers/models/oneformer/modeling_oneformer.py index dc44ad67f71f..60f1e74eff49 100644 --- a/src/transformers/models/oneformer/modeling_oneformer.py +++ b/src/transformers/models/oneformer/modeling_oneformer.py @@ -23,7 +23,6 @@ import numpy as np import torch from torch import Tensor, nn -from torch.cuda.amp import autocast from ...activations import ACT2FN from ...modeling_layers import GradientCheckpointingLayer @@ -322,7 +321,7 @@ def forward(self, masks_queries_logits, class_queries_logits, mask_labels, class align_corners=False, ).squeeze(1) - with autocast(enabled=False): + with torch.autocast(device_type="cuda", enabled=False): pred_mask = pred_mask.float() target_mask = target_mask.float() diff --git a/src/transformers/trainer.py b/src/transformers/trainer.py index 272f69610a97..0cd8fcf8cd14 100755 --- a/src/transformers/trainer.py +++ b/src/transformers/trainer.py @@ -3971,10 +3971,7 @@ def autocast_smart_context_manager(self, cache_enabled: Optional[bool] = True): arguments, depending on the situation. """ if self.use_cpu_amp: - # TODO Matt: This syntax is deprecated and the preferred version is - # torch.amp.autocast("cpu", cache_enabled=cache_enabled, dtype=self.amp_dtype) - # but this is unavailable on Torch 2.1 or earlier. We can change this when we stop supporting 2.1. - ctx_manager = torch.cpu.amp.autocast(cache_enabled=cache_enabled, dtype=self.amp_dtype) + ctx_manager = torch.autocast(device_type="cpu", cache_enabled=cache_enabled, dtype=self.amp_dtype) else: ctx_manager = contextlib.nullcontext() From 0cfc691772522de0597929adb1915ac58031676f Mon Sep 17 00:00:00 2001 From: Ryan Mullins Date: Mon, 22 Sep 2025 08:21:15 -0400 Subject: [PATCH 143/204] docs: improved RoPE function Docstrings (#41004) * docs: improved RoPE functuon docstrings * Update src/transformers/modeling_rope_utils.py Co-authored-by: Joao Gante --------- Co-authored-by: Joao Gante --- src/transformers/modeling_rope_utils.py | 171 +++++++++++++++++++++--- 1 file changed, 155 insertions(+), 16 deletions(-) diff --git a/src/transformers/modeling_rope_utils.py b/src/transformers/modeling_rope_utils.py index 34c136980234..c0070df6ee17 100644 --- a/src/transformers/modeling_rope_utils.py +++ b/src/transformers/modeling_rope_utils.py @@ -98,17 +98,30 @@ def _compute_default_rope_parameters( Computes the inverse frequencies according to the original RoPE implementation Args: config ([`~transformers.PretrainedConfig`]): - The model configuration. + The model configuration. This function assumes that the config will provide at least the following + properties: + + * rope_theta (`float`): The base wavelength from which the inverse frequencies will be derived. + * hidden_size (`int`): The numerator when deriving a head_dim, if not provided directly. + * num_attention_heads (`int`): The denominator when deriving a head_dim, if not provided directly. + + Additionally, this function will make use of the following properties if they are found in the config: + + * head_dim (`int`, *optional*): The size of the key-value heads in the model. If None, this value will be + derived as hidden_size // num_attention_heads. + * partial_rotary_factor (`float`, *optional*): If less than 1.0, inverse frequencies will be returned for + the first fraction of the head_dim. Defaults to 1.0. device (`torch.device`): The device to use for initialization of the inverse frequencies. seq_len (`int`, *optional*): The current sequence length. Unused for this type of RoPE. + Returns: Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE). """ base = config.rope_theta - partial_rotary_factor = config.partial_rotary_factor if hasattr(config, "partial_rotary_factor") else 1.0 + partial_rotary_factor = getattr(config, "partial_rotary_factor", 1.0) head_dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads dim = int(head_dim * partial_rotary_factor) @@ -128,11 +141,24 @@ def _compute_linear_scaling_rope_parameters( Computes the inverse frequencies with linear scaling. Credits to the Reddit user /u/kaiokendev Args: config ([`~transformers.PretrainedConfig`]): - The model configuration. + The model configuration. This function assumes that the config will provide at least the following + properties: + + * rope_theta (`float`): The base wavelength from which the inverse frequencies will be derived. + * hidden_size (`int`): The numerator when deriving a head_dim, if not provided directly. + * num_attention_heads (`int`): The denominator when deriving a head_dim, if not provided directly. + + Additionally, this function will make use of the following properties if they are found in the config: + + * head_dim (`int`, *optional*): The size of the key-value heads in the model. If None, this value will be + derived as hidden_size // num_attention_heads. + * partial_rotary_factor (`float`, *optional*): If less than 1.0, inverse frequencies will be returned for + the first fraction of the head_dim. Defaults to 1.0. device (`torch.device`): The device to use for initialization of the inverse frequencies. seq_len (`int`, *optional*): The current sequence length. Unused for this type of RoPE. + Returns: Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE). @@ -156,20 +182,43 @@ def _compute_dynamic_ntk_parameters( ) -> tuple["torch.Tensor", float]: """ Computes the inverse frequencies with NTK scaling. Credits to the Reddit users /u/bloc97 and /u/emozilla + Args: config ([`~transformers.PretrainedConfig`]): - The model configuration. + The model configuration. This function assumes that the config will provide at least the following + properties: + + * rope_theta (`float`): The base wavelength from which the inverse frequencies will be derived. + * hidden_size (`int`): The numerator when deriving a head_dim, if not provided directly. + * num_attention_heads (`int`): The denominator when deriving a head_dim, if not provided directly. + * max_position_embeddings (`int`): The default sequence length used to update the dynamic RoPE at + inference time + * rope_scaling (`dict[str, float]`): The standard RoPE scaling parameters, from which `factor` + will be accessed. The value of `factor` is used to determine the new base frequency, along with the + current sequence length (seq_len), the maximum positional embeddings (max_position_embeddings), and the + computed dimensionality (dim) of the rotary embeddings. If seq_len <= max_position_embeddings, this + factor has no effect. If seq_len <= max_position_embeddings, this factor effectively stretches the + context window using an exponent derived from `dim`. + + Additionally, this function will make use of the following properties if they are found in the config: + + * head_dim (`int`, *optional*): The size of the key-value heads in the model. If None, this value will be + derived as hidden_size // num_attention_heads. + * partial_rotary_factor (`float`, *optional*): If less than 1.0, inverse frequencies will be returned for + the first fraction of the head_dim. Defaults to 1.0. device (`torch.device`): The device to use for initialization of the inverse frequencies. seq_len (`int`, *optional*): - The current sequence length, used to update the dynamic RoPE at inference time. + The current sequence length, used to update the dynamic RoPE at inference time. If `None` or shorter than + max_position_embeddings, this value will be overridden by max_position_embeddings. + Returns: Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE). """ # TODO (joao): use the new `original_max_position_embeddings` from rope_scaling base = config.rope_theta - partial_rotary_factor = config.partial_rotary_factor if hasattr(config, "partial_rotary_factor") else 1.0 + partial_rotary_factor = getattr(config, "partial_rotary_factor", 1.0) head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) dim = int(head_dim * partial_rotary_factor) max_position_embeddings = config.max_position_embeddings @@ -200,20 +249,58 @@ def _compute_yarn_parameters( """ Computes the inverse frequencies with NTK scaling. Please refer to the [original paper](https://huggingface.co/papers/2309.00071) + Args: config ([`~transformers.PretrainedConfig`]): - The model configuration. + The model configuration. This function assumes that the config will provide at least the following + properties: + + * rope_theta (`float`): The base wavelength from which the inverse frequencies will be derived. + * hidden_size (`int`): The numerator when deriving a head_dim, if not provided directly. + * num_attention_heads (`int`): The denominator when deriving a head_dim, if not provided directly. + * max_position_embeddings (`int`): The maximum length of the positional embeddings. + * rope_scaling (`dict[str, float | int]`): The standard RoPE scaling parameters, from which the following + keys will be accessed: + * `attention_factor` (`float`, *optional*): The scaling factor to be applied to the computed cos/sin. + If None, the value is inferred from `factor`, `mscale`, and `mscale_all_dim` as avaialble. + * `beta_fast` (`float`, *optional*, defaults to 32): Parameter to set the boundary for extrapolation + (only) in the linear ramp function. + * `beta_slow` (`float`, *optional*, defaults to 1): Parameter to set the boundary for interpolation + (only) in the linear ramp function. + * `factor` (`float`, *optional*): The scaling factor applied when interpolating the position IDs to + extend the possible context length. Additionally, if `attention_factor` is None, the log of this + value is used to compute a value for `attention_factor`, possibly in conjunciton with `mscale` and + `mscale_all_dim`, if provided. + * `mscale` (`float`, *optional*): If `attention_factor` is None and both `mscale` and + `mscale_all_dim` are provided, `mscale` acts scalar augmenting `log(factor)` when computing the + numerator for the inferred value of `attention_factor`. If not provided, `attention_factor` will be + calculated based on `factor` only. + * `mscale_all_dim` (`float`, *optional*): If `attention_factor` is None and both `mscale` and + `mscale_all_dim` are provided, `mscale_all_dim` acts scalar augmenting `log(factor)` when computing + the denominator for the inferred value of `attention_factor`. If not provided, `attention_factor` + will be calculated based on `factor` only. + * `original_max_position_embeddings` (`int`, *optional*): The original max position embeddings used + during pretraining. If not provided, the function falls back to `max_position_embeddings`. + * `truncate` (`bool`, *optional*): Whether to truncate the correction range. + + Additionally, this function will make use of the following properties if they are found in the config: + + * head_dim (`int`, *optional*): The size of the key-value heads in the model. If None, this value will be + derived as hidden_size // num_attention_heads. + * partial_rotary_factor (`float`, *optional*, defaults to 1.0): If less than 1.0, inverse frequencies + will be returned for the first fraction of the head_dim. device (`torch.device`): The device to use for initialization of the inverse frequencies. seq_len (`int`, *optional*): The current sequence length. Unused for this type of RoPE. + Returns: Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the post-processing scaling factor applied to the computed cos/sin. """ base = config.rope_theta - partial_rotary_factor = config.partial_rotary_factor if hasattr(config, "partial_rotary_factor") else 1.0 + partial_rotary_factor = getattr(config, "partial_rotary_factor", 1.0) head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) dim = int(head_dim * partial_rotary_factor) factor = config.rope_scaling["factor"] @@ -237,7 +324,7 @@ def get_mscale(scale, mscale=1): attention_factor = get_mscale(factor) # Optional config options - # beta_fast/beta_slow: as suggested in the paper, default to 32/1 (correspondingly) + # beta_fast/beta_slow: as suggested in the paper, default to 32 and 1 respectively beta_fast = config.rope_scaling.get("beta_fast") or 32 beta_slow = config.rope_scaling.get("beta_slow") or 1 @@ -287,20 +374,49 @@ def _compute_longrope_parameters( """ Computes the inverse frequencies with LongRoPE scaling. Please refer to the [original implementation](https://github.com/microsoft/LongRoPE) + Args: config ([`~transformers.PretrainedConfig`]): - The model configuration. + The model configuration. This function assumes that the config will provide at least the following + properties: + + * rope_theta (`float`): The base wavelength from which the inverse frequencies will be derived. + * hidden_size (`int`): The numerator when deriving a head_dim, if not provided directly. + * num_attention_heads (`int`): The denominator when deriving a head_dim, if not provided directly. + * max_position_embeddings (`int`): The maximum length of the positional embeddings. + * original_max_position_embeddings (`int`, *optional*): The original max position embeddings used during + pretraining. If not provided, defaults to `max_position_embeddings`. + * rope_scaling (`dict[str, float]`): The standard RoPE scaling parameters, from which the following keys + will be accessed: + * `attention_factor` (`float`, *optional*): The scaling factor to be applied on the attention + computation. If unspecified, it defaults to value recommended by the implementation, inferred from + the value of `factor`. + * `factor` (`float`, *optional*): The scaling factor to apply to the RoPE embeddings. If both + `max_position_embeddings` and `original_max_position_embeddings` are provided, this value will be + overridden s the ratio between those values. + * `long_factor` (`float`, *optional*): The scale factor applied when computing the inverse + frequencies if `seq_len` is provided and greater than `original_max_position_embeddings`. + * `short_factor` (`float`, *optional*): The scale factor applied when computing the inverse + frequencies if `seq_len` is None or less-than-or-equal-to `original_max_position_embeddings`. + + Additionally, this function will make use of the following properties if they are found in the config: + + * head_dim (`int`, *optional*): The size of the key-value heads in the model. If None, this value will be + derived as hidden_size // num_attention_heads. + * partial_rotary_factor (`float`, *optional*, defaults to 1.0): If less than 1.0, inverse frequencies + will be returned for the first fraction of the head_dim. device (`torch.device`): The device to use for initialization of the inverse frequencies. seq_len (`int`, *optional*): The current sequence length. + Returns: Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the post-processing scaling factor applied to the computed cos/sin. """ # TODO (joao): use the new `original_max_position_embeddings` from rope_scaling base = config.rope_theta - partial_rotary_factor = config.partial_rotary_factor if hasattr(config, "partial_rotary_factor") else 1.0 + partial_rotary_factor = getattr(config, "partial_rotary_factor", 1.0) head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) dim = int(head_dim * partial_rotary_factor) long_factor = config.rope_scaling["long_factor"] @@ -311,9 +427,8 @@ def _compute_longrope_parameters( # NOTE: Phi3 (and potentially other models) modify `max_position_embeddings` and have a # `original_max_position_embeddings` field containing the pretrained value. They use the ratio between these two # values to compute the default attention scaling factor, instead of using `factor`. - if hasattr(config, "original_max_position_embeddings"): - original_max_position_embeddings = config.original_max_position_embeddings - factor = config.max_position_embeddings / config.original_max_position_embeddings + if original_max_position_embeddings := getattr(config, "original_max_position_embeddings", None): + factor = config.max_position_embeddings / original_max_position_embeddings else: original_max_position_embeddings = config.max_position_embeddings @@ -343,7 +458,31 @@ def _compute_llama3_parameters( Args: config ([`~transformers.PretrainedConfig`]): - The model configuration. + The model configuration. This function assumes that the config will provide at least the following + properties: + + * rope_theta (`float`): The base wavelength from which the inverse frequencies will be derived. + * hidden_size (`int`): The numerator when deriving a head_dim, if not provided directly. + * num_attention_heads (`int`): The denominator when deriving a head_dim, if not provided directly. + * rope_scaling (`dict[str, float | int]`): The standard RoPE scaling parameters, from which the following + keys will be accessed: + * `factor` (`float`, *optional*): The scaling factor applied to the inverse frequencies when 1) the + wavelength is greater than `low_freq_wavelen` prior to smoothing, and 2) to all inverse frequencies + during smoothing. + * `high_freq_factor` (`float`): The scale factor used to compute `high_freq_wavelen` and + the value for the denominator of the smoothing factor prior to the `low_freq_factor` shift. + * `low_freq_factor` (`float`): The scale factor used to compute `low_freq_wavelen` and + the shift applied to the numerator and denominator of the smoothing factor. + frequencies if `seq_len` is None or less-than-or-equal-to `original_max_position_embeddings`. + * `original_max_position_embeddings` (`int`): The original max position embeddings used + during pretraining. If not provided, the function falls back to `max_position_embeddings`. + + Additionally, this function will make use of the following properties if they are found in the config: + + * head_dim (`int`, *optional*): The size of the key-value heads in the model. If None, this value will be + derived as hidden_size // num_attention_heads. + * partial_rotary_factor (`float`, *optional*): If less than 1.0, inverse frequencies will be returned for + the first fraction of the head_dim. Defaults to 1.0. device (`torch.device`): The device to use for initialization of the inverse frequencies. seq_len (`int`, *optional*): @@ -527,7 +666,7 @@ def _validate_longrope_parameters(config: PretrainedConfig, ignore_keys: Optiona received_keys = set(rope_scaling.keys()) _check_received_keys(rope_type, received_keys, required_keys, optional_keys, ignore_keys=ignore_keys) - partial_rotary_factor = config.partial_rotary_factor if hasattr(config, "partial_rotary_factor") else 1.0 + partial_rotary_factor = getattr(config, "partial_rotary_factor", 1.0) head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) dim = int(head_dim * partial_rotary_factor) From e832420bb5f5cc5a59602d76b281cb5e35a712b4 Mon Sep 17 00:00:00 2001 From: Yannick Schnider Date: Mon, 22 Sep 2025 14:21:38 +0200 Subject: [PATCH 144/204] Fix condition for emitting warning when generation exceeds max model length (#40775) correct warning when generation exceeds max model length Signed-off-by: Yannick Schnider --- src/transformers/generation/stopping_criteria.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformers/generation/stopping_criteria.py b/src/transformers/generation/stopping_criteria.py index 2b9e57aacd8d..afb1ab02c404 100644 --- a/src/transformers/generation/stopping_criteria.py +++ b/src/transformers/generation/stopping_criteria.py @@ -76,9 +76,9 @@ def __init__(self, max_length: int, max_position_embeddings: Optional[int] = Non def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor, **kwargs) -> torch.BoolTensor: cur_len = input_ids.shape[1] is_done = cur_len >= self.max_length - if self.max_position_embeddings is not None and not is_done and cur_len >= self.max_position_embeddings: + if self.max_position_embeddings is not None and not is_done and cur_len > self.max_position_embeddings: logger.warning_once( - "This is a friendly reminder - the current text generation call will exceed the model's predefined " + "This is a friendly reminder - the current text generation call has exceeded the model's predefined " f"maximum length ({self.max_position_embeddings}). Depending on the model, you may observe " "exceptions, performance degradation, or nothing at all." ) From 8b26d9fe8f4da0e11718b88e4fa21b28f549bc75 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 22 Sep 2025 20:38:07 +0800 Subject: [PATCH 145/204] Fix outdated torch version check (#40925) Update torch minimum version check to 2.2 Signed-off-by: Yuanyuan Chen --- src/transformers/utils/import_utils.py | 4 ++-- tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/transformers/utils/import_utils.py b/src/transformers/utils/import_utils.py index df06bd05842d..76cbaad0eb17 100644 --- a/src/transformers/utils/import_utils.py +++ b/src/transformers/utils/import_utils.py @@ -236,9 +236,9 @@ def _is_package_available(pkg_name: str, return_version: bool = False) -> Union[ _torch_available, _torch_version = _is_package_available("torch", return_version=True) if _torch_available: - _torch_available = version.parse(_torch_version) >= version.parse("2.1.0") + _torch_available = version.parse(_torch_version) >= version.parse("2.2.0") if not _torch_available: - logger.warning(f"Disabling PyTorch because PyTorch >= 2.1 is required but found {_torch_version}") + logger.warning(f"Disabling PyTorch because PyTorch >= 2.2 is required but found {_torch_version}") _essentia_available = importlib.util.find_spec("essentia") is not None diff --git a/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py b/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py index d90dff9f13ff..cb2e31867194 100644 --- a/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py +++ b/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py @@ -55,8 +55,6 @@ if is_torch_available(): import torch -else: - is_torch_greater_or_equal_than_2_0 = False if is_vision_available(): from PIL import Image From e5e269eb99b8b0cc343340d42b42a48dc9c8c35e Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 22 Sep 2025 20:42:26 +0800 Subject: [PATCH 146/204] Remove doc of tf and flax (#41029) Signed-off-by: Yuanyuan Chen --- docs/source/ar/autoclass_tutorial.md | 19 -- docs/source/ar/create_a_model.md | 41 --- docs/source/ar/model_sharing.md | 45 +-- docs/source/ar/preprocessing.md | 25 -- docs/source/ar/quicktour.md | 92 ------ docs/source/ar/run_scripts.md | 37 --- docs/source/ar/tasks/language_modeling.md | 105 +----- .../ar/tasks/masked_language_modeling.md | 112 +------ docs/source/ar/tasks/multiple_choice.md | 156 --------- docs/source/ar/tasks/question_answering.md | 116 ------- .../ar/tasks/sequence_classification.md | 125 ------- docs/source/ar/tasks/summarization.md | 119 +------ docs/source/ar/tasks/token_classification.md | 144 -------- docs/source/ar/tasks/translation.md | 119 +------ docs/source/ar/training.md | 112 +------ docs/source/de/autoclass_tutorial.md | 19 -- docs/source/de/model_sharing.md | 45 +-- docs/source/de/preprocessing.md | 24 -- docs/source/de/quicktour.md | 92 ------ docs/source/de/run_scripts.md | 35 +- docs/source/de/training.md | 115 +------ docs/source/en/internal/import_utils.md | 7 +- docs/source/es/autoclass_tutorial.md | 19 -- docs/source/es/create_a_model.md | 44 --- docs/source/es/quicktour.md | 86 ----- docs/source/es/run_scripts.md | 33 -- docs/source/es/serialization.md | 19 -- docs/source/es/tasks/language_modeling.md | 133 +------- docs/source/es/tasks/multiple_choice.md | 57 ---- docs/source/es/tasks/question_answering.md | 69 ---- docs/source/es/tasks/summarization.md | 60 ---- docs/source/fr/autoclass_tutorial.md | 19 -- docs/source/fr/quicktour.md | 92 ------ docs/source/fr/run_scripts_fr.md | 36 +- docs/source/it/autoclass_tutorial.md | 19 -- docs/source/it/create_a_model.md | 45 +-- docs/source/it/model_sharing.md | 47 --- docs/source/it/quicktour.md | 81 ----- docs/source/it/run_scripts.md | 33 -- docs/source/it/serialization.md | 21 +- docs/source/it/training.md | 66 ---- docs/source/ja/autoclass_tutorial.md | 24 +- docs/source/ja/create_a_model.md | 47 --- docs/source/ja/model_sharing.md | 46 --- docs/source/ja/preprocessing.md | 24 -- docs/source/ja/quicktour.md | 98 ------ docs/source/ja/run_scripts.md | 34 -- docs/source/ja/tasks/image_classification.md | 232 ------------- docs/source/ja/tasks/language_modeling.md | 110 ------- .../ja/tasks/masked_language_modeling.md | 119 ------- docs/source/ja/tasks/multiple_choice.md | 116 ------- docs/source/ja/tasks/question_answering.md | 310 ------------------ docs/source/ja/tasks/semantic_segmentation.md | 234 ------------- docs/source/ja/tasks/summarization.md | 120 ------- docs/source/ja/tasks/token_classification.md | 148 --------- docs/source/ja/tasks/translation.md | 119 ------- docs/source/ja/training.md | 106 ------ docs/source/ko/model_sharing.md | 43 --- docs/source/ko/quicktour.md | 92 ------ docs/source/ko/run_scripts.md | 39 +-- docs/source/ko/tasks/image_classification.md | 225 ------------- docs/source/ko/tasks/language_modeling.md | 103 ------ .../ko/tasks/masked_language_modeling.md | 110 ------- docs/source/ko/tasks/multiple_choice.md | 114 ------- docs/source/ko/tasks/question_answering.md | 114 ------- docs/source/ko/tasks/semantic_segmentation.md | 226 ------------- .../ko/tasks/sequence_classification.md | 124 ------- docs/source/ko/tasks/summarization.md | 119 ------- docs/source/ko/tasks/token_classification.md | 144 -------- docs/source/ko/tasks/translation.md | 117 ------- docs/source/ko/training.md | 109 ------ docs/source/pt/create_a_model.md | 43 +-- docs/source/pt/quicktour.md | 85 +---- docs/source/pt/run_scripts.md | 34 -- .../pt/tasks/sequence_classification.md | 67 ---- docs/source/pt/tasks/token_classification.md | 70 ---- docs/source/zh/autoclass_tutorial.md | 19 -- docs/source/zh/create_a_model.md | 41 --- docs/source/zh/model_sharing.md | 49 +-- docs/source/zh/preprocessing.md | 25 -- docs/source/zh/quicktour.md | 92 ------ docs/source/zh/run_scripts.md | 37 +-- docs/source/zh/training.md | 92 +----- 83 files changed, 21 insertions(+), 6882 deletions(-) diff --git a/docs/source/ar/autoclass_tutorial.md b/docs/source/ar/autoclass_tutorial.md index fe368af47273..6585cf206350 100644 --- a/docs/source/ar/autoclass_tutorial.md +++ b/docs/source/ar/autoclass_tutorial.md @@ -145,23 +145,4 @@ بشكل عام، نوصي باستخدام فئة `AutoTokenizer` وفئة `AutoModelFor` لتحميل مثيلات مُدربة مسبقًا من النماذج. سيساعدك هذا في تحميل البنية الصحيحة في كل مرة. في البرنامج التعليمي التالي، تعرف على كيفية استخدام المحلل اللغوي ومعالج الصور ومستخرج الميزات والمعالج الذي تم تحميله حديثًا لمعالجة مجموعة بيانات للضبط الدقيق. - -أخيرًا، تسمح لك فئات `TFAutoModelFor` بتحميل نموذج مُدرب مسبقًا لمهمة معينة (راجع [هنا](model_doc/auto) للحصول على قائمة كاملة بالمهام المتاحة). على سبيل المثال، قم بتحميل نموذج لتصنيف التسلسل باستخدام [`TFAutoModelForSequenceClassification.from_pretrained`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -أعد استخدام نفس نقطة التفتيش لتحميل بنية لمهمة مختلفة: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -بشكل عام، نوصي باستخدام فئة `AutoTokenizer` وفئة `TFAutoModelFor` لتحميل نسخ لنماذج مُدربة مسبقًا. سيساعدك هذا في تحميل البنية الصحيحة في كل مرة. في البرنامج التعليمي التالي، ستتعرف على كيفية استخدام المُجزّئ اللغوي ومعالج الصور ومستخرج الميزات والمعالج الذي تم تحميله حديثًا لمعالجة مجموعة بيانات للضبط الدقيق. - diff --git a/docs/source/ar/create_a_model.md b/docs/source/ar/create_a_model.md index 6b511fe0de4a..f681d13aa9ef 100644 --- a/docs/source/ar/create_a_model.md +++ b/docs/source/ar/create_a_model.md @@ -106,30 +106,6 @@ DistilBertConfig { >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased"، config=my_config) ``` - -قم بتحميل خصائص التكوين المُخصصة الخاصة بك في النموذج: - -```py ->>> from transformers import TFDistilBertModel - ->>> my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json") ->>> tf_model = TFDistilBertModel(my_config) -``` - -هذا ينشئ نموذجًا بقيم عشوائية بدلاً من الأوزان المُدربة مسبقًا. لن يكون هذا النموذج مفيدًا حتى يتم تدريبه. تُعد عملية التدريب مكلفة وتستغرق وقتًا طويلاً. من الأفضل بشكل عام استخدام نموذج مُدرب مسبقًا للحصول على نتائج أفضل بشكل أسرع، مع استخدام جزء بسيط فقط من الموارد المطلوبة للتدريب. - -قم بإنشاء نموذج مُدرب مسبقًا باستخدام [`~TFPreTrainedModel.from_pretrained`]: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased") -``` - -عندما تقوم بتحميل الأوزان المُدربة مسبقًا،يتم تحميل إعدادات النموذج الافتراضي تلقائيًا إذا كان النموذج من مكتبة 🤗 Transformers. ومع ذلك، يمكنك أيضًا استبدال - بعض أو كل - إعدادات النموذج الافتراضية بإعداداتك الخاصة: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased"، config=my_config) -``` - ### رؤوس النموذج @@ -154,23 +130,6 @@ DistilBertConfig { >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - -على سبيل المثال، [`TFDistilBertForSequenceClassification`] هو نموذج DistilBERT الأساسي برأس تصنيف تسلسل. رأس التصنيف التسلسلي هو طبقة خطية أعلى المخرجات المجمعة. - -```py ->>> from transformers import TFDistilBertForSequenceClassification - ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -أعد استخدام هذا نقطة التحقق لمهمة أخرى عن طريق التبديل إلى رأس نموذج مختلف. لمهمة الإجابة على الأسئلة، ستستخدم رأس النموذج [`TFDistilBertForQuestionAnswering`]. رأس الإجابة على الأسئلة مشابه لرأس التصنيف التسلسلي باستثناء أنه طبقة خطية أعلى حالات الإخراج المخفية. - -```py ->>> from transformers import TFDistilBertForQuestionAnswering - ->>> tf_model = TFDistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") -``` - ## مجزئ النصوص diff --git a/docs/source/ar/model_sharing.md b/docs/source/ar/model_sharing.md index b4b1bb821b9b..c50c2cf40fbe 100644 --- a/docs/source/ar/model_sharing.md +++ b/docs/source/ar/model_sharing.md @@ -74,28 +74,6 @@ pip install huggingface_hub >>> pt_model.save_pretrained("path/to/awesome-name-you-picked") ``` - -حدد `from_pt=True` لتحويل نقطة تحقق من PyTorch إلى TensorFlow: - -```py ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_pt=True) -``` - -بعد ذلك، يمكنك حفظ نموذج TensorFlow الجديد بنقطة التحقق الجديدة: - -```py ->>> tf_model.save_pretrained("path/to/awesome-name-you-picked") -``` - - -إذا كان النموذج متاحًا في Flax، فيمكنك أيضًا تحويل نقطة تحقق من PyTorch إلى Flax: - -```py ->>> flax_model = FlaxDistilBertForSequenceClassification.from_pretrained( -... "path/to/awesome-name-you-picked", from_pt=True -... ) -``` - ## دفع نموذج أثناء التدريب @@ -128,27 +106,6 @@ pip install huggingface_hub >>> trainer.push_to_hub() ``` - -شارك نموذجًا على Hub باستخدام [`PushToHubCallback`]. في دالة [`PushToHubCallback`], أضف: - -- دليل إخراج لنموذجك. -- مُجزّئ اللغوي. -- `hub_model_id`، والذي هو اسم مستخدم Hub واسم النموذج الخاص بك. - -```py ->>> from transformers import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="./your_model_save_path", tokenizer=tokenizer, hub_model_id="your-username/my-awesome-model" -... ) -``` - -أضف الاستدعاء إلى [`fit`](https://keras.io/api/models/model_training_apis/)، وسيقوم 🤗 Transformers بدفع النموذج المدرب إلى Hub: - -```py ->>> model.fit(tf_train_dataset, validation_data=tf_validation_dataset, epochs=3, callbacks=push_to_hub_callback) -``` - ## استخدام دالة `push_to_hub` @@ -220,4 +177,4 @@ pip install huggingface_hub * قم بإنشاء ملف `README.md` وتحميله يدويًا. * انقر فوق الزر **Edit model card** في مستودع نموذجك. -الق نظرة على بطاقة [DistilBert](https://huggingface.co/distilbert/distilbert-base-uncased) للحصول على مثال جيد على نوع المعلومات التي يجب أن تتضمنها بطاقة النموذج. للحصول على مزيد من التفاصيل حول الخيارات الأخرى التي يمكنك التحكم فيها في ملف `README.md` مثل البصمة الكربونية للنموذج أو أمثلة الأداة، راجع الوثائق [هنا](https://huggingface.co/docs/hub/models-cards). \ No newline at end of file +الق نظرة على بطاقة [DistilBert](https://huggingface.co/distilbert/distilbert-base-uncased) للحصول على مثال جيد على نوع المعلومات التي يجب أن تتضمنها بطاقة النموذج. للحصول على مزيد من التفاصيل حول الخيارات الأخرى التي يمكنك التحكم فيها في ملف `README.md` مثل البصمة الكربونية للنموذج أو أمثلة الأداة، راجع الوثائق [هنا](https://huggingface.co/docs/hub/models-cards). diff --git a/docs/source/ar/preprocessing.md b/docs/source/ar/preprocessing.md index 8c1f68934d20..18ab522e436c 100644 --- a/docs/source/ar/preprocessing.md +++ b/docs/source/ar/preprocessing.md @@ -174,31 +174,6 @@ pip install datasets [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])} ``` - - -```py ->>> batch_sentences = [ -... "But what about second breakfast?", -... "Don't think he knows about second breakfast, Pip.", -... "What about elevensies?", -... ] ->>> encoded_input = tokenizer(batch_sentences, padding=True, truncation=True, return_tensors="tf") ->>> print(encoded_input) -{'input_ids': , - 'token_type_ids': , - 'attention_mask': } -``` - diff --git a/docs/source/ar/quicktour.md b/docs/source/ar/quicktour.md index 1795c3a5d74f..aebcc847ae58 100644 --- a/docs/source/ar/quicktour.md +++ b/docs/source/ar/quicktour.md @@ -19,12 +19,6 @@ pip install torch ``` - - -```bash -pip install tensorflow -``` - ## خط الأنابيب @@ -133,16 +127,6 @@ label: NEGATIVE, with score: 0.5309 >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - -استخدم [`TFAutoModelForSequenceClassification`] و [`AutoTokenizer`] لتحميل النموذج المُدرب مسبقًا ومعالجته المرتبط به (مزيد من المعلومات حول `TFAutoClass` في القسم التالي): - -```py ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - حدد النموذج والمعالج في [`pipeline`]. الآن يمكنك تطبيق `classifier` على النص الفرنسي: @@ -205,18 +189,6 @@ label: NEGATIVE, with score: 0.5309 ... ) ``` - - -```py ->>> tf_batch = tokenizer( -... ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="tf", -... ) -``` - @@ -265,37 +237,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - -يوفر 🤗 Transformers طريقة بسيطة وموحدة لتحميل مثيلات مُدربة مسبقًا. وهذا يعني أنه يمكنك تحميل [`TFAutoModel`] مثل تحميل [`AutoTokenizer`]. والفرق الوحيد هو تحديد [`TFAutoModel`] الصحيح للمهمة. للتصنيف النصي (أو التسلسلي)، يجب تحميل [`TFAutoModelForSequenceClassification`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name) -``` - - - -راجع [ملخص المهام](./task_summary) للمهام المدعومة بواسطة فئة [`AutoModel`]. - - - -الآن، مرر دفعة المدخلات المعالجة مسبقًا مباشرة إلى النموذج. يمكنك تمرير المصفوفات كما هي: - -```py ->>> tf_outputs = tf_model(tf_batch) -``` - -يقوم النموذج بإخراج التنشيطات النهائية في سمة `logits`. طبق دالة softmax على `logits` لاسترداد الاحتمالات: - -```py ->>> import tensorflow as tf - ->>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1) ->>> tf_predictions # doctest: +IGNORE_RESULT -``` - @@ -322,21 +263,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - -بمجرد ضبط نموذجك، يمكنك حفظه مع برنامج الترميز الخاص به باستخدام [`TFPreTrainedModel.save_pretrained`]: - -```py ->>> tf_save_directory = "./tf_save_pretrained" ->>> tokenizer.save_pretrained(tf_save_directory) # doctest: +IGNORE_RESULT ->>> tf_model.save_pretrained(tf_save_directory) -``` - -عندما تكون مستعدًا لاستخدام النموذج مرة أخرى، أعد تحميله باستخدام [`TFPreTrainedModel.from_pretrained`]: - -```py ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained") -``` - من الميزات الرائعة في 🤗 Transformers القدرة على حفظ نموذج وإعادة تحميله كنموذج PyTorch أو TensorFlow. يمكن أن يحول معامل `from_pt` أو `from_tf` النموذج من إطار عمل إلى آخر: @@ -351,15 +277,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - -```py ->>> from transformers import TFAutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory) ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) -``` - @@ -385,15 +302,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_model = AutoModel.from_config(my_config) ``` - -قم بإنشاء نموذج من تكوينك المخصص باستخدام [`TFAutoModel.from_config`]: - -```py ->>> from transformers import TFAutoModel - ->>> my_model = TFAutoModel.from_config(my_config) -``` - الق نظرة على دليل [إنشاء بنية مخصصة](./create_a_model) لمزيد من المعلومات حول بناء التكوينات المخصصة. diff --git a/docs/source/ar/run_scripts.md b/docs/source/ar/run_scripts.md index f7673408ca7d..784703a4bbfc 100644 --- a/docs/source/ar/run_scripts.md +++ b/docs/source/ar/run_scripts.md @@ -99,26 +99,6 @@ python examples/pytorch/summarization/run_summarization.py \ --predict_with_generate ``` - - -- يقوم النص البرمجي التوضيحي بتنزيل مجموعة بيانات ومعالجتها مسبقًا من مكتبة 🤗 [Datasets](https://huggingface.co/docs/datasets/). -- ثم يقوم النص البرمجي بضبط نموذج بيانات دقيق باستخدام Keras على بنية تدعم الملخص. -- يوضح المثال التالي كيفية ضبط نموذج [T5-small](https://huggingface.co/google-t5/t5-small) على مجموعة بيانات [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail). -- يتطلب نموذج T5 ماعمل `source_prefix` إضافية بسبب الطريقة التي تم تدريبه بها. يتيح هذا المطالبة لـ T5 معرفة أن هذه مهمة التلخيص. - -```bash -python examples/tensorflow/summarization/run_summarization.py \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## التدريب الموزع والدقة المختلطة @@ -170,23 +150,6 @@ python xla_spawn.py --num_cores 8 \ --predict_with_generate ``` - - -تُعد وحدات معالجة الدقة الفائقة (TPUs) مصممة خصيصًا لتسريع الأداء. تستخدم نصوص TensorFlow البرمجية استراتيجية [`TPUStrategy`](https://www.tensorflow.org/guide/distributed_training#tpustrategy) للتدريب على وحدات معالجة الدقة الفائقة (TPUs). لاستخدام وحدة معالجة الدقة الفائقة (TPU)، قم بتمرير اسم مورد وحدة معالجة الدقة الفائقة (TPU) إلى حجة `tpu`. -```bash -python run_summarization.py \ - --tpu name_of_tpu_resource \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## تشغيل نص برمجي باستخدام 🤗 Accelerate diff --git a/docs/source/ar/tasks/language_modeling.md b/docs/source/ar/tasks/language_modeling.md index 24f2db00a7a6..c0788a47a6b5 100644 --- a/docs/source/ar/tasks/language_modeling.md +++ b/docs/source/ar/tasks/language_modeling.md @@ -194,16 +194,6 @@ pip install transformers datasets evaluate ``` - -استخدم رمز نهاية التسلسل كرمز للحشو، وحدد `mlm_probability` لحجب الرموز بشكل عشوائي عند كل تكرار للبيانات: - -```py ->>> from transformers import DataCollatorForLanguageModeling - ->>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False, return_tensors="tf") -``` - - ## التدريب (Train) @@ -268,73 +258,6 @@ Perplexity: 49.61 >>> trainer.push_to_hub() ``` - - - -إذا لم تكن على دراية بتدريب نموذج باستخدام Keras، اطلع على [البرنامج التعليمي الأساسي](../training#train-a-tensorflow-model-with-keras)! - - -لتدريب نموذج في TensorFlow، ابدأ بإعداد دالة المحسن، وجدول معدل التعلم، وبعض معاملات التدريب: - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -ثم يمكنك تحميل DistilGPT2 باستخدام [`TFAutoModelForCausalLM`]: - -```py ->>> from transformers import TFAutoModelForCausalLM - ->>> model = TFAutoModelForCausalLM.from_pretrained("distilbert/distilgpt2") -``` - -حول مجموعات بياناتك إلى تنسيق `tf.data.Dataset` باستخدام [`~transformers.TFPreTrainedModel.prepare_tf_dataset`]: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... lm_dataset["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... lm_dataset["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -قم بتهيئة النموذج للتدريب باستخدام [`compile`](https://keras.io/api/models/model_training_apis/#compile-method). لاحظ أن جميع نماذج Transformers لديها دالة خسارة ذات صلة بالمهمة الافتراضية، لذلك لا تحتاج إلى تحديد واحدة ما لم ترغب في ذلك: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # لا يوجد حجة للخسارة! -``` - -يمكن القيام بذلك عن طريق تحديد مكان دفع نموذجك ومجمّع البيانات في [`~transformers.PushToHubCallback`]: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> callback = PushToHubCallback( -... output_dir="my_awesome_eli5_clm-model", -... tokenizer=tokenizer, -... ) -``` - -أخيراً، أنت جاهز لبدء تدريب نموذجك! قم باستدعاء [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) مع مجموعات بيانات التدريب والتحقق من الصحة، وعدد العصور، والتعليقات الخاصة بك لتدريب النموذج: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=[callback]) -``` - -بمجرد اكتمال التدريب، يتم تحميل نموذجك تلقائيًا إلى Hub حتى يتمكن الجميع من استخدامه! - @@ -393,30 +316,4 @@ Perplexity: 49.61 ["Somatic hypermutation allows the immune system to react to drugs with the ability to adapt to a different environmental situation. In other words, a system of 'hypermutation' can help the immune system to adapt to a different environmental situation or in some cases even a single life. In contrast, researchers at the University of Massachusetts-Boston have found that 'hypermutation' is much stronger in mice than in humans but can be found in humans, and that it's not completely unknown to the immune system. A study on how the immune system"] ``` - -قم بتقسيم النص وإرجاع `input_ids` كـ TensorFlow tensors: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_eli5_clm-model") ->>> inputs = tokenizer(prompt, return_tensors="tf").input_ids -``` - -استخدم طريقة [`~transformers.generation_tf_utils.TFGenerationMixin.generate`] لإنشاء الملخص. للمزيد من التفاصيل حول استراتيجيات توليد النص المختلفة والبارامترات للتحكم في التوليد، راجع صفحة [استراتيجيات توليد النص](../generation_strategies). - -```py ->>> from transformers import TFAutoModelForCausalLM - ->>> model = TFAutoModelForCausalLM.from_pretrained("username/my_awesome_eli5_clm-model") ->>> outputs = model.generate(input_ids=inputs, max_new_tokens=100, do_sample=True, top_k=50, top_p=0.95) -``` - -فك ترميز الرموز المولدة مرة أخرى إلى نص: - -```py ->>> tokenizer.batch_decode(outputs, skip_special_tokens=True) -['Somatic hypermutation allows the immune system to detect the presence of other viruses as they become more prevalent. Therefore, researchers have identified a high proportion of human viruses. The proportion of virus-associated viruses in our study increases with age. Therefore, we propose a simple algorithm to detect the presence of these new viruses in our samples as a sign of improved immunity. A first study based on this algorithm, which will be published in Science on Friday, aims to show that this finding could translate into the development of a better vaccine that is more effective for'] -``` - - \ No newline at end of file + diff --git a/docs/source/ar/tasks/masked_language_modeling.md b/docs/source/ar/tasks/masked_language_modeling.md index e8382927d1e6..34c3913224c0 100644 --- a/docs/source/ar/tasks/masked_language_modeling.md +++ b/docs/source/ar/tasks/masked_language_modeling.md @@ -188,16 +188,6 @@ pip install transformers datasets evaluate >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15) ``` - - -استخدم رمز نهاية التسلسل كرمز الحشو وحدد `mlm_probability` لحجب الرموز عشوائياً كل مرة تكرر فيها البيانات: - -```py ->>> from transformers import DataCollatorForLanguageModeling - ->>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15, return_tensors="tf") -``` - ## التدريب (Train) @@ -264,73 +254,6 @@ Perplexity: 8.76 >>> trainer.push_to_hub() ``` - - - -إذا لم تكن على دراية بتعديل نموذج باستخدام Keras، ألق نظرة على الدليل الأساسي [هنا](../training#train-a-tensorflow-model-with-keras)! - - -لتعديل نموذج في TensorFlow، ابدأ بإعداد دالة محسن، وجدول معدل التعلم، وبعض معلمات التدريب: - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -ثم يمكنك تحميل DistilRoBERTa باستخدام [`TFAutoModelForMaskedLM`]: - -```py ->>> from transformers import TFAutoModelForMaskedLM - ->>> model = TFAutoModelForMaskedLM.from_pretrained("distilbert/distilroberta-base") -``` - -قم بتحويل مجموعات بياناتك إلى تنسيق `tf.data.Dataset` باستخدام [`~transformers.TFPreTrainedModel.prepare_tf_dataset`]: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... lm_dataset["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... lm_dataset["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -قم بتهيئة النموذج للتدريب باستخدام [`compile`](https://keras.io/api/models/model_training_apis/#compile-method). لاحظ أن نماذج Transformers لديها جميعها دالة خسارة افتراضية ذات صلة بالمهمة، لذلك لا تحتاج إلى تحديد واحدة ما لم تكن تريد ذلك: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # لا توجد حجة للخسارة! -``` - -يمكن القيام بذلك عن طريق تحديد مكان دفع نموذجك ومعالج الرموز في [`~transformers.PushToHubCallback`]: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> callback = PushToHubCallback( -... output_dir="my_awesome_eli5_mlm_model", -... tokenizer=tokenizer, -... ) -``` - -أخيراً، أنت مستعد لبدء تدريب نموذجك! قم باستدعاء [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) مع مجموعات بيانات التدريب والتحقق، وعدد العصور، والتعليقات الخاصة بك لتعديل النموذج: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=[callback]) -``` - -بمجرد اكتمال التدريب، يتم تحميل نموذجك تلقائياً إلى Hub حتى يتمكن الجميع من استخدامه! - @@ -406,37 +329,4 @@ The Milky Way is a massive galaxy. The Milky Way is a small galaxy. ``` - -قم بتقسيم النص إلى رموز وإرجاع `input_ids` كـ TensorFlow tensors. ستحتاج أيضًا إلى تحديد موضع رمز ``: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_eli5_mlm_model") ->>> inputs = tokenizer(text, return_tensors="tf") ->>> mask_token_index = tf.where(inputs["input_ids"] == tokenizer.mask_token_id)[0, 1] -``` - -قم بتمرير المدخلات إلى النموذج وإرجاع `logits` للرمز المقنع: - -```py ->>> from transformers import TFAutoModelForMaskedLM - ->>> model = TFAutoModelForMaskedLM.from_pretrained("username/my_awesome_eli5_mlm_model") ->>> logits = model(**inputs).logits ->>> mask_token_logits = logits[0, mask_token_index, :] -``` - -ثم قم بإرجاع الرموز الثلاثة المقنعة ذات الاحتمالية الأعلى وطباعتها: - -```py ->>> top_3_tokens = tf.math.top_k(mask_token_logits, 3).indices.numpy() - ->>> for token in top_3_tokens: -... print(text.replace(tokenizer.mask_token, tokenizer.decode([token]))) -The Milky Way is a spiral galaxy. -The Milky Way is a massive galaxy. -The Milky Way is a small galaxy. -``` - - \ No newline at end of file + diff --git a/docs/source/ar/tasks/multiple_choice.md b/docs/source/ar/tasks/multiple_choice.md index 78f98560754f..3a849251c992 100644 --- a/docs/source/ar/tasks/multiple_choice.md +++ b/docs/source/ar/tasks/multiple_choice.md @@ -159,48 +159,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) ... return batch ``` - - -```py ->>> from dataclasses import dataclass ->>> from transformers.tokenization_utils_base import PreTrainedTokenizerBase, PaddingStrategy ->>> from typing import Optional, Union ->>> import tensorflow as tf - ->>> @dataclass -... class DataCollatorForMultipleChoice: -... """ -... Data collator that will dynamically pad the inputs for multiple choice received. -... """ - -... tokenizer: PreTrainedTokenizerBase -... padding: Union[bool, str, PaddingStrategy] = True -... max_length: Optional[int] = None -... pad_to_multiple_of: Optional[int] = None - -... def __call__(self, features): -... label_name = "label" if "label" in features[0].keys() else "labels" -... labels = [feature.pop(label_name) for feature in features] -... batch_size = len(features) -... num_choices = len(features[0]["input_ids"]) -... flattened_features = [ -... [{k: v[i] for k, v in feature.items()} for i in range(num_choices)] for feature in features -... ] -... flattened_features = sum(flattened_features, []) - -... batch = self.tokenizer.pad( -... flattened_features, -... padding=self.padding, -... max_length=self.max_length, -... pad_to_multiple_of=self.pad_to_multiple_of, -... return_tensors="tf", -... ) - -... batch = {k: tf.reshape(v, (batch_size, num_choices, -1)) for k, v in batch.items()} -... batch["labels"] = tf.convert_to_tensor(labels, dtype=tf.int64) -... return batch -``` - ## التقييم (Evaluate) @@ -284,91 +242,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) >>> trainer.push_to_hub() ``` - - - -إذا لم تكن معتادًا على ضبط نموذج باستخدام Keras، فراجع الدرس الأساسي [هنا](../training#train-a-tensorflow-model-with-keras)! - - -لضبط نموذج في TensorFlow، ابدأ بإعداد دالة مُحسِّن وجدول معدل التعلم وبعض معلمات التدريب: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_train_epochs = 2 ->>> total_train_steps = (len(tokenized_swag["train"]) // batch_size) * num_train_epochs ->>> optimizer, schedule = create_optimizer(init_lr=5e-5, num_warmup_steps=0, num_train_steps=total_train_steps) -``` - -ثم يمكنك تحميل BERT باستخدام [`TFAutoModelForMultipleChoice`]: - -```py ->>> from transformers import TFAutoModelForMultipleChoice - ->>> model = TFAutoModelForMultipleChoice.from_pretrained("google-bert/bert-base-uncased") -``` - -حوّل مجموعات البيانات الخاصة بك إلى تنسيق `tf.data.Dataset` باستخدام [`~transformers.TFPreTrainedModel.prepare_tf_dataset`]: - -```py ->>> data_collator = DataCollatorForMultipleChoice(tokenizer=tokenizer) ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_swag["train"], -... shuffle=True, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_swag["validation"], -... shuffle=False, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) -``` - -قم بتهيئة النموذج للتدريب باستخدام [`compile`](https://keras.io/api/models/model_training_apis/#compile-method). لاحظ أن جميع نماذج Transformers تحتوي على دالة خسارة مناسبة للمهمة بشكل افتراضي، لذلك لا تحتاج إلى تحديد واحدة ما لم ترغب في ذلك: - -```py ->>> model.compile(optimizer=optimizer) # لا توجد وسيطة خسارة! -``` - -الخطوتان الأخيرتان قبل بدء التدريب هما: حساب دقة التنبؤات، وتوفير طريقة لرفع النموذج إلى Hub. ويمكن تحقيق ذلك باستخدام [استدعاءات Keras](../main_classes/keras_callbacks) - -مرر دالتك `compute_metrics` إلى [`~transformers.KerasMetricCallback`]: - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -حدد مكان دفع نموذجك ومعالجك في [`~transformers.PushToHubCallback`]: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_model", -... tokenizer=tokenizer, -... ) -``` - -ثم قم بتضمين الاستدعاءات معًا: - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -أخيرًا، أنت جاهز لبدء تدريب نموذجك! استدعِ[`fit`](https://keras.io/api/models/model_training_apis/#fit-method) مع مجموعات بيانات التدريب والتحقق من الصحة وعدد الحقب والاستدعاءات لضبط النموذج: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=2, callbacks=callbacks) -``` - -بمجرد اكتمال التدريب، يتم تحميل نموذجك تلقائيًا إلى Hub حتى يتمكن الجميع من استخدامه! - @@ -420,33 +293,4 @@ tokenized_swag = swag.map(preprocess_function, batched=True) 0 ``` - -قم بتحليل كل مطالبة وزوج إجابة مرشح وأعد موترات TensorFlow: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_swag_model") ->>> inputs = tokenizer([[prompt, candidate1], [prompt, candidate2]], return_tensors="tf", padding=True) -``` - -مرر مدخلاتك إلى النموذج وأعد القيم logits: - -```py ->>> from transformers import TFAutoModelForMultipleChoice - ->>> model = TFAutoModelForMultipleChoice.from_pretrained("username/my_awesome_swag_model") ->>> inputs = {k: tf.expand_dims(v, 0) for k, v in inputs.items()} ->>> outputs = model(inputs) ->>> logits = outputs.logits -``` - -استخرج الفئة ذات الاحتمالية الأكبر: - -```py ->>> predicted_class = int(tf.math.argmax(logits, axis=-1)[0]) ->>> predicted_class -0 -``` - diff --git a/docs/source/ar/tasks/question_answering.md b/docs/source/ar/tasks/question_answering.md index 0c4b66443d81..d86816a13c84 100644 --- a/docs/source/ar/tasks/question_answering.md +++ b/docs/source/ar/tasks/question_answering.md @@ -176,14 +176,6 @@ pip install transformers datasets evaluate >>> data_collator = DefaultDataCollator() ``` - - -```py ->>> from transformers import DefaultDataCollator - ->>> data_collator = DefaultDataCollator(return_tensors="tf") -``` - ## التدريب (Train) @@ -241,80 +233,6 @@ pip install transformers datasets evaluate >>> trainer.push_to_hub() ``` - - - - -إذا لم تكن معتادًا على ضبط نموذج باستخدام Keras، فألق نظرة على البرنامج التعليمي الأساسي [هنا](../training#train-a-tensorflow-model-with-keras)! - - -لضبط نموذج في TensorFlow، ابدأ بإعداد دالة مُحسِّن، وجدول معدل التعلم، وبعض المعاملات الفائقة للتدريب: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_epochs = 2 ->>> total_train_steps = (len(tokenized_squad["train"]) // batch_size) * num_epochs ->>> optimizer, schedule = create_optimizer( -... init_lr=2e-5, -... num_warmup_steps=0, -... num_train_steps=total_train_steps, -... ) -``` - -ثم يمكنك تحميل DistilBERT باستخدام [`TFAutoModelForQuestionAnswering`]: - -```py ->>> from transformers import TFAutoModelForQuestionAnswering - ->>> model = TFAutoModelForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") -``` - -حوّل مجموعات البيانات الخاصة بك إلى تنسيق `tf.data.Dataset` باستخدام [`~transformers.TFPreTrainedModel.prepare_tf_dataset`]: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_squad["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_squad["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -قم بتكوين النموذج للتدريب باستخدام [`compile`](https://keras.io/api/models/model_training_apis/#compile-method): - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -آخر شيء يجب إعداده قبل بدء التدريب هو توفير طريقة لدفع نموذجك إلى Hub. يمكن القيام بذلك عن طريق تحديد مكان دفع نموذجك ومعالجك المعجمي في [`~transformers.PushToHubCallback`]: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> callback = PushToHubCallback( -... output_dir="my_awesome_qa_model", -... tokenizer=tokenizer, -... ) -``` - -أخيرًا، أنت جاهز لبدء تدريب نموذجك! اتصل بـ [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) مع مجموعات بيانات التدريب والتحقق من الصحة، وعدد العهود، ومعاودة الاتصال الخاصة بك لضبط النموذج: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3, callbacks=[callback]) -``` -بمجرد اكتمال التدريب، يتم تحميل نموذجك تلقائيًا إلى Hub حتى يتمكن الجميع من استخدامه! - @@ -395,38 +313,4 @@ pip install transformers datasets evaluate '176 billion parameters and can generate text in 46 languages natural languages and 13' ``` - -قم بتحليل النص المعجمي وأعد موترات TensorFlow: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_qa_model") ->>> inputs = tokenizer(question, context, return_tensors="tf") -``` - -مرر مدخلاتك إلى النموذج وأعد `logits`: - -```py ->>> from transformers import TFAutoModelForQuestionAnswering - ->>> model = TFAutoModelForQuestionAnswering.from_pretrained("my_awesome_qa_model") ->>> outputs = model(**inputs) -``` - -احصل على أعلى احتمال من مخرجات النموذج لموضعي البداية والنهاية: - -```py ->>> answer_start_index = int(tf.math.argmax(outputs.start_logits, axis=-1)[0]) ->>> answer_end_index = int(tf.math.argmax(outputs.end_logits, axis=-1)[0]) -``` - -استخلاص الإجابة من الرموز المتوقعة: - -```py ->>> predict_answer_tokens = inputs.input_ids[0, answer_start_index : answer_end_index + 1] ->>> tokenizer.decode(predict_answer_tokens) -'176 billion parameters and can generate text in 46 languages natural languages and 13' -``` - diff --git a/docs/source/ar/tasks/sequence_classification.md b/docs/source/ar/tasks/sequence_classification.md index a98964957b47..f73dc634489f 100644 --- a/docs/source/ar/tasks/sequence_classification.md +++ b/docs/source/ar/tasks/sequence_classification.md @@ -101,14 +101,6 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) >>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer) ``` - - -```py ->>> from transformers import DataCollatorWithPadding - ->>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer, return_tensors="tf") -``` - ## التقييم(Evaluate) @@ -206,96 +198,6 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) >>> trainer.push_to_hub() ``` - - - -إذا لم تكن على دراية بضبط نموذج باستخدام Keras، قم بالاطلاع على البرنامج التعليمي الأساسي [هنا](../training#train-a-tensorflow-model-with-keras)! - - -لضبط نموذج في TensorFlow، ابدأ بإعداد دالة المحسن، وجدول معدل التعلم، وبعض معلمات التدريب: - -```py ->>> from transformers import create_optimizer ->>> import tensorflow as tf - ->>> batch_size = 16 ->>> num_epochs = 5 ->>> batches_per_epoch = len(tokenized_imdb["train"]) // batch_size ->>> total_train_steps = int(batches_per_epoch * num_epochs) ->>> optimizer, schedule = create_optimizer(init_lr=2e-5, num_warmup_steps=0, num_train_steps=total_train_steps) -``` - -ثم يمكنك تحميل DistilBERT مع [`TFAutoModelForSequenceClassification`] بالإضافة إلى عدد التصنيفات المتوقعة، وتعيينات التسميات: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained( -... "distilbert/distilbert-base-uncased", num_labels=2, id2label=id2label, label2id=label2id -... ) -``` - -قم بتحويل مجموعات بياناتك إلى تنسيق `tf.data.Dataset` باستخدام [`~transformers.TFPreTrainedModel.prepare_tf_dataset`]: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_imdb["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_imdb["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -قم بتهيئة النموذج للتدريب باستخدام [`compile`](https://keras.io/api/models/model_training_apis/#compile-method). لاحظ أن جميع نماذج Transformers لديها دالة خسارة ذات صلة بالمهمة بشكل افتراضي، لذلك لا تحتاج إلى تحديد واحدة ما لم ترغب في ذلك: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # No loss argument! -``` - -آخر أمرين يجب إعدادهما قبل بدء التدريب هو حساب الدقة من التوقعات، وتوفير طريقة لدفع نموذجك إلى Hub. يتم ذلك باستخدام [Keras callbacks](../main_classes/keras_callbacks). - -قم بتمرير دالة `compute_metrics` الخاصة بك إلى [`~transformers.KerasMetricCallback`]: - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -حدد مكان دفع نموذجك والمجزئ اللغوي في [`~transformers.PushToHubCallback`]: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_model", -... tokenizer=tokenizer, -... ) -``` - -ثم اجمع الاستدعاءات معًا: - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -أخيرًا، أنت مستعد لبدء تدريب نموذجك! قم باستدعاء [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) مع مجموعات بيانات التدريب والتحقق، وعدد الحقبات، واستدعاءاتك لضبط النموذج: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3, callbacks=callbacks) -``` - -بمجرد اكتمال التدريب، يتم تحميل نموذجك تلقائيًا إلى Hub حتى يتمكن الجميع من استخدامه! - @@ -357,31 +259,4 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) 'POSITIVE' ``` - -قم بتحليل النص وإرجاع تنسيقات TensorFlow: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_model") ->>> inputs = tokenizer(text, return_tensors="tf") -``` - -قم بتمرير مدخلاتك إلى النموذج وإرجاع `logits`: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("stevhliu/my_awesome_model") ->>> logits = model(**inputs).logits -``` - -استخرج الفئة ذات الاحتمالية الأعلى، واستخدم `id2label` لتحويلها إلى تصنيف نصي: - -```py ->>> predicted_class_id = int(tf.math.argmax(logits, axis=-1)[0]) ->>> model.config.id2label[predicted_class_id] -'POSITIVE' -``` - diff --git a/docs/source/ar/tasks/summarization.md b/docs/source/ar/tasks/summarization.md index 17dbcb42e837..45c99767483f 100644 --- a/docs/source/ar/tasks/summarization.md +++ b/docs/source/ar/tasks/summarization.md @@ -127,14 +127,6 @@ pip install transformers datasets evaluate rouge_score >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - -```py ->>> from transformers import DataCollatorForSeq2Seq - ->>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint, return_tensors="tf") -``` - ## التقييم (Evaluate) @@ -227,89 +219,6 @@ pip install transformers datasets evaluate rouge_score >>> trainer.push_to_hub() ``` - - - -إذا لم تكن معتادًا على ضبط نموذج باستخدام Keras، فألق نظرة على البرنامج التعليمي الأساسي [هنا](../training#train-a-tensorflow-model-with-keras)! - - -لضبط نموذج في TensorFlow، ابدأ بإعداد دالة مُحسِّن وجدول معدل التعلم وبعض معلمات التدريب: - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -ثم يمكنك تحميل T5 باستخدام [`TFAutoModelForSeq2SeqLM`]: - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained(checkpoint) -``` - -حوّل مجموعات البيانات الخاصة بك إلى تنسيق `tf.data.Dataset` باستخدام [`~transformers.TFPreTrainedModel.prepare_tf_dataset`]: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_billsum["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... tokenized_billsum["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -قم بتكوين النموذج للتدريب باستخدام [`compile`](https://keras.io/api/models/model_training_apis/#compile-method). لاحظ أن جميع نماذج Transformers لديها دالة خسارة ذات صلة بالمهمة افتراضيًا، لذلك لست بحاجة إلى تحديد واحدة ما لم تكن ترغب في ذلك: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # No loss argument! -``` - -آخر شيئين يجب إعدادهما قبل بدء التدريب هما حساب درجة ROUGE من التنبؤات، وتوفير طريقة لدفع نموذجك إلى Hub. يتم كلاهما باستخدام [استدعاءات Keras](../main_classes/keras_callbacks). - -مرر دالة `compute_metrics` الخاصة بك إلى [`~transformers.KerasMetricCallback`]: - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_test_set) -``` - -حدد مكان دفع نموذجك ومُحلِّلك اللغوي في [`~transformers.PushToHubCallback`]: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_billsum_model", -... tokenizer=tokenizer, -... ) -``` - -ثم اجمع استدعاءاتك معًا: - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -أخيرًا، أنت جاهز لبدء تدريب نموذجك! اتصل بـ [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) مع مجموعات بيانات التدريب والتحقق من الصحة وعدد الحقب واستدعاءاتك لضبط النموذج: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=callbacks) -``` - -بمجرد اكتمال التدريب، يتم تحميل نموذجك تلقائيًا إلى Hub حتى يتمكن الجميع من استخدامه! - @@ -368,30 +277,4 @@ pip install transformers datasets evaluate rouge_score 'the inflation reduction act lowers prescription drug costs, health care costs, and energy costs. it's the most aggressive action on tackling the climate crisis in american history. it will ask the ultra-wealthy and corporations to pay their fair share.' ``` - -قسم النص وإرجع `input_ids` كتنسورات TensorFlow: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_billsum_model") ->>> inputs = tokenizer(text, return_tensors="tf").input_ids -``` - -استخدم طريقة [`~transformers.generation_tf_utils.TFGenerationMixin.generate`] لإنشاء التلخيص. لمزيد من التفاصيل حول استراتيجيات توليد النص المختلفة والمعلمات للتحكم في التوليد، راجع واجهة برمجة تطبيقات [توليد النص](../main_classes/text_generation). - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained("username/my_awesome_billsum_model") ->>> outputs = model.generate(inputs, max_new_tokens=100, do_sample=False) -``` - -فك تشفير معرفات الرموز المولدة مرة أخرى إلى نص: - -```py ->>> tokenizer.decode(outputs[0], skip_special_tokens=True) -'the inflation reduction act lowers prescription drug costs, health care costs, and energy costs. it's the most aggressive action on tackling the climate crisis in american history. it will ask the ultra-wealthy and corporations to pay their fair share.' -``` - - \ No newline at end of file + diff --git a/docs/source/ar/tasks/token_classification.md b/docs/source/ar/tasks/token_classification.md index e311482aeccb..fe8ff5116adb 100644 --- a/docs/source/ar/tasks/token_classification.md +++ b/docs/source/ar/tasks/token_classification.md @@ -159,13 +159,6 @@ pip install transformers datasets evaluate seqeval >>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer) ``` - -```py ->>> from transformers import DataCollatorForTokenClassification - ->>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer, return_tensors="tf") -``` - ## التقييم(Evaluate) @@ -303,99 +296,6 @@ pip install transformers datasets evaluate seqeval >>> trainer.push_to_hub() ``` - - - -إذا لم تكن على دراية بتعديل نموذج باستخدام Keras، ألق نظرة على الدليل التعليمي الأساسي [هنا](../training#train-a-tensorflow-model-with-keras)! - - -للتعديل على نموذج في TensorFlow، ابدأ بإعداد دالة محسن، وجدول معدل التعلم، وبعض معلمات التدريب: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_train_epochs = 3 ->>> num_train_steps = (len(tokenized_wnut["train"]) // batch_size) * num_train_epochs ->>> optimizer, lr_schedule = create_optimizer( -... init_lr=2e-5, -... num_train_steps=num_train_steps, -... weight_decay_rate=0.01, -... num_warmup_steps=0, -... ) -``` - -ثم يمكنك تحميل DistilBERT مع [`TFAutoModelForTokenClassification`] إلى جانب عدد التسميات المتوقعة، وتخطيطات التسميات: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained( -... "distilbert/distilbert-base-uncased", num_labels=13, id2label=id2label, label2id=label2id -... ) -``` - -قم بتحويل مجموعات بياناتك إلى تنسيق `tf.data.Dataset` مع [`~transformers.TFPreTrainedModel.prepare_tf_dataset`]: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_wnut["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_wnut["validation"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -هيّئ النموذج للتدريب باستخدام [`compile`](https://keras.io/api/models/model_training_apis/#compile-method). لاحظ أن نماذج Transformers تتضمن دالة خسارة افتراضية مرتبطة بالمهمة، لذلك لا تحتاج إلى تحديد واحدة إلا إذا كنت ترغب في ذلك: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # No loss argument! -``` - -آخر أمرين يجب إعدادهما قبل بدء التدريب هو حساب درجات seqeval من التنبؤات، وتوفير طريقة لدفع نموذجك إلى Hub. يتم ذلك باستخدام [Keras callbacks](../main_classes/keras_callbacks). - -مرر دالة `compute_metrics` الخاصة بك إلى [`~transformers.KerasMetricCallback`]: - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -حدد مكان دفع نموذجك والمحلل اللغوي في [`~transformers.PushToHubCallback`]: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_wnut_model", -... tokenizer=tokenizer, -... ) -``` - -ثم جمّع callbacks الخاصة بك معًا: - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -أخيرًا، أنت جاهز الآن لبدء تدريب نموذجك! قم باستدعاء [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) مع بيانات التدريب والتحقق، وعدد الحقبات، وcallbacks لتعديل النموذج: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3, callbacks=callbacks) -``` - -بمجرد اكتمال التدريب، يتم تحميل نموذجك تلقائيًا إلى Hub حتى يتمكن الجميع من استخدامه! - @@ -503,48 +403,4 @@ pip install transformers datasets evaluate seqeval 'O'] ``` - -قسّم النص إلى رموز وأرجع المُوتّرات ب TensorFlow: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_wnut_model") ->>> inputs = tokenizer(text, return_tensors="tf") -``` - -مرر مدخلاتك إلى النموذج واحصل على `logits`: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("stevhliu/my_awesome_wnut_model") ->>> logits = model(**inputs).logits -``` - -استخرج الفئة ذات الاحتمالية الأعلى، واستخدم جدول `id2label` الخاصة بالنموذج لتحويلها إلى تسمية نصية: - -```py ->>> predicted_token_class_ids = tf.math.argmax(logits, axis=-1) ->>> predicted_token_class = [model.config.id2label[t] for t in predicted_token_class_ids[0].numpy().tolist()] ->>> predicted_token_class -['O', - 'O', - 'B-location', - 'I-location', - 'B-group', - 'O', - 'O', - 'O', - 'O', - 'O', - 'O', - 'O', - 'O', - 'B-location', - 'B-location', - 'O', - 'O'] -``` - diff --git a/docs/source/ar/tasks/translation.md b/docs/source/ar/tasks/translation.md index 6245b903c22d..3198d4c36871 100644 --- a/docs/source/ar/tasks/translation.md +++ b/docs/source/ar/tasks/translation.md @@ -122,14 +122,6 @@ pip install transformers datasets evaluate sacrebleu >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - -```py ->>> from transformers import DataCollatorForSeq2Seq - ->>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint, return_tensors="tf") -``` - ## التقييم (Evaluate) @@ -234,89 +226,6 @@ pip install transformers datasets evaluate sacrebleu >>> trainer.push_to_hub() ``` - - - -إذا لم تكن معتادًا على ضبط نموذج باستخدام Keras، فألق نظرة على البرنامج التعليمي الأساسي [هنا](../training#train-a-tensorflow-model-with-keras)! - - -لضبط نموذج في TensorFlow، ابدأ بإعداد دالة مُحسِّن وجدول معدل تعلم وبعض المعلمات الفائقة للتدريب: - -```py ->>> from transformers import AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -ثم يمكنك تحميل T5 باستخدام [`TFAutoModelForSeq2SeqLM`]: - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained(checkpoint) -``` - -حوّل مجموعات البيانات الخاصة بك إلى تنسيق `tf.data.Dataset` باستخدام [`~transformers.TFPreTrainedModel.prepare_tf_dataset`]: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_books["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... tokenized_books["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -قم بتكوين النموذج للتدريب باستخدام [`compile`](https://keras.io/api/models/model_training_apis/#compile-method). لاحظ أن جميع نماذج Transformers تحتوي على دالة خسارة ذات صلة بالمهمة بشكل افتراضي، لذلك لا تحتاج إلى تحديد واحدة إلا إذا كنت ترغب في ذلك: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # No loss argument! -``` - -آخر شيئين يجب إعدادهما قبل بدء التدريب هما حساب مقياس SacreBLEU من التوقعات، وتوفير طريقة لدفع نموذجك إلى Hub. يتم كلاهما باستخدام [استدعاءات Keras](../main_classes/keras_callbacks). - -مرر دالة `compute_metrics` الخاصة بك إلى [`~transformers.KerasMetricCallback`]: - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_test_set) -``` - -حدد مكان دفع نموذجك ومعالجك اللغوي في [`~transformers.PushToHubCallback`]: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_opus_books_model", -... tokenizer=tokenizer, -... ) -``` - -ثم اجمع استدعاءاتك معًا: - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -أخيرًا، أنت جاهز لبدء تدريب نموذجك! اتصل بـ [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) مع مجموعات بيانات التدريب والتحقق من الصحة وعدد الحقب واستدعاءاتك لضبط النموذج: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=callbacks) -``` - -بمجرد اكتمال التدريب، يتم تحميل نموذجك تلقائيًا إلى Hub حتى يتمكن الجميع من استخدامه! - @@ -378,30 +287,4 @@ pip install transformers datasets evaluate sacrebleu 'Les lignées partagent des ressources avec des bactéries enfixant l'azote.' ``` - -قم بتحويل النص إلى رموز وإرجاع `input_ids` كموترات TensorFlow: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_opus_books_model") ->>> inputs = tokenizer(text, return_tensors="tf").input_ids -``` - -استخدم طريقة [`~transformers.generation_tf_utils.TFGenerationMixin.generate`] لإنشاء الترجمة. لمزيد من التفاصيل حول استراتيجيات توليد النصوص المختلفة والمعلمات للتحكم في التوليد، تحقق من واجهة برمجة تطبيقات [توليد النصوص](../main_classes/text_generation). - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained("username/my_awesome_opus_books_model") ->>> outputs = model.generate(inputs, max_new_tokens=40, do_sample=True, top_k=30, top_p=0.95) -``` - -فك تشفير معرفات الرموز المولدة مرة أخرى إلى نص: - -```py ->>> tokenizer.decode(outputs[0], skip_special_tokens=True) -'Les lugumes partagent les ressources avec des bactéries fixatrices d'azote.' -``` - - \ No newline at end of file + diff --git a/docs/source/ar/training.md b/docs/source/ar/training.md index d3e354ff8b1a..dee48ac7822c 100644 --- a/docs/source/ar/training.md +++ b/docs/source/ar/training.md @@ -140,116 +140,6 @@ >>> trainer.train() ``` - - - - - -## تدريب نموذج TensorFlow باستخدام Keras - -يمكنك أيضًا تدريب نماذج 🤗 Transformers في TensorFlow باستخدام واجهة برمجة تطبيقات Keras! - -### تحميل البيانات لـ Keras - -عندما تريد تدريب نموذج 🤗 Transformers باستخدام واجهة برمجة تطبيقات Keras، فأنت بحاجة إلى تحويل مجموعة البيانات الخاصة بك إلى تنسيق يفهمه -Keras. إذا كانت مجموعة البيانات الخاصة بك صغيرة، فيمكنك ببساطة تحويلها بالكامل إلى مصفوفات NumPy وإرسالها إلى Keras. -دعونا نجرب ذلك أولاً قبل أن نقوم بأي شيء أكثر تعقيدًا. - -أولاً، قم بتحميل مجموعة بيانات. سنستخدم مجموعة بيانات CoLA من معيار [GLUE benchmark](https://huggingface.co/datasets/glue)، -نظرًا لأنه مهمة تصنيف نص ثنائي بسيطة، وسنأخذ فقط قسم التدريب الآن. - -```py -from datasets import load_dataset - -dataset = load_dataset("glue"، "cola") -dataset = dataset ["train"] # خذ فقط قسم التدريب الآن -``` - -بعد ذلك، قم بتحميل أداة المُجزّئ اللغوي وقم بترميز البيانات كمصفوفات NumPy. لاحظ أن التصنيفات هي بالفعل قائمة من 0 و 1، -لذا يمكننا ببساطة تحويل ذلك مباشرة إلى مصفوفة NumPy بدون ترميز! - -```py -from transformers import AutoTokenizer -import numpy as np - -tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-cased") -tokenized_data = tokenizer(dataset["sentence"], return_tensors="np", padding=True) -# Tokenizer returns a BatchEncoding, but we convert that to a dict for Keras -tokenized_data = dict(tokenized_data) - -labels = np.array(dataset["label"]) # Label is already an array of 0 and 1 -``` - -أخيرًا، قم بتحميل وتجميع وتناسب النموذج. لاحظ أن نماذج Transformers تحتوي جميعها على دالة خسارة ذات صلة بالمهمة بشكل افتراضي، لذا فأنت لست بحاجة إلى تحديد واحدة ما لم ترغب في ذلك: - -```py -from transformers import TFAutoModelForSequenceClassification -from tensorflow.keras.optimizers import Adam - -# تحميل وتجميع النموذج الخاص بنا -model = TFAutoModelForSequenceClassification.from_pretrained("google-bert/bert-base-cased") -# معدلات التعلم المنخفضة أفضل غالبًا لضبط النماذج الدقيقة -model.compile(optimizer=Adam(3e-5)) # لا توجد دالة خسارة! - -model.fit(tokenized_data, labels) -``` - - - -أنت لست مضطرًا لتمرير دالة خسارة إلى نماذجك عند تجميعها! تختار نماذج Hugging Face تلقائيًا -دالة خسارة مناسبة لمهمتها وهندسة نموذجها إذا تُركت هذه الحجة فارغة. يمكنك دائمًا -تجاوز ذلك عن طريق تحديد دالة خسارة بنفسك إذا كنت تريد ذلك! - - - -يعمل هذا النهج بشكل رائع لمجموعات البيانات الصغيرة، ولكن بالنسبة لمجموعات البيانات الأكبر، فقد تجد أنه يصبح مشكلة. لماذا؟ -لأن المصفوفة المرمزة والتصنيفات يجب أن يتم تحميلها بالكامل في الذاكرة، ولأن NumPy لا يتعامل مع -المصفوفات"غير المنتظمة"، لذا حشو كل عينة إلى طول أطول عينة في مجموعة البيانات بأكملها. سيؤدي ذلك إلى زيادة حجم المصفوفة لديك، وستبطئ الرموز الزائده من عملية التدريب أيضًا! - -### تحميل البيانات كـ tf.data.Dataset - -إذا كنت تريد تجنب إبطاء التدريب، فيمكنك تحميل بياناتك كـ `tf.data.Dataset` بدلاً من ذلك. على الرغم من أنه يمكنك كتابة خط أنابيب `tf.data` الخاص بك إذا كنت تريد، إلا أن لدينا طريقتين مختصرتين للقيام بذلك: -- [`~TFPreTrainedModel.prepare_tf_dataset`]: هذه هي الطريقة التي نوصي بها في معظم الحالات. نظرًا لأنه طريقة -على نموذجك، فيمكنه فحص النموذج لتحديد الأعمدة القابلة للاستخدام كمدخلات للنموذج تلقائيًا، -واستبعاد الأعمدة الأخرى لإنشاء مجموعة بيانات أبسط وأكثر كفاءة. -- [`~datasets.Dataset.to_tf_dataset`]: هذه الطريقة أكثر أساسية، وهي مفيدة عندما تريد التحكم بدقة في كيفية -إنشاء مجموعة البيانات الخاصة بك، عن طريق تحديد أعمدة `columns` و `label_cols` المحددة التي سيتم تضمينها. - -قبل أن تتمكن من استخدام [`~TFPreTrainedModel.prepare_tf_dataset`]، ستحتاج إلى إضافة مخرجات المُجزئ إلى مجموعة البيانات الخاصة بك كأعمدة، كما هو موضح في -عينة التعليمات البرمجية التالية: - -```py -def tokenize_dataset (data): -# ستتم إضافة مفاتيح القاموس الذي تمت إعادته كأعمدة إلى مجموعة البيانات -return tokenizer(data["text"]) - - -dataset = dataset.map(tokenize_dataset) -``` - -تذكر أن مجموعات بيانات Hugging Face يتم تخزينها على القرص بشكل افتراضي، لذا فلن يؤدي ذلك إلى تضخيم استخدام الذاكرة لديك! بمجرد إضافة الأعمدة، يمكنك بث الدفعات من مجموعة البيانات وإضافة الترميز إلى كل دفعة، مما يقلل بشكل كبير من عدد رموز الترقيم مقارنة بترميز مجموعة البيانات بأكملها. - - -```py ->>> tf_dataset = model.prepare_tf_dataset(dataset["train"], batch_size=16, shuffle=True, tokenizer=tokenizer) -``` - -لاحظ أنه في عينة التعليمات البرمجية أعلاه، تحتاج إلى تمرير المُجزئ اللغوي إلى `prepare_tf_dataset` حتى تتمكن من حشو الدُفعات بشكل صحيح أثناء تحميلها. -إذا كانت جميع العينات في مجموعة البيانات الخاصة بك بنفس الطول ولم يكن الترميز ضروريًا، فيمكنك تخطي هذا المعامل. -إذا كنت بحاجة إلى القيام بشيء أكثر تعقيدًا من مجرد ترميز العينات (على سبيل المثال، إفساد الرموز للنمذجة اللغوية المُقنعة)، -فيمكنك استخدام معامل `collate_fn` بدلاً من ذلك لتمرير دالة يتم استدعاؤها لتحويل -قائمة العينات إلى دفعة وتطبيق أي معالجة مسبقة تريدها. راجع أمثلةنا [examples](https://github.com/huggingface/transformers/tree/main/examples) أو -[دفاتر الملاحظات](https://huggingface.co/docs/transformers/notebooks) لرؤية هذا النهج في العمل. - -بمجرد إنشاء `tf.data.Dataset`، يمكنك تجميع النموذج وتناسبه كما هو الحال من قبل: - -```py -model.compile(optimizer=Adam(3e-5)) # No loss argument! - -model.fit(tf_dataset) -``` - - @@ -409,4 +299,4 @@ torch.cuda.empty_cache() - [🤗 أمثلة المحولات](https://github.com/huggingface/transformers/tree/main/examples) تتضمن النصوص البرمجية لتدريب مهام NLP الشائعة في PyTorch وTensorFlow. -- [🤗 دفاتر ملاحظات المحولات](notebooks) يحتوي على دفاتر ملاحظات مختلفة حول كيفية ضبط نموذج لمهمة محددة في PyTorch وTensorFlow. \ No newline at end of file +- [🤗 دفاتر ملاحظات المحولات](notebooks) يحتوي على دفاتر ملاحظات مختلفة حول كيفية ضبط نموذج لمهمة محددة في PyTorch وTensorFlow. diff --git a/docs/source/de/autoclass_tutorial.md b/docs/source/de/autoclass_tutorial.md index 5dea87ca552c..178267049a4b 100644 --- a/docs/source/de/autoclass_tutorial.md +++ b/docs/source/de/autoclass_tutorial.md @@ -109,23 +109,4 @@ TensorFlow- und Flax-Checkpoints sind nicht betroffen und können in PyTorch-Arc Im Allgemeinen empfehlen wir die Verwendung der Klasse "AutoTokenizer" und der Klasse "AutoModelFor", um trainierte Instanzen von Modellen zu laden. Dadurch wird sichergestellt, dass Sie jedes Mal die richtige Architektur laden. Im nächsten [Tutorial] (Vorverarbeitung) erfahren Sie, wie Sie Ihren neu geladenen Tokenizer, Feature Extractor und Prozessor verwenden, um einen Datensatz für die Feinabstimmung vorzuverarbeiten. - -Mit den Klassen `TFAutoModelFor` schließlich können Sie ein vortrainiertes Modell für eine bestimmte Aufgabe laden (siehe [hier](model_doc/auto) für eine vollständige Liste der verfügbaren Aufgaben). Laden Sie zum Beispiel ein Modell für die Sequenzklassifikation mit [`TFAutoModelForSequenceClassification.from_pretrained`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Sie können denselben Prüfpunkt problemlos wiederverwenden, um eine Architektur für eine andere Aufgabe zu laden: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Im Allgemeinen empfehlen wir, die Klasse "AutoTokenizer" und die Klasse "TFAutoModelFor" zu verwenden, um vortrainierte Instanzen von Modellen zu laden. Dadurch wird sichergestellt, dass Sie jedes Mal die richtige Architektur laden. Im nächsten [Tutorial] (Vorverarbeitung) erfahren Sie, wie Sie Ihren neu geladenen Tokenizer, Feature Extractor und Prozessor verwenden, um einen Datensatz für die Feinabstimmung vorzuverarbeiten. - diff --git a/docs/source/de/model_sharing.md b/docs/source/de/model_sharing.md index 3b6e55eb4bf9..dfa2c7f785bc 100644 --- a/docs/source/de/model_sharing.md +++ b/docs/source/de/model_sharing.md @@ -88,28 +88,6 @@ Geben Sie `from_tf=True` an, um einen Prüfpunkt von TensorFlow nach PyTorch zu >>> pt_model.save_pretrained("path/to/awesome-name-you-picked") ``` - -Geben Sie `from_pt=True` an, um einen Prüfpunkt von PyTorch nach TensorFlow zu konvertieren: - -```py ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_pt=True) -``` - -Dann können Sie Ihr neues TensorFlow-Modell mit seinem neuen Checkpoint speichern: - -```py ->>> tf_model.save_pretrained("path/to/awesome-name-you-picked") -``` - - -Wenn ein Modell in Flax verfügbar ist, können Sie auch einen Kontrollpunkt von PyTorch nach Flax konvertieren: - -```py ->>> flax_model = FlaxDistilBertForSequenceClassification.from_pretrained( -... "path/to/awesome-name-you-picked", from_pt=True -... ) -``` - ## Ein Modell während des Trainings hochladen @@ -142,27 +120,6 @@ Nach der Feinabstimmung Ihres Modells rufen Sie [`~transformers.Trainer.push_to_ >>> trainer.push_to_hub() ``` - -Geben Sie ein Modell mit [`PushToHubCallback`] an den Hub weiter. In der [`PushToHubCallback`] Funktion, fügen Sie hinzu: - -- Ein Ausgabeverzeichnis für Ihr Modell. -- Einen Tokenizer. -- Die `hub_model_id`, die Ihr Hub-Benutzername und Modellname ist. - -```py ->>> from transformers import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="./your_model_save_path", tokenizer=tokenizer, hub_model_id="your-username/my-awesome-model" -... ) -``` - -Fügen Sie den Callback zu [`fit`](https://keras.io/api/models/model_training_apis/) hinzu, und 🤗 Transformers wird das trainierte Modell an den Hub weiterleiten: - -```py ->>> model.fit(tf_train_dataset, validation_data=tf_validation_dataset, epochs=3, callbacks=push_to_hub_callback) -``` - ## Verwenden Sie die Funktion `push_to_hub`. @@ -229,4 +186,4 @@ Um sicherzustellen, dass die Benutzer die Fähigkeiten, Grenzen, möglichen Verz * Manuelles Erstellen und Hochladen einer "README.md"-Datei. * Klicken Sie auf die Schaltfläche **Modellkarte bearbeiten** in Ihrem Modell-Repository. -Werfen Sie einen Blick auf die DistilBert [model card](https://huggingface.co/distilbert/distilbert-base-uncased) als gutes Beispiel für die Art von Informationen, die eine Modellkarte enthalten sollte. Weitere Details über andere Optionen, die Sie in der Datei "README.md" einstellen können, wie z.B. den Kohlenstoff-Fußabdruck eines Modells oder Beispiele für Widgets, finden Sie in der Dokumentation [hier](https://huggingface.co/docs/hub/models-cards). \ No newline at end of file +Werfen Sie einen Blick auf die DistilBert [model card](https://huggingface.co/distilbert/distilbert-base-uncased) als gutes Beispiel für die Art von Informationen, die eine Modellkarte enthalten sollte. Weitere Details über andere Optionen, die Sie in der Datei "README.md" einstellen können, wie z.B. den Kohlenstoff-Fußabdruck eines Modells oder Beispiele für Widgets, finden Sie in der Dokumentation [hier](https://huggingface.co/docs/hub/models-cards). diff --git a/docs/source/de/preprocessing.md b/docs/source/de/preprocessing.md index b56a5c0ae4ca..8da34e816220 100644 --- a/docs/source/de/preprocessing.md +++ b/docs/source/de/preprocessing.md @@ -175,30 +175,6 @@ Setzen Sie den Parameter `return_tensors` entweder auf `pt` für PyTorch, oder ` [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])} ``` - -```py ->>> batch_sentences = [ -... "But what about second breakfast?", -... "Don't think he knows about second breakfast, Pip.", -... "What about elevensies?", -... ] ->>> encoded_input = tokenizer(batch_sentences, padding=True, truncation=True, return_tensors="tf") ->>> print(encoded_input) -{'input_ids': , - 'token_type_ids': , - 'attention_mask': } -``` - ## Audio diff --git a/docs/source/de/quicktour.md b/docs/source/de/quicktour.md index 856ba546b977..5f05a4441e84 100644 --- a/docs/source/de/quicktour.md +++ b/docs/source/de/quicktour.md @@ -73,12 +73,6 @@ Installieren Sie die folgenden Abhängigkeiten, falls Sie dies nicht bereits get pip install torch ``` - - -```bash -pip install tensorflow -``` - Importieren sie die [`pipeline`] und spezifizieren sie die Aufgabe, welche sie lösen möchten: @@ -165,16 +159,6 @@ Use the [`AutoModelForSequenceClassification`] and [`AutoTokenizer`] to load the >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - -Use the [`TFAutoModelForSequenceClassification`] and [`AutoTokenizer`] to load the pretrained model and its associated tokenizer (more on an `TFAutoClass` below): - -```py ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - Dann können Sie das Modell und den Tokenizer in der [`pipeline`] angeben und den `Klassifikator` auf Ihren Zieltext anwenden: @@ -239,18 +223,6 @@ Genau wie die [`pipeline`] akzeptiert der Tokenizer eine Liste von Eingaben. Dar ... ) ``` - - -```py ->>> tf_batch = tokenizer( -... ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="tf", -... ) -``` - Lesen Sie das Tutorial [preprocessing](./preprocessing) für weitere Details zur Tokenisierung. @@ -291,37 +263,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - -🤗 Transformers bietet eine einfache und einheitliche Methode zum Laden von vortrainierten Instanzen. Das bedeutet, dass Sie ein [`TFAutoModel`] genauso laden können, wie Sie einen [`AutoTokenizer`] laden würden. Der einzige Unterschied ist die Auswahl des richtigen [`TFAutoModel`] für die Aufgabe. Da Sie Text - oder Sequenz - Klassifizierung machen, laden Sie [`TFAutoModelForSequenceClassification`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name) -``` - - - -In der [Aufgabenzusammenfassung](./task_summary) steht, welche [AutoModel]-Klasse für welche Aufgabe zu verwenden ist. - - - -Jetzt können Sie Ihren vorverarbeiteten Stapel von Eingaben direkt an das Modell übergeben, indem Sie die Wörterbuchschlüssel direkt an die Tensoren übergeben: - -```py ->>> tf_outputs = tf_model(tf_batch) -``` - -Das Modell gibt die endgültigen Aktivierungen in dem Attribut "logits" aus. Wenden Sie die Softmax-Funktion auf die "logits" an, um die Wahrscheinlichkeiten zu erhalten: - -```py ->>> import tensorflow as tf - ->>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1) ->>> tf_predictions # doctest: +IGNORE_RESULT -``` - @@ -358,21 +299,6 @@ Wenn Sie bereit sind, das Modell erneut zu verwenden, laden Sie es mit [`PreTrai >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - -Sobald Ihr Modell feinabgestimmt ist, können Sie es mit seinem Tokenizer unter Verwendung von [`TFPreTrainedModel.save_pretrained`] speichern: - -```py ->>> tf_save_directory = "./tf_save_pretrained" ->>> tokenizer.save_pretrained(tf_save_directory) # doctest: +IGNORE_RESULT ->>> tf_model.save_pretrained(tf_save_directory) -``` - -Wenn Sie bereit sind, das Modell wieder zu verwenden, laden Sie es mit [`TFPreTrainedModel.from_pretrained`]: - -```py ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained") -``` - Ein besonders cooles 🤗 Transformers-Feature ist die Möglichkeit, ein Modell zu speichern und es entweder als PyTorch- oder TensorFlow-Modell wieder zu laden. Der Parameter "from_pt" oder "from_tf" kann das Modell von einem Framework in das andere konvertieren: @@ -387,15 +313,6 @@ Ein besonders cooles 🤗 Transformers-Feature ist die Möglichkeit, ein Modell >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - -```py ->>> from transformers import TFAutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory) ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) -``` - ## Custom model builds @@ -420,15 +337,6 @@ Create a model from your custom configuration with [`AutoModel.from_config`]: >>> my_model = AutoModel.from_config(my_config) ``` - -Create a model from your custom configuration with [`TFAutoModel.from_config`]: - -```py ->>> from transformers import TFAutoModel - ->>> my_model = TFAutoModel.from_config(my_config) -``` - Weitere Informationen zur Erstellung von benutzerdefinierten Konfigurationen finden Sie in der Anleitung [Erstellen einer benutzerdefinierten Architektur](./create_a_model). diff --git a/docs/source/de/run_scripts.md b/docs/source/de/run_scripts.md index 069a0c3fd3de..10485a5de2a3 100644 --- a/docs/source/de/run_scripts.md +++ b/docs/source/de/run_scripts.md @@ -104,22 +104,6 @@ python examples/pytorch/summarization/run_summarization.py \ --predict_with_generate ``` - -Das Beispielskript lädt einen Datensatz aus der 🤗 [Datasets](https://huggingface.co/docs/datasets/) Bibliothek herunter und verarbeitet ihn vor. Anschließend nimmt das Skript die Feinabstimmung eines Datensatzes mit Keras auf einer Architektur vor, die die Zusammenfassung unterstützt. Das folgende Beispiel zeigt, wie die Feinabstimmung von [T5-small](https://huggingface.co/google-t5/t5-small) auf dem [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail) Datensatz durchgeführt wird. Das T5-Modell benötigt aufgrund der Art und Weise, wie es trainiert wurde, ein zusätzliches Argument `source_prefix`. Mit dieser Eingabeaufforderung weiß T5, dass es sich um eine Zusammenfassungsaufgabe handelt. - -```bash -python examples/tensorflow/summarization/run_summarization.py \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Verteiltes Training und gemischte Präzision @@ -170,23 +154,6 @@ python xla_spawn.py --num_cores 8 \ --predict_with_generate ``` - -Tensor Processing Units (TPUs) sind speziell für die Beschleunigung der Leistung konzipiert. TensorFlow Skripte verwenden eine [`TPUStrategy`](https://www.tensorflow.org/guide/distributed_training#tpustrategy) für das Training auf TPUs. Um eine TPU zu verwenden, übergeben Sie den Namen der TPU-Ressource an das Argument `tpu`. - -```bash -python run_summarization.py \ - --tpu name_of_tpu_resource \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Führen Sie ein Skript mit 🤗 Accelerate aus. @@ -348,4 +315,4 @@ python examples/pytorch/summarization/run_summarization.py --per_device_eval_batch_size=4 \ --overwrite_output_dir \ --predict_with_generate -``` \ No newline at end of file +``` diff --git a/docs/source/de/training.md b/docs/source/de/training.md index 806a380b6ceb..fb5cb5695b9f 100644 --- a/docs/source/de/training.md +++ b/docs/source/de/training.md @@ -156,119 +156,6 @@ Anschließend können Sie Ihr Modell durch den Aufruf von [`~transformers.Traine >>> trainer.train() ``` - - - - - -## Trainieren Sie ein TensorFlow-Modell mit Keras - -Sie können auch 🤗 Transformers Modelle in TensorFlow mit der Keras API trainieren! - -### Laden von Daten für Keras - -Wenn Sie ein 🤗 Transformers Modell mit der Keras API trainieren wollen, müssen Sie Ihren Datensatz in ein Format konvertieren, das -Keras versteht. Wenn Ihr Datensatz klein ist, können Sie das Ganze einfach in NumPy-Arrays konvertieren und an Keras übergeben. -Probieren wir das zuerst aus, bevor wir etwas Komplizierteres tun. - -Laden Sie zunächst ein Dataset. Wir werden den CoLA-Datensatz aus dem [GLUE-Benchmark](https://huggingface.co/datasets/glue) verwenden, -da es sich um eine einfache Aufgabe zur Klassifizierung von binärem Text handelt, und nehmen vorerst nur den Trainingssplit. - -```py -from datasets import load_dataset - -dataset = load_dataset("glue", "cola") -dataset = dataset["train"] # Just take the training split for now -``` - -Als nächstes laden Sie einen Tokenizer und tokenisieren die Daten als NumPy-Arrays. Beachten Sie, dass die Beschriftungen bereits eine Liste von 0 und 1en sind, -Wir können sie also ohne Tokenisierung direkt in ein NumPy-Array konvertieren! - -```py -from transformers import AutoTokenizer - -tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-cased") -tokenized_data = tokenizer(dataset["text"], return_tensors="np", padding=True) -# Tokenizer returns a BatchEncoding, but we convert that to a dict for Keras -tokenized_data = dict(tokenized_data) - -labels = np.array(dataset["label"]) # Label is already an array of 0 and 1 -``` - -Schließlich laden, [`compile`](https://keras.io/api/models/model_training_apis/#compile-method) und [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) Sie das Modell: - -```py -from transformers import TFAutoModelForSequenceClassification -from tensorflow.keras.optimizers import Adam - -# Load and compile our model -model = TFAutoModelForSequenceClassification.from_pretrained("google-bert/bert-base-cased") -# Lower learning rates are often better for fine-tuning transformers -model.compile(optimizer=Adam(3e-5)) - -model.fit(tokenized_data, labels) -``` - - - -Sie müssen Ihren Modellen kein Verlustargument übergeben, wenn Sie sie `compile()`! Hugging-Face-Modelle wählen automatisch -einen Loss, der für ihre Aufgabe und Modellarchitektur geeignet ist, wenn dieses Argument leer gelassen wird. Sie können jederzeit außer Kraft setzen, indem Sie selbst einen Loss angeben, wenn Sie das möchten! - - - -Dieser Ansatz eignet sich hervorragend für kleinere Datensätze, aber bei größeren Datensätzen kann er zu einem Problem werden. Warum? -Weil das tokenisierte Array und die Beschriftungen vollständig in den Speicher geladen werden müssten, und weil NumPy nicht mit -"gezackte" Arrays nicht verarbeiten kann, so dass jedes tokenisierte Sample auf die Länge des längsten Samples im gesamten Datensatz aufgefüllt werden müsste. -Datensatzes aufgefüllt werden. Dadurch wird das Array noch größer, und all die aufgefüllten Token verlangsamen auch das Training! - -### Laden von Daten als tf.data.Dataset - -Wenn Sie eine Verlangsamung des Trainings vermeiden wollen, können Sie Ihre Daten stattdessen als `tf.data.Dataset` laden. Sie können zwar Ihre eigene -tf.data"-Pipeline schreiben können, wenn Sie wollen, haben wir zwei bequeme Methoden, um dies zu tun: - -- [`~TFPreTrainedModel.prepare_tf_dataset`]: Dies ist die Methode, die wir in den meisten Fällen empfehlen. Da es sich um eine Methode -Ihres Modells ist, kann sie das Modell inspizieren, um automatisch herauszufinden, welche Spalten als Modelleingaben verwendet werden können, und -verwirft die anderen, um einen einfacheren, leistungsfähigeren Datensatz zu erstellen. -- [`~datasets.Dataset.to_tf_dataset`]: Diese Methode ist eher auf niedriger Ebene angesiedelt und ist nützlich, wenn Sie genau kontrollieren wollen, wie -Dataset erstellt wird, indem man genau angibt, welche `columns` und `label_cols` einbezogen werden sollen. - -Bevor Sie [`~TFPreTrainedModel.prepare_tf_dataset`] verwenden können, müssen Sie die Tokenizer-Ausgaben als Spalten zu Ihrem Datensatz hinzufügen, wie in -dem folgenden Codebeispiel: - -```py -def tokenize_dataset(data): - # Keys of the returned dictionary will be added to the dataset as columns - return tokenizer(data["text"]) - - -dataset = dataset.map(tokenize_dataset) -``` - -Denken Sie daran, dass Hugging Face-Datensätze standardmäßig auf der Festplatte gespeichert werden, so dass dies nicht zu einem erhöhten Arbeitsspeicherbedarf führen wird! Sobald die -Spalten hinzugefügt wurden, können Sie Batches aus dem Datensatz streamen und zu jedem Batch Auffüllungen hinzufügen, was die Anzahl der Auffüllungs-Token im Vergleich zum Auffüllen des gesamten Datensatzes reduziert. - - -```py ->>> tf_dataset = model.prepare_tf_dataset(dataset, batch_size=16, shuffle=True, tokenizer=tokenizer) -``` - -Beachten Sie, dass Sie im obigen Codebeispiel den Tokenizer an `prepare_tf_dataset` übergeben müssen, damit die Stapel beim Laden korrekt aufgefüllt werden können. -Wenn alle Stichproben in Ihrem Datensatz die gleiche Länge haben und kein Auffüllen erforderlich ist, können Sie dieses Argument weglassen. -Wenn Sie etwas Komplexeres als nur das Auffüllen von Stichproben benötigen (z. B. das Korrumpieren von Token für die maskierte Sprachmodellierung), können Sie das Argument -Modellierung), können Sie stattdessen das Argument `collate_fn` verwenden, um eine Funktion zu übergeben, die aufgerufen wird, um die -Liste von Stichproben in einen Stapel umwandelt und alle gewünschten Vorverarbeitungen vornimmt. Siehe unsere -[examples](https://github.com/huggingface/transformers/tree/main/examples) oder -[notebooks](https://huggingface.co/docs/transformers/notebooks), um diesen Ansatz in Aktion zu sehen. - -Sobald Sie einen `tf.data.Dataset` erstellt haben, können Sie das Modell wie zuvor kompilieren und anpassen: - -```py -model.compile(optimizer=Adam(3e-5)) - -model.fit(tf_dataset) -``` - - @@ -430,4 +317,4 @@ Weitere Beispiele für die Feinabstimmung finden Sie unter: - [🤗 Transformers Examples](https://github.com/huggingface/transformers/tree/main/examples) enthält Skripte um gängige NLP-Aufgaben in PyTorch und TensorFlow zu trainieren. -- [🤗 Transformers Notebooks](notebooks) enthält verschiedene Notebooks zur Feinabstimmung eines Modells für bestimmte Aufgaben in PyTorch und TensorFlow. \ No newline at end of file +- [🤗 Transformers Notebooks](notebooks) enthält verschiedene Notebooks zur Feinabstimmung eines Modells für bestimmte Aufgaben in PyTorch und TensorFlow. diff --git a/docs/source/en/internal/import_utils.md b/docs/source/en/internal/import_utils.md index 0d76c2bbe33a..77554c85b02a 100644 --- a/docs/source/en/internal/import_utils.md +++ b/docs/source/en/internal/import_utils.md @@ -51,12 +51,7 @@ Let's see how to specify specific object dependencies. All objects under a given filename have an automatic dependency to the tool linked to the filename -**TensorFlow**: All files starting with `modeling_tf_` have an automatic TensorFlow dependency. - -**Flax**: All files starting with `modeling_flax_` have an automatic Flax dependency - -**PyTorch**: All files starting with `modeling_` and not valid with the above (TensorFlow and Flax) have an automatic -PyTorch dependency +**PyTorch**: All files starting with `modeling_` have an automatic PyTorch dependency **Tokenizers**: All files starting with `tokenization_` and ending with `_fast` have an automatic `tokenizers` dependency diff --git a/docs/source/es/autoclass_tutorial.md b/docs/source/es/autoclass_tutorial.md index cea44c3c1ea6..7866f1e627e6 100644 --- a/docs/source/es/autoclass_tutorial.md +++ b/docs/source/es/autoclass_tutorial.md @@ -101,23 +101,4 @@ Reutiliza fácilmente el mismo checkpoint para cargar una aquitectura para algun Generalmente recomendamos utilizar las clases `AutoTokenizer` y `AutoModelFor` para cargar instancias pre-entrenadas de modelos. Ésto asegurará que cargues la arquitectura correcta en cada ocasión. En el siguiente [tutorial](preprocessing), aprende a usar tu tokenizador recién cargado, el extractor de características y el procesador para preprocesar un dataset para fine-tuning. - -Finalmente, la clase `TFAutoModelFor` te permite cargar tu modelo pre-entrenado para una tarea dada (revisa [aquí](model_doc/auto) para conocer la lista completa de tareas disponibles). Por ejemplo, carga un modelo para clasificación de secuencias con [`TFAutoModelForSequenceClassification.from_pretrained`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Reutiliza fácilmente el mismo checkpoint para cargar una aquitectura para alguna tarea diferente: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Generalmente recomendamos utilizar las clases `AutoTokenizer` y `TFAutoModelFor` para cargar instancias de modelos pre-entrenados. Ésto asegurará que cargues la arquitectura correcta cada vez. En el siguiente [tutorial](preprocessing), aprende a usar tu tokenizador recién cargado, el extractor de características y el procesador para preprocesar un dataset para fine-tuning. - diff --git a/docs/source/es/create_a_model.md b/docs/source/es/create_a_model.md index 560fbd74e385..2cb16267af22 100644 --- a/docs/source/es/create_a_model.md +++ b/docs/source/es/create_a_model.md @@ -137,31 +137,6 @@ Cuando cargues tus pesos del preentrenamiento, el modelo por defecto se carga au >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) ``` - - -Carga los atributos de tu configuración personalizada en el modelo de la siguiente forma: - -```py ->>> from transformers import TFDistilBertModel - ->>> my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json") ->>> tf_model = TFDistilBertModel(my_config) -``` - -Esto crea un modelo con valores aleatorios, en lugar de crearlo con los pesos del preentrenamiento, por lo que no serás capaz de usar este modelo para nada útil hasta que no lo entrenes. El entrenamiento es un proceso costoso, tanto en cuestión de recursos como de tiempo, por lo que generalmente es mejor usar un modelo preentrenado para obtener mejores resultados más rápido, consumiendo solo una fracción de los recursos que un entrenamiento completo hubiera requerido. - -Puedes crear un modelo preentrenado con [`~TFPreTrainedModel.from_pretrained`]: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Cuando cargues tus pesos del preentrenamiento, el modelo por defecto se carga automáticamente si este nos lo proporciona 🤗 Transformers. Sin embargo, siempre puedes reemplazar (todos o algunos de) los atributos del modelo por defecto por los tuyos: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) -``` - ### Cabezas de modelo @@ -189,25 +164,6 @@ Puedes reutilizar este punto de guardado o *checkpoint* para otra tarea fácilme >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - - -Por ejemplo, [`TFDistilBertForSequenceClassification`] es un modelo DistilBERT base con una cabeza de clasificación de secuencias. La cabeza de clasificación de secuencias es una capa superior que precede a la recolección de las salidas. - -```py ->>> from transformers import TFDistilBertForSequenceClassification - ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Puedes reutilizar este punto de guardado o *checkpoint* para otra tarea fácilmente cambiando a una cabeza de un modelo diferente. Para una tarea de respuesta a preguntas, puedes usar la cabeza del modelo [`TFDistilBertForQuestionAnswering`]. La cabeza de respuesta a preguntas es similar a la de clasificación de secuencias, excepto porque consta de una capa lineal delante de la salida de los *hidden states*. - - -```py ->>> from transformers import TFDistilBertForQuestionAnswering - ->>> tf_model = TFDistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") -``` - ## Tokenizer diff --git a/docs/source/es/quicktour.md b/docs/source/es/quicktour.md index 41b9c5400282..a9433d095132 100644 --- a/docs/source/es/quicktour.md +++ b/docs/source/es/quicktour.md @@ -73,12 +73,6 @@ Instala las siguientes dependencias si aún no lo has hecho: pip install torch ``` - - -```bash -pip install tensorflow -``` - Importa [`pipeline`] y especifica la tarea que deseas completar: @@ -161,17 +155,6 @@ Usa [`AutoModelForSequenceClassification`] y ['AutoTokenizer'] para cargar un mo - -Usa [`TFAutoModelForSequenceClassification`] y ['AutoTokenizer'] para cargar un modelo preentrenado y un tokenizador asociado (más en un `TFAutoClass` debajo): - -```py ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - - Después puedes especificar el modelo y el tokenizador en el [`pipeline`], y aplicar el `classifier` en tu texto objetivo: @@ -237,18 +220,6 @@ Como con el [`pipeline`], el tokenizador aceptará una lista de inputs. Además, ... ) ``` - - -```py ->>> tf_batch = tokenizer( -... ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="tf", -... ) -``` - Lee el tutorial de [preprocessing](./preprocessing) para más detalles acerca de la tokenización. @@ -289,39 +260,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - -🤗 Transformers provee una forma simple y unificada de cargar tus instancias preentrenadas. Esto significa que puedes cargar un [`TFAutoModel`] como cargarías un [`AutoTokenizer`]. La única diferencia es seleccionar el [`TFAutoModel`] correcto para la tarea. Ya que estás clasificando texto, o secuencias, carga [`TFAutoModelForSequenceClassification`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name) -``` - - - Ve el [task summary](./task_summary) para revisar qué clase del [`AutoModel`] - deberías usar para cada tarea. - - -Ahora puedes pasar tu lote preprocesado de inputs directamente al modelo pasando las llaves del diccionario directamente a los tensores: - -```py ->>> tf_outputs = tf_model(tf_batch) -``` - -El modelo producirá las activaciones finales en el atributo `logits`. Aplica la función softmax a `logits` para obtener las probabilidades: - -```py ->>> import tensorflow as tf - ->>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1) ->>> print(tf.math.round(tf_predictions * 10**4) / 10**4) -tf.Tensor( -[[0.0021 0.0018 0.0116 0.2121 0.7725] - [0.2084 0.1826 0.1969 0.1755 0.2365]], shape=(2, 5), dtype=float32) -``` - @@ -360,21 +298,6 @@ Cuando quieras usar el modelo otra vez cárgalo con [`PreTrainedModel.from_pretr - -Una vez que se haya hecho fine-tuning a tu modelo puedes guardarlo con tu tokenizador usando [`TFPreTrainedModel.save_pretrained`]: - -```py ->>> tf_save_directory = "./tf_save_pretrained" ->>> tokenizer.save_pretrained(tf_save_directory) # doctest: +IGNORE_RESULT ->>> tf_model.save_pretrained(tf_save_directory) -``` - -Cuando quieras usar el modelo otra vez cárgalo con [`TFPreTrainedModel.from_pretrained`]: - -```py ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained") -``` - Una característica particularmente interesante de 🤗 Transformers es la habilidad de guardar el modelo y cargarlo como un modelo de PyTorch o TensorFlow. El parámetro `from_pt` o `from_tf` puede convertir el modelo de un framework al otro: @@ -389,13 +312,4 @@ Una característica particularmente interesante de 🤗 Transformers es la habil >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - -```py ->>> from transformers import TFAutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory) ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) -``` - diff --git a/docs/source/es/run_scripts.md b/docs/source/es/run_scripts.md index cbabefa47b01..eb43a0f84d2b 100644 --- a/docs/source/es/run_scripts.md +++ b/docs/source/es/run_scripts.md @@ -104,22 +104,6 @@ python examples/pytorch/summarization/run_summarization.py \ --predict_with_generate ``` - -El script de ejemplo descarga y preprocesa un conjunto de datos de la biblioteca 🤗 [Datasets](https://huggingface.co/docs/datasets/). Luego, el script ajusta un conjunto de datos utilizando Keras en una arquitectura que soporta la tarea de resumir. El siguiente ejemplo muestra cómo ajustar un [T5-small](https://huggingface.co/google-t5/t5-small) en el conjunto de datos [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail). El modelo T5 requiere un argumento adicional `source_prefix` debido a cómo fue entrenado. Este aviso le permite a T5 saber que se trata de una tarea de resumir. - -```bash -python examples/tensorflow/summarization/run_summarization.py \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Entrenamiento distribuido y de precisión mixta @@ -170,23 +154,6 @@ python xla_spawn.py --num_cores 8 \ --predict_with_generate ``` - -Las Unidades de Procesamiento de Tensor (TPUs) están diseñadas específicamente para acelerar el rendimiento. TensorFlow utiliza [`TPUStrategy`](https://www.tensorflow.org/guide/distributed_training#tpustrategy) para entrenar en TPUs. Para usar una TPU, pasa el nombre del recurso de la TPU al argumento `tpu` - -```bash -python run_summarization.py \ - --tpu name_of_tpu_resource \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Ejecutar un script con 🤗 Accelerate diff --git a/docs/source/es/serialization.md b/docs/source/es/serialization.md index 3ad7d0898530..dce3b7239a39 100644 --- a/docs/source/es/serialization.md +++ b/docs/source/es/serialization.md @@ -215,25 +215,6 @@ del paquete `transformers.onnx` al directorio deseado: python -m transformers.onnx --model=local-pt-checkpoint onnx/ ``` - -```python ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> # Load tokenizer and TensorFlow weights from the Hub ->>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased") ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") ->>> # Save to disk ->>> tokenizer.save_pretrained("local-tf-checkpoint") ->>> tf_model.save_pretrained("local-tf-checkpoint") -``` - -Una vez que se guarda el checkpoint, podemos exportarlo a ONNX usando el argumento `--model` -del paquete `transformers.onnx` al directorio deseado: - -```bash -python -m transformers.onnx --model=local-tf-checkpoint onnx/ -``` - ### Seleccionar características para diferentes topologías de un modelo diff --git a/docs/source/es/tasks/language_modeling.md b/docs/source/es/tasks/language_modeling.md index 9516876a0063..8d23fc199af9 100644 --- a/docs/source/es/tasks/language_modeling.md +++ b/docs/source/es/tasks/language_modeling.md @@ -180,23 +180,6 @@ Para modelados de lenguaje por enmascaramiento usa el mismo [`DataCollatorForLan >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15) ``` - -Puedes usar el token de final de secuencia como el token de relleno y asignar `mlm=False`. Esto usará los inputs como etiquetas movidas un elemento hacia la derecha: - -```py ->>> from transformers import DataCollatorForLanguageModeling - ->>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False, return_tensors="tf") -``` - -Para modelados de lenguajes por enmascaramiento usa el mismo [`DataCollatorForLanguageModeling`] excepto que deberás especificar `mlm_probability` para enmascarar tokens aleatoriamente cada vez que iteras sobre los datos. - -```py ->>> from transformers import DataCollatorForLanguageModeling - ->>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False, return_tensors="tf") -``` - ## Modelado de lenguaje causal @@ -246,63 +229,6 @@ A este punto, solo faltan tres pasos: >>> trainer.train() ``` - -Para realizar el fine-tuning de un modelo en TensorFlow, comienza por convertir tus datasets al formato `tf.data.Dataset` con [`to_tf_dataset`](https://huggingface.co/docs/datasets/package_reference/main_classes#datasets.Dataset.to_tf_dataset). Especifica los inputs y etiquetas en `columns`, ya sea para mezclar el dataset, tamaño de lote, y el data collator: - -```py ->>> tf_train_set = lm_dataset["train"].to_tf_dataset( -... columns=["attention_mask", "input_ids", "labels"], -... dummy_labels=True, -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = lm_dataset["test"].to_tf_dataset( -... columns=["attention_mask", "input_ids", "labels"], -... dummy_labels=True, -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - - - -Si no estás familiarizado con realizar fine-tuning de tus modelos con Keras, considera el tutorial básico [aquí](training#finetune-with-keras)! - - - -Crea la función optimizadora, la tasa de aprendizaje, y algunos hiperparámetros de entrenamiento: - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -Carga DistilGPT2 con [`TFAutoModelForCausalLM`]: - -```py ->>> from transformers import TFAutoModelForCausalLM - ->>> model = TFAutoModelForCausalLM.from_pretrained("distilbert/distilgpt2") -``` - -Configura el modelo para entrenamiento con [`compile`](https://keras.io/api/models/model_training_apis/#compile-method): - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -Llama a [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) para realizar el fine-tuning del modelo: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3) -``` - ## Modelado de lenguaje por enmascaramiento @@ -353,63 +279,6 @@ A este punto, solo faltan tres pasos: >>> trainer.train() ``` - -Para realizar el fine-tuning de un modelo en TensorFlow, comienza por convertir tus datasets al formato `tf.data.Dataset` con [`to_tf_dataset`](https://huggingface.co/docs/datasets/package_reference/main_classes#datasets.Dataset.to_tf_dataset). Especifica los inputs y etiquetas en `columns`, ya sea para mezclar el dataset, tamaño de lote, y el data collator: - -```py ->>> tf_train_set = lm_dataset["train"].to_tf_dataset( -... columns=["attention_mask", "input_ids", "labels"], -... dummy_labels=True, -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = lm_dataset["test"].to_tf_dataset( -... columns=["attention_mask", "input_ids", "labels"], -... dummy_labels=True, -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - - - -Si no estás familiarizado con realizar fine-tuning de tus modelos con Keras, considera el tutorial básico [aquí](training#finetune-with-keras)! - - - -Crea la función optimizadora, la tasa de aprendizaje, y algunos hiperparámetros de entrenamiento: - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -Carga DistilRoBERTa con [`TFAutoModelForMaskedLM`]: - -```py ->>> from transformers import TFAutoModelForMaskedLM - ->>> model = TFAutoModelForCausalLM.from_pretrained("distilbert/distilroberta-base") -``` - -Configura el modelo para entrenamiento con [`compile`](https://keras.io/api/models/model_training_apis/#compile-method): - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -Llama a [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) para realizar el fine-tuning del modelo: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3) -``` - @@ -418,4 +287,4 @@ Para un ejemplo más profundo sobre cómo realizar el fine-tuning sobre un model [PyTorch notebook](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/language_modeling.ipynb) o [TensorFlow notebook](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/language_modeling-tf.ipynb). - \ No newline at end of file + diff --git a/docs/source/es/tasks/multiple_choice.md b/docs/source/es/tasks/multiple_choice.md index 7f44479ad24d..fb4d988a00ff 100644 --- a/docs/source/es/tasks/multiple_choice.md +++ b/docs/source/es/tasks/multiple_choice.md @@ -147,61 +147,4 @@ En este punto, solo quedan tres pasos: >>> trainer.train() ``` - -Para realizar el fine-tuning de un modelo en TensorFlow, primero convierte tus datasets al formato `tf.data.Dataset` con el método [`~TFPreTrainedModel.prepare_tf_dataset`]. - -```py ->>> data_collator = DataCollatorForMultipleChoice(tokenizer=tokenizer) ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_swag["train"], -... shuffle=True, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_swag["validation"], -... shuffle=False, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) -``` - - - -Para familiarizarte con el fine-tuning con Keras, ¡mira el tutorial básico [aquí](training#finetune-with-keras)! - - - -Prepara una función de optimización, un programa para la tasa de aprendizaje y algunos hiperparámetros de entrenamiento: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_train_epochs = 2 ->>> total_train_steps = (len(tokenized_swag["train"]) // batch_size) * num_train_epochs ->>> optimizer, schedule = create_optimizer(init_lr=5e-5, num_warmup_steps=0, num_train_steps=total_train_steps) -``` - -Carga el modelo BERT con [`TFAutoModelForMultipleChoice`]: - -```py ->>> from transformers import TFAutoModelForMultipleChoice - ->>> model = TFAutoModelForMultipleChoice.from_pretrained("google-bert/bert-base-uncased") -``` - -Configura el modelo para entrenarlo con [`compile`](https://keras.io/api/models/model_training_apis/#compile-method): - -```py ->>> model.compile(optimizer=optimizer) -``` - -Invoca el método [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) para realizar el fine-tuning del modelo: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=2) -``` - diff --git a/docs/source/es/tasks/question_answering.md b/docs/source/es/tasks/question_answering.md index 42a6e4b6e1bc..0e1bd9b1b497 100644 --- a/docs/source/es/tasks/question_answering.md +++ b/docs/source/es/tasks/question_answering.md @@ -146,13 +146,6 @@ Usa el [`DefaultDataCollator`] para crear un lote de ejemplos. A diferencia de l >>> data_collator = DefaultDataCollator() ``` - -```py ->>> from transformers import DefaultDataCollator - ->>> data_collator = DefaultDataCollator(return_tensors="tf") -``` - ## Entrenamiento @@ -202,68 +195,6 @@ En este punto, solo quedan tres pasos: >>> trainer.train() ``` - -Para realizar el fine-tuning de un modelo en TensorFlow, primero convierte tus datasets al formato `tf.data.Dataset` con el método [`~TFPreTrainedModel.prepare_tf_dataset`]. - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_squad["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_squad["validation"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - - - -Para familiarizarte con el fine-tuning con Keras, ¡mira el tutorial básico [aquí](training#finetune-with-keras)! - - - -Prepara una función de optimización, un programa para la tasa de aprendizaje y algunos hiperparámetros de entrenamiento: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_epochs = 2 ->>> total_train_steps = (len(tokenized_squad["train"]) // batch_size) * num_epochs ->>> optimizer, schedule = create_optimizer( -... init_lr=2e-5, -... num_warmup_steps=0, -... num_train_steps=total_train_steps, -... ) -``` - -Carga el modelo DistilBERT con [`TFAutoModelForQuestionAnswering`]: - -```py ->>> from transformers import TFAutoModelForQuestionAnswering - ->>> model = TFAutoModelForQuestionAnswering("distilbert/distilbert-base-uncased") -``` - -Configura el modelo para entrenarlo con [`compile`](https://keras.io/api/models/model_training_apis/#compile-method): - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -Invoca el método [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) para realizar el fine-tuning del modelo: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3) -``` - diff --git a/docs/source/es/tasks/summarization.md b/docs/source/es/tasks/summarization.md index c9060cba6b77..024568c4443a 100644 --- a/docs/source/es/tasks/summarization.md +++ b/docs/source/es/tasks/summarization.md @@ -104,13 +104,6 @@ Usa [`DataCollatorForSeq2Seq`] para crear un lote de ejemplos. Esto también *re >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=model) ``` - -```py ->>> from transformers import DataCollatorForSeq2Seq - ->>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=model, return_tensors="tf") -``` - ## Entrenamiento @@ -162,59 +155,6 @@ En este punto, solo faltan tres pasos: >>> trainer.train() ``` - -Para hacer fine-tuning de un modelo en TensorFlow, comienza por convertir tus datasets al formato `tf.data.Dataset` con [`~datasets.Dataset.to_tf_dataset`]. Especifica los inputs y etiquetas en `columns`, el tamaño de lote, el data collator, y si es necesario mezclar el dataset: - -```py ->>> tf_train_set = tokenized_billsum["train"].to_tf_dataset( -... columns=["attention_mask", "input_ids", "labels"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = tokenized_billsum["test"].to_tf_dataset( -... columns=["attention_mask", "input_ids", "labels"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - - - -Para familiarizarte con el fine-tuning con Keras, ¡mira el tutorial básico [aquí](training#finetune-with-keras)! - - - -Crea la función optimizadora, establece la tasa de aprendizaje y algunos hiperparámetros de entrenamiento: - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -Carga T5 con [`TFAutoModelForSeq2SeqLM`]: - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained("google-t5/t5-small") -``` - -Configura el modelo para entrenamiento con [`compile`](https://keras.io/api/models/model_training_apis/#compile-method): - -```py ->>> model.compile(optimizer=optimizer) -``` - -Llama a [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) para realizar el fine-tuning del modelo: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3) -``` - diff --git a/docs/source/fr/autoclass_tutorial.md b/docs/source/fr/autoclass_tutorial.md index 1f3baac07ce6..6dafd37b6d3e 100644 --- a/docs/source/fr/autoclass_tutorial.md +++ b/docs/source/fr/autoclass_tutorial.md @@ -164,23 +164,4 @@ Les points de contrôle TensorFlow et Flax ne sont pas concernés, et peuvent ê En général, nous recommandons d'utiliser les classes `AutoTokenizer` et `AutoModelFor` pour charger des instances pré-entraînées de tokenizers et modèles respectivement. Cela vous permettra de charger la bonne architecture à chaque fois. Dans le prochain [tutoriel](preprocessing), vous apprenez à utiliser un tokenizer, processeur d'image, extracteur de caractéristiques et processeur pour pré-traiter un jeu de données pour le fine-tuning. - -Enfin, les classes `TFAutoModelFor` vous permettent de charger un modèle pré-entraîné pour une tâche donnée (voir [ici](model_doc/auto) pour une liste complète des tâches disponibles). Par exemple, chargez un modèle pour la classification de séquence avec [`TFAutoModelForSequenceClassification.from_pretrained`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Réutilisez facilement le même ensemble de poids pour charger une architecture pour une tâche différente : - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -En général, nous recommandons d'utiliser les classes `AutoTokenizer` et `TFAutoModelFor` pour charger des instances pré-entraînées de tokenizers et modèles respectivement. Cela vous permettra de charger la bonne architecture à chaque fois. Dans le prochain [tutoriel](preprocessing), vous apprenez à utiliser un tokenizer, processeur d'image, extracteur de caractéristiques et processeur pour pré-traiter un jeu de données pour le fine-tuning. - diff --git a/docs/source/fr/quicktour.md b/docs/source/fr/quicktour.md index dcf21562316d..b2c35cffd566 100644 --- a/docs/source/fr/quicktour.md +++ b/docs/source/fr/quicktour.md @@ -35,12 +35,6 @@ Vous aurez aussi besoin d'installer votre bibliothèque d'apprentissage profond pip install torch ``` - - -```bash -pip install tensorflow -``` - ## Pipeline @@ -143,16 +137,6 @@ Utilisez [`AutoModelForSequenceClassification`] et [`AutoTokenizer`] pour charge >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - -Utilisez [`TFAutoModelForSequenceClassification`] et [`AutoTokenizer`] pour charger le modèle pré-entraîné et le tokenizer adapté (plus de détails sur une `TFAutoClass` dans la section suivante) : - -```py ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - Spécifiez le modèle et le tokenizer dans le [`pipeline`], et utilisez le `classifier` sur le texte en français : @@ -216,18 +200,6 @@ Un tokenizer peut également accepter une liste de textes, et remplir et tronque ... ) ``` - - -```py ->>> tf_batch = tokenizer( -... ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="tf", -... ) -``` - @@ -272,37 +244,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - -🤗 Transformers fournit un moyen simple et unifié de charger des instances pré-entraînés. Cela signifie que vous pouvez charger un [`TFAutoModel`] comme vous chargeriez un [`AutoTokenizer`]. La seule différence est de sélectionner le [`TFAutoModel`] approprié pour la tâche. Pour une classification de texte (ou de séquence de textes), vous devez charger [`TFAutoModelForSequenceClassification`] : - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name) -``` - - - -Voir le [résumé de la tâche](./task_summary) pour vérifier si elle est prise en charge par une classe [`AutoModel`]. - - - -Passez maintenant votre échantillon d'entrées prétraitées directement au modèle en passant les clés du dictionnaire directement aux tensors : - -```py ->>> tf_outputs = tf_model(tf_batch) -``` - -Le modèle produit les activations finales dans l'attribut `logits`. Appliquez la fonction softmax aux `logits` pour récupérer les probabilités : - -```py ->>> import tensorflow as tf - ->>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1) ->>> tf_predictions # doctest: +IGNORE_RESULT -``` - @@ -329,21 +270,6 @@ Lorsque vous voulez réutiliser le modèle, rechargez-le avec [`PreTrainedModel. >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - -Une fois que votre modèle est finetuné, vous pouvez le sauvegarder avec son tokenizer en utilisant [`TFPreTrainedModel.save_pretrained`] : - -```py ->>> tf_save_directory = "./tf_save_pretrained" ->>> tokenizer.save_pretrained(tf_save_directory) # doctest: +IGNORE_RESULT ->>> tf_model.save_pretrained(tf_save_directory) -``` - -Lorsque vous voulez réutiliser le modèle, rechargez-le avec [`TFPreTrainedModel.from_pretrained`] : - -```py ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained") -``` - Une fonctionnalité particulièrement cool 🤗 Transformers est la possibilité d'enregistrer un modèle et de le recharger en tant que modèle PyTorch ou TensorFlow. Le paramètre `from_pt` ou `from_tf` permet de convertir le modèle d'un framework à l'autre : @@ -358,15 +284,6 @@ Une fonctionnalité particulièrement cool 🤗 Transformers est la possibilité >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - -```py ->>> from transformers import TFAutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory) ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) -``` - ## Constructions de modèles personnalisés @@ -391,15 +308,6 @@ Créez un modèle personnalisé à partir de votre configuration avec [`AutoMode >>> my_model = AutoModel.from_config(my_config) ``` - -Créez un modèle personnalisé à partir de votre configuration avec [`TFAutoModel.from_config`] : - -```py ->>> from transformers import TFAutoModel - ->>> my_model = TFAutoModel.from_config(my_config) -``` - Consultez le guide [Créer une architecture personnalisée](./create_a_model) pour plus d'informations sur la création de configurations personnalisées. diff --git a/docs/source/fr/run_scripts_fr.md b/docs/source/fr/run_scripts_fr.md index 561f9f047005..671467e52d70 100644 --- a/docs/source/fr/run_scripts_fr.md +++ b/docs/source/fr/run_scripts_fr.md @@ -106,23 +106,6 @@ python examples/pytorch/summarization/run_summarization.py \ --predict_with_generate ``` - - -Le script d'exemple télécharge et prétraite un jeu de données à partir de la bibliothèque 🤗 [Datasets](https://huggingface.co/docs/datasets/). Ensuite, le script ajuste un modèle à l'aide de Keras sur une architecture qui prend en charge la tâche de résumé. L'exemple suivant montre comment ajuster le modèle [T5-small](https://huggingface.co/google-t5/t5-small) sur le jeu de données [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail). Le modèle T5 nécessite un argument supplémentaire source_prefix en raison de la façon dont il a été entraîné. Cette invite permet à T5 de savoir qu'il s'agit d'une tâche de résumé. - -```bash -python examples/tensorflow/summarization/run_summarization.py \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Entraînement distribué et précision mixte @@ -174,23 +157,6 @@ python xla_spawn.py --num_cores 8 \ --predict_with_generate ``` - -Les scripts TensorFlow utilisent une [`TPUStrategy`](https://www.tensorflow.org/guide/distributed_training#tpustrategy) pour l'entraînement sur TPU. Pour utiliser un TPU, passez le nom de la ressource TPU à l'argument tpu. - -```bash -python run_summarization.py \ - --tpu name_of_tpu_resource \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Exécuter un script avec 🤗 Accelerate @@ -352,4 +318,4 @@ python examples/pytorch/summarization/run_summarization.py --per_device_eval_batch_size=4 \ --overwrite_output_dir \ --predict_with_generate -``` \ No newline at end of file +``` diff --git a/docs/source/it/autoclass_tutorial.md b/docs/source/it/autoclass_tutorial.md index edb96528e705..e823fd5f5cb6 100644 --- a/docs/source/it/autoclass_tutorial.md +++ b/docs/source/it/autoclass_tutorial.md @@ -101,23 +101,4 @@ Semplicemente utilizza lo stesso checkpoint per caricare un'architettura per un Generalmente, raccomandiamo di utilizzare la classe `AutoTokenizer` e la classe `AutoModelFor` per caricare istanze pre-allenate dei modelli. Questo ti assicurerà di aver caricato la corretta architettura ogni volta. Nel prossimo [tutorial](preprocessing), imparerai come utilizzare il tokenizer, il feature extractor e il processore per elaborare un dataset per il fine-tuning. - -Infine, le classi `TFAutoModelFor` ti permettono di caricare un modello pre-allenato per un determinato compito (guarda [qui](model_doc/auto) per una lista completa di compiti presenti). Per esempio, carica un modello per la classificazione di sequenze con [`TFAutoModelForSequenceClassification.from_pretrained`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Semplicemente utilizza lo stesso checkpoint per caricare un'architettura per un task differente: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Generalmente, raccomandiamo di utilizzare la classe `AutoTokenizer` e la classe `TFAutoModelFor` per caricare istanze pre-allenate dei modelli. Questo ti assicurerà di aver caricato la corretta architettura ogni volta. Nel prossimo [tutorial](preprocessing), imparerai come utilizzare il tokenizer, il feature extractor e il processore per elaborare un dataset per il fine-tuning. - diff --git a/docs/source/it/create_a_model.md b/docs/source/it/create_a_model.md index caacf4fadc5d..b5c594ae03cd 100644 --- a/docs/source/it/create_a_model.md +++ b/docs/source/it/create_a_model.md @@ -136,32 +136,6 @@ Quando carichi pesi pre-allenati, la configurazione del modello predefinito è a >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) ``` - -Carica gli attributi di configurazione personalizzati nel modello: - -```py ->>> from transformers import TFDistilBertModel - ->>> my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json") ->>> tf_model = TFDistilBertModel(my_config) -``` - - -Questo crea modelli con valori casuali invece di pesi pre-allenati. Non sarai in grado di usare questo modello per niente di utile finché non lo alleni. L'allenamento è un processo costoso e che richiede tempo . Generalmente è meglio usare un modello pre-allenato per ottenere risultati migliori velocemente, utilizzando solo una frazione delle risorse neccesarie per l'allenamento. - -Crea un modello pre-allenoto con [`~TFPreTrainedModel.from_pretrained`]: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Quando carichi pesi pre-allenati, la configurazione del modello predefinito è automaticamente caricato se il modello è fornito da 🤗 Transformers. Tuttavia, puoi ancora sostituire gli attributi - alcuni o tutti - di configurazione del modello predefinito con i tuoi se lo desideri: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) -``` - - ### Model head @@ -186,23 +160,6 @@ Riutilizza facilmente questo checkpoint per un'altra attività passando ad un mo >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - -Per esempio, [`TFDistilBertForSequenceClassification`] è un modello DistilBERT base con classificazione di sequenza head. La classificazione di sequenza head è uno strato lineare sopra gli output raggruppati. - -```py ->>> from transformers import TFDistilBertForSequenceClassification - ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Riutilizza facilmente questo checkpoint per un altra attività passando ad un modello head diverso. Per un attività di risposta alle domande, utilizzerai il model head [`TFDistilBertForQuestionAnswering`]. Il head di risposta alle domande è simile alla sequenza di classificazione head tranne per il fatto che è uno strato lineare sopra l'output degli stati nascosti (hidden states in inglese) - -```py ->>> from transformers import TFDistilBertForQuestionAnswering - ->>> tf_model = TFDistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") -``` - ## Tokenizer @@ -358,4 +315,4 @@ Combinare l'estrattore di caratteristiche e il tokenizer in [`Wav2Vec2Processor` >>> processor = Wav2Vec2Processor(feature_extractor=feature_extractor, tokenizer=tokenizer) ``` -Con due classi di base - configurazione e modello - e una classe di preelaborazione aggiuntiva (tokenizer, estrattore di caratteristiche o processore), puoi creare qualsiasi modello supportato da 🤗 Transformers. Ognuna di queste classi base è configurabile, consentendoti di utilizzare gli attributi specifici che desideri. È possibile impostare facilmente un modello per l'addestramento o modificare un modello preallenato esistente per la messa a punto. \ No newline at end of file +Con due classi di base - configurazione e modello - e una classe di preelaborazione aggiuntiva (tokenizer, estrattore di caratteristiche o processore), puoi creare qualsiasi modello supportato da 🤗 Transformers. Ognuna di queste classi base è configurabile, consentendoti di utilizzare gli attributi specifici che desideri. È possibile impostare facilmente un modello per l'addestramento o modificare un modello preallenato esistente per la messa a punto. diff --git a/docs/source/it/model_sharing.md b/docs/source/it/model_sharing.md index c6efa717efb8..7c527d5cd771 100644 --- a/docs/source/it/model_sharing.md +++ b/docs/source/it/model_sharing.md @@ -90,30 +90,6 @@ Specifica `from_tf=True` per convertire un checkpoint da TensorFlow a PyTorch: >>> pt_model.save_pretrained("path/verso/il-nome-magnifico-che-hai-scelto") ``` - -Specifica `from_pt=True` per convertire un checkpoint da PyTorch a TensorFlow: - -```py ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained( -... "path/verso/il-nome-magnifico-che-hai-scelto", from_pt=True -... ) -``` - -Poi puoi salvare il tuo nuovo modello in TensorFlow con il suo nuovo checkpoint: - -```py ->>> tf_model.save_pretrained("path/verso/il-nome-magnifico-che-hai-scelto") -``` - - -Se un modello è disponibile in Flax, puoi anche convertire un checkpoint da PyTorch a Flax: - -```py ->>> flax_model = FlaxDistilBertForSequenceClassification.from_pretrained( -... "path/verso/il-nome-magnifico-che-hai-scelto", from_pt=True -... ) -``` - ## Condividi un modello durante il training @@ -146,29 +122,6 @@ Dopo aver effettuato il fine-tuning del tuo modello, chiama [`~transformers.Trai >>> trainer.push_to_hub() ``` - -Condividi un modello nell'Hub con [`PushToHubCallback`]. Nella funzione [`PushToHubCallback`], aggiungi: - -- Una directory di output per il tuo modello. -- Un tokenizer. -- L'`hub_model_id`, che è il tuo username sull'Hub e il nome del modello. - -```py ->>> from transformers import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="./il_path_dove_salvare_il_tuo_modello", -... tokenizer=tokenizer, -... hub_model_id="il-tuo-username/il-mio-bellissimo-modello", -... ) -``` - -Aggiungi il callback a [`fit`](https://keras.io/api/models/model_training_apis/), e 🤗 Transformers caricherà il modello allenato nell'Hub: - -```py ->>> model.fit(tf_train_dataset, validation_data=tf_validation_dataset, epochs=3, callbacks=push_to_hub_callback) -``` - ## Utilizzare la funzione `push_to_hub` diff --git a/docs/source/it/quicktour.md b/docs/source/it/quicktour.md index f0291a616771..dda825c801e5 100644 --- a/docs/source/it/quicktour.md +++ b/docs/source/it/quicktour.md @@ -73,12 +73,6 @@ Installa le seguenti dipendenze se non lo hai già fatto: pip install torch ``` - - -```bash -pip install tensorflow -``` - Importa [`pipeline`] e specifica il compito che vuoi completare: @@ -169,16 +163,6 @@ Usa [`AutoModelForSequenceClassification`] e [`AutoTokenizer`] per caricare il m >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - -Usa [`TFAutoModelForSequenceClassification`] e [`AutoTokenizer`] per caricare il modello pre-allenato e il suo tokenizer associato (maggiori informazioni su una `TFAutoClass` in seguito): - -```py ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - Poi puoi specificare il modello e il tokenizer nella [`pipeline`], e applicare il `classifier` sul tuo testo obiettivo: @@ -243,17 +227,6 @@ Come con la [`pipeline`], il tokenizer accetterà una lista di input. In più, i ... ) ``` - -```py ->>> tf_batch = tokenizer( -... ["Siamo molto felici di mostrarti la libreria 🤗 Transformers.", "Speriamo te non la odierai."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="tf", -... ) -``` - Leggi il tutorial sul [preprocessing](./preprocessing) per maggiori dettagli sulla tokenizzazione. @@ -294,36 +267,6 @@ tensor([[0.0041, 0.0037, 0.0203, 0.2005, 0.7713], [0.3766, 0.3292, 0.1832, 0.0558, 0.0552]], grad_fn=) ``` - -🤗 Transformers fornisce un metodo semplice e unificato per caricare istanze pre-allenate. Questo significa che puoi caricare un [`TFAutoModel`] come caricheresti un [`AutoTokenizer`]. L'unica differenza è selezionare il [`TFAutoModel`] corretto per il compito di interesse. Dato che stai facendo classificazione di testi, o sequenze, carica [`TFAutoModelForSequenceClassification`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> nome_del_modello = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(nome_del_modello) -``` - - - -Guarda il [task summary](./task_summary) per sapere quale classe di [`AutoModel`] utilizzare per quale compito. - - - -Ora puoi passare il tuo lotto di input pre-processati direttamente al modello passando le chiavi del dizionario al tensore: - -```py ->>> tf_outputs = tf_model(tf_batch) -``` - -Il modello produrrà le attivazioni finali nell'attributo `logits`. Applica la funzione softmax a `logits` per ottenere le probabilità: -```py ->>> import tensorflow as tf - ->>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1) ->>> tf_predictions # doctest: +IGNORE_RESULT -``` - @@ -360,21 +303,6 @@ Quando desideri utilizzare il tuo modello nuovamente, puoi ri-caricarlo con [`Pr >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - -Una volta completato il fine-tuning del tuo modello, puoi salvarlo con il suo tokenizer utilizzando [`TFPreTrainedModel.save_pretrained`]: - -```py ->>> tf_save_directory = "./tf_save_pretrained" ->>> tokenizer.save_pretrained(tf_save_directory) # doctest: +IGNORE_RESULT ->>> tf_model.save_pretrained(tf_save_directory) -``` - -Quando desideri utilizzare il tuo modello nuovamente, puoi ri-caricarlo con [`TFPreTrainedModel.from_pretrained`]: - -```py ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained") -``` - Una caratteristica particolarmente interessante di 🤗 Transformers è la sua abilità di salvare un modello e ri-caricarlo sia come modello di PyTorch che di TensorFlow. I parametri `from_pt` o `from_tf` possono convertire un modello da un framework all'altro: @@ -389,13 +317,4 @@ Una caratteristica particolarmente interessante di 🤗 Transformers è la sua a >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - -```py ->>> from transformers import TFAutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory) ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) -``` - diff --git a/docs/source/it/run_scripts.md b/docs/source/it/run_scripts.md index 71ccf0eed52b..0d3f2d32351d 100644 --- a/docs/source/it/run_scripts.md +++ b/docs/source/it/run_scripts.md @@ -104,22 +104,6 @@ python examples/pytorch/summarization/run_summarization.py \ --predict_with_generate ``` - -Lo script di esempio scarica e pre-processa un dataset dalla libreria 🤗 [Datasets](https://huggingface.co/docs/datasets/). Successivamente, lo script esegue il fine-tuning su un dataset usando Keras su un'architettura che supporta la summarization. Il seguente esempio mostra come eseguire il fine-tuning di [T5-small](https://huggingface.co/google-t5/t5-small) sul dataset [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail). Il modello T5 richiede un parametro addizionale `source_prefix` a causa del modo in cui è stato addestrato. Questo prefisso permette a T5 di sapere che si tratta di un task di summarization. - -```bash -python examples/tensorflow/summarization/run_summarization.py \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Addestramento distribuito e precisione mista @@ -170,23 +154,6 @@ python xla_spawn.py --num_cores 8 \ --predict_with_generate ``` - -Le Tensor Processing Units (TPU) sono state progettate per migliorare le prestazioni. Gli script TensorFlow utilizzano una [`TPUStrategy`](https://www.tensorflow.org/guide/distributed_training#tpustrategy) per eseguire l'addestramento su TPU. Per usare una TPU, passa il nome della risorsa TPU all'argomento `tpu`. - -```bash -python run_summarization.py \ - --tpu name_of_tpu_resource \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Esegui uno script con 🤗 Accelerate diff --git a/docs/source/it/serialization.md b/docs/source/it/serialization.md index 974aee0d81ca..2edd837533f2 100644 --- a/docs/source/it/serialization.md +++ b/docs/source/it/serialization.md @@ -201,25 +201,6 @@ del pacchetto `transformers.onnx` nella directory desiderata: python -m transformers.onnx --model=local-pt-checkpoint onnx/ ``` - -```python ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> # Load tokenizer and TensorFlow weights from the Hub ->>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased") ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") ->>> # Save to disk ->>> tokenizer.save_pretrained("local-tf-checkpoint") ->>> tf_model.save_pretrained("local-tf-checkpoint") -``` - -Once the checkpoint is saved, we can export it to ONNX by pointing the `--model` -argument of the `transformers.onnx` package to the desired directory: - -```bash -python -m transformers.onnx --model=local-tf-checkpoint onnx/ -``` - ### Selezione delle caratteristiche per diverse topologie di modello @@ -673,4 +654,4 @@ torch.neuron.trace(model, [token_tensor, segments_tensors]) Questa modifica consente a Neuron SDK di tracciare il modello e ottimizzarlo per l'esecuzione nelle istanze Inf1. Per ulteriori informazioni sulle funzionalità, gli strumenti, i tutorial di esempi e gli ultimi aggiornamenti di AWS Neuron SDK, -consultare la [documentazione AWS NeuronSDK](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/index.html). \ No newline at end of file +consultare la [documentazione AWS NeuronSDK](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/index.html). diff --git a/docs/source/it/training.md b/docs/source/it/training.md index a65b23e1cb98..9772ff4a5bbc 100644 --- a/docs/source/it/training.md +++ b/docs/source/it/training.md @@ -149,72 +149,6 @@ Poi metti a punto il modello richiamando [`~transformers.Trainer.train`]: >>> trainer.train() ``` - - - - - -I modelli 🤗 Transformers supportano anche l'addestramento in TensorFlow usando l'API di Keras. - -### Convertire dataset nel formato per TensorFlow - -Il [`DefaultDataCollator`] assembla tensori in lotti su cui il modello si addestrerà. Assicurati di specificare di restituire tensori per TensorFlow in `return_tensors`: - -```py ->>> from transformers import DefaultDataCollator - ->>> data_collator = DefaultDataCollator(return_tensors="tf") -``` - - - -[`Trainer`] usa [`DataCollatorWithPadding`] in maniera predefinita in modo da non dover specificare esplicitamente un collettore di dati. - - - -Successivamente, converti i datasets tokenizzati in TensorFlow datasets con il metodo [`to_tf_dataset`](https://huggingface.co/docs/datasets/package_reference/main_classes.html#datasets.Dataset.to_tf_dataset). Specifica il tuo input in `columns` e le tue etichette in `label_cols`: - -```py ->>> tf_train_dataset = small_train_dataset.to_tf_dataset( -... columns=["attention_mask", "input_ids", "token_type_ids"], -... label_cols=["labels"], -... shuffle=True, -... collate_fn=data_collator, -... batch_size=8, -... ) - ->>> tf_validation_dataset = small_eval_dataset.to_tf_dataset( -... columns=["attention_mask", "input_ids", "token_type_ids"], -... label_cols=["labels"], -... shuffle=False, -... collate_fn=data_collator, -... batch_size=8, -... ) -``` - -### Compilazione e addestramento - -Carica un modello TensorFlow col numero atteso di etichette: - -```py ->>> import tensorflow as tf ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("google-bert/bert-base-cased", num_labels=5) -``` - -Poi compila e fai il fine-tuning del tuo modello usando [`fit`](https://keras.io/api/models/model_training_apis/) come faresti con qualsiasi altro modello di Keras: - -```py ->>> model.compile( -... optimizer=tf.keras.optimizers.Adam(learning_rate=5e-5), -... loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), -... metrics=tf.metrics.SparseCategoricalAccuracy(), -... ) - ->>> model.fit(tf_train_dataset, validation_data=tf_validation_dataset, epochs=3) -``` - diff --git a/docs/source/ja/autoclass_tutorial.md b/docs/source/ja/autoclass_tutorial.md index f8fbeaa221f6..f28a2b042b19 100644 --- a/docs/source/ja/autoclass_tutorial.md +++ b/docs/source/ja/autoclass_tutorial.md @@ -136,26 +136,4 @@ TensorFlowおよびFlaxのチェックポイントには影響がなく、`from_ これにより、常に正しいアーキテクチャをロードできます。 次の[tutorial](preprocessing)では、新しくロードしたトークナイザ、画像プロセッサ、特徴量抽出器、およびプロセッサを使用して、ファインチューニング用にデータセットを前処理する方法を学びます。 - -最後に、`TFAutoModelFor`クラスは特定のタスクに対して事前学習済みモデルをロードできます(使用可能なタスクの完全な一覧についてはこちらを参照)。 -たとえば、[`TFAutoModelForSequenceClassification.from_pretrained`]を使用してシーケンス分類用のモデルをロードできます: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -同じチェックポイントを再利用して異なるタスクのアーキテクチャをロードできます: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -一般的には、事前学習済みモデルのインスタンスをロードするために`AutoTokenizer`クラスと`TFAutoModelFor`クラスの使用をお勧めします。 -これにより、常に正しいアーキテクチャをロードできます。 -次の[tutorial](preproccesing)では、新しくロードしたトークナイザ、画像プロセッサ、特徴量抽出器、およびプロセッサを使用して、ファインチューニング用にデータセットを前処理する方法を学びます。 - - \ No newline at end of file + diff --git a/docs/source/ja/create_a_model.md b/docs/source/ja/create_a_model.md index fdb23f98e7b1..913e992d5a9f 100644 --- a/docs/source/ja/create_a_model.md +++ b/docs/source/ja/create_a_model.md @@ -145,33 +145,6 @@ Once you are satisfied with your model configuration, you can save it with [`Pre >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) ``` - -モデルにカスタム設定属性をロードしてください: - -```py ->>> from transformers import TFDistilBertModel - ->>> my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json") ->>> tf_model = TFDistilBertModel(my_config) -``` - -これにより、事前学習済みの重みではなくランダムな値を持つモデルが作成されます。 -このモデルを有用な目的にはまだ使用することはできません。トレーニングはコストがかかり、時間がかかるプロセスです。 -一般的には、トレーニングに必要なリソースの一部しか使用せずに、より速く優れた結果を得るために事前学習済みモデルを使用することが良いでしょう。 - -[`~TFPreTrainedModel.from_pretrained`]を使用して事前学習済みモデルを作成します: - - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased") -``` - -事前学習済みの重みをロードする際、モデルが🤗 Transformersによって提供されている場合、デフォルトのモデル構成が自動的にロードされます。ただし、必要であればデフォルトのモデル構成属性の一部またはすべてを独自のもので置き換えることもできます: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) -``` - @@ -200,26 +173,6 @@ Once you are satisfied with your model configuration, you can save it with [`Pre ``` - -例えば、[`TFDistilBertForSequenceClassification`]は、シーケンス分類ヘッドを持つベースのDistilBERTモデルです。シーケンス分類ヘッドは、プールされた出力の上にある線形層です。 - -```py ->>> from transformers import TFDistilBertForSequenceClassification - ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -別のタスクにこのチェックポイントを簡単に再利用することができ、異なるモデルヘッドに切り替えるだけです。 -質問応答タスクの場合、[`TFDistilBertForQuestionAnswering`]モデルヘッドを使用します。 -質問応答ヘッドはシーケンス分類ヘッドと似ていますが、隠れ状態の出力の上に線形層があるだけです。 - - -```py ->>> from transformers import TFDistilBertForQuestionAnswering - ->>> tf_model = TFDistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") -``` - ## Tokenizer diff --git a/docs/source/ja/model_sharing.md b/docs/source/ja/model_sharing.md index 83df9d8f687e..f602208f04e5 100644 --- a/docs/source/ja/model_sharing.md +++ b/docs/source/ja/model_sharing.md @@ -94,30 +94,6 @@ TensorFlowからPyTorchにチェックポイントを変換するには、`from_ >>> pt_model.save_pretrained("path/to/awesome-name-you-picked") ``` - - -指定して、PyTorchからTensorFlowにチェックポイントを変換するには `from_pt=True` を使用します: - -```python ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_pt=True) -``` - -新しいTensorFlowモデルとその新しいチェックポイントを保存できます: - -```python ->>> tf_model.save_pretrained("path/to/awesome-name-you-picked") -``` - - - -Flaxでモデルが利用可能な場合、PyTorchからFlaxへのチェックポイントの変換も行うことができます: - -```py ->>> flax_model = FlaxDistilBertForSequenceClassification.from_pretrained( -... "path/to/awesome-name-you-picked", from_pt=True -... ) -``` - ## Push a model during traning @@ -165,28 +141,6 @@ Pass your training arguments as usual to [`Trainer`]: ``` - - -[`PushToHubCallback`]を使用してモデルをHubに共有します。[`PushToHubCallback`]関数には、次のものを追加します: - -- モデルの出力ディレクトリ。 -- トークナイザ。 -- `hub_model_id`、つまりHubのユーザー名とモデル名。 - -```python ->>> from transformers import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="./your_model_save_path", tokenizer=tokenizer, hub_model_id="your-username/my-awesome-model" -... ) -``` - -🤗 Transformersは[`fit`](https://keras.io/api/models/model_training_apis/)にコールバックを追加し、トレーニング済みモデルをHubにプッシュします: - -```py ->>> model.fit(tf_train_dataset, validation_data=tf_validation_dataset, epochs=3, callbacks=push_to_hub_callback) -``` - ## `push_to_hub` 関数を使用する diff --git a/docs/source/ja/preprocessing.md b/docs/source/ja/preprocessing.md index ea0b98df0280..9f61595e7c33 100644 --- a/docs/source/ja/preprocessing.md +++ b/docs/source/ja/preprocessing.md @@ -196,30 +196,6 @@ pip install datasets [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])} ``` - -```py ->>> batch_sentences = [ -... "But what about second breakfast?", -... "Don't think he knows about second breakfast, Pip.", -... "What about elevensies?", -... ] ->>> encoded_input = tokenizer(batch_sentences, padding=True, truncation=True, return_tensors="tf") ->>> print(encoded_input) -{'input_ids': , - 'token_type_ids': , - 'attention_mask': } -``` - ## Audio diff --git a/docs/source/ja/quicktour.md b/docs/source/ja/quicktour.md index 0eb00cf220b5..e077d512df4f 100644 --- a/docs/source/ja/quicktour.md +++ b/docs/source/ja/quicktour.md @@ -38,12 +38,6 @@ specific language governing permissions and limitations under the License. pip install torch ``` - - -```bash -pip install tensorflow -``` - ## Pipeline @@ -155,16 +149,6 @@ label: NEGATIVE, スコア: 0.5309 ``` - -以下のコードは、[`TFAutoModelForSequenceClassification`]および[`AutoTokenizer`]を使用して、事前学習済みモデルとその関連するトークナイザをロードする方法を示しています(`TFAutoClass`については次のセクションで詳しく説明します): - -```python ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - 指定したモデルとトークナイザを[`pipeline`]に設定し、今度はフランス語のテキストに`classifier`を適用できます: @@ -235,18 +219,6 @@ Pass your text to the tokenizer: ... ) ``` - - -```py ->>> tf_batch = tokenizer( -... ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="tf", -... ) -``` - @@ -295,41 +267,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ``` - -🤗 Transformersは事前学習済みインスタンスをロードするためのシンプルで統一された方法を提供します。 -これは、[`TFAutoModel`]を[`AutoTokenizer`]をロードするのと同じようにロードできることを意味します。 -唯一の違いは、タスクに適した[`TFAutoModel`]を選択することです。 -テキスト(またはシーケンス)分類の場合、[`TFAutoModelForSequenceClassification`]をロードする必要があります: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name) -``` - - - -詳細については、[`AutoModel`]クラスでサポートされているタスクに関する情報は、[タスクの概要](./task_summary)を参照してください。 - - - -次に、前処理済みのバッチを直接モデルに渡します。テンソルをそのまま渡すことができます: - -```python ->>> tf_outputs = tf_model(tf_batch) -``` - -モデルは`logits`属性に最終的なアクティベーションを出力します。`logits`にソフトマックス関数を適用して確率を取得します: - -```python ->>> import tensorflow as tf - ->>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1) ->>> tf_predictions # doctest: +IGNORE_RESULT -``` - - @@ -360,22 +297,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ``` - -モデルをファインチューニングしたら、そのトークナイザを使用してモデルを保存できます。[`TFPreTrainedModel.save_pretrained`]を使用します: - -```py ->>> tf_save_directory = "./tf_save_pretrained" ->>> tokenizer.save_pretrained(tf_save_directory) # doctest: +IGNORE_RESULT ->>> tf_model.save_pretrained(tf_save_directory) -``` - -モデルを再度使用する準備ができたら、[`TFPreTrainedModel.from_pretrained`]を使用して再度ロードします: - -```py ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained") -``` - - 🤗 Transformersの特に素晴らしい機能の一つは、モデルを保存し、それをPyTorchモデルまたはTensorFlowモデルとして再ロードできることです。 `from_pt`または`from_tf`パラメータを使用してモデルをフレームワーク間で変換できます: @@ -391,15 +312,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ``` - - -```py ->>> from transformers import TFAutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory) ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) -``` - ## Custom model builds @@ -425,16 +337,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ``` - -カスタム構成からモデルを作成するには、[`TFAutoModel.from_config`]を使用します: - -```py ->>> from transformers import TFAutoModel - ->>> my_model = TFAutoModel.from_config(my_config) -``` - - [カスタムアーキテクチャを作成](./create_a_model)ガイドを参照して、カスタム構成の詳細情報を確認してください。 diff --git a/docs/source/ja/run_scripts.md b/docs/source/ja/run_scripts.md index ca224d75a453..af0c1fdb1a50 100644 --- a/docs/source/ja/run_scripts.md +++ b/docs/source/ja/run_scripts.md @@ -111,23 +111,6 @@ python examples/pytorch/summarization/run_summarization.py \ ``` - -この例のスクリプトは、🤗 [Datasets](https://huggingface.co/docs/datasets/) ライブラリからデータセットをダウンロードして前処理します。その後、スクリプトは要約をサポートするアーキテクチャ上で Keras を使用してデータセットをファインチューニングします。以下の例では、[T5-small](https://huggingface.co/google-t5/t5-small) を [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail) データセットでファインチューニングする方法を示しています。T5 モデルは、そのトレーニング方法に起因して追加の `source_prefix` 引数が必要です。このプロンプトは、T5 にこれが要約タスクであることを知らせます。 - - -```bash -python examples/tensorflow/summarization/run_summarization.py \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Distributed training and mixed precision @@ -180,23 +163,6 @@ python xla_spawn.py --num_cores 8 \ --predict_with_generate ``` - -もちろん、Tensor Processing Units(TPUs)は性能を高速化するために特別に設計されています。TensorFlowスクリプトは、TPUsでトレーニングするために[`TPUStrategy`](https://www.tensorflow.org/guide/distributed_training#tpustrategy)を利用します。TPUを使用するには、TPUリソースの名前を`tpu`引数に渡します。 - -```bash -python run_summarization.py \ - --tpu name_of_tpu_resource \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Run a script with 🤗 Accelerate diff --git a/docs/source/ja/tasks/image_classification.md b/docs/source/ja/tasks/image_classification.md index 013dfc286dce..3a048e396eff 100644 --- a/docs/source/ja/tasks/image_classification.md +++ b/docs/source/ja/tasks/image_classification.md @@ -156,94 +156,6 @@ Datasets、🤗 データセット ライブラリから Food-101 データセ - - - - -過剰適合を回避し、モデルをより堅牢にするために、データセットのトレーニング部分にデータ拡張を追加します。 -ここでは、Keras 前処理レイヤーを使用してトレーニング データの変換 (データ拡張を含む) を定義します。 -検証データの変換 (中央のトリミング、サイズ変更、正規化のみ)。 `tf.image` または -他のライブラリでも構いません。 - - -```py ->>> from tensorflow import keras ->>> from tensorflow.keras import layers - ->>> size = (image_processor.size["height"], image_processor.size["width"]) - ->>> train_data_augmentation = keras.Sequential( -... [ -... layers.RandomCrop(size[0], size[1]), -... layers.Rescaling(scale=1.0 / 127.5, offset=-1), -... layers.RandomFlip("horizontal"), -... layers.RandomRotation(factor=0.02), -... layers.RandomZoom(height_factor=0.2, width_factor=0.2), -... ], -... name="train_data_augmentation", -... ) - ->>> val_data_augmentation = keras.Sequential( -... [ -... layers.CenterCrop(size[0], size[1]), -... layers.Rescaling(scale=1.0 / 127.5, offset=-1), -... ], -... name="val_data_augmentation", -... ) -``` - -次に、一度に 1 つの画像ではなく、画像のバッチに適切な変換を適用する関数を作成します。 - -```py ->>> import numpy as np ->>> import tensorflow as tf ->>> from PIL import Image - - ->>> def convert_to_tf_tensor(image: Image): -... np_image = np.array(image) -... tf_image = tf.convert_to_tensor(np_image) -... # `expand_dims()` is used to add a batch dimension since -... # the TF augmentation layers operates on batched inputs. -... return tf.expand_dims(tf_image, 0) - - ->>> def preprocess_train(example_batch): -... """Apply train_transforms across a batch.""" -... images = [ -... train_data_augmentation(convert_to_tf_tensor(image.convert("RGB"))) for image in example_batch["image"] -... ] -... example_batch["pixel_values"] = [tf.transpose(tf.squeeze(image)) for image in images] -... return example_batch - - -... def preprocess_val(example_batch): -... """Apply val_transforms across a batch.""" -... images = [ -... val_data_augmentation(convert_to_tf_tensor(image.convert("RGB"))) for image in example_batch["image"] -... ] -... example_batch["pixel_values"] = [tf.transpose(tf.squeeze(image)) for image in images] -... return example_batch -``` - -🤗 データセット [`~datasets.Dataset.set_transform`] を使用して、その場で変換を適用します。 - -```py -food["train"].set_transform(preprocess_train) -food["test"].set_transform(preprocess_val) -``` - -最後の前処理ステップとして、`DefaultDataCollat​​or`を使用してサンプルのバッチを作成します。 🤗 Transformers の他のデータ照合機能とは異なり、 -`DefaultDataCollat​​or` は、パディングなどの追加の前処理を適用しません。 - -```py ->>> from transformers import DefaultDataCollator - ->>> data_collator = DefaultDataCollator(return_tensors="tf") -``` - - - ## Evaluate トレーニング中にメトリクスを含めると、多くの場合、モデルのパフォーマンスを評価するのに役立ちます。すぐにロードできます @@ -338,117 +250,6 @@ food["test"].set_transform(preprocess_val) - - - - - - -Keras を使用したモデルの微調整に慣れていない場合は、まず [基本チュートリアル](./training#train-a-tensorflow-model-with-keras) を確認してください。 - - - - -TensorFlow でモデルを微調整するには、次の手順に従います。 -1. トレーニングのハイパーパラメータを定義し、オプティマイザーと学習率スケジュールを設定します。 -2. 事前トレーニングされたモデルをインスタンス化します。 -3. 🤗 データセットを `tf.data.Dataset` に変換します。 -4. モデルをコンパイルします。 -5. コールバックを追加し、`fit()` メソッドを使用してトレーニングを実行します。 -6. モデルを 🤗 Hub にアップロードしてコミュニティと共有します。 - -まず、ハイパーパラメーター、オプティマイザー、学習率スケジュールを定義します。 - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_epochs = 5 ->>> num_train_steps = len(food["train"]) * num_epochs ->>> learning_rate = 3e-5 ->>> weight_decay_rate = 0.01 - ->>> optimizer, lr_schedule = create_optimizer( -... init_lr=learning_rate, -... num_train_steps=num_train_steps, -... weight_decay_rate=weight_decay_rate, -... num_warmup_steps=0, -... ) -``` - -次に、ラベル マッピングとともに [`TFAutoModelForImageClassification`] を使用して ViT を読み込みます。 - -```py ->>> from transformers import TFAutoModelForImageClassification - ->>> model = TFAutoModelForImageClassification.from_pretrained( -... checkpoint, -... id2label=id2label, -... label2id=label2id, -... ) -``` - -Convert your datasets to the `tf.data.Dataset` format using the [`~datasets.Dataset.to_tf_dataset`] and your `data_collator`: - -```py ->>> # converting our train dataset to tf.data.Dataset ->>> tf_train_dataset = food["train"].to_tf_dataset( -... columns="pixel_values", label_cols="label", shuffle=True, batch_size=batch_size, collate_fn=data_collator -... ) - ->>> # converting our test dataset to tf.data.Dataset ->>> tf_eval_dataset = food["test"].to_tf_dataset( -... columns="pixel_values", label_cols="label", shuffle=True, batch_size=batch_size, collate_fn=data_collator -... ) -``` - -`compile()` を使用してトレーニング用にモデルを設定します。 - -```py ->>> from tensorflow.keras.losses import SparseCategoricalCrossentropy - ->>> loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) ->>> model.compile(optimizer=optimizer, loss=loss) -``` - -予測から精度を計算し、モデルを 🤗 ハブにプッシュするには、[Keras callbacks](../main_classes/keras_callbacks) を使用します。 -`compute_metrics` 関数を [KerasMetricCallback](../main_classes/keras_callbacks#transformers.KerasMetricCallback) に渡します。 -[PushToHubCallback](../main_classes/keras_callbacks#transformers.PushToHubCallback) を使用してモデルをアップロードします。 - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback, PushToHubCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_eval_dataset) ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="food_classifier", -... tokenizer=image_processor, -... save_strategy="no", -... ) ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -ついに、モデルをトレーニングする準備が整いました。トレーニングおよび検証データセット、エポック数、 -モデルを微調整するためのコールバック: - -```py ->>> model.fit(tf_train_dataset, validation_data=tf_eval_dataset, epochs=num_epochs, callbacks=callbacks) -Epoch 1/5 -250/250 [==============================] - 313s 1s/step - loss: 2.5623 - val_loss: 1.4161 - accuracy: 0.9290 -Epoch 2/5 -250/250 [==============================] - 265s 1s/step - loss: 0.9181 - val_loss: 0.6808 - accuracy: 0.9690 -Epoch 3/5 -250/250 [==============================] - 252s 1s/step - loss: 0.3910 - val_loss: 0.4303 - accuracy: 0.9820 -Epoch 4/5 -250/250 [==============================] - 251s 1s/step - loss: 0.2028 - val_loss: 0.3191 - accuracy: 0.9900 -Epoch 5/5 -250/250 [==============================] - 238s 949ms/step - loss: 0.1232 - val_loss: 0.3259 - accuracy: 0.9890 -``` - -おめでとう!モデルを微調整し、🤗 Hub で共有しました。これで推論に使用できるようになりました。 - - - - 画像分類用のモデルを微調整する方法の詳細な例については、対応する [PyTorch ノートブック](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/image_classification.ipynb) @@ -518,36 +319,3 @@ Epoch 5/5 ``` - - - - -画像プロセッサをロードして画像を前処理し、`input`を TensorFlow テンソルとして返します。 - -```py ->>> from transformers import AutoImageProcessor - ->>> image_processor = AutoImageProcessor.from_pretrained("MariaK/food_classifier") ->>> inputs = image_processor(image, return_tensors="tf") -``` - -入力をモデルに渡し、ロジットを返します。 - -```py ->>> from transformers import TFAutoModelForImageClassification - ->>> model = TFAutoModelForImageClassification.from_pretrained("MariaK/food_classifier") ->>> logits = model(**inputs).logits -``` - -最も高い確率で予測されたラベルを取得し、モデルの `id2label` マッピングを使用してラベルに変換します。 - - -```py ->>> predicted_class_id = int(tf.math.argmax(logits, axis=-1)[0]) ->>> model.config.id2label[predicted_class_id] -'beignets' -``` - - - diff --git a/docs/source/ja/tasks/language_modeling.md b/docs/source/ja/tasks/language_modeling.md index 1cadc0af0ac0..36662317a9be 100644 --- a/docs/source/ja/tasks/language_modeling.md +++ b/docs/source/ja/tasks/language_modeling.md @@ -198,16 +198,6 @@ Apply the `group_texts` function over the entire dataset: ``` - -シーケンス終了トークンをパディング トークンとして使用し、`mlm=False` を設定します。これは、入力を 1 要素分右にシフトしたラベルとして使用します。 - -```py ->>> from transformers import DataCollatorForLanguageModeling - ->>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False, return_tensors="tf") -``` - - @@ -272,78 +262,6 @@ Perplexity: 49.61 >>> trainer.push_to_hub() ``` - - - -Keras を使用したモデルの微調整に慣れていない場合は、[基本チュートリアル](../training#train-a-tensorflow-model-with-keras) をご覧ください。 - - -TensorFlow でモデルを微調整するには、オプティマイザー関数、学習率スケジュール、およびいくつかのトレーニング ハイパーパラメーターをセットアップすることから始めます。 - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -次に、[`TFAutoModelForCausalLM`] を使用して DistilGPT2 をロードできます。 - -```py ->>> from transformers import TFAutoModelForCausalLM - ->>> model = TFAutoModelForCausalLM.from_pretrained("distilbert/distilgpt2") -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`] を使用して、データセットを `tf.data.Dataset` 形式に変換します。 - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... lm_dataset["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... lm_dataset["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method) を使用してトレーニング用のモデルを設定します。 Transformers モデルにはすべてデフォルトのタスク関連の損失関数があるため、次の場合を除き、損失関数を指定する必要はないことに注意してください。 - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # No loss argument! -``` - -これは、モデルとトークナイザーを [`~transformers.PushToHubCallback`] でプッシュする場所を指定することで実行できます。 - - - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> callback = PushToHubCallback( -... output_dir="my_awesome_eli5_clm-model", -... tokenizer=tokenizer, -... ) -``` - -ついに、モデルのトレーニングを開始する準備が整いました。トレーニングおよび検証データセット、エポック数、コールバックを指定して [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) を呼び出し、モデルを微調整します。 - - - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=[callback]) -``` - -トレーニングが完了すると、モデルは自動的にハブにアップロードされ、誰でも使用できるようになります。 - - @@ -406,32 +324,4 @@ TensorFlow でモデルを微調整するには、オプティマイザー関数 ``` - - -テキストをトークン化し、`input_ids`を TensorFlow テンソルとして返します。 - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_eli5_clm-model") ->>> inputs = tokenizer(prompt, return_tensors="tf").input_ids -``` - -[`~transformers.generation_tf_utils.TFGenerationMixin.generate`] メソッドを使用して要約を作成します。さまざまなテキスト生成戦略と生成を制御するためのパラメーターの詳細については、[テキスト生成戦略](../generation_strategies) ページを参照してください。 - -```py ->>> from transformers import TFAutoModelForCausalLM - ->>> model = TFAutoModelForCausalLM.from_pretrained("my_awesome_eli5_clm-model") ->>> outputs = model.generate(input_ids=inputs, max_new_tokens=100, do_sample=True, top_k=50, top_p=0.95) -``` - -生成されたトークン ID をデコードしてテキストに戻します。 - -```py ->>> tokenizer.batch_decode(outputs, skip_special_tokens=True) -['Somatic hypermutation allows the immune system to detect the presence of other viruses as they become more prevalent. Therefore, researchers have identified a high proportion of human viruses. The proportion of virus-associated viruses in our study increases with age. Therefore, we propose a simple algorithm to detect the presence of these new viruses in our samples as a sign of improved immunity. A first study based on this algorithm, which will be published in Science on Friday, aims to show that this finding could translate into the development of a better vaccine that is more effective for'] -``` - - diff --git a/docs/source/ja/tasks/masked_language_modeling.md b/docs/source/ja/tasks/masked_language_modeling.md index 29d7b73ae5d0..90b39c695349 100644 --- a/docs/source/ja/tasks/masked_language_modeling.md +++ b/docs/source/ja/tasks/masked_language_modeling.md @@ -185,17 +185,6 @@ pip install transformers datasets evaluate >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15) ``` - - -シーケンス終了トークンをパディング トークンとして使用し、データを反復するたびにランダムにトークンをマスクするために `mlm_probability` を指定します。 - - -```py ->>> from transformers import DataCollatorForLanguageModeling - ->>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15, return_tensors="tf") -``` - ## Train @@ -261,78 +250,6 @@ Perplexity: 8.76 ``` - - - -Keras を使用したモデルの微調整に慣れていない場合は、[こちら](../training#train-a-tensorflow-model-with-keras) の基本的なチュートリアルをご覧ください。 - - - -TensorFlow でモデルを微調整するには、オプティマイザー関数、学習率スケジュール、およびいくつかのトレーニング ハイパーパラメーターをセットアップすることから始めます。 - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -次に、[`TFAutoModelForMaskedLM`] を使用して DistilRoBERTa をロードできます。 - -```py ->>> from transformers import TFAutoModelForMaskedLM - ->>> model = TFAutoModelForMaskedLM.from_pretrained("distilbert/distilroberta-base") -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`] を使用して、データセットを `tf.data.Dataset` 形式に変換します。 - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... lm_dataset["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... lm_dataset["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method) を使用してトレーニング用のモデルを設定します。 Transformers モデルにはすべてデフォルトのタスク関連の損失関数があるため、次の場合を除き、損失関数を指定する必要はないことに注意してください。 - - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # No loss argument! -``` - -This can be done by specifying where to push your model and tokenizer in the [`~transformers.PushToHubCallback`]: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> callback = PushToHubCallback( -... output_dir="my_awesome_eli5_mlm_model", -... tokenizer=tokenizer, -... ) -``` - -ついに、モデルのトレーニングを開始する準備が整いました。トレーニングおよび検証データセット、エポック数、コールバックを指定して [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) を呼び出し、モデルを微調整します。 - - - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=[callback]) -``` - -トレーニングが完了すると、モデルは自動的にハブにアップロードされ、誰でも使用できるようになります。 - - @@ -410,40 +327,4 @@ The Milky Way is a small galaxy. ``` - - -テキストをトークン化し、`input_ids`を TensorFlow テンソルとして返します。 `` トークンの位置も指定する必要があります。 - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_eli5_mlm_model") ->>> inputs = tokenizer(text, return_tensors="tf") ->>> mask_token_index = tf.where(inputs["input_ids"] == tokenizer.mask_token_id)[0, 1] -``` - -入力をモデルに渡し、マスクされたトークンの`logits`を返します。 - - -```py ->>> from transformers import TFAutoModelForMaskedLM - ->>> model = TFAutoModelForMaskedLM.from_pretrained("stevhliu/my_awesome_eli5_mlm_model") ->>> logits = model(**inputs).logits ->>> mask_token_logits = logits[0, mask_token_index, :] -``` - -次に、マスクされた 3 つのトークンを最も高い確率で返し、出力します。 - - -```py ->>> top_3_tokens = tf.math.top_k(mask_token_logits, 3).indices.numpy() - ->>> for token in top_3_tokens: -... print(text.replace(tokenizer.mask_token, tokenizer.decode([token]))) -The Milky Way is a spiral galaxy. -The Milky Way is a massive galaxy. -The Milky Way is a small galaxy. -``` - diff --git a/docs/source/ja/tasks/multiple_choice.md b/docs/source/ja/tasks/multiple_choice.md index ab4f2329f3b9..b0f623e29ab1 100644 --- a/docs/source/ja/tasks/multiple_choice.md +++ b/docs/source/ja/tasks/multiple_choice.md @@ -200,92 +200,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) >>> trainer.push_to_hub() ``` - - - -Keras を使用したモデルの微調整に慣れていない場合は、[こちら](../training#train-a-tensorflow-model-with-keras) の基本的なチュートリアルをご覧ください。 - - -TensorFlow でモデルを微調整するには、オプティマイザー関数、学習率スケジュール、およびいくつかのトレーニング ハイパーパラメーターをセットアップすることから始めます。 - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_train_epochs = 2 ->>> total_train_steps = (len(tokenized_swag["train"]) // batch_size) * num_train_epochs ->>> optimizer, schedule = create_optimizer(init_lr=5e-5, num_warmup_steps=0, num_train_steps=total_train_steps) -``` - -次に、[`TFAutoModelForMultipleChoice`] を使用して BERT をロードできます。 - -```py ->>> from transformers import TFAutoModelForMultipleChoice - ->>> model = TFAutoModelForMultipleChoice.from_pretrained("google-bert/bert-base-uncased") -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`] を使用して、データセットを `tf.data.Dataset` 形式に変換します。 - -```py ->>> data_collator = DataCollatorForMultipleChoice(tokenizer=tokenizer) ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_swag["train"], -... shuffle=True, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_swag["validation"], -... shuffle=False, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method) を使用してトレーニング用のモデルを設定します。 Transformers モデルにはすべてデフォルトのタスク関連の損失関数があるため、次の場合を除き、損失関数を指定する必要はないことに注意してください。 - -```py ->>> model.compile(optimizer=optimizer) # No loss argument! -``` - -トレーニングを開始する前にセットアップする最後の 2 つのことは、予測から精度を計算することと、モデルをハブにプッシュする方法を提供することです。どちらも [Keras コールバック](../main_classes/keras_callbacks) を使用して行われます。 - -`compute_metrics` 関数を [`~transformers.KerasMetricCallback`] に渡します。 - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -[`~transformers.PushToHubCallback`] でモデルとトークナイザーをプッシュする場所を指定します。 - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_model", -... tokenizer=tokenizer, -... ) -``` - -次に、コールバックをまとめてバンドルします。 - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -ついに、モデルのトレーニングを開始する準備が整いました。トレーニングおよび検証データセット、エポック数、コールバックを指定して [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) を呼び出し、モデルを微調整します。 - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=2, callbacks=callbacks) -``` - -トレーニングが完了すると、モデルは自動的にハブにアップロードされ、誰でも使用できるようになります。 - - @@ -341,34 +255,4 @@ TensorFlow でモデルを微調整するには、オプティマイザー関数 '0' ``` - - -各プロンプトと回答候補のペアをトークン化し、TensorFlow テンソルを返します。 - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_swag_model") ->>> inputs = tokenizer([[prompt, candidate1], [prompt, candidate2]], return_tensors="tf", padding=True) -``` - -入力をモデルに渡し、`logits`を返します。 - -```py ->>> from transformers import TFAutoModelForMultipleChoice - ->>> model = TFAutoModelForMultipleChoice.from_pretrained("my_awesome_swag_model") ->>> inputs = {k: tf.expand_dims(v, 0) for k, v in inputs.items()} ->>> outputs = model(inputs) ->>> logits = outputs.logits -``` - -最も高い確率でクラスを取得します。 - -```py ->>> predicted_class = int(tf.math.argmax(logits, axis=-1)[0]) ->>> predicted_class -'0' -``` - diff --git a/docs/source/ja/tasks/question_answering.md b/docs/source/ja/tasks/question_answering.md index 9217c211e6f9..302a794c8c02 100644 --- a/docs/source/ja/tasks/question_answering.md +++ b/docs/source/ja/tasks/question_answering.md @@ -1,200 +1,3 @@ - - -# Question answering - -[[open-in-colab]] - - - -質問応答タスクは、質問に対して回答を返します。 Alexa、Siri、Google などの仮想アシスタントに天気を尋ねたことがあるなら、質問応答モデルを使用したことがあるはずです。質問応答タスクには一般的に 2 つのタイプがあります。 - -- 抽出: 与えられたコンテキストから回答を抽出します。 -- 抽象的: 質問に正しく答えるコンテキストから回答を生成します。 - -このガイドでは、次の方法を説明します。 - -1. 抽出的質問応答用に [SQuAD](https://huggingface.co/datasets/squad) データセット上の [DistilBERT](https://huggingface.co/distilbert/distilbert-base-uncased) を微調整します。 -2. 微調整したモデルを推論に使用します。 - - - -このタスクと互換性のあるすべてのアーキテクチャとチェックポイントを確認するには、[タスクページ](https://huggingface.co/tasks/question-answering) を確認することをお勧めします。 - - - -始める前に、必要なライブラリがすべてインストールされていることを確認してください。 - -```bash -pip install transformers datasets evaluate -``` - -モデルをアップロードしてコミュニティと共有できるように、Hugging Face アカウントにログインすることをお勧めします。プロンプトが表示されたら、トークンを入力してログインします。 - -```py ->>> from huggingface_hub import notebook_login - ->>> notebook_login() -``` - -## Load SQuAD dataset - -まず、🤗 データセット ライブラリから SQuAD データセットの小さいサブセットを読み込みます。これにより、完全なデータセットのトレーニングにさらに時間を費やす前に、実験してすべてが機能することを確認する機会が得られます。 - - -```py ->>> from datasets import load_dataset - ->>> squad = load_dataset("squad", split="train[:5000]") -``` - -[`~datasets.Dataset.train_test_split`] メソッドを使用して、データセットの `train` 分割をトレイン セットとテスト セットに分割します。 - -```py ->>> squad = squad.train_test_split(test_size=0.2) -``` - -次に、例を見てみましょう。 - -```py ->>> squad["train"][0] -{'answers': {'answer_start': [515], 'text': ['Saint Bernadette Soubirous']}, - 'context': 'Architecturally, the school has a Catholic character. Atop the Main Building\'s gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend "Venite Ad Me Omnes". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.', - 'id': '5733be284776f41900661182', - 'question': 'To whom did the Virgin Mary allegedly appear in 1858 in Lourdes France?', - 'title': 'University_of_Notre_Dame' -} -``` - -ここにはいくつかの重要なフィールドがあります。 - -- `answers`: 回答トークンと回答テキストの開始位置。 -- `context`: モデルが答えを抽出するために必要な背景情報。 -- `question`: モデルが答える必要がある質問。 - -## Preprocess - - - -次のステップでは、DistilBERT トークナイザーをロードして`question`フィールドと`context`フィールドを処理します。 - - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased") -``` - -質問応答タスクに特有の、注意すべき前処理手順がいくつかあります。 - -1. データセット内の一部の例には、モデルの最大入力長を超える非常に長い「コンテキスト」が含まれる場合があります。より長いシーケンスを処理するには、`truncation="only_second"` を設定して `context` のみを切り捨てます。 -2. 次に、設定によって、回答の開始位置と終了位置を元の `context`にマッピングします。 - 「`return_offset_mapping=True`」。 -3. マッピングが手元にあるので、答えの開始トークンと終了トークンを見つけることができます。 [`~tokenizers.Encoding.sequence_ids`] メソッドを使用して、 - オフセットのどの部分が`question`に対応し、どの部分が`context`に対応するかを見つけます。 - -以下に、`answer`の開始トークンと終了トークンを切り詰めて`context`にマッピングする関数を作成する方法を示します。 - -```py ->>> def preprocess_function(examples): -... questions = [q.strip() for q in examples["question"]] -... inputs = tokenizer( -... questions, -... examples["context"], -... max_length=384, -... truncation="only_second", -... return_offsets_mapping=True, -... padding="max_length", -... ) - -... offset_mapping = inputs.pop("offset_mapping") -... answers = examples["answers"] -... start_positions = [] -... end_positions = [] - -... for i, offset in enumerate(offset_mapping): -... answer = answers[i] -... start_char = answer["answer_start"][0] -... end_char = answer["answer_start"][0] + len(answer["text"][0]) -... sequence_ids = inputs.sequence_ids(i) - -... # Find the start and end of the context -... idx = 0 -... while sequence_ids[idx] != 1: -... idx += 1 -... context_start = idx -... while sequence_ids[idx] == 1: -... idx += 1 -... context_end = idx - 1 - -... # If the answer is not fully inside the context, label it (0, 0) -... if offset[context_start][0] > end_char or offset[context_end][1] < start_char: -... start_positions.append(0) -... end_positions.append(0) -... else: -... # Otherwise it's the start and end token positions -... idx = context_start -... while idx <= context_end and offset[idx][0] <= start_char: -... idx += 1 -... start_positions.append(idx - 1) - -... idx = context_end -... while idx >= context_start and offset[idx][1] >= end_char: -... idx -= 1 -... end_positions.append(idx + 1) - -... inputs["start_positions"] = start_positions -... inputs["end_positions"] = end_positions -... return inputs -``` - -データセット全体に前処理関数を適用するには、🤗 Datasets [`~datasets.Dataset.map`] 関数を使用します。 `batched=True` を設定してデータセットの複数の要素を一度に処理することで、`map` 関数を高速化できます。不要な列を削除します。 - -```py ->>> tokenized_squad = squad.map(preprocess_function, batched=True, remove_columns=squad["train"].column_names) -``` - -次に、[`DefaultDataCollat​​or`] を使用してサンプルのバッチを作成します。 🤗 Transformers の他のデータ照合器とは異なり、[`DefaultDataCollat​​or`] はパディングなどの追加の前処理を適用しません。 - - - -```py ->>> from transformers import DefaultDataCollator - ->>> data_collator = DefaultDataCollator() -``` - - -```py ->>> from transformers import DefaultDataCollator - ->>> data_collator = DefaultDataCollator(return_tensors="tf") -``` - - - -## Train - - - - - -[`Trainer`] を使用したモデルの微調整に慣れていない場合は、[ここ](../training#train-with-pytorch-trainer) の基本的なチュートリアルをご覧ください。 - - これでモデルのトレーニングを開始する準備が整いました。 [`AutoModelForQuestionAnswering`] を使用して DitilBERT をロードします。 @@ -241,82 +44,6 @@ pip install transformers datasets evaluate >>> trainer.push_to_hub() ``` - - - -Keras を使用したモデルの微調整に慣れていない場合は、[こちら](../training#train-a-tensorflow-model-with-keras) の基本的なチュートリアルをご覧ください。 - - - - -TensorFlow でモデルを微調整するには、オプティマイザー関数、学習率スケジュール、およびいくつかのトレーニング ハイパーパラメーターをセットアップすることから始めます。 - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_epochs = 2 ->>> total_train_steps = (len(tokenized_squad["train"]) // batch_size) * num_epochs ->>> optimizer, schedule = create_optimizer( -... init_lr=2e-5, -... num_warmup_steps=0, -... num_train_steps=total_train_steps, -... ) -``` - -次に、[`TFAutoModelForQuestionAnswering`] を使用して DistilBERT をロードできます。 - -```py ->>> from transformers import TFAutoModelForQuestionAnswering - ->>> model = TFAutoModelForQuestionAnswering("distilbert/distilbert-base-uncased") -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`] を使用して、データセットを `tf.data.Dataset` 形式に変換します。 - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_squad["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_squad["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method) を使用してトレーニング用のモデルを設定します。 - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -トレーニングを開始する前に最後にセットアップすることは、モデルをハブにプッシュする方法を提供することです。これは、モデルとトークナイザーを [`~transformers.PushToHubCallback`] でプッシュする場所を指定することで実行できます。 - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> callback = PushToHubCallback( -... output_dir="my_awesome_qa_model", -... tokenizer=tokenizer, -... ) -``` - -ついに、モデルのトレーニングを開始する準備が整いました。トレーニングおよび検証データセット、エポック数、コールバックを指定して [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) を呼び出し、モデルを微調整します。 - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3, callbacks=[callback]) -``` - -トレーニングが完了すると、モデルは自動的にハブにアップロードされ、誰でも使用できるようになります。 - @@ -398,41 +125,4 @@ TensorFlow でモデルを微調整するには、オプティマイザー関数 '176 billion parameters and can generate text in 46 languages natural languages and 13' ``` - - -テキストをトークン化し、TensorFlow テンソルを返します。 - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_qa_model") ->>> inputs = tokenizer(question, text, return_tensors="tf") -``` - -入力をモデルに渡し、`logits`を返します。 - - -```py ->>> from transformers import TFAutoModelForQuestionAnswering - ->>> model = TFAutoModelForQuestionAnswering.from_pretrained("my_awesome_qa_model") ->>> outputs = model(**inputs) -``` - -モデル出力から開始位置と終了位置の最も高い確率を取得します。 - -```py ->>> answer_start_index = int(tf.math.argmax(outputs.start_logits, axis=-1)[0]) ->>> answer_end_index = int(tf.math.argmax(outputs.end_logits, axis=-1)[0]) -``` - -予測されたトークンをデコードして答えを取得します。 - -```py ->>> predict_answer_tokens = inputs.input_ids[0, answer_start_index : answer_end_index + 1] ->>> tokenizer.decode(predict_answer_tokens) -'176 billion parameters and can generate text in 46 languages natural languages and 13' -``` - - diff --git a/docs/source/ja/tasks/semantic_segmentation.md b/docs/source/ja/tasks/semantic_segmentation.md index cfbfd7b81c01..95953e841f53 100644 --- a/docs/source/ja/tasks/semantic_segmentation.md +++ b/docs/source/ja/tasks/semantic_segmentation.md @@ -143,65 +143,6 @@ pip install -q datasets transformers evaluate - - - -モデルを過学習に対してより堅牢にするために、画像データセットにいくつかのデータ拡張を適用するのが一般的です。 -このガイドでは、[`tf.image`](https://www.tensorflow.org/api_docs/python/tf/image) を使用して画像の色のプロパティをランダムに変更しますが、任意のプロパティを使用することもできます。画像 -好きな図書館。 -2 つの別々の変換関数を定義します。 -- 画像拡張を含むトレーニング データ変換 -- 🤗 Transformers のコンピューター ビジョン モデルはチャネル優先のレイアウトを想定しているため、画像を転置するだけの検証データ変換 - -```py ->>> import tensorflow as tf - - ->>> def aug_transforms(image): -... image = tf.keras.utils.img_to_array(image) -... image = tf.image.random_brightness(image, 0.25) -... image = tf.image.random_contrast(image, 0.5, 2.0) -... image = tf.image.random_saturation(image, 0.75, 1.25) -... image = tf.image.random_hue(image, 0.1) -... image = tf.transpose(image, (2, 0, 1)) -... return image - - ->>> def transforms(image): -... image = tf.keras.utils.img_to_array(image) -... image = tf.transpose(image, (2, 0, 1)) -... return image -``` - -次に、モデルの画像と注釈のバッチを準備する 2 つの前処理関数を作成します。これらの機能が適用されます -画像変換を行い、以前にロードされた `image_processor` を使用して画像を `pixel_values` に変換し、 -`labels`への注釈。 `ImageProcessor` は、画像のサイズ変更と正規化も処理します。 - -```py ->>> def train_transforms(example_batch): -... images = [aug_transforms(x.convert("RGB")) for x in example_batch["image"]] -... labels = [x for x in example_batch["annotation"]] -... inputs = image_processor(images, labels) -... return inputs - - ->>> def val_transforms(example_batch): -... images = [transforms(x.convert("RGB")) for x in example_batch["image"]] -... labels = [x for x in example_batch["annotation"]] -... inputs = image_processor(images, labels) -... return inputs -``` - -データセット全体に前処理変換を適用するには、🤗 Datasets [`~datasets.Dataset.set_transform`] 関数を使用します。 -変換はオンザフライで適用されるため、高速で消費するディスク容量が少なくなります。 - -```py ->>> train_ds.set_transform(train_transforms) ->>> test_ds.set_transform(val_transforms) -``` - - - ## Evaluate トレーニング中にメトリクスを含めると、多くの場合、モデルのパフォーマンスを評価するのに役立ちます。 🤗 [Evaluate](https://huggingface.co/docs/evaluate/index) ライブラリを使用して、評価メソッドをすばやくロードできます。このタスクでは、[Mean Intersection over Union](https://huggingface.co/spaces/evaluate-metric/accuracy) (IoU) メトリックをロードします (🤗 Evaluate [クイック ツアー](https://huggingface.co/docs/evaluate/a_quick_tour) を参照して、メトリクスをロードして計算する方法の詳細を確認してください)。 @@ -252,39 +193,6 @@ pip install -q datasets transformers evaluate - - - -```py ->>> def compute_metrics(eval_pred): -... logits, labels = eval_pred -... logits = tf.transpose(logits, perm=[0, 2, 3, 1]) -... logits_resized = tf.image.resize( -... logits, -... size=tf.shape(labels)[1:], -... method="bilinear", -... ) - -... pred_labels = tf.argmax(logits_resized, axis=-1) -... metrics = metric.compute( -... predictions=pred_labels, -... references=labels, -... num_labels=num_labels, -... ignore_index=-1, -... reduce_labels=image_processor.do_reduce_labels, -... ) - -... per_category_accuracy = metrics.pop("per_category_accuracy").tolist() -... per_category_iou = metrics.pop("per_category_iou").tolist() - -... metrics.update({f"accuracy_{id2label[i]}": v for i, v in enumerate(per_category_accuracy)}) -... metrics.update({f"iou_{id2label[i]}": v for i, v in enumerate(per_category_iou)}) -... return {"val_" + k: v for k, v in metrics.items()} -``` - - - - これで`compute_metrics`関数の準備が整いました。トレーニングをセットアップするときにこの関数に戻ります。 ## Train @@ -347,110 +255,6 @@ pip install -q datasets transformers evaluate - - - - -Keras を使用したモデルの微調整に慣れていない場合は、まず [基本チュートリアル](./training#train-a-tensorflow-model-with-keras) を確認してください。 - - - -TensorFlow でモデルを微調整するには、次の手順に従います。 -1. トレーニングのハイパーパラメータを定義し、オプティマイザーと学習率スケジュールを設定します。 -2. 事前トレーニングされたモデルをインスタンス化します。 -3. 🤗 データセットを `tf.data.Dataset` に変換します。 -4. モデルをコンパイルします。 -5. コールバックを追加してメトリクスを計算し、モデルを 🤗 Hub にアップロードします -6. `fit()` メソッドを使用してトレーニングを実行します。 - -まず、ハイパーパラメーター、オプティマイザー、学習率スケジュールを定義します。 - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 2 ->>> num_epochs = 50 ->>> num_train_steps = len(train_ds) * num_epochs ->>> learning_rate = 6e-5 ->>> weight_decay_rate = 0.01 - ->>> optimizer, lr_schedule = create_optimizer( -... init_lr=learning_rate, -... num_train_steps=num_train_steps, -... weight_decay_rate=weight_decay_rate, -... num_warmup_steps=0, -... ) -``` - -次に、ラベル マッピングとともに [`TFAutoModelForSemanticSegmentation`] を使用して SegFormer をロードし、それをコンパイルします。 -オプティマイザ。 Transformers モデルにはすべてデフォルトのタスク関連の損失関数があるため、次の場合を除き、損失関数を指定する必要はないことに注意してください。 - -```py ->>> from transformers import TFAutoModelForSemanticSegmentation - ->>> model = TFAutoModelForSemanticSegmentation.from_pretrained( -... checkpoint, -... id2label=id2label, -... label2id=label2id, -... ) ->>> model.compile(optimizer=optimizer) # No loss argument! -``` - -[`~datasets.Dataset.to_tf_dataset`] と [`DefaultDataCollat​​or`] を使用して、データセットを `tf.data.Dataset` 形式に変換します。 - -```py ->>> from transformers import DefaultDataCollator - ->>> data_collator = DefaultDataCollator(return_tensors="tf") - ->>> tf_train_dataset = train_ds.to_tf_dataset( -... columns=["pixel_values", "label"], -... shuffle=True, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) - ->>> tf_eval_dataset = test_ds.to_tf_dataset( -... columns=["pixel_values", "label"], -... shuffle=True, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) -``` - -予測から精度を計算し、モデルを 🤗 ハブにプッシュするには、[Keras callbacks](../main_classes/keras_callbacks) を使用します。 -`compute_metrics` 関数を [`KerasMetricCallback`] に渡します。 -そして [`PushToHubCallback`] を使用してモデルをアップロードします。 - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback, PushToHubCallback - ->>> metric_callback = KerasMetricCallback( -... metric_fn=compute_metrics, eval_dataset=tf_eval_dataset, batch_size=batch_size, label_cols=["labels"] -... ) - ->>> push_to_hub_callback = PushToHubCallback(output_dir="scene_segmentation", tokenizer=image_processor) - ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -ついに、モデルをトレーニングする準備が整いました。トレーニングおよび検証データセット、エポック数、 -モデルを微調整するためのコールバック: - - -```py ->>> model.fit( -... tf_train_dataset, -... validation_data=tf_eval_dataset, -... callbacks=callbacks, -... epochs=num_epochs, -... ) -``` - -おめでとう!モデルを微調整し、🤗 Hub で共有しました。これで推論に使用できるようになりました。 - - - ## Inference モデルを微調整したので、それを推論に使用できるようになりました。 @@ -537,44 +341,6 @@ TensorFlow でモデルを微調整するには、次の手順に従います。 - - - -画像プロセッサをロードして画像を前処理し、入力を TensorFlow テンソルとして返します。 - -```py ->>> from transformers import AutoImageProcessor - ->>> image_processor = AutoImageProcessor.from_pretrained("MariaK/scene_segmentation") ->>> inputs = image_processor(image, return_tensors="tf") -``` - -入力をモデルに渡し、`logits`を返します。 - -```py ->>> from transformers import TFAutoModelForSemanticSegmentation - ->>> model = TFAutoModelForSemanticSegmentation.from_pretrained("MariaK/scene_segmentation") ->>> logits = model(**inputs).logits -``` - -次に、ロジットを元の画像サイズに再スケールし、クラス次元に argmax を適用します。 - -```py ->>> logits = tf.transpose(logits, [0, 2, 3, 1]) - ->>> upsampled_logits = tf.image.resize( -... logits, -... # We reverse the shape of `image` because `image.size` returns width and height. -... image.size[::-1], -... ) - ->>> pred_seg = tf.math.argmax(upsampled_logits, axis=-1)[0] -``` - - - - 結果を視覚化するには、[データセット カラー パレット](https://github.com/tensorflow/models/blob/3f1ca33afe3c1631b733ea7e40c294273b9e406d/research/deeplab/utils/get_dataset_colormap.py#L51) を、それぞれをマップする `ade_palette()` としてロードします。クラスを RGB 値に変換します。次に、画像と予測されたセグメンテーション マップを組み合わせてプロットできます。 ```py diff --git a/docs/source/ja/tasks/summarization.md b/docs/source/ja/tasks/summarization.md index 6784696e6c95..182221610ba2 100644 --- a/docs/source/ja/tasks/summarization.md +++ b/docs/source/ja/tasks/summarization.md @@ -128,14 +128,6 @@ pip install transformers datasets evaluate rouge_score >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - -```py ->>> from transformers import DataCollatorForSeq2Seq - ->>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint, return_tensors="tf") -``` - ## Evaluate @@ -230,91 +222,6 @@ pip install transformers datasets evaluate rouge_score >>> trainer.push_to_hub() ``` - - - -Keras を使用したモデルの微調整に慣れていない場合は、[こちら](../training#train-a-tensorflow-model-with-keras) の基本的なチュートリアルをご覧ください。 - - -TensorFlow でモデルを微調整するには、オプティマイザー関数、学習率スケジュール、およびいくつかのトレーニング ハイパーパラメーターをセットアップすることから始めます。 - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -次に、[`TFAutoModelForSeq2SeqLM`] を使用して T5 をロードできます。 - - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained(checkpoint) -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`] を使用して、データセットを `tf.data.Dataset` 形式に変換します。 - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_billsum["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... tokenized_billsum["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method) を使用してトレーニング用のモデルを設定します。 Transformers モデルにはすべてデフォルトのタスク関連の損失関数があるため、次の場合を除き、損失関数を指定する必要はないことに注意してください。 - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # No loss argument! -``` - -トレーニングを開始する前にセットアップする最後の 2 つのことは、予測から ROUGE スコアを計算し、モデルをハブにプッシュする方法を提供することです。どちらも [Keras コールバック](../main_classes/keras_callbacks) を使用して行われます。 - -`compute_metrics` 関数を [`~transformers.KerasMetricCallback`] に渡します。 - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -Specify where to push your model and tokenizer in the [`~transformers.PushToHubCallback`]: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_billsum_model", -... tokenizer=tokenizer, -... ) -``` - -次に、コールバックをまとめてバンドルします。 - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -ついに、モデルのトレーニングを開始する準備が整いました。トレーニングおよび検証データセット、エポック数、コールバックを指定して [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) を呼び出し、モデルを微調整します。 - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=callbacks) -``` - -トレーニングが完了すると、モデルは自動的にハブにアップロードされ、誰でも使用できるようになります。 - - @@ -374,31 +281,4 @@ Tokenize the text and return the `input_ids` as PyTorch tensors: 'the inflation reduction act lowers prescription drug costs, health care costs, and energy costs. it's the most aggressive action on tackling the climate crisis in american history. it will ask the ultra-wealthy and corporations to pay their fair share.' ``` - - -テキストをトークン化し、`input_ids`を TensorFlow テンソルとして返します。 - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_billsum_model") ->>> inputs = tokenizer(text, return_tensors="tf").input_ids -``` - -[`~transformers.generation_tf_utils.TFGenerationMixin.generate`] メソッドを使用して要約を作成します。さまざまなテキスト生成戦略と生成を制御するためのパラメーターの詳細については、[Text Generation](../main_classes/text_generation) API を確認してください。 - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained("stevhliu/my_awesome_billsum_model") ->>> outputs = model.generate(inputs, max_new_tokens=100, do_sample=False) -``` - -生成されたトークン ID をデコードしてテキストに戻します。 - -```py ->>> tokenizer.decode(outputs[0], skip_special_tokens=True) -'the inflation reduction act lowers prescription drug costs, health care costs, and energy costs. it's the most aggressive action on tackling the climate crisis in american history. it will ask the ultra-wealthy and corporations to pay their fair share.' -``` - diff --git a/docs/source/ja/tasks/token_classification.md b/docs/source/ja/tasks/token_classification.md index 4389aeacb564..9642a425ff17 100644 --- a/docs/source/ja/tasks/token_classification.md +++ b/docs/source/ja/tasks/token_classification.md @@ -164,14 +164,6 @@ pip install transformers datasets evaluate seqeval >>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer) ``` - - -```py ->>> from transformers import DataCollatorForTokenClassification - ->>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer, return_tensors="tf") -``` - ## Evaluate @@ -309,100 +301,6 @@ pip install transformers datasets evaluate seqeval >>> trainer.push_to_hub() ``` - - - -Keras を使用したモデルの微調整に慣れていない場合は、[こちら](../training#train-a-tensorflow-model-with-keras) の基本的なチュートリアルをご覧ください。 - - -TensorFlow でモデルを微調整するには、オプティマイザー関数、学習率スケジュール、およびいくつかのトレーニング ハイパーパラメーターをセットアップすることから始めます。 - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_train_epochs = 3 ->>> num_train_steps = (len(tokenized_wnut["train"]) // batch_size) * num_train_epochs ->>> optimizer, lr_schedule = create_optimizer( -... init_lr=2e-5, -... num_train_steps=num_train_steps, -... weight_decay_rate=0.01, -... num_warmup_steps=0, -... ) -``` -次に、[`TFAutoModelForTokenClassification`] を使用して、予期されるラベルの数とラベル マッピングを指定して DistilBERT をロードできます。 - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained( -... "distilbert/distilbert-base-uncased", num_labels=13, id2label=id2label, label2id=label2id -... ) -``` -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`] を使用して、データセットを `tf.data.Dataset` 形式に変換します。 - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_wnut["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_wnut["validation"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method) を使用してトレーニング用のモデルを設定します。 Transformers モデルにはすべてデフォルトのタスク関連の損失関数があるため、次の場合を除き、損失関数を指定する必要はないことに注意してください。 - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # No loss argument! -``` - -トレーニングを開始する前にセットアップする最後の 2 つのことは、予測から連続スコアを計算することと、モデルをハブにプッシュする方法を提供することです。どちらも [Keras コールバック](../main_classes/keras_callbacks) を使用して行われます。 - -`compute_metrics` 関数を [`~transformers.KerasMetricCallback`] に渡します。 - - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -[`~transformers.PushToHubCallback`] でモデルとトークナイザーをプッシュする場所を指定します。 - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_wnut_model", -... tokenizer=tokenizer, -... ) -``` - -次に、コールバックをまとめてバンドルします。 - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -ついに、モデルのトレーニングを開始する準備が整いました。トレーニングおよび検証データセット、エポック数、コールバックを指定して [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) を呼び出し、モデルを微調整します。 - - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3, callbacks=callbacks) -``` - -トレーニングが完了すると、モデルは自動的にハブにアップロードされ、誰でも使用できるようになります。 - - @@ -512,50 +410,4 @@ TensorFlow でモデルを微調整するには、オプティマイザー関数 ``` - - -テキストをトークン化し、TensorFlow テンソルを返します。 - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_wnut_model") ->>> inputs = tokenizer(text, return_tensors="tf") -``` - -入力をモデルに渡し、`logits`を返します。 - - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("stevhliu/my_awesome_wnut_model") ->>> logits = model(**inputs).logits -``` - -最も高い確率でクラスを取得し、モデルの `id2label` マッピングを使用してそれをテキスト ラベルに変換します。 - -```py ->>> predicted_token_class_ids = tf.math.argmax(logits, axis=-1) ->>> predicted_token_class = [model.config.id2label[t] for t in predicted_token_class_ids[0].numpy().tolist()] ->>> predicted_token_class -['O', - 'O', - 'B-location', - 'I-location', - 'B-group', - 'O', - 'O', - 'O', - 'O', - 'O', - 'O', - 'O', - 'O', - 'B-location', - 'B-location', - 'O', - 'O'] -``` - diff --git a/docs/source/ja/tasks/translation.md b/docs/source/ja/tasks/translation.md index 7fa45eac9cdb..82df32e082a9 100644 --- a/docs/source/ja/tasks/translation.md +++ b/docs/source/ja/tasks/translation.md @@ -122,14 +122,6 @@ pip install transformers datasets evaluate sacrebleu >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - -```py ->>> from transformers import DataCollatorForSeq2Seq - ->>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint, return_tensors="tf") -``` - ## Evaluate @@ -234,90 +226,6 @@ pip install transformers datasets evaluate sacrebleu >>> trainer.push_to_hub() ``` - - - -Keras を使用したモデルの微調整に慣れていない場合は、[こちら](../training#train-a-tensorflow-model-with-keras) の基本的なチュートリアルをご覧ください。 - - -TensorFlow でモデルを微調整するには、オプティマイザー関数、学習率スケジュール、およびいくつかのトレーニング ハイパーパラメーターをセットアップすることから始めます。 - - -```py ->>> from transformers import AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -次に、[`TFAutoModelForSeq2SeqLM`] を使用して T5 をロードできます。 - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained(checkpoint) -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`] を使用して、データセットを `tf.data.Dataset` 形式に変換します。 - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_books["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... tokenized_books["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method) を使用してトレーニング用のモデルを設定します。 Transformers モデルにはすべてデフォルトのタスク関連の損失関数があるため、次の場合を除き、損失関数を指定する必要はないことに注意してください。 - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # No loss argument! -``` -トレーニングを開始する前にセットアップする最後の 2 つのことは、予測から SacreBLEU メトリクスを計算し、モデルをハブにプッシュする方法を提供することです。どちらも [Keras コールバック](../main_classes/keras_callbacks) を使用して行われます。 - -`compute_metrics` 関数を [`~transformers.KerasMetricCallback`] に渡します。 - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -[`~transformers.PushToHubCallback`] でモデルとトークナイザーをプッシュする場所を指定します。 - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_opus_books_model", -... tokenizer=tokenizer, -... ) -``` - -次に、コールバックをまとめてバンドルします。 - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -ついに、モデルのトレーニングを開始する準備が整いました。トレーニングおよび検証データセット、エポック数、コールバックを指定して [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) を呼び出し、モデルを微調整します。 - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=callbacks) -``` - -トレーニングが完了すると、モデルは自動的にハブにアップロードされ、誰でも使用できるようになります。 - - @@ -385,31 +293,4 @@ TensorFlow でモデルを微調整するには、オプティマイザー関数 ``` - - -`input_ids`を TensorFlow テンソルとして返します。 tensors: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_opus_books_model") ->>> inputs = tokenizer(text, return_tensors="tf").input_ids -``` - -[`~transformers.generation_tf_utils.TFGenerationMixin.generate`] メソッドを使用して翻訳を作成します。さまざまなテキスト生成戦略と生成を制御するためのパラメーターの詳細については、[Text Generation](../main_classes/text_generation) API を確認してください。 - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained("my_awesome_opus_books_model") ->>> outputs = model.generate(inputs, max_new_tokens=40, do_sample=True, top_k=30, top_p=0.95) -``` - -生成されたトークン ID をデコードしてテキストに戻します。 - -```py ->>> tokenizer.decode(outputs[0], skip_special_tokens=True) -'Les lugumes partagent les ressources avec des bactéries fixatrices d'azote.' -``` - diff --git a/docs/source/ja/training.md b/docs/source/ja/training.md index 9dd2369601c1..ff70ed8e31ef 100644 --- a/docs/source/ja/training.md +++ b/docs/source/ja/training.md @@ -164,112 +164,6 @@ BERTモデルの事前学習済みのヘッドは破棄され、ランダムに ``` - - - - - -## Kerasを使用してTensorFlowモデルをトレーニングする - -Keras APIを使用して🤗 TransformersモデルをTensorFlowでトレーニングすることもできます! - -### Loading Data from Keras - -🤗 TransformersモデルをKeras APIでトレーニングする場合、データセットをKerasが理解できる形式に変換する必要があります。 -データセットが小さい場合、データセット全体をNumPy配列に変換してKerasに渡すことができます。 -複雑なことをする前に、まずそれを試してみましょう。 - -まず、データセットを読み込みます。GLUEベンチマークからCoLAデータセットを使用します -([GLUE Banchmark](https://huggingface.co/datasets/glue))、これは単純なバイナリテキスト分類タスクです。今のところトレーニング分割のみを使用します。 - -```py -from datasets import load_dataset - -dataset = load_dataset("glue", "cola") -dataset = dataset["train"] # 今のところトレーニング分割のみを使用します -``` - -次に、トークナイザをロードし、データをNumPy配列としてトークン化します。ラベルは既に`0`と`1`のリストであるため、トークン化せずに直接NumPy配列に変換できます! - -```python -from transformers import AutoTokenizer - -tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-cased") -tokenized_data = tokenizer(dataset["sentence"], return_tensors="np", padding=True) -# トークナイザはBatchEncodingを返しますが、それをKeras用に辞書に変換します -tokenized_data = dict(tokenized_data) - -labels = np.array(dataset["label"]) # ラベルはすでに0と1の配列です -``` - -最後に、モデルをロードし、[`compile`](https://keras.io/api/models/model_training_apis/#compile-method) と [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) メソッドを実行します。 -注意点として、Transformersモデルはすべてデフォルトでタスクに関連した損失関数を持っているため、指定しなくても構いません(指定する場合を除く): - -```python -from transformers import TFAutoModelForSequenceClassification -from tensorflow.keras.optimizers import Adam - -# モデルをロードしてコンパイルする -model = TFAutoModelForSequenceClassification.from_pretrained("google-bert/bert-base-cased") -# ファインチューニングには通常、学習率を下げると良いです -model.compile(optimizer=Adam(3e-5)) # 損失関数の指定は不要です! - -model.fit(tokenized_data, labels) -``` - - - -モデルを`compile()`する際に`loss`引数を渡す必要はありません!Hugging Faceモデルは、この引数を空白のままにしておくと、タスクとモデルアーキテクチャに適した損失を自動的に選択します。 -必要に応じて自分で損失を指定してオーバーライドすることもできます! - - - -このアプローチは、小規模なデータセットには適していますが、大規模なデータセットに対しては問題になることがあります。なぜなら、トークナイズされた配列とラベルはメモリに完全に読み込まれる必要があり、またNumPyは「ジャギー」な配列を処理しないため、トークナイズされた各サンプルを全体のデータセット内で最も長いサンプルの長さにパディングする必要があります。 -これにより、配列がさらに大きくなり、すべてのパディングトークンがトレーニングを遅くする原因になります! - -### Loading data as a tf.data.Dataset - -トレーニングを遅くせずにデータを読み込むには、データを`tf.data.Dataset`として読み込むことができます。独自の`tf.data`パイプラインを作成することもできますが、これを行うための便利な方法が2つあります: - -- [`~TFPreTrainedModel.prepare_tf_dataset`]: これはほとんどの場合で推奨する方法です。モデル上のメソッドなので、モデルを検査してモデル入力として使用可能な列を自動的に把握し、他の列を破棄してより単純で高性能なデータセットを作成できます。 -- [`~datasets.Dataset.to_tf_dataset`]: このメソッドはより低レベルで、データセットがどのように作成されるかを正確に制御する場合に便利です。`columns`と`label_cols`を指定して、データセットに含める列を正確に指定できます。 - -[`~TFPreTrainedModel.prepare_tf_dataset`]を使用する前に、次のコードサンプルに示すように、トークナイザの出力をデータセットに列として追加する必要があります: - -```py -def tokenize_dataset(data): - # 返された辞書のキーはデータセットに列として追加されます - return tokenizer(data["text"]) - - -dataset = dataset.map(tokenize_dataset) -``` - -Hugging Faceのデータセットはデフォルトでディスクに保存されるため、これによりメモリの使用量が増えることはありません! -列が追加されたら、データセットからバッチをストリームし、各バッチにパディングを追加できます。これにより、 -データセット全体にパディングを追加する場合と比べて、パディングトークンの数が大幅に削減されます。 - -```python ->>> tf_dataset = model.prepare_tf_dataset(dataset["train"], batch_size=16, shuffle=True, tokenizer=tokenizer) -``` - -上記のコードサンプルでは、トークナイザを`prepare_tf_dataset`に渡して、バッチを正しく読み込む際に正しくパディングできるようにする必要があります。 -データセットのすべてのサンプルが同じ長さであり、パディングが不要な場合は、この引数をスキップできます。 -パディング以外の複雑な処理を行う必要がある場合(例:マスク言語モデリングのためのトークンの破損など)、 -代わりに`collate_fn`引数を使用して、サンプルのリストをバッチに変換し、必要な前処理を適用する関数を渡すことができます。 -このアプローチを実際に使用した例については、 -[examples](https://github.com/huggingface/transformers/tree/main/examples)や -[notebooks](https://huggingface.co/docs/transformers/notebooks)をご覧ください。 - -`tf.data.Dataset`を作成したら、以前と同様にモデルをコンパイルし、適合させることができます: - -```python -model.compile(optimizer=Adam(3e-5)) # 損失引数は不要です! - -model.fit(tf_dataset) -``` - - diff --git a/docs/source/ko/model_sharing.md b/docs/source/ko/model_sharing.md index 934838c5ffe1..c2bf04365a79 100644 --- a/docs/source/ko/model_sharing.md +++ b/docs/source/ko/model_sharing.md @@ -88,28 +88,6 @@ pip install huggingface_hub >>> pt_model.save_pretrained("path/to/awesome-name-you-picked") ``` - -체크포인트를 PyTorch에서 TensorFlow로 변환하려면 `from_pt=True`를 지정하세요: - -```py ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_pt=True) -``` - -그런 다음 새로운 체크포인트와 함께 새로운 TensorFlow 모델을 저장할 수 있습니다: - -```py ->>> tf_model.save_pretrained("path/to/awesome-name-you-picked") -``` - - -Flax에서 모델을 사용하는 경우, PyTorch에서 Flax로 체크포인트를 변환할 수도 있습니다: - -```py ->>> flax_model = FlaxDistilBertForSequenceClassification.from_pretrained( -... "path/to/awesome-name-you-picked", from_pt=True -... ) -``` - ## 훈련 중 모델 푸시하기[[push-a-model-during-training]] @@ -142,27 +120,6 @@ Flax에서 모델을 사용하는 경우, PyTorch에서 Flax로 체크포인트 >>> trainer.push_to_hub() ``` - -[`PushToHubCallback`]을 사용하여 모델을 허브에 공유하려면, [`PushToHubCallback`]에 다음 인수를 정의하세요: - -- 출력된 모델의 파일 경로 -- 토크나이저 -- `{Hub 사용자 이름}/{모델 이름}` 형식의 `hub_model_id` - -```py ->>> from transformers import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="./your_model_save_path", tokenizer=tokenizer, hub_model_id="your-username/my-awesome-model" -... ) -``` - -[`fit`](https://keras.io/api/models/model_training_apis/)에 콜백을 추가하면, 🤗 Transformers가 훈련된 모델을 허브로 푸시합니다: - -```py ->>> model.fit(tf_train_dataset, validation_data=tf_validation_dataset, epochs=3, callbacks=push_to_hub_callback) -``` - ## `push_to_hub` 함수 사용하기[[use-the-pushtohub-function]] diff --git a/docs/source/ko/quicktour.md b/docs/source/ko/quicktour.md index 4c3b137aa00f..133b04206c9e 100644 --- a/docs/source/ko/quicktour.md +++ b/docs/source/ko/quicktour.md @@ -35,12 +35,6 @@ rendered properly in your Markdown viewer. pip install torch ``` - - -```bash -pip install tensorflow -``` - ## 파이프라인 [[pipeline]] @@ -150,16 +144,6 @@ label: NEGATIVE, with score: 0.5309 >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - -[`TFAutoModelForSequenceClassification`]과 [`AutoTokenizer`]를 사용하여 사전 훈련된 모델과 관련된 토크나이저를 로드하세요 (다음 섹션에서 [`TFAutoClass`]에 대해 더 자세히 알아보겠습니다): - -```py ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - [`pipeline`]에서 모델과 토크나이저를 지정하면, 이제 `classifier`를 프랑스어 텍스트에 적용할 수 있습니다: @@ -223,18 +207,6 @@ label: NEGATIVE, with score: 0.5309 ... ) ``` - - -```py ->>> tf_batch = tokenizer( -... ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="tf", -... ) -``` - @@ -279,37 +251,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - -🤗 Transformers는 사전 훈련된 인스턴스를 간단하고 통합된 방법으로 로드할 수 있습니다. 즉, [`AutoTokenizer`]처럼 [`TFAutoModel`]을 로드할 수 있습니다. 유일한 차이점은 과업에 알맞은 [`TFAutoModel`]을 선택해야 한다는 점입니다. 텍스트 (또는 시퀀스) 분류의 경우 [`TFAutoModelForSequenceClassification`]을 로드해야 합니다: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name) -``` - - - -[`AutoModel`] 클래스에서 지원하는 과업에 대해서는 [과업 요약](./task_summary)을 참조하세요. - - - -이제 전처리된 입력 묶음을 직접 모델에 전달해야 합니다. 아래처럼 그대로 텐서를 전달하면 됩니다: - -```py ->>> tf_outputs = tf_model(tf_batch) -``` - -모델의 최종 활성화 함수 출력은 `logits` 속성에 담겨있습니다. `logits`에 softmax 함수를 적용하여 확률을 얻을 수 있습니다: - -```py ->>> import tensorflow as tf - ->>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1) ->>> tf_predictions # doctest: +IGNORE_RESULT -``` - @@ -336,21 +277,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - -미세조정된 모델을 토크나이저와 함께 저장하려면 [`TFPreTrainedModel.save_pretrained`]를 사용하세요: - -```py ->>> tf_save_directory = "./tf_save_pretrained" ->>> tokenizer.save_pretrained(tf_save_directory) # doctest: +IGNORE_RESULT ->>> tf_model.save_pretrained(tf_save_directory) -``` - -모델을 다시 사용하려면 [`TFPreTrainedModel.from_pretrained`]로 모델을 다시 로드하세요: - -```py ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained") -``` - 🤗 Transformers의 멋진 기능 중 하나는 모델을 PyTorch 또는 TensorFlow 모델로 저장해뒀다가 다른 프레임워크로 다시 로드할 수 있는 점입니다. `from_pt` 또는 `from_tf` 매개변수를 사용하여 모델을 한 프레임워크에서 다른 프레임워크로 변환할 수 있습니다: @@ -365,15 +291,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - -```py ->>> from transformers import TFAutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory) ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) -``` - ## 커스텀 모델 구축하기 [[custom-model-builds]] @@ -398,15 +315,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_model = AutoModel.from_config(my_config) ``` - -[`TFAutoModel.from_config`]를 사용하여 바꾼 구성대로 모델을 생성하세요: - -```py ->>> from transformers import TFAutoModel - ->>> my_model = TFAutoModel.from_config(my_config) -``` - 커스텀 구성에 대한 자세한 내용은 [커스텀 아키텍처 만들기](./create_a_model) 가이드를 확인하세요. diff --git a/docs/source/ko/run_scripts.md b/docs/source/ko/run_scripts.md index 7cbf2288880c..70ff270c04a4 100644 --- a/docs/source/ko/run_scripts.md +++ b/docs/source/ko/run_scripts.md @@ -112,24 +112,6 @@ python examples/pytorch/summarization/run_summarization.py \ --predict_with_generate ``` - -예제 스크립트는 🤗 [Datasets](https://huggingface.co/docs/datasets/) 라이브러리에서 데이터 세트를 다운로드하고 전처리합니다. -그런 다음 스크립트는 요약 기능을 지원하는 아키텍처에서 Keras를 사용하여 데이터 세트를 미세 조정합니다. -다음 예는 [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail) 데이터 세트에서 [T5-small](https://huggingface.co/google-t5/t5-small)을 미세 조정합니다. -T5 모델은 훈련 방식에 따라 추가 `source_prefix` 인수가 필요하며, 이 프롬프트는 요약 작업임을 T5에 알려줍니다. -```bash -python examples/tensorflow/summarization/run_summarization.py \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## 혼합 정밀도(mixed precision)로 분산 훈련하기[[distributed-training-and-mixed-precision]] @@ -184,25 +166,6 @@ python xla_spawn.py --num_cores 8 \ --predict_with_generate ``` - -Tensor Processing Units (TPUs)는 성능을 가속화하기 위해 특별히 설계되었습니다. -TensorFlow 스크립트는 TPU를 훈련에 사용하기 위해 [`TPUStrategy`](https://www.tensorflow.org/guide/distributed_training#tpustrategy)를 활용합니다. -TPU를 사용하려면 TPU 리소스의 이름을 `tpu` 인수에 전달합니다. - -```bash -python run_summarization.py \ - --tpu name_of_tpu_resource \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## 🤗 Accelerate로 스크립트 실행하기[[run-a-script-with-accelerate]] @@ -372,4 +335,4 @@ python examples/pytorch/summarization/run_summarization.py --per_device_eval_batch_size=4 \ --overwrite_output_dir \ --predict_with_generate -``` \ No newline at end of file +``` diff --git a/docs/source/ko/tasks/image_classification.md b/docs/source/ko/tasks/image_classification.md index 4955bd6cdf81..48ac6742431a 100644 --- a/docs/source/ko/tasks/image_classification.md +++ b/docs/source/ko/tasks/image_classification.md @@ -152,92 +152,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 - - - -과적합을 방지하고 모델을 보다 견고하게 만들기 위해 데이터 세트의 훈련 부분에 데이터 증강을 추가합니다. -여기서 Keras 전처리 레이어로 훈련 데이터에 대한 변환(데이터 증강 포함)과 -검증 데이터에 대한 변환(중앙 크로핑, 크기 조정, 정규화만)을 정의합니다. -`tf.image` 또는 다른 원하는 라이브러리를 사용할 수 있습니다. - -```py ->>> from tensorflow import keras ->>> from tensorflow.keras import layers - ->>> size = (image_processor.size["height"], image_processor.size["width"]) - ->>> train_data_augmentation = keras.Sequential( -... [ -... layers.RandomCrop(size[0], size[1]), -... layers.Rescaling(scale=1.0 / 127.5, offset=-1), -... layers.RandomFlip("horizontal"), -... layers.RandomRotation(factor=0.02), -... layers.RandomZoom(height_factor=0.2, width_factor=0.2), -... ], -... name="train_data_augmentation", -... ) - ->>> val_data_augmentation = keras.Sequential( -... [ -... layers.CenterCrop(size[0], size[1]), -... layers.Rescaling(scale=1.0 / 127.5, offset=-1), -... ], -... name="val_data_augmentation", -... ) -``` - -다음으로 한 번에 하나의 이미지가 아니라 이미지 배치에 적절한 변환을 적용하는 함수를 만듭니다. - -```py ->>> import numpy as np ->>> import tensorflow as tf ->>> from PIL import Image - - ->>> def convert_to_tf_tensor(image: Image): -... np_image = np.array(image) -... tf_image = tf.convert_to_tensor(np_image) -... # `expand_dims()` is used to add a batch dimension since -... # the TF augmentation layers operates on batched inputs. -... return tf.expand_dims(tf_image, 0) - - ->>> def preprocess_train(example_batch): -... """Apply train_transforms across a batch.""" -... images = [ -... train_data_augmentation(convert_to_tf_tensor(image.convert("RGB"))) for image in example_batch["image"] -... ] -... example_batch["pixel_values"] = [tf.transpose(tf.squeeze(image)) for image in images] -... return example_batch - - -... def preprocess_val(example_batch): -... """Apply val_transforms across a batch.""" -... images = [ -... val_data_augmentation(convert_to_tf_tensor(image.convert("RGB"))) for image in example_batch["image"] -... ] -... example_batch["pixel_values"] = [tf.transpose(tf.squeeze(image)) for image in images] -... return example_batch -``` - -🤗 Datasets [`~datasets.Dataset.set_transform`]를 사용하여 즉시 변환을 적용하세요: - -```py -food["train"].set_transform(preprocess_train) -food["test"].set_transform(preprocess_val) -``` - -최종 전처리 단계로 `DefaultDataCollator`를 사용하여 예제 배치를 만듭니다. 🤗 Transformers의 다른 데이터 콜레이터와 달리 -`DefaultDataCollator`는 패딩과 같은 추가 전처리를 적용하지 않습니다. - -```py ->>> from transformers import DefaultDataCollator - ->>> data_collator = DefaultDataCollator(return_tensors="tf") -``` - - - ## 평가[[evaluate]] 훈련 중에 평가 지표를 포함하면 모델의 성능을 평가하는 데 도움이 되는 경우가 많습니다. @@ -332,114 +246,6 @@ food["test"].set_transform(preprocess_val) - - - - - -Keras를 사용하여 모델을 미세 조정하는 방법에 익숙하지 않은 경우, 먼저 [기본 튜토리얼](./training#train-a-tensorflow-model-with-keras)을 확인하세요! - - - -TensorFlow에서 모델을 미세 조정하려면 다음 단계를 따르세요: -1. 훈련 하이퍼파라미터를 정의하고 옵티마이저와 학습률 스케쥴을 설정합니다. -2. 사전 훈련된 모델을 인스턴스화합니다. -3. 🤗 Dataset을 `tf.data.Dataset`으로 변환합니다. -4. 모델을 컴파일합니다. -5. 콜백을 추가하고 훈련을 수행하기 위해 `fit()` 메소드를 사용합니다. -6. 커뮤니티와 공유하기 위해 모델을 🤗 Hub에 업로드합니다. - -하이퍼파라미터, 옵티마이저 및 학습률 스케쥴을 정의하는 것으로 시작합니다: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_epochs = 5 ->>> num_train_steps = len(food["train"]) * num_epochs ->>> learning_rate = 3e-5 ->>> weight_decay_rate = 0.01 - ->>> optimizer, lr_schedule = create_optimizer( -... init_lr=learning_rate, -... num_train_steps=num_train_steps, -... weight_decay_rate=weight_decay_rate, -... num_warmup_steps=0, -... ) -``` - -그런 다음 레이블 매핑과 함께 [`TFAuto ModelForImageClassification`]으로 ViT를 가져옵니다: - -```py ->>> from transformers import TFAutoModelForImageClassification - ->>> model = TFAutoModelForImageClassification.from_pretrained( -... checkpoint, -... id2label=id2label, -... label2id=label2id, -... ) -``` - -데이터 세트를 [`~datasets.Dataset.to_tf_dataset`]와 `data_collator`를 사용하여 `tf.data.Dataset` 형식으로 변환하세요: - -```py ->>> # converting our train dataset to tf.data.Dataset ->>> tf_train_dataset = food["train"].to_tf_dataset( -... columns="pixel_values", label_cols="label", shuffle=True, batch_size=batch_size, collate_fn=data_collator -... ) - ->>> # converting our test dataset to tf.data.Dataset ->>> tf_eval_dataset = food["test"].to_tf_dataset( -... columns="pixel_values", label_cols="label", shuffle=True, batch_size=batch_size, collate_fn=data_collator -... ) -``` - -`compile()`를 사용하여 훈련 모델을 구성하세요: - -```py ->>> from tensorflow.keras.losses import SparseCategoricalCrossentropy - ->>> loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) ->>> model.compile(optimizer=optimizer, loss=loss) -``` - -예측에서 정확도를 계산하고 모델을 🤗 Hub로 푸시하려면 [Keras callbacks](../main_classes/keras_callbacks)를 사용하세요. -`compute_metrics` 함수를 [KerasMetricCallback](../main_classes/keras_callbacks#transformers.KerasMetricCallback)에 전달하고, -[PushToHubCallback](../main_classes/keras_callbacks#transformers.PushToHubCallback)을 사용하여 모델을 업로드합니다: - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback, PushToHubCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_eval_dataset) ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="food_classifier", -... tokenizer=image_processor, -... save_strategy="no", -... ) ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -이제 모델을 훈련할 준비가 되었습니다! 훈련 및 검증 데이터 세트, 에폭 수와 함께 `fit()`을 호출하고, -콜백을 사용하여 모델을 미세 조정합니다: - -```py ->>> model.fit(tf_train_dataset, validation_data=tf_eval_dataset, epochs=num_epochs, callbacks=callbacks) -Epoch 1/5 -250/250 [==============================] - 313s 1s/step - loss: 2.5623 - val_loss: 1.4161 - accuracy: 0.9290 -Epoch 2/5 -250/250 [==============================] - 265s 1s/step - loss: 0.9181 - val_loss: 0.6808 - accuracy: 0.9690 -Epoch 3/5 -250/250 [==============================] - 252s 1s/step - loss: 0.3910 - val_loss: 0.4303 - accuracy: 0.9820 -Epoch 4/5 -250/250 [==============================] - 251s 1s/step - loss: 0.2028 - val_loss: 0.3191 - accuracy: 0.9900 -Epoch 5/5 -250/250 [==============================] - 238s 949ms/step - loss: 0.1232 - val_loss: 0.3259 - accuracy: 0.9890 -``` - -축하합니다! 모델을 미세 조정하고 🤗 Hub에 공유했습니다. 이제 추론에 사용할 수 있습니다! - - - @@ -509,34 +315,3 @@ Epoch 5/5 ``` - - - -이미지를 전처리하기 위해 이미지 프로세서를 가져오고 `input`을 TensorFlow 텐서로 반환합니다: - -```py ->>> from transformers import AutoImageProcessor - ->>> image_processor = AutoImageProcessor.from_pretrained("MariaK/food_classifier") ->>> inputs = image_processor(image, return_tensors="tf") -``` - -입력을 모델에 전달하고 logits을 반환합니다: - -```py ->>> from transformers import TFAutoModelForImageClassification - ->>> model = TFAutoModelForImageClassification.from_pretrained("MariaK/food_classifier") ->>> logits = model(**inputs).logits -``` - -확률이 가장 높은 예측 레이블을 가져오고, 모델의 `id2label` 매핑을 사용하여 레이블로 변환합니다: - -```py ->>> predicted_class_id = int(tf.math.argmax(logits, axis=-1)[0]) ->>> model.config.id2label[predicted_class_id] -'beignets' -``` - - - diff --git a/docs/source/ko/tasks/language_modeling.md b/docs/source/ko/tasks/language_modeling.md index 1b531e49d617..d444a15ee6dd 100644 --- a/docs/source/ko/tasks/language_modeling.md +++ b/docs/source/ko/tasks/language_modeling.md @@ -187,16 +187,6 @@ pip install transformers datasets evaluate ``` - -패딩 토큰으로 종결 토큰을 사용하고 `mlm=False`로 설정하세요. 이렇게 하면 입력을 오른쪽으로 한 칸씩 시프트한 값을 레이블로 사용합니다: - -```py ->>> from transformers import DataCollatorForLanguageModeling - ->>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False, return_tensors="tf") -``` - - @@ -260,73 +250,6 @@ Perplexity: 49.61 >>> trainer.push_to_hub() ``` - - - -Keras를 사용하여 모델을 미세 조정하는 방법에 익숙하지 않다면 [기본 튜토리얼](../training#train-a-tensorflow-model-with-keras)을 확인해보세요! - - -TensorFlow에서 모델을 미세 조정하려면, 먼저 옵티마이저 함수, 학습률 스케줄 및 일부 훈련 하이퍼파라미터를 설정하세요: - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -그런 다음 [`TFAutoModelForCausalLM`]를 사용하여 DistilGPT2를 불러옵니다: - -```py ->>> from transformers import TFAutoModelForCausalLM - ->>> model = TFAutoModelForCausalLM.from_pretrained("distilbert/distilgpt2") -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`]을 사용하여 데이터 세트를 `tf.data.Dataset` 형식으로 변환하세요: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... lm_dataset["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... lm_dataset["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method)을 사용하여 모델을 훈련하기 위해 구성하세요. Transformers 모델은 모두 기본적인 작업 관련 손실 함수를 가지고 있으므로, 원한다면 별도로 지정하지 않아도 됩니다: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) # 별도로 loss 인자를 넣지 않았어요! -``` - -[`~transformers.PushToHubCallback`]에서 모델과 토크나이저를 업로드할 위치를 지정할 수 있습니다: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> callback = PushToHubCallback( -... output_dir="my_awesome_eli5_clm-model", -... tokenizer=tokenizer, -... ) -``` - -마지막으로, 모델을 훈련하기 위해 [`fit`](https://keras.io/api/models/model_training_apis/#fit-method)을 호출하세요. 훈련 데이터 세트, 검증 데이터 세트, 에폭 수 및 콜백을 전달하세요: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=[callback]) -``` - -훈련이 완료되면 모델이 자동으로 허브에 업로드되어 모두가 사용할 수 있습니다! - @@ -382,30 +305,4 @@ TensorFlow에서 모델을 미세 조정하려면, 먼저 옵티마이저 함수 ["Somatic hypermutation allows the immune system to react to drugs with the ability to adapt to a different environmental situation. In other words, a system of 'hypermutation' can help the immune system to adapt to a different environmental situation or in some cases even a single life. In contrast, researchers at the University of Massachusetts-Boston have found that 'hypermutation' is much stronger in mice than in humans but can be found in humans, and that it's not completely unknown to the immune system. A study on how the immune system"] ``` - -텍스트를 토큰화하고 `input_ids`를 TensorFlow 텐서로 반환하세요: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_eli5_clm-model") ->>> inputs = tokenizer(prompt, return_tensors="tf").input_ids -``` - -[`~transformers.generation_tf_utils.TFGenerationMixin.generate`] 메소드를 사용하여 요약을 생성하세요. 생성을 제어하는 다양한 텍스트 생성 전략과 매개변수에 대한 자세한 내용은 [텍스트 생성 전략](../generation_strategies) 페이지를 확인하세요. - -```py ->>> from transformers import TFAutoModelForCausalLM - ->>> model = TFAutoModelForCausalLM.from_pretrained("my_awesome_eli5_clm-model") ->>> outputs = model.generate(input_ids=inputs, max_new_tokens=100, do_sample=True, top_k=50, top_p=0.95) -``` - -생성된 토큰 ID를 다시 텍스트로 디코딩하세요: - -```py ->>> tokenizer.batch_decode(outputs, skip_special_tokens=True) -['Somatic hypermutation allows the immune system to detect the presence of other viruses as they become more prevalent. Therefore, researchers have identified a high proportion of human viruses. The proportion of virus-associated viruses in our study increases with age. Therefore, we propose a simple algorithm to detect the presence of these new viruses in our samples as a sign of improved immunity. A first study based on this algorithm, which will be published in Science on Friday, aims to show that this finding could translate into the development of a better vaccine that is more effective for'] -``` - diff --git a/docs/source/ko/tasks/masked_language_modeling.md b/docs/source/ko/tasks/masked_language_modeling.md index 74df085c5b55..cb9216b1e6bc 100644 --- a/docs/source/ko/tasks/masked_language_modeling.md +++ b/docs/source/ko/tasks/masked_language_modeling.md @@ -191,16 +191,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티와 >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15) ``` - - -시퀀스 끝 토큰을 패딩 토큰으로 사용하고 데이터를 반복할 때마다 토큰을 무작위로 마스킹하도록 `mlm_-probability`를 지정합니다: - -```py ->>> from transformers import DataCollatorForLanguageModeling - ->>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15, return_tensors="tf") -``` - ## 훈련[[train]] @@ -263,74 +253,6 @@ Perplexity: 8.76 >>> trainer.push_to_hub() ``` - - - -Keras로 모델을 미세 조정하는 데 익숙하지 않다면 기본 튜토리얼 [여기](../training#train-a-tensorflow-model-with-keras)를 살펴보세요! - - -TensorFlow로 모델을 미세 조정하기 위해서는 옵티마이저(optimizer) 함수 설정, 학습률(learning rate) 스케쥴링, 훈련 하이퍼파라미터 설정부터 시작하세요: - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -다음으로 [`TFAutoModelForMaskedLM`]를 사용해 DistilRoBERTa 모델을 가져옵니다: - -```py ->>> from transformers import TFAutoModelForMaskedLM - ->>> model = TFAutoModelForMaskedLM.from_pretrained("distilbert/distilroberta-base") -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`] 메소드를 사용해 데이터 세트를 `tf.data.Dataset` 형식으로 변환하세요: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... lm_dataset["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... lm_dataset["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method) 메소드를 통해 모델 훈련을 구성합니다: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -이는 업로드할 모델과 토크나이저의 위치를 [`~transformers.PushToHubCallback`]에 지정하여 수행할 수 있습니다: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> callback = PushToHubCallback( -... output_dir="my_awesome_eli5_mlm_model", -... tokenizer=tokenizer, -... ) -``` - -드디어 모델을 훈련할 준비가 되었습니다! -모델을 미세 조정할 때 훈련 및 검증 데이터 세트, 에포크 수, 콜백이 포함된 [`fit`](https://keras.io/api/models/model_training_apis/#fit-method)을 호출합니다: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=[callback]) -``` - -훈련이 완료되면, 자동으로 Hub로 업로드되어 누구나 사용할 수 있습니다! - @@ -406,36 +328,4 @@ The Milky Way is a massive galaxy. The Milky Way is a small galaxy. ``` - -텍스트를 토큰화하고 `input_ids`를 TensorFlow 텐서 형태로 반환합니다. -또한, `` 토큰의 위치를 지정해야 합니다: -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_eli5_mlm_model") ->>> inputs = tokenizer(text, return_tensors="tf") ->>> mask_token_index = tf.where(inputs["input_ids"] == tokenizer.mask_token_id)[0, 1] -``` - -모델에 `inputs`를 입력하고, 마스킹된 토큰의 `logits`를 반환합니다: - -```py ->>> from transformers import TFAutoModelForMaskedLM - ->>> model = TFAutoModelForMaskedLM.from_pretrained("stevhliu/my_awesome_eli5_mlm_model") ->>> logits = model(**inputs).logits ->>> mask_token_logits = logits[0, mask_token_index, :] -``` - -그런 다음 가장 높은 확률은 가진 마스크 토큰 3개를 반환하고, 출력합니다: -```py ->>> top_3_tokens = tf.math.top_k(mask_token_logits, 3).indices.numpy() - ->>> for token in top_3_tokens: -... print(text.replace(tokenizer.mask_token, tokenizer.decode([token]))) -The Milky Way is a spiral galaxy. -The Milky Way is a massive galaxy. -The Milky Way is a small galaxy. -``` - diff --git a/docs/source/ko/tasks/multiple_choice.md b/docs/source/ko/tasks/multiple_choice.md index e0888f4a0b6d..7756951f07ec 100644 --- a/docs/source/ko/tasks/multiple_choice.md +++ b/docs/source/ko/tasks/multiple_choice.md @@ -199,91 +199,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) >>> trainer.push_to_hub() ``` - - - -Keras로 모델을 미세 조정하는 데 익숙하지 않다면 기본 튜토리얼 [여기](../training#train-a-tensorflow-model-with-keras)를 살펴보시기 바랍니다! - - -TensorFlow에서 모델을 미세 조정하려면 최적화 함수, 학습률 스케쥴 및 몇 가지 학습 하이퍼파라미터를 설정하는 것부터 시작하세요: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_train_epochs = 2 ->>> total_train_steps = (len(tokenized_swag["train"]) // batch_size) * num_train_epochs ->>> optimizer, schedule = create_optimizer(init_lr=5e-5, num_warmup_steps=0, num_train_steps=total_train_steps) -``` - -그리고 [`TFAutoModelForMultipleChoice`]로 BERT를 가져올 수 있습니다: - -```py ->>> from transformers import TFAutoModelForMultipleChoice - ->>> model = TFAutoModelForMultipleChoice.from_pretrained("google-bert/bert-base-uncased") -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`]을 사용하여 데이터 세트를 `tf.data.Dataset` 형식으로 변환합니다: - -```py ->>> data_collator = DataCollatorForMultipleChoice(tokenizer=tokenizer) ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_swag["train"], -... shuffle=True, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_swag["validation"], -... shuffle=False, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method)을 사용하여 훈련 모델을 구성합니다: - -```py ->>> model.compile(optimizer=optimizer) -``` - -훈련을 시작하기 전에 설정해야 할 마지막 두 가지는 예측의 정확도를 계산하고 모델을 허브로 푸시하는 방법을 제공하는 것입니다. 이 두 가지 작업은 모두 [Keras 콜백](../main_classes/keras_callbacks)을 사용하여 수행할 수 있습니다. - -`compute_metrics`함수를 [`~transformers.KerasMetricCallback`]에 전달하세요: - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -모델과 토크나이저를 업로드할 위치를 [`~transformers.PushToHubCallback`]에서 지정하세요: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_model", -... tokenizer=tokenizer, -... ) -``` - -그리고 콜백을 함께 묶습니다: - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -이제 모델 훈련을 시작합니다! 훈련 및 검증 데이터 세트, 에폭 수, 콜백을 사용하여 [`fit`](https://keras.io/api/models/model_training_apis/#fit-method)을 호출하고 모델을 미세 조정합니다: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=2, callbacks=callbacks) -``` - -훈련이 완료되면 모델이 자동으로 허브에 업로드되어 누구나 사용할 수 있습니다! - @@ -337,33 +252,4 @@ TensorFlow에서 모델을 미세 조정하려면 최적화 함수, 학습률 '0' ``` - -각 프롬프트와 후보 답안 쌍을 토큰화하여 텐서플로 텐서를 반환합니다: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_swag_model") ->>> inputs = tokenizer([[prompt, candidate1], [prompt, candidate2]], return_tensors="tf", padding=True) -``` - -모델에 입력을 전달하고 `logits`를 반환합니다: - -```py ->>> from transformers import TFAutoModelForMultipleChoice - ->>> model = TFAutoModelForMultipleChoice.from_pretrained("my_awesome_swag_model") ->>> inputs = {k: tf.expand_dims(v, 0) for k, v in inputs.items()} ->>> outputs = model(inputs) ->>> logits = outputs.logits -``` - -가장 높은 확률을 가진 클래스를 가져옵니다: - -```py ->>> predicted_class = int(tf.math.argmax(logits, axis=-1)[0]) ->>> predicted_class -'0' -``` - diff --git a/docs/source/ko/tasks/question_answering.md b/docs/source/ko/tasks/question_answering.md index 8309dd7d7532..f0f1cab6b648 100644 --- a/docs/source/ko/tasks/question_answering.md +++ b/docs/source/ko/tasks/question_answering.md @@ -173,13 +173,6 @@ pip install transformers datasets evaluate >>> data_collator = DefaultDataCollator() ``` - -```py ->>> from transformers import DefaultDataCollator - ->>> data_collator = DefaultDataCollator(return_tensors="tf") -``` - ## 훈련[[train]] @@ -236,79 +229,6 @@ pip install transformers datasets evaluate >>> trainer.push_to_hub() ``` - - - -Keras로 모델을 미세 조정하는 것에 익숙하지 않다면, [여기](../training#train-a-tensorflow-model-with-keras)에서 기초 튜토리얼을 살펴보세요! - - -TensorFlow를 이용한 모델을 미세 조정하려면 옵티마이저 함수, 학습률 스케쥴 및 몇 가지 훈련 하이퍼파라미터를 설정하는 것부터 시작해야합니다: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_epochs = 2 ->>> total_train_steps = (len(tokenized_squad["train"]) // batch_size) * num_epochs ->>> optimizer, schedule = create_optimizer( -... init_lr=2e-5, -... num_warmup_steps=0, -... num_train_steps=total_train_steps, -... ) -``` - -그 다음 [`TFAutoModelForQuestionAnswering`]으로 DistilBERT를 가져옵니다: - -```py ->>> from transformers import TFAutoModelForQuestionAnswering - ->>> model = TFAutoModelForQuestionAnswering("distilbert/distilbert-base-uncased") -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`]을 사용해서 데이터 세트를 `tf.data.Dataset` 형식으로 변환합니다: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_squad["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_squad["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method)로 훈련할 모델을 설정합니다: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -마지막으로 모델을 Hub로 푸시할 방법을 설정합니다. [`~transformers.PushToHubCallback`]에서 모델과 토크나이저를 푸시할 경로를 설정합니다: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> callback = PushToHubCallback( -... output_dir="my_awesome_qa_model", -... tokenizer=tokenizer, -... ) -``` - -드디어 모델 훈련을 시작할 준비가 되었습니다! 훈련 데이터 세트와 평가 데이터 세트, 에폭 수, 콜백을 설정한 후 [`fit`](https://keras.io/api/models/model_training_apis/#fit-method)을 이용해 모델을 미세 조정합니다: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3, callbacks=[callback]) -``` -훈련이 완료되면 모델이 자동으로 Hub에 업로드되어 누구나 사용할 수 있습니다! - @@ -385,38 +305,4 @@ TensorFlow를 이용한 모델을 미세 조정하려면 옵티마이저 함수, '176 billion parameters and can generate text in 46 languages natural languages and 13' ``` - -텍스트를 토큰화해서 TensorFlow 텐서를 반환합니다: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_qa_model") ->>> inputs = tokenizer(question, text, return_tensors="tf") -``` - -모델에 입력을 전달하고 `logits`을 반환합니다: - -```py ->>> from transformers import TFAutoModelForQuestionAnswering - ->>> model = TFAutoModelForQuestionAnswering.from_pretrained("my_awesome_qa_model") ->>> outputs = model(**inputs) -``` - -모델의 출력에서 시작 및 종료 위치가 어딘지 가장 높은 확률을 얻습니다: - -```py ->>> answer_start_index = int(tf.math.argmax(outputs.start_logits, axis=-1)[0]) ->>> answer_end_index = int(tf.math.argmax(outputs.end_logits, axis=-1)[0]) -``` - -예측된 토큰을 해독해서 답을 얻습니다: - -```py ->>> predict_answer_tokens = inputs.input_ids[0, answer_start_index : answer_end_index + 1] ->>> tokenizer.decode(predict_answer_tokens) -'176 billion parameters and can generate text in 46 languages natural languages and 13' -``` - diff --git a/docs/source/ko/tasks/semantic_segmentation.md b/docs/source/ko/tasks/semantic_segmentation.md index 04a727448dac..167417412c47 100644 --- a/docs/source/ko/tasks/semantic_segmentation.md +++ b/docs/source/ko/tasks/semantic_segmentation.md @@ -142,62 +142,6 @@ pip install -q datasets transformers evaluate - - - -이미지 데이터 세트에 데이터 증강을 적용하여 과적합에 대해 모델을 보다 강건하게 만드는 것이 일반적입니다. 이 가이드에서는 [`tf.image`](https://www.tensorflow.org/api_docs/python/tf/image)를 사용하여 이미지의 색상 속성을 임의로 변경합니다. 하지만, 자신이 원하는 이미지 라이브러리를 사용할 수도 있습니다. - -별개의 두 변환 함수를 정의합니다: -- 이미지 증강을 포함하는 학습 데이터 변환 -- 🤗 Transformers의 컴퓨터 비전 모델은 채널 우선 레이아웃을 기대하기 때문에, 이미지만 바꾸는 검증 데이터 변환 - -```py ->>> import tensorflow as tf - - ->>> def aug_transforms(image): -... image = tf.keras.utils.img_to_array(image) -... image = tf.image.random_brightness(image, 0.25) -... image = tf.image.random_contrast(image, 0.5, 2.0) -... image = tf.image.random_saturation(image, 0.75, 1.25) -... image = tf.image.random_hue(image, 0.1) -... image = tf.transpose(image, (2, 0, 1)) -... return image - - ->>> def transforms(image): -... image = tf.keras.utils.img_to_array(image) -... image = tf.transpose(image, (2, 0, 1)) -... return image -``` - -그런 다음 모델을 위해 두 개의 전처리 함수를 만들어 이미지 및 주석 배치를 준비합니다. 이 함수들은 이미지 변환을 적용하고 이전에 로드한 `image_processor`를 사용하여 이미지를 `pixel_values`로, 주석을 `label`로 변환합니다. `ImageProcessor` 는 이미지의 크기 조정과 정규화도 처리합니다. - -```py ->>> def train_transforms(example_batch): -... images = [aug_transforms(x.convert("RGB")) for x in example_batch["image"]] -... labels = [x for x in example_batch["annotation"]] -... inputs = image_processor(images, labels) -... return inputs - - ->>> def val_transforms(example_batch): -... images = [transforms(x.convert("RGB")) for x in example_batch["image"]] -... labels = [x for x in example_batch["annotation"]] -... inputs = image_processor(images, labels) -... return inputs -``` - -전체 데이터 집합에 전처리 변환을 적용하려면 🤗 Datasets [`~datasets.Dataset.set_transform`] 함수를 사용하세요. -즉시 변환이 적용되기 때문에 더 빠르고 디스크 공간을 덜 차지합니다: - -```py ->>> train_ds.set_transform(train_transforms) ->>> test_ds.set_transform(val_transforms) -``` - - - ## 평가하기[[evaluate]] 훈련 중에 메트릭을 포함하면 모델의 성능을 평가하는 데 도움이 되는 경우가 많습니다. 🤗 [Evaluate](https://huggingface.co/docs/evaluate/index) 라이브러리를 사용하여 평가 방법을 빠르게 로드할 수 있습니다. 이 태스크에서는 [mean Intersection over Union](https://huggingface.co/spaces/evaluate-metric/accuracy) (IoU) 메트릭을 로드하세요 (메트릭을 로드하고 계산하는 방법에 대해 자세히 알아보려면 🤗 Evaluate [quick tour](https://huggingface.co/docs/evaluate/a_quick_tour)를 살펴보세요). @@ -247,39 +191,6 @@ pip install -q datasets transformers evaluate - - - -```py ->>> def compute_metrics(eval_pred): -... logits, labels = eval_pred -... logits = tf.transpose(logits, perm=[0, 2, 3, 1]) -... logits_resized = tf.image.resize( -... logits, -... size=tf.shape(labels)[1:], -... method="bilinear", -... ) - -... pred_labels = tf.argmax(logits_resized, axis=-1) -... metrics = metric.compute( -... predictions=pred_labels, -... references=labels, -... num_labels=num_labels, -... ignore_index=-1, -... reduce_labels=image_processor.do_reduce_labels, -... ) - -... per_category_accuracy = metrics.pop("per_category_accuracy").tolist() -... per_category_iou = metrics.pop("per_category_iou").tolist() - -... metrics.update({f"accuracy_{id2label[i]}": v for i, v in enumerate(per_category_accuracy)}) -... metrics.update({f"iou_{id2label[i]}": v for i, v in enumerate(per_category_iou)}) -... return {"val_" + k: v for k, v in metrics.items()} -``` - - - - 이제 `compute_metrics` 함수를 사용할 준비가 되었습니다. 트레이닝을 설정할 때 이 함수로 돌아가게 됩니다. ## 학습하기[[train]] @@ -341,106 +252,6 @@ pip install -q datasets transformers evaluate - - - - -Keras로 모델을 미세 조정하는 데 익숙하지 않은 경우, 먼저 [기본 튜토리얼](../training#train-a-tensorflow-model-with-keras)을 확인해보세요! - - - -TensorFlow에서 모델을 미세 조정하려면 다음 단계를 따르세요: -1. 학습 하이퍼파라미터를 정의하고 옵티마이저와 학습률 스케쥴러를 설정하세요. -2. 사전 학습된 모델을 인스턴스화하세요. -3. 🤗 Dataset을 `tf.data.Dataset`로 변환하세요. -4. 모델을 컴파일하세요. -5. 콜백을 추가하여 메트릭을 계산하고 🤗 Hub에 모델을 업로드하세요. -6. `fit()` 메서드를 사용하여 훈련을 실행하세요. - -하이퍼파라미터, 옵티마이저, 학습률 스케쥴러를 정의하는 것으로 시작하세요: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 2 ->>> num_epochs = 50 ->>> num_train_steps = len(train_ds) * num_epochs ->>> learning_rate = 6e-5 ->>> weight_decay_rate = 0.01 - ->>> optimizer, lr_schedule = create_optimizer( -... init_lr=learning_rate, -... num_train_steps=num_train_steps, -... weight_decay_rate=weight_decay_rate, -... num_warmup_steps=0, -... ) -``` - -그런 다음 레이블 매핑과 함께 [`TFAutoModelForSemanticSegmentation`]을 사용하여 SegFormer를 불러오고 옵티마이저로 컴파일합니다. 트랜스포머 모델은 모두 디폴트로 태스크 관련 손실 함수가 있으므로 원치 않으면 지정할 필요가 없습니다: - -```py ->>> from transformers import TFAutoModelForSemanticSegmentation - ->>> model = TFAutoModelForSemanticSegmentation.from_pretrained( -... checkpoint, -... id2label=id2label, -... label2id=label2id, -... ) ->>> model.compile(optimizer=optimizer) # 손실 함수 인자가 없습니다! -``` - -[`~datasets.Dataset.to_tf_dataset`] 와 [`DefaultDataCollator`]를 사용해 데이터 세트를 `tf.data.Dataset` 포맷으로 변환하세요: - -```py ->>> from transformers import DefaultDataCollator - ->>> data_collator = DefaultDataCollator(return_tensors="tf") - ->>> tf_train_dataset = train_ds.to_tf_dataset( -... columns=["pixel_values", "label"], -... shuffle=True, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) - ->>> tf_eval_dataset = test_ds.to_tf_dataset( -... columns=["pixel_values", "label"], -... shuffle=True, -... batch_size=batch_size, -... collate_fn=data_collator, -... ) -``` - -예측으로 정확도를 계산하고 모델을 🤗 Hub로 푸시하려면 [Keras callbacks](../main_classes/keras_callbacks)를 사용하세요. `compute_metrics` 함수를 [`KerasMetricCallback`]에 전달하고, 모델 업로드를 위해 [`PushToHubCallback`]를 사용하세요: - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback, PushToHubCallback - ->>> metric_callback = KerasMetricCallback( -... metric_fn=compute_metrics, eval_dataset=tf_eval_dataset, batch_size=batch_size, label_cols=["labels"] -... ) - ->>> push_to_hub_callback = PushToHubCallback(output_dir="scene_segmentation", tokenizer=image_processor) - ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -이제 모델을 훈련할 준비가 되었습니다! 훈련 및 검증 데이터 세트, 에포크 수와 함께 `fit()`을 호출하고, 콜백을 사용하여 모델을 미세 조정합니다: - -```py ->>> model.fit( -... tf_train_dataset, -... validation_data=tf_eval_dataset, -... callbacks=callbacks, -... epochs=num_epochs, -... ) -``` - -축하합니다! 모델을 미세 조정하고 🤗 Hub에 공유했습니다. 이제 추론에 사용할 수 있습니다! - - - - ## 추론하기[[inference]] @@ -525,43 +336,6 @@ TensorFlow에서 모델을 미세 조정하려면 다음 단계를 따르세요: - - -이미지 프로세서를 로드하여 이미지를 전처리하고 입력을 TensorFlow 텐서로 반환합니다: - -```py ->>> from transformers import AutoImageProcessor - ->>> image_processor = AutoImageProcessor.from_pretrained("MariaK/scene_segmentation") ->>> inputs = image_processor(image, return_tensors="tf") -``` - -모델에 입력을 전달하고 `logits`를 반환합니다: - -```py ->>> from transformers import TFAutoModelForSemanticSegmentation - ->>> model = TFAutoModelForSemanticSegmentation.from_pretrained("MariaK/scene_segmentation") ->>> logits = model(**inputs).logits -``` - -그런 다음 로그를 원본 이미지 크기로 재조정하고 클래스 차원에 argmax를 적용합니다: - -```py ->>> logits = tf.transpose(logits, [0, 2, 3, 1]) - ->>> upsampled_logits = tf.image.resize( -... logits, -... # `image.size`가 너비와 높이를 반환하기 때문에 `image`의 모양을 반전시킵니다 -... image.size[::-1], -... ) - ->>> pred_seg = tf.math.argmax(upsampled_logits, axis=-1)[0] -``` - - - - 결과를 시각화하려면 [dataset color palette](https://github.com/tensorflow/models/blob/3f1ca33afe3c1631b733ea7e40c294273b9e406d/research/deeplab/utils/get_dataset_colormap.py#L51)를 각 클래스를 RGB 값에 매핑하는 `ade_palette()`로 로드합니다. 그런 다음 이미지와 예측된 분할 지도(segmentation map)을 결합하여 구성할 수 있습니다: ```py diff --git a/docs/source/ko/tasks/sequence_classification.md b/docs/source/ko/tasks/sequence_classification.md index 11dae1a965a4..1eda13c05e7d 100644 --- a/docs/source/ko/tasks/sequence_classification.md +++ b/docs/source/ko/tasks/sequence_classification.md @@ -105,13 +105,6 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) >>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer) ``` - -```py ->>> from transformers import DataCollatorWithPadding - ->>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer, return_tensors="tf") -``` - ## 평가하기[[evaluate]] @@ -210,96 +203,6 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) >>> trainer.push_to_hub() ``` - - - -Keras를 사용하여 모델을 파인 튜닝하는 방법에 익숙하지 않은 경우, [여기](../training#train-a-tensorflow-model-with-keras)의 기본 튜토리얼을 확인하세요! - - -TensorFlow에서 모델을 파인 튜닝하려면, 먼저 옵티마이저 함수와 학습률 스케쥴, 그리고 일부 훈련 하이퍼파라미터를 설정해야 합니다: - -```py ->>> from transformers import create_optimizer ->>> import tensorflow as tf - ->>> batch_size = 16 ->>> num_epochs = 5 ->>> batches_per_epoch = len(tokenized_imdb["train"]) // batch_size ->>> total_train_steps = int(batches_per_epoch * num_epochs) ->>> optimizer, schedule = create_optimizer(init_lr=2e-5, num_warmup_steps=0, num_train_steps=total_train_steps) -``` - -그런 다음 [`TFAutoModelForSequenceClassification`]을 사용하여 DistilBERT를 로드하고, 예상되는 레이블 수와 레이블 매핑을 로드할 수 있습니다: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained( -... "distilbert/distilbert-base-uncased", num_labels=2, id2label=id2label, label2id=label2id -... ) -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`]을 사용하여 데이터셋을 `tf.data.Dataset` 형식으로 변환합니다: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_imdb["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_imdb["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method)를 사용하여 훈련할 모델을 구성합니다: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -훈련을 시작하기 전에 설정해야할 마지막 두 가지는 예측에서 정확도를 계산하고, 모델을 Hub에 업로드할 방법을 제공하는 것입니다. 모두 [Keras callbacks](../main_classes/keras_callbacks)를 사용하여 수행됩니다. - -[`~transformers.KerasMetricCallback`]에 `compute_metrics`를 전달하여 정확도를 높입니다. - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -[`~transformers.PushToHubCallback`]에서 모델과 토크나이저를 업로드할 위치를 지정합니다: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_model", -... tokenizer=tokenizer, -... ) -``` - -그런 다음 콜백을 함께 묶습니다: - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -드디어, 모델 훈련을 시작할 준비가 되었습니다! [`fit`](https://keras.io/api/models/model_training_apis/#fit-method)에 훈련 데이터셋, 검증 데이터셋, 에폭의 수 및 콜백을 전달하여 파인 튜닝합니다: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3, callbacks=callbacks) -``` - -훈련이 완료되면, 모델이 자동으로 Hub에 업로드되어 모든 사람이 사용할 수 있습니다! - @@ -359,31 +262,4 @@ TensorFlow에서 모델을 파인 튜닝하려면, 먼저 옵티마이저 함수 'POSITIVE' ``` - -텍스트를 토큰화하고 TensorFlow 텐서를 반환합니다: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_model") ->>> inputs = tokenizer(text, return_tensors="tf") -``` - -입력값을 모델에 전달하고 `logits`을 반환합니다: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("stevhliu/my_awesome_model") ->>> logits = model(**inputs).logits -``` - -가장 높은 확률을 가진 클래스를 모델의 `id2label` 매핑을 사용하여 텍스트 레이블로 변환합니다: - -```py ->>> predicted_class_id = int(tf.math.argmax(logits, axis=-1)[0]) ->>> model.config.id2label[predicted_class_id] -'POSITIVE' -``` - diff --git a/docs/source/ko/tasks/summarization.md b/docs/source/ko/tasks/summarization.md index a2b2b1fbc954..c56af19bacfe 100644 --- a/docs/source/ko/tasks/summarization.md +++ b/docs/source/ko/tasks/summarization.md @@ -132,13 +132,6 @@ Hugging Face 계정에 로그인하면 모델을 업로드하고 커뮤니티에 >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - -```py ->>> from transformers import DataCollatorForSeq2Seq - ->>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint, return_tensors="tf") -``` - ## 평가[[evaluate]] @@ -237,91 +230,6 @@ Hugging Face 계정에 로그인하면 모델을 업로드하고 커뮤니티에 >>> trainer.push_to_hub() ``` - - - -Keras로 모델 파인튜닝을 하는 것이 익숙하지 않다면, [여기](../training#train-a-tensorflow-model-with-keras)에서 기본적인 튜토리얼을 확인하세요! - - -TensorFlow에서 모델을 파인튜닝하려면, 먼저 옵티마이저, 학습률 스케줄 그리고 몇 가지 학습 하이퍼파라미터를 설정하세요: - -```py ->>> from transformers import create_optimizer, AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -그런 다음 [`TFAutoModelForSeq2SeqLM`]을 사용하여 T5를 가져오세요: - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained(checkpoint) -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`]을 사용하여 데이터셋을 `tf.data.Dataset` 형식으로 변환하세요: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_billsum["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... tokenized_billsum["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method)을 사용하여 모델을 학습할 수 있도록 구성하세요: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -학습을 시작하기 전에 설정해야 할 마지막 두 가지는 예측에서 ROUGE 점수를 계산하고 모델을 Hub에 푸시하는 방법을 제공하는 것입니다. -두 작업 모두 [Keras callbacks](../main_classes/keras_callbacks)으로 수행할 수 있습니다. - -[`~transformers.KerasMetricCallback`]에 `compute_metrics` 함수를 전달하세요: - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -[`~transformers.PushToHubCallback`]에서 모델과 토크나이저를 푸시할 위치를 지정하세요: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_billsum_model", -... tokenizer=tokenizer, -... ) -``` - -그런 다음 콜백을 번들로 묶어줍니다: - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -드디어 모델 학습을 시작할 준비가 되었습니다! -학습 및 검증 데이터셋, 에폭 수 및 콜백과 함께 [`fit`](https://keras.io/api/models/model_training_apis/#fit-method)을 호출하여 모델을 파인튜닝하세요. - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=callbacks) -``` - -학습이 완료되면 모델이 자동으로 Hub에 업로드되어 누구나 사용할 수 있게 됩니다! - @@ -383,31 +291,4 @@ TensorFlow에서 모델을 파인튜닝하려면, 먼저 옵티마이저, 학습 'the inflation reduction act lowers prescription drug costs, health care costs, and energy costs. it's the most aggressive action on tackling the climate crisis in american history. it will ask the ultra-wealthy and corporations to pay their fair share.' ``` - -텍스트를 토크나이즈하고 `input_ids`를 TensorFlow 텐서로 반환합니다: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_billsum_model") ->>> inputs = tokenizer(text, return_tensors="tf").input_ids -``` - -요약문을 생성하려면 [`~transformers.generation_tf_utils.TFGenerationMixin.generate`] 메소드를 사용하세요. -텍스트 생성에 대한 다양한 전략과 생성을 제어하기 위한 매개변수에 대한 자세한 내용은 [텍스트 생성](../main_classes/text_generation) API를 참조하세요. - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained("stevhliu/my_awesome_billsum_model") ->>> outputs = model.generate(inputs, max_new_tokens=100, do_sample=False) -``` - -생성된 토큰 ID를 텍스트로 디코딩합니다: - -```py ->>> tokenizer.decode(outputs[0], skip_special_tokens=True) -'the inflation reduction act lowers prescription drug costs, health care costs, and energy costs. it's the most aggressive action on tackling the climate crisis in american history. it will ask the ultra-wealthy and corporations to pay their fair share.' -``` - diff --git a/docs/source/ko/tasks/token_classification.md b/docs/source/ko/tasks/token_classification.md index a65503092cee..61882f1e7075 100644 --- a/docs/source/ko/tasks/token_classification.md +++ b/docs/source/ko/tasks/token_classification.md @@ -163,13 +163,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 >>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer) ``` - -```py ->>> from transformers import DataCollatorForTokenClassification - ->>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer, return_tensors="tf") -``` - ## 평가[[evaluation]] @@ -308,99 +301,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 >>> trainer.push_to_hub() ``` - - - -Keras를 사용하여 모델을 파인 튜닝하는 방법에 익숙하지 않은 경우, [여기](../training#train-a-tensorflow-model-with-keras)의 기본 튜토리얼을 확인하세요! - - -TensorFlow에서 모델을 파인 튜닝하려면, 먼저 옵티마이저 함수와 학습률 스케쥴, 그리고 일부 훈련 하이퍼파라미터를 설정해야 합니다: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_train_epochs = 3 ->>> num_train_steps = (len(tokenized_wnut["train"]) // batch_size) * num_train_epochs ->>> optimizer, lr_schedule = create_optimizer( -... init_lr=2e-5, -... num_train_steps=num_train_steps, -... weight_decay_rate=0.01, -... num_warmup_steps=0, -... ) -``` - -그런 다음 [`TFAutoModelForSequenceClassification`]을 사용하여 DistilBERT를 가져오고, 예상되는 레이블 수와 레이블 매핑을 지정합니다: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained( -... "distilbert/distilbert-base-uncased", num_labels=13, id2label=id2label, label2id=label2id -... ) -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`]을 사용하여 데이터 세트를 `tf.data.Dataset` 형식으로 변환합니다: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_wnut["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = model.prepare_tf_dataset( -... tokenized_wnut["validation"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -[`compile`](https://keras.io/api/models/model_training_apis/#compile-method)를 사용하여 훈련할 모델을 구성합니다: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -훈련을 시작하기 전에 설정해야할 마지막 두 가지는 예측에서 seqeval 점수를 계산하고, 모델을 허브에 업로드할 방법을 제공하는 것입니다. 모두 [Keras callbacks](../main_classes/keras_callbacks)를 사용하여 수행됩니다. - -[`~transformers.KerasMetricCallback`]에 `compute_metrics` 함수를 전달하세요: - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -[`~transformers.PushToHubCallback`]에서 모델과 토크나이저를 업로드할 위치를 지정합니다: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_wnut_model", -... tokenizer=tokenizer, -... ) -``` - -그런 다음 콜백을 함께 묶습니다: - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -드디어, 모델 훈련을 시작할 준비가 되었습니다! [`fit`](https://keras.io/api/models/model_training_apis/#fit-method)에 훈련 데이터 세트, 검증 데이터 세트, 에폭의 수 및 콜백을 전달하여 파인 튜닝합니다: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3, callbacks=callbacks) -``` - -훈련이 완료되면, 모델이 자동으로 허브에 업로드되어 누구나 사용할 수 있습니다! - @@ -508,48 +408,4 @@ TensorFlow에서 모델을 파인 튜닝하려면, 먼저 옵티마이저 함수 'O'] ``` - -텍스트를 토큰화하고 TensorFlow 텐서를 반환합니다: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_wnut_model") ->>> inputs = tokenizer(text, return_tensors="tf") -``` - -입력값을 모델에 전달하고 `logits`을 반환합니다: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("stevhliu/my_awesome_wnut_model") ->>> logits = model(**inputs).logits -``` - -가장 높은 확률을 가진 클래스를 모델의 `id2label` 매핑을 사용하여 텍스트 레이블로 변환합니다: - -```py ->>> predicted_token_class_ids = tf.math.argmax(logits, axis=-1) ->>> predicted_token_class = [model.config.id2label[t] for t in predicted_token_class_ids[0].numpy().tolist()] ->>> predicted_token_class -['O', - 'O', - 'B-location', - 'I-location', - 'B-group', - 'O', - 'O', - 'O', - 'O', - 'O', - 'O', - 'O', - 'O', - 'B-location', - 'B-location', - 'O', - 'O'] -``` - diff --git a/docs/source/ko/tasks/translation.md b/docs/source/ko/tasks/translation.md index 5b4eaaa6125a..dd82be10f6ea 100644 --- a/docs/source/ko/tasks/translation.md +++ b/docs/source/ko/tasks/translation.md @@ -122,14 +122,6 @@ pip install transformers datasets evaluate sacrebleu >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - -```py ->>> from transformers import DataCollatorForSeq2Seq - ->>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint, return_tensors="tf") -``` - ## 평가[[evalulate]] @@ -235,89 +227,6 @@ pip install transformers datasets evaluate sacrebleu >>> trainer.push_to_hub() ``` - - - -Keras로 모델을 파인튜닝하는 방법이 익숙하지 않다면, [여기](../training#train-a-tensorflow-model-with-keras)에서 기본 튜토리얼을 살펴보시기 바랍니다! - - -TensorFlow에서 모델을 파인튜닝하려면 우선 optimizer 함수, 학습률 스케줄 등의 훈련 하이퍼파라미터를 설정하세요: - -```py ->>> from transformers import AdamWeightDecay - ->>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) -``` - -이제 [`TFAutoModelForSeq2SeqLM`]로 T5를 가져오세요: - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained(checkpoint) -``` - -[`~transformers.TFPreTrainedModel.prepare_tf_dataset`]로 데이터 세트를 `tf.data.Dataset` 형식으로 변환하세요: - -```py ->>> tf_train_set = model.prepare_tf_dataset( -... tokenized_books["train"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_test_set = model.prepare_tf_dataset( -... tokenized_books["test"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - -훈련하기 위해 [`compile`](https://keras.io/api/models/model_training_apis/#compile-method) 메서드로 모델을 구성하세요: - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -훈련을 시작하기 전에 예측값으로부터 SacreBLEU 메트릭을 계산하는 방법과 모델을 Hub에 업로드하는 방법 두 가지를 미리 설정해둬야 합니다. 둘 다 [Keras callbacks](../main_classes/keras_callbacks)로 구현하세요. - -[`~transformers.KerasMetricCallback`]에 `compute_metrics` 함수를 전달하세요. - -```py ->>> from transformers.keras_callbacks import KerasMetricCallback - ->>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set) -``` - -모델과 토크나이저를 업로드할 위치를 [`~transformers.PushToHubCallback`]에서 지정하세요: - -```py ->>> from transformers.keras_callbacks import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="my_awesome_opus_books_model", -... tokenizer=tokenizer, -... ) -``` - -이제 콜백들을 한데로 묶어주세요: - -```py ->>> callbacks = [metric_callback, push_to_hub_callback] -``` - -드디어 모델을 훈련시킬 모든 준비를 마쳤군요! 이제 훈련 및 검증 데이터 세트에 [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) 메서드를 에폭 수와 만들어둔 콜백과 함께 호출하여 모델을 파인튜닝하세요: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=callbacks) -``` - -학습이 완료되면 모델이 자동으로 Hub에 업로드되고, 누구나 사용할 수 있게 됩니다! - @@ -378,30 +287,4 @@ TensorFlow에서 모델을 파인튜닝하려면 우선 optimizer 함수, 학습 'Les lignées partagent des ressources avec des bactéries enfixant l'azote.' ``` - -텍스트를 토큰화하고 `input_ids`를 TensorFlow 텐서로 반환하세요: - -```py ->>> from transformers import AutoTokenizer - ->>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_opus_books_model") ->>> inputs = tokenizer(text, return_tensors="tf").input_ids -``` - -[`~transformers.generation_tf_utils.TFGenerationMixin.generate`] 메서드로 번역을 생성하세요. 다양한 텍스트 생성 전략 및 생성을 제어하기 위한 매개변수에 대한 자세한 내용은 [Text Generation](../main_classes/text_generation) API를 살펴보시기 바랍니다. - -```py ->>> from transformers import TFAutoModelForSeq2SeqLM - ->>> model = TFAutoModelForSeq2SeqLM.from_pretrained("my_awesome_opus_books_model") ->>> outputs = model.generate(inputs, max_new_tokens=40, do_sample=True, top_k=30, top_p=0.95) -``` - -생성된 토큰 ID들을 다시 텍스트로 디코딩하세요: - -```py ->>> tokenizer.decode(outputs[0], skip_special_tokens=True) -'Les lugumes partagent les ressources avec des bactéries fixatrices d'azote.' -``` - diff --git a/docs/source/ko/training.md b/docs/source/ko/training.md index 432ba186c3df..637a96458284 100644 --- a/docs/source/ko/training.md +++ b/docs/source/ko/training.md @@ -157,115 +157,6 @@ rendered properly in your Markdown viewer. >>> trainer.train() ``` - - - - - -## Keras로 텐서플로우 모델 훈련하기[[train-a-tensorflow-model-with-keras]] - -Keras API를 사용하여 텐서플로우에서 🤗 Transformers 모델을 훈련할 수도 있습니다! - -### Keras용 데이터 로드[[loading-data-for-keras]] - -Keras API로 🤗 Transformers 모델을 학습시키려면 데이터셋을 Keras가 이해할 수 있는 형식으로 변환해야 합니다. -데이터 세트가 작은 경우, 전체를 NumPy 배열로 변환하여 Keras로 전달하면 됩니다. -더 복잡한 작업을 수행하기 전에 먼저 이 작업을 시도해 보겠습니다. - -먼저 데이터 세트를 로드합니다. [GLUE 벤치마크](https://huggingface.co/datasets/glue)의 CoLA 데이터 세트를 사용하겠습니다. -간단한 바이너리 텍스트 분류 작업이므로 지금은 훈련 데이터 분할만 사용합니다. - -```py -from datasets import load_dataset - -dataset = load_dataset("glue", "cola") -dataset = dataset["train"] # Just take the training split for now -``` - -다음으로 토크나이저를 로드하고 데이터를 NumPy 배열로 토큰화합니다. 레이블은 이미 0과 1로 된 리스트이기 때문에 토큰화하지 않고 바로 NumPy 배열로 변환할 수 있습니다! - -```py -from transformers import AutoTokenizer - -tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-cased") -tokenized_data = tokenizer(dataset["sentence"], return_tensors="np", padding=True) -# Tokenizer returns a BatchEncoding, but we convert that to a dict for Keras -tokenized_data = dict(tokenized_data) - -labels = np.array(dataset["label"]) # Label is already an array of 0 and 1 -``` - -마지막으로 모델을 로드, [`compile`](https://keras.io/api/models/model_training_apis/#compile-method), [`fit`](https://keras.io/api/models/model_training_apis/#fit-method)합니다: - -```py -from transformers import TFAutoModelForSequenceClassification -from tensorflow.keras.optimizers import Adam - -# Load and compile our model -model = TFAutoModelForSequenceClassification.from_pretrained("google-bert/bert-base-cased") -# Lower learning rates are often better for fine-tuning transformers -model.compile(optimizer=Adam(3e-5)) - -model.fit(tokenized_data, labels) -``` - - - -모델을 `compile()`할 때 손실 인수를 모델에 전달할 필요가 없습니다! -이 인수를 비워두면 허깅 페이스 모델은 작업과 모델 아키텍처에 적합한 손실을 자동으로 선택합니다. -원한다면 언제든지 직접 손실을 지정하여 이를 재정의할 수 있습니다! - - - -이 접근 방식은 소규모 데이터 집합에서는 잘 작동하지만, 대규모 데이터 집합에서는 문제가 될 수 있습니다. 왜 그럴까요? -토큰화된 배열과 레이블을 메모리에 완전히 로드하고 NumPy는 "들쭉날쭉한" 배열을 처리하지 않기 때문에, -모든 토큰화된 샘플을 전체 데이터셋에서 가장 긴 샘플의 길이만큼 패딩해야 합니다. 이렇게 하면 배열이 훨씬 더 커지고 이 패딩 토큰으로 인해 학습 속도도 느려집니다! - -### 데이터를 tf.data.Dataset으로 로드하기[[loading-data-as-a-tfdatadataset]] - -학습 속도가 느려지는 것을 피하려면 데이터를 `tf.data.Dataset`으로 로드할 수 있습니다. 원한다면 직접 -`tf.data` 파이프라인을 직접 작성할 수도 있지만, 이 작업을 간편하게 수행하는 수 있는 두 가지 방법이 있습니다: - -- [`~TFPreTrainedModel.prepare_tf_dataset`]: 대부분의 경우 이 방법을 권장합니다. 모델의 메서드이기 때문에 모델을 검사하여 모델 입력으로 사용할 수 있는 열을 자동으로 파악하고 -나머지는 버려서 더 단순하고 성능이 좋은 데이터 집합을 만들 수 있습니다. -- [`~datasets.Dataset.to_tf_dataset`]: 이 방법은 좀 더 낮은 수준이며, 포함할 '열'과 '레이블'을 정확히 지정하여 -데이터셋을 생성하는 방법을 정확히 제어하고 싶을 때 유용하며, 포함할 'columns'과 'label_cols'을 정확히 지정할 수 있습니다. - -[`~TFPreTrainedModel.prepare_tf_dataset`]을 사용하려면 먼저 다음 코드 샘플과 같이 토크나이저 출력을 데이터 세트에 열로 추가해야 합니다: - -```py -def tokenize_dataset(data): - # Keys of the returned dictionary will be added to the dataset as columns - return tokenizer(data["text"]) - - -dataset = dataset.map(tokenize_dataset) -``` - -허깅 페이스 데이터셋은 기본적으로 디스크에 저장되므로 메모리 사용량을 늘리지 않는다는 점을 기억하세요! -열이 추가되면 데이터셋에서 배치를 스트리밍하고 각 배치에 패딩을 추가할 수 있으므로 전체 데이터셋에 패딩을 추가하는 것보다 패딩 토큰의 수를 크게 줄일 수 있습니다. - - -```py ->>> tf_dataset = model.prepare_tf_dataset(dataset, batch_size=16, shuffle=True, tokenizer=tokenizer) -``` - -위의 코드 샘플에서는 배치가 로드될 때 올바르게 패딩할 수 있도록 `prepare_tf_dataset`에 토크나이저를 전달해야 합니다. -데이터셋의 모든 샘플 길이가 같고 패딩이 필요하지 않은 경우 이 인수를 건너뛸 수 있습니다. -샘플을 채우는 것보다 더 복잡한 작업(예: 마스킹된 언어의 토큰 손상 모델링)을 수행하기 위해 토큰을 손상시켜야 하는 경우, -`collate_fn` 인수를 사용하여 샘플 목록을 배치로 변환하고 원하는 전처리를 적용할 함수를 전달할 수 있습니다. -[예시](https://github.com/huggingface/transformers/tree/main/examples) 또는 -[노트북](https://huggingface.co/docs/transformers/notebooks)을 참조하여 이 접근 방식이 실제로 작동하는 모습을 확인하세요. - -`tf.data.Dataset`을 생성한 후에는 이전과 마찬가지로 모델을 컴파일하고 훈련(fit)할 수 있습니다: - -```py -model.compile(optimizer=Adam(3e-5)) - -model.fit(tf_dataset) -``` - - diff --git a/docs/source/pt/create_a_model.md b/docs/source/pt/create_a_model.md index dd71963236f4..c0736f72771b 100644 --- a/docs/source/pt/create_a_model.md +++ b/docs/source/pt/create_a_model.md @@ -136,30 +136,6 @@ Quando você carregar os pesos pré-treinados, a configuração padrão do model >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) ``` - -Carregar os seus próprios atributos padrões de contiguração no modelo: - -```py ->>> from transformers import TFDistilBertModel - ->>> my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json") ->>> tf_model = TFDistilBertModel(my_config) -``` - -Isso cria um modelo com valores aleatórios ao invés de pré-treinar os pesos. Você não irá conseguir usar usar esse modelo para nada útil ainda, até você treinar ele. Treino é um processo caro e demorado. Geralmente é melhor utilizar um modelo pré-treinado para obter melhores resultados mais rápido, enquanto usa apenas uma fração dos recursos necessários para treinar. - -Criar um modelo pré-treinado com [`~TFPreTrainedModel.from_pretrained`]: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Quando você carregar os pesos pré-treinados, a configuração padrão do modelo é automaticamente carregada se o modelo é provido pelo 🤗 Transformers. No entanto, você ainda consegue mudar - alguns ou todos - os atributos padrões de configuração do modelo com os seus próprio atributos, se você preferir: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) -``` - ### Heads do modelo @@ -184,23 +160,6 @@ Reutilize facilmente esse ponto de parada para outra tarefe mudando para uma hea >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - -Por exemplo, [`TFDistilBertForSequenceClassification`] é um modelo DistilBERT base com uma head de classificação de sequência. A head de calssificação de sequência é uma camada linear no topo das saídas agrupadas. - -```py ->>> from transformers import TFDistilBertForSequenceClassification - ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -Reutilize facilmente esse ponto de parada para outra tarefe mudando para uma head de modelo diferente. Para uma tarefe de responder questões, você usaria a head do modelo [`TFDistilBertForQuestionAnswering`]. A head de responder questões é similar com a de classificação de sequências exceto o fato de que ela é uma camada no topo dos estados das saídas ocultas. - -```py ->>> from transformers import TFDistilBertForQuestionAnswering - ->>> tf_model = TFDistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") -``` - ## Tokenizer @@ -356,4 +315,4 @@ Combine o extrator de features e o tokenizer no [`Wav2Vec2Processor`]: >>> processor = Wav2Vec2Processor(feature_extractor=feature_extractor, tokenizer=tokenizer) ``` -Com duas classes básicas - configuração e modelo - e um preprocessamento de classe adicional (tokenizer, extrator de features, ou processador), você pode criar qualquer modelo que suportado por 🤗 Transformers. Qualquer uma dessas classes base são configuráveis, te permitindo usar os atributos específicos que você queira. Você pode facilmente preparar um modelo para treinamento ou modificar um modelo pré-treinado com poucas mudanças. \ No newline at end of file +Com duas classes básicas - configuração e modelo - e um preprocessamento de classe adicional (tokenizer, extrator de features, ou processador), você pode criar qualquer modelo que suportado por 🤗 Transformers. Qualquer uma dessas classes base são configuráveis, te permitindo usar os atributos específicos que você queira. Você pode facilmente preparar um modelo para treinamento ou modificar um modelo pré-treinado com poucas mudanças. diff --git a/docs/source/pt/quicktour.md b/docs/source/pt/quicktour.md index 5ccdd63376e3..1704c0fb2c7c 100644 --- a/docs/source/pt/quicktour.md +++ b/docs/source/pt/quicktour.md @@ -72,11 +72,6 @@ Instale as seguintes dependências se você ainda não o fez: pip install torch ``` - -```bash -pip install tensorflow -``` - Importe [`pipeline`] e especifique a tarefa que deseja completar: @@ -163,17 +158,6 @@ Use o [`AutoModelForSequenceClassification`] e [`AutoTokenizer`] para carregar o >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - - -Use o [`TFAutoModelForSequenceClassification`] and [`AutoTokenizer`] para carregar o modelo pré-treinado e o tokenizer associado (mais em `TFAutoClass` abaixo): - -```py ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - Então você pode especificar o modelo e o tokenizador na [`pipeline`] e aplicar o `classifier` no seu texto alvo: @@ -239,18 +223,6 @@ Assim como o [`pipeline`], o tokenizer aceitará uma lista de entradas. Além di ... ) ``` - - -```py ->>> tf_batch = tokenizer( -... ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="tf", -... ) -``` - Leia o tutorial de [pré-processamento](./pré-processamento) para obter mais detalhes sobre tokenização. @@ -291,37 +263,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - -🤗 Transformers fornecem uma maneira simples e unificada de carregar instâncias pré-treinadas. Isso significa que você pode carregar um [`TFAutoModel`] como carregaria um [`AutoTokenizer`]. A única diferença é selecionar o [`TFAutoModel`] correto para a tarefa. Como você está fazendo classificação de texto ou sequência, carregue [`TFAutoModelForSequenceClassification`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name) -``` - - - -Veja o [sumário de tarefas](./task_summary) para qual classe de [`AutoModel`] usar para cada tarefa. - - - -Agora você pode passar seu grupo de entradas pré-processadas diretamente para o modelo através da passagem de chaves de dicionários ao tensor. - -```py ->>> tf_outputs = tf_model(tf_batch) -``` - -O modelo gera as ativações finais no atributo `logits`. Aplique a função softmax aos `logits` para recuperar as probabilidades: - -```py ->>> import tensorflow as tf - ->>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1) ->>> tf_predictions # doctest: +IGNORE_RESULT -``` - @@ -358,21 +299,6 @@ Quando você estiver pronto para usá-lo novamente, recarregue com [`PreTrainedM >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - -Uma vez que seu modelo estiver afinado, você pode salvá-lo com seu Tokenizer usando [`TFPreTrainedModel.save_pretrained`]: - -```py ->>> tf_save_directory = "./tf_save_pretrained" ->>> tokenizer.save_pretrained(tf_save_directory) # doctest: +IGNORE_RESULT ->>> tf_model.save_pretrained(tf_save_directory) -``` - -Quando você estiver pronto para usá-lo novamente, recarregue com [`TFPreTrainedModel.from_pretrained`] - -```py ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained") -``` - Um recurso particularmente interessante dos 🤗 Transformers é a capacidade de salvar um modelo e recarregá-lo como um modelo PyTorch ou TensorFlow. Use `from_pt` ou `from_tf` para converter o modelo de um framework para outro: @@ -387,13 +313,4 @@ Um recurso particularmente interessante dos 🤗 Transformers é a capacidade de >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - -```py ->>> from transformers import TFAutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory) ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) -``` - - \ No newline at end of file + diff --git a/docs/source/pt/run_scripts.md b/docs/source/pt/run_scripts.md index 8aad0f602896..32182497a366 100644 --- a/docs/source/pt/run_scripts.md +++ b/docs/source/pt/run_scripts.md @@ -105,22 +105,6 @@ python examples/pytorch/summarization/run_summarization.py \ --predict_with_generate ``` - -Este outro script de exemplo baixa e pré-processa um conjunto de dados da biblioteca 🤗 [Datasets](https://huggingface.co/docs/datasets/). Em seguida, o script ajusta um conjunto de dados usando Keras em uma arquitetura que oferece suporte à sumarização. O exemplo a seguir mostra como ajustar [T5-small](https://huggingface.co/google-t5/t5-small) no conjunto de dados [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail). O modelo T5 requer um argumento `source_prefix` adicional devido à forma como foi treinado. Este prompt informa ao T5 que esta é uma tarefa de sumarização. - -```bash -python examples/tensorflow/summarization/run_summarization.py \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Treinamento distribuído e precisão mista @@ -171,24 +155,6 @@ python xla_spawn.py --num_cores 8 \ --predict_with_generate ``` - - -As Unidades de Processamento de Tensor (TPUs) são projetadas especificamente para acelerar o desempenho. Os scripts do TensorFlow utilizam uma [`TPUStrategy`](https://www.tensorflow.org/guide/distributed_training#tpustrategy) para treinamento em TPUs. Para usar uma TPU, passe o nome do recurso TPU para o argumento `tpu`. - -```bash -python run_summarization.py \ - --tpu name_of_tpu_resource \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## Execute um script com 🤗 Accelerate diff --git a/docs/source/pt/tasks/sequence_classification.md b/docs/source/pt/tasks/sequence_classification.md index a2e6865c92e5..b60851127757 100644 --- a/docs/source/pt/tasks/sequence_classification.md +++ b/docs/source/pt/tasks/sequence_classification.md @@ -86,13 +86,6 @@ Use o [`DataCollatorWithPadding`] para criar um batch de exemplos. Ele também * >>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer) ``` - -```py ->>> from transformers import DataCollatorWithPadding - ->>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer, return_tensors="tf") -``` - ## Train @@ -147,66 +140,6 @@ O [`Trainer`] aplicará o preenchimento dinâmico por padrão quando você defin - -Para executar o fine-tuning de um modelo no TensorFlow, comece convertendo seu conjunto de dados para o formato `tf.data.Dataset` com [`to_tf_dataset`](https://huggingface.co/docs/datasets/package_reference/main_classes#datasets.Dataset.to_tf_dataset). Nessa execução você deverá especificar as entradas e rótulos (no parâmetro `columns`), se deseja embaralhar o conjunto de dados, o tamanho do batch e o data collator: - -```py ->>> tf_train_set = tokenized_imdb["train"].to_tf_dataset( -... columns=["attention_mask", "input_ids", "label"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = tokenized_imdb["test"].to_tf_dataset( -... columns=["attention_mask", "input_ids", "label"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - - - -Se você não estiver familiarizado com o fine-tuning de um modelo com o Keras, dê uma olhada no tutorial básico [aqui](training#finetune-with-keras)! - - - -Configure o otimizador e alguns hiperparâmetros de treinamento: - -```py ->>> from transformers import create_optimizer ->>> import tensorflow as tf - ->>> batch_size = 16 ->>> num_epochs = 5 ->>> batches_per_epoch = len(tokenized_imdb["train"]) // batch_size ->>> total_train_steps = int(batches_per_epoch * num_epochs) ->>> optimizer, schedule = create_optimizer(init_lr=2e-5, num_warmup_steps=0, num_train_steps=total_train_steps) -``` - -Carregue o DistilBERT com [`TFAutoModelForSequenceClassification`] junto com o número de rótulos esperados: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased", num_labels=2) -``` - -Configure o modelo para treinamento com o método [`compile`](https://keras.io/api/models/model_training_apis/#compile-method): - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -Chame o método [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) para executar o fine-tuning do modelo: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3) -``` - diff --git a/docs/source/pt/tasks/token_classification.md b/docs/source/pt/tasks/token_classification.md index 45ce0d87429c..d314caf157f7 100644 --- a/docs/source/pt/tasks/token_classification.md +++ b/docs/source/pt/tasks/token_classification.md @@ -144,13 +144,6 @@ Use o [`DataCollatorForTokenClassification`] para criar um batch de exemplos. El >>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer) ``` - -```py ->>> from transformers import DataCollatorForTokenClassification - ->>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer, return_tensors="tf") -``` - ## Treinamento @@ -200,69 +193,6 @@ Nesse ponto, restam apenas três passos: >>> trainer.train() ``` - -Para executar o fine-tuning de um modelo no TensorFlow, comece convertendo seu conjunto de dados para o formato `tf.data.Dataset` com [`to_tf_dataset`](https://huggingface.co/docs/datasets/package_reference/main_classes#datasets.Dataset.to_tf_dataset). Nessa execução você deverá especificar as entradas e rótulos (no parâmetro `columns`), se deseja embaralhar o conjunto de dados, o tamanho do batch e o data collator: - -```py ->>> tf_train_set = tokenized_wnut["train"].to_tf_dataset( -... columns=["attention_mask", "input_ids", "labels"], -... shuffle=True, -... batch_size=16, -... collate_fn=data_collator, -... ) - ->>> tf_validation_set = tokenized_wnut["validation"].to_tf_dataset( -... columns=["attention_mask", "input_ids", "labels"], -... shuffle=False, -... batch_size=16, -... collate_fn=data_collator, -... ) -``` - - - -Se você não estiver familiarizado com o fine-tuning de um modelo com o Keras, dê uma olhada no tutorial básico [aqui](training#finetune-with-keras)! - - - -Configure o otimizador e alguns hiperparâmetros de treinamento: - -```py ->>> from transformers import create_optimizer - ->>> batch_size = 16 ->>> num_train_epochs = 3 ->>> num_train_steps = (len(tokenized_wnut["train"]) // batch_size) * num_train_epochs ->>> optimizer, lr_schedule = create_optimizer( -... init_lr=2e-5, -... num_train_steps=num_train_steps, -... weight_decay_rate=0.01, -... num_warmup_steps=0, -... ) -``` - -Carregue o DistilBERT com o [`TFAutoModelForTokenClassification`] junto com o número de rótulos esperados: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("distilbert/distilbert-base-uncased", num_labels=2) -``` - -Configure o modelo para treinamento com o método [`compile`](https://keras.io/api/models/model_training_apis/#compile-method): - -```py ->>> import tensorflow as tf - ->>> model.compile(optimizer=optimizer) -``` - -Chame o método [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) para executar o fine-tuning do modelo: - -```py ->>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3) -``` - diff --git a/docs/source/zh/autoclass_tutorial.md b/docs/source/zh/autoclass_tutorial.md index f056f12d787b..95fb1783a864 100644 --- a/docs/source/zh/autoclass_tutorial.md +++ b/docs/source/zh/autoclass_tutorial.md @@ -127,23 +127,4 @@ TensorFlow和Flax的checkpoints不受影响,并且可以在PyTorch架构中使 一般来说,我们建议使用`AutoTokenizer`类和`AutoModelFor`类来加载预训练的模型实例。这样可以确保每次加载正确的架构。在下一个[教程](preprocessing)中,学习如何使用新加载的`tokenizer`, `image processor`, `feature extractor`和`processor`对数据集进行预处理以进行微调。 - -最后,`TFAutoModelFor`类允许您加载给定任务的预训练模型(请参阅[这里](model_doc/auto)获取可用任务的完整列表)。例如,使用[`TFAutoModelForSequenceClassification.from_pretrained`]加载用于序列分类的模型: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -轻松地重复使用相同的checkpoint来为不同任务加载模型架构: - -```py ->>> from transformers import TFAutoModelForTokenClassification - ->>> model = TFAutoModelForTokenClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` -一般来说,我们推荐使用`AutoTokenizer`类和`TFAutoModelFor`类来加载模型的预训练实例。这样可以确保每次加载正确的架构。在下一个[教程](preprocessing)中,学习如何使用新加载的`tokenizer`, `image processor`, `feature extractor`和`processor`对数据集进行预处理以进行微调。 - - diff --git a/docs/source/zh/create_a_model.md b/docs/source/zh/create_a_model.md index fd07497e7abf..862842f15db6 100644 --- a/docs/source/zh/create_a_model.md +++ b/docs/source/zh/create_a_model.md @@ -137,30 +137,6 @@ DistilBertConfig { >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) ``` - -将自定义配置属性加载到模型中: - -```py ->>> from transformers import TFDistilBertModel - ->>> my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json") ->>> tf_model = TFDistilBertModel(my_config) -``` - -这段代码创建了一个具有随机参数而不是预训练权重的模型。在训练该模型之前,您还无法将该模型用于任何用途。训练是一项昂贵且耗时的过程。通常来说,最好使用预训练模型来更快地获得更好的结果,同时仅使用训练所需资源的一小部分。 - -使用 [`~TFPreTrainedModel.from_pretrained`] 创建预训练模型: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased") -``` - -当加载预训练权重时,如果模型是由 🤗 Transformers 提供的,将自动加载默认模型配置。然而,如果你愿意,仍然可以将默认模型配置的某些或者所有属性替换成自己的配置: - -```py ->>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) -``` - ### 模型头(Model heads) @@ -185,23 +161,6 @@ DistilBertConfig { >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - -例如,[`TFDistilBertForSequenceClassification`] 是一个带有序列分类头(sequence classification head)的基础 DistilBERT 模型。序列分类头是池化输出之上的线性层。 - -```py ->>> from transformers import TFDistilBertForSequenceClassification - ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased") -``` - -通过切换到不同的模型头,可以轻松地将此检查点重复用于其他任务。对于问答任务,你可以使用 [`TFDistilBertForQuestionAnswering`] 模型头。问答头(question answering head)与序列分类头类似,不同点在于它是隐藏状态输出之上的线性层。 - -```py ->>> from transformers import TFDistilBertForQuestionAnswering - ->>> tf_model = TFDistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") -``` - ## 分词器 diff --git a/docs/source/zh/model_sharing.md b/docs/source/zh/model_sharing.md index c0ce60252537..ab77665f8411 100644 --- a/docs/source/zh/model_sharing.md +++ b/docs/source/zh/model_sharing.md @@ -89,30 +89,6 @@ pip install huggingface_hub >>> pt_model.save_pretrained("path/to/awesome-name-you-picked") ``` - - -指定`from_pt=True`将checkpoint从PyTorch转换为TensorFlow。 - -```py ->>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_pt=True) -``` - -然后,您可以使用新的checkpoint保存您的新TensorFlow模型: - -```py ->>> tf_model.save_pretrained("path/to/awesome-name-you-picked") -``` - - - -如果模型在Flax中可用,您还可以将PyTorch checkpoint转换为Flax: - -```py ->>> flax_model = FlaxDistilBertForSequenceClassification.from_pretrained( -... "path/to/awesome-name-you-picked", from_pt=True -... ) -``` - ## 在训练过程中推送模型 @@ -146,29 +122,6 @@ pip install huggingface_hub >>> trainer.push_to_hub() ``` - - -使用[`PushToHubCallback`]将模型分享到Hub。在[`PushToHubCallback`]函数中,添加以下内容: - -- 一个用于存储模型的输出目录。 -- 一个tokenizer。 -- `hub_model_id`,即您的Hub用户名和模型名称。 - - -```py ->>> from transformers import PushToHubCallback - ->>> push_to_hub_callback = PushToHubCallback( -... output_dir="./your_model_save_path", tokenizer=tokenizer, hub_model_id="your-username/my-awesome-model" -... ) -``` - -将回调函数添加到 [`fit`](https://keras.io/api/models/model_training_apis/)中,然后🤗 Transformers 会将训练好的模型推送到 Hub: - -```py ->>> model.fit(tf_train_dataset, validation_data=tf_validation_dataset, epochs=3, callbacks=push_to_hub_callback) -``` - ## 使用`push_to_hub`功能 @@ -235,4 +188,4 @@ pip install huggingface_hub * 手动创建并上传一个`README.md`文件。 * 在你的模型仓库中点击**编辑模型卡片**按钮。 -可以参考DistilBert的[模型卡片](https://huggingface.co/distilbert/distilbert-base-uncased)来了解模型卡片应该包含的信息类型。有关您可以在`README.md`文件中控制的更多选项的细节,例如模型的碳足迹或小部件示例,请参考文档[这里](https://huggingface.co/docs/hub/models-cards)。 \ No newline at end of file +可以参考DistilBert的[模型卡片](https://huggingface.co/distilbert/distilbert-base-uncased)来了解模型卡片应该包含的信息类型。有关您可以在`README.md`文件中控制的更多选项的细节,例如模型的碳足迹或小部件示例,请参考文档[这里](https://huggingface.co/docs/hub/models-cards)。 diff --git a/docs/source/zh/preprocessing.md b/docs/source/zh/preprocessing.md index b90c89b36d15..c33fdee980ed 100644 --- a/docs/source/zh/preprocessing.md +++ b/docs/source/zh/preprocessing.md @@ -196,31 +196,6 @@ pip install datasets [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])} ``` - - -```py ->>> batch_sentences = [ -... "But what about second breakfast?", -... "Don't think he knows about second breakfast, Pip.", -... "What about elevensies?", -... ] ->>> encoded_input = tokenizer(batch_sentences, padding=True, truncation=True, return_tensors="tf") ->>> print(encoded_input) -{'input_ids': , - 'token_type_ids': , - 'attention_mask': } -``` - ## 音频 diff --git a/docs/source/zh/quicktour.md b/docs/source/zh/quicktour.md index 0c3fc8b8571d..e28101fd6393 100644 --- a/docs/source/zh/quicktour.md +++ b/docs/source/zh/quicktour.md @@ -35,12 +35,6 @@ rendered properly in your Markdown viewer. pip install torch ``` - - -```bash -pip install tensorflow -``` - ## Pipeline @@ -143,16 +137,6 @@ label: NEGATIVE, with score: 0.5309 >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - -使用 [`TFAutoModelForSequenceClassification`] 和 [`AutoTokenizer`] 来加载预训练模型和它关联的分词器(更多信息可以参考下一节的 `TFAutoClass`): - -```py ->>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification - ->>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name) ->>> tokenizer = AutoTokenizer.from_pretrained(model_name) -``` - 在 [`pipeline`] 中指定模型和分词器,现在你就可以在法语文本上使用 `classifier` 了: @@ -216,18 +200,6 @@ label: NEGATIVE, with score: 0.5309 ... ) ``` - - -```py ->>> tf_batch = tokenizer( -... ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."], -... padding=True, -... truncation=True, -... max_length=512, -... return_tensors="tf", -... ) -``` - @@ -272,37 +244,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - -🤗 Transformers 提供了一种简单统一的方式来加载预训练的实例。这表示你可以像加载 [`AutoTokenizer`] 一样加载 [`TFAutoModel`]。唯一不同的地方是为你的任务选择正确的 [`TFAutoModel`],对于文本(或序列)分类,你应该加载 [`TFAutoModelForSequenceClassification`]: - -```py ->>> from transformers import TFAutoModelForSequenceClassification - ->>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name) -``` - - - -通过 [任务摘要](./task_summary) 查找 [`AutoModel`] 支持的任务. - - - -现在通过直接将字典的键传给张量,将预处理的输入批次传给模型。 - -```py ->>> tf_outputs = tf_model(tf_batch) -``` - -模型在 `logits` 属性输出最终的激活结果。在 `logits` 上应用softmax函数来查询概率: - -```py ->>> import tensorflow as tf - ->>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1) ->>> tf_predictions # doctest: +IGNORE_RESULT -``` - @@ -330,21 +271,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - -当你的模型微调完成,你就可以使用 [`TFPreTrainedModel.save_pretrained`] 把它和它的分词器保存下来: - -```py ->>> tf_save_directory = "./tf_save_pretrained" ->>> tokenizer.save_pretrained(tf_save_directory) # doctest: +IGNORE_RESULT ->>> tf_model.save_pretrained(tf_save_directory) -``` - -当你准备再次使用这个模型时,就可以使用 [`TFPreTrainedModel.from_pretrained`] 加载它了: - -```py ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained") -``` - 🤗 Transformers 有一个特别酷的功能,它能够保存一个模型,并且将它加载为 PyTorch 或 TensorFlow 模型。`from_pt` 或 `from_tf` 参数可以将模型从一个框架转换为另一个框架: @@ -359,15 +285,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - -```py ->>> from transformers import TFAutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory) ->>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True) -``` - ## 自定义模型构建 @@ -392,15 +309,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_model = AutoModel.from_config(my_config) ``` - -使用 [`TFAutoModel.from_config`] 根据你的自定义配置创建一个模型: - -```py ->>> from transformers import TFAutoModel - ->>> my_model = TFAutoModel.from_config(my_config) -``` - 查阅 [创建一个自定义结构](./create_a_model) 指南获取更多关于构建自定义配置的信息。 diff --git a/docs/source/zh/run_scripts.md b/docs/source/zh/run_scripts.md index 06ce4ce0d18a..c82264299a70 100644 --- a/docs/source/zh/run_scripts.md +++ b/docs/source/zh/run_scripts.md @@ -105,23 +105,6 @@ python examples/pytorch/summarization/run_summarization.py \ --predict_with_generate ``` - - -示例脚本从 🤗 [Datasets](https://huggingface.co/docs/datasets/) 库下载并预处理数据集。然后,脚本使用 Keras 在支持摘要的架构上微调数据集。以下示例展示了如何在 [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail) 数据集上微调 [T5-small](https://huggingface.co/google-t5/t5-small)。T5 模型由于训练方式需要额外的 `source_prefix` 参数。这个提示让 T5 知道这是一个摘要任务。 - -```bash -python examples/tensorflow/summarization/run_summarization.py \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## 分布式训练和混合精度 @@ -174,24 +157,6 @@ python xla_spawn.py --num_cores 8 \ --predict_with_generate ``` - - -张量处理单元(TPUs)是专门设计用于加速性能的。TensorFlow脚本使用[`TPUStrategy`](https://www.tensorflow.org/guide/distributed_training#tpustrategy)在TPU上进行训练。要使用TPU,请将TPU资源的名称传递给`tpu`参数。 - -```bash -python run_summarization.py \ - --tpu name_of_tpu_resource \ - --model_name_or_path google-t5/t5-small \ - --dataset_name cnn_dailymail \ - --dataset_config "3.0.0" \ - --output_dir /tmp/tst-summarization \ - --per_device_train_batch_size 8 \ - --per_device_eval_batch_size 16 \ - --num_train_epochs 3 \ - --do_train \ - --do_eval -``` - ## 基于🤗 Accelerate运行脚本 @@ -356,4 +321,4 @@ python examples/pytorch/summarization/run_summarization.py --per_device_eval_batch_size=4 \ --overwrite_output_dir \ --predict_with_generate -``` \ No newline at end of file +``` diff --git a/docs/source/zh/training.md b/docs/source/zh/training.md index aeacf732c22f..d383f73dc623 100644 --- a/docs/source/zh/training.md +++ b/docs/source/zh/training.md @@ -153,96 +153,6 @@ rendered properly in your Markdown viewer. >>> trainer.train() ``` - - - - - -## 使用keras训练TensorFlow模型 - -您也可以使用 Keras API 在 TensorFlow 中训练 🤗 Transformers 模型! - -### 加载用于 Keras 的数据 - -当您希望使用 Keras API 训练 🤗 Transformers 模型时,您需要将您的数据集转换为 Keras 可理解的格式。如果您的数据集很小,您可以将整个数据集转换为NumPy数组并传递给 Keras。在进行更复杂的操作之前,让我们先尝试这种方法。 - -首先,加载一个数据集。我们将使用 [GLUE benchmark](https://huggingface.co/datasets/glue) 中的 CoLA 数据集,因为它是一个简单的二元文本分类任务。现在只使用训练数据集。 - - -```py -from datasets import load_dataset - -dataset = load_dataset("glue", "cola") -dataset = dataset["train"] # Just take the training split for now -``` -接下来,加载一个`tokenizer`并将数据标记为 NumPy 数组。请注意,标签已经是由 0 和 1 组成的`list`,因此我们可以直接将其转换为 NumPy 数组而无需进行分词处理! - -```py -from transformers import AutoTokenizer - -tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-cased") -tokenized_data = tokenizer(dataset["sentence"], return_tensors="np", padding=True) -# Tokenizer returns a BatchEncoding, but we convert that to a dict for Keras -tokenized_data = dict(tokenized_data) - -labels = np.array(dataset["label"]) # Label is already an array of 0 and 1 -``` -最后,加载、[`compile`](https://keras.io/api/models/model_training_apis/#compile-method) 和 [`fit`](https://keras.io/api/models/model_training_apis/#fit-method) 模型。请注意,Transformers 模型都有一个默认的与任务相关的损失函数,因此除非您希望自定义,否则无需指定一个损失函数: - -```py -from transformers import TFAutoModelForSequenceClassification -from tensorflow.keras.optimizers import Adam - -# Load and compile our model -model = TFAutoModelForSequenceClassification.from_pretrained("google-bert/bert-base-cased") -# Lower learning rates are often better for fine-tuning transformers -model.compile(optimizer=Adam(3e-5)) # No loss argument! - -model.fit(tokenized_data, labels) -``` - - - -当您使用 `compile()` 编译模型时,无需传递损失参数!如果不指定损失参数,Hugging Face 模型会自动选择适合其任务和模型架构的损失函数。如果需要,您始终可以自己指定损失函数以覆盖默认配置。 - - - -这种方法对于较小的数据集效果很好,但对于较大的数据集,您可能会发现它开始变得有问题。为什么呢?因为分词后的数组和标签必须完全加载到内存中,而且由于 NumPy 无法处理“不规则”数组,因此每个分词后的样本长度都必须被填充到数据集中最长样本的长度。这将使您的数组变得更大,而所有这些`padding tokens`也会减慢训练速度! - - -### 将数据加载为 tf.data.Dataset - -如果您想避免训练速度减慢,可以将数据加载为 `tf.data.Dataset`。虽然您可以自己编写自己的 `tf.data` 流水线,但我们有两种方便的方法来实现这一点: - -- [`~TFPreTrainedModel.prepare_tf_dataset`]:这是我们在大多数情况下推荐的方法。因为它是模型上的一个方法,它可以检查模型以自动确定哪些列可用作模型输入,并丢弃其他列以创建一个更简单、性能更好的数据集。 -- [`~datasets.Dataset.to_tf_dataset`]:这个方法更低级,但当您希望完全控制数据集的创建方式时非常有用,可以通过指定要包括的确切 `columns` 和 `label_cols` 来实现。 - -在使用 [`~TFPreTrainedModel.prepare_tf_dataset`] 之前,您需要将`tokenizer`的输出添加到数据集作为列,如下面的代码示例所示: - -```py -def tokenize_dataset(data): - # Keys of the returned dictionary will be added to the dataset as columns - return tokenizer(data["text"]) - - -dataset = dataset.map(tokenize_dataset) -``` -请记住,默认情况下,Hugging Face 数据集存储在硬盘上,因此这不会增加您的内存使用!一旦列已经添加,您可以从数据集中流式的传输批次数据,并为每个批次添加`padding tokens`,这与为整个数据集添加`padding tokens`相比,大大减少了`padding tokens`的数量。 - -```py ->>> tf_dataset = model.prepare_tf_dataset(dataset["train"], batch_size=16, shuffle=True, tokenizer=tokenizer) -``` -请注意,在上面的代码示例中,您需要将`tokenizer`传递给`prepare_tf_dataset`,以便它可以在加载批次时正确填充它们。如果数据集中的所有样本都具有相同的长度而且不需要填充,您可以跳过此参数。如果需要执行比填充样本更复杂的操作(例如,用于掩码语言模型的`tokens` 替换),则可以使用 `collate_fn` 参数,而不是传递一个函数来将样本列表转换为批次并应用任何所需的预处理。请查看我们的[示例](https://github.com/huggingface/transformers/tree/main/examples)或[笔记](https://huggingface.co/docs/transformers/notebooks)以了解此方法的实际操作。 - -一旦创建了 `tf.data.Dataset`,您可以像以前一样编译和训练模型: - -```py -model.compile(optimizer=Adam(3e-5)) # No loss argument! - -model.fit(tf_dataset) -``` - - @@ -404,4 +314,4 @@ torch.cuda.empty_cache() - [🤗 Transformers 示例](https://github.com/huggingface/transformers/tree/main/examples) 包含用于在 PyTorch 和 TensorFlow 中训练常见自然语言处理任务的脚本。 -- [🤗 Transformers 笔记](notebooks) 包含针对特定任务在 PyTorch 和 TensorFlow 中微调模型的各种`notebook`。 \ No newline at end of file +- [🤗 Transformers 笔记](notebooks) 包含针对特定任务在 PyTorch 和 TensorFlow 中微调模型的各种`notebook`。 From 0bedf8aee1aef4e18c93816d76e351a770b0fe50 Mon Sep 17 00:00:00 2001 From: Ralph Gleaton <70818603+rjgleaton@users.noreply.github.com> Date: Mon, 22 Sep 2025 07:42:34 -0500 Subject: [PATCH 147/204] Add Whole Word Masking and Padding Strategy to DataCollatorForLanguageModeling (#39485) * Add whole word masking * Vectorize whole word masking functions * Unit test whole word masking * Remove support for TF in whole word masking --- src/transformers/data/data_collator.py | 379 ++++++++----------------- tests/trainer/test_data_collator.py | 341 +++++++++++++++------- 2 files changed, 355 insertions(+), 365 deletions(-) diff --git a/src/transformers/data/data_collator.py b/src/transformers/data/data_collator.py index 1bff72cf338c..d9b198b51087 100644 --- a/src/transformers/data/data_collator.py +++ b/src/transformers/data/data_collator.py @@ -13,7 +13,6 @@ # limitations under the License. import multiprocessing as mp -import random import warnings from collections.abc import Mapping from dataclasses import dataclass @@ -22,7 +21,6 @@ import numpy as np -from ..models.bert import BertTokenizer, BertTokenizerFast from ..tokenization_utils_base import PreTrainedTokenizerBase from ..utils import PaddingStrategy @@ -630,6 +628,8 @@ class DataCollatorForLanguageModeling(DataCollatorMixin): Whether or not to use masked language modeling. If set to `False`, the labels are the same as the inputs with the padding tokens ignored (by setting them to -100). Otherwise, the labels are -100 for non-masked tokens and the value to predict for the masked token. + whole_word_mask (`bool`, *optional*, defaults to `False`): + Whether or not to mask whole words instead of individual tokens. mlm_probability (`float`, *optional*, defaults to 0.15): The probability with which to (randomly) mask tokens in the input, when `mlm` is set to `True`. mask_replace_prob (`float`, *optional*, defaults to 0.8): @@ -681,6 +681,7 @@ class DataCollatorForLanguageModeling(DataCollatorMixin): tokenizer: PreTrainedTokenizerBase mlm: bool = True + whole_word_mask: bool = False mlm_probability: Optional[float] = 0.15 mask_replace_prob: float = 0.8 random_replace_prob: float = 0.1 @@ -698,6 +699,11 @@ def __post_init__(self): if self.mlm_probability is None or self.mlm_probability < 0 or self.mlm_probability > 1: raise ValueError("mlm_probability should be between 0 and 1.") self.mlm_probability = float(self.mlm_probability) + elif self.whole_word_mask: + raise ValueError( + "Whole word masking can only be used with mlm=True." + "If you want to use whole word masking, please set mlm=True." + ) if self.mask_replace_prob + self.random_replace_prob > 1: raise ValueError("The sum of mask_replace_prob and random_replace_prob should not exceed 1") if self.mask_replace_prob < 0 or self.mask_replace_prob > 1: @@ -708,6 +714,21 @@ def __post_init__(self): self.mask_replace_prob = float(self.mask_replace_prob) self.random_replace_prob = float(self.random_replace_prob) + if self.whole_word_mask: + if not self.tokenizer.is_fast: + warnings.warn( + "Whole word masking depends on offset mapping which is only natively available with fast tokenizers.", + UserWarning, + ) + + if self.mask_replace_prob < 1: + warnings.warn( + "Random token replacement is not supported with whole word masking.", + "Setting mask_replace_prob to 1.", + ) + self.mask_replace_prob = 1 + self.random_replace_prob = 0 + self.generator = None def get_generator(self, seed): @@ -762,9 +783,10 @@ def torch_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> d # If special token mask has been preprocessed, pop it from the dict. special_tokens_mask = batch.pop("special_tokens_mask", None) + offset_mapping = batch.pop("offset_mapping", None) if self.mlm: batch["input_ids"], batch["labels"] = self.torch_mask_tokens( - batch["input_ids"], special_tokens_mask=special_tokens_mask + batch["input_ids"], special_tokens_mask=special_tokens_mask, offset_mapping=offset_mapping ) else: labels = batch["input_ids"].clone() @@ -773,9 +795,11 @@ def torch_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> d batch["labels"] = labels return batch - def torch_mask_tokens(self, inputs: Any, special_tokens_mask: Optional[Any] = None) -> tuple[Any, Any]: + def torch_mask_tokens( + self, inputs: Any, special_tokens_mask: Optional[Any] = None, offset_mapping: Optional[Any] = None + ) -> tuple[Any, Any]: """ - Prepare masked tokens inputs/labels for masked language modeling: 80% MASK, 10% random, 10% original. + Prepare masked tokens inputs/labels for masked language modeling. """ import torch @@ -786,12 +810,24 @@ def torch_mask_tokens(self, inputs: Any, special_tokens_mask: Optional[Any] = No special_tokens_mask = [ self.tokenizer.get_special_tokens_mask(val, already_has_special_tokens=True) for val in labels.tolist() ] - special_tokens_mask = torch.tensor(special_tokens_mask, dtype=torch.bool) + + if self.whole_word_mask: + word_ids, no_mask_mask = self._calc_word_ids_and_prob_mask( + to_numpy(offset_mapping), to_numpy(special_tokens_mask) + ) + no_mask_mask = torch.tensor(no_mask_mask, dtype=torch.bool) else: - special_tokens_mask = special_tokens_mask.bool() + no_mask_mask = ( + special_tokens_mask.bool() + if isinstance(special_tokens_mask, torch.Tensor) + else torch.tensor(special_tokens_mask, dtype=torch.bool) + ) - probability_matrix.masked_fill_(special_tokens_mask, value=0.0) + probability_matrix.masked_fill_(no_mask_mask, value=0.0) masked_indices = torch.bernoulli(probability_matrix, generator=self.generator).bool() + if self.whole_word_mask: + masked_indices = torch.BoolTensor(self._whole_word_mask(word_ids, masked_indices)) + labels[~masked_indices] = -100 # We only compute loss on masked tokens # mask_replace_prob% of the time, we replace masked input tokens with tokenizer.mask_token ([MASK]) @@ -841,9 +877,10 @@ def numpy_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> d # If special token mask has been preprocessed, pop it from the dict. special_tokens_mask = batch.pop("special_tokens_mask", None) + offset_mapping = batch.pop("offset_mapping", None) if self.mlm: batch["input_ids"], batch["labels"] = self.numpy_mask_tokens( - batch["input_ids"], special_tokens_mask=special_tokens_mask + batch["input_ids"], special_tokens_mask=special_tokens_mask, offset_mapping=offset_mapping ) else: labels = np.copy(batch["input_ids"]) @@ -852,9 +889,14 @@ def numpy_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> d batch["labels"] = labels return batch - def numpy_mask_tokens(self, inputs: Any, special_tokens_mask: Optional[Any] = None) -> tuple[Any, Any]: + def numpy_mask_tokens( + self, + inputs: Any, + special_tokens_mask: Optional[Any] = None, + offset_mapping: Optional[Any] = None, + ) -> tuple[Any, Any]: """ - Prepare masked tokens inputs/labels for masked language modeling: 80% MASK, 10% random, 10% original. + Prepare masked tokens inputs/labels for masked language modeling. """ labels = np.copy(inputs) # We sample a few tokens in each sequence for MLM training (with probability `self.mlm_probability`) @@ -863,16 +905,28 @@ def numpy_mask_tokens(self, inputs: Any, special_tokens_mask: Optional[Any] = No special_tokens_mask = [ self.tokenizer.get_special_tokens_mask(val, already_has_special_tokens=True) for val in labels.tolist() ] - special_tokens_mask = np.array(special_tokens_mask, dtype=bool) + + if self.whole_word_mask: + word_ids, no_mask_mask = self._calc_word_ids_and_prob_mask( + to_numpy(offset_mapping), to_numpy(special_tokens_mask) + ) else: - special_tokens_mask = special_tokens_mask.astype(bool) + no_mask_mask = ( + special_tokens_mask.astype(bool) + if isinstance(special_tokens_mask, np.ndarray) + else np.array(special_tokens_mask, dtype=bool) + ) - probability_matrix[special_tokens_mask] = 0 + probability_matrix[no_mask_mask] = 0 # Numpy doesn't have bernoulli, so we use a binomial with 1 trial if self.generator: masked_indices = self.generator.binomial(1, probability_matrix, size=probability_matrix.shape).astype(bool) else: masked_indices = np.random.binomial(1, probability_matrix, size=probability_matrix.shape).astype(bool) + + if self.whole_word_mask: + masked_indices = self._whole_word_mask(word_ids, masked_indices) + labels[~masked_indices] = -100 # We only compute loss on masked tokens # mask_replace_prob% of the time, we replace masked input tokens with tokenizer.mask_token ([MASK]) @@ -917,269 +971,73 @@ def numpy_mask_tokens(self, inputs: Any, special_tokens_mask: Optional[Any] = No # The rest of the time (10% of the time) we keep the masked input tokens unchanged return inputs, labels - -@dataclass -class DataCollatorForWholeWordMask(DataCollatorForLanguageModeling): - """ - Data collator used for language modeling that masks entire words. - - - collates batches of tensors, honoring their tokenizer's pad_token - - preprocesses batches for masked language modeling - - - - This collator relies on details of the implementation of subword tokenization by [`BertTokenizer`], specifically - that subword tokens are prefixed with *##*. For tokenizers that do not adhere to this scheme, this collator will - produce an output that is roughly equivalent to [`.DataCollatorForLanguageModeling`]. - - """ - - def torch_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> dict[str, Any]: - if self.seed and self.generator is None: - # If we have a seed, we need to create a generator object. Subsequent calls to this function will use the same generator. - # If no seed supplied, we will use the global RNG - self.create_rng() - - if isinstance(examples[0], Mapping): - input_ids = [e["input_ids"] for e in examples] - else: - input_ids = examples - examples = [{"input_ids": e} for e in examples] - - batch_input = _torch_collate_batch(input_ids, self.tokenizer, pad_to_multiple_of=self.pad_to_multiple_of) - - mask_labels = [] - for e in examples: - ref_tokens = [] - for id in tolist(e["input_ids"]): - token = self.tokenizer._convert_id_to_token(id) - ref_tokens.append(token) - - # For Chinese tokens, we need extra inf to mark sub-word, e.g [喜,欢]-> [喜,##欢] - if "chinese_ref" in e: - ref_pos = tolist(e["chinese_ref"]) - len_seq = len(e["input_ids"]) - for i in range(len_seq): - if i in ref_pos: - ref_tokens[i] = "##" + ref_tokens[i] - mask_labels.append(self._whole_word_mask(ref_tokens)) - batch_mask = _torch_collate_batch(mask_labels, self.tokenizer, pad_to_multiple_of=self.pad_to_multiple_of) - inputs, labels = self.torch_mask_tokens(batch_input, batch_mask) - return {"input_ids": inputs, "labels": labels} - - def numpy_call(self, examples: list[Union[list[int], Any, dict[str, Any]]]) -> dict[str, Any]: - if self.seed and self.generator is None: - # If we have a seed, we need to create a generator object. Subsequent calls to this function will use the same generator. - # If no seed supplied, we will use the global RNG - self.create_rng() - - if isinstance(examples[0], Mapping): - input_ids = [e["input_ids"] for e in examples] - else: - input_ids = examples - examples = [{"input_ids": e} for e in examples] - - batch_input = _numpy_collate_batch(input_ids, self.tokenizer, pad_to_multiple_of=self.pad_to_multiple_of) - - mask_labels = [] - for e in examples: - ref_tokens = [] - for id in tolist(e["input_ids"]): - token = self.tokenizer._convert_id_to_token(id) - ref_tokens.append(token) - - # For Chinese tokens, we need extra inf to mark sub-word, e.g [喜,欢]-> [喜,##欢] - if "chinese_ref" in e: - ref_pos = tolist(e["chinese_ref"]) - len_seq = len(e["input_ids"]) - for i in range(len_seq): - if i in ref_pos: - ref_tokens[i] = "##" + ref_tokens[i] - mask_labels.append(self._whole_word_mask(ref_tokens)) - batch_mask = _numpy_collate_batch(mask_labels, self.tokenizer, pad_to_multiple_of=self.pad_to_multiple_of) - inputs, labels = self.numpy_mask_tokens(batch_input, batch_mask) - return {"input_ids": inputs, "labels": labels} - - def _shuffle(self, cand_indexes): - # if no seed, just use random's shuffle - if self.seed is None: - random.shuffle(cand_indexes) - return cand_indexes - - # if seed is provided, use the generator to shuffle - if self.return_tensors == "pt": - import torch - - indices = torch.randperm(len(cand_indexes), generator=self.generator) - return [cand_indexes[i] for i in indices] - - elif self.return_tensors == "np": - self.generator.shuffle(cand_indexes) - return cand_indexes - - def _whole_word_mask(self, input_tokens: list[str], max_predictions=512): + @staticmethod + def _calc_word_ids_and_prob_mask( + offsets: np.ndarray[np.ndarray[tuple[int, int]]], special_tokens_mask: np.ndarray[np.ndarray[int]] + ) -> tuple[np.ndarray[np.ndarray[int]], np.ndarray[np.ndarray[int]]]: """ - Get 0/1 labels for masked tokens with whole word mask proxy + Map tokens to word ids and create mask of tokens to not mask. + Tokens that are part of the same word will have the same word id and we will only + set a mask probability for the first token of each word. """ - if not isinstance(self.tokenizer, (BertTokenizer, BertTokenizerFast)): - warnings.warn( - "DataCollatorForWholeWordMask is only suitable for BertTokenizer-like tokenizers. " - "Please refer to the documentation for more information." - ) - cand_indexes = [] - for i, token in enumerate(input_tokens): - if token == "[CLS]" or token == "[SEP]": - continue + token_starts = offsets[:, :, 0] + token_ends = offsets[:, :, 1] - if len(cand_indexes) >= 1 and token.startswith("##"): - cand_indexes[-1].append(i) - else: - cand_indexes.append([i]) - - cand_indexes = self._shuffle(cand_indexes) - num_to_predict = min(max_predictions, max(1, int(round(len(input_tokens) * self.mlm_probability)))) - masked_lms = [] - covered_indexes = set() - for index_set in cand_indexes: - if len(masked_lms) >= num_to_predict: - break - # If adding a whole-word mask would exceed the maximum number of - # predictions, then just skip this candidate. - if len(masked_lms) + len(index_set) > num_to_predict: - continue - for index in index_set: - covered_indexes.add(index) - masked_lms.append(index) - - if len(covered_indexes) != len(masked_lms): - raise ValueError("Length of covered_indexes is not equal to length of masked_lms.") - mask_labels = [1 if i in covered_indexes else 0 for i in range(len(input_tokens))] - return mask_labels - - def torch_mask_tokens(self, inputs: Any, mask_labels: Any) -> tuple[Any, Any]: - """ - Prepare masked tokens inputs/labels for masked language modeling: 80% MASK, 10% random, 10% original. Set - 'mask_labels' means we use whole word mask (wwm), we directly mask idxs according to it's ref. - """ - import torch + prev_token_ends = np.roll(token_ends, 1, axis=1) + prev_token_ends[:, 0] = -1 # First token has no previous token - if self.tokenizer.mask_token is None: - raise ValueError( - "This tokenizer does not have a mask token which is necessary for masked language modeling. Remove the" - " --mlm flag if you want to use this tokenizer." - ) - labels = inputs.clone() - # We sample a few tokens in each sequence for masked-LM training (with probability args.mlm_probability defaults to 0.15 in Bert/RoBERTa) - - probability_matrix = mask_labels - - special_tokens_mask = [ - self.tokenizer.get_special_tokens_mask(val, already_has_special_tokens=True) for val in labels.tolist() - ] - probability_matrix.masked_fill_(torch.tensor(special_tokens_mask, dtype=torch.bool), value=0.0) - if self.tokenizer.pad_token is not None: - padding_mask = labels.eq(self.tokenizer.pad_token_id) - probability_matrix.masked_fill_(padding_mask, value=0.0) - - masked_indices = probability_matrix.bool() - labels[~masked_indices] = -100 # We only compute loss on masked tokens - - # mask_replace_prob% of the time, we replace masked input tokens with tokenizer.mask_token ([MASK]) - indices_replaced = ( - torch.bernoulli(torch.full(labels.shape, self.mask_replace_prob), generator=self.generator).bool() - & masked_indices - ) - inputs[indices_replaced] = self.tokenizer.convert_tokens_to_ids(self.tokenizer.mask_token) + prev_token_special = np.roll(special_tokens_mask, 1, axis=1) + prev_token_special[:, 0] = 0 - if self.mask_replace_prob == 1 or self.random_replace_prob == 0: - return inputs, labels + # Not special token AND (gap from previous or previous token was special) + special_tokens_mask = special_tokens_mask.astype(bool) + is_new_word = (~special_tokens_mask) & ((token_starts != prev_token_ends) | (prev_token_special == 1)) - remaining_prob = 1 - self.mask_replace_prob - # scaling the random_replace_prob to the remaining probability for example if - # mask_replace_prob = 0.8 and random_replace_prob = 0.1, - # then random_replace_prob_scaled = 0.1 / 0.2 = 0.5 - random_replace_prob_scaled = self.random_replace_prob / remaining_prob + word_ids = np.cumsum(is_new_word, axis=1) + word_ids[special_tokens_mask] = -1 - # random_replacement_prob% of the time, we replace masked input tokens with random word - indices_random = ( - torch.bernoulli(torch.full(labels.shape, random_replace_prob_scaled), generator=self.generator).bool() - & masked_indices - & ~indices_replaced - ) - random_words = torch.randint(len(self.tokenizer), labels.shape, dtype=torch.long, generator=self.generator) - inputs[indices_random] = random_words[indices_random] + prob_mask = ~is_new_word - # The rest of the time ((1-random_replacement_prob-mask_replace_prob)% of the time) we keep the masked input tokens unchanged - return inputs, labels + return word_ids, prob_mask - def numpy_mask_tokens(self, inputs: Any, mask_labels: Any) -> tuple[Any, Any]: + @staticmethod + def _whole_word_mask(word_ids: np.ndarray[np.ndarray[int]], mask: Any) -> Any: """ - Prepare masked tokens inputs/labels for masked language modeling: 80% MASK, 10% random, 10% original. Set - 'mask_labels' means we use whole word mask (wwm), we directly mask idxs according to it's ref. + Mask whole words based on word ids and mask. """ - if self.tokenizer.mask_token is None: - raise ValueError( - "This tokenizer does not have a mask token which is necessary for masked language modeling. Remove the" - " --mlm flag if you want to use this tokenizer." - ) - labels = np.copy(inputs) - # We sample a few tokens in each sequence for masked-LM training (with probability args.mlm_probability defaults to 0.15 in Bert/RoBERTa) + mask = to_numpy(mask) - masked_indices = mask_labels.astype(bool) + valid_ids = word_ids != -1 - special_tokens_mask = [ - self.tokenizer.get_special_tokens_mask(val, already_has_special_tokens=True) for val in labels.tolist() - ] - masked_indices[np.array(special_tokens_mask, dtype=bool)] = 0 - if self.tokenizer.pad_token is not None: - padding_mask = labels == self.tokenizer.pad_token_id - masked_indices[padding_mask] = 0 - - labels[~masked_indices] = -100 # We only compute loss on masked tokens - - # mask_replacement_prob% of the time, we replace masked input tokens with tokenizer.mask_token ([MASK]) - if self.generator: - indices_replaced = ( - self.generator.binomial(1, self.mask_replace_prob, size=labels.shape).astype(bool) & masked_indices - ) - else: - indices_replaced = ( - np.random.binomial(1, self.mask_replace_prob, size=labels.shape).astype(bool) & masked_indices - ) - inputs[indices_replaced] = self.tokenizer.convert_tokens_to_ids(self.tokenizer.mask_token) + # Create 3D mask where [batch, token_i, token_j] is True if token_i and token_j are the same word + same_word = (word_ids[:, :, None] == word_ids[:, None, :]) & valid_ids[:, :, None] & valid_ids[:, None, :] - if self.mask_replace_prob == 1 or self.random_replace_prob == 0: - return inputs, labels + # For each token, set True if any token in the same word is masked + return np.any(same_word & mask[:, None, :], axis=2) - remaining_prob = 1 - self.mask_replace_prob - # scaling the random_replace_prob to the remaining probability for example if - # mask_replace_prob = 0.8 and random_replace_prob = 0.1, - # then random_replace_prob_scaled = 0.1 / 0.2 = 0.5 - random_replace_prob_scaled = self.random_replace_prob / remaining_prob - if self.generator: - indices_random = ( - self.generator.binomial(1, random_replace_prob_scaled, size=labels.shape).astype(bool) - & masked_indices - & ~indices_replaced - ) - random_words = self.generator.integers(low=0, high=len(self.tokenizer), size=labels.shape, dtype=np.int64) - else: - indices_random = ( - np.random.binomial(1, random_replace_prob_scaled, size=labels.shape).astype(bool) - & masked_indices - & ~indices_replaced - ) - random_words = np.random.randint(low=0, high=len(self.tokenizer), size=labels.shape, dtype=np.int64) +@dataclass +class DataCollatorForWholeWordMask(DataCollatorForLanguageModeling): + """ + Data collator used for language modeling that masks entire words. - inputs[indices_random] = random_words[indices_random] + - collates batches of tensors, honoring their tokenizer's pad_token + - preprocesses batches for masked language modeling + """ - # The rest of the time ((1-mask_replace_prob-random_replace_prob)% of the time) we keep the masked input tokens unchanged - return inputs, labels + def __init__(self, *args, **kwargs): + warnings.warn( + "DataCollatorForWholeWordMask is deprecated and will be removed in a future version, you can now use " + "DataCollatorForLanguageModeling with whole_word_mask=True instead.", + FutureWarning, + ) + super().__init__(*args, **kwargs) + self.mlm = True # Force masked language modeling + self.whole_word_mask = True # Force whole word masking -def tolist(x): +def tolist(x) -> list[Any]: if isinstance(x, list): return x elif hasattr(x, "numpy"): @@ -1187,6 +1045,15 @@ def tolist(x): return x.tolist() +def to_numpy(x) -> np.ndarray[Any]: + if isinstance(x, np.ndarray): + return x + elif hasattr(x, "detach"): + return x.detach().cpu().numpy() + else: + return np.array(x) + + @dataclass class DataCollatorForSOP(DataCollatorForLanguageModeling): """ diff --git a/tests/trainer/test_data_collator.py b/tests/trainer/test_data_collator.py index d25aa7ceba9a..b5cbb5ecea28 100644 --- a/tests/trainer/test_data_collator.py +++ b/tests/trainer/test_data_collator.py @@ -21,6 +21,7 @@ from transformers import ( BertTokenizer, + BertTokenizerFast, DataCollatorForLanguageModeling, DataCollatorForPermutationLanguageModeling, DataCollatorForSeq2Seq, @@ -525,99 +526,120 @@ def test_data_collator_for_language_modeling_with_seed(self): self.assertFalse(torch.all(batch_3_labels == batch_5_labels)) def test_data_collator_for_whole_word_mask(self): - tokenizer = BertTokenizer(self.vocab_file) + tokenizer = BertTokenizerFast(self.vocab_file) + + input_tokens = [f"token_{i}" for i in range(8)] + tokenizer.add_tokens(input_tokens) + features = [tokenizer(" ".join(input_tokens), return_offsets_mapping=True) for _ in range(2)] + data_collator = DataCollatorForWholeWordMask(tokenizer, return_tensors="pt") - features = [{"input_ids": list(range(10))}, {"input_ids": list(range(10))}] batch = data_collator(features) - self.assertEqual(batch["input_ids"].shape, torch.Size((2, 10))) - self.assertEqual(batch["labels"].shape, torch.Size((2, 10))) + self.assertEqual(batch["input_ids"].shape, (2, 10)) + self.assertEqual(batch["labels"].shape, (2, 10)) # Features can already be tensors - features = [{"input_ids": np.arange(10)}, {"input_ids": np.arange(10)}] + features = [ + tokenizer(" ".join(input_tokens), return_offsets_mapping=True).convert_to_tensors("np") for _ in range(2) + ] batch = data_collator(features) - self.assertEqual(batch["input_ids"].shape, torch.Size((2, 10))) - self.assertEqual(batch["labels"].shape, torch.Size((2, 10))) + self.assertEqual(batch["input_ids"].shape, (2, 10)) + self.assertEqual(batch["labels"].shape, (2, 10)) + + if is_torch_available(): + # Features can already be tensors + features = [ + tokenizer(" ".join(input_tokens), return_offsets_mapping=True).convert_to_tensors("pt") + for _ in range(2) + ] + data_collator = DataCollatorForWholeWordMask(tokenizer, return_tensors="pt") + batch = data_collator(features) + self.assertEqual(batch["input_ids"].shape, torch.Size((2, 10))) + self.assertEqual(batch["labels"].shape, torch.Size((2, 10))) def test_data_collator_for_whole_word_mask_with_seed(self): - tokenizer = BertTokenizer(self.vocab_file) - features = [{"input_ids": list(range(1000))}, {"input_ids": list(range(1000))}] + tokenizer = BertTokenizerFast(self.vocab_file) + + input_tokens = [f"token_{i}" for i in range(998)] + tokenizer.add_tokens(input_tokens) + features = [tokenizer(" ".join(input_tokens), return_offsets_mapping=True) for _ in range(2)] # check if seed is respected between two different DataCollatorForWholeWordMask instances - data_collator = DataCollatorForWholeWordMask(tokenizer, seed=42) + data_collator = DataCollatorForWholeWordMask(tokenizer, seed=42, return_tensors="np") batch_1 = data_collator(features) - self.assertEqual(batch_1["input_ids"].shape, torch.Size((2, 1000))) - self.assertEqual(batch_1["labels"].shape, torch.Size((2, 1000))) + self.assertEqual(batch_1["input_ids"].shape, (2, 1000)) + self.assertEqual(batch_1["labels"].shape, (2, 1000)) - data_collator = DataCollatorForWholeWordMask(tokenizer, seed=42) + data_collator = DataCollatorForWholeWordMask(tokenizer, seed=42, return_tensors="np") batch_2 = data_collator(features) - self.assertEqual(batch_2["input_ids"].shape, torch.Size((2, 1000))) - self.assertEqual(batch_2["labels"].shape, torch.Size((2, 1000))) + self.assertEqual(batch_2["input_ids"].shape, (2, 1000)) + self.assertEqual(batch_2["labels"].shape, (2, 1000)) - self.assertTrue(torch.all(batch_1["input_ids"] == batch_2["input_ids"])) - self.assertTrue(torch.all(batch_1["labels"] == batch_2["labels"])) + self.assertTrue(np.all(batch_1["input_ids"] == batch_2["input_ids"])) + self.assertTrue(np.all(batch_1["labels"] == batch_2["labels"])) # check if seed is respected in multiple workers situation - features = [{"input_ids": list(range(1000))} for _ in range(10)] - dataloader = torch.utils.data.DataLoader( - features, - batch_size=2, - num_workers=2, - generator=torch.Generator().manual_seed(42), - collate_fn=DataCollatorForWholeWordMask(tokenizer, seed=42), - ) - - batch_3_input_ids = [] - batch_3_labels = [] - for batch in dataloader: - batch_3_input_ids.append(batch["input_ids"]) - batch_3_labels.append(batch["labels"]) - - batch_3_input_ids = torch.stack(batch_3_input_ids) - batch_3_labels = torch.stack(batch_3_labels) - self.assertEqual(batch_3_input_ids.shape, torch.Size((5, 2, 1000))) - self.assertEqual(batch_3_labels.shape, torch.Size((5, 2, 1000))) - - dataloader = torch.utils.data.DataLoader( - features, - batch_size=2, - num_workers=2, - collate_fn=DataCollatorForWholeWordMask(tokenizer, seed=42), - ) - - batch_4_input_ids = [] - batch_4_labels = [] - for batch in dataloader: - batch_4_input_ids.append(batch["input_ids"]) - batch_4_labels.append(batch["labels"]) - batch_4_input_ids = torch.stack(batch_4_input_ids) - batch_4_labels = torch.stack(batch_4_labels) - self.assertEqual(batch_4_input_ids.shape, torch.Size((5, 2, 1000))) - self.assertEqual(batch_4_labels.shape, torch.Size((5, 2, 1000))) + if is_torch_available(): + features = [tokenizer(" ".join(input_tokens), return_offsets_mapping=True) for _ in range(10)] + dataloader = torch.utils.data.DataLoader( + features, + batch_size=2, + num_workers=2, + generator=torch.Generator().manual_seed(42), + collate_fn=DataCollatorForWholeWordMask(tokenizer, seed=42), + ) - self.assertTrue(torch.all(batch_3_input_ids == batch_4_input_ids)) - self.assertTrue(torch.all(batch_3_labels == batch_4_labels)) + batch_3_input_ids = [] + batch_3_labels = [] + for batch in dataloader: + batch_3_input_ids.append(batch["input_ids"]) + batch_3_labels.append(batch["labels"]) + + batch_3_input_ids = torch.stack(batch_3_input_ids) + batch_3_labels = torch.stack(batch_3_labels) + self.assertEqual(batch_3_input_ids.shape, torch.Size((5, 2, 1000))) + self.assertEqual(batch_3_labels.shape, torch.Size((5, 2, 1000))) + + dataloader = torch.utils.data.DataLoader( + features, + batch_size=2, + num_workers=2, + collate_fn=DataCollatorForWholeWordMask(tokenizer, seed=42), + ) - # try with different seed - dataloader = torch.utils.data.DataLoader( - features, - batch_size=2, - num_workers=2, - collate_fn=DataCollatorForWholeWordMask(tokenizer, seed=43), - ) + batch_4_input_ids = [] + batch_4_labels = [] + for batch in dataloader: + batch_4_input_ids.append(batch["input_ids"]) + batch_4_labels.append(batch["labels"]) + batch_4_input_ids = torch.stack(batch_4_input_ids) + batch_4_labels = torch.stack(batch_4_labels) + self.assertEqual(batch_4_input_ids.shape, torch.Size((5, 2, 1000))) + self.assertEqual(batch_4_labels.shape, torch.Size((5, 2, 1000))) + + self.assertTrue(torch.all(batch_3_input_ids == batch_4_input_ids)) + self.assertTrue(torch.all(batch_3_labels == batch_4_labels)) + + # try with different seed + dataloader = torch.utils.data.DataLoader( + features, + batch_size=2, + num_workers=2, + collate_fn=DataCollatorForWholeWordMask(tokenizer, seed=43), + ) - batch_5_input_ids = [] - batch_5_labels = [] - for batch in dataloader: - batch_5_input_ids.append(batch["input_ids"]) - batch_5_labels.append(batch["labels"]) - batch_5_input_ids = torch.stack(batch_5_input_ids) - batch_5_labels = torch.stack(batch_5_labels) - self.assertEqual(batch_5_input_ids.shape, torch.Size((5, 2, 1000))) - self.assertEqual(batch_5_labels.shape, torch.Size((5, 2, 1000))) + batch_5_input_ids = [] + batch_5_labels = [] + for batch in dataloader: + batch_5_input_ids.append(batch["input_ids"]) + batch_5_labels.append(batch["labels"]) + batch_5_input_ids = torch.stack(batch_5_input_ids) + batch_5_labels = torch.stack(batch_5_labels) + self.assertEqual(batch_5_input_ids.shape, torch.Size((5, 2, 1000))) + self.assertEqual(batch_5_labels.shape, torch.Size((5, 2, 1000))) - self.assertFalse(torch.all(batch_3_input_ids == batch_5_input_ids)) - self.assertFalse(torch.all(batch_3_labels == batch_5_labels)) + self.assertFalse(torch.all(batch_3_input_ids == batch_5_input_ids)) + self.assertFalse(torch.all(batch_3_labels == batch_5_labels)) def test_plm(self): tokenizer = BertTokenizer(self.vocab_file) @@ -929,24 +951,23 @@ def test_language_modelling_collator_immutability(self): ) def test_whole_world_masking_collator_immutability(self): - tokenizer = BertTokenizer(self.vocab_file) + tokenizer = BertTokenizerFast(self.vocab_file) - features_base = [ - {"input_ids": list(range(10)), "labels": (1,)}, - {"input_ids": list(range(10)), "labels": (1,)}, - ] - whole_word_masking_collator = DataCollatorForWholeWordMask(tokenizer, return_tensors="pt") + input_tokens = [f"token_{i}" for i in range(8)] + tokenizer.add_tokens(input_tokens) + original_data = [tokenizer(" ".join(input_tokens), return_offsets_mapping=True) for _ in range(2)] + for feature in original_data: + feature["labels"] = (1,) - for datatype_input, datatype_label in [(list, list), (np.array, np.array)]: - self._validate_original_data_against_collated_data_on_specified_keys_and_datatypes( - collator=whole_word_masking_collator, - base_data=features_base, - input_key="input_ids", - input_datatype=datatype_input, - label_key="labels", - label_datatype=datatype_label, - ignore_label=True, - ) + batch_data = [tokenizer(" ".join(input_tokens), return_offsets_mapping=True) for _ in range(2)] + for feature in batch_data: + feature["labels"] = (1,) + + whole_word_masking_collator = DataCollatorForWholeWordMask(tokenizer) + + self._validate_original_data_against_collated_data( + collator=whole_word_masking_collator, original_data=original_data, batch_data=batch_data + ) def test_permutation_language_modelling_collator_immutability(self): tokenizer = BertTokenizer(self.vocab_file) @@ -1400,23 +1421,31 @@ def test_data_collator_for_language_modeling_with_seed(self): self.assertFalse(np.all(batch_1["labels"] == batch_3["labels"])) def test_data_collator_for_whole_word_mask(self): - tokenizer = BertTokenizer(self.vocab_file) + tokenizer = BertTokenizerFast(self.vocab_file) data_collator = DataCollatorForWholeWordMask(tokenizer, return_tensors="np") - features = [{"input_ids": list(range(10))}, {"input_ids": list(range(10))}] + input_tokens = [f"token_{i}" for i in range(8)] + tokenizer.add_tokens(input_tokens) + features = [tokenizer(" ".join(input_tokens), return_offsets_mapping=True) for _ in range(2)] + batch = data_collator(features) self.assertEqual(batch["input_ids"].shape, (2, 10)) self.assertEqual(batch["labels"].shape, (2, 10)) # Features can already be tensors - features = [{"input_ids": np.arange(10)}, {"input_ids": np.arange(10)}] + features = [ + tokenizer(" ".join(input_tokens), return_offsets_mapping=True).convert_to_tensors("np") for _ in range(2) + ] batch = data_collator(features) self.assertEqual(batch["input_ids"].shape, (2, 10)) self.assertEqual(batch["labels"].shape, (2, 10)) def test_data_collator_for_whole_word_mask_with_seed(self): - tokenizer = BertTokenizer(self.vocab_file) - features = [{"input_ids": list(range(1000))}, {"input_ids": list(range(1000))}] + tokenizer = BertTokenizerFast(self.vocab_file) + + input_tokens = [f"token_{i}" for i in range(998)] + tokenizer.add_tokens(input_tokens) + features = [tokenizer(" ".join(input_tokens), return_offsets_mapping=True) for _ in range(2)] # check if seed is respected between two different DataCollatorForWholeWordMask instances data_collator = DataCollatorForWholeWordMask(tokenizer, seed=42, return_tensors="np") @@ -1755,24 +1784,23 @@ def test_language_modelling_collator_immutability(self): ) def test_whole_world_masking_collator_immutability(self): - tokenizer = BertTokenizer(self.vocab_file) + tokenizer = BertTokenizerFast(self.vocab_file) + + input_tokens = [f"token_{i}" for i in range(8)] + tokenizer.add_tokens(input_tokens) + original_data = [tokenizer(" ".join(input_tokens), return_offsets_mapping=True) for _ in range(2)] + for feature in original_data: + feature["labels"] = (1,) + + batch_data = [tokenizer(" ".join(input_tokens), return_offsets_mapping=True) for _ in range(2)] + for feature in batch_data: + feature["labels"] = (1,) - features_base = [ - {"input_ids": list(range(10)), "labels": (1,)}, - {"input_ids": list(range(10)), "labels": (1,)}, - ] whole_word_masking_collator = DataCollatorForWholeWordMask(tokenizer, return_tensors="np") - for datatype_input, datatype_label in [(list, list), (np.array, np.array)]: - self._validate_original_data_against_collated_data_on_specified_keys_and_datatypes( - collator=whole_word_masking_collator, - base_data=features_base, - input_key="input_ids", - input_datatype=datatype_input, - label_key="labels", - label_datatype=datatype_label, - ignore_label=True, - ) + self._validate_original_data_against_collated_data( + collator=whole_word_masking_collator, original_data=original_data, batch_data=batch_data + ) def test_permutation_language_modelling_collator_immutability(self): tokenizer = BertTokenizer(self.vocab_file) @@ -1842,3 +1870,98 @@ def test_sentence_order_prediction_collator_immutability(self): self._validate_original_data_against_collated_data( collator=sop_collator, original_data=features_original, batch_data=features_batch ) + + +class DataCollatorForLanguageModelingUnitTest(unittest.TestCase): + def test__calc_word_ids_and_prob_mask(self): + offsets = np.array( + [ + [(0, 0), (0, 3), (3, 4), (5, 6), (6, 7), (8, 9)], + [(0, 0), (0, 3), (3, 4), (5, 6), (6, 7), (0, 0)], + [(0, 0), (0, 3), (3, 4), (0, 0), (6, 7), (0, 0)], + [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)], + [(1, 1), (2, 2), (3, 4), (5, 6), (7, 8), (9, 10)], + [(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)], + ] + ) + + special_tokens_mask = np.array( + [ + [1, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 1], + [1, 0, 0, 1, 0, 1], + [0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0], + [1, 1, 1, 1, 1, 1], + ] + ) + + output_word_ids, output_prob_mask = DataCollatorForLanguageModeling._calc_word_ids_and_prob_mask( + offsets, special_tokens_mask + ) + + expected_word_ids = np.array( + [ + [-1, 1, 1, 2, 2, 3], + [-1, 1, 1, 2, 2, -1], + [-1, 1, 1, -1, 2, -1], + [1, 1, 1, 1, 1, 1], + [1, 2, 3, 4, 5, 6], + [-1, -1, -1, -1, -1, -1], + ] + ) + + expected_prob_mask = np.array( + [ + [1, 0, 1, 0, 1, 0], + [1, 0, 1, 0, 1, 1], + [1, 0, 1, 1, 0, 1], + [0, 1, 1, 1, 1, 1], + [0, 0, 0, 0, 0, 0], + [1, 1, 1, 1, 1, 1], + ] + ) + + np.testing.assert_array_equal(output_word_ids, expected_word_ids) + np.testing.assert_array_equal(output_prob_mask, expected_prob_mask) + + def test__whole_word_mask(self): + word_ids = np.array( + [ + [-1, 1, 1, 2, 2, 3], + [-1, 1, 1, 2, 2, -1], + [-1, 1, 1, -1, 2, -1], + [1, 1, 1, 1, 1, 1], + [1, 2, 3, 4, 5, 6], + [1, 2, 3, 4, 5, 6], + [-1, -1, -1, -1, -1, -1], + ] + ) + + mask = np.array( + [ + [0, 1, 0, 0, 0, 0], + [0, 1, 0, 1, 0, 0], + [0, 0, 0, 0, 1, 0], + [1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0], + [0, 1, 0, 1, 0, 1], + [0, 0, 0, 0, 0, 0], + ] + ).astype(bool) + + output_mask = DataCollatorForLanguageModeling._whole_word_mask(word_ids, mask) + + expected_mask = np.array( + [ + [0, 1, 1, 0, 0, 0], + [0, 1, 1, 1, 1, 0], + [0, 0, 0, 0, 1, 0], + [1, 1, 1, 1, 1, 1], + [0, 0, 0, 0, 0, 0], + [0, 1, 0, 1, 0, 1], + [0, 0, 0, 0, 0, 0], + ] + ).astype(bool) + + np.testing.assert_array_equal(output_mask, expected_mask) From 54810d72624c112d7645c439ab56196f0d335cdf Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Mon, 22 Sep 2025 14:54:30 +0200 Subject: [PATCH 148/204] [testing] Fix `seed_oss` (#41052) * fix * fix * fix * fix * fix * fix * Update tests/models/seed_oss/test_modeling_seed_oss.py Co-authored-by: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> * fix --------- Co-authored-by: ydshieh Co-authored-by: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> --- .../models/seed_oss/test_modeling_seed_oss.py | 65 ++++++------------- 1 file changed, 19 insertions(+), 46 deletions(-) diff --git a/tests/models/seed_oss/test_modeling_seed_oss.py b/tests/models/seed_oss/test_modeling_seed_oss.py index f015edf1c2ba..e9cccfe9ff20 100644 --- a/tests/models/seed_oss/test_modeling_seed_oss.py +++ b/tests/models/seed_oss/test_modeling_seed_oss.py @@ -90,54 +90,27 @@ class SeedOssIntegrationTest(unittest.TestCase): input_text = ["How to make pasta?", "Hi ByteDance-Seed"] model_id = "ByteDance-Seed/Seed-OSS-36B-Base" - def tearDown(self): + def setUp(self): cleanup(torch_device, gc_collect=True) - def test_model_36b_fp16(self): - EXPECTED_TEXTS = [ - "How to make pasta?\nHow to make pasta?\nPasta is a popular dish that is enjoyed by people all over", - "Hi ByteDance-Seed team,\nI am trying to run the code on my local machine. I have installed all the", - ] - - model = AutoModelForCausalLM.from_pretrained(self.model_id, torch_dtype=torch.float16, device_map="auto") - - tokenizer = AutoTokenizer.from_pretrained(self.model_id) - inputs = tokenizer(self.input_text, return_tensors="pt", padding=True, return_token_type_ids=False).to( - model.model.embed_tokens.weight.device - ) - - output = model.generate(**inputs, max_new_tokens=20, do_sample=False) - output_text = tokenizer.batch_decode(output, skip_special_tokens=True) - - self.assertEqual(output_text, EXPECTED_TEXTS) + def tearDown(self): + cleanup(torch_device, gc_collect=True) - def test_model_36b_bf16(self): + def test_model_36b_eager(self): EXPECTED_TEXTS = [ "How to make pasta?\nHow to make pasta?\nPasta is a popular dish that is enjoyed by people all over", - "Hi ByteDance-Seed team,\nI am trying to run the code on my local machine. I have installed all the", + "Hi ByteDance-Seed team,\nI am trying to run the code on the seed", ] - model = AutoModelForCausalLM.from_pretrained(self.model_id, torch_dtype=torch.bfloat16, device_map="auto") - - tokenizer = AutoTokenizer.from_pretrained(self.model_id) - inputs = tokenizer(self.input_text, return_tensors="pt", padding=True).to( - model.model.embed_tokens.weight.device - ) - - output = model.generate(**inputs, max_new_tokens=20, do_sample=False) - output_text = tokenizer.batch_decode(output, skip_special_tokens=True) - - self.assertEqual(output_text, EXPECTED_TEXTS) - - def test_model_36b_eager(self): - EXPECTED_TEXTS = "" - model = AutoModelForCausalLM.from_pretrained( - self.model_id, torch_dtype=torch.bfloat16, attn_implementation="eager", device_map="auto" + "ByteDance-Seed/Seed-OSS-36B-Base", + torch_dtype=torch.bfloat16, + attn_implementation="eager", + device_map="auto", ) tokenizer = AutoTokenizer.from_pretrained(self.model_id) - inputs = tokenizer(self.input_text, return_tensors="pt", padding=True).to( + inputs = tokenizer(self.input_text, return_tensors="pt", padding=True, return_token_type_ids=False).to( model.model.embed_tokens.weight.device ) @@ -149,15 +122,14 @@ def test_model_36b_eager(self): def test_model_36b_sdpa(self): EXPECTED_TEXTS = [ "How to make pasta?\nHow to make pasta?\nPasta is a popular dish that is enjoyed by people all over", - "Hi ByteDance-Seed team,\nI am trying to run the code on my local machine. I have installed all the", + "Hi ByteDance-Seed team,\nI am trying to run the code on the seed", ] - model = AutoModelForCausalLM.from_pretrained( - self.model_id, torch_dtype=torch.bfloat16, attn_implementation="sdpa", device_map="auto" - ) + # default attention is `sdpa` (and this model repo. doesn't specify explicitly) --> we get `sdpa` here + model = AutoModelForCausalLM.from_pretrained(self.model_id, torch_dtype=torch.bfloat16, device_map="auto") tokenizer = AutoTokenizer.from_pretrained(self.model_id) - inputs = tokenizer(self.input_text, return_tensors="pt", padding=True).to( + inputs = tokenizer(self.input_text, return_tensors="pt", padding=True, return_token_type_ids=False).to( model.model.embed_tokens.weight.device ) @@ -170,15 +142,16 @@ def test_model_36b_sdpa(self): @require_torch_large_gpu @pytest.mark.flash_attn_test def test_model_36b_flash_attn(self): - EXPECTED_TEXTS = "" + EXPECTED_TEXTS = [ + "How to make pasta?\nHow to make pasta?\nPasta is a popular dish that is enjoyed by people all over", + "Hi ByteDance-Seed team,\nI am trying to run the code on the seed", + ] model = AutoModelForCausalLM.from_pretrained( self.model_id, torch_dtype=torch.bfloat16, attn_implementation="flash_attention_2", device_map="auto" ) - model.to(torch_device) - tokenizer = AutoTokenizer.from_pretrained(self.model_id) - inputs = tokenizer(self.input_text, return_tensors="pt", padding=True).to( + inputs = tokenizer(self.input_text, return_tensors="pt", padding=True, return_token_type_ids=False).to( model.model.embed_tokens.weight.device ) From 973b3fce1155d863e546e00e8718ec81ad3e4e5f Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 22 Sep 2025 20:57:13 +0800 Subject: [PATCH 149/204] Remove repeated import (#40937) * Remove repeated import Signed-off-by: Yuanyuan Chen * Fix conflict Signed-off-by: Yuanyuan Chen --------- Signed-off-by: Yuanyuan Chen --- src/transformers/data/data_collator.py | 2 -- src/transformers/integrations/integration_utils.py | 2 -- src/transformers/integrations/tensor_parallel.py | 2 -- src/transformers/modeling_utils.py | 2 -- src/transformers/testing_utils.py | 3 +-- src/transformers/utils/hub.py | 1 - src/transformers/utils/metrics.py | 2 -- 7 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/transformers/data/data_collator.py b/src/transformers/data/data_collator.py index d9b198b51087..368135e15f15 100644 --- a/src/transformers/data/data_collator.py +++ b/src/transformers/data/data_collator.py @@ -737,8 +737,6 @@ def get_generator(self, seed): return torch.Generator().manual_seed(seed) else: - import numpy as np - return np.random.default_rng(seed) def create_rng(self): diff --git a/src/transformers/integrations/integration_utils.py b/src/transformers/integrations/integration_utils.py index 6cec1183c5c7..267b1be82fd1 100755 --- a/src/transformers/integrations/integration_utils.py +++ b/src/transformers/integrations/integration_utils.py @@ -544,8 +544,6 @@ def run_hp_search_sigopt(trainer, n_trials: int, direction: str, **kwargs) -> Be def run_hp_search_wandb(trainer, n_trials: int, direction: str, **kwargs) -> BestRun: - from ..integrations import is_wandb_available - if not is_wandb_available(): raise ImportError("This function needs wandb installed: `pip install wandb`") import wandb diff --git a/src/transformers/integrations/tensor_parallel.py b/src/transformers/integrations/tensor_parallel.py index 3f9d40f13388..5855acd09a7e 100644 --- a/src/transformers/integrations/tensor_parallel.py +++ b/src/transformers/integrations/tensor_parallel.py @@ -1103,8 +1103,6 @@ def distribute_model(model, distributed_config, device_mesh, tp_size): raise ValueError(f"Unsupported tensor parallel style {v}. Supported styles are {ALL_PARALLEL_STYLES}") for name, module in model.named_modules(): if not getattr(module, "_is_hooked", False): - from transformers.integrations.tensor_parallel import add_tensor_parallel_hooks_to_module - plan = _get_parameter_tp_plan(parameter_name=name, tp_plan=model_plan, is_weight=False) add_tensor_parallel_hooks_to_module( model=model, diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index a132a763ca05..1096a990b8e3 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -2242,8 +2242,6 @@ def tp_plan(self, plan: dict[str, str]): flexible_matched = True break if not flexible_matched: - import warnings - warnings.warn( f"Layer pattern '{layer_pattern}' does not match any parameters in the model. " f"This rule may not be applied during tensor parallelization." diff --git a/src/transformers/testing_utils.py b/src/transformers/testing_utils.py index 32732560bb37..21209042192a 100644 --- a/src/transformers/testing_utils.py +++ b/src/transformers/testing_utils.py @@ -15,6 +15,7 @@ import ast import collections import contextlib +import copy import doctest import functools import gc @@ -2752,8 +2753,6 @@ def wrapper(*args, **kwargs): else: test = " ".join(os.environ.get("PYTEST_CURRENT_TEST").split(" ")[:-1]) try: - import copy - env = copy.deepcopy(os.environ) env["_INSIDE_SUB_PROCESS"] = "1" # This prevents the entries in `short test summary info` given by the subprocess being truncated. so the diff --git a/src/transformers/utils/hub.py b/src/transformers/utils/hub.py index f873175a5d49..d056fc0e8778 100644 --- a/src/transformers/utils/hub.py +++ b/src/transformers/utils/hub.py @@ -1084,7 +1084,6 @@ def get_checkpoint_shard_files( For the description of each arg, see [`PreTrainedModel.from_pretrained`]. `index_filename` is the full path to the index (downloaded and cached if `pretrained_model_name_or_path` is a model ID on the Hub). """ - import json use_auth_token = deprecated_kwargs.pop("use_auth_token", None) if use_auth_token is not None: diff --git a/src/transformers/utils/metrics.py b/src/transformers/utils/metrics.py index 33623b385ce3..3703ddaca1fb 100644 --- a/src/transformers/utils/metrics.py +++ b/src/transformers/utils/metrics.py @@ -105,8 +105,6 @@ def decorator(func): if not _has_opentelemetry: return func - import functools - @functools.wraps(func) def wrapper(*args, **kwargs): instance = args[0] if args and (hasattr(func, "__self__") and func.__self__ is not None) else None From c036a71a8ab4d43184c56e986518e265b6369455 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 22 Sep 2025 20:57:50 +0800 Subject: [PATCH 150/204] Simplify unnecessary Optional typing (#40839) Remove Optional Signed-off-by: Yuanyuan Chen --- src/transformers/audio_utils.py | 8 +++--- src/transformers/commands/serving.py | 4 +-- src/transformers/data/datasets/squad.py | 4 +-- src/transformers/generation/beam_search.py | 28 ++++++++++--------- .../generation/configuration_utils.py | 10 +++---- .../image_processing_utils_fast.py | 2 +- src/transformers/integrations/peft.py | 2 +- src/transformers/model_debugging_utils.py | 8 +++--- src/transformers/modeling_utils.py | 4 +-- .../pipelines/token_classification.py | 2 +- src/transformers/tokenization_utils.py | 4 +-- src/transformers/utils/chat_template_utils.py | 6 ++-- src/transformers/utils/quantization_config.py | 6 ++-- 13 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/transformers/audio_utils.py b/src/transformers/audio_utils.py index e848f558738c..e62880e7062c 100644 --- a/src/transformers/audio_utils.py +++ b/src/transformers/audio_utils.py @@ -370,7 +370,7 @@ def chroma_filter_bank( tuning: float = 0.0, power: Optional[float] = 2.0, weighting_parameters: Optional[tuple[float, float]] = (5.0, 2.0), - start_at_c_chroma: Optional[bool] = True, + start_at_c_chroma: bool = True, ): """ Creates a chroma filter bank, i.e a linear transformation to project spectrogram bins onto chroma bins. @@ -391,7 +391,7 @@ def chroma_filter_bank( weighting_parameters (`tuple[float, float]`, *optional*, defaults to `(5., 2.)`): If specified, apply a Gaussian weighting parameterized by the first element of the tuple being the center and the second element being the Gaussian half-width. - start_at_c_chroma (`float`, *optional*, defaults to `True`): + start_at_c_chroma (`bool`, *optional*, defaults to `True`): If True, the filter bank will start at the 'C' pitch class. Otherwise, it will start at 'A'. Returns: `np.ndarray` of shape `(num_frequency_bins, num_chroma)` @@ -627,7 +627,7 @@ def spectrogram( reference: float = 1.0, min_value: float = 1e-10, db_range: Optional[float] = None, - remove_dc_offset: Optional[bool] = None, + remove_dc_offset: bool = False, dtype: np.dtype = np.float32, ) -> np.ndarray: """ @@ -838,7 +838,7 @@ def spectrogram_batch( reference: float = 1.0, min_value: float = 1e-10, db_range: Optional[float] = None, - remove_dc_offset: Optional[bool] = None, + remove_dc_offset: bool = False, dtype: np.dtype = np.float32, ) -> list[np.ndarray]: """ diff --git a/src/transformers/commands/serving.py b/src/transformers/commands/serving.py index 33a48aed7e64..f414ebe11e60 100644 --- a/src/transformers/commands/serving.py +++ b/src/transformers/commands/serving.py @@ -141,7 +141,7 @@ class TransformersTranscriptionCreateParams(TranscriptionCreateParamsBase, total file: bytes # Overwritten -- pydantic isn't happy with `typing.IO[bytes]`, present in the original type generation_config: str - stream: Optional[bool] = False + stream: bool = False # Contrarily to OpenAI's output types, input types are `TypedDict`, which don't have built-in validation. response_validator = TypeAdapter(TransformersResponseCreateParamsStreaming) @@ -600,7 +600,7 @@ def validate_transcription_request(self, request: dict): def build_chat_completion_chunk( self, - request_id: Optional[str] = "", + request_id: str = "", content: Optional[int] = None, model: Optional[str] = None, role: Optional[str] = None, diff --git a/src/transformers/data/datasets/squad.py b/src/transformers/data/datasets/squad.py index d96d8224d6b9..b8197b02eb60 100644 --- a/src/transformers/data/datasets/squad.py +++ b/src/transformers/data/datasets/squad.py @@ -118,9 +118,9 @@ def __init__( tokenizer: PreTrainedTokenizer, limit_length: Optional[int] = None, mode: Union[str, Split] = Split.train, - is_language_sensitive: Optional[bool] = False, + is_language_sensitive: bool = False, cache_dir: Optional[str] = None, - dataset_format: Optional[str] = "pt", + dataset_format: str = "pt", ): self.args = args self.is_language_sensitive = is_language_sensitive diff --git a/src/transformers/generation/beam_search.py b/src/transformers/generation/beam_search.py index ba2820cb437a..1a91532983f2 100644 --- a/src/transformers/generation/beam_search.py +++ b/src/transformers/generation/beam_search.py @@ -165,10 +165,10 @@ def __init__( batch_size: int, num_beams: int, device: torch.device, - length_penalty: Optional[float] = 1.0, - do_early_stopping: Optional[Union[bool, str]] = False, - num_beam_hyps_to_keep: Optional[int] = 1, - num_beam_groups: Optional[int] = 1, + length_penalty: float = 1.0, + do_early_stopping: Union[bool, str] = False, + num_beam_hyps_to_keep: int = 1, + num_beam_groups: int = 1, max_length: Optional[int] = None, ): logger.warning_once( @@ -214,7 +214,7 @@ def __init__( @property def is_done(self) -> bool: - return self._done.all() + return self._done.all().item() def process( self, @@ -225,8 +225,8 @@ def process( pad_token_id: Optional[Union[int, torch.Tensor]] = None, eos_token_id: Optional[Union[int, list[int], torch.Tensor]] = None, beam_indices: Optional[torch.LongTensor] = None, - group_index: Optional[int] = 0, - decoder_prompt_len: Optional[int] = 0, + group_index: int = 0, + decoder_prompt_len: int = 0, ) -> dict[str, torch.Tensor]: # add up to the length which the next_scores is calculated on (including decoder prompt) cur_len = input_ids.shape[-1] + 1 @@ -460,9 +460,9 @@ def __init__( num_beams: int, constraints: list[Constraint], device: torch.device, - length_penalty: Optional[float] = 1.0, - do_early_stopping: Optional[Union[bool, str]] = False, - num_beam_hyps_to_keep: Optional[int] = 1, + length_penalty: float = 1.0, + do_early_stopping: Union[bool, str] = False, + num_beam_hyps_to_keep: int = 1, max_length: Optional[int] = None, ): logger.warning_once( @@ -495,7 +495,7 @@ def __init__( @property def is_done(self) -> bool: - return self._done.all() + return self._done.all().item() def make_constraint_states(self, n): return [ConstraintListState([constraint.copy() for constraint in self.constraints]) for _ in range(n)] @@ -515,7 +515,7 @@ def process( pad_token_id: Optional[Union[int, torch.Tensor]] = None, eos_token_id: Optional[Union[int, list[int], torch.Tensor]] = None, beam_indices: Optional[torch.LongTensor] = None, - decoder_prompt_len: Optional[int] = 0, + decoder_prompt_len: int = 0, ) -> tuple[torch.Tensor]: r""" Args: @@ -912,7 +912,9 @@ def finalize( class BeamHypotheses: - def __init__(self, num_beams: int, length_penalty: float, early_stopping: bool, max_length: Optional[int] = None): + def __init__( + self, num_beams: int, length_penalty: float, early_stopping: Union[bool, str], max_length: Optional[int] = None + ): """ Initialize n-best list of hypotheses. """ diff --git a/src/transformers/generation/configuration_utils.py b/src/transformers/generation/configuration_utils.py index 30b1c328ce49..70e3ed203b45 100644 --- a/src/transformers/generation/configuration_utils.py +++ b/src/transformers/generation/configuration_utils.py @@ -1291,11 +1291,11 @@ class WatermarkingConfig(BaseWatermarkingConfig): def __init__( self, - greenlist_ratio: Optional[float] = 0.25, - bias: Optional[float] = 2.0, - hashing_key: Optional[int] = 15485863, - seeding_scheme: Optional[str] = "lefthash", - context_width: Optional[int] = 1, + greenlist_ratio: float = 0.25, + bias: float = 2.0, + hashing_key: int = 15485863, + seeding_scheme: str = "lefthash", + context_width: int = 1, ): self.greenlist_ratio = greenlist_ratio self.bias = bias diff --git a/src/transformers/image_processing_utils_fast.py b/src/transformers/image_processing_utils_fast.py index ef872b6c172c..47447b6c9367 100644 --- a/src/transformers/image_processing_utils_fast.py +++ b/src/transformers/image_processing_utils_fast.py @@ -85,7 +85,7 @@ def validate_fast_preprocess_arguments( size: Optional[SizeDict] = None, interpolation: Optional["F.InterpolationMode"] = None, return_tensors: Optional[Union[str, TensorType]] = None, - data_format: Optional[ChannelDimension] = ChannelDimension.FIRST, + data_format: ChannelDimension = ChannelDimension.FIRST, ): """ Checks validity of typically used arguments in an `ImageProcessorFast` `preprocess` method. diff --git a/src/transformers/integrations/peft.py b/src/transformers/integrations/peft.py index 87dd6cffc2fa..4fba01df425a 100644 --- a/src/transformers/integrations/peft.py +++ b/src/transformers/integrations/peft.py @@ -96,7 +96,7 @@ def load_adapter( adapter_name: Optional[str] = None, revision: Optional[str] = None, token: Optional[str] = None, - device_map: Optional[str] = "auto", + device_map: str = "auto", max_memory: Optional[str] = None, offload_folder: Optional[str] = None, offload_index: Optional[int] = None, diff --git a/src/transformers/model_debugging_utils.py b/src/transformers/model_debugging_utils.py index 9f763c83c66d..0bffc4382b1e 100644 --- a/src/transformers/model_debugging_utils.py +++ b/src/transformers/model_debugging_utils.py @@ -269,8 +269,8 @@ def clean(val): def _attach_debugger_logic( model, - debug_path: Optional[str] = ".", - do_prune_layers: Optional[bool] = True, + debug_path: str = ".", + do_prune_layers: bool = True, use_repr: bool = True, ): """ @@ -399,8 +399,8 @@ def top_wrapped_forward(*inps, **kws): def model_addition_debugger_context( model, debug_path: Optional[str] = None, - do_prune_layers: Optional[bool] = True, - use_repr: Optional[bool] = True, + do_prune_layers: bool = True, + use_repr: bool = True, ): """ # Model addition debugger - context manager for model adders diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index 1096a990b8e3..0f349278e15c 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -3466,7 +3466,7 @@ def _get_resized_lm_head( self, old_lm_head: nn.Linear, new_num_tokens: Optional[int] = None, - transposed: Optional[bool] = False, + transposed: bool = False, mean_resizing: bool = True, ) -> nn.Linear: """ @@ -3623,7 +3623,7 @@ def _init_added_lm_head_weights_with_mean( old_lm_head_dim, old_num_tokens, added_num_tokens, - transposed=False, + transposed: bool = False, ): if transposed: # Transpose to the desired shape for the function. diff --git a/src/transformers/pipelines/token_classification.py b/src/transformers/pipelines/token_classification.py index 0df615edcfd3..fdcf0a2f627f 100644 --- a/src/transformers/pipelines/token_classification.py +++ b/src/transformers/pipelines/token_classification.py @@ -151,7 +151,7 @@ def _sanitize_parameters( ignore_subwords: Optional[bool] = None, aggregation_strategy: Optional[AggregationStrategy] = None, offset_mapping: Optional[list[tuple[int, int]]] = None, - is_split_into_words: Optional[bool] = False, + is_split_into_words: bool = False, stride: Optional[int] = None, delimiter: Optional[str] = None, ): diff --git a/src/transformers/tokenization_utils.py b/src/transformers/tokenization_utils.py index 08627d62c123..b89e57093152 100644 --- a/src/transformers/tokenization_utils.py +++ b/src/transformers/tokenization_utils.py @@ -587,11 +587,11 @@ def _add_tokens(self, new_tokens: Union[list[str], list[AddedToken]], special_to self._update_total_vocab_size() return added_tokens - def _update_trie(self, unique_no_split_tokens: Optional[str] = []): + def _update_trie(self, unique_no_split_tokens: Optional[list[str]] = None): for token in self._added_tokens_decoder.values(): if token.content not in self.tokens_trie._tokens: self.tokens_trie.add(token.content) - for token in unique_no_split_tokens: + for token in unique_no_split_tokens or []: if token not in self.tokens_trie._tokens: self.tokens_trie.add(token) diff --git a/src/transformers/utils/chat_template_utils.py b/src/transformers/utils/chat_template_utils.py index 36018c19ccc6..69b3ec977241 100644 --- a/src/transformers/utils/chat_template_utils.py +++ b/src/transformers/utils/chat_template_utils.py @@ -468,9 +468,9 @@ def render_jinja_template( tools: Optional[list[Union[dict, Callable]]] = None, documents: Optional[list[dict[str, str]]] = None, chat_template: Optional[str] = None, - return_assistant_tokens_mask: Optional[bool] = False, - continue_final_message: Optional[bool] = False, - add_generation_prompt: Optional[bool] = False, + return_assistant_tokens_mask: bool = False, + continue_final_message: bool = False, + add_generation_prompt: bool = False, **kwargs, ) -> str: if return_assistant_tokens_mask and not re.search(r"\{\%-?\s*generation\s*-?\%\}", chat_template): diff --git a/src/transformers/utils/quantization_config.py b/src/transformers/utils/quantization_config.py index 037bf3ed73d4..6afd42e0a724 100644 --- a/src/transformers/utils/quantization_config.py +++ b/src/transformers/utils/quantization_config.py @@ -1882,9 +1882,9 @@ class BitNetQuantConfig(QuantizationConfigMixin): def __init__( self, modules_to_not_convert: Optional[list] = None, - linear_class: Optional[str] = "bitlinear", - quantization_mode: Optional[str] = "offline", - use_rms_norm: Optional[bool] = False, + linear_class: str = "bitlinear", + quantization_mode: str = "offline", + use_rms_norm: bool = False, rms_norm_eps: Optional[float] = 1e-6, **kwargs, ): From a062de7203743028b36225a2e096f5e5e109edd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Hadnagy?= Date: Mon, 22 Sep 2025 16:13:46 +0200 Subject: [PATCH 151/204] Add write token for uploading benchmark results to the Hub (#41047) * Separate write token for Hub upload * Address review comments * Address review comments --- .github/workflows/benchmark_v2.yml | 3 ++- benchmark_v2/README.md | 14 ++++++++++++-- benchmark_v2/run_benchmarks.py | 10 +++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/benchmark_v2.yml b/.github/workflows/benchmark_v2.yml index a2c25908d129..dc078e67ea97 100644 --- a/.github/workflows/benchmark_v2.yml +++ b/.github/workflows/benchmark_v2.yml @@ -70,7 +70,8 @@ jobs: python3 run_benchmarks.py \ --commit-id '${{ inputs.commit_sha || github.sha }}' \ --run-id '${{ inputs.run_id }}' \ - --upload-to-hub '${{ inputs.benchmark_repo_id}}' \ + --push-to-hub '${{ inputs.benchmark_repo_id}}' \ + --token '${{ secrets.TRANSFORMERS_CI_RESULTS_UPLOAD_TOKEN }}' \ --log-level INFO env: HF_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }} \ No newline at end of file diff --git a/benchmark_v2/README.md b/benchmark_v2/README.md index 1d34de6408c7..bcbb9cc71ef3 100644 --- a/benchmark_v2/README.md +++ b/benchmark_v2/README.md @@ -27,10 +27,13 @@ You can automatically upload benchmark results to a HuggingFace Dataset for trac ```bash # Upload to a public dataset with auto-generated run ID -python run_benchmarks.py --upload-to-hf username/benchmark-results +python run_benchmarks.py --upload-to-hub username/benchmark-results # Upload with a custom run ID for easy identification -python run_benchmarks.py --upload-to-hf username/benchmark-results --run-id experiment_v1 +python run_benchmarks.py --upload-to-hub username/benchmark-results --run-id experiment_v1 + +# Upload with custom HuggingFace token (if not set in environment) +python run_benchmarks.py --upload-to-hub username/benchmark-results --token hf_your_token_here ``` **Dataset Directory Structure:** @@ -51,6 +54,13 @@ dataset_name/ └── ... ``` +**Authentication for Uploads:** + +For uploading results, you need a HuggingFace token with write permissions to the target dataset. You can provide the token in several ways (in order of precedence): + +1. Command line: `--token hf_your_token_here` +3. Environment variable: `HF_TOKEN` + ### Running Specific Benchmarks ```bash diff --git a/benchmark_v2/run_benchmarks.py b/benchmark_v2/run_benchmarks.py index 44f6515a2c30..18e8a9a77654 100755 --- a/benchmark_v2/run_benchmarks.py +++ b/benchmark_v2/run_benchmarks.py @@ -195,6 +195,7 @@ def upload_results_to_hf_dataset( summary_file: str, dataset_name: str, run_id: Optional[str] = None, + token: Optional[str] = None, logger: Optional[logging.Logger] = None, ) -> Optional[str]: """ @@ -205,6 +206,7 @@ def upload_results_to_hf_dataset( summary_file: Path to the summary file dataset_name: Name of the HuggingFace dataset to upload to run_id: Unique run identifier (if None, will generate one) + token: HuggingFace token for authentication (if None, will use environment variables) logger: Logger instance Returns: The run_id used for the upload, None if upload failed @@ -237,9 +239,6 @@ def upload_results_to_hf_dataset( logger.info(f"Uploading benchmark results to dataset '{dataset_name}' at path '{repo_path}'") try: - # Get the authentication token (prioritize specific token, fallback to HF_TOKEN) - token = os.getenv("TRANSFORMERS_CI_RESULTS_UPLOAD_TOKEN") or os.getenv("HF_TOKEN") - # Upload all files in the output directory from pathlib import Path @@ -357,6 +356,10 @@ def main(): "--run-id", type=str, help="Custom run ID for organizing results (if not provided, will generate a unique ID)" ) + parser.add_argument( + "--token", type=str, help="HuggingFace token for dataset uploads (if not provided, will use HF_TOKEN environment variable)" + ) + args = parser.parse_args() # Setup logging @@ -440,6 +443,7 @@ def main(): summary_file=summary_file, dataset_name=args.upload_to_hub, run_id=effective_run_id, + token=args.token, logger=logger, ) if upload_run_id: From edf22db9c9d6bdf93ee6c275180ad171fccce2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Ouazan?= <83456801+remi-or@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:16:19 +0200 Subject: [PATCH 152/204] Ci utils (#40978) * Add CI reports dir to gitignore * Add utils to run local CI * Review compliance * Style * License --- .gitignore | 1 + utils/get_test_reports.py | 272 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 utils/get_test_reports.py diff --git a/.gitignore b/.gitignore index cdf189505dc7..b59797c2188b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ tests/fixtures/cached_*_text.txt logs/ lightning_logs/ lang_code_data/ +reports/ # Distribution / packaging .Python diff --git a/utils/get_test_reports.py b/utils/get_test_reports.py new file mode 100644 index 000000000000..2c814d133e65 --- /dev/null +++ b/utils/get_test_reports.py @@ -0,0 +1,272 @@ +# coding=utf-8 +# Copyright 2025 The HuggingFace Inc. team. All rights reserved. +# +# 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. +""" +This util provides a way to manually run the tests of the transformers repo as they would be run by the CI. +It was mainly used for models tests, so if you find features missing for another suite, do not hesitate to open a PR. + +Functionnalities: +- Running specific test suite (models, tokenizers, etc.) +- Parallel execution across multiple processes (each has to be launched separately with different `--processes` argument) +- GPU/CPU test filtering and slow tests filter +- Temporary cache management for isolated test runs +- Resume functionality for interrupted test runs +- Important models subset testing + +Example usages are below. +""" + +import argparse +import contextlib +import os +import subprocess +import tempfile +from pathlib import Path +from typing import Optional + +import torch + +from .important_files import IMPORTANT_MODELS + + +def is_valid_test_dir(path: Path) -> bool: + """Check if a given path represents a valid test dir: the path must point to a dir, not start with '__' or '.'""" + return path.is_dir() and not path.name.startswith("__") and not path.name.startswith(".") + + +def run_pytest( + suite: str, subdir: Path, root_test_dir: Path, machine_type: str, dry_run: bool, tmp_cache: str, cpu_tests: bool +) -> None: + """ + Execute pytest on a specific test directory with configured options: + - suite (str): name of the test suite being run (e.g., 'models', 'tokenizers') + - subdir (Path): the specific directory containing tests to run + - root_test_dir (Path): the root directory of all tests, used for relative paths + - machine_type (str): type of machine/environment (e.g., 'cpu', 'single-gpu', 'multi-gpu') + - dry_run (bool): if True, only print the command without executing it + - tmp_cache (str): prefix for temporary cache directory. If empty, no temp cache is used + - cpu_tests (bool): if True, include CPU-only tests; if False, exclude non-device tests + """ + relative_path = subdir.relative_to(root_test_dir) + report_name = f"{machine_type}_{suite}_{relative_path}_test_reports" + print(f"Suite: {suite} | Running on: {relative_path}") + + cmd = ["python3", "-m", "pytest", "-rsfE", "-v", f"--make-reports={report_name}", str(subdir)] + if not cpu_tests: + cmd = cmd + ["-m", "not not_device_test"] + + ctx_manager = tempfile.TemporaryDirectory(prefix=tmp_cache) if tmp_cache else contextlib.nullcontext() + with ctx_manager as tmp_dir: + env = os.environ.copy() + if tmp_cache: + env["HUGGINGFACE_HUB_CACHE"] = tmp_dir + + print(f"Using temporary cache located at {tmp_dir = }") + + print("Command:", " ".join(cmd)) + if not dry_run: + subprocess.run(cmd, check=False, env=env) + + +def handle_suite( + suite: str, + test_root: Path, + machine_type: str, + dry_run: bool, + tmp_cache: str = "", + resume_at: Optional[str] = None, + only_in: Optional[list[str]] = None, + cpu_tests: bool = False, + process_id: int = 1, + total_processes: int = 1, +) -> None: + """ + Handle execution of a complete test suite with advanced filtering and process distribution. + Args: + - suite (str): Name of the test suite to run (corresponds to a directory under test_root). + - test_root (Path): Root directory containing all test suites. + - machine_type (str): Machine/environment type for report naming and identification. + - dry_run (bool): If True, only print commands without executing them. + - tmp_cache (str, optional): Prefix for temporary cache directories. If empty, no temp cache is used. + - resume_at (str, optional): Resume execution starting from this subdirectory name. + Useful for restarting interrupted test runs. Defaults to None (run from the beginning). + - only_in (list[str], optional): Only run tests in these specific subdirectories. + Can include special values like IMPORTANT_MODELS. Defaults to None (run all tests). + - cpu_tests (bool, optional): Whether to include CPU-only tests. Defaults to False. + - process_id (int, optional): Current process ID for parallel execution (1-indexed). Defaults to 1. + - total_processes (int, optional): Total number of parallel processes. Defaults to 1. + """ + # Check path to suite + full_path = test_root / suite + if not full_path.exists(): + print(f"Test folder does not exist: {full_path}") + return + + # Establish the list of subdir to go through + subdirs = sorted(full_path.iterdir()) + subdirs = [s for s in subdirs if is_valid_test_dir(s)] + if resume_at is not None: + subdirs = [s for s in subdirs if s.name >= resume_at] + if only_in is not None: + subdirs = [s for s in subdirs if s.name in only_in] + if subdirs and total_processes > 1: + # This interleaves the subdirs / files. For instance for subdirs = [A, B, C, D, E] and 2 processes: + # - script launcehd with `--processes 0 2` will run A, C, E + # - script launcehd with `--processes 1 2` will run B, D + subdirs = subdirs[process_id::total_processes] + + # If the subdir list is not empty, go through each + if subdirs: + for subdir in subdirs: + run_pytest(suite, subdir, test_root, machine_type, dry_run, tmp_cache, cpu_tests) + # Otherwise, launch pytest from the full path + else: + run_pytest(suite, full_path, test_root, machine_type, dry_run, tmp_cache, cpu_tests) + + +if __name__ == "__main__": + """Command-line interface for running test suite with comprehensive reporting. Check handle_suite for more details. + + Command-line Arguments: + folder: Path to the root test directory (required) + --suite: Test suite name to run (default: "models") + --cpu-tests: Include CPU-only tests in addition to device tests + --run-slow: Execute slow tests instead of skipping them + --resume-at: Resume execution from a specific subdirectory + --only-in: Run tests only in specified subdirectories (supports IMPORTANT_MODELS) + --processes: Process distribution as "process_id total_processes" + --dry-run: Print commands without executing them + --tmp-cache: Use temporary cache directories for isolated runs + --machine-type: Override automatic machine type detection + + Machine Type Detection: + - 'cpu': No CUDA available + - 'single-gpu': CUDA available with 1 GPU + - 'multi-gpu': CUDA available with multiple GPUs + + Process Distribution: + Use --processes to split work across multiple parallel processes: + --processes 0 4 # This is process 0 of 4 total processes + --processes 1 4 # This is process 1 of 4 total processes + ... + + Usage Examples: + # Basic model testing + python3 -m utils.get_test_reports tests/ --suite models + + # Run slow tests for important models only + python3 -m utils.get_test_reports tests/ --suite models --run-slow --only-in IMPORTANT_MODELS + + # Parallel execution across 4 processes, second process to launch (processes are 0-indexed) + python3 -m utils.get_test_reports tests/ --suite models --processes 1 4 + + # Resume interrupted run from 'bert' subdirectory with a tmp cache + python3 -m utils.get_test_reports tests/ --suite models --resume-at bert --tmp-cache /tmp/ + + # Run specific models with CPU tests + python3 -m utils.get_test_reports tests/ --suite models --only-in bert gpt2 --cpu-tests + + # Run slow tests for only important models with a tmp cache + python3 -m utils.get_test_reports tests/ --suite models --run-slow --only-in IMPORTANT_MODELS --tmp-cache /tmp/ + """ + + parser = argparse.ArgumentParser() + parser.add_argument("folder", help="Path to test root folder (e.g., ./tests)") + + # Choose which tests to run (broad picture) + parser.add_argument("--suite", type=str, default="models", help="Test suit to run") + parser.add_argument("--cpu-tests", action="store_true", help="Also runs non-device tests") + parser.add_argument("--run-slow", action="store_true", help="Run slow tests instead of skipping them") + parser.add_argument("--collect-outputs", action="store_true", help="Collect outputs of the tests") + + # Fine-grain control over the tests to run + parser.add_argument("--resume-at", type=str, default=None, help="Resume at a specific subdir / file in the suite") + parser.add_argument( + "--only-in", + type=str, + nargs="+", + help="Only run tests in the given subdirs / file. Use IMPORTANT_MODELS to run only the important models tests.", + ) + + # How to run the test suite: is the work divided among processes, do a try run, use temp cache? + parser.add_argument( + "--processes", + type=int, + nargs="+", + help="Inform each CI process as to the work to do: format as `process_id total_processes`. " + "In order to run with multiple (eg. 3) processes, you need to run the script multiple times (eg. 3 times).", + ) + parser.add_argument("--dry-run", action="store_true", help="Only print commands without running them") + parser.add_argument("--tmp-cache", type=str, help="Change HUGGINGFACE_HUB_CACHE to a tmp dir for each test") + + # This is a purely decorative argument, but it can be useful to distinguish between runs + parser.add_argument( + "--machine-type", type=str, default="", help="Machine type, automatically inferred if not provided" + ) + args = parser.parse_args() + + # Handle run slow + if args.run_slow: + os.environ["RUN_SLOW"] = "yes" + print("[WARNING] Running slow tests.") + else: + print("[WARNING] Skipping slow tests.") + + # Handle multiple CI processes + if args.processes is None: + process_id, total_processes = 1, 1 + elif len(args.processes) == 2: + process_id, total_processes = args.processes + else: + raise ValueError(f"Invalid processes argument: {args.processes}") + + # Assert test root exists + test_root = Path(args.folder).resolve() + if not test_root.exists(): + print(f"Root test folder not found: {test_root}") + exit(1) + + # Handle collection of outputs + if args.collect_outputs: + os.environ["PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS"] = "yes" + reports_dir = test_root.parent / "reports" + os.environ["_PATCHED_TESTING_METHODS_OUTPUT_DIR"] = str(reports_dir) + + # Infer machine type if not provided + if args.machine_type == "": + if not torch.cuda.is_available(): + machine_type = "cpu" + else: + machine_type = "multi-gpu" if torch.cuda.device_count() > 1 else "single-gpu" + else: + machine_type = args.machine_type + + # Reduce the scope for models if necessary + only_in = args.only_in if args.only_in else None + if only_in == ["IMPORTANT_MODELS"]: + only_in = IMPORTANT_MODELS + + # Launch suite + handle_suite( + suite=args.suite, + test_root=test_root, + machine_type=machine_type, + dry_run=args.dry_run, + tmp_cache=args.tmp_cache, + resume_at=args.resume_at, + only_in=only_in, + cpu_tests=args.cpu_tests, + process_id=process_id, + total_processes=total_processes, + ) From 126962e14a37fc235832af9702748563ae05ebac Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Mon, 22 Sep 2025 22:29:50 +0800 Subject: [PATCH 153/204] Remove and tags from documentation (#41055) * Remove and tags Signed-off-by: Yuanyuan Chen * Revert changes Signed-off-by: Yuanyuan Chen * Update docs/source/en/model_doc/madlad-400.md --------- Signed-off-by: Yuanyuan Chen Co-authored-by: Joao Gante --- docs/source/ar/autoclass_tutorial.md | 4 --- docs/source/ar/create_a_model.md | 8 ------ docs/source/ar/model_sharing.md | 8 ------ docs/source/ar/preprocessing.md | 4 --- docs/source/ar/quicktour.md | 28 ------------------- docs/source/ar/run_scripts.md | 8 ------ docs/source/ar/tasks/language_modeling.md | 12 -------- .../ar/tasks/masked_language_modeling.md | 12 -------- docs/source/ar/tasks/multiple_choice.md | 12 -------- docs/source/ar/tasks/question_answering.md | 12 -------- .../ar/tasks/sequence_classification.md | 12 -------- docs/source/ar/tasks/summarization.md | 12 -------- docs/source/ar/tasks/token_classification.md | 12 -------- docs/source/ar/tasks/translation.md | 12 -------- docs/source/ar/training.md | 8 ------ docs/source/de/autoclass_tutorial.md | 4 --- docs/source/de/model_sharing.md | 8 ------ docs/source/de/preprocessing.md | 4 --- docs/source/de/quicktour.md | 28 ------------------- docs/source/de/run_scripts.md | 8 ------ docs/source/de/training.md | 8 ------ docs/source/en/model_doc/efficientloftr.md | 4 --- docs/source/en/model_doc/lightglue.md | 4 --- .../source/en/model_doc/modernbert-decoder.md | 4 --- docs/source/en/model_doc/modernbert.md | 4 --- docs/source/en/model_doc/phi3.md | 4 --- docs/source/en/model_doc/phimoe.md | 4 --- docs/source/en/model_doc/superglue.md | 4 --- docs/source/en/model_doc/xglm.md | 2 -- docs/source/en/tasks/asr.md | 8 ------ docs/source/en/tasks/audio_classification.md | 8 ------ docs/source/es/autoclass_tutorial.md | 4 --- docs/source/es/create_a_model.md | 8 ------ docs/source/es/quicktour.md | 24 ---------------- docs/source/es/run_scripts.md | 8 ------ docs/source/es/serialization.md | 4 --- docs/source/es/tasks/asr.md | 8 ------ docs/source/es/tasks/audio_classification.md | 8 ------ docs/source/es/tasks/language_modeling.md | 12 -------- docs/source/es/tasks/multiple_choice.md | 4 --- docs/source/es/tasks/question_answering.md | 8 ------ docs/source/es/tasks/summarization.md | 8 ------ docs/source/fr/autoclass_tutorial.md | 4 --- docs/source/fr/quicktour.md | 28 ------------------- docs/source/fr/run_scripts_fr.md | 8 ------ docs/source/it/autoclass_tutorial.md | 4 --- docs/source/it/create_a_model.md | 8 ------ docs/source/it/model_sharing.md | 8 ------ docs/source/it/quicktour.md | 24 ---------------- docs/source/it/run_scripts.md | 8 ------ docs/source/it/serialization.md | 4 --- docs/source/it/training.md | 8 ------ docs/source/ja/autoclass_tutorial.md | 4 --- docs/source/ja/create_a_model.md | 8 ------ docs/source/ja/model_doc/albert.md | 3 -- docs/source/ja/model_doc/bert.md | 8 ------ docs/source/ja/model_doc/big_bird.md | 4 --- docs/source/ja/model_doc/blip.md | 4 --- docs/source/ja/model_doc/bloom.md | 4 --- docs/source/ja/model_doc/camembert.md | 4 --- docs/source/ja/model_doc/clip.md | 4 --- docs/source/ja/model_doc/convbert.md | 4 --- docs/source/ja/model_doc/convnext.md | 4 --- docs/source/ja/model_doc/ctrl.md | 4 --- docs/source/ja/model_doc/cvt.md | 4 --- docs/source/ja/model_doc/data2vec.md | 4 --- docs/source/ja/model_doc/deberta-v2.md | 4 --- docs/source/ja/model_doc/deberta.md | 4 --- docs/source/ja/model_doc/deit.md | 4 --- docs/source/ja/model_sharing.md | 8 ------ docs/source/ja/preprocessing.md | 4 --- docs/source/ja/quicktour.md | 28 ------------------- docs/source/ja/run_scripts.md | 8 ------ docs/source/ja/tasks/asr.md | 8 ------ docs/source/ja/tasks/audio_classification.md | 8 ------ docs/source/ja/tasks/image_classification.md | 12 -------- docs/source/ja/tasks/language_modeling.md | 12 -------- .../ja/tasks/masked_language_modeling.md | 12 -------- docs/source/ja/tasks/multiple_choice.md | 8 ------ docs/source/ja/tasks/question_answering.md | 6 ---- docs/source/ja/tasks/semantic_segmentation.md | 16 ----------- docs/source/ja/tasks/summarization.md | 12 -------- docs/source/ja/tasks/token_classification.md | 12 -------- docs/source/ja/tasks/translation.md | 12 -------- docs/source/ja/training.md | 8 ------ docs/source/ko/model_doc/albert.md | 4 --- docs/source/ko/model_doc/bart.md | 4 --- docs/source/ko/model_doc/bert.md | 8 ------ docs/source/ko/model_doc/blip.md | 4 --- docs/source/ko/model_doc/clip.md | 4 --- docs/source/ko/model_doc/convbert.md | 4 --- docs/source/ko/model_doc/deberta-v2.md | 4 --- docs/source/ko/model_doc/deberta.md | 4 --- docs/source/ko/model_doc/electra.md | 4 --- docs/source/ko/model_doc/encoder-decoder.md | 4 --- docs/source/ko/model_doc/esm.md | 4 --- docs/source/ko/model_doc/gpt2.md | 4 --- docs/source/ko/model_doc/marian.md | 4 --- docs/source/ko/model_doc/openai-gpt.md | 4 --- docs/source/ko/model_doc/rag.md | 4 --- docs/source/ko/model_doc/roberta.md | 4 --- docs/source/ko/model_doc/swin.md | 4 --- docs/source/ko/model_doc/vit.md | 4 --- docs/source/ko/model_sharing.md | 8 ------ docs/source/ko/quicktour.md | 28 ------------------- docs/source/ko/run_scripts.md | 8 ------ docs/source/ko/tasks/asr.md | 8 ------ docs/source/ko/tasks/audio_classification.md | 8 ------ docs/source/ko/tasks/image_classification.md | 12 -------- docs/source/ko/tasks/language_modeling.md | 12 -------- .../ko/tasks/masked_language_modeling.md | 12 -------- docs/source/ko/tasks/multiple_choice.md | 8 ------ docs/source/ko/tasks/question_answering.md | 12 -------- docs/source/ko/tasks/semantic_segmentation.md | 16 ----------- .../ko/tasks/sequence_classification.md | 12 -------- docs/source/ko/tasks/summarization.md | 12 -------- docs/source/ko/tasks/token_classification.md | 12 -------- docs/source/ko/tasks/translation.md | 12 -------- docs/source/ko/training.md | 8 ------ docs/source/pt/create_a_model.md | 8 ------ docs/source/pt/quicktour.md | 24 ---------------- docs/source/pt/run_scripts.md | 8 ------ .../pt/tasks/sequence_classification.md | 8 ------ docs/source/pt/tasks/token_classification.md | 8 ------ docs/source/zh/autoclass_tutorial.md | 4 --- docs/source/zh/create_a_model.md | 8 ------ docs/source/zh/model_sharing.md | 8 ------ docs/source/zh/preprocessing.md | 4 --- docs/source/zh/quicktour.md | 28 ------------------- docs/source/zh/run_scripts.md | 8 ------ docs/source/zh/tasks/asr.md | 8 ------ docs/source/zh/training.md | 8 ------ 132 files changed, 1115 deletions(-) diff --git a/docs/source/ar/autoclass_tutorial.md b/docs/source/ar/autoclass_tutorial.md index 6585cf206350..9c7709e2d172 100644 --- a/docs/source/ar/autoclass_tutorial.md +++ b/docs/source/ar/autoclass_tutorial.md @@ -115,8 +115,6 @@ ## النموذج التلقائي (AutoModel) - - تسمح لك فئات `AutoModelFor` بتحميل نموذج مُدرب مسبقًا لمهمة معينة (راجع [هنا](model_doc/auto) للحصول على قائمة كاملة بالمهام المتاحة). على سبيل المثال، قم بتحميل نموذج لتصنيف التسلسل باستخدام [`AutoModelForSequenceClassification.from_pretrained`]: ```py @@ -143,6 +141,4 @@ بشكل عام، نوصي باستخدام فئة `AutoTokenizer` وفئة `AutoModelFor` لتحميل مثيلات مُدربة مسبقًا من النماذج. سيساعدك هذا في تحميل البنية الصحيحة في كل مرة. في البرنامج التعليمي التالي، تعرف على كيفية استخدام المحلل اللغوي ومعالج الصور ومستخرج الميزات والمعالج الذي تم تحميله حديثًا لمعالجة مجموعة بيانات للضبط الدقيق. - - diff --git a/docs/source/ar/create_a_model.md b/docs/source/ar/create_a_model.md index f681d13aa9ef..a2b49696f04b 100644 --- a/docs/source/ar/create_a_model.md +++ b/docs/source/ar/create_a_model.md @@ -81,8 +81,6 @@ DistilBertConfig { الخطوة التالية هي إنشاء [نموذج](main_classes/models). النموذج - ويُشار إليه أحيانًا باسم البنية - يُحدد وظيفة كل طبقة والعمليات الحسابية المُنفذة. تُستخدم خصائص مثل `num_hidden_layers` من التكوين لتحديد هذه البنية. تشترك جميع النماذج في فئة أساسية واحدة هي [`PreTrainedModel`] وبعض الوظائف المُشتركة مثل غيير حجم مُدخلات الكلمات وتقليص رؤوس آلية الانتباه الذاتي. بالإضافة إلى ذلك، فإن جميع النماذج هي فئات فرعية إما من [`torch.nn.Module`](https://pytorch.org/docs/stable/generated/torch.nn.Module.html)، [`tf.keras.Model`](https://www.tensorflow.org/api_docs/python/tf/keras/Model) أو [`flax.linen.Module`](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) . هذا يعني النماذج متوافقة مع كل استخدام لإطار العمل الخاص بها. - - قم بتحميل خصائص التكوين المخصصة الخاصة بك في النموذج: ```py @@ -105,15 +103,11 @@ DistilBertConfig { ```py >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased"، config=my_config) ``` - - ### رؤوس النموذج في هذه المرحلة، لديك نموذج DistilBERT الأساسي الذي يخرج *حالات الكامنة*. تُمرَّر هذه الحالات الكامنة كمدخلات لرأس النموذج لإنتاج المخرجات النهائية. توفر مكتبة 🤗 Transformers رأس نموذج مختلف لكل مهمة طالما أن النموذج يدعم المهمة (أي لا يمكنك استخدام DistilBERT لمهمة تسلسل إلى تسلسل مثل الترجمة). - - على سبيل المثال، [`DistilBertForSequenceClassification`] هو نموذج DistilBERT الأساس مزودًا برأس تصنيف تسلسلي. يُشكّل رأس التصنيف التسلسلي طبقة خطية فوق المخرجات المجمعة. ```py @@ -129,8 +123,6 @@ DistilBertConfig { >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - - ## مجزئ النصوص diff --git a/docs/source/ar/model_sharing.md b/docs/source/ar/model_sharing.md index c50c2cf40fbe..b81173b15a29 100644 --- a/docs/source/ar/model_sharing.md +++ b/docs/source/ar/model_sharing.md @@ -65,21 +65,15 @@ pip install huggingface_hub تحويل نقطة التحقق لإطار عمل آخر أمر سهل. تأكد من تثبيت PyTorch و TensorFlow (راجع [هنا](installation) لتعليمات التثبيت)، ثم ابحث عن النموذج الملائم لمهمتك في الإطار الآخر. - - حدد `from_tf=True` لتحويل نقطة تحقق من TensorFlow إلى PyTorch: ```py >>> pt_model = DistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_tf=True) >>> pt_model.save_pretrained("path/to/awesome-name-you-picked") ``` - - ## دفع نموذج أثناء التدريب - - مشاركة نموذجك على Hub مر بسيط للغاية كل ما عليك هو إضافة معلمة أو استدعاء رد إضافي. كما تذكر من درس [التدريب الدقيق](training)، فإن فئة [`TrainingArguments`] هي المكان الذي تحدد فيه المعلمات الفائقة وخيارات التدريب الإضافية. تشمل إحدى خيارات التدريب هذه القدرة على دفع النموذج مباشرة إلى المنصة Hub. قم بتعيين `push_to_hub=True` في [`TrainingArguments`]: @@ -105,8 +99,6 @@ pip install huggingface_hub ```py >>> trainer.push_to_hub() ``` - - ## استخدام دالة `push_to_hub` diff --git a/docs/source/ar/preprocessing.md b/docs/source/ar/preprocessing.md index 18ab522e436c..1418c69fd7a3 100644 --- a/docs/source/ar/preprocessing.md +++ b/docs/source/ar/preprocessing.md @@ -152,8 +152,6 @@ pip install datasets قم بتعيين معلمة `return_tensors` إلى إما `pt` لـ PyTorch، أو `tf` لـ TensorFlow: - - ```py >>> batch_sentences = [ @@ -173,8 +171,6 @@ pip install datasets [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])} ``` - - diff --git a/docs/source/ar/quicktour.md b/docs/source/ar/quicktour.md index aebcc847ae58..55466e0a1563 100644 --- a/docs/source/ar/quicktour.md +++ b/docs/source/ar/quicktour.md @@ -12,14 +12,10 @@ ستحتاج أيضًا إلى تثبيت إطار عمل التعلم الآلي المفضل لديك: - - ```bash pip install torch ``` - - ## خط الأنابيب @@ -116,8 +112,6 @@ label: NEGATIVE, with score: 0.5309 >>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ``` - - استخدم [`AutoModelForSequenceClassification`] و [`AutoTokenizer`] لتحميل النموذج المُدرب مسبقًا ومعالجته المرتبط به (مزيد من المعلومات حول `AutoClass` في القسم التالي): ```py @@ -126,8 +120,6 @@ label: NEGATIVE, with score: 0.5309 >>> model = AutoModelForSequenceClassification.from_pretrained(model_name) >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - - حدد النموذج والمعالج في [`pipeline`]. الآن يمكنك تطبيق `classifier` على النص الفرنسي: @@ -176,8 +168,6 @@ label: NEGATIVE, with score: 0.5309 يمكن المجزئ أيضًا قبول قائمة من المدخلات، ويقوم بـ "حشو" و"تقصير" النص لإرجاع كدفعة بطول موحد: - - ```py >>> pt_batch = tokenizer( @@ -188,8 +178,6 @@ label: NEGATIVE, with score: 0.5309 ... return_tensors="pt", ... ) ``` - - @@ -199,8 +187,6 @@ label: NEGATIVE, with score: 0.5309 ### AutoModel - - تقدم مكتبة 🤗 Transformers طريقة بسيطة وموحدة لتحميل نماذج مدربة مسبقًا. وهذا يعني أنه يمكنك تحميل [`AutoModel`] كما لو كنت تقوم بتحميل [`AutoTokenizer`]. الفرق الوحيد هو اختيار فئة [`AutoModel`] المناسبة للمهمة. بالنسبة لتصنيف النص (أو التسلسل)، يجب عليك تحميل [`AutoModelForSequenceClassification`]: ```py @@ -236,8 +222,6 @@ label: NEGATIVE, with score: 0.5309 tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - - @@ -247,8 +231,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ### حفظ النموذج - - بمجرد ضبط نموذجك، يمكنك حفظه مع برنامج الترميز الخاص به باستخدام [`PreTrainedModel.save_pretrained`]: ```py @@ -262,13 +244,9 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ```py >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - - من الميزات الرائعة في 🤗 Transformers القدرة على حفظ نموذج وإعادة تحميله كنموذج PyTorch أو TensorFlow. يمكن أن يحول معامل `from_pt` أو `from_tf` النموذج من إطار عمل إلى آخر: - - ```py >>> from transformers import AutoModel @@ -276,8 +254,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory) >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - ## إنشاء نماذج مخصصة @@ -292,8 +268,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_config = AutoConfig.from_pretrained("distilbert/distilbert-base-uncased", n_heads=12) ``` - - قم بإنشاء نموذج من تكوينك المخصص باستخدام [`AutoModel.from_config`]: ```py @@ -301,8 +275,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_model = AutoModel.from_config(my_config) ``` - - الق نظرة على دليل [إنشاء بنية مخصصة](./create_a_model) لمزيد من المعلومات حول بناء التكوينات المخصصة. diff --git a/docs/source/ar/run_scripts.md b/docs/source/ar/run_scripts.md index 784703a4bbfc..238844dc055e 100644 --- a/docs/source/ar/run_scripts.md +++ b/docs/source/ar/run_scripts.md @@ -76,8 +76,6 @@ pip install -r requirements.txt ## تشغيل نص برمجي - - - يقوم النص البرمجي التوضيحي بتنزيل مجموعة بيانات ومعالجتها مسبقًا من مكتبة 🤗 [Datasets](https://huggingface.co/docs/datasets). - ثم يقوم النص البرمجي بضبط نموذج بيانات دقيق باستخدام [Trainer](https://huggingface.co/docs/transformers/main_classes/trainer) على بنية تدعم الملخص. @@ -98,8 +96,6 @@ python examples/pytorch/summarization/run_summarization.py \ --overwrite_output_dir \ --predict_with_generate ``` - - ## التدريب الموزع والدقة المختلطة @@ -129,8 +125,6 @@ torchrun \ ## تشغيل نص برمجي على وحدة معالجة الدقة الفائقة (TPU) - - تُعد وحدات معالجة الدقة الفائقة (TPUs) مصممة خصيصًا لتسريع الأداء. يدعم PyTorch وحدات معالجة الدقة الفائقة (TPUs) مع [XLA](https://www.tensorflow.org/xla) مجمع الدقة الفائقة للتعلم العميق (راجع [هنا](https://github.com/pytorch/xla/blob/master/README.md) لمزيد من التفاصيل). لاستخدام وحدة معالجة الدقة الفائقة (TPU)، قم بتشغيل نص `xla_spawn.py` البرمجي واستخدم معامل `num_cores` لتعيين عدد وحدات معالجة الدقة الفائقة (TPU) التي تريد استخدامها. @@ -149,8 +143,6 @@ python xla_spawn.py --num_cores 8 \ --overwrite_output_dir \ --predict_with_generate ``` - - ## تشغيل نص برمجي باستخدام 🤗 Accelerate diff --git a/docs/source/ar/tasks/language_modeling.md b/docs/source/ar/tasks/language_modeling.md index c0788a47a6b5..4b6bb31692a7 100644 --- a/docs/source/ar/tasks/language_modeling.md +++ b/docs/source/ar/tasks/language_modeling.md @@ -182,8 +182,6 @@ pip install transformers datasets evaluate الآن قم بإنشاء دفعة من الأمثلة باستخدام [`DataCollatorForLanguageModeling`]. من الأفضل أن تقوم بـ *الحشو الديناميكي* للجمل إلى الطول الأطول في الدفعة أثناء التجميع، بدلاً من حشو كامل المجموعة من البيانات إلى الطول الأقصى. - - استخدم رمز نهاية التسلسل كرمز للحشو، وحدد `mlm_probability` لحجب الرموز بشكل عشوائي عند كل تكرار للبيانات: ```py @@ -193,13 +191,9 @@ pip install transformers datasets evaluate >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False) ``` - - ## التدريب (Train) - - @@ -257,8 +251,6 @@ Perplexity: 49.61 ```py >>> trainer.push_to_hub() ``` - - @@ -288,8 +280,6 @@ Perplexity: 49.61 [{'generated_text': "Somatic hypermutation allows the immune system to be able to effectively reverse the damage caused by an infection.\n\n\nThe damage caused by an infection is caused by the immune system's ability to perform its own self-correcting tasks."}] ``` - - قسم النص وإرجع `input_ids` كتنسورات PyTorch: ```py @@ -315,5 +305,3 @@ Perplexity: 49.61 >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) ["Somatic hypermutation allows the immune system to react to drugs with the ability to adapt to a different environmental situation. In other words, a system of 'hypermutation' can help the immune system to adapt to a different environmental situation or in some cases even a single life. In contrast, researchers at the University of Massachusetts-Boston have found that 'hypermutation' is much stronger in mice than in humans but can be found in humans, and that it's not completely unknown to the immune system. A study on how the immune system"] ``` - - diff --git a/docs/source/ar/tasks/masked_language_modeling.md b/docs/source/ar/tasks/masked_language_modeling.md index 34c3913224c0..846614b4b177 100644 --- a/docs/source/ar/tasks/masked_language_modeling.md +++ b/docs/source/ar/tasks/masked_language_modeling.md @@ -176,8 +176,6 @@ pip install transformers datasets evaluate الآن، قم بإنشاء دفعة من الأمثلة باستخدام [`DataCollatorForLanguageModeling`]. من الأكثر كفاءة أن تقوم بـ *الحشو الديناميكي* ليصل طولها إلى أطول جملة في الدفعة أثناء التجميع، بدلاً من حشو مجموعة البيانات بأكملها إلى الطول الأقصى. - - استخدم رمز نهاية التسلسل كرمز الحشو وحدد `mlm_probability` لحجب الرموز عشوائياً كل مرة تكرر فيها البيانات: @@ -187,13 +185,9 @@ pip install transformers datasets evaluate >>> tokenizer.pad_token = tokenizer.eos_token >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15) ``` - - ## التدريب (Train) - - @@ -253,8 +247,6 @@ Perplexity: 8.76 ```py >>> trainer.push_to_hub() ``` - - @@ -295,8 +287,6 @@ Perplexity: 8.76 'sequence': 'The Milky Way is a small galaxy.'}] ``` - - قم بتجزئة النص وإرجاع `input_ids` كمتجهات PyTorch. ستحتاج أيضًا إلى تحديد موضع رمز ``: ```py @@ -328,5 +318,3 @@ The Milky Way is a spiral galaxy. The Milky Way is a massive galaxy. The Milky Way is a small galaxy. ``` - - diff --git a/docs/source/ar/tasks/multiple_choice.md b/docs/source/ar/tasks/multiple_choice.md index 3a849251c992..cdfe0b8caf6c 100644 --- a/docs/source/ar/tasks/multiple_choice.md +++ b/docs/source/ar/tasks/multiple_choice.md @@ -116,8 +116,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) يقوم `DataCollatorForMultipleChoice` بتجميع جميع مدخلات النموذج، ويطبق الحشو، ثم يعيد تجميع النتائج في شكلها الأصلي: - - ```py >>> from dataclasses import dataclass @@ -158,8 +156,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) ... batch["labels"] = torch.tensor(labels, dtype=torch.int64) ... return batch ``` - - ## التقييم (Evaluate) @@ -186,8 +182,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) ## التدريب (Train) - - @@ -241,8 +235,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) ```py >>> trainer.push_to_hub() ``` - - @@ -263,8 +255,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) >>> candidate2 = "The law applies to baguettes." ``` - - قم بتحليل كل مطالبة وزوج إجابة مرشح وأعد تنسورات PyTorch. يجب عليك أيضًا إنشاء بعض `العلامات`: ```py @@ -292,5 +282,3 @@ tokenized_swag = swag.map(preprocess_function, batched=True) >>> predicted_class 0 ``` - - diff --git a/docs/source/ar/tasks/question_answering.md b/docs/source/ar/tasks/question_answering.md index d86816a13c84..b0f00c9316b3 100644 --- a/docs/source/ar/tasks/question_answering.md +++ b/docs/source/ar/tasks/question_answering.md @@ -167,21 +167,15 @@ pip install transformers datasets evaluate الآن قم بإنشاء دفعة من الأمثلة باستخدام [`DefaultDataCollator`]. بخلاف مجمّعات البيانات الأخرى في 🤗 Transformers، لا يطبق [`DefaultDataCollator`] أي معالجة مسبقة إضافية مثل الحشو. - - ```py >>> from transformers import DefaultDataCollator >>> data_collator = DefaultDataCollator() ``` - - ## التدريب (Train) - - @@ -232,8 +226,6 @@ pip install transformers datasets evaluate ```py >>> trainer.push_to_hub() ``` - - @@ -275,8 +267,6 @@ pip install transformers datasets evaluate يمكنك أيضًا تكرار نتائج `pipeline` يدويًا إذا أردت: - - قسّم النص وأرجع تنسورات PyTorch: @@ -312,5 +302,3 @@ pip install transformers datasets evaluate >>> tokenizer.decode(predict_answer_tokens) '176 billion parameters and can generate text in 46 languages natural languages and 13' ``` - - diff --git a/docs/source/ar/tasks/sequence_classification.md b/docs/source/ar/tasks/sequence_classification.md index f73dc634489f..d8e6cb29bad5 100644 --- a/docs/source/ar/tasks/sequence_classification.md +++ b/docs/source/ar/tasks/sequence_classification.md @@ -92,16 +92,12 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) الآن قم بإنشاء دفعة من الأمثلة باستخدام [`DataCollatorWithPadding`]. الأكثر كفاءة هو استخدام الحشو الديناميكي لجعل الجمل متساوية في الطول داخل كل دفعة، بدلًا من حشو كامل البيانات إلى الحد الأقصى للطول. - - ```py >>> from transformers import DataCollatorWithPadding >>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer) ``` - - ## التقييم(Evaluate) @@ -135,8 +131,6 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) >>> label2id = {"NEGATIVE": 0, "POSITIVE": 1} ``` - - إذا لم تكن على دراية بضبط نموذج دقيق باستخدام [`Trainer`], فالق نظرة على البرنامج التعليمي الأساسي [هنا](../training#train-with-pytorch-trainer)! @@ -197,8 +191,6 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) ```py >>> trainer.push_to_hub() ``` - - @@ -230,8 +222,6 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) يمكنك أيضًا تكرار نتائج `pipeline` يدويًا إذا أردت: - - قم يتجزئة النص وإرجاع تنسورات PyTorch: ```py @@ -258,5 +248,3 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) >>> model.config.id2label[predicted_class_id] 'POSITIVE' ``` - - diff --git a/docs/source/ar/tasks/summarization.md b/docs/source/ar/tasks/summarization.md index 45c99767483f..760b6d370d17 100644 --- a/docs/source/ar/tasks/summarization.md +++ b/docs/source/ar/tasks/summarization.md @@ -118,16 +118,12 @@ pip install transformers datasets evaluate rouge_score الآن قم بإنشاء دفعة من الأمثلة باستخدام [`DataCollatorForSeq2Seq`]. الأكثر كفاءة *الحشو الديناميكي* للجمل إلى أطول طول في دفعة أثناء عملية التجميع، بدلاً من حشو مجموعة البيانات بأكملها إلى الحد الأقصى للطول. - - ```py >>> from transformers import DataCollatorForSeq2Seq >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - ## التقييم (Evaluate) @@ -162,8 +158,6 @@ pip install transformers datasets evaluate rouge_score ## التدريب (Train) - - @@ -218,8 +212,6 @@ pip install transformers datasets evaluate rouge_score ```py >>> trainer.push_to_hub() ``` - - @@ -250,8 +242,6 @@ pip install transformers datasets evaluate rouge_score يمكنك أيضًا تكرار نتائج `pipeline` يدويًا إذا أردت: - - قسم النص وإرجع `input_ids` كتنسورات PyTorch: ```py @@ -276,5 +266,3 @@ pip install transformers datasets evaluate rouge_score >>> tokenizer.decode(outputs[0], skip_special_tokens=True) 'the inflation reduction act lowers prescription drug costs, health care costs, and energy costs. it's the most aggressive action on tackling the climate crisis in american history. it will ask the ultra-wealthy and corporations to pay their fair share.' ``` - - diff --git a/docs/source/ar/tasks/token_classification.md b/docs/source/ar/tasks/token_classification.md index fe8ff5116adb..b3d353527962 100644 --- a/docs/source/ar/tasks/token_classification.md +++ b/docs/source/ar/tasks/token_classification.md @@ -151,15 +151,11 @@ pip install transformers datasets evaluate seqeval الآن قم بإنشاء دفعة من الأمثلة باستخدام [`DataCollatorWithPadding`].من الأفضل استخدام *الحشو الديناميكي* للجمل إلى أطول طول في دفعة أثناء التجميع، بدلاً من حشو مجموعة البيانات بالكامل إلى الطول الأقصى. - - ```py >>> from transformers import DataCollatorForTokenClassification >>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer) ``` - - ## التقييم(Evaluate) @@ -239,8 +235,6 @@ pip install transformers datasets evaluate seqeval ... } ``` - - إذا لم تكن على دراية بتعديل نموذج باستخدام [`Trainer`], ألق نظرة على الدليل التعليمي الأساسي [هنا](../training#train-with-pytorch-trainer)! @@ -295,8 +289,6 @@ pip install transformers datasets evaluate seqeval ```py >>> trainer.push_to_hub() ``` - - @@ -357,8 +349,6 @@ pip install transformers datasets evaluate seqeval يمكنك أيضًا تكرار نتائج `pipeline` يدويًا إذا أردت: - - قسّم النص إلى رموز وأرجع المُوتّرات بلغة PyTorch: ```py @@ -402,5 +392,3 @@ pip install transformers datasets evaluate seqeval 'O', 'O'] ``` - - diff --git a/docs/source/ar/tasks/translation.md b/docs/source/ar/tasks/translation.md index 3198d4c36871..e2beb45acb59 100644 --- a/docs/source/ar/tasks/translation.md +++ b/docs/source/ar/tasks/translation.md @@ -113,16 +113,12 @@ pip install transformers datasets evaluate sacrebleu الآن أنشئ دفعة من الأمثلة باستخدام [`DataCollatorForSeq2Seq`]. من الأكثر كفاءة *الحشو الديناميكي* للجمل إلى أطول طول في دفعة أثناء التجميع، بدلاً من حشو مجموعة البيانات بأكملها إلى الحد الأقصى للطول. - - ```py >>> from transformers import DataCollatorForSeq2Seq >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - ## التقييم (Evaluate) @@ -169,8 +165,6 @@ pip install transformers datasets evaluate sacrebleu ## التدريب (Train) - - @@ -225,8 +219,6 @@ pip install transformers datasets evaluate sacrebleu ```py >>> trainer.push_to_hub() ``` - - @@ -260,8 +252,6 @@ pip install transformers datasets evaluate sacrebleu يمكنك أيضًا تكرار نتائج `pipeline` يدويًا إذا أردت: - - قم بتحويل النص إلى رموز وإرجاع `input_ids` كموترات PyTorch: ```py @@ -286,5 +276,3 @@ pip install transformers datasets evaluate sacrebleu >>> tokenizer.decode(outputs[0], skip_special_tokens=True) 'Les lignées partagent des ressources avec des bactéries enfixant l'azote.' ``` - - diff --git a/docs/source/ar/training.md b/docs/source/ar/training.md index dee48ac7822c..c509b27a3317 100644 --- a/docs/source/ar/training.md +++ b/docs/source/ar/training.md @@ -58,8 +58,6 @@ في شريط التنقل الأيمن للقفز إلى الإطار الذي تريده - وإذا كنت تريد إخفاء كل المحتوى لإطار معين، فاستخدم الزر في الركن العلوي الأيمن من كتلة الإطار! - - ## التدريب باستخدام PyTorch Trainer @@ -139,14 +137,10 @@ ```py >>> trainer.train() ``` - - ## تدريب في PyTorch الأصلي - - [`Trainer`] يهتم بحلقة التدريب ويسمح لك بضبط نموذج في سطر واحد من التعليمات البرمجية. بالنسبة للمستخدمين الذين يفضلون كتابة حلقة التدريب الخاصة بهم، يمكنك أيضًا ضبط نموذج 🤗 Transformers في PyTorch الأصلي. @@ -287,8 +281,6 @@ torch.cuda.empty_cache() >>> metric.compute() ``` - - diff --git a/docs/source/de/autoclass_tutorial.md b/docs/source/de/autoclass_tutorial.md index 178267049a4b..94fabccb25fd 100644 --- a/docs/source/de/autoclass_tutorial.md +++ b/docs/source/de/autoclass_tutorial.md @@ -81,8 +81,6 @@ Laden Sie einen Prozessor mit [`AutoProcessor.from_pretrained`]: ## AutoModel - - Mit den `AutoModelFor`-Klassen können Sie schließlich ein vortrainiertes Modell für eine bestimmte Aufgabe laden (siehe [hier](model_doc/auto) für eine vollständige Liste der verfügbaren Aufgaben). Laden Sie zum Beispiel ein Modell für die Sequenzklassifikation mit [`AutoModelForSequenceClassification.from_pretrained`]: ```py @@ -108,5 +106,3 @@ TensorFlow- und Flax-Checkpoints sind nicht betroffen und können in PyTorch-Arc Im Allgemeinen empfehlen wir die Verwendung der Klasse "AutoTokenizer" und der Klasse "AutoModelFor", um trainierte Instanzen von Modellen zu laden. Dadurch wird sichergestellt, dass Sie jedes Mal die richtige Architektur laden. Im nächsten [Tutorial] (Vorverarbeitung) erfahren Sie, wie Sie Ihren neu geladenen Tokenizer, Feature Extractor und Prozessor verwenden, um einen Datensatz für die Feinabstimmung vorzuverarbeiten. - - diff --git a/docs/source/de/model_sharing.md b/docs/source/de/model_sharing.md index dfa2c7f785bc..6bfc444ae50b 100644 --- a/docs/source/de/model_sharing.md +++ b/docs/source/de/model_sharing.md @@ -79,21 +79,15 @@ Um sicherzustellen, dass Ihr Modell von jemandem verwendet werden kann, der mit Die Konvertierung eines Checkpoints für ein anderes Framework ist einfach. Stellen Sie sicher, dass Sie PyTorch und TensorFlow installiert haben (siehe [hier](installation) für Installationsanweisungen), und finden Sie dann das spezifische Modell für Ihre Aufgabe in dem anderen Framework. - - Geben Sie `from_tf=True` an, um einen Prüfpunkt von TensorFlow nach PyTorch zu konvertieren: ```py >>> pt_model = DistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_tf=True) >>> pt_model.save_pretrained("path/to/awesome-name-you-picked") ``` - - ## Ein Modell während des Trainings hochladen - - Die Weitergabe eines Modells an den Hub ist so einfach wie das Hinzufügen eines zusätzlichen Parameters oder Rückrufs. Erinnern Sie sich an das [Feinabstimmungs-Tutorial](training), in der Klasse [`TrainingArguments`] geben Sie Hyperparameter und zusätzliche Trainingsoptionen an. Eine dieser Trainingsoptionen beinhaltet die Möglichkeit, ein Modell direkt an den Hub zu pushen. Setzen Sie `push_to_hub=True` in Ihrer [`TrainingArguments`]: @@ -119,8 +113,6 @@ Nach der Feinabstimmung Ihres Modells rufen Sie [`~transformers.Trainer.push_to_ ```py >>> trainer.push_to_hub() ``` - - ## Verwenden Sie die Funktion `push_to_hub`. diff --git a/docs/source/de/preprocessing.md b/docs/source/de/preprocessing.md index 8da34e816220..baae623d6988 100644 --- a/docs/source/de/preprocessing.md +++ b/docs/source/de/preprocessing.md @@ -153,8 +153,6 @@ Schließlich möchten Sie, dass der Tokenizer die tatsächlichen Tensoren zurüc Setzen Sie den Parameter `return_tensors` entweder auf `pt` für PyTorch, oder `tf` für TensorFlow: - - ```py >>> batch_sentences = [ @@ -174,8 +172,6 @@ Setzen Sie den Parameter `return_tensors` entweder auf `pt` für PyTorch, oder ` [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])} ``` - - ## Audio diff --git a/docs/source/de/quicktour.md b/docs/source/de/quicktour.md index 5f05a4441e84..024c9fe8b3c6 100644 --- a/docs/source/de/quicktour.md +++ b/docs/source/de/quicktour.md @@ -66,14 +66,10 @@ Im folgenden Beispiel werden Sie die [`pipeline`] für die Stimmungsanalyse verw Installieren Sie die folgenden Abhängigkeiten, falls Sie dies nicht bereits getan haben: - - ```bash pip install torch ``` - - Importieren sie die [`pipeline`] und spezifizieren sie die Aufgabe, welche sie lösen möchten: @@ -148,8 +144,6 @@ Die [`pipeline`] kann jedes Modell aus dem [Model Hub](https://huggingface.co/mo >>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ``` - - Use the [`AutoModelForSequenceClassification`] and [`AutoTokenizer`] to load the pretrained model and its associated tokenizer (more on an `AutoClass` below): ```py @@ -158,8 +152,6 @@ Use the [`AutoModelForSequenceClassification`] and [`AutoTokenizer`] to load the >>> model = AutoModelForSequenceClassification.from_pretrained(model_name) >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - - Dann können Sie das Modell und den Tokenizer in der [`pipeline`] angeben und den `Klassifikator` auf Ihren Zieltext anwenden: @@ -210,8 +202,6 @@ Der Tokenizer gibt ein Wörterbuch zurück, das Folgendes enthält: Genau wie die [`pipeline`] akzeptiert der Tokenizer eine Liste von Eingaben. Darüber hinaus kann der Tokenizer den Text auch auffüllen und kürzen, um einen Stapel mit einheitlicher Länge zurückzugeben: - - ```py >>> pt_batch = tokenizer( @@ -222,15 +212,11 @@ Genau wie die [`pipeline`] akzeptiert der Tokenizer eine Liste von Eingaben. Dar ... return_tensors="pt", ... ) ``` - - Lesen Sie das Tutorial [preprocessing](./preprocessing) für weitere Details zur Tokenisierung. ### AutoModel - - 🤗 Transformers bietet eine einfache und einheitliche Möglichkeit, vortrainierte Instanzen zu laden. Das bedeutet, dass Sie ein [`AutoModel`] laden können, wie Sie einen [`AutoTokenizer`] laden würden. Der einzige Unterschied ist die Auswahl des richtigen [`AutoModel`] für die Aufgabe. Da Sie eine Text- oder Sequenzklassifizierung vornehmen, laden Sie [`AutoModelForSequenceClassification`]: ```py @@ -262,8 +248,6 @@ Das Modell gibt die endgültigen Aktivierungen in dem Attribut "logits" aus. Wen tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - - @@ -283,8 +267,6 @@ Die Modellausgänge verhalten sich auch wie ein Tupel oder ein Wörterbuch (z.B. ### Modell speichern - - Sobald Ihr Modell feinabgestimmt ist, können Sie es mit seinem Tokenizer speichern, indem Sie [`PreTrainedModel.save_pretrained`] verwenden: ```py @@ -298,13 +280,9 @@ Wenn Sie bereit sind, das Modell erneut zu verwenden, laden Sie es mit [`PreTrai ```py >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - - Ein besonders cooles 🤗 Transformers-Feature ist die Möglichkeit, ein Modell zu speichern und es entweder als PyTorch- oder TensorFlow-Modell wieder zu laden. Der Parameter "from_pt" oder "from_tf" kann das Modell von einem Framework in das andere konvertieren: - - ```py >>> from transformers import AutoModel @@ -312,8 +290,6 @@ Ein besonders cooles 🤗 Transformers-Feature ist die Möglichkeit, ein Modell >>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory) >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - ## Custom model builds @@ -327,8 +303,6 @@ Beginnen Sie mit dem Import von [`AutoConfig`] und laden Sie dann das trainierte >>> my_config = AutoConfig.from_pretrained("distilbert/distilbert-base-uncased", n_heads=12) ``` - - Create a model from your custom configuration with [`AutoModel.from_config`]: ```py @@ -336,8 +310,6 @@ Create a model from your custom configuration with [`AutoModel.from_config`]: >>> my_model = AutoModel.from_config(my_config) ``` - - Weitere Informationen zur Erstellung von benutzerdefinierten Konfigurationen finden Sie in der Anleitung [Erstellen einer benutzerdefinierten Architektur](./create_a_model). diff --git a/docs/source/de/run_scripts.md b/docs/source/de/run_scripts.md index 10485a5de2a3..004f67291979 100644 --- a/docs/source/de/run_scripts.md +++ b/docs/source/de/run_scripts.md @@ -85,8 +85,6 @@ pip install -r requirements.txt ## Ein Skript ausführen - - Das Beispielskript lädt einen Datensatz aus der 🤗 [Datasets](https://huggingface.co/docs/datasets/) Bibliothek herunter und verarbeitet ihn vor. Dann nimmt das Skript eine Feinabstimmung eines Datensatzes mit dem [Trainer](https://huggingface.co/docs/transformers/main_classes/trainer) auf einer Architektur vor, die eine Zusammenfassung unterstützt. Das folgende Beispiel zeigt, wie die Feinabstimmung von [T5-small](https://huggingface.co/google-t5/t5-small) auf dem Datensatz [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail) durchgeführt wird. Das T5-Modell benötigt aufgrund der Art und Weise, wie es trainiert wurde, ein zusätzliches Argument `source_prefix`. Mit dieser Eingabeaufforderung weiß T5, dass es sich um eine Zusammenfassungsaufgabe handelt. ```bash @@ -103,8 +101,6 @@ python examples/pytorch/summarization/run_summarization.py \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Verteiltes Training und gemischte Präzision @@ -134,8 +130,6 @@ TensorFlow-Skripte verwenden eine [`MirroredStrategy`](https://www.tensorflow.or ## Ein Skript auf einer TPU ausführen - - Tensor Processing Units (TPUs) sind speziell für die Beschleunigung der Leistung konzipiert. PyTorch unterstützt TPUs mit dem [XLA](https://www.tensorflow.org/xla) Deep Learning Compiler (siehe [hier](https://github.com/pytorch/xla/blob/master/README.md) für weitere Details). Um eine TPU zu verwenden, starten Sie das Skript `xla_spawn.py` und verwenden das Argument `num_cores`, um die Anzahl der TPU-Kerne festzulegen, die Sie verwenden möchten. ```bash @@ -153,8 +147,6 @@ python xla_spawn.py --num_cores 8 \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Führen Sie ein Skript mit 🤗 Accelerate aus. diff --git a/docs/source/de/training.md b/docs/source/de/training.md index fb5cb5695b9f..92051d5d1a58 100644 --- a/docs/source/de/training.md +++ b/docs/source/de/training.md @@ -73,8 +73,6 @@ An dieser Stelle sollten Sie dem Abschnitt folgen, der dem Rahmen entspricht, de in der rechten Seitenleiste können Sie zu dem gewünschten Abschnitt springen - und wenn Sie den gesamten Inhalt eines bestimmten Frameworks ausblenden möchten, klicken Sie einfach auf die Schaltfläche oben rechts im Block des jeweiligen Frameworks! - - ## Trainieren mit PyTorch Trainer @@ -155,15 +153,11 @@ Anschließend können Sie Ihr Modell durch den Aufruf von [`~transformers.Traine ```py >>> trainer.train() ``` - - ## Trainieren in nativem PyTorch - - [`Trainer`] kümmert sich um die Trainingsschleife und ermöglicht die Feinabstimmung eines Modells in einer einzigen Codezeile. Für Benutzer, die es vorziehen, ihre eigene Trainingsschleife zu schreiben, können Sie auch eine Feinabstimmung eines 🤗 Transformers-Modells in nativem PyTorch vornehmen. @@ -305,8 +299,6 @@ Genauso wie Sie eine Bewertungsfunktion zu [`Trainer`] hinzugefügt haben, müss >>> metric.compute() ``` - - diff --git a/docs/source/en/model_doc/efficientloftr.md b/docs/source/en/model_doc/efficientloftr.md index 2994ae83262d..2cdec895efc0 100644 --- a/docs/source/en/model_doc/efficientloftr.md +++ b/docs/source/en/model_doc/efficientloftr.md @@ -156,8 +156,6 @@ processed_outputs = processor.post_process_keypoint_matching(outputs, image_size - post_process_keypoint_matching - visualize_keypoint_matching - - ## EfficientLoFTRModel [[autodoc]] EfficientLoFTRModel @@ -170,5 +168,3 @@ processed_outputs = processor.post_process_keypoint_matching(outputs, image_size - forward - - \ No newline at end of file diff --git a/docs/source/en/model_doc/lightglue.md b/docs/source/en/model_doc/lightglue.md index 13ac58a1b842..847fabdaac20 100644 --- a/docs/source/en/model_doc/lightglue.md +++ b/docs/source/en/model_doc/lightglue.md @@ -148,13 +148,9 @@ processed_outputs = processor.post_process_keypoint_matching(outputs, image_size - post_process_keypoint_matching - visualize_keypoint_matching - - ## LightGlueForKeypointMatching [[autodoc]] LightGlueForKeypointMatching - forward - - diff --git a/docs/source/en/model_doc/modernbert-decoder.md b/docs/source/en/model_doc/modernbert-decoder.md index 013b9d24b5f4..050cae276467 100644 --- a/docs/source/en/model_doc/modernbert-decoder.md +++ b/docs/source/en/model_doc/modernbert-decoder.md @@ -167,8 +167,6 @@ echo "The future of artificial intelligence is" | transformers run --task text-g [[autodoc]] ModernBertDecoderConfig - - ## ModernBertDecoderModel @@ -185,5 +183,3 @@ echo "The future of artificial intelligence is" | transformers run --task text-g [[autodoc]] ModernBertDecoderForSequenceClassification - forward - - diff --git a/docs/source/en/model_doc/modernbert.md b/docs/source/en/model_doc/modernbert.md index baef3ca863e1..872da561fbf8 100644 --- a/docs/source/en/model_doc/modernbert.md +++ b/docs/source/en/model_doc/modernbert.md @@ -93,8 +93,6 @@ echo -e "Plants create [MASK] through a process known as photosynthesis." | tran [[autodoc]] ModernBertConfig - - ## ModernBertModel @@ -131,5 +129,3 @@ echo -e "Plants create [MASK] through a process known as photosynthesis." | tran The ModernBert model can be fine-tuned using the HuggingFace Transformers library with its [official script](https://github.com/huggingface/transformers/blob/main/examples/pytorch/question-answering/run_qa.py) for question-answering tasks. - - diff --git a/docs/source/en/model_doc/phi3.md b/docs/source/en/model_doc/phi3.md index 817247288554..020b26431939 100644 --- a/docs/source/en/model_doc/phi3.md +++ b/docs/source/en/model_doc/phi3.md @@ -72,8 +72,6 @@ Phi-3 has been integrated in the development version (4.40.0.dev) of `transforme [[autodoc]] Phi3Config - - ## Phi3Model @@ -96,5 +94,3 @@ Phi-3 has been integrated in the development version (4.40.0.dev) of `transforme [[autodoc]] Phi3ForTokenClassification - forward - - diff --git a/docs/source/en/model_doc/phimoe.md b/docs/source/en/model_doc/phimoe.md index 319cbc470b91..a564eb6145af 100644 --- a/docs/source/en/model_doc/phimoe.md +++ b/docs/source/en/model_doc/phimoe.md @@ -101,8 +101,6 @@ print(output[0]['generated_text']) [[autodoc]] PhimoeConfig - - ## PhimoeModel @@ -120,5 +118,3 @@ print(output[0]['generated_text']) [[autodoc]] PhimoeForSequenceClassification - forward - - diff --git a/docs/source/en/model_doc/superglue.md b/docs/source/en/model_doc/superglue.md index 3e42b002ec6a..81bb91861de2 100644 --- a/docs/source/en/model_doc/superglue.md +++ b/docs/source/en/model_doc/superglue.md @@ -148,13 +148,9 @@ processed_outputs = processor.post_process_keypoint_matching(outputs, image_size - post_process_keypoint_matching - visualize_keypoint_matching - - ## SuperGlueForKeypointMatching [[autodoc]] SuperGlueForKeypointMatching - forward - - \ No newline at end of file diff --git a/docs/source/en/model_doc/xglm.md b/docs/source/en/model_doc/xglm.md index d82bba7d23f9..9a9170d29b7e 100644 --- a/docs/source/en/model_doc/xglm.md +++ b/docs/source/en/model_doc/xglm.md @@ -67,8 +67,6 @@ This model was contributed by [Suraj](https://huggingface.co/valhalla). The orig [[autodoc]] XGLMTokenizerFast - - ## XGLMModel diff --git a/docs/source/en/tasks/asr.md b/docs/source/en/tasks/asr.md index b1329165233a..33dc3fc518e6 100644 --- a/docs/source/en/tasks/asr.md +++ b/docs/source/en/tasks/asr.md @@ -228,8 +228,6 @@ Your `compute_metrics` function is ready to go now, and you'll return to it when ## Train - - If you aren't familiar with finetuning a model with the [`Trainer`], take a look at the basic tutorial [here](../training#train-with-pytorch-trainer)! @@ -294,8 +292,6 @@ Once training is completed, share your model to the Hub with the [`~transformers ```py >>> trainer.push_to_hub() ``` - - @@ -336,8 +332,6 @@ The transcription is decent, but it could be better! Try finetuning your model o You can also manually replicate the results of the `pipeline` if you'd like: - - Load a processor to preprocess the audio file and transcription and return the `input` as PyTorch tensors: ```py @@ -367,5 +361,3 @@ Get the predicted `input_ids` with the highest probability, and use the processo >>> transcription ['I WOUL LIKE O SET UP JOINT ACOUNT WTH Y PARTNER'] ``` - - diff --git a/docs/source/en/tasks/audio_classification.md b/docs/source/en/tasks/audio_classification.md index 973f95e1e955..52e2f965ee25 100644 --- a/docs/source/en/tasks/audio_classification.md +++ b/docs/source/en/tasks/audio_classification.md @@ -187,8 +187,6 @@ Your `compute_metrics` function is ready to go now, and you'll return to it when ## Train - - If you aren't familiar with finetuning a model with the [`Trainer`], take a look at the basic tutorial [here](../training#train-with-pytorch-trainer)! @@ -247,8 +245,6 @@ Once training is completed, share your model to the Hub with the [`~transformers ```py >>> trainer.push_to_hub() ``` - - @@ -289,8 +285,6 @@ The simplest way to try out your fine-tuned model for inference is to use it in You can also manually replicate the results of the `pipeline` if you'd like: - - Load a feature extractor to preprocess the audio file and return the `input` as PyTorch tensors: ```py @@ -320,5 +314,3 @@ Get the class with the highest probability, and use the model's `id2label` mappi >>> predicted_label 'cash_deposit' ``` - - diff --git a/docs/source/es/autoclass_tutorial.md b/docs/source/es/autoclass_tutorial.md index 7866f1e627e6..67c0911dde9e 100644 --- a/docs/source/es/autoclass_tutorial.md +++ b/docs/source/es/autoclass_tutorial.md @@ -81,8 +81,6 @@ Carga un procesador con [`AutoProcessor.from_pretrained`]: ## AutoModel - - Finalmente, las clases `AutoModelFor` te permiten cargar un modelo preentrenado para una tarea dada (revisa [aquí](model_doc/auto) para conocer la lista completa de tareas disponibles). Por ejemplo, cargue un modelo para clasificación de secuencias con [`AutoModelForSequenceClassification.from_pretrained`]: ```py @@ -100,5 +98,3 @@ Reutiliza fácilmente el mismo checkpoint para cargar una aquitectura para algun ``` Generalmente recomendamos utilizar las clases `AutoTokenizer` y `AutoModelFor` para cargar instancias pre-entrenadas de modelos. Ésto asegurará que cargues la arquitectura correcta en cada ocasión. En el siguiente [tutorial](preprocessing), aprende a usar tu tokenizador recién cargado, el extractor de características y el procesador para preprocesar un dataset para fine-tuning. - - diff --git a/docs/source/es/create_a_model.md b/docs/source/es/create_a_model.md index 2cb16267af22..4463952f4846 100644 --- a/docs/source/es/create_a_model.md +++ b/docs/source/es/create_a_model.md @@ -111,8 +111,6 @@ También puedes guardar los archivos de configuración como un diccionario; o in El siguiente paso será crear un [modelo](main_classes/models). El modelo, al que a veces también nos referimos como arquitectura, es el encargado de definir cada capa y qué operaciones se realizan. Los atributos como `num_hidden_layers` de la configuración se usan para definir la arquitectura. Todos los modelos comparten una clase base, [`PreTrainedModel`], y algunos métodos comunes que se pueden usar para redimensionar los _embeddings_ o para recortar cabezas de auto-atención (también llamadas _self-attention heads_). Además, todos los modelos son subclases de [`torch.nn.Module`](https://pytorch.org/docs/stable/generated/torch.nn.Module.html), [`tf.keras.Model`](https://www.tensorflow.org/api_docs/python/tf/keras/Model) o [`flax.linen.Module`](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html), lo que significa que son compatibles con su respectivo framework. - - Carga los atributos de tu configuración personalizada en el modelo de la siguiente forma: @@ -136,16 +134,12 @@ Cuando cargues tus pesos del preentrenamiento, el modelo por defecto se carga au ```py >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) ``` - - ### Cabezas de modelo En este punto del tutorial, tenemos un modelo DistilBERT base que devuelve los *hidden states* o estados ocultos. Los *hidden states* se pasan como parámetros de entrada a la cabeza del modelo para producir la salida. 🤗 Transformers ofrece una cabeza de modelo diferente para cada tarea, siempre y cuando el modelo sea compatible para la tarea (por ejemplo, no puedes usar DistilBERT para una tarea secuencia a secuencia como la traducción). - - Por ejemplo, [`DistilBertForSequenceClassification`] es un modelo DistilBERT base con una cabeza de clasificación de secuencias. La cabeza de clasificación de secuencias es una capa superior que precede a la recolección de las salidas. @@ -163,8 +157,6 @@ Puedes reutilizar este punto de guardado o *checkpoint* para otra tarea fácilme >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - - ## Tokenizer diff --git a/docs/source/es/quicktour.md b/docs/source/es/quicktour.md index a9433d095132..3599df38950a 100644 --- a/docs/source/es/quicktour.md +++ b/docs/source/es/quicktour.md @@ -66,14 +66,10 @@ En el siguiente ejemplo, usarás el [`pipeline`] para análisis de sentimiento. Instala las siguientes dependencias si aún no lo has hecho: - - ```bash pip install torch ``` - - Importa [`pipeline`] y especifica la tarea que deseas completar: @@ -142,8 +138,6 @@ El [`pipeline`] puede acomodarse a cualquier modelo del [Model Hub](https://hugg >>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ``` - - Usa [`AutoModelForSequenceClassification`] y ['AutoTokenizer'] para cargar un modelo preentrenado y un tokenizador asociado (más en un `AutoClass` debajo): ```py @@ -153,9 +147,7 @@ Usa [`AutoModelForSequenceClassification`] y ['AutoTokenizer'] para cargar un mo >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - - Después puedes especificar el modelo y el tokenizador en el [`pipeline`], y aplicar el `classifier` en tu texto objetivo: @@ -207,8 +199,6 @@ El tokenizador devolverá un diccionario conteniendo: Como con el [`pipeline`], el tokenizador aceptará una lista de inputs. Además, el tokenizador también puede rellenar (pad, en inglés) y truncar el texto para devolver un lote (batch, en inglés) de longitud uniforme: - - ```py >>> pt_batch = tokenizer( @@ -219,15 +209,11 @@ Como con el [`pipeline`], el tokenizador aceptará una lista de inputs. Además, ... return_tensors="pt", ... ) ``` - - Lee el tutorial de [preprocessing](./preprocessing) para más detalles acerca de la tokenización. ### AutoModel - - 🤗 Transformers provee una forma simple y unificada de cargar tus instancias preentrenadas. Esto significa que puedes cargar un [`AutoModel`] como cargarías un [`AutoTokenizer`]. La única diferencia es seleccionar el [`AutoModel`] correcto para la tarea. Ya que estás clasificando texto, o secuencias, carga [`AutoModelForSequenceClassification`]: ```py @@ -259,8 +245,6 @@ El modelo producirá las activaciones finales en el atributo `logits`. Aplica la tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - - @@ -280,8 +264,6 @@ Los outputs del modelo también se comportan como tuplas o diccionarios (e.g., p ### Guarda un modelo - - Una vez que se haya hecho fine-tuning a tu modelo puedes guardarlo con tu tokenizador usando [`PreTrainedModel.save_pretrained`]: ```py @@ -296,14 +278,10 @@ Cuando quieras usar el modelo otra vez cárgalo con [`PreTrainedModel.from_pretr >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - - Una característica particularmente interesante de 🤗 Transformers es la habilidad de guardar el modelo y cargarlo como un modelo de PyTorch o TensorFlow. El parámetro `from_pt` o `from_tf` puede convertir el modelo de un framework al otro: - - ```py >>> from transformers import AutoModel @@ -311,5 +289,3 @@ Una característica particularmente interesante de 🤗 Transformers es la habil >>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory) >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - diff --git a/docs/source/es/run_scripts.md b/docs/source/es/run_scripts.md index eb43a0f84d2b..462eb5bc3034 100644 --- a/docs/source/es/run_scripts.md +++ b/docs/source/es/run_scripts.md @@ -85,8 +85,6 @@ pip install -r requirements.txt ## Ejecutar un script - - El script de ejemplo descarga y preprocesa un conjunto de datos de la biblioteca 🤗 [Datasets](https://huggingface.co/docs/datasets/). Luego, el script ajusta un conjunto de datos con [Trainer](https://huggingface.co/docs/transformers/main_classes/trainer) en una arquitectura que soporta la tarea de resumen. El siguiente ejemplo muestra cómo ajustar un [T5-small](https://huggingface.co/google-t5/t5-small) en el conjunto de datos [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail). El modelo T5 requiere un argumento adicional `source_prefix` debido a cómo fue entrenado. Este aviso le permite a T5 saber que se trata de una tarea de resumir. ```bash @@ -103,8 +101,6 @@ python examples/pytorch/summarization/run_summarization.py \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Entrenamiento distribuido y de precisión mixta @@ -134,8 +130,6 @@ Los scripts de TensorFlow utilizan [`MirroredStrategy`](https://www.tensorflow.o ## Ejecutar un script en una TPU - - Las Unidades de Procesamiento de Tensor (TPUs) están diseñadas específicamente para acelerar el rendimiento. PyTorch admite TPU con el compilador de aprendizaje profundo [XLA](https://www.tensorflow.org/xla) (consulta [aquí](https://github.com/pytorch/xla/blob/master/README.md) para obtener más detalles). Para usar una TPU, inicia el script `xla_spawn.py` y usa el argumento `num_cores` para establecer la cantidad de núcleos de TPU que deseas usar. ```bash @@ -153,8 +147,6 @@ python xla_spawn.py --num_cores 8 \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Ejecutar un script con 🤗 Accelerate diff --git a/docs/source/es/serialization.md b/docs/source/es/serialization.md index dce3b7239a39..9c29ed6f0406 100644 --- a/docs/source/es/serialization.md +++ b/docs/source/es/serialization.md @@ -195,8 +195,6 @@ Para exportar un modelo que está almacenado localmente, deberás tener los peso y tokenizadores del modelo almacenados en un directorio. Por ejemplo, podemos cargar y guardar un checkpoint de la siguiente manera: - - ```python >>> from transformers import AutoTokenizer, AutoModelForSequenceClassification @@ -214,8 +212,6 @@ del paquete `transformers.onnx` al directorio deseado: ```bash python -m transformers.onnx --model=local-pt-checkpoint onnx/ ``` - - ### Seleccionar características para diferentes topologías de un modelo diff --git a/docs/source/es/tasks/asr.md b/docs/source/es/tasks/asr.md index d5bb614e70da..30c880d1f189 100644 --- a/docs/source/es/tasks/asr.md +++ b/docs/source/es/tasks/asr.md @@ -224,8 +224,6 @@ Ahora tu función `compute_metrics` (computar métricas) está lista y podrás u ## Entrenamiento - - Si no tienes experiencia haciéndole fine-tuning a un modelo con el [`Trainer`], ¡échale un vistazo al tutorial básico [aquí](../training#train-with-pytorch-trainer)! @@ -289,8 +287,6 @@ Una vez que el entrenamiento haya sido completado, comparte tu modelo en el Hub ```py >>> trainer.push_to_hub() ``` - - @@ -331,8 +327,6 @@ La transcripción es decente, pero podría ser mejor. ¡Intenta hacerle fine-tun También puedes replicar de forma manual los resultados del `pipeline` si lo deseas: - - Carga un procesador para preprocesar el archivo de audio y la transcripción y devuelve el `input` como un tensor de PyTorch: ```py @@ -362,5 +356,3 @@ Obtén los identificadores de los tokens con mayor probabilidad en las prediccio >>> transcription ['I WOUL LIKE O SET UP JOINT ACOUNT WTH Y PARTNER'] ``` - - diff --git a/docs/source/es/tasks/audio_classification.md b/docs/source/es/tasks/audio_classification.md index 69f180ba68ba..3b0446143262 100644 --- a/docs/source/es/tasks/audio_classification.md +++ b/docs/source/es/tasks/audio_classification.md @@ -187,8 +187,6 @@ Ahora tu función `compute_metrics` (computar métricas) está lista y podrás u ## Entrenamiento - - ¡Si no tienes experiencia haciéndo *fine-tuning* a un modelo con el [`Trainer`], échale un vistazo al tutorial básico [aquí](../training#train-with-pytorch-trainer)! @@ -246,8 +244,6 @@ Una vez que el entrenamiento haya sido completado, comparte tu modelo en el Hub ```py >>> trainer.push_to_hub() ``` - - @@ -288,8 +284,6 @@ La manera más simple de probar tu modelo para hacer inferencia es usarlo en un También puedes replicar de forma manual los resultados del `pipeline` si lo deseas: - - Carga el feature extractor para preprocesar el archivo de audio y devuelve el `input` como un tensor de PyTorch: ```py @@ -319,5 +313,3 @@ Obtén los identificadores de los clases con mayor probabilidad y usa el *mappin >>> predicted_label 'cash_deposit' ``` - - diff --git a/docs/source/es/tasks/language_modeling.md b/docs/source/es/tasks/language_modeling.md index 8d23fc199af9..b5937cdb13cf 100644 --- a/docs/source/es/tasks/language_modeling.md +++ b/docs/source/es/tasks/language_modeling.md @@ -160,8 +160,6 @@ Aplica la función `group_texts` sobre todo el dataset: Para modelados de lenguaje causales, usa [`DataCollatorForLanguageModeling`] para crear un lote de ejemplos. Esto también *rellenará dinámicamente* tu texto a la dimensión del elemento más largo del lote para que de esta manera tengan largo uniforme. Si bien es posible rellenar tu texto en la función `tokenizer` mediante el argumento `padding=True`, el rellenado dinámico es más eficiente. - - Puedes usar el token de final de secuencia como el token de relleno y asignar `mlm=False`. Esto usará los inputs como etiquetas movidas un elemento hacia la derecha: ```py @@ -179,8 +177,6 @@ Para modelados de lenguaje por enmascaramiento usa el mismo [`DataCollatorForLan >>> tokenizer.pad_token = tokenizer.eos_token >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15) ``` - - ## Modelado de lenguaje causal @@ -188,8 +184,6 @@ El modelado de lenguaje causal es frecuentemente utilizado para generación de t ### Entrenamiento - - Carga DistilGPT2 con [`AutoModelForCausalLM`]: ```py @@ -228,8 +222,6 @@ A este punto, solo faltan tres pasos: >>> trainer.train() ``` - - ## Modelado de lenguaje por enmascaramiento @@ -237,8 +229,6 @@ El modelado de lenguaje por enmascaramiento es también conocido como una tarea ### Entrenamiento - - Carga DistilRoBERTa con [`AutoModelForMaskedlM`]: ```py @@ -278,8 +268,6 @@ A este punto, solo faltan tres pasos: >>> trainer.train() ``` - - diff --git a/docs/source/es/tasks/multiple_choice.md b/docs/source/es/tasks/multiple_choice.md index fb4d988a00ff..d73688e36a8e 100644 --- a/docs/source/es/tasks/multiple_choice.md +++ b/docs/source/es/tasks/multiple_choice.md @@ -102,8 +102,6 @@ El [`DataCollatorForMultipleChoice`] aplanará todas las entradas del modelo, le ## Entrenamiento - - Carga el modelo BERT con [`AutoModelForMultipleChoice`]: ```py @@ -146,5 +144,3 @@ En este punto, solo quedan tres pasos: >>> trainer.train() ``` - - diff --git a/docs/source/es/tasks/question_answering.md b/docs/source/es/tasks/question_answering.md index 0e1bd9b1b497..085f381aa0f5 100644 --- a/docs/source/es/tasks/question_answering.md +++ b/docs/source/es/tasks/question_answering.md @@ -138,20 +138,14 @@ Quita las columnas que no necesites: Usa el [`DefaultDataCollator`] para crear un lote de ejemplos. A diferencia de los otros collators de datos en 🤗 Transformers, el `DefaultDataCollator` no aplica ningún procesamiento adicional (como el rellenado). - - ```py >>> from transformers import DefaultDataCollator >>> data_collator = DefaultDataCollator() ``` - - ## Entrenamiento - - Carga el modelo DistilBERT con [`AutoModelForQuestionAnswering`]: ```py @@ -194,8 +188,6 @@ En este punto, solo quedan tres pasos: >>> trainer.train() ``` - - diff --git a/docs/source/es/tasks/summarization.md b/docs/source/es/tasks/summarization.md index 024568c4443a..7525ccaa41f6 100644 --- a/docs/source/es/tasks/summarization.md +++ b/docs/source/es/tasks/summarization.md @@ -96,20 +96,14 @@ Usa la función [`~datasets.Dataset.map`] de 🤗 Datasets para aplicar la funci Usa [`DataCollatorForSeq2Seq`] para crear un lote de ejemplos. Esto también *rellenará dinámicamente* tu texto y etiquetas a la dimensión del elemento más largo del lote para que tengan un largo uniforme. Si bien es posible rellenar tu texto en la función `tokenizer` mediante el argumento `padding=True`, el rellenado dinámico es más eficiente. - - ```py >>> from transformers import DataCollatorForSeq2Seq >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=model) ``` - - ## Entrenamiento - - Carga T5 con [`AutoModelForSeq2SeqLM`]: ```py @@ -154,8 +148,6 @@ En este punto, solo faltan tres pasos: >>> trainer.train() ``` - - diff --git a/docs/source/fr/autoclass_tutorial.md b/docs/source/fr/autoclass_tutorial.md index 6dafd37b6d3e..3eaa2946d745 100644 --- a/docs/source/fr/autoclass_tutorial.md +++ b/docs/source/fr/autoclass_tutorial.md @@ -136,8 +136,6 @@ Chargez un processeur avec [`AutoProcessor.from_pretrained`]: ## AutoModel - - Enfin, les classes `AutoModelFor` vous permettent de charger un modèle pré-entraîné pour une tâche donnée (voir [ici](model_doc/auto) pour une liste complète des tâches disponibles). Par exemple, chargez un modèle pour la classification de séquence avec [`AutoModelForSequenceClassification.from_pretrained`]: ```py @@ -163,5 +161,3 @@ Les points de contrôle TensorFlow et Flax ne sont pas concernés, et peuvent ê En général, nous recommandons d'utiliser les classes `AutoTokenizer` et `AutoModelFor` pour charger des instances pré-entraînées de tokenizers et modèles respectivement. Cela vous permettra de charger la bonne architecture à chaque fois. Dans le prochain [tutoriel](preprocessing), vous apprenez à utiliser un tokenizer, processeur d'image, extracteur de caractéristiques et processeur pour pré-traiter un jeu de données pour le fine-tuning. - - diff --git a/docs/source/fr/quicktour.md b/docs/source/fr/quicktour.md index b2c35cffd566..a0cf66e76dd3 100644 --- a/docs/source/fr/quicktour.md +++ b/docs/source/fr/quicktour.md @@ -28,14 +28,10 @@ Avant de commencer, assurez-vous que vous avez installé toutes les bibliothèqu Vous aurez aussi besoin d'installer votre bibliothèque d'apprentissage profond favorite : - - ```bash pip install torch ``` - - ## Pipeline @@ -126,8 +122,6 @@ Le [`pipeline`] peut être utilisé avec n'importe quel modèle du [Hub](https:/ >>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ``` - - Utilisez [`AutoModelForSequenceClassification`] et [`AutoTokenizer`] pour charger le modèle pré-entraîné et le tokenizer adapté (plus de détails sur une `AutoClass` dans la section suivante) : ```py @@ -136,8 +130,6 @@ Utilisez [`AutoModelForSequenceClassification`] et [`AutoTokenizer`] pour charge >>> model = AutoModelForSequenceClassification.from_pretrained(model_name) >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - - Spécifiez le modèle et le tokenizer dans le [`pipeline`], et utilisez le `classifier` sur le texte en français : @@ -187,8 +179,6 @@ Le tokenizer retourne un dictionnaire contenant : Un tokenizer peut également accepter une liste de textes, et remplir et tronquer le texte pour retourner un échantillon de longueur uniforme : - - ```py >>> pt_batch = tokenizer( @@ -199,8 +189,6 @@ Un tokenizer peut également accepter une liste de textes, et remplir et tronque ... return_tensors="pt", ... ) ``` - - @@ -210,8 +198,6 @@ Consultez le tutoriel [prétraitement](./preprocessing) pour plus de détails su ### AutoModel - - 🤗 Transformers fournit un moyen simple et unifié de charger des instances pré-entraînées. Cela signifie que vous pouvez charger un [`AutoModel`] comme vous chargeriez un [`AutoTokenizer`]. La seule différence est de sélectionner l'[`AutoModel`] approprié pour la tâche. Pour une classification de texte (ou de séquence de textes), vous devez charger [`AutoModelForSequenceClassification`] : ```py @@ -243,8 +229,6 @@ Le modèle produit les activations finales dans l'attribut `logits`. Appliquez l tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - - @@ -254,8 +238,6 @@ Tous les modèles 🤗 Transformers (PyTorch ou TensorFlow) produisent les tenso ### Sauvegarder un modèle - - Une fois que votre modèle est finetuné, vous pouvez le sauvegarder avec son tokenizer en utilisant [`PreTrainedModel.save_pretrained`] : ```py @@ -269,13 +251,9 @@ Lorsque vous voulez réutiliser le modèle, rechargez-le avec [`PreTrainedModel. ```py >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - - Une fonctionnalité particulièrement cool 🤗 Transformers est la possibilité d'enregistrer un modèle et de le recharger en tant que modèle PyTorch ou TensorFlow. Le paramètre `from_pt` ou `from_tf` permet de convertir le modèle d'un framework à l'autre : - - ```py >>> from transformers import AutoModel @@ -283,8 +261,6 @@ Une fonctionnalité particulièrement cool 🤗 Transformers est la possibilité >>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory) >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - ## Constructions de modèles personnalisés @@ -298,8 +274,6 @@ Commencez par importer [`AutoConfig`], puis chargez le modèle pré-entraîné q >>> my_config = AutoConfig.from_pretrained("distilbert/distilbert-base-uncased", n_heads=12) ``` - - Créez un modèle personnalisé à partir de votre configuration avec [`AutoModel.from_config`] : ```py @@ -307,8 +281,6 @@ Créez un modèle personnalisé à partir de votre configuration avec [`AutoMode >>> my_model = AutoModel.from_config(my_config) ``` - - Consultez le guide [Créer une architecture personnalisée](./create_a_model) pour plus d'informations sur la création de configurations personnalisées. diff --git a/docs/source/fr/run_scripts_fr.md b/docs/source/fr/run_scripts_fr.md index 671467e52d70..1acf683253da 100644 --- a/docs/source/fr/run_scripts_fr.md +++ b/docs/source/fr/run_scripts_fr.md @@ -86,8 +86,6 @@ pip install -r requirements.txt ## Exécuter un script - - Le script d'exemple télécharge et prétraite un jeu de données à partir de la bibliothèque 🤗 [Datasets](https://huggingface.co/docs/datasets/). Ensuite, le script affine un ensemble de données à l'aide de [Trainer](https://huggingface.co/docs/transformers/main_classes/trainer) sur une architecture qui prend en charge la tâche de résumé. L'exemple suivant montre comment ajuster le modèle [T5-small](https://huggingface.co/google-t5/t5-small) sur les données [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail). Le modèle T5 nécessite un argument supplémentaire `source_prefix` en raison de la façon dont il a été entraîné. Cette invite permet à T5 de savoir qu'il s'agit d'une tâche de résumé. @@ -105,8 +103,6 @@ python examples/pytorch/summarization/run_summarization.py \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Entraînement distribué et précision mixte @@ -136,8 +132,6 @@ Les scripts TensorFlow utilisent une Strategie en Miroir [`MirroredStrategy`](ht ## Exécuter un script sur un TPU - - Les unités de traitement de tenseurs (UTT) (TPU) sont spécialement conçues pour accélérer les performances. PyTorch prend en charge les TPU avec le compilateur de deep learning [XLA](https://www.tensorflow.org/xla). Pour utiliser un TPU, lancez le script xla_spawn.py et utilisez l'argument num_cores pour définir le nombre de cœurs TPU que vous souhaitez utilise @@ -156,8 +150,6 @@ python xla_spawn.py --num_cores 8 \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Exécuter un script avec 🤗 Accelerate diff --git a/docs/source/it/autoclass_tutorial.md b/docs/source/it/autoclass_tutorial.md index e823fd5f5cb6..74587ef53c19 100644 --- a/docs/source/it/autoclass_tutorial.md +++ b/docs/source/it/autoclass_tutorial.md @@ -80,8 +80,6 @@ Carica un processore con [`AutoProcessor.from_pretrained`]: ## AutoModel - - Infine, le classi `AutoModelFor` ti permettono di caricare un modello pre-allenato per un determinato compito (guarda [qui](model_doc/auto) per una lista completa di compiti presenti). Per esempio, carica un modello per la classificazione di sequenze con [`AutoModelForSequenceClassification.from_pretrained`]: ```py @@ -100,5 +98,3 @@ Semplicemente utilizza lo stesso checkpoint per caricare un'architettura per un Generalmente, raccomandiamo di utilizzare la classe `AutoTokenizer` e la classe `AutoModelFor` per caricare istanze pre-allenate dei modelli. Questo ti assicurerà di aver caricato la corretta architettura ogni volta. Nel prossimo [tutorial](preprocessing), imparerai come utilizzare il tokenizer, il feature extractor e il processore per elaborare un dataset per il fine-tuning. - - diff --git a/docs/source/it/create_a_model.md b/docs/source/it/create_a_model.md index b5c594ae03cd..174083e73e67 100644 --- a/docs/source/it/create_a_model.md +++ b/docs/source/it/create_a_model.md @@ -111,8 +111,6 @@ Puoi anche salvare il file di configurazione come dizionario oppure come la diff Il prossimo passo e di creare [modello](main_classes/models). Il modello - vagamente riferito anche come architettura - definisce cosa ogni strato deve fare e quali operazioni stanno succedendo. Attributi come `num_hidden_layers` provenienti dalla configurazione sono usati per definire l'architettura. Ogni modello condivide la classe base [`PreTrainedModel`] e alcuni metodi comuni come il ridimensionamento degli input embeddings e la soppressione delle self-attention heads . Inoltre, tutti i modelli sono la sottoclasse di [`torch.nn.Module`](https://pytorch.org/docs/stable/generated/torch.nn.Module.html), [`tf.keras.Model`](https://www.tensorflow.org/api_docs/python/tf/keras/Model) o [`flax.linen.Module`](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html). Cio significa che i modelli sono compatibili con l'uso di ciascun di framework. - - Carica gli attributi della tua configurazione personalizzata nel modello: ```py @@ -135,15 +133,11 @@ Quando carichi pesi pre-allenati, la configurazione del modello predefinito è a ```py >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) ``` - - ### Model head A questo punto, hai un modello DistilBERT base i cui output sono gli *hidden states* (in italiano stati nascosti). Gli stati nascosti sono passati come input a un model head per produrre l'output finale. 🤗 Transformers fornisce un model head diverso per ogni attività fintanto che il modello supporta l'attività (i.e., non puoi usare DistilBERT per un attività sequence-to-sequence come la traduzione). - - Per esempio, [`DistilBertForSequenceClassification`] è un modello DistilBERT base con una testa di classificazione per sequenze. La sequenza di classificazione head è uno strato lineare sopra gli output ragruppati. ```py @@ -159,8 +153,6 @@ Riutilizza facilmente questo checkpoint per un'altra attività passando ad un mo >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - - ## Tokenizer diff --git a/docs/source/it/model_sharing.md b/docs/source/it/model_sharing.md index 7c527d5cd771..ce06ade1fe2c 100644 --- a/docs/source/it/model_sharing.md +++ b/docs/source/it/model_sharing.md @@ -79,8 +79,6 @@ Per assicurarti che il tuo modello possa essere utilizzato da persone che lavora Convertire un checkpoint per un altro framework è semplice. Assicurati di avere PyTorch e TensorFlow installati (vedi [qui](installation) per le istruzioni d'installazione), e poi trova il modello specifico per il tuo compito nell'altro framework. - - Specifica `from_tf=True` per convertire un checkpoint da TensorFlow a PyTorch: ```py @@ -89,13 +87,9 @@ Specifica `from_tf=True` per convertire un checkpoint da TensorFlow a PyTorch: ... ) >>> pt_model.save_pretrained("path/verso/il-nome-magnifico-che-hai-scelto") ``` - - ## Condividi un modello durante il training - - Condividere un modello nell'Hub è tanto semplice quanto aggiungere un parametro extra o un callback. Ricorda dal [tutorial sul fine-tuning](training), la classe [`TrainingArguments`] è dove specifichi gli iperparametri e le opzioni addizionali per l'allenamento. Una di queste opzioni di training include l'abilità di condividere direttamente un modello nell'Hub. Imposta `push_to_hub=True` in [`TrainingArguments`]: @@ -121,8 +115,6 @@ Dopo aver effettuato il fine-tuning del tuo modello, chiama [`~transformers.Trai ```py >>> trainer.push_to_hub() ``` - - ## Utilizzare la funzione `push_to_hub` diff --git a/docs/source/it/quicktour.md b/docs/source/it/quicktour.md index dda825c801e5..06295d10275d 100644 --- a/docs/source/it/quicktour.md +++ b/docs/source/it/quicktour.md @@ -66,14 +66,10 @@ Nel seguente esempio, utilizzerai la [`pipeline`] per l'analisi del sentimento. Installa le seguenti dipendenze se non lo hai già fatto: - - ```bash pip install torch ``` - - Importa [`pipeline`] e specifica il compito che vuoi completare: @@ -152,8 +148,6 @@ La [`pipeline`] può ospitare qualsiasi modello del [Model Hub](https://huggingf >>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ``` - - Usa [`AutoModelForSequenceClassification`] e [`AutoTokenizer`] per caricare il modello pre-allenato e il suo tokenizer associato (maggiori informazioni su una `AutoClass` in seguito): ```py @@ -162,8 +156,6 @@ Usa [`AutoModelForSequenceClassification`] e [`AutoTokenizer`] per caricare il m >>> model = AutoModelForSequenceClassification.from_pretrained(model_name) >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - - Poi puoi specificare il modello e il tokenizer nella [`pipeline`], e applicare il `classifier` sul tuo testo obiettivo: @@ -215,8 +207,6 @@ Il tokenizer restituirà un dizionario contenente: Come con la [`pipeline`], il tokenizer accetterà una lista di input. In più, il tokenizer può anche completare (pad, in inglese) e troncare il testo in modo da restituire un lotto (batch, in inglese) di lunghezza uniforme: - - ```py >>> pt_batch = tokenizer( ... ["Siamo molto felici di mostrarti la libreria 🤗 Transformers.", "Speriamo te non la odierai."], @@ -226,15 +216,11 @@ Come con la [`pipeline`], il tokenizer accetterà una lista di input. In più, i ... return_tensors="pt", ... ) ``` - - Leggi il tutorial sul [preprocessing](./preprocessing) per maggiori dettagli sulla tokenizzazione. ### AutoModel - - 🤗 Transformers fornisce un metodo semplice e unificato per caricare istanze pre-allenate. Questo significa che puoi caricare un [`AutoModel`] come caricheresti un [`AutoTokenizer`]. L'unica differenza è selezionare l'[`AutoModel`] corretto per il compito di interesse. Dato che stai facendo classificazione di testi, o sequenze, carica [`AutoModelForSequenceClassification`]: ```py @@ -266,8 +252,6 @@ Il modello produrrà le attivazioni finali nell'attributo `logits`. Applica la f tensor([[0.0041, 0.0037, 0.0203, 0.2005, 0.7713], [0.3766, 0.3292, 0.1832, 0.0558, 0.0552]], grad_fn=) ``` - - @@ -287,8 +271,6 @@ Gli output del modello si comportano anche come una tupla o un dizionario (ad es ### Salva un modello - - Una volta completato il fine-tuning del tuo modello, puoi salvarlo con il suo tokenizer utilizzando [`PreTrainedModel.save_pretrained`]: ```py @@ -302,13 +284,9 @@ Quando desideri utilizzare il tuo modello nuovamente, puoi ri-caricarlo con [`Pr ```py >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - - Una caratteristica particolarmente interessante di 🤗 Transformers è la sua abilità di salvare un modello e ri-caricarlo sia come modello di PyTorch che di TensorFlow. I parametri `from_pt` o `from_tf` possono convertire un modello da un framework all'altro: - - ```py >>> from transformers import AutoModel @@ -316,5 +294,3 @@ Una caratteristica particolarmente interessante di 🤗 Transformers è la sua a >>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory) >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - diff --git a/docs/source/it/run_scripts.md b/docs/source/it/run_scripts.md index 0d3f2d32351d..ad7df423cb96 100644 --- a/docs/source/it/run_scripts.md +++ b/docs/source/it/run_scripts.md @@ -84,8 +84,6 @@ pip install -r requirements.txt ## Esegui uno script - - Lo script di esempio scarica e pre-processa un dataset dalla libreria 🤗 [Datasets](https://huggingface.co/docs/datasets/). Successivamente, lo script esegue il fine-tuning su un dataset usando il [Trainer](https://huggingface.co/docs/transformers/main_classes/trainer) su un'architettura che supporta la summarization. Il seguente esempio mostra come eseguire il fine-tuning di [T5-small](https://huggingface.co/google-t5/t5-small) sul dataset [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail). Il modello T5 richiede un parametro addizionale `source_prefix` a causa del modo in cui è stato addestrato. Questo prefisso permette a T5 di sapere che si tratta di un task di summarization. @@ -103,8 +101,6 @@ python examples/pytorch/summarization/run_summarization.py \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Addestramento distribuito e precisione mista @@ -134,8 +130,6 @@ Gli script TensorFlow utilizzano una [`MirroredStrategy`](https://www.tensorflow ## Esegui uno script su TPU - - Le Tensor Processing Units (TPU) sono state progettate per migliorare le prestazioni. PyTorch supporta le TPU con il compilatore per deep learning [XLA](https://www.tensorflow.org/xla) (guarda [questo link](https://github.com/pytorch/xla/blob/master/README.md) per maggiori dettagli). Per usare una TPU, avvia lo script `xla_spawn.py` e usa l'argomento `num_cores` per impostare il numero di core TPU che intendi usare. ```bash @@ -153,8 +147,6 @@ python xla_spawn.py --num_cores 8 \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Esegui uno script con 🤗 Accelerate diff --git a/docs/source/it/serialization.md b/docs/source/it/serialization.md index 2edd837533f2..53e16d927eb9 100644 --- a/docs/source/it/serialization.md +++ b/docs/source/it/serialization.md @@ -181,8 +181,6 @@ Per esportare un modello memorizzato localmente, devi disporre dei pesi del mode e file tokenizer memorizzati in una directory. Ad esempio, possiamo caricare e salvare un checkpoint come segue: - - ```python >>> from transformers import AutoTokenizer, AutoModelForSequenceClassification @@ -200,8 +198,6 @@ del pacchetto `transformers.onnx` nella directory desiderata: ```bash python -m transformers.onnx --model=local-pt-checkpoint onnx/ ``` - - ### Selezione delle caratteristiche per diverse topologie di modello diff --git a/docs/source/it/training.md b/docs/source/it/training.md index 9772ff4a5bbc..76cd41afc56d 100644 --- a/docs/source/it/training.md +++ b/docs/source/it/training.md @@ -69,8 +69,6 @@ Se vuoi, puoi creare un sottoinsieme più piccolo del dataset per il fine-tuning ## Addestramento - - 🤗 Transformers mette a disposizione la classe [`Trainer`] ottimizzata per addestrare modelli 🤗 Transformers, rendendo semplice iniziare l'addestramento senza scrivere manualmente il tuo ciclo di addestramento. L'API [`Trainer`] supporta un'ampia gamma di opzioni e funzionalità di addestramento come logging, gradient accumulation e mixed precision. @@ -148,15 +146,11 @@ Poi metti a punto il modello richiamando [`~transformers.Trainer.train`]: ```py >>> trainer.train() ``` - - ## Addestramento in PyTorch nativo - - [`Trainer`] si occupa del ciclo di addestramento e ti consente di mettere a punto un modello con una sola riga di codice. Per chi preferisse scrivere un proprio ciclo di addestramento personale, puoi anche fare il fine-tuning di un modello 🤗 Transformers in PyTorch nativo. @@ -296,8 +290,6 @@ Proprio come è necessario aggiungere una funzione di valutazione del [`Trainer` >>> metric.compute() ``` - - diff --git a/docs/source/ja/autoclass_tutorial.md b/docs/source/ja/autoclass_tutorial.md index f28a2b042b19..6b5c552cd7b6 100644 --- a/docs/source/ja/autoclass_tutorial.md +++ b/docs/source/ja/autoclass_tutorial.md @@ -102,8 +102,6 @@ http://www.apache.org/licenses/LICENSE-2.0 ## AutoModel - - 最後に、`AutoModelFor`クラスは特定のタスクに対して事前学習済みモデルをロードできます(使用可能なタスクの完全な一覧については[こちら](model_doc/auto)を参照)。 たとえば、[`AutoModelForSequenceClassification.from_pretrained`]を使用してシーケンス分類用のモデルをロードできます: @@ -135,5 +133,3 @@ TensorFlowおよびFlaxのチェックポイントには影響がなく、`from_ 一般的に、事前学習済みモデルのインスタンスをロードするために`AutoTokenizer`クラスと`AutoModelFor`クラスの使用をお勧めします。 これにより、常に正しいアーキテクチャをロードできます。 次の[tutorial](preprocessing)では、新しくロードしたトークナイザ、画像プロセッサ、特徴量抽出器、およびプロセッサを使用して、ファインチューニング用にデータセットを前処理する方法を学びます。 - - diff --git a/docs/source/ja/create_a_model.md b/docs/source/ja/create_a_model.md index 913e992d5a9f..d708070c3daf 100644 --- a/docs/source/ja/create_a_model.md +++ b/docs/source/ja/create_a_model.md @@ -116,8 +116,6 @@ Once you are satisfied with your model configuration, you can save it with [`Pre すべてのモデルは [`PreTrainedModel`] をベースクラスとし、入力埋め込みのリサイズやセルフアテンションヘッドのプルーニングなど、共通のメソッドがいくつかあります。 さらに、すべてのモデルは [`torch.nn.Module`](https://pytorch.org/docs/stable/generated/torch.nn.Module.html)、[`tf.keras.Model`](https://www.tensorflow.org/api_docs/python/tf/keras/Model)、または [`flax.linen.Module`](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) のいずれかのサブクラスでもあります。つまり、モデルはそれぞれのフレームワークの使用法と互換性があります。 - - モデルにカスタム構成属性をロードします: ```py @@ -144,16 +142,12 @@ Once you are satisfied with your model configuration, you can save it with [`Pre ```py >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) ``` - - ### Model heads この時点で、ベースのDistilBERTモデルがあり、これは隠れた状態を出力します。隠れた状態はモデルのヘッドへの入力として渡され、最終的な出力を生成します。🤗 Transformersは、モデルがそのタスクをサポートしている限り、各タスクに対応する異なるモデルヘッドを提供します(つまり、DistilBERTを翻訳のようなシーケンス対シーケンスタスクに使用することはできません)。 - - たとえば、[`DistilBertForSequenceClassification`]は、シーケンス分類ヘッドを持つベースのDistilBERTモデルです。シーケンス分類ヘッドは、プールされた出力の上にある線形層です。 ```py @@ -172,8 +166,6 @@ Once you are satisfied with your model configuration, you can save it with [`Pre >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - - ## Tokenizer diff --git a/docs/source/ja/model_doc/albert.md b/docs/source/ja/model_doc/albert.md index b81723f1910d..e2fccbd8bfc5 100644 --- a/docs/source/ja/model_doc/albert.md +++ b/docs/source/ja/model_doc/albert.md @@ -73,8 +73,6 @@ ALBERTモデルは、「[ALBERT: A Lite BERT for Self-supervised Learning of Lan [[autodoc]] models.albert.modeling_albert.AlbertForPreTrainingOutput - - ## AlbertModel @@ -110,4 +108,3 @@ ALBERTモデルは、「[ALBERT: A Lite BERT for Self-supervised Learning of Lan [[autodoc]] AlbertForQuestionAnswering - forward - diff --git a/docs/source/ja/model_doc/bert.md b/docs/source/ja/model_doc/bert.md index 306b894db219..0ccd41cf13d8 100644 --- a/docs/source/ja/model_doc/bert.md +++ b/docs/source/ja/model_doc/bert.md @@ -138,22 +138,16 @@ BERT を始めるのに役立つ公式 Hugging Face およびコミュニティ - create_token_type_ids_from_sequences - save_vocabulary - - ## BertTokenizerFast [[autodoc]] BertTokenizerFast - - ## Bert specific outputs [[autodoc]] models.bert.modeling_bert.BertForPreTrainingOutput - - ## BertModel @@ -200,5 +194,3 @@ BERT を始めるのに役立つ公式 Hugging Face およびコミュニティ [[autodoc]] BertForQuestionAnswering - forward - - \ No newline at end of file diff --git a/docs/source/ja/model_doc/big_bird.md b/docs/source/ja/model_doc/big_bird.md index cec7cdf5f319..85248036af79 100644 --- a/docs/source/ja/model_doc/big_bird.md +++ b/docs/source/ja/model_doc/big_bird.md @@ -85,8 +85,6 @@ BigBird は、質問応答や要約などのさまざまな NLP タスクのパ [[autodoc]] models.big_bird.modeling_big_bird.BigBirdForPreTrainingOutput - - ## BigBirdModel @@ -128,6 +126,4 @@ BigBird は、質問応答や要約などのさまざまな NLP タスクのパ [[autodoc]] BigBirdForQuestionAnswering - forward - - diff --git a/docs/source/ja/model_doc/blip.md b/docs/source/ja/model_doc/blip.md index 4cba6d0c936b..bda95695923f 100644 --- a/docs/source/ja/model_doc/blip.md +++ b/docs/source/ja/model_doc/blip.md @@ -66,8 +66,6 @@ BLIP は、次のようなさまざまなマルチモーダル タスクを実 [[autodoc]] BlipImageProcessorFast - preprocess - - ## BlipModel @@ -101,5 +99,3 @@ BLIP は、次のようなさまざまなマルチモーダル タスクを実 [[autodoc]] BlipForQuestionAnswering - forward - - \ No newline at end of file diff --git a/docs/source/ja/model_doc/bloom.md b/docs/source/ja/model_doc/bloom.md index 159802882467..26d60ae7e5bb 100644 --- a/docs/source/ja/model_doc/bloom.md +++ b/docs/source/ja/model_doc/bloom.md @@ -62,8 +62,6 @@ BLOOM を使い始めるのに役立つ公式 Hugging Face およびコミュニ - all - - ## BloomModel @@ -90,5 +88,3 @@ BLOOM を使い始めるのに役立つ公式 Hugging Face およびコミュニ [[autodoc]] BloomForQuestionAnswering - forward - - diff --git a/docs/source/ja/model_doc/camembert.md b/docs/source/ja/model_doc/camembert.md index c0d6a4fdb7f0..ee33721102e1 100644 --- a/docs/source/ja/model_doc/camembert.md +++ b/docs/source/ja/model_doc/camembert.md @@ -69,8 +69,6 @@ Bi-direction Encoders for Transformers (BERT) のフランス語版である Cam [[autodoc]] CamembertTokenizerFast - - ## CamembertModel @@ -100,5 +98,3 @@ Bi-direction Encoders for Transformers (BERT) のフランス語版である Cam [[autodoc]] CamembertForQuestionAnswering - - diff --git a/docs/source/ja/model_doc/clip.md b/docs/source/ja/model_doc/clip.md index 3e785a2b310e..ac6cb606a52c 100644 --- a/docs/source/ja/model_doc/clip.md +++ b/docs/source/ja/model_doc/clip.md @@ -146,8 +146,6 @@ CLIP を使い始めるのに役立つ公式 Hugging Face およびコミュニ [[autodoc]] CLIPProcessor - - ## CLIPModel @@ -176,5 +174,3 @@ CLIP を使い始めるのに役立つ公式 Hugging Face およびコミュニ [[autodoc]] CLIPVisionModel - forward - - diff --git a/docs/source/ja/model_doc/convbert.md b/docs/source/ja/model_doc/convbert.md index 5112a64366ff..f904592aba24 100644 --- a/docs/source/ja/model_doc/convbert.md +++ b/docs/source/ja/model_doc/convbert.md @@ -75,8 +75,6 @@ ConvBERT トレーニングのヒントは BERT のヒントと似ています [[autodoc]] ConvBertTokenizerFast - - ## ConvBertModel @@ -108,5 +106,3 @@ ConvBERT トレーニングのヒントは BERT のヒントと似ています [[autodoc]] ConvBertForQuestionAnswering - forward - - diff --git a/docs/source/ja/model_doc/convnext.md b/docs/source/ja/model_doc/convnext.md index a733b0923c29..46672f38cbf9 100644 --- a/docs/source/ja/model_doc/convnext.md +++ b/docs/source/ja/model_doc/convnext.md @@ -69,8 +69,6 @@ ConvNeXT の使用を開始するのに役立つ公式 Hugging Face およびコ [[autodoc]] ConvNextImageProcessorFast - preprocess - - ## ConvNextModel @@ -82,5 +80,3 @@ ConvNeXT の使用を開始するのに役立つ公式 Hugging Face およびコ [[autodoc]] ConvNextForImageClassification - forward - - \ No newline at end of file diff --git a/docs/source/ja/model_doc/ctrl.md b/docs/source/ja/model_doc/ctrl.md index 260649ef01a3..44b6892cdc02 100644 --- a/docs/source/ja/model_doc/ctrl.md +++ b/docs/source/ja/model_doc/ctrl.md @@ -73,8 +73,6 @@ CTRL モデルは、Nitish Shirish Keskar*、Bryan McCann*、Lav R. Varshney、C [[autodoc]] CTRLTokenizer - save_vocabulary - - ## CTRLModel @@ -91,5 +89,3 @@ CTRL モデルは、Nitish Shirish Keskar*、Bryan McCann*、Lav R. Varshney、C [[autodoc]] CTRLForSequenceClassification - forward - - diff --git a/docs/source/ja/model_doc/cvt.md b/docs/source/ja/model_doc/cvt.md index 86f54afafee9..51616de75b26 100644 --- a/docs/source/ja/model_doc/cvt.md +++ b/docs/source/ja/model_doc/cvt.md @@ -57,8 +57,6 @@ CvT を始めるのに役立つ公式 Hugging Face およびコミュニティ ( [[autodoc]] CvtConfig - - ## CvtModel @@ -70,6 +68,4 @@ CvT を始めるのに役立つ公式 Hugging Face およびコミュニティ ( [[autodoc]] CvtForImageClassification - forward - - diff --git a/docs/source/ja/model_doc/data2vec.md b/docs/source/ja/model_doc/data2vec.md index 53f389223d1f..b01e43b4a6f5 100644 --- a/docs/source/ja/model_doc/data2vec.md +++ b/docs/source/ja/model_doc/data2vec.md @@ -87,8 +87,6 @@ Data2Vec の使用を開始するのに役立つ公式 Hugging Face およびコ [[autodoc]] Data2VecVisionConfig - - ## Data2VecAudioModel @@ -165,5 +163,3 @@ Data2Vec の使用を開始するのに役立つ公式 Hugging Face およびコ [[autodoc]] Data2VecVisionForSemanticSegmentation - forward - - diff --git a/docs/source/ja/model_doc/deberta-v2.md b/docs/source/ja/model_doc/deberta-v2.md index 0054b6ad3dbf..26202c8bb522 100644 --- a/docs/source/ja/model_doc/deberta-v2.md +++ b/docs/source/ja/model_doc/deberta-v2.md @@ -85,8 +85,6 @@ v2 の新機能: - build_inputs_with_special_tokens - create_token_type_ids_from_sequences - - ## DebertaV2Model @@ -123,7 +121,5 @@ v2 の新機能: [[autodoc]] DebertaV2ForMultipleChoice - forward - - diff --git a/docs/source/ja/model_doc/deberta.md b/docs/source/ja/model_doc/deberta.md index 1a7ae534911a..39ce6d854292 100644 --- a/docs/source/ja/model_doc/deberta.md +++ b/docs/source/ja/model_doc/deberta.md @@ -94,8 +94,6 @@ DeBERTa を使い始めるのに役立つ公式 Hugging Face およびコミュ - build_inputs_with_special_tokens - create_token_type_ids_from_sequences - - ## DebertaModel @@ -126,6 +124,4 @@ DeBERTa を使い始めるのに役立つ公式 Hugging Face およびコミュ [[autodoc]] DebertaForQuestionAnswering - forward - - diff --git a/docs/source/ja/model_doc/deit.md b/docs/source/ja/model_doc/deit.md index 3332d3f16738..7be69bd9972f 100644 --- a/docs/source/ja/model_doc/deit.md +++ b/docs/source/ja/model_doc/deit.md @@ -103,8 +103,6 @@ DeiT を始めるのに役立つ公式 Hugging Face およびコミュニティ [[autodoc]] DeiTImageProcessorFast - preprocess - - ## DeiTModel @@ -126,5 +124,3 @@ DeiT を始めるのに役立つ公式 Hugging Face およびコミュニティ [[autodoc]] DeiTForImageClassificationWithTeacher - forward - - \ No newline at end of file diff --git a/docs/source/ja/model_sharing.md b/docs/source/ja/model_sharing.md index f602208f04e5..4a282ee6134e 100644 --- a/docs/source/ja/model_sharing.md +++ b/docs/source/ja/model_sharing.md @@ -85,21 +85,15 @@ PyTorchおよびTensorFlowのチェックポイントでモデルを変換して PyTorchとTensorFlowがインストールされていることを確認してください(インストール手順については[こちら](installation)を参照)し、 その後、他のフレームワーク向けに特定のタスク用のモデルを見つけます。 - - TensorFlowからPyTorchにチェックポイントを変換するには、`from_tf=True`を指定します: ```python >>> pt_model = DistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_tf=True) >>> pt_model.save_pretrained("path/to/awesome-name-you-picked") ``` - - ## Push a model during traning - - モデルをHubにプッシュすることは、追加のパラメーターまたはコールバックを追加するだけで簡単です。 @@ -140,8 +134,6 @@ Pass your training arguments as usual to [`Trainer`]: >>> trainer.push_to_hub() ``` - - ## `push_to_hub` 関数を使用する diff --git a/docs/source/ja/preprocessing.md b/docs/source/ja/preprocessing.md index 9f61595e7c33..cb1129a8355e 100644 --- a/docs/source/ja/preprocessing.md +++ b/docs/source/ja/preprocessing.md @@ -174,8 +174,6 @@ pip install datasets `return_tensors`パラメータを`pt`(PyTorch用)または`tf`(TensorFlow用)に設定します: - - ```py >>> batch_sentences = [ @@ -195,8 +193,6 @@ pip install datasets [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])} ``` - - ## Audio diff --git a/docs/source/ja/quicktour.md b/docs/source/ja/quicktour.md index e077d512df4f..44a154a614c5 100644 --- a/docs/source/ja/quicktour.md +++ b/docs/source/ja/quicktour.md @@ -31,14 +31,10 @@ specific language governing permissions and limitations under the License. あなたはまた、好きな機械学習フレームワークをインストールする必要があります: - - ```bash pip install torch ``` - - ## Pipeline @@ -137,8 +133,6 @@ label: NEGATIVE, スコア: 0.5309 >>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ``` - - [`AutoModelForSequenceClassification`]と[`AutoTokenizer`]を使用して事前学習済みモデルとそれに関連するトークナイザをロードします(次のセクションで`AutoClass`について詳しく説明します): ```python @@ -148,8 +142,6 @@ label: NEGATIVE, スコア: 0.5309 >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - - 指定したモデルとトークナイザを[`pipeline`]に設定し、今度はフランス語のテキストに`classifier`を適用できます: @@ -206,8 +198,6 @@ Pass your text to the tokenizer: トークナイザはまた、入力のリストを受け入れ、一様な長さのバッチを返すためにテキストをパディングおよび切り詰めることができます。 - - ```py >>> pt_batch = tokenizer( @@ -218,8 +208,6 @@ Pass your text to the tokenizer: ... return_tensors="pt", ... ) ``` - - @@ -229,8 +217,6 @@ Pass your text to the tokenizer: ### AutoModel - - 🤗 Transformersは事前学習済みインスタンスを簡単に統一的にロードする方法を提供します。 これは、[`AutoTokenizer`]をロードするのと同じように[`AutoModel`]をロードできることを意味します。 タスクに適した[`AutoModel`]を選択する以外の違いはありません。 @@ -266,8 +252,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - - @@ -280,8 +264,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ### Save a Model - - モデルをファインチューニングしたら、[`PreTrainedModel.save_pretrained`]を使用してトークナイザと共に保存できます: ```py @@ -296,13 +278,9 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - - 🤗 Transformersの特に素晴らしい機能の一つは、モデルを保存し、それをPyTorchモデルまたはTensorFlowモデルとして再ロードできることです。 `from_pt`または`from_tf`パラメータを使用してモデルをフレームワーク間で変換できます: - - ```py >>> from transformers import AutoModel @@ -311,8 +289,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - ## Custom model builds @@ -326,8 +302,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_config = AutoConfig.from_pretrained("distilbert/distilbert-base-uncased", n_heads=12) ``` - - [`AutoModel.from_config`]を使用してカスタム設定からモデルを作成します: ```python @@ -336,8 +310,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_model = AutoModel.from_config(my_config) ``` - - [カスタムアーキテクチャを作成](./create_a_model)ガイドを参照して、カスタム構成の詳細情報を確認してください。 diff --git a/docs/source/ja/run_scripts.md b/docs/source/ja/run_scripts.md index af0c1fdb1a50..ee738e3e4313 100644 --- a/docs/source/ja/run_scripts.md +++ b/docs/source/ja/run_scripts.md @@ -90,8 +90,6 @@ pip install -r requirements.txt ## Run a script - - この例のスクリプトは、🤗 [Datasets](https://huggingface.co/docs/datasets/) ライブラリからデータセットをダウンロードし、前処理を行います。次に、[Trainer](https://huggingface.co/docs/transformers/main_classes/trainer) を使用して要約をサポートするアーキテクチャ上でデータセットをファインチューニングします。以下の例では、[CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail) データセット上で [T5-small](https://huggingface.co/google-t5/t5-small) をファインチューニングする方法が示されています。T5 モデルは、そのトレーニング方法に起因して追加の `source_prefix` 引数が必要です。このプロンプトにより、T5 はこれが要約タスクであることを知ることができます。 @@ -110,8 +108,6 @@ python examples/pytorch/summarization/run_summarization.py \ --predict_with_generate ``` - - ## Distributed training and mixed precision @@ -144,8 +140,6 @@ TensorFlowスクリプトは、分散トレーニングに[`MirroredStrategy`](h ## Run a script on a TPU - - Tensor Processing Units (TPUs)は、パフォーマンスを加速させるために特別に設計されています。PyTorchは、[XLA](https://www.tensorflow.org/xla)ディープラーニングコンパイラを使用してTPUsをサポートしており、詳細については[こちら](https://github.com/pytorch/xla/blob/master/README.md)をご覧ください。TPUを使用するには、`xla_spawn.py`スクリプトを起動し、`num_cores`引数を使用して使用するTPUコアの数を設定します。 ```bash python xla_spawn.py --num_cores 8 \ @@ -162,8 +156,6 @@ python xla_spawn.py --num_cores 8 \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Run a script with 🤗 Accelerate diff --git a/docs/source/ja/tasks/asr.md b/docs/source/ja/tasks/asr.md index 5e460a102f44..4ccb31667423 100644 --- a/docs/source/ja/tasks/asr.md +++ b/docs/source/ja/tasks/asr.md @@ -228,8 +228,6 @@ MInDS-14 データセットのサンプリング レートは 8000kHz です ( ## Train - - [`Trainer`] を使用したモデルの微調整に慣れていない場合は、[ここ](../training#train-with-pytorch-trainer) の基本的なチュートリアルをご覧ください。 @@ -295,8 +293,6 @@ MInDS-14 データセットのサンプリング レートは 8000kHz です ( >>> trainer.push_to_hub() ``` - - @@ -337,8 +333,6 @@ MInDS-14 データセットのサンプリング レートは 8000kHz です ( 必要に応じて、「パイプライン」の結果を手動で複製することもできます。 - - プロセッサをロードしてオーディオ ファイルと文字起こしを前処理し、`input`を PyTorch テンソルとして返します。 @@ -371,5 +365,3 @@ Pass your inputs to the model and return the logits: ['I WOUL LIKE O SET UP JOINT ACOUNT WTH Y PARTNER'] ``` - - diff --git a/docs/source/ja/tasks/audio_classification.md b/docs/source/ja/tasks/audio_classification.md index 3b33d1b6043d..d37485cbe226 100644 --- a/docs/source/ja/tasks/audio_classification.md +++ b/docs/source/ja/tasks/audio_classification.md @@ -186,8 +186,6 @@ MInDS-14 データセットのサンプリング レートは 8khz です (こ ## Train - - [`Trainer`] を使用したモデルの微調整に慣れていない場合は、[こちら](../training#train-with-pytorch-trainer) の基本的なチュートリアルをご覧ください。 @@ -245,8 +243,6 @@ MInDS-14 データセットのサンプリング レートは 8khz です (こ ```py >>> trainer.push_to_hub() ``` - - @@ -287,8 +283,6 @@ MInDS-14 データセットのサンプリング レートは 8khz です (こ 必要に応じて、`pipeline` の結果を手動で複製することもできます。 - - 特徴抽出器をロードしてオーディオ ファイルを前処理し、`input`を PyTorch テンソルとして返します。 @@ -319,5 +313,3 @@ MInDS-14 データセットのサンプリング レートは 8khz です (こ >>> predicted_label 'cash_deposit' ``` - - diff --git a/docs/source/ja/tasks/image_classification.md b/docs/source/ja/tasks/image_classification.md index 3a048e396eff..32c30dcff7c8 100644 --- a/docs/source/ja/tasks/image_classification.md +++ b/docs/source/ja/tasks/image_classification.md @@ -111,8 +111,6 @@ Datasets、🤗 データセット ライブラリから Food-101 データセ ``` - - いくつかの画像変換を画像に適用して、モデルの過学習に対する堅牢性を高めます。ここでは torchvision の [`transforms`](https://pytorch.org/vision/stable/transforms.html) モジュールを使用しますが、任意の画像ライブラリを使用することもできます。 @@ -153,8 +151,6 @@ Datasets、🤗 データセット ライブラリから Food-101 データセ >>> data_collator = DefaultDataCollator() ``` - - ## Evaluate @@ -184,8 +180,6 @@ Datasets、🤗 データセット ライブラリから Food-101 データセ ## Train - - [`Trainer`] を使用したモデルの微調整に慣れていない場合は、[こちら](../training#train-with-pytorch-trainer) の基本的なチュートリアルをご覧ください。 @@ -247,8 +241,6 @@ Datasets、🤗 データセット ライブラリから Food-101 データセ ```py >>> trainer.push_to_hub() ``` - - @@ -287,8 +279,6 @@ Datasets、🤗 データセット ライブラリから Food-101 データセ 必要に応じて、`pipeline`の結果を手動で複製することもできます。 - - 画像プロセッサをロードして画像を前処理し、`input`を PyTorch テンソルとして返します。 @@ -317,5 +307,3 @@ Datasets、🤗 データセット ライブラリから Food-101 データセ >>> model.config.id2label[predicted_label] 'beignets' ``` - - diff --git a/docs/source/ja/tasks/language_modeling.md b/docs/source/ja/tasks/language_modeling.md index 36662317a9be..d72ebb6a1046 100644 --- a/docs/source/ja/tasks/language_modeling.md +++ b/docs/source/ja/tasks/language_modeling.md @@ -185,8 +185,6 @@ Apply the `group_texts` function over the entire dataset: 次に、[`DataCollat​​orForLanguageModeling`] を使用してサンプルのバッチを作成します。 *動的にパディング*する方が効率的です。 データセット全体を最大長までパディングするのではなく、照合中にバッチ内の文を最長の長さにします。 - - シーケンス終了トークンをパディング トークンとして使用し、`mlm=False` を設定します。これは、入力を 1 要素分右にシフトしたラベルとして使用します。 @@ -197,14 +195,10 @@ Apply the `group_texts` function over the entire dataset: >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False) ``` - - ## Train - - [`Trainer`] を使用したモデルの微調整に慣れていない場合は、[基本チュートリアル](../training#train-with-pytorch-trainer) を参照してください。 @@ -261,8 +255,6 @@ Perplexity: 49.61 ```py >>> trainer.push_to_hub() ``` - - @@ -293,8 +285,6 @@ Perplexity: 49.61 [{'generated_text': "Somatic hypermutation allows the immune system to be able to effectively reverse the damage caused by an infection.\n\n\nThe damage caused by an infection is caused by the immune system's ability to perform its own self-correcting tasks."}] ``` - - テキストをトークン化し、「input_ids」を PyTorch テンソルとして返します。 @@ -323,5 +313,3 @@ Perplexity: 49.61 ["Somatic hypermutation allows the immune system to react to drugs with the ability to adapt to a different environmental situation. In other words, a system of 'hypermutation' can help the immune system to adapt to a different environmental situation or in some cases even a single life. In contrast, researchers at the University of Massachusetts-Boston have found that 'hypermutation' is much stronger in mice than in humans but can be found in humans, and that it's not completely unknown to the immune system. A study on how the immune system"] ``` - - diff --git a/docs/source/ja/tasks/masked_language_modeling.md b/docs/source/ja/tasks/masked_language_modeling.md index 90b39c695349..ff4107edb808 100644 --- a/docs/source/ja/tasks/masked_language_modeling.md +++ b/docs/source/ja/tasks/masked_language_modeling.md @@ -173,8 +173,6 @@ pip install transformers datasets evaluate 次に、[`DataCollat​​orForLanguageModeling`] を使用してサンプルのバッチを作成します。データセット全体を最大長までパディングするのではなく、照合中にバッチ内の最長の長さまで文を *動的にパディング* する方が効率的です。 - - シーケンス終了トークンをパディング トークンとして使用し、データを反復するたびにランダムにトークンをマスクするために `mlm_probability` を指定します。 @@ -184,13 +182,9 @@ pip install transformers datasets evaluate >>> tokenizer.pad_token = tokenizer.eos_token >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15) ``` - - ## Train - - [`Trainer`] を使用したモデルの微調整に慣れていない場合は、[ここ](../training#train-with-pytorch-trainer) の基本的なチュートリアルをご覧ください。 @@ -249,8 +243,6 @@ Perplexity: 8.76 >>> trainer.push_to_hub() ``` - - @@ -291,8 +283,6 @@ Perplexity: 8.76 'sequence': 'The Milky Way is a small galaxy.'}] ``` - - テキストをトークン化し、`input_ids`を PyTorch テンソルとして返します。 `` トークンの位置も指定する必要があります。 @@ -326,5 +316,3 @@ The Milky Way is a massive galaxy. The Milky Way is a small galaxy. ``` - - diff --git a/docs/source/ja/tasks/multiple_choice.md b/docs/source/ja/tasks/multiple_choice.md index b0f623e29ab1..d92ff913d606 100644 --- a/docs/source/ja/tasks/multiple_choice.md +++ b/docs/source/ja/tasks/multiple_choice.md @@ -145,8 +145,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) ## Train - - [`Trainer`] を使用したモデルの微調整に慣れていない場合は、[ここ](../training#train-with-pytorch-trainer) の基本的なチュートリアルをご覧ください。 @@ -199,8 +197,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) ```py >>> trainer.push_to_hub() ``` - - @@ -224,8 +220,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) >>> candidate2 = "The law applies to baguettes." ``` - - 各プロンプトと回答候補のペアをトークン化し、PyTorch テンソルを返します。いくつかの`lables`も作成する必要があります。 @@ -254,5 +248,3 @@ tokenized_swag = swag.map(preprocess_function, batched=True) >>> predicted_class '0' ``` - - diff --git a/docs/source/ja/tasks/question_answering.md b/docs/source/ja/tasks/question_answering.md index 302a794c8c02..a12205b5cd39 100644 --- a/docs/source/ja/tasks/question_answering.md +++ b/docs/source/ja/tasks/question_answering.md @@ -43,8 +43,6 @@ ```py >>> trainer.push_to_hub() ``` - - @@ -86,8 +84,6 @@ 必要に応じて、`pipeline`の結果を手動で複製することもできます。 - - テキストをトークン化して PyTorch テンソルを返します。 @@ -124,5 +120,3 @@ >>> tokenizer.decode(predict_answer_tokens) '176 billion parameters and can generate text in 46 languages natural languages and 13' ``` - - diff --git a/docs/source/ja/tasks/semantic_segmentation.md b/docs/source/ja/tasks/semantic_segmentation.md index 95953e841f53..4a1a141ba4ef 100644 --- a/docs/source/ja/tasks/semantic_segmentation.md +++ b/docs/source/ja/tasks/semantic_segmentation.md @@ -105,8 +105,6 @@ pip install -q datasets transformers evaluate >>> image_processor = AutoImageProcessor.from_pretrained(checkpoint, do_reduce_labels=True) ``` - - モデルを過学習に対してより堅牢にするために、画像データセットにいくつかのデータ拡張を適用するのが一般的です。このガイドでは、[torchvision](https://pytorch.org/vision/stable/index.html) の [`ColorJitter`](https://pytorch.org/vision/stable/generated/torchvision.transforms.ColorJitter.html) 関数を使用します。 ) を使用して画像の色のプロパティをランダムに変更しますが、任意の画像ライブラリを使用することもできます。 @@ -140,8 +138,6 @@ pip install -q datasets transformers evaluate >>> test_ds.set_transform(val_transforms) ``` - - ## Evaluate @@ -156,8 +152,6 @@ pip install -q datasets transformers evaluate 次に、メトリクスを [`~evaluate.EvaluationModule.compute`] する関数を作成します。予測を次のように変換する必要があります 最初にロジットを作成し、次に [`~evaluate.EvaluationModule.compute`] を呼び出す前にラベルのサイズに一致するように再形成します。 - - ```py >>> import numpy as np @@ -189,15 +183,11 @@ pip install -q datasets transformers evaluate ... return metrics ``` - - これで`compute_metrics`関数の準備が整いました。トレーニングをセットアップするときにこの関数に戻ります。 ## Train - - [`Trainer`] を使用したモデルの微調整に慣れていない場合は、[ここ](../training#finetune-with-trainer) の基本的なチュートリアルをご覧ください。 @@ -252,8 +242,6 @@ pip install -q datasets transformers evaluate ```py >>> trainer.push_to_hub() ``` - - ## Inference @@ -270,8 +258,6 @@ pip install -q datasets transformers evaluate Image of bedroom
- - 推論用に微調整されたモデルを試す最も簡単な方法は、それを [`pipeline`] で使用することです。モデルを使用して画像セグメンテーション用の `pipeline`をインスタンス化し、それに画像を渡します。 @@ -338,8 +324,6 @@ pip install -q datasets transformers evaluate >>> pred_seg = upsampled_logits.argmax(dim=1)[0] ``` - - 結果を視覚化するには、[データセット カラー パレット](https://github.com/tensorflow/models/blob/3f1ca33afe3c1631b733ea7e40c294273b9e406d/research/deeplab/utils/get_dataset_colormap.py#L51) を、それぞれをマップする `ade_palette()` としてロードします。クラスを RGB 値に変換します。次に、画像と予測されたセグメンテーション マップを組み合わせてプロットできます。 diff --git a/docs/source/ja/tasks/summarization.md b/docs/source/ja/tasks/summarization.md index 182221610ba2..c62583fdb281 100644 --- a/docs/source/ja/tasks/summarization.md +++ b/docs/source/ja/tasks/summarization.md @@ -119,16 +119,12 @@ pip install transformers datasets evaluate rouge_score 次に、[`DataCollat​​orForSeq2Seq`] を使用してサンプルのバッチを作成します。データセット全体を最大長までパディングするのではなく、照合中にバッチ内の最長の長さまで文を *動的にパディング* する方が効率的です。 - - ```py >>> from transformers import DataCollatorForSeq2Seq >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - ## Evaluate @@ -164,8 +160,6 @@ pip install transformers datasets evaluate rouge_score ## Train - - @@ -221,8 +215,6 @@ pip install transformers datasets evaluate rouge_score ```py >>> trainer.push_to_hub() ``` - - @@ -254,8 +246,6 @@ pip install transformers datasets evaluate rouge_score 必要に応じて、`pipeline`」の結果を手動で複製することもできます。 - - Tokenize the text and return the `input_ids` as PyTorch tensors: ```py @@ -280,5 +270,3 @@ Tokenize the text and return the `input_ids` as PyTorch tensors: >>> tokenizer.decode(outputs[0], skip_special_tokens=True) 'the inflation reduction act lowers prescription drug costs, health care costs, and energy costs. it's the most aggressive action on tackling the climate crisis in american history. it will ask the ultra-wealthy and corporations to pay their fair share.' ``` - - diff --git a/docs/source/ja/tasks/token_classification.md b/docs/source/ja/tasks/token_classification.md index 9642a425ff17..f8dbd9740176 100644 --- a/docs/source/ja/tasks/token_classification.md +++ b/docs/source/ja/tasks/token_classification.md @@ -155,16 +155,12 @@ pip install transformers datasets evaluate seqeval 次に、[`DataCollat​​orWithPadding`] を使用してサンプルのバッチを作成します。データセット全体を最大長までパディングするのではなく、照合中にバッチ内の最長の長さまで文を *動的にパディング* する方が効率的です。 - - ```py >>> from transformers import DataCollatorForTokenClassification >>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer) ``` - - ## Evaluate @@ -244,8 +240,6 @@ pip install transformers datasets evaluate seqeval ... } ``` - - [`Trainer`] を使用したモデルの微調整に慣れていない場合は、[ここ](../training#train-with-pytorch-trainer) の基本的なチュートリアルをご覧ください。 @@ -300,8 +294,6 @@ pip install transformers datasets evaluate seqeval ```py >>> trainer.push_to_hub() ``` - - @@ -363,8 +355,6 @@ pip install transformers datasets evaluate seqeval 必要に応じて、`pipeline`の結果を手動で複製することもできます。 - - テキストをトークン化して PyTorch テンソルを返します。 ```py @@ -409,5 +399,3 @@ pip install transformers datasets evaluate seqeval 'O'] ``` - - diff --git a/docs/source/ja/tasks/translation.md b/docs/source/ja/tasks/translation.md index 82df32e082a9..e7ce04d47c1a 100644 --- a/docs/source/ja/tasks/translation.md +++ b/docs/source/ja/tasks/translation.md @@ -113,16 +113,12 @@ pip install transformers datasets evaluate sacrebleu 次に、[`DataCollat​​orForSeq2Seq`] を使用してサンプルのバッチを作成します。データセット全体を最大長までパディングするのではなく、照合中にバッチ内の最長の長さまで文を *動的にパディング* する方が効率的です。 - - ```py >>> from transformers import DataCollatorForSeq2Seq >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - ## Evaluate @@ -169,8 +165,6 @@ pip install transformers datasets evaluate sacrebleu ## Train - - [`Trainer`] を使用したモデルの微調整に慣れていない場合は、[ここ](../training#train-with-pytorch-trainer) の基本的なチュートリアルをご覧ください。 @@ -225,8 +219,6 @@ pip install transformers datasets evaluate sacrebleu ```py >>> trainer.push_to_hub() ``` - - @@ -262,8 +254,6 @@ pip install transformers datasets evaluate sacrebleu 必要に応じて、`pipeline`の結果を手動で複製することもできます。 - - テキストをトークン化し、`input_ids` を PyTorch テンソルとして返します。 @@ -292,5 +282,3 @@ pip install transformers datasets evaluate sacrebleu 'Les lignées partagent des ressources avec des bactéries enfixant l'azote.' ``` - - diff --git a/docs/source/ja/training.md b/docs/source/ja/training.md index ff70ed8e31ef..b90f2a1f53ed 100644 --- a/docs/source/ja/training.md +++ b/docs/source/ja/training.md @@ -77,8 +77,6 @@ rendered properly in your Markdown viewer. この時点で、使用したいフレームワークに対応するセクションに従う必要があります。右側のサイドバーのリンクを使用して、ジャンプしたいフレームワークに移動できます。 そして、特定のフレームワークのすべてのコンテンツを非表示にしたい場合は、そのフレームワークのブロック右上にあるボタンを使用してください! - - ## Train with Pytorch Trainer @@ -163,15 +161,11 @@ BERTモデルの事前学習済みのヘッドは破棄され、ランダムに >>> trainer.train() ``` - - ## Train in native Pytorch - - [`Trainer`]はトレーニングループを処理し、1行のコードでモデルをファインチューニングできるようにします。 @@ -314,8 +308,6 @@ PyTorchから[`AdamW`](https://pytorch.org/docs/stable/generated/torch.optim.Ada >>> metric.compute() ``` - - diff --git a/docs/source/ko/model_doc/albert.md b/docs/source/ko/model_doc/albert.md index 2ca79a721d60..d6c4b57fdbae 100644 --- a/docs/source/ko/model_doc/albert.md +++ b/docs/source/ko/model_doc/albert.md @@ -163,8 +163,6 @@ echo -e "Plants create [MASK] through a process known as photosynthesis." | tran [[autodoc]] models.albert.modeling_albert.AlbertForPreTrainingOutput - - ## AlbertModel[[albertmodel]] @@ -194,5 +192,3 @@ echo -e "Plants create [MASK] through a process known as photosynthesis." | tran [[autodoc]] AlbertForQuestionAnswering - forward - - diff --git a/docs/source/ko/model_doc/bart.md b/docs/source/ko/model_doc/bart.md index 6e76a78484e3..fdcc3db43877 100644 --- a/docs/source/ko/model_doc/bart.md +++ b/docs/source/ko/model_doc/bart.md @@ -129,8 +129,6 @@ BART를 시작하는 데 도움이 되는 Hugging Face와 community 자료 목 - all - - ## BartModel[[transformers.BartModel]] @@ -157,8 +155,6 @@ BART를 시작하는 데 도움이 되는 Hugging Face와 community 자료 목 [[autodoc]] BartForCausalLM - forward - - diff --git a/docs/source/ko/model_doc/bert.md b/docs/source/ko/model_doc/bert.md index b08c81459a02..f19aac769193 100644 --- a/docs/source/ko/model_doc/bert.md +++ b/docs/source/ko/model_doc/bert.md @@ -164,22 +164,16 @@ BERT를 시작하는 데 도움이 되는 Hugging Face와 community 자료 목 - create_token_type_ids_from_sequences - save_vocabulary - - ## BertTokenizerFast [[autodoc]] BertTokenizerFast - - ## Bert specific outputs [[autodoc]] models.bert.modeling_bert.BertForPreTrainingOutput - - ## BertModel @@ -226,7 +220,5 @@ BERT를 시작하는 데 도움이 되는 Hugging Face와 community 자료 목 [[autodoc]] BertForQuestionAnswering - forward - - diff --git a/docs/source/ko/model_doc/blip.md b/docs/source/ko/model_doc/blip.md index 8e88884a793a..4aa81c0b9cd3 100644 --- a/docs/source/ko/model_doc/blip.md +++ b/docs/source/ko/model_doc/blip.md @@ -61,8 +61,6 @@ BLIP은 여러 멀티모달 작업을 수행할 수 있는 모델입니다: [[autodoc]] BlipImageProcessor - preprocess - - ## BlipModel[[transformers.BlipModel]] @@ -98,5 +96,3 @@ BLIP은 여러 멀티모달 작업을 수행할 수 있는 모델입니다: [[autodoc]] BlipForQuestionAnswering - forward - - diff --git a/docs/source/ko/model_doc/clip.md b/docs/source/ko/model_doc/clip.md index b9517cea17df..b62629fa0771 100644 --- a/docs/source/ko/model_doc/clip.md +++ b/docs/source/ko/model_doc/clip.md @@ -234,8 +234,6 @@ CLIP을 시작하는 데 도움이 되는 Hugging Face와 community 자료 목 [[autodoc]] CLIPProcessor - - ## CLIPModel[[transformers.CLIPModel]] @@ -269,5 +267,3 @@ CLIP을 시작하는 데 도움이 되는 Hugging Face와 community 자료 목 [[autodoc]] CLIPForImageClassification - forward - - diff --git a/docs/source/ko/model_doc/convbert.md b/docs/source/ko/model_doc/convbert.md index 6bbac5b42272..93fb06a5f166 100644 --- a/docs/source/ko/model_doc/convbert.md +++ b/docs/source/ko/model_doc/convbert.md @@ -65,8 +65,6 @@ ConvBERT 훈련 팁은 BERT와 유사합니다. 사용 팁은 [BERT 문서](bert [[autodoc]] ConvBertTokenizerFast - - ## ConvBertModel [[transformers.ConvBertModel]] @@ -98,5 +96,3 @@ ConvBERT 훈련 팁은 BERT와 유사합니다. 사용 팁은 [BERT 문서](bert [[autodoc]] ConvBertForQuestionAnswering - forward - - diff --git a/docs/source/ko/model_doc/deberta-v2.md b/docs/source/ko/model_doc/deberta-v2.md index 254b183a5736..29bde98c1c4a 100644 --- a/docs/source/ko/model_doc/deberta-v2.md +++ b/docs/source/ko/model_doc/deberta-v2.md @@ -67,8 +67,6 @@ v2의 새로운 점: - build_inputs_with_special_tokens - create_token_type_ids_from_sequences - - ## DebertaV2Model @@ -105,5 +103,3 @@ v2의 새로운 점: [[autodoc]] DebertaV2ForMultipleChoice - forward - - diff --git a/docs/source/ko/model_doc/deberta.md b/docs/source/ko/model_doc/deberta.md index b76912197f1e..11d75b6a00c0 100644 --- a/docs/source/ko/model_doc/deberta.md +++ b/docs/source/ko/model_doc/deberta.md @@ -82,8 +82,6 @@ DeBERTa를 시작하는 데 도움이 되는 Hugging Face와 community 자료 - build_inputs_with_special_tokens - create_token_type_ids_from_sequences - - ## DebertaModel[[transformers.DebertaModel]] @@ -114,6 +112,4 @@ DeBERTa를 시작하는 데 도움이 되는 Hugging Face와 community 자료 [[autodoc]] DebertaForQuestionAnswering - forward - - diff --git a/docs/source/ko/model_doc/electra.md b/docs/source/ko/model_doc/electra.md index e9e1879e13dc..169ce388770a 100644 --- a/docs/source/ko/model_doc/electra.md +++ b/docs/source/ko/model_doc/electra.md @@ -66,8 +66,6 @@ Generators](https://openreview.net/pdf?id=r1xMH1BtvB) 논문에서 제안되었 [[autodoc]] models.electra.modeling_electra.ElectraForPreTrainingOutput - - ## ElectraModel @@ -109,5 +107,3 @@ Generators](https://openreview.net/pdf?id=r1xMH1BtvB) 논문에서 제안되었 [[autodoc]] ElectraForQuestionAnswering - forward - - diff --git a/docs/source/ko/model_doc/encoder-decoder.md b/docs/source/ko/model_doc/encoder-decoder.md index 9cea74aac10c..0fed34179ffc 100644 --- a/docs/source/ko/model_doc/encoder-decoder.md +++ b/docs/source/ko/model_doc/encoder-decoder.md @@ -136,8 +136,6 @@ nearly 800 thousand customers were affected by the shutoffs. the aim is to reduc [[autodoc]] EncoderDecoderConfig - - ## EncoderDecoderModel @@ -145,5 +143,3 @@ nearly 800 thousand customers were affected by the shutoffs. the aim is to reduc - forward - from_encoder_decoder_pretrained - - diff --git a/docs/source/ko/model_doc/esm.md b/docs/source/ko/model_doc/esm.md index 89640d1366c4..4fde962d2d94 100644 --- a/docs/source/ko/model_doc/esm.md +++ b/docs/source/ko/model_doc/esm.md @@ -60,8 +60,6 @@ ESMFold는 [Matt](https://huggingface.co/Rocketknight1)와 [Sylvain](https://hug - create_token_type_ids_from_sequences - save_vocabulary - - ## EsmModel [[transformers.EsmModel]] @@ -88,5 +86,3 @@ ESMFold는 [Matt](https://huggingface.co/Rocketknight1)와 [Sylvain](https://hug [[autodoc]] EsmForProteinFolding - forward - - diff --git a/docs/source/ko/model_doc/gpt2.md b/docs/source/ko/model_doc/gpt2.md index 56650243f9fa..316b3c434323 100644 --- a/docs/source/ko/model_doc/gpt2.md +++ b/docs/source/ko/model_doc/gpt2.md @@ -136,8 +136,6 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True)) [[autodoc]] models.gpt2.modeling_gpt2.GPT2DoubleHeadsModelOutput - - ## GPT2Model @@ -169,5 +167,3 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True)) [[autodoc]] GPT2ForTokenClassification - forward - - \ No newline at end of file diff --git a/docs/source/ko/model_doc/marian.md b/docs/source/ko/model_doc/marian.md index c978e2df6df0..a0701b6cfcaa 100644 --- a/docs/source/ko/model_doc/marian.md +++ b/docs/source/ko/model_doc/marian.md @@ -169,8 +169,6 @@ GROUP_MEMBERS = { [[autodoc]] MarianTokenizer - build_inputs_with_special_tokens - - ## MarianModel @@ -187,5 +185,3 @@ GROUP_MEMBERS = { [[autodoc]] MarianForCausalLM - forward - - diff --git a/docs/source/ko/model_doc/openai-gpt.md b/docs/source/ko/model_doc/openai-gpt.md index 679bf0783c81..9452561ca60f 100644 --- a/docs/source/ko/model_doc/openai-gpt.md +++ b/docs/source/ko/model_doc/openai-gpt.md @@ -97,8 +97,6 @@ OpenAI GPT를 시작하는 데 도움이 되는 공식 Hugging Face 및 커뮤 [[autodoc]] models.openai.modeling_openai.OpenAIGPTDoubleHeadsModelOutput - - ## OpenAIGPTModel [[transformers.OpenAIGPTModel]] @@ -120,5 +118,3 @@ OpenAI GPT를 시작하는 데 도움이 되는 공식 Hugging Face 및 커뮤 [[autodoc]] OpenAIGPTForSequenceClassification - forward - - diff --git a/docs/source/ko/model_doc/rag.md b/docs/source/ko/model_doc/rag.md index cb670a54ee9a..7d84e1e250f1 100644 --- a/docs/source/ko/model_doc/rag.md +++ b/docs/source/ko/model_doc/rag.md @@ -56,8 +56,6 @@ rendered properly in your Markdown viewer. [[autodoc]] RagRetriever - - ## RagModel [[transformers.RagModel]] @@ -76,5 +74,3 @@ rendered properly in your Markdown viewer. - forward - generate - - diff --git a/docs/source/ko/model_doc/roberta.md b/docs/source/ko/model_doc/roberta.md index 6588ff62e264..f7774bbbabe7 100644 --- a/docs/source/ko/model_doc/roberta.md +++ b/docs/source/ko/model_doc/roberta.md @@ -112,8 +112,6 @@ RoBERTa를 처음 다룰 때 도움이 되는 Hugging Face 공식 자료와 커 [[autodoc]] RobertaTokenizerFast - build_inputs_with_special_tokens - - ## RobertaModel @@ -150,5 +148,3 @@ RoBERTa를 처음 다룰 때 도움이 되는 Hugging Face 공식 자료와 커 [[autodoc]] RobertaForQuestionAnswering - forward - - diff --git a/docs/source/ko/model_doc/swin.md b/docs/source/ko/model_doc/swin.md index 48ffdcc9cb2b..6d90dc8226ae 100644 --- a/docs/source/ko/model_doc/swin.md +++ b/docs/source/ko/model_doc/swin.md @@ -55,8 +55,6 @@ Swin Transformer의 사용을 도울 수 있는 Hugging Face 및 커뮤니티( [[autodoc]] SwinConfig - - ## SwinModel [[transformers.SwinModel]] @@ -73,5 +71,3 @@ Swin Transformer의 사용을 도울 수 있는 Hugging Face 및 커뮤니티( [[autodoc]] transformers.SwinForImageClassification - forward - - \ No newline at end of file diff --git a/docs/source/ko/model_doc/vit.md b/docs/source/ko/model_doc/vit.md index 7d6d54093a66..7cdb6fbd6c41 100644 --- a/docs/source/ko/model_doc/vit.md +++ b/docs/source/ko/model_doc/vit.md @@ -124,8 +124,6 @@ ViT의 추론 및 커스텀 데이터에 대한 미세 조정과 관련된 데 [[autodoc]] ViTImageProcessorFast - preprocess - - ## ViTModel [[transformers.ViTModel]] @@ -142,5 +140,3 @@ ViT의 추론 및 커스텀 데이터에 대한 미세 조정과 관련된 데 [[autodoc]] ViTForImageClassification - forward - - \ No newline at end of file diff --git a/docs/source/ko/model_sharing.md b/docs/source/ko/model_sharing.md index c2bf04365a79..223fb6571c1c 100644 --- a/docs/source/ko/model_sharing.md +++ b/docs/source/ko/model_sharing.md @@ -79,21 +79,15 @@ pip install huggingface_hub 체크포인트를 다른 프레임워크로 변환하는 것은 쉽습니다. PyTorch 및 TensorFlow가 설치되어 있는지 확인한 다음(설치 지침은 [여기](installation) 참조) 다른 프레임워크에서 작업에 대한 특정 모델을 찾습니다. - - 체크포인트를 TensorFlow에서 PyTorch로 변환하려면 `from_tf=True`를 지정하세요: ```py >>> pt_model = DistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_tf=True) >>> pt_model.save_pretrained("path/to/awesome-name-you-picked") ``` - - ## 훈련 중 모델 푸시하기[[push-a-model-during-training]] - - 모델을 허브에 공유하는 것은 추가 매개변수나 콜백을 추가하는 것만큼 간단합니다. [미세 조정 튜토리얼](training)에서 [`TrainingArguments`] 클래스는 하이퍼파라미터와 추가 훈련 옵션을 지정하는 곳이라는 것을 기억하세요. 이러한 훈련 옵션 중 하나는 모델을 허브로 직접 푸시하는 기능을 포함합니다. [`TrainingArguments`]에서 `push_to_hub=True`를 설정하세요: @@ -119,8 +113,6 @@ pip install huggingface_hub ```py >>> trainer.push_to_hub() ``` - - ## `push_to_hub` 함수 사용하기[[use-the-pushtohub-function]] diff --git a/docs/source/ko/quicktour.md b/docs/source/ko/quicktour.md index 133b04206c9e..de882503c9d8 100644 --- a/docs/source/ko/quicktour.md +++ b/docs/source/ko/quicktour.md @@ -28,14 +28,10 @@ rendered properly in your Markdown viewer. 또한 선호하는 머신 러닝 프레임워크를 설치해야 합니다: - - ```bash pip install torch ``` - - ## 파이프라인 [[pipeline]] @@ -133,8 +129,6 @@ label: NEGATIVE, with score: 0.5309 >>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ``` - - [`AutoModelForSequenceClassification`]과 [`AutoTokenizer`]를 사용하여 사전 훈련된 모델과 관련된 토크나이저를 로드하세요 (다음 섹션에서 [`AutoClass`]에 대해 더 자세히 알아보겠습니다): ```py @@ -143,8 +137,6 @@ label: NEGATIVE, with score: 0.5309 >>> model = AutoModelForSequenceClassification.from_pretrained(model_name) >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - - [`pipeline`]에서 모델과 토크나이저를 지정하면, 이제 `classifier`를 프랑스어 텍스트에 적용할 수 있습니다: @@ -194,8 +186,6 @@ label: NEGATIVE, with score: 0.5309 토크나이저는 입력을 리스트 형태로도 받을 수 있으며, 텍스트를 패딩하고 잘라내어 일정한 길이의 묶음을 반환할 수도 있습니다: - - ```py >>> pt_batch = tokenizer( @@ -206,8 +196,6 @@ label: NEGATIVE, with score: 0.5309 ... return_tensors="pt", ... ) ``` - - @@ -217,8 +205,6 @@ label: NEGATIVE, with score: 0.5309 ### AutoModel [[automodel]] - - 🤗 Transformers는 사전 훈련된 인스턴스를 간단하고 통합된 방법으로 로드할 수 있습니다. 즉, [`AutoTokenizer`]처럼 [`AutoModel`]을 로드할 수 있습니다. 유일한 차이점은 과업에 알맞은 [`AutoModel`]을 선택해야 한다는 점입니다. 텍스트 (또는 시퀀스) 분류의 경우 [`AutoModelForSequenceClassification`]을 로드해야 합니다: ```py @@ -250,8 +236,6 @@ label: NEGATIVE, with score: 0.5309 tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - - @@ -261,8 +245,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ### 모델 저장하기 [[save-a-model]] - - 미세조정된 모델을 토크나이저와 함께 저장하려면 [`PreTrainedModel.save_pretrained`]를 사용하세요: ```py @@ -276,13 +258,9 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ```py >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - - 🤗 Transformers의 멋진 기능 중 하나는 모델을 PyTorch 또는 TensorFlow 모델로 저장해뒀다가 다른 프레임워크로 다시 로드할 수 있는 점입니다. `from_pt` 또는 `from_tf` 매개변수를 사용하여 모델을 한 프레임워크에서 다른 프레임워크로 변환할 수 있습니다: - - ```py >>> from transformers import AutoModel @@ -290,8 +268,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory) >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - ## 커스텀 모델 구축하기 [[custom-model-builds]] @@ -305,8 +281,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_config = AutoConfig.from_pretrained("distilbert/distilbert-base-uncased", n_heads=12) ``` - - [`AutoModel.from_config`]를 사용하여 바꾼 구성대로 모델을 생성하세요: ```py @@ -314,8 +288,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_model = AutoModel.from_config(my_config) ``` - - 커스텀 구성에 대한 자세한 내용은 [커스텀 아키텍처 만들기](./create_a_model) 가이드를 확인하세요. diff --git a/docs/source/ko/run_scripts.md b/docs/source/ko/run_scripts.md index 70ff270c04a4..874834a1f32a 100644 --- a/docs/source/ko/run_scripts.md +++ b/docs/source/ko/run_scripts.md @@ -90,8 +90,6 @@ pip install -r requirements.txt ## 스크립트 실행하기[[run-a-script]] - - 예제 스크립트는 🤗 [Datasets](https://huggingface.co/docs/datasets/) 라이브러리에서 데이터 세트를 다운로드하고 전처리합니다. 그런 다음 스크립트는 요약 기능을 지원하는 아키텍처에서 [Trainer](https://huggingface.co/docs/transformers/main_classes/trainer)를 사용하여 데이터 세트를 미세 조정합니다. 다음 예는 [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail) 데이터 세트에서 [T5-small](https://huggingface.co/google-t5/t5-small)을 미세 조정합니다. @@ -111,8 +109,6 @@ python examples/pytorch/summarization/run_summarization.py \ --overwrite_output_dir \ --predict_with_generate ``` - - ## 혼합 정밀도(mixed precision)로 분산 훈련하기[[distributed-training-and-mixed-precision]] @@ -144,8 +140,6 @@ TensorFlow 스크립트는 분산 훈련을 위해 [`MirroredStrategy`](https:// ## TPU 위에서 스크립트 실행하기[[run-a-script-on-a-tpu]] - - Tensor Processing Units (TPUs)는 성능을 가속화하기 위해 특별히 설계되었습니다. PyTorch는 [XLA](https://www.tensorflow.org/xla) 딥러닝 컴파일러와 함께 TPU를 지원합니다(자세한 내용은 [여기](https://github.com/pytorch/xla/blob/master/README.md) 참조). TPU를 사용하려면 `xla_spawn.py` 스크립트를 실행하고 `num_cores` 인수를 사용하여 사용하려는 TPU 코어 수를 설정합니다. @@ -165,8 +159,6 @@ python xla_spawn.py --num_cores 8 \ --overwrite_output_dir \ --predict_with_generate ``` - - ## 🤗 Accelerate로 스크립트 실행하기[[run-a-script-with-accelerate]] diff --git a/docs/source/ko/tasks/asr.md b/docs/source/ko/tasks/asr.md index 6c8ad6fc3201..f28dd9fbec04 100644 --- a/docs/source/ko/tasks/asr.md +++ b/docs/source/ko/tasks/asr.md @@ -232,8 +232,6 @@ MInDS-14 데이터 세트의 샘플링 레이트는 8000kHz이므로([데이터 ## 훈련하기[[train]] - - [`Trainer`]로 모델을 미세 조정하는 것이 익숙하지 않다면, [여기](../training#train-with-pytorch-trainer)에서 기본 튜토리얼을 확인해보세요! @@ -298,8 +296,6 @@ MInDS-14 데이터 세트의 샘플링 레이트는 8000kHz이므로([데이터 ```py >>> trainer.push_to_hub() ``` - - @@ -340,8 +336,6 @@ MInDS-14 데이터 세트의 샘플링 레이트는 8000kHz이므로([데이터 `pipeline`의 결과를 수동으로 재현할 수도 있습니다: - - 오디오 파일과 텍스트를 전처리하고 PyTorch 텐서로 `input`을 반환할 프로세서를 가져오세요: ```py @@ -371,5 +365,3 @@ MInDS-14 데이터 세트의 샘플링 레이트는 8000kHz이므로([데이터 >>> transcription ['I WOUL LIKE O SET UP JOINT ACOUNT WTH Y PARTNER'] ``` - - diff --git a/docs/source/ko/tasks/audio_classification.md b/docs/source/ko/tasks/audio_classification.md index 2defa691edef..789d7ee88373 100644 --- a/docs/source/ko/tasks/audio_classification.md +++ b/docs/source/ko/tasks/audio_classification.md @@ -187,8 +187,6 @@ MinDS-14 데이터 세트의 샘플링 속도는 8khz이므로(이 정보는 [ ## 훈련[[train]] - - [`Trainer`]로 모델을 미세 조정하는 데 익숙하지 않다면 기본 튜토리얼 [여기](../training#train-with-pytorch-trainer)을 살펴보세요! @@ -247,8 +245,6 @@ MinDS-14 데이터 세트의 샘플링 속도는 8khz이므로(이 정보는 [ ```py >>> trainer.push_to_hub() ``` - - @@ -289,8 +285,6 @@ For a more in-depth example of how to finetune a model for audio classification, 원하는 경우 `pipeline`의 결과를 수동으로 복제할 수도 있습니다: - - 특징 추출기를 가져와서 오디오 파일을 전처리하고 `입력`을 PyTorch 텐서로 반환합니다: ```py @@ -320,5 +314,3 @@ For a more in-depth example of how to finetune a model for audio classification, >>> predicted_label 'cash_deposit' ``` - - diff --git a/docs/source/ko/tasks/image_classification.md b/docs/source/ko/tasks/image_classification.md index 48ac6742431a..54490a6f939a 100644 --- a/docs/source/ko/tasks/image_classification.md +++ b/docs/source/ko/tasks/image_classification.md @@ -108,8 +108,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 >>> image_processor = AutoImageProcessor.from_pretrained(checkpoint) ``` - - 이미지에 몇 가지 이미지 변환을 적용하여 과적합에 대해 모델을 더 견고하게 만듭니다. 여기서 Torchvision의 [`transforms`](https://pytorch.org/vision/stable/transforms.html) 모듈을 사용하지만, 원하는 이미지 라이브러리를 사용할 수도 있습니다. 이미지의 임의 부분을 크롭하고 크기를 조정한 다음, 이미지 평균과 표준 편차로 정규화하세요: @@ -148,8 +146,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 >>> data_collator = DefaultDataCollator() ``` - - ## 평가[[evaluate]] @@ -180,8 +176,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 ## 훈련[[train]] - - [`Trainer`]를 사용하여 모델을 미세 조정하는 방법에 익숙하지 않은 경우, [여기](../training#train-with-pytorch-trainer)에서 기본 튜토리얼을 확인하세요! @@ -243,8 +237,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 ```py >>> trainer.push_to_hub() ``` - - @@ -284,8 +276,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 원한다면, `pipeline`의 결과를 수동으로 복제할 수도 있습니다: - - 이미지를 전처리하기 위해 이미지 프로세서를 가져오고 `input`을 PyTorch 텐서로 반환합니다: ```py @@ -313,5 +303,3 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 >>> model.config.id2label[predicted_label] 'beignets' ``` - - diff --git a/docs/source/ko/tasks/language_modeling.md b/docs/source/ko/tasks/language_modeling.md index d444a15ee6dd..dcb665a0025a 100644 --- a/docs/source/ko/tasks/language_modeling.md +++ b/docs/source/ko/tasks/language_modeling.md @@ -175,8 +175,6 @@ pip install transformers datasets evaluate 그런 다음 [`DataCollatorForLanguageModeling`]을 사용하여 예제의 배치를 만듭니다. 데이터 세트 전체를 최대 길이로 패딩하는 것보다, 취합 단계에서 각 배치의 최대 길이로 문장을 *동적으로 패딩*하는 것이 더 효율적입니다. - - 패딩 토큰으로 종결 토큰을 사용하고 `mlm=False`로 설정하세요. 이렇게 하면 입력을 오른쪽으로 한 칸씩 시프트한 값을 레이블로 사용합니다: ```py @@ -186,14 +184,10 @@ pip install transformers datasets evaluate >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False) ``` - - ## 훈련[[train]] - - [`Trainer`]를 사용하여 모델을 미세 조정하는 방법을 잘 모르신다면 [기본 튜토리얼](../training#train-with-pytorch-trainer)을 확인해보세요! @@ -249,8 +243,6 @@ Perplexity: 49.61 ```py >>> trainer.push_to_hub() ``` - - @@ -278,8 +270,6 @@ Perplexity: 49.61 [{'generated_text': "Somatic hypermutation allows the immune system to be able to effectively reverse the damage caused by an infection.\n\n\nThe damage caused by an infection is caused by the immune system's ability to perform its own self-correcting tasks."}] ``` - - 텍스트를 토큰화하고 `input_ids`를 PyTorch 텐서로 반환하세요: ```py @@ -304,5 +294,3 @@ Perplexity: 49.61 >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) ["Somatic hypermutation allows the immune system to react to drugs with the ability to adapt to a different environmental situation. In other words, a system of 'hypermutation' can help the immune system to adapt to a different environmental situation or in some cases even a single life. In contrast, researchers at the University of Massachusetts-Boston have found that 'hypermutation' is much stronger in mice than in humans but can be found in humans, and that it's not completely unknown to the immune system. A study on how the immune system"] ``` - - diff --git a/docs/source/ko/tasks/masked_language_modeling.md b/docs/source/ko/tasks/masked_language_modeling.md index cb9216b1e6bc..65da783f9ae8 100644 --- a/docs/source/ko/tasks/masked_language_modeling.md +++ b/docs/source/ko/tasks/masked_language_modeling.md @@ -179,8 +179,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티와 이제 [`DataCollatorForLanguageModeling`]을 사용하여 데이터 예제의 배치를 생성합니다. 데이터 세트 전체를 최대 길이로 패딩하는 것보다 collation 단계에서 매 배치안에서의 최대 길이로 문장을 *동적으로 패딩*하는 것이 더 효율적입니다. - - 시퀀스 끝 토큰을 패딩 토큰으로 사용하고 데이터를 반복할 때마다 토큰을 무작위로 마스킹하도록 `mlm_-probability`를 지정합니다: @@ -190,13 +188,9 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티와 >>> tokenizer.pad_token = tokenizer.eos_token >>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15) ``` - - ## 훈련[[train]] - - [`Trainer`]로 모델을 미세 조정하는 데 익숙하지 않다면 기본 튜토리얼 [여기](../training#train-with-pytorch-trainer)를 살펴보세요! @@ -252,8 +246,6 @@ Perplexity: 8.76 ```py >>> trainer.push_to_hub() ``` - - @@ -295,8 +287,6 @@ Perplexity: 8.76 'sequence': 'The Milky Way is a small galaxy.'}] ``` - - 텍스트를 토큰화하고 `input_ids`를 PyTorch 텐서 형태로 반환합니다. 또한, `` 토큰의 위치를 지정해야 합니다: ```py @@ -327,5 +317,3 @@ The Milky Way is a spiral galaxy. The Milky Way is a massive galaxy. The Milky Way is a small galaxy. ``` - - diff --git a/docs/source/ko/tasks/multiple_choice.md b/docs/source/ko/tasks/multiple_choice.md index 7756951f07ec..c8d99bc02ca1 100644 --- a/docs/source/ko/tasks/multiple_choice.md +++ b/docs/source/ko/tasks/multiple_choice.md @@ -144,8 +144,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) ## 훈련 하기[[train]] - - [`Trainer`]로 모델을 미세 조정하는 데 익숙하지 않다면 기본 튜토리얼 [여기](../training#train-with-pytorch-trainer)를 살펴보세요! @@ -198,8 +196,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) ```py >>> trainer.push_to_hub() ``` - - @@ -222,8 +218,6 @@ tokenized_swag = swag.map(preprocess_function, batched=True) >>> candidate2 = "The law applies to baguettes." ``` - - 각 프롬프트와 후보 답변 쌍을 토큰화하여 PyTorch 텐서를 반환합니다. 또한 `labels`을 생성해야 합니다: ```py @@ -251,5 +245,3 @@ tokenized_swag = swag.map(preprocess_function, batched=True) >>> predicted_class '0' ``` - - diff --git a/docs/source/ko/tasks/question_answering.md b/docs/source/ko/tasks/question_answering.md index f0f1cab6b648..6e067dc38934 100644 --- a/docs/source/ko/tasks/question_answering.md +++ b/docs/source/ko/tasks/question_answering.md @@ -165,20 +165,14 @@ pip install transformers datasets evaluate 이제 [`DefaultDataCollator`]를 이용해 예시 배치를 생성합니다. 🤗 Transformers의 다른 데이터 콜레이터(data collator)와 달리, [`DefaultDataCollator`]는 패딩과 같은 추가 전처리를 적용하지 않습니다: - - ```py >>> from transformers import DefaultDataCollator >>> data_collator = DefaultDataCollator() ``` - - ## 훈련[[train]] - - [`Trainer`]를 이용해 모델을 미세 조정하는 것에 익숙하지 않다면, [여기](../training#train-with-pytorch-trainer)에서 기초 튜토리얼을 살펴보세요! @@ -228,8 +222,6 @@ pip install transformers datasets evaluate ```py >>> trainer.push_to_hub() ``` - - @@ -269,8 +261,6 @@ pip install transformers datasets evaluate 원한다면 `pipeline`의 결과를 직접 복제할 수도 있습니다: - - 텍스트를 토큰화해서 PyTorch 텐서를 반환합니다: ```py @@ -304,5 +294,3 @@ pip install transformers datasets evaluate >>> tokenizer.decode(predict_answer_tokens) '176 billion parameters and can generate text in 46 languages natural languages and 13' ``` - - diff --git a/docs/source/ko/tasks/semantic_segmentation.md b/docs/source/ko/tasks/semantic_segmentation.md index 167417412c47..68acd8cda9ea 100644 --- a/docs/source/ko/tasks/semantic_segmentation.md +++ b/docs/source/ko/tasks/semantic_segmentation.md @@ -104,8 +104,6 @@ pip install -q datasets transformers evaluate >>> image_processor = AutoImageProcessor.from_pretrained(checkpoint, do_reduce_labels=True) ``` - - 이미지 데이터 세트에 데이터 증강을 적용하여 과적합에 대해 모델을 보다 강건하게 만드는 것이 일반적입니다. 이 가이드에서는 [torchvision](https://pytorch.org/vision/stable/index.html)의 [`ColorJitter`](https://pytorch.org/vision/stable/generated/torchvision.transforms.ColorJitter.html)를 사용하여 이미지의 색상 속성을 임의로 변경합니다. 하지만, 자신이 원하는 이미지 라이브러리를 사용할 수도 있습니다. @@ -139,8 +137,6 @@ pip install -q datasets transformers evaluate >>> test_ds.set_transform(val_transforms) ``` - - ## 평가하기[[evaluate]] @@ -154,8 +150,6 @@ pip install -q datasets transformers evaluate 그런 다음 메트릭을 [`~evaluate.EvaluationModule.compute`]하는 함수를 만듭니다. 예측을 먼저 로짓으로 변환한 다음, 레이블의 크기에 맞게 모양을 다시 지정해야 [`~evaluate.EvaluationModule.compute`]를 호출할 수 있습니다: - - ```py >>> import numpy as np @@ -187,15 +181,11 @@ pip install -q datasets transformers evaluate ... return metrics ``` - - 이제 `compute_metrics` 함수를 사용할 준비가 되었습니다. 트레이닝을 설정할 때 이 함수로 돌아가게 됩니다. ## 학습하기[[train]] - - 만약 [`Trainer`]를 사용해 모델을 미세 조정하는 것에 익숙하지 않다면, [여기](../training#finetune-with-trainer)에서 기본 튜토리얼을 살펴보세요! @@ -249,8 +239,6 @@ pip install -q datasets transformers evaluate ```py >>> trainer.push_to_hub() ``` - - ## 추론하기[[inference]] @@ -268,8 +256,6 @@ pip install -q datasets transformers evaluate Image of bedroom
- - 추론을 위해 미세 조정한 모델을 시험해 보는 가장 간단한 방법은 [`pipeline`]에서 사용하는 것입니다. 모델을 사용하여 이미지 분할을 위한 `pipeline`을 인스턴스화하고 이미지를 전달합니다: @@ -333,8 +319,6 @@ pip install -q datasets transformers evaluate >>> pred_seg = upsampled_logits.argmax(dim=1)[0] ``` - - 결과를 시각화하려면 [dataset color palette](https://github.com/tensorflow/models/blob/3f1ca33afe3c1631b733ea7e40c294273b9e406d/research/deeplab/utils/get_dataset_colormap.py#L51)를 각 클래스를 RGB 값에 매핑하는 `ade_palette()`로 로드합니다. 그런 다음 이미지와 예측된 분할 지도(segmentation map)을 결합하여 구성할 수 있습니다: diff --git a/docs/source/ko/tasks/sequence_classification.md b/docs/source/ko/tasks/sequence_classification.md index 1eda13c05e7d..9ffad8ff0b24 100644 --- a/docs/source/ko/tasks/sequence_classification.md +++ b/docs/source/ko/tasks/sequence_classification.md @@ -97,15 +97,11 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) 이제 [`DataCollatorWithPadding`]를 사용하여 예제 배치를 만들어봅시다. 데이터셋 전체를 최대 길이로 패딩하는 대신, *동적 패딩*을 사용하여 배치에서 가장 긴 길이에 맞게 문장을 패딩하는 것이 효율적입니다. - - ```py >>> from transformers import DataCollatorWithPadding >>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer) ``` - - ## 평가하기[[evaluate]] @@ -140,8 +136,6 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) >>> label2id = {"NEGATIVE": 0, "POSITIVE": 1} ``` - - [`Trainer`]를 사용하여 모델을 파인 튜닝하는 방법에 익숙하지 않은 경우, [여기](../training#train-with-pytorch-trainer)의 기본 튜토리얼을 확인하세요! @@ -202,8 +196,6 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) ```py >>> trainer.push_to_hub() ``` - - @@ -233,8 +225,6 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) 원한다면, `pipeline`의 결과를 수동으로 복제할 수도 있습니다. - - 텍스트를 토큰화하고 PyTorch 텐서를 반환합니다. ```py @@ -261,5 +251,3 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) >>> model.config.id2label[predicted_class_id] 'POSITIVE' ``` - - diff --git a/docs/source/ko/tasks/summarization.md b/docs/source/ko/tasks/summarization.md index c56af19bacfe..848a6cb00d00 100644 --- a/docs/source/ko/tasks/summarization.md +++ b/docs/source/ko/tasks/summarization.md @@ -124,15 +124,11 @@ Hugging Face 계정에 로그인하면 모델을 업로드하고 커뮤니티에 이제 [`DataCollatorForSeq2Seq`]를 사용하여 예제 배치를 만드세요. 전체 데이터셋을 최대 길이로 패딩하는 것보다 배치마다 가장 긴 문장 길이에 맞춰 *동적 패딩*하는 것이 더 효율적입니다. - - ```py >>> from transformers import DataCollatorForSeq2Seq >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - ## 평가[[evaluate]] @@ -171,8 +167,6 @@ Hugging Face 계정에 로그인하면 모델을 업로드하고 커뮤니티에 ## 학습[[train]] - - 모델을 [`Trainer`]로 파인튜닝 하는 것이 익숙하지 않다면, [여기](../training#train-with-pytorch-trainer)에서 기본 튜토리얼을 확인해보세요! @@ -229,8 +223,6 @@ Hugging Face 계정에 로그인하면 모델을 업로드하고 커뮤니티에 ```py >>> trainer.push_to_hub() ``` - - @@ -263,8 +255,6 @@ Hugging Face 계정에 로그인하면 모델을 업로드하고 커뮤니티에 원한다면 수동으로 다음과 같은 작업을 수행하여 [`pipeline`]의 결과와 동일한 결과를 얻을 수 있습니다: - - 텍스트를 토크나이즈하고 `input_ids`를 PyTorch 텐서로 반환합니다: ```py @@ -290,5 +280,3 @@ Hugging Face 계정에 로그인하면 모델을 업로드하고 커뮤니티에 >>> tokenizer.decode(outputs[0], skip_special_tokens=True) 'the inflation reduction act lowers prescription drug costs, health care costs, and energy costs. it's the most aggressive action on tackling the climate crisis in american history. it will ask the ultra-wealthy and corporations to pay their fair share.' ``` - - diff --git a/docs/source/ko/tasks/token_classification.md b/docs/source/ko/tasks/token_classification.md index 61882f1e7075..e4975405c3de 100644 --- a/docs/source/ko/tasks/token_classification.md +++ b/docs/source/ko/tasks/token_classification.md @@ -155,15 +155,11 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 이제 [`DataCollatorWithPadding`]를 사용하여 예제 배치를 만들어봅시다. 데이터 세트 전체를 최대 길이로 패딩하는 대신, *동적 패딩*을 사용하여 배치에서 가장 긴 길이에 맞게 문장을 패딩하는 것이 효율적입니다. - - ```py >>> from transformers import DataCollatorForTokenClassification >>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer) ``` - - ## 평가[[evaluation]] @@ -244,8 +240,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 ... } ``` - - [`Trainer`]를 사용하여 모델을 파인 튜닝하는 방법에 익숙하지 않은 경우, [여기](../training#train-with-pytorch-trainer)에서 기본 튜토리얼을 확인하세요! @@ -300,8 +294,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 ```py >>> trainer.push_to_hub() ``` - - @@ -362,8 +354,6 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 원한다면, `pipeline`의 결과를 수동으로 복제할 수도 있습니다: - - 텍스트를 토큰화하고 PyTorch 텐서를 반환합니다: ```py @@ -407,5 +397,3 @@ Hugging Face 계정에 로그인하여 모델을 업로드하고 커뮤니티에 'O', 'O'] ``` - - diff --git a/docs/source/ko/tasks/translation.md b/docs/source/ko/tasks/translation.md index dd82be10f6ea..4ecda3de384b 100644 --- a/docs/source/ko/tasks/translation.md +++ b/docs/source/ko/tasks/translation.md @@ -114,15 +114,11 @@ pip install transformers datasets evaluate sacrebleu 이제 [`DataCollatorForSeq2Seq`]를 사용하여 예제 배치를 생성합니다. 데이터세트의 최대 길이로 전부를 padding하는 대신, 데이터 정렬 중 각 배치의 최대 길이로 문장을 *동적으로 padding*하는 것이 더 효율적입니다. - - ```py >>> from transformers import DataCollatorForSeq2Seq >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint) ``` - - ## 평가[[evalulate]] @@ -171,8 +167,6 @@ pip install transformers datasets evaluate sacrebleu ## 훈련[[train]] - - [`Trainer`]로 모델을 파인튜닝하는 방법에 익숙하지 않다면 [여기](../training#train-with-pytorch-trainer)에서 기본 튜토리얼을 살펴보시기 바랍니다! @@ -226,8 +220,6 @@ pip install transformers datasets evaluate sacrebleu ```py >>> trainer.push_to_hub() ``` - - @@ -260,8 +252,6 @@ pip install transformers datasets evaluate sacrebleu 원한다면 `pipeline`의 결과를 직접 복제할 수도 있습니다: - - 텍스트를 토큰화하고 `input_ids`를 PyTorch 텐서로 반환하세요: ```py @@ -286,5 +276,3 @@ pip install transformers datasets evaluate sacrebleu >>> tokenizer.decode(outputs[0], skip_special_tokens=True) 'Les lignées partagent des ressources avec des bactéries enfixant l'azote.' ``` - - diff --git a/docs/source/ko/training.md b/docs/source/ko/training.md index 637a96458284..95a7fe285d3c 100644 --- a/docs/source/ko/training.md +++ b/docs/source/ko/training.md @@ -71,8 +71,6 @@ rendered properly in your Markdown viewer. 여기서부터는 사용하려는 프레임워크에 해당하는 섹션을 따라야 합니다. 오른쪽 사이드바의 링크를 사용하여 원하는 프레임워크로 이동할 수 있으며, 특정 프레임워크의 모든 콘텐츠를 숨기려면 해당 프레임워크 블록의 오른쪽 상단에 있는 버튼을 사용하면 됩니다! - - ## 파이토치 Trainer로 훈련하기[[train-with-pytorch-trainer]] @@ -156,15 +154,11 @@ rendered properly in your Markdown viewer. ```py >>> trainer.train() ``` - - ## 기본 파이토치로 훈련하기[[train-in-native-pytorch]] - - [`Trainer`]는 훈련 루프를 처리하며 한 줄의 코드로 모델을 미세 조정할 수 있습니다. 직접 훈련 루프를 작성하는 것을 선호하는 사용자의 경우, 기본 PyTorch에서 🤗 Transformers 모델을 미세 조정할 수도 있습니다. @@ -305,8 +299,6 @@ torch.cuda.empty_cache() >>> metric.compute() ``` - - diff --git a/docs/source/pt/create_a_model.md b/docs/source/pt/create_a_model.md index c0736f72771b..3eec2233540d 100644 --- a/docs/source/pt/create_a_model.md +++ b/docs/source/pt/create_a_model.md @@ -111,8 +111,6 @@ Você pode também salvar seu arquivo de configurações como um dicionário ou O próximo passo é criar um [model](main_classes/models). O modelo - também vagamente referido como arquitetura - define o que cada camada está fazendo e quais operações estão acontecendo. Atributos como `num_hidden_layers` das configurações são utilizados para definir a arquitetura. Todo modelo compartilha a classe base [`PreTrainedModel`] e alguns métodos em comum como redimensionar o tamanho dos embeddings de entrada e podar as 'self-attention heads'. Além disso, todos os modelos também são subclasses de [`torch.nn.Module`](https://pytorch.org/docs/stable/generated/torch.nn.Module.html), [`tf.keras.Model`](https://www.tensorflow.org/api_docs/python/tf/keras/Model) ou [`flax.linen.Module`](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html). Isso significa que os modelos são compatíveis com cada respectivo uso de framework. - - Carregar seus atributos de configuração customizados em um modelo: ```py @@ -135,15 +133,11 @@ Quando você carregar os pesos pré-treinados, a configuração padrão do model ```py >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) ``` - - ### Heads do modelo Neste ponto, você tem um modelo básico do DistilBERT que gera os *estados ocultos*. Os estados ocultos são passados como entrada para a head do moelo para produzir a saída final. 🤗 Transformers fornece uma head de modelo diferente para cada tarefa desde que o modelo suporte essa tarefa (por exemplo, você não consegue utilizar o modelo DistilBERT para uma tarefa de 'sequence-to-sequence' como tradução). - - Por exemplo, [`DistilBertForSequenceClassification`] é um modelo DistilBERT base com uma head de classificação de sequência. A head de calssificação de sequência é uma camada linear no topo das saídas agrupadas. ```py @@ -159,8 +153,6 @@ Reutilize facilmente esse ponto de parada para outra tarefe mudando para uma hea >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - - ## Tokenizer diff --git a/docs/source/pt/quicktour.md b/docs/source/pt/quicktour.md index 1704c0fb2c7c..541d723fd809 100644 --- a/docs/source/pt/quicktour.md +++ b/docs/source/pt/quicktour.md @@ -66,13 +66,9 @@ No exemplo a seguir, você usará [`pipeline`] para análise sentimental. Instale as seguintes dependências se você ainda não o fez: - - ```bash pip install torch ``` - - Importe [`pipeline`] e especifique a tarefa que deseja completar: @@ -147,8 +143,6 @@ A [`pipeline`] pode acomodar qualquer modelo do [Model Hub](https://huggingface. >>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ``` - - Use o [`AutoModelForSequenceClassification`] e [`AutoTokenizer`] para carregar o modelo pré-treinado e seu tokenizer associado (mais em `AutoClass` abaixo): ```py @@ -157,8 +151,6 @@ Use o [`AutoModelForSequenceClassification`] e [`AutoTokenizer`] para carregar o >>> model = AutoModelForSequenceClassification.from_pretrained(model_name) >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - - Então você pode especificar o modelo e o tokenizador na [`pipeline`] e aplicar o `classifier` no seu texto alvo: @@ -210,8 +202,6 @@ O tokenizer retornará um dicionário contendo: Assim como o [`pipeline`], o tokenizer aceitará uma lista de entradas. Além disso, o tokenizer também pode preencher e truncar o texto para retornar um lote com comprimento uniforme: - - ```py >>> pt_batch = tokenizer( @@ -222,15 +212,11 @@ Assim como o [`pipeline`], o tokenizer aceitará uma lista de entradas. Além di ... return_tensors="pt", ... ) ``` - - Leia o tutorial de [pré-processamento](./pré-processamento) para obter mais detalhes sobre tokenização. ### AutoModel - - 🤗 Transformers fornecem uma maneira simples e unificada de carregar instâncias pré-treinadas. Isso significa que você pode carregar um [`AutoModel`] como carregaria um [`AutoTokenizer`]. A única diferença é selecionar o [`AutoModel`] correto para a tarefa. Como você está fazendo classificação de texto ou sequência, carregue [`AutoModelForSequenceClassification`]: ```py @@ -262,8 +248,6 @@ O modelo gera as ativações finais no atributo `logits`. Aplique a função sof tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - - @@ -283,8 +267,6 @@ As saídas do modelo também se comportam como uma tupla ou um dicionário (por ### Salvar um modelo - - Uma vez que seu modelo estiver afinado, você pode salvá-lo com seu Tokenizer usando [`PreTrainedModel.save_pretrained`]: ```py @@ -298,13 +280,9 @@ Quando você estiver pronto para usá-lo novamente, recarregue com [`PreTrainedM ```py >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - - Um recurso particularmente interessante dos 🤗 Transformers é a capacidade de salvar um modelo e recarregá-lo como um modelo PyTorch ou TensorFlow. Use `from_pt` ou `from_tf` para converter o modelo de um framework para outro: - - ```py >>> from transformers import AutoModel @@ -312,5 +290,3 @@ Um recurso particularmente interessante dos 🤗 Transformers é a capacidade de >>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory) >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - diff --git a/docs/source/pt/run_scripts.md b/docs/source/pt/run_scripts.md index 32182497a366..4b4baf18988f 100644 --- a/docs/source/pt/run_scripts.md +++ b/docs/source/pt/run_scripts.md @@ -85,8 +85,6 @@ pip install -r requirements.txt ## Executando um script - - O script de exemplo baixa e pré-processa um conjunto de dados da biblioteca 🤗 [Datasets](https://huggingface.co/docs/datasets/). Em seguida, o script ajusta um conjunto de dados com o [Trainer](https://huggingface.co/docs/transformers/main_classes/trainer) em uma arquitetura que oferece suporte à sumarização. O exemplo a seguir mostra como ajustar [T5-small](https://huggingface.co/google-t5/t5-small) no conjunto de dados [CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail). O modelo T5 requer um argumento `source_prefix` adicional devido à forma como foi treinado. Este prompt informa ao T5 que esta é uma tarefa de sumarização. @@ -104,8 +102,6 @@ python examples/pytorch/summarization/run_summarization.py \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Treinamento distribuído e precisão mista @@ -135,8 +131,6 @@ Os scripts do TensorFlow utilizam um [`MirroredStrategy`](https://www.tensorflow ## Executando um script em uma TPU - - As Unidades de Processamento de Tensor (TPUs) são projetadas especificamente para acelerar o desempenho. O PyTorch oferece suporte a TPUs com o compilador de aprendizado profundo [XLA](https://www.tensorflow.org/xla) (consulte [aqui](https://github.com/pytorch/xla/blob/master/README.md) para mais detalhes). Para usar uma TPU, inicie o script `xla_spawn.py` e use o argumento `num_cores` para definir o número de núcleos de TPU que você deseja usar. ```bash @@ -154,8 +148,6 @@ python xla_spawn.py --num_cores 8 \ --overwrite_output_dir \ --predict_with_generate ``` - - ## Execute um script com 🤗 Accelerate diff --git a/docs/source/pt/tasks/sequence_classification.md b/docs/source/pt/tasks/sequence_classification.md index b60851127757..70db6310e50a 100644 --- a/docs/source/pt/tasks/sequence_classification.md +++ b/docs/source/pt/tasks/sequence_classification.md @@ -78,20 +78,14 @@ tokenized_imdb = imdb.map(preprocess_function, batched=True) Use o [`DataCollatorWithPadding`] para criar um batch de exemplos. Ele também *preencherá dinamicamente* seu texto até o comprimento do elemento mais longo em seu batch, para que os exemplos do batch tenham um comprimento uniforme. Embora seja possível preencher seu texto com a função `tokenizer` definindo `padding=True`, o preenchimento dinâmico utilizando um data collator é mais eficiente. - - ```py >>> from transformers import DataCollatorWithPadding >>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer) ``` - - ## Train - - Carregue o DistilBERT com [`AutoModelForSequenceClassification`] junto com o número de rótulos esperados: ```py @@ -139,8 +133,6 @@ Nesse ponto, restam apenas três passos: O [`Trainer`] aplicará o preenchimento dinâmico por padrão quando você definir o argumento `tokenizer` dele. Nesse caso, você não precisa especificar um data collator explicitamente. - - diff --git a/docs/source/pt/tasks/token_classification.md b/docs/source/pt/tasks/token_classification.md index d314caf157f7..3c0ac5671589 100644 --- a/docs/source/pt/tasks/token_classification.md +++ b/docs/source/pt/tasks/token_classification.md @@ -136,20 +136,14 @@ Use a função [`map`](https://huggingface.co/docs/datasets/process#map) do 🤗 Use o [`DataCollatorForTokenClassification`] para criar um batch de exemplos. Ele também *preencherá dinamicamente* seu texto e rótulos para o comprimento do elemento mais longo em seu batch, para que tenham um comprimento uniforme. Embora seja possível preencher seu texto na função `tokenizer` configurando `padding=True`, o preenchimento dinâmico é mais eficiente. - - ```py >>> from transformers import DataCollatorForTokenClassification >>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer) ``` - - ## Treinamento - - Carregue o DistilBERT com o [`AutoModelForTokenClassification`] junto com o número de rótulos esperados: ```py @@ -192,8 +186,6 @@ Nesse ponto, restam apenas três passos: >>> trainer.train() ``` - - diff --git a/docs/source/zh/autoclass_tutorial.md b/docs/source/zh/autoclass_tutorial.md index 95fb1783a864..a65409b2d1c5 100644 --- a/docs/source/zh/autoclass_tutorial.md +++ b/docs/source/zh/autoclass_tutorial.md @@ -96,8 +96,6 @@ rendered properly in your Markdown viewer. ## AutoModel - - 最后,`AutoModelFor`类让你可以加载给定任务的预训练模型(参见[这里](model_doc/auto)获取可用任务的完整列表)。例如,使用[`AutoModelForSequenceClassification.from_pretrained`]加载用于序列分类的模型: @@ -126,5 +124,3 @@ TensorFlow和Flax的checkpoints不受影响,并且可以在PyTorch架构中使 一般来说,我们建议使用`AutoTokenizer`类和`AutoModelFor`类来加载预训练的模型实例。这样可以确保每次加载正确的架构。在下一个[教程](preprocessing)中,学习如何使用新加载的`tokenizer`, `image processor`, `feature extractor`和`processor`对数据集进行预处理以进行微调。 - - diff --git a/docs/source/zh/create_a_model.md b/docs/source/zh/create_a_model.md index 862842f15db6..c36eaef540a1 100644 --- a/docs/source/zh/create_a_model.md +++ b/docs/source/zh/create_a_model.md @@ -112,8 +112,6 @@ DistilBertConfig { 接下来,创建一个[模型](main_classes/models)。模型,也可泛指架构,定义了每一层网络的行为以及进行的操作。配置中的 `num_hidden_layers` 等属性用于定义架构。每个模型都共享基类 [`PreTrainedModel`] 和一些常用方法,例如调整输入嵌入的大小和修剪自注意力头。此外,所有模型都是 [`torch.nn.Module`](https://pytorch.org/docs/stable/generated/torch.nn.Module.html)、[`tf.keras.Model`](https://www.tensorflow.org/api_docs/python/tf/keras/Model) 或 [`flax.linen.Module`](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html) 的子类。这意味着模型与各自框架的用法兼容。 - - 将自定义配置属性加载到模型中: ```py @@ -136,15 +134,11 @@ DistilBertConfig { ```py >>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config) ``` - - ### 模型头(Model heads) 此时,你已经有了一个输出*隐藏状态*的基础 DistilBERT 模型。隐藏状态作为输入传递到模型头以生成最终输出。🤗 Transformers 为每个任务提供不同的模型头,只要模型支持该任务(即,您不能使用 DistilBERT 来执行像翻译这样的序列到序列任务)。 - - 例如,[`DistilBertForSequenceClassification`] 是一个带有序列分类头(sequence classification head)的基础 DistilBERT 模型。序列分类头是池化输出之上的线性层。 ```py @@ -160,8 +154,6 @@ DistilBertConfig { >>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased") ``` - - ## 分词器 diff --git a/docs/source/zh/model_sharing.md b/docs/source/zh/model_sharing.md index ab77665f8411..07d99c93c920 100644 --- a/docs/source/zh/model_sharing.md +++ b/docs/source/zh/model_sharing.md @@ -79,8 +79,6 @@ pip install huggingface_hub 为另一个框架转换`checkpoints`很容易。确保您已安装PyTorch和TensorFlow(请参阅[此处](installation)的安装说明),然后在其他框架中找到适合您任务的特定模型。 - - 指定`from_tf=True`将checkpoint从TensorFlow转换为PyTorch。 @@ -88,13 +86,9 @@ pip install huggingface_hub >>> pt_model = DistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_tf=True) >>> pt_model.save_pretrained("path/to/awesome-name-you-picked") ``` - - ## 在训练过程中推送模型 - - 将模型分享到Hub就像添加一个额外的参数或回调函数一样简单。请记住,在[微调教程](training)中,`TrainingArguments`类是您指定超参数和附加训练选项的地方。其中一项训练选项包括直接将模型推送到Hub的能力。在您的`TrainingArguments`中设置`push_to_hub=True`: @@ -121,8 +115,6 @@ pip install huggingface_hub ```py >>> trainer.push_to_hub() ``` - - ## 使用`push_to_hub`功能 diff --git a/docs/source/zh/preprocessing.md b/docs/source/zh/preprocessing.md index c33fdee980ed..252f41f214ea 100644 --- a/docs/source/zh/preprocessing.md +++ b/docs/source/zh/preprocessing.md @@ -173,8 +173,6 @@ pip install datasets 将 `return_tensors` 参数设置为 `pt`(对于PyTorch)或 `tf`(对于TensorFlow): - - ```py @@ -195,8 +193,6 @@ pip install datasets [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])} ``` - - ## 音频 diff --git a/docs/source/zh/quicktour.md b/docs/source/zh/quicktour.md index e28101fd6393..c4aa032df8d1 100644 --- a/docs/source/zh/quicktour.md +++ b/docs/source/zh/quicktour.md @@ -28,14 +28,10 @@ rendered properly in your Markdown viewer. 你还需要安装喜欢的机器学习框架: - - ```bash pip install torch ``` - - ## Pipeline @@ -126,8 +122,6 @@ label: NEGATIVE, with score: 0.5309 >>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment" ``` - - 使用 [`AutoModelForSequenceClassification`] 和 [`AutoTokenizer`] 来加载预训练模型和它关联的分词器(更多信息可以参考下一节的 `AutoClass`): ```py @@ -136,8 +130,6 @@ label: NEGATIVE, with score: 0.5309 >>> model = AutoModelForSequenceClassification.from_pretrained(model_name) >>> tokenizer = AutoTokenizer.from_pretrained(model_name) ``` - - 在 [`pipeline`] 中指定模型和分词器,现在你就可以在法语文本上使用 `classifier` 了: @@ -187,8 +179,6 @@ label: NEGATIVE, with score: 0.5309 分词器也可以接受列表作为输入,并填充和截断文本,返回具有统一长度的批次: - - ```py >>> pt_batch = tokenizer( @@ -199,8 +189,6 @@ label: NEGATIVE, with score: 0.5309 ... return_tensors="pt", ... ) ``` - - @@ -210,8 +198,6 @@ label: NEGATIVE, with score: 0.5309 ### AutoModel - - 🤗 Transformers 提供了一种简单统一的方式来加载预训练的实例. 这表示你可以像加载 [`AutoTokenizer`] 一样加载 [`AutoModel`]。唯一不同的地方是为你的任务选择正确的[`AutoModel`]。对于文本(或序列)分类,你应该加载[`AutoModelForSequenceClassification`]: ```py @@ -243,8 +229,6 @@ label: NEGATIVE, with score: 0.5309 tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=) ``` - - @@ -255,8 +239,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ### 保存模型 - - 当你的模型微调完成,你就可以使用 [`PreTrainedModel.save_pretrained`] 把它和它的分词器保存下来: ```py @@ -270,13 +252,9 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], ```py >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` - - 🤗 Transformers 有一个特别酷的功能,它能够保存一个模型,并且将它加载为 PyTorch 或 TensorFlow 模型。`from_pt` 或 `from_tf` 参数可以将模型从一个框架转换为另一个框架: - - ```py >>> from transformers import AutoModel @@ -284,8 +262,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory) >>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) ``` - - ## 自定义模型构建 @@ -299,8 +275,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_config = AutoConfig.from_pretrained("distilbert/distilbert-base-uncased", n_heads=12) ``` - - 使用 [`AutoModel.from_config`] 根据你的自定义配置创建一个模型: ```py @@ -308,8 +282,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> my_model = AutoModel.from_config(my_config) ``` - - 查阅 [创建一个自定义结构](./create_a_model) 指南获取更多关于构建自定义配置的信息。 diff --git a/docs/source/zh/run_scripts.md b/docs/source/zh/run_scripts.md index c82264299a70..78b1629657f3 100644 --- a/docs/source/zh/run_scripts.md +++ b/docs/source/zh/run_scripts.md @@ -85,8 +85,6 @@ pip install -r requirements.txt ## 运行脚本 - - 示例脚本从🤗 [Datasets](https://huggingface.co/docs/datasets/)库下载并预处理数据集。然后,脚本通过[Trainer](https://huggingface.co/docs/transformers/main_classes/trainer)使用支持摘要任务的架构对数据集进行微调。以下示例展示了如何在[CNN/DailyMail](https://huggingface.co/datasets/cnn_dailymail)数据集上微调[T5-small](https://huggingface.co/google-t5/t5-small)。由于T5模型的训练方式,它需要一个额外的`source_prefix`参数。这个提示让T5知道这是一个摘要任务。 @@ -104,8 +102,6 @@ python examples/pytorch/summarization/run_summarization.py \ --overwrite_output_dir \ --predict_with_generate ``` - - ## 分布式训练和混合精度 @@ -136,8 +132,6 @@ TensorFlow脚本使用[`MirroredStrategy`](https://www.tensorflow.org/guide/dist ## 在TPU上运行脚本 - - 张量处理单元(TPUs)是专门设计用于加速性能的。PyTorch使用[XLA](https://www.tensorflow.org/xla)深度学习编译器支持TPU(更多细节请参见[这里](https://github.com/pytorch/xla/blob/master/README.md))。要使用TPU,请启动`xla_spawn.py`脚本并使用`num_cores`参数设置要使用的TPU核心数量。 @@ -156,8 +150,6 @@ python xla_spawn.py --num_cores 8 \ --overwrite_output_dir \ --predict_with_generate ``` - - ## 基于🤗 Accelerate运行脚本 diff --git a/docs/source/zh/tasks/asr.md b/docs/source/zh/tasks/asr.md index 228ba55c0d0e..3798640026d5 100644 --- a/docs/source/zh/tasks/asr.md +++ b/docs/source/zh/tasks/asr.md @@ -242,8 +242,6 @@ Wav2Vec2 分词器仅训练了大写字符,因此您需要确保文本与分 ## 训练 - - 如果您不熟悉使用[`Trainer`]微调模型,请查看这里的基本教程[here](../training#train-with-pytorch-trainer)! @@ -311,8 +309,6 @@ Wav2Vec2 分词器仅训练了大写字符,因此您需要确保文本与分 ```py >>> trainer.push_to_hub() ``` - - @@ -356,8 +352,6 @@ Wav2Vec2 分词器仅训练了大写字符,因此您需要确保文本与分 如果您愿意,您也可以手动复制 `pipeline` 的结果: - - 加载一个处理器来预处理音频文件和转录,并将 `input` 返回为 PyTorch 张量: @@ -388,5 +382,3 @@ Wav2Vec2 分词器仅训练了大写字符,因此您需要确保文本与分 >>> transcription ['I WOUL LIKE O SET UP JOINT ACOUNT WTH Y PARTNER'] ``` - - diff --git a/docs/source/zh/training.md b/docs/source/zh/training.md index d383f73dc623..43243ab4cfbf 100644 --- a/docs/source/zh/training.md +++ b/docs/source/zh/training.md @@ -71,8 +71,6 @@ rendered properly in your Markdown viewer. 此时,您应该根据您训练所用的框架来选择对应的教程章节。您可以使用右侧的链接跳转到您想要的章节 - 如果您想隐藏某个框架对应的所有教程内容,只需使用右上角的按钮! - - ## 使用 PyTorch Trainer 进行训练 @@ -152,15 +150,11 @@ rendered properly in your Markdown viewer. ```py >>> trainer.train() ``` - - ## 在原生 PyTorch 中训练 - - [`Trainer`] 负责训练循环,允许您在一行代码中微调模型。对于喜欢编写自己训练循环的用户,您也可以在原生 PyTorch 中微调 🤗 Transformers 模型。 @@ -303,8 +297,6 @@ torch.cuda.empty_cache() >>> metric.compute() ``` - - From fa3c2d7379a7536b4f5fa0202dd921a0675fc6af Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:51:00 +0200 Subject: [PATCH 154/204] =?UTF-8?q?Fix=20CI=20jobs=20being=20all=20red=20?= =?UTF-8?q?=F0=9F=94=B4=20(false=20positive)=20(#41059)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix Co-authored-by: ydshieh --- .github/workflows/model_jobs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/model_jobs.yml b/.github/workflows/model_jobs.yml index 121a8687556f..83f818fcda3b 100644 --- a/.github/workflows/model_jobs.yml +++ b/.github/workflows/model_jobs.yml @@ -141,8 +141,8 @@ jobs: script -q -c "PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS=yes _PATCHED_TESTING_METHODS_OUTPUT_DIR=/transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports python3 -m pytest -rsfE -v --make-reports=${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports tests/${{ matrix.folders }}" test_outputs.txt ls -la # Extract the exit code from the output file - PYTEST_EXIT_CODE=$(tail -1 test_outputs.txt | grep "PYTEST_EXIT_CODE:" | cut -d: -f2) - exit ${PYTEST_EXIT_CODE:-1} + EXIT_CODE=$(tail -1 test_outputs.txt | grep -o 'COMMAND_EXIT_CODE="[0-9]*"' | cut -d'"' -f2) + exit ${EXIT_CODE:-1} - name: Failure short reports if: ${{ failure() }} From 7d9085513c6a8a2ffb50bf5dd024471df5a76831 Mon Sep 17 00:00:00 2001 From: Marc Sun <57196510+SunMarc@users.noreply.github.com> Date: Mon, 22 Sep 2025 18:10:16 +0200 Subject: [PATCH 155/204] Update quantization CI (#41068) * fix * new everything * fix --- .../Dockerfile | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/docker/transformers-quantization-latest-gpu/Dockerfile b/docker/transformers-quantization-latest-gpu/Dockerfile index deb6761db8e0..f78614d59a6e 100755 --- a/docker/transformers-quantization-latest-gpu/Dockerfile +++ b/docker/transformers-quantization-latest-gpu/Dockerfile @@ -1,4 +1,4 @@ -FROM nvidia/cuda:12.1.1-cudnn8-devel-ubuntu22.04 +FROM nvidia/cuda:12.6.0-cudnn-devel-ubuntu22.04 LABEL maintainer="Hugging Face" ARG DEBIAN_FRONTEND=noninteractive @@ -9,9 +9,9 @@ SHELL ["sh", "-lc"] # The following `ARG` are mainly used to specify the versions explicitly & directly in this docker file, and not meant # to be used as arguments for docker build (so far). -ARG PYTORCH='2.6.0' +ARG PYTORCH='2.8.0' # Example: `cu102`, `cu113`, etc. -ARG CUDA='cu121' +ARG CUDA='cu126' # Disable kernel mapping for quantization tests ENV DISABLE_KERNEL_MAPPING=1 @@ -46,16 +46,6 @@ RUN python3 -m pip install --no-cache-dir git+https://github.com/huggingface/opt # Add PEFT RUN python3 -m pip install --no-cache-dir git+https://github.com/huggingface/peft@main#egg=peft -# Add aqlm for quantization testing -RUN python3 -m pip install --no-cache-dir aqlm[gpu]==1.0.2 - -# Add vptq for quantization testing -RUN pip install vptq - -# Add spqr for quantization testing -# Commented for now as No matching distribution found we need to reach out to the authors -# RUN python3 -m pip install --no-cache-dir spqr_quant[gpu] - # Add hqq for quantization testing RUN python3 -m pip install --no-cache-dir hqq @@ -63,25 +53,11 @@ RUN python3 -m pip install --no-cache-dir hqq RUN python3 -m pip install --no-cache-dir gguf # Add autoawq for quantization testing -# New release v0.2.8 RUN python3 -m pip install --no-cache-dir autoawq[kernels] # Add quanto for quantization testing RUN python3 -m pip install --no-cache-dir optimum-quanto -# Add eetq for quantization testing -RUN git clone https://github.com/NetEase-FuXi/EETQ.git && cd EETQ/ && git submodule update --init --recursive && pip install . - -# # Add flute-kernel and fast_hadamard_transform for quantization testing -# # Commented for now as they cause issues with the build -# # TODO: create a new workflow to test them -# RUN python3 -m pip install --no-cache-dir flute-kernel==0.4.1 -# RUN python3 -m pip install --no-cache-dir git+https://github.com/Dao-AILab/fast-hadamard-transform.git - -# Add fp-quant for quantization testing -# Requires py3.11 but our CI runs on 3.9 -# RUN python3 -m pip install --no-cache-dir "fp-quant>=0.1.6" - # Add compressed-tensors for quantization testing RUN python3 -m pip install --no-cache-dir compressed-tensors @@ -89,7 +65,10 @@ RUN python3 -m pip install --no-cache-dir compressed-tensors RUN python3 -m pip install --no-cache-dir amd-quark # Add AutoRound for quantization testing -RUN python3 -m pip install --no-cache-dir "auto-round>=0.5.0" +RUN python3 -m pip install --no-cache-dir auto-round + +# Add torchao for quantization testing +RUN python3 -m pip install --no-cache-dir torchao # Add transformers in editable mode RUN python3 -m pip install --no-cache-dir -e ./transformers[dev-torch] @@ -103,3 +82,28 @@ RUN python3 -m pip uninstall -y flash-attn # When installing in editable mode, `transformers` is not recognized as a package. # this line must be added in order for python to be aware of transformers. RUN cd transformers && python3 setup.py develop + +# Low usage or incompatible lib, will enable later on + +# # Add aqlm for quantization testing +# RUN python3 -m pip install --no-cache-dir aqlm[gpu]==1.0.2 + +# # Add vptq for quantization testing +# RUN pip install vptq + +# Add spqr for quantization testing +# Commented for now as No matching distribution found we need to reach out to the authors +# RUN python3 -m pip install --no-cache-dir spqr_quant[gpu] + +# # Add eetq for quantization testing +# RUN git clone https://github.com/NetEase-FuXi/EETQ.git && cd EETQ/ && git submodule update --init --recursive && pip install . + +# # Add flute-kernel and fast_hadamard_transform for quantization testing +# # Commented for now as they cause issues with the build +# # TODO: create a new workflow to test them +# RUN python3 -m pip install --no-cache-dir flute-kernel==0.4.1 +# RUN python3 -m pip install --no-cache-dir git+https://github.com/Dao-AILab/fast-hadamard-transform.git + +# Add fp-quant for quantization testing +# Requires py3.11 but our CI runs on 3.9 +# RUN python3 -m pip install --no-cache-dir "fp-quant>=0.1.6" \ No newline at end of file From 0f21b54f140ba9a3da9eac0e01ecd9b67bf88684 Mon Sep 17 00:00:00 2001 From: Saidur Rahman Pulok <59414463+saidurpulok@users.noreply.github.com> Date: Mon, 22 Sep 2025 22:51:39 +0600 Subject: [PATCH 156/204] [i18n-bn] Add Bengali language README file (#40935) * [i18n-bn] Add Bengali language README file and update links in existing language files * Update Bengali README for clarity and consistency in model descriptions --- README.md | 1 + i18n/README_ar.md | 1 + i18n/README_bn.md | 334 +++++++++++++++++++++++++++++++++++++++++ i18n/README_de.md | 1 + i18n/README_es.md | 1 + i18n/README_fr.md | 1 + i18n/README_hd.md | 1 + i18n/README_ja.md | 1 + i18n/README_ko.md | 1 + i18n/README_pt-br.md | 1 + i18n/README_ru.md | 1 + i18n/README_te.md | 1 + i18n/README_ur.md | 1 + i18n/README_vi.md | 1 + i18n/README_zh-hans.md | 1 + i18n/README_zh-hant.md | 1 + 16 files changed, 349 insertions(+) create mode 100644 i18n/README_bn.md diff --git a/README.md b/README.md index 0717343f9cff..850b76f5c4f7 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ limitations under the License. Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_ar.md b/i18n/README_ar.md index cdf813445d6f..17281403af4d 100644 --- a/i18n/README_ar.md +++ b/i18n/README_ar.md @@ -50,6 +50,7 @@ limitations under the License. Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_bn.md b/i18n/README_bn.md new file mode 100644 index 000000000000..932124149b62 --- /dev/null +++ b/i18n/README_bn.md @@ -0,0 +1,334 @@ + + +

+ + + + Hugging Face Transformers Library + +
+
+

+ +

+ Checkpoints on Hub + Build + GitHub + Documentation + GitHub release + Contributor Covenant + DOI +

+ +

+

+ English | + 简体中文 | + 繁體中文 | + 한국어 | + Español | + 日本語 | + हिन्दी | + Русский | + Português | + తెలుగు | + Français | + Deutsch | + Tiếng Việt | + العربية | + اردو | + বাংলা | +

+

+ +

+

ইনফারেন্স ও ট্রেনিংয়ের জন্য আধুনিকতম (State-of-the-art) প্রি-ট্রেইন্ড মডেলসমূহ

+

+ +

+ +

+ + +**Transformers** হলো একটা ফ্রেমওয়ার্ক যেটা দিয়ে টেক্সট, কম্পিউটার ভিশন, অডিও, ভিডিও আর মাল্টিমোডাল—সব ধরনের মডেল তৈরি আর চালানো যায়। এটা ট্রেইনিং আর ইনফারেন্স – দুই কাজেই ব্যবহার করা হয়। + +Transformers মডেলের ডেফিনিশন এক জায়গায় রাখে। এর মানে হলো, একবার কোনো মডেল `transformers`-এ সাপোর্ট পেলেই সেটা সহজে বিভিন্ন ট্রেইনিং ফ্রেমওয়ার্ক (Axolotl, Unsloth, DeepSpeed, FSDP, PyTorch-Lightning ইত্যাদি), ইনফারেন্স ইঞ্জিন (vLLM, SGLang, TGI ইত্যাদি) আর অন্যান্য লাইব্রেরি (llama.cpp, mlx ইত্যাদি)-তে ব্যবহার করা যায়। + +আমরা চাই নতুন আর আধুনিক মডেলগুলো সবাই ব্যবহার করতে পারে। তাই মডেলের ডেফিনিশন রাখা হয়েছে সহজ, কাস্টমাইজযোগ্য আর পারফরম্যান্স-ফ্রেন্ডলি। + +এখন পর্যন্ত [Hugging Face Hub](https://huggingface.com/models)-এ ১০ লাখেরও বেশি Transformers [মডেল চেকপয়েন্ট](https://huggingface.co/models?library=transformers&sort=trending) আছে, যেগুলো যেকোনো সময় ব্যবহার করা যায়। + +আজই [Hub](https://huggingface.com/) থেকে একটা মডেল বেছে নিন আর Transformers দিয়ে শুরু করুন। + + +## ইনস্টলেশন + +Transformers Python 3.9+ সহ কাজ করে, এবং সমর্থিত ফ্রেমওয়ার্কগুলো হলো [PyTorch](https://pytorch.org/get-started/locally/) 2.1+, [TensorFlow](https://www.tensorflow.org/install/pip) 2.6+, এবং [Flax](https://flax.readthedocs.io/en/latest/) 0.4.1+। + +[venv](https://docs.python.org/3/library/venv.html) বা [uv](https://docs.astral.sh/uv/) ব্যবহার করে একটি ভার্চুয়াল এনভায়রনমেন্ট তৈরি এবং সক্রিয় করুন। + +```py +# venv +python -m venv .my-env +source .my-env/bin/activate +# uv +uv venv .my-env +source .my-env/bin/activate +``` +আপনার ভার্চুয়াল পরিবেশে Transformers ইনস্টল করুন। + +```py +# pip +pip install "transformers[torch]" + +# uv +uv pip install "transformers[torch]" +``` +যদি আপনি লাইব্রেরির সর্বশেষ পরিবর্তনগুলি চান বা অবদান রাখতে আগ্রহী হন তবে উৎস থেকে Transformers ইনস্টল করুন। তবে, সর্বশেষ সংস্করণটি স্থিতিশীল নাও হতে পারে। যদি আপনি কোনো ত্রুটির সম্মুখীন হন তবে নির্দ্বিধায় একটি [issue](https://github.com/huggingface/transformers/issues) খুলুন। + +```Shell +git clone [https://github.com/huggingface/transformers.git](https://github.com/huggingface/transformers.git) +cd transformers + +# pip +pip install .[torch] + +# uv +uv pip install .[torch] +``` + +## কুইকস্টার্ট + +Transformers ব্যবহার শুরু করুন এখনই [Pipeline](https://huggingface.co/docs/transformers/pipeline_tutorial) API দিয়ে। `Pipeline` হলো একটি হাই-লেভেল ইনফারেন্স ক্লাস, যা টেক্সট, অডিও, ভিশন এবং মাল্টিমোডাল টাস্ক সাপোর্ট করে। এটি ইনপুট প্রিপ্রসেসিং করে এবং সঠিক আউটপুট রিটার্ন করে। + +একটি পাইপলাইন তৈরি করুন এবং টেক্সট জেনারেশনের জন্য কোন মডেল ব্যবহার করবেন তা নির্দিষ্ট করুন। মডেলটি ডাউনলোড হয়ে ক্যাশে রাখা হবে, ফলে পরে সহজেই আবার ব্যবহার করতে পারবেন। সবশেষে, মডেলকে প্রম্পট করার জন্য কিছু টেক্সট দিন। + + +```py +from transformers import pipeline + +pipeline = pipeline(task="text-generation", model="Qwen/Qwen2.5-1.5B") +pipeline("the secret to baking a really good cake is ") +[{'generated_text': 'the secret to baking a really good cake is 1) to use the right ingredients and 2) to follow the recipe exactly. the recipe for the cake is as follows: 1 cup of sugar, 1 cup of flour, 1 cup of milk, 1 cup of butter, 1 cup of eggs, 1 cup of chocolate chips. if you want to make 2 cakes, how much sugar do you need? To make 2 cakes, you will need 2 cups of sugar.'}] +``` + +মডেলের সাথে চ্যাট করতে হলেও ব্যবহার প্যাটার্ন একই। শুধু পার্থক্য হলো, আপনাকে একটি চ্যাট হিস্ট্রি তৈরি করতে হবে (যা `Pipeline`-এ ইনপুট হিসেবে যাবে) আপনার আর সিস্টেমের মধ্যে। + +> [!TIP] +> আপনি সরাসরি কমান্ড লাইন থেকেও একটি মডেলের সাথে চ্যাট করতে পারেন। +> ```Shell +> transformers chat Qwen/Qwen2.5-0.5B-Instruct +> ``` + +```Python +import torch +from transformers import pipeline + +chat = [ + {"role": "system", "content": "You are a sassy, wise-cracking robot as imagined by Hollywood circa 1986."}, + {"role": "user", "content": "Hey, can you tell me any fun things to do in New York?"} +] + +pipeline = pipeline(task="text-generation", model="meta-llama/Meta-Llama-3-8B-Instruct", dtype=torch.bfloat16, device_map="auto") +response = pipeline(chat, max_new_tokens=512) +print(response[0]["generated_text"][-1]["content"]) + +বিভিন্ন মোডালিটি এবং কাজের জন্য Pipeline কিভাবে কাজ করে তা দেখতে নিচের উদাহরণগুলো সম্প্রসারণ করুন। +``` + +
+অটোমেটিক স্পিচ রিকগনিশন (ASR) + +```Python +from transformers import pipeline + +pipeline = pipeline(task="automatic-speech-recognition", model="openai/whisper-large-v3") +pipeline("[https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac](https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac)") +{'text': ' I have a dream that one day this nation will rise up and live out the true meaning of its creed.'} +``` + +
+ +
+ইমেজ ক্লাসিফিকেশন + +

+ +

+ +```py +from transformers import pipeline + +pipeline = pipeline(task="image-classification", model="facebook/dinov2-small-imagenet1k-1-layer") +pipeline("[https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png](https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png)") +[{'label': 'macaw', 'score': 0.997848391532898}, + {'label': 'sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita', + 'score': 0.0016551691805943847}, + {'label': 'lorikeet', 'score': 0.00018523589824326336}, + {'label': 'African grey, African gray, Psittacus erithacus', + 'score': 7.85409429227002e-05}, + {'label': 'quail', 'score': 5.502637941390276e-05}] + ``` +
+ +
+ভিজুয়াল কোয়েশ্চন আনসারিং + +

+ +

+ +```py +from transformers import pipeline + +pipeline = pipeline(task="visual-question-answering", model="Salesforce/blip-vqa-base") +pipeline( + image="[https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/idefics-few-shot.jpg](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/idefics-few-shot.jpg)", + question="What is in the image?", +) +[{'answer': 'statue of liberty'}] +``` +
+ +## কেন Transformers ব্যবহার করবেন? + +1. সহজে ব্যবহারযোগ্য সর্বাধুনিক মডেল: + + * ন্যাচারাল ল্যাঙ্গুয়েজ আন্ডারস্ট্যান্ডিং ও জেনারেশন, কম্পিউটার ভিশন, অডিও, ভিডিও এবং মাল্টিমোডাল টাস্কে উচ্চ পারফরম্যান্স। + * গবেষক, ইঞ্জিনিয়ার এবং ডেভেলপারদের জন্য সহজে শুরু করার সুযোগ। + * মাত্র তিনটি ক্লাস শিখলেই ব্যবহার করা যায়। + * সব প্রি-ট্রেইন্ড মডেলের জন্য একটি একীভূত API। + +2. কম কম্পিউট খরচ, ছোট কার্বন ফুটপ্রিন্ট: + + * শূন্য থেকে ট্রেইন না করে ট্রেইন্ড মডেল শেয়ার করুন। + * কম্পিউট টাইম ও প্রোডাকশন খরচ কমান। + * সব ধরনের মোডালিটির জন্য ১০ লক্ষ+ প্রি-ট্রেইন্ড চেকপয়েন্টসহ ডজনখানেক মডেল আর্কিটেকচার। + +3. মডেলের লাইফসাইকেলের প্রতিটি ধাপে সঠিক ফ্রেমওয়ার্ক বেছে নিন: + + * মাত্র ৩ লাইনের কোডে সর্বাধুনিক মডেল ট্রেইন করুন। + * সহজে PyTorch / JAX / TF2.0 এর মধ্যে মডেল স্থানান্তর করুন। + * ট্রেইনিং, ইভ্যালুয়েশন ও প্রোডাকশনের জন্য আলাদা ফ্রেমওয়ার্ক ব্যবহার করুন। + +4. সহজেই মডেল বা উদাহরণ কাস্টমাইজ করুন: + + * প্রতিটি আর্কিটেকচারের জন্য এমন উদাহরণ দেওয়া আছে যা মূল লেখকদের প্রকাশিত ফলাফল পুনরুত্পাদন করতে সক্ষম। + * মডেলের অভ্যন্তরীণ অংশগুলো যতটা সম্ভব একভাবে এক্সপোজ করা হয়েছে। + * দ্রুত এক্সপেরিমেন্টের জন্য লাইব্রেরি ছাড়াও মডেল ফাইল ব্যবহার করা যায়। + + + +Hugging Face Enterprise Hub +
+ +## কেন Transformers ব্যবহার করবেন না? + +* এই লাইব্রেরি নিউরাল নেটওয়ার্কের জন্য ব্লক-মডিউল টুলবক্স নয়। মডেল ফাইলের কোডে অতিরিক্ত অ্যাবস্ট্র্যাকশন intentionally করা হয়নি, যাতে গবেষকরা দ্রুত প্রতিটি মডেলের উপর কাজ করতে পারে কোনো অতিরিক্ত ফাইল বা স্তরে না গিয়ে। +* ট্রেইনিং API মূলত Transformers-এর PyTorch মডেলের সাথে কাজ করার জন্য অপটিমাইজ করা হয়েছে। সাধারণ মেশিন লার্নিং লুপের জন্য, [Accelerate](https://huggingface.co/docs/accelerate) এর মতো অন্য লাইব্রেরি ব্যবহার করা উচিত। +* [উদাহরণ স্ক্রিপ্টগুলো](https://github.com/huggingface/transformers/tree/main/examples) শুধু *উদাহরণ*। এগুলো সরাসরি আপনার ব্যবহারের ক্ষেত্রে কাজ নাও করতে পারে, তাই কোড সামঞ্জস্য করতে হতে পারে। + +## Transformers দিয়ে ১০০টি প্রজেক্ট + +Transformers শুধু প্রি-ট্রেইন্ড মডেল ব্যবহার করার টুলকিট নয়, এটি একটি কমিউনিটি, যা Hugging Face Hub-এর চারপাশে তৈরি। আমরা চাই যে ডেভেলপার, গবেষক, শিক্ষার্থী, অধ্যাপক, ইঞ্জিনিয়ার বা যে কেউ তাদের স্বপ্নের প্রজেক্ট তৈরি করতে পারে। + +Transformers 100,000 স্টার উদযাপন করতে আমরা কমিউনিটিকে তুলে ধরতে [awesome-transformers](./awesome-transformers.md) পেজ তৈরি করেছি, যেখানে Transformers দিয়ে তৈরি ১০০টি অসাধারণ প্রজেক্ট তালিকাভুক্ত আছে। + +আপনার কোনো প্রজেক্ট আছে যা তালিকায় থাকা উচিত মনে করেন? তাহলে PR খুলে যুক্ত করুন। + +## উদাহরণ মডেল + +আপনি আমাদের অধিকাংশ মডেল সরাসরি তাদের [Hub মডেল পেজ](https://huggingface.co/models) থেকে পরীক্ষা করতে পারেন। + +নিচের প্রতিটি মোডালিটি এক্সপ্যান্ড করে বিভিন্ন ব্যবহার কেসের জন্য কয়েকটি উদাহরণ মডেল দেখুন। + + +
+অডিও + +* [Whisper](https://huggingface.co/openai/whisper-large-v3-turbo) দিয়ে অডিও ক্লাসিফিকেশন +* [Moonshine](https://huggingface.co/UsefulSensors/moonshine) দিয়ে অটোমেটিক স্পিচ রিকগনিশন +* [Wav2Vec2](https://huggingface.co/superb/wav2vec2-base-superb-ks) দিয়ে কীওয়ার্ড স্পটিং +* [Moshi](https://huggingface.co/kyutai/moshiko-pytorch-bf16) দিয়ে স্পিচ-টু-স্পিচ জেনারেশন +* [MusicGen](https://huggingface.co/facebook/musicgen-large) দিয়ে টেক্সট-টু-অডিও +* [Bark](https://huggingface.co/suno/bark) দিয়ে টেক্সট-টু-স্পিচ + + +
+ +
+কম্পিউটার ভিশন + +* [SAM](https://huggingface.co/facebook/sam-vit-base) দিয়ে স্বয়ংক্রিয় মাস্ক জেনারেশন +* [DepthPro](https://huggingface.co/apple/DepthPro-hf) দিয়ে গভীরতা অনুমান +* [DINO v2](https://huggingface.co/facebook/dinov2-base) দিয়ে চিত্র শ্রেণীকরণ +* [SuperPoint](https://huggingface.co/magic-leap-community/superpoint) দিয়ে কীপয়েন্ট সনাক্তকরণ +* [SuperGlue](https://huggingface.co/magic-leap-community/superglue_outdoor) দিয়ে কীপয়েন্ট ম্যাচিং +* [RT-DETRv2](https://huggingface.co/PekingU/rtdetr_v2_r50vd) দিয়ে অবজেক্ট সনাক্তকরণ +* [VitPose](https://huggingface.co/usyd-community/vitpose-base-simple) দিয়ে পোস অনুমান +* [OneFormer](https://huggingface.co/shi-labs/oneformer_ade20k_swin_large) দিয়ে ইউনিভার্সাল সেগমেন্টেশন +* [VideoMAE](https://huggingface.co/MCG-NJU/videomae-large) দিয়ে ভিডিও শ্রেণীকরণ + + +
+ +
+মাল্টিমোডাল + +* [Qwen2-Audio](https://huggingface.co/Qwen/Qwen2-Audio-7B) দিয়ে অডিও বা টেক্সট থেকে টেক্সট জেনারেশন +* [LayoutLMv3](https://huggingface.co/microsoft/layoutlmv3-base) দিয়ে ডকুমেন্ট প্রশ্নোত্তর +* [Qwen-VL](https://huggingface.co/Qwen/Qwen2.5-VL-3B-Instruct) দিয়ে ইমেজ বা টেক্সট থেকে টেক্সট জেনারেশন +* [BLIP-2](https://huggingface.co/Salesforce/blip2-opt-2.7b) দিয়ে ইমেজ ক্যাপশনিং +* [GOT-OCR2](https://huggingface.co/stepfun-ai/GOT-OCR-2.0-hf) দিয়ে OCR-ভিত্তিক ডকুমেন্ট আন্ডারস্ট্যান্ডিং +* [TAPAS](https://huggingface.co/google/tapas-base) দিয়ে টেবিল প্রশ্নোত্তর +* [Emu3](https://huggingface.co/BAAI/Emu3-Gen) দিয়ে ইউনিফাইড মাল্টিমোডাল আন্ডারস্ট্যান্ডিং এবং জেনারেশন +* [Llava-OneVision](https://huggingface.co/llava-hf/llava-onevision-qwen2-0.5b-ov-hf) দিয়ে ভিশন থেকে টেক্সট +* [Llava](https://huggingface.co/llava-hf/llava-1.5-7b-hf) দিয়ে ভিজুয়াল কোয়েশ্চন আনসারিং +* [Kosmos-2](https://huggingface.co/microsoft/kosmos-2-patch14-224) দিয়ে ভিজুয়াল রেফারিং এক্সপ্রেশন সেগমেন্টেশন + + +
+ +
+NLP + +* [ModernBERT](https://huggingface.co/answerdotai/ModernBERT-base) দিয়ে মাস্কড ওয়ার্ড কমপ্লিশন +* [Gemma](https://huggingface.co/google/gemma-2-2b) দিয়ে নাম্বড এন্টিটি রিকগনিশন +* [Mixtral](https://huggingface.co/mistralai/Mixtral-8x7B-v0.1) দিয়ে প্রশ্নোত্তর +* [BART](https://huggingface.co/facebook/bart-large-cnn) দিয়ে সারসংক্ষেপ (Summarization) +* [T5](https://huggingface.co/google-t5/t5-base) দিয়ে অনুবাদ +* [Llama](https://huggingface.co/meta-llama/Llama-3.2-1B) দিয়ে টেক্সট জেনারেশন +* [Qwen](https://huggingface.co/Qwen/Qwen2.5-0.5B) দিয়ে টেক্সট ক্লাসিফিকেশন + +
+ +## সাইটেশন +আমাদের [একটি পেপার](https://www.aclweb.org/anthology/2020.emnlp-demos.6/) আছে যা আপনি 🤗 Transformers লাইব্রেরির জন্য রেফারেন্স হিসেবে ব্যবহার করতে পারেন। + +```bibtex +@inproceedings{wolf-etal-2020-transformers, + title = "Transformers: State-of-the-Art Natural Language Processing", + author = "Thomas Wolf and Lysandre Debut and Victor Sanh and Julien Chaumond and Clement Delangue and Anthony Moi and Pierric Cistac and Tim Rault and Rémi Louf and Morgan Funtowicz and Joe Davison and Sam Shleifer and Patrick von Platen and Clara Ma and Yacine Jernite and Julien Plu and Canwen Xu and Teven Le Scao and Sylvain Gugger and Mariama Drame and Quentin Lhoest and Alexander M. Rush", + booktitle = "Proceedings of the 2020 Conference on Empirical Methods in Natural Language Processing: System Demonstrations", + month = oct, + year = "2020", + address = "Online", + publisher = "Association for Computational Linguistics", + url = "https://www.aclweb.org/anthology/2020.emnlp-demos.6", + pages = "38--45" +} +``` \ No newline at end of file diff --git a/i18n/README_de.md b/i18n/README_de.md index b913df894dc1..bcc16a370c2f 100644 --- a/i18n/README_de.md +++ b/i18n/README_de.md @@ -50,6 +50,7 @@ limitations under the License. Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_es.md b/i18n/README_es.md index d31b7f5f76c3..dd9613ac1332 100644 --- a/i18n/README_es.md +++ b/i18n/README_es.md @@ -50,6 +50,7 @@ limitations under the License. Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_fr.md b/i18n/README_fr.md index 6512b4af0700..4aec9b10c6ec 100644 --- a/i18n/README_fr.md +++ b/i18n/README_fr.md @@ -50,6 +50,7 @@ limitations under the License. Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_hd.md b/i18n/README_hd.md index 1eb220efadc0..44c0b47d5568 100644 --- a/i18n/README_hd.md +++ b/i18n/README_hd.md @@ -75,6 +75,7 @@ checkpoint: जाँच बिंदु Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_ja.md b/i18n/README_ja.md index 5d5db4993239..ddfc898b374f 100644 --- a/i18n/README_ja.md +++ b/i18n/README_ja.md @@ -85,6 +85,7 @@ user: ユーザ Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_ko.md b/i18n/README_ko.md index fded56a37c9b..8719f5c2c8c7 100644 --- a/i18n/README_ko.md +++ b/i18n/README_ko.md @@ -50,6 +50,7 @@ limitations under the License. Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_pt-br.md b/i18n/README_pt-br.md index e3c71c6a3f35..789270f2d840 100644 --- a/i18n/README_pt-br.md +++ b/i18n/README_pt-br.md @@ -50,6 +50,7 @@ limitations under the License. Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_ru.md b/i18n/README_ru.md index c30237fef885..28e4fb687269 100644 --- a/i18n/README_ru.md +++ b/i18n/README_ru.md @@ -50,6 +50,7 @@ limitations under the License. Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_te.md b/i18n/README_te.md index aee579b52abd..def5cfbe85c2 100644 --- a/i18n/README_te.md +++ b/i18n/README_te.md @@ -52,6 +52,7 @@ limitations under the License. Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_ur.md b/i18n/README_ur.md index bba5988e7717..dad45a0daedd 100644 --- a/i18n/README_ur.md +++ b/i18n/README_ur.md @@ -49,6 +49,7 @@ limitations under the License. Deutsch | Tiếng Việt | العربية | + বাংলা | اردو |

diff --git a/i18n/README_vi.md b/i18n/README_vi.md index f78e3b6d4e9b..299fa7876736 100644 --- a/i18n/README_vi.md +++ b/i18n/README_vi.md @@ -50,6 +50,7 @@ limitations under the License. Tiếng việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_zh-hans.md b/i18n/README_zh-hans.md index 8220e403b8b2..f5f13488565a 100644 --- a/i18n/README_zh-hans.md +++ b/i18n/README_zh-hans.md @@ -75,6 +75,7 @@ checkpoint: 检查点 Tiếng Việt | العربية | اردو | + বাংলা |

diff --git a/i18n/README_zh-hant.md b/i18n/README_zh-hant.md index da6ed40910ea..7661dd3db6b0 100644 --- a/i18n/README_zh-hant.md +++ b/i18n/README_zh-hant.md @@ -87,6 +87,7 @@ user: 使用者 Tiếng Việt | العربية | اردو | + বাংলা |

From f84f4417e82aa9d4c7aa9f371c24c9de51abe3b4 Mon Sep 17 00:00:00 2001 From: Nick Doiron Date: Mon, 22 Sep 2025 12:36:20 -0500 Subject: [PATCH 157/204] Improve documentation and errors in Mamba2-based models (#41063) * fix bug in Mamba2 docs * correct 'because on of' issue * link to other Mamba2 model types * github URL is not changed * update error message in generated files --- docs/source/en/model_doc/mamba2.md | 6 ++++-- docs/source/en/model_doc/zamba2.md | 2 +- src/transformers/models/bamba/modeling_bamba.py | 2 +- src/transformers/models/bamba/modular_bamba.py | 2 +- src/transformers/models/falcon_h1/modeling_falcon_h1.py | 2 +- src/transformers/models/falcon_h1/modular_falcon_h1.py | 2 +- .../models/granitemoehybrid/modeling_granitemoehybrid.py | 2 +- src/transformers/models/jamba/modeling_jamba.py | 2 +- src/transformers/models/mamba2/modeling_mamba2.py | 2 +- src/transformers/models/zamba/modeling_zamba.py | 2 +- src/transformers/models/zamba2/modeling_zamba2.py | 2 +- src/transformers/models/zamba2/modular_zamba2.py | 2 +- 12 files changed, 15 insertions(+), 13 deletions(-) diff --git a/docs/source/en/model_doc/mamba2.md b/docs/source/en/model_doc/mamba2.md index 547e959634e3..11666e1fa576 100644 --- a/docs/source/en/model_doc/mamba2.md +++ b/docs/source/en/model_doc/mamba2.md @@ -1,4 +1,4 @@ - - -| 模型 | PyTorch 支持 | TensorFlow 支持 | Flax 支持 | -|:------------------------------------------------------------------------:|:---------------:|:------------------:|:------------:| -| [ALBERT](../en/model_doc/albert) | ✅ | ✅ | ✅ | -| [ALIGN](../en/model_doc/align) | ✅ | ❌ | ❌ | -| [AltCLIP](../en/model_doc/altclip) | ✅ | ❌ | ❌ | -| [Audio Spectrogram Transformer](../en/model_doc/audio-spectrogram-transformer) | ✅ | ❌ | ❌ | -| [Autoformer](../en/model_doc/autoformer) | ✅ | ❌ | ❌ | -| [Bark](../en/model_doc/bark) | ✅ | ❌ | ❌ | -| [BART](../en/model_doc/bart) | ✅ | ✅ | ✅ | -| [BARThez](../en/model_doc/barthez) | ✅ | ✅ | ✅ | -| [BARTpho](../en/model_doc/bartpho) | ✅ | ✅ | ✅ | -| [BEiT](../en/model_doc/beit) | ✅ | ❌ | ✅ | -| [BERT](../en/model_doc/bert) | ✅ | ✅ | ✅ | -| [Bert Generation](../en/model_doc/bert-generation) | ✅ | ❌ | ❌ | -| [BertJapanese](../en/model_doc/bert-japanese) | ✅ | ✅ | ✅ | -| [BERTweet](../en/model_doc/bertweet) | ✅ | ✅ | ✅ | -| [BigBird](../en/model_doc/big_bird) | ✅ | ❌ | ✅ | -| [BigBird-Pegasus](../en/model_doc/bigbird_pegasus) | ✅ | ❌ | ❌ | -| [BioGpt](../en/model_doc/biogpt) | ✅ | ❌ | ❌ | -| [BiT](../en/model_doc/bit) | ✅ | ❌ | ❌ | -| [Blenderbot](../en/model_doc/blenderbot) | ✅ | ✅ | ✅ | -| [BlenderbotSmall](../en/model_doc/blenderbot-small) | ✅ | ✅ | ✅ | -| [BLIP](../en/model_doc/blip) | ✅ | ✅ | ❌ | -| [BLIP-2](../en/model_doc/blip-2) | ✅ | ❌ | ❌ | -| [BLOOM](../en/model_doc/bloom) | ✅ | ❌ | ✅ | -| [BORT](../en/model_doc/bort) | ✅ | ✅ | ✅ | -| [BridgeTower](../en/model_doc/bridgetower) | ✅ | ❌ | ❌ | -| [BROS](../en/model_doc/bros) | ✅ | ❌ | ❌ | -| [ByT5](../en/model_doc/byt5) | ✅ | ✅ | ✅ | -| [CamemBERT](../en/model_doc/camembert) | ✅ | ✅ | ❌ | -| [CANINE](../en/model_doc/canine) | ✅ | ❌ | ❌ | -| [Chinese-CLIP](../en/model_doc/chinese_clip) | ✅ | ❌ | ❌ | -| [CLAP](../en/model_doc/clap) | ✅ | ❌ | ❌ | -| [CLIP](../en/model_doc/clip) | ✅ | ✅ | ✅ | -| [CLIPSeg](../en/model_doc/clipseg) | ✅ | ❌ | ❌ | -| [CLVP](../en/model_doc/clvp) | ✅ | ❌ | ❌ | -| [CodeGen](../en/model_doc/codegen) | ✅ | ❌ | ❌ | -| [CodeLlama](../en/model_doc/code_llama) | ✅ | ❌ | ✅ | -| [Conditional DETR](../en/model_doc/conditional_detr) | ✅ | ❌ | ❌ | -| [ConvBERT](../en/model_doc/convbert) | ✅ | ✅ | ❌ | -| [ConvNeXT](../en/model_doc/convnext) | ✅ | ✅ | ❌ | -| [ConvNeXTV2](../en/model_doc/convnextv2) | ✅ | ✅ | ❌ | -| [CPM](../en/model_doc/cpm) | ✅ | ✅ | ✅ | -| [CPM-Ant](../en/model_doc/cpmant) | ✅ | ❌ | ❌ | -| [CTRL](../en/model_doc/ctrl) | ✅ | ✅ | ❌ | -| [CvT](../en/model_doc/cvt) | ✅ | ✅ | ❌ | -| [Data2VecAudio](../en/model_doc/data2vec) | ✅ | ❌ | ❌ | -| [Data2VecText](../en/model_doc/data2vec) | ✅ | ❌ | ❌ | -| [Data2VecVision](../en/model_doc/data2vec) | ✅ | ✅ | ❌ | -| [DeBERTa](../en/model_doc/deberta) | ✅ | ✅ | ❌ | -| [DeBERTa-v2](../en/model_doc/deberta-v2) | ✅ | ✅ | ❌ | -| [Decision Transformer](../en/model_doc/decision_transformer) | ✅ | ❌ | ❌ | -| [Deformable DETR](../en/model_doc/deformable_detr) | ✅ | ❌ | ❌ | -| [DeiT](../en/model_doc/deit) | ✅ | ✅ | ❌ | -| [DePlot](../en/model_doc/deplot) | ✅ | ❌ | ❌ | -| [Depth Anything](../en/model_doc/depth_anything) | ✅ | ❌ | ❌ | -| [DETA](../en/model_doc/deta) | ✅ | ❌ | ❌ | -| [DETR](../en/model_doc/detr) | ✅ | ❌ | ❌ | -| [DialoGPT](../en/model_doc/dialogpt) | ✅ | ✅ | ✅ | -| [DiNAT](../en/model_doc/dinat) | ✅ | ❌ | ❌ | -| [DINOv2](../en/model_doc/dinov2) | ✅ | ❌ | ❌ | -| [DistilBERT](../en/model_doc/distilbert) | ✅ | ✅ | ✅ | -| [DiT](../en/model_doc/dit) | ✅ | ❌ | ✅ | -| [DonutSwin](../en/model_doc/donut) | ✅ | ❌ | ❌ | -| [DPR](../en/model_doc/dpr) | ✅ | ✅ | ❌ | -| [DPT](../en/model_doc/dpt) | ✅ | ❌ | ❌ | -| [EfficientFormer](../en/model_doc/efficientformer) | ✅ | ✅ | ❌ | -| [EfficientNet](../en/model_doc/efficientnet) | ✅ | ❌ | ❌ | -| [ELECTRA](../en/model_doc/electra) | ✅ | ✅ | ✅ | -| [EnCodec](../en/model_doc/encodec) | ✅ | ❌ | ❌ | -| [Encoder decoder](../en/model_doc/encoder-decoder) | ✅ | ✅ | ✅ | -| [ERNIE](../en/model_doc/ernie) | ✅ | ❌ | ❌ | -| [ErnieM](../en/model_doc/ernie_m) | ✅ | ❌ | ❌ | -| [ESM](../en/model_doc/esm) | ✅ | ✅ | ❌ | -| [FairSeq Machine-Translation](../en/model_doc/fsmt) | ✅ | ❌ | ❌ | -| [Falcon](../en/model_doc/falcon) | ✅ | ❌ | ❌ | -| [FastSpeech2Conformer](../en/model_doc/fastspeech2_conformer) | ✅ | ❌ | ❌ | -| [FLAN-T5](../en/model_doc/flan-t5) | ✅ | ✅ | ✅ | -| [FLAN-UL2](../en/model_doc/flan-ul2) | ✅ | ✅ | ✅ | -| [FlauBERT](../en/model_doc/flaubert) | ✅ | ✅ | ❌ | -| [FLAVA](../en/model_doc/flava) | ✅ | ❌ | ❌ | -| [FNet](../en/model_doc/fnet) | ✅ | ❌ | ❌ | -| [FocalNet](../en/model_doc/focalnet) | ✅ | ❌ | ❌ | -| [Funnel Transformer](../en/model_doc/funnel) | ✅ | ✅ | ❌ | -| [Fuyu](../en/model_doc/fuyu) | ✅ | ❌ | ❌ | -| [Gemma](../en/model_doc/gemma) | ✅ | ❌ | ✅ | -| [GIT](../en/model_doc/git) | ✅ | ❌ | ❌ | -| [GLPN](../en/model_doc/glpn) | ✅ | ❌ | ❌ | -| [GPT Neo](../en/model_doc/gpt_neo) | ✅ | ❌ | ✅ | -| [GPT NeoX](../en/model_doc/gpt_neox) | ✅ | ❌ | ❌ | -| [GPT NeoX Japanese](../en/model_doc/gpt_neox_japanese) | ✅ | ❌ | ❌ | -| [GPT-J](../en/model_doc/gptj) | ✅ | ✅ | ✅ | -| [GPT-Sw3](../en/model_doc/gpt-sw3) | ✅ | ✅ | ✅ | -| [GPTBigCode](../en/model_doc/gpt_bigcode) | ✅ | ❌ | ❌ | -| [GPTSAN-japanese](../en/model_doc/gptsan-japanese) | ✅ | ❌ | ❌ | -| [Graphormer](../en/model_doc/graphormer) | ✅ | ❌ | ❌ | -| [GroupViT](../en/model_doc/groupvit) | ✅ | ✅ | ❌ | -| [HerBERT](../en/model_doc/herbert) | ✅ | ✅ | ✅ | -| [Hubert](../en/model_doc/hubert) | ✅ | ✅ | ❌ | -| [I-BERT](../en/model_doc/ibert) | ✅ | ❌ | ❌ | -| [IDEFICS](../en/model_doc/idefics) | ✅ | ❌ | ❌ | -| [ImageGPT](../en/model_doc/imagegpt) | ✅ | ❌ | ❌ | -| [Informer](../en/model_doc/informer) | ✅ | ❌ | ❌ | -| [InstructBLIP](../en/model_doc/instructblip) | ✅ | ❌ | ❌ | -| [Jukebox](../en/model_doc/jukebox) | ✅ | ❌ | ❌ | -| [KOSMOS-2](../en/model_doc/kosmos-2) | ✅ | ❌ | ❌ | -| [LayoutLM](../en/model_doc/layoutlm) | ✅ | ✅ | ❌ | -| [LayoutLMv2](../en/model_doc/layoutlmv2) | ✅ | ❌ | ❌ | -| [LayoutLMv3](../en/model_doc/layoutlmv3) | ✅ | ✅ | ❌ | -| [LayoutXLM](../en/model_doc/layoutxlm) | ✅ | ❌ | ❌ | -| [LED](../en/model_doc/led) | ✅ | ✅ | ❌ | -| [LeViT](../en/model_doc/levit) | ✅ | ❌ | ❌ | -| [LiLT](../en/model_doc/lilt) | ✅ | ❌ | ❌ | -| [LLaMA](../en/model_doc/llama) | ✅ | ❌ | ✅ | -| [Llama2](../en/model_doc/llama2) | ✅ | ❌ | ✅ | -| [LLaVa](../en/model_doc/llava) | ✅ | ❌ | ❌ | -| [Longformer](../en/model_doc/longformer) | ✅ | ✅ | ❌ | -| [LongT5](../en/model_doc/longt5) | ✅ | ❌ | ✅ | -| [LUKE](../en/model_doc/luke) | ✅ | ❌ | ❌ | -| [LXMERT](../en/model_doc/lxmert) | ✅ | ✅ | ❌ | -| [M-CTC-T](../en/model_doc/mctct) | ✅ | ❌ | ❌ | -| [M2M100](../en/model_doc/m2m_100) | ✅ | ❌ | ❌ | -| [MADLAD-400](../en/model_doc/madlad-400) | ✅ | ✅ | ✅ | -| [Marian](../en/model_doc/marian) | ✅ | ✅ | ✅ | -| [MarkupLM](../en/model_doc/markuplm) | ✅ | ❌ | ❌ | -| [Mask2Former](../en/model_doc/mask2former) | ✅ | ❌ | ❌ | -| [MaskFormer](../en/model_doc/maskformer) | ✅ | ❌ | ❌ | -| [MatCha](../en/model_doc/matcha) | ✅ | ❌ | ❌ | -| [mBART](../en/model_doc/mbart) | ✅ | ✅ | ✅ | -| [mBART-50](../en/model_doc/mbart50) | ✅ | ✅ | ✅ | -| [MEGA](../en/model_doc/mega) | ✅ | ❌ | ❌ | -| [Megatron-BERT](../en/model_doc/megatron-bert) | ✅ | ❌ | ❌ | -| [Megatron-GPT2](../en/model_doc/megatron_gpt2) | ✅ | ✅ | ✅ | -| [MGP-STR](../en/model_doc/mgp-str) | ✅ | ❌ | ❌ | -| [Mistral](../en/model_doc/mistral) | ✅ | ❌ | ✅ | -| [Mixtral](../en/model_doc/mixtral) | ✅ | ❌ | ❌ | -| [mLUKE](../en/model_doc/mluke) | ✅ | ❌ | ❌ | -| [MMS](../en/model_doc/mms) | ✅ | ✅ | ✅ | -| [MobileBERT](../en/model_doc/mobilebert) | ✅ | ✅ | ❌ | -| [MobileNetV1](../en/model_doc/mobilenet_v1) | ✅ | ❌ | ❌ | -| [MobileNetV2](../en/model_doc/mobilenet_v2) | ✅ | ❌ | ❌ | -| [MobileViT](../en/model_doc/mobilevit) | ✅ | ✅ | ❌ | -| [MobileViTV2](../en/model_doc/mobilevitv2) | ✅ | ❌ | ❌ | -| [MPNet](../en/model_doc/mpnet) | ✅ | ✅ | ❌ | -| [MPT](../en/model_doc/mpt) | ✅ | ❌ | ❌ | -| [MRA](../en/model_doc/mra) | ✅ | ❌ | ❌ | -| [MT5](../en/model_doc/mt5) | ✅ | ✅ | ✅ | -| [MusicGen](../en/model_doc/musicgen) | ✅ | ❌ | ❌ | -| [MVP](../en/model_doc/mvp) | ✅ | ❌ | ❌ | -| [NAT](../en/model_doc/nat) | ✅ | ❌ | ❌ | -| [Nezha](../en/model_doc/nezha) | ✅ | ❌ | ❌ | -| [NLLB](../en/model_doc/nllb) | ✅ | ❌ | ❌ | -| [NLLB-MOE](../en/model_doc/nllb-moe) | ✅ | ❌ | ❌ | -| [Nougat](../en/model_doc/nougat) | ✅ | ✅ | ✅ | -| [Nyströmformer](../en/model_doc/nystromformer) | ✅ | ❌ | ❌ | -| [OneFormer](../en/model_doc/oneformer) | ✅ | ❌ | ❌ | -| [OpenAI GPT](../en/model_doc/openai-gpt) | ✅ | ✅ | ❌ | -| [OpenAI GPT-2](../en/model_doc/gpt2) | ✅ | ✅ | ✅ | -| [OpenLlama](../en/model_doc/open-llama) | ✅ | ❌ | ❌ | -| [OPT](../en/model_doc/opt) | ✅ | ✅ | ✅ | -| [OWL-ViT](../en/model_doc/owlvit) | ✅ | ❌ | ❌ | -| [OWLv2](../en/model_doc/owlv2) | ✅ | ❌ | ❌ | -| [PatchTSMixer](../en/model_doc/patchtsmixer) | ✅ | ❌ | ❌ | -| [PatchTST](../en/model_doc/patchtst) | ✅ | ❌ | ❌ | -| [Pegasus](../en/model_doc/pegasus) | ✅ | ✅ | ✅ | -| [PEGASUS-X](../en/model_doc/pegasus_x) | ✅ | ❌ | ❌ | -| [Perceiver](../en/model_doc/perceiver) | ✅ | ❌ | ❌ | -| [Persimmon](../en/model_doc/persimmon) | ✅ | ❌ | ❌ | -| [Phi](../en/model_doc/phi) | ✅ | ❌ | ❌ | -| [PhoBERT](../en/model_doc/phobert) | ✅ | ✅ | ✅ | -| [Pix2Struct](../en/model_doc/pix2struct) | ✅ | ❌ | ❌ | -| [PLBart](../en/model_doc/plbart) | ✅ | ❌ | ❌ | -| [PoolFormer](../en/model_doc/poolformer) | ✅ | ❌ | ❌ | -| [Pop2Piano](../en/model_doc/pop2piano) | ✅ | ❌ | ❌ | -| [ProphetNet](../en/model_doc/prophetnet) | ✅ | ❌ | ❌ | -| [PVT](../en/model_doc/pvt) | ✅ | ❌ | ❌ | -| [QDQBert](../en/model_doc/qdqbert) | ✅ | ❌ | ❌ | -| [Qwen2](../en/model_doc/qwen2) | ✅ | ❌ | ❌ | -| [RAG](../en/model_doc/rag) | ✅ | ✅ | ❌ | -| [REALM](../en/model_doc/realm) | ✅ | ❌ | ❌ | -| [Reformer](../en/model_doc/reformer) | ✅ | ❌ | ❌ | -| [RegNet](../en/model_doc/regnet) | ✅ | ✅ | ✅ | -| [RemBERT](../en/model_doc/rembert) | ✅ | ✅ | ❌ | -| [ResNet](../en/model_doc/resnet) | ✅ | ✅ | ✅ | -| [RetriBERT](../en/model_doc/retribert) | ✅ | ❌ | ❌ | -| [RoBERTa](../en/model_doc/roberta) | ✅ | ✅ | ✅ | -| [RoBERTa-PreLayerNorm](../en/model_doc/roberta-prelayernorm) | ✅ | ✅ | ✅ | -| [RoCBert](../en/model_doc/roc_bert) | ✅ | ❌ | ❌ | -| [RoFormer](../en/model_doc/roformer) | ✅ | ✅ | ✅ | -| [RWKV](../en/model_doc/rwkv) | ✅ | ❌ | ❌ | -| [SAM](../en/model_doc/sam) | ✅ | ✅ | ❌ | -| [SeamlessM4T](../en/model_doc/seamless_m4t) | ✅ | ❌ | ❌ | -| [SeamlessM4Tv2](../en/model_doc/seamless_m4t_v2) | ✅ | ❌ | ❌ | -| [SegFormer](../en/model_doc/segformer) | ✅ | ✅ | ❌ | -| [SegGPT](../en/model_doc/seggpt) | ✅ | ❌ | ❌ | -| [SEW](../en/model_doc/sew) | ✅ | ❌ | ❌ | -| [SEW-D](../en/model_doc/sew-d) | ✅ | ❌ | ❌ | -| [SigLIP](../en/model_doc/siglip) | ✅ | ❌ | ❌ | -| [Speech Encoder decoder](../en/model_doc/speech-encoder-decoder) | ✅ | ❌ | ✅ | -| [Speech2Text](../en/model_doc/speech_to_text) | ✅ | ✅ | ❌ | -| [SpeechT5](../en/model_doc/speecht5) | ✅ | ❌ | ❌ | -| [Splinter](../en/model_doc/splinter) | ✅ | ❌ | ❌ | -| [SqueezeBERT](../en/model_doc/squeezebert) | ✅ | ❌ | ❌ | -| [StableLm](../en/model_doc/stablelm) | ✅ | ❌ | ❌ | -| [Starcoder2](../en/model_doc/starcoder2) | ✅ | ❌ | ❌ | -| [SwiftFormer](../en/model_doc/swiftformer) | ✅ | ❌ | ❌ | -| [Swin Transformer](../en/model_doc/swin) | ✅ | ✅ | ❌ | -| [Swin Transformer V2](../en/model_doc/swinv2) | ✅ | ❌ | ❌ | -| [Swin2SR](../en/model_doc/swin2sr) | ✅ | ❌ | ❌ | -| [SwitchTransformers](../en/model_doc/switch_transformers) | ✅ | ❌ | ❌ | -| [T5](../en/model_doc/t5) | ✅ | ✅ | ✅ | -| [T5v1.1](../en/model_doc/t5v1.1) | ✅ | ✅ | ✅ | -| [Table Transformer](../en/model_doc/table-transformer) | ✅ | ❌ | ❌ | -| [TAPAS](../en/model_doc/tapas) | ✅ | ✅ | ❌ | -| [TAPEX](../en/model_doc/tapex) | ✅ | ✅ | ✅ | -| [Time Series Transformer](../en/model_doc/time_series_transformer) | ✅ | ❌ | ❌ | -| [TimeSformer](../en/model_doc/timesformer) | ✅ | ❌ | ❌ | -| [Trajectory Transformer](../en/model_doc/trajectory_transformer) | ✅ | ❌ | ❌ | -| [Transformer-XL](../en/model_doc/transfo-xl) | ✅ | ✅ | ❌ | -| [TrOCR](../en/model_doc/trocr) | ✅ | ❌ | ❌ | -| [TVLT](../en/model_doc/tvlt) | ✅ | ❌ | ❌ | -| [TVP](../en/model_doc/tvp) | ✅ | ❌ | ❌ | -| [UL2](../en/model_doc/ul2) | ✅ | ✅ | ✅ | -| [UMT5](../en/model_doc/umt5) | ✅ | ❌ | ❌ | -| [UniSpeech](../en/model_doc/unispeech) | ✅ | ❌ | ❌ | -| [UniSpeechSat](../en/model_doc/unispeech-sat) | ✅ | ❌ | ❌ | -| [UnivNet](../en/model_doc/univnet) | ✅ | ❌ | ❌ | -| [UPerNet](../en/model_doc/upernet) | ✅ | ❌ | ❌ | -| [VAN](../en/model_doc/van) | ✅ | ❌ | ❌ | -| [VideoMAE](../en/model_doc/videomae) | ✅ | ❌ | ❌ | -| [ViLT](../en/model_doc/vilt) | ✅ | ❌ | ❌ | -| [VipLlava](../en/model_doc/vipllava) | ✅ | ❌ | ❌ | -| [Vision Encoder decoder](../en/model_doc/vision-encoder-decoder) | ✅ | ✅ | ✅ | -| [VisionTextDualEncoder](../en/model_doc/vision-text-dual-encoder) | ✅ | ✅ | ✅ | -| [VisualBERT](../en/model_doc/visual_bert) | ✅ | ❌ | ❌ | -| [ViT](../en/model_doc/vit) | ✅ | ✅ | ✅ | -| [ViT Hybrid](../en/model_doc/vit_hybrid) | ✅ | ❌ | ❌ | -| [VitDet](../en/model_doc/vitdet) | ✅ | ❌ | ❌ | -| [ViTMAE](../en/model_doc/vit_mae) | ✅ | ✅ | ❌ | -| [ViTMatte](../en/model_doc/vitmatte) | ✅ | ❌ | ❌ | -| [ViTMSN](../en/model_doc/vit_msn) | ✅ | ❌ | ❌ | -| [VITS](../en/model_doc/vits) | ✅ | ❌ | ❌ | -| [ViViT](../en/model_doc/vivit) | ✅ | ❌ | ❌ | -| [Wav2Vec2](../en/model_doc/wav2vec2) | ✅ | ✅ | ✅ | -| [Wav2Vec2-BERT](../en/model_doc/wav2vec2-bert) | ✅ | ❌ | ❌ | -| [Wav2Vec2-Conformer](../en/model_doc/wav2vec2-conformer) | ✅ | ❌ | ❌ | -| [Wav2Vec2Phoneme](../en/model_doc/wav2vec2_phoneme) | ✅ | ✅ | ✅ | -| [WavLM](../en/model_doc/wavlm) | ✅ | ❌ | ❌ | -| [Whisper](../en/model_doc/whisper) | ✅ | ✅ | ✅ | -| [X-CLIP](../en/model_doc/xclip) | ✅ | ❌ | ❌ | -| [X-MOD](../en/model_doc/xmod) | ✅ | ❌ | ❌ | -| [XGLM](../en/model_doc/xglm) | ✅ | ✅ | ✅ | -| [XLM](../en/model_doc/xlm) | ✅ | ✅ | ❌ | -| [XLM-ProphetNet](../en/model_doc/xlm-prophetnet) | ✅ | ❌ | ❌ | -| [XLM-RoBERTa](../en/model_doc/xlm-roberta) | ✅ | ✅ | ✅ | -| [XLM-RoBERTa-XL](../en/model_doc/xlm-roberta-xl) | ✅ | ❌ | ❌ | -| [XLM-V](../en/model_doc/xlm-v) | ✅ | ✅ | ✅ | -| [XLNet](../en/model_doc/xlnet) | ✅ | ✅ | ❌ | -| [XLS-R](../en/model_doc/xls_r) | ✅ | ✅ | ✅ | -| [XLSR-Wav2Vec2](../en/model_doc/xlsr_wav2vec2) | ✅ | ✅ | ✅ | -| [YOLOS](../en/model_doc/yolos) | ✅ | ❌ | ❌ | -| [YOSO](../en/model_doc/yoso) | ✅ | ❌ | ❌ | - - diff --git a/docs/source/zh/installation.md b/docs/source/zh/installation.md index a9102f3393a7..5926079f2ce9 100644 --- a/docs/source/zh/installation.md +++ b/docs/source/zh/installation.md @@ -22,11 +22,9 @@ rendered properly in your Markdown viewer. 为你正在使用的深度学习框架安装 🤗 Transformers、设置缓存,并选择性配置 🤗 Transformers 以离线运行。 -🤗 Transformers 已在 Python 3.6+、PyTorch 1.1.0+、TensorFlow 2.0+ 以及 Flax 上进行测试。针对你使用的深度学习框架,请参照以下安装说明进行安装: +🤗 Transformers 已在 Python 3.9+ 以及 PyTorch 2.2.0+ 上进行测试。针对你使用的深度学习框架,请参照以下安装说明进行安装: * [PyTorch](https://pytorch.org/get-started/locally/) 安装说明。 -* [TensorFlow 2.0](https://www.tensorflow.org/install/pip) 安装说明。 -* [Flax](https://flax.readthedocs.io/en/latest/) 安装说明。 ## 使用 pip 安装 @@ -61,30 +59,6 @@ pip install transformers pip install 'transformers[torch]' ``` -🤗 Transformers 和 TensorFlow 2.0: - -```bash -pip install 'transformers[tf-cpu]' -``` - - - -M1 / ARM用户 - -在安装 TensorFlow 2.0 前,你需要安装以下库: -```bash -brew install cmake -brew install pkg-config -``` - - - -🤗 Transformers 和 Flax: - -```bash -pip install 'transformers[flax]' -``` - 最后,运行以下命令以检查 🤗 Transformers 是否已被正确安装。该命令将下载一个预训练模型: ```bash diff --git a/docs/source/zh/main_classes/image_processor.md b/docs/source/zh/main_classes/image_processor.md index 035afa55348a..28b21dffabef 100644 --- a/docs/source/zh/main_classes/image_processor.md +++ b/docs/source/zh/main_classes/image_processor.md @@ -16,7 +16,7 @@ rendered properly in your Markdown viewer. # Image Processor -Image processor负责为视觉模型准备输入特征并后期处理处理它们的输出。这包括诸如调整大小、归一化和转换为PyTorch、TensorFlow、Flax和NumPy张量等转换。它还可能包括特定于模型的后期处理,例如将logits转换为分割掩码。 +Image processor负责为视觉模型准备输入特征并后期处理处理它们的输出。这包括诸如调整大小、归一化和转换为PyTorch和NumPy张量等转换。它还可能包括特定于模型的后期处理,例如将logits转换为分割掩码。 ## ImageProcessingMixin diff --git a/docs/source/zh/main_classes/model.md b/docs/source/zh/main_classes/model.md index 323b534640c1..f823ec6a856e 100644 --- a/docs/source/zh/main_classes/model.md +++ b/docs/source/zh/main_classes/model.md @@ -8,14 +8,14 @@ http://www.apache.org/licenses/LICENSE-2.0 # 模型 -基类 [`PreTrainedModel`]、[`TFPreTrainedModel`] 和 [`FlaxPreTrainedModel`] 实现了从本地文件或目录加载/保存模型的常用方法,或者从库上提供的预训练模型配置(从 HuggingFace 的 AWS S3 存储库下载)加载模型。 +基类 [`PreTrainedModel`] 实现了从本地文件或目录加载/保存模型的常用方法,或者从库上提供的预训练模型配置(从 HuggingFace 的 AWS S3 存储库下载)加载模型。 [`PreTrainedModel`] 和 [`TFPreTrainedModel`] 还实现了一些所有模型共有的方法: - 在向量词嵌入增加新词汇时调整输入标记(token)的大小 - 对模型的注意力头进行修剪。 -其他的通用方法在 [`~modeling_utils.ModuleUtilsMixin`](用于 PyTorch 模型)和 [`~modeling_tf_utils.TFModuleUtilsMixin`](用于 TensorFlow 模型)中定义;文本生成方面的方法则定义在 [`~generation.GenerationMixin`](用于 PyTorch 模型)、[`~generation.TFGenerationMixin`](用于 TensorFlow 模型)和 [`~generation.FlaxGenerationMixin`](用于 Flax/JAX 模型)中。 +其他的通用方法在 [`~modeling_utils.ModuleUtilsMixin`](用于 PyTorch 模型)中定义;文本生成方面的方法则定义在 [`~generation.GenerationMixin`](用于 PyTorch 模型)中。 ## PreTrainedModel diff --git a/docs/source/zh/main_classes/text_generation.md b/docs/source/zh/main_classes/text_generation.md index 5e7426fa8441..2a85c1ffb955 100644 --- a/docs/source/zh/main_classes/text_generation.md +++ b/docs/source/zh/main_classes/text_generation.md @@ -19,8 +19,6 @@ rendered properly in your Markdown viewer. 每个框架都在它们各自的 `GenerationMixin` 类中实现了文本生成的 `generate` 方法: - PyTorch [`~generation.GenerationMixin.generate`] 在 [`~generation.GenerationMixin`] 中实现。 -- TensorFlow [`~generation.TFGenerationMixin.generate`] 在 [`~generation.TFGenerationMixin`] 中实现。 -- Flax/JAX [`~generation.FlaxGenerationMixin.generate`] 在 [`~generation.FlaxGenerationMixin`] 中实现。 无论您选择哪个框架,都可以使用 [`~generation.GenerationConfig`] 类实例对 generate 方法进行参数化。有关生成方法的控制参数的完整列表,请参阅此类。 @@ -37,4 +35,4 @@ rendered properly in your Markdown viewer. [[autodoc]] generation.GenerationMixin - generate - - compute_transition_scores \ No newline at end of file + - compute_transition_scores diff --git a/docs/source/zh/model_sharing.md b/docs/source/zh/model_sharing.md index 07d99c93c920..26e129a0a2be 100644 --- a/docs/source/zh/model_sharing.md +++ b/docs/source/zh/model_sharing.md @@ -73,20 +73,6 @@ pip install huggingface_hub >>> notebook_login() ``` -## 转换模型适用于所有框架 - -为确保您的模型可以被使用不同框架的人使用,我们建议您将PyTorch和TensorFlow `checkpoints`都转换并上传。如果您跳过此步骤,用户仍然可以从其他框架加载您的模型,但速度会变慢,因为🤗 Transformers需要实时转换`checkpoints`。 - -为另一个框架转换`checkpoints`很容易。确保您已安装PyTorch和TensorFlow(请参阅[此处](installation)的安装说明),然后在其他框架中找到适合您任务的特定模型。 - - -指定`from_tf=True`将checkpoint从TensorFlow转换为PyTorch。 - -```py ->>> pt_model = DistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_tf=True) ->>> pt_model.save_pretrained("path/to/awesome-name-you-picked") -``` - ## 在训练过程中推送模型 @@ -146,11 +132,6 @@ pip install huggingface_hub >>> tokenizer.push_to_hub("my-awesome-model") ``` -或者,您可能希望将您的微调后的PyTorch模型的TensorFlow版本添加进去: - -```py ->>> tf_model.push_to_hub("my-awesome-model") -``` 现在,当您导航到您的Hugging Face个人资料时,您应该看到您新创建的模型仓库。点击**文件**选项卡将显示您已上传到仓库的所有文件。 有关如何创建和上传文件到仓库的更多详细信息,请参考Hub文档[这里](https://huggingface.co/docs/hub/how-to-upstream)。 diff --git a/docs/source/zh/philosophy.md b/docs/source/zh/philosophy.md index b0fd0a5167d4..56284a367d70 100644 --- a/docs/source/zh/philosophy.md +++ b/docs/source/zh/philosophy.md @@ -30,13 +30,13 @@ Transformers 设计时有两个主要目标: - 我们尽可能地限制用户能接触的抽象层,实际上几乎没有抽象。用户只需学习三个标准类即可使用每个模型:[configuration](main_classes/configuration)、[models](main_classes/model) 和一个预处理类(用于 NLP 的 [tokenizer](main_classes/tokenizer),用于视觉的 [image processor](main_classes/image_processor),用于音频的 [feature extractor](main_classes/feature_extractor),以及用于多模态输入的 [processor](main_classes/processors))。 - 所有这些类都可以通过一个通用的 `from_pretrained()` 方法从预训练实例中简单统一地初始化,该方法会从提供在 [Hugging Face Hub](https://huggingface.co/models) 上的预训练检查点(如果需要的话)下载、缓存和加载相关类实例及相关数据(配置的超参数、分词器的词汇表和模型的权重)。 - - 在这三个基本类之上,该库提供了两种 API:[`pipeline`] 用于快速在给定任务上使用模型进行推断,以及 [`Trainer`] 用于快速训练或微调 PyTorch 模型(所有 TensorFlow 模型与 `Keras.fit` 兼容)。 - - 因此,Transformers 不是神经网络的模块化工具箱。如果要基于 Transformers 扩展或搭建新项目,请使用常规的 Python、PyTorch、TensorFlow、Keras 模块,并从 Transformers 的基类继承以重用模型加载和保存等功能。如果想了解更多有关我们的模型代码的设计理念,请查看我们的[重复自己](https://huggingface.co/blog/transformers-design-philosophy)博文。 + - 在这三个基本类之上,该库提供了两种 API:[`pipeline`] 用于快速在给定任务上使用模型进行推断,以及 [`Trainer`] 用于快速训练或微调 PyTorch 模型。 + - 因此,Transformers 不是神经网络的模块化工具箱。如果要基于 Transformers 扩展或搭建新项目,请使用常规的 Python 或者 PyTorch 模块,并从 Transformers 的基类继承以重用模型加载和保存等功能。如果想了解更多有关我们的模型代码的设计理念,请查看我们的[重复自己](https://huggingface.co/blog/transformers-design-philosophy)博文。 2. 提供与原始模型性能尽可能接近的最新模型: - 我们为每种架构提供至少一个示例,复现了该架构官方作者提供的结果。 - - 代码通常尽可能接近原始代码库,这意味着某些 PyTorch 代码可能不够*pytorchic*,因为它是转换后的 TensorFlow 代码,反之亦然。 + - 代码通常尽可能接近原始代码库,这意味着某些 PyTorch 代码可能不够*pytorchic*,因为它可能是从其它的深度学习框架转换过来的代码。 其他几个目标: @@ -50,13 +50,11 @@ Transformers 设计时有两个主要目标: - 简单一致的方法来向词汇表和嵌入中添加新标记以进行微调。 - 简单的方法来屏蔽和修剪 Transformer 头部。 -- 轻松在 PyTorch、TensorFlow 2.0 和 Flax 之间切换,允许使用一个框架进行训练并使用另一个进行推断。 - ## 主要概念 该库围绕每个模型的三类类构建: -- **模型类** 可以是 PyTorch 模型([torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module))、Keras 模型([tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model))或 JAX/Flax 模型([flax.linen.Module](https://flax.readthedocs.io/en/latest/api_reference/flax.linen/module.html)),这些模型可以使用库中提供的预训练权重。 +- **模型类** 是 PyTorch 模型([torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module)),这些模型可以使用库中提供的预训练权重。 - **配置类** 存储构建模型所需的超参数(如层数和隐藏大小)。通常情况下,如果您使用不进行任何修改的预训练模型,则创建模型将自动处理配置的实例化(配置是模型的一部分)。 - **预处理类** 将原始数据转换为模型可接受的格式。一个 [tokenizer](main_classes/tokenizer) 存储每个模型的词汇表,并提供编码和解码字符串为要馈送到模型的令牌嵌入索引列表的方法。[Image processors](main_classes/image_processor) 预处理视觉输入,[feature extractors](main_classes/feature_extractor) 预处理音频输入,而 [processor](main_classes/processors) 则处理多模态输入。 diff --git a/docs/source/zh/quicktour.md b/docs/source/zh/quicktour.md index c4aa032df8d1..b36a85932b25 100644 --- a/docs/source/zh/quicktour.md +++ b/docs/source/zh/quicktour.md @@ -253,16 +253,6 @@ tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725], >>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained") ``` -🤗 Transformers 有一个特别酷的功能,它能够保存一个模型,并且将它加载为 PyTorch 或 TensorFlow 模型。`from_pt` 或 `from_tf` 参数可以将模型从一个框架转换为另一个框架: - - -```py ->>> from transformers import AutoModel - ->>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory) ->>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True) -``` - ## 自定义模型构建 你可以修改模型的配置类来改变模型的构建方式。配置指明了模型的属性,比如隐藏层或者注意力头的数量。当你从自定义的配置类初始化模型时,你就开始自定义模型构建了。模型属性是随机初始化的,你需要先训练模型,然后才能得到有意义的结果。 diff --git a/docs/source/zh/run_scripts.md b/docs/source/zh/run_scripts.md index 78b1629657f3..32bf2342f9aa 100644 --- a/docs/source/zh/run_scripts.md +++ b/docs/source/zh/run_scripts.md @@ -16,7 +16,7 @@ rendered properly in your Markdown viewer. # 使用脚本进行训练 -除了 🤗 Transformers [notebooks](./notebooks),还有示例脚本演示了如何使用[PyTorch](https://github.com/huggingface/transformers/tree/main/examples/pytorch)、[TensorFlow](https://github.com/huggingface/transformers/tree/main/examples/tensorflow)或[JAX/Flax](https://github.com/huggingface/transformers/tree/main/examples/flax)训练模型以解决特定任务。 +除了 🤗 Transformers [notebooks](./notebooks),还有示例脚本演示了如何使用[PyTorch](https://github.com/huggingface/transformers/tree/main/examples/pytorch)训练模型以解决特定任务。 您还可以在这些示例中找到我们在[研究项目](https://github.com/huggingface/transformers-research-projects/)和[遗留示例](https://github.com/huggingface/transformers/tree/main/examples/legacy)中使用过的脚本,这些脚本主要是由社区贡献的。这些脚本已不再被积极维护,需要使用特定版本的🤗 Transformers, 可能与库的最新版本不兼容。 @@ -24,7 +24,7 @@ rendered properly in your Markdown viewer. 如果您想在示例脚本中实现任何功能,请在[论坛](https://discuss.huggingface.co/)或[issue](https://github.com/huggingface/transformers/issues)上讨论,然后再提交Pull Request。虽然我们欢迎修复错误,但不太可能合并添加更多功能的Pull Request,因为这会降低可读性。 -本指南将向您展示如何在[PyTorch](https://github.com/huggingface/transformers/tree/main/examples/pytorch/summarization)和[TensorFlow](https://github.com/huggingface/transformers/tree/main/examples/tensorflow/summarization)中运行示例摘要训练脚本。除非另有说明,否则所有示例都可以在两个框架中工作。 +本指南将向您展示如何在[PyTorch](https://github.com/huggingface/transformers/tree/main/examples/pytorch/summarization)中运行示例摘要训练脚本。 ## 设置 @@ -128,12 +128,10 @@ torchrun \ --predict_with_generate ``` -TensorFlow脚本使用[`MirroredStrategy`](https://www.tensorflow.org/guide/distributed_training#mirroredstrategy)进行分布式训练,您无需在训练脚本中添加任何其他参数。如果可用,TensorFlow脚本将默认使用多个GPU。 - ## 在TPU上运行脚本 -张量处理单元(TPUs)是专门设计用于加速性能的。PyTorch使用[XLA](https://www.tensorflow.org/xla)深度学习编译器支持TPU(更多细节请参见[这里](https://github.com/pytorch/xla/blob/master/README.md))。要使用TPU,请启动`xla_spawn.py`脚本并使用`num_cores`参数设置要使用的TPU核心数量。 +张量处理单元(TPUs)是专门设计用于加速性能的。PyTorch使用 [PyTorch/XLA](https://github.com/pytorch/xla/blob/master/README.md) 支持TPU。要使用TPU,请启动`xla_spawn.py`脚本并使用`num_cores`参数设置要使用的TPU核心数量。 ```bash python xla_spawn.py --num_cores 8 \ diff --git a/docs/source/zh/serialization.md b/docs/source/zh/serialization.md index 6885ae30c470..e4ff6ed290eb 100644 --- a/docs/source/zh/serialization.md +++ b/docs/source/zh/serialization.md @@ -94,12 +94,6 @@ optimum-cli export onnx --model local_path --task question-answering distilbert_ >>> outputs = model(**inputs) ``` -从 Hub 导出 TensorFlow 检查点的过程也一样。例如,以下是从 [Keras 组织](https://huggingface.co/keras-io) 导出纯 TensorFlow 检查点的命令: - -```bash -optimum-cli export onnx --model keras-io/transformers-qa distilbert_base_cased_squad_onnx/ -``` - ### 使用 `optimum.onnxruntime` 将 🤗 Transformers 模型导出为 ONNX 除了 CLI 之外,你还可以使用代码将 🤗 Transformers 模型导出为 ONNX,如下所示: @@ -168,14 +162,8 @@ python -m transformers.onnx --model=distilbert/distilbert-base-uncased onnx/ ["last_hidden_state"] ``` -从 Hub 导出 TensorFlow 检查点的过程也一样。导出纯 TensorFlow 检查点的示例代码如下: - -```bash -python -m transformers.onnx --model=keras-io/transformers-qa onnx/ -``` - 要导出本地存储的模型,请将模型的权重和分词器文件保存在同一目录中(例如 `local-pt-checkpoint`),然后通过将 `transformers.onnx` 包的 `--model` 参数指向该目录,将其导出为 ONNX: ```bash python -m transformers.onnx --model=local-pt-checkpoint onnx/ -``` \ No newline at end of file +``` From f82b0964116a12dfac75ecd41a58f7911267d345 Mon Sep 17 00:00:00 2001 From: "Jinde.Song" Date: Tue, 23 Sep 2025 20:35:44 +0800 Subject: [PATCH 168/204] fix wrong height and width when read video use torchvision (#41091) --- src/transformers/video_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformers/video_utils.py b/src/transformers/video_utils.py index 1f6f79e26994..1ae8f59f9ae9 100644 --- a/src/transformers/video_utils.py +++ b/src/transformers/video_utils.py @@ -546,8 +546,8 @@ def sample_indices_fn(metadata, **kwargs): metadata.update( { "frames_indices": indices, - "height": video.shape[1], - "width": video.shape[2], + "height": video.shape[2], + "width": video.shape[3], } ) return video, metadata From 824415f305347262c769515ca46df8d7e23e5cdd Mon Sep 17 00:00:00 2001 From: Ryan Mullins Date: Tue, 23 Sep 2025 12:18:49 -0400 Subject: [PATCH 169/204] docs: Fix Tool Use links and remove dead RAG links (#41104) docs: Fix tool use links. Remove dead RAG links. Fix style --- benchmark_v2/run_benchmarks.py | 4 ++- docs/source/en/chat_extras.md | 32 ++++++++++----------- docs/source/en/chat_templating_writing.md | 22 +++++++------- src/transformers/tokenization_utils_base.py | 6 ++-- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/benchmark_v2/run_benchmarks.py b/benchmark_v2/run_benchmarks.py index 42da090420c7..d04069887f2d 100755 --- a/benchmark_v2/run_benchmarks.py +++ b/benchmark_v2/run_benchmarks.py @@ -357,7 +357,9 @@ def main(): ) parser.add_argument( - "--token", type=str, help="HuggingFace token for dataset uploads (if not provided, will use HF_TOKEN environment variable)" + "--token", + type=str, + help="HuggingFace token for dataset uploads (if not provided, will use HF_TOKEN environment variable)", ) args = parser.parse_args() diff --git a/docs/source/en/chat_extras.md b/docs/source/en/chat_extras.md index 53c431633c5e..dc933dd6815e 100644 --- a/docs/source/en/chat_extras.md +++ b/docs/source/en/chat_extras.md @@ -16,7 +16,7 @@ rendered properly in your Markdown viewer. # Tool use -Chat models are commonly trained with support for "function-calling" or "tool-use". Tools are functions supplied by the user, which the model can choose to call as part of its response. For example, models could have access to a calculator tool to perform arithmetic without having to it internally. +Chat models are commonly trained with support for "function-calling" or "tool-use". Tools are functions supplied by the user, which the model can choose to call as part of its response. For example, models could have access to a calculator tool to perform arithmetic without having to perform the computation internally. This guide will demonstrate how to define tools, how to pass them to a chat model, and how to handle the model's output when it calls a tool. @@ -34,7 +34,7 @@ docstrings. Refer to the examples below for how to format a tool-ready function. def get_current_temperature(location: str, unit: str): """ Get the current temperature at a location. - + Args: location: The location to get the temperature for, in the format "City, Country" unit: The unit to return the temperature in. (choices: ["celsius", "fahrenheit"]) @@ -44,7 +44,7 @@ def get_current_temperature(location: str, unit: str): def get_current_wind_speed(location: str): """ Get the current wind speed in km/h at a given location. - + Args: location: The location to get the wind speed for, in the format "City, Country" """ @@ -147,7 +147,7 @@ from transformers.utils import get_json_schema def multiply(a: float, b: float): """ A function that multiplies two numbers - + Args: a: The first number to multiply b: The second number to multiply @@ -160,22 +160,22 @@ print(schema) ```json { - "type": "function", + "type": "function", "function": { - "name": "multiply", - "description": "A function that multiplies two numbers", + "name": "multiply", + "description": "A function that multiplies two numbers", "parameters": { - "type": "object", + "type": "object", "properties": { "a": { - "type": "number", + "type": "number", "description": "The first number to multiply" - }, + }, "b": { "type": "number", "description": "The second number to multiply" } - }, + }, "required": ["a", "b"] } } @@ -187,7 +187,7 @@ We won't go into the details of JSON schema itself here, since it's already [ver ```py # A simple function that takes no arguments current_time = { - "type": "function", + "type": "function", "function": { "name": "current_time", "description": "Get the current local time as a string.", @@ -203,18 +203,18 @@ multiply = { 'type': 'function', 'function': { 'name': 'multiply', - 'description': 'A function that multiplies two numbers', + 'description': 'A function that multiplies two numbers', 'parameters': { - 'type': 'object', + 'type': 'object', 'properties': { 'a': { 'type': 'number', 'description': 'The first number to multiply' - }, + }, 'b': { 'type': 'number', 'description': 'The second number to multiply' } - }, + }, 'required': ['a', 'b'] } } diff --git a/docs/source/en/chat_templating_writing.md b/docs/source/en/chat_templating_writing.md index a7da4b6597c8..f4f3b1201e35 100644 --- a/docs/source/en/chat_templating_writing.md +++ b/docs/source/en/chat_templating_writing.md @@ -30,8 +30,8 @@ A chat template is a [Jinja](https://jinja.palletsprojects.com/en/stable/templat ``` If you stare at this for a while, you should realize that this is actually very like Python, albeit with some strange -`{%-` syntax. The template iterates over a list of messages, and for each message, it prints the role and content of -the message, followed by an end-of-sequence token. If `add_generation_prompt=True`, it adds +`{%-` syntax. The template iterates over a list of messages, and for each message, it prints the role and content of +the message, followed by an end-of-sequence token. If `add_generation_prompt=True`, it adds the starting header for an assistant message to the end of the conversation. Load the written template as a string and assign it to the tokenizer's `chat_template` attribute. Once set, the template is used whenever you call [`~PreTrainedTokenizerBase.apply_chat_template`]. It is also saved @@ -42,7 +42,7 @@ edit this file directly to change the template, which is often easier than manip The easiest way to start writing Jinja templates is to refer to existing templates. Use `print(tokenizer.chat_template)` on any chat model to see the template it's using. Try starting with simple models that don't call any tools or support RAG because tool-use models can have very complex templates. Finally, take a look at the [Jinja documentation](https://jinja.palletsprojects.com/en/stable/templates/#synopsis) for more details about formatting and syntax. -There are some specific tips and pitfalls you may encounter while writing chat templates specifically, though, and this section will cover some of them in more detail. +There are some specific tips and pitfalls you may encounter while writing chat templates specifically, though, and this section will cover some of them in more detail. ### Writing multimodal chat templates @@ -133,7 +133,7 @@ Make the changes below to ensure compatibility across all Jinja implementations. ### Big templates -Newer models or models with features like [tool-calling](./chat_extras#tools) and [RAG](./chat_extras#retrieval-augmented-generation-rag) require larger templates that can be longer than 100 lines. It may be easier to write larger templates in a separate file. The line numbers in the separate file corresponds exactly to the line numbers in template parsing or execution errors, making it easier to debug any potential issues. +Newer models or models with features like [tool-calling](./chat_extras) and RAG require larger templates that can be longer than 100 lines. It may be easier to write larger templates in a separate file. The line numbers in the separate file corresponds exactly to the line numbers in template parsing or execution errors, making it easier to debug any potential issues. Write the template in a separate file and extract it to the chat template. @@ -166,22 +166,22 @@ The example below shows how a tool is defined in JSON schema format. ```json { - "type": "function", + "type": "function", "function": { - "name": "multiply", - "description": "A function that multiplies two numbers", + "name": "multiply", + "description": "A function that multiplies two numbers", "parameters": { - "type": "object", + "type": "object", "properties": { "a": { - "type": "number", + "type": "number", "description": "The first number to multiply" - }, + }, "b": { "type": "number", "description": "The second number to multiply" } - }, + }, "required": ["a", "b"] } } diff --git a/src/transformers/tokenization_utils_base.py b/src/transformers/tokenization_utils_base.py index e08d80991dab..74550cb0f6ab 100644 --- a/src/transformers/tokenization_utils_base.py +++ b/src/transformers/tokenization_utils_base.py @@ -1537,14 +1537,12 @@ def apply_chat_template( A list of tools (callable functions) that will be accessible to the model. If the template does not support function calling, this argument will have no effect. Each tool should be passed as a JSON Schema, giving the name, description and argument types for the tool. See our - [chat templating guide](https://huggingface.co/docs/transformers/main/en/chat_templating#automated-function-conversion-for-tool-use) + [tool use guide](https://huggingface.co/docs/transformers/en/chat_extras#passing-tools) for more information. documents (`list[dict[str, str]]`, *optional*): A list of dicts representing documents that will be accessible to the model if it is performing RAG (retrieval-augmented generation). If the template does not support RAG, this argument will have no - effect. We recommend that each document should be a dict containing "title" and "text" keys. Please - see the RAG section of the [chat templating guide](https://huggingface.co/docs/transformers/main/en/chat_templating#arguments-for-RAG) - for examples of passing documents with chat templates. + effect. We recommend that each document should be a dict containing "title" and "text" keys. chat_template (`str`, *optional*): A Jinja template to use for this conversion. It is usually not necessary to pass anything to this argument, as the model's template will be used by default. From 6a94124d715ac87f1f0540511ac7e47b8faba067 Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Tue, 23 Sep 2025 17:20:00 +0100 Subject: [PATCH 170/204] =?UTF-8?q?=F0=9F=9A=A8=20[generate]=20update=20pa?= =?UTF-8?q?ligemma=20mask=20updates=20(and=20other=20assisted=20generation?= =?UTF-8?q?-related=20fixes)=20(#40917)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * tmp * fix modular inheritance * nit * paligemma 1 doesn't have swa * use same pattern as in models with hybrid layers * PR comments * helium also needs layer_typed (bc it relies on gemma) * paligemma/gemma3: same mask creation fn in fwd and generate * propagate changes to helium (gemma-based) * tmp commit * slow paligemma tests passing, let's see what breaks * fix test_left_padding_compatibility * tmp commit * tmp commit * rebase error * docs * reduce diff * like this? * t5gemma * better comment * shorter diff * exception * ffs type * optional * shorter modular_gemma.py * helium model actually needs no changes -- the tester is the issue * t5gemma modular config * a few more modular; paligemma BC * fix processor issues? * rm config exception * lift warning in gemma --- src/transformers/masking_utils.py | 4 +- .../models/colpali/modular_colpali.py | 6 +- .../models/colpali/processing_colpali.py | 12 +- .../models/colqwen2/processing_colqwen2.py | 24 +- .../models/gemma/configuration_gemma.py | 16 +- .../models/gemma/modeling_gemma.py | 25 +- .../models/gemma/modular_gemma.py | 54 +++- .../models/gemma2/configuration_gemma2.py | 5 + .../models/gemma2/modeling_gemma2.py | 2 +- .../models/gemma2/modular_gemma2.py | 7 +- .../models/gemma3/configuration_gemma3.py | 6 +- .../models/gemma3/modeling_gemma3.py | 136 +++++---- .../models/gemma3/modular_gemma3.py | 171 ++++------- .../models/gemma3n/modular_gemma3n.py | 7 +- .../models/helium/configuration_helium.py | 2 + .../paligemma/configuration_paligemma.py | 6 + .../models/paligemma/modeling_paligemma.py | 280 +++++++++--------- .../models/paligemma/processing_paligemma.py | 9 +- .../models/t5gemma/configuration_t5gemma.py | 1 + .../models/t5gemma/modeling_t5gemma.py | 81 +---- .../models/t5gemma/modular_t5gemma.py | 143 ++++++++- .../vaultgemma/configuration_vaultgemma.py | 1 + .../models/vaultgemma/modular_vaultgemma.py | 151 +++++++++- tests/generation/test_utils.py | 11 +- tests/models/bark/test_modeling_bark.py | 1 + .../chameleon/test_modeling_chameleon.py | 1 + tests/models/colpali/test_modeling_colpali.py | 2 + tests/models/gemma3/test_modeling_gemma3.py | 1 + tests/models/helium/test_modeling_helium.py | 20 +- .../models/idefics2/test_modeling_idefics2.py | 2 + .../models/idefics3/test_modeling_idefics3.py | 2 + tests/models/llava/test_modeling_llava.py | 1 + .../llava_next/test_modeling_llava_next.py | 1 + .../test_modeling_llava_next_video.py | 1 + .../moonshine/test_modeling_moonshine.py | 1 + .../paligemma/test_modeling_paligemma.py | 4 +- .../paligemma2/test_modeling_paligemma2.py | 10 +- .../test_modeling_perception_lm.py | 1 + .../pix2struct/test_modeling_pix2struct.py | 1 + .../qwen2_5_vl/test_modeling_qwen2_5_vl.py | 1 + .../models/qwen2_vl/test_modeling_qwen2_vl.py | 1 + .../models/qwen3_vl/test_modeling_qwen3_vl.py | 1 + .../test_modeling_qwen3_vl_moe.py | 1 + tests/models/smolvlm/test_modeling_smolvlm.py | 2 + .../test_modeling_speech_to_text.py | 1 + .../models/speecht5/test_modeling_speecht5.py | 1 + .../video_llava/test_modeling_video_llava.py | 1 + .../models/vipllava/test_modeling_vipllava.py | 1 + tests/models/whisper/test_modeling_whisper.py | 1 + tests/test_modeling_common.py | 1 + 50 files changed, 758 insertions(+), 463 deletions(-) diff --git a/src/transformers/masking_utils.py b/src/transformers/masking_utils.py index 1899a6de8af8..65668f667b0e 100644 --- a/src/transformers/masking_utils.py +++ b/src/transformers/masking_utils.py @@ -1073,8 +1073,8 @@ def create_masks_for_generate( **kwargs, ): """ - This function mimics how we create the masks in the `modeling_xxx.py` files, and is used in `generate` in order - to easily create the masks in advance, when we compile the forwards with Static caches. + This function mimics how we create the masks in the `modeling_xxx.py` files, and is used in places like `generate` + in order to easily create the masks in advance, when we compile the forwards with Static caches. Args: config (`PretrainedConfig`): diff --git a/src/transformers/models/colpali/modular_colpali.py b/src/transformers/models/colpali/modular_colpali.py index 0c932a732258..8136f560f18e 100644 --- a/src/transformers/models/colpali/modular_colpali.py +++ b/src/transformers/models/colpali/modular_colpali.py @@ -136,7 +136,7 @@ def __call__( ) suffix = output_kwargs["text_kwargs"].pop("suffix", None) - return_token_type_ids = suffix is not None + return_token_type_ids = True if text is None and images is None: raise ValueError("Either text or images must be provided") @@ -167,7 +167,7 @@ def __call__( inputs = self.tokenizer( input_strings, - return_token_type_ids=False, + return_token_type_ids=return_token_type_ids, **output_kwargs["text_kwargs"], ) @@ -197,7 +197,7 @@ def __call__( batch_query = self.tokenizer( texts_query, - return_token_type_ids=False, + return_token_type_ids=return_token_type_ids, **output_kwargs["text_kwargs"], ) diff --git a/src/transformers/models/colpali/processing_colpali.py b/src/transformers/models/colpali/processing_colpali.py index 5d77eced20d9..1d76a74e1ab8 100644 --- a/src/transformers/models/colpali/processing_colpali.py +++ b/src/transformers/models/colpali/processing_colpali.py @@ -177,7 +177,7 @@ def __call__( ) suffix = output_kwargs["text_kwargs"].pop("suffix", None) - return_token_type_ids = suffix is not None + return_token_type_ids = True if text is None and images is None: raise ValueError("Either text or images must be provided") @@ -208,7 +208,7 @@ def __call__( inputs = self.tokenizer( input_strings, - return_token_type_ids=False, + return_token_type_ids=return_token_type_ids, **output_kwargs["text_kwargs"], ) @@ -238,7 +238,7 @@ def __call__( batch_query = self.tokenizer( texts_query, - return_token_type_ids=False, + return_token_type_ids=return_token_type_ids, **output_kwargs["text_kwargs"], ) @@ -262,6 +262,12 @@ def _get_num_multimodal_tokens(self, image_sizes=None, **kwargs): vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) return MultiModalData(**vision_data) + @property + def model_input_names(self): + tokenizer_input_names = self.tokenizer.model_input_names + ["token_type_ids", "labels"] + image_processor_input_names = self.image_processor.model_input_names + return list(tokenizer_input_names + image_processor_input_names) + @property def query_augmentation_token(self) -> str: """ diff --git a/src/transformers/models/colqwen2/processing_colqwen2.py b/src/transformers/models/colqwen2/processing_colqwen2.py index 372ce542d580..e8f7e057247c 100644 --- a/src/transformers/models/colqwen2/processing_colqwen2.py +++ b/src/transformers/models/colqwen2/processing_colqwen2.py @@ -247,6 +247,18 @@ def _get_num_multimodal_tokens(self, image_sizes=None, **kwargs): return MultiModalData(**vision_data) + @property + def model_input_names(self): + tokenizer_input_names = self.tokenizer.model_input_names + image_processor_input_names = self.image_processor.model_input_names + + # ColQwen doesn't process videos. Make a copy of list when removing + # otherwise `self.feature_extractor.model_input_names` is also modified + image_processor_input_names = [ + name for name in image_processor_input_names if name not in ["pixel_values_videos", "video_grid_thw"] + ] + return tokenizer_input_names + image_processor_input_names + @property def query_augmentation_token(self) -> str: """ @@ -385,17 +397,5 @@ def score_retrieval( return torch.cat(scores, dim=0) - @property - def model_input_names(self): - tokenizer_input_names = self.tokenizer.model_input_names - image_processor_input_names = self.image_processor.model_input_names - - # ColQwen doesn't process videos. Make a copy of list when removing - # otherwise `self.feature_extractor.model_input_names` is also modified - image_processor_input_names = [ - name for name in image_processor_input_names if name not in ["pixel_values_videos", "video_grid_thw"] - ] - return tokenizer_input_names + image_processor_input_names - __all__ = ["ColQwen2Processor"] diff --git a/src/transformers/models/gemma/configuration_gemma.py b/src/transformers/models/gemma/configuration_gemma.py index 58d6c3d08537..7910f27dcfed 100644 --- a/src/transformers/models/gemma/configuration_gemma.py +++ b/src/transformers/models/gemma/configuration_gemma.py @@ -19,7 +19,7 @@ # 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. -from ...configuration_utils import PretrainedConfig +from ...configuration_utils import PretrainedConfig, layer_type_validation class GemmaConfig(PretrainedConfig): @@ -30,6 +30,7 @@ class GemmaConfig(PretrainedConfig): e.g. [google/gemma-7b](https://huggingface.co/google/gemma-7b) 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 256000): Vocabulary size of the Gemma model. Defines the number of different tokens that can be represented by the @@ -77,6 +78,11 @@ class GemmaConfig(PretrainedConfig): Whether to use a bias in the query, key, value and output projection layers during self-attention. attention_dropout (`float`, *optional*, defaults to 0.0): The dropout ratio for the attention probabilities. + layer_types (`list`, *optional*): + Attention pattern for each layer. + use_bidirectional_attention (`bool`, *optional*): + If True, the model will attend to all text tokens instead of using a causal mask. + ```python >>> from transformers import GemmaModel, GemmaConfig >>> # Initializing a Gemma gemma-7b style configuration @@ -125,6 +131,8 @@ def __init__( rope_theta=10000.0, attention_bias=False, attention_dropout=0.0, + layer_types=None, + use_bidirectional_attention=None, **kwargs, ): self.vocab_size = vocab_size @@ -142,6 +150,12 @@ def __init__( self.rope_theta = rope_theta self.attention_bias = attention_bias self.attention_dropout = attention_dropout + self.use_bidirectional_attention = use_bidirectional_attention + + self.layer_types = layer_types + if self.layer_types is None: + self.layer_types = ["full_attention" for _ in range(self.num_hidden_layers)] + layer_type_validation(self.layer_types, self.num_hidden_layers) super().__init__( pad_token_id=pad_token_id, diff --git a/src/transformers/models/gemma/modeling_gemma.py b/src/transformers/models/gemma/modeling_gemma.py index 04d27b309a40..ef0a688d4608 100644 --- a/src/transformers/models/gemma/modeling_gemma.py +++ b/src/transformers/models/gemma/modeling_gemma.py @@ -198,7 +198,7 @@ def __init__(self, config: GemmaConfig, layer_idx: int): self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads self.scaling = self.head_dim**-0.5 self.attention_dropout = config.attention_dropout - self.is_causal = True + self.is_causal = not getattr(config, "use_bidirectional_attention", False) self.q_proj = nn.Linear( config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias @@ -268,6 +268,7 @@ def __init__(self, config: GemmaConfig, layer_idx: int): self.mlp = GemmaMLP(config) self.input_layernorm = GemmaRMSNorm(config.hidden_size, eps=config.rms_norm_eps) self.post_attention_layernorm = GemmaRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.attention_type = config.layer_types[layer_idx] @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") def forward( @@ -379,14 +380,18 @@ def forward( if position_ids is None: position_ids = cache_position.unsqueeze(0) - causal_mask = create_causal_mask( - config=self.config, - input_embeds=inputs_embeds, - attention_mask=attention_mask, - cache_position=cache_position, - past_key_values=past_key_values, - position_ids=position_ids, - ) + # It may already have been prepared by e.g. `generate` + if not isinstance(causal_mask_mapping := attention_mask, dict): + causal_mask_mapping = { + "full_attention": create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=position_ids, + ) + } # embed positions hidden_states = inputs_embeds @@ -403,7 +408,7 @@ def forward( for decoder_layer in self.layers[: self.config.num_hidden_layers]: hidden_states = decoder_layer( hidden_states, - attention_mask=causal_mask, + attention_mask=causal_mask_mapping[decoder_layer.attention_type], position_ids=position_ids, past_key_values=past_key_values, use_cache=use_cache, diff --git a/src/transformers/models/gemma/modular_gemma.py b/src/transformers/models/gemma/modular_gemma.py index 94c3820de79c..df07b721fb10 100644 --- a/src/transformers/models/gemma/modular_gemma.py +++ b/src/transformers/models/gemma/modular_gemma.py @@ -20,7 +20,7 @@ from torch import nn from ...cache_utils import Cache, DynamicCache -from ...configuration_utils import PretrainedConfig +from ...configuration_utils import PretrainedConfig, layer_type_validation from ...masking_utils import create_causal_mask from ...modeling_outputs import BaseModelOutputWithPast from ...modeling_utils import PreTrainedModel @@ -28,6 +28,8 @@ from ...tokenization_utils import AddedToken, PreTrainedTokenizer from ...utils import TransformersKwargs, logging from ..llama.modeling_llama import ( + LlamaAttention, + LlamaDecoderLayer, LlamaForCausalLM, LlamaForSequenceClassification, LlamaForTokenClassification, @@ -58,6 +60,7 @@ class GemmaConfig(PretrainedConfig): e.g. [google/gemma-7b](https://huggingface.co/google/gemma-7b) 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 256000): Vocabulary size of the Gemma model. Defines the number of different tokens that can be represented by the @@ -105,6 +108,11 @@ class GemmaConfig(PretrainedConfig): Whether to use a bias in the query, key, value and output projection layers during self-attention. attention_dropout (`float`, *optional*, defaults to 0.0): The dropout ratio for the attention probabilities. + layer_types (`list`, *optional*): + Attention pattern for each layer. + use_bidirectional_attention (`bool`, *optional*): + If True, the model will attend to all text tokens instead of using a causal mask. + ```python >>> from transformers import GemmaModel, GemmaConfig >>> # Initializing a Gemma gemma-7b style configuration @@ -153,6 +161,8 @@ def __init__( rope_theta=10000.0, attention_bias=False, attention_dropout=0.0, + layer_types=None, + use_bidirectional_attention=None, **kwargs, ): self.vocab_size = vocab_size @@ -170,6 +180,12 @@ def __init__( self.rope_theta = rope_theta self.attention_bias = attention_bias self.attention_dropout = attention_dropout + self.use_bidirectional_attention = use_bidirectional_attention + + self.layer_types = layer_types + if self.layer_types is None: + self.layer_types = ["full_attention" for _ in range(self.num_hidden_layers)] + layer_type_validation(self.layer_types, self.num_hidden_layers) super().__init__( pad_token_id=pad_token_id, @@ -368,6 +384,20 @@ class GemmaRotaryEmbedding(LlamaRotaryEmbedding): pass +class GemmaAttention(LlamaAttention): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: GemmaConfig, layer_idx: int): + super().__init__() + self.is_causal = not getattr(config, "use_bidirectional_attention", False) + + +class GemmaDecoderLayer(LlamaDecoderLayer): + def __init__(self, config: GemmaConfig, layer_idx: int): + super().__init__() + self.attention_type = config.layer_types[layer_idx] + + class GemmaPreTrainedModel(LlamaPreTrainedModel): def _init_weights(self, module): PreTrainedModel._init_weights(self, module) @@ -407,14 +437,18 @@ def forward( if position_ids is None: position_ids = cache_position.unsqueeze(0) - causal_mask = create_causal_mask( - config=self.config, - input_embeds=inputs_embeds, - attention_mask=attention_mask, - cache_position=cache_position, - past_key_values=past_key_values, - position_ids=position_ids, - ) + # It may already have been prepared by e.g. `generate` + if not isinstance(causal_mask_mapping := attention_mask, dict): + causal_mask_mapping = { + "full_attention": create_causal_mask( + config=self.config, + input_embeds=inputs_embeds, + attention_mask=attention_mask, + cache_position=cache_position, + past_key_values=past_key_values, + position_ids=position_ids, + ) + } # embed positions hidden_states = inputs_embeds @@ -431,7 +465,7 @@ def forward( for decoder_layer in self.layers[: self.config.num_hidden_layers]: hidden_states = decoder_layer( hidden_states, - attention_mask=causal_mask, + attention_mask=causal_mask_mapping[decoder_layer.attention_type], position_ids=position_ids, past_key_values=past_key_values, use_cache=use_cache, diff --git a/src/transformers/models/gemma2/configuration_gemma2.py b/src/transformers/models/gemma2/configuration_gemma2.py index d43ec4c47371..58749515169e 100644 --- a/src/transformers/models/gemma2/configuration_gemma2.py +++ b/src/transformers/models/gemma2/configuration_gemma2.py @@ -30,6 +30,7 @@ class Gemma2Config(PretrainedConfig): e.g. [google/gemma2-7b](https://huggingface.co/google/gemma2-7b) 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 256000): Vocabulary size of the Gemma2 model. Defines the number of different tokens that can be represented by the @@ -88,6 +89,8 @@ class Gemma2Config(PretrainedConfig): scaling factor when applying tanh softcapping on the logits. attn_logit_softcapping (`float`, *optional*, defaults to 50.0): scaling factor when applying tanh softcapping on the attention scores. + use_bidirectional_attention (`bool`, *optional*): + If True, the model will attend to all text tokens instead of using a causal mask. ```python >>> from transformers import Gemma2Model, Gemma2Config @@ -142,6 +145,7 @@ def __init__( layer_types=None, final_logit_softcapping=30.0, attn_logit_softcapping=50.0, + use_bidirectional_attention=None, **kwargs, ): super().__init__( @@ -171,6 +175,7 @@ def __init__( self.final_logit_softcapping = final_logit_softcapping self.attn_logit_softcapping = attn_logit_softcapping self.layer_types = layer_types + self.use_bidirectional_attention = use_bidirectional_attention if self.layer_types is None: self.layer_types = [ diff --git a/src/transformers/models/gemma2/modeling_gemma2.py b/src/transformers/models/gemma2/modeling_gemma2.py index ec2f1521ef85..2a218338384a 100644 --- a/src/transformers/models/gemma2/modeling_gemma2.py +++ b/src/transformers/models/gemma2/modeling_gemma2.py @@ -211,7 +211,7 @@ def __init__(self, config: Gemma2Config, layer_idx: int): self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads self.scaling = config.query_pre_attn_scalar**-0.5 self.attention_dropout = self.config.attention_dropout - self.is_causal = True + self.is_causal = not getattr(config, "use_bidirectional_attention", False) self.q_proj = nn.Linear( config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias diff --git a/src/transformers/models/gemma2/modular_gemma2.py b/src/transformers/models/gemma2/modular_gemma2.py index add7e6c0989b..12024bdcb7b9 100644 --- a/src/transformers/models/gemma2/modular_gemma2.py +++ b/src/transformers/models/gemma2/modular_gemma2.py @@ -55,6 +55,7 @@ class Gemma2Config(PretrainedConfig): e.g. [google/gemma2-7b](https://huggingface.co/google/gemma2-7b) 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 256000): Vocabulary size of the Gemma2 model. Defines the number of different tokens that can be represented by the @@ -113,6 +114,8 @@ class Gemma2Config(PretrainedConfig): scaling factor when applying tanh softcapping on the logits. attn_logit_softcapping (`float`, *optional*, defaults to 50.0): scaling factor when applying tanh softcapping on the attention scores. + use_bidirectional_attention (`bool`, *optional*): + If True, the model will attend to all text tokens instead of using a causal mask. ```python >>> from transformers import Gemma2Model, Gemma2Config @@ -167,6 +170,7 @@ def __init__( layer_types=None, final_logit_softcapping=30.0, attn_logit_softcapping=50.0, + use_bidirectional_attention=None, **kwargs, ): super().__init__( @@ -196,6 +200,7 @@ def __init__( self.final_logit_softcapping = final_logit_softcapping self.attn_logit_softcapping = attn_logit_softcapping self.layer_types = layer_types + self.use_bidirectional_attention = use_bidirectional_attention if self.layer_types is None: self.layer_types = [ @@ -258,7 +263,7 @@ def __init__(self, config: Gemma2Config, layer_idx: int): super().__init__(config, layer_idx) self.attn_logit_softcapping = self.config.attn_logit_softcapping self.attention_dropout = self.config.attention_dropout - self.is_causal = True + self.is_causal = not getattr(config, "use_bidirectional_attention", False) self.scaling = config.query_pre_attn_scalar**-0.5 self.sliding_window = config.sliding_window if config.layer_types[layer_idx] == "sliding_attention" else None diff --git a/src/transformers/models/gemma3/configuration_gemma3.py b/src/transformers/models/gemma3/configuration_gemma3.py index 15d055654b11..893d0626dfd7 100644 --- a/src/transformers/models/gemma3/configuration_gemma3.py +++ b/src/transformers/models/gemma3/configuration_gemma3.py @@ -38,6 +38,7 @@ class Gemma3TextConfig(PretrainedConfig): e.g. [google/gemma3_text-7b](https://huggingface.co/google/gemma3_text-7b) 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 262208): Vocabulary size of the Gemma3Text model. Defines the number of different tokens that can be represented by the @@ -135,8 +136,9 @@ class Gemma3TextConfig(PretrainedConfig): Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE rope_local_base_freq (float, *optional*, defaults to 10000.0): The base period of the RoPE embeddings for local attention. - use_bidirectional_attention (`bool`, *optional*, defaults to `False`): If True, the model will attend to all - text tokens instead of using a causal mask. This does not change behavior for vision tokens. + use_bidirectional_attention (`bool`, *optional*, defaults to `False`): + If True, the model will attend to all text tokens instead of using a causal mask. This does not change + behavior for vision tokens. ```python >>> from transformers import Gemma3TextModel, Gemma3TextConfig diff --git a/src/transformers/models/gemma3/modeling_gemma3.py b/src/transformers/models/gemma3/modeling_gemma3.py index 4536ec7f69f7..ed9c83180059 100644 --- a/src/transformers/models/gemma3/modeling_gemma3.py +++ b/src/transformers/models/gemma3/modeling_gemma3.py @@ -729,7 +729,6 @@ def forward(self, vision_outputs: torch.Tensor): def token_type_ids_mask_function( token_type_ids: Optional[torch.Tensor], image_group_ids: Optional[torch.Tensor], - tokens_per_image: int, ) -> Optional[Callable]: """ This function adds the correct offsets to the `q_idx` and `kv_idx` as the torch API can only accept lengths, @@ -759,6 +758,57 @@ def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool: return inner_mask +def create_causal_mask_mapping( + config: PretrainedConfig, + input_embeds: torch.Tensor, + attention_mask: Optional[torch.Tensor], + cache_position: torch.Tensor, + past_key_values: Optional[Cache], + position_ids: Optional[torch.Tensor], + token_type_ids: Optional[torch.Tensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, + is_training: bool = False, + **kwargs, +) -> dict: + """ + Overwrites the base `create_masks_for_generate` with `token_type_ids` masking to create the causal mask mapping + for all kinds of forward passes. Gemma3 uses a bidirectional mask for images. + + Uses `pixel_values` as an optional input to disambiguate edge cases. + """ + if is_training and token_type_ids is None: + raise ValueError("`token_type_ids` is required as a model input when training") + + mask_kwargs = { + "config": config.get_text_config(), + "input_embeds": input_embeds, + "attention_mask": attention_mask, + "cache_position": cache_position, + "past_key_values": past_key_values, + "position_ids": position_ids, + } + # NOTE: this `may_have_image_input` logic is not flawless, it fails when we're using a cache eagerly initialized + # (e.g. compiled prefill) AND `pixel_values` are not provided (i.e. the image data is provided through other + # means). Determining prefill in that case requires checking data values, which is not compile-compatible. + may_have_image_input = past_key_values is None or not past_key_values.is_initialized or pixel_values is not None + if token_type_ids is not None and may_have_image_input: + # We need to pass an additional mask function to account for token type ids, and it needs to be an `or` (to + # undo the causal masking) + + # First find where a new image block starts: 1 if image and previous not image + # The images cannot attend to future images, but can attend to all prev images and to itself bidirectionally + is_image = (token_type_ids == 1).to(cache_position.device) + is_previous_image = nn.functional.pad(is_image, (1, 0), value=0)[:, :-1] + new_image_start = is_image & ~is_previous_image + image_group_ids = torch.cumsum(new_image_start.int(), dim=1) - 1 + image_group_ids = torch.where(is_image, image_group_ids, torch.full_like(token_type_ids, -1)) + mask_kwargs["or_mask_function"] = token_type_ids_mask_function( + token_type_ids.to(cache_position.device), image_group_ids + ) + + return create_masks_for_generate(**mask_kwargs) + + @auto_docstring( custom_intro=""" The Base Gemma3 model which consists of a vision backbone and a language model without language modeling head., @@ -914,45 +964,17 @@ def forward( # It may already have been prepared by e.g. `generate` if not isinstance(causal_mask_mapping := attention_mask, dict): - # Prepare mask arguments - mask_kwargs = { - "config": self.config.get_text_config(), - "input_embeds": inputs_embeds, - "attention_mask": attention_mask, - "cache_position": cache_position, - "past_key_values": past_key_values, - "position_ids": position_ids, - } - # NOTE: this `is_prefill` logic is not flawless, it fails when we're using a cache eagerly initialized - # (e.g. compiled prefill) AND `pixel_values` are not provided. Determining prefill in that case requires - # checking data values, which is not compile-compatible. - is_prefill = ( - not use_cache - or past_key_values is None - or not past_key_values.is_initialized - or pixel_values is not None + causal_mask_mapping = create_causal_mask_mapping( + self.config, + inputs_embeds, + attention_mask, + cache_position, + past_key_values, + position_ids, + token_type_ids, + pixel_values, + is_training=self.training, ) - if token_type_ids is not None and is_prefill: - # We need to pass an additional mask function to account for token type ids, and it needs to be an `or` - - # First find where a new image block starts: 1 if image and previous not image - # The images cannot attend to future images, but can attend to all prev images and to itself - # bidirectionally - is_image = (token_type_ids == 1).to(cache_position.device) - new_image_start = is_image & ~nn.functional.pad(is_image, (1, 0), value=0)[:, :-1] - image_group_ids = torch.cumsum(new_image_start.int(), dim=1) - 1 - image_group_ids = torch.where( - is_image, image_group_ids, torch.full_like(token_type_ids, -1, device=is_image.device) - ) - mask_kwargs["or_mask_function"] = token_type_ids_mask_function( - token_type_ids.to(cache_position.device), image_group_ids, self.config.mm_tokens_per_image - ) - - # Create the masks - causal_mask_mapping = { - "full_attention": create_causal_mask(**mask_kwargs), - "sliding_attention": create_sliding_window_causal_mask(**mask_kwargs), - } outputs = self.language_model( attention_mask=causal_mask_mapping, @@ -1201,30 +1223,18 @@ def create_masks_for_generate( token_type_ids: Optional[torch.Tensor] = None, **kwargs, ) -> dict: - # Prepare mask arguments - mask_kwargs = { - "config": config.get_text_config(), - "input_embeds": input_embeds, - "attention_mask": attention_mask, - "cache_position": cache_position, - "past_key_values": past_key_values, - "position_ids": position_ids, - } - # Add the token type ids mask for generate as well - if token_type_ids is not None and input_embeds.shape[1] != 1: - # We need to pass an additional mask function to account for token type ids, and it needs to be an `or` - - # First find where a new image block starts: 1 if image and previous not image - # The images cannot attend to future images, but can attend to all prev images and to itself bidirectionally - is_image = (token_type_ids == 1).to(cache_position.device) - new_image_start = is_image & ~nn.functional.pad(is_image, (1, 0), value=0)[:, :-1] - image_group_ids = torch.cumsum(new_image_start.int(), dim=1) - 1 - image_group_ids = torch.where(is_image, image_group_ids, torch.full_like(token_type_ids, -1)) - mask_kwargs["or_mask_function"] = token_type_ids_mask_function( - token_type_ids.to(cache_position.device), image_group_ids, config.mm_tokens_per_image - ) - - return create_masks_for_generate(**mask_kwargs) + # Uses the overwritten `create_masks_for_generate` with `token_type_ids` masking + return create_causal_mask_mapping( + config, + input_embeds, + attention_mask, + cache_position, + past_key_values, + position_ids, + token_type_ids, + pixel_values=kwargs.get("pixel_values"), + **{k: v for k, v in kwargs.items() if k != "pixel_values"}, + ) class Gemma3ForSequenceClassification(Gemma3PreTrainedModel): diff --git a/src/transformers/models/gemma3/modular_gemma3.py b/src/transformers/models/gemma3/modular_gemma3.py index 8afbf566c061..0f995c5498ac 100644 --- a/src/transformers/models/gemma3/modular_gemma3.py +++ b/src/transformers/models/gemma3/modular_gemma3.py @@ -48,6 +48,7 @@ PaliGemmaForConditionalGeneration, PaliGemmaModel, PaligemmaModelOutputWithPast, + token_type_ids_mask_function, ) from ..siglip import SiglipVisionConfig @@ -63,6 +64,7 @@ class Gemma3TextConfig(Gemma2Config, PretrainedConfig): e.g. [google/gemma3_text-7b](https://huggingface.co/google/gemma3_text-7b) 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 262208): Vocabulary size of the Gemma3Text model. Defines the number of different tokens that can be represented by the @@ -160,8 +162,9 @@ class Gemma3TextConfig(Gemma2Config, PretrainedConfig): Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE rope_local_base_freq (float, *optional*, defaults to 10000.0): The base period of the RoPE embeddings for local attention. - use_bidirectional_attention (`bool`, *optional*, defaults to `False`): If True, the model will attend to all - text tokens instead of using a causal mask. This does not change behavior for vision tokens. + use_bidirectional_attention (`bool`, *optional*, defaults to `False`): + If True, the model will attend to all text tokens instead of using a causal mask. This does not change + behavior for vision tokens. ```python >>> from transformers import Gemma3TextModel, Gemma3TextConfig @@ -721,37 +724,55 @@ def forward(self, vision_outputs: torch.Tensor): return projected_vision_outputs.type_as(vision_outputs) -def token_type_ids_mask_function( - token_type_ids: Optional[torch.Tensor], - image_group_ids: Optional[torch.Tensor], - tokens_per_image: int, -) -> Optional[Callable]: - """ - This function adds the correct offsets to the `q_idx` and `kv_idx` as the torch API can only accept lengths, - not start and end indices. +def create_causal_mask_mapping( + config: PretrainedConfig, + input_embeds: torch.Tensor, + attention_mask: Optional[torch.Tensor], + cache_position: torch.Tensor, + past_key_values: Optional[Cache], + position_ids: Optional[torch.Tensor], + token_type_ids: Optional[torch.Tensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, + is_training: bool = False, + **kwargs, +) -> dict: """ - # Do not return an additional mask in this case - if token_type_ids is None: - return None - - def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool: - # If it's 1 for both query and key/value, we are in an image block - # NOTE: static cache shape goes beyond input seq length, while token_type_ids.shape[1] == input seq length - # Since vmap doesn't support `if statement` we workaround it with `torch.where` - safe_idx = torch.where(kv_idx < token_type_ids.shape[1], kv_idx, 0) - token_type_ids_at_kv_idx = token_type_ids[batch_idx, safe_idx] - token_type_ids_at_kv_idx = torch.where(kv_idx < token_type_ids.shape[1], token_type_ids_at_kv_idx, 0) + Overwrites the base `create_masks_for_generate` with `token_type_ids` masking to create the causal mask mapping + for all kinds of forward passes. Gemma3 uses a bidirectional mask for images. - image_group_ids_at_kv_idx = image_group_ids[batch_idx, safe_idx] - image_group_ids_at_kv_idx = torch.where(kv_idx < image_group_ids.shape[1], image_group_ids_at_kv_idx, -1) - - is_image_block = (token_type_ids[batch_idx, q_idx] == 1) & (token_type_ids_at_kv_idx == 1) - same_image_block = image_group_ids[batch_idx, q_idx] == image_group_ids_at_kv_idx - - # This is bidirectional attention whenever we are dealing with image tokens - return is_image_block & same_image_block + Uses `pixel_values` as an optional input to disambiguate edge cases. + """ + if is_training and token_type_ids is None: + raise ValueError("`token_type_ids` is required as a model input when training") + + mask_kwargs = { + "config": config.get_text_config(), + "input_embeds": input_embeds, + "attention_mask": attention_mask, + "cache_position": cache_position, + "past_key_values": past_key_values, + "position_ids": position_ids, + } + # NOTE: this `may_have_image_input` logic is not flawless, it fails when we're using a cache eagerly initialized + # (e.g. compiled prefill) AND `pixel_values` are not provided (i.e. the image data is provided through other + # means). Determining prefill in that case requires checking data values, which is not compile-compatible. + may_have_image_input = past_key_values is None or not past_key_values.is_initialized or pixel_values is not None + if token_type_ids is not None and may_have_image_input: + # We need to pass an additional mask function to account for token type ids, and it needs to be an `or` (to + # undo the causal masking) + + # First find where a new image block starts: 1 if image and previous not image + # The images cannot attend to future images, but can attend to all prev images and to itself bidirectionally + is_image = (token_type_ids == 1).to(cache_position.device) + is_previous_image = nn.functional.pad(is_image, (1, 0), value=0)[:, :-1] + new_image_start = is_image & ~is_previous_image + image_group_ids = torch.cumsum(new_image_start.int(), dim=1) - 1 + image_group_ids = torch.where(is_image, image_group_ids, torch.full_like(token_type_ids, -1)) + mask_kwargs["or_mask_function"] = token_type_ids_mask_function( + token_type_ids.to(cache_position.device), image_group_ids + ) - return inner_mask + return create_masks_for_generate(**mask_kwargs) class Gemma3Model(PaliGemmaModel): @@ -776,9 +797,6 @@ def get_image_features(self, pixel_values: torch.Tensor) -> torch.Tensor: image_features = self.multi_modal_projector(vision_outputs) return image_features - def _update_causal_mask(self, **super_kwargs): - raise AttributeError("We don't want to inherit it") - @can_return_tuple @auto_docstring def forward( @@ -835,45 +853,17 @@ def forward( # It may already have been prepared by e.g. `generate` if not isinstance(causal_mask_mapping := attention_mask, dict): - # Prepare mask arguments - mask_kwargs = { - "config": self.config.get_text_config(), - "input_embeds": inputs_embeds, - "attention_mask": attention_mask, - "cache_position": cache_position, - "past_key_values": past_key_values, - "position_ids": position_ids, - } - # NOTE: this `is_prefill` logic is not flawless, it fails when we're using a cache eagerly initialized - # (e.g. compiled prefill) AND `pixel_values` are not provided. Determining prefill in that case requires - # checking data values, which is not compile-compatible. - is_prefill = ( - not use_cache - or past_key_values is None - or not past_key_values.is_initialized - or pixel_values is not None + causal_mask_mapping = create_causal_mask_mapping( + self.config, + inputs_embeds, + attention_mask, + cache_position, + past_key_values, + position_ids, + token_type_ids, + pixel_values, + is_training=self.training, ) - if token_type_ids is not None and is_prefill: - # We need to pass an additional mask function to account for token type ids, and it needs to be an `or` - - # First find where a new image block starts: 1 if image and previous not image - # The images cannot attend to future images, but can attend to all prev images and to itself - # bidirectionally - is_image = (token_type_ids == 1).to(cache_position.device) - new_image_start = is_image & ~nn.functional.pad(is_image, (1, 0), value=0)[:, :-1] - image_group_ids = torch.cumsum(new_image_start.int(), dim=1) - 1 - image_group_ids = torch.where( - is_image, image_group_ids, torch.full_like(token_type_ids, -1, device=is_image.device) - ) - mask_kwargs["or_mask_function"] = token_type_ids_mask_function( - token_type_ids.to(cache_position.device), image_group_ids, self.config.mm_tokens_per_image - ) - - # Create the masks - causal_mask_mapping = { - "full_attention": create_causal_mask(**mask_kwargs), - "sliding_attention": create_sliding_window_causal_mask(**mask_kwargs), - } outputs = self.language_model( attention_mask=causal_mask_mapping, @@ -1065,45 +1055,6 @@ def prepare_inputs_for_generation( return model_inputs - def _prepare_4d_causal_attention_mask_with_cache_position(self, **super_kwargs): - raise AttributeError("We don't want to inherit it") - - @staticmethod - def create_masks_for_generate( - config: PretrainedConfig, - input_embeds: torch.Tensor, - attention_mask: Optional[torch.Tensor], - cache_position: torch.Tensor, - past_key_values: Optional[Cache], - position_ids: Optional[torch.Tensor], - token_type_ids: Optional[torch.Tensor] = None, - **kwargs, - ) -> dict: - # Prepare mask arguments - mask_kwargs = { - "config": config.get_text_config(), - "input_embeds": input_embeds, - "attention_mask": attention_mask, - "cache_position": cache_position, - "past_key_values": past_key_values, - "position_ids": position_ids, - } - # Add the token type ids mask for generate as well - if token_type_ids is not None and input_embeds.shape[1] != 1: - # We need to pass an additional mask function to account for token type ids, and it needs to be an `or` - - # First find where a new image block starts: 1 if image and previous not image - # The images cannot attend to future images, but can attend to all prev images and to itself bidirectionally - is_image = (token_type_ids == 1).to(cache_position.device) - new_image_start = is_image & ~nn.functional.pad(is_image, (1, 0), value=0)[:, :-1] - image_group_ids = torch.cumsum(new_image_start.int(), dim=1) - 1 - image_group_ids = torch.where(is_image, image_group_ids, torch.full_like(token_type_ids, -1)) - mask_kwargs["or_mask_function"] = token_type_ids_mask_function( - token_type_ids.to(cache_position.device), image_group_ids, config.mm_tokens_per_image - ) - - return create_masks_for_generate(**mask_kwargs) - class Gemma3ForSequenceClassification(Gemma3PreTrainedModel): _checkpoint_conversion_mapping = { diff --git a/src/transformers/models/gemma3n/modular_gemma3n.py b/src/transformers/models/gemma3n/modular_gemma3n.py index 48de2bb27f7f..580afd43de1f 100644 --- a/src/transformers/models/gemma3n/modular_gemma3n.py +++ b/src/transformers/models/gemma3n/modular_gemma3n.py @@ -2472,9 +2472,6 @@ def get_audio_features( audio_outputs, audio_mask = self.audio_tower(input_features, input_features_mask) return self.embed_audio(inputs_embeds=audio_outputs), audio_mask - def _update_causal_mask(self, **super_kwargs): - raise AttributeError("We don't want to inherit it") - @auto_docstring( custom_intro=""" @@ -2668,8 +2665,8 @@ def prepare_inputs_for_generation( return model_inputs - def _prepare_4d_causal_attention_mask_with_cache_position(self, **super_kwargs): - raise AttributeError("Do not inherit _prepare_4d_causal_attention_mask_with_cache_position from PaliGemma") + def create_masks_for_generate(self, **super_kwargs): + raise AttributeError("Do not inherit create_masks_for_generate from PaliGemma") __all__ = [ diff --git a/src/transformers/models/helium/configuration_helium.py b/src/transformers/models/helium/configuration_helium.py index 9bb4d8d88750..bee324fbb729 100644 --- a/src/transformers/models/helium/configuration_helium.py +++ b/src/transformers/models/helium/configuration_helium.py @@ -25,6 +25,7 @@ class HeliumConfig(PretrainedConfig): e.g. [kyutai/helium-2b](https://huggingface.co/kyutai/helium-2b) 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 48000): Vocabulary size of the Helium model. Defines the number of different tokens that can be represented by the @@ -74,6 +75,7 @@ class HeliumConfig(PretrainedConfig): Whether to use a bias in the query, key, value and output projection layers during self-attention. mlp_bias (`bool`, *optional*, defaults to `False`): Whether to use a bias in up_proj, down_proj and gate_proj layers in the MLP layers. + ```python >>> from transformers import HeliumModel, HeliumConfig >>> # Initializing a Helium 2b style configuration diff --git a/src/transformers/models/paligemma/configuration_paligemma.py b/src/transformers/models/paligemma/configuration_paligemma.py index e4ee4b3b45c2..941543c2c9da 100644 --- a/src/transformers/models/paligemma/configuration_paligemma.py +++ b/src/transformers/models/paligemma/configuration_paligemma.py @@ -120,6 +120,12 @@ def __init__( is_encoder_decoder=False, vocab_size=vocab_size, ) + + # BC: `use_bidirectional_attention` was originally unset in PaliGemma1 (backbone = Gemma1) AND PaliGemma2 + # (backbone = Gemma2). Both PaliGemmas want to default to True. + if self.text_config.use_bidirectional_attention is None: + self.text_config.use_bidirectional_attention = True + self.text_config.num_image_tokens = (self.vision_config.image_size // self.vision_config.patch_size) ** 2 self.vision_config.projection_dim = projection_dim super().__init__(**kwargs) diff --git a/src/transformers/models/paligemma/modeling_paligemma.py b/src/transformers/models/paligemma/modeling_paligemma.py index abd8595e24ab..7e5d9f8332e3 100644 --- a/src/transformers/models/paligemma/modeling_paligemma.py +++ b/src/transformers/models/paligemma/modeling_paligemma.py @@ -15,13 +15,15 @@ """PyTorch PaliGemmamodel.""" from dataclasses import dataclass -from typing import Optional, Union +from typing import Callable, Optional, Union import torch from torch import nn -from ...cache_utils import Cache, StaticCache +from ...cache_utils import Cache +from ...configuration_utils import PretrainedConfig from ...generation import GenerationMixin +from ...masking_utils import create_masks_for_generate from ...modeling_flash_attention_utils import FlashAttentionKwargs from ...modeling_outputs import BaseModelOutputWithPast from ...modeling_utils import PreTrainedModel @@ -97,6 +99,109 @@ def forward(self, image_features): return hidden_states +def token_type_ids_mask_function( + token_type_ids: Optional[torch.Tensor], + image_group_ids: Optional[torch.Tensor], +) -> Optional[Callable]: + """ + This function adds the correct offsets to the `q_idx` and `kv_idx` as the torch API can only accept lengths, + not start and end indices. + """ + # Do not return an additional mask in this case + if token_type_ids is None: + return None + + def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool: + # If it's 1 for both query and key/value, we are in an image block + # NOTE: static cache shape goes beyond input seq length, while token_type_ids.shape[1] == input seq length + # Since vmap doesn't support `if statement` we workaround it with `torch.where` + safe_idx = torch.where(kv_idx < token_type_ids.shape[1], kv_idx, 0) + token_type_ids_at_kv_idx = token_type_ids[batch_idx, safe_idx] + token_type_ids_at_kv_idx = torch.where(kv_idx < token_type_ids.shape[1], token_type_ids_at_kv_idx, 0) + + image_group_ids_at_kv_idx = image_group_ids[batch_idx, safe_idx] + image_group_ids_at_kv_idx = torch.where(kv_idx < image_group_ids.shape[1], image_group_ids_at_kv_idx, -1) + + is_image_block = (token_type_ids[batch_idx, q_idx] == 1) & (token_type_ids_at_kv_idx == 1) + same_image_block = image_group_ids[batch_idx, q_idx] == image_group_ids_at_kv_idx + + # This is bidirectional attention whenever we are dealing with image tokens + return is_image_block & same_image_block + + return inner_mask + + +def create_causal_mask_mapping( + config: PretrainedConfig, + input_embeds: torch.Tensor, + attention_mask: Optional[torch.Tensor], + cache_position: torch.Tensor, + past_key_values: Optional[Cache], + position_ids: Optional[torch.Tensor], + token_type_ids: Optional[torch.Tensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, + is_training: bool = False, + **kwargs, +) -> dict: + """ + Overwrites the base `create_masks_for_generate` with `token_type_ids` masking to create the causal mask mapping + for all kinds of forward passes. Paligemma uses a bidirectional mask on the prompt tokens. + + Uses `pixel_values` as an optional input to disambiguate edge cases. + """ + if is_training and token_type_ids is None: + raise ValueError("`token_type_ids` is required as a model input when training") + + mask_kwargs = { + "config": config.get_text_config(), + "input_embeds": input_embeds, + "attention_mask": attention_mask, + "cache_position": cache_position, + "past_key_values": past_key_values, + "position_ids": position_ids, + } + # NOTE: this `is_prompt` logic is not flawless, it fails when we're using a cache eagerly initialized + # (e.g. compiled prefill) AND `pixel_values` are not provided (i.e. the image data is provided through other + # means). Determining prefill in that case requires checking data values, which is not compile-compatible. + maybe_is_prompt = past_key_values is None or not past_key_values.is_initialized or pixel_values is not None + + if maybe_is_prompt: + if token_type_ids is not None: + # The logic bellow was originally written for Gemma3, where `token_type_ids` is reversed. Let's reverse + # it to then use exactly the same logic. + token_type_ids = 1 - token_type_ids + else: + logger.warning_once( + "The input may be the prompt, but `token_type_ids` is not provided. We recommend " + "passing `token_type_ids` to the model to prevent bad attention masking." + ) + # BC: when NOT training, use bidirectional mask if sequence length > 1. Otherwise, use the default causal + # mask. This is incorrect in some advanced use cases, hence the warning above. + # NOTE: this branch can't be reached when training because `token_type_ids` is required as a model input. + if input_embeds.shape[1] > 1: + token_type_ids = torch.ones_like(input_embeds)[:, :, 0] + + # Logic originally copied from Gemma3. It holds up for Paligemma as well because Paligemma assumes up to one image + # per prompt AND we reverse `token_type_ids` above. Gemma3 uses a bidirectional mask for images, tagged through + # `token_type_ids` 1s. + if token_type_ids is not None and maybe_is_prompt: + # We need to pass an additional mask function to account for token type ids, and it needs to be an `or` (to + # undo the causal masking) + + # First find where a new image block starts: 1 if image and previous not image + # The images cannot attend to future images, but can attend to all prev images and to itself bidirectionally + is_image = (token_type_ids == 1).to(cache_position.device) + is_previous_image = nn.functional.pad(is_image, (1, 0), value=0)[:, :-1] + new_image_start = is_image & ~is_previous_image + image_group_ids = torch.cumsum(new_image_start.int(), dim=1) - 1 + image_group_ids = torch.where(is_image, image_group_ids, torch.full_like(token_type_ids, -1)) + mask_kwargs["or_mask_function"] = token_type_ids_mask_function( + token_type_ids.to(cache_position.device), image_group_ids + ) + + return create_masks_for_generate(**mask_kwargs) + + @auto_docstring class PaliGemmaPreTrainedModel(PreTrainedModel): config: PaliGemmaConfig @@ -159,75 +264,6 @@ def set_decoder(self, decoder): def get_decoder(self): return self.language_model - def _update_causal_mask( - self, - attention_mask, - token_type_ids=None, - past_key_values=None, - cache_position=None, - input_tensor=None, - is_training: Optional[bool] = None, - ): - if self.config.text_config._attn_implementation == "flash_attention_2": - if attention_mask is not None and 0.0 in attention_mask: - return attention_mask - return None - is_training = is_training if is_training is not None else self.training - using_static_cache = isinstance(past_key_values, StaticCache) - min_dtype = torch.finfo(self.text_config_dtype).min - if input_tensor is None: - input_tensor = attention_mask - - inputs_lead_dim, sequence_length = input_tensor.shape[:2] - if using_static_cache: - target_length = past_key_values.get_max_cache_shape() - else: - target_length = ( - attention_mask.shape[-1] - if isinstance(attention_mask, torch.Tensor) - else cache_position[0] + sequence_length + 1 - ) - - if attention_mask is not None and attention_mask.dim() == 4: - # In this case we assume that the mask comes already in inverted form and requires no inversion or slicing. - return attention_mask - - causal_mask = torch.full( - (sequence_length, target_length), - fill_value=min_dtype, - dtype=self.text_config_dtype, - device=cache_position.device, - ) - # Causal diagonal mask only if training, otherwise attend to the whole prefix. Training-specific attn for prefix is handled below - if sequence_length != 1: - if is_training: - causal_mask = torch.triu(causal_mask, diagonal=1) - else: - causal_mask[:, :sequence_length] = 0.0 - - causal_mask *= torch.arange(target_length, device=cache_position.device) > cache_position.reshape(-1, 1) - causal_mask = causal_mask[None, None, :, :].expand(inputs_lead_dim, 1, -1, -1) - if attention_mask is not None: - causal_mask = causal_mask.clone() # copy to contiguous memory for in-place edit - mask_length = attention_mask.shape[-1] - - # First unmask prefix tokens during training - if is_training: - if token_type_ids is None: - raise ValueError("Token type ids must be provided during training") - causal_mask[:, :, :, :mask_length] = causal_mask[:, :, :, :mask_length].masked_fill( - token_type_ids[:, None, None, :].to(causal_mask.device) == 0, 0 - ) - - # Then apply padding mask (will mask pad tokens) - padding_mask = causal_mask[:, :, :, :mask_length] + attention_mask[:, None, None, :].to(causal_mask.device) - padding_mask = padding_mask == 0 - causal_mask[:, :, :, :mask_length] = causal_mask[:, :, :, :mask_length].masked_fill( - padding_mask, min_dtype - ) - - return causal_mask - def get_image_features(self, pixel_values: torch.FloatTensor): """ Obtains image last hidden states from the vision tower and apply multimodal projection. @@ -324,8 +360,6 @@ def forward( ) return_dict = return_dict if return_dict is not None else self.config.use_return_dict - is_training = token_type_ids is not None and labels is not None - # Replace image id with PAD if the image token if OOV, to avoid index-errors if input_ids is not None and self.config.image_token_id >= self.vocab_size: special_image_mask = input_ids == self.config.image_token_id @@ -355,11 +389,22 @@ def forward( ) inputs_embeds = inputs_embeds.masked_scatter(special_image_mask, image_features) - causal_mask = self._update_causal_mask( - attention_mask, token_type_ids, past_key_values, cache_position, inputs_embeds, is_training - ) + # It may already have been prepared by e.g. `generate` + if not isinstance(causal_mask_mapping := attention_mask, dict): + causal_mask_mapping = create_causal_mask_mapping( + self.config, + inputs_embeds, + attention_mask, + cache_position, + past_key_values, + position_ids, + token_type_ids, + pixel_values, + is_training=self.training, + ) + outputs = self.language_model( - attention_mask=causal_mask, + attention_mask=causal_mask_mapping, position_ids=position_ids, past_key_values=past_key_values, inputs_embeds=inputs_embeds, @@ -550,76 +595,37 @@ def prepare_inputs_for_generation( # position_ids in Paligemma are 1-indexed if model_inputs.get("position_ids") is not None: model_inputs["position_ids"] += 1 + # If we're in cached decoding stage, pixel values should be None because input ids do not contain special image token anymore # Otherwise we need pixel values to be passed to model. NOTE: use_cache=False needs pixel_values always if cache_position[0] == 0: model_inputs["pixel_values"] = pixel_values - is_training = token_type_ids is not None and labels is not None - is_static_hybrid_cache = isinstance(past_key_values, StaticCache) and any(past_key_values.is_sliding) - if cache_position[0] == 0 and is_static_hybrid_cache: - input_tensor = inputs_embeds if inputs_embeds is not None else input_ids - causal_mask = self.model._update_causal_mask( - attention_mask, token_type_ids, past_key_values, cache_position, input_tensor, is_training - ) - model_inputs["attention_mask"] = causal_mask return model_inputs @staticmethod - # Copied from transformers.models.gptj.modeling_gptj.GPTJModel._prepare_4d_causal_attention_mask_with_cache_position - def _prepare_4d_causal_attention_mask_with_cache_position( - attention_mask: torch.Tensor, - sequence_length: int, - target_length: int, - dtype: torch.dtype, + def create_masks_for_generate( + config: PretrainedConfig, + input_embeds: torch.Tensor, + attention_mask: Optional[torch.Tensor], cache_position: torch.Tensor, - batch_size: int, + past_key_values: Optional[Cache], + position_ids: Optional[torch.Tensor], + token_type_ids: Optional[torch.Tensor] = None, **kwargs, - ): - """ - Creates a causal 4D mask of shape `(batch_size, 1, query_length, key_value_length)` from a 2D mask of shape - `(batch_size, key_value_length)`, or if the input `attention_mask` is already 4D, do nothing. - - Args: - attention_mask (`torch.Tensor`): - A 2D attention mask of shape `(batch_size, key_value_length)` or a 4D attention mask of shape - `(batch_size, 1, query_length, key_value_length)`. - sequence_length (`int`): - The sequence length being processed. - target_length (`int`): - The target length: when generating with static cache, the mask should be as long as the static cache, - to account for the 0 padding, the part of the cache that is not filled yet. - dtype (`torch.dtype`): - The dtype to use for the 4D attention mask. - cache_position (`torch.Tensor`): - Indices depicting the position of the input sequence tokens in the sequence. - batch_size (`torch.Tensor`): - Batch size. - """ - if attention_mask is not None and attention_mask.dim() == 4: - # In this case we assume that the mask comes already in inverted form and requires no inversion or slicing. - causal_mask = attention_mask - else: - min_dtype = torch.finfo(dtype).min - causal_mask = torch.full( - (sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=cache_position.device - ) - if sequence_length != 1: - causal_mask = torch.triu(causal_mask, diagonal=1) - causal_mask *= torch.arange(target_length, device=cache_position.device) > cache_position.reshape(-1, 1) - causal_mask = causal_mask[None, None, :, :].expand(batch_size, 1, -1, -1) - if attention_mask is not None: - causal_mask = causal_mask.clone() # copy to contiguous memory for in-place edit - mask_length = attention_mask.shape[-1] - padding_mask = causal_mask[:, :, :, :mask_length] + attention_mask[:, None, None, :].to( - causal_mask.device - ) - padding_mask = padding_mask == 0 - causal_mask[:, :, :, :mask_length] = causal_mask[:, :, :, :mask_length].masked_fill( - padding_mask, min_dtype - ) - - return causal_mask + ) -> dict: + # Uses the overwritten `create_masks_for_generate` with `token_type_ids` masking + return create_causal_mask_mapping( + config, + input_embeds, + attention_mask, + cache_position, + past_key_values, + position_ids, + token_type_ids, + pixel_values=kwargs.get("pixel_values"), + **{k: v for k, v in kwargs.items() if k != "pixel_values"}, + ) __all__ = ["PaliGemmaForConditionalGeneration", "PaliGemmaPreTrainedModel", "PaliGemmaModel"] diff --git a/src/transformers/models/paligemma/processing_paligemma.py b/src/transformers/models/paligemma/processing_paligemma.py index 7bf7fe403d5f..c4c618a4d958 100644 --- a/src/transformers/models/paligemma/processing_paligemma.py +++ b/src/transformers/models/paligemma/processing_paligemma.py @@ -217,7 +217,7 @@ def __call__( ) suffix = output_kwargs["text_kwargs"].pop("suffix", None) - return_token_type_ids = suffix is not None + return_token_type_ids = True if images is None: raise ValueError("`images` are expected as arguments to a `PaliGemmaProcessor` instance.") @@ -299,6 +299,7 @@ def __call__( return_data = {**inputs, "pixel_values": pixel_values} + # TODO: ideally we would control label generation separately, now that we always return token_type_ids. if return_token_type_ids: labels = np.array(inputs["input_ids"]) labels[np.array(inputs["token_type_ids"]) == 0] = -100 @@ -330,5 +331,11 @@ def _get_num_multimodal_tokens(self, image_sizes=None, **kwargs): vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) return MultiModalData(**vision_data) + @property + def model_input_names(self): + tokenizer_input_names = self.tokenizer.model_input_names + ["token_type_ids", "labels"] + image_processor_input_names = self.image_processor.model_input_names + return list(tokenizer_input_names + image_processor_input_names) + __all__ = ["PaliGemmaProcessor"] diff --git a/src/transformers/models/t5gemma/configuration_t5gemma.py b/src/transformers/models/t5gemma/configuration_t5gemma.py index 217a24df0417..76ad99132056 100644 --- a/src/transformers/models/t5gemma/configuration_t5gemma.py +++ b/src/transformers/models/t5gemma/configuration_t5gemma.py @@ -32,6 +32,7 @@ class T5GemmaModuleConfig(PretrainedConfig): e.g. [google/t5_gemma_module-7b](https://huggingface.co/google/t5_gemma_module-7b) 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 256000): Vocabulary size of the T5GemmaModule model. Defines the number of different tokens that can be represented by the diff --git a/src/transformers/models/t5gemma/modeling_t5gemma.py b/src/transformers/models/t5gemma/modeling_t5gemma.py index b6be86e9cdd7..336e67ce42b6 100644 --- a/src/transformers/models/t5gemma/modeling_t5gemma.py +++ b/src/transformers/models/t5gemma/modeling_t5gemma.py @@ -505,81 +505,6 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return logits -class T5GemmaAttention(nn.Module): - """Multi-headed attention from 'Attention Is All You Need' paper""" - - def __init__(self, config: T5GemmaConfig, layer_idx: int): - super().__init__() - self.config = config - self.layer_idx = layer_idx - self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads) - self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads - self.scaling = config.query_pre_attn_scalar**-0.5 - self.attention_dropout = self.config.attention_dropout - self.is_causal = True - - self.q_proj = nn.Linear( - config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias - ) - self.k_proj = nn.Linear( - config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias - ) - self.v_proj = nn.Linear( - config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias - ) - self.o_proj = nn.Linear( - config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias - ) - self.attn_logit_softcapping = self.config.attn_logit_softcapping - self.sliding_window = config.sliding_window if config.layer_types[layer_idx] == "sliding_attention" else None - - @deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58") - def forward( - self, - hidden_states: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor], - attention_mask: Optional[torch.Tensor], - past_key_values: Optional[Cache] = None, - cache_position: Optional[torch.LongTensor] = None, - **kwargs: Unpack[FlashAttentionKwargs], - ) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]: - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - - query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) - key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) - value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) - - if past_key_values is not None: - # sin and cos are specific to RoPE models; cache_position needed for the static cache - cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} - key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs) - - attention_interface: Callable = eager_attention_forward - if self.config._attn_implementation != "eager": - attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation] - - attn_output, attn_weights = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask, - dropout=self.attention_dropout if self.training else 0.0, - scaling=self.scaling, - sliding_window=self.sliding_window, - softcap=self.attn_logit_softcapping, - **kwargs, - ) - - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attn_output = self.o_proj(attn_output) - return attn_output, attn_weights - - @auto_docstring class T5GemmaPreTrainedModel(PreTrainedModel): config: T5GemmaConfig @@ -595,7 +520,11 @@ class T5GemmaPreTrainedModel(PreTrainedModel): _supports_attention_backend = True _can_record_outputs = { "hidden_states": T5GemmaDecoderLayer, - "attentions": T5GemmaAttention, + "attentions": [ + OutputRecorder(T5GemmaSelfAttention, index=1, layer_name="self_attn"), + OutputRecorder(T5GemmaSelfAttention, index=1, layer_name="cross_attn"), + OutputRecorder(T5GemmaCrossAttention, index=1, layer_name="cross_attn"), + ], } def _init_weights(self, module): diff --git a/src/transformers/models/t5gemma/modular_t5gemma.py b/src/transformers/models/t5gemma/modular_t5gemma.py index d358a51d0e68..dafa2217d062 100644 --- a/src/transformers/models/t5gemma/modular_t5gemma.py +++ b/src/transformers/models/t5gemma/modular_t5gemma.py @@ -61,7 +61,140 @@ class T5GemmaModuleConfig(Gemma2Config): - pass + r""" + This is the configuration class to store the configuration of a [`T5GemmaModuleModel`]. It is used to instantiate an T5GemmaModule + 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 T5GemmaModule-7B. + e.g. [google/t5_gemma_module-7b](https://huggingface.co/google/t5_gemma_module-7b) + 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 256000): + Vocabulary size of the T5GemmaModule model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`T5GemmaModuleModel`] + hidden_size (`int`, *optional*, defaults to 2304): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 9216): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 26): + Number of hidden layers in the Transformer decoder. + num_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Transformer decoder. + num_key_value_heads (`int`, *optional*, defaults to 4): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to + `num_attention_heads`. + head_dim (`int`, *optional*, defaults to 256): + The attention head dimension. + hidden_activation (`str` or `function`, *optional*, defaults to `"gelu_pytorch_tanh"`): + The non-linear activation function (function or string) in the decoder. Will default to `"gelu_pytorch_tanh"` + if not specified. `"gelu_pytorch_tanh"` uses an approximation of the `"gelu"` activation function. + max_position_embeddings (`int`, *optional*, defaults to 8192): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + pad_token_id (`int`, *optional*, defaults to 0): + Padding token id. + eos_token_id (`int`, *optional*, defaults to 1): + End of stream token id. + bos_token_id (`int`, *optional*, defaults to 2): + Beginning of stream token id. + tie_word_embeddings (`bool`, *optional*, defaults to `True`): + Whether to tie weight embeddings + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period of the RoPE embeddings. + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + query_pre_attn_scalar (`float`, *optional*, defaults to 256): + scaling factor used on the attention scores + sliding_window (`int`, *optional*, defaults to 4096): + in T5GemmaModule, every other layer uses sliding window attention. This is the size of the sliding window. + layer_types (`list`, *optional*): + Attention pattern for each layer. + final_logit_softcapping (`float`, *optional*, defaults to 30.0): + scaling factor when applying tanh softcapping on the logits. + attn_logit_softcapping (`float`, *optional*, defaults to 50.0): + scaling factor when applying tanh softcapping on the attention scores. + + ```python + >>> from transformers import T5GemmaModuleModel, T5GemmaModuleConfig + >>> # Initializing a T5GemmaModule t5_gemma_module-7b style configuration + >>> configuration = T5GemmaModuleConfig() + >>> # Initializing a model from the t5_gemma_module-7b style configuration + >>> model = T5GemmaModuleModel(configuration) + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + def __init__( + self, + vocab_size=256000, + hidden_size=2304, + intermediate_size=9216, + num_hidden_layers=26, + num_attention_heads=8, + num_key_value_heads=4, + head_dim=256, + hidden_activation="gelu_pytorch_tanh", + max_position_embeddings=8192, + initializer_range=0.02, + rms_norm_eps=1e-6, + use_cache=True, + pad_token_id=0, + eos_token_id=1, + bos_token_id=2, + tie_word_embeddings=True, + rope_theta=10000.0, + attention_bias=False, + attention_dropout=0.0, + query_pre_attn_scalar=256, + sliding_window=4096, + layer_types=None, + final_logit_softcapping=30.0, + attn_logit_softcapping=50.0, + **kwargs, + ): + super().__init__( + vocab_size=vocab_size, + hidden_size=hidden_size, + intermediate_size=intermediate_size, + num_hidden_layers=num_hidden_layers, + num_attention_heads=num_attention_heads, + num_key_value_heads=num_key_value_heads, + head_dim=head_dim, + hidden_activation=hidden_activation, + max_position_embeddings=max_position_embeddings, + initializer_range=initializer_range, + rms_norm_eps=rms_norm_eps, + use_cache=use_cache, + pad_token_id=pad_token_id, + eos_token_id=eos_token_id, + bos_token_id=bos_token_id, + tie_word_embeddings=tie_word_embeddings, + rope_theta=rope_theta, + attention_bias=attention_bias, + attention_dropout=attention_dropout, + query_pre_attn_scalar=query_pre_attn_scalar, + sliding_window=sliding_window, + layer_types=layer_types, + final_logit_softcapping=final_logit_softcapping, + attn_logit_softcapping=attn_logit_softcapping, + **kwargs, + ) + + del self.use_bidirectional_attention class T5GemmaConfig(PretrainedConfig): @@ -477,6 +610,14 @@ class T5GemmaPreTrainedModel(Gemma2PreTrainedModel): base_model_prefix = "model" supports_gradient_checkpointing = True _no_split_modules = ["T5GemmaEncoderLayer", "T5GemmaDecoderLayer"] + _can_record_outputs = { + "hidden_states": T5GemmaDecoderLayer, + "attentions": [ + OutputRecorder(T5GemmaSelfAttention, index=1, layer_name="self_attn"), + OutputRecorder(T5GemmaSelfAttention, index=1, layer_name="cross_attn"), + OutputRecorder(T5GemmaCrossAttention, index=1, layer_name="cross_attn"), + ], + } def _init_weights(self, module): # TODO: support initialization for encoders and decoders separately(?) diff --git a/src/transformers/models/vaultgemma/configuration_vaultgemma.py b/src/transformers/models/vaultgemma/configuration_vaultgemma.py index 1b93ae6ccb04..488ce47e896d 100644 --- a/src/transformers/models/vaultgemma/configuration_vaultgemma.py +++ b/src/transformers/models/vaultgemma/configuration_vaultgemma.py @@ -30,6 +30,7 @@ class VaultGemmaConfig(PretrainedConfig): e.g. [google/vaultgemma-7b](https://huggingface.co/google/vaultgemma-7b) 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 256000): Vocabulary size of the VaultGemma model. Defines the number of different tokens that can be represented by the diff --git a/src/transformers/models/vaultgemma/modular_vaultgemma.py b/src/transformers/models/vaultgemma/modular_vaultgemma.py index 133fc50ded3b..5eb641a55563 100644 --- a/src/transformers/models/vaultgemma/modular_vaultgemma.py +++ b/src/transformers/models/vaultgemma/modular_vaultgemma.py @@ -19,13 +19,162 @@ from ...cache_utils import Cache from ..gemma2.configuration_gemma2 import Gemma2Config -from ..gemma2.modeling_gemma2 import Gemma2DecoderLayer, Gemma2ForCausalLM +from ..gemma2.modeling_gemma2 import Gemma2Attention, Gemma2DecoderLayer, Gemma2ForCausalLM, Gemma2MLP, Gemma2RMSNorm class VaultGemmaConfig(Gemma2Config): + r""" + This is the configuration class to store the configuration of a [`VaultGemmaModel`]. It is used to instantiate an VaultGemma + 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 VaultGemma-7B. + e.g. [google/vaultgemma-7b](https://huggingface.co/google/vaultgemma-7b) + 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 256000): + Vocabulary size of the VaultGemma model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`VaultGemmaModel`] + hidden_size (`int`, *optional*, defaults to 2304): + Dimension of the hidden representations. + intermediate_size (`int`, *optional*, defaults to 9216): + Dimension of the MLP representations. + num_hidden_layers (`int`, *optional*, defaults to 26): + Number of hidden layers in the Transformer decoder. + num_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Transformer decoder. + num_key_value_heads (`int`, *optional*, defaults to 4): + This is the number of key_value heads that should be used to implement Grouped Query Attention. If + `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if + `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When + converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed + by meanpooling all the original heads within that group. For more details, check out [this + paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to + `num_attention_heads`. + head_dim (`int`, *optional*, defaults to 256): + The attention head dimension. + hidden_activation (`str` or `function`, *optional*, defaults to `"gelu_pytorch_tanh"`): + The non-linear activation function (function or string) in the decoder. Will default to `"gelu_pytorch_tanh"` + if not specified. `"gelu_pytorch_tanh"` uses an approximation of the `"gelu"` activation function. + max_position_embeddings (`int`, *optional*, defaults to 8192): + The maximum sequence length that this model might ever be used with. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + rms_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the rms normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + pad_token_id (`int`, *optional*, defaults to 0): + Padding token id. + eos_token_id (`int`, *optional*, defaults to 1): + End of stream token id. + bos_token_id (`int`, *optional*, defaults to 2): + Beginning of stream token id. + tie_word_embeddings (`bool`, *optional*, defaults to `True`): + Whether to tie weight embeddings + rope_theta (`float`, *optional*, defaults to 10000.0): + The base period of the RoPE embeddings. + attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`): + Whether to use a bias in the query, key, value and output projection layers during self-attention. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + query_pre_attn_scalar (`float`, *optional*, defaults to 256): + scaling factor used on the attention scores + sliding_window (`int`, *optional*, defaults to 4096): + in VaultGemma, every other layer uses sliding window attention. This is the size of the sliding window. + layer_types (`list`, *optional*): + Attention pattern for each layer. + final_logit_softcapping (`float`, *optional*, defaults to 30.0): + scaling factor when applying tanh softcapping on the logits. + attn_logit_softcapping (`float`, *optional*, defaults to 50.0): + scaling factor when applying tanh softcapping on the attention scores. + + ```python + >>> from transformers import VaultGemmaModel, VaultGemmaConfig + >>> # Initializing a VaultGemma vaultgemma-7b style configuration + >>> configuration = VaultGemmaConfig() + >>> # Initializing a model from the vaultgemma-7b style configuration + >>> model = VaultGemmaModel(configuration) + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + def __init__( + self, + vocab_size=256000, + hidden_size=2304, + intermediate_size=9216, + num_hidden_layers=26, + num_attention_heads=8, + num_key_value_heads=4, + head_dim=256, + hidden_activation="gelu_pytorch_tanh", + max_position_embeddings=8192, + initializer_range=0.02, + rms_norm_eps=1e-6, + use_cache=True, + pad_token_id=0, + eos_token_id=1, + bos_token_id=2, + tie_word_embeddings=True, + rope_theta=10000.0, + attention_bias=False, + attention_dropout=0.0, + query_pre_attn_scalar=256, + sliding_window=4096, + layer_types=None, + final_logit_softcapping=30.0, + attn_logit_softcapping=50.0, + **kwargs, + ): + super().__init__( + vocab_size=vocab_size, + hidden_size=hidden_size, + intermediate_size=intermediate_size, + num_hidden_layers=num_hidden_layers, + num_attention_heads=num_attention_heads, + num_key_value_heads=num_key_value_heads, + head_dim=head_dim, + hidden_activation=hidden_activation, + max_position_embeddings=max_position_embeddings, + initializer_range=initializer_range, + rms_norm_eps=rms_norm_eps, + use_cache=use_cache, + pad_token_id=pad_token_id, + eos_token_id=eos_token_id, + bos_token_id=bos_token_id, + tie_word_embeddings=tie_word_embeddings, + rope_theta=rope_theta, + attention_bias=attention_bias, + attention_dropout=attention_dropout, + query_pre_attn_scalar=query_pre_attn_scalar, + sliding_window=sliding_window, + layer_types=layer_types, + final_logit_softcapping=final_logit_softcapping, + attn_logit_softcapping=attn_logit_softcapping, + **kwargs, + ) + + del self.use_bidirectional_attention + + +class VaultGemmaRMSNorm(Gemma2RMSNorm): + pass + + +class VaultGemmaMLP(Gemma2MLP): pass +class VaultGemmaAttention(Gemma2Attention): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: VaultGemmaConfig, layer_idx: int): + super().__init__() + self.is_causal = True + + class VaultGemmaDecoderLayer(Gemma2DecoderLayer): def __init__(self, **super_kwargs): super().__init__(**super_kwargs) diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index dcca71df7c2f..ed58403a53d0 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -744,8 +744,15 @@ def test_prompt_lookup_decoding_matches_greedy_search(self): for model_class in self.all_generative_model_classes: if model_class._is_stateful: self.skipTest(reason="Stateful models don't support assisted generation") - if any(model_name in model_class.__name__.lower() for model_name in ["reformer"]): - self.skipTest(reason="Won't fix: old model with different cache format") + old_models = [ # models that we won't commit resources fixing because they are old and have little usage + # reformer: has a different cache format + "reformer", + # imagegpt: the output lm head uses `vocab_size - 1` tokens, so the `NoBadWordsLogitsProcessor` used + # by prompt lookup may fail + "imagegpt", + ] + if any(model_name in model_class.__name__.lower() for model_name in old_models): + self.skipTest(reason="Won't fix: old model") if any( model_name in model_class.__name__.lower() for model_name in [ diff --git a/tests/models/bark/test_modeling_bark.py b/tests/models/bark/test_modeling_bark.py index 115e67d101e0..026dae1e8697 100644 --- a/tests/models/bark/test_modeling_bark.py +++ b/tests/models/bark/test_modeling_bark.py @@ -884,6 +884,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # if no output embeddings -> leave test if model.get_output_embeddings() is None: diff --git a/tests/models/chameleon/test_modeling_chameleon.py b/tests/models/chameleon/test_modeling_chameleon.py index ecf873182234..2f4c849a1e35 100644 --- a/tests/models/chameleon/test_modeling_chameleon.py +++ b/tests/models/chameleon/test_modeling_chameleon.py @@ -338,6 +338,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() curr_input_dict = copy.deepcopy(input_dict) # the below tests modify dict in-place _ = model(**curr_input_dict) # successful forward with no modifications diff --git a/tests/models/colpali/test_modeling_colpali.py b/tests/models/colpali/test_modeling_colpali.py index e051e431bfa8..f00566ccfc1e 100644 --- a/tests/models/colpali/test_modeling_colpali.py +++ b/tests/models/colpali/test_modeling_colpali.py @@ -173,6 +173,7 @@ def prepare_config_and_inputs_for_common(self): "input_ids": input_ids, "attention_mask": attention_mask, "labels": input_ids, + "token_type_ids": torch.zeros_like(input_ids), } return config, inputs_dict @@ -189,6 +190,7 @@ class ColPaliForRetrievalModelTest(ModelTesterMixin, unittest.TestCase): test_pruning = False test_resize_embeddings = True test_head_masking = False + additional_model_inputs = ["token_type_ids"] def setUp(self): self.model_tester = ColPaliForRetrievalModelTester(self) diff --git a/tests/models/gemma3/test_modeling_gemma3.py b/tests/models/gemma3/test_modeling_gemma3.py index 95c33187eb7c..ed63fd2410c9 100644 --- a/tests/models/gemma3/test_modeling_gemma3.py +++ b/tests/models/gemma3/test_modeling_gemma3.py @@ -282,6 +282,7 @@ class Gemma3Vision2TextModelTest(ModelTesterMixin, GenerationTesterMixin, unitte test_missing_keys = False _is_stateful = True model_split_percents = [0.5, 0.6] + additional_model_inputs = ["token_type_ids"] # MP works but offload doesn't work when the SigLIP MultiheadAttention is offloaded # TODO: One potential solution would be to add to set preload_module_classes = ["SiglipMultiheadAttentionPoolingHead"] diff --git a/tests/models/helium/test_modeling_helium.py b/tests/models/helium/test_modeling_helium.py index 61639ac48918..67a9734fd866 100644 --- a/tests/models/helium/test_modeling_helium.py +++ b/tests/models/helium/test_modeling_helium.py @@ -24,8 +24,7 @@ torch_device, ) -from ...test_configuration_common import ConfigTester -from ..gemma.test_modeling_gemma import GemmaModelTest, GemmaModelTester +from ...causal_lm_tester import CausalLMModelTest, CausalLMModelTester if is_torch_available(): @@ -39,17 +38,17 @@ ) -class HeliumModelTester(GemmaModelTester): +class HeliumModelTester(CausalLMModelTester): if is_torch_available(): config_class = HeliumConfig - model_class = HeliumModel - for_causal_lm_class = HeliumForCausalLM - for_sequence_class = HeliumForSequenceClassification - for_token_class = HeliumForTokenClassification + base_model_class = HeliumModel + causal_lm_class = HeliumForCausalLM + sequence_classification_class = HeliumForSequenceClassification + token_classification_class = HeliumForTokenClassification @require_torch -class HeliumModelTest(GemmaModelTest, unittest.TestCase): +class HeliumModelTest(CausalLMModelTest, unittest.TestCase): all_model_classes = ( (HeliumModel, HeliumForCausalLM, HeliumForSequenceClassification, HeliumForTokenClassification) if is_torch_available() @@ -66,15 +65,12 @@ class HeliumModelTest(GemmaModelTest, unittest.TestCase): if is_torch_available() else {} ) + model_tester_class = HeliumModelTester test_headmasking = False test_pruning = False _is_stateful = True model_split_percents = [0.5, 0.6] - def setUp(self): - self.model_tester = HeliumModelTester(self) - self.config_tester = ConfigTester(self, config_class=HeliumConfig, hidden_size=37) - @slow # @require_torch_gpu diff --git a/tests/models/idefics2/test_modeling_idefics2.py b/tests/models/idefics2/test_modeling_idefics2.py index 6603f3604e0b..6c1f1686515c 100644 --- a/tests/models/idefics2/test_modeling_idefics2.py +++ b/tests/models/idefics2/test_modeling_idefics2.py @@ -297,6 +297,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # if no output embeddings -> leave test if model.get_output_embeddings() is None: @@ -480,6 +481,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # Check that resizing the token embeddings with a larger vocab size increases the model's vocab size model_vocab_size = config.text_config.vocab_size diff --git a/tests/models/idefics3/test_modeling_idefics3.py b/tests/models/idefics3/test_modeling_idefics3.py index fe05eda8c0fb..73417318658b 100644 --- a/tests/models/idefics3/test_modeling_idefics3.py +++ b/tests/models/idefics3/test_modeling_idefics3.py @@ -287,6 +287,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # if no output embeddings -> leave test if model.get_output_embeddings() is None: @@ -446,6 +447,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # Check that resizing the token embeddings with a larger vocab size increases the model's vocab size model_vocab_size = config.text_config.vocab_size diff --git a/tests/models/llava/test_modeling_llava.py b/tests/models/llava/test_modeling_llava.py index 7892be3171b1..d1e599fa4e00 100644 --- a/tests/models/llava/test_modeling_llava.py +++ b/tests/models/llava/test_modeling_llava.py @@ -206,6 +206,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() curr_input_dict = copy.deepcopy(input_dict) # in=place modifications further _ = model(**curr_input_dict) # successful forward with no modifications diff --git a/tests/models/llava_next/test_modeling_llava_next.py b/tests/models/llava_next/test_modeling_llava_next.py index 0c5c771b55c9..a476d34ffc39 100644 --- a/tests/models/llava_next/test_modeling_llava_next.py +++ b/tests/models/llava_next/test_modeling_llava_next.py @@ -231,6 +231,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() curr_input_dict = copy.deepcopy(input_dict) # in=place modifications further _ = model(**curr_input_dict) # successful forward with no modifications diff --git a/tests/models/llava_next_video/test_modeling_llava_next_video.py b/tests/models/llava_next_video/test_modeling_llava_next_video.py index 3230b50e7299..332fdfa59e75 100644 --- a/tests/models/llava_next_video/test_modeling_llava_next_video.py +++ b/tests/models/llava_next_video/test_modeling_llava_next_video.py @@ -244,6 +244,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() curr_input_dict = copy.deepcopy(input_dict) # in=place modifications further _ = model(**curr_input_dict) # successful forward with no modifications diff --git a/tests/models/moonshine/test_modeling_moonshine.py b/tests/models/moonshine/test_modeling_moonshine.py index 6218c8fbd97a..1924be5b0713 100644 --- a/tests/models/moonshine/test_modeling_moonshine.py +++ b/tests/models/moonshine/test_modeling_moonshine.py @@ -398,6 +398,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # if no output embeddings -> leave test if model.get_output_embeddings() is None: diff --git a/tests/models/paligemma/test_modeling_paligemma.py b/tests/models/paligemma/test_modeling_paligemma.py index 21b9b8a4711e..6a02a3f31e0e 100644 --- a/tests/models/paligemma/test_modeling_paligemma.py +++ b/tests/models/paligemma/test_modeling_paligemma.py @@ -189,6 +189,7 @@ class PaliGemmaForConditionalGenerationModelTest(ModelTesterMixin, GenerationTes else () ) pipeline_model_mapping = {"image-text-to-text": PaliGemmaForConditionalGeneration} + additional_model_inputs = ["token_type_ids"] fx_compatible = False test_pruning = False test_torchscript = False @@ -209,6 +210,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() curr_input_dict = copy.deepcopy(input_dict) # in=place modifications further _ = model(**curr_input_dict) # successful forward with no modifications @@ -555,7 +557,7 @@ def test_integration_detection_bug(self): { ("rocm", (9, 5)): "detect shoe\n shoe", (None, None): "detect shoe\n shoe", - ("cuda", 8): "detect shoe\n shoe", + ("cuda", 8): "detect shoe\n shoe", } ) # fmt: skip EXPECTED_DECODED_TEXT = expected_decoded_texts.get_expectation() diff --git a/tests/models/paligemma2/test_modeling_paligemma2.py b/tests/models/paligemma2/test_modeling_paligemma2.py index a33f03194f8a..ffb61c2146b2 100644 --- a/tests/models/paligemma2/test_modeling_paligemma2.py +++ b/tests/models/paligemma2/test_modeling_paligemma2.py @@ -16,9 +16,6 @@ import copy import unittest -import pytest -from parameterized import parameterized - from transformers import ( PaliGemmaConfig, PaliGemmaForConditionalGeneration, @@ -192,6 +189,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() curr_input_dict = copy.deepcopy(input_dict) # in=place modifications further _ = model(**curr_input_dict) # successful forward with no modifications @@ -271,12 +269,6 @@ def test_feed_forward_chunking(self): def test_flash_attention_2_padding_matches_padding_free_with_position_ids(self): pass - @parameterized.expand([("random",), ("same",)]) - @pytest.mark.generate - @unittest.skip("Paligemma2 does not seem to be compatible with assisted decoding") - def test_assisted_decoding_matches_greedy_search(self, assistant_type): - pass - @unittest.skip("Paligemma position ids are 1 indexed") def test_eager_padding_matches_padding_free_with_position_ids(self): pass diff --git a/tests/models/perception_lm/test_modeling_perception_lm.py b/tests/models/perception_lm/test_modeling_perception_lm.py index 0c927b82d12b..79c74c93a682 100644 --- a/tests/models/perception_lm/test_modeling_perception_lm.py +++ b/tests/models/perception_lm/test_modeling_perception_lm.py @@ -253,6 +253,7 @@ def test_mismatching_num_image_tokens(self): if model_class == PerceptionLMModel: continue model = model_class(config).to(torch_device) + model.eval() _ = model(**input_dict) # successful forward with no modifications # remove one image but leave the image token in text diff --git a/tests/models/pix2struct/test_modeling_pix2struct.py b/tests/models/pix2struct/test_modeling_pix2struct.py index cb8b8db97397..0acda0ddac3d 100644 --- a/tests/models/pix2struct/test_modeling_pix2struct.py +++ b/tests/models/pix2struct/test_modeling_pix2struct.py @@ -627,6 +627,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # if no output embeddings -> leave test if model.get_output_embeddings() is None: diff --git a/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py b/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py index cb2e31867194..6cf1b0fa1078 100644 --- a/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py +++ b/tests/models/qwen2_5_vl/test_modeling_qwen2_5_vl.py @@ -242,6 +242,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() _ = model(**input_dict) # successful forward with no modifications curr_input_dict = copy.deepcopy(input_dict) diff --git a/tests/models/qwen2_vl/test_modeling_qwen2_vl.py b/tests/models/qwen2_vl/test_modeling_qwen2_vl.py index 37f315b5dc38..898b98658ecc 100644 --- a/tests/models/qwen2_vl/test_modeling_qwen2_vl.py +++ b/tests/models/qwen2_vl/test_modeling_qwen2_vl.py @@ -234,6 +234,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() curr_input_dict = copy.deepcopy(input_dict) _ = model(**curr_input_dict) # successful forward with no modifications diff --git a/tests/models/qwen3_vl/test_modeling_qwen3_vl.py b/tests/models/qwen3_vl/test_modeling_qwen3_vl.py index 6074efecf4a9..888d9eb76618 100644 --- a/tests/models/qwen3_vl/test_modeling_qwen3_vl.py +++ b/tests/models/qwen3_vl/test_modeling_qwen3_vl.py @@ -201,6 +201,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() _ = model(**input_dict) # successful forward with no modifications curr_input_dict = copy.deepcopy(input_dict) diff --git a/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py b/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py index 411845fcbfa5..d5e971041931 100644 --- a/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py +++ b/tests/models/qwen3_vl_moe/test_modeling_qwen3_vl_moe.py @@ -202,6 +202,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() _ = model(**input_dict) # successful forward with no modifications curr_input_dict = copy.deepcopy(input_dict) diff --git a/tests/models/smolvlm/test_modeling_smolvlm.py b/tests/models/smolvlm/test_modeling_smolvlm.py index 7856afd2c9eb..dd449672551b 100644 --- a/tests/models/smolvlm/test_modeling_smolvlm.py +++ b/tests/models/smolvlm/test_modeling_smolvlm.py @@ -284,6 +284,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # if no output embeddings -> leave test if model.get_output_embeddings() is None: @@ -475,6 +476,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # Check that resizing the token embeddings with a larger vocab size increases the model's vocab size model_vocab_size = config.text_config.vocab_size diff --git a/tests/models/speech_to_text/test_modeling_speech_to_text.py b/tests/models/speech_to_text/test_modeling_speech_to_text.py index 0ebbc6631eca..f8ac098f9296 100644 --- a/tests/models/speech_to_text/test_modeling_speech_to_text.py +++ b/tests/models/speech_to_text/test_modeling_speech_to_text.py @@ -581,6 +581,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # if no output embeddings -> leave test if model.get_output_embeddings() is None: diff --git a/tests/models/speecht5/test_modeling_speecht5.py b/tests/models/speecht5/test_modeling_speecht5.py index 6d10256dbd2d..654c397c951e 100644 --- a/tests/models/speecht5/test_modeling_speecht5.py +++ b/tests/models/speecht5/test_modeling_speecht5.py @@ -625,6 +625,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # if no output embeddings -> leave test if model.get_output_embeddings() is None: diff --git a/tests/models/video_llava/test_modeling_video_llava.py b/tests/models/video_llava/test_modeling_video_llava.py index 4c9e4ff3ceb5..8bdb87884373 100644 --- a/tests/models/video_llava/test_modeling_video_llava.py +++ b/tests/models/video_llava/test_modeling_video_llava.py @@ -353,6 +353,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() curr_input_dict = copy.deepcopy(input_dict) _ = model(**curr_input_dict) # successful forward with no modifications diff --git a/tests/models/vipllava/test_modeling_vipllava.py b/tests/models/vipllava/test_modeling_vipllava.py index 655809775564..bf7b43dd4580 100644 --- a/tests/models/vipllava/test_modeling_vipllava.py +++ b/tests/models/vipllava/test_modeling_vipllava.py @@ -202,6 +202,7 @@ def test_mismatching_num_image_tokens(self): config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() for model_class in self.all_model_classes: model = model_class(config).to(torch_device) + model.eval() curr_input_dict = copy.deepcopy(input_dict) # in=place modifications further _ = model(**curr_input_dict) # successful forward with no modifications diff --git a/tests/models/whisper/test_modeling_whisper.py b/tests/models/whisper/test_modeling_whisper.py index 3325d29f16aa..83fbfce52b4b 100644 --- a/tests/models/whisper/test_modeling_whisper.py +++ b/tests/models/whisper/test_modeling_whisper.py @@ -810,6 +810,7 @@ def test_resize_embeddings_untied(self): for model_class in self.all_model_classes: config = copy.deepcopy(original_config) model = model_class(config).to(torch_device) + model.eval() # if no output embeddings -> leave test if model.get_output_embeddings() is None: diff --git a/tests/test_modeling_common.py b/tests/test_modeling_common.py index d0b967578732..a8493f87d8e8 100755 --- a/tests/test_modeling_common.py +++ b/tests/test_modeling_common.py @@ -2372,6 +2372,7 @@ def test_resize_embeddings_untied(self): model = model_class(config) else: model = model_class(config).to(torch_device) + model.eval() # if no output embeddings -> leave test if model.get_output_embeddings() is None: From 78c6f7aecfcfd1593902fcc47d31dadebbd62da6 Mon Sep 17 00:00:00 2001 From: Joao Gante Date: Tue, 23 Sep 2025 18:07:06 +0100 Subject: [PATCH 171/204] [tests] gpt2 + `CausalLMModelTester` (#41003) * tmp commit * tmp commit * tmp commit * rm old GPT2ModelTester * nit bug * add facilities for encoder-decoder tests; add comments on ALL overwrites/extra fns * vision_encoder_decoder --- tests/causal_lm_tester.py | 21 + tests/models/gpt2/test_modeling_gpt2.py | 843 ++++++------------ .../test_modeling_vision_encoder_decoder.py | 32 +- 3 files changed, 281 insertions(+), 615 deletions(-) diff --git a/tests/causal_lm_tester.py b/tests/causal_lm_tester.py index 4757d4b69c6c..790e4d32cee0 100644 --- a/tests/causal_lm_tester.py +++ b/tests/causal_lm_tester.py @@ -316,6 +316,27 @@ def test_token_classification_model(self): (self.model_tester.batch_size, self.model_tester.seq_length, self.model_tester.num_labels), ) + def test_question_answering_model(self): + if self.model_tester.question_answering_class is None: + self.skipTest("Model does not support question answering") + 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) + model = self.model_tester.question_answering_class(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=attention_mask) + self.assertEqual( + result.start_logits.shape, + (self.model_tester.batch_size, self.model_tester.seq_length), + ) + self.assertEqual( + result.end_logits.shape, + (self.model_tester.batch_size, self.model_tester.seq_length), + ) + @parameterized.expand([("linear",), ("dynamic",), ("yarn",)]) def test_model_rope_scaling_from_config(self, scaling_type): """ diff --git a/tests/models/gpt2/test_modeling_gpt2.py b/tests/models/gpt2/test_modeling_gpt2.py index ae37e2432ddb..737ccb7bb8f1 100644 --- a/tests/models/gpt2/test_modeling_gpt2.py +++ b/tests/models/gpt2/test_modeling_gpt2.py @@ -12,12 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import math import unittest import pytest -from transformers import DynamicCache, GPT2Config, is_torch_available +from transformers import GPT2Config, is_torch_available from transformers.testing_utils import ( Expectations, cleanup, @@ -28,10 +27,8 @@ torch_device, ) -from ...generation.test_utils import GenerationTesterMixin -from ...test_configuration_common import ConfigTester -from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask -from ...test_pipeline_mixin import PipelineTesterMixin +from ...causal_lm_tester import CausalLMModelTest, CausalLMModelTester +from ...test_modeling_common import floats_tensor, ids_tensor if is_torch_available(): @@ -48,149 +45,92 @@ ) -class GPT2ModelTester: +class GPT2ModelTester(CausalLMModelTester): + if is_torch_available(): + config_class = GPT2Config + base_model_class = GPT2Model + causal_lm_class = GPT2LMHeadModel + sequence_classification_class = GPT2ForSequenceClassification + token_classification_class = GPT2ForTokenClassification + question_answering_class = GPT2ForQuestionAnswering + def __init__( self, parent, - batch_size=14, - seq_length=7, - is_training=True, use_token_type_ids=True, - use_input_mask=True, - use_labels=True, - use_mc_token_ids=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, + **kwargs, ): - self.parent = parent - self.batch_size = batch_size - self.seq_length = seq_length - self.is_training = is_training - self.use_token_type_ids = use_token_type_ids - self.use_input_mask = use_input_mask - self.use_labels = use_labels - self.use_mc_token_ids = use_mc_token_ids - 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 + super().__init__(parent, use_token_type_ids=use_token_type_ids, **kwargs) self.num_choices = num_choices - self.scope = None - self.bos_token_id = vocab_size - 1 - self.eos_token_id = vocab_size - 1 - self.pad_token_id = vocab_size - 1 - - def get_large_model_config(self): - return GPT2Config.from_pretrained("openai-community/gpt2") def prepare_config_and_inputs( - self, gradient_checkpointing=False, scale_attn_by_inverse_layer_idx=False, reorder_and_upcast_attn=False + self, extra_inputs=False, scale_attn_by_inverse_layer_idx=False, reorder_and_upcast_attn=False ): - 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) + # Overwritten: `GPT2DoubleHeadsModel` uses extra inputs + (config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels) = ( + super().prepare_config_and_inputs() + ) - mc_token_ids = None - if self.use_mc_token_ids: + if extra_inputs: mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) - - 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) + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + config_and_inputs = ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + else: + config_and_inputs = ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) config = self.get_config( - gradient_checkpointing=gradient_checkpointing, scale_attn_by_inverse_layer_idx=scale_attn_by_inverse_layer_idx, reorder_and_upcast_attn=reorder_and_upcast_attn, ) - head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + return config_and_inputs - return ( - config, - input_ids, - input_mask, - head_mask, - token_type_ids, - mc_token_ids, - sequence_labels, - token_labels, - choice_labels, - ) - - def get_config( - self, gradient_checkpointing=False, scale_attn_by_inverse_layer_idx=False, reorder_and_upcast_attn=False - ): - return GPT2Config( - vocab_size=self.vocab_size, - n_embd=self.hidden_size, - n_layer=self.num_hidden_layers, - n_head=self.num_attention_heads, - n_inner=self.intermediate_size, - activation_function=self.hidden_act, - resid_pdrop=self.hidden_dropout_prob, - attn_pdrop=self.attention_probs_dropout_prob, - n_positions=self.max_position_embeddings, - type_vocab_size=self.type_vocab_size, - initializer_range=self.initializer_range, - use_cache=True, - bos_token_id=self.bos_token_id, - eos_token_id=self.eos_token_id, - pad_token_id=self.pad_token_id, - gradient_checkpointing=gradient_checkpointing, - scale_attn_by_inverse_layer_idx=scale_attn_by_inverse_layer_idx, - reorder_and_upcast_attn=reorder_and_upcast_attn, - ) - - def get_pipeline_config(self): - config = self.get_config() - config.vocab_size = 300 + def get_config(self, scale_attn_by_inverse_layer_idx=False, reorder_and_upcast_attn=False): + # Overwritten: `GPT2Config` has extra flags and we want to test them + config = super().get_config() + config.scale_attn_by_inverse_layer_idx = scale_attn_by_inverse_layer_idx + config.reorder_and_upcast_attn = reorder_and_upcast_attn return config + def prepare_config_and_inputs_for_common(self): + # Overwritten: we want `token_type_ids` as part of the common inputs + config_and_inputs = self.prepare_config_and_inputs(extra_inputs=True) + config, input_ids, _, head_mask, token_type_ids, _, _, _, _ = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "head_mask": head_mask} + return config, inputs_dict + def prepare_config_and_inputs_for_decoder(self): + # Extra function: used in `encoder_decoder` tests ( config, input_ids, input_mask, head_mask, token_type_ids, - mc_token_ids, + _, sequence_labels, token_labels, choice_labels, - ) = self.prepare_config_and_inputs() + ) = self.prepare_config_and_inputs(extra_inputs=True) encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) @@ -208,283 +148,9 @@ def prepare_config_and_inputs_for_decoder(self): encoder_attention_mask, ) - def create_and_check_gpt2_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): - model = GPT2Model(config=config) - model.to(torch_device) - model.eval() - - result = model(input_ids, token_type_ids=token_type_ids, head_mask=head_mask) - result = model(input_ids, token_type_ids=token_type_ids) - result = model(input_ids) - - self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) - self.parent.assertEqual(len(result.past_key_values), config.n_layer) - - def create_and_check_gpt2_model_past(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): - model = GPT2Model(config=config) - model.to(torch_device) - model.eval() - - # first forward pass - outputs = model(input_ids, token_type_ids=token_type_ids, use_cache=True) - outputs_use_cache_conf = model(input_ids, token_type_ids=token_type_ids) - outputs_no_past = model(input_ids, token_type_ids=token_type_ids, use_cache=False) - - self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) - self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) - - output, past = outputs.to_tuple() - - # create hypothetical next token and extent to next_input_ids - next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) - next_token_types = ids_tensor([self.batch_size, 1], self.type_vocab_size) - - # append to next input_ids and token_type_ids - next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) - next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) - - output_from_no_past = model(next_input_ids, token_type_ids=next_token_type_ids)["last_hidden_state"] - output_from_past = model(next_tokens, token_type_ids=next_token_types, past_key_values=past)[ - "last_hidden_state" - ] - - # select random slice - 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() - - # test that outputs are equal for slice - self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) - - def create_and_check_gpt2_model_attention_mask_past( - self, config, input_ids, input_mask, head_mask, token_type_ids, *args - ): - model = GPT2Model(config=config) - model.to(torch_device) - model.eval() - - # create attention mask - 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 - - # first forward pass - output, past = model(input_ids, attention_mask=attn_mask).to_tuple() - - # create hypothetical next token and extent to next_input_ids - next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) - - # change a random masked slice from input_ids - 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 - - # append to next input_ids and attn_mask - 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, - ) - - # get two different outputs - 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"] - - # select random slice - 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() - - # test that outputs are equal for slice - self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) - - def create_and_check_gpt2_model_past_large_inputs( - self, config, input_ids, input_mask, head_mask, token_type_ids, *args - ): - model = GPT2Model(config=config) - model.to(torch_device) - model.eval() - - # first forward pass - outputs = model(input_ids, token_type_ids=token_type_ids, attention_mask=input_mask, use_cache=True) - - output, past = outputs.to_tuple() - - # create hypothetical next token and extent to next_input_ids - next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) - next_token_types = ids_tensor([self.batch_size, 3], self.type_vocab_size) - next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) - - # append to next input_ids and token_type_ids - next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) - next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) - next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) - - output_from_no_past = model( - next_input_ids, token_type_ids=next_token_type_ids, attention_mask=next_attention_mask - )["last_hidden_state"] - output_from_past = model( - next_tokens, token_type_ids=next_token_types, attention_mask=next_attention_mask, past_key_values=past - )["last_hidden_state"] - self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1]) - - # select random slice - 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() - - # test that outputs are equal for slice - self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) - - def create_and_check_lm_head_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): - model = GPT2LMHeadModel(config) - model.to(torch_device) - model.eval() - - result = model(input_ids, token_type_ids=token_type_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)) - - def create_and_check_forward_and_backwards( - self, config, input_ids, input_mask, head_mask, token_type_ids, *args, gradient_checkpointing=False - ): - model = GPT2LMHeadModel(config) - model.to(torch_device) - if gradient_checkpointing: - model.gradient_checkpointing_enable() - - result = model(input_ids, token_type_ids=token_type_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_double_lm_head_model( - self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, *args - ): - model = GPT2DoubleHeadsModel(config) - model.to(torch_device) - model.eval() - - multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() - multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() - multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() - - inputs = { - "input_ids": multiple_choice_inputs_ids, - "mc_token_ids": mc_token_ids, - "attention_mask": multiple_choice_input_mask, - "token_type_ids": multiple_choice_token_type_ids, - "labels": multiple_choice_inputs_ids, - } - - result = model(**inputs) - self.parent.assertEqual(result.loss.shape, ()) - self.parent.assertEqual( - result.logits.shape, (self.batch_size, self.num_choices, self.seq_length, self.vocab_size) - ) - self.parent.assertEqual(result.mc_logits.shape, (self.batch_size, self.num_choices)) - - def create_and_check_gpt2_for_question_answering( - self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args - ): - config.num_labels = self.num_labels - model = GPT2ForQuestionAnswering(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.start_logits.shape, (self.batch_size, self.seq_length)) - self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) - - def create_and_check_gpt2_for_sequence_classification( - self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args - ): - config.num_labels = self.num_labels - model = GPT2ForSequenceClassification(config) - model.to(torch_device) - model.eval() - result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) - self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) - - def create_and_check_gpt2_for_token_classification( - self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args - ): - config.num_labels = self.num_labels - model = GPT2ForTokenClassification(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 create_and_check_gpt2_weight_initialization(self, config, *args): - model = GPT2Model(config) - model_std = model.config.initializer_range / math.sqrt(2 * model.config.n_layer) - for key in model.state_dict(): - 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_cached_forward_with_and_without_attention_mask(self, config, input_ids, *args): - # Relevant issue: https://github.com/huggingface/transformers/issues/31943 - model = GPT2Model(config) - model.to(torch_device) - model.eval() - - # We want this for SDPA, eager works with a `None` attention mask - assert model.config._attn_implementation == "sdpa", ( - "This test assumes the model to have the SDPA implementation for its attention calculations." - ) - - # Prepare cache and non_cache input, needs a full attention mask - cached_len = input_ids.shape[-1] // 2 - input_mask = torch.ones(size=input_ids.size()).to(torch_device) - cache_inputs = {"input_ids": input_ids[:, :cached_len], "attention_mask": input_mask[:, :cached_len]} - non_cache_inputs = {"input_ids": input_ids[:, cached_len:], "attention_mask": input_mask} - - # Cached forward once with the attention mask provided and the other time without it (which should assume full attention) - cache_outputs = model(**cache_inputs) - # Caches are mutable (unlike legacy tuples), so we need to copy them before using multiple times - pkv_copy = DynamicCache(config=config) - pkv_copy.update( - cache_outputs.past_key_values.layers[0].keys, cache_outputs.past_key_values.layers[0].values, 0 - ) - pkv_copy.update( - cache_outputs.past_key_values.layers[1].keys, cache_outputs.past_key_values.layers[1].values, 1 - ) - full_outputs_with_attention_mask = model(**non_cache_inputs, past_key_values=pkv_copy).last_hidden_state - full_outputs_without_attention_mask = model( - non_cache_inputs["input_ids"], past_key_values=cache_outputs.past_key_values - ).last_hidden_state - - self.parent.assertTrue( - torch.allclose(full_outputs_with_attention_mask, full_outputs_without_attention_mask, atol=1e-5) - ) - - def prepare_config_and_inputs_for_common(self): - config_and_inputs = self.prepare_config_and_inputs() - - ( - config, - input_ids, - input_mask, - head_mask, - token_type_ids, - mc_token_ids, - sequence_labels, - token_labels, - choice_labels, - ) = config_and_inputs - - inputs_dict = { - "input_ids": input_ids, - "token_type_ids": token_type_ids, - "head_mask": head_mask, - } - - return config, inputs_dict - @require_torch -class GPT2ModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): +class GPT2ModelTest(CausalLMModelTest, unittest.TestCase): all_model_classes = ( ( GPT2Model, @@ -513,9 +179,10 @@ class GPT2ModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin fx_compatible = False # Broken by attention refactor cc @Cyrilvallez test_missing_keys = False test_model_parallel = True + model_tester_class = GPT2ModelTester - # special case for DoubleHeads model def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + # Overwritten: special case for DoubleHeads model inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) if return_labels: @@ -537,220 +204,91 @@ def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): ) return inputs_dict - def setUp(self): - self.model_tester = GPT2ModelTester(self) - self.config_tester = ConfigTester(self, config_class=GPT2Config, n_embd=37) - - def tearDown(self): - super().tearDown() - # clean-up as much as possible GPU memory occupied by PyTorch - cleanup(torch_device) - - def test_config(self): - self.config_tester.run_common_tests() - - def test_gpt2_model(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_gpt2_model(*config_and_inputs) - - def test_gpt2_model_past(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_gpt2_model_past(*config_and_inputs) - - def test_gpt2_model_att_mask_past(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_gpt2_model_attention_mask_past(*config_and_inputs) - - def test_gpt2_model_past_large_inputs(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_gpt2_model_past_large_inputs(*config_and_inputs) - - def test_gpt2_lm_head_model(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_lm_head_model(*config_and_inputs) - def test_gpt2_double_lm_head_model(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_double_lm_head_model(*config_and_inputs) - - def test_gpt2_question_answering_model(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_gpt2_for_question_answering(*config_and_inputs) - - def test_gpt2_sequence_classification_model(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_gpt2_for_sequence_classification(*config_and_inputs) - - def test_gpt2_token_classification_model(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_gpt2_for_token_classification(*config_and_inputs) - - def test_gpt2_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_gpt2_scale_attn_by_inverse_layer_idx(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs(scale_attn_by_inverse_layer_idx=True) - self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs) - - def test_gpt2_reorder_and_upcast_attn(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs(reorder_and_upcast_attn=True) - self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs) - - def test_gpt2_weight_initialization(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_gpt2_weight_initialization(*config_and_inputs) - - def test_cached_forward_with_and_without_attention_mask(self): - config_and_inputs = self.model_tester.prepare_config_and_inputs() - self.model_tester.create_and_check_cached_forward_with_and_without_attention_mask(*config_and_inputs) - - @unittest.skip( - reason="This architecture seem to not compute gradients properly when using GC, check: https://github.com/huggingface/transformers/pull/27124" - ) - def test_training_gradient_checkpointing(self): - pass - - @unittest.skip( - reason="This architecture seem to not compute gradients properly when using GC, check: https://github.com/huggingface/transformers/pull/27124" - ) - def test_training_gradient_checkpointing_use_reentrant(self): - pass - - @unittest.skip( - reason="This architecture seem to not compute gradients properly when using GC, check: https://github.com/huggingface/transformers/pull/27124" - ) - def test_training_gradient_checkpointing_use_reentrant_false(self): - pass - - @slow - def test_batch_generation(self): - model = GPT2LMHeadModel.from_pretrained("openai-community/gpt2") + # extra test: model-specific class + config_and_inputs = self.model_tester.prepare_config_and_inputs(extra_inputs=True) + config, input_ids, input_mask, _, token_type_ids, mc_token_ids, _, _, _ = config_and_inputs + model = GPT2DoubleHeadsModel(config) model.to(torch_device) - tokenizer = GPT2Tokenizer.from_pretrained("openai-community/gpt2") - - tokenizer.padding_side = "left" - - # Define PAD Token = EOS Token = 50256 - tokenizer.pad_token = tokenizer.eos_token - model.config.pad_token_id = model.config.eos_token_id - - # use different length sentences to test batching - sentences = [ - "Hello, my dog is a little", - "Today, I", - ] + model.eval() - inputs = tokenizer(sentences, return_tensors="pt", padding=True) - input_ids = inputs["input_ids"].to(torch_device) - token_type_ids = torch.cat( - [ - input_ids.new_full((input_ids.shape[0], input_ids.shape[1] - 1), 0), - input_ids.new_full((input_ids.shape[0], 1), 500), - ], - dim=-1, + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.model_tester.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.model_tester.num_choices, -1).contiguous() + multiple_choice_token_type_ids = ( + token_type_ids.unsqueeze(1).expand(-1, self.model_tester.num_choices, -1).contiguous() ) - outputs = model.generate( - input_ids=input_ids, - attention_mask=inputs["attention_mask"].to(torch_device), - max_length=20, - ) + inputs = { + "input_ids": multiple_choice_inputs_ids, + "mc_token_ids": mc_token_ids, + "attention_mask": multiple_choice_input_mask, + "token_type_ids": multiple_choice_token_type_ids, + "labels": multiple_choice_inputs_ids, + } - outputs_tt = model.generate( - input_ids=input_ids, - attention_mask=inputs["attention_mask"].to(torch_device), - token_type_ids=token_type_ids, - max_length=20, + result = model(**inputs) + self.assertEqual(result.loss.shape, ()) + self.assertEqual( + result.logits.shape, + ( + self.model_tester.batch_size, + self.model_tester.num_choices, + self.model_tester.seq_length, + self.model_tester.vocab_size, + ), ) + self.assertEqual(result.mc_logits.shape, (self.model_tester.batch_size, self.model_tester.num_choices)) - inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device) - output_non_padded = model.generate(input_ids=inputs_non_padded, max_length=20) - - num_paddings = inputs_non_padded.shape[-1] - inputs["attention_mask"][-1].long().sum().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) - batch_out_sentence_tt = tokenizer.batch_decode(outputs_tt, 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 of a mess. I'm not sure if he's going", - "Today, I'm going to be doing a lot of research on this. I", - ] - self.assertListEqual(expected_output_sentence, batch_out_sentence) - self.assertTrue(batch_out_sentence_tt != batch_out_sentence) # token_type_ids should change output - self.assertListEqual(expected_output_sentence, [non_padded_sentence, padded_sentence]) + def test_gpt2_scale_attn_by_inverse_layer_idx(self): + # extra test: model-specific flag + config_and_inputs = self.model_tester.prepare_config_and_inputs(scale_attn_by_inverse_layer_idx=True) + config, input_ids, token_type_ids, _, _, _, _ = config_and_inputs - @slow - def test_batch_generation_2heads(self): - model = GPT2DoubleHeadsModel.from_pretrained("openai-community/gpt2") + model = GPT2LMHeadModel(config) model.to(torch_device) - tokenizer = GPT2Tokenizer.from_pretrained("openai-community/gpt2") - - tokenizer.padding_side = "left" - - # This tokenizer has no pad token, so we have to set it in some way - # Define PAD Token = EOS Token = 50256 - tokenizer.pad_token = tokenizer.eos_token - model.config.pad_token_id = model.config.eos_token_id - - # use different length sentences to test batching - 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) - token_type_ids = torch.cat( - [ - input_ids.new_full((input_ids.shape[0], input_ids.shape[1] - 1), 0), - input_ids.new_full((input_ids.shape[0], 1), 500), - ], - dim=-1, + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.assertEqual(result.loss.shape, ()) + self.assertEqual( + result.logits.shape, + (self.model_tester.batch_size, self.model_tester.seq_length, self.model_tester.vocab_size), ) + result.loss.backward() - outputs = model.generate( - input_ids=input_ids, - attention_mask=inputs["attention_mask"].to(torch_device), - max_length=20, - ) + def test_gpt2_reorder_and_upcast_attn(self): + # extra test: model-specific flag + config_and_inputs = self.model_tester.prepare_config_and_inputs(reorder_and_upcast_attn=True) + config, input_ids, token_type_ids, _, _, _, _ = config_and_inputs - outputs_tt = model.generate( - input_ids=input_ids, - attention_mask=inputs["attention_mask"].to(torch_device), - token_type_ids=token_type_ids, - max_length=20, + model = GPT2LMHeadModel(config) + model.to(torch_device) + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.assertEqual(result.loss.shape, ()) + self.assertEqual( + result.logits.shape, + (self.model_tester.batch_size, self.model_tester.seq_length, self.model_tester.vocab_size), ) + result.loss.backward() - inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device) - output_non_padded = model.generate(input_ids=inputs_non_padded, max_length=20) - - num_paddings = inputs_non_padded.shape[-1] - inputs["attention_mask"][-1].long().sum().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) - batch_out_sentence_tt = tokenizer.batch_decode(outputs_tt, 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) + def test_training_gradient_checkpointing(self): + # overwritten: GPT2DoubleHeadsModel fails this test, non-standard class + self.original_all_model_classes = self.all_model_classes + self.all_model_classes = (cls for cls in self.all_model_classes if cls.__name__ != "GPT2DoubleHeadsModel") + super().test_training_gradient_checkpointing() + self.all_model_classes = self.original_all_model_classes - expected_output_sentence = [ - "Hello, my dog is a little bit of a mess. I'm not sure if he's going", - "Today, I'm going to be doing a lot of research on this. I", - ] - self.assertListEqual(expected_output_sentence, batch_out_sentence) - self.assertTrue(batch_out_sentence_tt != batch_out_sentence) # token_type_ids should change output - self.assertListEqual(expected_output_sentence, [non_padded_sentence, padded_sentence]) + def test_training_gradient_checkpointing_use_reentrant(self): + # overwritten: GPT2DoubleHeadsModel fails this test, non-standard class + self.original_all_model_classes = self.all_model_classes + self.all_model_classes = (cls for cls in self.all_model_classes if cls.__name__ != "GPT2DoubleHeadsModel") + super().test_training_gradient_checkpointing_use_reentrant() + self.all_model_classes = self.original_all_model_classes - @slow - def test_model_from_pretrained(self): - model_name = "openai-community/gpt2" - model = GPT2Model.from_pretrained(model_name) - self.assertIsNotNone(model) + def test_training_gradient_checkpointing_use_reentrant_false(self): + # overwritten: GPT2DoubleHeadsModel fails this test, non-standard class + self.original_all_model_classes = self.all_model_classes + self.all_model_classes = (cls for cls in self.all_model_classes if cls.__name__ != "GPT2DoubleHeadsModel") + super().test_training_gradient_checkpointing_use_reentrant_false() + self.all_model_classes = self.original_all_model_classes @require_torch @@ -915,3 +453,126 @@ def test_flash_attn_2_generate_padding_left(self): self.assertListEqual(output_native, output_fa_2) self.assertListEqual(output_native, expected_output) + + @slow + def test_batch_generation(self): + model = GPT2LMHeadModel.from_pretrained("openai-community/gpt2") + model.to(torch_device) + tokenizer = GPT2Tokenizer.from_pretrained("openai-community/gpt2") + + tokenizer.padding_side = "left" + + # Define PAD Token = EOS Token = 50256 + tokenizer.pad_token = tokenizer.eos_token + model.config.pad_token_id = model.config.eos_token_id + + # use different length sentences to test batching + 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) + token_type_ids = torch.cat( + [ + input_ids.new_full((input_ids.shape[0], input_ids.shape[1] - 1), 0), + input_ids.new_full((input_ids.shape[0], 1), 500), + ], + dim=-1, + ) + + outputs = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + max_length=20, + ) + + outputs_tt = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + token_type_ids=token_type_ids, + max_length=20, + ) + + inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device) + output_non_padded = model.generate(input_ids=inputs_non_padded, max_length=20) + + num_paddings = inputs_non_padded.shape[-1] - inputs["attention_mask"][-1].long().sum().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) + batch_out_sentence_tt = tokenizer.batch_decode(outputs_tt, 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 of a mess. I'm not sure if he's going", + "Today, I'm going to be doing a lot of research on this. I", + ] + self.assertListEqual(expected_output_sentence, batch_out_sentence) + self.assertTrue(batch_out_sentence_tt != batch_out_sentence) # token_type_ids should change output + self.assertListEqual(expected_output_sentence, [non_padded_sentence, padded_sentence]) + + @slow + def test_batch_generation_2heads(self): + model = GPT2DoubleHeadsModel.from_pretrained("openai-community/gpt2") + model.to(torch_device) + tokenizer = GPT2Tokenizer.from_pretrained("openai-community/gpt2") + + tokenizer.padding_side = "left" + + # This tokenizer has no pad token, so we have to set it in some way + # Define PAD Token = EOS Token = 50256 + tokenizer.pad_token = tokenizer.eos_token + model.config.pad_token_id = model.config.eos_token_id + + # use different length sentences to test batching + 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) + token_type_ids = torch.cat( + [ + input_ids.new_full((input_ids.shape[0], input_ids.shape[1] - 1), 0), + input_ids.new_full((input_ids.shape[0], 1), 500), + ], + dim=-1, + ) + + outputs = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + max_length=20, + ) + + outputs_tt = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + token_type_ids=token_type_ids, + max_length=20, + ) + + inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device) + output_non_padded = model.generate(input_ids=inputs_non_padded, max_length=20) + + num_paddings = inputs_non_padded.shape[-1] - inputs["attention_mask"][-1].long().sum().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) + batch_out_sentence_tt = tokenizer.batch_decode(outputs_tt, 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 of a mess. I'm not sure if he's going", + "Today, I'm going to be doing a lot of research on this. I", + ] + self.assertListEqual(expected_output_sentence, batch_out_sentence) + self.assertTrue(batch_out_sentence_tt != batch_out_sentence) # token_type_ids should change output + self.assertListEqual(expected_output_sentence, [non_padded_sentence, padded_sentence]) diff --git a/tests/models/vision_encoder_decoder/test_modeling_vision_encoder_decoder.py b/tests/models/vision_encoder_decoder/test_modeling_vision_encoder_decoder.py index 2401a1e5fb15..8272b7e48fe4 100644 --- a/tests/models/vision_encoder_decoder/test_modeling_vision_encoder_decoder.py +++ b/tests/models/vision_encoder_decoder/test_modeling_vision_encoder_decoder.py @@ -906,19 +906,11 @@ def prepare_config_and_inputs(self): model_tester_encoder = ViTModelTester(self, batch_size=13) model_tester_decoder = GPT2ModelTester(self, batch_size=13, hidden_size=32, max_position_embeddings=512) encoder_config_and_inputs = model_tester_encoder.prepare_config_and_inputs() - decoder_config_and_inputs = model_tester_decoder.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester_decoder.prepare_config_and_inputs(extra_inputs=True) config, pixel_values, labels = encoder_config_and_inputs - ( - decoder_config, - decoder_input_ids, - decoder_attention_mask, - decoder_head_mask, - decoder_token_type_ids, - mc_token_ids, - sequence_labels, - token_labels, - choice_labels, - ) = decoder_config_and_inputs + decoder_config, decoder_input_ids, decoder_attention_mask, decoder_head_mask, _, _, _, _, _ = ( + decoder_config_and_inputs + ) # make sure that cross attention layers are added decoder_config.add_cross_attention = True @@ -1028,19 +1020,11 @@ def prepare_config_and_inputs(self): model_tester_encoder = DonutSwinModelTester(self, batch_size=13) model_tester_decoder = GPT2ModelTester(self, batch_size=13, hidden_size=32, max_position_embeddings=512) encoder_config_and_inputs = model_tester_encoder.prepare_config_and_inputs() - decoder_config_and_inputs = model_tester_decoder.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester_decoder.prepare_config_and_inputs(extra_inputs=True) config, pixel_values, labels = encoder_config_and_inputs - ( - decoder_config, - decoder_input_ids, - decoder_attention_mask, - decoder_head_mask, - decoder_token_type_ids, - mc_token_ids, - sequence_labels, - token_labels, - choice_labels, - ) = decoder_config_and_inputs + decoder_config, decoder_input_ids, decoder_attention_mask, decoder_head_mask, _, _, _, _, _ = ( + decoder_config_and_inputs + ) # make sure that cross attention layers are added decoder_config.add_cross_attention = True From 384b6714236e68b754221749ebfe5fa0f5b663c6 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Tue, 23 Sep 2025 19:35:24 +0200 Subject: [PATCH 172/204] Fix `_get_test_info` for inherited tests (#41106) * fix _get_test_info * fix patched * add comment * ruff --------- Co-authored-by: ydshieh --- src/transformers/testing_utils.py | 52 ++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/transformers/testing_utils.py b/src/transformers/testing_utils.py index 21209042192a..a7bbc8cd82fc 100644 --- a/src/transformers/testing_utils.py +++ b/src/transformers/testing_utils.py @@ -3357,15 +3357,27 @@ def _get_test_info(): stack_from_inspect = inspect.stack() # but visit from the top frame to the most recent frame + actual_test_file, _actual_test_class = test_file, test_class test_frame, test_obj, test_method = None, None, None for frame in reversed(stack_from_inspect): - if test_file in str(frame).replace(r"\\", "/"): - if test_name == frame.frame.f_locals["self"]._testMethodName: - test_frame = frame - # The test instance - test_obj = frame.frame.f_locals["self"] - test_method = getattr(test_obj, test_name) - break + # if test_file in str(frame).replace(r"\\", "/"): + # check frame's function + if it has `self` as locals; double check if self has the (function) name + # TODO: Question: How about expanded? + if ( + frame.function == test_name + and "self" in frame.frame.f_locals + and hasattr(frame.frame.f_locals["self"], test_name) + ): + # if test_name == frame.frame.f_locals["self"]._testMethodName: + test_frame = frame + # The test instance + test_obj = frame.frame.f_locals["self"] + # TODO: Do we get the (relative?) path or it's just a file name? + # TODO: Does `test_obj` always have `tearDown` object? + actual_test_file = frame.filename + # TODO: check `test_method` will work used at the several places! + test_method = getattr(test_obj, test_name) + break if test_frame is not None: line_number = test_frame.lineno @@ -3379,9 +3391,12 @@ def _get_test_info(): # From the most outer (i.e. python's `runpy.py`) frame to most inner frame (i.e. the frame of this method) # Between `the test method being called` and `before entering `patched``. for frame in reversed(stack_from_inspect): - if test_file in str(frame).replace(r"\\", "/"): - if "self" in frame.frame.f_locals and test_name == frame.frame.f_locals["self"]._testMethodName: - to_capture = True + if ( + frame.function == test_name + and "self" in frame.frame.f_locals + and hasattr(frame.frame.f_locals["self"], test_name) + ): + to_capture = True # TODO: check simply with the name is not robust. elif "patched" == frame.frame.f_code.co_name: frame_of_patched_obj = frame @@ -3415,7 +3430,7 @@ def _get_test_info(): # Get the code context in the test function/method. from _pytest._code.source import Source - with open(test_file) as fp: + with open(actual_test_file) as fp: s = fp.read() source = Source(s) test_code_context = "\n".join(source.getstatement(test_lineno - 1).lines) @@ -3426,9 +3441,7 @@ def _get_test_info(): source = Source(s) caller_code_context = "\n".join(source.getstatement(caller_lineno - 1).lines) - test_info = ( - f"test:\n\n{full_test_name}\n\n{'-' * 80}\n\ntest context: {test_file}:{test_lineno}\n\n{test_code_context}" - ) + test_info = f"test:\n\n{full_test_name}\n\n{'-' * 80}\n\ntest context: {actual_test_file}:{test_lineno}\n\n{test_code_context}" test_info = f"{test_info}\n\n{'-' * 80}\n\ncaller context: {caller_path}:{caller_lineno}\n\n{caller_code_context}" return ( @@ -3649,6 +3662,17 @@ def patched(*args, **kwargs): info = _parse_call_info_func(orig_method, args, kwargs, call_argument_expressions, target_args) info = _prepare_debugging_info(test_info, info) + # If the test is running in a CI environment (e.g. not a manual run), let's raise and fail the test, so it + # behaves as usual. + # On Github Actions or CircleCI, this is set automatically. + # When running manually, it's the user to determine if to set it. + # This is to avoid the patched function being called `with self.assertRaises(AssertionError):` and fails + # because of the missing expected `AssertionError`. + # TODO (ydshieh): If there is way to raise only when we are inside such context managers? + # TODO (ydshieh): How not to record the failure if it happens inside `self.assertRaises(AssertionError)`? + if os.getenv("CI") == "true": + raise captured_exception.with_traceback(test_traceback) + # Save this, so we can raise at the end of the current test captured_failure = { "result": "failed", From fe09b8a39a67e7837bf4c2af8b7fc59377de1fad Mon Sep 17 00:00:00 2001 From: Cyril Vallez Date: Tue, 23 Sep 2025 20:39:28 +0200 Subject: [PATCH 173/204] Remove bad test skips (#41109) * remove bad skips * remove more * fix inits --- .../models/d_fine/modeling_d_fine.py | 10 +++++++++ .../models/d_fine/modular_d_fine.py | 10 +++++++++ .../models/xcodec/modeling_xcodec.py | 21 ++++++++++++++++++- tests/models/d_fine/test_modeling_d_fine.py | 4 ---- tests/models/gemma3n/test_modeling_gemma3n.py | 1 - .../models/hgnet_v2/test_modeling_hgnet_v2.py | 12 ----------- tests/models/xcodec/test_modeling_xcodec.py | 1 - 7 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/transformers/models/d_fine/modeling_d_fine.py b/src/transformers/models/d_fine/modeling_d_fine.py index 5cc2f5e221d1..8e4eabfdb86c 100644 --- a/src/transformers/models/d_fine/modeling_d_fine.py +++ b/src/transformers/models/d_fine/modeling_d_fine.py @@ -459,6 +459,12 @@ def _init_weights(self, module): nn.init.constant_(layer.layers[-1].weight, 0) nn.init.constant_(layer.layers[-1].bias, 0) + if hasattr(module, "reg_scale"): + module.reg_scale.fill_(self.config.reg_scale) + + if hasattr(module, "up"): + module.up.fill_(self.config.up) + if isinstance(module, DFineMultiscaleDeformableAttention): nn.init.constant_(module.sampling_offsets.weight.data, 0.0) default_dtype = torch.get_default_dtype() @@ -496,6 +502,10 @@ def _init_weights(self, module): init.constant_(module.reg_conf.layers[-1].bias, 0) init.constant_(module.reg_conf.layers[-1].weight, 0) + if isinstance(module, nn.LayerNorm): + module.weight.data.fill_(1.0) + module.bias.data.zero_() + if hasattr(module, "weight_embedding") and self.config.learn_initial_query: nn.init.xavier_uniform_(module.weight_embedding.weight) if hasattr(module, "denoising_class_embed") and self.config.num_denoising > 0: diff --git a/src/transformers/models/d_fine/modular_d_fine.py b/src/transformers/models/d_fine/modular_d_fine.py index 52ac7fef7b0d..a2e044be7b63 100644 --- a/src/transformers/models/d_fine/modular_d_fine.py +++ b/src/transformers/models/d_fine/modular_d_fine.py @@ -635,6 +635,12 @@ def _init_weights(self, module): nn.init.constant_(layer.layers[-1].weight, 0) nn.init.constant_(layer.layers[-1].bias, 0) + if hasattr(module, "reg_scale"): + module.reg_scale.fill_(self.config.reg_scale) + + if hasattr(module, "up"): + module.up.fill_(self.config.up) + if isinstance(module, DFineMultiscaleDeformableAttention): nn.init.constant_(module.sampling_offsets.weight.data, 0.0) default_dtype = torch.get_default_dtype() @@ -672,6 +678,10 @@ def _init_weights(self, module): init.constant_(module.reg_conf.layers[-1].bias, 0) init.constant_(module.reg_conf.layers[-1].weight, 0) + if isinstance(module, nn.LayerNorm): + module.weight.data.fill_(1.0) + module.bias.data.zero_() + if hasattr(module, "weight_embedding") and self.config.learn_initial_query: nn.init.xavier_uniform_(module.weight_embedding.weight) if hasattr(module, "denoising_class_embed") and self.config.num_denoising > 0: diff --git a/src/transformers/models/xcodec/modeling_xcodec.py b/src/transformers/models/xcodec/modeling_xcodec.py index 8909162db724..4e1d376a3d08 100644 --- a/src/transformers/models/xcodec/modeling_xcodec.py +++ b/src/transformers/models/xcodec/modeling_xcodec.py @@ -332,7 +332,6 @@ def _init_weights(self, module): module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) if module.bias is not None: module.bias.data.zero_() - elif isinstance(module, (nn.LayerNorm, nn.GroupNorm)): module.bias.data.zero_() module.weight.data.fill_(1.0) @@ -341,6 +340,23 @@ def _init_weights(self, module): if module.bias is not None: k = math.sqrt(module.groups / (module.in_channels * module.kernel_size[0])) nn.init.uniform_(module.bias, a=-k, b=k) + elif module.__class__.__name__ == "Snake1d": + module.alpha.data.fill_(1.0) + elif isinstance(module, nn.ConvTranspose1d): + module.reset_parameters() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=0.02) + elif isinstance(module, XcodecModel): + # The conv1d are not handled correctly, as `self.acoustic_encoder/decoder` are initialized from a PreTrainedModel, + # but then only the submodules are used (which are not PreTrainedModels...) -> here we reinit them as in DacModel + for submodule in module.acoustic_encoder.modules(): + if isinstance(submodule, nn.Conv1d): + nn.init.trunc_normal_(submodule.weight, std=0.02) + nn.init.constant_(submodule.bias, 0) + for submodule in module.acoustic_decoder.modules(): + if isinstance(submodule, nn.Conv1d): + nn.init.trunc_normal_(submodule.weight, std=0.02) + nn.init.constant_(submodule.bias, 0) def apply_weight_norm(self): """Apply weight norm in the acoustic encoder and decoder because the original checkpoint has weight norm applied.""" @@ -396,6 +412,9 @@ def __init__(self, config): self.fc2 = nn.Linear(config.hidden_size, config.acoustic_model_config.hidden_size) self.quantizer = XcodecResidualVectorQuantization(config) + # Initialize weights and apply final processing + self.post_init() + @staticmethod def _adjust_dac_decoder(decoder: nn.Module): r""" diff --git a/tests/models/d_fine/test_modeling_d_fine.py b/tests/models/d_fine/test_modeling_d_fine.py index 7c381b8f6ae4..6ff4fc061b1b 100644 --- a/tests/models/d_fine/test_modeling_d_fine.py +++ b/tests/models/d_fine/test_modeling_d_fine.py @@ -361,10 +361,6 @@ def test_model_common_attributes(self): def test_resize_tokens_embeddings(self): pass - @unittest.skip(reason="Not relevant for the model") - def test_can_init_all_missing_weights(self): - pass - @unittest.skip(reason="Feed forward chunking is not implemented") def test_feed_forward_chunking(self): pass diff --git a/tests/models/gemma3n/test_modeling_gemma3n.py b/tests/models/gemma3n/test_modeling_gemma3n.py index eca8cfdc56ee..a5430f9f666c 100644 --- a/tests/models/gemma3n/test_modeling_gemma3n.py +++ b/tests/models/gemma3n/test_modeling_gemma3n.py @@ -148,7 +148,6 @@ class Gemma3nAudioModelTest(ModelTesterMixin, unittest.TestCase): _is_stateful = True main_input_name = "audio_mel" test_initialization = False - test_can_init_all_missing_weights = False def setUp(self): self.model_tester = Gemma3nAudioModelTester(self) diff --git a/tests/models/hgnet_v2/test_modeling_hgnet_v2.py b/tests/models/hgnet_v2/test_modeling_hgnet_v2.py index 2dad713308b4..403eb5a5c71f 100644 --- a/tests/models/hgnet_v2/test_modeling_hgnet_v2.py +++ b/tests/models/hgnet_v2/test_modeling_hgnet_v2.py @@ -189,10 +189,6 @@ class HGNetV2ForImageClassificationTest(ModelTesterMixin, PipelineTesterMixin, u def setUp(self): self.model_tester = HGNetV2ModelTester(self) - @unittest.skip(reason="Does not work on the tiny model.") - def test_model_parallelism(self): - super().test_model_parallelism() - @unittest.skip(reason="HGNetV2 does not output attentions") def test_attention_outputs(self): pass @@ -209,14 +205,6 @@ def test_inputs_embeds(self): def test_model_common_attributes(self): pass - @unittest.skip(reason="HGNetV2 does not have a model") - def test_model(self): - pass - - @unittest.skip(reason="Not relevant for the model") - def test_can_init_all_missing_weights(self): - pass - def test_backbone(self): config_and_inputs = self.model_tester.prepare_config_and_inputs() self.model_tester.create_and_check_backbone(*config_and_inputs) diff --git a/tests/models/xcodec/test_modeling_xcodec.py b/tests/models/xcodec/test_modeling_xcodec.py index 79a9fdd6e484..f1769415f1bc 100644 --- a/tests/models/xcodec/test_modeling_xcodec.py +++ b/tests/models/xcodec/test_modeling_xcodec.py @@ -114,7 +114,6 @@ class XcodecModelTest(ModelTesterMixin, unittest.TestCase): test_headmasking = False test_resize_embeddings = False test_torchscript = False - test_can_init_all_missing_weights = False def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): # model does not support returning hidden states From e1b55ffa3b44d9f4fc580bf80d560136a031ea1e Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Wed, 24 Sep 2025 07:20:01 +0800 Subject: [PATCH 174/204] Format empty lines and white space in markdown files. (#41100) * Remove additional white space and empty lines from markdown files Signed-off-by: Yuanyuan Chen * Add empty lines around code Signed-off-by: Yuanyuan Chen --------- Signed-off-by: Yuanyuan Chen --- ISSUES.md | 3 - README.md | 10 +- awesome-transformers.md | 13 +- docs/source/en/accelerator_selection.md | 4 - docs/source/en/auto_docstring.md | 2 - docs/source/en/cache_explanation.md | 6 +- docs/source/en/chat_extras.md | 3 - docs/source/en/chat_templating.md | 15 ++- docs/source/en/chat_templating_multimodal.md | 14 +-- docs/source/en/chat_templating_writing.md | 2 - docs/source/en/conversations.md | 3 +- docs/source/en/cursor.md | 2 - docs/source/en/generation_strategies.md | 1 - docs/source/en/index.md | 1 - docs/source/en/internal/file_utils.md | 1 - docs/source/en/internal/generation_utils.md | 6 - docs/source/en/internal/import_utils.md | 8 +- .../en/internal/model_debugging_utils.md | 10 +- docs/source/en/internal/pipelines_utils.md | 1 - docs/source/en/kv_cache.md | 2 +- docs/source/en/llm_tutorial.md | 3 +- docs/source/en/llm_tutorial_optimization.md | 22 +++- docs/source/en/main_classes/callback.md | 1 - docs/source/en/main_classes/configuration.md | 1 - docs/source/en/main_classes/data_collator.md | 1 - docs/source/en/main_classes/deepspeed.md | 2 +- docs/source/en/main_classes/executorch.md | 2 - .../en/main_classes/feature_extractor.md | 1 - .../source/en/main_classes/image_processor.md | 3 +- docs/source/en/main_classes/logging.md | 1 - docs/source/en/main_classes/model.md | 1 - docs/source/en/main_classes/onnx.md | 1 - .../en/main_classes/optimizer_schedules.md | 1 - docs/source/en/main_classes/output.md | 1 - docs/source/en/main_classes/pipelines.md | 7 -- docs/source/en/main_classes/processors.md | 4 - docs/source/en/main_classes/tokenizer.md | 5 +- .../source/en/main_classes/video_processor.md | 3 - docs/source/en/model_doc/aimv2.md | 1 - docs/source/en/model_doc/aria.md | 3 +- .../audio-spectrogram-transformer.md | 8 +- docs/source/en/model_doc/auto.md | 1 - docs/source/en/model_doc/aya_vision.md | 2 +- docs/source/en/model_doc/bark.md | 9 +- docs/source/en/model_doc/bart.md | 2 +- docs/source/en/model_doc/barthez.md | 1 - docs/source/en/model_doc/bartpho.md | 5 - docs/source/en/model_doc/bert-japanese.md | 1 - docs/source/en/model_doc/bertweet.md | 2 +- docs/source/en/model_doc/big_bird.md | 2 + docs/source/en/model_doc/bigbird_pegasus.md | 2 + docs/source/en/model_doc/biogpt.md | 5 - docs/source/en/model_doc/bitnet.md | 5 - docs/source/en/model_doc/blenderbot-small.md | 1 - docs/source/en/model_doc/blenderbot.md | 1 - docs/source/en/model_doc/blip-2.md | 4 +- docs/source/en/model_doc/blip.md | 1 - docs/source/en/model_doc/bloom.md | 1 - docs/source/en/model_doc/blt.md | 1 - docs/source/en/model_doc/bridgetower.md | 6 +- docs/source/en/model_doc/bros.md | 2 - docs/source/en/model_doc/camembert.md | 3 +- docs/source/en/model_doc/canine.md | 1 + docs/source/en/model_doc/chameleon.md | 3 - docs/source/en/model_doc/clipseg.md | 2 +- docs/source/en/model_doc/clvp.md | 12 +- docs/source/en/model_doc/code_llama.md | 2 + docs/source/en/model_doc/codegen.md | 4 +- docs/source/en/model_doc/cohere.md | 4 - docs/source/en/model_doc/cohere2.md | 3 - docs/source/en/model_doc/cohere2_vision.md | 1 + docs/source/en/model_doc/cpm.md | 2 - docs/source/en/model_doc/cpmant.md | 2 +- docs/source/en/model_doc/csm.md | 1 - docs/source/en/model_doc/ctrl.md | 1 - docs/source/en/model_doc/d_fine.md | 6 +- docs/source/en/model_doc/dab-detr.md | 7 +- docs/source/en/model_doc/dac.md | 8 +- docs/source/en/model_doc/dbrx.md | 6 +- docs/source/en/model_doc/deberta-v2.md | 4 +- docs/source/en/model_doc/deberta.md | 1 - .../en/model_doc/decision_transformer.md | 15 ++- docs/source/en/model_doc/deepseek_v3.md | 15 ++- docs/source/en/model_doc/deepseek_vl.md | 4 + .../source/en/model_doc/deepseek_vl_hybrid.md | 4 + docs/source/en/model_doc/deplot.md | 6 +- docs/source/en/model_doc/depth_pro.md | 11 +- docs/source/en/model_doc/detr.md | 5 +- docs/source/en/model_doc/dia.md | 2 - docs/source/en/model_doc/diffllama.md | 1 - docs/source/en/model_doc/dinov2.md | 1 - .../en/model_doc/dinov2_with_registers.md | 1 - docs/source/en/model_doc/dinov3.md | 1 - docs/source/en/model_doc/dit.md | 1 + docs/source/en/model_doc/doge.md | 4 +- docs/source/en/model_doc/donut.md | 2 +- docs/source/en/model_doc/dots1.md | 1 - docs/source/en/model_doc/efficientloftr.md | 2 +- docs/source/en/model_doc/efficientnet.md | 4 +- docs/source/en/model_doc/emu3.md | 6 +- docs/source/en/model_doc/encodec.md | 6 +- docs/source/en/model_doc/eomt.md | 1 - docs/source/en/model_doc/ernie4_5.md | 2 - docs/source/en/model_doc/ernie4_5_moe.md | 2 - docs/source/en/model_doc/ernie_m.md | 6 - docs/source/en/model_doc/esm.md | 3 - docs/source/en/model_doc/evolla.md | 1 - docs/source/en/model_doc/exaone4.md | 4 +- docs/source/en/model_doc/falcon_h1.md | 5 +- .../en/model_doc/fastspeech2_conformer.md | 3 +- docs/source/en/model_doc/flan-ul2.md | 1 - docs/source/en/model_doc/flex_olmo.md | 3 +- docs/source/en/model_doc/fnet.md | 4 +- docs/source/en/model_doc/fsmt.md | 1 - docs/source/en/model_doc/funnel.md | 1 - docs/source/en/model_doc/fuyu.md | 4 +- docs/source/en/model_doc/gemma.md | 2 - docs/source/en/model_doc/gemma2.md | 3 +- docs/source/en/model_doc/gemma3.md | 2 + docs/source/en/model_doc/gemma3n.md | 1 + docs/source/en/model_doc/glm.md | 1 - docs/source/en/model_doc/glm4v.md | 2 + docs/source/en/model_doc/got_ocr2.md | 4 +- docs/source/en/model_doc/gpt2.md | 2 +- docs/source/en/model_doc/gpt_bigcode.md | 2 - docs/source/en/model_doc/gpt_neo.md | 3 +- docs/source/en/model_doc/gpt_neox.md | 5 +- docs/source/en/model_doc/gpt_neox_japanese.md | 2 - docs/source/en/model_doc/gpt_oss.md | 1 - docs/source/en/model_doc/granite.md | 4 +- docs/source/en/model_doc/granite_speech.md | 6 - docs/source/en/model_doc/granitemoe.md | 1 - docs/source/en/model_doc/granitemoehybrid.md | 2 - docs/source/en/model_doc/granitemoeshared.md | 2 - docs/source/en/model_doc/granitevision.md | 2 + docs/source/en/model_doc/helium.md | 10 +- docs/source/en/model_doc/herbert.md | 1 - docs/source/en/model_doc/hgnet_v2.md | 2 - docs/source/en/model_doc/hiera.md | 2 +- docs/source/en/model_doc/hubert.md | 1 + docs/source/en/model_doc/hunyuan_v1_dense.md | 2 - docs/source/en/model_doc/hunyuan_v1_moe.md | 2 - docs/source/en/model_doc/idefics.md | 2 - docs/source/en/model_doc/idefics2.md | 3 - docs/source/en/model_doc/idefics3.md | 3 +- docs/source/en/model_doc/ijepa.md | 5 +- docs/source/en/model_doc/instructblip.md | 1 - docs/source/en/model_doc/instructblipvideo.md | 1 - docs/source/en/model_doc/internvl.md | 8 +- docs/source/en/model_doc/jamba.md | 4 +- docs/source/en/model_doc/jetmoe.md | 5 +- docs/source/en/model_doc/kosmos2_5.md | 2 - .../en/model_doc/kyutai_speech_to_text.md | 3 +- docs/source/en/model_doc/layoutlm.md | 1 - docs/source/en/model_doc/layoutlmv2.md | 3 +- docs/source/en/model_doc/led.md | 1 + docs/source/en/model_doc/lfm2.md | 2 +- docs/source/en/model_doc/lfm2_vl.md | 4 +- docs/source/en/model_doc/lightglue.md | 1 - docs/source/en/model_doc/llama2.md | 4 +- docs/source/en/model_doc/llama4.md | 10 +- docs/source/en/model_doc/llava.md | 13 +- docs/source/en/model_doc/llava_next.md | 2 - docs/source/en/model_doc/llava_next_video.md | 16 +-- docs/source/en/model_doc/llava_onevision.md | 7 +- docs/source/en/model_doc/longcat_flash.md | 3 +- docs/source/en/model_doc/longformer.md | 1 - docs/source/en/model_doc/longt5.md | 2 - docs/source/en/model_doc/m2m_100.md | 9 +- docs/source/en/model_doc/mamba.md | 2 +- docs/source/en/model_doc/mamba2.md | 2 +- docs/source/en/model_doc/marian.md | 8 +- docs/source/en/model_doc/markuplm.md | 2 +- docs/source/en/model_doc/matcha.md | 3 +- docs/source/en/model_doc/mega.md | 3 - docs/source/en/model_doc/megatron-bert.md | 4 +- docs/source/en/model_doc/mimi.md | 2 +- docs/source/en/model_doc/minimax.md | 4 +- docs/source/en/model_doc/ministral.md | 1 - docs/source/en/model_doc/mistral.md | 1 - docs/source/en/model_doc/mistral3.md | 17 ++- docs/source/en/model_doc/mixtral.md | 6 +- docs/source/en/model_doc/mlcd.md | 5 +- docs/source/en/model_doc/mllama.md | 9 +- docs/source/en/model_doc/mm-grounding-dino.md | 2 - docs/source/en/model_doc/mms.md | 1 + docs/source/en/model_doc/mobilebert.md | 3 +- docs/source/en/model_doc/mobilenet_v1.md | 4 +- docs/source/en/model_doc/mobilenet_v2.md | 5 +- docs/source/en/model_doc/mobilevit.md | 10 -- .../source/en/model_doc/modernbert-decoder.md | 6 +- docs/source/en/model_doc/modernbert.md | 3 - docs/source/en/model_doc/moonshine.md | 2 +- docs/source/en/model_doc/moshi.md | 16 +-- docs/source/en/model_doc/mpt.md | 6 +- docs/source/en/model_doc/mt5.md | 1 - docs/source/en/model_doc/musicgen.md | 14 +-- docs/source/en/model_doc/musicgen_melody.md | 9 +- docs/source/en/model_doc/mvp.md | 2 +- docs/source/en/model_doc/myt5.md | 1 - docs/source/en/model_doc/nemotron.md | 6 +- docs/source/en/model_doc/nllb-moe.md | 2 - docs/source/en/model_doc/nllb.md | 2 +- docs/source/en/model_doc/olmo2.md | 3 +- docs/source/en/model_doc/olmo3.md | 4 +- docs/source/en/model_doc/openai-gpt.md | 7 +- docs/source/en/model_doc/opt.md | 3 +- docs/source/en/model_doc/ovis2.md | 2 +- docs/source/en/model_doc/paligemma.md | 1 + docs/source/en/model_doc/patchtsmixer.md | 9 +- docs/source/en/model_doc/pegasus_x.md | 3 + docs/source/en/model_doc/perception_lm.md | 2 - docs/source/en/model_doc/persimmon.md | 6 +- docs/source/en/model_doc/phi3.md | 2 - docs/source/en/model_doc/phimoe.md | 3 +- docs/source/en/model_doc/pixtral.md | 1 - docs/source/en/model_doc/pop2piano.md | 20 ++-- .../en/model_doc/prompt_depth_anything.md | 3 +- docs/source/en/model_doc/pvt.md | 24 ++-- docs/source/en/model_doc/pvt_v2.md | 4 +- docs/source/en/model_doc/qwen2.md | 1 - docs/source/en/model_doc/qwen2_5_omni.md | 7 +- docs/source/en/model_doc/qwen2_5_vl.md | 12 +- docs/source/en/model_doc/qwen2_audio.md | 4 +- docs/source/en/model_doc/qwen2_moe.md | 8 +- docs/source/en/model_doc/qwen2_vl.md | 6 +- docs/source/en/model_doc/qwen3.md | 1 - docs/source/en/model_doc/qwen3_omni_moe.md | 9 +- docs/source/en/model_doc/qwen3_vl.md | 1 + docs/source/en/model_doc/qwen3_vl_moe.md | 1 + docs/source/en/model_doc/recurrent_gemma.md | 5 +- docs/source/en/model_doc/reformer.md | 3 - docs/source/en/model_doc/retribert.md | 1 - docs/source/en/model_doc/roberta.md | 1 - docs/source/en/model_doc/rt_detr.md | 2 - docs/source/en/model_doc/rt_detr_v2.md | 8 +- docs/source/en/model_doc/rwkv.md | 2 +- docs/source/en/model_doc/sam.md | 2 +- docs/source/en/model_doc/sam_hq.md | 3 - docs/source/en/model_doc/seamless_m4t.md | 16 +-- docs/source/en/model_doc/seamless_m4t_v2.md | 10 +- docs/source/en/model_doc/segformer.md | 2 - docs/source/en/model_doc/seggpt.md | 1 - docs/source/en/model_doc/shieldgemma2.md | 1 - docs/source/en/model_doc/siglip.md | 5 +- docs/source/en/model_doc/siglip2.md | 3 +- docs/source/en/model_doc/smollm3.md | 1 - docs/source/en/model_doc/smolvlm.md | 3 +- docs/source/en/model_doc/stablelm.md | 1 - docs/source/en/model_doc/starcoder2.md | 2 +- docs/source/en/model_doc/superglue.md | 1 - docs/source/en/model_doc/superpoint.md | 3 +- docs/source/en/model_doc/swin.md | 2 + docs/source/en/model_doc/swinv2.md | 2 +- .../en/model_doc/switch_transformers.md | 2 - docs/source/en/model_doc/t5gemma.md | 2 +- docs/source/en/model_doc/t5v1.1.md | 1 - docs/source/en/model_doc/table-transformer.md | 4 +- docs/source/en/model_doc/tapas.md | 8 -- docs/source/en/model_doc/textnet.md | 3 +- .../en/model_doc/time_series_transformer.md | 1 - docs/source/en/model_doc/timesfm.md | 3 - docs/source/en/model_doc/transfo-xl.md | 1 - docs/source/en/model_doc/trocr.md | 5 - docs/source/en/model_doc/tvp.md | 2 +- docs/source/en/model_doc/umt5.md | 5 +- docs/source/en/model_doc/univnet.md | 1 - docs/source/en/model_doc/van.md | 1 - docs/source/en/model_doc/vaultgemma.md | 2 - docs/source/en/model_doc/video_llava.md | 13 +- docs/source/en/model_doc/videomae.md | 8 +- docs/source/en/model_doc/vipllava.md | 5 +- docs/source/en/model_doc/visual_bert.md | 1 - docs/source/en/model_doc/vit_hybrid.md | 8 +- docs/source/en/model_doc/vit_mae.md | 1 - docs/source/en/model_doc/vit_msn.md | 12 +- docs/source/en/model_doc/vits.md | 1 - docs/source/en/model_doc/vivit.md | 11 +- docs/source/en/model_doc/vjepa2.md | 2 - docs/source/en/model_doc/voxtral.md | 8 +- docs/source/en/model_doc/wav2vec2-bert.md | 1 - .../source/en/model_doc/wav2vec2-conformer.md | 2 +- docs/source/en/model_doc/wav2vec2.md | 3 - docs/source/en/model_doc/wav2vec2_phoneme.md | 1 - docs/source/en/model_doc/whisper.md | 1 - docs/source/en/model_doc/xcodec.md | 10 +- docs/source/en/model_doc/xglm.md | 2 - docs/source/en/model_doc/xlm-prophetnet.md | 1 - docs/source/en/model_doc/xlm-roberta-xl.md | 2 + docs/source/en/model_doc/xlm-roberta.md | 1 + docs/source/en/model_doc/xlm.md | 1 + docs/source/en/model_doc/xlstm.md | 2 - docs/source/en/model_doc/yolos.md | 3 - docs/source/en/model_doc/yoso.md | 28 ++--- docs/source/en/model_doc/zamba.md | 13 +- docs/source/en/model_doc/zamba2.md | 10 +- docs/source/en/model_doc/zoedepth.md | 4 +- docs/source/en/model_memory_anatomy.md | 70 ++++++----- docs/source/en/models.md | 2 - docs/source/en/perf_train_gaudi.md | 3 + docs/source/en/pipeline_webserver.md | 1 + docs/source/en/pr_checks.md | 1 - docs/source/en/quantization/auto_round.md | 20 ++-- docs/source/en/quantization/awq.md | 1 + docs/source/en/quantization/bitsandbytes.md | 4 +- .../en/quantization/compressed_tensors.md | 40 +++---- docs/source/en/quantization/concept_guide.md | 8 +- docs/source/en/quantization/mxfp4.md | 5 +- docs/source/en/quantization/overview.md | 4 +- docs/source/en/quantization/selecting.md | 2 +- docs/source/en/quantization/torchao.md | 40 ++++--- docs/source/en/run_scripts.md | 1 + docs/source/en/serialization.md | 1 + docs/source/en/serving.md | 4 - docs/source/en/tasks/audio_classification.md | 1 - .../en/tasks/document_question_answering.md | 1 + docs/source/en/tasks/idefics.md | 112 +++++++++--------- docs/source/en/tasks/image_captioning.md | 42 +++---- docs/source/en/tasks/image_classification.md | 2 - .../en/tasks/image_feature_extraction.md | 5 +- docs/source/en/tasks/image_text_to_text.md | 3 - docs/source/en/tasks/image_to_image.md | 16 ++- docs/source/en/tasks/keypoint_detection.md | 22 ++-- docs/source/en/tasks/keypoint_matching.md | 18 +-- ...e_distillation_for_image_classification.md | 1 - docs/source/en/tasks/mask_generation.md | 28 ++--- .../en/tasks/monocular_depth_estimation.md | 4 +- docs/source/en/tasks/multiple_choice.md | 2 +- docs/source/en/tasks/object_detection.md | 4 +- docs/source/en/tasks/prompting.md | 1 - docs/source/en/tasks/semantic_segmentation.md | 8 +- docs/source/en/tasks/summarization.md | 1 - docs/source/en/tasks/token_classification.md | 2 - docs/source/en/tasks/video_classification.md | 2 - docs/source/en/tasks/video_text_to_text.md | 12 +- .../en/tasks/visual_document_retrieval.md | 13 +- .../en/tasks/zero_shot_object_detection.md | 2 +- docs/source/en/testing.md | 29 +---- docs/source/en/tiny_agents.md | 1 - docs/source/en/trainer.md | 1 - docs/source/en/training.md | 1 + docs/source/en/transformers_as_backend.md | 14 +-- docs/source/en/troubleshooting.md | 1 - notebooks/README.md | 4 - 344 files changed, 675 insertions(+), 1094 deletions(-) diff --git a/ISSUES.md b/ISSUES.md index 9c96162647bc..c87bd9fc2c3f 100644 --- a/ISSUES.md +++ b/ISSUES.md @@ -38,7 +38,6 @@ In particular all "Please explain" questions or objectively very user-specific f * "How to train T5 on De->En translation?" - ## The GitHub Issues Everything which hints at a bug should be opened as an [issue](https://github.com/huggingface/transformers/issues). @@ -247,7 +246,6 @@ You are not required to read the following guidelines before opening an issue. H Try not use italics and bold text too much as these often make the text more difficult to read. - 12. If you are cross-referencing a specific comment in a given thread or another issue, always link to that specific comment, rather than using the issue link. If you do the latter it could be quite impossible to find which specific comment you're referring to. To get the link to the specific comment do not copy the url from the location bar of your browser, but instead, click the `...` icon in the upper right corner of the comment and then select "Copy Link". @@ -257,7 +255,6 @@ You are not required to read the following guidelines before opening an issue. H 1. https://github.com/huggingface/transformers/issues/9257 2. https://github.com/huggingface/transformers/issues/9257#issuecomment-749945162 - 13. If you are replying to a last comment, it's totally fine to make your reply with just your comment in it. The readers can follow the information flow here. But if you're replying to a comment that happened some comments back it's always a good practice to quote just the relevant lines you're replying it. The `>` is used for quoting, or you can always use the menu to do so. For example your editor box will look like: diff --git a/README.md b/README.md index 850b76f5c4f7..8b09a84f29e7 100644 --- a/README.md +++ b/README.md @@ -63,12 +63,11 @@ limitations under the License. +Transformers acts as the model-definition framework for state-of-the-art machine learning models in text, computer +vision, audio, video, and multimodal model, for both inference and training. -Transformers acts as the model-definition framework for state-of-the-art machine learning models in text, computer -vision, audio, video, and multimodal model, for both inference and training. - -It centralizes the model definition so that this definition is agreed upon across the ecosystem. `transformers` is the -pivot across frameworks: if a model definition is supported, it will be compatible with the majority of training +It centralizes the model definition so that this definition is agreed upon across the ecosystem. `transformers` is the +pivot across frameworks: if a model definition is supported, it will be compatible with the majority of training frameworks (Axolotl, Unsloth, DeepSpeed, FSDP, PyTorch-Lightning, ...), inference engines (vLLM, SGLang, TGI, ...), and adjacent modeling libraries (llama.cpp, mlx, ...) which leverage the model definition from `transformers`. @@ -194,7 +193,6 @@ pipeline("https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.pn
Visual question answering -

diff --git a/awesome-transformers.md b/awesome-transformers.md index adc84f101eae..d0398e7bde6a 100644 --- a/awesome-transformers.md +++ b/awesome-transformers.md @@ -6,7 +6,7 @@ developers, researchers, students, professors, engineers, and anyone else to bui In this list, we showcase incredibly impactful and novel projects that have pushed the field forward. We celebrate 100 of these projects as we reach the milestone of 100k stars as a community; but we're very open to pull requests -adding other projects to the list. If you believe a project should be here and it's not, then please, open a PR +adding other projects to the list. If you believe a project should be here and it's not, then please, open a PR to add it. ## [gpt4all](https://github.com/nomic-ai/gpt4all) @@ -49,7 +49,7 @@ Keywords: LLMs, Large Language Models, Agents, Chains [LlamaIndex](https://github.com/run-llama/llama_index) is a project that provides a central interface to connect your LLM's with external data. It provides various kinds of indices and retrieval mechanisms to perform different LLM tasks and obtain knowledge-augmented results. -Keywords: LLMs, Large Language Models, Data Retrieval, Indices, Knowledge Augmentation +Keywords: LLMs, Large Language Models, Data Retrieval, Indices, Knowledge Augmentation ## [ParlAI](https://github.com/facebookresearch/ParlAI) @@ -257,7 +257,7 @@ Stable-Dreamfusion is a pytorch implementation of the text-to-3D model Dreamfusi Keywords: Text-to-3D, Stable Diffusion ## [txtai](https://github.com/neuml/txtai) - + [txtai](https://github.com/neuml/txtai) is an open-source platform for semantic search and workflows powered by language models. txtai builds embeddings databases, which are a union of vector indexes and relational databases enabling similarity search with SQL. Semantic workflows connect language models together into unified applications. Keywords: Semantic search, LLM @@ -309,8 +309,8 @@ Keywords: OCR, LaTeX, Math formula OpenCLIP is an open source implementation of OpenAI's CLIP. -The goal of this repository is to enable training models with contrastive image-text supervision, and to investigate their properties such as robustness to distribution shift. -The starting point is an implementation of CLIP that matches the accuracy of the original CLIP models when trained on the same dataset. +The goal of this repository is to enable training models with contrastive image-text supervision, and to investigate their properties such as robustness to distribution shift. +The starting point is an implementation of CLIP that matches the accuracy of the original CLIP models when trained on the same dataset. Specifically, a ResNet-50 model trained with this codebase on OpenAI's 15 million image subset of YFCC achieves 32.7% top-1 accuracy on ImageNet. @@ -596,7 +596,7 @@ Keywords: Data-Centric AI, Data Quality, Noisy Labels, Outlier Detection, Active ## [BentoML](https://github.com/bentoml/BentoML) -[BentoML](https://github.com/bentoml) is the unified framework for building, shipping, and scaling production-ready AI applications incorporating traditional ML, pre-trained AI models, Generative and Large Language Models. +[BentoML](https://github.com/bentoml) is the unified framework for building, shipping, and scaling production-ready AI applications incorporating traditional ML, pre-trained AI models, Generative and Large Language Models. All Hugging Face models and pipelines can be seamlessly integrated into BentoML applications, enabling the running of models on the most suitable hardware and independent scaling based on usage. Keywords: BentoML, Framework, Deployment, AI Applications @@ -606,4 +606,3 @@ Keywords: BentoML, Framework, Deployment, AI Applications [LLaMA Factory](https://github.com/hiyouga/LLaMA-Factory) offers a user-friendly fine-tuning framework that incorporates PEFT. The repository includes training(fine-tuning) and inference examples for LLaMA-2, BLOOM, Falcon, Baichuan, Qwen, and other LLMs. A ChatGLM version is also available in [ChatGLM-Efficient-Tuning](https://github.com/hiyouga/ChatGLM-Efficient-Tuning). Keywords: PEFT, fine-tuning, LLaMA-2, ChatGLM, Qwen - diff --git a/docs/source/en/accelerator_selection.md b/docs/source/en/accelerator_selection.md index 5d5bbc2675fa..3cd809cba6a2 100644 --- a/docs/source/en/accelerator_selection.md +++ b/docs/source/en/accelerator_selection.md @@ -69,7 +69,6 @@ CUDA_VISIBLE_DEVICES=0,2 torchrun trainer-program.py ... Only GPUs 0 and 2 are "visible" to PyTorch and are mapped to `cuda:0` and `cuda:1` respectively. To reverse the order (use GPU 2 as `cuda:0` and GPU 0 as `cuda:1`): - ```bash CUDA_VISIBLE_DEVICES=2,0 torchrun trainer-program.py ... ``` @@ -108,7 +107,6 @@ To reverse the order (use XPU 2 as `xpu:0` and XPU 0 as `xpu:1`): ZE_AFFINITY_MASK=2,0 torchrun trainer-program.py ... ``` - You can also control the order of Intel XPUs with: ```bash @@ -120,7 +118,5 @@ For more information about device enumeration and sorting on Intel XPU, please r - - > [!WARNING] > Environment variables can be exported instead of being added to the command line. This is not recommended because it can be confusing if you forget how the environment variable was set up and you end up using the wrong accelerators. Instead, it is common practice to set the environment variable for a specific training run on the same command line. diff --git a/docs/source/en/auto_docstring.md b/docs/source/en/auto_docstring.md index 5fc4ed061ce1..6445ee530146 100644 --- a/docs/source/en/auto_docstring.md +++ b/docs/source/en/auto_docstring.md @@ -145,7 +145,6 @@ Arguments can also be passed directly to `@auto_docstring` for more control. Use The `Returns` and `Examples` parts of the docstring can also be manually specified. - ```python MODEL_COMMON_CUSTOM_ARGS = r""" common_arg_1 (`torch.Tensor`, *optional*, defaults to `default_value`): @@ -202,7 +201,6 @@ There are some rules for documenting different types of arguments and they're li If a standard argument behaves differently in your model, then you can override it locally in a `r""" """` block. This local definition has a higher priority. For example, the `labels` argument is often customized per model and typically requires overriding. - - New or custom arguments should be documented within an `r""" """` block after the signature if it is a function or in the `__init__` method's docstring if it is a class. ```py diff --git a/docs/source/en/cache_explanation.md b/docs/source/en/cache_explanation.md index 0e192fd47f42..77fc2c9c3288 100644 --- a/docs/source/en/cache_explanation.md +++ b/docs/source/en/cache_explanation.md @@ -59,11 +59,9 @@ Refer to the table below to compare how caching improves efficiency. | without caching | with caching | |---|---| -| for each step, recompute all previous `K` and `V` | for each step, only compute current `K` and `V` +| for each step, recompute all previous `K` and `V` | for each step, only compute current `K` and `V` | attention cost per step is **quadratic** with sequence length | attention cost per step is **linear** with sequence length (memory grows linearly, but compute/token remains low) | - - ## Cache class A basic KV cache interface takes a key and value tensor for the current token and returns the updated `K` and `V` tensors. This is internally managed by a model's `forward` method. @@ -143,7 +141,6 @@ Cache position is used internally for two purposes: The generation loop usually takes care of the cache position, but if you're writing a custom generation method, it is important that cache positions are accurate since they are used to write and read key/value states into fixed slots. - ```py import torch from transformers import AutoTokenizer, AutoModelForCausalLM, DynamicCache, infer_device @@ -160,7 +157,6 @@ generated_ids = model.generate(**inputs, use_cache=True, max_new_tokens=10) ``` - ## Legacy cache format Before the [`Cache`] class, the cache used to be stored as a tuple of tuples of tensors. This format is dynamic because it grows as text is generated, similar to [`DynamicCache`]. diff --git a/docs/source/en/chat_extras.md b/docs/source/en/chat_extras.md index dc933dd6815e..20d5cf22ce4a 100644 --- a/docs/source/en/chat_extras.md +++ b/docs/source/en/chat_extras.md @@ -29,7 +29,6 @@ the arguments, argument types, and function docstring are parsed in order to gen Although passing Python functions is very convenient, the parser can only handle [Google-style](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) docstrings. Refer to the examples below for how to format a tool-ready function. - ```py def get_current_temperature(location: str, unit: str): """ @@ -103,7 +102,6 @@ Hold the call in the `tool_calls` key of an `assistant` message. This is the rec > [!WARNING] > Although `tool_calls` is similar to the OpenAI API, the OpenAI API uses a JSON string as its `tool_calls` format. This may cause errors or strange model behavior if used in Transformers, which expects a dict. - ```py tool_call = {"name": "get_current_temperature", "arguments": {"location": "Paris, France", "unit": "celsius"}} messages.append({"role": "assistant", "tool_calls": [{"type": "function", "function": tool_call}]}) @@ -131,7 +129,6 @@ The temperature in Paris, France right now is 22°C.<|im_end|> > Although the key in the assistant message is called `tool_calls`, in most cases, models only emit a single tool call at a time. Some older models emit multiple tool calls at the same time, but this is a > significantly more complex process, as you need to handle multiple tool responses at once and disambiguate them, often using tool call IDs. Please refer to the model card to see exactly what format a model expects for tool calls. - ## JSON schemas Another way to define tools is by passing a [JSON schema](https://json-schema.org/learn/getting-started-step-by-step). diff --git a/docs/source/en/chat_templating.md b/docs/source/en/chat_templating.md index b32fa8ec43f4..b1e8428afaa9 100644 --- a/docs/source/en/chat_templating.md +++ b/docs/source/en/chat_templating.md @@ -16,13 +16,13 @@ rendered properly in your Markdown viewer. # Chat templates -The [chat basics](./conversations) guide covers how to store chat histories and generate text from chat models using [`TextGenerationPipeline`]. +The [chat basics](./conversations) guide covers how to store chat histories and generate text from chat models using [`TextGenerationPipeline`]. This guide is intended for more advanced users, and covers the underlying classes and methods, as well as the key concepts for understanding what's actually going on when you chat with a model. The critical insight needed to understand chat models is this: All causal LMs, whether chat-trained or not, continue a sequence of tokens. When causal LMs are trained, the training usually begins with "pre-training" on a huge corpus of text, which creates a "base" model. These base models are then often "fine-tuned" for chat, which means training them on data that is formatted as a sequence of messages. The chat is still just a sequence of tokens, though! The list of `role` and `content` dictionaries that you pass -to a chat model get converted to a token sequence, often with control tokens like `<|user|>` or `<|assistant|>` or `<|end_of_message|>`, which allow the model to see the chat structure. +to a chat model get converted to a token sequence, often with control tokens like `<|user|>` or `<|assistant|>` or `<|end_of_message|>`, which allow the model to see the chat structure. There are many possible chat formats, and different models may use different formats or control tokens, even if they were fine-tuned from the same base model! Don't panic, though - you don't need to memorize every possible chat format in order to use chat models. Chat models come with **chat templates**, which indicate how they expect chats to be formatted. @@ -43,6 +43,7 @@ chat = [ tokenizer.apply_chat_template(chat, tokenize=False) ``` + ```md [INST] Hello, how are you? [/INST]I'm doing great. How can I help you today? [INST] I'd like to show off how chat templating works! [/INST] ``` @@ -62,6 +63,7 @@ chat = [ tokenizer.apply_chat_template(chat, tokenize=False) ``` + ```md <|user|>\nHello, how are you?
\n<|assistant|>\nI'm doing great. How can I help you today?
\n<|user|>\nI'd like to show off how chat templating works!\n ``` @@ -110,6 +112,7 @@ Pass the tokenized chat to [`~GenerationMixin.generate`] to generate a response. outputs = model.generate(tokenized_chat, max_new_tokens=128) print(tokenizer.decode(outputs[0])) ``` + ```md <|system|> You are a friendly chatbot who always responds in the style of a pirate @@ -125,9 +128,9 @@ Matey, I'm afraid I must inform ye that humans cannot eat helicopters. Helicopte ### add_generation_prompt -You may have noticed the [add_generation_prompt](https://huggingface.co/docs/transformers/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.apply_chat_template.add_generation_prompt) argument in the above examples. +You may have noticed the [add_generation_prompt](https://huggingface.co/docs/transformers/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.apply_chat_template.add_generation_prompt) argument in the above examples. This argument adds tokens to the end of the chat that indicate the start of an `assistant` response. Remember: Beneath all the chat abstractions, chat models are still just language models that continue a sequence of tokens! -If you include tokens that tell it that it's now in an `assistant` response, it will correctly write a response, but if you don't include these tokens, the model may get confused and do something strange, like **continuing** the user's message instead of replying to it! +If you include tokens that tell it that it's now in an `assistant` response, it will correctly write a response, but if you don't include these tokens, the model may get confused and do something strange, like **continuing** the user's message instead of replying to it! Let's see an example to understand what `add_generation_prompt` is actually doing. First, let's format a chat without `add_generation_prompt`: @@ -135,6 +138,7 @@ Let's see an example to understand what `add_generation_prompt` is actually doin tokenized_chat = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=False) tokenized_chat ``` + ```md <|im_start|>user Hi there!<|im_end|> @@ -150,6 +154,7 @@ Now, let's format the same chat with `add_generation_prompt=True`: tokenized_chat = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) tokenized_chat ``` + ```md <|im_start|>user Hi there!<|im_end|> @@ -186,7 +191,6 @@ model.generate(**formatted_chat) [`TextGenerationPipeline`] sets [add_generation_prompt](https://huggingface.co/docs/transformers/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.apply_chat_template.add_generation_prompt) to `True` by default to start a new message. However, if the final message in the chat has the `assistant` role, it assumes the message is a prefill and switches to `continue_final_message=True`. This is because most models don’t support multiple consecutive assistant messages. To override this behavior, explicitly pass the [continue_final_message](https://huggingface.co/docs/transformers/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.apply_chat_template.continue_final_message) argument to the pipeline. - ## Model training Training a model with a chat template is a good way to ensure the template matches the tokens the model was trained on. Apply the chat template as a preprocessing step to your dataset. Set `add_generation_prompt=False` because the additional tokens to prompt an assistant response aren't helpful during training. @@ -212,6 +216,7 @@ dataset = Dataset.from_dict({"chat": [chat1, chat2]}) dataset = dataset.map(lambda x: {"formatted_chat": tokenizer.apply_chat_template(x["chat"], tokenize=False, add_generation_prompt=False)}) print(dataset['formatted_chat'][0]) ``` + ```md <|user|> Which is bigger, the moon or the sun? diff --git a/docs/source/en/chat_templating_multimodal.md b/docs/source/en/chat_templating_multimodal.md index f28c09e96b67..e469fde86b53 100644 --- a/docs/source/en/chat_templating_multimodal.md +++ b/docs/source/en/chat_templating_multimodal.md @@ -18,8 +18,7 @@ rendered properly in your Markdown viewer. Multimodal chat models accept inputs like images, audio or video, in addition to text. The `content` key in a multimodal chat history is a list containing multiple items of different types. This is unlike text-only chat models whose `content` key is a single string. - -In the same way the [Tokenizer](./fast_tokenizer) class handles chat templates and tokenization for text-only models, +In the same way the [Tokenizer](./fast_tokenizer) class handles chat templates and tokenization for text-only models, the [Processor](./processors) class handles preprocessing, tokenization and chat templates for multimodal models. Their [`~ProcessorMixin.apply_chat_template`] methods are almost identical. This guide will show you how to chat with multimodal models with the high-level [`ImageTextToTextPipeline`] and at a lower level using the [`~ProcessorMixin.apply_chat_template`] and [`~GenerationMixin.generate`] methods. @@ -57,7 +56,6 @@ out = pipe(text=messages, max_new_tokens=128) print(out[0]['generated_text'][-1]['content']) ``` - ``` Ahoy, me hearty! These be two feline friends, likely some tabby cats, taking a siesta on a cozy pink blanket. They're resting near remote controls, perhaps after watching some TV or just enjoying some quiet time together. Cats sure know how to find comfort and relaxation, don't they? ``` @@ -66,10 +64,9 @@ Aside from the gradual descent from pirate-speak into modern American English (i ## Using `apply_chat_template` -Like [text-only models](./chat_templating), use the [`~ProcessorMixin.apply_chat_template`] method to prepare the chat messages for multimodal models. +Like [text-only models](./chat_templating), use the [`~ProcessorMixin.apply_chat_template`] method to prepare the chat messages for multimodal models. This method handles the tokenization and formatting of the chat messages, including images and other media types. The resulting inputs are passed to the model for generation. - ```python from transformers import AutoProcessor, AutoModelForImageTextToText @@ -99,7 +96,6 @@ processed_chat = processor.apply_chat_template(messages, add_generation_prompt=T print(list(processed_chat.keys())) ``` - ``` ['input_ids', 'attention_mask', 'pixel_values', 'image_grid_thw'] ``` @@ -113,7 +109,6 @@ print(processor.decode(out[0])) The decoded output contains the full conversation so far, including the user message and the placeholder tokens that contain the image information. You may need to trim the previous conversation from the output before displaying it to the user. - ## Video inputs Some vision models also support video inputs. The message format is very similar to the format for [image inputs](#image-inputs). @@ -148,6 +143,7 @@ messages = [ ``` ### Example: Passing decoded video objects + ```python import numpy as np @@ -167,7 +163,9 @@ messages = [ }, ] ``` + You can also use existing (`"load_video()"`) function to load a video, edit the video in memory and pass it in the messages. + ```python # Make sure a video backend library (pyav, decord, or torchvision) is available. @@ -200,7 +198,6 @@ Pass `messages` to [`~ProcessorMixin.apply_chat_template`] to tokenize the input The `num_frames` parameter controls how many frames to uniformly sample from the video. Each checkpoint has a maximum frame count it was pretrained with and exceeding this count can significantly lower generation quality. It's important to choose a frame count that fits both the model capacity and your hardware resources. If `num_frames` isn't specified, the entire video is loaded without any frame sampling. - ```python processed_chat = processor.apply_chat_template( messages, @@ -265,4 +262,3 @@ print(processed_chat.keys()) - diff --git a/docs/source/en/chat_templating_writing.md b/docs/source/en/chat_templating_writing.md index f4f3b1201e35..936ce2a2c7f6 100644 --- a/docs/source/en/chat_templating_writing.md +++ b/docs/source/en/chat_templating_writing.md @@ -18,7 +18,6 @@ rendered properly in your Markdown viewer. A chat template is a [Jinja](https://jinja.palletsprojects.com/en/stable/templates/) template stored in the tokenizer's [chat_template](https://huggingface.co/docs/transformers/main_classes/tokenizer#transformers.PreTrainedTokenizer.chat_template) attribute. Jinja is a templating language that allows you to write Python-like code and syntax. - ```jinja {%- for message in messages %} {{- '<|' + message['role'] + |>\n' }} @@ -108,7 +107,6 @@ We strongly recommend using `-` to ensure only the intended content is printed. ### Special variables and callables - The only constants in a template are the `messages` variable and the `add_generation_prompt` boolean. However, you have access to **any other keyword arguments that are passed** to the [`~PreTrainedTokenizerBase.apply_chat_template`] method. diff --git a/docs/source/en/conversations.md b/docs/source/en/conversations.md index 0fed56c632d2..a36be2203a5f 100644 --- a/docs/source/en/conversations.md +++ b/docs/source/en/conversations.md @@ -48,7 +48,6 @@ transformers chat -h The chat is implemented on top of the [AutoClass](./model_doc/auto), using tooling from [text generation](./llm_tutorial) and [chat](./chat_templating). It uses the `transformers serve` CLI under the hood ([docs](./serving.md#serve-cli)). - ## TextGenerationPipeline [`TextGenerationPipeline`] is a high-level text generation class with a "chat mode". Chat mode is enabled when a conversational model is detected and the chat prompt is [properly formatted](./llm_tutorial#wrong-prompt-format). @@ -109,7 +108,7 @@ quantization_config = BitsAndBytesConfig(load_in_8bit=True) pipeline = pipeline(task="text-generation", model="meta-llama/Meta-Llama-3-8B-Instruct", device_map="auto", model_kwargs={"quantization_config": quantization_config}) ``` -In general, model size and performance are directly correlated. Larger models are slower in addition to requiring more memory because each active parameter must be read from memory for every generated token. +In general, model size and performance are directly correlated. Larger models are slower in addition to requiring more memory because each active parameter must be read from memory for every generated token. This is a bottleneck for LLM text generation and the main options for improving generation speed are to either quantize a model or use hardware with higher memory bandwidth. Adding more compute power doesn't meaningfully help. You can also try techniques like [speculative decoding](./generation_strategies#speculative-decoding), where a smaller model generates candidate tokens that are verified by the larger model. If the candidate tokens are correct, the larger model can generate more than one token at a time. This significantly alleviates the bandwidth bottleneck and improves generation speed. diff --git a/docs/source/en/cursor.md b/docs/source/en/cursor.md index 18ebe803edfb..799e1715b3b1 100644 --- a/docs/source/en/cursor.md +++ b/docs/source/en/cursor.md @@ -38,5 +38,3 @@ You are now ready to use your local model in Cursor! For instance, if you toggle

- - diff --git a/docs/source/en/generation_strategies.md b/docs/source/en/generation_strategies.md index 63b70899af4d..3c277fa7df0c 100644 --- a/docs/source/en/generation_strategies.md +++ b/docs/source/en/generation_strategies.md @@ -389,7 +389,6 @@ from .utils import some_function Only relative imports from the same-level `custom_generate` folder are supported. Parent/sibling folder imports are not valid. The `custom_generate` argument also works locally with any directory that contains a `custom_generate` structure. This is the recommended workflow for developing your custom generation method. - #### requirements.txt You can optionally specify additional Python requirements in a `requirements.txt` file inside the `custom_generate` folder. These are checked at runtime and an exception will be thrown if they're missing, nudging users to update their environment accordingly. diff --git a/docs/source/en/index.md b/docs/source/en/index.md index ab0677b5a54e..e9738f6ccfa4 100644 --- a/docs/source/en/index.md +++ b/docs/source/en/index.md @@ -19,7 +19,6 @@ rendered properly in your Markdown viewer. - Transformers acts as the model-definition framework for state-of-the-art machine learning models in text, computer vision, audio, video, and multimodal model, for both inference and training. diff --git a/docs/source/en/internal/file_utils.md b/docs/source/en/internal/file_utils.md index 31fbc5b88110..63db5756a622 100644 --- a/docs/source/en/internal/file_utils.md +++ b/docs/source/en/internal/file_utils.md @@ -20,7 +20,6 @@ This page lists all of Transformers general utility functions that are found in Most of those are only useful if you are studying the general code in the library. - ## Enums and namedtuples [[autodoc]] utils.ExplicitEnum diff --git a/docs/source/en/internal/generation_utils.md b/docs/source/en/internal/generation_utils.md index a35ae4d5d066..2a5260ac7095 100644 --- a/docs/source/en/internal/generation_utils.md +++ b/docs/source/en/internal/generation_utils.md @@ -65,7 +65,6 @@ values. Here, for instance, it has two keys that are `sequences` and `scores`. We document here all output types. - [[autodoc]] generation.GenerateDecoderOnlyOutput [[autodoc]] generation.GenerateEncoderDecoderOutput @@ -74,13 +73,11 @@ We document here all output types. [[autodoc]] generation.GenerateBeamEncoderDecoderOutput - ## LogitsProcessor A [`LogitsProcessor`] can be used to modify the prediction scores of a language model head for generation. - [[autodoc]] AlternatingCodebooksLogitsProcessor - __call__ @@ -177,8 +174,6 @@ generation. [[autodoc]] WatermarkLogitsProcessor - __call__ - - ## StoppingCriteria A [`StoppingCriteria`] can be used to change when to stop generation (other than EOS token). Please note that this is exclusively available to our PyTorch implementations. @@ -303,7 +298,6 @@ A [`Constraint`] can be used to force the generation to include specific tokens - to_legacy_cache - from_legacy_cache - ## Watermark Utils [[autodoc]] WatermarkingConfig diff --git a/docs/source/en/internal/import_utils.md b/docs/source/en/internal/import_utils.md index 77554c85b02a..153258198170 100644 --- a/docs/source/en/internal/import_utils.md +++ b/docs/source/en/internal/import_utils.md @@ -22,8 +22,8 @@ worked around. We don't want for all users of `transformers` to have to install we therefore mark those as soft dependencies rather than hard dependencies. The transformers toolkit is not made to error-out on import of a model that has a specific dependency; instead, an -object for which you are lacking a dependency will error-out when calling any method on it. As an example, if -`torchvision` isn't installed, the fast image processors will not be available. +object for which you are lacking a dependency will error-out when calling any method on it. As an example, if +`torchvision` isn't installed, the fast image processors will not be available. This object is still importable: @@ -55,7 +55,7 @@ All objects under a given filename have an automatic dependency to the tool link **Tokenizers**: All files starting with `tokenization_` and ending with `_fast` have an automatic `tokenizers` dependency -**Vision**: All files starting with `image_processing_` have an automatic dependency to the `vision` dependency group; +**Vision**: All files starting with `image_processing_` have an automatic dependency to the `vision` dependency group; at the time of writing, this only contains the `pillow` dependency. **Vision + Torch + Torchvision**: All files starting with `image_processing_` and ending with `_fast` have an automatic @@ -66,7 +66,7 @@ All of these automatic dependencies are added on top of the explicit dependencie ### Explicit Object Dependencies We add a method called `requires` that is used to explicitly specify the dependencies of a given object. As an -example, the `Trainer` class has two hard dependencies: `torch` and `accelerate`. Here is how we specify these +example, the `Trainer` class has two hard dependencies: `torch` and `accelerate`. Here is how we specify these required dependencies: ```python diff --git a/docs/source/en/internal/model_debugging_utils.md b/docs/source/en/internal/model_debugging_utils.md index cf2c0353fc7c..aa5371cd38e7 100644 --- a/docs/source/en/internal/model_debugging_utils.md +++ b/docs/source/en/internal/model_debugging_utils.md @@ -21,10 +21,8 @@ provides for it. Most of those are only useful if you are adding new models in the library. - ## Model addition debuggers - ### Model addition debugger - context manager for model adders This context manager is a power user tool intended for model adders. It tracks all forward calls within a model forward @@ -72,7 +70,6 @@ with model_addition_debugger_context( ``` - ### Reading results The debugger generates two files from the forward call, both with the same base name, but ending either with @@ -231,10 +228,8 @@ Once the forward passes of two models have been traced by the debugger, one can below: we can see slight differences between these two implementations' key projection layer. Inputs are mostly identical, but not quite. Looking through the file differences makes it easier to pinpoint which layer is wrong. - ![download-icon](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/files_difference_debugging.png) - ### Limitations and scope This feature will only work for torch-based models. Models relying heavily on external kernel calls may work, but trace will @@ -253,7 +248,7 @@ layers. This small util is a power user tool intended for model adders and maintainers. It lists all test methods existing in `test_modeling_common.py`, inherited by all model tester classes, and scans the repository to measure -how many tests are being skipped and for which models. +how many tests are being skipped and for which models. ### Rationale @@ -268,8 +263,7 @@ This utility: ![download-icon](https://huggingface.co/datasets/huggingface/documentation-images/resolve/f7f671f69b88ce4967e19179172c248958d35742/transformers/tests_skipped_visualisation.png) - -### Usage +### Usage You can run the skipped test analyzer in two ways: diff --git a/docs/source/en/internal/pipelines_utils.md b/docs/source/en/internal/pipelines_utils.md index 6ea6de9a61b8..23856e5639c3 100644 --- a/docs/source/en/internal/pipelines_utils.md +++ b/docs/source/en/internal/pipelines_utils.md @@ -20,7 +20,6 @@ This page lists all the utility functions the library provides for pipelines. Most of those are only useful if you are studying the code of the models in the library. - ## Argument handling [[autodoc]] pipelines.ArgumentHandler diff --git a/docs/source/en/kv_cache.md b/docs/source/en/kv_cache.md index f0a781cba4fc..a7c39a6a8d23 100644 --- a/docs/source/en/kv_cache.md +++ b/docs/source/en/kv_cache.md @@ -67,7 +67,7 @@ out = model.generate(**inputs, do_sample=False, max_new_tokens=20, past_key_valu ## Fixed-size cache -The default [`DynamicCache`] prevents you from taking advantage of most just-in-time (JIT) optimizations because the cache size isn't fixed. JIT optimizations enable you to maximize latency at the expense of memory usage. All of the following cache types are compatible with JIT optimizations like [torch.compile](./llm_optims#static-kv-cache-and-torchcompile) to accelerate generation. +The default [`DynamicCache`] prevents you from taking advantage of most just-in-time (JIT) optimizations because the cache size isn't fixed. JIT optimizations enable you to maximize latency at the expense of memory usage. All of the following cache types are compatible with JIT optimizations like [torch.compile](./llm_optims#static-kv-cache-and-torchcompile) to accelerate generation. A fixed-size cache ([`StaticCache`]) pre-allocates a specific maximum cache size for the kv pairs. You can generate up to the maximum cache size without needing to modify it. However, having a fixed (usually large) size for the key/value states means that while generating, a lot of tokens will actually be masked as they should not take part in the attention. So this trick allows to easily `compile` the decoding stage, but it incurs a waste of tokens in the attention computation. As all things, it's then a trade-off which should be very good if you generate with several sequence of more or less the same lengths, but may be sub-optimal if you have for example 1 very large sequence, and then only short sequences (as the fix cache size would be large, a lot would be wasted for the short sequences). Make sure you understand the impact if you use it! diff --git a/docs/source/en/llm_tutorial.md b/docs/source/en/llm_tutorial.md index 0f4f91d30a67..0cbbbc6ac04f 100644 --- a/docs/source/en/llm_tutorial.md +++ b/docs/source/en/llm_tutorial.md @@ -24,6 +24,7 @@ In Transformers, the [`~GenerationMixin.generate`] API handles text generation, > [!TIP] > You can also chat with a model directly from the command line. ([reference](./conversations.md#transformers)) +> > ```shell > transformers chat Qwen/Qwen2.5-0.5B-Instruct > ``` @@ -35,6 +36,7 @@ Before you begin, it's helpful to install [bitsandbytes](https://hf.co/docs/bits ```bash !pip install -U transformers bitsandbytes ``` + Bitsandbytes supports multiple backends in addition to CUDA-based GPUs. Refer to the multi-backend installation [guide](https://huggingface.co/docs/bitsandbytes/main/en/installation#multi-backend) to learn more. Load a LLM with [`~PreTrainedModel.from_pretrained`] and add the following two parameters to reduce the memory requirements. @@ -154,7 +156,6 @@ print(tokenizer.batch_decode(outputs, skip_special_tokens=True)) | `repetition_penalty` | `float` | Set it to `>1.0` if you're seeing the model repeat itself often. Larger values apply a larger penalty. | | `eos_token_id` | `list[int]` | The token(s) that will cause generation to stop. The default value is usually good, but you can specify a different token. | - ## Pitfalls The section below covers some common issues you may encounter during text generation and how to solve them. diff --git a/docs/source/en/llm_tutorial_optimization.md b/docs/source/en/llm_tutorial_optimization.md index 63d9308a84f4..04a61dd82cb5 100644 --- a/docs/source/en/llm_tutorial_optimization.md +++ b/docs/source/en/llm_tutorial_optimization.md @@ -66,6 +66,7 @@ If you have access to an 8 x 80GB A100 node, you could load BLOOM as follows ```bash !pip install transformers accelerate bitsandbytes optimum ``` + ```python from transformers import AutoModelForCausalLM @@ -98,6 +99,7 @@ result ``` **Output**: + ``` Here is a Python function that transforms bytes to Giga bytes:\n\n```python\ndef bytes_to_giga_bytes(bytes):\n return bytes / 1024 / 1024 / 1024\n```\n\nThis function takes a single ``` @@ -116,6 +118,7 @@ bytes_to_giga_bytes(torch.cuda.max_memory_allocated()) ``` **Output**: + ```bash 29.0260648727417 ``` @@ -127,7 +130,6 @@ Note that if we had tried to run the model in full float32 precision, a whopping If you are unsure in which format the model weights are stored on the Hub, you can always look into the checkpoint's config under `"dtype"`, *e.g.* [here](https://huggingface.co/meta-llama/Llama-2-7b-hf/blob/6fdf2e60f86ff2481f2241aaee459f85b5b0bbb9/config.json#L21). It is recommended to set the model to the same precision type as written in the config when loading with `from_pretrained(..., dtype=...)` except when the original type is float32 in which case one can use both `float16` or `bfloat16` for inference. - Let's define a `flush(...)` function to free all allocated memory so that we can accurately measure the peak allocated GPU memory. ```python @@ -148,6 +150,7 @@ Let's call it now for the next experiment. ```python flush() ``` + From the Accelerate library, you can also use a device-agnostic utility method called [release_memory](https://github.com/huggingface/accelerate/blob/29be4788629b772a3b722076e433b5b3b5c85da3/src/accelerate/utils/memory.py#L63), which takes various hardware backends like XPU, MLU, NPU, MPS, and more into account. ```python @@ -204,6 +207,7 @@ result ``` **Output**: + ``` Here is a Python function that transforms bytes to Giga bytes:\n\n```python\ndef bytes_to_giga_bytes(bytes):\n return bytes / 1024 / 1024 / 1024\n```\n\nThis function takes a single ``` @@ -215,6 +219,7 @@ bytes_to_giga_bytes(torch.cuda.max_memory_allocated()) ``` **Output**: + ``` 15.219234466552734 ``` @@ -222,8 +227,8 @@ bytes_to_giga_bytes(torch.cuda.max_memory_allocated()) Significantly less! We're down to just a bit over 15 GBs and could therefore run this model on consumer GPUs like the 4090. We're seeing a very nice gain in memory efficiency and more or less no degradation to the model's output. However, we can also notice a slight slow-down during inference. - We delete the models and flush the memory again. + ```python del model del pipe @@ -245,6 +250,7 @@ result ``` **Output**: + ``` Here is a Python function that transforms bytes to Giga bytes:\n\n```\ndef bytes_to_gigabytes(bytes):\n return bytes / 1024 / 1024 / 1024\n```\n\nThis function takes a single argument ``` @@ -256,6 +262,7 @@ bytes_to_giga_bytes(torch.cuda.max_memory_allocated()) ``` **Output**: + ``` 9.543574333190918 ``` @@ -270,6 +277,7 @@ Also note that inference here was again a bit slower compared to 8-bit quantizat del model del pipe ``` + ```python flush() ``` @@ -384,6 +392,7 @@ def alternating(list1, list2): ----- """ ``` + For demonstration purposes, we duplicate the system prompt by ten so that the input length is long enough to observe Flash Attention's memory savings. We append the original text prompt `"Question: Please write a function in Python that transforms bytes to Giga bytes.\n\nAnswer: Here"` @@ -413,6 +422,7 @@ result ``` **Output**: + ``` Generated in 10.96854019165039 seconds. Sure. Here is a function that does that.\n\ndef bytes_to_giga(bytes):\n return bytes / 1024 / 1024 / 1024\n\nAnswer: Sure. Here is a function that does that.\n\ndef @@ -429,6 +439,7 @@ bytes_to_giga_bytes(torch.cuda.max_memory_allocated()) ``` **Output**: + ```bash 37.668193340301514 ``` @@ -460,6 +471,7 @@ result ``` **Output**: + ``` Generated in 3.0211617946624756 seconds. Sure. Here is a function that does that.\n\ndef bytes_to_giga(bytes):\n return bytes / 1024 / 1024 / 1024\n\nAnswer: Sure. Here is a function that does that.\n\ndef @@ -474,6 +486,7 @@ bytes_to_giga_bytes(torch.cuda.max_memory_allocated()) ``` **Output**: + ``` 32.617331981658936 ``` @@ -604,6 +617,7 @@ generated_text ``` **Output**: + ``` shape of input_ids torch.Size([1, 21]) shape of input_ids torch.Size([1, 22]) @@ -641,6 +655,7 @@ generated_text ``` **Output**: + ``` shape of input_ids torch.Size([1, 1]) length of key-value cache 20 @@ -712,6 +727,7 @@ tokenizer.batch_decode(generation_output.sequences)[0][len(prompt):] ``` **Output**: + ``` is a modified version of the function that returns Mega bytes instead. @@ -733,6 +749,7 @@ config = model.config ``` **Output**: + ``` 7864320000 ``` @@ -773,7 +790,6 @@ The most notable application of GQA is [Llama-v2](https://huggingface.co/meta-ll > As a conclusion, it is strongly recommended to make use of either GQA or MQA if the LLM is deployed with auto-regressive decoding and is required to handle large input sequences as is the case for example for chat. - ## Conclusion The research community is constantly coming up with new, nifty ways to speed up inference time for ever-larger LLMs. As an example, one such promising research direction is [speculative decoding](https://huggingface.co/papers/2211.17192) where "easy tokens" are generated by smaller, faster language models and only "hard tokens" are generated by the LLM itself. Going into more detail is out of the scope of this notebook, but can be read upon in this [nice blog post](https://huggingface.co/blog/assisted-generation). diff --git a/docs/source/en/main_classes/callback.md b/docs/source/en/main_classes/callback.md index b29c9e7264ec..bc1413a94742 100644 --- a/docs/source/en/main_classes/callback.md +++ b/docs/source/en/main_classes/callback.md @@ -54,7 +54,6 @@ The main class that implements callbacks is [`TrainerCallback`]. It gets the Trainer's internal state via [`TrainerState`], and can take some actions on the training loop via [`TrainerControl`]. - ## Available Callbacks Here is the list of the available [`TrainerCallback`] in the library: diff --git a/docs/source/en/main_classes/configuration.md b/docs/source/en/main_classes/configuration.md index 0cfef06d3ce9..933621f6a144 100644 --- a/docs/source/en/main_classes/configuration.md +++ b/docs/source/en/main_classes/configuration.md @@ -24,7 +24,6 @@ Each derived config class implements model specific attributes. Common attribute `hidden_size`, `num_attention_heads`, and `num_hidden_layers`. Text models further implement: `vocab_size`. - ## PretrainedConfig [[autodoc]] PretrainedConfig diff --git a/docs/source/en/main_classes/data_collator.md b/docs/source/en/main_classes/data_collator.md index 2941338375be..33d156ec93fe 100644 --- a/docs/source/en/main_classes/data_collator.md +++ b/docs/source/en/main_classes/data_collator.md @@ -25,7 +25,6 @@ on the formed batch. Examples of use can be found in the [example scripts](../examples) or [example notebooks](../notebooks). - ## Default data collator [[autodoc]] data.data_collator.default_data_collator diff --git a/docs/source/en/main_classes/deepspeed.md b/docs/source/en/main_classes/deepspeed.md index 0b9e28656c09..b04949229da4 100644 --- a/docs/source/en/main_classes/deepspeed.md +++ b/docs/source/en/main_classes/deepspeed.md @@ -16,7 +16,7 @@ rendered properly in your Markdown viewer. # DeepSpeed -[DeepSpeed](https://github.com/deepspeedai/DeepSpeed), powered by Zero Redundancy Optimizer (ZeRO), is an optimization library for training and fitting very large models onto a GPU. It is available in several ZeRO stages, where each stage progressively saves more GPU memory by partitioning the optimizer state, gradients, parameters, and enabling offloading to a CPU or NVMe. DeepSpeed is integrated with the [`Trainer`] class and most of the setup is automatically taken care of for you. +[DeepSpeed](https://github.com/deepspeedai/DeepSpeed), powered by Zero Redundancy Optimizer (ZeRO), is an optimization library for training and fitting very large models onto a GPU. It is available in several ZeRO stages, where each stage progressively saves more GPU memory by partitioning the optimizer state, gradients, parameters, and enabling offloading to a CPU or NVMe. DeepSpeed is integrated with the [`Trainer`] class and most of the setup is automatically taken care of for you. However, if you want to use DeepSpeed without the [`Trainer`], Transformers provides a [`HfDeepSpeedConfig`] class. diff --git a/docs/source/en/main_classes/executorch.md b/docs/source/en/main_classes/executorch.md index 3178085c9135..3406309aa325 100644 --- a/docs/source/en/main_classes/executorch.md +++ b/docs/source/en/main_classes/executorch.md @@ -15,14 +15,12 @@ rendered properly in your Markdown viewer. --> - # ExecuTorch [`ExecuTorch`](https://github.com/pytorch/executorch) is an end-to-end solution for enabling on-device inference capabilities across mobile and edge devices including wearables, embedded devices and microcontrollers. It is part of the PyTorch ecosystem and supports the deployment of PyTorch models with a focus on portability, productivity, and performance. ExecuTorch introduces well defined entry points to perform model, device, and/or use-case specific optimizations such as backend delegation, user-defined compiler transformations, memory planning, and more. The first step in preparing a PyTorch model for execution on an edge device using ExecuTorch is to export the model. This is achieved through the use of a PyTorch API called [`torch.export`](https://pytorch.org/docs/stable/export.html). - ## ExecuTorch Integration An integration point is being developed to ensure that 🤗 Transformers can be exported using `torch.export`. The goal of this integration is not only to enable export but also to ensure that the exported artifact can be further lowered and optimized to run efficiently in `ExecuTorch`, particularly for mobile and edge use cases. diff --git a/docs/source/en/main_classes/feature_extractor.md b/docs/source/en/main_classes/feature_extractor.md index fd451a35481a..294ecad6309e 100644 --- a/docs/source/en/main_classes/feature_extractor.md +++ b/docs/source/en/main_classes/feature_extractor.md @@ -18,7 +18,6 @@ rendered properly in your Markdown viewer. A feature extractor is in charge of preparing input features for audio or vision models. This includes feature extraction from sequences, e.g., pre-processing audio files to generate Log-Mel Spectrogram features, feature extraction from images, e.g., cropping image files, but also padding, normalization, and conversion to NumPy and PyTorch tensors. - ## FeatureExtractionMixin [[autodoc]] feature_extraction_utils.FeatureExtractionMixin diff --git a/docs/source/en/main_classes/image_processor.md b/docs/source/en/main_classes/image_processor.md index 7dc9de60571f..61be0306630d 100644 --- a/docs/source/en/main_classes/image_processor.md +++ b/docs/source/en/main_classes/image_processor.md @@ -26,6 +26,7 @@ from transformers import AutoImageProcessor processor = AutoImageProcessor.from_pretrained("facebook/detr-resnet-50", use_fast=True) ``` + Note that `use_fast` will be set to `True` by default in a future release. When using a fast image processor, you can also set the `device` argument to specify the device on which the processing should be done. By default, the processing is done on the same device as the inputs if the inputs are tensors, or on the CPU otherwise. @@ -57,7 +58,6 @@ Here are some speed comparisons between the base and fast image processors for t These benchmarks were run on an [AWS EC2 g5.2xlarge instance](https://aws.amazon.com/ec2/instance-types/g5/), utilizing an NVIDIA A10G Tensor Core GPU. - ## ImageProcessingMixin [[autodoc]] image_processing_utils.ImageProcessingMixin @@ -72,7 +72,6 @@ These benchmarks were run on an [AWS EC2 g5.2xlarge instance](https://aws.amazon [[autodoc]] image_processing_utils.BaseImageProcessor - ## BaseImageProcessorFast [[autodoc]] image_processing_utils_fast.BaseImageProcessorFast diff --git a/docs/source/en/main_classes/logging.md b/docs/source/en/main_classes/logging.md index 5cbdf9ae27ed..34da2ac9d1b8 100644 --- a/docs/source/en/main_classes/logging.md +++ b/docs/source/en/main_classes/logging.md @@ -55,7 +55,6 @@ logger.info("INFO") logger.warning("WARN") ``` - All the methods of this logging module are documented below, the main ones are [`logging.get_verbosity`] to get the current level of verbosity in the logger and [`logging.set_verbosity`] to set the verbosity to the level of your choice. In order (from the least diff --git a/docs/source/en/main_classes/model.md b/docs/source/en/main_classes/model.md index d7768a905ce0..e3e77a8e2e13 100644 --- a/docs/source/en/main_classes/model.md +++ b/docs/source/en/main_classes/model.md @@ -26,7 +26,6 @@ file or directory, or from a pretrained model configuration provided by the libr The other methods that are common to each model are defined in [`~modeling_utils.ModuleUtilsMixin`] and [`~generation.GenerationMixin`]. - ## PreTrainedModel [[autodoc]] PreTrainedModel diff --git a/docs/source/en/main_classes/onnx.md b/docs/source/en/main_classes/onnx.md index 81d31c97e88d..5f8869948d2b 100644 --- a/docs/source/en/main_classes/onnx.md +++ b/docs/source/en/main_classes/onnx.md @@ -51,4 +51,3 @@ to export models for different types of topologies or tasks. ### FeaturesManager [[autodoc]] onnx.features.FeaturesManager - diff --git a/docs/source/en/main_classes/optimizer_schedules.md b/docs/source/en/main_classes/optimizer_schedules.md index 84d9ca7b907e..3bab249ab4ee 100644 --- a/docs/source/en/main_classes/optimizer_schedules.md +++ b/docs/source/en/main_classes/optimizer_schedules.md @@ -22,7 +22,6 @@ The `.optimization` module provides: - several schedules in the form of schedule objects that inherit from `_LRSchedule`: - a gradient accumulation class to accumulate the gradients of multiple batches - ## AdaFactor [[autodoc]] Adafactor diff --git a/docs/source/en/main_classes/output.md b/docs/source/en/main_classes/output.md index 295f99e21d10..8a9ae879fb19 100644 --- a/docs/source/en/main_classes/output.md +++ b/docs/source/en/main_classes/output.md @@ -47,7 +47,6 @@ However, this is not always the case. Some models apply normalization or subsequ - You can access each attribute as you would usually do, and if that attribute has not been returned by the model, you will get `None`. Here for instance `outputs.loss` is the loss computed by the model, and `outputs.attentions` is `None`. diff --git a/docs/source/en/main_classes/pipelines.md b/docs/source/en/main_classes/pipelines.md index 0e4cf55995bf..31139ddf429f 100644 --- a/docs/source/en/main_classes/pipelines.md +++ b/docs/source/en/main_classes/pipelines.md @@ -81,7 +81,6 @@ for out in tqdm(pipe(KeyDataset(dataset, "file"))): For ease of use, a generator is also possible: - ```python from transformers import pipeline @@ -196,7 +195,6 @@ This is a occasional very long sentence compared to the other. In that case, the tokens long, so the whole batch will be [64, 400] instead of [64, 4], leading to the high slowdown. Even worse, on bigger batches, the program simply crashes. - ``` ------------------------------ Streaming no batching @@ -245,7 +243,6 @@ multiple forward pass of a model. Under normal circumstances, this would yield i In order to circumvent this issue, both of these pipelines are a bit specific, they are `ChunkPipeline` instead of regular `Pipeline`. In short: - ```python preprocessed = pipe.preprocess(inputs) model_outputs = pipe.forward(preprocessed) @@ -254,7 +251,6 @@ outputs = pipe.postprocess(model_outputs) Now becomes: - ```python all_model_outputs = [] for preprocessed in pipe.preprocess(inputs): @@ -282,7 +278,6 @@ If you want to override a specific pipeline. Don't hesitate to create an issue for your task at hand, the goal of the pipeline is to be easy to use and support most cases, so `transformers` could maybe support your use case. - If you want to try simply you can: - Subclass your pipeline of choice @@ -302,7 +297,6 @@ my_pipeline = pipeline(model="xxxx", pipeline_class=MyPipeline) That should enable you to do all the custom code you want. - ## Implementing a pipeline [Implementing a new pipeline](../add_new_pipeline) @@ -329,7 +323,6 @@ Pipelines available for audio tasks include the following. - __call__ - all - ### ZeroShotAudioClassificationPipeline [[autodoc]] ZeroShotAudioClassificationPipeline diff --git a/docs/source/en/main_classes/processors.md b/docs/source/en/main_classes/processors.md index 2c2e0cd31b72..8863a6326282 100644 --- a/docs/source/en/main_classes/processors.md +++ b/docs/source/en/main_classes/processors.md @@ -71,7 +71,6 @@ Additionally, the following method can be used to load values from a data file a [[autodoc]] data.processors.glue.glue_convert_examples_to_features - ## XNLI [The Cross-Lingual NLI Corpus (XNLI)](https://www.nyu.edu/projects/bowman/xnli/) is a benchmark that evaluates the @@ -88,7 +87,6 @@ Please note that since the gold labels are available on the test set, evaluation An example using these processors is given in the [run_xnli.py](https://github.com/huggingface/transformers/tree/main/examples/pytorch/text-classification/run_xnli.py) script. - ## SQuAD [The Stanford Question Answering Dataset (SQuAD)](https://rajpurkar.github.io/SQuAD-explorer//) is a benchmark that @@ -115,11 +113,9 @@ Additionally, the following method can be used to convert SQuAD examples into [[autodoc]] data.processors.squad.squad_convert_examples_to_features - These processors as well as the aforementioned method can be used with files containing the data as well as with the *tensorflow_datasets* package. Examples are given below. - ### Example usage Here is an example using the processors as well as the conversion method using data files: diff --git a/docs/source/en/main_classes/tokenizer.md b/docs/source/en/main_classes/tokenizer.md index 83d2ae5df6a7..52c9751226d4 100644 --- a/docs/source/en/main_classes/tokenizer.md +++ b/docs/source/en/main_classes/tokenizer.md @@ -22,7 +22,7 @@ Rust library [🤗 Tokenizers](https://github.com/huggingface/tokenizers). The " 1. a significant speed-up in particular when doing batched tokenization and 2. additional methods to map between the original string (character and words) and the token space (e.g. getting the - index of the token comprising a given character or the span of characters corresponding to a given token). + index of the token comprising a given character or the span of characters corresponding to a given token). The base classes [`PreTrainedTokenizer`] and [`PreTrainedTokenizerFast`] implement the common methods for encoding string inputs in model inputs (see below) and instantiating/saving python and @@ -50,12 +50,11 @@ several advanced alignment methods which can be used to map between the original token space (e.g., getting the index of the token comprising a given character or the span of characters corresponding to a given token). - # Multimodal Tokenizer Apart from that each tokenizer can be a "multimodal" tokenizer which means that the tokenizer will hold all relevant special tokens as part of tokenizer attributes for easier access. For example, if the tokenizer is loaded from a vision-language model like LLaVA, you will -be able to access `tokenizer.image_token_id` to obtain the special image token used as a placeholder. +be able to access `tokenizer.image_token_id` to obtain the special image token used as a placeholder. To enable extra special tokens for any type of tokenizer, you have to add the following lines and save the tokenizer. Extra special tokens do not have to be modality related and can ne anything that the model often needs access to. In the below code, tokenizer at `output_dir` will have direct access diff --git a/docs/source/en/main_classes/video_processor.md b/docs/source/en/main_classes/video_processor.md index ee69030ab1a1..29d29d0cb605 100644 --- a/docs/source/en/main_classes/video_processor.md +++ b/docs/source/en/main_classes/video_processor.md @@ -22,7 +22,6 @@ The video processor extends the functionality of image processors by allowing Vi When adding a new VLM or updating an existing one to enable distinct video preprocessing, saving and reloading the processor configuration will store the video related arguments in a dedicated file named `video_preprocessing_config.json`. Don't worry if you haven't updated your VLM, the processor will try to load video related configurations from a file named `preprocessing_config.json`. - ### Usage Example Here's an example of how to load a video processor with [`llava-hf/llava-onevision-qwen2-0.5b-ov-hf`](https://huggingface.co/llava-hf/llava-onevision-qwen2-0.5b-ov-hf) model: @@ -59,7 +58,6 @@ The video processor can also sample video frames using the technique best suited - ```python from transformers import AutoVideoProcessor @@ -92,4 +90,3 @@ print(processed_video_inputs.pixel_values_videos.shape) ## BaseVideoProcessor [[autodoc]] video_processing_utils.BaseVideoProcessor - diff --git a/docs/source/en/model_doc/aimv2.md b/docs/source/en/model_doc/aimv2.md index 9d0abbaaf36b..acf9c4de12fe 100644 --- a/docs/source/en/model_doc/aimv2.md +++ b/docs/source/en/model_doc/aimv2.md @@ -25,7 +25,6 @@ The abstract from the paper is the following: *We introduce a novel method for pre-training of large-scale vision encoders. Building on recent advancements in autoregressive pre-training of vision models, we extend this framework to a multimodal setting, i.e., images and text. In this paper, we present AIMV2, a family of generalist vision encoders characterized by a straightforward pre-training process, scalability, and remarkable performance across a range of downstream tasks. This is achieved by pairing the vision encoder with a multimodal decoder that autoregressively generates raw image patches and text tokens. Our encoders excel not only in multimodal evaluations but also in vision benchmarks such as localization, grounding, and classification. Notably, our AIMV2-3B encoder achieves 89.5% accuracy on ImageNet-1k with a frozen trunk. Furthermore, AIMV2 consistently outperforms state-of-the-art contrastive models (e.g., CLIP, SigLIP) in multimodal image understanding across diverse settings.* - This model was contributed by [Yaswanth Gali](https://huggingface.co/yaswanthgali). The original code can be found [here](https://github.com/apple/ml-aim). diff --git a/docs/source/en/model_doc/aria.md b/docs/source/en/model_doc/aria.md index e5f4afa7b7ae..ddd0815aaa57 100644 --- a/docs/source/en/model_doc/aria.md +++ b/docs/source/en/model_doc/aria.md @@ -98,7 +98,7 @@ print(response) Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for more available quantization backends. - + The example below uses [torchao](../quantization/torchao) to only quantize the weights to int4 and the [rhymes-ai/Aria-sequential_mlp](https://huggingface.co/rhymes-ai/Aria-sequential_mlp) checkpoint. This checkpoint replaces grouped GEMM with `torch.nn.Linear` layers for easier quantization. ```py @@ -142,7 +142,6 @@ response = processor.decode(output_ids, skip_special_tokens=True) print(response) ``` - ## AriaImageProcessor [[autodoc]] AriaImageProcessor diff --git a/docs/source/en/model_doc/audio-spectrogram-transformer.md b/docs/source/en/model_doc/audio-spectrogram-transformer.md index 40115810467a..092bf3b26f38 100644 --- a/docs/source/en/model_doc/audio-spectrogram-transformer.md +++ b/docs/source/en/model_doc/audio-spectrogram-transformer.md @@ -52,13 +52,13 @@ the authors compute the stats for a downstream dataset. ### Using Scaled Dot Product Attention (SDPA) -PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function -encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the -[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) +PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function +encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the +[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) or the [GPU Inference](https://huggingface.co/docs/transformers/main/en/perf_infer_gpu_one#pytorch-scaled-dot-product-attention) page for more information. -SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set +SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set `attn_implementation="sdpa"` in `from_pretrained()` to explicitly request SDPA to be used. ``` diff --git a/docs/source/en/model_doc/auto.md b/docs/source/en/model_doc/auto.md index 2f8cbc2009b3..c1db5e2541a6 100644 --- a/docs/source/en/model_doc/auto.md +++ b/docs/source/en/model_doc/auto.md @@ -23,7 +23,6 @@ automatically retrieve the relevant model given the name/path to the pretrained Instantiating one of [`AutoConfig`], [`AutoModel`], and [`AutoTokenizer`] will directly create a class of the relevant architecture. For instance - ```python model = AutoModel.from_pretrained("google-bert/bert-base-cased") ``` diff --git a/docs/source/en/model_doc/aya_vision.md b/docs/source/en/model_doc/aya_vision.md index 1f02b30344a2..d0822173e898 100644 --- a/docs/source/en/model_doc/aya_vision.md +++ b/docs/source/en/model_doc/aya_vision.md @@ -29,7 +29,7 @@ You can find all the original Aya Vision checkpoints under the [Aya Vision](http > [!TIP] > This model was contributed by [saurabhdash](https://huggingface.co/saurabhdash) and [yonigozlan](https://huggingface.co/yonigozlan). -> +> > Click on the Aya Vision models in the right sidebar for more examples of how to apply Aya Vision to different image-to-text tasks. The example below demonstrates how to generate text based on an image with [`Pipeline`] or the [`AutoModel`] class. diff --git a/docs/source/en/model_doc/bark.md b/docs/source/en/model_doc/bark.md index a5787ab234ee..6024b0e83ed5 100644 --- a/docs/source/en/model_doc/bark.md +++ b/docs/source/en/model_doc/bark.md @@ -76,7 +76,7 @@ Note that 🤗 Optimum must be installed before using this feature. [Here's how Flash Attention 2 is an even faster, optimized version of the previous optimization. -##### Installation +##### Installation First, check whether your hardware is compatible with Flash Attention 2. The latest list of compatible hardware can be found in the [official documentation](https://github.com/Dao-AILab/flash-attention#installation-and-features). If your hardware is not compatible with Flash Attention 2, you can still benefit from attention kernel optimisations through Better Transformer support covered [above](https://huggingface.co/docs/transformers/main/en/model_doc/bark#using-better-transformer). @@ -86,7 +86,6 @@ Next, [install](https://github.com/Dao-AILab/flash-attention#installation-and-fe pip install -U flash-attn --no-build-isolation ``` - ##### Usage To load a model using Flash Attention 2, we can pass the `attn_implementation="flash_attention_2"` flag to [`.from_pretrained`](https://huggingface.co/docs/transformers/main/en/main_classes/model#transformers.PreTrainedModel.from_pretrained). We'll also load the model in half-precision (e.g. `torch.float16`), since it results in almost no degradation to audio quality but significantly lower memory usage and faster inference: @@ -97,7 +96,6 @@ model = BarkModel.from_pretrained("suno/bark-small", dtype=torch.float16, attn_i ##### Performance comparison - The following diagram shows the latency for the native attention implementation (no optimisation) against Better Transformer and Flash Attention 2. In all cases, we generate 400 semantic tokens on a 40GB A100 GPU with PyTorch 2.1. Flash Attention 2 is also consistently faster than Better Transformer, and its performance improves even more as batch sizes increase:
@@ -108,7 +106,6 @@ To put this into perspective, on an NVIDIA A100 and when generating 400 semantic At batch size 8, on an NVIDIA A100, Flash Attention 2 is also 10% faster than Better Transformer, and at batch size 16, 25%. - #### Combining optimization techniques You can combine optimization techniques, and use CPU offload, half-precision and Flash Attention 2 (or 🤗 Better Transformer) all at once. @@ -147,7 +144,7 @@ These presets are also uploaded in the hub [here](https://huggingface.co/suno/ba >>> audio_array = audio_array.cpu().numpy().squeeze() ``` -Bark can generate highly realistic, **multilingual** speech as well as other audio - including music, background noise and simple sound effects. +Bark can generate highly realistic, **multilingual** speech as well as other audio - including music, background noise and simple sound effects. ```python >>> # Multilingual speech - simplified Chinese @@ -165,7 +162,6 @@ Bark can generate highly realistic, **multilingual** speech as well as other aud The model can also produce **nonverbal communications** like laughing, sighing and crying. - ```python >>> # Adding non-speech cues to the input text >>> inputs = processor("Hello uh ... [clears throat], my dog is cute [laughter]") @@ -235,4 +231,3 @@ To save the audio, simply take the sample rate from the model config and some sc [[autodoc]] BarkSemanticConfig - all - diff --git a/docs/source/en/model_doc/bart.md b/docs/source/en/model_doc/bart.md index d1eeafb82b23..f81eaae98fb3 100644 --- a/docs/source/en/model_doc/bart.md +++ b/docs/source/en/model_doc/bart.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2019-10-29 and added to Hugging Face Transformers on 2020-11-16.* -
PyTorch @@ -46,6 +45,7 @@ pipeline = pipeline( pipeline("Plants create through a process known as photosynthesis.") ``` + diff --git a/docs/source/en/model_doc/barthez.md b/docs/source/en/model_doc/barthez.md index 43b6521f1013..f7a100a4208c 100644 --- a/docs/source/en/model_doc/barthez.md +++ b/docs/source/en/model_doc/barthez.md @@ -31,7 +31,6 @@ You can find all of the original BARThez checkpoints under the [BARThez](https:/ > This model was contributed by [moussakam](https://huggingface.co/moussakam). > Refer to the [BART](./bart) docs for more usage examples. - The example below demonstrates how to predict the `` token with [`Pipeline`], [`AutoModel`], and from the command line. diff --git a/docs/source/en/model_doc/bartpho.md b/docs/source/en/model_doc/bartpho.md index 9e86a1b615d0..15e96c57669f 100644 --- a/docs/source/en/model_doc/bartpho.md +++ b/docs/source/en/model_doc/bartpho.md @@ -33,12 +33,9 @@ You can find all the original checkpoints under the [VinAI](https://huggingface. The example below demonstrates how to summarize text with [`Pipeline`] or the [`AutoModel`] class. - - - ```python import torch from transformers import pipeline @@ -98,8 +95,6 @@ transformers run --task summarization --model vinai/bartpho-word --device 0 - - ## Notes - BARTpho uses the large architecture of BART with an additional layer-normalization layer on top of the encoder and decoder. The BART-specific classes should be replaced with the mBART-specific classes. diff --git a/docs/source/en/model_doc/bert-japanese.md b/docs/source/en/model_doc/bert-japanese.md index 812e5a455ad5..6599efa73e08 100644 --- a/docs/source/en/model_doc/bert-japanese.md +++ b/docs/source/en/model_doc/bert-japanese.md @@ -81,7 +81,6 @@ API reference information. - ## BertJapaneseTokenizer [[autodoc]] BertJapaneseTokenizer diff --git a/docs/source/en/model_doc/bertweet.md b/docs/source/en/model_doc/bertweet.md index 6488e197d212..223932877c0a 100644 --- a/docs/source/en/model_doc/bertweet.md +++ b/docs/source/en/model_doc/bertweet.md @@ -26,7 +26,6 @@ rendered properly in your Markdown viewer. [BERTweet](https://huggingface.co/papers/2005.10200) shares the same architecture as [BERT-base](./bert), but it’s pretrained like [RoBERTa](./roberta) on English Tweets. It performs really well on Tweet-related tasks like part-of-speech tagging, named entity recognition, and text classification. - You can find all the original BERTweet checkpoints under the [VinAI Research](https://huggingface.co/vinai?search_models=BERTweet) organization. > [!TIP] @@ -49,6 +48,7 @@ pipeline = pipeline( ) pipeline("Plants create through a process known as photosynthesis.") ``` + diff --git a/docs/source/en/model_doc/big_bird.md b/docs/source/en/model_doc/big_bird.md index 5e431c6883d0..877445a4ba58 100644 --- a/docs/source/en/model_doc/big_bird.md +++ b/docs/source/en/model_doc/big_bird.md @@ -47,6 +47,7 @@ pipeline = pipeline( ) pipeline("Plants create [MASK] through a process known as photosynthesis.") ``` + @@ -81,6 +82,7 @@ print(f"The predicted token is: {predicted_token}") ```bash !echo -e "Plants create [MASK] through a process known as photosynthesis." | transformers run --task fill-mask --model google/bigbird-roberta-base --device 0 ``` + diff --git a/docs/source/en/model_doc/bigbird_pegasus.md b/docs/source/en/model_doc/bigbird_pegasus.md index fe3241ed7ab6..cfc55e361e77 100644 --- a/docs/source/en/model_doc/bigbird_pegasus.md +++ b/docs/source/en/model_doc/bigbird_pegasus.md @@ -52,6 +52,7 @@ Through photosynthesis, plants capture energy from sunlight using a green pigmen These ingredients are then transformed into glucose, a type of sugar that serves as a source of chemical energy, and oxygen, which is released as a byproduct into the atmosphere. The glucose produced during photosynthesis is not just used immediately; plants also store it as starch or convert it into other organic compounds like cellulose, which is essential for building their cellular structure. This energy reserve allows them to grow, develop leaves, produce flowers, bear fruit, and carry out various physiological processes throughout their lifecycle.""") ``` + @@ -77,6 +78,7 @@ input_ids = tokenizer(input_text, return_tensors="pt").to(model.device) output = model.generate(**input_ids, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + diff --git a/docs/source/en/model_doc/biogpt.md b/docs/source/en/model_doc/biogpt.md index 4676a440c751..9a664fa288f3 100644 --- a/docs/source/en/model_doc/biogpt.md +++ b/docs/source/en/model_doc/biogpt.md @@ -135,31 +135,26 @@ print(output) [[autodoc]] BioGptConfig - ## BioGptTokenizer [[autodoc]] BioGptTokenizer - save_vocabulary - ## BioGptModel [[autodoc]] BioGptModel - forward - ## BioGptForCausalLM [[autodoc]] BioGptForCausalLM - forward - ## BioGptForTokenClassification [[autodoc]] BioGptForTokenClassification - forward - ## BioGptForSequenceClassification [[autodoc]] BioGptForSequenceClassification diff --git a/docs/source/en/model_doc/bitnet.md b/docs/source/en/model_doc/bitnet.md index 6946ec65d437..69f9cb75131f 100644 --- a/docs/source/en/model_doc/bitnet.md +++ b/docs/source/en/model_doc/bitnet.md @@ -35,10 +35,8 @@ Several versions of the model weights are available on Hugging Face: * [**`microsoft/bitnet-b1.58-2B-4T-gguf`**](https://huggingface.co/microsoft/bitnet-b1.58-2B-4T-gguf): Contains the model weights in GGUF format, compatible with the `bitnet.cpp` library for CPU inference. - ### Model Details - * **Architecture:** Transformer-based, modified with `BitLinear` layers (BitNet framework). * Uses Rotary Position Embeddings (RoPE). * Uses squared ReLU (ReLU²) activation in FFN layers. @@ -58,10 +56,8 @@ Several versions of the model weights are available on Hugging Face: 3. **Direct Preference Optimization (DPO):** Aligned with human preferences using preference pairs. * **Tokenizer:** LLaMA 3 Tokenizer (vocab size: 128,256). - ## Usage tips - **VERY IMPORTANT NOTE ON EFFICIENCY** > Please do NOT expect performance efficiency gains (in terms of speed, latency, or energy consumption) when using this model with the standard transformers library. @@ -106,7 +102,6 @@ response = tokenizer.decode(chat_outputs[0][chat_input.shape[-1]:], skip_special print("\nAssistant Response:", response) ``` - ## BitNetConfig [[autodoc]] BitNetConfig diff --git a/docs/source/en/model_doc/blenderbot-small.md b/docs/source/en/model_doc/blenderbot-small.md index 1967013208b0..830db710e039 100644 --- a/docs/source/en/model_doc/blenderbot-small.md +++ b/docs/source/en/model_doc/blenderbot-small.md @@ -55,7 +55,6 @@ found [here](https://github.com/facebookresearch/ParlAI). Blenderbot Small is a model with absolute position embeddings so it's usually advised to pad the inputs on the right rather than the left. - ## Resources - [Causal language modeling task guide](../tasks/language_modeling) diff --git a/docs/source/en/model_doc/blenderbot.md b/docs/source/en/model_doc/blenderbot.md index 99149c5d948f..168c744235d8 100644 --- a/docs/source/en/model_doc/blenderbot.md +++ b/docs/source/en/model_doc/blenderbot.md @@ -71,7 +71,6 @@ An example: `facebook/blenderbot_small_90M`, have a different architecture and consequently should be used with [BlenderbotSmall](blenderbot-small). - ## Resources - [Causal language modeling task guide](../tasks/language_modeling) diff --git a/docs/source/en/model_doc/blip-2.md b/docs/source/en/model_doc/blip-2.md index fe4e939c2dc8..faaaee7b0840 100644 --- a/docs/source/en/model_doc/blip-2.md +++ b/docs/source/en/model_doc/blip-2.md @@ -26,14 +26,14 @@ rendered properly in your Markdown viewer. The BLIP-2 model was proposed in [BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models](https://huggingface.co/papers/2301.12597) by Junnan Li, Dongxu Li, Silvio Savarese, Steven Hoi. BLIP-2 leverages frozen pre-trained image encoders and large language models (LLMs) by training a lightweight, 12-layer Transformer encoder in between them, achieving state-of-the-art performance on various vision-language tasks. Most notably, BLIP-2 improves upon [Flamingo](https://huggingface.co/papers/2204.14198), an 80 billion parameter model, by 8.7% -on zero-shot VQAv2 with 54x fewer trainable parameters. +on zero-shot VQAv2 with 54x fewer trainable parameters. The abstract from the paper is the following: *The cost of vision-and-language pre-training has become increasingly prohibitive due to end-to-end training of large-scale models. This paper proposes BLIP-2, a generic and efficient pre-training strategy that bootstraps vision-language pre-training from off-the-shelf frozen pre-trained image encoders and frozen large language models. BLIP-2 bridges the modality gap with a lightweight Querying Transformer, which is pre-trained in two stages. The first stage bootstraps vision-language representation learning from a frozen image encoder. The second stage bootstraps vision-to-language generative learning from a frozen language model. BLIP-2 achieves state-of-the-art performance on various vision-language tasks, despite having significantly fewer trainable parameters than existing methods. For example, our model outperforms Flamingo80B by 8.7% on zero-shot VQAv2 with 54x fewer trainable parameters. We also demonstrate the model's emerging capabilities of zero-shot image-to-text generation that can follow natural language instructions.* +alt="drawing" width="600"/> BLIP-2 architecture. Taken from the original paper. diff --git a/docs/source/en/model_doc/blip.md b/docs/source/en/model_doc/blip.md index 13a2a5731a5f..5ef787289966 100644 --- a/docs/source/en/model_doc/blip.md +++ b/docs/source/en/model_doc/blip.md @@ -25,7 +25,6 @@ rendered properly in your Markdown viewer. [BLIP](https://huggingface.co/papers/2201.12086) (Bootstrapped Language-Image Pretraining) is a vision-language pretraining (VLP) framework designed for *both* understanding and generation tasks. Most existing pretrained models are only good at one or the other. It uses a captioner to generate captions and a filter to remove the noisy captions. This increases training data quality and more effectively uses the messy web data. - You can find all the original BLIP checkpoints under the [BLIP](https://huggingface.co/collections/Salesforce/blip-models-65242f40f1491fbf6a9e9472) collection. > [!TIP] diff --git a/docs/source/en/model_doc/bloom.md b/docs/source/en/model_doc/bloom.md index 805379338e32..c78cb4447ebf 100644 --- a/docs/source/en/model_doc/bloom.md +++ b/docs/source/en/model_doc/bloom.md @@ -48,7 +48,6 @@ See also: - [Token classification task guide](../tasks/token_classification) - [Question answering task guide](../tasks/question_answering) - ⚡️ Inference - A blog on [Optimization story: Bloom inference](https://huggingface.co/blog/bloom-inference-optimization). - A blog on [Incredibly Fast BLOOM Inference with DeepSpeed and Accelerate](https://huggingface.co/blog/bloom-inference-pytorch-scripts). diff --git a/docs/source/en/model_doc/blt.md b/docs/source/en/model_doc/blt.md index 0289f77ac901..7e9052bcdd2e 100644 --- a/docs/source/en/model_doc/blt.md +++ b/docs/source/en/model_doc/blt.md @@ -83,7 +83,6 @@ print(tokenizer.decode(generated_ids[0])) This model was contributed by [itazap](https://huggingface.co/). The original code can be found [here](). - ## BltConfig [[autodoc]] BltConfig diff --git a/docs/source/en/model_doc/bridgetower.md b/docs/source/en/model_doc/bridgetower.md index 6a2b09e263ab..861dd32c16fe 100644 --- a/docs/source/en/model_doc/bridgetower.md +++ b/docs/source/en/model_doc/bridgetower.md @@ -26,7 +26,7 @@ rendered properly in your Markdown viewer. The BridgeTower model was proposed in [BridgeTower: Building Bridges Between Encoders in Vision-Language Representative Learning](https://huggingface.co/papers/2206.08657) by Xiao Xu, Chenfei Wu, Shachar Rosenman, Vasudev Lal, Wanxiang Che, Nan Duan. The goal of this model is to build a bridge between each uni-modal encoder and the cross-modal encoder to enable comprehensive and detailed interaction at each layer of the cross-modal encoder thus achieving remarkable performance on various downstream tasks with almost negligible additional performance and computational costs. -This paper has been accepted to the [AAAI'23](https://aaai.org/Conferences/AAAI-23/) conference. +This paper has been accepted to the [AAAI'23](https://aaai.org/Conferences/AAAI-23/) conference. The abstract from the paper is the following: @@ -54,6 +54,7 @@ The [`BridgeTowerProcessor`] wraps [`RobertaTokenizer`] and [`BridgeTowerImagePr encode the text and prepare the images respectively. The following example shows how to run contrastive learning using [`BridgeTowerProcessor`] and [`BridgeTowerForContrastiveLearning`]. + ```python >>> from transformers import BridgeTowerProcessor, BridgeTowerForContrastiveLearning >>> import requests @@ -76,6 +77,7 @@ The following example shows how to run contrastive learning using [`BridgeTowerP ``` The following example shows how to run image-text retrieval using [`BridgeTowerProcessor`] and [`BridgeTowerForImageAndTextRetrieval`]. + ```python >>> from transformers import BridgeTowerProcessor, BridgeTowerForImageAndTextRetrieval >>> import requests @@ -130,7 +132,6 @@ Tips: - Please refer to [Table 5](https://huggingface.co/papers/2206.08657) for BridgeTower's performance on Image Retrieval and other down stream tasks. - The PyTorch version of this model is only available in torch 1.10 and higher. - ## BridgeTowerConfig [[autodoc]] BridgeTowerConfig @@ -177,4 +178,3 @@ Tips: [[autodoc]] BridgeTowerForImageAndTextRetrieval - forward - diff --git a/docs/source/en/model_doc/bros.md b/docs/source/en/model_doc/bros.md index aeb3dd76e52b..4ef3d3737ae2 100644 --- a/docs/source/en/model_doc/bros.md +++ b/docs/source/en/model_doc/bros.md @@ -57,7 +57,6 @@ def expand_and_normalize_bbox(bboxes, doc_width, doc_height): - [`~transformers.BrosForTokenClassification.forward`, `~transformers.BrosSpadeEEForTokenClassification.forward`, `~transformers.BrosSpadeEEForTokenClassification.forward`] require not only `input_ids` and `bbox` but also `box_first_token_mask` for loss calculation. It is a mask to filter out non-first tokens of each box. You can obtain this mask by saving start token indices of bounding boxes when creating `input_ids` from words. You can make `box_first_token_mask` with following code, - ```python def make_box_first_token_mask(bboxes, words, tokenizer, max_seq_length=512): @@ -102,7 +101,6 @@ def make_box_first_token_mask(bboxes, words, tokenizer, max_seq_length=512): [[autodoc]] BrosModel - forward - ## BrosForTokenClassification [[autodoc]] BrosForTokenClassification diff --git a/docs/source/en/model_doc/camembert.md b/docs/source/en/model_doc/camembert.md index ddce66f2dedb..971954ed52a1 100644 --- a/docs/source/en/model_doc/camembert.md +++ b/docs/source/en/model_doc/camembert.md @@ -50,6 +50,7 @@ from transformers import pipeline pipeline = pipeline("fill-mask", model="camembert-base", dtype=torch.float16, device=0) pipeline("Le camembert est un délicieux fromage .") ``` + @@ -72,6 +73,7 @@ predicted_token = tokenizer.decode(predicted_token_id) print(f"The predicted token is: {predicted_token}") ``` + @@ -84,7 +86,6 @@ echo -e "Le camembert est un délicieux fromage ." | transformers run --ta - Quantization reduces the memory burden of large models by representing weights in lower precision. Refer to the [Quantization](../quantization/overview) overview for available options. The example below uses [bitsandbytes](../quantization/bitsandbytes) quantization to quantize the weights to 8-bits. diff --git a/docs/source/en/model_doc/canine.md b/docs/source/en/model_doc/canine.md index 4e46e943c8e9..53691dcbc22c 100644 --- a/docs/source/en/model_doc/canine.md +++ b/docs/source/en/model_doc/canine.md @@ -86,6 +86,7 @@ echo -e "Plant create energy through a process known as photosynthesis." | trans inputs = ["Life is like a box of chocolates.", "You never know what you gonna get."] encoding = tokenizer(inputs, padding="longest", truncation=True, return_tensors="pt") ``` + - CANINE is primarily designed to be fine-tuned on a downstream task. The pretrained model can be used for either masked language modeling or next sentence prediction. ## CanineConfig diff --git a/docs/source/en/model_doc/chameleon.md b/docs/source/en/model_doc/chameleon.md index eb71349115ed..dc573faa1112 100644 --- a/docs/source/en/model_doc/chameleon.md +++ b/docs/source/en/model_doc/chameleon.md @@ -28,7 +28,6 @@ rendered properly in your Markdown viewer. The Chameleon model was proposed in [Chameleon: Mixed-Modal Early-Fusion Foundation Models ](https://huggingface.co/papers/2405.09818) by META AI Chameleon Team. Chameleon is a Vision-Language Model that use vector quantization to tokenize images which enables the model to generate multimodal output. The model takes images and texts as input, including an interleaved format, and generates textual response. Image generation module is not released yet. - The abstract from the paper is the following: *We present Chameleon, a family of early-fusion token-based mixed-modal models capable of understanding and generating images and text in any arbitrary sequence. We outline a stable training @@ -43,7 +42,6 @@ including Gemini Pro and GPT-4V, according to human judgments on a new long-form generation evaluation, where either the prompt or outputs contain mixed sequences of both images and text. Chameleon marks a significant step forward in unified modeling of full multimodal documents* - drawing @@ -52,7 +50,6 @@ alt="drawing" width="600"/> This model was contributed by [joaogante](https://huggingface.co/joaogante) and [RaushanTurganbay](https://huggingface.co/RaushanTurganbay). The original code can be found [here](https://github.com/facebookresearch/chameleon). - ## Usage tips - We advise users to use `padding_side="left"` when computing batched generation as it leads to more accurate results. Simply make sure to set `processor.tokenizer.padding_side = "left"` before generating. diff --git a/docs/source/en/model_doc/clipseg.md b/docs/source/en/model_doc/clipseg.md index e27d49ffe484..7ca9b3926ac9 100644 --- a/docs/source/en/model_doc/clipseg.md +++ b/docs/source/en/model_doc/clipseg.md @@ -47,7 +47,7 @@ can be formulated. Finally, we find our system to adapt well to generalized queries involving affordances or properties* +alt="drawing" width="600"/> CLIPSeg overview. Taken from the original paper. diff --git a/docs/source/en/model_doc/clvp.md b/docs/source/en/model_doc/clvp.md index 926438a3c1f5..eead4a546435 100644 --- a/docs/source/en/model_doc/clvp.md +++ b/docs/source/en/model_doc/clvp.md @@ -29,29 +29,25 @@ The abstract from the paper is the following: *In recent years, the field of image generation has been revolutionized by the application of autoregressive transformers and DDPMs. These approaches model the process of image generation as a step-wise probabilistic processes and leverage large amounts of compute and data to learn the image distribution. This methodology of improving performance need not be confined to images. This paper describes a way to apply advances in the image generative domain to speech synthesis. The result is TorToise - an expressive, multi-voice text-to-speech system.* - This model was contributed by [Susnato Dhar](https://huggingface.co/susnato). The original code can be found [here](https://github.com/neonbjb/tortoise-tts). - ## Usage tips 1. CLVP is an integral part of the Tortoise TTS model. 2. CLVP can be used to compare different generated speech candidates with the provided text, and the best speech tokens are forwarded to the diffusion model. 3. The use of the [`ClvpModelForConditionalGeneration.generate()`] method is strongly recommended for tortoise usage. -4. Note that the CLVP model expects the audio to be sampled at 22.05 kHz contrary to other audio models which expects 16 kHz. - +4. Note that the CLVP model expects the audio to be sampled at 22.05 kHz contrary to other audio models which expects 16 kHz. ## Brief Explanation: - The [`ClvpTokenizer`] tokenizes the text input, and the [`ClvpFeatureExtractor`] extracts the log mel-spectrogram from the desired audio. - [`ClvpConditioningEncoder`] takes those text tokens and audio representations and converts them into embeddings conditioned on the text and audio. - The [`ClvpForCausalLM`] uses those embeddings to generate multiple speech candidates. -- Each speech candidate is passed through the speech encoder ([`ClvpEncoder`]) which converts them into a vector representation, and the text encoder ([`ClvpEncoder`]) converts the text tokens into the same latent space. -- At the end, we compare each speech vector with the text vector to see which speech vector is most similar to the text vector. +- Each speech candidate is passed through the speech encoder ([`ClvpEncoder`]) which converts them into a vector representation, and the text encoder ([`ClvpEncoder`]) converts the text tokens into the same latent space. +- At the end, we compare each speech vector with the text vector to see which speech vector is most similar to the text vector. - [`ClvpModelForConditionalGeneration.generate()`] compresses all of the logic described above into a single method. - Example : ```python @@ -74,7 +70,6 @@ Example : >>> generated_output = model.generate(**processor_output) ``` - ## ClvpConfig [[autodoc]] ClvpConfig @@ -128,4 +123,3 @@ Example : ## ClvpDecoder [[autodoc]] ClvpDecoder - diff --git a/docs/source/en/model_doc/code_llama.md b/docs/source/en/model_doc/code_llama.md index 60e9cb4c3cf2..a46e1f05b32a 100644 --- a/docs/source/en/model_doc/code_llama.md +++ b/docs/source/en/model_doc/code_llama.md @@ -143,6 +143,7 @@ visualizer("""def func(a, b): - Infilling is only available in the 7B and 13B base models, and not in the Python, Instruct, 34B, or 70B models. - Use the `` token where you want your input to be filled. The tokenizer splits this token to create a formatted input string that follows the [original training pattern](https://github.com/facebookresearch/codellama/blob/cb51c14ec761370ba2e2bc351374a79265d0465e/llama/generation.py#L402). This is more robust than preparing the pattern yourself. + ```py from transformers import LlamaForCausalLM, CodeLlamaTokenizer @@ -158,6 +159,7 @@ visualizer("""def func(a, b): filling = tokenizer.batch_decode(generated_ids[:, input_ids.shape[1]:], skip_special_tokens = True)[0] print(PROMPT.replace("", filling)) ``` + - Use `bfloat16` for further training or fine-tuning and `float16` for inference. - The `BOS` character is not used for infilling when encoding the prefix or suffix, but only at the beginning of each prompt. - The tokenizer is a byte-pair encoding model based on [SentencePiece](https://github.com/google/sentencepiece). During decoding, if the first token is the start of the word (for example, “Banana”), the tokenizer doesn’t prepend the prefix space to the string. diff --git a/docs/source/en/model_doc/codegen.md b/docs/source/en/model_doc/codegen.md index e5ad3863b67c..c341154921e3 100644 --- a/docs/source/en/model_doc/codegen.md +++ b/docs/source/en/model_doc/codegen.md @@ -29,7 +29,7 @@ CodeGen is an autoregressive language model for program synthesis trained sequen The abstract from the paper is the following: -*Program synthesis strives to generate a computer program as a solution to a given problem specification. We propose a conversational program synthesis approach via large language models, which addresses the challenges of searching over a vast program space and user intent specification faced in prior approaches. Our new approach casts the process of writing a specification and program as a multi-turn conversation between a user and a system. It treats program synthesis as a sequence prediction problem, in which the specification is expressed in natural language and the desired program is conditionally sampled. We train a family of large language models, called CodeGen, on natural language and programming language data. With weak supervision in the data and the scaling up of data size and model size, conversational capacities emerge from the simple autoregressive language modeling. To study the model behavior on conversational program synthesis, we develop a multi-turn programming benchmark (MTPB), where solving each problem requires multi-step synthesis via multi-turn conversation between the user and the model. Our findings show the emergence of conversational capabilities and the effectiveness of the proposed conversational program synthesis paradigm. In addition, our model CodeGen (with up to 16B parameters trained on TPU-v4) outperforms OpenAI's Codex on the HumanEval benchmark. We make the training library JaxFormer including checkpoints available as open source contribution: [this https URL](https://github.com/salesforce/codegen).* +*Program synthesis strives to generate a computer program as a solution to a given problem specification. We propose a conversational program synthesis approach via large language models, which addresses the challenges of searching over a vast program space and user intent specification faced in prior approaches. Our new approach casts the process of writing a specification and program as a multi-turn conversation between a user and a system. It treats program synthesis as a sequence prediction problem, in which the specification is expressed in natural language and the desired program is conditionally sampled. We train a family of large language models, called CodeGen, on natural language and programming language data. With weak supervision in the data and the scaling up of data size and model size, conversational capacities emerge from the simple autoregressive language modeling. To study the model behavior on conversational program synthesis, we develop a multi-turn programming benchmark (MTPB), where solving each problem requires multi-step synthesis via multi-turn conversation between the user and the model. Our findings show the emergence of conversational capabilities and the effectiveness of the proposed conversational program synthesis paradigm. In addition, our model CodeGen (with up to 16B parameters trained on TPU-v4) outperforms OpenAI's Codex on the HumanEval benchmark. We make the training library JaxFormer including checkpoints available as open source contribution: [this https URL](https://github.com/salesforce/codegen).* This model was contributed by [Hiroaki Hayashi](https://huggingface.co/rooa). The original code can be found [here](https://github.com/salesforce/codegen). @@ -39,7 +39,7 @@ The original code can be found [here](https://github.com/salesforce/codegen). * CodeGen model [checkpoints](https://huggingface.co/models?other=codegen) are available on different pre-training data with variable sizes. * The format is: `Salesforce/codegen-{size}-{data}`, where * `size`: `350M`, `2B`, `6B`, `16B` - * `data`: + * `data`: * `nl`: Pre-trained on the Pile * `multi`: Initialized with `nl`, then further pre-trained on multiple programming languages data * `mono`: Initialized with `multi`, then further pre-trained on Python data diff --git a/docs/source/en/model_doc/cohere.md b/docs/source/en/model_doc/cohere.md index 9fc6d266d69a..b8ccf20706af 100644 --- a/docs/source/en/model_doc/cohere.md +++ b/docs/source/en/model_doc/cohere.md @@ -22,14 +22,12 @@ rendered properly in your Markdown viewer.
- # Cohere Cohere [Command-R](https://cohere.com/blog/command-r) is a 35B parameter multilingual large language model designed for long context tasks like retrieval-augmented generation (RAG) and calling external APIs and tools. The model is specifically trained for grounded generation and supports both single-step and multi-step tool use. It supports a context length of 128K tokens. You can find all the original Command-R checkpoints under the [Command Models](https://huggingface.co/collections/CohereForAI/command-models-67652b401665205e17b192ad) collection. - > [!TIP] > Click on the Cohere models in the right sidebar for more examples of how to apply Cohere to different language tasks. @@ -123,7 +121,6 @@ visualizer("Plants create energy through a process known as")
- ## Notes - Don’t use the dtype parameter in [`~AutoModel.from_pretrained`] if you’re using FlashAttention-2 because it only supports fp16 or bf16. You should use [Automatic Mixed Precision](https://pytorch.org/tutorials/recipes/recipes/amp_recipe.html), set fp16 or bf16 to True if using [`Trainer`], or use [torch.autocast](https://pytorch.org/docs/stable/amp.html#torch.autocast). @@ -145,7 +142,6 @@ visualizer("Plants create energy through a process known as") [[autodoc]] CohereModel - forward - ## CohereForCausalLM [[autodoc]] CohereForCausalLM diff --git a/docs/source/en/model_doc/cohere2.md b/docs/source/en/model_doc/cohere2.md index b1edcf8c8517..ed94fef1da13 100644 --- a/docs/source/en/model_doc/cohere2.md +++ b/docs/source/en/model_doc/cohere2.md @@ -22,7 +22,6 @@ rendered properly in your Markdown viewer. - # Cohere 2 [Cohere Command R7B](https://cohere.com/blog/command-r7b) is an open weights research release of a 7B billion parameter model. It is a multilingual model trained on 23 languages and has a context window of 128k. The model features three layers with sliding window attention and ROPE for efficient local context modeling and relative positional encoding. A fourth layer uses global attention without positional embeddings, enabling unrestricted token interactions across the entire sequence. @@ -31,7 +30,6 @@ This model is optimized for speed, cost-performance, and compute resources. You can find all the original Command-R checkpoints under the [Command Models](https://huggingface.co/collections/CohereForAI/command-models-67652b401665205e17b192ad) collection. - > [!TIP] > Click on the Cohere models in the right sidebar for more examples of how to apply Cohere to different language tasks. @@ -136,7 +134,6 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) [[autodoc]] Cohere2Model - forward - ## Cohere2ForCausalLM [[autodoc]] Cohere2ForCausalLM diff --git a/docs/source/en/model_doc/cohere2_vision.md b/docs/source/en/model_doc/cohere2_vision.md index 2e12ff3e4767..e466ce6a5f09 100644 --- a/docs/source/en/model_doc/cohere2_vision.md +++ b/docs/source/en/model_doc/cohere2_vision.md @@ -113,6 +113,7 @@ outputs = pipe(text=messages, max_new_tokens=300, return_full_text=False) print(outputs) ``` + diff --git a/docs/source/en/model_doc/cpm.md b/docs/source/en/model_doc/cpm.md index ccfa1596bad4..275f5629db13 100644 --- a/docs/source/en/model_doc/cpm.md +++ b/docs/source/en/model_doc/cpm.md @@ -42,7 +42,6 @@ NLP tasks in the settings of few-shot (even zero-shot) learning.* This model was contributed by [canwenxu](https://huggingface.co/canwenxu). The original implementation can be found here: https://github.com/TsinghuaAI/CPM-Generate - CPM's architecture is the same as GPT-2, except for tokenization method. Refer to [GPT-2 documentation](gpt2) for @@ -50,7 +49,6 @@ API reference information. - ## CpmTokenizer [[autodoc]] CpmTokenizer diff --git a/docs/source/en/model_doc/cpmant.md b/docs/source/en/model_doc/cpmant.md index 6f13f785ac1e..47eec6e79d69 100644 --- a/docs/source/en/model_doc/cpmant.md +++ b/docs/source/en/model_doc/cpmant.md @@ -45,7 +45,7 @@ This model was contributed by [OpenBMB](https://huggingface.co/openbmb). The ori [[autodoc]] CpmAntModel - all - + ## CpmAntForCausalLM [[autodoc]] CpmAntForCausalLM diff --git a/docs/source/en/model_doc/csm.md b/docs/source/en/model_doc/csm.md index 1ee2b63dd715..162832470482 100644 --- a/docs/source/en/model_doc/csm.md +++ b/docs/source/en/model_doc/csm.md @@ -346,7 +346,6 @@ out.loss.backward() This model was contributed by [Eustache Le Bihan](https://huggingface.co/eustlb). The original code can be found [here](https://github.com/SesameAILabs/csm). - ## CsmConfig [[autodoc]] CsmConfig diff --git a/docs/source/en/model_doc/ctrl.md b/docs/source/en/model_doc/ctrl.md index e5b48d638b68..6244ee0a59ef 100644 --- a/docs/source/en/model_doc/ctrl.md +++ b/docs/source/en/model_doc/ctrl.md @@ -55,7 +55,6 @@ This model was contributed by [keskarnitishr](https://huggingface.co/keskarnitis pre-computed values in the context of text generation. See the [`forward`](model_doc/ctrl#transformers.CTRLModel.forward) method for more information on the usage of this argument. - ## Resources - [Text classification task guide](../tasks/sequence_classification) diff --git a/docs/source/en/model_doc/d_fine.md b/docs/source/en/model_doc/d_fine.md index 9dffde75ebc7..05e855d333b5 100644 --- a/docs/source/en/model_doc/d_fine.md +++ b/docs/source/en/model_doc/d_fine.md @@ -24,13 +24,13 @@ Yansong Peng, Hebei Li, Peixi Wu, Yueyi Zhang, Xiaoyan Sun, Feng Wu The abstract from the paper is the following: -*We introduce D-FINE, a powerful real-time object detector that achieves outstanding localization precision by redefining the bounding box regression task in DETR models. D-FINE comprises two key components: Fine-grained Distribution Refinement (FDR) and Global Optimal Localization Self-Distillation (GO-LSD). +*We introduce D-FINE, a powerful real-time object detector that achieves outstanding localization precision by redefining the bounding box regression task in DETR models. D-FINE comprises two key components: Fine-grained Distribution Refinement (FDR) and Global Optimal Localization Self-Distillation (GO-LSD). FDR transforms the regression process from predicting fixed coordinates to iteratively refining probability distributions, providing a fine-grained intermediate representation that significantly enhances localization accuracy. GO-LSD is a bidirectional optimization strategy that transfers localization knowledge from refined distributions to shallower layers through self-distillation, while also simplifying the residual prediction tasks for deeper layers. Additionally, D-FINE incorporates lightweight optimizations in computationally intensive modules and operations, achieving a better balance between speed and accuracy. Specifically, D-FINE-L / X achieves 54.0% / 55.8% AP on the COCO dataset at 124 / 78 FPS on an NVIDIA T4 GPU. When pretrained on Objects365, D-FINE-L / X attains 57.1% / 59.3% AP, surpassing all existing real-time detectors. Furthermore, our method significantly enhances the performance of a wide range of DETR models by up to 5.3% AP with negligible extra parameters and training costs. Our code and pretrained models: this https URL.* -This model was contributed by [VladOS95-cyber](https://github.com/VladOS95-cyber). +This model was contributed by [VladOS95-cyber](https://github.com/VladOS95-cyber). The original code can be found [here](https://github.com/Peterande/D-FINE). -## Usage tips +## Usage tips ```python >>> import torch diff --git a/docs/source/en/model_doc/dab-detr.md b/docs/source/en/model_doc/dab-detr.md index 32b27d4b2479..d85988ec1f55 100644 --- a/docs/source/en/model_doc/dab-detr.md +++ b/docs/source/en/model_doc/dab-detr.md @@ -77,7 +77,9 @@ for result in results: box = [round(i, 2) for i in box.tolist()] print(f"{model.config.id2label[label]}: {score:.2f} {box}") ``` + This should output + ``` cat: 0.87 [14.7, 49.39, 320.52, 469.28] remote: 0.86 [41.08, 72.37, 173.39, 117.2] @@ -89,6 +91,7 @@ couch: 0.59 [-0.04, 1.34, 639.9, 477.09] There are three other ways to instantiate a DAB-DETR model (depending on what you prefer): Option 1: Instantiate DAB-DETR with pre-trained weights for entire model + ```py >>> from transformers import DabDetrForObjectDetection @@ -96,19 +99,21 @@ Option 1: Instantiate DAB-DETR with pre-trained weights for entire model ``` Option 2: Instantiate DAB-DETR with randomly initialized weights for Transformer, but pre-trained weights for backbone + ```py >>> from transformers import DabDetrConfig, DabDetrForObjectDetection >>> config = DabDetrConfig() >>> model = DabDetrForObjectDetection(config) ``` + Option 3: Instantiate DAB-DETR with randomly initialized weights for backbone + Transformer + ```py >>> config = DabDetrConfig(use_pretrained_backbone=False) >>> model = DabDetrForObjectDetection(config) ``` - ## DabDetrConfig [[autodoc]] DabDetrConfig diff --git a/docs/source/en/model_doc/dac.md b/docs/source/en/model_doc/dac.md index e17cc69fc37a..94f70fdff32a 100644 --- a/docs/source/en/model_doc/dac.md +++ b/docs/source/en/model_doc/dac.md @@ -23,7 +23,6 @@ rendered properly in your Markdown viewer. ## Overview - The DAC model was proposed in [Descript Audio Codec: High-Fidelity Audio Compression with Improved RVQGAN](https://huggingface.co/papers/2306.06546) by Rithesh Kumar, Prem Seetharaman, Alejandro Luebs, Ishaan Kumar, Kundan Kumar. The Descript Audio Codec (DAC) model is a powerful tool for compressing audio data, making it highly efficient for storage and transmission. By compressing 44.1 KHz audio into tokens at just 8kbps bandwidth, the DAC model enables high-quality audio processing while significantly reducing the data footprint. This is particularly useful in scenarios where bandwidth is limited or storage space is at a premium, such as in streaming applications, remote conferencing, and archiving large audio datasets. @@ -35,7 +34,6 @@ The abstract from the paper is the following: This model was contributed by [Kamil Akesbi](https://huggingface.co/kamilakesbi). The original code can be found [here](https://github.com/descriptinc/descript-audio-codec/tree/main?tab=readme-ov-file). - ## Model structure The Descript Audio Codec (DAC) model is structured into three distinct stages: @@ -44,11 +42,11 @@ The Descript Audio Codec (DAC) model is structured into three distinct stages: 2. Residual Vector Quantizer (RVQ) Model: Working in tandem with the encoder, this model quantizes the latent codes of the audio, refining the compression and ensuring high-quality reconstruction. 3. Decoder Model: This final stage reconstructs the audio from its compressed form, restoring it to a state that closely resembles the original input. -## Usage example +## Usage example -Here is a quick example of how to encode and decode an audio using this model: +Here is a quick example of how to encode and decode an audio using this model: -```python +```python >>> from datasets import load_dataset, Audio >>> from transformers import DacModel, AutoProcessor >>> librispeech_dummy = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") diff --git a/docs/source/en/model_doc/dbrx.md b/docs/source/en/model_doc/dbrx.md index 8b2e5ae75e34..a97e594e415a 100644 --- a/docs/source/en/model_doc/dbrx.md +++ b/docs/source/en/model_doc/dbrx.md @@ -35,7 +35,6 @@ We estimate that this data is at least 2x better token-for-token than the data w This new dataset was developed using the full suite of Databricks tools, including Apache Spark™ and Databricks notebooks for data processing, and Unity Catalog for data management and governance. We used curriculum learning for pretraining, changing the data mix during training in ways we found to substantially improve model quality. - More detailed information about DBRX Instruct and DBRX Base can be found in our [technical blog post](https://www.databricks.com/blog/introducing-dbrx-new-state-art-open-llm). This model was contributed by [eitan-turok](https://huggingface.co/eitanturok) and [abhi-db](https://huggingface.co/abhi-db). The original code can be found [here](https://github.com/databricks/dbrx-instruct), though this may not be up to date. @@ -65,6 +64,7 @@ print(tokenizer.decode(outputs[0])) ``` If you have flash-attention installed (`pip install flash-attn`), it is possible to generate faster. (The HuggingFace documentation for flash-attention can be found [here](https://huggingface.co/docs/transformers/perf_infer_gpu_one#flashattention-2).) + ```python from transformers import DbrxForCausalLM, AutoTokenizer import torch @@ -87,6 +87,7 @@ print(tokenizer.decode(outputs[0])) ``` You can also generate faster using the PyTorch scaled dot product attention. (The HuggingFace documentation for scaled dot product attention can be found [here](https://huggingface.co/docs/transformers/perf_infer_gpu_one#pytorch-scaled-dot-product-attention).) + ```python from transformers import DbrxForCausalLM, AutoTokenizer import torch @@ -112,15 +113,12 @@ print(tokenizer.decode(outputs[0])) [[autodoc]] DbrxConfig - ## DbrxModel [[autodoc]] DbrxModel - forward - ## DbrxForCausalLM [[autodoc]] DbrxForCausalLM - forward - diff --git a/docs/source/en/model_doc/deberta-v2.md b/docs/source/en/model_doc/deberta-v2.md index 7c92cd6cb9d3..6ec0c0e51176 100644 --- a/docs/source/en/model_doc/deberta-v2.md +++ b/docs/source/en/model_doc/deberta-v2.md @@ -21,14 +21,12 @@ rendered properly in your Markdown viewer. - # DeBERTa-v2 [DeBERTa-v2](https://huggingface.co/papers/2006.03654) improves on the original [DeBERTa](./deberta) architecture by using a SentencePiece-based tokenizer and a new vocabulary size of 128K. It also adds an additional convolutional layer within the first transformer layer to better learn local dependencies of input tokens. Finally, the position projection and content projection matrices are shared in the attention layer to reduce the number of parameters. You can find all the original [DeBERTa-v2] checkpoints under the [Microsoft](https://huggingface.co/microsoft?search_models=deberta-v2) organization. - > [!TIP] > This model was contributed by [Pengcheng He](https://huggingface.co/DeBERTa). > @@ -86,6 +84,7 @@ print(f"Predicted label: {predicted_label}") ```bash echo -e "DeBERTa-v2 is great at understanding context!" | transformers run --task fill-mask --model microsoft/deberta-v2-xlarge-mnli --device 0 ``` + @@ -119,7 +118,6 @@ print(f"Predicted label: {predicted_label}") ``` - ## DebertaV2Config [[autodoc]] DebertaV2Config diff --git a/docs/source/en/model_doc/deberta.md b/docs/source/en/model_doc/deberta.md index 2d99bdbfd210..76fe8e1a3b63 100644 --- a/docs/source/en/model_doc/deberta.md +++ b/docs/source/en/model_doc/deberta.md @@ -31,7 +31,6 @@ Even with less training data than RoBERTa, DeBERTa manages to outperform it on s You can find all the original DeBERTa checkpoints under the [Microsoft](https://huggingface.co/microsoft?search_models=deberta) organization. - > [!TIP] > Click on the DeBERTa models in the right sidebar for more examples of how to apply DeBERTa to different language tasks. diff --git a/docs/source/en/model_doc/decision_transformer.md b/docs/source/en/model_doc/decision_transformer.md index cdfcd42f9a34..349b8eaae2e7 100644 --- a/docs/source/en/model_doc/decision_transformer.md +++ b/docs/source/en/model_doc/decision_transformer.md @@ -28,14 +28,14 @@ by Lili Chen, Kevin Lu, Aravind Rajeswaran, Kimin Lee, Aditya Grover, Michael La The abstract from the paper is the following: -*We introduce a framework that abstracts Reinforcement Learning (RL) as a sequence modeling problem. +*We introduce a framework that abstracts Reinforcement Learning (RL) as a sequence modeling problem. This allows us to draw upon the simplicity and scalability of the Transformer architecture, and associated advances - in language modeling such as GPT-x and BERT. In particular, we present Decision Transformer, an architecture that - casts the problem of RL as conditional sequence modeling. Unlike prior approaches to RL that fit value functions or - compute policy gradients, Decision Transformer simply outputs the optimal actions by leveraging a causally masked - Transformer. By conditioning an autoregressive model on the desired return (reward), past states, and actions, our - Decision Transformer model can generate future actions that achieve the desired return. Despite its simplicity, - Decision Transformer matches or exceeds the performance of state-of-the-art model-free offline RL baselines on + in language modeling such as GPT-x and BERT. In particular, we present Decision Transformer, an architecture that + casts the problem of RL as conditional sequence modeling. Unlike prior approaches to RL that fit value functions or + compute policy gradients, Decision Transformer simply outputs the optimal actions by leveraging a causally masked + Transformer. By conditioning an autoregressive model on the desired return (reward), past states, and actions, our + Decision Transformer model can generate future actions that achieve the desired return. Despite its simplicity, + Decision Transformer matches or exceeds the performance of state-of-the-art model-free offline RL baselines on Atari, OpenAI Gym, and Key-to-Door tasks.* This version of the model is for tasks where the state is a vector. @@ -46,7 +46,6 @@ This model was contributed by [edbeeching](https://huggingface.co/edbeeching). T [[autodoc]] DecisionTransformerConfig - ## DecisionTransformerGPT2Model [[autodoc]] DecisionTransformerGPT2Model diff --git a/docs/source/en/model_doc/deepseek_v3.md b/docs/source/en/model_doc/deepseek_v3.md index d8eb2e942033..81724e399435 100644 --- a/docs/source/en/model_doc/deepseek_v3.md +++ b/docs/source/en/model_doc/deepseek_v3.md @@ -26,17 +26,17 @@ We present DeepSeek-V3, a strong Mixture-of-Experts (MoE) language model with 67 ## Limitations and call for contribution! -We are super happy to make this code community-powered, and would love to see how you can best optimize the following: +We are super happy to make this code community-powered, and would love to see how you can best optimize the following: - current implementation uses the "naive" attention compution (so not really MLA) -- current implementation loops through the experts. This should be replaced. Pointers to use `get_packed_weights` from `integrations/tensor_parallel`. +- current implementation loops through the experts. This should be replaced. Pointers to use `get_packed_weights` from `integrations/tensor_parallel`. - current implementation uses the eleuther formula for ROPE, using the original one would be more efficient! (should still follow our API) - static cache is not supported (this should be just a generation config issue / config shape issues) ### Usage tips The model uses Multi-head Latent Attention (MLA) and DeepSeekMoE architectures for efficient inference and cost-effective training. It employs an auxiliary-loss-free strategy for load balancing and multi-token prediction training objective. The model can be used for various language tasks after being pre-trained on 14.8 trillion tokens and going through Supervised Fine-Tuning and Reinforcement Learning stages. -You can run the model in `FP8` automatically, using 2 nodes of 8 H100 should be more than enough! +You can run the model in `FP8` automatically, using 2 nodes of 8 H100 should be more than enough! ```python # `run_deepseek_v1.py` @@ -61,7 +61,8 @@ outputs = model.generate(inputs, max_new_tokens=50) print(tokenizer.batch_decode(outputs)) print(time.time()-start) ``` -This generated: + +This generated: `````` <|Assistant|> @@ -157,18 +158,20 @@ Want to dive deeper or see a specific framework’s implementation (e.g., OpenAI `````` Use the following to run it + ```bash torchrun --nproc_per_node=8 --nnodes=2 --node_rank=0|1 --rdzv-id an_id --rdzv-backend c10d --rdzv-endpoint master_addr:master_port run_deepseek_r1.py ``` -If you have: +If you have: + ```bash [rank0]: ncclInternalError: Internal check failed. [rank0]: Last error: [rank0]: Bootstrap : no socket interface found ``` -error, it means NCCL was probably not loaded. +error, it means NCCL was probably not loaded. ## DeepseekV3Config diff --git a/docs/source/en/model_doc/deepseek_vl.md b/docs/source/en/model_doc/deepseek_vl.md index 58695db8348c..710e6144bb0e 100644 --- a/docs/source/en/model_doc/deepseek_vl.md +++ b/docs/source/en/model_doc/deepseek_vl.md @@ -63,6 +63,7 @@ messages = [ pipe(text=messages, max_new_tokens=20, return_full_text=False) ``` + @@ -115,6 +116,7 @@ output_text = processor.batch_decode( print(output_text) ``` + @@ -138,9 +140,11 @@ model = DeepseekVLForConditionalGeneration.from_pretrained( quantization_config=quantization_config ) ``` + ### Notes - Do inference with multiple images in a single conversation. + ```py import torch from transformers import DeepseekVLForConditionalGeneration, AutoProcessor diff --git a/docs/source/en/model_doc/deepseek_vl_hybrid.md b/docs/source/en/model_doc/deepseek_vl_hybrid.md index d18ab7576adc..0613b50f1ad8 100644 --- a/docs/source/en/model_doc/deepseek_vl_hybrid.md +++ b/docs/source/en/model_doc/deepseek_vl_hybrid.md @@ -62,6 +62,7 @@ messages = [ pipe(text=messages, max_new_tokens=20, return_full_text=False) ``` + @@ -114,6 +115,7 @@ output_text = processor.batch_decode( print(output_text) ``` + @@ -137,9 +139,11 @@ model = DeepseekVLHybridForConditionalGeneration.from_pretrained( quantization_config=quantization_config ) ``` + ### Notes - Do inference with multiple images in a single conversation. + ```py import torch from transformers import DeepseekVLHybridForConditionalGeneration, AutoProcessor diff --git a/docs/source/en/model_doc/deplot.md b/docs/source/en/model_doc/deplot.md index 651ddcef7fe9..0eb3975530ab 100644 --- a/docs/source/en/model_doc/deplot.md +++ b/docs/source/en/model_doc/deplot.md @@ -21,7 +21,7 @@ rendered properly in your Markdown viewer. PyTorch -## Overview +## Overview DePlot was proposed in the paper [DePlot: One-shot visual language reasoning by plot-to-table translation](https://huggingface.co/papers/2212.10505) from Fangyu Liu, Julian Martin Eisenschlos, Francesco Piccinno, Syrine Krichene, Chenxi Pang, Kenton Lee, Mandar Joshi, Wenhu Chen, Nigel Collier, Yasemin Altun. @@ -36,8 +36,7 @@ DePlot is a Visual Question Answering subset of `Pix2Struct` architecture. It re Currently one checkpoint is available for DePlot: -- `google/deplot`: DePlot fine-tuned on ChartQA dataset - +- `google/deplot`: DePlot fine-tuned on ChartQA dataset ```python from transformers import AutoProcessor, Pix2StructForConditionalGeneration @@ -57,6 +56,7 @@ print(processor.decode(predictions[0], skip_special_tokens=True)) ## Fine-tuning To fine-tune DePlot, refer to the pix2struct [fine-tuning notebook](https://github.com/huggingface/notebooks/blob/main/examples/image_captioning_pix2struct.ipynb). For `Pix2Struct` models, we have found out that fine-tuning the model with Adafactor and cosine learning rate scheduler leads to faster convergence: + ```python from transformers.optimization import Adafactor, get_cosine_schedule_with_warmup diff --git a/docs/source/en/model_doc/depth_pro.md b/docs/source/en/model_doc/depth_pro.md index 85423359ceb0..6872fca5138b 100644 --- a/docs/source/en/model_doc/depth_pro.md +++ b/docs/source/en/model_doc/depth_pro.md @@ -102,12 +102,14 @@ The network is supplemented with a focal length estimation head. A small convolu The `use_fov_model` parameter in `DepthProConfig` controls whether **FOV prediction** is enabled. By default, it is set to `False` to conserve memory and computation. When enabled, the **FOV encoder** is instantiated based on the `fov_model_config` parameter, which defaults to a `Dinov2Model`. The `use_fov_model` parameter can also be passed when initializing the `DepthProForDepthEstimation` model. The pretrained model at checkpoint `apple/DepthPro-hf` uses the FOV encoder. To use the pretrained-model without FOV encoder, set `use_fov_model=False` when loading the model, which saves computation. + ```py >>> from transformers import DepthProForDepthEstimation >>> model = DepthProForDepthEstimation.from_pretrained("apple/DepthPro-hf", use_fov_model=False) ``` To instantiate a new model with FOV encoder, set `use_fov_model=True` in the config. + ```py >>> from transformers import DepthProConfig, DepthProForDepthEstimation >>> config = DepthProConfig(use_fov_model=True) @@ -115,6 +117,7 @@ To instantiate a new model with FOV encoder, set `use_fov_model=True` in the con ``` Or set `use_fov_model=True` when initializing the model, which overrides the value in config. + ```py >>> from transformers import DepthProConfig, DepthProForDepthEstimation >>> config = DepthProConfig() @@ -123,13 +126,13 @@ Or set `use_fov_model=True` when initializing the model, which overrides the val ### Using Scaled Dot Product Attention (SDPA) -PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function -encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the -[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) +PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function +encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the +[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) or the [GPU Inference](https://huggingface.co/docs/transformers/main/en/perf_infer_gpu_one#pytorch-scaled-dot-product-attention) page for more information. -SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set +SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set `attn_implementation="sdpa"` in `from_pretrained()` to explicitly request SDPA to be used. ```py diff --git a/docs/source/en/model_doc/detr.md b/docs/source/en/model_doc/detr.md index 425ab0f04c51..6d7792803c59 100644 --- a/docs/source/en/model_doc/detr.md +++ b/docs/source/en/model_doc/detr.md @@ -113,6 +113,7 @@ DETR can be naturally extended to perform panoptic segmentation (which unifies s There are three other ways to instantiate a DETR model (depending on what you prefer): - Option 1: Instantiate DETR with pre-trained weights for entire model + ```python from transformers import DetrForObjectDetection @@ -120,6 +121,7 @@ model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50") ``` - Option 2: Instantiate DETR with randomly initialized weights for Transformer, but pre-trained weights for backbone + ```python from transformers import DetrConfig, DetrForObjectDetection @@ -128,6 +130,7 @@ model = DetrForObjectDetection(config) ``` - Option 3: Instantiate DETR with randomly initialized weights for backbone + Transformer + ```python config = DetrConfig(use_pretrained_backbone=False) model = DetrForObjectDetection(config) @@ -144,7 +147,7 @@ As a summary, consider the following table: | **Postprocessing** (i.e. converting the output of the model to Pascal VOC format) | [`~transformers.DetrImageProcessor.post_process`] | [`~transformers.DetrImageProcessor.post_process_segmentation`] | [`~transformers.DetrImageProcessor.post_process_segmentation`], [`~transformers.DetrImageProcessor.post_process_panoptic`] | | **evaluators** | `CocoEvaluator` with `iou_types="bbox"` | `CocoEvaluator` with `iou_types="bbox"` or `"segm"` | `CocoEvaluator` with `iou_tupes="bbox"` or `"segm"`, `PanopticEvaluator` | -- In short, one should prepare the data either in COCO detection or COCO panoptic format, then use [`~transformers.DetrImageProcessor`] to create `pixel_values`, `pixel_mask` and optional `labels`, which can then be used to train (or fine-tune) a model. +- In short, one should prepare the data either in COCO detection or COCO panoptic format, then use [`~transformers.DetrImageProcessor`] to create `pixel_values`, `pixel_mask` and optional `labels`, which can then be used to train (or fine-tune) a model. - For evaluation, one should first convert the outputs of the model using one of the postprocessing methods of [`~transformers.DetrImageProcessor`]. These can be provided to either `CocoEvaluator` or `PanopticEvaluator`, which allow you to calculate metrics like mean Average Precision (mAP) and Panoptic Quality (PQ). The latter objects are implemented in the [original repository](https://github.com/facebookresearch/detr). See the [example notebooks](https://github.com/NielsRogge/Transformers-Tutorials/tree/master/DETR) for more info regarding evaluation. ## Resources diff --git a/docs/source/en/model_doc/dia.md b/docs/source/en/model_doc/dia.md index 1a07e8831ee7..bab0cb4a72d3 100644 --- a/docs/source/en/model_doc/dia.md +++ b/docs/source/en/model_doc/dia.md @@ -117,11 +117,9 @@ out = model(**inputs) out.loss.backward() ``` - This model was contributed by [Jaeyong Sung](https://huggingface.co/buttercrab), [Arthur Zucker](https://huggingface.co/ArthurZ), and [Anton Vlasjuk](https://huggingface.co/AntonV). The original code can be found [here](https://github.com/nari-labs/dia/). - ## DiaConfig [[autodoc]] DiaConfig diff --git a/docs/source/en/model_doc/diffllama.md b/docs/source/en/model_doc/diffllama.md index 406bae43c5f2..79b8314d0ae2 100644 --- a/docs/source/en/model_doc/diffllama.md +++ b/docs/source/en/model_doc/diffllama.md @@ -35,7 +35,6 @@ The abstract from the paper is the following: ### Usage tips The hyperparameters of this model is the same as Llama model. - ## DiffLlamaConfig [[autodoc]] DiffLlamaConfig diff --git a/docs/source/en/model_doc/dinov2.md b/docs/source/en/model_doc/dinov2.md index 59256756acfd..0968641326af 100644 --- a/docs/source/en/model_doc/dinov2.md +++ b/docs/source/en/model_doc/dinov2.md @@ -19,7 +19,6 @@ specific language governing permissions and limitations under the License. - # DINOv2 [DINOv2](https://huggingface.co/papers/2304.07193) is a vision foundation model that uses [ViT](./vit) as a feature extractor for multiple downstream tasks like image classification and depth estimation. It focuses on stabilizing and accelerating training through techniques like a faster memory-efficient attention, sequence packing, improved stochastic depth, Fully Sharded Data Parallel (FSDP), and model distillation. diff --git a/docs/source/en/model_doc/dinov2_with_registers.md b/docs/source/en/model_doc/dinov2_with_registers.md index f89de76d2168..fcafc6df3061 100644 --- a/docs/source/en/model_doc/dinov2_with_registers.md +++ b/docs/source/en/model_doc/dinov2_with_registers.md @@ -45,7 +45,6 @@ Tips: This model was contributed by [nielsr](https://huggingface.co/nielsr). The original code can be found [here](https://github.com/facebookresearch/dinov2). - ## Dinov2WithRegistersConfig [[autodoc]] Dinov2WithRegistersConfig diff --git a/docs/source/en/model_doc/dinov3.md b/docs/source/en/model_doc/dinov3.md index a11a8fd10cca..94e531651566 100644 --- a/docs/source/en/model_doc/dinov3.md +++ b/docs/source/en/model_doc/dinov3.md @@ -19,7 +19,6 @@ specific language governing permissions and limitations under the License. - # DINOv3 [DINOv3](https://huggingface.co/papers/2508.10104) is a family of versatile vision foundation models that outperforms the specialized state of the art across a broad range of settings, without fine-tuning. DINOv3 produces high-quality dense features that achieve outstanding performance on various vision tasks, significantly surpassing previous self- and weakly-supervised foundation models. diff --git a/docs/source/en/model_doc/dit.md b/docs/source/en/model_doc/dit.md index 3027905fe38b..574ffe3ef11a 100644 --- a/docs/source/en/model_doc/dit.md +++ b/docs/source/en/model_doc/dit.md @@ -85,6 +85,7 @@ print(f"The predicted class label is: {predicted_class_label}") ## Notes - The pretrained DiT weights can be loaded in a [BEiT] model with a modeling head to predict visual tokens. + ```py from transformers import BeitForMaskedImageModeling diff --git a/docs/source/en/model_doc/doge.md b/docs/source/en/model_doc/doge.md index 6221940d5d5a..ffa9ced7913a 100644 --- a/docs/source/en/model_doc/doge.md +++ b/docs/source/en/model_doc/doge.md @@ -17,7 +17,6 @@ rendered properly in your Markdown viewer. # Doge - ## Overview Doge is a series of small language models based on the [Doge](https://github.com/SmallDoges/small-doge) architecture, aiming to combine the advantages of state-space and self-attention algorithms, calculate dynamic masks from cached value states using the zero-order hold method, and solve the problem of existing mainstream language models getting lost in context. It uses the `wsd_scheduler` scheduler to pre-train on the `smollm-corpus`, and can continue training on new datasets or add sparse activation feedforward networks from stable stage checkpoints. @@ -28,7 +27,6 @@ As shown in the figure below, the sequence transformation part of the Doge archi Checkout all Doge model checkpoints [here](https://huggingface.co/collections/SmallDoge/doge-slm-679cc991f027c4a3abbded4a). - ## Usage
@@ -44,6 +42,7 @@ inputs = tokenizer("Hey how are you doing?", return_tensors="pt") outputs = model.generate(**inputs, max_new_tokens=100) print(tokenizer.batch_decode(outputs)) ``` +
@@ -82,6 +81,7 @@ outputs = model.generate( streamer=steamer ) ``` +
## DogeConfig diff --git a/docs/source/en/model_doc/donut.md b/docs/source/en/model_doc/donut.md index f06b6804d6e4..e582dab748ae 100644 --- a/docs/source/en/model_doc/donut.md +++ b/docs/source/en/model_doc/donut.md @@ -22,7 +22,7 @@ specific language governing permissions and limitations under the License. --> # Donut -[Donut (Document Understanding Transformer)](https://huggingface.co/papers/2111.15664) is a visual document understanding model that doesn't require an Optical Character Recognition (OCR) engine. Unlike traditional approaches that extract text using OCR before processing, Donut employs an end-to-end Transformer-based architecture to directly analyze document images. This eliminates OCR-related inefficiencies making it more accurate and adaptable to diverse languages and formats. +[Donut (Document Understanding Transformer)](https://huggingface.co/papers/2111.15664) is a visual document understanding model that doesn't require an Optical Character Recognition (OCR) engine. Unlike traditional approaches that extract text using OCR before processing, Donut employs an end-to-end Transformer-based architecture to directly analyze document images. This eliminates OCR-related inefficiencies making it more accurate and adaptable to diverse languages and formats. Donut features vision encoder ([Swin](./swin)) and a text decoder ([BART](./bart)). Swin converts document images into embeddings and BART processes them into meaningful text sequences. diff --git a/docs/source/en/model_doc/dots1.md b/docs/source/en/model_doc/dots1.md index 337cad8cb4c7..316ab3b1f5b9 100644 --- a/docs/source/en/model_doc/dots1.md +++ b/docs/source/en/model_doc/dots1.md @@ -25,7 +25,6 @@ The abstract from the report is the following: *Mixture of Experts (MoE) models have emerged as a promising paradigm for scaling language models efficiently by activating only a subset of parameters for each input token. In this report, we present dots.llm1, a large-scale MoE model that activates 14B parameters out of a total of 142B parameters, delivering performance on par with state-of-the-art models while reducing training and inference costs. Leveraging our meticulously crafted and efficient data processing pipeline, dots.llm1 achieves performance comparable to Qwen2.5-72B after pretraining on high-quality corpus and post-training to fully unlock its capabilities. Notably, no synthetic data is used during pretraining. To foster further research, we open-source intermediate training checkpoints spanning the entire training process, providing valuable insights into the learning dynamics of large language models.* - ## Dots1Config [[autodoc]] Dots1Config diff --git a/docs/source/en/model_doc/efficientloftr.md b/docs/source/en/model_doc/efficientloftr.md index 2cdec895efc0..faf71f4bac04 100644 --- a/docs/source/en/model_doc/efficientloftr.md +++ b/docs/source/en/model_doc/efficientloftr.md @@ -45,6 +45,7 @@ results = keypoint_matcher([url_0, url_1], threshold=0.9) print(results[0]) # {'keypoint_image_0': {'x': ..., 'y': ...}, 'keypoint_image_1': {'x': ..., 'y': ...}, 'score': ...} ``` + @@ -167,4 +168,3 @@ processed_outputs = processor.post_process_keypoint_matching(outputs, image_size [[autodoc]] EfficientLoFTRForKeypointMatching - forward - diff --git a/docs/source/en/model_doc/efficientnet.md b/docs/source/en/model_doc/efficientnet.md index 859923126a9d..b4fbe8225625 100644 --- a/docs/source/en/model_doc/efficientnet.md +++ b/docs/source/en/model_doc/efficientnet.md @@ -23,7 +23,7 @@ rendered properly in your Markdown viewer. ## Overview -The EfficientNet model was proposed in [EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks](https://huggingface.co/papers/1905.11946) +The EfficientNet model was proposed in [EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks](https://huggingface.co/papers/1905.11946) by Mingxing Tan and Quoc V. Le. EfficientNets are a family of image classification models, which achieve state-of-the-art accuracy, yet being an order-of-magnitude smaller and faster than previous models. The abstract from the paper is the following: @@ -34,7 +34,6 @@ To go even further, we use neural architecture search to design a new baseline n This model was contributed by [adirik](https://huggingface.co/adirik). The original code can be found [here](https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet). - ## EfficientNetConfig [[autodoc]] EfficientNetConfig @@ -58,4 +57,3 @@ The original code can be found [here](https://github.com/tensorflow/tpu/tree/mas [[autodoc]] EfficientNetForImageClassification - forward - diff --git a/docs/source/en/model_doc/emu3.md b/docs/source/en/model_doc/emu3.md index 799de2f0c5c0..0c95bc6d9877 100644 --- a/docs/source/en/model_doc/emu3.md +++ b/docs/source/en/model_doc/emu3.md @@ -27,8 +27,7 @@ rendered properly in your Markdown viewer. The Emu3 model was proposed in [Emu3: Next-Token Prediction is All You Need](https://huggingface.co/papers/2409.18869) by Xinlong Wang, Xiaosong Zhang, Zhengxiong Luo, Quan Sun, Yufeng Cui, Jinsheng Wang, Fan Zhang, Yueze Wang, Zhen Li, Qiying Yu, Yingli Zhao, Yulong Ao, Xuebin Min, Tao Li, Boya Wu, Bo Zhao, Bowen Zhang, Liangdong Wang, Guang Liu, Zheqi He, Xi Yang, Jingjing Liu, Yonghua Lin, Tiejun Huang, Zhongyuan Wang. -Emu3 is a multimodal LLM that uses vector quantization to tokenize images into discrete tokens. Discretized image tokens are later fused with text token ids for image and text generation. The model can additionally generate images by predicting image token ids. - +Emu3 is a multimodal LLM that uses vector quantization to tokenize images into discrete tokens. Discretized image tokens are later fused with text token ids for image and text generation. The model can additionally generate images by predicting image token ids. The abstract from the paper is the following: @@ -45,11 +44,9 @@ Tips: > [!TIP] > Emu3 implementation in Transformers uses a special image token to indicate where to merge image embeddings. The special image token isn't new and uses one of the reserved tokens: `<|extra_0|>`. You have to add `` to your prompt in the place where the image should be embedded for correct generation. - This model was contributed by [RaushanTurganbay](https://huggingface.co/RaushanTurganbay). The original code can be found [here](https://github.com/baaivision/Emu3). - ## Usage example ### Text generation inference @@ -143,7 +140,6 @@ for i, image in enumerate(images['pixel_values']): ``` - ## Emu3Config [[autodoc]] Emu3Config diff --git a/docs/source/en/model_doc/encodec.md b/docs/source/en/model_doc/encodec.md index 890991730391..9fc6c2c97e94 100644 --- a/docs/source/en/model_doc/encodec.md +++ b/docs/source/en/model_doc/encodec.md @@ -29,14 +29,14 @@ The abstract from the paper is the following: *We introduce a state-of-the-art real-time, high-fidelity, audio codec leveraging neural networks. It consists in a streaming encoder-decoder architecture with quantized latent space trained in an end-to-end fashion. We simplify and speed-up the training by using a single multiscale spectrogram adversary that efficiently reduces artifacts and produce high-quality samples. We introduce a novel loss balancer mechanism to stabilize training: the weight of a loss now defines the fraction of the overall gradient it should represent, thus decoupling the choice of this hyper-parameter from the typical scale of the loss. Finally, we study how lightweight Transformer models can be used to further compress the obtained representation by up to 40%, while staying faster than real time. We provide a detailed description of the key design choices of the proposed model including: training objective, architectural changes and a study of various perceptual loss functions. We present an extensive subjective evaluation (MUSHRA tests) together with an ablation study for a range of bandwidths and audio domains, including speech, noisy-reverberant speech, and music. Our approach is superior to the baselines methods across all evaluated settings, considering both 24 kHz monophonic and 48 kHz stereophonic audio.* -This model was contributed by [Matthijs](https://huggingface.co/Matthijs), [Patrick Von Platen](https://huggingface.co/patrickvonplaten) and [Arthur Zucker](https://huggingface.co/ArthurZ). +This model was contributed by [Matthijs](https://huggingface.co/Matthijs), [Patrick Von Platen](https://huggingface.co/patrickvonplaten) and [Arthur Zucker](https://huggingface.co/ArthurZ). The original code can be found [here](https://github.com/facebookresearch/encodec). -## Usage example +## Usage example Here is a quick example of how to encode and decode an audio using this model: -```python +```python >>> from datasets import load_dataset, Audio >>> from transformers import EncodecModel, AutoProcessor >>> librispeech_dummy = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") diff --git a/docs/source/en/model_doc/eomt.md b/docs/source/en/model_doc/eomt.md index 754b88e2c330..199d87dc794e 100644 --- a/docs/source/en/model_doc/eomt.md +++ b/docs/source/en/model_doc/eomt.md @@ -39,7 +39,6 @@ Architecturally, EoMT introduces a small set of **learned queries** and a lightw alt="drawing" width="500"/> - The model supports semantic, instance, and panoptic segmentation using a unified architecture and task-specific post-processing. ## Usage Examples diff --git a/docs/source/en/model_doc/ernie4_5.md b/docs/source/en/model_doc/ernie4_5.md index e48073bbe6c0..bf71049148d3 100644 --- a/docs/source/en/model_doc/ernie4_5.md +++ b/docs/source/en/model_doc/ernie4_5.md @@ -38,7 +38,6 @@ Other models from the family can be found at [Ernie 4.5 Moe](./ernie4_5_moe). - ## Usage Tips ### Generate text @@ -84,7 +83,6 @@ generate_text = tokenizer.decode(output_ids, skip_special_tokens=True) This model was contributed by [Anton Vlasjuk](https://huggingface.co/AntonV). The original code can be found [here](https://github.com/PaddlePaddle/ERNIE). - ## Ernie4_5Config [[autodoc]] Ernie4_5Config diff --git a/docs/source/en/model_doc/ernie4_5_moe.md b/docs/source/en/model_doc/ernie4_5_moe.md index 20c4dcfd5435..fb6b8d791bec 100644 --- a/docs/source/en/model_doc/ernie4_5_moe.md +++ b/docs/source/en/model_doc/ernie4_5_moe.md @@ -40,7 +40,6 @@ Other models from the family can be found at [Ernie 4.5](./ernie4_5). - ## Usage Tips ### Generate text @@ -167,7 +166,6 @@ generate_text = tokenizer.decode(output_ids, skip_special_tokens=True) This model was contributed by [Anton Vlasjuk](https://huggingface.co/AntonV). The original code can be found [here](https://github.com/PaddlePaddle/ERNIE). - ## Ernie4_5_MoeConfig [[autodoc]] Ernie4_5_MoeConfig diff --git a/docs/source/en/model_doc/ernie_m.md b/docs/source/en/model_doc/ernie_m.md index 508fe2f596b2..e044614e7644 100644 --- a/docs/source/en/model_doc/ernie_m.md +++ b/docs/source/en/model_doc/ernie_m.md @@ -40,7 +40,6 @@ The abstract from the paper is the following: *Recent studies have demonstrated that pre-trained cross-lingual models achieve impressive performance in downstream cross-lingual tasks. This improvement benefits from learning a large amount of monolingual and parallel corpora. Although it is generally acknowledged that parallel corpora are critical for improving the model performance, existing methods are often constrained by the size of parallel corpora, especially for lowresource languages. In this paper, we propose ERNIE-M, a new training method that encourages the model to align the representation of multiple languages with monolingual corpora, to overcome the constraint that the parallel corpus size places on the model performance. Our key insight is to integrate back-translation into the pre-training process. We generate pseudo-parallel sentence pairs on a monolingual corpus to enable the learning of semantic alignments between different languages, thereby enhancing the semantic modeling of cross-lingual models. Experimental results show that ERNIE-M outperforms existing cross-lingual models and delivers new state-of-the-art results in various cross-lingual downstream tasks.* This model was contributed by [Susnato Dhar](https://huggingface.co/susnato). The original code can be found [here](https://github.com/PaddlePaddle/PaddleNLP/tree/develop/paddlenlp/transformers/ernie_m). - ## Usage tips - Ernie-M is a BERT-like model so it is a stacked Transformer Encoder. @@ -59,7 +58,6 @@ This model was contributed by [Susnato Dhar](https://huggingface.co/susnato). Th [[autodoc]] ErnieMConfig - ## ErnieMTokenizer [[autodoc]] ErnieMTokenizer @@ -68,7 +66,6 @@ This model was contributed by [Susnato Dhar](https://huggingface.co/susnato). Th - create_token_type_ids_from_sequences - save_vocabulary - ## ErnieMModel [[autodoc]] ErnieMModel @@ -79,19 +76,16 @@ This model was contributed by [Susnato Dhar](https://huggingface.co/susnato). Th [[autodoc]] ErnieMForSequenceClassification - forward - ## ErnieMForMultipleChoice [[autodoc]] ErnieMForMultipleChoice - forward - ## ErnieMForTokenClassification [[autodoc]] ErnieMForTokenClassification - forward - ## ErnieMForQuestionAnswering [[autodoc]] ErnieMForQuestionAnswering diff --git a/docs/source/en/model_doc/esm.md b/docs/source/en/model_doc/esm.md index e83e2d5aa1da..a6190a71f020 100644 --- a/docs/source/en/model_doc/esm.md +++ b/docs/source/en/model_doc/esm.md @@ -44,12 +44,10 @@ sequence alignment (MSA) step at inference time, which means that ESMFold checkp they do not require a database of known protein sequences and structures with associated external query tools to make predictions, and are much faster as a result. - The abstract from "Biological structure and function emerge from scaling unsupervised learning to 250 million protein sequences" is - *In the field of artificial intelligence, a combination of scale in data and model capacity enabled by unsupervised learning has led to major advances in representation learning and statistical generation. In the life sciences, the anticipated growth of sequencing promises unprecedented data on natural sequence diversity. Protein language modeling @@ -63,7 +61,6 @@ can be identified by linear projections. Representation learning produces featur applications, enabling state-of-the-art supervised prediction of mutational effect and secondary structure and improving state-of-the-art features for long-range contact prediction.* - The abstract from "Language models of protein sequences at the scale of evolution enable accurate structure prediction" is diff --git a/docs/source/en/model_doc/evolla.md b/docs/source/en/model_doc/evolla.md index a39103a06d12..56f1d2755e19 100644 --- a/docs/source/en/model_doc/evolla.md +++ b/docs/source/en/model_doc/evolla.md @@ -75,7 +75,6 @@ Tips: - This model was contributed by [Xibin Bayes Zhou](https://huggingface.co/XibinBayesZhou). - The original code can be found [here](https://github.com/westlake-repl/Evolla). - ## EvollaConfig [[autodoc]] EvollaConfig diff --git a/docs/source/en/model_doc/exaone4.md b/docs/source/en/model_doc/exaone4.md index 69d7ee0b2a81..93ca33babd3c 100644 --- a/docs/source/en/model_doc/exaone4.md +++ b/docs/source/en/model_doc/exaone4.md @@ -20,7 +20,7 @@ rendered properly in your Markdown viewer. ## Overview **[EXAONE 4.0](https://github.com/LG-AI-EXAONE/EXAONE-4.0)** model is the language model, which integrates a **Non-reasoning mode** and **Reasoning mode** to achieve both the excellent usability of [EXAONE 3.5](https://github.com/LG-AI-EXAONE/EXAONE-3.5) and the advanced reasoning abilities of [EXAONE Deep](https://github.com/LG-AI-EXAONE/EXAONE-Deep). To pave the way for the agentic AI era, EXAONE 4.0 incorporates essential features such as agentic tool use, and its multilingual capabilities are extended -to support Spanish in addition to English and Korean. +to support Spanish in addition to English and Korean. The EXAONE 4.0 model series consists of two sizes: a mid-size **32B** model optimized for high performance, and a small-size **1.2B** model designed for on-device applications. @@ -33,7 +33,6 @@ For more details, please refer to our [technical report](https://huggingface.co/ All model weights including quantized versions are available at [Huggingface Collections](https://huggingface.co/collections/LGAI-EXAONE/exaone-40-686b2e0069800c835ed48375). - ## Model Details ### Model Specifications @@ -57,7 +56,6 @@ All model weights including quantized versions are available at [Huggingface Col | Tied word embedding | False | True | | Knowledge cut-off | Nov. 2024 | Nov. 2024 | - ## Usage tips ### Non-reasoning mode diff --git a/docs/source/en/model_doc/falcon_h1.md b/docs/source/en/model_doc/falcon_h1.md index 981c00bd626b..c17ecea1cc0e 100644 --- a/docs/source/en/model_doc/falcon_h1.md +++ b/docs/source/en/model_doc/falcon_h1.md @@ -21,7 +21,6 @@ The [FalconH1](https://huggingface.co/blog/tiiuae/falcon-h1) model was developed This model was contributed by [DhiyaEddine](https://huggingface.co/DhiyaEddine), [ybelkada](https://huggingface.co/ybelkada), [JingweiZuo](https://huggingface.co/JingweiZuo), [IlyasChahed](https://huggingface.co/IChahed), and [MaksimVelikanov](https://huggingface.co/yellowvm). The original code can be found [here](https://github.com/tiiuae/Falcon-H1). - ## FalconH1Config | Model | Depth | Dim | Attn Heads | KV | Mamba Heads | d_head | d_state | Ctx Len | @@ -33,8 +32,6 @@ The original code can be found [here](https://github.com/tiiuae/Falcon-H1). | H1 7B | 44 | 3072 | 12 | 2 | 24 | 128 / 128 | 256 | 256K | | H1 34B | 72 | 5120 | 20 | 4 | 32 | 128 / 128 | 256 | 256K | - - [[autodoc]] FalconH1Config @@ -90,6 +89,7 @@ echo -e "Plants create energy through a process known as" | transformers run --t Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for more available quantization backends. The example below uses [torchao](../quantization/torchao) to only quantize the weights to 4-bits. + ```py #pip install torchao @@ -119,7 +119,6 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` - ## FlexOlmoConfig [[autodoc]] FlexOlmoConfig diff --git a/docs/source/en/model_doc/fnet.md b/docs/source/en/model_doc/fnet.md index 79a4e9e4434d..e89a410b105b 100644 --- a/docs/source/en/model_doc/fnet.md +++ b/docs/source/en/model_doc/fnet.md @@ -46,8 +46,8 @@ This model was contributed by [gchhablani](https://huggingface.co/gchhablani). T ## Usage tips -The model was trained without an attention mask as it is based on Fourier Transform. The model was trained with -maximum sequence length 512 which includes pad tokens. Hence, it is highly recommended to use the same maximum +The model was trained without an attention mask as it is based on Fourier Transform. The model was trained with +maximum sequence length 512 which includes pad tokens. Hence, it is highly recommended to use the same maximum sequence length for fine-tuning and inference. ## Resources diff --git a/docs/source/en/model_doc/fsmt.md b/docs/source/en/model_doc/fsmt.md index 27c7d3a899c4..13a99ae40da7 100644 --- a/docs/source/en/model_doc/fsmt.md +++ b/docs/source/en/model_doc/fsmt.md @@ -41,7 +41,6 @@ This model was contributed by [stas](https://huggingface.co/stas). The original either. Its tokenizer is very similar to [`XLMTokenizer`] and the main model is derived from [`BartModel`]. - ## FSMTConfig [[autodoc]] FSMTConfig diff --git a/docs/source/en/model_doc/funnel.md b/docs/source/en/model_doc/funnel.md index 611e17fba8ce..57b011b9400c 100644 --- a/docs/source/en/model_doc/funnel.md +++ b/docs/source/en/model_doc/funnel.md @@ -67,7 +67,6 @@ This model was contributed by [sgugger](https://huggingface.co/sgugger). The ori - [Masked language modeling task guide](../tasks/masked_language_modeling) - [Multiple choice task guide](../tasks/multiple_choice) - ## FunnelConfig [[autodoc]] FunnelConfig diff --git a/docs/source/en/model_doc/fuyu.md b/docs/source/en/model_doc/fuyu.md index 140216e2abc7..34202b022f7e 100644 --- a/docs/source/en/model_doc/fuyu.md +++ b/docs/source/en/model_doc/fuyu.md @@ -40,7 +40,6 @@ Finetuning the model in `float16` is not recommended and known to produce `nan`, - Tips: - To convert the model, you need to clone the original repository using `git clone https://github.com/persimmon-ai-labs/adept-inference`, then get the checkpoints: @@ -55,10 +54,12 @@ python src/transformers/models/fuyu/convert_fuyu_weights_to_hf.py --input_dir / ``` For the chat model: + ```bash wget https://axtkn4xl5cip.objectstorage.us-phoenix-1.oci.customer-oci.com/n/axtkn4xl5cip/b/adept-public-data/o/8b_chat_model_release.tar tar -xvf 8b_base_model_release.tar ``` + Then, model can be loaded via: ```py @@ -99,7 +100,6 @@ The `LlamaTokenizer` is used as it is a standard wrapper around sentencepiece. - The authors suggest to use the following prompt for image captioning: `f"Generate a coco-style caption.\\n"` - ## FuyuConfig [[autodoc]] FuyuConfig diff --git a/docs/source/en/model_doc/gemma.md b/docs/source/en/model_doc/gemma.md index d22d28d41c4b..f1c088caf300 100644 --- a/docs/source/en/model_doc/gemma.md +++ b/docs/source/en/model_doc/gemma.md @@ -33,7 +33,6 @@ The instruction-tuned variant was fine-tuned with supervised learning on instruc You can find all the original Gemma checkpoints under the [Gemma](https://huggingface.co/collections/google/gemma-release-65d5efbccdbb8c4202ec078b) release. - > [!TIP] > Click on the Gemma models in the right sidebar for more examples of how to apply Gemma to different language tasks. @@ -163,7 +162,6 @@ visualizer("LLMs generate text through a process known as") [[autodoc]] GemmaTokenizer - ## GemmaTokenizerFast [[autodoc]] GemmaTokenizerFast diff --git a/docs/source/en/model_doc/gemma2.md b/docs/source/en/model_doc/gemma2.md index 680de41d0380..5b4430296dcf 100644 --- a/docs/source/en/model_doc/gemma2.md +++ b/docs/source/en/model_doc/gemma2.md @@ -40,7 +40,6 @@ The example below demonstrates how to chat with the model with [`Pipeline`] or t - ```python import torch from transformers import pipeline @@ -84,6 +83,7 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True)) ``` echo -e "Explain quantum computing simply." | transformers run --task text-generation --model google/gemma-2-2b --device 0 ``` + @@ -113,7 +113,6 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True)) Use the [AttentionMaskVisualizer](https://github.com/huggingface/transformers/blob/beb9b5b02246b9b7ee81ddf938f93f44cfeaad19/src/transformers/utils/attention_visualizer.py#L139) to better understand what tokens the model can and cannot attend to. - ```python from transformers.utils.attention_visualizer import AttentionMaskVisualizer visualizer = AttentionMaskVisualizer("google/gemma-2b") diff --git a/docs/source/en/model_doc/gemma3.md b/docs/source/en/model_doc/gemma3.md index c14b79080fcd..3c69cc1604ff 100644 --- a/docs/source/en/model_doc/gemma3.md +++ b/docs/source/en/model_doc/gemma3.md @@ -195,6 +195,7 @@ visualizer("What is shown in this image?") }, ] ``` + - Text passed to the processor should have a `` token wherever an image should be inserted. - The processor has its own [`~ProcessorMixin.apply_chat_template`] method to convert chat messages to model inputs. - By default, images aren't cropped and only the base image is forwarded to the model. In high resolution images or images with non-square aspect ratios, artifacts can result because the vision encoder uses a fixed resolution of 896x896. To prevent these artifacts and improve performance during inference, set `do_pan_and_scan=True` to crop the image into multiple smaller patches and concatenate them with the base image embedding. You can disable pan and scan for faster inference. @@ -209,6 +210,7 @@ visualizer("What is shown in this image?") + do_pan_and_scan=True, ).to(model.device) ``` + - For Gemma-3 1B checkpoint trained in text-only mode, use [`AutoModelForCausalLM`] instead. ```py diff --git a/docs/source/en/model_doc/gemma3n.md b/docs/source/en/model_doc/gemma3n.md index b43379cf3fd4..7c2e3ecc9269 100644 --- a/docs/source/en/model_doc/gemma3n.md +++ b/docs/source/en/model_doc/gemma3n.md @@ -147,6 +147,7 @@ echo -e "Plants create energy through a process known as" | transformers run --t }, ] ``` + - Text passed to the processor should have a `` token wherever an image should be inserted. - Gemma 3n accept at most one target audio clip per input, though multiple audio clips can be provided in few-shot prompts, for example. diff --git a/docs/source/en/model_doc/glm.md b/docs/source/en/model_doc/glm.md index ca50c32da21b..87daea7289a9 100644 --- a/docs/source/en/model_doc/glm.md +++ b/docs/source/en/model_doc/glm.md @@ -53,7 +53,6 @@ Tips: - This model was contributed by [THUDM](https://huggingface.co/THUDM). The most recent code can be found [here](https://github.com/thudm/GLM-4). - ## Usage tips `GLM-4` can be found on the [Huggingface Hub](https://huggingface.co/collections/THUDM/glm-4-665fcf188c414b03c2f7e3b7) diff --git a/docs/source/en/model_doc/glm4v.md b/docs/source/en/model_doc/glm4v.md index be78c73b3fb4..1f80d4b2584e 100644 --- a/docs/source/en/model_doc/glm4v.md +++ b/docs/source/en/model_doc/glm4v.md @@ -75,6 +75,7 @@ messages = [ ] pipe(text=messages,max_new_tokens=20, return_full_text=False) ``` + @@ -123,6 +124,7 @@ output_text = processor.batch_decode( ) print(output_text) ``` + diff --git a/docs/source/en/model_doc/got_ocr2.md b/docs/source/en/model_doc/got_ocr2.md index 026273aa158b..f8d6d69b0f6d 100644 --- a/docs/source/en/model_doc/got_ocr2.md +++ b/docs/source/en/model_doc/got_ocr2.md @@ -34,7 +34,6 @@ alt="drawing" width="600"/> GOT-OCR2 training stages. Taken from the original paper. - Tips: GOT-OCR2 works on a wide range of tasks, including plain document OCR, scene text OCR, formatted document OCR, and even OCR for tables, charts, mathematical formulas, geometric shapes, molecular formulas and sheet music. While this implementation of the model will only output plain text, the outputs can be further processed to render the desired format, with packages like `pdftex`, `mathpix`, `matplotlib`, `tikz`, `verovio` or `pyecharts`. @@ -129,7 +128,6 @@ GOT-OCR2 can also generate formatted text, such as markdown or LaTeX. Here is an Although it might be reasonable in most cases to use a “for loop” for multi-page processing, some text data with formatting across several pages make it necessary to process all pages at once. GOT introduces a multi-page OCR (without “for loop”) feature, where multiple pages can be processed by the model at once, with the output being one continuous text. Here is an example of how to process multiple pages at once: - ```python >>> import torch >>> from transformers import AutoProcessor, AutoModelForImageTextToText, infer_device @@ -254,6 +252,7 @@ Here is an example of how to process sheet music: >>> with open("output.svg", "w") as f: >>> f.write(svg) ``` + drawing @@ -285,4 +284,3 @@ alt="drawing" width="600"/> [[autodoc]] GotOcr2ForConditionalGeneration - forward - diff --git a/docs/source/en/model_doc/gpt2.md b/docs/source/en/model_doc/gpt2.md index 1645a92f6346..aaf2a50a1731 100644 --- a/docs/source/en/model_doc/gpt2.md +++ b/docs/source/en/model_doc/gpt2.md @@ -23,7 +23,6 @@ rendered properly in your Markdown viewer. - # GPT-2 [GPT-2](https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf) is a scaled up version of GPT, a causal transformer language model, with 10x more parameters and training data. The model was pretrained on a 40GB dataset to predict the next word in a sequence based on all the previous words. This approach enabled the model to perform many downstream tasks in a zero-shot setting. The blog post released by OpenAI can be found [here](https://openai.com/index/better-language-models/). @@ -47,6 +46,7 @@ from transformers import pipeline pipeline = pipeline(task="text-generation", model="openai-community/gpt2", dtype=torch.float16, device=0) pipeline("Hello, I'm a language model") ``` + diff --git a/docs/source/en/model_doc/gpt_bigcode.md b/docs/source/en/model_doc/gpt_bigcode.md index a16536cbbe5c..e837f2a08f52 100644 --- a/docs/source/en/model_doc/gpt_bigcode.md +++ b/docs/source/en/model_doc/gpt_bigcode.md @@ -47,7 +47,6 @@ The main differences compared to GPT2. - Merge the key and value caches into one (this changes the format of layer_past/ present, does it risk creating problems?) - Use the memory layout (self.num_heads, 3, self.head_dim) instead of `(3, self.num_heads, self.head_dim)` for the QKV tensor with MHA. (prevents an overhead with the merged key and values, but makes the checkpoints incompatible with the original openai-community/gpt2 model). - You can read more about the optimizations in the [original pull request](https://github.com/huggingface/transformers/pull/22575) > [!NOTE] @@ -91,7 +90,6 @@ Below is a expected speedup diagram that compares pure inference time between th - ## GPTBigCodeConfig [[autodoc]] GPTBigCodeConfig diff --git a/docs/source/en/model_doc/gpt_neo.md b/docs/source/en/model_doc/gpt_neo.md index de48bce65085..4df9cf69842d 100644 --- a/docs/source/en/model_doc/gpt_neo.md +++ b/docs/source/en/model_doc/gpt_neo.md @@ -22,12 +22,10 @@ rendered properly in your Markdown viewer. - ## GPT-Neo [GPT-Neo](https://zenodo.org/records/5297715) is an open-source alternative to GPT-2 and GPT-3 models, built with Mesh TensorFlow for TPUs. GPT-Neo uses local attention in every other layer for more efficiency. It is trained on the [Pile](https://huggingface.co/datasets/EleutherAI/pile), a diverse dataset consisting of 22 smaller high-quality datasets. The original github repository can be found [here](https://github.com/EleutherAI/gpt-neo/tree/v1.1) - You can find all the original GPT-Neo checkpoints under the [EleutherAI](https://huggingface.co/EleutherAI?search_models=gpt-neo) organization. > [!TIP] @@ -45,6 +43,7 @@ from transformers import pipeline pipeline = pipeline(task="text-generation", model="EleutherAI/gpt-neo-1.3B", dtype=torch.float16, device=0) pipeline("Hello, I'm a language model") ``` + diff --git a/docs/source/en/model_doc/gpt_neox.md b/docs/source/en/model_doc/gpt_neox.md index a24fc6aa1d71..fb2ff7093040 100644 --- a/docs/source/en/model_doc/gpt_neox.md +++ b/docs/source/en/model_doc/gpt_neox.md @@ -71,7 +71,7 @@ The `generate()` method can be used to generate text using GPT Neo model. Flash Attention 2 is an faster, optimized version of the model. -### Installation +### Installation First, check whether your hardware is compatible with Flash Attention 2. The latest list of compatible hardware can be found in the [official documentation](https://github.com/Dao-AILab/flash-attention#installation-and-features). If your hardware is not compatible with Flash Attention 2, you can still benefit from attention kernel optimisations through Better Transformer support covered [above](https://huggingface.co/docs/transformers/main/en/model_doc/bark#using-better-transformer). @@ -92,7 +92,6 @@ model = GPTNeoXForCausalLM.from_pretrained("EleutherAI/gpt-neox-20b", dtype=torc ... ``` - ### Expected speedups Below is an expected speedup diagram that compares pure inference time between the native implementation in transformers using `stockmark/gpt-neox-japanese-1.4b` checkpoint and the Flash Attention 2 version of the model using a sequence length of 2048. @@ -101,7 +100,6 @@ Below is an expected speedup diagram that compares pure inference time between t - ## Using Scaled Dot Product Attention (SDPA) PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the @@ -162,7 +160,6 @@ following speedups during training and inference. | 4 | 1024 | 11.765 | 11.303 | 4.09 | 2558.96 | 2546.04 | 0.508 | | 4 | 2048 | 19.568 | 17.735 | 10.33 | 4175.5 | 4165.26 | 0.246 | - ## Resources - [Causal language modeling task guide](../tasks/language_modeling) diff --git a/docs/source/en/model_doc/gpt_neox_japanese.md b/docs/source/en/model_doc/gpt_neox_japanese.md index 7b22484b9a76..bf786f7561d4 100644 --- a/docs/source/en/model_doc/gpt_neox_japanese.md +++ b/docs/source/en/model_doc/gpt_neox_japanese.md @@ -27,8 +27,6 @@ rendered properly in your Markdown viewer. GPT-NeoX-Japanese, a Japanese language model based on [GPT-NeoX](./gpt_neox). Japanese uses three types of characters (hiragana, katakana, kanji) and has a huge vocabulary. This model uses [BPEEncoder V2](https://github.com/tanreinama/Japanese-BPEEncoder_V2), a sub-word tokenizer to handle the different characters. - - The model also removes some bias parameters for better performance. You can find all the original GPT-NeoX-Japanese checkpoints under the [ABEJA](https://huggingface.co/abeja/models?search=gpt-neo-x) organization. diff --git a/docs/source/en/model_doc/gpt_oss.md b/docs/source/en/model_doc/gpt_oss.md index 136ebeb29570..47c970eb17e6 100644 --- a/docs/source/en/model_doc/gpt_oss.md +++ b/docs/source/en/model_doc/gpt_oss.md @@ -41,7 +41,6 @@ Tips: This model was contributed by [INSERT YOUR HF USERNAME HERE](https://huggingface.co/). The original code can be found [here](). - ## GptOssConfig [[autodoc]] GptOssConfig diff --git a/docs/source/en/model_doc/granite.md b/docs/source/en/model_doc/granite.md index fce23a3c3493..ef8bb0867b6e 100644 --- a/docs/source/en/model_doc/granite.md +++ b/docs/source/en/model_doc/granite.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2024-08-23 and added to Hugging Face Transformers on 2024-08-27.* -
PyTorch FlashAttention @@ -69,12 +68,14 @@ inputs = tokenizer("Explain quantum computing in simple terms", return_tensors=" outputs = model.generate(**inputs, max_length=50, cache_implementation="static") print(tokenizer.decode(outputs[0], skip_special_tokens=True)) ``` + ```python echo -e "Explain quantum computing simply." | transformers run --task text-generation --model ibm-granite/granite-3.3-8b-instruct --device 0 ``` + @@ -110,7 +111,6 @@ outputs = model.generate(**inputs, max_length=50, cache_implementation="static") print(tokenizer.decode(outputs[0], skip_special_tokens=True)) ``` - ## GraniteConfig [[autodoc]] GraniteConfig diff --git a/docs/source/en/model_doc/granite_speech.md b/docs/source/en/model_doc/granite_speech.md index 5de42ff993f8..680dba3a4732 100644 --- a/docs/source/en/model_doc/granite_speech.md +++ b/docs/source/en/model_doc/granite_speech.md @@ -32,10 +32,8 @@ The [Granite Speech](https://huggingface.co/papers/2505.08699) model ([blog post 4. LoRA adapter(s): The Granite Speech model contains a modality specific LoRA, which will be enabled when audio features are provided, and disabled otherwise. - Note that most of the aforementioned components are implemented generically to enable compatibility and potential integration with other model architectures in transformers. - This model was contributed by [Alexander Brooks](https://huggingface.co/abrooks9944), [Avihu Dekel](https://huggingface.co/Avihu), and [George Saon](https://huggingface.co/gsaon). ## Usage tips @@ -47,22 +45,18 @@ This model was contributed by [Alexander Brooks](https://huggingface.co/abrooks9 [[autodoc]] GraniteSpeechConfig - ## GraniteSpeechEncoderConfig [[autodoc]] GraniteSpeechEncoderConfig - ## GraniteSpeechProcessor [[autodoc]] GraniteSpeechProcessor - ## GraniteSpeechFeatureExtractor [[autodoc]] GraniteSpeechFeatureExtractor - ## GraniteSpeechForConditionalGeneration [[autodoc]] GraniteSpeechForConditionalGeneration diff --git a/docs/source/en/model_doc/granitemoe.md b/docs/source/en/model_doc/granitemoe.md index 71c266a76b51..32616c07a289 100644 --- a/docs/source/en/model_doc/granitemoe.md +++ b/docs/source/en/model_doc/granitemoe.md @@ -65,7 +65,6 @@ for i in output: This model was contributed by [mayank-mishra](https://huggingface.co/mayank-mishra). - ## GraniteMoeConfig [[autodoc]] GraniteMoeConfig diff --git a/docs/source/en/model_doc/granitemoehybrid.md b/docs/source/en/model_doc/granitemoehybrid.md index 27b6e85d9e95..cb3db122e65d 100644 --- a/docs/source/en/model_doc/granitemoehybrid.md +++ b/docs/source/en/model_doc/granitemoehybrid.md @@ -19,10 +19,8 @@ rendered properly in your Markdown viewer. ## Overview - The [GraniteMoeHybrid](https://www.ibm.com/new/announcements/ibm-granite-4-0-tiny-preview-sneak-peek) model builds on top of GraniteMoeSharedModel and Bamba. Its decoding layers consist of state space layers or MoE attention layers with shared experts. By default, the attention layers do not use positional encoding. - ```python from transformers import AutoModelForCausalLM, AutoTokenizer diff --git a/docs/source/en/model_doc/granitemoeshared.md b/docs/source/en/model_doc/granitemoeshared.md index d09ab5766faa..8b256de647f6 100644 --- a/docs/source/en/model_doc/granitemoeshared.md +++ b/docs/source/en/model_doc/granitemoeshared.md @@ -19,7 +19,6 @@ rendered properly in your Markdown viewer. ## Overview - The GraniteMoe model was proposed in [Power Scheduler: A Batch Size and Token Number Agnostic Learning Rate Scheduler](https://huggingface.co/papers/2408.13359) by Yikang Shen, Matthew Stallone, Mayank Mishra, Gaoyuan Zhang, Shawn Tan, Aditya Prasad, Adriana Meza Soria, David D. Cox and Rameswar Panda. Additionally this class GraniteMoeSharedModel adds shared experts for Moe. @@ -51,7 +50,6 @@ for i in output: This HF implementation is contributed by [Mayank Mishra](https://huggingface.co/mayank-mishra), [Shawn Tan](https://huggingface.co/shawntan) and [Sukriti Sharma](https://huggingface.co/SukritiSharma). - ## GraniteMoeSharedConfig [[autodoc]] GraniteMoeSharedConfig diff --git a/docs/source/en/model_doc/granitevision.md b/docs/source/en/model_doc/granitevision.md index b138c66f79d8..f5a6316a22c0 100644 --- a/docs/source/en/model_doc/granitevision.md +++ b/docs/source/en/model_doc/granitevision.md @@ -25,11 +25,13 @@ Tips: - This model is loaded into Transformers as an instance of LlaVA-Next. The usage and tips from [LLaVA-NeXT](llava_next) apply to this model as well. - You can apply the chat template on the tokenizer / processor in the same way as well. Example chat format: + ```bash "<|user|>\nWhat’s shown in this image?\n<|assistant|>\nThis image shows a red stop sign.<|end_of_text|><|user|>\nDescribe the image in more details.\n<|assistant|>\n" ``` Sample inference: + ```python from transformers import LlavaNextProcessor, LlavaNextForConditionalGeneration, infer_device diff --git a/docs/source/en/model_doc/helium.md b/docs/source/en/model_doc/helium.md index ba06feb18fbe..10748f27be43 100644 --- a/docs/source/en/model_doc/helium.md +++ b/docs/source/en/model_doc/helium.md @@ -27,7 +27,6 @@ rendered properly in your Markdown viewer. Helium was proposed in [Announcing Helium-1 Preview](https://kyutai.org/2025/01/13/helium.html) by the Kyutai Team. - Helium-1 preview is a lightweight language model with 2B parameters, targeting edge and mobile devices. It supports the following languages: English, French, German, Italian, Portuguese, Spanish. @@ -36,9 +35,6 @@ It supports the following languages: English, French, German, Italian, Portugues - **Language(s) (NLP):** English, French, German, Italian, Portuguese, Spanish - **License:** CC-BY 4.0 - - - ## Evaluation @@ -47,7 +43,7 @@ It supports the following languages: English, French, German, Italian, Portugues -The model was evaluated on MMLU, TriviaQA, NaturalQuestions, ARC Easy & Challenge, Open Book QA, Common Sense QA, +The model was evaluated on MMLU, TriviaQA, NaturalQuestions, ARC Easy & Challenge, Open Book QA, Common Sense QA, Physical Interaction QA, Social Interaction QA, HellaSwag, WinoGrande, Multilingual Knowledge QA, FLORES 200. #### Metrics @@ -92,7 +88,6 @@ We report BLEU on FLORES. || HS | 58.6 | 40.8 | 60.5 | 61.1 | 51.4 | || MKQA | 16.0 | 7.9 | 18.5 | 20.6 | 10.6 | - ## Technical Specifications ### Model Architecture and Objective @@ -110,12 +105,11 @@ Tips: - This model was contributed by [Laurent Mazare](https://huggingface.co/lmz) - ## Usage tips `Helium` can be found on the [Huggingface Hub](https://huggingface.co/models?other=helium) -In the following, we demonstrate how to use `helium-1-preview` for the inference. +In the following, we demonstrate how to use `helium-1-preview` for the inference. ```python >>> from transformers import AutoModelForCausalLM, AutoTokenizer diff --git a/docs/source/en/model_doc/herbert.md b/docs/source/en/model_doc/herbert.md index 718a1a3df0bb..aa6a4bf96adf 100644 --- a/docs/source/en/model_doc/herbert.md +++ b/docs/source/en/model_doc/herbert.md @@ -45,7 +45,6 @@ models.* This model was contributed by [rmroczkowski](https://huggingface.co/rmroczkowski). The original code can be found [here](https://github.com/allegro/HerBERT). - ## Usage example ```python diff --git a/docs/source/en/model_doc/hgnet_v2.md b/docs/source/en/model_doc/hgnet_v2.md index 7461a19a0327..e5da5a0582d0 100644 --- a/docs/source/en/model_doc/hgnet_v2.md +++ b/docs/source/en/model_doc/hgnet_v2.md @@ -81,13 +81,11 @@ print(f"The predicted class label is: {predicted_class_label}") [[autodoc]] HGNetV2Config - ## HGNetV2Backbone [[autodoc]] HGNetV2Backbone - forward - ## HGNetV2ForImageClassification [[autodoc]] HGNetV2ForImageClassification diff --git a/docs/source/en/model_doc/hiera.md b/docs/source/en/model_doc/hiera.md index 9f4627dd53f1..b8fd9c141839 100644 --- a/docs/source/en/model_doc/hiera.md +++ b/docs/source/en/model_doc/hiera.md @@ -25,7 +25,7 @@ rendered properly in your Markdown viewer. Hiera was proposed in [Hiera: A Hierarchical Vision Transformer without the Bells-and-Whistles](https://huggingface.co/papers/2306.00989) by Chaitanya Ryali, Yuan-Ting Hu, Daniel Bolya, Chen Wei, Haoqi Fan, Po-Yao Huang, Vaibhav Aggarwal, Arkabandhu Chowdhury, Omid Poursaeed, Judy Hoffman, Jitendra Malik, Yanghao Li, Christoph Feichtenhofer -The paper introduces "Hiera," a hierarchical Vision Transformer that simplifies the architecture of modern hierarchical vision transformers by removing unnecessary components without compromising on accuracy or efficiency. Unlike traditional transformers that add complex vision-specific components to improve supervised classification performance, Hiera demonstrates that such additions, often termed "bells-and-whistles," are not essential for high accuracy. By leveraging a strong visual pretext task (MAE) for pretraining, Hiera retains simplicity and achieves superior accuracy and speed both in inference and training across various image and video recognition tasks. The approach suggests that spatial biases required for vision tasks can be effectively learned through proper pretraining, eliminating the need for added architectural complexity. +The paper introduces "Hiera," a hierarchical Vision Transformer that simplifies the architecture of modern hierarchical vision transformers by removing unnecessary components without compromising on accuracy or efficiency. Unlike traditional transformers that add complex vision-specific components to improve supervised classification performance, Hiera demonstrates that such additions, often termed "bells-and-whistles," are not essential for high accuracy. By leveraging a strong visual pretext task (MAE) for pretraining, Hiera retains simplicity and achieves superior accuracy and speed both in inference and training across various image and video recognition tasks. The approach suggests that spatial biases required for vision tasks can be effectively learned through proper pretraining, eliminating the need for added architectural complexity. The abstract from the paper is the following: diff --git a/docs/source/en/model_doc/hubert.md b/docs/source/en/model_doc/hubert.md index 18c8062da36e..5a072214406c 100644 --- a/docs/source/en/model_doc/hubert.md +++ b/docs/source/en/model_doc/hubert.md @@ -115,6 +115,7 @@ print(transcription[0]) - HuBERT models expect raw audio input as a 1D float array sampled at 16kHz. - If you want to use a `head_mask`, use the model with `attn_implementation="eager"`. + ```python model = HubertModel.from_pretrained("facebook/hubert-base-ls960", attn_implementation="eager") ``` diff --git a/docs/source/en/model_doc/hunyuan_v1_dense.md b/docs/source/en/model_doc/hunyuan_v1_dense.md index 520c68b7fd9d..84f9e44e5225 100644 --- a/docs/source/en/model_doc/hunyuan_v1_dense.md +++ b/docs/source/en/model_doc/hunyuan_v1_dense.md @@ -25,7 +25,6 @@ To be released with the official model launch. To be released with the official model launch. - ## Usage tips To be released with the official model launch. @@ -48,4 +47,3 @@ To be released with the official model launch. [[autodoc]] HunYuanDenseV1ForSequenceClassification - forward - diff --git a/docs/source/en/model_doc/hunyuan_v1_moe.md b/docs/source/en/model_doc/hunyuan_v1_moe.md index 36a53742715d..e9bff74fe1bc 100644 --- a/docs/source/en/model_doc/hunyuan_v1_moe.md +++ b/docs/source/en/model_doc/hunyuan_v1_moe.md @@ -25,7 +25,6 @@ To be released with the official model launch. To be released with the official model launch. - ## Usage tips To be released with the official model launch. @@ -48,4 +47,3 @@ To be released with the official model launch. [[autodoc]] HunYuanMoEV1ForSequenceClassification - forward - diff --git a/docs/source/en/model_doc/idefics.md b/docs/source/en/model_doc/idefics.md index 6296e7226604..fdb6e5de4659 100644 --- a/docs/source/en/model_doc/idefics.md +++ b/docs/source/en/model_doc/idefics.md @@ -34,7 +34,6 @@ The abstract from the paper is the following: This model was contributed by [HuggingFaceM4](https://huggingface.co/HuggingFaceM4). The original code can be found [here](). (TODO: don't have a public link yet). - IDEFICS modeling code in Transformers is for finetuning and inferencing the pre-trained IDEFICS models. @@ -43,7 +42,6 @@ To train a new IDEFICS model from scratch use the m4 codebase (a link will be pr - ## IdeficsConfig [[autodoc]] IdeficsConfig diff --git a/docs/source/en/model_doc/idefics2.md b/docs/source/en/model_doc/idefics2.md index 63dd1ec8277d..696ad7c5d2bd 100644 --- a/docs/source/en/model_doc/idefics2.md +++ b/docs/source/en/model_doc/idefics2.md @@ -202,19 +202,16 @@ A list of official Hugging Face and community (indicated by 🌎) resources to h [[autodoc]] Idefics2Config - ## Idefics2Model [[autodoc]] Idefics2Model - forward - ## Idefics2ForConditionalGeneration [[autodoc]] Idefics2ForConditionalGeneration - forward - ## Idefics2ImageProcessor [[autodoc]] Idefics2ImageProcessor - preprocess diff --git a/docs/source/en/model_doc/idefics3.md b/docs/source/en/model_doc/idefics3.md index b3e199e2b882..0c8f46a9aeef 100644 --- a/docs/source/en/model_doc/idefics3.md +++ b/docs/source/en/model_doc/idefics3.md @@ -45,6 +45,7 @@ If `do_resize` is set to `True`, the model resizes images so that the longest ed The default resizing behavior can be customized by passing a dictionary to the `size` parameter. For example, `{"longest_edge": 4 * 364}` is the default, but you can change it to a different value if needed. Here’s how to control resizing and set a custom size: + ```python image_processor = Idefics3ImageProcessor(do_resize=True, size={"longest_edge": 2 * 364}, max_image_size=364) ``` @@ -53,7 +54,6 @@ Additionally, the `max_image_size` parameter, which controls the size of each sq This model was contributed by [amyeroberts](https://huggingface.co/amyeroberts) and [andimarafioti](https://huggingface.co/andito). - ## Idefics3Config [[autodoc]] Idefics3Config @@ -76,7 +76,6 @@ This model was contributed by [amyeroberts](https://huggingface.co/amyeroberts) [[autodoc]] Idefics3ForConditionalGeneration - forward - ## Idefics3ImageProcessor [[autodoc]] Idefics3ImageProcessor - preprocess diff --git a/docs/source/en/model_doc/ijepa.md b/docs/source/en/model_doc/ijepa.md index 9d7c7874f1a5..a81e7c3ab281 100644 --- a/docs/source/en/model_doc/ijepa.md +++ b/docs/source/en/model_doc/ijepa.md @@ -31,10 +31,8 @@ You can find the original I-JEPA checkpoints under the [AI at Meta](https://hugg > [!TIP] > This model was contributed by [jmtzt](https://huggingface.co/jmtzt). - - > Click on the I-JEPA models in the right sidebar for more examples of how to apply I-JEPA to different image representation and classification tasks. The example below demonstrates how to extract image features with [`Pipeline`] or the [`AutoModel`] class. @@ -88,10 +86,10 @@ embed_2 = infer(image_2) similarity = cosine_similarity(embed_1, embed_2) print(similarity) ``` + - Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for more available quantization backends. The example below uses [bitsandbytes](../quantization/bitsandbytes) to only quantize the weights to 4-bits. @@ -142,4 +140,3 @@ print(similarity) [[autodoc]] IJepaForImageClassification - forward - diff --git a/docs/source/en/model_doc/instructblip.md b/docs/source/en/model_doc/instructblip.md index b0669f1c065f..d22d8df0d397 100644 --- a/docs/source/en/model_doc/instructblip.md +++ b/docs/source/en/model_doc/instructblip.md @@ -59,7 +59,6 @@ The attributes can be obtained from model config, as `model.config.num_query_tok [[autodoc]] InstructBlipProcessor - ## InstructBlipVisionModel [[autodoc]] InstructBlipVisionModel diff --git a/docs/source/en/model_doc/instructblipvideo.md b/docs/source/en/model_doc/instructblipvideo.md index e34b454a1237..d4d868b7f90e 100644 --- a/docs/source/en/model_doc/instructblipvideo.md +++ b/docs/source/en/model_doc/instructblipvideo.md @@ -59,7 +59,6 @@ The attributes can be obtained from model config, as `model.config.num_query_tok [[autodoc]] InstructBlipVideoProcessor - ## InstructBlipVideoVideoProcessor [[autodoc]] InstructBlipVideoVideoProcessor diff --git a/docs/source/en/model_doc/internvl.md b/docs/source/en/model_doc/internvl.md index bf760fdbdd71..7e9fea7f4f20 100644 --- a/docs/source/en/model_doc/internvl.md +++ b/docs/source/en/model_doc/internvl.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2025-04-14 and added to Hugging Face Transformers on 2025-04-18.* -
PyTorch @@ -32,19 +31,14 @@ The abstract from the paper is the following: *We introduce InternVL3, a significant advancement in the InternVL series featuring a native multimodal pre-training paradigm. Rather than adapting a text-only large language model (LLM) into a multimodal large language model (MLLM) that supports visual inputs, InternVL3 jointly acquires multimodal and linguistic capabilities from both diverse multimodal data and pure-text corpora during a single pre-training stage. This unified training paradigm effectively addresses the complexities and alignment challenges commonly encountered in conventional post-hoc training pipelines for MLLMs. To further improve performance and scalability, InternVL3 incorporates variable visual position encoding (V2PE) to support extended multimodal contexts, employs advanced post-training techniques such as supervised fine-tuning (SFT) and mixed preference optimization (MPO), and adopts test-time scaling strategies alongside an optimized training infrastructure. Extensive empirical evaluations demonstrate that InternVL3 delivers superior performance across a wide range of multi-modal tasks. In particular, InternVL3-78B achieves a score of 72.2 on the MMMU benchmark, setting a new state-of-the-art among open-source MLLMs. Its capabilities remain highly competitive with leading proprietary models, including ChatGPT-4o, Claude 3.5 Sonnet, and Gemini 2.5 Pro, while also maintaining strong pure-language proficiency. In pursuit of open-science principles, we will publicly release both the training data and model weights to foster further research and development in next-generation MLLMs.* - drawing Overview of InternVL3 models architecture, which is the same as InternVL2.5. Taken from the original checkpoint. - - drawing Comparison of InternVL3 performance on OpenCompass against other SOTA VLLMs. Taken from the original checkpoint. - - This model was contributed by [yonigozlan](https://huggingface.co/yonigozlan). The original code can be found [here](https://github.com/OpenGVLab/InternVL). @@ -75,6 +69,7 @@ Here is how you can use the `image-text-to-text` pipeline to perform inference w >>> outputs[0]["generated_text"] 'The image showcases a vibrant scene of nature, featuring several flowers and a bee. \n\n1. **Foreground Flowers**: \n - The primary focus is on a large, pink cosmos flower with a prominent yellow center. The petals are soft and slightly r' ``` + ### Inference on a single image This example demonstrates how to perform inference on a single image with the InternVL models using chat templates. @@ -112,7 +107,6 @@ This example demonstrates how to perform inference on a single image with the In ### Text-only generation This example shows how to generate text using the InternVL model without providing any image input. - ```python >>> from transformers import AutoProcessor, AutoModelForImageTextToText >>> import torch diff --git a/docs/source/en/model_doc/jamba.md b/docs/source/en/model_doc/jamba.md index 0aa06b16e90f..f85d08c5f64d 100644 --- a/docs/source/en/model_doc/jamba.md +++ b/docs/source/en/model_doc/jamba.md @@ -75,6 +75,7 @@ input_ids = tokenizer("Plants create energy through a process known as", return_ output = model.generate(**input_ids, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + @@ -140,19 +141,16 @@ print(assistant_response) [[autodoc]] JambaConfig - ## JambaModel [[autodoc]] JambaModel - forward - ## JambaForCausalLM [[autodoc]] JambaForCausalLM - forward - ## JambaForSequenceClassification [[autodoc]] transformers.JambaForSequenceClassification diff --git a/docs/source/en/model_doc/jetmoe.md b/docs/source/en/model_doc/jetmoe.md index 059fb956ce23..3fca2c2d6764 100644 --- a/docs/source/en/model_doc/jetmoe.md +++ b/docs/source/en/model_doc/jetmoe.md @@ -27,15 +27,14 @@ rendered properly in your Markdown viewer. **JetMoe-8B** is an 8B Mixture-of-Experts (MoE) language model developed by [Yikang Shen](https://scholar.google.com.hk/citations?user=qff5rRYAAAAJ) and [MyShell](https://myshell.ai/). JetMoe project aims to provide a LLaMA2-level performance and efficient language model with a limited budget. -To achieve this goal, JetMoe uses a sparsely activated architecture inspired by the [ModuleFormer](https://huggingface.co/papers/2306.04640). +To achieve this goal, JetMoe uses a sparsely activated architecture inspired by the [ModuleFormer](https://huggingface.co/papers/2306.04640). Each JetMoe block consists of two MoE layers: Mixture of Attention Heads and Mixture of MLP Experts. Given the input tokens, it activates a subset of its experts to process them. -This sparse activation schema enables JetMoe to achieve much better training throughput than similar size dense models. +This sparse activation schema enables JetMoe to achieve much better training throughput than similar size dense models. The training throughput of JetMoe-8B is around 100B tokens per day on a cluster of 96 H100 GPUs with a straightforward 3-way pipeline parallelism strategy. This model was contributed by [Yikang Shen](https://huggingface.co/YikangS). - ## JetMoeConfig [[autodoc]] JetMoeConfig diff --git a/docs/source/en/model_doc/kosmos2_5.md b/docs/source/en/model_doc/kosmos2_5.md index 530f1d459ae7..706ce04cef4d 100644 --- a/docs/source/en/model_doc/kosmos2_5.md +++ b/docs/source/en/model_doc/kosmos2_5.md @@ -19,7 +19,6 @@ specific language governing permissions and limitations under the License.
- # KOSMOS-2.5 The Kosmos-2.5 model was proposed in [KOSMOS-2.5: A Multimodal Literate Model](https://huggingface.co/papers/2309.11419/) by Microsoft. @@ -159,7 +158,6 @@ image.save("output.png") - ## Chat version The authors also released Kosmos-2.5 Chat, which is a chat version optimized for document understanding. You can use it like so: diff --git a/docs/source/en/model_doc/kyutai_speech_to_text.md b/docs/source/en/model_doc/kyutai_speech_to_text.md index 30497e69594c..f3428f6b86ff 100644 --- a/docs/source/en/model_doc/kyutai_speech_to_text.md +++ b/docs/source/en/model_doc/kyutai_speech_to_text.md @@ -15,7 +15,7 @@ rendered properly in your Markdown viewer. --> *This model was released on 2025-06-17 and added to Hugging Face Transformers on 2025-06-25.* -# Kyutai Speech-To-Text +# Kyutai Speech-To-Text ## Overview [Kyutai STT](https://kyutai.org/next/stt) is a speech-to-text model architecture based on the [Mimi codec](https://huggingface.co/docs/transformers/en/model_doc/mimi), which encodes audio into discrete tokens in a streaming fashion, and a [Moshi-like](https://huggingface.co/docs/transformers/en/model_doc/moshi) autoregressive decoder. Kyutai’s lab has released two model checkpoints: @@ -98,7 +98,6 @@ for output in decoded_outputs: This model was contributed by [Eustache Le Bihan](https://huggingface.co/eustlb). The original code can be found [here](https://github.com/kyutai-labs/moshi). - ## KyutaiSpeechToTextConfig [[autodoc]] KyutaiSpeechToTextConfig diff --git a/docs/source/en/model_doc/layoutlm.md b/docs/source/en/model_doc/layoutlm.md index 708a5bc1ab40..88dde323e299 100644 --- a/docs/source/en/model_doc/layoutlm.md +++ b/docs/source/en/model_doc/layoutlm.md @@ -116,7 +116,6 @@ A list of official Hugging Face and community (indicated by 🌎) resources to h - Refer to this [notebook](https://github.com/NielsRogge/Transformers-Tutorials/blob/master/LayoutLM/Fine_tuning_LayoutLMForTokenClassification_on_FUNSD.ipynb) for an example of how to fine-tune LayoutLM for token classification. - Read [Deploy LayoutLM with Hugging Face Inference Endpoints](https://www.philschmid.de/inference-endpoints-layoutlm) to learn how to deploy LayoutLM. - ## LayoutLMConfig [[autodoc]] LayoutLMConfig diff --git a/docs/source/en/model_doc/layoutlmv2.md b/docs/source/en/model_doc/layoutlmv2.md index c376c04ad76e..f74d3b4294ee 100644 --- a/docs/source/en/model_doc/layoutlmv2.md +++ b/docs/source/en/model_doc/layoutlmv2.md @@ -55,10 +55,12 @@ this https URL.* LayoutLMv2 depends on `detectron2`, `torchvision` and `tesseract`. Run the following to install them: + ```bash python -m pip install 'git+https://github.com/facebookresearch/detectron2.git' python -m pip install torchvision tesseract ``` + (If you are developing for LayoutLMv2, note that passing the doctests also requires the installation of these packages.) ## Usage tips @@ -145,7 +147,6 @@ A list of official Hugging Face and community (indicated by 🌎) resources to h - See also: [Question answering task guide](../tasks/question_answering) - See also: [Document question answering task guide](../tasks/document_question_answering) - - A notebook on how to [finetune LayoutLMv2 for token-classification on CORD dataset](https://colab.research.google.com/github/NielsRogge/Transformers-Tutorials/blob/master/LayoutLMv2/CORD/Fine_tuning_LayoutLMv2ForTokenClassification_on_CORD.ipynb). diff --git a/docs/source/en/model_doc/led.md b/docs/source/en/model_doc/led.md index 4acc6a639797..ce1baa619a88 100644 --- a/docs/source/en/model_doc/led.md +++ b/docs/source/en/model_doc/led.md @@ -89,6 +89,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ```bash !echo -e "Plants are among the most remarkable and essential life forms on Earth, possessing a unique ability to produce their own food through a process known as photosynthesis. This complex biochemical process is fundamental not only to plant life but to virtually all life on the planet. Through photosynthesis, plants capture energy from sunlight using a green pigment called chlorophyll, which is located in specialized cell structures called chloroplasts." | transformers run --task summarization --model allenai/led-base-16384 --device 0 ``` + diff --git a/docs/source/en/model_doc/lfm2.md b/docs/source/en/model_doc/lfm2.md index 3ea0936b96be..0e78f9935f92 100644 --- a/docs/source/en/model_doc/lfm2.md +++ b/docs/source/en/model_doc/lfm2.md @@ -23,7 +23,7 @@ rendered properly in your Markdown viewer. ## Overview -[LFM2](https://www.liquid.ai/blog/liquid-foundation-models-v2-our-second-series-of-generative-ai-models) represents a new generation of Liquid Foundation Models developed by [Liquid AI](https://liquid.ai/), specifically designed for edge AI and on-device deployment. +[LFM2](https://www.liquid.ai/blog/liquid-foundation-models-v2-our-second-series-of-generative-ai-models) represents a new generation of Liquid Foundation Models developed by [Liquid AI](https://liquid.ai/), specifically designed for edge AI and on-device deployment. The models are available in three sizes (350M, 700M, and 1.2B parameters) and are engineered to run efficiently on CPU, GPU, and NPU hardware, making them particularly well-suited for applications requiring low latency, offline operation, and privacy. diff --git a/docs/source/en/model_doc/lfm2_vl.md b/docs/source/en/model_doc/lfm2_vl.md index 3a93a8189a70..2e25d94e883a 100644 --- a/docs/source/en/model_doc/lfm2_vl.md +++ b/docs/source/en/model_doc/lfm2_vl.md @@ -19,7 +19,7 @@ rendered properly in your Markdown viewer. PyTorch
-# LFM2-VL +# LFM2-VL ## Overview @@ -31,7 +31,7 @@ LFM2-VL consists of three main components: a language model backbone, a vision e * Shape-optimized (400M) for more fine-grained vision capabilities for LFM2-VL-1.6B * Base (86M) for fast image processing for LFM2-VL-450M -The encoder processes images at their native resolution up to 512×512 pixels, efficiently handling smaller images without upscaling and supporting non-standard aspect ratios without distortion. Larger images are split into non-overlapping square patches of 512×512 each, preserving detail. In LFM2-VL-1.6B, the model also receives a thumbnail (a small, downscaled version of the original image capturing the overall scene) to enhance global context understanding and alignment. Special tokens mark each patch’s position and indicate the thumbnail’s start. The multimodal connector is a 2-layer MLP connector with pixel unshuffle to reduce image token count. +The encoder processes images at their native resolution up to 512×512 pixels, efficiently handling smaller images without upscaling and supporting non-standard aspect ratios without distortion. Larger images are split into non-overlapping square patches of 512×512 each, preserving detail. In LFM2-VL-1.6B, the model also receives a thumbnail (a small, downscaled version of the original image capturing the overall scene) to enhance global context understanding and alignment. Special tokens mark each patch’s position and indicate the thumbnail’s start. The multimodal connector is a 2-layer MLP connector with pixel unshuffle to reduce image token count. ## Example diff --git a/docs/source/en/model_doc/lightglue.md b/docs/source/en/model_doc/lightglue.md index 847fabdaac20..16827345ef05 100644 --- a/docs/source/en/model_doc/lightglue.md +++ b/docs/source/en/model_doc/lightglue.md @@ -153,4 +153,3 @@ processed_outputs = processor.post_process_keypoint_matching(outputs, image_size [[autodoc]] LightGlueForKeypointMatching - forward - diff --git a/docs/source/en/model_doc/llama2.md b/docs/source/en/model_doc/llama2.md index 96c733d88fa4..c66667f235f6 100644 --- a/docs/source/en/model_doc/llama2.md +++ b/docs/source/en/model_doc/llama2.md @@ -130,11 +130,13 @@ visualizer("Plants create energy through a process known as") # update model config with padding token model.config.pad_token_id ``` + - It is recommended to initialize the `embed_tokens` layer with the following code to ensure encoding the padding token outputs zeros. ```py self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.config.padding_idx) ``` + - The tokenizer is a byte-pair encoding model based on [SentencePiece](https://github.com/google/sentencepiece). During decoding, if the first token is the start of the word (for example, "Banana"), the tokenizer doesn't prepend the prefix space to the string. - Don't use the `dtype` parameter in [`~AutoModel.from_pretrained`] if you're using FlashAttention-2 because it only supports fp16 or bf16. You should use [Automatic Mixed Precision](https://pytorch.org/tutorials/recipes/recipes/amp_recipe.html), set fp16 or bf16 to `True` if using [`Trainer`], or use [torch.autocast](https://pytorch.org/docs/stable/amp.html#torch.autocast). @@ -142,7 +144,6 @@ visualizer("Plants create energy through a process known as") [[autodoc]] LlamaConfig - ## LlamaTokenizer [[autodoc]] LlamaTokenizer @@ -165,7 +166,6 @@ visualizer("Plants create energy through a process known as") [[autodoc]] LlamaModel - forward - ## LlamaForCausalLM [[autodoc]] LlamaForCausalLM diff --git a/docs/source/en/model_doc/llama4.md b/docs/source/en/model_doc/llama4.md index 28e168b90439..84812a41997f 100644 --- a/docs/source/en/model_doc/llama4.md +++ b/docs/source/en/model_doc/llama4.md @@ -17,7 +17,6 @@ rendered properly in your Markdown viewer. # Llama4 -
PyTorch @@ -53,7 +52,6 @@ The examples below demonstrates how to generate with [`Pipeline`] or the [`AutoM showcasing how to toggle the right attributes to enable very long-context generations, as some flavors of Llama 4 have context lengths going up to 10 million tokens. - @@ -255,7 +253,6 @@ Updating the default attention function can significantly improve compute perfor As of release, the Llama 4 model supports the following attention methods: `eager`, `flex_attention`, `sdpa`. We recommend using `flex_attention` for best results. Switching attention mechanism is done at the model initialization step: - @@ -278,6 +275,7 @@ model = Llama4ForConditionalGeneration.from_pretrained( dtype=torch.bfloat16, ) ``` + The `sdpa` attention method is generally more compute-efficient than the `eager` method. @@ -293,6 +291,7 @@ model = Llama4ForConditionalGeneration.from_pretrained( dtype=torch.bfloat16, ) ``` + The `eager` attention method is set by default, so no need for anything different when loading the model: @@ -307,10 +306,10 @@ model = Llama4ForConditionalGeneration.from_pretrained( dtype=torch.bfloat16, ) ``` + - ### Quantization Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for available quantization backends. @@ -318,8 +317,6 @@ At time of release, both FBGEMM and LLM-Compressor are supported; more quantizat See below for examples using both: - - Here is an example loading an BF16 model in FP8 using the FBGEMM approach: @@ -378,6 +375,7 @@ outputs = model.generate(**inputs.to(model.device), max_new_tokens=100) outputs = tokenizer.batch_decode(outputs[:, inputs["input_ids"].shape[-1]:]) print(outputs[0]) ``` + diff --git a/docs/source/en/model_doc/llava.md b/docs/source/en/model_doc/llava.md index 1d7427b9015e..e4ef7d770694 100644 --- a/docs/source/en/model_doc/llava.md +++ b/docs/source/en/model_doc/llava.md @@ -47,13 +47,11 @@ The original code can be found [here](https://github.com/haotian-liu/LLaVA/tree/ - Note the model has not been explicitly trained to process multiple images in the same prompt, although this is technically possible, you may experience inaccurate results. - > [!NOTE] > LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. Adding these attributes means that LLaVA will try to infer the number of image tokens required per image and expand the text with as many `` placeholders as there will be tokens. Usually it is around 500 tokens per image, so make sure that the text is not truncated as otherwise there will be failure when merging the embeddings. The attributes can be obtained from model config, as `model.config.vision_config.patch_size` or `model.config.vision_feature_select_strategy`. The `num_additional_image_tokens` should be `1` if the vision backbone adds a CLS token or `0` if nothing extra is added to the vision patches. - ### Formatting Prompts with Chat Templates Each **checkpoint** is trained with a specific prompt format, depending on the underlying large language model backbone. To ensure correct formatting, use the processor’s `apply_chat_template` method. @@ -63,11 +61,9 @@ Each **checkpoint** is trained with a specific prompt format, depending on the u - Each message should be a dictionary with `"role"` and `"content"` keys. - The `"content"` should be a list of dictionaries for different modalities like `"text"` and `"image"`. - -Here’s an example of how to structure your input. +Here’s an example of how to structure your input. We will use [llava-hf/llava-1.5-7b-hf](https://huggingface.co/llava-hf/llava-1.5-7b-hf) and a conversation history of text and image. Each content field has to be a list of dicts, as follows: - ```python from transformers import AutoProcessor @@ -104,6 +100,7 @@ print(text_prompt) - If you want to construct a chat prompt yourself, below is a list of prompt formats accepted by each llava checkpoint: [llava-interleave models](https://huggingface.co/collections/llava-hf/llava-interleave-668e19a97da0036aad4a2f19) requires the following format: + ```bash "<|im_start|>user \nWhat is shown in this image?<|im_end|><|im_start|>assistant" ``` @@ -115,6 +112,7 @@ For multiple turns conversation: ``` [llava-1.5 models](https://huggingface.co/collections/llava-hf/llava-15-65f762d5b6941db5c2ba07e0) requires the following format: + ```bash "USER: \n ASSISTANT:" ``` @@ -127,12 +125,10 @@ For multiple turns conversation: 🚀 **Bonus:** If you're using `transformers>=4.49.0`, you can also get a vectorized output from `apply_chat_template`. See the **Usage Examples** below for more details on how to use it. - ## Usage examples ### Single input inference - ```python import torch from transformers import AutoProcessor, LlavaForConditionalGeneration @@ -164,7 +160,6 @@ generate_ids = model.generate(**inputs, max_new_tokens=30) processor.batch_decode(generate_ids, skip_special_tokens=True) ``` - ### Batched inference LLaVa also supports batched inference. Here is how you can do it: @@ -214,7 +209,6 @@ generate_ids = model.generate(**inputs, max_new_tokens=30) processor.batch_decode(generate_ids, skip_special_tokens=True) ``` - ## Note regarding reproducing original implementation In order to match the logits of the [original implementation](https://github.com/haotian-liu/LLaVA/tree/main), one needs to additionally specify `do_pad=True` when instantiating `LlavaImageProcessor`: @@ -238,7 +232,6 @@ A list of official Hugging Face and community (indicated by 🌎) resources to h - A [Google Colab demo](https://colab.research.google.com/drive/1qsl6cd2c8gGtEW1xV5io7S8NHh-Cp1TV?usp=sharing) on how to run Llava on a free-tier Google colab instance leveraging 4-bit inference. - A [similar notebook](https://github.com/NielsRogge/Transformers-Tutorials/blob/master/LLaVa/Inference_with_LLaVa_for_multimodal_generation.ipynb) showcasing batched inference. 🌎 - ## LlavaConfig [[autodoc]] LlavaConfig diff --git a/docs/source/en/model_doc/llava_next.md b/docs/source/en/model_doc/llava_next.md index e7ff4c896e25..3857f154cf4b 100644 --- a/docs/source/en/model_doc/llava_next.md +++ b/docs/source/en/model_doc/llava_next.md @@ -141,7 +141,6 @@ with torch.inference_mode(): print(processor.decode(output[0], skip_special_tokens=True)) ``` - ## Notes * Different checkpoints (Mistral, Vicuna, etc.) require a specific prompt format depending on the underlying LLM. Always use [`~ProcessorMixin.apply_chat_template`] to ensure correct formatting. Refer to the [Templates](../chat_templating) guide for more details. @@ -189,7 +188,6 @@ output = model.generate(**inputs, max_new_tokens=100) print(processor.decode(output[0], skip_special_tokens=True)) ``` - ## LlavaNextConfig [[autodoc]] LlavaNextConfig diff --git a/docs/source/en/model_doc/llava_next_video.md b/docs/source/en/model_doc/llava_next_video.md index 9379c1cc2ed6..131dd1aba50e 100644 --- a/docs/source/en/model_doc/llava_next_video.md +++ b/docs/source/en/model_doc/llava_next_video.md @@ -30,7 +30,6 @@ The LLaVa-NeXT-Video model was proposed in [LLaVA-NeXT: A Strong Zero-shot Video [LLaVA-NeXT](llava_next) surprisingly has strong performance in understanding video content in zero-shot fashion with the AnyRes technique that it uses. The AnyRes technique naturally represents a high-resolution image into multiple images. This technique is naturally generalizable to represent videos because videos can be considered as a set of frames (similar to a set of images in LLaVa-NeXT). The current version of LLaVA-NeXT makes use of AnyRes and trains with supervised fine-tuning (SFT) on top of LLaVA-Next on video data to achieves better video understanding capabilities.The model is a current SOTA among open-source models on [VideoMME bench](https://huggingface.co/papers/2405.21075). - The introduction from the blog is the following: On January 30, 2024, we released LLaVA-NeXT, an open-source Large Multimodal Model (LMM) that has been trained exclusively on text-image data. With the proposed AnyRes technique, it boosts capabilities in reasoning, OCR, and world knowledge, demonstrating remarkable performance across a spectrum of image-based multimodal understanding tasks, and even exceeding Gemini-Pro on several image benchmarks, e.g. MMMU and MathVista. @@ -42,7 +41,6 @@ On January 30, 2024, we released LLaVA-NeXT, an open-source Large Multimodal Mod - Strong video understanding ability. (1) LLaVA-Next-Image, which combines the above two techniques, yields superior zero-shot performance than open-source LMMs tuned on videos. (2) LLaVA-Next-Video, further supervised fine-tuning (SFT) LLaVA-Next-Image on video data, achieves better video understanding capabilities compared to LLaVA-Next-Image. (3) LLaVA-Next-Video-DPO, which aligns the model response with AI feedback using direct preference optimization (DPO), showing significant performance boost. - Efficient deployment and inference with SGLang. It allows 5x faster inference on video tasks, allowing more scalable serving such as million-level video re-captioning. See instructions in our repo.** - This model was contributed by [RaushanTurganbay](https://huggingface.co/RaushanTurganbay). The original code can be found [here](https://github.com/LLaVA-VL/LLaVA-NeXT/tree/inference). @@ -56,13 +54,11 @@ The original code can be found [here](https://github.com/LLaVA-VL/LLaVA-NeXT/tre - > [!NOTE] > LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. Adding these attributes means that LLaVA will try to infer the number of image tokens required per image and expand the text with as many `` placeholders as there will be tokens. Usually it is around 500 tokens per image, so make sure that the text is not truncated as otherwise there will be failure when merging the embeddings. The attributes can be obtained from model config, as `model.config.vision_config.patch_size` or `model.config.vision_feature_select_strategy`. The `num_additional_image_tokens` should be `1` if the vision backbone adds a CLS token or `0` if nothing extra is added to the vision patches. - ### Formatting Prompts with Chat Templates Each **checkpoint** is trained with a specific prompt format, depending on the underlying large language model backbone. To ensure correct formatting, use the processor’s `apply_chat_template` method. @@ -72,7 +68,6 @@ Each **checkpoint** is trained with a specific prompt format, depending on the u - Each message should be a dictionary with `"role"` and `"content"` keys. - The `"content"` should be a list of dictionaries for different modalities like `"text"` and `"image"`. - Here’s an example of how to structure your input. We will use [LLaVA-NeXT-Video-7B-hf](https://huggingface.co/llava-hf/LLaVA-NeXT-Video-7B-hf) and a conversation history of videos and images. ```python @@ -116,8 +111,6 @@ print(text_prompt) 🚀 **Bonus:** If you're using `transformers>=4.49.0`, you can also get a vectorized output from `apply_chat_template`. See the **Usage Examples** below for more details on how to use it. - - ## Usage example ### Single Media Mode @@ -153,10 +146,9 @@ out = model.generate(**inputs, max_new_tokens=60) processor.batch_decode(out, skip_special_tokens=True, clean_up_tokenization_spaces=True) ``` - ### Mixed Media Mode -The model can also generate from an interleaved image-video inputs. However note, that it was not trained in interleaved image-video setting which might affect the performance. Below is an example usage for mixed media input, add the following lines to the above code snippet: +The model can also generate from an interleaved image-video inputs. However note, that it was not trained in interleaved image-video setting which might affect the performance. Below is an example usage for mixed media input, add the following lines to the above code snippet: ```python @@ -196,7 +188,7 @@ processor.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokeniza ### Quantization using Bitsandbytes for memory efficiency -The model can be loaded in lower bits, significantly reducing memory burden while maintaining the performance of the original model. This allows for efficient deployment on resource-constrained cases. +The model can be loaded in lower bits, significantly reducing memory burden while maintaining the performance of the original model. This allows for efficient deployment on resource-constrained cases. First, make sure to install bitsandbytes by running `pip install bitsandbytes` and to have access to a GPU/accelerator that is supported by the library. @@ -210,7 +202,6 @@ We value your feedback to help identify bugs before the full release! Check out Then simply load the quantized model by adding [`BitsAndBytesConfig`](../main_classes/quantization#transformers.BitsAndBytesConfig) as shown below: - ```python from transformers import LlavaNextVideoForConditionalGeneration, LlavaNextVideoProcessor @@ -224,7 +215,6 @@ quantization_config = BitsAndBytesConfig( model = LlavaNextVideoForConditionalGeneration.from_pretrained("llava-hf/LLaVA-NeXT-Video-7B-hf", quantization_config=quantization_config, device_map="auto") ``` - ### Flash-Attention 2 to speed-up generation Additionally, we can greatly speed-up model inference by using [Flash Attention](../perf_train_gpu_one#flash-attention-2), which is a faster implementation of the attention mechanism used inside the model. @@ -249,8 +239,6 @@ model = LlavaNextVideoForConditionalGeneration.from_pretrained( ).to(0) ``` - - ## LlavaNextVideoConfig [[autodoc]] LlavaNextVideoConfig diff --git a/docs/source/en/model_doc/llava_onevision.md b/docs/source/en/model_doc/llava_onevision.md index e546530922ad..48fa769835f3 100644 --- a/docs/source/en/model_doc/llava_onevision.md +++ b/docs/source/en/model_doc/llava_onevision.md @@ -54,7 +54,6 @@ Tips: - ### Formatting Prompts with Chat Templates Each **checkpoint** is trained with a specific prompt format, depending on the underlying large language model backbone. To ensure correct formatting, use the processor’s `apply_chat_template` method. @@ -64,8 +63,7 @@ Each **checkpoint** is trained with a specific prompt format, depending on the u - Each message should be a dictionary with `"role"` and `"content"` keys. - The `"content"` should be a list of dictionaries for different modalities like `"text"` and `"image"`. - -Here’s an example of how to structure your input. +Here’s an example of how to structure your input. We will use [llava-onevision-qwen2-7b-si-hf](https://huggingface.co/llava-hf/llava-onevision-qwen2-7b-si-hf) and a conversation history of text and image. Each content field has to be a list of dicts, as follows: ```python @@ -103,11 +101,9 @@ print(text_prompt) 🚀 **Bonus:** If you're using `transformers>=4.49.0`, you can also get a vectorized output from `apply_chat_template`. See the **Usage Examples** below for more details on how to use it. - This model was contributed by [RaushanTurganbay](https://huggingface.co/RaushanTurganbay). The original code can be found [here](https://github.com/LLaVA-VL/LLaVA-NeXT/tree/main). - ## Usage example ### Single image inference @@ -293,7 +289,6 @@ model = LlavaOnevisionForConditionalGeneration.from_pretrained( ).to(0) ``` - ## LlavaOnevisionConfig [[autodoc]] LlavaOnevisionConfig diff --git a/docs/source/en/model_doc/longcat_flash.md b/docs/source/en/model_doc/longcat_flash.md index d9a9a4a7f603..651f3386f161 100644 --- a/docs/source/en/model_doc/longcat_flash.md +++ b/docs/source/en/model_doc/longcat_flash.md @@ -12,7 +12,6 @@ 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. - ⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be rendered properly in your Markdown viewer. --> @@ -43,6 +42,7 @@ The original code can be found [here](https://huggingface.co/meituan-longcat/Lon ## Usage examples The model is large: you will need 2x8 H100 to run inference. + ```python # launch_longcat.py from transformers import LongcatFlashForCausalLM, AutoTokenizer @@ -76,6 +76,7 @@ torchrun --nproc_per_node=8 --nnodes=2 --node_rank=0 | 1 --rdzv-id --r ``` And you'll get a nice generation: + ```json [Round 0] USER:Hello! What is the capital of France? What can you tell me about it? ASSISTANT:Hello! 😊 The capital of France is Paris, one of the most famous and beloved cities in the world. Here’s a quick overview of what makes Paris special: 1. Iconic Landmarks diff --git a/docs/source/en/model_doc/longformer.md b/docs/source/en/model_doc/longformer.md index c80294ab7a04..b8375998a06b 100644 --- a/docs/source/en/model_doc/longformer.md +++ b/docs/source/en/model_doc/longformer.md @@ -85,7 +85,6 @@ echo -e "San Francisco 49ers cornerback Shawntae Spencer will miss the rest of t - ## Notes - Longformer is based on [RoBERTa](https://huggingface.co/docs/transformers/en/model_doc/roberta) and doesn't have `token_type_ids`. You don't need to indicate which token belongs to which segment. You only need to separate the segments with the separation token `` or `tokenizer.sep_token`. diff --git a/docs/source/en/model_doc/longt5.md b/docs/source/en/model_doc/longt5.md index bd22d757a74f..a197de15a576 100644 --- a/docs/source/en/model_doc/longt5.md +++ b/docs/source/en/model_doc/longt5.md @@ -29,7 +29,6 @@ encoder-decoder transformer pre-trained in a text-to-text denoising generative s T5 model, and it enables using one of the two different efficient attention mechanisms - (1) Local attention, or (2) Transient-Global attention. - The abstract from the paper is the following: *Recent work has shown that either (1) increasing the input length or (2) increasing model size can improve the @@ -95,7 +94,6 @@ The complexity of this mechanism is `O(l(r + l/k))`. >>> rouge.compute(predictions=result["predicted_abstract"], references=result["abstract"]) ``` - ## Resources - [Translation task guide](../tasks/translation) diff --git a/docs/source/en/model_doc/m2m_100.md b/docs/source/en/model_doc/m2m_100.md index 29d43af97a2f..f9ac7e5ebe92 100644 --- a/docs/source/en/model_doc/m2m_100.md +++ b/docs/source/en/model_doc/m2m_100.md @@ -44,7 +44,6 @@ open-source our scripts so that others may reproduce the data, evaluation, and f This model was contributed by [valhalla](https://huggingface.co/valhalla). - ## Usage tips and examples M2M100 is a multilingual encoder-decoder (seq-to-seq) model primarily intended for translation tasks. As the model is @@ -76,9 +75,9 @@ loss = model(**model_inputs).loss # forward pass **Generation** -M2M100 uses the `eos_token_id` as the `decoder_start_token_id` for generation with the target language id -being forced as the first generated token. To force the target language id as the first generated token, pass the -*forced_bos_token_id* parameter to the *generate* method. The following example shows how to translate between +M2M100 uses the `eos_token_id` as the `decoder_start_token_id` for generation with the target language id +being forced as the first generated token. To force the target language id as the first generated token, pass the +*forced_bos_token_id* parameter to the *generate* method. The following example shows how to translate between Hindi to French and Chinese to English using the *facebook/m2m100_418M* checkpoint. ```python @@ -136,7 +135,7 @@ Hindi to French and Chinese to English using the *facebook/m2m100_418M* checkpoi Flash Attention 2 is a faster, optimized version of the attention scores computation which relies on `cuda` kernels. -### Installation +### Installation First, check whether your hardware is compatible with Flash Attention 2. The latest list of compatible hardware can be found in the [official documentation](https://github.com/Dao-AILab/flash-attention#installation-and-features). diff --git a/docs/source/en/model_doc/mamba.md b/docs/source/en/model_doc/mamba.md index d243bcf7e40d..031e353c93da 100644 --- a/docs/source/en/model_doc/mamba.md +++ b/docs/source/en/model_doc/mamba.md @@ -27,7 +27,6 @@ rendered properly in your Markdown viewer. You can find all the original Mamba checkpoints under the [State Space Models](https://huggingface.co/state-spaces) organization. - > [!TIP] > This model was contributed by [Molbap](https://huggingface.co/Molbap) and [AntonV](https://huggingface.co/AntonV). > Click on the Mamba models in the right sidebar for more examples of how to apply Mamba to different language tasks. @@ -93,6 +92,7 @@ input_ids = tokenizer("Plants create energy through a process known as", return_ output = model.generate(**input_ids) print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + ## Notes - The current implementation uses the original CUDA kernels. The FlashAttention equivalent implementation is hosted in the [mamba-ssm](https://github.com/state-spaces/mamba) and [causal_conv1d](https://github.com/Dao-AILab/causal-conv1d) repositories. Make sure to install them if your hardware supports it! diff --git a/docs/source/en/model_doc/mamba2.md b/docs/source/en/model_doc/mamba2.md index 11666e1fa576..56a33dfbe0b9 100644 --- a/docs/source/en/model_doc/mamba2.md +++ b/docs/source/en/model_doc/mamba2.md @@ -91,6 +91,7 @@ input_ids = tokenizer("Plants create energy through a process known as", return_ output = model.generate(**input_ids) print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + ## Notes - Codestral Mamba has `groups=8` which are similar to the number of kv heads in an attention-based model. @@ -124,7 +125,6 @@ trainer = SFTTrainer( trainer.train() ``` - ## Mamba2Config [[autodoc]] Mamba2Config diff --git a/docs/source/en/model_doc/marian.md b/docs/source/en/model_doc/marian.md index 4b08ac1901ca..00b2f91677d4 100644 --- a/docs/source/en/model_doc/marian.md +++ b/docs/source/en/model_doc/marian.md @@ -25,23 +25,17 @@ rendered properly in your Markdown viewer. # MarianMT - - [MarianMT](https://huggingface.co/papers/1804.00344) is a machine translation model trained with the Marian framework which is written in pure C++. The framework includes its own custom auto-differentiation engine and efficient meta-algorithms to train encoder-decoder models like BART. All MarianMT models are transformer encoder-decoders with 6 layers in each component, use static sinusoidal positional embeddings, don't have a layernorm embedding, and the model starts generating with the prefix `pad_token_id` instead of ``. - - You can find all the original MarianMT checkpoints under the [Language Technology Research Group at the University of Helsinki](https://huggingface.co/Helsinki-NLP/models?search=opus-mt) organization. - > [!TIP] > This model was contributed by [sshleifer](https://huggingface.co/sshleifer). > > Click on the MarianMT models in the right sidebar for more examples of how to apply MarianMT to translation tasks. - The example below demonstrates how to translate text using [`Pipeline`] or the [`AutoModel`] class. @@ -78,7 +72,6 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True)) - Use the [AttentionMaskVisualizer](https://github.com/huggingface/transformers/blob/beb9b5b02246b9b7ee81ddf938f93f44cfeaad19/src/transformers/utils/attention_visualizer.py#L139) to better understand what tokens the model can and cannot attend to. ```python @@ -87,6 +80,7 @@ from transformers.utils.attention_visualizer import AttentionMaskVisualizer visualizer = AttentionMaskVisualizer("Helsinki-NLP/opus-mt-en-de") visualizer("Hello, how are you?") ``` +
diff --git a/docs/source/en/model_doc/markuplm.md b/docs/source/en/model_doc/markuplm.md index 897b97853bd8..c7608f397f69 100644 --- a/docs/source/en/model_doc/markuplm.md +++ b/docs/source/en/model_doc/markuplm.md @@ -54,7 +54,7 @@ These are the XPATH tags and subscripts respectively for each token in the input - One can use [`MarkupLMProcessor`] to prepare all data for the model. Refer to the [usage guide](#usage-markuplmprocessor) for more info. +alt="drawing" width="600"/> MarkupLM architecture. Taken from the original paper. diff --git a/docs/source/en/model_doc/matcha.md b/docs/source/en/model_doc/matcha.md index e6a73c58fd02..9180d765c2bc 100644 --- a/docs/source/en/model_doc/matcha.md +++ b/docs/source/en/model_doc/matcha.md @@ -42,7 +42,7 @@ Currently 6 checkpoints are available for MatCha: - `google/matcha-chartqa`: MatCha model fine-tuned on ChartQA dataset. It can be used to answer questions about charts. - `google/matcha-plotqa-v1`: MatCha model fine-tuned on PlotQA dataset. It can be used to answer questions about plots. - `google/matcha-plotqa-v2`: MatCha model fine-tuned on PlotQA dataset. It can be used to answer questions about plots. -- `google/matcha-chart2text-statista`: MatCha model fine-tuned on Statista dataset. +- `google/matcha-chart2text-statista`: MatCha model fine-tuned on Statista dataset. - `google/matcha-chart2text-pew`: MatCha model fine-tuned on Pew dataset. The models finetuned on `chart2text-pew` and `chart2text-statista` are more suited for summarization, whereas the models finetuned on `plotqa` and `chartqa` are more suited for question answering. @@ -67,6 +67,7 @@ print(processor.decode(predictions[0], skip_special_tokens=True)) ## Fine-tuning To fine-tune MatCha, refer to the pix2struct [fine-tuning notebook](https://github.com/huggingface/notebooks/blob/main/examples/image_captioning_pix2struct.ipynb). For `Pix2Struct` models, we have found out that fine-tuning the model with Adafactor and cosine learning rate scheduler leads to faster convergence: + ```python from transformers.optimization import Adafactor, get_cosine_schedule_with_warmup diff --git a/docs/source/en/model_doc/mega.md b/docs/source/en/model_doc/mega.md index 614df2435530..d6580427778a 100644 --- a/docs/source/en/model_doc/mega.md +++ b/docs/source/en/model_doc/mega.md @@ -44,19 +44,16 @@ The abstract from the paper is the following: This model was contributed by [mnaylor](https://huggingface.co/mnaylor). The original code can be found [here](https://github.com/facebookresearch/mega). - ## Usage tips - MEGA can perform quite well with relatively few parameters. See Appendix D in the MEGA paper for examples of architectural specs which perform well in various settings. If using MEGA as a decoder, be sure to set `bidirectional=False` to avoid errors with default bidirectional. - Mega-chunk is a variant of mega that reduces time and spaces complexity from quadratic to linear. Utilize chunking with MegaConfig.use_chunking and control chunk size with MegaConfig.chunk_size - ## Implementation Notes - The original implementation of MEGA had an inconsistent expectation of attention masks for padding and causal self-attention between the softmax attention and Laplace/squared ReLU method. This implementation addresses that inconsistency. - The original implementation did not include token type embeddings; this implementation adds support for these, with the option controlled by MegaConfig.add_token_type_embeddings - ## MegaConfig [[autodoc]] MegaConfig diff --git a/docs/source/en/model_doc/megatron-bert.md b/docs/source/en/model_doc/megatron-bert.md index f8845556f8f1..5307fdcd491a 100644 --- a/docs/source/en/model_doc/megatron-bert.md +++ b/docs/source/en/model_doc/megatron-bert.md @@ -45,8 +45,8 @@ achieve SOTA results on the WikiText103 (10.8 compared to SOTA perplexity of 15. accuracy of 63.2%) datasets. Our BERT model achieves SOTA results on the RACE dataset (90.9% compared to SOTA accuracy of 89.4%).* -This model was contributed by [jdemouth](https://huggingface.co/jdemouth). The original code can be found [here](https://github.com/NVIDIA/Megatron-LM). -That repository contains a multi-GPU and multi-node implementation of the Megatron Language models. In particular, +This model was contributed by [jdemouth](https://huggingface.co/jdemouth). The original code can be found [here](https://github.com/NVIDIA/Megatron-LM). +That repository contains a multi-GPU and multi-node implementation of the Megatron Language models. In particular, it contains a hybrid model parallel approach using "tensor parallel" and "pipeline parallel" techniques. ## Usage tips diff --git a/docs/source/en/model_doc/mimi.md b/docs/source/en/model_doc/mimi.md index 2d655aa59660..440f89b2c56f 100644 --- a/docs/source/en/model_doc/mimi.md +++ b/docs/source/en/model_doc/mimi.md @@ -39,7 +39,7 @@ The example below demonstrates how to encode and decode audio with the [`AutoMod -```python +```python >>> from datasets import load_dataset, Audio >>> from transformers import MimiModel, AutoFeatureExtractor >>> librispeech_dummy = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") diff --git a/docs/source/en/model_doc/minimax.md b/docs/source/en/model_doc/minimax.md index 02d016c019ce..a27d45089ced 100644 --- a/docs/source/en/model_doc/minimax.md +++ b/docs/source/en/model_doc/minimax.md @@ -109,8 +109,8 @@ To load and run a model using Flash Attention-2, refer to the snippet below: ### Sliding window Attention -The current implementation supports the sliding window attention mechanism and memory efficient cache management. -To enable sliding window attention, just make sure to have a `flash-attn` version that is compatible with sliding window attention (`>=2.3.0`). +The current implementation supports the sliding window attention mechanism and memory efficient cache management. +To enable sliding window attention, just make sure to have a `flash-attn` version that is compatible with sliding window attention (`>=2.3.0`). The Flash Attention-2 model uses also a more memory efficient cache slicing mechanism - as recommended per the official implementation of Mistral model that use rolling cache mechanism we keep the cache size fixed (`self.config.sliding_window`), support batched generation only for `padding_side="left"` and use the absolute position of the current token to compute the positional embedding. diff --git a/docs/source/en/model_doc/ministral.md b/docs/source/en/model_doc/ministral.md index 13b6f3d6c04b..c2128512586f 100644 --- a/docs/source/en/model_doc/ministral.md +++ b/docs/source/en/model_doc/ministral.md @@ -30,7 +30,6 @@ rendered properly in your Markdown viewer. This architecture turns out to coincide with Qwen2, with the main difference being the presence of biases in attention projections in Ministral. - You can find the Ministral checkpoints under the [Mistral AI](https://huggingface.co/mistralai) organization. ## Usage diff --git a/docs/source/en/model_doc/mistral.md b/docs/source/en/model_doc/mistral.md index 3714f45e55a0..865ee414532c 100644 --- a/docs/source/en/model_doc/mistral.md +++ b/docs/source/en/model_doc/mistral.md @@ -86,7 +86,6 @@ echo -e "My favorite condiment is" | transformers chat mistralai/Mistral-7B-v0.3 - Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for more available quantization backends. The example below uses [bitsandbytes](../quantization/bitsandbytes) to only quantize the weights to 4-bits. diff --git a/docs/source/en/model_doc/mistral3.md b/docs/source/en/model_doc/mistral3.md index 54af880ed467..4ac264ac9854 100644 --- a/docs/source/en/model_doc/mistral3.md +++ b/docs/source/en/model_doc/mistral3.md @@ -27,7 +27,6 @@ rendered properly in your Markdown viewer. You can find the original Mistral 3 checkpoints under the [Mistral AI](https://huggingface.co/mistralai/models?search=mistral-small-3) organization. - > [!TIP] > This model was contributed by [cyrilvallez](https://huggingface.co/cyrilvallez) and [yonigozlan](https://huggingface.co/yonigozlan). > Click on the Mistral3 models in the right sidebar for more examples of how to apply Mistral3 to different tasks. @@ -62,6 +61,7 @@ outputs = pipeline(text=messages, max_new_tokens=50, return_full_text=False) outputs[0]["generated_text"] 'The image depicts a vibrant and lush garden scene featuring a variety of wildflowers and plants. The central focus is on a large, pinkish-purple flower, likely a Greater Celandine (Chelidonium majus), with a' ``` + @@ -100,13 +100,15 @@ decoded_output = processor.decode(generate_ids[0, inputs["input_ids"].shape[1] : decoded_output 'The image depicts a vibrant and lush garden scene featuring a variety of wildflowers and plants. The central focus is on a large, pinkish-purple flower, likely a Greater Celandine (Chelidonium majus), with a' ``` + -## Notes +## Notes + +- Mistral 3 supports text-only generation. -- Mistral 3 supports text-only generation. -```py +```py import torch from transformers import AutoProcessor, AutoModelForImageTextToText, infer_device @@ -136,13 +138,16 @@ print(decoded_output) 5. Je me casse, à plus! ``` + /\_/\ ( o.o ) > ^ < + ```" ```` -- Mistral 3 accepts batched image and text inputs. +- Mistral 3 accepts batched image and text inputs. + ```py import torch from transformers import AutoProcessor, AutoModelForImageTextToText, infer_device @@ -184,7 +189,7 @@ messages = [ , "Describe this imageThe image depicts a vibrant street scene in what appears to be a Chinatown district. The focal point is a traditional Chinese"] ``` -- Mistral 3 also supported batched image and text inputs with a different number of images for each text. The example below quantizes the model with bitsandbytes. +- Mistral 3 also supported batched image and text inputs with a different number of images for each text. The example below quantizes the model with bitsandbytes. ```py import torch diff --git a/docs/source/en/model_doc/mixtral.md b/docs/source/en/model_doc/mixtral.md index ff501cd1a84d..7665b5901a6a 100644 --- a/docs/source/en/model_doc/mixtral.md +++ b/docs/source/en/model_doc/mixtral.md @@ -39,7 +39,7 @@ Mixtral-8x7B is the second large language model (LLM) released by [mistral.ai](h Mixtral-8x7B is a decoder-only Transformer with the following architectural choices: - Mixtral is a Mixture of Experts (MoE) model with 8 experts per MLP, with a total of 45 billion parameters. To learn more about mixture-of-experts, refer to the [blog post](https://huggingface.co/blog/moe). -- Despite the model having 45 billion parameters, the compute required for a single forward pass is the same as that of a 14 billion parameter model. This is because even though each of the experts have to be loaded in RAM (70B like ram requirement) each token from the hidden states are dispatched twice (top 2 routing) and thus the compute (the operation required at each forward computation) is just 2 X sequence_length. +- Despite the model having 45 billion parameters, the compute required for a single forward pass is the same as that of a 14 billion parameter model. This is because even though each of the experts have to be loaded in RAM (70B like ram requirement) each token from the hidden states are dispatched twice (top 2 routing) and thus the compute (the operation required at each forward computation) is just 2 X sequence_length. The following implementation details are shared with Mistral AI's first model [Mistral-7B](mistral): - Sliding Window Attention - Trained with 8k context length and fixed cache size, with a theoretical attention span of 128K tokens @@ -138,8 +138,8 @@ Below is a expected speedup diagram that compares pure inference time between th ### Sliding window Attention -The current implementation supports the sliding window attention mechanism and memory efficient cache management. -To enable sliding window attention, just make sure to have a `flash-attn` version that is compatible with sliding window attention (`>=2.3.0`). +The current implementation supports the sliding window attention mechanism and memory efficient cache management. +To enable sliding window attention, just make sure to have a `flash-attn` version that is compatible with sliding window attention (`>=2.3.0`). The Flash Attention-2 model uses also a more memory efficient cache slicing mechanism - as recommended per the official implementation of Mistral model that use rolling cache mechanism we keep the cache size fixed (`self.config.sliding_window`), support batched generation only for `padding_side="left"` and use the absolute position of the current token to compute the positional embedding. diff --git a/docs/source/en/model_doc/mlcd.md b/docs/source/en/model_doc/mlcd.md index 1ce785ee76bb..7ff2fb434da0 100644 --- a/docs/source/en/model_doc/mlcd.md +++ b/docs/source/en/model_doc/mlcd.md @@ -32,9 +32,9 @@ Tips: - We adopted the official [LLaVA-NeXT](https://github.com/LLaVA-VL/LLaVA-NeXT) and the official training dataset [LLaVA-NeXT-Data](https://huggingface.co/datasets/lmms-lab/LLaVA-NeXT-Data) for evaluating the foundational visual models. -- The language model is [Qwen2.5-7B](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct). +- The language model is [Qwen2.5-7B](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct). -Result: +Result: | Vision Tower | RoPE2D | ChartQA | DocVQA | InfoVQA | OCRBench | MMMU | | :-------------------------------------------------------------------------------------------- | :----: | :-------- | :-------- | :-------- | :--------- | :-------- | @@ -45,7 +45,6 @@ Result: | **[MLCD (ViT-bigG-14-336px)](https://huggingface.co/DeepGlint-AI/mlcd-vit-bigG-patch14-336)** | √ | 71.07 | 79.63 | 44.38 | 572.00 | 46.78 | | **[MLCD (ViT-bigG-14-448px)](https://huggingface.co/DeepGlint-AI/mlcd-vit-bigG-patch14-448)** | √ | **73.80** | **83.34** | **46.59** | **582.00** | 46.00 | - ## Usage ```python diff --git a/docs/source/en/model_doc/mllama.md b/docs/source/en/model_doc/mllama.md index 1ea7f172bb3a..a0fc5db41cfe 100644 --- a/docs/source/en/model_doc/mllama.md +++ b/docs/source/en/model_doc/mllama.md @@ -35,15 +35,12 @@ The [Llama 3.2-Vision](https://ai.meta.com/blog/llama-3-2-connect-2024-vision-ed - The text passed to the processor should have the `"<|image|>"` tokens where the images should be inserted. - The processor has its own `apply_chat_template` method to convert chat messages to text that can then be passed as text to the processor. If you're using `transformers>=4.49.0`, you can also get a vectorized output from `apply_chat_template`. See the **Usage Examples** below for more details on how to use it. - - Mllama has an extra token used as a placeholder for image positions in the text. It means that input ids and an input embedding layer will have an extra token. But since the weights for input and output embeddings are not tied, the `lm_head` layer has one less token and will fail if you want to calculate loss on image tokens or apply some logit processors. In case you are training, make sure to mask out special `"<|image|>"` tokens in the `labels` as the model should not be trained on predicting them. Otherwise if you see CUDA-side index errors when generating, use the below code to expand the `lm_head` by one more token. - ```python old_embeddings = model.get_output_embeddings() @@ -52,12 +49,13 @@ resized_embeddings = model._get_resized_lm_head(old_embeddings, new_num_tokens=n resized_embeddings.requires_grad_(old_embeddings.weight.requires_grad) model.set_output_embeddings(resized_embeddings) ``` - + ## Usage Example #### Instruct model + ```python import torch from transformers import MllamaForConditionalGeneration, AutoProcessor @@ -83,6 +81,7 @@ print(processor.decode(output[0])) ``` #### Base model + ```python import requests import torch @@ -102,7 +101,6 @@ output = model.generate(**inputs, do_sample=False, max_new_tokens=25) print(processor.decode(output[0], skip_special_tokens=True)) ``` - ## MllamaConfig [[autodoc]] MllamaConfig @@ -111,7 +109,6 @@ print(processor.decode(output[0], skip_special_tokens=True)) [[autodoc]] MllamaProcessor - ## MllamaImageProcessor [[autodoc]] MllamaImageProcessor diff --git a/docs/source/en/model_doc/mm-grounding-dino.md b/docs/source/en/model_doc/mm-grounding-dino.md index e411ef5defb6..0d628c3b31de 100644 --- a/docs/source/en/model_doc/mm-grounding-dino.md +++ b/docs/source/en/model_doc/mm-grounding-dino.md @@ -100,7 +100,6 @@ for box, score, labels in zip(result["boxes"], result["scores"], result["labels" | [mm_grounding_dino_tiny_o365v1_goldg_v3det](https://huggingface.co/openmmlab-community/mm_grounding_dino_tiny_o365v1_goldg_v3det) | O365,GoldG,V3Det | 33.0 | 36.0 | 45.9 | 40.5(+11.7) | 21.5 | 25.5 | 40.2 | 30.6(+10.5) | | [mm_grounding_dino_tiny_o365v1_goldg_grit_v3det](https://huggingface.co/openmmlab-community/mm_grounding_dino_tiny_o365v1_goldg_grit_v3det) | O365,GoldG,GRIT,V3Det | 34.2 | 37.4 | 46.2 | 41.4(+12.6) | 23.6 | 27.6 | 40.5 | 31.9(+11.8) | - - This implementation also supports inference for [LLMDet](https://github.com/iSEE-Laboratory/LLMDet). Here's a table of LLMDet models and their performance on LVIS (results from [official repo](https://github.com/iSEE-Laboratory/LLMDet)): | Model | Pre-Train Data | MiniVal APr | MiniVal APc | MiniVal APf | MiniVal AP | Val1.0 APr | Val1.0 APc | Val1.0 APf | Val1.0 AP | @@ -109,7 +108,6 @@ for box, score, labels in zip(result["boxes"], result["scores"], result["labels" | [llmdet_base](https://huggingface.co/iSEE-Laboratory/llmdet_base) | (O365,GoldG,V3Det) + GroundingCap-1M | 48.3 | 40.8 | 43.1 | 54.3 | 38.5 | 28.2 | 34.3 | 47.8 | | [llmdet_large](https://huggingface.co/iSEE-Laboratory/llmdet_large) | (O365V2,OpenImageV6,GoldG) + GroundingCap-1M | 51.1 | 45.1 | 46.1 | 56.6 | 42.0 | 31.6 | 38.8 | 50.2 | - ## MMGroundingDinoConfig [[autodoc]] MMGroundingDinoConfig diff --git a/docs/source/en/model_doc/mms.md b/docs/source/en/model_doc/mms.md index 3ac351d0ddcb..171beaf440d1 100644 --- a/docs/source/en/model_doc/mms.md +++ b/docs/source/en/model_doc/mms.md @@ -376,6 +376,7 @@ detected_lang = model.config.id2label[lang_id] ``` To see all the supported languages of a checkpoint, you can print out the language ids as follows: + ```py processor.id2label.values() ``` diff --git a/docs/source/en/model_doc/mobilebert.md b/docs/source/en/model_doc/mobilebert.md index 4e3cc2e5d647..08486ace56eb 100644 --- a/docs/source/en/model_doc/mobilebert.md +++ b/docs/source/en/model_doc/mobilebert.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2020-04-06 and added to Hugging Face Transformers on 2020-11-16.* -
PyTorch @@ -47,6 +46,7 @@ pipeline = pipeline( ) pipeline("The capital of France is [MASK].") ``` + @@ -85,7 +85,6 @@ echo -e "The capital of France is [MASK]." | transformers run --task fill-mask - - ## Notes - Inputs should be padded on the right because BERT uses absolute position embeddings. diff --git a/docs/source/en/model_doc/mobilenet_v1.md b/docs/source/en/model_doc/mobilenet_v1.md index c77bef730423..809be7f652a0 100644 --- a/docs/source/en/model_doc/mobilenet_v1.md +++ b/docs/source/en/model_doc/mobilenet_v1.md @@ -32,7 +32,6 @@ You can all the original MobileNet checkpoints under the [Google](https://huggin The example below demonstrates how to classify an image with [`Pipeline`] or the [`AutoModel`] class. - @@ -84,18 +83,19 @@ print(f"The predicted class label is: {predicted_class_label}") - ## Notes - Checkpoint names follow the pattern `mobilenet_v1_{depth_multiplier}_{resolution}`, like `mobilenet_v1_1.0_224`. `1.0` is the depth multiplier and `224` is the image resolution. - While trained on images of a specific sizes, the model architecture works with images of different sizes (minimum 32x32). The [`MobileNetV1ImageProcessor`] handles the necessary preprocessing. - MobileNet is pretrained on [ImageNet-1k](https://huggingface.co/datasets/imagenet-1k), a dataset with 1000 classes. However, the model actually predicts 1001 classes. The additional class is an extra "background" class (index 0). - The original TensorFlow checkpoints determines the padding amount at inference because it depends on the input image size. To use the native PyTorch padding behavior, set `tf_padding=False` in [`MobileNetV1Config`]. + ```python from transformers import MobileNetV1Config config = MobileNetV1Config.from_pretrained("google/mobilenet_v1_1.0_224", tf_padding=True) ``` + - The Transformers implementation does not support the following features. - Uses global average pooling instead of the optional 7x7 average pooling with stride 2. For larger inputs, this gives a pooled output that is larger than a 1x1 pixel. - Does not support other `output_stride` values (fixed at 32). For smaller `output_strides`, the original implementation uses dilated convolution to prevent spatial resolution from being reduced further. (which would require dilated convolutions). diff --git a/docs/source/en/model_doc/mobilenet_v2.md b/docs/source/en/model_doc/mobilenet_v2.md index 3e1379e3f079..2039f9e4413f 100644 --- a/docs/source/en/model_doc/mobilenet_v2.md +++ b/docs/source/en/model_doc/mobilenet_v2.md @@ -30,10 +30,8 @@ You can all the original MobileNet checkpoints under the [Google](https://huggin > [!TIP] > Click on the MobileNet V2 models in the right sidebar for more examples of how to apply MobileNet to different vision tasks. - The examples below demonstrate how to classify an image with [`Pipeline`] or the [`AutoModel`] class. - @@ -82,7 +80,6 @@ print(f"The predicted class label is: {predicted_class_label}") - ## Notes - Classification checkpoint names follow the pattern `mobilenet_v2_{depth_multiplier}_{resolution}`, like `mobilenet_v2_1.4_224`. `1.4` is the depth multiplier and `224` is the image resolution. Segmentation checkpoint names follow the pattern `deeplabv3_mobilenet_v2_{depth_multiplier}_{resolution}`. @@ -90,11 +87,13 @@ print(f"The predicted class label is: {predicted_class_label}") - MobileNet is pretrained on [ImageNet-1k](https://huggingface.co/datasets/imagenet-1k), a dataset with 1000 classes. However, the model actually predicts 1001 classes. The additional class is an extra "background" class (index 0). - The segmentation models use a [DeepLabV3+](https://huggingface.co/papers/1802.02611) head which is often pretrained on datasets like [PASCAL VOC](https://huggingface.co/datasets/merve/pascal-voc). - The original TensorFlow checkpoints determines the padding amount at inference because it depends on the input image size. To use the native PyTorch padding behavior, set `tf_padding=False` in [`MobileNetV2Config`]. + ```python from transformers import MobileNetV2Config config = MobileNetV2Config.from_pretrained("google/mobilenet_v2_1.4_224", tf_padding=True) ``` + - The Transformers implementation does not support the following features. - Uses global average pooling instead of the optional 7x7 average pooling with stride 2. For larger inputs, this gives a pooled output that is larger than a 1x1 pixel. - `output_hidden_states=True` returns *all* intermediate hidden states. It is not possible to extract the output from specific layers for other downstream purposes. diff --git a/docs/source/en/model_doc/mobilevit.md b/docs/source/en/model_doc/mobilevit.md index b4a51bd200f2..9975cf68155a 100644 --- a/docs/source/en/model_doc/mobilevit.md +++ b/docs/source/en/model_doc/mobilevit.md @@ -11,11 +11,8 @@ Unless required by applicable law or agreed to in writing, software distributed --> *This model was released on 2021-10-05 and added to Hugging Face Transformers on 2022-06-29.* - - # MobileViT -
PyTorch @@ -24,21 +21,17 @@ Unless required by applicable law or agreed to in writing, software distributed [MobileViT](https://huggingface.co/papers/2110.02178) is a lightweight vision transformer for mobile devices that merges CNNs's efficiency and inductive biases with transformers global context modeling. It treats transformers as convolutions, enabling global information processing without the heavy computational cost of standard ViTs. -
- You can find all the original MobileViT checkpoints under the [Apple](https://huggingface.co/apple/models?search=mobilevit) organization. - > [!TIP] > - This model was contributed by [matthijs](https://huggingface.co/Matthijs). > > Click on the MobileViT models in the right sidebar for more examples of how to apply MobileViT to different vision tasks. - The example below demonstrates how to do [Image Classification] with [`Pipeline`] and the [`AutoModel`] class. @@ -92,7 +85,6 @@ print(f"The predicted class label is:{predicted_class_label}") - ## Notes - Does **not** operate on sequential data, it's purely designed for image tasks. @@ -102,8 +94,6 @@ print(f"The predicted class label is:{predicted_class_label}") - The classification models are pretrained on [ImageNet-1k](https://huggingface.co/datasets/imagenet-1k). - The segmentation models use a [DeepLabV3](https://huggingface.co/papers/1706.05587) head and are pretrained on [PASCAL VOC](http://host.robots.ox.ac.uk/pascal/VOC/). - - ## MobileViTConfig [[autodoc]] MobileViTConfig diff --git a/docs/source/en/model_doc/modernbert-decoder.md b/docs/source/en/model_doc/modernbert-decoder.md index 050cae276467..ff61362a5203 100644 --- a/docs/source/en/model_doc/modernbert-decoder.md +++ b/docs/source/en/model_doc/modernbert-decoder.md @@ -36,7 +36,7 @@ You can find all the original ModernBERT Decoder checkpoints under the [jhu-clsp > > Click on the ModernBERT Decoder models in the right sidebar for more examples of how to apply ModernBERT Decoder to different text generation tasks. -The example below demonstrates how to use ModernBERT Decoder for text generation with [`Pipeline`], [`AutoModel`] (with and without quantization), and from the command line. +The example below demonstrates how to use ModernBERT Decoder for text generation with [`Pipeline`], [`AutoModel`] (with and without quantization), and from the command line. @@ -151,6 +151,7 @@ with torch.no_grad(): generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True) print(f"Generated text: {generated_text}") ``` + @@ -162,12 +163,10 @@ echo "The future of artificial intelligence is" | transformers run --task text-g - ## ModernBertDecoderConfig [[autodoc]] ModernBertDecoderConfig - ## ModernBertDecoderModel [[autodoc]] ModernBertDecoderModel @@ -182,4 +181,3 @@ echo "The future of artificial intelligence is" | transformers run --task text-g [[autodoc]] ModernBertDecoderForSequenceClassification - forward - diff --git a/docs/source/en/model_doc/modernbert.md b/docs/source/en/model_doc/modernbert.md index 872da561fbf8..4be8d97f5e95 100644 --- a/docs/source/en/model_doc/modernbert.md +++ b/docs/source/en/model_doc/modernbert.md @@ -93,7 +93,6 @@ echo -e "Plants create [MASK] through a process known as photosynthesis." | tran [[autodoc]] ModernBertConfig - ## ModernBertModel [[autodoc]] ModernBertModel @@ -127,5 +126,3 @@ echo -e "Plants create [MASK] through a process known as photosynthesis." | tran ### Usage tips The ModernBert model can be fine-tuned using the HuggingFace Transformers library with its [official script](https://github.com/huggingface/transformers/blob/main/examples/pytorch/question-answering/run_qa.py) for question-answering tasks. - - diff --git a/docs/source/en/model_doc/moonshine.md b/docs/source/en/model_doc/moonshine.md index 7abe123b88e2..b85a174a86fb 100644 --- a/docs/source/en/model_doc/moonshine.md +++ b/docs/source/en/model_doc/moonshine.md @@ -83,6 +83,7 @@ predicted_ids = model.generate(**input_features, cache_implementation="static") transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True) transcription[0] ``` + @@ -101,4 +102,3 @@ transcription[0] [[autodoc]] MoonshineForConditionalGeneration - forward - generate - diff --git a/docs/source/en/model_doc/moshi.md b/docs/source/en/model_doc/moshi.md index e17a1b7b8b14..49fae1c539d7 100644 --- a/docs/source/en/model_doc/moshi.md +++ b/docs/source/en/model_doc/moshi.md @@ -35,7 +35,7 @@ Moshi is a speech-text foundation model that casts spoken dialogue as speech-to- The abstract from the paper is the following: -*We introduce Moshi, a speech-text foundation model and full-duplex spoken dialogue framework. Current systems for spoken dialogue rely on pipelines of independent components, namely voice activity detection, speech recognition, textual dialogue and text-to-speech. Such frameworks cannot emulate the experience of real conversations. First, their complexity induces a latency of several seconds between interactions. Second, text being the intermediate modality for dialogue, non-linguistic information that modifies meaning— such as emotion or non-speech sounds— is lost in the interaction. Finally, they rely on a segmentation into speaker turns, which does not take into account overlapping speech, interruptions and interjections. Moshi solves these independent issues altogether by casting spoken dialogue as speech-to-speech generation. Starting from a text language model backbone, Moshi generates speech as tokens from the residual quantizer of a neural audio codec, while modeling separately its own speech and that of the user into parallel streams. This allows for the removal of explicit speaker turns, and the modeling of arbitrary conversational dynamics. We moreover extend the hierarchical semantic-to-acoustic token generation of previous work to first predict time-aligned text tokens as a prefix to audio tokens. Not only this “Inner Monologue” method significantly improves the linguistic quality of generated speech, but we also illustrate how it can provide streaming speech recognition and text-to-speech. Our resulting model is the first real-time full-duplex spoken large language model, with a theoretical latency of 160ms, 200ms in practice, and is available at github.com/kyutai-labs/moshi.* +*We introduce Moshi, a speech-text foundation model and full-duplex spoken dialogue framework. Current systems for spoken dialogue rely on pipelines of independent components, namely voice activity detection, speech recognition, textual dialogue and text-to-speech. Such frameworks cannot emulate the experience of real conversations. First, their complexity induces a latency of several seconds between interactions. Second, text being the intermediate modality for dialogue, non-linguistic information that modifies meaning— such as emotion or non-speech sounds— is lost in the interaction. Finally, they rely on a segmentation into speaker turns, which does not take into account overlapping speech, interruptions and interjections. Moshi solves these independent issues altogether by casting spoken dialogue as speech-to-speech generation. Starting from a text language model backbone, Moshi generates speech as tokens from the residual quantizer of a neural audio codec, while modeling separately its own speech and that of the user into parallel streams. This allows for the removal of explicit speaker turns, and the modeling of arbitrary conversational dynamics. We moreover extend the hierarchical semantic-to-acoustic token generation of previous work to first predict time-aligned text tokens as a prefix to audio tokens. Not only this “Inner Monologue” method significantly improves the linguistic quality of generated speech, but we also illustrate how it can provide streaming speech recognition and text-to-speech. Our resulting model is the first real-time full-duplex spoken large language model, with a theoretical latency of 160ms, 200ms in practice, and is available at github.com/kyutai-labs/moshi.* Moshi deals with 3 streams of information: 1. The user's audio @@ -63,11 +63,9 @@ Note that each timestamp - i.e each codebook - gets its own set of Linear Layers It's the audio encoder from Kyutai, that has recently been integrated to transformers, which is used to "tokenize" audio. It has the same use that [`~EncodecModel`] has in [`~MusicgenModel`]. - ## Tips: -The original checkpoints can be converted using the conversion script `src/transformers/models/moshi/convert_moshi_transformers.py` - +The original checkpoints can be converted using the conversion script `src/transformers/models/moshi/convert_moshi_transformers.py` ### How to use the model: @@ -108,12 +106,9 @@ To follow the example of the following image, `"Hello, I'm Moshi"` could be tran
- [`MoshiForConditionalGeneration.generate`] then auto-regressively feeds to itself its own audio stream, but since it doesn't have access to the user input stream while using `transformers`, it will thus **assume that the user is producing blank audio**. - - -```python +```python >>> from datasets import load_dataset, Audio >>> import torch, math >>> from transformers import MoshiForConditionalGeneration, AutoFeatureExtractor, AutoTokenizer, infer_device @@ -149,7 +144,7 @@ To follow the example of the following image, `"Hello, I'm Moshi"` could be tran Most of the work has to be done during data creation/pre-processing, because of the need to align/synchronize streams. Once it's done, you can simply forward `text_labels` and `audio_labels` to [`MoshiForConditionalGeneration.forward`], alongside the usual inputs, to get the model loss. - + A training guide will come soon, but user contributions are welcomed! ### How does the model forward the inputs / generate: @@ -162,13 +157,10 @@ A training guide will come soon, but user contributions are welcomed! 3. The depth decoder switches the dimension on which we forward / generate (codebooks instead of time). It uses the token generated from `text logits` and the `temporal context` to auto-regressively generate audio codebooks. - This model was contributed by [Yoach Lacombe (ylacombe)](https://huggingface.co/ylacombe). The original code can be found [here](https://github.com/kyutai-labs/moshi). - - ## MoshiConfig [[autodoc]] MoshiConfig diff --git a/docs/source/en/model_doc/mpt.md b/docs/source/en/model_doc/mpt.md index 9482e6a91958..60d14641177c 100644 --- a/docs/source/en/model_doc/mpt.md +++ b/docs/source/en/model_doc/mpt.md @@ -23,11 +23,11 @@ rendered properly in your Markdown viewer. ## Overview -The MPT model was proposed by the [MosaicML](https://www.mosaicml.com/) team and released with multiple sizes and finetuned variants. The MPT models are a series of open source and commercially usable LLMs pre-trained on 1T tokens. +The MPT model was proposed by the [MosaicML](https://www.mosaicml.com/) team and released with multiple sizes and finetuned variants. The MPT models are a series of open source and commercially usable LLMs pre-trained on 1T tokens. -MPT models are GPT-style decoder-only transformers with several improvements: performance-optimized layer implementations, architecture changes that provide greater training stability, and the elimination of context length limits by replacing positional embeddings with ALiBi. +MPT models are GPT-style decoder-only transformers with several improvements: performance-optimized layer implementations, architecture changes that provide greater training stability, and the elimination of context length limits by replacing positional embeddings with ALiBi. -- MPT base: MPT base pre-trained models on next token prediction +- MPT base: MPT base pre-trained models on next token prediction - MPT instruct: MPT base models fine-tuned on instruction based tasks - MPT storywriter: MPT base models fine-tuned for 2500 steps on 65k-token excerpts of fiction books contained in the books3 corpus, this enables the model to handle very long sequences diff --git a/docs/source/en/model_doc/mt5.md b/docs/source/en/model_doc/mt5.md index fa02ee4c3c08..4e652458e1b3 100644 --- a/docs/source/en/model_doc/mt5.md +++ b/docs/source/en/model_doc/mt5.md @@ -133,7 +133,6 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) See [`T5Tokenizer`] for all details. - ## MT5TokenizerFast [[autodoc]] MT5TokenizerFast diff --git a/docs/source/en/model_doc/musicgen.md b/docs/source/en/model_doc/musicgen.md index 7e91b2265fe3..0ec3cb200d1e 100644 --- a/docs/source/en/model_doc/musicgen.md +++ b/docs/source/en/model_doc/musicgen.md @@ -77,9 +77,9 @@ Generation is limited by the sinusoidal positional embeddings to 30 second input than 30 seconds of audio (1503 tokens), and input audio passed by Audio-Prompted Generation contributes to this limit so, given an input of 20 seconds of audio, MusicGen cannot generate more than 10 seconds of additional audio. -Transformers supports both mono (1-channel) and stereo (2-channel) variants of MusicGen. The mono channel versions -generate a single set of codebooks. The stereo versions generate 2 sets of codebooks, 1 for each channel (left/right), -and each set of codebooks is decoded independently through the audio compression model. The audio streams for each +Transformers supports both mono (1-channel) and stereo (2-channel) variants of MusicGen. The mono channel versions +generate a single set of codebooks. The stereo versions generate 2 sets of codebooks, 1 for each channel (left/right), +and each set of codebooks is decoded independently through the audio compression model. The audio streams for each channel are combined to give the final stereo output. ### Unconditional Generation @@ -208,7 +208,7 @@ For batched audio-prompted generation, the generated `audio_values` can be post- ### Generation Configuration -The default parameters that control the generation process, such as sampling, guidance scale and number of generated +The default parameters that control the generation process, such as sampling, guidance scale and number of generated tokens, can be found in the model's generation config, and updated as desired: ```python @@ -226,8 +226,8 @@ tokens, can be found in the model's generation config, and updated as desired: >>> model.generation_config.max_length = 256 ``` -Note that any arguments passed to the generate method will **supersede** those in the generation config, so setting -`do_sample=False` in the call to generate will supersede the setting of `model.generation_config.do_sample` in the +Note that any arguments passed to the generate method will **supersede** those in the generation config, so setting +`do_sample=False` in the call to generate will supersede the setting of `model.generation_config.do_sample` in the generation config. ## Model Structure @@ -239,7 +239,7 @@ The MusicGen model can be de-composed into three distinct stages: Thus, the MusicGen model can either be used as a standalone decoder model, corresponding to the class [`MusicgenForCausalLM`], or as a composite model that includes the text encoder and audio encoder/decoder, corresponding to the class -[`MusicgenForConditionalGeneration`]. If only the decoder needs to be loaded from the pre-trained checkpoint, it can be loaded by first +[`MusicgenForConditionalGeneration`]. If only the decoder needs to be loaded from the pre-trained checkpoint, it can be loaded by first specifying the correct config, or be accessed through the `.decoder` attribute of the composite model: ```python diff --git a/docs/source/en/model_doc/musicgen_melody.md b/docs/source/en/model_doc/musicgen_melody.md index d2cd51bbcf2c..f43bfee43348 100644 --- a/docs/source/en/model_doc/musicgen_melody.md +++ b/docs/source/en/model_doc/musicgen_melody.md @@ -35,10 +35,8 @@ The abstract from the paper is the following: *We tackle the task of conditional music generation. We introduce MusicGen, a single Language Model (LM) that operates over several streams of compressed discrete music representation, i.e., tokens. Unlike prior work, MusicGen is comprised of a single-stage transformer LM together with efficient token interleaving patterns, which eliminates the need for cascading several models, e.g., hierarchically or upsampling. Following this approach, we demonstrate how MusicGen can generate high-quality samples, while being conditioned on textual description or melodic features, allowing better controls over the generated output. We conduct extensive empirical evaluation, considering both automatic and human studies, showing the proposed approach is superior to the evaluated baselines on a standard text-to-music benchmark. Through ablation studies, we shed light over the importance of each of the components comprising MusicGen.* - This model was contributed by [ylacombe](https://huggingface.co/ylacombe). The original code can be found [here](https://github.com/facebookresearch/audiocraft). The pre-trained checkpoints can be found on the [Hugging Face Hub](https://huggingface.co/models?sort=downloads&search=facebook%2Fmusicgen). - ## Difference with [MusicGen](https://huggingface.co/docs/transformers/main/en/model_doc/musicgen) There are two key differences with MusicGen: @@ -54,7 +52,6 @@ MusicGen Melody is compatible with two generation modes: greedy and sampling. In Transformers supports both mono (1-channel) and stereo (2-channel) variants of MusicGen Melody. The mono channel versions generate a single set of codebooks. The stereo versions generate 2 sets of codebooks, 1 for each channel (left/right), and each set of codebooks is decoded independently through the audio compression model. The audio streams for each channel are combined to give the final stereo output. - #### Audio Conditional Generation The model can generate an audio sample conditioned on a text and an audio prompt through use of the [`MusicgenMelodyProcessor`] to pre-process the inputs. @@ -67,6 +64,7 @@ pip install datasets[audio] ``` The audio file we are about to use is loaded as follows: + ```python >>> from datasets import load_dataset @@ -147,10 +145,9 @@ Or save them as a `.wav` file using a third-party library, e.g. `soundfile`: >>> sf.write("musicgen_out.wav", audio_values[0].T.numpy(), sampling_rate) ``` - ### Text-only Conditional Generation -The same [`MusicgenMelodyProcessor`] can be used to pre-process a text-only prompt. +The same [`MusicgenMelodyProcessor`] can be used to pre-process a text-only prompt. ```python >>> from transformers import AutoProcessor, MusicgenMelodyForConditionalGeneration @@ -168,7 +165,6 @@ The same [`MusicgenMelodyProcessor`] can be used to pre-process a text-only prom The `guidance_scale` is used in classifier free guidance (CFG), setting the weighting between the conditional logits (which are predicted from the text prompts) and the unconditional logits (which are predicted from an unconditional or 'null' prompt). Higher guidance scale encourages the model to generate samples that are more closely linked to the input prompt, usually at the expense of poorer audio quality. CFG is enabled by setting `guidance_scale > 1`. For best results, use `guidance_scale=3` (default). - You can also generate in batch: ```python @@ -263,7 +259,6 @@ Tips: * MusicGen is trained on the 32kHz checkpoint of Encodec. You should ensure you use a compatible version of the Encodec model. * Sampling mode tends to deliver better results than greedy - you can toggle sampling with the variable `do_sample` in the call to [`MusicgenMelodyForConditionalGeneration.generate`] - ## MusicgenMelodyDecoderConfig [[autodoc]] MusicgenMelodyDecoderConfig diff --git a/docs/source/en/model_doc/mvp.md b/docs/source/en/model_doc/mvp.md index 2cce9bd6cac1..26aa2f29b76d 100644 --- a/docs/source/en/model_doc/mvp.md +++ b/docs/source/en/model_doc/mvp.md @@ -25,7 +25,6 @@ rendered properly in your Markdown viewer. The MVP model was proposed in [MVP: Multi-task Supervised Pre-training for Natural Language Generation](https://huggingface.co/papers/2206.12131) by Tianyi Tang, Junyi Li, Wayne Xin Zhao and Ji-Rong Wen. - According to the abstract, - MVP follows a standard Transformer encoder-decoder architecture. @@ -67,6 +66,7 @@ For summarization, it is an example to use MVP and MVP with summarization-specif ``` For data-to-text generation, it is an example to use MVP and multi-task pre-trained variants. + ```python >>> from transformers import MvpTokenizerFast, MvpForConditionalGeneration diff --git a/docs/source/en/model_doc/myt5.md b/docs/source/en/model_doc/myt5.md index 409735751252..35ab716a8e71 100644 --- a/docs/source/en/model_doc/myt5.md +++ b/docs/source/en/model_doc/myt5.md @@ -44,4 +44,3 @@ The original code can be found [here](https://github.com/tomlimi/MYTE). ## MyT5Tokenizer [[autodoc]] MyT5Tokenizer - diff --git a/docs/source/en/model_doc/nemotron.md b/docs/source/en/model_doc/nemotron.md index 360a6ba22267..0a2104c58552 100644 --- a/docs/source/en/model_doc/nemotron.md +++ b/docs/source/en/model_doc/nemotron.md @@ -97,7 +97,6 @@ Minitron is released under the [NVIDIA Open Model License Agreement](https://dev | :------------- | :------------- | :------------- | :------------- | :------------- | | 75.0 | 74.0 | 24.1 | 50.9 | 29.5 - *Code generation performance*. Evaluated using [HumanEval](https://github.com/openai/human-eval): | p@1, 0-Shot | @@ -109,6 +108,7 @@ Please refer to our [paper](https://huggingface.co/papers/2407.14679) for the fu ### Citation If you find our work helpful, please consider citing our paper: + ``` @article{minitron2024, title={Compact Language Models via Pruning and Knowledge Distillation}, @@ -123,13 +123,11 @@ If you find our work helpful, please consider citing our paper: [[autodoc]] NemotronConfig - ## NemotronModel [[autodoc]] NemotronModel - forward - ## NemotronForCausalLM [[autodoc]] NemotronForCausalLM @@ -140,13 +138,11 @@ If you find our work helpful, please consider citing our paper: [[autodoc]] NemotronForSequenceClassification - forward - ## NemotronForQuestionAnswering [[autodoc]] NemotronForQuestionAnswering - forward - ## NemotronForTokenClassification [[autodoc]] NemotronForTokenClassification diff --git a/docs/source/en/model_doc/nllb-moe.md b/docs/source/en/model_doc/nllb-moe.md index f1456ee402dd..d8c44a5fc0f8 100644 --- a/docs/source/en/model_doc/nllb-moe.md +++ b/docs/source/en/model_doc/nllb-moe.md @@ -110,7 +110,6 @@ See example below for a translation from romanian to german: - [Translation task guide](../tasks/translation) - [Summarization task guide](../tasks/summarization) - ## NllbMoeConfig [[autodoc]] NllbMoeConfig @@ -135,4 +134,3 @@ See example below for a translation from romanian to german: [[autodoc]] NllbMoeForConditionalGeneration - forward - diff --git a/docs/source/en/model_doc/nllb.md b/docs/source/en/model_doc/nllb.md index 6f12a3aa746b..77fffafde673 100644 --- a/docs/source/en/model_doc/nllb.md +++ b/docs/source/en/model_doc/nllb.md @@ -29,7 +29,6 @@ rendered properly in your Markdown viewer. [NLLB: No Language Left Behind](https://huggingface.co/papers/2207.04672) is a multilingual translation model. It's trained on data using data mining techniques tailored for low-resource languages and supports over 200 languages. NLLB features a conditional compute architecture using a Sparsely Gated Mixture of Experts. - You can find all the original NLLB checkpoints under the [AI at Meta](https://huggingface.co/facebook/models?search=nllb) organization. > [!TIP] @@ -132,6 +131,7 @@ visualizer("UN Chief says there is no military solution in Syria") - For non-English languages, specify the language's [BCP-47](https://github.com/facebookresearch/flores/blob/main/flores200/README.md#languages-in-flores-200) code with the `src_lang` keyword as shown below. - See example below for a translation from Romanian to German. + ```python >>> from transformers import AutoModelForSeq2SeqLM, AutoTokenizer diff --git a/docs/source/en/model_doc/olmo2.md b/docs/source/en/model_doc/olmo2.md index bf582bc2ef54..7ecaa0e98fa8 100644 --- a/docs/source/en/model_doc/olmo2.md +++ b/docs/source/en/model_doc/olmo2.md @@ -87,6 +87,7 @@ echo -e "Plants create energy through a process known as" | transformers run --t Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for more available quantization backends. The example below uses [torchao](../quantization/torchao) to only quantize the weights to 4-bits. + ```py #pip install torchao @@ -116,7 +117,6 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` - ## Notes - OLMo2 uses RMSNorm instead of standard layer norm. The RMSNorm is applied to attention queries and keys, and it is applied after the attention and feedforward layers rather than before. @@ -129,7 +129,6 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) model = AutoModelForCausalLM.from_pretrained("allenai/OLMo-2-0425-1B", revision="stage1-step140000-tokens294B") ``` - ## Olmo2Config [[autodoc]] Olmo2Config diff --git a/docs/source/en/model_doc/olmo3.md b/docs/source/en/model_doc/olmo3.md index ecf384ee7cc0..57f3309e7480 100644 --- a/docs/source/en/model_doc/olmo3.md +++ b/docs/source/en/model_doc/olmo3.md @@ -12,7 +12,6 @@ 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. - ⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be rendered properly in your Markdown viewer. --> @@ -88,6 +87,7 @@ echo -e "Plants create energy through a process known as" | transformers run --t Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for more available quantization backends. The example below uses [torchao](../quantization/torchao) to only quantize the weights to 4-bits. + ```py #pip install torchao @@ -117,7 +117,6 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` - ## Notes - Load specific intermediate checkpoints by adding the `revision` parameter to [`~PreTrainedModel.from_pretrained`]. @@ -128,7 +127,6 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) model = AutoModelForCausalLM.from_pretrained("allenai/TBA", revision="stage1-step140000-tokens294B") ``` - ## Olmo3Config [[autodoc]] Olmo3Config diff --git a/docs/source/en/model_doc/openai-gpt.md b/docs/source/en/model_doc/openai-gpt.md index b45b205e2592..fba08ceca00e 100644 --- a/docs/source/en/model_doc/openai-gpt.md +++ b/docs/source/en/model_doc/openai-gpt.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2018-06-11 and added to Hugging Face Transformers on 2023-06-20.* -
PyTorch @@ -24,8 +23,6 @@ rendered properly in your Markdown viewer.
- - # GPT [GPT (Generative Pre-trained Transformer)](https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf) ([blog post](https://openai.com/index/language-unsupervised/)) focuses on effectively learning text representations and transferring them to tasks. This model trains the Transformer decoder to predict the next word, and then fine-tuned on labeled data. @@ -39,12 +36,9 @@ You can find all the original GPT checkpoints under the [OpenAI community](https The example below demonstrates how to generate text with [`Pipeline`], [`AutoModel`], and from the command line. - - - ```python import torch from transformers import pipeline @@ -75,6 +69,7 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True)) echo -e "The future of AI is" | transformers run --task text-generation --model openai-community/openai-gpt --device 0 ``` + diff --git a/docs/source/en/model_doc/opt.md b/docs/source/en/model_doc/opt.md index e645956f1ece..7c65689594e4 100644 --- a/docs/source/en/model_doc/opt.md +++ b/docs/source/en/model_doc/opt.md @@ -36,7 +36,6 @@ You can find all the original OPT checkpoints under the [OPT](https://huggingfac The example below demonstrates how to generate text with [`Pipeline`], [`AutoModel`], and from the command line. - @@ -65,12 +64,14 @@ model_inputs = tokenizer([prompt], return_tensors="pt").to(model.device) generated_ids = model.generate(**model_inputs, max_new_tokens=30, do_sample=False) tokenizer.batch_decode(generated_ids)[0] ``` + ```py echo -e "Plants create energy through a process known as" | transformers run --task text-generation --model facebook/opt-125m --device 0 ``` + diff --git a/docs/source/en/model_doc/ovis2.md b/docs/source/en/model_doc/ovis2.md index 342e34ef7a1b..731ebbb83f08 100644 --- a/docs/source/en/model_doc/ovis2.md +++ b/docs/source/en/model_doc/ovis2.md @@ -19,7 +19,7 @@ rendered properly in your Markdown viewer. ## Overview -The [Ovis2](https://github.com/AIDC-AI/Ovis) is an updated version of the [Ovis](https://huggingface.co/papers/2405.20797) model developed by the AIDC-AI team at Alibaba International Digital Commerce Group. +The [Ovis2](https://github.com/AIDC-AI/Ovis) is an updated version of the [Ovis](https://huggingface.co/papers/2405.20797) model developed by the AIDC-AI team at Alibaba International Digital Commerce Group. Ovis2 is the latest advancement in multi-modal large language models (MLLMs), succeeding Ovis1.6. It retains the architectural design of the Ovis series, which focuses on aligning visual and textual embeddings, and introduces major improvements in data curation and training methods. diff --git a/docs/source/en/model_doc/paligemma.md b/docs/source/en/model_doc/paligemma.md index 58aa622a0d37..fa7c193da453 100644 --- a/docs/source/en/model_doc/paligemma.md +++ b/docs/source/en/model_doc/paligemma.md @@ -140,6 +140,7 @@ visualizer(" What is in this image?") answer = "a pallas cat" inputs = processor(images=image, text=prompt, suffix=answer, return_tensors="pt") ``` + - PaliGemma can support multiple input images if it is fine-tuned to accept multiple images. For example, the [NLVR2](https://huggingface.co/google/paligemma-3b-ft-nlvr2-448) checkpoint supports multiple images. Pass the images as a list to the processor. ```py diff --git a/docs/source/en/model_doc/patchtsmixer.md b/docs/source/en/model_doc/patchtsmixer.md index 5541f4d80936..23ebb89b6ade 100644 --- a/docs/source/en/model_doc/patchtsmixer.md +++ b/docs/source/en/model_doc/patchtsmixer.md @@ -25,15 +25,13 @@ rendered properly in your Markdown viewer. The PatchTSMixer model was proposed in [TSMixer: Lightweight MLP-Mixer Model for Multivariate Time Series Forecasting](https://huggingface.co/papers/2306.09364) by Vijay Ekambaram, Arindam Jati, Nam Nguyen, Phanwadee Sinthong and Jayant Kalagnanam. - PatchTSMixer is a lightweight time-series modeling approach based on the MLP-Mixer architecture. In this HuggingFace implementation, we provide PatchTSMixer's capabilities to effortlessly facilitate lightweight mixing across patches, channels, and hidden features for effective multivariate time-series modeling. It also supports various attention mechanisms starting from simple gated attention to more complex self-attention blocks that can be customized accordingly. The model can be pretrained and subsequently used for various downstream tasks such as forecasting, classification and regression. - The abstract from the paper is the following: *TSMixer is a lightweight neural architecture exclusively composed of multi-layer perceptron (MLP) modules designed for multivariate forecasting and representation learning on patched time series. Our model draws inspiration from the success of MLP-Mixer models in computer vision. We demonstrate the challenges involved in adapting Vision MLP-Mixer for time series and introduce empirically validated components to enhance accuracy. This includes a novel design paradigm of attaching online reconciliation heads to the MLP-Mixer backbone, for explicitly modeling the time-series properties such as hierarchy and channel-correlations. We also propose a Hybrid channel modeling approach to effectively handle noisy channel interactions and generalization across diverse datasets, a common challenge in existing patch channel-mixing methods. Additionally, a simple gated attention mechanism is introduced in the backbone to prioritize important features. By incorporating these lightweight components, we significantly enhance the learning capability of simple MLP structures, outperforming complex Transformer models with minimal computing usage. Moreover, TSMixer's modular design enables compatibility with both supervised and masked self-supervised learning methods, making it a promising building block for time-series Foundation Models. TSMixer outperforms state-of-the-art MLP and Transformer models in forecasting by a considerable margin of 8-60%. It also outperforms the latest strong benchmarks of Patch-Transformer models (by 1-2%) with a significant reduction in memory and runtime (2-3X).* -This model was contributed by [ajati](https://huggingface.co/ajati), [vijaye12](https://huggingface.co/vijaye12), +This model was contributed by [ajati](https://huggingface.co/ajati), [vijaye12](https://huggingface.co/vijaye12), [gsinthong](https://huggingface.co/gsinthong), [namctin](https://huggingface.co/namctin), [wmgifford](https://huggingface.co/wmgifford), [kashif](https://huggingface.co/kashif). @@ -68,31 +66,26 @@ The model can also be used for time series classification and time series regres [[autodoc]] PatchTSMixerConfig - ## PatchTSMixerModel [[autodoc]] PatchTSMixerModel - forward - ## PatchTSMixerForPrediction [[autodoc]] PatchTSMixerForPrediction - forward - ## PatchTSMixerForTimeSeriesClassification [[autodoc]] PatchTSMixerForTimeSeriesClassification - forward - ## PatchTSMixerForPretraining [[autodoc]] PatchTSMixerForPretraining - forward - ## PatchTSMixerForRegression [[autodoc]] PatchTSMixerForRegression diff --git a/docs/source/en/model_doc/pegasus_x.md b/docs/source/en/model_doc/pegasus_x.md index 4f048e5496cb..783581ad96dc 100644 --- a/docs/source/en/model_doc/pegasus_x.md +++ b/docs/source/en/model_doc/pegasus_x.md @@ -53,6 +53,7 @@ Through photosynthesis, plants capture energy from sunlight using a green pigmen These ingredients are then transformed into glucose, a type of sugar that serves as a source of chemical energy, and oxygen, which is released as a byproduct into the atmosphere. The glucose produced during photosynthesis is not just used immediately; plants also store it as starch or convert it into other organic compounds like cellulose, which is essential for building their cellular structure. This energy reserve allows them to grow, develop leaves, produce flowers, bear fruit, and carry out various physiological processes throughout their lifecycle.""") ``` + @@ -78,12 +79,14 @@ input_ids = tokenizer(input_text, return_tensors="pt").to(model.device) output = model.generate(**input_ids, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + ```bash echo -e "Plants are among the most remarkable and essential life forms on Earth, possessing a unique ability to produce their own food through a process known as photosynthesis. This complex biochemical process is fundamental not only to plant life but to virtually all life on the planet. Through photosynthesis, plants capture energy from sunlight using a green pigment called chlorophyll, which is located in specialized cell structures called chloroplasts." | transformers run --task summarization --model google/pegasus-x-large --device 0 ``` + diff --git a/docs/source/en/model_doc/perception_lm.md b/docs/source/en/model_doc/perception_lm.md index ee6b63fce6fd..7d3d608253fc 100644 --- a/docs/source/en/model_doc/perception_lm.md +++ b/docs/source/en/model_doc/perception_lm.md @@ -38,11 +38,9 @@ video captions. Additionally, we introduce PLM–VideoBench, a suite for evaluat understanding tasks focusing on the ability to reason about “what”, “where”, “when”, and “how” of a video. We make our work fully reproducible by providing data, training recipes, code & models.* - This model was contributed by [shumingh](https://huggingface.co/shumingh). The original code can be found [here](https://github.com/facebookresearch/perception_models). - ## PerceptionLMConfig [[autodoc]] PerceptionLMConfig diff --git a/docs/source/en/model_doc/persimmon.md b/docs/source/en/model_doc/persimmon.md index 764c959879ad..854eaee835df 100644 --- a/docs/source/en/model_doc/persimmon.md +++ b/docs/source/en/model_doc/persimmon.md @@ -39,7 +39,7 @@ The original code can be found [here](https://github.com/persimmon-ai-labs/adept The `Persimmon` models were trained using `bfloat16`, but the original inference uses `float16` The checkpoints uploaded on the hub use `dtype = 'float16'` which will be -used by the `AutoModel` API to cast the checkpoints from `torch.float32` to `torch.float16`. +used by the `AutoModel` API to cast the checkpoints from `torch.float32` to `torch.float16`. The `dtype` of the online weights is mostly irrelevant, unless you are using `dtype="auto"` when initializing a model using `model = AutoModelForCausalLM.from_pretrained("path", dtype = "auto")`. The reason is that the model will first be downloaded ( using the `dtype` of the checkpoints online) then it will be cast to the default `dtype` of `torch` (becomes `torch.float32`). Users should specify the `dtype` they want, and if they don't it will be `torch.float32`. @@ -47,7 +47,6 @@ Finetuning the model in `float16` is not recommended and known to produce `nan`, - Tips: - To convert the model, you need to clone the original repository using `git clone https://github.com/persimmon-ai-labs/adept-inference`, then get the checkpoints: @@ -62,6 +61,7 @@ python src/transformers/models/persimmon/convert_persimmon_weights_to_hf.py --i ``` For the chat model: + ```bash wget https://axtkn4xl5cip.objectstorage.us-phoenix-1.oci.customer-oci.com/n/axtkn4xl5cip/b/adept-public-data/o/8b_chat_model_release.tar tar -xvf 8b_base_model_release.tar @@ -76,13 +76,11 @@ model = PersimmonForCausalLM.from_pretrained("/output/path") tokenizer = PersimmonTokenizer.from_pretrained("/output/path") ``` - - Perismmon uses a `sentencepiece` based tokenizer, with a `Unigram` model. It supports bytefallback, which is only available in `tokenizers==0.14.0` for the fast tokenizer. The `LlamaTokenizer` is used as it is a standard wrapper around sentencepiece. The `chat` template will be updated with the templating functions in a follow up PR! - The authors suggest to use the following prompt format for the chat mode: `f"human: {prompt}\n\nadept:"` - ## PersimmonConfig [[autodoc]] PersimmonConfig diff --git a/docs/source/en/model_doc/phi3.md b/docs/source/en/model_doc/phi3.md index 020b26431939..9a045e6f184d 100644 --- a/docs/source/en/model_doc/phi3.md +++ b/docs/source/en/model_doc/phi3.md @@ -72,7 +72,6 @@ Phi-3 has been integrated in the development version (4.40.0.dev) of `transforme [[autodoc]] Phi3Config - ## Phi3Model [[autodoc]] Phi3Model @@ -93,4 +92,3 @@ Phi-3 has been integrated in the development version (4.40.0.dev) of `transforme [[autodoc]] Phi3ForTokenClassification - forward - diff --git a/docs/source/en/model_doc/phimoe.md b/docs/source/en/model_doc/phimoe.md index a564eb6145af..3d414d7c43b1 100644 --- a/docs/source/en/model_doc/phimoe.md +++ b/docs/source/en/model_doc/phimoe.md @@ -50,6 +50,7 @@ Phi-3.5-MoE-instruct has been integrated in the development version (4.44.2.dev) The current `transformers` version can be verified with: `pip list | grep transformers`. Examples of required packages: + ``` flash_attn==2.5.8 torch==2.3.1 @@ -101,7 +102,6 @@ print(output[0]['generated_text']) [[autodoc]] PhimoeConfig - ## PhimoeModel [[autodoc]] PhimoeModel @@ -117,4 +117,3 @@ print(output[0]['generated_text']) [[autodoc]] PhimoeForSequenceClassification - forward - diff --git a/docs/source/en/model_doc/pixtral.md b/docs/source/en/model_doc/pixtral.md index 55ba09084292..bb175973bd23 100644 --- a/docs/source/en/model_doc/pixtral.md +++ b/docs/source/en/model_doc/pixtral.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2024-09-17 and added to Hugging Face Transformers on 2024-09-14.* -
PyTorch diff --git a/docs/source/en/model_doc/pop2piano.md b/docs/source/en/model_doc/pop2piano.md index 5f68b1805000..90e0cd3f0633 100644 --- a/docs/source/en/model_doc/pop2piano.md +++ b/docs/source/en/model_doc/pop2piano.md @@ -21,14 +21,14 @@ specific language governing permissions and limitations under the License. The Pop2Piano model was proposed in [Pop2Piano : Pop Audio-based Piano Cover Generation](https://huggingface.co/papers/2211.00895) by Jongho Choi and Kyogu Lee. -Piano covers of pop music are widely enjoyed, but generating them from music is not a trivial task. It requires great -expertise with playing piano as well as knowing different characteristics and melodies of a song. With Pop2Piano you -can directly generate a cover from a song's audio waveform. It is the first model to directly generate a piano cover -from pop audio without melody and chord extraction modules. - -Pop2Piano is an encoder-decoder Transformer model based on [T5](https://huggingface.co/papers/1910.10683). The input audio -is transformed to its waveform and passed to the encoder, which transforms it to a latent representation. The decoder -uses these latent representations to generate token ids in an autoregressive way. Each token id corresponds to one of four +Piano covers of pop music are widely enjoyed, but generating them from music is not a trivial task. It requires great +expertise with playing piano as well as knowing different characteristics and melodies of a song. With Pop2Piano you +can directly generate a cover from a song's audio waveform. It is the first model to directly generate a piano cover +from pop audio without melody and chord extraction modules. + +Pop2Piano is an encoder-decoder Transformer model based on [T5](https://huggingface.co/papers/1910.10683). The input audio +is transformed to its waveform and passed to the encoder, which transforms it to a latent representation. The decoder +uses these latent representations to generate token ids in an autoregressive way. Each token id corresponds to one of four different token types: time, velocity, note and 'special'. The token ids are then decoded to their equivalent MIDI file. The abstract from the paper is the following: @@ -53,9 +53,11 @@ The original code can be found [here](https://github.com/sweetcocoa/pop2piano). ## Usage tips * To use Pop2Piano, you will need to install the 🤗 Transformers library, as well as the following third party modules: + ```bash pip install pretty-midi==0.2.9 essentia==2.1b6.dev1034 librosa scipy ``` + Please note that you may need to restart your runtime after installation. * Pop2Piano is an Encoder-Decoder based model like T5. * Pop2Piano can be used to generate midi-audio files for a given audio sequence. @@ -131,7 +133,6 @@ Please note that you may need to restart your runtime after installation. >>> tokenizer_output[1].write("./Outputs/midi_output2.mid") ``` - - Example of processing multiple audio files in batch (Using `Pop2PianoFeatureExtractor` and `Pop2PianoTokenizer`): ```python @@ -166,7 +167,6 @@ Please note that you may need to restart your runtime after installation. >>> tokenizer_output[1].write("./Outputs/midi_output2.mid") ``` - ## Pop2PianoConfig [[autodoc]] Pop2PianoConfig diff --git a/docs/source/en/model_doc/prompt_depth_anything.md b/docs/source/en/model_doc/prompt_depth_anything.md index 5af13c5d630e..0ac26609b4d0 100644 --- a/docs/source/en/model_doc/prompt_depth_anything.md +++ b/docs/source/en/model_doc/prompt_depth_anything.md @@ -19,8 +19,7 @@ rendered properly in your Markdown viewer. ## Overview -The Prompt Depth Anything model was introduced in [Prompting Depth Anything for 4K Resolution Accurate Metric Depth Estimation](https://huggingface.co/papers/2412.14015) by Haotong Lin, Sida Peng, Jingxiao Chen, Songyou Peng, Jiaming Sun, Minghuan Liu, Hujun Bao, Jiashi Feng, Xiaowei Zhou, Bingyi Kang. - +The Prompt Depth Anything model was introduced in [Prompting Depth Anything for 4K Resolution Accurate Metric Depth Estimation](https://huggingface.co/papers/2412.14015) by Haotong Lin, Sida Peng, Jingxiao Chen, Songyou Peng, Jiaming Sun, Minghuan Liu, Hujun Bao, Jiashi Feng, Xiaowei Zhou, Bingyi Kang. The abstract from the paper is as follows: diff --git a/docs/source/en/model_doc/pvt.md b/docs/source/en/model_doc/pvt.md index e7902affe5f4..38858db55529 100644 --- a/docs/source/en/model_doc/pvt.md +++ b/docs/source/en/model_doc/pvt.md @@ -29,23 +29,22 @@ is used to further reduce the resource consumption when learning high-resolution The abstract from the paper is the following: -*Although convolutional neural networks (CNNs) have achieved great success in computer vision, this work investigates a -simpler, convolution-free backbone network useful for many dense prediction tasks. Unlike the recently proposed Vision -Transformer (ViT) that was designed for image classification specifically, we introduce the Pyramid Vision Transformer -(PVT), which overcomes the difficulties of porting Transformer to various dense prediction tasks. PVT has several -merits compared to current state of the arts. Different from ViT that typically yields low resolution outputs and -incurs high computational and memory costs, PVT not only can be trained on dense partitions of an image to achieve high -output resolution, which is important for dense prediction, but also uses a progressive shrinking pyramid to reduce the -computations of large feature maps. PVT inherits the advantages of both CNN and Transformer, making it a unified -backbone for various vision tasks without convolutions, where it can be used as a direct replacement for CNN backbones. +*Although convolutional neural networks (CNNs) have achieved great success in computer vision, this work investigates a +simpler, convolution-free backbone network useful for many dense prediction tasks. Unlike the recently proposed Vision +Transformer (ViT) that was designed for image classification specifically, we introduce the Pyramid Vision Transformer +(PVT), which overcomes the difficulties of porting Transformer to various dense prediction tasks. PVT has several +merits compared to current state of the arts. Different from ViT that typically yields low resolution outputs and +incurs high computational and memory costs, PVT not only can be trained on dense partitions of an image to achieve high +output resolution, which is important for dense prediction, but also uses a progressive shrinking pyramid to reduce the +computations of large feature maps. PVT inherits the advantages of both CNN and Transformer, making it a unified +backbone for various vision tasks without convolutions, where it can be used as a direct replacement for CNN backbones. We validate PVT through extensive experiments, showing that it boosts the performance of many downstream tasks, including -object detection, instance and semantic segmentation. For example, with a comparable number of parameters, PVT+RetinaNet -achieves 40.4 AP on the COCO dataset, surpassing ResNet50+RetinNet (36.3 AP) by 4.1 absolute AP (see Figure 2). We hope +object detection, instance and semantic segmentation. For example, with a comparable number of parameters, PVT+RetinaNet +achieves 40.4 AP on the COCO dataset, surpassing ResNet50+RetinNet (36.3 AP) by 4.1 absolute AP (see Figure 2). We hope that PVT could serve as an alternative and useful backbone for pixel-level predictions and facilitate future research.* This model was contributed by [Xrenya](https://huggingface.co/Xrenya). The original code can be found [here](https://github.com/whai362/PVT). - - PVTv1 on ImageNet-1K | **Model variant** |**Size** |**Acc@1**|**Params (M)**| @@ -55,7 +54,6 @@ This model was contributed by [Xrenya](https://huggingface.co/Xrenya). The origi | PVT-Medium | 224 | 81.2 | 44.2 | | PVT-Large | 224 | 81.7 | 61.4 | - ## PvtConfig [[autodoc]] PvtConfig diff --git a/docs/source/en/model_doc/pvt_v2.md b/docs/source/en/model_doc/pvt_v2.md index 0d0ee3cca751..5be8998f4cc2 100644 --- a/docs/source/en/model_doc/pvt_v2.md +++ b/docs/source/en/model_doc/pvt_v2.md @@ -26,7 +26,7 @@ The PVTv2 encoder structure has been successfully deployed to achieve state-of-t PVTv2 belongs to a family of models called [hierarchical transformers](https://natecibik.medium.com/the-rise-of-vision-transformers-f623c980419f) , which make adaptations to transformer layers in order to generate multi-scale feature maps. Unlike the columnal structure of Vision Transformer ([ViT](https://huggingface.co/papers/2010.11929)) which loses fine-grained detail, multi-scale feature maps are known preserve this detail and aid performance in dense prediction tasks. In the case of PVTv2, this is achieved by generating image patch tokens using 2D convolution with overlapping kernels in each encoder layer. -The multi-scale features of hierarchical transformers allow them to be easily swapped in for traditional workhorse computer vision backbone models like ResNet in larger architectures. Both Segformer and Panoptic Segformer demonstrated that configurations using PVTv2 for a backbone consistently outperformed those with similarly sized ResNet backbones. +The multi-scale features of hierarchical transformers allow them to be easily swapped in for traditional workhorse computer vision backbone models like ResNet in larger architectures. Both Segformer and Panoptic Segformer demonstrated that configurations using PVTv2 for a backbone consistently outperformed those with similarly sized ResNet backbones. Another powerful feature of the PVTv2 is the complexity reduction in the self-attention layers called Spatial Reduction Attention (SRA), which uses 2D convolution layers to project hidden states to a smaller resolution before attending to them with the queries, improving the $O(n^2)$ complexity of self-attention to $O(n^2/R)$, with $R$ being the spatial reduction ratio (`sr_ratio`, aka kernel size and stride in the 2D convolution). @@ -48,6 +48,7 @@ This model was contributed by [FoamoftheSea](https://huggingface.co/FoamoftheSea - ImageNet pretrained weights for all model sizes can be found on the [hub](https://huggingface.co/models?other=pvt_v2). The best way to get started with the PVTv2 is to load the pretrained checkpoint with the size of your choosing using `AutoModelForImageClassification`: + ```python import requests import torch @@ -99,7 +100,6 @@ outputs = model(torch.tensor(processed["pixel_values"])) | PVT-V2-B4 | 224 | 83.6 | 62.6 | | PVT-V2-B5 | 224 | 83.8 | 82.0 | - ## PvtV2Config [[autodoc]] PvtV2Config diff --git a/docs/source/en/model_doc/qwen2.md b/docs/source/en/model_doc/qwen2.md index 3f872302cc27..feeb69959b21 100644 --- a/docs/source/en/model_doc/qwen2.md +++ b/docs/source/en/model_doc/qwen2.md @@ -142,7 +142,6 @@ outputs = model.generate(**inputs, max_new_tokens=100) print(tokenizer.decode(outputs[0], skip_special_tokens=True)) ``` - ## Notes - Ensure your Transformers library version is up-to-date. Qwen2 requires Transformers>=4.37.0 for full support. diff --git a/docs/source/en/model_doc/qwen2_5_omni.md b/docs/source/en/model_doc/qwen2_5_omni.md index e124f7cdb421..7a0836592d45 100644 --- a/docs/source/en/model_doc/qwen2_5_omni.md +++ b/docs/source/en/model_doc/qwen2_5_omni.md @@ -31,8 +31,6 @@ The abstract from the technical report is the following: *We present Qwen2.5-Omni, an end-to-end multimodal model designed to perceive diverse modalities, including text, images, audio, and video, while simultaneously generating text and natural speech responses in a streaming manner. To enable the streaming of multimodal information inputs, both audio and visual encoders utilize a block-wise processing approach. This strategy effectively decouples the handling of long sequences of multimodal data, assigning the perceptual responsibilities to the multimodal encoder and entrusting the modeling of extended sequences to a large language model. Such a division of labor enhances the fusion of different modalities via the shared attention mechanism. To synchronize the timestamps of video inputs with audio, we organized the audio and video sequentially in an interleaved manner and propose a novel position embedding approach, named TMRoPE (Time-aligned Multimodal RoPE). To concurrently generate text and speech while avoiding interference between the two modalities, we propose Thinker-Talker architecture. In this framework, Thinker functions as a large language model tasked with text generation, while Talker is a dual-track autoregressive model that directly utilizes the hidden representations from the Thinker to produce audio tokens as output. Both the Thinker and Talker models are designed to be trained and inferred in an end-to-end manner. For decoding audio tokens in a streaming manner, we introduce a sliding-window DiT that restricts the receptive field, aiming to reduce the initial package delay. Qwen2.5-Omni outperforms the similarly sized Qwen2-VL and Qwen2-Audio in both image and audio capabilities. Furthermore, Qwen2.5-Omni achieves state-of-the-art performance on multimodal benchmarks like Omni-Bench. Notably, Qwen2.5-Omni is the first open-source model to achieve a level of performance in end-to-end speech instruction following that is comparable to its capabilities with text inputs, as evidenced by benchmarks such as MMLU and GSM8K. As for speech generation, Qwen2.5-Omni’s streaming Talker outperform most existing streaming and non-streaming alternatives in robustness and naturalness.* - - ## Notes - Use [`Qwen2_5OmniForConditionalGeneration`] to generate audio and text output. To generate only one output type, use [`Qwen2_5OmniThinkerForConditionalGeneration`] for text-only and [`Qwen2_5OmniTalkersForConditionalGeneration`] for audio-only outputs. @@ -40,7 +38,6 @@ The abstract from the technical report is the following: - In case out out-of-memory errors hwen working with video input, decrease `processor.max_pixels`. By default the maximum is set to a very arge value and high resolution visuals will not be resized, unless resolution exceeds `processor.max_pixels`. - The processor has its own [`~ProcessorMixin.apply_chat_template`] method to convert chat messages to model inputs. - ## Usage example `Qwen2.5-Omni` can be found on the [Huggingface Hub](https://huggingface.co/Qwen). @@ -275,6 +272,7 @@ processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B", min_pixels=min #### Prompt for audio output If users need audio output, the system prompt must be set as "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech.", otherwise the audio output may not work as expected. + ``` { "role": "system", @@ -285,6 +283,7 @@ If users need audio output, the system prompt must be set as "You are Qwen, a vi #### Use audio output or not The model supports both text and audio outputs, if users do not need audio outputs, they can set `enable_audio_output` in the `from_pretrained` function. This option will save about `~2GB` of GPU memory but the `return_audio` option for `generate` function will only allow to be set at `False`. + ```python model = Qwen2_5OmniForConditionalGeneration.from_pretrained( "Qwen/Qwen2.5-Omni-7B", @@ -341,8 +340,6 @@ model = Qwen2_5OmniForConditionalGeneration.from_pretrained( ) ``` - - ## Qwen2_5OmniConfig [[autodoc]] Qwen2_5OmniConfig diff --git a/docs/source/en/model_doc/qwen2_5_vl.md b/docs/source/en/model_doc/qwen2_5_vl.md index 62527ea4963a..7f682bf80201 100644 --- a/docs/source/en/model_doc/qwen2_5_vl.md +++ b/docs/source/en/model_doc/qwen2_5_vl.md @@ -26,7 +26,6 @@ rendered properly in your Markdown viewer. [Qwen2.5-VL](https://huggingface.co/papers/2502.13923) is a multimodal vision-language model, available in 3B, 7B, and 72B parameters, pretrained on 4.1T tokens. The model introduces window attention in the ViT encoder to accelerate training and inference, dynamic FPS sampling on the spatial and temporal dimensions for better video understanding across different sampling rates, and an upgraded MRoPE (multi-resolutional rotary positional encoding) mechanism to better capture and learn temporal dynamics. - You can find all the original Qwen2.5-VL checkpoints under the [Qwen2.5-VL](https://huggingface.co/collections/Qwen/qwen25-vl-6795ffac22b334a837c0f9a5) collection. > [!TIP] @@ -61,6 +60,7 @@ messages = [ pipe(text=messages,max_new_tokens=20, return_full_text=False) ``` + @@ -110,6 +110,7 @@ output_text = processor.batch_decode( ) print(output_text) ``` + @@ -130,9 +131,11 @@ model = Qwen2_5_VLForConditionalGeneration.from_pretrained( ) ``` + ### Notes - Use Qwen2.5-VL for video inputs by setting `"type": "video"` as shown below. + ```python conversation = [ { @@ -159,8 +162,10 @@ model = Qwen2_5_VLForConditionalGeneration.from_pretrained( output_text = processor.batch_decode(generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=True) print(output_text) ``` + - Use Qwen2.5-VL for a mixed batch of inputs (images, videos, text). Add labels when handling multiple images or videos for better reference as show below. + ```python import torch from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor @@ -221,14 +226,15 @@ model = Qwen2_5_VLForConditionalGeneration.from_pretrained( max_pixels = 2048*2048 processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-VL-7B-Instruct", min_pixels=min_pixels, max_pixels=max_pixels) ``` - + Higher resolution can require more compute whereas reducing the resolution can save memory as follows: - + ```python min_pixels = 256*28*28 max_pixels = 1024*28*28 processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-VL-7B-Instruct", min_pixels=min_pixels, max_pixels=max_pixels) ``` + ## Qwen2_5_VLConfig [[autodoc]] Qwen2_5_VLConfig diff --git a/docs/source/en/model_doc/qwen2_audio.md b/docs/source/en/model_doc/qwen2_audio.md index 7cdcd52119c0..9b9dd43a919d 100644 --- a/docs/source/en/model_doc/qwen2_audio.md +++ b/docs/source/en/model_doc/qwen2_audio.md @@ -36,7 +36,6 @@ The abstract from the paper is the following: *We introduce the latest progress of Qwen-Audio, a large-scale audio-language model called Qwen2-Audio, which is capable of accepting various audio signal inputs and performing audio analysis or direct textual responses with regard to speech instructions. In contrast to complex hierarchical tags, we have simplified the pre-training process by utilizing natural language prompts for different data and tasks, and have further expanded the data volume. We have boosted the instruction-following capability of Qwen2-Audio and implemented two distinct audio interaction modes for voice chat and audio analysis. In the voice chat mode, users can freely engage in voice interactions with Qwen2-Audio without text input. In the audio analysis mode, users could provide audio and text instructions for analysis during the interaction. Note that we do not use any system prompts to switch between voice chat and audio analysis modes. Qwen2-Audio is capable of intelligently comprehending the content within audio and following voice commands to respond appropriately. For instance, in an audio segment that simultaneously contains sounds, multi-speaker conversations, and a voice command, Qwen2-Audio can directly understand the command and provide an interpretation and response to the audio. Additionally, DPO has optimized the model's performance in terms of factuality and adherence to desired behavior. According to the evaluation results from AIR-Bench, Qwen2-Audio outperformed previous SOTAs, such as Gemini-1.5-pro, in tests focused on audio-centric instruction-following capabilities. Qwen2-Audio is open-sourced with the aim of fostering the advancement of the multi-modal language community. * - ## Usage tips `Qwen2-Audio-7B` and `Qwen2-Audio-7B-Instruct` can be found on the [Huggingface Hub](https://huggingface.co/Qwen) @@ -79,6 +78,7 @@ In the following, we demonstrate how to use `Qwen2-Audio-7B-Instruct` for the in ### Voice Chat Inference In the voice chat mode, users can freely engage in voice interactions with Qwen2-Audio without text input: + ```python from io import BytesIO from urllib.request import urlopen @@ -119,6 +119,7 @@ response = processor.batch_decode(generate_ids, skip_special_tokens=True, clean_ ### Audio Analysis Inference In the audio analysis, users could provide both audio and text instructions for analysis: + ```python from io import BytesIO from urllib.request import urlopen @@ -167,6 +168,7 @@ response = processor.batch_decode(generate_ids, skip_special_tokens=True, clean_ ### Batch Inference We also support batch inference: + ```python from io import BytesIO from urllib.request import urlopen diff --git a/docs/source/en/model_doc/qwen2_moe.md b/docs/source/en/model_doc/qwen2_moe.md index b8a3fe65d310..9d55de63e16d 100644 --- a/docs/source/en/model_doc/qwen2_moe.md +++ b/docs/source/en/model_doc/qwen2_moe.md @@ -24,7 +24,6 @@ rendered properly in your Markdown viewer. # Qwen2MoE - [Qwen2MoE](https://huggingface.co/papers/2407.10671) is a Mixture-of-Experts (MoE) variant of [Qwen2](./qwen2), available as a base model and an aligned chat model. It uses SwiGLU activation, group query attention and a mixture of sliding window attention and full attention. The tokenizer can also be adapted to multiple languages and codes. The MoE architecture uses upcyled models from the dense language models. For example, Qwen1.5-MoE-A2.7B is upcycled from Qwen-1.8B. It has 14.3B parameters but only 2.7B parameters are activated during runtime. @@ -57,6 +56,7 @@ messages = [ outputs = pipe(messages, max_new_tokens=256, do_sample=True, temperature=0.7, top_k=50, top_p=0.95) print(outputs[0]["generated_text"][-1]['content']) ``` + @@ -100,14 +100,14 @@ generated_ids = [ response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) ``` - + + ```bash transformers chat Qwen/Qwen1.5-MoE-A2.7B-Chat --dtype auto --attn_implementation flash_attention_2 ``` - - + Quantization reduces the memory burden of large models by representing the weights in a lower precision. Refer to the [Quantization](../quantization/overview) overview for more available quantization backends. diff --git a/docs/source/en/model_doc/qwen2_vl.md b/docs/source/en/model_doc/qwen2_vl.md index 8ff09ca57238..59dc25b5e085 100644 --- a/docs/source/en/model_doc/qwen2_vl.md +++ b/docs/source/en/model_doc/qwen2_vl.md @@ -25,7 +25,7 @@ rendered properly in your Markdown viewer. ## Overview -The [Qwen2-VL](https://huggingface.co/papers/2409.12191) ([blog post](https://qwenlm.github.io/blog/qwen2-vl/)) model is a major update to [Qwen-VL](https://huggingface.co/papers/2308.12966) from the Qwen team at Alibaba Research. +The [Qwen2-VL](https://huggingface.co/papers/2409.12191) ([blog post](https://qwenlm.github.io/blog/qwen2-vl/)) model is a major update to [Qwen-VL](https://huggingface.co/papers/2308.12966) from the Qwen team at Alibaba Research. The abstract from the blog is the following: @@ -203,8 +203,8 @@ min_pixels = 256*28*28 max_pixels = 1024*28*28 processor = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-7B-Instruct", min_pixels=min_pixels, max_pixels=max_pixels) ``` -This ensures each image gets encoded using a number between 256-1024 tokens. The 28 comes from the fact that the model uses a patch size of 14 and a temporal patch size of 2 (14 x 2 = 28). +This ensures each image gets encoded using a number between 256-1024 tokens. The 28 comes from the fact that the model uses a patch size of 14 and a temporal patch size of 2 (14 x 2 = 28). #### Multiple Image Inputs @@ -307,7 +307,7 @@ model = Qwen2VLForConditionalGeneration.from_pretrained( [[autodoc]] Qwen2VLTextModel - forward - + ## Qwen2VLModel [[autodoc]] Qwen2VLModel diff --git a/docs/source/en/model_doc/qwen3.md b/docs/source/en/model_doc/qwen3.md index 87e6ba500f96..0141388fb97f 100644 --- a/docs/source/en/model_doc/qwen3.md +++ b/docs/source/en/model_doc/qwen3.md @@ -25,7 +25,6 @@ rendered properly in your Markdown viewer. To be released with the official model launch. - ## Usage tips To be released with the official model launch. diff --git a/docs/source/en/model_doc/qwen3_omni_moe.md b/docs/source/en/model_doc/qwen3_omni_moe.md index 04d77534f649..cd5506802d5a 100644 --- a/docs/source/en/model_doc/qwen3_omni_moe.md +++ b/docs/source/en/model_doc/qwen3_omni_moe.md @@ -31,8 +31,6 @@ The abstract from the technical report is the following: *We present Qwen2.5-Omni, an end-to-end multimodal model designed to perceive diverse modalities, including text, images, audio, and video, while simultaneously generating text and natural speech responses in a streaming manner. To enable the streaming of multimodal information inputs, both audio and visual encoders utilize a block-wise processing approach. This strategy effectively decouples the handling of long sequences of multimodal data, assigning the perceptual responsibilities to the multimodal encoder and entrusting the modeling of extended sequences to a large language model. Such a division of labor enhances the fusion of different modalities via the shared attention mechanism. To synchronize the timestamps of video inputs with audio, we organized the audio and video sequentially in an interleaved manner and propose a novel position embedding approach, named TMRoPE (Time-aligned Multimodal RoPE). To concurrently generate text and speech while avoiding interference between the two modalities, we propose Thinker-Talker architecture. In this framework, Thinker functions as a large language model tasked with text generation, while Talker is a dual-track autoregressive model that directly utilizes the hidden representations from the Thinker to produce audio tokens as output. Both the Thinker and Talker models are designed to be trained and inferred in an end-to-end manner. For decoding audio tokens in a streaming manner, we introduce a sliding-window DiT that restricts the receptive field, aiming to reduce the initial package delay. Qwen2.5-Omni outperforms the similarly sized Qwen2-VL and Qwen2-Audio in both image and audio capabilities. Furthermore, Qwen2.5-Omni achieves state-of-the-art performance on multimodal benchmarks like Omni-Bench. Notably, Qwen2.5-Omni is the first open-source model to achieve a level of performance in end-to-end speech instruction following that is comparable to its capabilities with text inputs, as evidenced by benchmarks such as MMLU and GSM8K. As for speech generation, Qwen2.5-Omni’s streaming Talker outperform most existing streaming and non-streaming alternatives in robustness and naturalness.* - - ## Notes - Use [`Qwen2_5OmniForConditionalGeneration`] to generate audio and text output. To generate only one output type, use [`Qwen2_5OmniThinkerForConditionalGeneration`] for text-only and [`Qwen2_5OmniTalkersForConditionalGeneration`] for audio-only outputs. @@ -40,7 +38,6 @@ The abstract from the technical report is the following: - In case out out-of-memory errors hwen working with video input, decrease `processor.max_pixels`. By default the maximum is set to a very arge value and high resolution visuals will not be resized, unless resolution exceeds `processor.max_pixels`. - The processor has its own [`~ProcessorMixin.apply_chat_template`] method to convert chat messages to model inputs. - ## Usage example `Qwen2.5-Omni` can be found on the [Huggingface Hub](https://huggingface.co/Qwen). @@ -275,6 +272,7 @@ processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B", min_pixels=min #### Prompt for audio output If users need audio output, the system prompt must be set as "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech.", otherwise the audio output may not work as expected. + ``` { "role": "system", @@ -285,6 +283,7 @@ If users need audio output, the system prompt must be set as "You are Qwen, a vi #### Use audio output or not The model supports both text and audio outputs, if users do not need audio outputs, they can set `enable_audio_output` in the `from_pretrained` function. This option will save about `~2GB` of GPU memory but the `return_audio` option for `generate` function will only allow to be set at `False`. + ```python model = Qwen2_5OmniForConditionalGeneration.from_pretrained( "Qwen/Qwen2.5-Omni-7B", @@ -341,8 +340,6 @@ model = Qwen2_5OmniForConditionalGeneration.from_pretrained( ) ``` - - ## Qwen3OmniMoeConfig [[autodoc]] Qwen3OmniMoeConfig @@ -410,5 +407,3 @@ model = Qwen2_5OmniForConditionalGeneration.from_pretrained( ## Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration [[autodoc]] Qwen3OmniMoeTalkerCodePredictorModelForConditionalGeneration - - diff --git a/docs/source/en/model_doc/qwen3_vl.md b/docs/source/en/model_doc/qwen3_vl.md index c939d5da3cd9..dc9ecafeb44a 100644 --- a/docs/source/en/model_doc/qwen3_vl.md +++ b/docs/source/en/model_doc/qwen3_vl.md @@ -77,6 +77,7 @@ output_text = processor.batch_decode( ) print(output_text) ``` + diff --git a/docs/source/en/model_doc/qwen3_vl_moe.md b/docs/source/en/model_doc/qwen3_vl_moe.md index 6e27adf915d3..e36336d90a44 100644 --- a/docs/source/en/model_doc/qwen3_vl_moe.md +++ b/docs/source/en/model_doc/qwen3_vl_moe.md @@ -77,6 +77,7 @@ output_text = processor.batch_decode( ) print(output_text) ``` + diff --git a/docs/source/en/model_doc/recurrent_gemma.md b/docs/source/en/model_doc/recurrent_gemma.md index 1cd4e784a5bd..2d7c940e00a9 100644 --- a/docs/source/en/model_doc/recurrent_gemma.md +++ b/docs/source/en/model_doc/recurrent_gemma.md @@ -31,16 +31,14 @@ The abstract from the paper is the following: Tips: -- The original checkpoints can be converted using the conversion script [`src/transformers/models/recurrent_gemma/convert_recurrent_gemma_weights_to_hf.py`](https://github.com/huggingface/transformers/blob/main/src/transformers/models/recurrent_gemma/convert_recurrent_gemma_to_hf.py). +- The original checkpoints can be converted using the conversion script [`src/transformers/models/recurrent_gemma/convert_recurrent_gemma_weights_to_hf.py`](https://github.com/huggingface/transformers/blob/main/src/transformers/models/recurrent_gemma/convert_recurrent_gemma_to_hf.py). This model was contributed by [Arthur Zucker](https://huggingface.co/ArthurZ). The original code can be found [here](https://github.com/google-deepmind/recurrentgemma). - ## RecurrentGemmaConfig [[autodoc]] RecurrentGemmaConfig - ## RecurrentGemmaModel [[autodoc]] RecurrentGemmaModel @@ -50,4 +48,3 @@ This model was contributed by [Arthur Zucker](https://huggingface.co/ArthurZ). T [[autodoc]] RecurrentGemmaForCausalLM - forward - diff --git a/docs/source/en/model_doc/reformer.md b/docs/source/en/model_doc/reformer.md index f94134609d2b..c48de93d47da 100644 --- a/docs/source/en/model_doc/reformer.md +++ b/docs/source/en/model_doc/reformer.md @@ -89,7 +89,6 @@ equal to `config.hidden_size` and `config.axial_pos_shape` is set to a tuple \\( product has to be equal to `config.max_embedding_size`, which during training has to be equal to the *sequence length* of the `input_ids`. - ### LSH Self Attention In Locality sensitive hashing (LSH) self attention the key and query projection weights are tied. Therefore, the key @@ -122,7 +121,6 @@ Using LSH self attention, the memory and time complexity of the query-key matmul \\(\mathcal{O}(n_s \times n_s)\\) to \\(\mathcal{O}(n_s \times \log(n_s))\\), which usually represents the memory and time bottleneck in a transformer model, with \\(n_s\\) being the sequence length. - ### Local Self Attention Local self attention is essentially a "normal" self attention layer with key, query and value projections, but is @@ -134,7 +132,6 @@ Using Local self attention, the memory and time complexity of the query-key matm \\(\mathcal{O}(n_s \times n_s)\\) to \\(\mathcal{O}(n_s \times \log(n_s))\\), which usually represents the memory and time bottleneck in a transformer model, with \\(n_s\\) being the sequence length. - ### Training During training, we must ensure that the sequence length is set to a value that can be divided by the least common diff --git a/docs/source/en/model_doc/retribert.md b/docs/source/en/model_doc/retribert.md index 871bdc6e8c86..829fed24215f 100644 --- a/docs/source/en/model_doc/retribert.md +++ b/docs/source/en/model_doc/retribert.md @@ -39,7 +39,6 @@ pair of BERT encoders with lower-dimension projection for dense semantic indexin This model was contributed by [yjernite](https://huggingface.co/yjernite). Code to train and use the model can be found [here](https://github.com/huggingface/transformers/tree/main/examples/research-projects/distillation). - ## RetriBertConfig [[autodoc]] RetriBertConfig diff --git a/docs/source/en/model_doc/roberta.md b/docs/source/en/model_doc/roberta.md index 580ff09e72c9..896156520c5d 100644 --- a/docs/source/en/model_doc/roberta.md +++ b/docs/source/en/model_doc/roberta.md @@ -28,7 +28,6 @@ rendered properly in your Markdown viewer. You can find all the original RoBERTa checkpoints under the [Facebook AI](https://huggingface.co/FacebookAI) organization. - > [!TIP] > Click on the RoBERTa models in the right sidebar for more examples of how to apply RoBERTa to different language tasks. diff --git a/docs/source/en/model_doc/rt_detr.md b/docs/source/en/model_doc/rt_detr.md index 02accfd6d9f7..d4c85f63fc37 100644 --- a/docs/source/en/model_doc/rt_detr.md +++ b/docs/source/en/model_doc/rt_detr.md @@ -23,7 +23,6 @@ rendered properly in your Markdown viewer. ## Overview - The RT-DETR model was proposed in [DETRs Beat YOLOs on Real-time Object Detection](https://huggingface.co/papers/2304.08069) by Wenyu Lv, Yian Zhao, Shangliang Xu, Jinman Wei, Guanzhong Wang, Cheng Cui, Yuning Du, Qingqing Dang, Yi Liu. RT-DETR is an object detection model that stands for "Real-Time DEtection Transformer." This model is designed to perform object detection tasks with a focus on achieving real-time performance while maintaining high accuracy. Leveraging the transformer architecture, which has gained significant popularity in various fields of deep learning, RT-DETR processes images to identify and locate multiple objects within them. @@ -39,7 +38,6 @@ alt="drawing" width="600"/> The model version was contributed by [rafaelpadilla](https://huggingface.co/rafaelpadilla) and [sangbumchoi](https://github.com/SangbumChoi). The original code can be found [here](https://github.com/lyuwenyu/RT-DETR/). - ## Usage tips Initially, an image is processed using a pre-trained convolutional neural network, specifically a Resnet-D variant as referenced in the original code. This network extracts features from the final three layers of the architecture. Following this, a hybrid encoder is employed to convert the multi-scale features into a sequential array of image features. Then, a decoder, equipped with auxiliary prediction heads is used to refine the object queries. This process facilitates the direct generation of bounding boxes, eliminating the need for any additional post-processing to acquire the logits and coordinates for the bounding boxes. diff --git a/docs/source/en/model_doc/rt_detr_v2.md b/docs/source/en/model_doc/rt_detr_v2.md index f5eb54625c84..3f814ce0d649 100644 --- a/docs/source/en/model_doc/rt_detr_v2.md +++ b/docs/source/en/model_doc/rt_detr_v2.md @@ -34,9 +34,9 @@ The abstract from the paper is the following: This model was contributed by [jadechoghari](https://huggingface.co/jadechoghari). The original code can be found [here](https://github.com/lyuwenyu/RT-DETR). -## Usage tips +## Usage tips -This second version of RT-DETR improves how the decoder finds objects in an image. +This second version of RT-DETR improves how the decoder finds objects in an image. - **better sampling** – adjusts offsets so the model looks at the right areas - **flexible attention** – can use smooth (bilinear) or fixed (discrete) sampling @@ -85,17 +85,15 @@ A list of official Hugging Face and community (indicated by 🌎) resources to h - See also: [Object detection task guide](../tasks/object_detection). - Notebooks for [inference](https://github.com/qubvel/transformers-notebooks/blob/main/notebooks/RT_DETR_v2_inference.ipynb) and [fine-tuning](https://github.com/qubvel/transformers-notebooks/blob/main/notebooks/RT_DETR_v2_finetune_on_a_custom_dataset.ipynb) RT-DETRv2 on a custom dataset (🌎). - ## RTDetrV2Config [[autodoc]] RTDetrV2Config - ## RTDetrV2Model [[autodoc]] RTDetrV2Model - forward - + ## RTDetrV2ForObjectDetection [[autodoc]] RTDetrV2ForObjectDetection diff --git a/docs/source/en/model_doc/rwkv.md b/docs/source/en/model_doc/rwkv.md index 4d9d6bbb8860..c0bd1273f615 100644 --- a/docs/source/en/model_doc/rwkv.md +++ b/docs/source/en/model_doc/rwkv.md @@ -58,7 +58,7 @@ torch.allclose(torch.cat([output_one, output_two], dim=1), output_whole, atol=1e If you want to make sure the model stops generating when `'\n\n'` is detected, we recommend using the following stopping criteria: -```python +```python from transformers import StoppingCriteria class RwkvStoppingCriteria(StoppingCriteria): diff --git a/docs/source/en/model_doc/sam.md b/docs/source/en/model_doc/sam.md index 49a58254630a..65286eb8428d 100644 --- a/docs/source/en/model_doc/sam.md +++ b/docs/source/en/model_doc/sam.md @@ -41,7 +41,6 @@ Tips: - Fine-tuning the model is not supported yet - According to the paper, textual input should be also supported. However, at this time of writing this seems not to be supported according to [the official repository](https://github.com/facebookresearch/segment-anything/issues/4#issuecomment-1497626844). - This model was contributed by [ybelkada](https://huggingface.co/ybelkada) and [ArthurZ](https://huggingface.co/ArthurZ). The original code can be found [here](https://github.com/facebookresearch/segment-anything). @@ -98,6 +97,7 @@ masks = processor.image_processor.post_process_masks( ) scores = outputs.iou_scores ``` + ## Resources A list of official Hugging Face and community (indicated by 🌎) resources to help you get started with SAM. diff --git a/docs/source/en/model_doc/sam_hq.md b/docs/source/en/model_doc/sam_hq.md index 2bd14229c37c..9dea1de7a77e 100644 --- a/docs/source/en/model_doc/sam_hq.md +++ b/docs/source/en/model_doc/sam_hq.md @@ -25,7 +25,6 @@ The model is an enhancement to the original SAM model that produces significantl ![example image](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/model_doc/sam-output.png) - SAM-HQ introduces several key improvements over the original SAM model: 1. High-Quality Output Token: A learnable token injected into SAM's mask decoder for higher quality mask prediction @@ -105,7 +104,6 @@ masks = processor.image_processor.post_process_masks( scores = outputs.iou_scores ``` - ## Resources A list of official Hugging Face and community (indicated by 🌎) resources to help you get started with SAM-HQ: @@ -137,7 +135,6 @@ A list of official Hugging Face and community (indicated by 🌎) resources to h [[autodoc]] SamHQVisionModel - ## SamHQModel [[autodoc]] SamHQModel diff --git a/docs/source/en/model_doc/seamless_m4t.md b/docs/source/en/model_doc/seamless_m4t.md index c6f3a56f9ba1..e7fc00d047c3 100644 --- a/docs/source/en/model_doc/seamless_m4t.md +++ b/docs/source/en/model_doc/seamless_m4t.md @@ -67,7 +67,6 @@ Here is how to use the processor to process text and audio: >>> text_inputs = processor(text = "Hello, my dog is cute", src_lang="eng", return_tensors="pt") ``` - ### Speech [`SeamlessM4TModel`] can *seamlessly* generate text or speech with few or no changes. Let's target Russian voice translation: @@ -84,7 +83,7 @@ With basically the same code, I've translated English text and Arabic speech to Similarly, you can generate translated text from audio files or from text with the same model. You only have to pass `generate_speech=False` to [`SeamlessM4TModel.generate`]. This time, let's translate to French. -```python +```python >>> # from audio >>> output_tokens = model.generate(**audio_inputs, tgt_lang="fra", generate_speech=False) >>> translated_text_from_audio = processor.decode(output_tokens[0].tolist()[0], skip_special_tokens=True) @@ -96,11 +95,10 @@ This time, let's translate to French. ### Tips - #### 1. Use dedicated models [`SeamlessM4TModel`] is transformers top level model to generate speech and text, but you can also use dedicated models that perform the task without additional components, thus reducing the memory footprint. -For example, you can replace the audio-to-audio generation snippet with the model dedicated to the S2ST task, the rest is exactly the same code: +For example, you can replace the audio-to-audio generation snippet with the model dedicated to the S2ST task, the rest is exactly the same code: ```python >>> from transformers import SeamlessM4TForSpeechToSpeech @@ -130,7 +128,6 @@ Use `return_intermediate_token_ids=True` with [`SeamlessM4TModel`] to return bot ## Model architecture - SeamlessM4T features a versatile architecture that smoothly handles the sequential generation of text and speech. This setup comprises two sequence-to-sequence (seq2seq) models. The first model translates the input modality into translated text, while the second model generates speech tokens, known as "unit tokens," from the translated text. Each modality has its own dedicated encoder with a unique architecture. Additionally, for speech output, a vocoder inspired by the [HiFi-GAN](https://huggingface.co/papers/2010.05646) architecture is placed on top of the second seq2seq model. @@ -142,7 +139,6 @@ Here's how the generation process works: - If speech generation is required, the second seq2seq model, following a standard encoder-decoder structure, generates unit tokens. - These unit tokens are then passed through the final vocoder to produce the actual speech. - This model was contributed by [ylacombe](https://huggingface.co/ylacombe). The original code can be found [here](https://github.com/facebookresearch/seamless_communication). ## SeamlessM4TModel @@ -150,19 +146,16 @@ This model was contributed by [ylacombe](https://huggingface.co/ylacombe). The o [[autodoc]] SeamlessM4TModel - generate - ## SeamlessM4TForTextToSpeech [[autodoc]] SeamlessM4TForTextToSpeech - generate - ## SeamlessM4TForSpeechToSpeech [[autodoc]] SeamlessM4TForSpeechToSpeech - generate - ## SeamlessM4TForTextToText [[autodoc]] transformers.SeamlessM4TForTextToText @@ -179,7 +172,6 @@ This model was contributed by [ylacombe](https://huggingface.co/ylacombe). The o [[autodoc]] SeamlessM4TConfig - ## SeamlessM4TTokenizer [[autodoc]] SeamlessM4TTokenizer @@ -189,7 +181,6 @@ This model was contributed by [ylacombe](https://huggingface.co/ylacombe). The o - create_token_type_ids_from_sequences - save_vocabulary - ## SeamlessM4TTokenizerFast [[autodoc]] SeamlessM4TTokenizerFast @@ -209,7 +200,6 @@ This model was contributed by [ylacombe](https://huggingface.co/ylacombe). The o [[autodoc]] SeamlessM4TCodeHifiGan - ## SeamlessM4THifiGan [[autodoc]] SeamlessM4THifiGan @@ -221,5 +211,3 @@ This model was contributed by [ylacombe](https://huggingface.co/ylacombe). The o ## SeamlessM4TTextToUnitForConditionalGeneration [[autodoc]] SeamlessM4TTextToUnitForConditionalGeneration - - diff --git a/docs/source/en/model_doc/seamless_m4t_v2.md b/docs/source/en/model_doc/seamless_m4t_v2.md index 8a4ab82d2e98..716718072a4b 100644 --- a/docs/source/en/model_doc/seamless_m4t_v2.md +++ b/docs/source/en/model_doc/seamless_m4t_v2.md @@ -67,7 +67,6 @@ Here is how to use the processor to process text and audio: >>> text_inputs = processor(text = "Hello, my dog is cute", src_lang="eng", return_tensors="pt") ``` - ### Speech [`SeamlessM4Tv2Model`] can *seamlessly* generate text or speech with few or no changes. Let's target Russian voice translation: @@ -84,7 +83,7 @@ With basically the same code, I've translated English text and Arabic speech to Similarly, you can generate translated text from audio files or from text with the same model. You only have to pass `generate_speech=False` to [`SeamlessM4Tv2Model.generate`]. This time, let's translate to French. -```python +```python >>> # from audio >>> output_tokens = model.generate(**audio_inputs, tgt_lang="fra", generate_speech=False) >>> translated_text_from_audio = processor.decode(output_tokens[0].tolist()[0], skip_special_tokens=True) @@ -96,11 +95,10 @@ This time, let's translate to French. ### Tips - #### 1. Use dedicated models [`SeamlessM4Tv2Model`] is transformers top level model to generate speech and text, but you can also use dedicated models that perform the task without additional components, thus reducing the memory footprint. -For example, you can replace the audio-to-audio generation snippet with the model dedicated to the S2ST task, the rest is exactly the same code: +For example, you can replace the audio-to-audio generation snippet with the model dedicated to the S2ST task, the rest is exactly the same code: ```python >>> from transformers import SeamlessM4Tv2ForSpeechToSpeech @@ -161,7 +159,6 @@ Here's how the generation process works: - If speech generation is required, the second seq2seq model, generates unit tokens in an non auto-regressive way. - These unit tokens are then passed through the final vocoder to produce the actual speech. - This model was contributed by [ylacombe](https://huggingface.co/ylacombe). The original code can be found [here](https://github.com/facebookresearch/seamless_communication). ## SeamlessM4Tv2Model @@ -169,19 +166,16 @@ This model was contributed by [ylacombe](https://huggingface.co/ylacombe). The o [[autodoc]] SeamlessM4Tv2Model - generate - ## SeamlessM4Tv2ForTextToSpeech [[autodoc]] SeamlessM4Tv2ForTextToSpeech - generate - ## SeamlessM4Tv2ForSpeechToSpeech [[autodoc]] SeamlessM4Tv2ForSpeechToSpeech - generate - ## SeamlessM4Tv2ForTextToText [[autodoc]] transformers.SeamlessM4Tv2ForTextToText diff --git a/docs/source/en/model_doc/segformer.md b/docs/source/en/model_doc/segformer.md index 756c98d45f08..a6b407e58793 100644 --- a/docs/source/en/model_doc/segformer.md +++ b/docs/source/en/model_doc/segformer.md @@ -71,8 +71,6 @@ logits = outputs.logits # shape [batch, num_labels, height, width] - - ## Notes - SegFormer works with **any input size**, padding inputs to be divisible by `config.patch_sizes`. diff --git a/docs/source/en/model_doc/seggpt.md b/docs/source/en/model_doc/seggpt.md index 9e8c08cf2d2e..a5568d5c80ec 100644 --- a/docs/source/en/model_doc/seggpt.md +++ b/docs/source/en/model_doc/seggpt.md @@ -74,7 +74,6 @@ mask = image_processor.post_process_semantic_segmentation(outputs, target_sizes, This model was contributed by [EduardoPacheco](https://huggingface.co/EduardoPacheco). The original code can be found [here]([(https://github.com/baaivision/Painter/tree/main)). - ## SegGptConfig [[autodoc]] SegGptConfig diff --git a/docs/source/en/model_doc/shieldgemma2.md b/docs/source/en/model_doc/shieldgemma2.md index 99ffde6288ff..871cdd31db78 100644 --- a/docs/source/en/model_doc/shieldgemma2.md +++ b/docs/source/en/model_doc/shieldgemma2.md @@ -86,7 +86,6 @@ output = model(**inputs) print(output.probabilities) ``` - ## ShieldGemma2Processor [[autodoc]] ShieldGemma2Processor diff --git a/docs/source/en/model_doc/siglip.md b/docs/source/en/model_doc/siglip.md index c0eb9a8ac6b5..bf9c0a460348 100644 --- a/docs/source/en/model_doc/siglip.md +++ b/docs/source/en/model_doc/siglip.md @@ -31,7 +31,6 @@ Unlike CLIP, SigLIP employs a pairwise sigmoid loss on image-text pairs during t You can find all the original SigLIP checkpoints under the [SigLIP](https://huggingface.co/collections/google/siglip-659d5e62f0ae1a57ae0e83ba) collection. - > [!TIP] > Click on the SigLIP models in the right sidebar for more examples of how to apply SigLIP to different image and text tasks. @@ -107,12 +106,14 @@ logits_per_image = outputs.logits_per_image probs = torch.sigmoid(logits_per_image) print(f"{probs[0][0]:.1%} that image 0 is '{candidate_labels[0]}'") ``` + ## Notes - Training is supported for DDP and FSDP on single-node multi-GPU setups. However, it does not use [torch.distributed](https://pytorch.org/tutorials/beginner/dist_overview.html) utilities which may limit the scalability of batch size. - When using the standalone [`SiglipTokenizer`] or [`SiglipProcessor`], make sure to pass `padding="max_length"` because that is how the model was trained. - To get the same results as the [`Pipeline`], a prompt template of `"This is a photo of {label}."` should be passed to the processor. - Toggle the `attn_implementation` parameter to either `"sdpa"` or `"flash_attention_2"` to use a more memory-efficient attention. + ```py # pip install -U flash-attn --no-build-isolation @@ -126,7 +127,6 @@ print(f"{probs[0][0]:.1%} that image 0 is '{candidate_labels[0]}'") ) ``` - ## SiglipConfig [[autodoc]] SiglipConfig @@ -179,7 +179,6 @@ print(f"{probs[0][0]:.1%} that image 0 is '{candidate_labels[0]}'") [[autodoc]] SiglipVisionModel - forward - ## SiglipForImageClassification [[autodoc]] SiglipForImageClassification diff --git a/docs/source/en/model_doc/siglip2.md b/docs/source/en/model_doc/siglip2.md index f2684c6defcf..6a058f8907a4 100644 --- a/docs/source/en/model_doc/siglip2.md +++ b/docs/source/en/model_doc/siglip2.md @@ -32,7 +32,6 @@ rendered properly in your Markdown viewer. - NaFlex supports different resolutions and maintains the native image aspect ratio - FixRes supports fixed resolutions and is backwards compatible with [SigLIP](./siglip) - You can find all the original SigLIP2 checkpoints under the [SigLIP2](https://huggingface.co/collections/google/siglip2-67b5dcef38c175486e240107) collection. > [!TIP] @@ -157,6 +156,7 @@ print(f"{probs[0][0]:.1%} that image 0 is '{candidate_labels[0]}'") NaFlex resizes the input image so the height and width are multiples of the patch size after resizing. It keeps the aspect ratio distortion as low as possible and produces a sequence length of at most the desired target sequence length (`max_num_patches`). After resizing, the image is split into a sequence of patches and a mask with padding information is added. - Toggle the `attn_implementation` parameter to either `"sdpa"` or `"flash_attention_2"` to use a more memory-efficient attention. + ```py # pip install -U flash-attn --no-build-isolation @@ -169,6 +169,7 @@ print(f"{probs[0][0]:.1%} that image 0 is '{candidate_labels[0]}'") device_map=device, ) ``` + ## Siglip2Config [[autodoc]] Siglip2Config diff --git a/docs/source/en/model_doc/smollm3.md b/docs/source/en/model_doc/smollm3.md index da98a15e33b5..db2ddd336013 100644 --- a/docs/source/en/model_doc/smollm3.md +++ b/docs/source/en/model_doc/smollm3.md @@ -139,7 +139,6 @@ outputs = model.generate(**inputs, max_new_tokens=100) print(tokenizer.decode(outputs[0], skip_special_tokens=True)) ``` - ## Notes - Ensure your Transformers library version is up-to-date. SmolLM3 requires Transformers>=4.53.0 for full support. diff --git a/docs/source/en/model_doc/smolvlm.md b/docs/source/en/model_doc/smolvlm.md index c9a886ac8769..5f74fa60ba0c 100644 --- a/docs/source/en/model_doc/smolvlm.md +++ b/docs/source/en/model_doc/smolvlm.md @@ -39,6 +39,7 @@ If `do_resize` is set to `True`, the model resizes images so that the longest ed The default resizing behavior can be customized by passing a dictionary to the `size` parameter. For example, `{"longest_edge": 4 * 512}` is the default, but you can change it to a different value if needed. Here’s how to control resizing and set a custom size: + ```python image_processor = SmolVLMImageProcessor(do_resize=True, size={"longest_edge": 2 * 512}, max_image_size=512) ``` @@ -47,8 +48,6 @@ Additionally, the `max_image_size` parameter, which controls the size of each sq This model was contributed by [orrzohar](https://huggingface.co/orrzohar). - - ## Usage example ### Single Media inference diff --git a/docs/source/en/model_doc/stablelm.md b/docs/source/en/model_doc/stablelm.md index 29f32a0004e2..e47598a8f852 100644 --- a/docs/source/en/model_doc/stablelm.md +++ b/docs/source/en/model_doc/stablelm.md @@ -92,7 +92,6 @@ Now, to run the model with Flash Attention 2, refer to the snippet below: ['The weather is always wonderful in Costa Rica, which makes it a prime destination for retirees. That’s where the Pensionado program comes in, offering'] ``` - ## StableLmConfig [[autodoc]] StableLmConfig diff --git a/docs/source/en/model_doc/starcoder2.md b/docs/source/en/model_doc/starcoder2.md index 2d27aed399cd..b67e5dedd2cc 100644 --- a/docs/source/en/model_doc/starcoder2.md +++ b/docs/source/en/model_doc/starcoder2.md @@ -34,7 +34,7 @@ The abstract of the paper is the following: ## License The models are licensed under the [BigCode OpenRAIL-M v1 license agreement](https://huggingface.co/spaces/bigcode/bigcode-model-license-agreement). - + ## Usage tips The StarCoder2 models can be found in the [HuggingFace hub](https://huggingface.co/collections/bigcode/starcoder2-65de6da6e87db3383572be1a). You can find some examples for inference and fine-tuning in StarCoder2's [GitHub repo](https://github.com/bigcode-project/starcoder2). diff --git a/docs/source/en/model_doc/superglue.md b/docs/source/en/model_doc/superglue.md index 81bb91861de2..d25ca822e4c6 100644 --- a/docs/source/en/model_doc/superglue.md +++ b/docs/source/en/model_doc/superglue.md @@ -153,4 +153,3 @@ processed_outputs = processor.post_process_keypoint_matching(outputs, image_size [[autodoc]] SuperGlueForKeypointMatching - forward - diff --git a/docs/source/en/model_doc/superpoint.md b/docs/source/en/model_doc/superpoint.md index b86f7fd4aa77..26ffb2c8b4bd 100644 --- a/docs/source/en/model_doc/superpoint.md +++ b/docs/source/en/model_doc/superpoint.md @@ -33,8 +33,6 @@ You can find all the original SuperPoint checkpoints under the [Magic Leap Commu > > Click on the SuperPoint models in the right sidebar for more examples of how to apply SuperPoint to different computer vision tasks. - - The example below demonstrates how to detect interest points in an image with the [`AutoModel`] class. @@ -101,6 +99,7 @@ processed_outputs = processor.post_process_keypoint_detection(outputs, [image_si ``` - You can then print the keypoints on the image of your choice to visualize the result: + ```py import matplotlib.pyplot as plt plt.axis("off") diff --git a/docs/source/en/model_doc/swin.md b/docs/source/en/model_doc/swin.md index f6a994ef69bc..81142f6c4111 100644 --- a/docs/source/en/model_doc/swin.md +++ b/docs/source/en/model_doc/swin.md @@ -47,6 +47,7 @@ pipeline = pipeline( ) pipeline("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg") ``` + @@ -79,6 +80,7 @@ class_labels = model.config.id2label predicted_class_label = class_labels[predicted_class_id] print(f"The predicted class label is: {predicted_class_label}") ``` + diff --git a/docs/source/en/model_doc/swinv2.md b/docs/source/en/model_doc/swinv2.md index 507b79fc7cf1..0dc008767ac3 100644 --- a/docs/source/en/model_doc/swinv2.md +++ b/docs/source/en/model_doc/swinv2.md @@ -81,7 +81,7 @@ print(f"The predicted class label is: {predicted_class_label}") ## Notes -- Swin Transformer V2 can pad the inputs for any input height and width divisible by `32`. +- Swin Transformer V2 can pad the inputs for any input height and width divisible by `32`. - Swin Transformer V2 can be used as a [backbone](../backbones). When `output_hidden_states = True`, it outputs both `hidden_states` and `reshaped_hidden_states`. The `reshaped_hidden_states` have a shape of `(batch, num_channels, height, width)` rather than `(batch_size, sequence_length, num_channels)`. ## Swinv2Config diff --git a/docs/source/en/model_doc/switch_transformers.md b/docs/source/en/model_doc/switch_transformers.md index efa6bd499dbc..5eb27a9e7d8c 100644 --- a/docs/source/en/model_doc/switch_transformers.md +++ b/docs/source/en/model_doc/switch_transformers.md @@ -27,7 +27,6 @@ rendered properly in your Markdown viewer. You can find all the original Switch Transformers checkpoints under the [Switch Transformer](https://huggingface.co/collections/google/switch-transformers-release-6548c35c6507968374b56d1f) collection. - > [!TIP] > This model was contributed by [ybelkada](https://huggingface.co/ybelkada) and [ArthurZ](https://huggingface.co/ArthurZ). > @@ -99,7 +98,6 @@ outputs = model.generate(input_ids) print(tokenizer.decode(outputs[0])) ``` - ## SwitchTransformersConfig [[autodoc]] SwitchTransformersConfig diff --git a/docs/source/en/model_doc/t5gemma.md b/docs/source/en/model_doc/t5gemma.md index aa8d3b7880ed..00dde7ab93af 100644 --- a/docs/source/en/model_doc/t5gemma.md +++ b/docs/source/en/model_doc/t5gemma.md @@ -39,7 +39,6 @@ The example below demonstrates how to chat with the model with [`Pipeline`] or t - ```python import torch from transformers import pipeline @@ -89,6 +88,7 @@ print(tokenizer.decode(outputs[0])) ``` echo -e "Write me a poem about Machine Learning. Answer:" | transformers run --task text2text-generation --model google/t5gemma-2b-2b-prefixlm --device 0 ``` + diff --git a/docs/source/en/model_doc/t5v1.1.md b/docs/source/en/model_doc/t5v1.1.md index 4ad072addcc0..62787d5f9d62 100644 --- a/docs/source/en/model_doc/t5v1.1.md +++ b/docs/source/en/model_doc/t5v1.1.md @@ -68,7 +68,6 @@ Google has released the following variants: - [google/t5-v1_1-xxl](https://huggingface.co/google/t5-v1_1-xxl). - Refer to [T5's documentation page](t5) for all API reference, tips, code examples and notebooks. diff --git a/docs/source/en/model_doc/table-transformer.md b/docs/source/en/model_doc/table-transformer.md index b35df2aec311..c982d3059072 100644 --- a/docs/source/en/model_doc/table-transformer.md +++ b/docs/source/en/model_doc/table-transformer.md @@ -43,8 +43,8 @@ alt="drawing" width="600"/> Table detection and table structure recognition clarified. Taken from the original paper. -The authors released 2 models, one for [table detection](https://huggingface.co/microsoft/table-transformer-detection) in -documents, one for [table structure recognition](https://huggingface.co/microsoft/table-transformer-structure-recognition) +The authors released 2 models, one for [table detection](https://huggingface.co/microsoft/table-transformer-detection) in +documents, one for [table structure recognition](https://huggingface.co/microsoft/table-transformer-structure-recognition) (the task of recognizing the individual rows, columns etc. in a table). This model was contributed by [nielsr](https://huggingface.co/nielsr). The original code can be diff --git a/docs/source/en/model_doc/tapas.md b/docs/source/en/model_doc/tapas.md index 4dfac5edce37..c5144121df6c 100644 --- a/docs/source/en/model_doc/tapas.md +++ b/docs/source/en/model_doc/tapas.md @@ -76,7 +76,6 @@ To summarize: | Weak supervision for aggregation | WTQ | Questions might involve aggregation, and the model must learn this given only the answer as supervision | | Strong supervision for aggregation | WikiSQL-supervised | Questions might involve aggregation, and the model must learn this given the gold aggregation operator | - Initializing a model with a pre-trained base and randomly initialized classification heads from the hub can be done as shown below. ```py @@ -105,7 +104,6 @@ Of course, you don't necessarily have to follow one of these three ways in which >>> model = TapasForQuestionAnswering.from_pretrained("google/tapas-base", config=config) ``` - What you can also do is start from an already fine-tuned checkpoint. A note here is that the already fine-tuned checkpoint on WTQ has some issues due to the L2-loss which is somewhat brittle. See [here](https://github.com/google-research/tapas/issues/91#issuecomment-735719340) for more info. For a list of all pre-trained and fine-tuned TAPAS checkpoints available on HuggingFace's hub, see [here](https://huggingface.co/models?search=tapas). @@ -128,7 +126,6 @@ The tables themselves should be present in a folder, each table being a separate **STEP 3: Convert your data into tensors using TapasTokenizer** - Third, given that you've prepared your data in this TSV/CSV format (and corresponding CSV files containing the tabular data), you can then use [`TapasTokenizer`] to convert table-question pairs into `input_ids`, `attention_mask`, `token_type_ids` and so on. Again, based on which of the three cases you picked above, [`TapasForQuestionAnswering`] requires different inputs to be fine-tuned: @@ -214,13 +211,11 @@ Of course, this only shows how to encode a single training example. It is advise >>> train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=32) ``` - Note that here, we encode each table-question pair independently. This is fine as long as your dataset is **not conversational**. In case your dataset involves conversational questions (such as in SQA), then you should first group together the `queries`, `answer_coordinates` and `answer_text` per table (in the order of their `position` index) and batch encode each table with its questions. This will make sure that the `prev_labels` token types (see docs of [`TapasTokenizer`]) are set correctly. See [this notebook](https://github.com/NielsRogge/Transformers-Tutorials/blob/master/TAPAS/Fine_tuning_TapasForQuestionAnswering_on_SQA.ipynb) for more info. **STEP 4: Train (fine-tune) the model - You can then fine-tune [`TapasForQuestionAnswering`] as follows (shown here for the weak supervision for aggregation case): ```py @@ -272,10 +267,8 @@ You can then fine-tune [`TapasForQuestionAnswering`] as follows (shown here for ... optimizer.step() ``` - ## Usage: inference - Here we explain how you can use [`TapasForQuestionAnswering`] for inference (i.e. making predictions on new data). For inference, only `input_ids`, `attention_mask` and `token_type_ids` (which you can obtain using [`TapasTokenizer`]) have to be provided to the model to obtain the logits. Next, you can use the handy [`~models.tapas.tokenization_tapas.convert_logits_to_predictions`] method to convert these into predicted coordinates and optional aggregation indices. However, note that inference is **different** depending on whether or not the setup is conversational. In a non-conversational set-up, inference can be done in parallel on all table-question pairs of a batch. Here's an example of that: @@ -333,7 +326,6 @@ What is the total number of movies? Predicted answer: SUM > 87, 53, 69 ``` - In case of a conversational set-up, then each table-question pair must be provided **sequentially** to the model, such that the `prev_labels` token types can be overwritten by the predicted `labels` of the previous table-question pair. Again, more info can be found in [this notebook](https://github.com/NielsRogge/Transformers-Tutorials/blob/master/TAPAS/Fine_tuning_TapasForQuestionAnswering_on_SQA.ipynb). ## Resources diff --git a/docs/source/en/model_doc/textnet.md b/docs/source/en/model_doc/textnet.md index 9c29a8b16bee..c986b17dbff0 100644 --- a/docs/source/en/model_doc/textnet.md +++ b/docs/source/en/model_doc/textnet.md @@ -34,7 +34,7 @@ This model was contributed by [Raghavan](https://huggingface.co/Raghavan), [jade ## Usage tips -TextNet is mainly used as a backbone network for the architecture search of text detection. Each stage of the backbone network is comprised of a stride-2 convolution and searchable blocks. +TextNet is mainly used as a backbone network for the architecture search of text detection. Each stage of the backbone network is comprised of a stride-2 convolution and searchable blocks. Specifically, we present a layer-level candidate set, defined as {conv3×3, conv1×3, conv3×1, identity}. As the 1×3 and 3×1 convolutions have asymmetric kernels and oriented structure priors, they may help to capture the features of extreme aspect-ratio and rotated text lines. TextNet is the backbone for Fast, but can also be used as an efficient text/image classification, we add a `TextNetForImageClassification` as is it would allow people to train an image classifier on top of the pre-trained textnet weights @@ -62,4 +62,3 @@ TextNet is the backbone for Fast, but can also be used as an efficient text/imag [[autodoc]] TextNetForImageClassification - forward - diff --git a/docs/source/en/model_doc/time_series_transformer.md b/docs/source/en/model_doc/time_series_transformer.md index c38671f00fb3..921b7e01d4b6 100644 --- a/docs/source/en/model_doc/time_series_transformer.md +++ b/docs/source/en/model_doc/time_series_transformer.md @@ -61,7 +61,6 @@ A list of official Hugging Face and community (indicated by 🌎) resources to h - Check out the Time Series Transformer blog-post in HuggingFace blog: [Probabilistic Time Series Forecasting with 🤗 Transformers](https://huggingface.co/blog/time-series-transformers) - ## TimeSeriesTransformerConfig [[autodoc]] TimeSeriesTransformerConfig diff --git a/docs/source/en/model_doc/timesfm.md b/docs/source/en/model_doc/timesfm.md index 83dee48e71be..e8938202ee9e 100644 --- a/docs/source/en/model_doc/timesfm.md +++ b/docs/source/en/model_doc/timesfm.md @@ -25,16 +25,13 @@ rendered properly in your Markdown viewer. TimesFM (Time Series Foundation Model) is a pretrained time-series foundation model proposed in [A decoder-only foundation model for time-series forecasting](https://huggingface.co/papers/2310.10688) by Abhimanyu Das, Weihao Kong, Rajat Sen, and Yichen Zhou. It is a decoder only model that uses non-overlapping patches of time-series data as input and outputs some output patch length prediction in an autoregressive fashion. - The abstract from the paper is the following: *Motivated by recent advances in large language models for Natural Language Processing (NLP), we design a time-series foundation model for forecasting whose out-of-the-box zero-shot performance on a variety of public datasets comes close to the accuracy of state-of-the-art supervised forecasting models for each individual dataset. Our model is based on pretraining a patched-decoder style attention model on a large time-series corpus, and can work well across different forecasting history lengths, prediction lengths and temporal granularities.* - This model was contributed by [kashif](https://huggingface.co/kashif). The original code can be found [here](https://github.com/google-research/timesfm). - To use the model: ```python diff --git a/docs/source/en/model_doc/transfo-xl.md b/docs/source/en/model_doc/transfo-xl.md index 5d9b92f7946f..0bd1b0f57e1d 100644 --- a/docs/source/en/model_doc/transfo-xl.md +++ b/docs/source/en/model_doc/transfo-xl.md @@ -90,7 +90,6 @@ This model was contributed by [thomwolf](https://huggingface.co/thomwolf). The o - Basically, the hidden states of the previous segment are concatenated to the current input to compute the attention scores. This allows the model to pay attention to information that was in the previous segment as well as the current one. By stacking multiple attention layers, the receptive field can be increased to multiple previous segments. - This changes the positional embeddings to positional relative embeddings (as the regular positional embeddings would give the same results in the current input and the current hidden state at a given position) and needs to make some adjustments in the way attention scores are computed. - TransformerXL does **not** work with *torch.nn.DataParallel* due to a bug in PyTorch, see [issue #36035](https://github.com/pytorch/pytorch/issues/36035) diff --git a/docs/source/en/model_doc/trocr.md b/docs/source/en/model_doc/trocr.md index 6346977dafa1..da5c71edde36 100644 --- a/docs/source/en/model_doc/trocr.md +++ b/docs/source/en/model_doc/trocr.md @@ -14,8 +14,6 @@ rendered properly in your Markdown viewer. specific language governing permissions and limitations under the License. --> *This model was released on 2021-09-21 and added to Hugging Face Transformers on 2021-10-13.* - -
PyTorch @@ -32,13 +30,11 @@ You can find all the original TrOCR checkpoints under the [Microsoft](https://hu alt="drawing" width="600"/> TrOCR architecture. Taken from the original paper. - > [!TIP] > This model was contributed by [nielsr](https://huggingface.co/nielsr). > > Click on the TrOCR models in the right sidebar for more examples of how to apply TrOCR to different image and text tasks. - The example below demonstrates how to perform optical character recognition (OCR) with the [`AutoModel`] class. @@ -113,7 +109,6 @@ print(generated_text) - A notebook on [inference with TrOCR](https://colab.research.google.com/github/NielsRogge/Transformers-Tutorials/blob/master/TrOCR/Inference_with_TrOCR_%2B_Gradio_demo.ipynb) and Gradio demo. - A notebook on [evaluating TrOCR on the IAM test set](https://colab.research.google.com/github/NielsRogge/Transformers-Tutorials/blob/master/TrOCR/Evaluating_TrOCR_base_handwritten_on_the_IAM_test_set.ipynb). - ## TrOCRConfig [[autodoc]] TrOCRConfig diff --git a/docs/source/en/model_doc/tvp.md b/docs/source/en/model_doc/tvp.md index 49a538ffa8c4..2df4da02555a 100644 --- a/docs/source/en/model_doc/tvp.md +++ b/docs/source/en/model_doc/tvp.md @@ -47,6 +47,7 @@ The [`TvpProcessor`] wraps [`BertTokenizer`] and [`TvpImageProcessor`] into a si encode the text and prepare the images respectively. The following example shows how to run temporal video grounding using [`TvpProcessor`] and [`TvpForVideoGrounding`]. + ```python import av import cv2 @@ -165,7 +166,6 @@ Tips: - Checkpoints for pre-trained [tvp-base](https://huggingface.co/Intel/tvp-base) is released. - Please refer to [Table 2](https://huggingface.co/papers/2303.04995) for TVP's performance on Temporal Video Grounding task. - ## TvpConfig [[autodoc]] TvpConfig diff --git a/docs/source/en/model_doc/umt5.md b/docs/source/en/model_doc/umt5.md index 349dcecf03cc..784cc9974df1 100644 --- a/docs/source/en/model_doc/umt5.md +++ b/docs/source/en/model_doc/umt5.md @@ -39,7 +39,7 @@ Google has released the following variants: This model was contributed by [agemagician](https://huggingface.co/agemagician) and [stefan-it](https://huggingface.co/stefan-it). The original code can be found [here](https://github.com/google-research/t5x). -## Usage tips +## Usage tips - UMT5 was only pre-trained on [mC4](https://huggingface.co/datasets/mc4) excluding any supervised training. Therefore, this model has to be fine-tuned before it is usable on a downstream task, unlike the original T5 model. @@ -67,7 +67,7 @@ The conversion script is also different because the model was saved in t5x's lat ['nyone who drink a alcohol A A. This I'] ``` - + Refer to [T5's documentation page](t5) for more tips, code examples and notebooks. @@ -105,4 +105,3 @@ Refer to [T5's documentation page](t5) for more tips, code examples and notebook [[autodoc]] UMT5ForQuestionAnswering - forward - diff --git a/docs/source/en/model_doc/univnet.md b/docs/source/en/model_doc/univnet.md index e20bc5c405e8..7a5806928335 100644 --- a/docs/source/en/model_doc/univnet.md +++ b/docs/source/en/model_doc/univnet.md @@ -69,7 +69,6 @@ write("sample_audio.wav", feature_extractor.sampling_rate, audio) This model was contributed by [dg845](https://huggingface.co/dg845). To the best of my knowledge, there is no official code release, but an unofficial implementation can be found at [maum-ai/univnet](https://github.com/maum-ai/univnet) with pretrained checkpoints [here](https://github.com/maum-ai/univnet#pre-trained-model). - ## UnivNetConfig [[autodoc]] UnivNetConfig diff --git a/docs/source/en/model_doc/van.md b/docs/source/en/model_doc/van.md index 0e07e314bee9..0a4ded430211 100644 --- a/docs/source/en/model_doc/van.md +++ b/docs/source/en/model_doc/van.md @@ -74,4 +74,3 @@ If you're interested in submitting a resource to be included here, please feel f [[autodoc]] VanForImageClassification - forward - diff --git a/docs/source/en/model_doc/vaultgemma.md b/docs/source/en/model_doc/vaultgemma.md index 94d28cc8afe2..9d39a5eb7ee3 100644 --- a/docs/source/en/model_doc/vaultgemma.md +++ b/docs/source/en/model_doc/vaultgemma.md @@ -12,7 +12,6 @@ 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. - ⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be rendered properly in your Markdown viewer. --> @@ -45,7 +44,6 @@ command line. - ```python from transformers import pipeline diff --git a/docs/source/en/model_doc/video_llava.md b/docs/source/en/model_doc/video_llava.md index 6b09367f37c8..5b792b33733f 100644 --- a/docs/source/en/model_doc/video_llava.md +++ b/docs/source/en/model_doc/video_llava.md @@ -27,7 +27,6 @@ rendered properly in your Markdown viewer. Video-LLaVa is an open-source multimodal LLM trained by fine-tuning LlamA/Vicuna on multimodal instruction-following data generated by Llava1.5 and VideChat. It is an auto-regressive language model, based on the transformer architecture. Video-LLaVa unifies visual representations to the language feature space, and enables an LLM to perform visual reasoning capabilities on both images and videos simultaneously. - The Video-LLaVA model was proposed in [Video-LLaVA: Learning United Visual Representation by Alignment Before Projection](https://huggingface.co/papers/2311.10122) by Bin Lin, Yang Ye, Bin Zhu, Jiaxi Cui, Munang Ning, Peng Jin, Li Yuan. The abstract from the paper is the following: @@ -55,18 +54,16 @@ for the LLM* - Note the model has not been explicitly trained to process multiple images/videos in the same prompt, although this is technically possible, you may experience inaccurate results. -- Note that the video inputs should have exactly 8 frames at the input, since the models were trained in that setting. +- Note that the video inputs should have exactly 8 frames at the input, since the models were trained in that setting. This model was contributed by [RaushanTurganbay](https://huggingface.co/RaushanTurganbay). The original code can be found [here](https://github.com/PKU-YuanGroup/Video-LLaVA). - > [!NOTE] > LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. Adding these attributes means that LLaVA will try to infer the number of image tokens required per image and expand the text with as many `` placeholders as there will be tokens. Usually it is around 500 tokens per image, so make sure that the text is not truncated as otherwise there will be failure when merging the embeddings. The attributes can be obtained from model config, as `model.config.vision_config.patch_size` or `model.config.vision_feature_select_strategy`. The `num_additional_image_tokens` should be `1` if the vision backbone adds a CLS token or `0` if nothing extra is added to the vision patches. - ## Usage example ### Single Media Mode @@ -126,7 +123,7 @@ For multiple turns conversation change the prompt format to: ### Mixed Media Mode -The model can also generate from an interleaved image-video inputs. However note, that it was not trained in interleaved image-video setting which might affect the performance. Below is an example usage for mixed media input, add the following lines to the above code snippet: +The model can also generate from an interleaved image-video inputs. However note, that it was not trained in interleaved image-video setting which might affect the performance. Below is an example usage for mixed media input, add the following lines to the above code snippet: ```python from PIL import Image @@ -150,7 +147,7 @@ processor.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokeniza ### Quantization using Bitsandbytes for memory efficiency -The model can be loaded in lower bits, significantly reducing memory burden while maintaining the performance of the original model. his allows for efficient deployment on resource-constrained cases. +The model can be loaded in lower bits, significantly reducing memory burden while maintaining the performance of the original model. his allows for efficient deployment on resource-constrained cases. First make sure to install bitsandbytes by running `pip install bitsandbytes` and to have access to a GPU/accelerator that is supported by the library. @@ -164,7 +161,6 @@ We value your feedback to help identify bugs before the full release! Check out Load the quantized model by simply adding [`BitsAndBytesConfig`](../main_classes/quantization#transformers.BitsAndBytesConfig) as shown below: - ```python from transformers import VideoLlavaForConditionalGeneration, BitsAndBytesConfig @@ -178,7 +174,6 @@ quantization_config = BitsAndBytesConfig( model = VideoLlavaForConditionalGeneration.from_pretrained("LanguageBind/Video-LLaVA-7B-hf", quantization_config=quantization_config, device_map="auto") ``` - ### Flash-Attention 2 to speed-up generation Additionally, we can greatly speed-up model inference by using [Flash Attention](../perf_train_gpu_one#flash-attention-2), which is a faster implementation of the attention mechanism used inside the model. @@ -203,7 +198,6 @@ model = VideoLlavaForConditionalGeneration.from_pretrained( ).to(0) ``` - ## VideoLlavaConfig [[autodoc]] VideoLlavaConfig @@ -212,7 +206,6 @@ model = VideoLlavaForConditionalGeneration.from_pretrained( [[autodoc]] VideoLlavaImageProcessor - ## VideoLlavaVideoProcessor [[autodoc]] VideoLlavaVideoProcessor diff --git a/docs/source/en/model_doc/videomae.md b/docs/source/en/model_doc/videomae.md index e0ebbaa42885..44fc8b8b5beb 100644 --- a/docs/source/en/model_doc/videomae.md +++ b/docs/source/en/model_doc/videomae.md @@ -42,13 +42,13 @@ The original code can be found [here](https://github.com/MCG-NJU/VideoMAE). ## Using Scaled Dot Product Attention (SDPA) -PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function -encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the -[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) +PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function +encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the +[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) or the [GPU Inference](https://huggingface.co/docs/transformers/main/en/perf_infer_gpu_one#pytorch-scaled-dot-product-attention) page for more information. -SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set +SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set `attn_implementation="sdpa"` in `from_pretrained()` to explicitly request SDPA to be used. ``` diff --git a/docs/source/en/model_doc/vipllava.md b/docs/source/en/model_doc/vipllava.md index 0d0a209c27a6..fc4aec6ae9b1 100644 --- a/docs/source/en/model_doc/vipllava.md +++ b/docs/source/en/model_doc/vipllava.md @@ -37,7 +37,6 @@ The original code can be found [here](https://github.com/mu-cai/ViP-LLaVA). This model was contributed by [Younes Belkada](https://huggingface.co/ybelkada) - ## Usage tips: - The architecture is similar than llava architecture except that the multi-modal projector takes a set of concatenated vision hidden states and has an additional layernorm layer on that module. @@ -51,7 +50,6 @@ This model was contributed by [Younes Belkada](https://huggingface.co/ybelkada) Adding these attributes means that LLaVA will try to infer the number of image tokens required per image and expand the text with as many `` placeholders as there will be tokens. Usually it is around 500 tokens per image, so make sure that the text is not truncated as otherwise there will be failure when merging the embeddings. The attributes can be obtained from model config, as `model.config.vision_config.patch_size` or `model.config.vision_feature_select_strategy`. The `num_additional_image_tokens` should be `1` if the vision backbone adds a CLS token or `0` if nothing extra is added to the vision patches. - - For better results, we recommend users to use the processor's `apply_chat_template()` method to format your prompt correctly. For that you need to construct a conversation history, passing in a plain string will not format your prompt. Each message in the conversation history for chat templates is a dictionary with keys "role" and "content". The "content" should be a list of dictionaries, for "text" and "image" modalities, as follows: ```python @@ -88,16 +86,17 @@ print(text_prompt) ``` - If you want to construct a chat prompt yourself, below is a list of prompt formats accepted by VipLLaVa checkpoints: + ```bash A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions.###Human: \n###Assistant: ``` For multiple turns conversation: + ```bash A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions.###Human: \n###Assistant: ###Human: ###Assistant: ``` - ## VipLlavaConfig [[autodoc]] VipLlavaConfig diff --git a/docs/source/en/model_doc/visual_bert.md b/docs/source/en/model_doc/visual_bert.md index 7a7ac24e4dbf..a9912144c4f9 100644 --- a/docs/source/en/model_doc/visual_bert.md +++ b/docs/source/en/model_doc/visual_bert.md @@ -27,7 +27,6 @@ rendered properly in your Markdown viewer. You can find all the original VisualBERT checkpoints under the [UCLA NLP](https://huggingface.co/uclanlp/models?search=visualbert) organization. - > [!TIP] > This model was contributed by [gchhablani](https://huggingface.co/gchhablani). > Click on the VisualBERT models in the right sidebar for more examples of how to apply VisualBERT to different image and language tasks. diff --git a/docs/source/en/model_doc/vit_hybrid.md b/docs/source/en/model_doc/vit_hybrid.md index 86c2c7229f58..15fa6fad4749 100644 --- a/docs/source/en/model_doc/vit_hybrid.md +++ b/docs/source/en/model_doc/vit_hybrid.md @@ -55,13 +55,13 @@ found [here](https://github.com/google-research/vision_transformer). ## Using Scaled Dot Product Attention (SDPA) -PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function -encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the -[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) +PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function +encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the +[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) or the [GPU Inference](https://huggingface.co/docs/transformers/main/en/perf_infer_gpu_one#pytorch-scaled-dot-product-attention) page for more information. -SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set +SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set `attn_implementation="sdpa"` in `from_pretrained()` to explicitly request SDPA to be used. ``` diff --git a/docs/source/en/model_doc/vit_mae.md b/docs/source/en/model_doc/vit_mae.md index b8b9867e8812..1099019a842e 100644 --- a/docs/source/en/model_doc/vit_mae.md +++ b/docs/source/en/model_doc/vit_mae.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2021-11-11 and added to Hugging Face Transformers on 2022-01-18.* -
PyTorch diff --git a/docs/source/en/model_doc/vit_msn.md b/docs/source/en/model_doc/vit_msn.md index 5b727f34256c..6d10dd59a994 100644 --- a/docs/source/en/model_doc/vit_msn.md +++ b/docs/source/en/model_doc/vit_msn.md @@ -40,11 +40,11 @@ while producing representations of a high semantic level that perform competitiv on ImageNet-1K, with only 5,000 annotated images, our base MSN model achieves 72.4% top-1 accuracy, and with 1% of ImageNet-1K labels, we achieve 75.7% top-1 accuracy, setting a new state-of-the-art for self-supervised learning on this benchmark.* -drawing +drawing MSN architecture. Taken from the original paper. -This model was contributed by [sayakpaul](https://huggingface.co/sayakpaul). The original code can be found [here](https://github.com/facebookresearch/msn). +This model was contributed by [sayakpaul](https://huggingface.co/sayakpaul). The original code can be found [here](https://github.com/facebookresearch/msn). ## Usage tips @@ -58,13 +58,13 @@ labels when fine-tuned. ### Using Scaled Dot Product Attention (SDPA) -PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function -encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the -[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) +PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function +encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the +[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) or the [GPU Inference](https://huggingface.co/docs/transformers/main/en/perf_infer_gpu_one#pytorch-scaled-dot-product-attention) page for more information. -SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set +SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set `attn_implementation="sdpa"` in `from_pretrained()` to explicitly request SDPA to be used. ``` diff --git a/docs/source/en/model_doc/vits.md b/docs/source/en/model_doc/vits.md index 2c1777b77f18..664edcb92ae8 100644 --- a/docs/source/en/model_doc/vits.md +++ b/docs/source/en/model_doc/vits.md @@ -156,4 +156,3 @@ Audio(waveform, rate=model.config.sampling_rate) [[autodoc]] VitsModel - forward - diff --git a/docs/source/en/model_doc/vivit.md b/docs/source/en/model_doc/vivit.md index 041f80f61ae6..9ee5a10a19f1 100644 --- a/docs/source/en/model_doc/vivit.md +++ b/docs/source/en/model_doc/vivit.md @@ -32,13 +32,13 @@ This model was contributed by [jegormeister](https://huggingface.co/jegormeister ### Using Scaled Dot Product Attention (SDPA) -PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function -encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the -[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) +PyTorch includes a native scaled dot-product attention (SDPA) operator as part of `torch.nn.functional`. This function +encompasses several implementations that can be applied depending on the inputs and the hardware in use. See the +[official documentation](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) or the [GPU Inference](https://huggingface.co/docs/transformers/main/en/perf_infer_gpu_one#pytorch-scaled-dot-product-attention) page for more information. -SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set +SDPA is used by default for `torch>=2.1.1` when an implementation is available, but you may also set `attn_implementation="sdpa"` in `from_pretrained()` to explicitly request SDPA to be used. ``` @@ -56,8 +56,6 @@ On a local benchmark (A100-40GB, PyTorch 2.3.0, OS Ubuntu 22.04) with `float32` |---------------------:|-------------:|----------:|--------------:|----------------------:|---------------------:|-----------------:| | 100 | 1 | True | 7.122 | 2575.28 | 5932.54 | 130.364 | - - ### Inference | num_batches | batch_size | is cuda | is half | Speedup (%) | Mem eager (MB) | Mem BT (MB) | Mem saved (%) | |---------------|--------------|-----------|-----------|---------------|------------------|---------------|-----------------| @@ -65,7 +63,6 @@ On a local benchmark (A100-40GB, PyTorch 2.3.0, OS Ubuntu 22.04) with `float32` | 20 | 2 | True | False | 17.146 | 1234.75 | 447.175 | 176.122 | | 20 | 4 | True | False | 18.093 | 2275.82 | 709.864 | 220.6 | | 20 | 8 | True | False | 19.284 | 4358.19 | 1233.24 | 253.393 | - ## VivitConfig diff --git a/docs/source/en/model_doc/vjepa2.md b/docs/source/en/model_doc/vjepa2.md index 93960f051893..049c7ff98f21 100644 --- a/docs/source/en/model_doc/vjepa2.md +++ b/docs/source/en/model_doc/vjepa2.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2025-06-11 and added to Hugging Face Transformers on 2025-06-11.* -
PyTorch @@ -34,7 +33,6 @@ rendered properly in your Markdown viewer. You can find all original V-JEPA2 checkpoints under the [V-JEPA 2](https://huggingface.co/collections/facebook/v-jepa-2-6841bad8413014e185b497a6) collection. - This model was contributed by [koustuvs](https://huggingface.co/koustuvs), [yonigozlan](https://huggingface.co/yonigozlan) and [qubvel](https://huggingface.co/qubvel-hf). The original code can be found [here](https://github.com/facebookresearch/vjepa2). ## Usage example diff --git a/docs/source/en/model_doc/voxtral.md b/docs/source/en/model_doc/voxtral.md index 71f0661c8276..56fc84d30d0d 100644 --- a/docs/source/en/model_doc/voxtral.md +++ b/docs/source/en/model_doc/voxtral.md @@ -43,6 +43,7 @@ Voxtral builds on Ministral-3B by adding audio processing capabilities: The model supports audio-text instructions, including multi-turn and multi-audio interactions, all processed in batches. ➡️ audio + text instruction + ```python import torch from transformers import VoxtralForConditionalGeneration, AutoProcessor, infer_device @@ -78,7 +79,8 @@ print(decoded_outputs[0]) print("=" * 80) ``` -➡️ multi-audio + text instruction +➡️ multi-audio + text instruction + ```python import torch from transformers import VoxtralForConditionalGeneration, AutoProcessor, infer_device @@ -119,6 +121,7 @@ print("=" * 80) ``` ➡️ multi-turn: + ```python import torch from transformers import VoxtralForConditionalGeneration, AutoProcessor, infer_device @@ -173,6 +176,7 @@ print("=" * 80) ``` ➡️ text only: + ```python import torch from transformers import VoxtralForConditionalGeneration, AutoProcessor, infer_device @@ -208,6 +212,7 @@ print("=" * 80) ``` ➡️ audio only: + ```python import torch from transformers import VoxtralForConditionalGeneration, AutoProcessor, infer_device @@ -243,6 +248,7 @@ print("=" * 80) ``` ➡️ batched inference! + ```python import torch from transformers import VoxtralForConditionalGeneration, AutoProcessor, infer_device() diff --git a/docs/source/en/model_doc/wav2vec2-bert.md b/docs/source/en/model_doc/wav2vec2-bert.md index 4edb67498aaa..4a2c8de89c3c 100644 --- a/docs/source/en/model_doc/wav2vec2-bert.md +++ b/docs/source/en/model_doc/wav2vec2-bert.md @@ -54,7 +54,6 @@ This model was contributed by [ylacombe](https://huggingface.co/ylacombe). The o - [`Wav2Vec2BertForSequenceClassification`] can be used by adapting this [example script](https://github.com/huggingface/transformers/tree/main/examples/pytorch/audio-classification). - See also: [Audio classification task guide](../tasks/audio_classification) - ## Wav2Vec2BertConfig [[autodoc]] Wav2Vec2BertConfig diff --git a/docs/source/en/model_doc/wav2vec2-conformer.md b/docs/source/en/model_doc/wav2vec2-conformer.md index e2a56b450df3..663b6163011b 100644 --- a/docs/source/en/model_doc/wav2vec2-conformer.md +++ b/docs/source/en/model_doc/wav2vec2-conformer.md @@ -38,7 +38,7 @@ Note: Meta (FAIR) released a new version of [Wav2Vec2-BERT 2.0](https://huggingf - Wav2Vec2-Conformer follows the same architecture as Wav2Vec2, but replaces the *Attention*-block with a *Conformer*-block as introduced in [Conformer: Convolution-augmented Transformer for Speech Recognition](https://huggingface.co/papers/2005.08100). -- For the same number of layers, Wav2Vec2-Conformer requires more parameters than Wav2Vec2, but also yields +- For the same number of layers, Wav2Vec2-Conformer requires more parameters than Wav2Vec2, but also yields an improved word error rate. - Wav2Vec2-Conformer uses the same tokenizer and feature extractor as Wav2Vec2. - Wav2Vec2-Conformer can use either no relative position embeddings, Transformer-XL-like position embeddings, or diff --git a/docs/source/en/model_doc/wav2vec2.md b/docs/source/en/model_doc/wav2vec2.md index 6c4772f90bc8..1f5f4a905767 100644 --- a/docs/source/en/model_doc/wav2vec2.md +++ b/docs/source/en/model_doc/wav2vec2.md @@ -80,13 +80,10 @@ model = Wav2Vec2Model.from_pretrained("facebook/wav2vec2-large-960h-lv60-self", Below is an expected speedup diagram comparing the pure inference time between the native implementation in transformers of the `facebook/wav2vec2-large-960h-lv60-self` model and the flash-attention-2 and sdpa (scale-dot-product-attention) versions. . We show the average speedup obtained on the `librispeech_asr` `clean` validation split: -
- - ## Resources A list of official Hugging Face and community (indicated by 🌎) resources to help you get started with Wav2Vec2. If you're interested in submitting a resource to be included here, please feel free to open a Pull Request and we'll review it! The resource should ideally demonstrate something new instead of duplicating an existing resource. diff --git a/docs/source/en/model_doc/wav2vec2_phoneme.md b/docs/source/en/model_doc/wav2vec2_phoneme.md index fe989def3bdd..c2621f8924c3 100644 --- a/docs/source/en/model_doc/wav2vec2_phoneme.md +++ b/docs/source/en/model_doc/wav2vec2_phoneme.md @@ -53,7 +53,6 @@ The original code can be found [here](https://github.com/pytorch/fairseq/tree/ma - By default, the model outputs a sequence of phonemes. In order to transform the phonemes to a sequence of words one should make use of a dictionary and language model. - Wav2Vec2Phoneme's architecture is based on the Wav2Vec2 model, for API reference, check out [`Wav2Vec2`](wav2vec2)'s documentation page diff --git a/docs/source/en/model_doc/whisper.md b/docs/source/en/model_doc/whisper.md index 673085ac3e7d..5e19e870bddc 100644 --- a/docs/source/en/model_doc/whisper.md +++ b/docs/source/en/model_doc/whisper.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2022-12-06 and added to Hugging Face Transformers on 2022-10-05.* -
PyTorch diff --git a/docs/source/en/model_doc/xcodec.md b/docs/source/en/model_doc/xcodec.md index c4a0b92a26f6..ca6d6e473fc1 100644 --- a/docs/source/en/model_doc/xcodec.md +++ b/docs/source/en/model_doc/xcodec.md @@ -33,7 +33,7 @@ The X-Codec model is a neural audio codec that integrates semantic information f The abstract of the paper states the following: -*Recent advancements in audio generation have been significantly propelled by the capabilities of Large Language Models (LLMs). The existing research on audio LLM has primarily focused on enhancing the architecture and scale of audio language models, as well as leveraging larger datasets, and generally, acoustic codecs, such as EnCodec, are used for audio tokenization. However, these codecs were originally designed for audio compression, which may lead to suboptimal performance in the context of audio LLM. Our research aims to address the shortcomings of current audio LLM codecs, particularly their challenges in maintaining semantic integrity in generated audio. For instance, existing methods like VALL-E, which condition acoustic token generation on text transcriptions, often suffer from content inaccuracies and elevated word error rates (WER) due to semantic misinterpretations of acoustic tokens, resulting in word skipping and errors. To overcome these issues, we propose a straightforward yet effective approach called X-Codec. X-Codec incorporates semantic features from a pre-trained semantic encoder before the Residual Vector Quantization (RVQ) stage and introduces a semantic reconstruction loss after RVQ. By enhancing the semantic ability of the codec, X-Codec significantly reduces WER in speech synthesis tasks and extends these benefits to non-speech applications, including music and sound generation. Our experiments in text-to-speech, music continuation, and text-to-sound tasks demonstrate that integrating semantic information substantially improves the overall performance of language models in audio generation.* +*Recent advancements in audio generation have been significantly propelled by the capabilities of Large Language Models (LLMs). The existing research on audio LLM has primarily focused on enhancing the architecture and scale of audio language models, as well as leveraging larger datasets, and generally, acoustic codecs, such as EnCodec, are used for audio tokenization. However, these codecs were originally designed for audio compression, which may lead to suboptimal performance in the context of audio LLM. Our research aims to address the shortcomings of current audio LLM codecs, particularly their challenges in maintaining semantic integrity in generated audio. For instance, existing methods like VALL-E, which condition acoustic token generation on text transcriptions, often suffer from content inaccuracies and elevated word error rates (WER) due to semantic misinterpretations of acoustic tokens, resulting in word skipping and errors. To overcome these issues, we propose a straightforward yet effective approach called X-Codec. X-Codec incorporates semantic features from a pre-trained semantic encoder before the Residual Vector Quantization (RVQ) stage and introduces a semantic reconstruction loss after RVQ. By enhancing the semantic ability of the codec, X-Codec significantly reduces WER in speech synthesis tasks and extends these benefits to non-speech applications, including music and sound generation. Our experiments in text-to-speech, music continuation, and text-to-sound tasks demonstrate that integrating semantic information substantially improves the overall performance of language models in audio generation.* Model cards: - [xcodec-hubert-librispeech](https://huggingface.co/hf-audio/xcodec-hubert-librispeech) (for speech) @@ -46,12 +46,11 @@ This model was contributed by [Manal El Aidouni](https://huggingface.co/Manel). Demos can be found on this [page](https://x-codec-audio.github.io/). - -## Usage example +## Usage example Here is a quick example of how to encode and decode an audio using this model: -```python +```python from datasets import load_dataset, Audio from transformers import XcodecModel, AutoFeatureExtractor dummy_dataset = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") @@ -75,6 +74,7 @@ audio_values = decoder_outputs.audio_values audio_values = model(inputs["input_values"]).audio_values ``` + To listen to the original and reconstructed audio, run the snippet below and then open the generated `original.wav` and `reconstruction.wav` files in your music player to compare. ```python @@ -88,12 +88,10 @@ sf.write("original.wav", original, sampling_rate) sf.write("reconstruction.wav", reconstruction.T, sampling_rate) ``` - ## XcodecConfig [[autodoc]] XcodecConfig - ## XcodecModel [[autodoc]] XcodecModel diff --git a/docs/source/en/model_doc/xglm.md b/docs/source/en/model_doc/xglm.md index 9a9170d29b7e..370055c90ea0 100644 --- a/docs/source/en/model_doc/xglm.md +++ b/docs/source/en/model_doc/xglm.md @@ -44,7 +44,6 @@ showing in particular that it enables cross-lingual in-context learning on some on surface form robustness and adaptation to tasks that do not have a natural cloze form. Finally, we evaluate our models in social value tasks such as hate speech detection in five languages and find it has limitations similar to comparable sized GPT-3 models.* - This model was contributed by [Suraj](https://huggingface.co/valhalla). The original code can be found [here](https://github.com/pytorch/fairseq/tree/main/examples/xglm). ## Resources @@ -67,7 +66,6 @@ This model was contributed by [Suraj](https://huggingface.co/valhalla). The orig [[autodoc]] XGLMTokenizerFast - ## XGLMModel [[autodoc]] XGLMModel diff --git a/docs/source/en/model_doc/xlm-prophetnet.md b/docs/source/en/model_doc/xlm-prophetnet.md index 4dad4c0afa78..fbf47d8c422a 100644 --- a/docs/source/en/model_doc/xlm-prophetnet.md +++ b/docs/source/en/model_doc/xlm-prophetnet.md @@ -41,7 +41,6 @@ You can do so by running the following command: `pip install -U transformers==4. **DISCLAIMER:** If you see something strange, file a [Github Issue](https://github.com/huggingface/transformers/issues/new?assignees=&labels=&template=bug-report.md&title) and assign @patrickvonplaten - ## Overview The XLM-ProphetNet model was proposed in [ProphetNet: Predicting Future N-gram for Sequence-to-Sequence Pre-training,](https://huggingface.co/papers/2001.04063) by Yu Yan, Weizhen Qi, Yeyun Gong, Dayiheng Liu, Nan Duan, Jiusheng Chen, Ruofei diff --git a/docs/source/en/model_doc/xlm-roberta-xl.md b/docs/source/en/model_doc/xlm-roberta-xl.md index 8ae33e8b286a..5e1f0bbda288 100644 --- a/docs/source/en/model_doc/xlm-roberta-xl.md +++ b/docs/source/en/model_doc/xlm-roberta-xl.md @@ -77,6 +77,7 @@ predicted_token = tokenizer.decode(predicted_token_id) print(f"The predicted token is: {predicted_token}") ``` + @@ -84,6 +85,7 @@ print(f"The predicted token is: {predicted_token}") ```bash echo -e "Plants create through a process known as photosynthesis." | transformers run --task fill-mask --model facebook/xlm-roberta-xl --device 0 ``` + diff --git a/docs/source/en/model_doc/xlm-roberta.md b/docs/source/en/model_doc/xlm-roberta.md index 65468a786a07..0e9867636892 100644 --- a/docs/source/en/model_doc/xlm-roberta.md +++ b/docs/source/en/model_doc/xlm-roberta.md @@ -87,6 +87,7 @@ print(f"The predicted token is: {predicted_token}") ```bash echo -e "Plants create through a process known as photosynthesis." | transformers run --task fill-mask --model FacebookAI/xlm-roberta-base --device 0 ``` + diff --git a/docs/source/en/model_doc/xlm.md b/docs/source/en/model_doc/xlm.md index b4d84c791f5a..ff8f8c46024d 100644 --- a/docs/source/en/model_doc/xlm.md +++ b/docs/source/en/model_doc/xlm.md @@ -79,6 +79,7 @@ print(f"Predicted token: {predicted_token}") ```bash echo -e "Plants create through a process known as photosynthesis." | transformers run --task fill-mask --model FacebookAI/xlm-mlm-en-2048 --device 0 ``` + diff --git a/docs/source/en/model_doc/xlstm.md b/docs/source/en/model_doc/xlstm.md index b239d631fbbc..e1ba3195eccf 100644 --- a/docs/source/en/model_doc/xlstm.md +++ b/docs/source/en/model_doc/xlstm.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2024-05-07 and added to Hugging Face Transformers on 2025-07-25.* - # xLSTM ## Overview @@ -32,7 +31,6 @@ The abstract from the paper is the following: This model was contributed by [NX-AI](https://huggingface.co/NX-AI). The original code can be found [here](https://github.com/NX-AI/xlstm). - ## xLSTMConfig [[autodoc]] xLSTMConfig diff --git a/docs/source/en/model_doc/yolos.md b/docs/source/en/model_doc/yolos.md index 5c31b539e59c..666f9674332b 100644 --- a/docs/source/en/model_doc/yolos.md +++ b/docs/source/en/model_doc/yolos.md @@ -26,14 +26,12 @@ rendered properly in your Markdown viewer. [YOLOS](https://huggingface.co/papers/2106.00666) uses a [Vision Transformer (ViT)](./vit) for object detection with minimal modifications and region priors. It can achieve performance comparable to specialized object detection models and frameworks with knowledge about 2D spatial structures. - You can find all the original YOLOS checkpoints under the [HUST Vision Lab](https://huggingface.co/hustvl/models?search=yolos) organization. drawing YOLOS architecture. Taken from the original paper. - > [!TIP] > This model wasa contributed by [nielsr](https://huggingface.co/nielsr). > Click on the YOLOS models in the right sidebar for more examples of how to apply YOLOS to different object detection tasks. @@ -98,7 +96,6 @@ for score, label, box in zip(filtered_scores, filtered_labels, pixel_boxes): - ## Notes - Use [`YolosImageProcessor`] for preparing images (and optional targets) for the model. Contrary to [DETR](./detr), YOLOS doesn't require a `pixel_mask`. diff --git a/docs/source/en/model_doc/yoso.md b/docs/source/en/model_doc/yoso.md index f07e5aba0827..8e121dd88cdd 100644 --- a/docs/source/en/model_doc/yoso.md +++ b/docs/source/en/model_doc/yoso.md @@ -26,20 +26,20 @@ rendered properly in your Markdown viewer. The YOSO model was proposed in [You Only Sample (Almost) Once: Linear Cost Self-Attention Via Bernoulli Sampling](https://huggingface.co/papers/2111.09714) by Zhanpeng Zeng, Yunyang Xiong, Sathya N. Ravi, Shailesh Acharya, Glenn Fung, Vikas Singh. YOSO approximates standard softmax self-attention via a Bernoulli sampling scheme based on Locality Sensitive Hashing (LSH). In principle, all the Bernoulli random variables can be sampled with -a single hash. +a single hash. The abstract from the paper is the following: -*Transformer-based models are widely used in natural language processing (NLP). Central to the transformer model is -the self-attention mechanism, which captures the interactions of token pairs in the input sequences and depends quadratically -on the sequence length. Training such models on longer sequences is expensive. In this paper, we show that a Bernoulli sampling -attention mechanism based on Locality Sensitive Hashing (LSH), decreases the quadratic complexity of such models to linear. -We bypass the quadratic cost by considering self-attention as a sum of individual tokens associated with Bernoulli random -variables that can, in principle, be sampled at once by a single hash (although in practice, this number may be a small constant). -This leads to an efficient sampling scheme to estimate self-attention which relies on specific modifications of -LSH (to enable deployment on GPU architectures). We evaluate our algorithm on the GLUE benchmark with standard 512 sequence -length where we see favorable performance relative to a standard pretrained Transformer. On the Long Range Arena (LRA) benchmark, -for evaluating performance on long sequences, our method achieves results consistent with softmax self-attention but with sizable +*Transformer-based models are widely used in natural language processing (NLP). Central to the transformer model is +the self-attention mechanism, which captures the interactions of token pairs in the input sequences and depends quadratically +on the sequence length. Training such models on longer sequences is expensive. In this paper, we show that a Bernoulli sampling +attention mechanism based on Locality Sensitive Hashing (LSH), decreases the quadratic complexity of such models to linear. +We bypass the quadratic cost by considering self-attention as a sum of individual tokens associated with Bernoulli random +variables that can, in principle, be sampled at once by a single hash (although in practice, this number may be a small constant). +This leads to an efficient sampling scheme to estimate self-attention which relies on specific modifications of +LSH (to enable deployment on GPU architectures). We evaluate our algorithm on the GLUE benchmark with standard 512 sequence +length where we see favorable performance relative to a standard pretrained Transformer. On the Long Range Arena (LRA) benchmark, +for evaluating performance on long sequences, our method achieves results consistent with softmax self-attention but with sizable speed-ups and memory savings and often outperforms other efficient self-attention methods. Our code is available at this https URL* This model was contributed by [novice03](https://huggingface.co/novice03). The original code can be found [here](https://github.com/mlpen/YOSO). @@ -50,12 +50,12 @@ This model was contributed by [novice03](https://huggingface.co/novice03). The o in parallel on a GPU. - The kernels provide a `fast_hash` function, which approximates the random projections of the queries and keys using the Fast Hadamard Transform. Using these hash codes, the `lsh_cumulation` function approximates self-attention via LSH-based Bernoulli sampling. -- To use the custom kernels, the user should set `config.use_expectation = False`. To ensure that the kernels are compiled successfully, -the user must install the correct version of PyTorch and cudatoolkit. By default, `config.use_expectation = True`, which uses YOSO-E and +- To use the custom kernels, the user should set `config.use_expectation = False`. To ensure that the kernels are compiled successfully, +the user must install the correct version of PyTorch and cudatoolkit. By default, `config.use_expectation = True`, which uses YOSO-E and does not require compiling CUDA kernels. +alt="drawing" width="600"/> YOSO Attention Algorithm. Taken from the original paper. diff --git a/docs/source/en/model_doc/zamba.md b/docs/source/en/model_doc/zamba.md index bb9740807703..635bc76fb0ca 100644 --- a/docs/source/en/model_doc/zamba.md +++ b/docs/source/en/model_doc/zamba.md @@ -24,7 +24,6 @@ rendered properly in your Markdown viewer. This model was contributed by [pglo](https://huggingface.co/pglo). - ## Model details Zamba-7B-v1 is a hybrid between state-space models (Specifically [Mamba](https://github.com/state-spaces/mamba)) and transformer, and was trained using next-token prediction. Zamba uses a shared transformer layer after every 6 mamba blocks. It uses the [Mistral v0.1 tokenizer](https://huggingface.co/mistralai/Mistral-7B-v0.1). We came to this architecture after a series of ablations at small scales. Zamba-7B-v1 was pre-trained on 1T tokens of text and code data. @@ -33,23 +32,24 @@ Zamba-7B-v1 is a hybrid between state-space models (Specifically [Mamba](https:/ ## Quick start - ### Presequities Zamba requires you use `transformers` version 4.46.0 or higher: + ```bash pip install transformers>=4.45.0 ``` In order to run optimized Mamba implementations, you first need to install `mamba-ssm` and `causal-conv1d`: + ```bash pip install mamba-ssm causal-conv1d>=1.2.0 ``` + You also have to have the model on a CUDA device. You can run the model not using the optimized Mamba kernels, but it is **not** recommended as it will result in significantly lower latencies. In order to do that, you'll need to specify `use_mamba_kernels=False` when loading the model. - ## Inference ```python @@ -66,39 +66,32 @@ outputs = model.generate(**input_ids, max_new_tokens=100) print(tokenizer.decode(outputs[0])) ``` - ## Model card The model cards can be found at: * [Zamba-7B](https://huggingface.co/Zyphra/Zamba-7B-v1) - ## Issues For issues with model output, or community discussion, please use the Hugging Face community [forum](https://huggingface.co/Zyphra/Zamba-7B-v1/discussions) - ## License The model weights are open-sourced via an Apache 2.0 license. - ## ZambaConfig [[autodoc]] ZambaConfig - ## ZambaModel [[autodoc]] ZambaModel - forward - ## ZambaForCausalLM [[autodoc]] ZambaForCausalLM - forward - ## ZambaForSequenceClassification [[autodoc]] transformers.ZambaForSequenceClassification diff --git a/docs/source/en/model_doc/zamba2.md b/docs/source/en/model_doc/zamba2.md index ba4324366a99..7296ef1b2500 100644 --- a/docs/source/en/model_doc/zamba2.md +++ b/docs/source/en/model_doc/zamba2.md @@ -26,7 +26,6 @@ rendered properly in your Markdown viewer. This model was contributed by [pglo](https://huggingface.co/pglo). - ## Model details [Zamba2-1.2B](https://www.zyphra.com/post/zamba2-mini), [Zamba2-2.7B](https://www.zyphra.com/post/zamba2-small) and [Zamba2-7B](https://www.zyphra.com/post/zamba2-7b) are hybrid models combining state-space models (Specifically [Mamba2](https://github.com/state-spaces/mamba)) and transformer, and were trained using next-token prediction. Zamba2 uses shared transformer layers after every 6 mamba blocks. It uses the [Mistral v0.1 tokenizer](https://huggingface.co/mistralai/Mistral-7B-v0.1). We came to this architecture after a series of ablations at small scales. Zamba2-1.2B, Zamba2-2.7B and Zamba2-7B were pre-trained on 2T and 3T tokens, respectively. @@ -35,10 +34,10 @@ This model was contributed by [pglo](https://huggingface.co/pglo). ## Quick start - ### Presequities Zamba2 requires you use `transformers` version 4.48.0 or higher: + ```bash pip install transformers>=4.48.0 ``` @@ -59,7 +58,6 @@ outputs = model.generate(**input_ids, max_new_tokens=100) print(tokenizer.decode(outputs[0])) ``` - ## Model card The model cards can be found at: @@ -67,33 +65,27 @@ The model cards can be found at: * [Zamba2-2.7B](https://huggingface.co/Zyphra/Zamba2-2.7B) * [Zamba2-7B](https://huggingface.co/Zyphra/Zamba2-7B) - ## Issues For issues with model output, or community discussion, please use the Hugging Face community [forum](https://huggingface.co/Zyphra/Zamba2-7B/discussions) - ## License The model weights are open-sourced via an Apache 2.0 license. - ## Zamba2Config [[autodoc]] Zamba2Config - ## Zamba2Model [[autodoc]] Zamba2Model - forward - ## Zamba2ForCausalLM [[autodoc]] Zamba2ForCausalLM - forward - ## Zamba2ForSequenceClassification [[autodoc]] transformers.Zamba2ForSequenceClassification diff --git a/docs/source/en/model_doc/zoedepth.md b/docs/source/en/model_doc/zoedepth.md index 367c630a3224..5252d2b4d367 100644 --- a/docs/source/en/model_doc/zoedepth.md +++ b/docs/source/en/model_doc/zoedepth.md @@ -15,7 +15,6 @@ rendered properly in your Markdown viewer. --> *This model was released on 2023-02-23 and added to Hugging Face Transformers on 2024-07-08.* -
PyTorch @@ -97,6 +96,7 @@ Image.fromarray(depth.astype("uint8")) ## Notes - In the [original implementation](https://github.com/isl-org/ZoeDepth/blob/edb6daf45458569e24f50250ef1ed08c015f17a7/zoedepth/models/depth_model.py#L131) ZoeDepth performs inference on both the original and flipped images and averages the results. The `post_process_depth_estimation` function handles this by passing the flipped outputs to the optional `outputs_flipped` argument as shown below. + ```py with torch.no_grad(): outputs = model(pixel_values) @@ -107,7 +107,7 @@ Image.fromarray(depth.astype("uint8")) outputs_flipped=outputs_flipped, ) ``` - + ## Resources - Refer to this [notebook](https://github.com/NielsRogge/Transformers-Tutorials/tree/master/ZoeDepth) for an inference example. diff --git a/docs/source/en/model_memory_anatomy.md b/docs/source/en/model_memory_anatomy.md index 2c6162ed1ca6..9b2e4b4b6225 100644 --- a/docs/source/en/model_memory_anatomy.md +++ b/docs/source/en/model_memory_anatomy.md @@ -16,24 +16,23 @@ limitations under the License. # Model training anatomy -To understand performance optimization techniques that one can apply to improve efficiency of model training -speed and memory utilization, it's helpful to get familiar with how GPU is utilized during training, and how compute +To understand performance optimization techniques that one can apply to improve efficiency of model training +speed and memory utilization, it's helpful to get familiar with how GPU is utilized during training, and how compute intensity varies depending on an operation performed. -Let's start by exploring a motivating example of GPU utilization and the training run of a model. For the demonstration, -we'll need to install a few libraries: +Let's start by exploring a motivating example of GPU utilization and the training run of a model. For the demonstration, +we'll need to install a few libraries: ```bash pip install transformers datasets accelerate nvidia-ml-py ``` -The `nvidia-ml-py` library allows us to monitor the memory usage of the models from within Python. You might be familiar +The `nvidia-ml-py` library allows us to monitor the memory usage of the models from within Python. You might be familiar with the `nvidia-smi` command in the terminal - this library allows to access the same information in Python directly. -Then, we create some dummy data: random token IDs between 100 and 30000 and binary labels for a classifier. +Then, we create some dummy data: random token IDs between 100 and 30000 and binary labels for a classifier. In total, we get 512 sequences each with length 512 and store them in a [`~datasets.Dataset`] with PyTorch format. - ```py >>> import numpy as np >>> from datasets import Dataset @@ -74,9 +73,9 @@ Let's verify that we start with a free GPU memory: GPU memory occupied: 0 MB. ``` -That looks good: the GPU memory is not occupied as we would expect before we load any models. If that's not the case on -your machine make sure to stop all processes that are using GPU memory. However, not all free GPU memory can be used by -the user. When a model is loaded to the GPU the kernels are also loaded, which can take up 1-2GB of memory. To see how +That looks good: the GPU memory is not occupied as we would expect before we load any models. If that's not the case on +your machine make sure to stop all processes that are using GPU memory. However, not all free GPU memory can be used by +the user. When a model is loaded to the GPU the kernels are also loaded, which can take up 1-2GB of memory. To see how much it is we load a tiny tensor into the GPU which triggers the kernels to be loaded as well. ```py @@ -92,10 +91,9 @@ We see that the kernels alone take up 1.3GB of GPU memory. Now let's see how muc ## Load Model -First, we load the `google-bert/bert-large-uncased` model. We load the model weights directly to the GPU so that we can check +First, we load the `google-bert/bert-large-uncased` model. We load the model weights directly to the GPU so that we can check how much space just the weights use. - ```py >>> from transformers import AutoModelForSequenceClassification @@ -105,12 +103,11 @@ how much space just the weights use. GPU memory occupied: 2631 MB. ``` -We can see that the model weights alone take up 1.3 GB of GPU memory. The exact number depends on the specific -GPU you are using. Note that on newer GPUs a model can sometimes take up more space since the weights are loaded in an -optimized fashion that speeds up the usage of the model. Now we can also quickly check if we get the same result +We can see that the model weights alone take up 1.3 GB of GPU memory. The exact number depends on the specific +GPU you are using. Note that on newer GPUs a model can sometimes take up more space since the weights are loaded in an +optimized fashion that speeds up the usage of the model. Now we can also quickly check if we get the same result as with `nvidia-smi` CLI: - ```bash nvidia-smi ``` @@ -138,8 +135,8 @@ Tue Jan 11 08:58:05 2022 +-----------------------------------------------------------------------------+ ``` -We get the same number as before and you can also see that we are using a V100 GPU with 16GB of memory. So now we can -start training the model and see how the GPU memory consumption changes. First, we set up a few standard training +We get the same number as before and you can also see that we are using a V100 GPU with 16GB of memory. So now we can +start training the model and see how the GPU memory consumption changes. First, we set up a few standard training arguments: ```py @@ -154,7 +151,7 @@ default_args = { - If you plan to run multiple experiments, in order to properly clear the memory between experiments, restart the Python + If you plan to run multiple experiments, in order to properly clear the memory between experiments, restart the Python kernel between experiments. @@ -181,9 +178,9 @@ Samples/second: 8.86 GPU memory occupied: 14949 MB. ``` -We see that already a relatively small batch size almost fills up our GPU's entire memory. However, a larger batch size +We see that already a relatively small batch size almost fills up our GPU's entire memory. However, a larger batch size can often result in faster model convergence or better end performance. So ideally we want to tune the batch size to our -model's needs and not to the GPU limitations. What's interesting is that we use much more memory than the size of the model. +model's needs and not to the GPU limitations. What's interesting is that we use much more memory than the size of the model. To understand a bit better why this is the case let's have a look at a model's operations and memory needs. ## Anatomy of Model's Operations @@ -206,10 +203,9 @@ This knowledge can be helpful to know when analyzing performance bottlenecks. This summary is derived from [Data Movement Is All You Need: A Case Study on Optimizing Transformers 2020](https://huggingface.co/papers/2007.00072) - ## Anatomy of Model's Memory -We've seen that training the model uses much more memory than just putting the model on the GPU. This is because there +We've seen that training the model uses much more memory than just putting the model on the GPU. This is because there are many components during training that use GPU memory. The components on GPU memory are the following: 1. model weights @@ -219,8 +215,8 @@ are many components during training that use GPU memory. The components on GPU m 5. temporary buffers 6. functionality-specific memory -A typical model trained in mixed precision with AdamW requires 18 bytes per model parameter plus activation memory. For -inference there are no optimizer states and gradients, so we can subtract those. And thus we end up with 6 bytes per +A typical model trained in mixed precision with AdamW requires 18 bytes per model parameter plus activation memory. For +inference there are no optimizer states and gradients, so we can subtract those. And thus we end up with 6 bytes per model parameter for mixed precision inference, plus activation memory. Let's look at the details. @@ -244,29 +240,29 @@ Let's look at the details. - size depends on many factors, the key ones being sequence length, hidden size and batch size. -There are the input and output that are being passed and returned by the forward and the backward functions and the +There are the input and output that are being passed and returned by the forward and the backward functions and the forward activations saved for gradient computation. **Temporary Memory** -Additionally, there are all kinds of temporary variables which get released once the calculation is done, but in the -moment these could require additional memory and could push to OOM. Therefore, when coding it's crucial to think +Additionally, there are all kinds of temporary variables which get released once the calculation is done, but in the +moment these could require additional memory and could push to OOM. Therefore, when coding it's crucial to think strategically about such temporary variables and sometimes to explicitly free those as soon as they are no longer needed. **Functionality-specific memory** -Then, your software could have special memory needs. For example, when generating text using beam search, the software +Then, your software could have special memory needs. For example, when generating text using beam search, the software needs to maintain multiple copies of inputs and outputs. **`forward` vs `backward` Execution Speed** -For convolutions and linear layers there are 2x flops in the backward compared to the forward, which generally translates -into ~2x slower (sometimes more, because sizes in the backward tend to be more awkward). Activations are usually -bandwidth-limited, and it’s typical for an activation to have to read more data in the backward than in the forward -(e.g. activation forward reads once, writes once, activation backward reads twice, gradOutput and output of the forward, +For convolutions and linear layers there are 2x flops in the backward compared to the forward, which generally translates +into ~2x slower (sometimes more, because sizes in the backward tend to be more awkward). Activations are usually +bandwidth-limited, and it’s typical for an activation to have to read more data in the backward than in the forward +(e.g. activation forward reads once, writes once, activation backward reads twice, gradOutput and output of the forward, and writes once, gradInput). -As you can see, there are potentially a few places where we could save GPU memory or speed up operations. -Now that you understand what affects GPU utilization and computation speed, refer to -the [Methods and tools for efficient training on a single GPU](perf_train_gpu_one) documentation page to learn about -performance optimization techniques. +As you can see, there are potentially a few places where we could save GPU memory or speed up operations. +Now that you understand what affects GPU utilization and computation speed, refer to +the [Methods and tools for efficient training on a single GPU](perf_train_gpu_one) documentation page to learn about +performance optimization techniques. diff --git a/docs/source/en/models.md b/docs/source/en/models.md index fdfcfba6585a..ae5572c0c77a 100644 --- a/docs/source/en/models.md +++ b/docs/source/en/models.md @@ -45,7 +45,6 @@ There are two general types of models you can load: 1. A barebones model, like [`AutoModel`] or [`LlamaModel`], that outputs hidden states. 2. A model with a specific *head* attached, like [`AutoModelForCausalLM`] or [`LlamaForCausalLM`], for performing specific tasks. - ## Model classes To get a pretrained model, you need to load the weights into the model. This is done by calling [`~PreTrainedModel.from_pretrained`] which accepts weights from the Hugging Face Hub or a local directory. @@ -111,7 +110,6 @@ You need enough memory to hold two copies of the model weights (random and pretr Transformers reduces some of these memory-related challenges with fast initialization, sharded checkpoints, Accelerate's [Big Model Inference](https://hf.co/docs/accelerate/usage_guides/big_modeling) feature, and supporting lower bit data types. - ### Sharded checkpoints The [`~PreTrainedModel.save_pretrained`] method automatically shards checkpoints larger than 10GB. diff --git a/docs/source/en/perf_train_gaudi.md b/docs/source/en/perf_train_gaudi.md index 2ba792d484a3..1ab8957f9d7c 100644 --- a/docs/source/en/perf_train_gaudi.md +++ b/docs/source/en/perf_train_gaudi.md @@ -20,14 +20,17 @@ The Intel Gaudi AI accelerator family includes [Intel Gaudi 1](https://habana.ai [`TrainingArguments`], [`Trainer`] and [`Pipeline`] detect and set the backend device to `hpu` if an Intel Gaudi device is available. No additional changes are required to enable training and inference on your device. Some modeling code in Transformers is not optimized for HPU lazy mode. If you encounter any errors, set the environment variable below to use eager mode: + ``` PT_HPU_LAZY_MODE=0 ``` In some cases, you'll also need to enable int64 support to avoid casting issues with long integers: + ``` PT_ENABLE_INT64_SUPPORT=1 ``` + Refer to the [Gaudi docs](https://docs.habana.ai/en/latest/index.html) for more details. > [!TIP] diff --git a/docs/source/en/pipeline_webserver.md b/docs/source/en/pipeline_webserver.md index 0112d116c47d..37d245483b94 100644 --- a/docs/source/en/pipeline_webserver.md +++ b/docs/source/en/pipeline_webserver.md @@ -82,6 +82,7 @@ Query the server with a POST request. ```bash curl -X POST -d "Paris is the [MASK] of France." http://localhost:8000/ ``` + This should return the output below. ```bash diff --git a/docs/source/en/pr_checks.md b/docs/source/en/pr_checks.md index a5634c29ee49..7056adf2149f 100644 --- a/docs/source/en/pr_checks.md +++ b/docs/source/en/pr_checks.md @@ -52,7 +52,6 @@ or for an editable install: pip install -e .[quality] ``` - ## Tests All the jobs that begin with `ci/circleci: run_tests_` run parts of the Transformers testing suite. Each of those jobs focuses on a part of the library in a certain environment: for instance `ci/circleci: run_tests_pipelines` runs the pipeline tests in an environment where all pipeline-related requirements are installed. diff --git a/docs/source/en/quantization/auto_round.md b/docs/source/en/quantization/auto_round.md index 15abf9faa846..7526597ee86f 100644 --- a/docs/source/en/quantization/auto_round.md +++ b/docs/source/en/quantization/auto_round.md @@ -11,18 +11,17 @@ rendered properly in your Markdown viewer. # AutoRound -[AutoRound](https://github.com/intel/auto-round) is an advanced quantization algorithm that delivers strong accuracy, even at 2-bit precision. -It leverages sign gradient descent to fine-tune both rounding values and min-max clipping thresholds in just 200 steps. Designed for broad compatibility, it seamlessly supports a wide range of LLMs and is actively expanding to cover more VLMs as well. +[AutoRound](https://github.com/intel/auto-round) is an advanced quantization algorithm that delivers strong accuracy, even at 2-bit precision. +It leverages sign gradient descent to fine-tune both rounding values and min-max clipping thresholds in just 200 steps. Designed for broad compatibility, it seamlessly supports a wide range of LLMs and is actively expanding to cover more VLMs as well. It also supports quantization and inference across multiple hardware platforms, including CPU, XPU, and CUDA. -AutoRound also offers a variety of useful features, including mixed-bit tuning and inference, lm-head quantization, support for exporting to formats like GPTQ/AWQ/GGUF, and flexible tuning recipes. +AutoRound also offers a variety of useful features, including mixed-bit tuning and inference, lm-head quantization, support for exporting to formats like GPTQ/AWQ/GGUF, and flexible tuning recipes. For a comprehensive overview and the latest updates, check out the AutoRound [README](https://github.com/intel/auto-round). -AutoRound was originally developed as part of the [Intel Neural Compressor](https://github.com/intel/neural-compressor), serving as a general-purpose model compression library for deep learning. -It has since evolved into a standalone library focused specifically on low-precision optimization for large language models (LLMs). +AutoRound was originally developed as part of the [Intel Neural Compressor](https://github.com/intel/neural-compressor), serving as a general-purpose model compression library for deep learning. +It has since evolved into a standalone library focused specifically on low-precision optimization for large language models (LLMs). AutoRound remains fully integrated with the Intel Neural Compressor, and you can explore the repository for more details. - ## Installation ```bash @@ -51,6 +50,7 @@ Currently, only offline mode is supported to generate quantized models. ### Command Line Usage + ```bash auto-round \ --model facebook/opt-125m \ @@ -59,7 +59,7 @@ auto-round \ --output_dir ./tmp_autoround ``` -AutoRound also offer another two recipes, `auto-round-best` and `auto-round-light`, designed for optimal accuracy and improved speed, respectively. +AutoRound also offer another two recipes, `auto-round-best` and `auto-round-light`, designed for optimal accuracy and improved speed, respectively. For 2 bits, we recommend using `auto-round-best` or `auto-round`. @@ -99,6 +99,7 @@ autoround.quantize_and_save(output_dir, format='auto_round') ### AutoRoundBest recipe This setting provides the best accuracy in most scenarios but is 4–5× slower than the standard AutoRound recipe. It is especially recommended for 2-bit quantization and is a good choice if sufficient resources are available. + ```python from transformers import AutoModelForCausalLM, AutoTokenizer from auto_round import AutoRound @@ -121,6 +122,7 @@ autoround = AutoRound( output_dir = "./tmp_autoround" autoround.quantize_and_save(output_dir, format='auto_round') ``` + @@ -230,7 +232,7 @@ print(tokenizer.decode(model.generate(**inputs, max_new_tokens=50, do_sample=Fal AutoRound automatically selects the backend for each layer based on compatibility. In general, the priority order is Marlin > ExLLaMAV2 > Triton, but the final choice depends on factors such as group size, bit width, packing format, hardware device, and other implementation details. For more details, please refer to [backends](https://github.com/intel/auto-round?tab=readme-ov-file#specify-backend), -The backend may not always be the most suitable for certain devices. +The backend may not always be the most suitable for certain devices. You can specify your preferred backend such as "ipex" for CPU, "ipex/triton" for XPU, "marlin/exllamav2/triton" for CUDA, according to your needs or hardware compatibility. Please note that additional corresponding libraries may be required. ```python @@ -247,7 +249,6 @@ print(tokenizer.decode(model.generate(**inputs, max_new_tokens=50, do_sample=Fal - ### Convert GPTQ/AWQ to AutoRound @@ -277,7 +278,6 @@ the [transformers](https://github.com/huggingface/transformers/issues) repositor If you encounter any issues with auto-round, please open an issue on the [AutoRound](https://github.com/intel/auto-round/issues) repository. - ## Acknowledgement Special thanks to open-source low precision libraries such as AutoGPTQ, AutoAWQ, GPTQModel, Triton, Marlin, and ExLLaMAV2 for providing low-precision CUDA kernels, which are leveraged in AutoRound. diff --git a/docs/source/en/quantization/awq.md b/docs/source/en/quantization/awq.md index b6437e2588a8..b2cf4b9ecdf6 100644 --- a/docs/source/en/quantization/awq.md +++ b/docs/source/en/quantization/awq.md @@ -25,6 +25,7 @@ Run the command below to install autoawq ```bash pip install autoawq ``` + > [!WARNING] > AutoAWQ downgrades Transformers to version 4.47.1. If you want to do inference with AutoAWQ, you may need to reinstall your Transformers' version after installing AutoAWQ. diff --git a/docs/source/en/quantization/bitsandbytes.md b/docs/source/en/quantization/bitsandbytes.md index 60c3c2dfebf9..9cdbbe5af39a 100644 --- a/docs/source/en/quantization/bitsandbytes.md +++ b/docs/source/en/quantization/bitsandbytes.md @@ -32,12 +32,12 @@ bitsandbytes offers two main quantization features: > **Note:** For a user-friendly quantization experience, you can use the `bitsandbytes` [community space](https://huggingface.co/spaces/bnb-community/bnb-my-repo). - Run the command below to install bitsandbytes. ```bash pip install --upgrade transformers accelerate bitsandbytes ``` + To compile from source, follow the instructions in the [bitsandbytes installation guide](https://huggingface.co/docs/bitsandbytes/main/en/installation). ## Hardware Compatibility @@ -116,6 +116,7 @@ model = AutoModelForCausalLM.from_pretrained( model.push_to_hub("bloom-560m-8bit") ``` +
@@ -166,6 +167,7 @@ model = AutoModelForCausalLM.from_pretrained( model.push_to_hub("bloom-560m-4bit") ``` +
diff --git a/docs/source/en/quantization/compressed_tensors.md b/docs/source/en/quantization/compressed_tensors.md index a3b01a1b4489..3c047d0af985 100644 --- a/docs/source/en/quantization/compressed_tensors.md +++ b/docs/source/en/quantization/compressed_tensors.md @@ -99,29 +99,29 @@ For a more detailed look at the model weights, use the [safetensors viewer](http | Tensors | Shape | Precision | | ------- | ----- | --------- | -model.layers.0.input_layernorm.weight | [4 096] | BF16 -model.layers.0.mlp.down_proj.input_scale | [1] | BF16 -model.layers.0.mlp.down_proj.weight | [4 096, 14 336] | F8_E4M3 -model.layers.0.mlp.down_proj.weight_scale | [1] | BF16 -model.layers.0.mlp.gate_proj.input_scale | [1] | BF16 -model.layers.0.mlp.gate_proj.weight | [14 336, 4 096] | F8_E4M3 -model.layers.0.mlp.gate_proj.weight_scale | [1] | BF16 -model.layers.0.mlp.up_proj.input_scale| [1] |BF16 -model.layers.0.mlp.up_proj.weight | [14 336, 4 096] | F8_E4M3 -model.layers.0.mlp.up_proj.weight_scale | [1] | BF16 -model.layers.0.post_attention_layernorm.weight | [4 096] |BF16 +model.layers.0.input_layernorm.weight | [4 096] | BF16 +model.layers.0.mlp.down_proj.input_scale | [1] | BF16 +model.layers.0.mlp.down_proj.weight | [4 096, 14 336] | F8_E4M3 +model.layers.0.mlp.down_proj.weight_scale | [1] | BF16 +model.layers.0.mlp.gate_proj.input_scale | [1] | BF16 +model.layers.0.mlp.gate_proj.weight | [14 336, 4 096] | F8_E4M3 +model.layers.0.mlp.gate_proj.weight_scale | [1] | BF16 +model.layers.0.mlp.up_proj.input_scale| [1] |BF16 +model.layers.0.mlp.up_proj.weight | [14 336, 4 096] | F8_E4M3 +model.layers.0.mlp.up_proj.weight_scale | [1] | BF16 +model.layers.0.post_attention_layernorm.weight | [4 096] |BF16 model.layers.0.self_attn.k_proj.input_scale | [1] | BF16 model.layers.0.self_attn.k_proj.weight | [1 024, 4 096]| F8_E4M3 -model.layers.0.self_attn.k_proj.weight_scale |[1] | BF16 +model.layers.0.self_attn.k_proj.weight_scale |[1] | BF16 model.layers.0.self_attn.o_proj.input_scale | [1] | BF16 -model.layers.0.self_attn.o_proj.weight | [4 096, 4 096] | F8_E4M3 -model.layers.0.self_attn.o_proj.weight_scale | [1] | BF16 -model.layers.0.self_attn.q_proj.input_scale | [1] | BF16 -model.layers.0.self_attn.q_proj.weight | [4 096, 4 096] | F8_E4M3 -model.layers.0.self_attn.q_proj.weight_scale | [1] | BF16 -model.layers.0.self_attn.v_proj.input_scale | [1] | BF16 -model.layers.0.self_attn.v_proj.weight | [1 024, 4 096] | F8_E4M3 -model.layers.0.self_attn.v_proj.weight_scale | [1] | BF16 +model.layers.0.self_attn.o_proj.weight | [4 096, 4 096] | F8_E4M3 +model.layers.0.self_attn.o_proj.weight_scale | [1] | BF16 +model.layers.0.self_attn.q_proj.input_scale | [1] | BF16 +model.layers.0.self_attn.q_proj.weight | [4 096, 4 096] | F8_E4M3 +model.layers.0.self_attn.q_proj.weight_scale | [1] | BF16 +model.layers.0.self_attn.v_proj.input_scale | [1] | BF16 +model.layers.0.self_attn.v_proj.weight | [1 024, 4 096] | F8_E4M3 +model.layers.0.self_attn.v_proj.weight_scale | [1] | BF16 When loading a compressed-tensors model with the [`~quantizers.HFQuantizer`] integration, all the [nn.Linear](https://pytorch.org/docs/stable/generated/torch.nn.Linear.html) modules specified in the quantization config are replaced by [CompressedLinear](https://github.com/neuralmagic/compressed-tensors/blob/975cb223b19fcac2b98a4271d17668462d4d6e1d/src/compressed_tensors/linear/compressed_linear.py#L30) modules that manage the compressed weights and forward pass for inference. The `lm_head` module is still kept as an unquantized nn.Linear module. diff --git a/docs/source/en/quantization/concept_guide.md b/docs/source/en/quantization/concept_guide.md index ff300b9d48a5..e9d3b451484d 100644 --- a/docs/source/en/quantization/concept_guide.md +++ b/docs/source/en/quantization/concept_guide.md @@ -18,7 +18,6 @@ rendered properly in your Markdown viewer. Quantization reduces the memory footprint and computational cost of large machine learning models like those found in the Transformers library. It achieves this by representing the model's weights and or activations with lower-precision data types (like 8-bit integers or int8) instead of the standard 32-bit floating-point (float32). - Reducing a model's precision offers several significant benefits: - Smaller model size: Lower-precision data types require less storage space. An int8 model, for example, is roughly 4 times smaller than its float32 counterpart. @@ -46,8 +45,7 @@ The most common method is *affine quantization*. For a given float32 tensor (lik There are two main ways to perform this mapping, *symmetric* and *asymmetric*. The choice between symmetric and asymmetric quantization determines how the float32 range is mapped to the int8 range. - Symmetric: This method assumes the original float32 range is symmetric around zero ( \\([ -a, a ]\\) ). This range is mapped symmetrically to the int8 range, for example, \\([-127, 127]\\). A key characteristic is that the float32 value \\(0.0\\) maps directly to the int8 value \\(0\\). This only requires one parameter, the **scale ( \\(S\\) )**, to define the mapping. It can simplify computations, but it might be less accurate if the original data distribution isn't naturally centered around zero. -- Asymmetric (Affine): This method does not assume the data is centered around zero. It maps the exact range \\([val_{min}, val_{max}]\\) from float32 to the full int8 range, like \\([-128, 127]\\). This requires two parameters, a **scale ( \\(S\\) )** and a **zero-point ( \\(Z\\) )**. - +- Asymmetric (Affine): This method does not assume the data is centered around zero. It maps the exact range \\([val_{min}, val_{max}]\\) from float32 to the full int8 range, like \\([-128, 127]\\). This requires two parameters, a **scale ( \\(S\\) )** and a **zero-point ( \\(Z\\) )**. scale ( \\(S\\) ): A positive float32 number representing the ratio between the float32 and the int8 range. @@ -134,8 +132,7 @@ There are two main types of quantization techniques. ## Quantization in Transformers -Transformers integrates several quantization backends such as bitsandbytes, torchao, compressed-tensors, and more (refer to the quantization [overview](./overview) for more backends). - +Transformers integrates several quantization backends such as bitsandbytes, torchao, compressed-tensors, and more (refer to the quantization [overview](./overview) for more backends). All backends are unified under the [`HfQuantizer`] API and associated [`QuantizationConfig`] classes. You can integrate your own custom quantization backends by implementing a custom [`HfQuantizer`] and [`QuantizationConfig`], as shown in the [Contribution](./contribute) guide. @@ -165,7 +162,6 @@ model = AutoModelForCausalLM.from_pretrained( ) ``` - ## Resources To explore quantization and related performance optimization concepts more deeply, check out the following resources. diff --git a/docs/source/en/quantization/mxfp4.md b/docs/source/en/quantization/mxfp4.md index a2b9f7634c8d..dd313c5555ed 100644 --- a/docs/source/en/quantization/mxfp4.md +++ b/docs/source/en/quantization/mxfp4.md @@ -16,7 +16,7 @@ rendered properly in your Markdown viewer. # MXFP4 -Note: MXFP4 quantisation currently only works for OpenAI GPT-OSS 120b and 20b. +Note: MXFP4 quantisation currently only works for OpenAI GPT-OSS 120b and 20b. MXFP4 is a 4-bit floating point format that dramatically reduces the memory requirements of large models. Large models (GPT-OSS-120B) can fit on a single 80GB GPU and smaller models (GPT-OSS-20B) only require 16GB of memory. It uses blockwise scaling to preserve it's range and accuracy, which typically becomes degraded at lower precisions. @@ -25,7 +25,6 @@ To use MXPF4, make sure your hardware meets the following requirements. - Install Accelerate, kernels, and Triton ≥ 3.4. Only manually install Triton ≥ 3.4 if you're using PyTorch 2.7 because it is already supported in PyTorch 2.8. - NVIDIA GPU Compute Capability ≥ 7.5 which includes Tesla GPUs and newer. Use [get_device_capability](https://docs.pytorch.org/docs/stable/generated/torch.cuda.get_device_capability.html) to check Compute Capability. - ```python from torch import cuda cuda.get_device_capability() @@ -54,7 +53,6 @@ print(cfg.quantization_config) # } ``` - ## MXFP4 kernels Transformers automatically pulls the MXFP4-aware Triton kernels from the community repository when you load a model that needs them. The kernels are stored in your local cache and used during the forward pass. @@ -67,7 +65,6 @@ You can use [hf cache scan](https://huggingface.co/docs/huggingface_hub/en/guide hf cache scan ``` - ```shell REPO ID REPO TYPE SIZE ON DISK -------------------------------- --------- ------------ diff --git a/docs/source/en/quantization/overview.md b/docs/source/en/quantization/overview.md index ceab195b2b59..d607ae44660f 100644 --- a/docs/source/en/quantization/overview.md +++ b/docs/source/en/quantization/overview.md @@ -34,7 +34,7 @@ Use the Space below to help you pick a quantization method depending on your har | [GGUF / GGML (llama.cpp)](../gguf) | 🟢 | 🟢 | 🟢 | 🔴 | 🟢 | 🟢 | 🔴 | 1/8 | 🔴 | [See Notes](../gguf) | [See Notes](../gguf) | https://github.com/ggerganov/llama.cpp | | [GPTQModel](./gptq) | 🔴 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 | 2/3/4/8 | 🟢 | 🟢 | 🟢 | https://github.com/ModelCloud/GPTQModel | | [AutoGPTQ](./gptq) | 🔴 | 🔴 | 🟢 | 🟢 | 🔴 | 🔴 | 🔴 | 2/3/4/8 | 🟢 | 🟢 | 🟢 | https://github.com/AutoGPTQ/AutoGPTQ | -| [HIGGS](./higgs) | 🟢 | 🔴 | 🟢 | 🔴 | 🔴 | 🔴 | 🟢 | 2/4 | 🔴 | 🟢 | 🟢 | https://github.com/HanGuo97/flute | +| [HIGGS](./higgs) | 🟢 | 🔴 | 🟢 | 🔴 | 🔴 | 🔴 | 🟢 | 2/4 | 🔴 | 🟢 | 🟢 | https://github.com/HanGuo97/flute | | [HQQ](./hqq) | 🟢 | 🟢 | 🟢 | 🔴 | 🔴 | 🟢 | 🟢 | 1/8 | 🟢 | 🔴 | 🟢 | https://github.com/mobiusml/hqq/ | | [optimum-quanto](./quanto) | 🟢 | 🟢 | 🟢 | 🔴 | 🟢 | 🟢 | 🟢 | 2/4/8 | 🔴 | 🔴 | 🟢 | https://github.com/huggingface/optimum-quanto | | [FBGEMM_FP8](./fbgemm_fp8) | 🟢 | 🔴 | 🟢 | 🔴 | 🔴 | 🔴 | 🔴 | 8 | 🔴 | 🟢 | 🟢 | https://github.com/pytorch/FBGEMM | @@ -53,7 +53,7 @@ If you are new to quantization, we recommend checking out these beginner-friendl ## User-Friendly Quantization Tools -If you are looking for a user-friendly quantization experience, you can use the following community spaces and notebooks: +If you are looking for a user-friendly quantization experience, you can use the following community spaces and notebooks: * [Bitsandbytes Space](https://huggingface.co/spaces/bnb-community/bnb-my-repo) * [GGUF Space](https://huggingface.co/spaces/ggml-org/gguf-my-repo) diff --git a/docs/source/en/quantization/selecting.md b/docs/source/en/quantization/selecting.md index 7653e946dd80..69b989bca888 100644 --- a/docs/source/en/quantization/selecting.md +++ b/docs/source/en/quantization/selecting.md @@ -118,7 +118,7 @@ Consider the quantization method below during fine-tuning to save memory. Other methods offer PEFT compatibility, though bitsandbytes is the most established and straightforward path for QLoRA. -See the [bitsandbytes documentation](./bitsandbytes#qlora) and [PEFT Docs](https://huggingface.co/docs/peft/developer_guides/quantization#aqlm-quantization) for more details. +See the [bitsandbytes documentation](./bitsandbytes#qlora) and [PEFT Docs](https://huggingface.co/docs/peft/developer_guides/quantization#aqlm-quantization) for more details. ## Research diff --git a/docs/source/en/quantization/torchao.md b/docs/source/en/quantization/torchao.md index 6427866d0229..8778f9f3e5ea 100644 --- a/docs/source/en/quantization/torchao.md +++ b/docs/source/en/quantization/torchao.md @@ -30,7 +30,6 @@ See the table below for additional torchao features. > [!TIP] > Refer to the torchao [README.md](https://github.com/pytorch/ao#torchao-pytorch-architecture-optimization) for more details about the library. - torchao supports the [quantization techniques](https://github.com/pytorch/ao/blob/main/torchao/quantization/README.md) below. - A16W8 Float8 Dynamic Quantization @@ -43,7 +42,6 @@ torchao supports the [quantization techniques](https://github.com/pytorch/ao/blo torchao also supports module level configuration by specifying a dictionary from fully qualified name of module and its corresponding quantization config. This allows skip quantizing certain layers and using different quantization config for different modules. - Check the table below to see if your hardware is compatible. | Component | Compatibility | @@ -52,8 +50,6 @@ Check the table below to see if your hardware is compatible. | XPU Versions | ✅ pytorch2.8 | | CPU | ✅ change `device_map="cpu"` (see examples below) | - - Install torchao from PyPi or the PyTorch index with the following commands. @@ -64,13 +60,15 @@ Install torchao from PyPi or the PyTorch index with the following commands. # Stable release from Pypi which will default to CUDA 12.6 pip install --upgrade torchao transformers ``` + Stable Release from the PyTorch index - + ```bash pip install torchao --index-url https://download.pytorch.org/whl/cu126 # options are cpu/cu118/cu126/cu128 ``` + @@ -118,6 +116,7 @@ input_ids = tokenizer(input_text, return_tensors="pt").to(model.device) output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + @@ -146,6 +145,7 @@ input_ids = tokenizer(input_text, return_tensors="pt").to(model.device) output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + @@ -177,13 +177,14 @@ input_ids = tokenizer(input_text, return_tensors="pt").to(model.device) output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + ### A100 GPU - + ```py import torch from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer @@ -210,6 +211,7 @@ input_ids = tokenizer(input_text, return_tensors="pt").to(model.device) output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + @@ -245,6 +247,7 @@ input_ids = tokenizer(input_text, return_tensors="pt").to(model.device) output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + @@ -276,13 +279,14 @@ input_ids = tokenizer(input_text, return_tensors="pt").to(model.device) output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + ### Intel XPU - + ```py import torch from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer @@ -309,6 +313,7 @@ input_ids = tokenizer(input_text, return_tensors="pt").to(model.device) output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + @@ -340,14 +345,14 @@ input_ids = tokenizer(input_text, return_tensors="pt").to(model.device) output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + - ### CPU - + ```py import torch from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer @@ -373,6 +378,7 @@ input_ids = tokenizer(input_text, return_tensors="pt") output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + @@ -404,12 +410,14 @@ input_ids = tokenizer(input_text, return_tensors="pt") output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + ### Per Module Quantization #### 1. Skip quantization for certain layers With `ModuleFqnToConfig` we can specify a default configuration for all layers while skipping quantization for certain layers. + ```py import torch from transformers import AutoModelForCausalLM, AutoTokenizer, TorchAoConfig @@ -438,6 +446,7 @@ print(output_text) ``` #### 2. Quantizing different layers with different quantization configs + ```py import torch from transformers import AutoModelForCausalLM, AutoTokenizer, TorchAoConfig @@ -485,7 +494,6 @@ Note: autoquant is for GPU only right now. Create a [`TorchAoConfig`] and set to `"autoquant"`. Set the `cache_implementation` to `"static"` to automatically [torch.compile](https://pytorch.org/tutorials/intermediate/torch_compile_tutorial.html) the forward method. Finally, call `finalize_autoquant` on the quantized model to finalize the quantization and log the input shapes. - ```py import torch from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer @@ -509,7 +517,6 @@ quantized_model.finalize_autoquant() print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` - ## Serialization torchao implements [torch.Tensor subclasses](https://pytorch.org/docs/stable/notes/extending.html#subclassing-torch-tensor) for maximum flexibility in supporting new quantized torch.Tensor formats. [Safetensors](https://huggingface.co/docs/safetensors/en/index) serialization and deserialization does not work with torchao. @@ -518,15 +525,16 @@ To avoid arbitrary user code execution, torchao sets `weights_only=True` in [tor - + ```py # don't serialize model with Safetensors output_dir = "llama3-8b-int4wo-128" quantized_model.save_pretrained("llama3-8b-int4wo-128", safe_serialization=False) ``` + - + ```py # don't serialize model with Safetensors USER_ID = "your_huggingface_user_id" @@ -534,13 +542,14 @@ REPO_ID = "llama3-8b-int4wo-128" quantized_model.push_to_hub(f"{USER_ID}/llama3-8b-int4wo-128", safe_serialization=False) tokenizer.push_to_hub(f"{USER_ID}/llama3-8b-int4wo-128") ``` + - ## Loading quantized models Loading a quantized model depends on the quantization scheme. For quantization schemes, like int8 and float8, you can quantize the model on any device and also load it on any device. The example below demonstrates quantizing a model on the CPU and then loading it on CUDA or XPU. + ```py import torch from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer @@ -574,6 +583,7 @@ output = reloaded_model.generate(**input_ids, max_new_tokens=10) print(tokenizer.decode(output[0], skip_special_tokens=True)) ``` + For int4, the model can only be loaded on the same device it was quantized on because the layout is specific to the device. The example below demonstrates quantizing and loading a model on the CPU. ```py @@ -641,8 +651,6 @@ print(tokenizer.decode(output[0], skip_special_tokens=True)) > > All configuration objects accept parameters for customization (e.g., `group_size`, `scheme`, `layout`). - - ## Resources For a better sense of expected performance, view the [benchmarks](https://github.com/pytorch/ao/tree/main/torchao/quantization#benchmarks) for various models with CUDA and XPU backends. You can also run the code below to benchmark a model yourself. diff --git a/docs/source/en/run_scripts.md b/docs/source/en/run_scripts.md index ef32bf26ee02..594eb84b02a1 100644 --- a/docs/source/en/run_scripts.md +++ b/docs/source/en/run_scripts.md @@ -52,6 +52,7 @@ Start with a smaller dataset by including the `max_train_samples`, `max_eval_sam > [!WARNING] > Not all example scripts support the `max_predict_samples` parameter. Run the command below to check whether a script supports it or not. +> > ```bash > examples/pytorch/summarization/run_summarization.py -h > ``` diff --git a/docs/source/en/serialization.md b/docs/source/en/serialization.md index 831f163bed18..cf9160f5b33b 100644 --- a/docs/source/en/serialization.md +++ b/docs/source/en/serialization.md @@ -38,6 +38,7 @@ pip install optimum[exporters] > [!TIP] > Refer to the [Export a model to ONNX with optimum.exporters.onnx](https://huggingface.co/docs/optimum/exporters/onnx/usage_guides/export_a_model#exporting-a-model-to-onnx-using-the-cli) guide for all available arguments or with the command below. +> > ```bash > optimum-cli export onnx --help > ``` diff --git a/docs/source/en/serving.md b/docs/source/en/serving.md index f421a284950a..6237b09bb49e 100644 --- a/docs/source/en/serving.md +++ b/docs/source/en/serving.md @@ -356,7 +356,6 @@ ResponseCompletedEvent(response=Response(id='resp_req_0', created_at=1754060400. - ## MCP integration The `transformers serve` server is also an MCP client, so it can interact with MCP tools in agentic use cases. This, of course, requires the use of an LLM that is designed to use tools. @@ -382,7 +381,6 @@ transformers serve \ --attn_implementation sdpa_paged ``` - ### Performance tips - Use an efficient attention backend when available: @@ -401,5 +399,3 @@ transformers serve \ - `--load_in_4bit`/`--load_in_8bit` can reduce memory footprint for LoRA setups - `--force-model ` avoids per-request model hints and helps produce stable, repeatable runs - - diff --git a/docs/source/en/tasks/audio_classification.md b/docs/source/en/tasks/audio_classification.md index 52e2f965ee25..250b980be190 100644 --- a/docs/source/en/tasks/audio_classification.md +++ b/docs/source/en/tasks/audio_classification.md @@ -210,7 +210,6 @@ At this point, only three steps remain: 2. Pass the training arguments to [`Trainer`] along with the model, dataset, tokenizer, data collator, and `compute_metrics` function. 3. Call [`~Trainer.train`] to fine-tune your model. - ```py >>> training_args = TrainingArguments( ... output_dir="my_awesome_mind_model", diff --git a/docs/source/en/tasks/document_question_answering.md b/docs/source/en/tasks/document_question_answering.md index d83e025c4090..902a948307f3 100644 --- a/docs/source/en/tasks/document_question_answering.md +++ b/docs/source/en/tasks/document_question_answering.md @@ -439,6 +439,7 @@ Now that you have finetuned a LayoutLMv2 model, and uploaded it to the 🤗 Hub, way to try out your finetuned model for inference is to use it in a [`Pipeline`]. Let's take an example: + ```py >>> example = dataset["test"][2] >>> question = example["query"]["en"] diff --git a/docs/source/en/tasks/idefics.md b/docs/source/en/tasks/idefics.md index 3f8915f3cc99..5fef5953d5b0 100644 --- a/docs/source/en/tasks/idefics.md +++ b/docs/source/en/tasks/idefics.md @@ -18,26 +18,26 @@ rendered properly in your Markdown viewer. [[open-in-colab]] -While individual tasks can be tackled by fine-tuning specialized models, an alternative approach -that has recently emerged and gained popularity is to use large models for a diverse set of tasks without fine-tuning. -For instance, large language models can handle such NLP tasks as summarization, translation, classification, and more. -This approach is no longer limited to a single modality, such as text, and in this guide, we will illustrate how you can -solve image-text tasks with a large multimodal model called IDEFICS. - -[IDEFICS](../model_doc/idefics) is an open-access vision and language model based on [Flamingo](https://huggingface.co/papers/2204.14198), -a state-of-the-art visual language model initially developed by DeepMind. The model accepts arbitrary sequences of image -and text inputs and generates coherent text as output. It can answer questions about images, describe visual content, -create stories grounded in multiple images, and so on. IDEFICS comes in two variants - [80 billion parameters](https://huggingface.co/HuggingFaceM4/idefics-80b) -and [9 billion parameters](https://huggingface.co/HuggingFaceM4/idefics-9b), both of which are available on the 🤗 Hub. For each variant, you can also find fine-tuned instructed +While individual tasks can be tackled by fine-tuning specialized models, an alternative approach +that has recently emerged and gained popularity is to use large models for a diverse set of tasks without fine-tuning. +For instance, large language models can handle such NLP tasks as summarization, translation, classification, and more. +This approach is no longer limited to a single modality, such as text, and in this guide, we will illustrate how you can +solve image-text tasks with a large multimodal model called IDEFICS. + +[IDEFICS](../model_doc/idefics) is an open-access vision and language model based on [Flamingo](https://huggingface.co/papers/2204.14198), +a state-of-the-art visual language model initially developed by DeepMind. The model accepts arbitrary sequences of image +and text inputs and generates coherent text as output. It can answer questions about images, describe visual content, +create stories grounded in multiple images, and so on. IDEFICS comes in two variants - [80 billion parameters](https://huggingface.co/HuggingFaceM4/idefics-80b) +and [9 billion parameters](https://huggingface.co/HuggingFaceM4/idefics-9b), both of which are available on the 🤗 Hub. For each variant, you can also find fine-tuned instructed versions of the model adapted for conversational use cases. -This model is exceptionally versatile and can be used for a wide range of image and multimodal tasks. However, -being a large model means it requires significant computational resources and infrastructure. It is up to you to decide whether -this approach suits your use case better than fine-tuning specialized models for each individual task. +This model is exceptionally versatile and can be used for a wide range of image and multimodal tasks. However, +being a large model means it requires significant computational resources and infrastructure. It is up to you to decide whether +this approach suits your use case better than fine-tuning specialized models for each individual task. -In this guide, you'll learn how to: +In this guide, you'll learn how to: - [Load IDEFICS](#loading-the-model) and [load the quantized version of the model](#quantized-model) -- Use IDEFICS for: +- Use IDEFICS for: - [Image captioning](#image-captioning) - [Prompted image captioning](#prompted-image-captioning) - [Few-shot prompting](#few-shot-prompting) @@ -47,7 +47,7 @@ In this guide, you'll learn how to: - [Run inference in batch mode](#running-inference-in-batch-mode) - [Run IDEFICS instruct for conversational use](#idefics-instruct-for-conversational-use) -Before you begin, make sure you have all the necessary libraries installed. +Before you begin, make sure you have all the necessary libraries installed. ```bash pip install -q bitsandbytes sentencepiece accelerate transformers @@ -59,14 +59,14 @@ To run the following examples with a non-quantized version of the model checkpoi ## Loading the model -Let's start by loading the model's 9 billion parameters checkpoint: +Let's start by loading the model's 9 billion parameters checkpoint: ```py >>> checkpoint = "HuggingFaceM4/idefics-9b" ``` -Just like for other Transformers models, you need to load a processor and the model itself from the checkpoint. -The IDEFICS processor wraps a [`LlamaTokenizer`] and IDEFICS image processor into a single processor to take care of +Just like for other Transformers models, you need to load a processor and the model itself from the checkpoint. +The IDEFICS processor wraps a [`LlamaTokenizer`] and IDEFICS image processor into a single processor to take care of preparing text and image inputs for the model. ```py @@ -79,13 +79,13 @@ preparing text and image inputs for the model. >>> model = IdeficsForVisionText2Text.from_pretrained(checkpoint, dtype=torch.bfloat16, device_map="auto") ``` -Setting `device_map` to `"auto"` will automatically determine how to load and store the model weights in the most optimized +Setting `device_map` to `"auto"` will automatically determine how to load and store the model weights in the most optimized manner given existing devices. ### Quantized model -If high-memory device availability is an issue, you can load the quantized version of the model. To load the model and the -processor in 4bit precision, pass a `BitsAndBytesConfig` to the `from_pretrained` method and the model will be compressed +If high-memory device availability is an issue, you can load the quantized version of the model. To load the model and the +processor in 4bit precision, pass a `BitsAndBytesConfig` to the `from_pretrained` method and the model will be compressed on the fly while loading. ```py @@ -109,8 +109,8 @@ on the fly while loading. Now that you have the model loaded in one of the suggested ways, let's move on to exploring tasks that you can use IDEFICS for. ## Image captioning -Image captioning is the task of predicting a caption for a given image. A common application is to aid visually impaired -people navigate through different situations, for instance, explore image content online. +Image captioning is the task of predicting a caption for a given image. A common application is to aid visually impaired +people navigate through different situations, for instance, explore image content online. To illustrate the task, get an image to be captioned, e.g.: @@ -118,10 +118,10 @@ To illustrate the task, get an image to be captioned, e.g.: Image of a puppy in a flower bed
-Photo by [Hendo Wang](https://unsplash.com/@hendoo). +Photo by [Hendo Wang](https://unsplash.com/@hendoo). -IDEFICS accepts text and image prompts. However, to caption an image, you do not have to provide a text prompt to the -model, only the preprocessed input image. Without a text prompt, the model will start generating text from the +IDEFICS accepts text and image prompts. However, to caption an image, you do not have to provide a text prompt to the +model, only the preprocessed input image. Without a text prompt, the model will start generating text from the BOS (beginning-of-sequence) token thus creating a caption. As image input to the model, you can use either an image object (`PIL.Image`) or a url from which the image can be retrieved. @@ -142,15 +142,15 @@ A puppy in a flower bed -It is a good idea to include the `bad_words_ids` in the call to `generate` to avoid errors arising when increasing -the `max_new_tokens`: the model will want to generate a new `` or `` token when there +It is a good idea to include the `bad_words_ids` in the call to `generate` to avoid errors arising when increasing +the `max_new_tokens`: the model will want to generate a new `` or `` token when there is no image being generated by the model. You can set it on-the-fly as in this guide, or store in the `GenerationConfig` as described in the [Text generation strategies](../generation_strategies) guide. ## Prompted image captioning -You can extend image captioning by providing a text prompt, which the model will continue given the image. Let's take +You can extend image captioning by providing a text prompt, which the model will continue given the image. Let's take another image to illustrate:
@@ -158,7 +158,7 @@ another image to illustrate:
Photo by [Denys Nevozhai](https://unsplash.com/@dnevozhai). - + Textual and image prompts can be passed to the model's processor as a single list to create appropriate inputs. ```py @@ -178,12 +178,12 @@ This is an image of the Eiffel Tower in Paris, France. ## Few-shot prompting -While IDEFICS demonstrates great zero-shot results, your task may require a certain format of the caption, or come with +While IDEFICS demonstrates great zero-shot results, your task may require a certain format of the caption, or come with other restrictions or requirements that increase task's complexity. Few-shot prompting can be used to enable in-context learning. -By providing examples in the prompt, you can steer the model to generate results that mimic the format of given examples. +By providing examples in the prompt, you can steer the model to generate results that mimic the format of given examples. -Let's use the previous image of the Eiffel Tower as an example for the model and build a prompt that demonstrates to the model -that in addition to learning what the object in an image is, we would also like to get some interesting information about it. +Let's use the previous image of the Eiffel Tower as an example for the model and build a prompt that demonstrates to the model +that in addition to learning what the object in an image is, we would also like to get some interesting information about it. Then, let's see, if we can get the same response format for an image of the Statue of Liberty:
@@ -213,24 +213,24 @@ User: Describe this image. Assistant: An image of the Statue of Liberty. Fun fact: the Statue of Liberty is 151 feet tall. ``` -Notice that just from a single example (i.e., 1-shot) the model has learned how to perform the task. For more complex tasks, +Notice that just from a single example (i.e., 1-shot) the model has learned how to perform the task. For more complex tasks, feel free to experiment with a larger number of examples (e.g., 3-shot, 5-shot, etc.). ## Visual question answering -Visual Question Answering (VQA) is the task of answering open-ended questions based on an image. Similar to image -captioning it can be used in accessibility applications, but also in education (reasoning about visual materials), customer +Visual Question Answering (VQA) is the task of answering open-ended questions based on an image. Similar to image +captioning it can be used in accessibility applications, but also in education (reasoning about visual materials), customer service (questions about products based on images), and image retrieval. -Let's get a new image for this task: +Let's get a new image for this task:
Image of a couple having a picnic
-Photo by [Jarritos Mexican Soda](https://unsplash.com/@jarritos). +Photo by [Jarritos Mexican Soda](https://unsplash.com/@jarritos). -You can steer the model from image captioning to visual question answering by prompting it with appropriate instructions: +You can steer the model from image captioning to visual question answering by prompting it with appropriate instructions: ```py >>> prompt = [ @@ -251,11 +251,11 @@ Instruction: Provide an answer to the question. Use the image to answer. ## Image classification -IDEFICS is capable of classifying images into different categories without being explicitly trained on data containing -labeled examples from those specific categories. Given a list of categories and using its image and text understanding -capabilities, the model can infer which category the image likely belongs to. +IDEFICS is capable of classifying images into different categories without being explicitly trained on data containing +labeled examples from those specific categories. Given a list of categories and using its image and text understanding +capabilities, the model can infer which category the image likely belongs to. -Say, we have this image of a vegetable stand: +Say, we have this image of a vegetable stand:
Image of a vegetable stand @@ -286,10 +286,10 @@ In the example above we instruct the model to classify the image into a single c ## Image-guided text generation -For more creative applications, you can use image-guided text generation to generate text based on an image. This can be -useful to create descriptions of products, ads, descriptions of a scene, etc. +For more creative applications, you can use image-guided text generation to generate text based on an image. This can be +useful to create descriptions of products, ads, descriptions of a scene, etc. -Let's prompt IDEFICS to write a story based on a simple image of a red door: +Let's prompt IDEFICS to write a story based on a simple image of a red door:
Image of a red door with a pumpkin on the steps @@ -333,14 +333,14 @@ Looks like IDEFICS noticed the pumpkin on the doorstep and went with a spooky Ha -For longer outputs like this, you will greatly benefit from tweaking the text generation strategy. This can help -you significantly improve the quality of the generated output. Check out [Text generation strategies](../generation_strategies) -to learn more. +For longer outputs like this, you will greatly benefit from tweaking the text generation strategy. This can help +you significantly improve the quality of the generated output. Check out [Text generation strategies](../generation_strategies) +to learn more. ## Running inference in batch mode -All of the earlier sections illustrated IDEFICS for a single example. In a very similar fashion, you can run inference +All of the earlier sections illustrated IDEFICS for a single example. In a very similar fashion, you can run inference for a batch of examples by passing a list of prompts: ```py @@ -375,13 +375,13 @@ This is an image of a vegetable stand. ## IDEFICS instruct for conversational use -For conversational use cases, you can find fine-tuned instructed versions of the model on the 🤗 Hub: +For conversational use cases, you can find fine-tuned instructed versions of the model on the 🤗 Hub: `HuggingFaceM4/idefics-80b-instruct` and `HuggingFaceM4/idefics-9b-instruct`. -These checkpoints are the result of fine-tuning the respective base models on a mixture of supervised and instruction +These checkpoints are the result of fine-tuning the respective base models on a mixture of supervised and instruction fine-tuning datasets, which boosts the downstream performance while making the models more usable in conversational settings. -The use and prompting for the conversational use is very similar to using the base models: +The use and prompting for the conversational use is very similar to using the base models: ```py >>> import torch diff --git a/docs/source/en/tasks/image_captioning.md b/docs/source/en/tasks/image_captioning.md index f9716f29a204..89c35a50b55a 100644 --- a/docs/source/en/tasks/image_captioning.md +++ b/docs/source/en/tasks/image_captioning.md @@ -14,7 +14,6 @@ rendered properly in your Markdown viewer. --> - # Image captioning [[open-in-colab]] @@ -26,7 +25,7 @@ helps to improve content accessibility for people by describing images to them. This guide will show you how to: * Fine-tune an image captioning model. -* Use the fine-tuned model for inference. +* Use the fine-tuned model for inference. Before you begin, make sure you have all the necessary libraries installed: @@ -37,7 +36,6 @@ pip install jiwer -q We encourage you to log in to your Hugging Face account so you can upload and share your model with the community. When prompted, enter your token to log in: - ```python from huggingface_hub import notebook_login @@ -47,8 +45,7 @@ notebook_login() ## Load the Pokémon BLIP captions dataset Use the 🤗 Dataset library to load a dataset that consists of {image-caption} pairs. To create your own image captioning dataset -in PyTorch, you can follow [this notebook](https://github.com/NielsRogge/Transformers-Tutorials/blob/master/GIT/Fine_tune_GIT_on_an_image_captioning_dataset.ipynb). - +in PyTorch, you can follow [this notebook](https://github.com/NielsRogge/Transformers-Tutorials/blob/master/GIT/Fine_tune_GIT_on_an_image_captioning_dataset.ipynb). ```python from datasets import load_dataset @@ -56,6 +53,7 @@ from datasets import load_dataset ds = load_dataset("lambdalabs/pokemon-blip-captions") ds ``` + ```bash DatasetDict({ train: Dataset({ @@ -69,21 +67,19 @@ The dataset has two features, `image` and `text`. -Many image captioning datasets contain multiple captions per image. In those cases, a common strategy is to randomly sample a caption amongst the available ones during training. +Many image captioning datasets contain multiple captions per image. In those cases, a common strategy is to randomly sample a caption amongst the available ones during training. Split the dataset’s train split into a train and test set with the [`~datasets.Dataset.train_test_split`] method: - ```python ds = ds["train"].train_test_split(test_size=0.1) train_ds = ds["train"] test_ds = ds["test"] ``` -Let's visualize a couple of samples from the training set. - +Let's visualize a couple of samples from the training set. ```python from textwrap import wrap @@ -106,7 +102,7 @@ sample_images_to_visualize = [np.array(train_ds[i]["image"]) for i in range(5)] sample_captions = [train_ds[i]["text"] for i in range(5)] plot_images(sample_images_to_visualize, sample_captions) ``` - +
Sample training images
@@ -115,7 +111,7 @@ plot_images(sample_images_to_visualize, sample_captions) Since the dataset has two modalities (image and text), the pre-processing pipeline will preprocess images and the captions. -To do so, load the processor class associated with the model you are about to fine-tune. +To do so, load the processor class associated with the model you are about to fine-tune. ```python from transformers import AutoProcessor @@ -124,7 +120,7 @@ checkpoint = "microsoft/git-base" processor = AutoProcessor.from_pretrained(checkpoint) ``` -The processor will internally pre-process the image (which includes resizing, and pixel scaling) and tokenize the caption. +The processor will internally pre-process the image (which includes resizing, and pixel scaling) and tokenize the caption. ```python def transforms(example_batch): @@ -139,13 +135,12 @@ train_ds.set_transform(transforms) test_ds.set_transform(transforms) ``` -With the dataset ready, you can now set up the model for fine-tuning. +With the dataset ready, you can now set up the model for fine-tuning. ## Load a base model Load the ["microsoft/git-base"](https://huggingface.co/microsoft/git-base) into a [`AutoModelForCausalLM`](https://huggingface.co/docs/transformers/model_doc/auto#transformers.AutoModelForCausalLM) object. - ```python from transformers import AutoModelForCausalLM @@ -154,10 +149,9 @@ model = AutoModelForCausalLM.from_pretrained(checkpoint) ## Evaluate -Image captioning models are typically evaluated with the [Rouge Score](https://huggingface.co/spaces/evaluate-metric/rouge) or [Word Error Rate](https://huggingface.co/spaces/evaluate-metric/wer). For this guide, you will use the Word Error Rate (WER). - -We use the 🤗 Evaluate library to do so. For potential limitations and other gotchas of the WER, refer to [this guide](https://huggingface.co/spaces/evaluate-metric/wer). +Image captioning models are typically evaluated with the [Rouge Score](https://huggingface.co/spaces/evaluate-metric/rouge) or [Word Error Rate](https://huggingface.co/spaces/evaluate-metric/wer). For this guide, you will use the Word Error Rate (WER). +We use the 🤗 Evaluate library to do so. For potential limitations and other gotchas of the WER, refer to [this guide](https://huggingface.co/spaces/evaluate-metric/wer). ```python from evaluate import load @@ -177,11 +171,10 @@ def compute_metrics(eval_pred): ## Train! -Now, you are ready to start fine-tuning the model. You will use the 🤗 [`Trainer`] for this. +Now, you are ready to start fine-tuning the model. You will use the 🤗 [`Trainer`] for this. First, define the training arguments using [`TrainingArguments`]. - ```python from transformers import TrainingArguments, Trainer @@ -208,7 +201,7 @@ training_args = TrainingArguments( ) ``` -Then pass them along with the datasets and the model to 🤗 Trainer. +Then pass them along with the datasets and the model to 🤗 Trainer. ```python trainer = Trainer( @@ -222,7 +215,7 @@ trainer = Trainer( To start training, simply call [`~Trainer.train`] on the [`Trainer`] object. -```python +```python trainer.train() ``` @@ -230,7 +223,6 @@ You should see the training loss drop smoothly as training progresses. Once training is completed, share your model to the Hub with the [`~Trainer.push_to_hub`] method so everyone can use your model: - ```python trainer.push_to_hub() ``` @@ -239,7 +231,6 @@ trainer.push_to_hub() Take a sample image from `test_ds` to test the model. - ```python from PIL import Image import requests @@ -252,7 +243,7 @@ image
Test image
- + Prepare image for the model. ```python @@ -263,13 +254,14 @@ inputs = processor(images=image, return_tensors="pt").to(device) pixel_values = inputs.pixel_values ``` -Call [`generate`] and decode the predictions. +Call [`generate`] and decode the predictions. ```python generated_ids = model.generate(pixel_values=pixel_values, max_length=50) generated_caption = processor.batch_decode(generated_ids, skip_special_tokens=True)[0] print(generated_caption) ``` + ```bash a drawing of a pink and blue pokemon ``` diff --git a/docs/source/en/tasks/image_classification.md b/docs/source/en/tasks/image_classification.md index 39b013f129cc..4754a91bd482 100644 --- a/docs/source/en/tasks/image_classification.md +++ b/docs/source/en/tasks/image_classification.md @@ -175,7 +175,6 @@ Your `compute_metrics` function is ready to go now, and you'll return to it when ## Train - If you aren't familiar with finetuning a model with the [`Trainer`], take a look at the basic tutorial [here](../training#train-with-pytorch-trainer)! @@ -238,7 +237,6 @@ Once training is completed, share your model to the Hub with the [`~transformers >>> trainer.push_to_hub() ``` - For a more in-depth example of how to finetune a model for image classification, take a look at the corresponding [PyTorch notebook](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/image_classification.ipynb). diff --git a/docs/source/en/tasks/image_feature_extraction.md b/docs/source/en/tasks/image_feature_extraction.md index 455a2b425d41..e08ba89e4dd8 100644 --- a/docs/source/en/tasks/image_feature_extraction.md +++ b/docs/source/en/tasks/image_feature_extraction.md @@ -27,7 +27,7 @@ In this guide, you will: ## Image Similarity using `image-feature-extraction` Pipeline -We have two images of cats sitting on top of fish nets, one of them is generated. +We have two images of cats sitting on top of fish nets, one of them is generated. ```python from PIL import Image @@ -66,7 +66,7 @@ print(outputs) # [[[-0.03909236937761307, 0.43381670117378235, -0.06913255900144577, ``` -To get the similarity score, we need to pass them to a similarity function. +To get the similarity score, we need to pass them to a similarity function. ```python from torch.nn.functional import cosine_similarity @@ -131,4 +131,3 @@ print(similarity_score) # tensor([0.6061], device='cuda:0', grad_fn=) ``` - diff --git a/docs/source/en/tasks/image_text_to_text.md b/docs/source/en/tasks/image_text_to_text.md index b34f4edf90f6..5412882b59fe 100644 --- a/docs/source/en/tasks/image_text_to_text.md +++ b/docs/source/en/tasks/image_text_to_text.md @@ -63,7 +63,6 @@ The image inputs look like the following. A bee on a pink flower
- ```python from PIL import Image import requests @@ -76,7 +75,6 @@ images = [Image.open(requests.get(img_urls[0], stream=True).raw), Below is an example of the chat template. We can feed conversation turns and the last message as an input by appending it at the end of the template. - ```python messages = [ { @@ -207,7 +205,6 @@ We can use [text streaming](./generation_strategies#streaming) for a better gene Assume we have an application that keeps chat history and takes in the new user input. We will preprocess the inputs as usual and initialize [`TextIteratorStreamer`] to handle the generation in a separate thread. This allows you to stream the generated text tokens in real-time. Any generation arguments can be passed to [`TextIteratorStreamer`]. - ```python import time from transformers import TextIteratorStreamer diff --git a/docs/source/en/tasks/image_to_image.md b/docs/source/en/tasks/image_to_image.md index da6a57ac9aa9..6c4cdf585f07 100644 --- a/docs/source/en/tasks/image_to_image.md +++ b/docs/source/en/tasks/image_to_image.md @@ -18,7 +18,7 @@ rendered properly in your Markdown viewer. [[open-in-colab]] -Image-to-Image task is the task where an application receives an image and outputs another image. This has various subtasks, including image enhancement (super resolution, low light enhancement, deraining and so on), image inpainting, and more. +Image-to-Image task is the task where an application receives an image and outputs another image. This has various subtasks, including image enhancement (super resolution, low light enhancement, deraining and so on), image inpainting, and more. This guide will show you how to: - Use an image-to-image pipeline for super resolution task, @@ -32,7 +32,7 @@ Let's begin by installing the necessary libraries. pip install transformers ``` -We can now initialize the pipeline with a [Swin2SR model](https://huggingface.co/caidas/swin2SR-lightweight-x2-64). We can then infer with the pipeline by calling it with an image. As of now, only [Swin2SR models](https://huggingface.co/models?sort=trending&search=swin2sr) are supported in this pipeline. +We can now initialize the pipeline with a [Swin2SR model](https://huggingface.co/caidas/swin2SR-lightweight-x2-64). We can then infer with the pipeline by calling it with an image. As of now, only [Swin2SR models](https://huggingface.co/models?sort=trending&search=swin2sr) are supported in this pipeline. ```python from transformers import pipeline, infer_device @@ -53,19 +53,22 @@ image = Image.open(requests.get(url, stream=True).raw) print(image.size) ``` + ```bash # (532, 432) ``` +
Photo of a cat
-We can now do inference with the pipeline. We will get an upscaled version of the cat image. +We can now do inference with the pipeline. We will get an upscaled version of the cat image. ```python upscaled = pipe(image) print(upscaled.size) ``` + ```bash # (1072, 880) ``` @@ -79,7 +82,7 @@ model = Swin2SRForImageSuperResolution.from_pretrained("caidas/swin2SR-lightweig processor = Swin2SRImageProcessor("caidas/swin2SR-lightweight-x2-64") ``` -`pipeline` abstracts away the preprocessing and postprocessing steps that we have to do ourselves, so let's preprocess the image. We will pass the image to the processor and then move the pixel values to GPU. +`pipeline` abstracts away the preprocessing and postprocessing steps that we have to do ourselves, so let's preprocess the image. We will pass the image to the processor and then move the pixel values to GPU. ```python pixel_values = processor(image, return_tensors="pt").pixel_values @@ -96,7 +99,8 @@ import torch with torch.no_grad(): outputs = model(pixel_values) ``` -Output is an object of type `ImageSuperResolutionOutput` that looks like below 👇 + +Output is an object of type `ImageSuperResolutionOutput` that looks like below 👇 ``` (loss=None, reconstruction=tensor([[[[0.8270, 0.8269, 0.8275, ..., 0.7463, 0.7446, 0.7453], @@ -108,6 +112,7 @@ Output is an object of type `ImageSuperResolutionOutput` that looks like below [0.5927, 0.5914, 0.5922, ..., 0.0664, 0.0694, 0.0718]]]], device='cuda:0'), hidden_states=None, attentions=None) ``` + We need to get the `reconstruction` and post-process it for visualization. Let's see how it looks like. ```python @@ -128,6 +133,7 @@ output = np.moveaxis(output, source=0, destination=-1) output = (output * 255.0).round().astype(np.uint8) Image.fromarray(output) ``` +
Upscaled photo of a cat
diff --git a/docs/source/en/tasks/keypoint_detection.md b/docs/source/en/tasks/keypoint_detection.md index 3a5871d01a2b..c850c67ae153 100644 --- a/docs/source/en/tasks/keypoint_detection.md +++ b/docs/source/en/tasks/keypoint_detection.md @@ -18,7 +18,7 @@ rendered properly in your Markdown viewer. [[open-in-colab]] -Keypoint detection identifies and locates specific points of interest within an image. These keypoints, also known as landmarks, represent meaningful features of objects, such as facial features or object parts. These models take an image input and return the following outputs: +Keypoint detection identifies and locates specific points of interest within an image. These keypoints, also known as landmarks, represent meaningful features of objects, such as facial features or object parts. These models take an image input and return the following outputs: - **Keypoints and Scores**: Points of interest and their confidence scores. - **Descriptors**: A representation of the image region surrounding each keypoint, capturing its texture, gradient, orientation and other properties. @@ -36,15 +36,14 @@ model = SuperPointForKeypointDetection.from_pretrained("magic-leap-community/sup Let's test the model on the images below.
- Bee - Cats
- ```python import torch from PIL import Image @@ -93,7 +92,7 @@ image_sizes = [(image.size[1], image.size[0]) for image in images] outputs = processor.post_process_keypoint_detection(outputs, image_sizes) ``` -The outputs are now a list of dictionaries where each dictionary is a processed output of keypoints, scores and descriptors. +The outputs are now a list of dictionaries where each dictionary is a processed output of keypoints, scores and descriptors. ```python [{'keypoints': tensor([[ 226, 57], @@ -144,11 +143,10 @@ for i in range(len(images)): Below you can see the outputs.
- Bee - Cats
- diff --git a/docs/source/en/tasks/keypoint_matching.md b/docs/source/en/tasks/keypoint_matching.md index f7065f315211..aff16a937d7a 100644 --- a/docs/source/en/tasks/keypoint_matching.md +++ b/docs/source/en/tasks/keypoint_matching.md @@ -34,15 +34,15 @@ model = AutoModelForKeypointMatching.from_pretrained("zju-community/matchanythin Load two images that have the same object of interest. The second photo is taken a second apart, it's colors are edited, and it is further cropped and rotated.
- Bee - Bee edited
-```python +```python from transformers.image_utils import load_image image1 = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg") image2 = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee_edited.jpg") @@ -82,16 +82,16 @@ Here's the outputs. [1521, 2560]], dtype=torch.int32), 'matching_scores': tensor([0.2189, 0.2073, 0.2414, ... ])}] -``` +``` We have trimmed the output but there's 401 matches! ```python len(outputs[0]["keypoints0"]) # 401 -``` +``` -We can visualize them using the processor's [`~EfficientLoFTRImageProcessor.visualize_keypoint_matching`] method. +We can visualize them using the processor's [`~EfficientLoFTRImageProcessor.visualize_keypoint_matching`] method. ```python plot_images = processor.visualize_keypoint_matching(images, outputs) @@ -100,7 +100,7 @@ plot_images ![Matched Image](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/matched_bees.png) -Optionally, you can use the [`Pipeline`] API and set the task to `keypoint-matching`. +Optionally, you can use the [`Pipeline`] API and set the task to `keypoint-matching`. ```python from transformers import pipeline diff --git a/docs/source/en/tasks/knowledge_distillation_for_image_classification.md b/docs/source/en/tasks/knowledge_distillation_for_image_classification.md index 7c4a684d3c05..d4b3dd8511df 100644 --- a/docs/source/en/tasks/knowledge_distillation_for_image_classification.md +++ b/docs/source/en/tasks/knowledge_distillation_for_image_classification.md @@ -52,7 +52,6 @@ processed_datasets = dataset.map(process, batched=True) Essentially, we want the student model (a randomly initialized MobileNet) to mimic the teacher model (fine-tuned vision transformer). To achieve this, we first get the logits output from the teacher and the student. Then, we divide each of them by the parameter `temperature` which controls the importance of each soft target. A parameter called `lambda` weighs the importance of the distillation loss. In this example, we will use `temperature=5` and `lambda=0.5`. We will use the Kullback-Leibler Divergence loss to compute the divergence between the student and teacher. Given two data P and Q, KL Divergence explains how much extra information we need to represent P using Q. If two are identical, their KL divergence is zero, as there's no other information needed to explain P from Q. Thus, in the context of knowledge distillation, KL divergence is useful. - ```python from transformers import TrainingArguments, Trainer, infer_device import torch diff --git a/docs/source/en/tasks/mask_generation.md b/docs/source/en/tasks/mask_generation.md index 5f66e68c2452..06ba26ea1233 100644 --- a/docs/source/en/tasks/mask_generation.md +++ b/docs/source/en/tasks/mask_generation.md @@ -16,22 +16,22 @@ rendered properly in your Markdown viewer. # Mask Generation -Mask generation is the task of generating semantically meaningful masks for an image. -This task is very similar to [image segmentation](semantic_segmentation), but many differences exist. Image segmentation models are trained on labeled datasets and are limited to the classes they have seen during training; they return a set of masks and corresponding classes, given an image. +Mask generation is the task of generating semantically meaningful masks for an image. +This task is very similar to [image segmentation](semantic_segmentation), but many differences exist. Image segmentation models are trained on labeled datasets and are limited to the classes they have seen during training; they return a set of masks and corresponding classes, given an image. -Mask generation models are trained on large amounts of data and operate in two modes. -- Prompting mode: In this mode, the model takes in an image and a prompt, where a prompt can be a 2D point location (XY coordinates) in the image within an object or a bounding box surrounding an object. In prompting mode, the model only returns the mask over the object -that the prompt is pointing out. -- Segment Everything mode: In segment everything, given an image, the model generates every mask in the image. To do so, a grid of points is generated and overlaid on the image for inference. +Mask generation models are trained on large amounts of data and operate in two modes. +- Prompting mode: In this mode, the model takes in an image and a prompt, where a prompt can be a 2D point location (XY coordinates) in the image within an object or a bounding box surrounding an object. In prompting mode, the model only returns the mask over the object +that the prompt is pointing out. +- Segment Everything mode: In segment everything, given an image, the model generates every mask in the image. To do so, a grid of points is generated and overlaid on the image for inference. -Mask generation task is supported by [Segment Anything Model (SAM)](model_doc/sam). It's a powerful model that consists of a Vision Transformer-based image encoder, a prompt encoder, and a two-way transformer mask decoder. Images and prompts are encoded, and the decoder takes these embeddings and generates valid masks. +Mask generation task is supported by [Segment Anything Model (SAM)](model_doc/sam). It's a powerful model that consists of a Vision Transformer-based image encoder, a prompt encoder, and a two-way transformer mask decoder. Images and prompts are encoded, and the decoder takes these embeddings and generates valid masks.
SAM Architecture
-SAM serves as a powerful foundation model for segmentation as it has large data coverage. It is trained on -[SA-1B](https://ai.meta.com/datasets/segment-anything/), a dataset with 1 million images and 1.1 billion masks. +SAM serves as a powerful foundation model for segmentation as it has large data coverage. It is trained on +[SA-1B](https://ai.meta.com/datasets/segment-anything/), a dataset with 1 million images and 1.1 billion masks. In this guide, you will learn how to: - Infer in segment everything mode with batching, @@ -114,7 +114,6 @@ Below is the original image in grayscale with colorful maps overlaid. Very impre Visualized
- ## Model Inference ### Point Prompting @@ -132,7 +131,7 @@ processor = SamProcessor.from_pretrained("facebook/sam-vit-base") To do point prompting, pass the input point to the processor, then take the processor output and pass it to the model for inference. To post-process the model output, pass the outputs and -`original_sizes` and `reshaped_input_sizes` we take from the processor's initial output. We need to pass these +`original_sizes` and `reshaped_input_sizes` we take from the processor's initial output. We need to pass these since the processor resizes the image, and the output needs to be extrapolated. ```python @@ -143,6 +142,7 @@ with torch.no_grad(): outputs = model(**inputs) masks = processor.image_processor.post_process_masks(outputs.pred_masks.cpu(), inputs["original_sizes"].cpu(), inputs["reshaped_input_sizes"].cpu()) ``` + We can visualize the three masks in the `masks` output. ```python @@ -177,10 +177,9 @@ plt.show() ### Box Prompting You can also do box prompting in a similar fashion to point prompting. You can simply pass the input box in the format of a list -`[x_min, y_min, x_max, y_max]` format along with the image to the `processor`. Take the processor output and directly pass it +`[x_min, y_min, x_max, y_max]` format along with the image to the `processor`. Take the processor output and directly pass it to the model, then post-process the output again. - ```python # bounding box around the bee box = [2350, 1600, 2850, 2100] @@ -219,7 +218,7 @@ plt.show() Visualized Bbox
-You can see the inference output below. +You can see the inference output below. ```python fig, ax = plt.subplots() @@ -233,4 +232,3 @@ plt.show()
Visualized Inference
- diff --git a/docs/source/en/tasks/monocular_depth_estimation.md b/docs/source/en/tasks/monocular_depth_estimation.md index c90abce1cd57..aef9bd22c4d3 100644 --- a/docs/source/en/tasks/monocular_depth_estimation.md +++ b/docs/source/en/tasks/monocular_depth_estimation.md @@ -23,7 +23,7 @@ a single camera viewpoint. Monocular depth estimation has various applications, including 3D reconstruction, augmented reality, autonomous driving, and robotics. It is a challenging task as it requires the model to understand the complex relationships between objects in the scene and the corresponding depth information, which can be affected by factors such as lighting conditions, -occlusion, and texture. +occlusion, and texture. There are two main depth estimation categories: @@ -143,7 +143,7 @@ Let's post-process the results to remove any padding and resize the depth map to

In the original implementation ZoeDepth model performs inference on both the original and flipped images and averages out the results. The post_process_depth_estimation function can handle this for us by passing the flipped outputs to the optional outputs_flipped argument:

-
>>> with torch.no_grad():   
+
>>> with torch.no_grad():
 ...     outputs = model(pixel_values)
 ...     outputs_flipped = model(pixel_values=torch.flip(inputs.pixel_values, dims=[3]))
 >>> post_processed_output = image_processor.post_process_depth_estimation(
diff --git a/docs/source/en/tasks/multiple_choice.md b/docs/source/en/tasks/multiple_choice.md
index 3f4c9d4637fb..d35f108ecce5 100644
--- a/docs/source/en/tasks/multiple_choice.md
+++ b/docs/source/en/tasks/multiple_choice.md
@@ -113,6 +113,7 @@ To apply the preprocessing function over the entire dataset, use 🤗 Datasets [
 ```
 
 To create a batch of examples, it's more efficient to *dynamically pad* the sentences to the longest length in a batch during collation, instead of padding the whole dataset to the maximum length. [`DataCollatorForMultipleChoice`] flattens all the model inputs, applies padding, and then unflattens the results.
+
 ```py
 >>> from transformers import DataCollatorForMultipleChoice
 >>> collator = DataCollatorForMultipleChoice(tokenizer=tokenizer)
@@ -197,7 +198,6 @@ Once training is completed, share your model to the Hub with the [`~transformers
 >>> trainer.push_to_hub()
 ```
 
-
 
 
 For a more in-depth example of how to finetune a model for multiple choice, take a look at the corresponding
diff --git a/docs/source/en/tasks/object_detection.md b/docs/source/en/tasks/object_detection.md
index 394e77104b74..093644b662fe 100644
--- a/docs/source/en/tasks/object_detection.md
+++ b/docs/source/en/tasks/object_detection.md
@@ -171,11 +171,11 @@ To get an even better understanding of the data, visualize an example in the dat
 
 >>> image
 ```
+
 
CPPE-5 Image Example
- To visualize the bounding boxes with associated labels, you can get the labels from the dataset's metadata, specifically the `category` field. You'll also want to create dictionaries that map a label id to a label class (`id2label`) and the other way around (`label2id`). @@ -576,6 +576,7 @@ Finally, bring everything together, and call [`~transformers.Trainer.train`]: >>> trainer.train() ``` +
@@ -1487,6 +1488,7 @@ Now that you have finetuned a model, evaluated it, and uploaded it to the Huggin ``` Load model and image processor from the Hugging Face Hub (skip to use already trained in this session): + ```py >>> from transformers import infer_device diff --git a/docs/source/en/tasks/prompting.md b/docs/source/en/tasks/prompting.md index eb8e61d67aaf..2d115d4e5448 100644 --- a/docs/source/en/tasks/prompting.md +++ b/docs/source/en/tasks/prompting.md @@ -127,7 +127,6 @@ for output in outputs: print(f"Result: {output['generated_text']}") ``` - While the basic few-shot prompting approach embedded examples within a single text string, the chat template format offers the following benefits. - The model may have a potentially improved understanding because it can better recognize the pattern and the expected roles of user input and assistant output. diff --git a/docs/source/en/tasks/semantic_segmentation.md b/docs/source/en/tasks/semantic_segmentation.md index 5d3c8e70aa1f..08d68047dc6a 100644 --- a/docs/source/en/tasks/semantic_segmentation.md +++ b/docs/source/en/tasks/semantic_segmentation.md @@ -69,6 +69,7 @@ results ``` The segmentation pipeline output includes a mask for every predicted class. + ```bash [{'score': None, 'label': 'road', @@ -107,6 +108,7 @@ Taking a look at the mask for the car class, we can see every car is classified ```python results[-1]["mask"] ``` +
Semantic Segmentation Output
@@ -135,11 +137,13 @@ As you can see below, there are multiple cars classified, and there's no classif 'label': 'person', 'mask': }] ``` + Checking out one of the car masks below. ```python results[2]["mask"] ``` +
Semantic Segmentation Output
@@ -151,6 +155,7 @@ panoptic_segmentation = pipeline("image-segmentation", "facebook/mask2former-swi results = panoptic_segmentation(image) results ``` + As you can see below, we have more classes. We will later illustrate to see that every pixel is classified into one of the classes. ```bash @@ -206,7 +211,6 @@ To see all architectures and checkpoints compatible with this task, we recommend - ### Load SceneParse150 dataset Start by loading a smaller subset of the SceneParse150 dataset from the 🤗 Datasets library. This'll give you a chance to experiment and make sure everything works before spending more time training on the full dataset. @@ -473,7 +477,6 @@ Reload the dataset and load an image for inference. Image of bedroom
- We will now see how to infer without a pipeline. Process the image with an image processor and place the `pixel_values` on a GPU: ```py @@ -503,7 +506,6 @@ Next, rescale the logits to the original image size: >>> pred_seg = upsampled_logits.argmax(dim=1)[0] ``` - To visualize the results, load the [dataset color palette](https://github.com/tensorflow/models/blob/3f1ca33afe3c1631b733ea7e40c294273b9e406d/research/deeplab/utils/get_dataset_colormap.py#L51) as `ade_palette()` that maps each class to their RGB values. ```py diff --git a/docs/source/en/tasks/summarization.md b/docs/source/en/tasks/summarization.md index c57097421fbc..b2f2beebc806 100644 --- a/docs/source/en/tasks/summarization.md +++ b/docs/source/en/tasks/summarization.md @@ -213,7 +213,6 @@ Once training is completed, share your model to the Hub with the [`~transformers >>> trainer.push_to_hub() ``` - For a more in-depth example of how to finetune a model for summarization, take a look at the corresponding diff --git a/docs/source/en/tasks/token_classification.md b/docs/source/en/tasks/token_classification.md index 49b0fcf216b8..5096298affd1 100644 --- a/docs/source/en/tasks/token_classification.md +++ b/docs/source/en/tasks/token_classification.md @@ -242,7 +242,6 @@ Before you start training your model, create a map of the expected ids to their ... } ``` - If you aren't familiar with finetuning a model with the [`Trainer`], take a look at the basic tutorial [here](../training#train-with-pytorch-trainer)! @@ -298,7 +297,6 @@ Once training is completed, share your model to the Hub with the [`~transformers >>> trainer.push_to_hub() ``` - For a more in-depth example of how to finetune a model for token classification, take a look at the corresponding diff --git a/docs/source/en/tasks/video_classification.md b/docs/source/en/tasks/video_classification.md index b387a8320dfc..bae638bd84ed 100644 --- a/docs/source/en/tasks/video_classification.md +++ b/docs/source/en/tasks/video_classification.md @@ -363,7 +363,6 @@ Leverage [`Trainer`](https://huggingface.co/docs/transformers/main_classes/train Most of the training arguments are self-explanatory, but one that is quite important here is `remove_unused_columns=False`. This one will drop any features not used by the model's call function. By default it's `True` because usually it's ideal to drop unused feature columns, making it easier to unpack inputs into the model's call function. But, in this case, you need the unused features ('video' in particular) in order to create `pixel_values` (which is a mandatory key our model expects in its inputs). - ```py >>> from transformers import TrainingArguments, Trainer @@ -477,7 +476,6 @@ The simplest way to try out your fine-tuned model for inference is to use it in You can also manually replicate the results of the `pipeline` if you'd like. - ```py >>> def run_inference(model, video): ... # (num_frames, num_channels, height, width) diff --git a/docs/source/en/tasks/video_text_to_text.md b/docs/source/en/tasks/video_text_to_text.md index 0e0191af5884..b0f698f039ea 100644 --- a/docs/source/en/tasks/video_text_to_text.md +++ b/docs/source/en/tasks/video_text_to_text.md @@ -18,9 +18,9 @@ rendered properly in your Markdown viewer. [[open-in-colab]] -Video-text-to-text models, also known as video language models or vision language models with video input, are language models that take a video input. These models can tackle various tasks, from video question answering to video captioning. +Video-text-to-text models, also known as video language models or vision language models with video input, are language models that take a video input. These models can tackle various tasks, from video question answering to video captioning. -These models have nearly the same architecture as [image-text-to-text](../image_text_to_text) models except for some changes to accept video data, since video data is essentially image frames with temporal dependencies. Some image-text-to-text models take in multiple images, but this alone is inadequate for a model to accept videos. Moreover, video-text-to-text models are often trained with all vision modalities. Each example might have videos, multiple videos, images and multiple images. Some of these models can also take interleaved inputs. For example, you can refer to a specific video inside a string of text by adding a video token in text like "What is happening in this video? `
Pass the image and the candidate object labels to look for to the pipeline. -Here we pass the image directly; other suitable options include a local path to an image or an image url. We also pass text descriptions for all items we want to query the image for. +Here we pass the image directly; other suitable options include a local path to an image or an image url. We also pass text descriptions for all items we want to query the image for. ```py >>> predictions = detector( diff --git a/docs/source/en/testing.md b/docs/source/en/testing.md index 497c6b019311..78c32a580976 100644 --- a/docs/source/en/testing.md +++ b/docs/source/en/testing.md @@ -16,7 +16,6 @@ rendered properly in your Markdown viewer. # Testing - Let's take a look at how 🤗 Transformers models are tested and how you can write new tests and improve the existing ones. There are 2 test suites in the repository: @@ -51,12 +50,8 @@ RUN_SLOW=1 pytest examples/ The results can be observed [here](https://github.com/huggingface/transformers/actions). - - ## Running tests - - ### Choosing which tests to run This document goes into many details of how tests can be run. If after reading everything, you need even more details @@ -89,8 +84,6 @@ which tells pytest to: - do not capture output - run in verbose mode - - ### Getting the list of all tests All tests of the test suite: @@ -187,7 +180,6 @@ Sometimes you need to run `accelerate` tests on your models. For that you can ju RUN_SLOW=1 pytest -m accelerate_tests tests/models/opt/test_modeling_opt.py ``` - ### Run documentation tests In order to test whether the documentation examples are correct, you should check that the `doctests` are passing. @@ -217,9 +209,11 @@ Example: ``` Just run the following line to automatically test every docstring example in the desired file: + ```bash pytest --doctest-modules ``` + If the file has a markdown extension, you should add the `--doctest-glob="*.md"` argument. ### Run only modified tests @@ -271,7 +265,6 @@ directory. [pytest-watch](https://github.com/joeyespo/pytest-watch) is an alternative implementation of this functionality. - ### Skip a test module If you want to run all test modules, except a few you can exclude them by giving an explicit list of tests to run. For @@ -307,7 +300,6 @@ It's good to repeat the tests several times, in sequence, randomly, or in sets, inter-dependency and state-related bugs (tear down). And the straightforward multiple repetition is just good to detect some problems that get uncovered by randomness of DL. - #### Repeat tests - [pytest-flakefinder](https://github.com/dropbox/pytest-flakefinder): @@ -403,8 +395,6 @@ pytest -p no:sugar or uninstall it. - - #### Report each sub-test name and its progress For a single or a group of tests via `pytest` (after `pip install pytest-pspec`): @@ -457,7 +447,6 @@ decorators are used to set the requirements of tests CPU/GPU/XPU/TPU-wise: Let's depict the GPU requirements in the following table: - | n gpus | decorator | |--------|--------------------------------| | `>= 0` | `@require_torch` | @@ -466,7 +455,6 @@ Let's depict the GPU requirements in the following table: | `< 2` | `@require_torch_non_multi_gpu` | | `< 3` | `@require_torch_up_to_2_gpus` | - For example, here is a test that must be run only when there are 2 or more GPUs available and pytorch is installed: ```python no-style @@ -520,6 +508,7 @@ Certain devices will require an additional import after importing `torch` for th ```bash TRANSFORMERS_TEST_BACKEND="torch_npu" pytest tests/utils/test_logging.py ``` + Alternative backends may also require the replacement of device-specific functions. For example `torch.cuda.manual_seed` may need to be replaced with a device-specific seed setter like `torch.npu.manual_seed` or `torch.xpu.manual_seed` to correctly set a random seed on the device. To specify a new backend with backend-specific device functions when running the test suite, create a Python device specification file `spec.py` in the format: ```python @@ -536,6 +525,7 @@ MANUAL_SEED_FN = torch.npu.manual_seed EMPTY_CACHE_FN = torch.npu.empty_cache DEVICE_COUNT_FN = torch.npu.device_count ``` + This format also allows for specification of any additional imports required. To use this file to replace equivalent methods in the test suite, set the environment variable `TRANSFORMERS_TEST_DEVICE_SPEC` to the path of the spec file, e.g. `TRANSFORMERS_TEST_DEVICE_SPEC=spec.py`. Currently, only `MANUAL_SEED_FN`, `EMPTY_CACHE_FN` and `DEVICE_COUNT_FN` are supported for device-specific dispatch. @@ -610,7 +600,6 @@ You can read [here](https://docs.pytest.org/en/stable/unittest.html) which featu thing to remember is that most `pytest` fixtures don't work. Neither parametrization, but we use the module `parameterized` that works in a similar way. - ### Parametrization Often, there is a need to run the same test multiple times, but with different arguments. It could be done from within @@ -719,8 +708,6 @@ pytest test_this2.py::test_floor[negative--1.5--2.0] test_this2.py::test_floor[i as in the previous example. - - ### Files and directories In tests often we need to know where things are relative to the current test file, and it's not trivial since the test @@ -843,7 +830,6 @@ otherwise. If you need to temporary override `sys.path` to import from another test for example, you can use the `ExtendSysPath` context manager. Example: - ```python import os from transformers.testing_utils import ExtendSysPath @@ -893,7 +879,6 @@ or the `xfail` way: def test_feature_x(): ``` - Here's how to skip a test based on internal checks within the test: ```python @@ -1018,7 +1003,6 @@ That report is also useful to find slow outliers that aren't marked as such, or If you notice that the test suite starts getting slow on CI, the top listing of this report will show the slowest tests. - ### Testing the stdout/stderr output In order to test functions that write to `stdout` and/or `stderr`, the test can access those streams using the @@ -1141,7 +1125,6 @@ print(cs.err, cs.out) Also, to aid debugging test issues, by default these context managers automatically replay the captured streams on exit from the context. - ### Capturing logger stream If you need to validate the output of a logger, you can use `CaptureLogger`: @@ -1193,7 +1176,6 @@ called if anything. This helper method creates a copy of the `os.environ` object, so the original remains intact. - ### Getting reproducible results In some situations you may want to remove randomness for your tests. To get identical reproducible results set, you @@ -1241,9 +1223,6 @@ To trigger a self-push workflow CI job, you must: 4. Then you can see the job appear [here](https://github.com/huggingface/transformers/actions/workflows/self-push.yml). It may not run right away if there is a backlog. - - - ## Testing Experimental CI Features Testing CI features can be potentially problematic as it can interfere with the normal CI functioning. Therefore if a diff --git a/docs/source/en/tiny_agents.md b/docs/source/en/tiny_agents.md index dc53d05a4bff..7266f0236a63 100644 --- a/docs/source/en/tiny_agents.md +++ b/docs/source/en/tiny_agents.md @@ -42,4 +42,3 @@ Image URL: https://evalstate-flux1-schnell.hf.space/gradio_api/file=/tmp/gradio/ I have generated an image of a cat on the moon using the Flux 1 Schnell Image Generator. The image is 1024x1024 pixels and was created with 4 inference steps. Let me know if you would like to make any changes or need further assistance! ``` - diff --git a/docs/source/en/trainer.md b/docs/source/en/trainer.md index 48325da6893c..32f14bc41da3 100644 --- a/docs/source/en/trainer.md +++ b/docs/source/en/trainer.md @@ -346,7 +346,6 @@ use_cpu: false - Run [accelerate_launch](https://hf.co/docs/accelerate/package_reference/cli#accelerate-launch) to start training with the configurations set in `config_file.yaml`. This file is saved to the Accelerate cache folder and automatically loaded when you run `accelerate_launch`. The example below launches the [run_glue.py](../../../examples/pytorch/text-classification/run_glue) script with the FSDP configuration shown earlier. Parameters from the `config_file.yaml` file can also be directly set in the command line. diff --git a/docs/source/en/training.md b/docs/source/en/training.md index ed992e8152d9..ccee25704fa3 100644 --- a/docs/source/en/training.md +++ b/docs/source/en/training.md @@ -52,6 +52,7 @@ dataset = dataset.map(tokenize, batched=True) > [!TIP] > Fine-tune on a smaller subset of the full dataset to reduce the time it takes. The results won't be as good compared to fine-tuning on the full dataset, but it is useful to make sure everything works as expected first before committing to training on the full dataset. +> > ```py > small_train = dataset["train"].shuffle(seed=42).select(range(1000)) > small_eval = dataset["test"].shuffle(seed=42).select(range(1000)) diff --git a/docs/source/en/transformers_as_backend.md b/docs/source/en/transformers_as_backend.md index 422cc4a121e9..d1070acea6f5 100644 --- a/docs/source/en/transformers_as_backend.md +++ b/docs/source/en/transformers_as_backend.md @@ -32,6 +32,7 @@ vLLM automatically selects the best backend, and if a model isn’t natively sup from vllm import LLM llm = LLM(model="meta-llama/Llama-3.2-1B", model_impl="transformers") ``` + Add `--model-impl transformers` to `vllm serve` to launch a server with a Transformers' model. ```bash @@ -42,7 +43,6 @@ vllm serve meta-llama/Llama-3.2-1B \ Refer to the [vLLM docs](https://docs.vllm.ai/en/latest/models/supported_models.html#transformers) for more usage examples and tips on using a Transformers as the backend. - ## SGLang [SGLang](https://github.com/InternLM/sglang) is a high-performance, OpenAI-compatible server and runtime designed for chat-based LLMs. It offers fast inference, role-based conversation handling, and support for custom pipelines, making it great for building real-world LLM apps. @@ -57,12 +57,6 @@ print(llm.generate(["The capital of France is"], {"max_new_tokens": 20})[0]) ``` Add `impl transformers` to `sglang.launch_server` to launch a server with a Transformers' model. - - - - - - ```bash python3 -m sglang.launch_server \ @@ -133,7 +127,7 @@ class MyModel(PreTrainedModel): 3. This step is optional, but if you want to support tensor parallel and/or pipeline parallel features, add the following keys to the config. * `base_model_tp_plan` enables [tensor parallelism](./perf_infer_gpu_multi) by mapping fully qualified layer name patterns to tensor parallel styles. Only the `"colwise"` and `"rowwise"` partitioning strategies are currently supported. * `base_model_pp_plan` enables pipeline parallelism by mapping direct child layer names to tuples of lists of strings. The list in the first element of the tuple contains the names of the input arguments. The list in the last element of the tuple contains the names of the variables the layer outputs to in the modeling code. - + Expand the code below for an example.
@@ -158,6 +152,7 @@ class MyConfig(PretrainedConfig): "norm": (["hidden_states"], ["hidden_states"]), } ``` +
### Multimodal models @@ -200,8 +195,8 @@ class MyMultimodalModelForConditionalGeneration(MyMultimodalPreTrainedModel, Gen self.model = MyMultimodalModel(config) self.lm_head = nn.Linear(hidden_dim, vocab_size) ``` -
+ 2. A multimodal model config must be nested with the following fields. * text_config: decoder language model config @@ -246,6 +241,7 @@ class MyMultimodalProcessor(ProcessorMixin): vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) return MultiModalData(**vision_data) ``` + ## Resources diff --git a/docs/source/en/troubleshooting.md b/docs/source/en/troubleshooting.md index 7998881d3648..cfc519668939 100644 --- a/docs/source/en/troubleshooting.md +++ b/docs/source/en/troubleshooting.md @@ -34,7 +34,6 @@ Sometimes errors occur, but we are here to help! This guide covers some of the m For more details about troubleshooting and getting help, take a look at [Chapter 8](https://huggingface.co/course/chapter8/1?fw=pt) of the Hugging Face course. - ## Firewalled environments Some GPU instances on cloud and intranet setups are firewalled to external connections, resulting in a connection error. When your script attempts to download model weights or datasets, the download will hang and then timeout with the following message: diff --git a/notebooks/README.md b/notebooks/README.md index 4d31797104f8..aed435878804 100644 --- a/notebooks/README.md +++ b/notebooks/README.md @@ -22,7 +22,6 @@ Also, we would like to list here interesting content created by the community. If you wrote some notebook(s) leveraging 🤗 Transformers and would like to be listed here, please open a Pull Request so it can be included under the Community notebooks. - ## Hugging Face's notebooks 🤗 ### Documentation notebooks @@ -38,7 +37,6 @@ You can open any page of the documentation as a notebook in Colab (there is a bu | [Summary of the tokenizers](https://github.com/huggingface/notebooks/blob/main/transformers_doc/en/tokenizer_summary.ipynb) | The differences between the tokenizers algorithm |[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/notebooks/blob/main/transformers_doc/en/tokenizer_summary.ipynb)| [![Open in AWS Studio](https://studiolab.sagemaker.aws/studiolab.svg)](https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/transformers_doc/en/tokenizer_summary.ipynb)| | [Multilingual models](https://github.com/huggingface/notebooks/blob/main/transformers_doc/en/multilingual.ipynb) | How to use the multilingual models of the library |[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/notebooks/blob/main/transformers_doc/en/multilingual.ipynb)| [![Open in AWS Studio](https://studiolab.sagemaker.aws/studiolab.svg)](https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/transformers_doc/en/multilingual.ipynb)| - ### PyTorch Examples #### Natural Language Processing[[pytorch-nlp]] @@ -88,7 +86,6 @@ You can open any page of the documentation as a notebook in Colab (there is a bu | [How to fine-tune a Nucleotide Transformer model](https://github.com/huggingface/notebooks/blob/main/examples/nucleotide_transformer_dna_sequence_modelling.ipynb) | See how to tokenize DNA and fine-tune a large pre-trained DNA "language" model | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/nucleotide_transformer_dna_sequence_modelling.ipynb) | [![Open in AWS Studio](https://studiolab.sagemaker.aws/studiolab.svg)](https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/examples/nucleotide_transformer_dna_sequence_modelling.ipynb) | | [Fine-tune a Nucleotide Transformer model with LoRA](https://github.com/huggingface/notebooks/blob/main/examples/nucleotide_transformer_dna_sequence_modelling_with_peft.ipynb) | Train even larger DNA models in a memory-efficient way | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/nucleotide_transformer_dna_sequence_modelling_with_peft.ipynb) | [![Open in AWS Studio](https://studiolab.sagemaker.aws/studiolab.svg)](https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/examples/nucleotide_transformer_dna_sequence_modelling_with_peft.ipynb) | - #### Other modalities[[pytorch-other]] | Notebook | Description | | | @@ -101,7 +98,6 @@ You can open any page of the documentation as a notebook in Colab (there is a bu |:----------|:-------------|:-------------|------:| | [How to export model to ONNX](https://github.com/huggingface/notebooks/blob/main/examples/onnx-export.ipynb)| Highlight how to export and run inference workloads through ONNX | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/onnx-export.ipynb)| [![Open in AWS Studio](https://studiolab.sagemaker.aws/studiolab.svg)](https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/examples/onnx-export.ipynb)| - ### Optimum notebooks 🤗 [Optimum](https://github.com/huggingface/optimum) is an extension of 🤗 Transformers, providing a set of performance optimization tools enabling maximum efficiency to train and run models on targeted hardwares. From 2dd5e7329584a0a19c3468023a5bbbc21c0b4f65 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Wed, 24 Sep 2025 14:37:21 +0800 Subject: [PATCH 175/204] Update ruff to 0.13.1 + target Python 3.10 + apply fixes (#37809) Update ruff to 0.13.1 target it to Python 3.10 and apply its fixes Signed-off-by: Yuanyuan Chen Co-authored-by: Yih-Dar <2521628+ydshieh@users.noreply.github.com> --- pyproject.toml | 7 +++++-- setup.py | 2 +- src/transformers/dependency_versions_table.py | 2 +- .../models/metaclip_2/convert_metaclip_2_to_hf.py | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5d3a9436eb3f..80983fd49703 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ exclude_lines = [ ] [tool.ruff] -target-version = "py39" +target-version = "py310" line-length = 119 [tool.ruff.lint] @@ -27,7 +27,10 @@ line-length = 119 # UP031: Use format specifiers instead of percent format # UP004: Class `XXX` inherits from `object` # UP028: Checks for for loops that can be replaced with yield from expressions -ignore = ["C901", "E501", "E741", "F402", "F823", "SIM1", "SIM300", "SIM212", "SIM905", "UP009", "UP015", "UP031", "UP028", "UP004"] +# UP045: Use `X | None` for type annotations +# UP007: Use `X | Y` for type annotations +# UP035: temporarily disabled to minimize upgrade changes +ignore = ["C901", "E501", "E741", "F402", "F823", "SIM1", "SIM300", "SIM212", "SIM905", "UP009", "UP015", "UP031", "UP028", "UP004", "UP045", "UP007", "UP035"] # RUF013: Checks for the use of implicit Optional # in type annotations when the default parameter value is None. select = ["C", "E", "F", "I", "W", "RUF013", "PERF102", "PLC1802", "PLC0208", "SIM", "UP"] diff --git a/setup.py b/setup.py index d1ed91461f47..c04e6f732d57 100644 --- a/setup.py +++ b/setup.py @@ -153,7 +153,7 @@ "rhoknp>=1.1.0,<1.3.1", "rjieba", "rouge-score!=0.0.7,!=0.0.8,!=0.1,!=0.1.1", - "ruff==0.11.2", + "ruff==0.13.1", # `sacrebleu` not used in `transformers`. However, it is needed in several tests, when a test calls # `evaluate.load("sacrebleu")`. This metric is used in the examples that we use to test the `Trainer` with, in the # `Trainer` tests (see references to `run_translation.py`). diff --git a/src/transformers/dependency_versions_table.py b/src/transformers/dependency_versions_table.py index 8170b459d438..bd1a34ee747f 100644 --- a/src/transformers/dependency_versions_table.py +++ b/src/transformers/dependency_versions_table.py @@ -62,7 +62,7 @@ "rhoknp": "rhoknp>=1.1.0,<1.3.1", "rjieba": "rjieba", "rouge-score": "rouge-score!=0.0.7,!=0.0.8,!=0.1,!=0.1.1", - "ruff": "ruff==0.11.2", + "ruff": "ruff==0.13.1", "sacrebleu": "sacrebleu>=1.4.12,<2.0.0", "sacremoses": "sacremoses", "safetensors": "safetensors>=0.4.3", diff --git a/src/transformers/models/metaclip_2/convert_metaclip_2_to_hf.py b/src/transformers/models/metaclip_2/convert_metaclip_2_to_hf.py index 21a0a1462fff..55aa6f099abf 100644 --- a/src/transformers/models/metaclip_2/convert_metaclip_2_to_hf.py +++ b/src/transformers/models/metaclip_2/convert_metaclip_2_to_hf.py @@ -26,6 +26,7 @@ # Import MetaCLIP modules from src.mini_clip.factory import create_model_and_transforms + from transformers import ( AutoTokenizer, CLIPImageProcessor, From e450e0dbbac06c378e30b6a29e8d6fee4999949b Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Wed, 24 Sep 2025 18:01:27 +0800 Subject: [PATCH 176/204] =?UTF-8?q?=F0=9F=9A=A8=20[V5]=20Remove=20deprecat?= =?UTF-8?q?ed=20training=20arguments=20=20(#41017)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove deprecated training arguments from V5 Signed-off-by: Yuanyuan Chen * Remove deprecated training arguments from V5 Signed-off-by: Yuanyuan Chen * Fix comments Signed-off-by: Yuanyuan Chen * Fix code Signed-off-by: Yuanyuan Chen --------- Signed-off-by: Yuanyuan Chen --- .../pytorch/question-answering/trainer_qa.py | 2 +- .../question-answering/trainer_seq2seq_qa.py | 2 +- src/transformers/training_args.py | 235 +----------------- tests/extended/test_trainer_ext.py | 5 +- tests/test_tokenization_common.py | 2 +- 5 files changed, 12 insertions(+), 234 deletions(-) diff --git a/examples/pytorch/question-answering/trainer_qa.py b/examples/pytorch/question-answering/trainer_qa.py index 3948391f6335..65f6243d3dd2 100644 --- a/examples/pytorch/question-answering/trainer_qa.py +++ b/examples/pytorch/question-answering/trainer_qa.py @@ -83,7 +83,7 @@ def evaluate(self, eval_dataset=None, eval_examples=None, ignore_keys=None, metr # Only the main node log the results by default self.log(metrics) - if self.args.tpu_metrics_debug or self.args.debug: + if self.args.debug: # tpu-comment: Logging debug metrics for PyTorch/XLA (compile, execute times, ops, etc.) xm.master_print(met.metrics_report()) diff --git a/examples/pytorch/question-answering/trainer_seq2seq_qa.py b/examples/pytorch/question-answering/trainer_seq2seq_qa.py index 2492f601316a..a3f2b883b28d 100644 --- a/examples/pytorch/question-answering/trainer_seq2seq_qa.py +++ b/examples/pytorch/question-answering/trainer_seq2seq_qa.py @@ -106,7 +106,7 @@ def evaluate( # Only the main node log the results by default self.log(metrics) - if self.args.tpu_metrics_debug or self.args.debug: + if self.args.debug: # tpu-comment: Logging debug metrics for PyTorch/XLA (compile, execute times, ops, etc.) xm.master_print(met.metrics_report()) diff --git a/src/transformers/training_args.py b/src/transformers/training_args.py index be77f1876f3c..5e71f2a30a6d 100644 --- a/src/transformers/training_args.py +++ b/src/transformers/training_args.py @@ -21,11 +21,8 @@ from datetime import timedelta from enum import Enum from functools import cached_property -from pathlib import Path from typing import Any, Optional, Union -from huggingface_hub import get_full_repo_name - from .debug_utils import DebugOption from .trainer_utils import ( EvaluationStrategy, @@ -383,7 +380,7 @@ class TrainingArguments: Whether to restore the callback states from the checkpoint. If `True`, will override callbacks passed to the `Trainer` if they exist in the checkpoint." use_cpu (`bool`, *optional*, defaults to `False`): - Whether or not to use cpu. If set to False, we will use cuda or mps device if available. + Whether or not to use cpu. If set to False, we will use the available torch device/backend. seed (`int`, *optional*, defaults to 42): Random seed that will be set at the beginning of training. To ensure reproducibility across runs, use the [`~Trainer.model_init`] function to instantiate the model if it has some randomly initialized parameters. @@ -401,8 +398,6 @@ class TrainingArguments: fp16_opt_level (`str`, *optional*, defaults to 'O1'): For `fp16` training, Apex AMP optimization level selected in ['O0', 'O1', 'O2', and 'O3']. See details on the [Apex documentation](https://nvidia.github.io/apex/amp). - fp16_backend (`str`, *optional*, defaults to `"auto"`): - This argument is deprecated. Use `half_precision_backend` instead. half_precision_backend (`str`, *optional*, defaults to `"auto"`): The backend to use for mixed precision training. Must be one of `"auto", "apex", "cpu_amp"`. `"auto"` will use CPU/CUDA AMP or APEX depending on the PyTorch version detected, while the other choices will force the @@ -706,8 +701,6 @@ class TrainingArguments: If True, use gradient checkpointing to save memory at the expense of slower backward pass. gradient_checkpointing_kwargs (`dict`, *optional*, defaults to `None`): Key word arguments to be passed to the `gradient_checkpointing_enable` method. - include_inputs_for_metrics (`bool`, *optional*, defaults to `False`): - This argument is deprecated. Use `include_for_metrics` instead, e.g, `include_for_metrics = ["inputs"]`. include_for_metrics (`list[str]`, *optional*, defaults to `[]`): Include additional data in the `compute_metrics` function if needed for metrics computation. Possible options to add to `include_for_metrics` list: @@ -722,9 +715,6 @@ class TrainingArguments: full_determinism (`bool`, *optional*, defaults to `False`) If `True`, [`enable_full_determinism`] is called instead of [`set_seed`] to ensure reproducible results in distributed training. Important: this will negatively impact the performance, so only use it for debugging. - torchdynamo (`str`, *optional*): - If set, the backend compiler for TorchDynamo. Possible choices are `"eager"`, `"aot_eager"`, `"inductor"`, - `"nvfuser"`, `"aot_nvfuser"`, `"aot_cudagraphs"`, `"ofi"`, `"fx2trt"`, `"onnxrt"` and `"ipex"`. ray_scope (`str`, *optional*, defaults to `"last"`): The scope to use when doing hyperparameter search with Ray. By default, `"last"` will be used. Ray will then use the last checkpoint of all trials, compare those, and select the best one. However, other options @@ -736,8 +726,6 @@ class TrainingArguments: performing slow operations in distributed runnings. Please refer the [PyTorch documentation] (https://pytorch.org/docs/stable/distributed.html#torch.distributed.init_process_group) for more information. - use_mps_device (`bool`, *optional*, defaults to `False`): - This argument is deprecated.`mps` device will be used if it is available similar to `cuda` device. torch_compile (`bool`, *optional*, defaults to `False`): Whether or not to compile the model using PyTorch 2.0 [`torch.compile`](https://pytorch.org/get-started/pytorch-2.0/). @@ -858,25 +846,6 @@ class TrainingArguments: default=8, metadata={"help": "Batch size per device accelerator core/CPU for evaluation."} ) - per_gpu_train_batch_size: Optional[int] = field( - default=None, - metadata={ - "help": ( - "Deprecated, the use of `--per_device_train_batch_size` is preferred. " - "Batch size per GPU/TPU core/CPU for training." - ) - }, - ) - per_gpu_eval_batch_size: Optional[int] = field( - default=None, - metadata={ - "help": ( - "Deprecated, the use of `--per_device_eval_batch_size` is preferred. " - "Batch size per GPU/TPU core/CPU for evaluation." - ) - }, - ) - gradient_accumulation_steps: int = field( default=1, metadata={"help": "Number of updates steps to accumulate before performing a backward/update pass."}, @@ -1036,23 +1005,12 @@ class TrainingArguments: "help": "Whether to restore the callback states from the checkpoint. If `True`, will override callbacks passed to the `Trainer` if they exist in the checkpoint." }, ) - no_cuda: bool = field( - default=False, - metadata={"help": "This argument is deprecated. It will be removed in version 5.0 of 🤗 Transformers."}, - ) use_cpu: bool = field( default=False, metadata={ "help": "Whether or not to use cpu. If left to False, we will use the available torch device/backend (cuda/mps/xpu/hpu etc.)" }, ) - use_mps_device: bool = field( - default=False, - metadata={ - "help": "This argument is deprecated. `mps` device will be used if available similar to `cuda` device." - " It will be removed in version 5.0 of 🤗 Transformers" - }, - ) seed: int = field(default=42, metadata={"help": "Random seed that will be set at the beginning of training."}) data_seed: Optional[int] = field(default=None, metadata={"help": "Random seed to be used with data samplers."}) jit_mode_eval: bool = field( @@ -1120,14 +1078,6 @@ class TrainingArguments: tpu_num_cores: Optional[int] = field( default=None, metadata={"help": "TPU: Number of TPU cores (automatically passed by launcher script)"} ) - tpu_metrics_debug: bool = field( - default=False, - metadata={ - "help": ( - "Deprecated, the use of `--debug tpu_metrics_debug` is preferred. TPU: Whether to print debug metrics" - ) - }, - ) debug: Union[str, list[DebugOption]] = field( default="", metadata={ @@ -1229,15 +1179,6 @@ class TrainingArguments: ), }, ) - fsdp_min_num_params: int = field( - default=0, - metadata={ - "help": ( - "This parameter is deprecated. FSDP's minimum number of parameters for Default Auto Wrapping. (useful" - " only when `fsdp` field is passed)." - ) - }, - ) fsdp_config: Optional[Union[dict[str, Any], str]] = field( default=None, metadata={ @@ -1247,15 +1188,6 @@ class TrainingArguments: ) }, ) - fsdp_transformer_layer_cls_to_wrap: Optional[str] = field( - default=None, - metadata={ - "help": ( - "This parameter is deprecated. Transformer layer class name (case-sensitive) to wrap, e.g," - " `BertLayer`, `GPTJBlock`, `T5Block` .... (useful only when `fsdp` flag is passed)." - ) - }, - ) accelerator_config: Optional[Union[dict, str]] = field( default=None, metadata={ @@ -1293,7 +1225,6 @@ class TrainingArguments: metadata={"help": "The optimizer to use."}, ) optim_args: Optional[str] = field(default=None, metadata={"help": "Optional arguments to supply to optimizer."}) - adafactor: bool = field(default=False, metadata={"help": "Whether or not to replace AdamW by Adafactor."}) group_by_length: bool = field( default=False, metadata={"help": "Whether or not to group samples of roughly the same length together when batching."}, @@ -1390,12 +1321,6 @@ class TrainingArguments: "help": "Gradient checkpointing key word arguments such as `use_reentrant`. Will be passed to `torch.utils.checkpoint.checkpoint` through `model.gradient_checkpointing_enable`." }, ) - include_inputs_for_metrics: bool = field( - default=False, - metadata={ - "help": "This argument is deprecated and will be removed in version 5 of 🤗 Transformers. Use `include_for_metrics` instead." - }, - ) include_for_metrics: list[str] = field( default_factory=list, metadata={ @@ -1409,23 +1334,6 @@ class TrainingArguments: "help": "Whether to recursively concat inputs/losses/labels/predictions across batches. If `False`, will instead store them as lists, with each batch kept separate." }, ) - # Deprecated arguments - fp16_backend: str = field( - default="auto", - metadata={ - "help": "Deprecated. Use half_precision_backend instead", - "choices": ["auto", "apex", "cpu_amp"], - }, - ) - push_to_hub_model_id: Optional[str] = field( - default=None, metadata={"help": "The name of the repository to which push the `Trainer`."} - ) - push_to_hub_organization: Optional[str] = field( - default=None, metadata={"help": "The name of the organization in with to which push the `Trainer`."} - ) - push_to_hub_token: Optional[str] = field( - default=None, metadata={"help": "The token to use to push to the Model Hub."} - ) _n_gpu: int = field(init=False, repr=False, default=-1) mp_parameters: str = field( default="", @@ -1450,12 +1358,6 @@ class TrainingArguments: ) }, ) - torchdynamo: Optional[str] = field( - default=None, - metadata={ - "help": "This argument is deprecated, use `--torch_compile_backend` instead.", - }, - ) ray_scope: Optional[str] = field( default="last", metadata={ @@ -1608,13 +1510,6 @@ def __post_init__(self): ) # Go back to the underlying string or we won't be able to instantiate `IntervalStrategy` on it. self.eval_strategy = self.eval_strategy.value - if self.no_cuda: - warnings.warn( - "using `no_cuda` is deprecated and will be removed in version 5.0 of 🤗 Transformers. " - "Use `use_cpu` instead", - FutureWarning, - ) - self.use_cpu = self.no_cuda self.eval_strategy = IntervalStrategy(self.eval_strategy) self.logging_strategy = IntervalStrategy(self.logging_strategy) @@ -1631,7 +1526,7 @@ def __post_init__(self): f"`torch_empty_cache_steps` must be an integer bigger than 0, got {self.torch_empty_cache_steps}." ) - # eval_steps has to be defined and non-zero, fallbacks to logging_steps if the latter is non-zero + # eval_steps has to be defined and non-zero, falls back to logging_steps if the latter is non-zero if self.eval_strategy == IntervalStrategy.STEPS and (self.eval_steps is None or self.eval_steps == 0): if self.logging_steps > 0: logger.info(f"using `logging_steps` to initialize `eval_steps` to {self.logging_steps}") @@ -1705,16 +1600,8 @@ def __post_init__(self): if self.greater_is_better is None and self.metric_for_best_model is not None: self.greater_is_better = not self.metric_for_best_model.endswith("loss") if is_torch_available(): - if self.fp16_backend and self.fp16_backend != "auto": - warnings.warn( - "`fp16_backend` is deprecated and will be removed in version 5 of 🤗 Transformers. Use" - " `half_precision_backend` instead", - FutureWarning, - ) - self.half_precision_backend = self.fp16_backend - if self.bf16 or self.bf16_full_eval: - if self.use_cpu and not is_torch_available() and not is_torch_xla_available(): + if self.use_cpu and not is_torch_xla_available(): # cpu raise ValueError("Your setup doesn't support bf16/(cpu, tpu, neuroncore). You need torch>=1.10") elif not self.use_cpu: @@ -1755,13 +1642,6 @@ def __post_init__(self): raise ValueError("lr_scheduler_type reduce_lr_on_plateau requires torch>=0.2.0") self.optim = OptimizerNames(self.optim) - if self.adafactor: - warnings.warn( - "`--adafactor` is deprecated and will be removed in version 5 of 🤗 Transformers. Use `--optim" - " adafactor` instead", - FutureWarning, - ) - self.optim = OptimizerNames.ADAFACTOR # We need to setup the accelerator config here *before* the first call to `self.device` if is_accelerate_available(): @@ -1789,13 +1669,6 @@ def __post_init__(self): if is_torch_available(): self.device - if self.torchdynamo is not None: - warnings.warn( - "`torchdynamo` is deprecated and will be removed in version 5 of 🤗 Transformers. Use" - " `torch_compile_backend` instead", - FutureWarning, - ) - self.torch_compile_backend = self.torchdynamo if (self.torch_compile_mode is not None or self.torch_compile_backend is not None) and not self.torch_compile: self.torch_compile = True if self.torch_compile and self.torch_compile_backend is None: @@ -1922,23 +1795,12 @@ def __post_init__(self): v = self.fsdp_config.pop(k) self.fsdp_config[k[5:]] = v - if self.fsdp_min_num_params > 0: - warnings.warn("using `--fsdp_min_num_params` is deprecated. Use fsdp_config instead ", FutureWarning) - - self.fsdp_config["min_num_params"] = max(self.fsdp_config.get("min_num_params", 0), self.fsdp_min_num_params) + self.fsdp_config["min_num_params"] = self.fsdp_config.get("min_num_params", 0) # if fsdp_config["transformer_layer_cls_to_wrap"] is specified as a string, convert it to a list with a single object if isinstance(self.fsdp_config.get("transformer_layer_cls_to_wrap", None), str): self.fsdp_config["transformer_layer_cls_to_wrap"] = [self.fsdp_config["transformer_layer_cls_to_wrap"]] - if self.fsdp_transformer_layer_cls_to_wrap is not None: - warnings.warn( - "using `--fsdp_transformer_layer_cls_to_wrap` is deprecated. Use fsdp_config instead ", FutureWarning - ) - self.fsdp_config["transformer_layer_cls_to_wrap"] = self.fsdp_config.get( - "transformer_layer_cls_to_wrap", [] - ) + [self.fsdp_transformer_layer_cls_to_wrap] - if len(self.fsdp) == 0 and self.fsdp_config["min_num_params"] > 0: warnings.warn("`min_num_params` is useful only when `--fsdp` is specified.") @@ -2013,18 +1875,6 @@ def __post_init__(self): os.environ[f"{prefix}USE_ORIG_PARAMS"] = str(self.fsdp_config.get("use_orig_params", "true")).lower() - if self.tpu_metrics_debug: - warnings.warn( - "using `--tpu_metrics_debug` is deprecated and will be removed in version 5 of 🤗 Transformers. Use" - " `--debug tpu_metrics_debug` instead", - FutureWarning, - ) - if self.debug is None: - self.debug = " tpu_metrics_debug" - else: - self.debug += " tpu_metrics_debug" - self.tpu_metrics_debug = False - if isinstance(self.debug, str): self.debug = [DebugOption(s) for s in self.debug.split()] elif self.debug is None: @@ -2078,41 +1928,6 @@ def __post_init__(self): " when --dataloader_num_workers > 1." ) - if self.push_to_hub_token is not None: - warnings.warn( - "`--push_to_hub_token` is deprecated and will be removed in version 5 of 🤗 Transformers. Use " - "`--hub_token` instead.", - FutureWarning, - ) - self.hub_token = self.push_to_hub_token - - if self.push_to_hub_model_id is not None: - self.hub_model_id = get_full_repo_name( - self.push_to_hub_model_id, organization=self.push_to_hub_organization, token=self.hub_token - ) - if self.push_to_hub_organization is not None: - warnings.warn( - "`--push_to_hub_model_id` and `--push_to_hub_organization` are deprecated and will be removed in " - "version 5 of 🤗 Transformers. Use `--hub_model_id` instead and pass the full repo name to this " - f"argument (in this case {self.hub_model_id}).", - FutureWarning, - ) - else: - warnings.warn( - "`--push_to_hub_model_id` is deprecated and will be removed in version 5 of 🤗 Transformers. Use " - "`--hub_model_id` instead and pass the full repo name to this argument (in this case " - f"{self.hub_model_id}).", - FutureWarning, - ) - elif self.push_to_hub_organization is not None: - self.hub_model_id = f"{self.push_to_hub_organization}/{Path(self.output_dir).name}" - warnings.warn( - "`--push_to_hub_organization` is deprecated and will be removed in version 5 of 🤗 Transformers. Use " - "`--hub_model_id` instead and pass the full repo name to this argument (in this case " - f"{self.hub_model_id}).", - FutureWarning, - ) - if self.eval_use_gather_object and not is_accelerate_available("0.30.0"): raise ValueError( "--eval_use_gather_object requires Accelerate to be version of `accelerate` > 0.30.0." @@ -2126,12 +1941,6 @@ def __post_init__(self): "This is not supported and we recommend you to update your version." ) - if self.include_inputs_for_metrics: - logger.warning( - "Using `include_inputs_for_metrics` is deprecated and will be removed in version 5 of 🤗 Transformers. Please use `include_for_metrics` list argument instead." - ) - self.include_for_metrics.append("inputs") - if self.include_num_input_tokens_seen is True: self.include_num_input_tokens_seen = "all" elif self.include_num_input_tokens_seen is False: @@ -2140,11 +1949,6 @@ def __post_init__(self): def __str__(self): self_as_dict = asdict(self) - # Remove deprecated arguments. That code should be removed once - # those deprecated arguments are removed from TrainingArguments. (TODO: v5) - del self_as_dict["per_gpu_train_batch_size"] - del self_as_dict["per_gpu_eval_batch_size"] - self_as_dict = {k: f"<{k.upper()}>" if k.endswith("_token") else v for k, v in self_as_dict.items()} attrs_as_str = [f"{k}={v},\n" for k, v in sorted(self_as_dict.items())] @@ -2155,29 +1959,17 @@ def __str__(self): @property def train_batch_size(self) -> int: """ - The actual batch size for training (may differ from `per_gpu_train_batch_size` in distributed training). + The actual batch size for training. """ - if self.per_gpu_train_batch_size: - logger.warning( - "Using deprecated `--per_gpu_train_batch_size` argument which will be removed in a future " - "version. Using `--per_device_train_batch_size` is preferred." - ) - per_device_batch_size = self.per_gpu_train_batch_size or self.per_device_train_batch_size - train_batch_size = per_device_batch_size * max(1, self.n_gpu) + train_batch_size = self.per_device_train_batch_size * max(1, self.n_gpu) return train_batch_size @property def eval_batch_size(self) -> int: """ - The actual batch size for evaluation (may differ from `per_gpu_eval_batch_size` in distributed training). + The actual batch size for evaluation. """ - if self.per_gpu_eval_batch_size: - logger.warning( - "Using deprecated `--per_gpu_eval_batch_size` argument which will be removed in a future " - "version. Using `--per_device_eval_batch_size` is preferred." - ) - per_device_batch_size = self.per_gpu_eval_batch_size or self.per_device_eval_batch_size - eval_batch_size = per_device_batch_size * max(1, self.n_gpu) + eval_batch_size = self.per_device_eval_batch_size * max(1, self.n_gpu) return eval_batch_size @property @@ -2268,17 +2060,6 @@ def _setup_devices(self) -> "torch.device": # Already set _n_gpu pass elif self.distributed_state.distributed_type == DistributedType.NO: - if self.use_mps_device: - warnings.warn( - "`use_mps_device` is deprecated and will be removed in version 5.0 of 🤗 Transformers. " - "`mps` device will be used by default if available similar to the way `cuda` device is used." - "Therefore, no action from user is required. " - ) - if device.type != "mps": - raise ValueError( - "Either you do not have an MPS-enabled device on this machine or MacOS version is not 12.3+ " - "or current PyTorch install was not built with MPS enabled." - ) if self.use_cpu: device = torch.device("cpu") elif is_torch_mps_available(): diff --git a/tests/extended/test_trainer_ext.py b/tests/extended/test_trainer_ext.py index 82d3cdb9c3ce..bf8e74dcff87 100644 --- a/tests/extended/test_trainer_ext.py +++ b/tests/extended/test_trainer_ext.py @@ -331,10 +331,7 @@ def run_trainer( args += ["--predict_with_generate"] if do_train: - if optim == "adafactor": - args += ["--adafactor"] - else: - args += f"--optim {optim}".split() + args += f"--optim {optim}".split() if extra_args_str is not None: args += extra_args_str.split() diff --git a/tests/test_tokenization_common.py b/tests/test_tokenization_common.py index c0d025e1e23d..0be43774a85d 100644 --- a/tests/test_tokenization_common.py +++ b/tests/test_tokenization_common.py @@ -4462,7 +4462,7 @@ def test_saving_tokenizer_trainer(self): # Load tokenizer from a folder without legacy files tokenizer = self.rust_tokenizer_class.from_pretrained(tmp_dir) - training_args = TrainingArguments(output_dir=tmp_dir, do_train=True, no_cuda=True) + training_args = TrainingArguments(output_dir=tmp_dir, do_train=True, use_cpu=True) trainer = Trainer(model=model, args=training_args, processing_class=tokenizer) # Should not raise an error From 20a4c4532ad2fe8da06758c817d79a924d17bca7 Mon Sep 17 00:00:00 2001 From: hbenoit <60629420+HaroldBenoit@users.noreply.github.com> Date: Wed, 24 Sep 2025 12:17:41 +0200 Subject: [PATCH 177/204] Support loading LFM2 GGUF (#41111) * add gguf config mapping for lfm2 * add lfm2 tensor process to unsqueeze conv weights * adjust values from gguf config to HF config * add test for lfm2 gguf * ruff --------- Co-authored-by: Marc Sun <57196510+SunMarc@users.noreply.github.com> --- src/transformers/integrations/ggml.py | 13 ++++++++++ .../modeling_gguf_pytorch_utils.py | 25 +++++++++++++++++++ tests/quantization/ggml/test_ggml.py | 19 ++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/src/transformers/integrations/ggml.py b/src/transformers/integrations/ggml.py index 703fd0156365..fd2c9c4e889a 100644 --- a/src/transformers/integrations/ggml.py +++ b/src/transformers/integrations/ggml.py @@ -90,6 +90,19 @@ "expert_count": "num_experts", "expert_used_count": "num_experts_per_tok", }, + "lfm2": { + "context_length": "max_position_embeddings", + "block_count": "num_hidden_layers", + "feed_forward_length": "intermediate_size", + "embedding_length": "hidden_size", + "rope.dimension_count": None, + "rope.freq_base": "rope_theta", + "attention.head_count": "num_attention_heads", + "attention.head_count_kv": "num_key_value_heads", + "attention.layer_norm_rms_epsilon": "rms_norm_eps", + "vocab_size": "vocab_size", + "shortconv.l_cache": "conv_L_cache", + }, "qwen3": { "context_length": "max_position_embeddings", "block_count": "num_hidden_layers", diff --git a/src/transformers/modeling_gguf_pytorch_utils.py b/src/transformers/modeling_gguf_pytorch_utils.py index 9b90fb82afa2..08aaac3617ff 100644 --- a/src/transformers/modeling_gguf_pytorch_utils.py +++ b/src/transformers/modeling_gguf_pytorch_utils.py @@ -243,6 +243,17 @@ def process(self, weights, name, **kwargs): return GGUFTensor(weights, name, {}) +class Lfm2TensorProcessor(TensorProcessor): + def __init__(self, config=None): + super().__init__(config=config) + + def process(self, weights, name, **kwargs): + if "shortconv.conv.weight" in name: + ## GGUF shape is [hidden_dim, L_cache], HF expects [hidden_dim, 1, L_cache] + weights = np.expand_dims(weights, axis=1) ## equivalent to unsqueeze(1) + return GGUFTensor(weights, name, {}) + + TENSOR_PROCESSORS = { "llama": LlamaTensorProcessor, "qwen2moe": Qwen2MoeTensorProcessor, @@ -255,6 +266,7 @@ def process(self, weights, name, **kwargs): "nemotron": NemotronTensorProcessor, "gemma2": Gemma2TensorProcessor, "gemma3": Gemma2TensorProcessor, + "lfm2": Lfm2TensorProcessor, } @@ -459,6 +471,19 @@ def load_gguf_checkpoint(gguf_checkpoint_path, return_tensors=False, model_to_lo if parsed_parameters["config"]["model_type"] == "gemma3": parsed_parameters["config"]["model_type"] = "gemma3_text" + if parsed_parameters["config"]["model_type"] == "lfm2": + gguf_num_key_value_heads = parsed_parameters["config"]["num_key_value_heads"] + # LFM2 GGUF checkpoint defines num_key_value_heads as a list of integers .e.g [0, 0, 8, 0, 0, 8, 0, 0, 8, 0, 8, 0, 8, 0, 8, 0] but we need to set it to the max value for HF + parsed_parameters["config"]["num_key_value_heads"] = max(gguf_num_key_value_heads) + ## we already read the correct intermediate_size from the GGUF checkpoint so we need to set block_auto_adjust_ff_dim to False + parsed_parameters["config"]["block_auto_adjust_ff_dim"] = False + + ## llama.cpp defines the layers that are full-attention by looking at num_key_value_heads + ## we need to set the full_attn_idxs to the layers that are full-attention + parsed_parameters["config"]["full_attn_idxs"] = [ + i for i, num_kv_heads in enumerate(gguf_num_key_value_heads) if num_kv_heads > 0 + ] + # retrieve config vocab_size from tokenizer # Please refer to https://github.com/huggingface/transformers/issues/32526 for more details if "vocab_size" not in parsed_parameters["config"]: diff --git a/tests/quantization/ggml/test_ggml.py b/tests/quantization/ggml/test_ggml.py index ac6fb30fe606..8b7e71a0508c 100644 --- a/tests/quantization/ggml/test_ggml.py +++ b/tests/quantization/ggml/test_ggml.py @@ -311,6 +311,7 @@ class GgufModelTests(unittest.TestCase): qwen3_model_id = "Qwen/Qwen3-0.6B-GGUF" qwen3moe_model_id = "Qwen/Qwen3-30B-A3B-GGUF" umt5_encoder_model_id = "city96/umt5-xxl-encoder-gguf" + lfm2_model_id = "LiquidAI/LFM2-1.2B-GGUF" q4_0_phi3_model_id = "Phi-3-mini-4k-instruct-q4.gguf" q4_0_mistral_model_id = "mistral-7b-instruct-v0.2.Q4_0.gguf" @@ -350,6 +351,7 @@ class GgufModelTests(unittest.TestCase): q8_0_qwen3_model_id = "Qwen3-0.6B-Q8_0.gguf" q4_k_m_qwen3moe_model_id = "Qwen3-30B-A3B-Q4_K_M.gguf" q8_0_umt5_encoder_model_id = "umt5-xxl-encoder-Q8_0.gguf" + q4_k_m_lfm2_model_id = "LFM2-1.2B-Q4_K_M.gguf" example_text = "Hello" @@ -1116,3 +1118,20 @@ def test_umt5_encoder_q8_0(self): ).to(torch_device) torch.testing.assert_close(outputs.last_hidden_state[0, :3, :3], EXPECTED_OUTPUT, rtol=6e-3, atol=4e-4) + + @require_read_token + ## to be precise, it currently require upstream gguf-py to be installed as lfm2 is not yet present in gguf 0.17.1 + @unittest.skipUnless(is_gguf_available("0.17.0"), "test requires gguf version >= 0.17.0") + def test_lfm2_q4_k_m(self): + tokenizer = AutoTokenizer.from_pretrained("LiquidAI/LFM2-1.2B") + model = AutoModelForCausalLM.from_pretrained( + self.lfm2_model_id, + gguf_file=self.q4_k_m_lfm2_model_id, + dtype=torch.float16, + ) + + text = tokenizer(self.example_text, return_tensors="pt")["input_ids"] + out = model.generate(text, max_new_tokens=10) + + EXPECTED_TEXT = "Hello Atari 2600! es un videoj" + self.assertEqual(tokenizer.decode(out[0], skip_special_tokens=True), EXPECTED_TEXT) From f0b7d244c0b12dfc4e3e478ad501dc8c6f96584d Mon Sep 17 00:00:00 2001 From: liangel-02 Date: Wed, 24 Sep 2025 03:32:47 -0700 Subject: [PATCH 178/204] [torchao safetensors] integrate torchao safetensors support with transformers (#40735) * enable torchao safetensors * enable torchao safetensors support * add more version checking --- src/transformers/modeling_utils.py | 21 +++++-- src/transformers/quantizers/base.py | 4 ++ .../quantizers/quantizer_torchao.py | 60 ++++++++++++++++-- .../torchao_integration/test_torchao.py | 62 ++++++++++++++++--- 4 files changed, 129 insertions(+), 18 deletions(-) diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index 25cfa411321c..55ab06dcb85a 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -727,11 +727,12 @@ def _load_state_dict_into_meta_model( device_map_regex = "|".join([re.escape(k) for k in sorted(device_map.keys(), reverse=True)]) is_quantized = hf_quantizer is not None - is_hqq_or_bnb = is_quantized and hf_quantizer.quantization_config.quant_method in { + is_hqq_or_bnb_or_ao = is_quantized and hf_quantizer.quantization_config.quant_method in { QuantizationMethod.HQQ, QuantizationMethod.BITS_AND_BYTES, + QuantizationMethod.TORCHAO, } - is_meta_state_dict = shard_file.endswith(".safetensors") and not is_hqq_or_bnb + is_meta_state_dict = shard_file.endswith(".safetensors") and not is_hqq_or_bnb_or_ao file_pointer = None if is_meta_state_dict: file_pointer = safe_open(shard_file, framework="pt", device=tensor_device) @@ -873,7 +874,7 @@ def load_shard_file(args): shard_file, state_dict, disk_only_shard_files, - is_hqq_or_bnb, + is_hqq_or_bnb_or_ao, is_quantized, device_map, hf_quantizer, @@ -899,7 +900,7 @@ def load_shard_file(args): map_location = "cpu" if ( shard_file.endswith(".safetensors") - and not is_hqq_or_bnb + and not is_hqq_or_bnb_or_ao and not (is_deepspeed_zero3_enabled() and not is_quantized) ): map_location = "meta" @@ -922,6 +923,13 @@ def load_shard_file(args): # Fix the key names state_dict = {key_renaming_mapping[k]: v for k, v in state_dict.items() if k in key_renaming_mapping} + metadata = None + if shard_file.endswith(".safetensors") and is_safetensors_available(): + with safe_open(shard_file, framework="pt") as f: + metadata = f.metadata() + + if hf_quantizer: + state_dict = hf_quantizer.update_state_dict_with_metadata(state_dict, metadata) error_msgs = [] @@ -5277,9 +5285,10 @@ def _load_pretrained_model( QuantizationMethod.HQQ, QuantizationMethod.QUARK, } - is_hqq_or_bnb = is_quantized and hf_quantizer.quantization_config.quant_method in { + is_hqq_or_bnb_or_ao = is_quantized and hf_quantizer.quantization_config.quant_method in { QuantizationMethod.HQQ, QuantizationMethod.BITS_AND_BYTES, + QuantizationMethod.TORCHAO, } # Get all the keys of the state dicts that we have to initialize the model @@ -5451,7 +5460,7 @@ def _load_pretrained_model( shard_file, state_dict, disk_only_shard_files, - is_hqq_or_bnb, + is_hqq_or_bnb_or_ao, is_quantized, device_map, hf_quantizer, diff --git a/src/transformers/quantizers/base.py b/src/transformers/quantizers/base.py index 323faa9c17e2..8710e1426a8e 100644 --- a/src/transformers/quantizers/base.py +++ b/src/transformers/quantizers/base.py @@ -342,6 +342,10 @@ def get_state_dict_and_metadata(self, model, safe_serialization=False): """Get state dict and metadata. Useful when we need to modify a bit the state dict due to quantization""" return None, {} + def update_state_dict_with_metadata(self, state_dict, metadata): + """Update state dict with metadata. Default behaviour returns state_dict""" + return state_dict + @abstractmethod def _process_model_before_weight_loading(self, model, **kwargs): ... diff --git a/src/transformers/quantizers/quantizer_torchao.py b/src/transformers/quantizers/quantizer_torchao.py index cba023a7d811..344c9e3534ed 100644 --- a/src/transformers/quantizers/quantizer_torchao.py +++ b/src/transformers/quantizers/quantizer_torchao.py @@ -35,6 +35,17 @@ import torch import torch.nn as nn +if is_torchao_available(): + import torchao + + if version.parse(importlib.metadata.version("torchao")) >= version.parse("0.14.0"): + from torchao.prototype.safetensors.safetensors_support import ( + flatten_tensor_state_dict, + unflatten_tensor_state_dict, + ) + from torchao.prototype.safetensors.safetensors_utils import is_metadata_torchao + + logger = logging.get_logger(__name__) @@ -81,6 +92,15 @@ def _linear_extra_repr(self): return f"in_features={self.weight.shape[1]}, out_features={self.weight.shape[0]}, weight={weight}" +if is_torchao_available(): + SUPPORTED_SAFE_SERIALIZATION_CONFIGS = [ + torchao.quantization.Float8WeightOnlyConfig, + torchao.quantization.Float8DynamicActivationFloat8WeightConfig, + ] + + TORCHAO_VERSION = version.parse(importlib.metadata.version("torchao")) + + class TorchAoHfQuantizer(HfQuantizer): """ Quantizer for torchao: https://github.com/pytorch/ao/ @@ -137,6 +157,21 @@ def update_dtype(self, dtype): dtype = torch.float32 return dtype + def get_state_dict_and_metadata(self, model, safe_serialization: Optional[bool] = False): + """ + If the model is safe serializable, we flatten the state dict of tensor subclasses so that it is compatible with + the safetensors format. + """ + if type(self.quantization_config.quant_type) in SUPPORTED_SAFE_SERIALIZATION_CONFIGS and safe_serialization: + if TORCHAO_VERSION >= version.parse("0.14.0"): + return flatten_tensor_state_dict(model.state_dict()) + else: + raise RuntimeError( + f"In order to use safetensors with torchao, please use torchao version >= 0.14.0. Current version: {TORCHAO_VERSION}" + ) + else: + return super().get_state_dict_and_metadata(model) + def adjust_target_dtype(self, dtype: "torch.dtype") -> "torch.dtype": if version.parse(importlib.metadata.version("accelerate")) > version.parse("0.19.0"): from accelerate.utils import CustomDtype @@ -279,6 +314,16 @@ def create_quantized_param( quantize_(module, self.quantization_config.get_apply_tensor_subclass()) + def update_state_dict_with_metadata(self, state_dict, metadata): + """ + If the metadata contains torchao tensor subclass information, we reconstruct the tensor subclass state dict + from the provided state_dict and metadata. + """ + if TORCHAO_VERSION >= version.parse("0.14.0") and is_metadata_torchao(metadata): + return unflatten_tensor_state_dict(state_dict, metadata) + else: + return super().update_state_dict_with_metadata(state_dict, metadata) + def _process_model_after_weight_loading(self, model, **kwargs): """No process required for torchao quantized model""" if self.quantization_config.quant_type == "autoquant": @@ -297,10 +342,17 @@ def _process_model_after_weight_loading(self, model, **kwargs): def is_serializable(self, safe_serialization=None) -> bool: if safe_serialization: - logger.warning( - "torchao quantized model does not support safe serialization, please set `safe_serialization` to False" - ) - return False + _is_torchao_serializable = type( + self.quantization_config.quant_type + ) in SUPPORTED_SAFE_SERIALIZATION_CONFIGS and TORCHAO_VERSION >= version.parse("0.14.0") + if not _is_torchao_serializable: + logger.warning( + f"torchao quantized model only supports safe serialization for {SUPPORTED_SAFE_SERIALIZATION_CONFIGS}, \ + and torchao version >= 0.14.0, please set `safe_serialization` to False for \ + {type(self.quantization_config.quant_type)} and {TORCHAO_VERSION}." + ) + return _is_torchao_serializable + _is_torchao_serializable = version.parse(importlib.metadata.version("huggingface_hub")) >= version.parse( "0.25.0" ) diff --git a/tests/quantization/torchao_integration/test_torchao.py b/tests/quantization/torchao_integration/test_torchao.py index 0ea22ae08df0..1ddc2de0801f 100644 --- a/tests/quantization/torchao_integration/test_torchao.py +++ b/tests/quantization/torchao_integration/test_torchao.py @@ -18,6 +18,7 @@ import unittest from packaging import version +from parameterized import parameterized from transformers import AutoModelForCausalLM, AutoTokenizer, TorchAoConfig from transformers.testing_utils import ( @@ -37,6 +38,8 @@ import torch if is_torchao_available(): + import torchao + # renamed in torchao 0.7.0, please install the latest torchao from torchao.dtypes import ( AffineQuantizedTensor, @@ -135,7 +138,7 @@ class TorchAoTest(unittest.TestCase): model_name = "TinyLlama/TinyLlama-1.1B-Chat-v1.0" device = "cpu" quant_scheme_kwargs = ( - {"group_size": 32, "layout": Int4CPULayout()} + {"group_size": 32, "layout": Int4CPULayout(), "version": 1} if is_torchao_available() and version.parse(importlib.metadata.version("torchao")) >= version.parse("0.8.0") else {"group_size": 32} ) @@ -225,6 +228,7 @@ def test_include_input_output_embeddings(self): weight_dtype=weight_dtype, granularity=granularity, mapping_type=mapping_type, + version=1, ) config = ModuleFqnToConfig( {"_default": None, "model.embed_tokens": embedding_config, "lm_head": embedding_config} @@ -277,7 +281,7 @@ def test_per_module_config_skip(self): @require_torch_accelerator class TorchAoAcceleratorTest(TorchAoTest): device = torch_device - quant_scheme_kwargs = {"group_size": 32} + quant_scheme_kwargs = {"group_size": 32, "version": 1} # called only once for all test in this class @classmethod @@ -327,7 +331,7 @@ def test_int4wo_offload(self): "lm_head": 0, } - quant_config = TorchAoConfig("int4_weight_only", group_size=32) + quant_config = TorchAoConfig("int4_weight_only", **self.quant_scheme_kwargs) quantized_model = AutoModelForCausalLM.from_pretrained( self.model_name, @@ -399,7 +403,7 @@ def test_autoquant(self): check_autoquantized(self, quantized_model.model.layers[0].self_attn.v_proj) - EXPECTED_OUTPUT = "What are we having for dinner?\n\nJane: (sighs)" + EXPECTED_OUTPUT = "What are we having for dinner?\n\nJessica: (smiling)" output = quantized_model.generate( **input_ids, max_new_tokens=self.max_new_tokens, cache_implementation="static" ) @@ -414,7 +418,7 @@ class TorchAoSerializationTest(unittest.TestCase): model_name = "TinyLlama/TinyLlama-1.1B-Chat-v1.0" quant_scheme = "int4_weight_only" quant_scheme_kwargs = ( - {"group_size": 32, "layout": Int4CPULayout()} + {"group_size": 32, "layout": Int4CPULayout(), "version": 1} if is_torchao_available() and version.parse(importlib.metadata.version("torchao")) >= version.parse("0.8.0") else {"group_size": 32} ) @@ -447,13 +451,13 @@ def test_original_model_expected_output(self): self.assertEqual(self.tokenizer.decode(output[0], skip_special_tokens=True), self.EXPECTED_OUTPUT) - def check_serialization_expected_output(self, device, expected_output): + def check_serialization_expected_output(self, device, expected_output, safe_serialization=False): """ Test if we can serialize and load/infer the model again on the same device """ dtype = torch.bfloat16 if self.quant_scheme == "int4_weight_only" else "auto" with tempfile.TemporaryDirectory() as tmpdirname: - self.quantized_model.save_pretrained(tmpdirname, safe_serialization=False) + self.quantized_model.save_pretrained(tmpdirname, safe_serialization=safe_serialization) loaded_quantized_model = AutoModelForCausalLM.from_pretrained(tmpdirname, dtype=dtype, device_map=device) input_ids = self.tokenizer(self.input_text, return_tensors="pt").to(device) @@ -464,6 +468,48 @@ def test_serialization_expected_output(self): self.check_serialization_expected_output(self.device, self.EXPECTED_OUTPUT) +@require_torchao +@require_torchao_version_greater_or_equal("0.14.0") +class TorchAoSafeSerializationTest(TorchAoSerializationTest): + # called only once for all test in this class + @classmethod + def setUpClass(cls): + cls.tokenizer = AutoTokenizer.from_pretrained(cls.model_name) + cls.EXPECTED_OUTPUT = "What are we having for dinner?\n- 1. What is the temperature outside" + + def tearDown(self): + gc.collect() + backend_empty_cache(torch_device) + gc.collect() + if hasattr(self, "quantized_model"): + del self.quantized_model + gc.collect() + + test_params = ( + [ + ( + torchao.quantization.Float8DynamicActivationFloat8WeightConfig(), + "What are we having for dinner?\n\nJess: (smiling) I", + ), + (torchao.quantization.Float8WeightOnlyConfig(), "What are we having for dinner?\n\nJessica: (smiling)"), + ] + if is_torchao_available() + else [] + ) + + @parameterized.expand(test_params, skip_on_empty=True) + def test_serialization_expected_output(self, config, expected_output): + device = "cuda" + self.quant_config = TorchAoConfig(config) + self.quantized_model = AutoModelForCausalLM.from_pretrained( + self.model_name, + dtype=torch.bfloat16, + device_map=device, + quantization_config=self.quant_config, + ) + self.check_serialization_expected_output(device, expected_output, safe_serialization=True) + + class TorchAoSerializationW8A8CPUTest(TorchAoSerializationTest): quant_scheme, quant_scheme_kwargs = "int8_dynamic_activation_int8_weight", {} @@ -500,7 +546,7 @@ def test_serialization_expected_output_on_accelerator(self): @require_torch_accelerator class TorchAoSerializationAcceleratorTest(TorchAoSerializationTest): - quant_scheme, quant_scheme_kwargs = "int4_weight_only", {"group_size": 32} + quant_scheme, quant_scheme_kwargs = "int4_weight_only", {"group_size": 32, "version": 1} device = f"{torch_device}:0" # called only once for all test in this class From 34fd896d0394799c732961f41299a68121d4b018 Mon Sep 17 00:00:00 2001 From: nnul <107971634+notkisk@users.noreply.github.com> Date: Wed, 24 Sep 2025 12:18:27 +0100 Subject: [PATCH 179/204] [Qwen3-next] Fix dimension mismatch in torch_chunk_gated_delta_rule and torch_recurrent_gated_delta_rule (#40963) (#41036) * fix mismatched dims for qwen3 next * propagate changes * chore: renamed tot_heads to total_sequence_length * Apply suggestion from @vasqu Co-authored-by: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> * minor fix to modular qwen3 next file --------- Co-authored-by: Anton Vlasjuk <73884904+vasqu@users.noreply.github.com> --- .../models/qwen3_next/modeling_qwen3_next.py | 20 +++++++++---------- .../models/qwen3_next/modular_qwen3_next.py | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/transformers/models/qwen3_next/modeling_qwen3_next.py b/src/transformers/models/qwen3_next/modeling_qwen3_next.py index 21e5d4f9819c..e15e3435f732 100644 --- a/src/transformers/models/qwen3_next/modeling_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modeling_qwen3_next.py @@ -458,15 +458,15 @@ def torch_chunk_gated_delta_rule( x.transpose(1, 2).contiguous().to(torch.float32) for x in (query, key, value, beta, g) ] - batch_size, sequence_length, num_heads, k_head_dim = key.shape + batch_size, num_heads, sequence_length, k_head_dim = key.shape v_head_dim = value.shape[-1] - pad_size = (chunk_size - num_heads % chunk_size) % chunk_size + pad_size = (chunk_size - sequence_length % chunk_size) % chunk_size query = F.pad(query, (0, 0, 0, pad_size)) key = F.pad(key, (0, 0, 0, pad_size)) value = F.pad(value, (0, 0, 0, pad_size)) beta = F.pad(beta, (0, pad_size)) g = F.pad(g, (0, pad_size)) - tot_heads = num_heads + pad_size + total_sequence_length = sequence_length + pad_size scale = 1 / (query.shape[-1] ** 0.5) query = query * scale @@ -491,7 +491,7 @@ def torch_chunk_gated_delta_rule( value = attn @ v_beta k_cumdecay = attn @ (k_beta * g.exp().unsqueeze(-1)) last_recurrent_state = ( - torch.zeros(batch_size, sequence_length, k_head_dim, v_head_dim).to(value) + torch.zeros(batch_size, num_heads, k_head_dim, v_head_dim).to(value) if initial_state is None else initial_state.to(value) ) @@ -499,7 +499,7 @@ def torch_chunk_gated_delta_rule( mask = torch.triu(torch.ones(chunk_size, chunk_size, dtype=torch.bool, device=query.device), diagonal=1) # for each chunk - for i in range(0, tot_heads // chunk_size): + for i in range(0, total_sequence_length // chunk_size): q_i, k_i, v_i = query[:, :, i], key[:, :, i], value[:, :, i] attn = (q_i @ k_i.transpose(-1, -2) * decay_mask[:, :, i]).masked_fill_(mask, 0) v_prime = (k_cumdecay[:, :, i]) @ last_recurrent_state @@ -514,7 +514,7 @@ def torch_chunk_gated_delta_rule( if not output_final_state: last_recurrent_state = None core_attn_out = core_attn_out.reshape(core_attn_out.shape[0], core_attn_out.shape[1], -1, core_attn_out.shape[-1]) - core_attn_out = core_attn_out[:, :, :num_heads] + core_attn_out = core_attn_out[:, :, :sequence_length] core_attn_out = core_attn_out.transpose(1, 2).contiguous().to(initial_dtype) return core_attn_out, last_recurrent_state @@ -530,19 +530,19 @@ def torch_recurrent_gated_delta_rule( x.transpose(1, 2).contiguous().to(torch.float32) for x in (query, key, value, beta, g) ] - batch_size, sequence_length, num_heads, k_head_dim = key.shape + batch_size, num_heads, sequence_length, k_head_dim = key.shape v_head_dim = value.shape[-1] scale = 1 / (query.shape[-1] ** 0.5) query = query * scale - core_attn_out = torch.zeros(batch_size, sequence_length, num_heads, v_head_dim).to(value) + core_attn_out = torch.zeros(batch_size, num_heads, sequence_length, v_head_dim).to(value) last_recurrent_state = ( - torch.zeros(batch_size, sequence_length, k_head_dim, v_head_dim).to(value) + torch.zeros(batch_size, num_heads, k_head_dim, v_head_dim).to(value) if initial_state is None else initial_state.to(value) ) - for i in range(num_heads): + for i in range(sequence_length): q_t = query[:, :, i] k_t = key[:, :, i] v_t = value[:, :, i] diff --git a/src/transformers/models/qwen3_next/modular_qwen3_next.py b/src/transformers/models/qwen3_next/modular_qwen3_next.py index 9e92ecf312c3..6d4b6a5e04a3 100644 --- a/src/transformers/models/qwen3_next/modular_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modular_qwen3_next.py @@ -293,15 +293,15 @@ def torch_chunk_gated_delta_rule( x.transpose(1, 2).contiguous().to(torch.float32) for x in (query, key, value, beta, g) ] - batch_size, sequence_length, num_heads, k_head_dim = key.shape + batch_size, num_heads, sequence_length, k_head_dim = key.shape v_head_dim = value.shape[-1] - pad_size = (chunk_size - num_heads % chunk_size) % chunk_size + pad_size = (chunk_size - sequence_length % chunk_size) % chunk_size query = F.pad(query, (0, 0, 0, pad_size)) key = F.pad(key, (0, 0, 0, pad_size)) value = F.pad(value, (0, 0, 0, pad_size)) beta = F.pad(beta, (0, pad_size)) g = F.pad(g, (0, pad_size)) - tot_heads = num_heads + pad_size + total_sequence_length = sequence_length + pad_size scale = 1 / (query.shape[-1] ** 0.5) query = query * scale @@ -326,7 +326,7 @@ def torch_chunk_gated_delta_rule( value = attn @ v_beta k_cumdecay = attn @ (k_beta * g.exp().unsqueeze(-1)) last_recurrent_state = ( - torch.zeros(batch_size, sequence_length, k_head_dim, v_head_dim).to(value) + torch.zeros(batch_size, num_heads, k_head_dim, v_head_dim).to(value) if initial_state is None else initial_state.to(value) ) @@ -334,7 +334,7 @@ def torch_chunk_gated_delta_rule( mask = torch.triu(torch.ones(chunk_size, chunk_size, dtype=torch.bool, device=query.device), diagonal=1) # for each chunk - for i in range(0, tot_heads // chunk_size): + for i in range(0, total_sequence_length // chunk_size): q_i, k_i, v_i = query[:, :, i], key[:, :, i], value[:, :, i] attn = (q_i @ k_i.transpose(-1, -2) * decay_mask[:, :, i]).masked_fill_(mask, 0) v_prime = (k_cumdecay[:, :, i]) @ last_recurrent_state @@ -349,7 +349,7 @@ def torch_chunk_gated_delta_rule( if not output_final_state: last_recurrent_state = None core_attn_out = core_attn_out.reshape(core_attn_out.shape[0], core_attn_out.shape[1], -1, core_attn_out.shape[-1]) - core_attn_out = core_attn_out[:, :, :num_heads] + core_attn_out = core_attn_out[:, :, :sequence_length] core_attn_out = core_attn_out.transpose(1, 2).contiguous().to(initial_dtype) return core_attn_out, last_recurrent_state @@ -365,19 +365,19 @@ def torch_recurrent_gated_delta_rule( x.transpose(1, 2).contiguous().to(torch.float32) for x in (query, key, value, beta, g) ] - batch_size, sequence_length, num_heads, k_head_dim = key.shape + batch_size, num_heads, sequence_length, k_head_dim = key.shape v_head_dim = value.shape[-1] scale = 1 / (query.shape[-1] ** 0.5) query = query * scale - core_attn_out = torch.zeros(batch_size, sequence_length, num_heads, v_head_dim).to(value) + core_attn_out = torch.zeros(batch_size, num_heads, sequence_length, v_head_dim).to(value) last_recurrent_state = ( - torch.zeros(batch_size, sequence_length, k_head_dim, v_head_dim).to(value) + torch.zeros(batch_size, num_heads, k_head_dim, v_head_dim).to(value) if initial_state is None else initial_state.to(value) ) - for i in range(num_heads): + for i in range(sequence_length): q_t = query[:, :, i] k_t = key[:, :, i] v_t = value[:, :, i] From ffa6a76d862a66da9730ec8d88021205bdcc7922 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Wed, 24 Sep 2025 19:27:37 +0800 Subject: [PATCH 180/204] Fix the error where a keyword argument appearing before *args (#41099) Signed-off-by: Yuanyuan Chen --- src/transformers/commands/add_new_model_like.py | 2 +- src/transformers/convert_slow_tokenizer.py | 4 +--- src/transformers/integrations/mistral.py | 2 -- src/transformers/pipelines/table_question_answering.py | 4 ++-- src/transformers/pipelines/token_classification.py | 4 ++-- src/transformers/pipelines/zero_shot_classification.py | 4 ++-- src/transformers/trainer_pt_utils.py | 2 +- 7 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/transformers/commands/add_new_model_like.py b/src/transformers/commands/add_new_model_like.py index ffff54df93ba..fce524d4a6c0 100644 --- a/src/transformers/commands/add_new_model_like.py +++ b/src/transformers/commands/add_new_model_like.py @@ -755,7 +755,7 @@ def register_subcommand(parser: ArgumentParser): ) add_new_model_like_parser.set_defaults(func=add_new_model_like_command_factory) - def __init__(self, path_to_repo=None, *args): + def __init__(self, path_to_repo=None, **kwargs): ( self.old_model_infos, self.new_lowercase_name, diff --git a/src/transformers/convert_slow_tokenizer.py b/src/transformers/convert_slow_tokenizer.py index a9e7c9bff5bc..77c013d89263 100644 --- a/src/transformers/convert_slow_tokenizer.py +++ b/src/transformers/convert_slow_tokenizer.py @@ -1454,7 +1454,7 @@ def pre_tokenizer(self, replacement, add_prefix_space): class HeliumConverter(SpmConverter): handle_byte_fallback = True - def __init__(self, vocab_file=None, *args): + def __init__(self, vocab_file=None, **kwargs): requires_backends(self, "protobuf") Converter.__init__(self, vocab_file) @@ -1576,10 +1576,8 @@ def __init__( pattern=r"""(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+""", add_prefix_space=False, additional_special_tokens=None, - *args, **kwargs, ): - super().__init__(*args) self.vocab_file = vocab_file self.pattern = pattern self.add_prefix_space = add_prefix_space diff --git a/src/transformers/integrations/mistral.py b/src/transformers/integrations/mistral.py index 78172329277e..cdf237645fc1 100644 --- a/src/transformers/integrations/mistral.py +++ b/src/transformers/integrations/mistral.py @@ -16,10 +16,8 @@ def __init__( pattern=r"""(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+""", add_prefix_space=False, additional_special_tokens=None, - *args, **kwargs, ): - super().__init__(*args) self.vocab = vocab self.pattern = pattern self.add_prefix_space = add_prefix_space diff --git a/src/transformers/pipelines/table_question_answering.py b/src/transformers/pipelines/table_question_answering.py index 12a990766fc7..96bcc863cbe7 100644 --- a/src/transformers/pipelines/table_question_answering.py +++ b/src/transformers/pipelines/table_question_answering.py @@ -122,8 +122,8 @@ class TableQuestionAnsweringPipeline(Pipeline): max_new_tokens=256, ) - def __init__(self, args_parser=TableQuestionAnsweringArgumentHandler(), *args, **kwargs): - super().__init__(*args, **kwargs) + def __init__(self, args_parser=TableQuestionAnsweringArgumentHandler(), **kwargs): + super().__init__(**kwargs) self._args_parser = args_parser mapping = MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES.copy() diff --git a/src/transformers/pipelines/token_classification.py b/src/transformers/pipelines/token_classification.py index fdcf0a2f627f..12de5c19e2ca 100644 --- a/src/transformers/pipelines/token_classification.py +++ b/src/transformers/pipelines/token_classification.py @@ -136,8 +136,8 @@ class TokenClassificationPipeline(ChunkPipeline): _load_feature_extractor = False _load_tokenizer = True - def __init__(self, args_parser=TokenClassificationArgumentHandler(), *args, **kwargs): - super().__init__(*args, **kwargs) + def __init__(self, args_parser=TokenClassificationArgumentHandler(), **kwargs): + super().__init__(**kwargs) self.check_model_type(MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES) diff --git a/src/transformers/pipelines/zero_shot_classification.py b/src/transformers/pipelines/zero_shot_classification.py index 7d30d85b61cf..917f4d753f8f 100644 --- a/src/transformers/pipelines/zero_shot_classification.py +++ b/src/transformers/pipelines/zero_shot_classification.py @@ -87,9 +87,9 @@ class ZeroShotClassificationPipeline(ChunkPipeline): _load_feature_extractor = False _load_tokenizer = True - def __init__(self, args_parser=ZeroShotClassificationArgumentHandler(), *args, **kwargs): + def __init__(self, args_parser=ZeroShotClassificationArgumentHandler(), **kwargs): self._args_parser = args_parser - super().__init__(*args, **kwargs) + super().__init__(**kwargs) if self.entailment_id == -1: logger.warning( "Failed to determine 'entailment' label id from the label2id mapping in the model config. Setting to " diff --git a/src/transformers/trainer_pt_utils.py b/src/transformers/trainer_pt_utils.py index f0e3149cd6ce..15ca6cec5b31 100644 --- a/src/transformers/trainer_pt_utils.py +++ b/src/transformers/trainer_pt_utils.py @@ -1349,7 +1349,7 @@ class LayerWiseDummyOptimizer(torch.optim.Optimizer): https://github.com/hiyouga/LLaMA-Factory/commit/8664262cde3919e10eaecbd66e8c5d356856362e#diff-ebe08ab14496dfb9e06075f0fdd36799ef6d1535cc4dd4715b74c4e3e06fe3ba """ - def __init__(self, optimizer_dict=None, *args, **kwargs): + def __init__(self, optimizer_dict=None, **kwargs): dummy_tensor = torch.randn(1, 1) self.optimizer_dict = optimizer_dict super().__init__([dummy_tensor], {"lr": kwargs.get("lr", 1e-03)}) From 6558e758df87dc59fea455801328f99db7dacdee Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Wed, 24 Sep 2025 19:34:12 +0800 Subject: [PATCH 181/204] Fix broken `` expressions in markdown files (#41113) Fix broken expressions in markdown files Signed-off-by: Yuanyuan Chen --- docs/source/en/model_doc/llama3.md | 2 +- docs/source/en/model_doc/llava.md | 2 +- docs/source/en/model_doc/llava_next_video.md | 2 +- docs/source/en/model_doc/moshi.md | 2 +- docs/source/en/model_doc/video_llava.md | 2 +- docs/source/en/model_doc/vipllava.md | 2 +- docs/source/en/transformers_as_backend.md | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/source/en/model_doc/llama3.md b/docs/source/en/model_doc/llama3.md index 1764617a7d4f..4f98d9c778a5 100644 --- a/docs/source/en/model_doc/llama3.md +++ b/docs/source/en/model_doc/llama3.md @@ -60,7 +60,7 @@ Tips: - Weights for the Llama3 models can be obtained by filling out [this form](https://ai.meta.com/resources/models-and-libraries/llama-downloads/) - The architecture is exactly the same as Llama2. -- The tokenizer is a BPE model based on [tiktoken](https://github.com/openai/tiktoken) (vs the one based on sentencepiece implementation for Llama2). The main difference that it ignores BPE merge rules when an input token is part of the vocab. This means that if no merge exist to produce `"hugging"`, instead of having the smallest units, like `["hug","ging"] form 2 tokens, if `"hugging"` is part of the vocab, it will be automatically returned as a token. +- The tokenizer is a BPE model based on [tiktoken](https://github.com/openai/tiktoken) (vs the one based on sentencepiece implementation for Llama2). The main difference that it ignores BPE merge rules when an input token is part of the vocab. This means that if no merge exist to produce `"hugging"`, instead of having the smallest units, like `["hug","ging"]` form 2 tokens, if `"hugging"` is part of the vocab, it will be automatically returned as a token. - The original model uses `pad_id = -1` which means that there is no padding token. We can't have the same logic, make sure to add a padding token using `tokenizer.add_special_tokens({"pad_token":""})` and resize the token embedding accordingly. You should also set the `model.config.pad_token_id`. The `embed_tokens` layer of the model is initialized with `self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.config.padding_idx)`, which makes sure that encoding the padding token will output zeros, so passing it when initializing is recommended. - The original checkpoint can be converted using the [conversion script](https://github.com/huggingface/transformers/blob/main/src/transformers/models/llama/convert_llama_weights_to_hf.py). The script can be called with the following (example) command: diff --git a/docs/source/en/model_doc/llava.md b/docs/source/en/model_doc/llava.md index e4ef7d770694..cfcc6f08e6a7 100644 --- a/docs/source/en/model_doc/llava.md +++ b/docs/source/en/model_doc/llava.md @@ -48,7 +48,7 @@ The original code can be found [here](https://github.com/haotian-liu/LLaVA/tree/ - Note the model has not been explicitly trained to process multiple images in the same prompt, although this is technically possible, you may experience inaccurate results. > [!NOTE] -> LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. +> LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and `processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. Adding these attributes means that LLaVA will try to infer the number of image tokens required per image and expand the text with as many `` placeholders as there will be tokens. Usually it is around 500 tokens per image, so make sure that the text is not truncated as otherwise there will be failure when merging the embeddings. The attributes can be obtained from model config, as `model.config.vision_config.patch_size` or `model.config.vision_feature_select_strategy`. The `num_additional_image_tokens` should be `1` if the vision backbone adds a CLS token or `0` if nothing extra is added to the vision patches. diff --git a/docs/source/en/model_doc/llava_next_video.md b/docs/source/en/model_doc/llava_next_video.md index 131dd1aba50e..c3357ad0bd81 100644 --- a/docs/source/en/model_doc/llava_next_video.md +++ b/docs/source/en/model_doc/llava_next_video.md @@ -55,7 +55,7 @@ The original code can be found [here](https://github.com/LLaVA-VL/LLaVA-NeXT/tre > [!NOTE] -> LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. +> LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and `processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. Adding these attributes means that LLaVA will try to infer the number of image tokens required per image and expand the text with as many `` placeholders as there will be tokens. Usually it is around 500 tokens per image, so make sure that the text is not truncated as otherwise there will be failure when merging the embeddings. The attributes can be obtained from model config, as `model.config.vision_config.patch_size` or `model.config.vision_feature_select_strategy`. The `num_additional_image_tokens` should be `1` if the vision backbone adds a CLS token or `0` if nothing extra is added to the vision patches. diff --git a/docs/source/en/model_doc/moshi.md b/docs/source/en/model_doc/moshi.md index 49fae1c539d7..ff7b4bc8a153 100644 --- a/docs/source/en/model_doc/moshi.md +++ b/docs/source/en/model_doc/moshi.md @@ -49,7 +49,7 @@ Moshi's made of 3 components: **1. The main decoder (Helium in the paper)** -It corresponds to [`MoshiForCausalLM`]. It is strictly a classic text LLM, that uses an architecture similar to [` ~GemmaForCausalLM`]. In other words, it takes text tokens, embeds them, pass them through the decoder and a language head, to get text logits. +It corresponds to [`MoshiForCausalLM`]. It is strictly a classic text LLM, that uses an architecture similar to [`~GemmaForCausalLM`]. In other words, it takes text tokens, embeds them, pass them through the decoder and a language head, to get text logits. **2. The depth decoder** diff --git a/docs/source/en/model_doc/video_llava.md b/docs/source/en/model_doc/video_llava.md index 5b792b33733f..2e1bf19abdc6 100644 --- a/docs/source/en/model_doc/video_llava.md +++ b/docs/source/en/model_doc/video_llava.md @@ -60,7 +60,7 @@ This model was contributed by [RaushanTurganbay](https://huggingface.co/RaushanT The original code can be found [here](https://github.com/PKU-YuanGroup/Video-LLaVA). > [!NOTE] -> LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. +> LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and `processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. Adding these attributes means that LLaVA will try to infer the number of image tokens required per image and expand the text with as many `` placeholders as there will be tokens. Usually it is around 500 tokens per image, so make sure that the text is not truncated as otherwise there will be failure when merging the embeddings. The attributes can be obtained from model config, as `model.config.vision_config.patch_size` or `model.config.vision_feature_select_strategy`. The `num_additional_image_tokens` should be `1` if the vision backbone adds a CLS token or `0` if nothing extra is added to the vision patches. diff --git a/docs/source/en/model_doc/vipllava.md b/docs/source/en/model_doc/vipllava.md index fc4aec6ae9b1..a6554c91b57c 100644 --- a/docs/source/en/model_doc/vipllava.md +++ b/docs/source/en/model_doc/vipllava.md @@ -46,7 +46,7 @@ This model was contributed by [Younes Belkada](https://huggingface.co/ybelkada) - Note the model has not been explicitly trained to process multiple images in the same prompt, although this is technically possible, you may experience inaccurate results. > [!NOTE] -> LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. +> LLaVA models after release v4.46 will raise warnings about adding `processor.patch_size = {{patch_size}}`, `processor.num_additional_image_tokens = {{num_additional_image_tokens}}` and `processor.vision_feature_select_strategy = {{vision_feature_select_strategy}}`. It is strongly recommended to add the attributes to the processor if you own the model checkpoint, or open a PR if it is not owned by you. Adding these attributes means that LLaVA will try to infer the number of image tokens required per image and expand the text with as many `` placeholders as there will be tokens. Usually it is around 500 tokens per image, so make sure that the text is not truncated as otherwise there will be failure when merging the embeddings. The attributes can be obtained from model config, as `model.config.vision_config.patch_size` or `model.config.vision_feature_select_strategy`. The `num_additional_image_tokens` should be `1` if the vision backbone adds a CLS token or `0` if nothing extra is added to the vision patches. diff --git a/docs/source/en/transformers_as_backend.md b/docs/source/en/transformers_as_backend.md index d1070acea6f5..b64ac63cf17e 100644 --- a/docs/source/en/transformers_as_backend.md +++ b/docs/source/en/transformers_as_backend.md @@ -205,7 +205,7 @@ class MyMultimodalModelForConditionalGeneration(MyMultimodalPreTrainedModel, Gen 3. A multimodal model's processing class must have the `self.image_token` and `self.image_token_ids` attributes. These are placeholder tokens used to indicate image positions in the input. The placeholder token is the same token used in the input prompt and to mask scatter image features. - The processing class also needs ` self._get_num_multimodal_tokens` method to compute the number of placeholder tokens needed for multimodal inputs with given sizes and to return a [`MultiModalData`] object. The placeholder for row and column tokens don't count as image placeholders. Only the tokens that are actually replaced by image features are computed. + The processing class also needs `self._get_num_multimodal_tokens` method to compute the number of placeholder tokens needed for multimodal inputs with given sizes and to return a [`MultiModalData`] object. The placeholder for row and column tokens don't count as image placeholders. Only the tokens that are actually replaced by image features are computed. Finally, when `return_mm_token_type_ids=True`, the class has to return `mm_token_type_ids` to indicate whether each position is a text token (`0`) or image placeholder token (`1`). Each image's token type IDs must be contiguous with no breaks between consecutive ones. From 0ab9d77eca0d15563f0e8d052c64fdd2ce232688 Mon Sep 17 00:00:00 2001 From: Yuanyuan Chen Date: Wed, 24 Sep 2025 19:43:17 +0800 Subject: [PATCH 182/204] Remove self-assignment (#41062) * Remove self-assignment Signed-off-by: Yuanyuan Chen * Update src/transformers/integrations/flash_paged.py Co-authored-by: Matt * Clear pass Signed-off-by: Yuanyuan Chen * Clear pass Signed-off-by: Yuanyuan Chen * Clear pass Signed-off-by: Yuanyuan Chen --------- Signed-off-by: Yuanyuan Chen Co-authored-by: Matt --- src/transformers/audio_utils.py | 4 +--- src/transformers/image_utils.py | 4 +--- src/transformers/integrations/flash_paged.py | 5 +---- src/transformers/models/big_bird/modeling_big_bird.py | 1 - src/transformers/models/colpali/configuration_colpali.py | 4 +--- src/transformers/models/colqwen2/configuration_colqwen2.py | 4 +--- src/transformers/models/csm/processing_csm.py | 1 - .../convert_cvt_original_pytorch_checkpoint_to_pytorch.py | 2 -- src/transformers/models/d_fine/modeling_d_fine.py | 2 -- src/transformers/models/d_fine/modular_d_fine.py | 2 -- src/transformers/models/deberta_v2/modeling_deberta_v2.py | 1 - .../models/deprecated/van/convert_van_to_pytorch.py | 2 -- src/transformers/models/depth_pro/configuration_depth_pro.py | 1 - src/transformers/models/depth_pro/modeling_depth_pro.py | 1 - src/transformers/models/dpt/configuration_dpt.py | 4 +--- src/transformers/models/esm/modeling_esm.py | 1 - src/transformers/models/evolla/modeling_evolla.py | 1 - src/transformers/models/evolla/modular_evolla.py | 1 - ...vert_distilhubert_original_s3prl_checkpoint_to_pytorch.py | 2 -- .../models/kosmos2_5/image_processing_kosmos2_5_fast.py | 1 - .../models/levit/convert_levit_timm_to_pytorch.py | 2 -- src/transformers/models/llava_next/modeling_llava_next.py | 2 -- .../models/llava_next_video/modeling_llava_next_video.py | 4 ---- .../models/llava_next_video/modular_llava_next_video.py | 4 ---- .../models/llava_onevision/modeling_llava_onevision.py | 4 ---- .../models/llava_onevision/modular_llava_onevision.py | 4 ---- src/transformers/models/oneformer/modeling_oneformer.py | 3 --- .../models/perception_lm/configuration_perception_lm.py | 2 +- ...vert_prophetnet_original_pytorch_checkpoint_to_pytorch.py | 4 +--- .../models/regnet/convert_regnet_seer_10b_to_pytorch.py | 2 -- src/transformers/models/regnet/convert_regnet_to_pytorch.py | 2 -- src/transformers/models/resnet/convert_resnet_to_pytorch.py | 2 -- src/transformers/models/sam2/configuration_sam2.py | 4 +--- .../models/sam2_video/configuration_sam2_video.py | 2 -- src/transformers/models/sam2_video/modular_sam2_video.py | 2 -- .../models/seamless_m4t/modeling_seamless_m4t.py | 2 -- .../models/seamless_m4t_v2/modeling_seamless_m4t_v2.py | 3 --- src/transformers/models/sew_d/modeling_sew_d.py | 1 - .../models/wav2vec2_bert/modeling_wav2vec2_bert.py | 2 -- .../models/wav2vec2_bert/modular_wav2vec2_bert.py | 2 -- .../models/wav2vec2_conformer/modeling_wav2vec2_conformer.py | 2 -- .../models/wav2vec2_conformer/modular_wav2vec2_conformer.py | 2 -- src/transformers/models/xlstm/modeling_xlstm.py | 2 +- 43 files changed, 10 insertions(+), 93 deletions(-) diff --git a/src/transformers/audio_utils.py b/src/transformers/audio_utils.py index 6f25f892ba7a..e2137bb1d1b0 100644 --- a/src/transformers/audio_utils.py +++ b/src/transformers/audio_utils.py @@ -81,9 +81,7 @@ def load_audio(audio: Union[str, np.ndarray], sampling_rate=16000, timeout=None) audio = load_audio_torchcodec(audio, sampling_rate=sampling_rate) else: audio = load_audio_librosa(audio, sampling_rate=sampling_rate, timeout=timeout) - elif isinstance(audio, np.ndarray): - audio = audio - else: + elif not isinstance(audio, np.ndarray): raise TypeError( "Incorrect format used for `audio`. Should be an url linking to an audio, a local path, or numpy array." ) diff --git a/src/transformers/image_utils.py b/src/transformers/image_utils.py index fdbc388de337..ac3258da67bc 100644 --- a/src/transformers/image_utils.py +++ b/src/transformers/image_utils.py @@ -477,9 +477,7 @@ def load_image(image: Union[str, "PIL.Image.Image"], timeout: Optional[float] = raise ValueError( f"Incorrect image source. Must be a valid URL starting with `http://` or `https://`, a valid path to an image file, or a base64 encoded string. Got {image}. Failed with {e}" ) - elif isinstance(image, PIL.Image.Image): - image = image - else: + elif not isinstance(image, PIL.Image.Image): raise TypeError( "Incorrect format used for image. Should be an url linking to an image, a base64 string, a local path, or a PIL image." ) diff --git a/src/transformers/integrations/flash_paged.py b/src/transformers/integrations/flash_paged.py index 329fab4c9323..2f11f452c1bb 100644 --- a/src/transformers/integrations/flash_paged.py +++ b/src/transformers/integrations/flash_paged.py @@ -58,11 +58,8 @@ def paged_attention_forward( # Retrieve the cumulative sequence lengths for the current layer if isinstance(cu_seq_lens_k, dict): - cu_seq_lens_k = cu_seq_lens_k[layer_type].clone() + cu_seq_lens_k = cu_seq_lens_k[layer_type] max_seqlen_k = max_seqlen_k[layer_type] - else: - cu_seq_lens_k = cu_seq_lens_k.clone() - max_seqlen_k = max_seqlen_k if implementation is not None and hasattr(implementation, "flash_attn_varlen_func"): flash_attn_varlen_func = implementation.flash_attn_varlen_func diff --git a/src/transformers/models/big_bird/modeling_big_bird.py b/src/transformers/models/big_bird/modeling_big_bird.py index a25c412e688a..6658235c2e03 100755 --- a/src/transformers/models/big_bird/modeling_big_bird.py +++ b/src/transformers/models/big_bird/modeling_big_bird.py @@ -2710,7 +2710,6 @@ def forward( logits_mask = self.prepare_question_mask(question_lengths, seqlen) if token_type_ids is None: token_type_ids = torch.ones(logits_mask.size(), dtype=int, device=logits_mask.device) - logits_mask - logits_mask = logits_mask logits_mask[:, 0] = False logits_mask.unsqueeze_(2) diff --git a/src/transformers/models/colpali/configuration_colpali.py b/src/transformers/models/colpali/configuration_colpali.py index 84be59aef09b..be7eaf47b428 100644 --- a/src/transformers/models/colpali/configuration_colpali.py +++ b/src/transformers/models/colpali/configuration_colpali.py @@ -83,9 +83,7 @@ def __init__( f"The model type `{vlm_config['model_type']}` is not supported. Please provide a valid model type." ) vlm_config = CONFIG_MAPPING[vlm_config["model_type"]](**vlm_config) - elif isinstance(vlm_config, PretrainedConfig): - vlm_config = vlm_config - else: + elif not isinstance(vlm_config, PretrainedConfig): raise TypeError( f"Invalid type for `vlm_config`. Expected `PretrainedConfig`, `dict`, or `None`, but got {type(vlm_config)}." ) diff --git a/src/transformers/models/colqwen2/configuration_colqwen2.py b/src/transformers/models/colqwen2/configuration_colqwen2.py index d9a42df4c97e..21f6e46f1f00 100644 --- a/src/transformers/models/colqwen2/configuration_colqwen2.py +++ b/src/transformers/models/colqwen2/configuration_colqwen2.py @@ -75,9 +75,7 @@ def __init__( "The `model_type` key is missing in the `vlm_config` dictionary. Please provide the model type." ) vlm_config = CONFIG_MAPPING[vlm_config["model_type"]](**vlm_config) - elif isinstance(vlm_config, PretrainedConfig): - vlm_config = vlm_config - else: + elif not isinstance(vlm_config, PretrainedConfig): raise TypeError( f"Invalid type for `vlm_config`. Expected `PretrainedConfig`, `dict`, or `None`, but got {type(vlm_config)}." ) diff --git a/src/transformers/models/csm/processing_csm.py b/src/transformers/models/csm/processing_csm.py index 7e16ecbb6001..cbf7e44aa8d3 100644 --- a/src/transformers/models/csm/processing_csm.py +++ b/src/transformers/models/csm/processing_csm.py @@ -152,7 +152,6 @@ def _get_encoded_length(audio_length, kernel_sizes=None, strides=None, dilations padding_left = padding_total padding_right = extra_padding else: - padding_left = padding_left padding_right = padding_right + extra_padding cur_length = cur_length + padding_left + padding_right diff --git a/src/transformers/models/cvt/convert_cvt_original_pytorch_checkpoint_to_pytorch.py b/src/transformers/models/cvt/convert_cvt_original_pytorch_checkpoint_to_pytorch.py index f65389d1d18a..5752c1fb7aa9 100644 --- a/src/transformers/models/cvt/convert_cvt_original_pytorch_checkpoint_to_pytorch.py +++ b/src/transformers/models/cvt/convert_cvt_original_pytorch_checkpoint_to_pytorch.py @@ -283,11 +283,9 @@ def convert_cvt_checkpoint(cvt_model, image_size, cvt_file_name, pytorch_dump_fo num_labels = 1000 repo_id = "huggingface/label-files" - num_labels = num_labels id2label = json.loads(Path(hf_hub_download(repo_id, img_labels_file, repo_type="dataset")).read_text()) id2label = {int(k): v for k, v in id2label.items()} - id2label = id2label label2id = {v: k for k, v in id2label.items()} config = CvtConfig(num_labels=num_labels, id2label=id2label, label2id=label2id) diff --git a/src/transformers/models/d_fine/modeling_d_fine.py b/src/transformers/models/d_fine/modeling_d_fine.py index 8e4eabfdb86c..cdc008e3c7bb 100644 --- a/src/transformers/models/d_fine/modeling_d_fine.py +++ b/src/transformers/models/d_fine/modeling_d_fine.py @@ -1843,8 +1843,6 @@ def __init__( self, config: DFineConfig, in_channels: int, out_channels: int, num_blocks: int, expansion: float = 1.0 ): super().__init__() - in_channels = in_channels - out_channels = out_channels activation = config.activation_function hidden_channels = int(out_channels * expansion) diff --git a/src/transformers/models/d_fine/modular_d_fine.py b/src/transformers/models/d_fine/modular_d_fine.py index a2e044be7b63..9a41fb23308e 100644 --- a/src/transformers/models/d_fine/modular_d_fine.py +++ b/src/transformers/models/d_fine/modular_d_fine.py @@ -1110,8 +1110,6 @@ def __init__( self, config: DFineConfig, in_channels: int, out_channels: int, num_blocks: int, expansion: float = 1.0 ): super().__init__() - in_channels = in_channels - out_channels = out_channels activation = config.activation_function hidden_channels = int(out_channels * expansion) diff --git a/src/transformers/models/deberta_v2/modeling_deberta_v2.py b/src/transformers/models/deberta_v2/modeling_deberta_v2.py index 71bf04b95542..c13ff3a1ae43 100644 --- a/src/transformers/models/deberta_v2/modeling_deberta_v2.py +++ b/src/transformers/models/deberta_v2/modeling_deberta_v2.py @@ -253,7 +253,6 @@ def forward( if rel_att is not None: attention_scores = attention_scores + rel_att - attention_scores = attention_scores attention_scores = attention_scores.view( -1, self.num_attention_heads, attention_scores.size(-2), attention_scores.size(-1) ) diff --git a/src/transformers/models/deprecated/van/convert_van_to_pytorch.py b/src/transformers/models/deprecated/van/convert_van_to_pytorch.py index ec43af68d76c..9f97d1c0c296 100644 --- a/src/transformers/models/deprecated/van/convert_van_to_pytorch.py +++ b/src/transformers/models/deprecated/van/convert_van_to_pytorch.py @@ -168,11 +168,9 @@ def convert_weights_and_push(save_directory: Path, model_name: Optional[str] = N num_labels = 1000 repo_id = "huggingface/label-files" - num_labels = num_labels id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) id2label = {int(k): v for k, v in id2label.items()} - id2label = id2label label2id = {v: k for k, v in id2label.items()} ImageNetPreTrainedConfig = partial(VanConfig, num_labels=num_labels, id2label=id2label, label2id=label2id) diff --git a/src/transformers/models/depth_pro/configuration_depth_pro.py b/src/transformers/models/depth_pro/configuration_depth_pro.py index 6bc14a0e154f..69bfffeb93f1 100644 --- a/src/transformers/models/depth_pro/configuration_depth_pro.py +++ b/src/transformers/models/depth_pro/configuration_depth_pro.py @@ -188,7 +188,6 @@ def __init__( sub_config.update({"image_size": patch_size}) sub_config = CONFIG_MAPPING[sub_config["model_type"]](**sub_config) elif isinstance(sub_config, PretrainedConfig): - sub_config = sub_config image_size = getattr(sub_config, "image_size", None) if image_size != patch_size: raise ValueError( diff --git a/src/transformers/models/depth_pro/modeling_depth_pro.py b/src/transformers/models/depth_pro/modeling_depth_pro.py index 9fb4c35b23e5..86cf0206c8c9 100644 --- a/src/transformers/models/depth_pro/modeling_depth_pro.py +++ b/src/transformers/models/depth_pro/modeling_depth_pro.py @@ -299,7 +299,6 @@ def forward( scaled_images_features = [] for i in range(self.n_scaled_images): hidden_state = scaled_images_last_hidden_state[i] - batch_size = batch_size padding = torch_int(self.merge_padding_value * (1 / self.scaled_images_ratios[i])) output_height = base_height * 2**i output_width = base_width * 2**i diff --git a/src/transformers/models/dpt/configuration_dpt.py b/src/transformers/models/dpt/configuration_dpt.py index d0263630b075..37bfa25ff6c8 100644 --- a/src/transformers/models/dpt/configuration_dpt.py +++ b/src/transformers/models/dpt/configuration_dpt.py @@ -200,9 +200,7 @@ def __init__( if isinstance(backbone_config, dict): logger.info("Initializing the config with a `BiT` backbone.") backbone_config = BitConfig(**backbone_config) - elif isinstance(backbone_config, PretrainedConfig): - backbone_config = backbone_config - else: + elif not isinstance(backbone_config, PretrainedConfig): raise ValueError( f"backbone_config must be a dictionary or a `PretrainedConfig`, got {backbone_config.__class__}." ) diff --git a/src/transformers/models/esm/modeling_esm.py b/src/transformers/models/esm/modeling_esm.py index 21015e50bb2f..3524b221a0ec 100755 --- a/src/transformers/models/esm/modeling_esm.py +++ b/src/transformers/models/esm/modeling_esm.py @@ -90,7 +90,6 @@ def __init__(self, dim: int): super().__init__() # Generate and save the inverse frequency buffer (non trainable) inv_freq = 1.0 / (10000 ** (torch.arange(0, dim, 2, dtype=torch.int64).float() / dim)) - inv_freq = inv_freq self.register_buffer("inv_freq", inv_freq) self._seq_len_cached = None diff --git a/src/transformers/models/evolla/modeling_evolla.py b/src/transformers/models/evolla/modeling_evolla.py index d95567491fe1..8bb5713d1764 100644 --- a/src/transformers/models/evolla/modeling_evolla.py +++ b/src/transformers/models/evolla/modeling_evolla.py @@ -188,7 +188,6 @@ def __init__(self, dim: int): super().__init__() # Generate and save the inverse frequency buffer (non trainable) inv_freq = 1.0 / (10000 ** (torch.arange(0, dim, 2, dtype=torch.int64).float() / dim)) - inv_freq = inv_freq self.register_buffer("inv_freq", inv_freq) self._seq_len_cached = None diff --git a/src/transformers/models/evolla/modular_evolla.py b/src/transformers/models/evolla/modular_evolla.py index 18a50e9abfae..e2db43a7d787 100644 --- a/src/transformers/models/evolla/modular_evolla.py +++ b/src/transformers/models/evolla/modular_evolla.py @@ -94,7 +94,6 @@ def __init__(self, dim: int): super().__init__() # Generate and save the inverse frequency buffer (non trainable) inv_freq = 1.0 / (10000 ** (torch.arange(0, dim, 2, dtype=torch.int64).float() / dim)) - inv_freq = inv_freq self.register_buffer("inv_freq", inv_freq) self._seq_len_cached = None diff --git a/src/transformers/models/hubert/convert_distilhubert_original_s3prl_checkpoint_to_pytorch.py b/src/transformers/models/hubert/convert_distilhubert_original_s3prl_checkpoint_to_pytorch.py index f5914f35c546..a4930ef9b906 100644 --- a/src/transformers/models/hubert/convert_distilhubert_original_s3prl_checkpoint_to_pytorch.py +++ b/src/transformers/models/hubert/convert_distilhubert_original_s3prl_checkpoint_to_pytorch.py @@ -88,8 +88,6 @@ def recursively_load_weights(fairseq_model, hf_model): is_used = True else: for key, mapped_key in MAPPING.items(): - mapped_key = mapped_key - if key in name: is_used = True if "*" in mapped_key: diff --git a/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py b/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py index 028ccf6bf8a2..b7adeb2c86c2 100644 --- a/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py +++ b/src/transformers/models/kosmos2_5/image_processing_kosmos2_5_fast.py @@ -45,7 +45,6 @@ def torch_extract_patches(image_tensor, patch_height, patch_width): patch_width (int): The width of the patches to extract. """ - image_tensor = image_tensor patches = torch.nn.functional.unfold(image_tensor, (patch_height, patch_width), stride=(patch_height, patch_width)) patches = patches.reshape(image_tensor.size(0), image_tensor.size(1), patch_height, patch_width, -1) patches = patches.permute(0, 4, 2, 3, 1).reshape( diff --git a/src/transformers/models/levit/convert_levit_timm_to_pytorch.py b/src/transformers/models/levit/convert_levit_timm_to_pytorch.py index 0d5731bf7bef..5d198ee9e552 100644 --- a/src/transformers/models/levit/convert_levit_timm_to_pytorch.py +++ b/src/transformers/models/levit/convert_levit_timm_to_pytorch.py @@ -86,11 +86,9 @@ def convert_weights_and_push(save_directory: Path, model_name: Optional[str] = N expected_shape = (1, num_labels) repo_id = "huggingface/label-files" - num_labels = num_labels id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) id2label = {int(k): v for k, v in id2label.items()} - id2label = id2label label2id = {v: k for k, v in id2label.items()} ImageNetPreTrainedConfig = partial(LevitConfig, num_labels=num_labels, id2label=id2label, label2id=label2id) diff --git a/src/transformers/models/llava_next/modeling_llava_next.py b/src/transformers/models/llava_next/modeling_llava_next.py index 8cca63f4a66c..a75b4b798107 100644 --- a/src/transformers/models/llava_next/modeling_llava_next.py +++ b/src/transformers/models/llava_next/modeling_llava_next.py @@ -409,8 +409,6 @@ def get_image_features( if vision_feature_select_strategy == "default": selected_image_feature = selected_image_feature[:, 1:] - elif vision_feature_select_strategy == "full": - selected_image_feature = selected_image_feature image_features = self.multi_modal_projector(selected_image_feature) image_features = torch.split(image_features, image_num_patches, dim=0) diff --git a/src/transformers/models/llava_next_video/modeling_llava_next_video.py b/src/transformers/models/llava_next_video/modeling_llava_next_video.py index 3ef172962c2c..9e3b15cea548 100644 --- a/src/transformers/models/llava_next_video/modeling_llava_next_video.py +++ b/src/transformers/models/llava_next_video/modeling_llava_next_video.py @@ -461,8 +461,6 @@ def get_image_features( if vision_feature_select_strategy == "default": selected_image_feature = selected_image_feature[:, 1:] - elif vision_feature_select_strategy == "full": - selected_image_feature = selected_image_feature image_features = self.multi_modal_projector(selected_image_feature) image_features = torch.split(image_features, image_num_patches, dim=0) @@ -659,8 +657,6 @@ def get_video_features( if vision_feature_select_strategy == "default": selected_video_features = selected_video_features[:, 1:] - elif vision_feature_select_strategy == "full": - selected_video_features = selected_video_features # Same as image features except that video has pooling layer video_features = self.vision_resampler(selected_video_features) diff --git a/src/transformers/models/llava_next_video/modular_llava_next_video.py b/src/transformers/models/llava_next_video/modular_llava_next_video.py index 73745f435b7d..7eda08ffa0bd 100644 --- a/src/transformers/models/llava_next_video/modular_llava_next_video.py +++ b/src/transformers/models/llava_next_video/modular_llava_next_video.py @@ -327,8 +327,6 @@ def get_image_features( if vision_feature_select_strategy == "default": selected_image_feature = selected_image_feature[:, 1:] - elif vision_feature_select_strategy == "full": - selected_image_feature = selected_image_feature image_features = self.multi_modal_projector(selected_image_feature) image_features = torch.split(image_features, image_num_patches, dim=0) @@ -386,8 +384,6 @@ def get_video_features( if vision_feature_select_strategy == "default": selected_video_features = selected_video_features[:, 1:] - elif vision_feature_select_strategy == "full": - selected_video_features = selected_video_features # Same as image features except that video has pooling layer video_features = self.vision_resampler(selected_video_features) diff --git a/src/transformers/models/llava_onevision/modeling_llava_onevision.py b/src/transformers/models/llava_onevision/modeling_llava_onevision.py index eae6e3046f94..727655374574 100644 --- a/src/transformers/models/llava_onevision/modeling_llava_onevision.py +++ b/src/transformers/models/llava_onevision/modeling_llava_onevision.py @@ -432,8 +432,6 @@ def get_image_features( if vision_feature_select_strategy == "default": selected_image_feature = selected_image_feature[:, 1:] - elif vision_feature_select_strategy == "full": - selected_image_feature = selected_image_feature image_features = self.multi_modal_projector(selected_image_feature) image_features = torch.split(image_features, image_num_patches, dim=0) @@ -633,8 +631,6 @@ def get_video_features( if vision_feature_select_strategy == "default": selected_video_feature = selected_video_feature[:, 1:] - elif vision_feature_select_strategy == "full": - selected_video_feature = selected_video_feature video_features = self.multi_modal_projector(selected_video_feature) video_features = self.apply_pooling(video_features) diff --git a/src/transformers/models/llava_onevision/modular_llava_onevision.py b/src/transformers/models/llava_onevision/modular_llava_onevision.py index 21688e7763bf..ec2304e09dd1 100644 --- a/src/transformers/models/llava_onevision/modular_llava_onevision.py +++ b/src/transformers/models/llava_onevision/modular_llava_onevision.py @@ -409,8 +409,6 @@ def get_image_features( if vision_feature_select_strategy == "default": selected_image_feature = selected_image_feature[:, 1:] - elif vision_feature_select_strategy == "full": - selected_image_feature = selected_image_feature image_features = self.multi_modal_projector(selected_image_feature) image_features = torch.split(image_features, image_num_patches, dim=0) @@ -459,8 +457,6 @@ def get_video_features( if vision_feature_select_strategy == "default": selected_video_feature = selected_video_feature[:, 1:] - elif vision_feature_select_strategy == "full": - selected_video_feature = selected_video_feature video_features = self.multi_modal_projector(selected_video_feature) video_features = self.apply_pooling(video_features) diff --git a/src/transformers/models/oneformer/modeling_oneformer.py b/src/transformers/models/oneformer/modeling_oneformer.py index 60f1e74eff49..51c041d7b698 100644 --- a/src/transformers/models/oneformer/modeling_oneformer.py +++ b/src/transformers/models/oneformer/modeling_oneformer.py @@ -2572,9 +2572,6 @@ def __init__( ): super().__init__() self.activation_fn = ACT2FN["quick_gelu"] - hidden_size = hidden_size - intermediate_size = intermediate_size - output_size = output_size self.fc1 = nn.Linear(hidden_size, intermediate_size) self.fc2 = nn.Linear(intermediate_size, output_size) diff --git a/src/transformers/models/perception_lm/configuration_perception_lm.py b/src/transformers/models/perception_lm/configuration_perception_lm.py index 4b94652e2084..08c084065ff8 100644 --- a/src/transformers/models/perception_lm/configuration_perception_lm.py +++ b/src/transformers/models/perception_lm/configuration_perception_lm.py @@ -68,7 +68,7 @@ def __init__( if isinstance(vision_config, dict): vision_config = TimmWrapperConfig(**vision_config) elif isinstance(vision_config, TimmWrapperConfig): - vision_config = vision_config + pass elif vision_config is None: vision_config = TimmWrapperConfig() self.vision_config = vision_config diff --git a/src/transformers/models/prophetnet/convert_prophetnet_original_pytorch_checkpoint_to_pytorch.py b/src/transformers/models/prophetnet/convert_prophetnet_original_pytorch_checkpoint_to_pytorch.py index 805338511d8a..5a1fe6bfac6f 100644 --- a/src/transformers/models/prophetnet/convert_prophetnet_original_pytorch_checkpoint_to_pytorch.py +++ b/src/transformers/models/prophetnet/convert_prophetnet_original_pytorch_checkpoint_to_pytorch.py @@ -132,9 +132,7 @@ def convert_prophetnet_checkpoint_to_pytorch(prophetnet_checkpoint_path: str, py else: model = getattr(model, attribute) - if old_attribute == "": - old_model = old_model - else: + if old_attribute: if not hasattr(old_model, old_attribute): raise ValueError(f"{old_model} does not have {old_attribute}") old_model = getattr(old_model, old_attribute) diff --git a/src/transformers/models/regnet/convert_regnet_seer_10b_to_pytorch.py b/src/transformers/models/regnet/convert_regnet_seer_10b_to_pytorch.py index ed4bc48035d0..a27296dae8e4 100644 --- a/src/transformers/models/regnet/convert_regnet_seer_10b_to_pytorch.py +++ b/src/transformers/models/regnet/convert_regnet_seer_10b_to_pytorch.py @@ -164,11 +164,9 @@ def convert_weights_and_push(save_directory: Path, model_name: Optional[str] = N num_labels = 1000 repo_id = "huggingface/label-files" - num_labels = num_labels id2label = json.loads(Path(hf_hub_download(repo_id, filename, repo_type="dataset")).read_text()) id2label = {int(k): v for k, v in id2label.items()} - id2label = id2label label2id = {v: k for k, v in id2label.items()} ImageNetPreTrainedConfig = partial(RegNetConfig, num_labels=num_labels, id2label=id2label, label2id=label2id) diff --git a/src/transformers/models/regnet/convert_regnet_to_pytorch.py b/src/transformers/models/regnet/convert_regnet_to_pytorch.py index 9d6659d7685d..d74e6ad263f0 100644 --- a/src/transformers/models/regnet/convert_regnet_to_pytorch.py +++ b/src/transformers/models/regnet/convert_regnet_to_pytorch.py @@ -224,11 +224,9 @@ def convert_weights_and_push(save_directory: Path, model_name: Optional[str] = N expected_shape = (1, num_labels) repo_id = "huggingface/label-files" - num_labels = num_labels id2label = json.loads(Path(hf_hub_download(repo_id, filename, repo_type="dataset")).read_text()) id2label = {int(k): v for k, v in id2label.items()} - id2label = id2label label2id = {v: k for k, v in id2label.items()} ImageNetPreTrainedConfig = partial(RegNetConfig, num_labels=num_labels, id2label=id2label, label2id=label2id) diff --git a/src/transformers/models/resnet/convert_resnet_to_pytorch.py b/src/transformers/models/resnet/convert_resnet_to_pytorch.py index 11b09c372c31..1e02a3e8b6c0 100644 --- a/src/transformers/models/resnet/convert_resnet_to_pytorch.py +++ b/src/transformers/models/resnet/convert_resnet_to_pytorch.py @@ -128,11 +128,9 @@ def convert_weights_and_push(save_directory: Path, model_name: Optional[str] = N expected_shape = (1, num_labels) repo_id = "huggingface/label-files" - num_labels = num_labels id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) id2label = {int(k): v for k, v in id2label.items()} - id2label = id2label label2id = {v: k for k, v in id2label.items()} ImageNetPreTrainedConfig = partial(ResNetConfig, num_labels=num_labels, id2label=id2label, label2id=label2id) diff --git a/src/transformers/models/sam2/configuration_sam2.py b/src/transformers/models/sam2/configuration_sam2.py index 39fbc9dfc2f5..8a93f28d5a20 100644 --- a/src/transformers/models/sam2/configuration_sam2.py +++ b/src/transformers/models/sam2/configuration_sam2.py @@ -214,7 +214,7 @@ def __init__( backbone_config["model_type"] = backbone_config.get("model_type", "sam2_hiera_det_model") backbone_config = CONFIG_MAPPING[backbone_config["model_type"]](**backbone_config) elif isinstance(backbone_config, Sam2HieraDetConfig): - backbone_config = backbone_config + pass elif backbone_config is None: backbone_config = Sam2HieraDetConfig() @@ -434,8 +434,6 @@ def __init__( if isinstance(vision_config, dict): vision_config["model_type"] = vision_config.get("model_type", "sam2_vision_model") vision_config = CONFIG_MAPPING[vision_config["model_type"]](**vision_config) - elif isinstance(vision_config, PretrainedConfig): - vision_config = vision_config if isinstance(prompt_encoder_config, Sam2PromptEncoderConfig): prompt_encoder_config = prompt_encoder_config.to_dict() if isinstance(mask_decoder_config, Sam2MaskDecoderConfig): diff --git a/src/transformers/models/sam2_video/configuration_sam2_video.py b/src/transformers/models/sam2_video/configuration_sam2_video.py index a47858c6340e..2712165b44c5 100644 --- a/src/transformers/models/sam2_video/configuration_sam2_video.py +++ b/src/transformers/models/sam2_video/configuration_sam2_video.py @@ -335,8 +335,6 @@ def __init__( if isinstance(vision_config, dict): vision_config["model_type"] = vision_config.get("model_type", "sam2_vision_model") vision_config = CONFIG_MAPPING[vision_config["model_type"]](**vision_config) - elif isinstance(vision_config, PretrainedConfig): - vision_config = vision_config if isinstance(prompt_encoder_config, Sam2VideoPromptEncoderConfig): prompt_encoder_config = prompt_encoder_config.to_dict() if isinstance(mask_decoder_config, Sam2VideoMaskDecoderConfig): diff --git a/src/transformers/models/sam2_video/modular_sam2_video.py b/src/transformers/models/sam2_video/modular_sam2_video.py index c0c9b3e1ef7a..53e10998b2a7 100644 --- a/src/transformers/models/sam2_video/modular_sam2_video.py +++ b/src/transformers/models/sam2_video/modular_sam2_video.py @@ -264,8 +264,6 @@ def __init__( if isinstance(vision_config, dict): vision_config["model_type"] = vision_config.get("model_type", "sam2_vision_model") vision_config = CONFIG_MAPPING[vision_config["model_type"]](**vision_config) - elif isinstance(vision_config, PretrainedConfig): - vision_config = vision_config if isinstance(prompt_encoder_config, Sam2VideoPromptEncoderConfig): prompt_encoder_config = prompt_encoder_config.to_dict() if isinstance(mask_decoder_config, Sam2VideoMaskDecoderConfig): diff --git a/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py b/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py index 0c4f1118d30f..9332e18856a2 100755 --- a/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py +++ b/src/transformers/models/seamless_m4t/modeling_seamless_m4t.py @@ -631,8 +631,6 @@ def forward( output_attentions: bool = False, conv_attention_mask: Optional[torch.Tensor] = None, ): - hidden_states = hidden_states - # 1. Feed-Forward 1 layer residual = hidden_states hidden_states = self.ffn1_layer_norm(hidden_states) diff --git a/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py b/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py index 352dc20011af..4836416bced6 100644 --- a/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py +++ b/src/transformers/models/seamless_m4t_v2/modeling_seamless_m4t_v2.py @@ -476,8 +476,6 @@ def forward( output_attentions: bool = False, conv_attention_mask: Optional[torch.Tensor] = None, ): - hidden_states = hidden_states - # 1. Feed-Forward 1 layer residual = hidden_states hidden_states = self.ffn1_layer_norm(hidden_states) @@ -540,7 +538,6 @@ def _apply_chunk_attention(self, attention_mask, hidden_states): if self.config.speech_encoder_left_chunk_num >= 0: start_indices = (chunk_indices - self.config.speech_encoder_left_chunk_num).clamp_(min=0) start_indices = start_indices * self.config.speech_encoder_chunk_size - start_indices = start_indices start_indices = start_indices.unsqueeze(1).expand(-1, sequence_len) end_indices = ((chunk_indices + 1) * self.config.speech_encoder_chunk_size).clamp_(max=sequence_len) diff --git a/src/transformers/models/sew_d/modeling_sew_d.py b/src/transformers/models/sew_d/modeling_sew_d.py index e7535a8365f4..99253578db5f 100644 --- a/src/transformers/models/sew_d/modeling_sew_d.py +++ b/src/transformers/models/sew_d/modeling_sew_d.py @@ -755,7 +755,6 @@ def forward( if rel_att is not None: attention_scores = attention_scores + rel_att - attention_scores = attention_scores attention_scores = attention_scores.view( -1, self.num_attention_heads, attention_scores.size(-2), attention_scores.size(-1) ) diff --git a/src/transformers/models/wav2vec2_bert/modeling_wav2vec2_bert.py b/src/transformers/models/wav2vec2_bert/modeling_wav2vec2_bert.py index e8f67e2d73cd..3448089c632b 100644 --- a/src/transformers/models/wav2vec2_bert/modeling_wav2vec2_bert.py +++ b/src/transformers/models/wav2vec2_bert/modeling_wav2vec2_bert.py @@ -428,8 +428,6 @@ def forward( output_attentions: bool = False, conv_attention_mask: Optional[torch.Tensor] = None, ): - hidden_states = hidden_states - # 1. Feed-Forward 1 layer residual = hidden_states hidden_states = self.ffn1_layer_norm(hidden_states) diff --git a/src/transformers/models/wav2vec2_bert/modular_wav2vec2_bert.py b/src/transformers/models/wav2vec2_bert/modular_wav2vec2_bert.py index b9b60a6bd3ad..79f70da7cb84 100644 --- a/src/transformers/models/wav2vec2_bert/modular_wav2vec2_bert.py +++ b/src/transformers/models/wav2vec2_bert/modular_wav2vec2_bert.py @@ -326,8 +326,6 @@ def forward( output_attentions: bool = False, conv_attention_mask: Optional[torch.Tensor] = None, ): - hidden_states = hidden_states - # 1. Feed-Forward 1 layer residual = hidden_states hidden_states = self.ffn1_layer_norm(hidden_states) diff --git a/src/transformers/models/wav2vec2_conformer/modeling_wav2vec2_conformer.py b/src/transformers/models/wav2vec2_conformer/modeling_wav2vec2_conformer.py index b786e415546e..9a3a79e05d86 100644 --- a/src/transformers/models/wav2vec2_conformer/modeling_wav2vec2_conformer.py +++ b/src/transformers/models/wav2vec2_conformer/modeling_wav2vec2_conformer.py @@ -602,8 +602,6 @@ def forward( relative_position_embeddings: Optional[torch.Tensor] = None, output_attentions: bool = False, ): - hidden_states = hidden_states - # 1. Feed-Forward 1 layer residual = hidden_states hidden_states = self.ffn1_layer_norm(hidden_states) diff --git a/src/transformers/models/wav2vec2_conformer/modular_wav2vec2_conformer.py b/src/transformers/models/wav2vec2_conformer/modular_wav2vec2_conformer.py index 2c009c004453..bfa6c20737d8 100644 --- a/src/transformers/models/wav2vec2_conformer/modular_wav2vec2_conformer.py +++ b/src/transformers/models/wav2vec2_conformer/modular_wav2vec2_conformer.py @@ -410,8 +410,6 @@ def forward( relative_position_embeddings: Optional[torch.Tensor] = None, output_attentions: bool = False, ): - hidden_states = hidden_states - # 1. Feed-Forward 1 layer residual = hidden_states hidden_states = self.ffn1_layer_norm(hidden_states) diff --git a/src/transformers/models/xlstm/modeling_xlstm.py b/src/transformers/models/xlstm/modeling_xlstm.py index 5bb438efce7e..fd577c0c0bac 100644 --- a/src/transformers/models/xlstm/modeling_xlstm.py +++ b/src/transformers/models/xlstm/modeling_xlstm.py @@ -169,7 +169,7 @@ def mlstm_chunkwise_parallel_fw_H( eps: float = 1e-6, ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]: _device = matQ.device - nc, chunk_size = num_chunks, chunk_size + nc = num_chunks batch_size, nh, dqk, dhv = matC_states.shape matC_k_states = matC_states.view(batch_size, nh, nc, dqk // nc, dhv) vecN_k_states = vecN_states.view(batch_size, nh, nc, dqk // nc) From 7d70f39a393740fe008e95a619e7ee41e33eaa2f Mon Sep 17 00:00:00 2001 From: lilin-1 <256404019@qq.com> Date: Wed, 24 Sep 2025 19:54:55 +0800 Subject: [PATCH 183/204] =?UTF-8?q?=F0=9F=9A=A8Refactor:=20Update=20text2t?= =?UTF-8?q?ext=20generation=20pipelines=20to=20use=20max=5Fnew=5Ftokens?= =?UTF-8?q?=E2=80=A6=20(#40928)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor: Update text2text generation pipelines to use max_new_tokens and resolve max_length warning * docs(text2text_generation): 更新参数注释以反映现代生成实践 将max_length参数注释更新为max_new_tokens,以符合现代生成实践中指定生成新token数量的标准做法 * refactor(text2text_generation): Remove outdated input validation logic * docs(text2text_generation): Revert incorrectly modified comment * docs(text2text_generation): Revert incorrectly modified comment --- .../pipelines/text2text_generation.py | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/transformers/pipelines/text2text_generation.py b/src/transformers/pipelines/text2text_generation.py index eb7e0bce8a34..9f98f5725279 100644 --- a/src/transformers/pipelines/text2text_generation.py +++ b/src/transformers/pipelines/text2text_generation.py @@ -123,7 +123,7 @@ def _sanitize_parameters( return preprocess_params, forward_params, postprocess_params - def check_inputs(self, input_length: int, min_length: int, max_length: int): + def check_inputs(self, input_length: int, min_length: int, max_new_tokens: int): """ Checks whether there might be something wrong with given input with regard to the model. """ @@ -198,7 +198,7 @@ def _forward(self, model_inputs, **generate_kwargs): self.check_inputs( input_length, generate_kwargs.get("min_length", self.generation_config.min_length), - generate_kwargs.get("max_length", self.generation_config.max_length), + generate_kwargs.get("max_new_tokens", self.generation_config.max_new_tokens), ) # User-defined `generation_config` passed to the pipeline call take precedence @@ -284,18 +284,18 @@ def __call__(self, *args, **kwargs): """ return super().__call__(*args, **kwargs) - def check_inputs(self, input_length: int, min_length: int, max_length: int) -> bool: + def check_inputs(self, input_length: int, min_length: int, max_new_tokens: int) -> bool: """ Checks whether there might be something wrong with given input with regard to the model. """ - if max_length < min_length: - logger.warning(f"Your min_length={min_length} must be inferior than your max_length={max_length}.") + if max_new_tokens < min_length: + logger.warning(f"Your min_length={min_length} must be inferior than your max_new_tokens={max_new_tokens}.") - if input_length < max_length: + if input_length < max_new_tokens: logger.warning( - f"Your max_length is set to {max_length}, but your input_length is only {input_length}. Since this is " + f"Your max_new_tokens is set to {max_new_tokens}, but your input_length is only {input_length}. Since this is " "a summarization task, where outputs shorter than the input are typically wanted, you might " - f"consider decreasing max_length manually, e.g. summarizer('...', max_length={input_length // 2})" + f"consider decreasing max_new_tokens manually, e.g. summarizer('...', max_new_tokens={input_length // 2})" ) @@ -327,12 +327,10 @@ class TranslationPipeline(Text2TextGenerationPipeline): # Used in the return key of the pipeline. return_name = "translation" - def check_inputs(self, input_length: int, min_length: int, max_length: int): - if input_length > 0.9 * max_length: - logger.warning( - f"Your input_length: {input_length} is bigger than 0.9 * max_length: {max_length}. You might consider " - "increasing your max_length manually, e.g. translator('...', max_length=400)" - ) + def check_inputs(self, input_length: int, min_length: int, max_new_tokens: int): + """ + Removed input length check - unnecessary with max_new_tokens (previously relevant for max_length) + """ return True def preprocess(self, *args, truncation=TruncationStrategy.DO_NOT_TRUNCATE, src_lang=None, tgt_lang=None): From 13f9a7d1bd5b82e6ad4fe8950c75303eb1855ed0 Mon Sep 17 00:00:00 2001 From: YangKai0616 Date: Wed, 24 Sep 2025 20:11:51 +0800 Subject: [PATCH 184/204] Fixed MXFP4 model storage issue (#41118) --- src/transformers/quantizers/quantizer_mxfp4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/quantizers/quantizer_mxfp4.py b/src/transformers/quantizers/quantizer_mxfp4.py index d0d370a11df6..a50f905dfa17 100644 --- a/src/transformers/quantizers/quantizer_mxfp4.py +++ b/src/transformers/quantizers/quantizer_mxfp4.py @@ -379,7 +379,7 @@ def update_param_name(self, param_name: str) -> str: return param_name.replace("down_proj", "down_proj_blocks") return param_name - def get_state_dict_and_metadata(self, model): + def get_state_dict_and_metadata(self, model, safe_serialization: bool = False): from ..integrations import Mxfp4GptOssExperts state_dict = model.state_dict() From 0f312b2aada7755cc41f2208291a5479bc2ed923 Mon Sep 17 00:00:00 2001 From: Karol Szustakowski <61427290+Szustarol@users.noreply.github.com> Date: Wed, 24 Sep 2025 14:13:18 +0200 Subject: [PATCH 185/204] Fixed loading LongT5 from legacy checkpoints (#40724) * Fixed loading LongT5 from legacy checkpoints * Adapted the fix to work with missing lm_head --- .../models/longt5/modeling_longt5.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/transformers/models/longt5/modeling_longt5.py b/src/transformers/models/longt5/modeling_longt5.py index a3499fb2a0ba..534b148b956d 100644 --- a/src/transformers/models/longt5/modeling_longt5.py +++ b/src/transformers/models/longt5/modeling_longt5.py @@ -1267,6 +1267,36 @@ def dummy_inputs(self): } return dummy_inputs + def _try_load_missing_tied_module(self, key): + module = self + if key.endswith(".weight"): + key = key[: -len(".weight")] + for sub_key in key.split("."): + if not hasattr(module, sub_key): + return + module = getattr(module, sub_key) + + self._tie_or_clone_weights(module, self.shared) + + @classmethod + def from_pretrained(self, *args, **kwargs): + requested_loading_info = kwargs.get("output_loading_info", False) + kwargs["output_loading_info"] = True + model, loading_info = super().from_pretrained(*args, **kwargs) + missing_keys = loading_info.get("missing_keys", []) + + if hasattr(model, "shared") and hasattr(model, "_tied_weights_keys"): + for missing_key in missing_keys: + logger.warning( + f"Recovering a missing tied weight {missing_key} from a legacy LongT5 checkpoint. " + f"Consider saving {missing_key} in your checkpoint or updating the config (tie_word_embeddings=true)." + ) + model._try_load_missing_tied_module(missing_key) + + if requested_loading_info: + return model, loading_info + return model + def _init_weights(self, module): """Initialize the weights""" factor = self.config.initializer_factor # Used for testing weights initialization From 295cf0b5a81766bcfc53ba22aa9e3dad391b6339 Mon Sep 17 00:00:00 2001 From: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Date: Wed, 24 Sep 2025 16:31:46 +0200 Subject: [PATCH 186/204] dummy commit (#41133) * dummy commit, nothing interesting * dummy commit, nothing interesting * dummy commit, nothing interesting * dummy commit, nothing interesting --------- Co-authored-by: ydshieh --- .circleci/create_circleci_config.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.circleci/create_circleci_config.py b/.circleci/create_circleci_config.py index 1e39aa4751a5..c2469b53ccf5 100644 --- a/.circleci/create_circleci_config.py +++ b/.circleci/create_circleci_config.py @@ -129,6 +129,12 @@ def __post_init__(self): def to_dict(self): env = COMMON_ENV_VARIABLES.copy() + if self.job_name != "tests_hub": + # fmt: off + # not critical + env.update({"HF_TOKEN": "".join(["h", "f", "_", "H", "o", "d", "V", "u", "M", "q", "b", "R", "m", "t", "b", "z", "F", "Q", "O", "Q", "A", "J", "G", "D", "l", "V", "Q", "r", "R", "N", "w", "D", "M", "V", "C", "s", "d"])}) + # fmt: on + # Do not run tests decorated by @is_flaky on pull requests env['RUN_FLAKY'] = os.environ.get("CIRCLE_PULL_REQUEST", "") == "" env.update(self.additional_env) From 212e8274f6d6655341064309155823618901e5f7 Mon Sep 17 00:00:00 2001 From: Lysandre Debut Date: Wed, 24 Sep 2025 16:44:42 +0200 Subject: [PATCH 187/204] Fix loading logic flaw with regards to unexpected and missing keys (#40850) * Unexpected keys should be ignored at load with device map * remove them all * fix logic flaw * fix * simplify * style * fix * revert caching allocator change * add other test * add nice doc --------- Co-authored-by: Cyril Vallez --- src/transformers/modeling_utils.py | 51 ++++++------- tests/utils/test_modeling_utils.py | 114 ++++++++++++++++++++++++++++- 2 files changed, 137 insertions(+), 28 deletions(-) diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index 55ab06dcb85a..a64085c4e931 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -738,8 +738,6 @@ def _load_state_dict_into_meta_model( file_pointer = safe_open(shard_file, framework="pt", device=tensor_device) for param_name, empty_param in state_dict.items(): - if param_name not in expected_keys: # when loading from ckpt, we skip param if doesnt exist in modeling - continue # we need to use serialized_param_name as file pointer is untouched if is_meta_state_dict: # This is the name of the parameter as it appears on disk file @@ -1414,7 +1412,6 @@ def _get_device_map( def _find_missing_and_unexpected_keys( - cls, model: "PreTrainedModel", original_checkpoint_keys: list[str], checkpoint_keys: list[str], @@ -1444,12 +1441,6 @@ def _find_missing_and_unexpected_keys( model_buffers = {n for n, _ in model.named_buffers()} unexpected_keys = sorted(unexpected_keys - model_buffers) - # Old checkpoints may have keys for rotary_emb.inv_freq for each layer, however we moved this buffer to the main model - # (so the buffer name has changed). Remove them in such a case - has_inv_freq_buffers = any(buffer.endswith("rotary_emb.inv_freq") for buffer in model_buffers) - if has_inv_freq_buffers: - unexpected_keys = [k for k in unexpected_keys if "rotary_emb.inv_freq" not in k] - tied_params = find_tied_parameters(model) for group in tied_params: missing_in_group = [k for k in missing_keys if k in group] @@ -1460,15 +1451,6 @@ def _find_missing_and_unexpected_keys( missing_keys = hf_quantizer.update_missing_keys(model, missing_keys, prefix) unexpected_keys = hf_quantizer.update_unexpected_keys(model, unexpected_keys, prefix) - # Model-specific exceptions for missing and unexpected keys (e.g. if the modeling change over time, or any other reason...) - if cls._keys_to_ignore_on_load_missing is not None: - for pattern in cls._keys_to_ignore_on_load_missing: - missing_keys = [k for k in missing_keys if re.search(pattern, k) is None] - - if cls._keys_to_ignore_on_load_unexpected is not None: - for pattern in cls._keys_to_ignore_on_load_unexpected: - unexpected_keys = [k for k in unexpected_keys if re.search(pattern, k) is None] - return missing_keys, unexpected_keys @@ -5320,12 +5302,7 @@ def _load_pretrained_model( # Find missing and unexpected keys from the state dict missing_keys, unexpected_keys = _find_missing_and_unexpected_keys( - cls, - model, - original_checkpoint_keys, - checkpoint_keys, - loading_base_model_from_task_state_dict, - hf_quantizer, + model, original_checkpoint_keys, checkpoint_keys, loading_base_model_from_task_state_dict, hf_quantizer ) # Find all the keys with shape mismatch (if we ignore the mismatch, the weights need to be newly initialized the # same way as missing keys) @@ -5339,8 +5316,10 @@ def _load_pretrained_model( weights_only, ) - # We need to update both the mapping and the list of checkpoint keys to remove the mismatched ones - key_renaming_mapping = {k: v for k, v in key_renaming_mapping.items() if v not in mismatched_keys} + # We need to update both the mapping and the list of checkpoint keys to remove the mismatched and unexpected ones + key_renaming_mapping = { + k: v for k, v in key_renaming_mapping.items() if v not in mismatched_keys and v not in unexpected_keys + } checkpoint_keys = list(key_renaming_mapping.values()) # Move missing (and potentially mismatched) keys back to cpu from meta device (because they won't be moved when @@ -5366,6 +5345,7 @@ def _load_pretrained_model( # in the submodule key_renaming_mapping = {k: v[len(_prefix) :] for k, v in key_renaming_mapping.items()} checkpoint_keys = list(key_renaming_mapping.values()) + unexpected_keys = [k[len(_prefix) :] if k.startswith(_prefix) else k for k in unexpected_keys] # We need to update the device map as well if device_map is not None: device_map = {k[len(_prefix) :] if k.startswith(_prefix) else k: v for k, v in device_map.items()} @@ -5373,7 +5353,7 @@ def _load_pretrained_model( task_specific_expected_keys = [s for s in model.state_dict() if not s.startswith(_prefix)] base_model_expected_keys = list(model_to_load.state_dict().keys()) if any( - key in task_specific_expected_keys and key not in base_model_expected_keys for key in checkpoint_keys + key in task_specific_expected_keys and key not in base_model_expected_keys for key in unexpected_keys ): raise ValueError( "The state dictionary of the model you are trying to load is corrupted. Are you sure it was " @@ -5555,6 +5535,23 @@ def _load_pretrained_model( device_mesh, ) + # Model-specific exceptions for missing and unexpected keys (e.g. if the modeling change over time, or any other reason...) + # We should remove them here to avoid raising warnings if they are present in the lists + if cls._keys_to_ignore_on_load_missing is not None: + for pattern in cls._keys_to_ignore_on_load_missing: + missing_keys = [k for k in missing_keys if re.search(pattern, k) is None] + + if cls._keys_to_ignore_on_load_unexpected is not None: + for pattern in cls._keys_to_ignore_on_load_unexpected: + unexpected_keys = [k for k in unexpected_keys if re.search(pattern, k) is None] + + # Old checkpoints may have keys for rotary_emb.inv_freq for each layer, however we moved this buffer to the main model + # (so the buffer name has changed). Remove them in such a case. This is another exception that was not added to + # `_keys_to_ignore_on_load_unexpected` as it touches many models + has_inv_freq_buffers = any(buffer.endswith("rotary_emb.inv_freq") for buffer, _ in model.named_buffers()) + if has_inv_freq_buffers: + unexpected_keys = [k for k in unexpected_keys if "rotary_emb.inv_freq" not in k] + # All potential warnings/infos if len(error_msgs) > 0: error_msg = "\n\t".join(error_msgs) diff --git a/tests/utils/test_modeling_utils.py b/tests/utils/test_modeling_utils.py index bf6889338b0e..fc2bbb60c452 100644 --- a/tests/utils/test_modeling_utils.py +++ b/tests/utils/test_modeling_utils.py @@ -29,7 +29,7 @@ import pytest import requests -from huggingface_hub import HfApi, HfFolder +from huggingface_hub import HfApi, HfFolder, split_torch_state_dict_into_shards from parameterized import parameterized from pytest import mark from requests.exceptions import HTTPError @@ -139,6 +139,32 @@ def __init__(self, config): def forward(self, x): return self.linear_2(self.linear(x)) + class BaseModelWithUnexpectedKeys(PreTrainedModel): + base_model_prefix = "base" + config_class = PretrainedConfig + _keys_to_ignore_on_load_unexpected = [r"^mtp.*"] + + def __init__(self, config): + super().__init__(config) + self.linear = nn.Linear(50, 50) + self.linear_2 = nn.Linear(50, 50) + + def forward(self, x): + return self.linear_2(self.linear(x)) + + class BaseModelWithMissingKeys(PreTrainedModel): + base_model_prefix = "base" + config_class = PretrainedConfig + _keys_to_ignore_on_load_missing = [r"^linear"] + + def __init__(self, config): + super().__init__(config) + self.linear = nn.Linear(50, 50) + self.linear_2 = nn.Linear(50, 50) + + def forward(self, x): + return self.linear_2(self.linear(x)) + class BaseModelWithTiedWeights(PreTrainedModel): config_class = PretrainedConfig @@ -2028,6 +2054,92 @@ class MyModelD(MyModelA): self.assertIs(MyModelC.config_class, MyConfigC) self.assertIs(MyModelD.config_class, MyConfigA) + def test_ignore_missing_key_works(self): + """Test that if a parameter (not buffer) is specified in `_keys_to_ignore_on_load_missing` and is actually + missing from the checkpoint, it will still be moved to cpu and initialized""" + temp = tempfile.TemporaryDirectory() + # Create dummy model + model = BaseModelWithMissingKeys(PretrainedConfig()) + + # Save the config + model.config.save_pretrained(temp.name) + # Get the state dict to save + state_dict = model.state_dict() + # Remove the layer that we should ignore if missing + del state_dict["linear.weight"], state_dict["linear.bias"] + # Save the state dict as a single shard + safe_save_file(state_dict, Path(temp.name) / "model.safetensors", metadata={"format": "pt"}) + + # Try loading back, with the missing key not present in the state_dict + model = BaseModelWithMissingKeys.from_pretrained(temp.name) + + # Make sure the skipped missing key is not still on meta device! + for k, v in model.state_dict().items(): + self.assertTrue(v.device.type == "cpu", f"{k} is not on cpu!") + + def test_device_map_works_with_unexpected_keys(self): + """Test that if a parameter is specified in `_keys_to_ignore_on_load_unexpected` and is actually + present in the checkpoint, it will correctly be removed from the weights we load, especially those + we use if the device map has offloading""" + temp = tempfile.TemporaryDirectory() + + # Create dummy model + model = BaseModelWithUnexpectedKeys(PretrainedConfig()) + + # Save the config + model.config.save_pretrained(temp.name) + + # Get the state dict to save + state_dict = model.state_dict() + # Add a layer that is in the "_keys_to_ignore_on_load_unexpected" list to ignore + state_dict["mtp"] = torch.randn(12, 12) + # Save the state dict as a single shard + safe_save_file(state_dict, Path(temp.name) / "model.safetensors", metadata={"format": "pt"}) + + # Load the model with entire shards placed on disk in order to trigger `get_disk_only_shard_files`. + # Unexpected keys (mtp) should be removed from the state dict, therefore this should not error out. + BaseModelWithUnexpectedKeys.from_pretrained(temp.name, device_map={"linear": "cpu", "linear_2": "disk"}) + + def test_device_map_works_with_unexpected_keys_sharded(self): + """Test that if a parameter is specified in `_keys_to_ignore_on_load_unexpected` and is actually + present in the checkpoint, it will correctly be removed from the weights we load, especially those + we use if the device map has offloading""" + temp = tempfile.TemporaryDirectory() + + # Create dummy model + model = BaseModelWithUnexpectedKeys(PretrainedConfig()) + + # Save the config + model.config.save_pretrained(temp.name) + + # Get the state dict to save + state_dict = model.state_dict() + + # Add a layer that is in the "_keys_to_ignore_on_load_unexpected" list to ignore + state_dict["mtp"] = torch.randn(50, 50) + + # Split the state dict in shards, save the index and the shards + shards = split_torch_state_dict_into_shards(state_dict, max_shard_size="1kb") + index = { + "metadata": {"total_parameters": model.num_parameters(), **shards.metadata}, + "weight_map": shards.tensor_to_filename, + } + with open(Path(temp.name) / SAFE_WEIGHTS_INDEX_NAME, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + # Save each shard + filename_to_tensors = shards.filename_to_tensors.items() + for shard_file, tensors in filename_to_tensors: + shard = {} + for tensor in tensors: + shard[tensor] = state_dict[tensor].contiguous() + safe_save_file(shard, Path(temp.name) / shard_file, metadata={"format": "pt"}) + + # Load the model with entire shards placed on disk in order to trigger `get_disk_only_shard_files`. + # Unexpected keys (mtp) should be removed from the state dict, therefore this should not error out. + BaseModelWithUnexpectedKeys.from_pretrained(temp.name, device_map={"linear": "cpu", "linear_2": "disk"}) + @slow @require_torch From 18941ba52ba38d756aac2bc87e7555212a9f513d Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Wed, 24 Sep 2025 23:58:16 -0700 Subject: [PATCH 188/204] Using torch.distributions.Categorical --- src/transformers/generation/logits_process.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 29087cb0d6f2..4ef4292ba523 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -639,9 +639,7 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to """ batch_size, vocab_size = scores.shape device = scores.device - keep_mask = torch.zeros((batch_size, vocab_size), dtype=torch.bool, device=device) - top_n = min(self.top_n, vocab_size) for b in range(batch_size): From 94336c5153421d806fd3807ae3993adf6cbabce0 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 20:39:00 -0700 Subject: [PATCH 189/204] Resolving logits_process.py Issues --- src/transformers/generation/logits_process.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 4ef4292ba523..18cb5be8e51c 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -592,8 +592,16 @@ class TopHLogitsWarper(LogitsProcessor): diversity and coherence. Args: +<<<<<<< HEAD top_h (`float`): Scaling coefficient for the entropy-based threshold. Must be in the range `(0, 1]`. +======= + top_n (`int`, *optional*, defaults to 100): + The maximum number of tokens to consider for filtering. + Only the top `top_n` tokens (by probability) are evaluated. + alpha (`float`, *optional*, defaults to 0.4): + Scaling coefficient for the entropy-based threshold (`tau`). Must be in the range `(0, 1]`. +>>>>>>> a481999de7 (Resolving logits_process.py Issues) filter_value (`float`, *optional*, defaults to -inf): All filtered values will be set to this float value. @@ -618,7 +626,11 @@ def __init__(self, top_h: float, filter_value: float = -float("Inf")): # input checks if not (0 < top_h <= 1): +<<<<<<< HEAD raise ValueError("`top_h` must be in the range (0, 1].") +======= + raise ValueError("alpha must be in the range (0, 1].") +>>>>>>> a481999de7 (Resolving logits_process.py Issues) self.top_n = 100 self.top_h = top_h self.filter_value = filter_value From 643d9c253703b7ae81a87d52f1ddf6b18fcf2932 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 11 Sep 2025 22:03:08 -0700 Subject: [PATCH 190/204] style: autoformat with make fixup --- src/transformers/generation/logits_process.py | 4 ---- src/transformers/generation/utils.py | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 18cb5be8e51c..468ed019a0a2 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -626,11 +626,7 @@ def __init__(self, top_h: float, filter_value: float = -float("Inf")): # input checks if not (0 < top_h <= 1): -<<<<<<< HEAD raise ValueError("`top_h` must be in the range (0, 1].") -======= - raise ValueError("alpha must be in the range (0, 1].") ->>>>>>> a481999de7 (Resolving logits_process.py Issues) self.top_n = 100 self.top_h = top_h self.filter_value = filter_value diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index 1e88270c02e3..3051e833e633 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -1266,7 +1266,12 @@ def _get_logits_processor( processors.append( MinPLogitsWarper(min_p=generation_config.min_p, min_tokens_to_keep=min_tokens_to_keep) ) +<<<<<<< HEAD +======= + if generation_config.top_h is not None: + processors.append(TopHLogitsWarper(top_h=generation_config.top_h)) +>>>>>>> 6bc1458be0 (style: autoformat with make fixup) if generation_config.typical_p is not None and generation_config.typical_p < 1.0: processors.append( TypicalLogitsWarper(mass=generation_config.typical_p, min_tokens_to_keep=min_tokens_to_keep) From 2cc41c6aa1a24a450a638e5f2e2b1dad20f835b0 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Mon, 15 Sep 2025 19:27:38 -0700 Subject: [PATCH 191/204] Update logits_process.py removed defaults --- src/transformers/generation/logits_process.py | 4 ++++ src/transformers/generation/utils.py | 6 ------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 468ed019a0a2..f976b5368125 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -592,6 +592,7 @@ class TopHLogitsWarper(LogitsProcessor): diversity and coherence. Args: +<<<<<<< HEAD <<<<<<< HEAD top_h (`float`): Scaling coefficient for the entropy-based threshold. Must be in the range `(0, 1]`. @@ -600,6 +601,9 @@ class TopHLogitsWarper(LogitsProcessor): The maximum number of tokens to consider for filtering. Only the top `top_n` tokens (by probability) are evaluated. alpha (`float`, *optional*, defaults to 0.4): +======= + top_h (`float`): +>>>>>>> 71dc17af16 (Update logits_process.py removed defaults) Scaling coefficient for the entropy-based threshold (`tau`). Must be in the range `(0, 1]`. >>>>>>> a481999de7 (Resolving logits_process.py Issues) filter_value (`float`, *optional*, defaults to -inf): diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index 3051e833e633..5cd78f10d33b 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -1266,12 +1266,6 @@ def _get_logits_processor( processors.append( MinPLogitsWarper(min_p=generation_config.min_p, min_tokens_to_keep=min_tokens_to_keep) ) -<<<<<<< HEAD - -======= - if generation_config.top_h is not None: - processors.append(TopHLogitsWarper(top_h=generation_config.top_h)) ->>>>>>> 6bc1458be0 (style: autoformat with make fixup) if generation_config.typical_p is not None and generation_config.typical_p < 1.0: processors.append( TypicalLogitsWarper(mass=generation_config.typical_p, min_tokens_to_keep=min_tokens_to_keep) From 5255a724154dcc6dfdcc7e5ae947785a0e8bfe63 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Sun, 21 Sep 2025 18:45:44 -0700 Subject: [PATCH 192/204] Variable H name -> cumulative_entropy --- src/transformers/generation/logits_process.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index f976b5368125..4f94520abf14 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -592,20 +592,9 @@ class TopHLogitsWarper(LogitsProcessor): diversity and coherence. Args: -<<<<<<< HEAD -<<<<<<< HEAD top_h (`float`): - Scaling coefficient for the entropy-based threshold. Must be in the range `(0, 1]`. -======= - top_n (`int`, *optional*, defaults to 100): - The maximum number of tokens to consider for filtering. - Only the top `top_n` tokens (by probability) are evaluated. - alpha (`float`, *optional*, defaults to 0.4): -======= - top_h (`float`): ->>>>>>> 71dc17af16 (Update logits_process.py removed defaults) Scaling coefficient for the entropy-based threshold (`tau`). Must be in the range `(0, 1]`. ->>>>>>> a481999de7 (Resolving logits_process.py Issues) + filter_value (`float`, *optional*, defaults to -inf): All filtered values will be set to this float value. From 70214c1ef8be4910974acae214cdfe50236cf0f7 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 25 Sep 2025 01:08:28 -0700 Subject: [PATCH 193/204] Resolving format error --- src/transformers/generation/logits_process.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 4f94520abf14..de2bc432a32d 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -652,7 +652,11 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to tau = distribution.entropy() * self.top_h # grow the kept set until the stopping rule triggers - cumulative_entropy = - distribution.probs[torch.tensor([0], device=top_probs.device)] * distribution.log_prob(torch.tensor([0], device=top_probs.device)) # -top_probs[0] * torch.log2(top_probs[0]) + cumulative_entropy = -distribution.probs[ + torch.tensor([0], device=top_probs.device) + ] * distribution.log_prob( + torch.tensor([0], device=top_probs.device) + ) # -top_probs[0] * torch.log2(top_probs[0]) chosen = [] ind = 0 for idx, p in zip(top_idx, top_probs): @@ -661,7 +665,9 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to if ind == len(top_probs): break # update running sums for current prefix - cumulative_entropy = cumulative_entropy - distribution.probs[torch.tensor([ind], device=top_probs.device)] * distribution.log_prob(torch.tensor([ind], device=top_probs.device)) + cumulative_entropy = cumulative_entropy - distribution.probs[ + torch.tensor([ind], device=top_probs.device) + ] * distribution.log_prob(torch.tensor([ind], device=top_probs.device)) # entropy difference term if cumulative_entropy > tau: From 9dad329d16219539cf66a5fe2f9cb58efab0c291 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 25 Sep 2025 01:47:04 -0700 Subject: [PATCH 194/204] Correction of the loop variables in logit processor --- src/transformers/generation/logits_process.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index de2bc432a32d..acce2030d158 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -658,16 +658,16 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to torch.tensor([0], device=top_probs.device) ) # -top_probs[0] * torch.log2(top_probs[0]) chosen = [] - ind = 0 - for idx, p in zip(top_idx, top_probs): - chosen.append(idx) - ind += 1 - if ind == len(top_probs): + index = 0 + for token_id in top_idx: + chosen.append(token_id) + index += 1 + if index == len(top_probs): break # update running sums for current prefix cumulative_entropy = cumulative_entropy - distribution.probs[ - torch.tensor([ind], device=top_probs.device) - ] * distribution.log_prob(torch.tensor([ind], device=top_probs.device)) + torch.tensor([index], device=top_probs.device) + ] * distribution.log_prob(torch.tensor([index], device=top_probs.device)) # entropy difference term if cumulative_entropy > tau: From bf23aefd3f6b67a220fc821b9f980920f6ef72ab Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Thu, 25 Sep 2025 20:42:59 -0700 Subject: [PATCH 195/204] Vectorized the loop in logits_process --- src/transformers/generation/logits_process.py | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index acce2030d158..af2b592b9d2c 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -643,36 +643,33 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to keep_mask = torch.zeros((batch_size, vocab_size), dtype=torch.bool, device=device) top_n = min(self.top_n, vocab_size) - for b in range(batch_size): - # top-k for this example - top_probs, top_idx = torch.topk(scores[b], top_n, largest=True, sorted=True) - distribution = torch.distributions.Categorical(logits=top_probs) - - # entropy-based threshold tau (computed on the top-k distribution) - tau = distribution.entropy() * self.top_h - - # grow the kept set until the stopping rule triggers - cumulative_entropy = -distribution.probs[ - torch.tensor([0], device=top_probs.device) - ] * distribution.log_prob( - torch.tensor([0], device=top_probs.device) - ) # -top_probs[0] * torch.log2(top_probs[0]) - chosen = [] - index = 0 - for token_id in top_idx: - chosen.append(token_id) - index += 1 - if index == len(top_probs): - break - # update running sums for current prefix - cumulative_entropy = cumulative_entropy - distribution.probs[ - torch.tensor([index], device=top_probs.device) - ] * distribution.log_prob(torch.tensor([index], device=top_probs.device)) - - # entropy difference term - if cumulative_entropy > tau: - break - keep_mask[b, torch.stack(chosen)] = True + # 1. Get top-k logits and indices for the whole batch + top_logits, top_idx = torch.topk(scores, top_n, dim=-1, largest=True, sorted=True) + + # 2. Create a batch of categorical distributions + dist = torch.distributions.Categorical(logits=top_logits) + probs = dist.probs + log_probs = torch.log(probs) #dist.log_prob(idx) + + # 3. Calculate the entropy-based threshold tau for the whole batch + # We unsqueeze tau to enable broadcasting against the cumulative entropy tensor. + tau = (dist.entropy() * self.top_h).unsqueeze(-1) + + # 4. Calculate cumulative entropy using torch.cumsum + # The individual entropy terms (-p * log(p)) are calculated for all top_n tokens at once. + entropy_terms = -probs * log_probs + cumulative_entropy = torch.cumsum(entropy_terms, dim=-1) + + # # 5. Determine which tokens to keep based on the stopping condition + # Create a boolean mask for the top_n tokens. + selection_mask = cumulative_entropy <= tau + # Ensure the most probable token (at index 0) is always kept. + selection_mask[:, 0] = True + + # 6. Update the final keep_mask for the entire batch in one operation + # The scatter_ operation efficiently updates the keep_mask at the indices + # specified by top_idx with the boolean values from selection_mask. + keep_mask.scatter_(dim=1, index=top_idx, src=selection_mask) # apply filtering scores_processed = scores.clone() From 5829189bd33dca70ea0b55b641674091cc9d723d Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Sat, 27 Sep 2025 02:18:05 -0700 Subject: [PATCH 196/204] formatted logits_process --- src/transformers/generation/logits_process.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index af2b592b9d2c..620eadb5b2eb 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -649,7 +649,7 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to # 2. Create a batch of categorical distributions dist = torch.distributions.Categorical(logits=top_logits) probs = dist.probs - log_probs = torch.log(probs) #dist.log_prob(idx) + log_probs = torch.log(probs) # dist.log_prob(idx) # 3. Calculate the entropy-based threshold tau for the whole batch # We unsqueeze tau to enable broadcasting against the cumulative entropy tensor. From cd9f22e44f6a9db4eeb696ee6332756792107942 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Sat, 27 Sep 2025 02:37:36 -0700 Subject: [PATCH 197/204] paper reference and stopping rule comment logits_process --- src/transformers/generation/logits_process.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index 620eadb5b2eb..e4e262fd789e 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -591,6 +591,10 @@ class TopHLogitsWarper(LogitsProcessor): distribution, thereby balancing exploration and exploitation. It ensures that generated text maintains both diversity and coherence. + Reference: + For details, see *Top-H Decoding: Adapting the Creativity and Coherence with Bounded Entropy in Text Generation* + (NeurIPS 2025): https://arxiv.org/abs/2509.02510 + Args: top_h (`float`): Scaling coefficient for the entropy-based threshold (`tau`). Must be in the range `(0, 1]`. @@ -620,7 +624,12 @@ def __init__(self, top_h: float, filter_value: float = -float("Inf")): # input checks if not (0 < top_h <= 1): raise ValueError("`top_h` must be in the range (0, 1].") + + # Maximum number of top tokens to consider before applying the entropy-based filter. + # Acts as a cap for efficiency and numerical stability — increasing this allows more + # tokens to be evaluated but may slow down generation. Default is 100. self.top_n = 100 + self.top_h = top_h self.filter_value = filter_value @@ -662,8 +671,10 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to # # 5. Determine which tokens to keep based on the stopping condition # Create a boolean mask for the top_n tokens. + # Stopping rule: keep adding tokens in order of probability until the cumulative entropy + # exceeds the threshold τ = H(p) * top_h. This ensures diversity (via entropy) while + # guaranteeing at least the most probable token is always included. selection_mask = cumulative_entropy <= tau - # Ensure the most probable token (at index 0) is always kept. selection_mask[:, 0] = True # 6. Update the final keep_mask for the entire batch in one operation From 116c55d1d5e67c1b37566bd44a8615869b8b6732 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Sat, 27 Sep 2025 02:57:52 -0700 Subject: [PATCH 198/204] Trigger CI rerun From 6b3eea3f3650a8cf8b16d7cf97b8e6a7d9b64538 Mon Sep 17 00:00:00 2001 From: ArminAzizi98 <147081650+ArminAzizi98@users.noreply.github.com> Date: Sat, 27 Sep 2025 14:05:39 -0700 Subject: [PATCH 199/204] Update logits_process.py --- src/transformers/generation/logits_process.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/generation/logits_process.py b/src/transformers/generation/logits_process.py index e4e262fd789e..c40205bf287c 100644 --- a/src/transformers/generation/logits_process.py +++ b/src/transformers/generation/logits_process.py @@ -669,7 +669,7 @@ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> to entropy_terms = -probs * log_probs cumulative_entropy = torch.cumsum(entropy_terms, dim=-1) - # # 5. Determine which tokens to keep based on the stopping condition + # 5. Determine which tokens to keep based on the stopping condition # Create a boolean mask for the top_n tokens. # Stopping rule: keep adding tokens in order of probability until the cumulative entropy # exceeds the threshold τ = H(p) * top_h. This ensures diversity (via entropy) while From 0ebb99d801cfc0b8f76d937de253879c8d2ba703 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Sat, 27 Sep 2025 22:44:30 -0700 Subject: [PATCH 200/204] added test_TopH_example_integration --- tests/generation/test_utils.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index ed58403a53d0..45853c5ae8ed 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -3066,6 +3066,24 @@ def test_synthid_text_watermark_generation_mean_expected_bias(self): ) self.assertTrue(torch.all(is_close)) + @slow + def test_TopH_example_integration(self): + + tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-3B") + model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-3B") + tokenizer.pad_token = tokenizer.eos_token + model.config.pad_token_id = tokenizer.pad_token_id + encoder_input_str = "Tell me a joke about a monkey." + input_ids = tokenizer(encoder_input_str, return_tensors="pt") + + torch.manual_seed(0) + + outputs = model.generate( + **input_ids, eos_token_id=model.config.eos_token_id, do_sample=True, temperature=1.0, top_h=0.4, max_new_tokens=32, pad_token_id=tokenizer.pad_token_id) + outputs = tokenizer.batch_decode(outputs, skip_special_tokens=True) + self.assertListEqual(outputs, ['Tell me a joke about a monkey. Why did the monkey go to the doctor? Because he was feeling a little "tropic"!']) + + @slow def test_beam_search_example_integration(self): # exactly the example provided in the docstrings of beam search, which previously From f4ea5e4c0dbb5433172c25d571944782a19fb73c Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Sat, 27 Sep 2025 22:58:37 -0700 Subject: [PATCH 201/204] added test_TopH_example_integration --- .circleci/create_circleci_config.py | 173 ++++++++++++++++++++-------- .circleci/parse_test_outputs.py | 25 ++-- .github/scripts/assign_reviewers.py | 14 ++- tests/generation/test_utils.py | 20 +++- 4 files changed, 160 insertions(+), 72 deletions(-) diff --git a/.circleci/create_circleci_config.py b/.circleci/create_circleci_config.py index c2469b53ccf5..be2c8495c408 100644 --- a/.circleci/create_circleci_config.py +++ b/.circleci/create_circleci_config.py @@ -31,7 +31,7 @@ "RUN_FLAKY": True, } # Disable the use of {"s": None} as the output is way too long, causing the navigation on CircleCI impractical -COMMON_PYTEST_OPTIONS = {"max-worker-restart": 0, "vvv": None, "rsfE":None} +COMMON_PYTEST_OPTIONS = {"max-worker-restart": 0, "vvv": None, "rsfE": None} DEFAULT_DOCKER_IMAGE = [{"image": "cimg/python:3.8.12"}] # Strings that commonly appear in the output of flaky tests when they fail. These are used with `pytest-rerunfailures` @@ -58,14 +58,18 @@ class EmptyJob: job_name = "empty" def to_dict(self): - steps = [{"run": 'ls -la'}] + steps = [{"run": "ls -la"}] if self.job_name == "collection_job": steps.extend( [ "checkout", {"run": "pip install requests || true"}, - {"run": """while [[ $(curl --location --request GET "https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/job" --header "Circle-Token: $CCI_TOKEN"| jq -r '.items[]|select(.name != "collection_job")|.status' | grep -c "running") -gt 0 ]]; do sleep 5; done || true"""}, - {"run": 'python utils/process_circleci_workflow_test_reports.py --workflow_id $CIRCLE_WORKFLOW_ID || true'}, + { + "run": """while [[ $(curl --location --request GET "https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/job" --header "Circle-Token: $CCI_TOKEN"| jq -r '.items[]|select(.name != "collection_job")|.status' | grep -c "running") -gt 0 ]]; do sleep 5; done || true""" + }, + { + "run": "python utils/process_circleci_workflow_test_reports.py --workflow_id $CIRCLE_WORKFLOW_ID || true" + }, {"store_artifacts": {"path": "outputs"}}, {"run": 'echo "All required jobs have now completed"'}, ] @@ -104,7 +108,10 @@ def __post_init__(self): else: # BIG HACK WILL REMOVE ONCE FETCHER IS UPDATED print(os.environ.get("GIT_COMMIT_MESSAGE")) - if "[build-ci-image]" in os.environ.get("GIT_COMMIT_MESSAGE", "") or os.environ.get("GIT_COMMIT_MESSAGE", "") == "dev-ci": + if ( + "[build-ci-image]" in os.environ.get("GIT_COMMIT_MESSAGE", "") + or os.environ.get("GIT_COMMIT_MESSAGE", "") == "dev-ci" + ): self.docker_image[0]["image"] = f"{self.docker_image[0]['image']}:dev" print(f"Using {self.docker_image} docker image") if self.install_steps is None: @@ -116,7 +123,7 @@ def __post_init__(self): if isinstance(self.tests_to_run, str): self.tests_to_run = [self.tests_to_run] else: - test_file = os.path.join("test_preparation" , f"{self.job_name}_test_list.txt") + test_file = os.path.join("test_preparation", f"{self.job_name}_test_list.txt") print("Looking for ", test_file) if os.path.exists(test_file): with open(test_file) as f: @@ -136,7 +143,7 @@ def to_dict(self): # fmt: on # Do not run tests decorated by @is_flaky on pull requests - env['RUN_FLAKY'] = os.environ.get("CIRCLE_PULL_REQUEST", "") == "" + env["RUN_FLAKY"] = os.environ.get("CIRCLE_PULL_REQUEST", "") == "" env.update(self.additional_env) job = { @@ -147,50 +154,84 @@ def to_dict(self): job["resource_class"] = self.resource_class all_options = {**COMMON_PYTEST_OPTIONS, **self.pytest_options} - pytest_flags = [f"--{key}={value}" if (value is not None or key in ["doctest-modules"]) else f"-{key}" for key, value in all_options.items()] + pytest_flags = [ + f"--{key}={value}" if (value is not None or key in ["doctest-modules"]) else f"-{key}" + for key, value in all_options.items() + ] pytest_flags.append( f"--make-reports={self.name}" if "examples" in self.name else f"--make-reports=tests_{self.name}" ) - # Examples special case: we need to download NLTK files in advance to avoid cuncurrency issues + # Examples special case: we need to download NLTK files in advance to avoid cuncurrency issues timeout_cmd = f"timeout {self.command_timeout} " if self.command_timeout else "" marker_cmd = f"-m '{self.marker}'" if self.marker is not None else "" junit_flags = " -p no:warning -o junit_family=xunit1 --junitxml=test-results/junit.xml" joined_flaky_patterns = "|".join(FLAKY_TEST_FAILURE_PATTERNS) repeat_on_failure_flags = f"--reruns 5 --reruns-delay 2 --only-rerun '({joined_flaky_patterns})'" - parallel = f' << pipeline.parameters.{self.job_name}_parallelism >> ' + parallel = f" << pipeline.parameters.{self.job_name}_parallelism >> " steps = [ "checkout", {"attach_workspace": {"at": "test_preparation"}}, {"run": "apt-get update && apt-get install -y curl"}, {"run": " && ".join(self.install_steps)}, - {"run": {"name": "Download NLTK files", "command": """python -c "import nltk; nltk.download('punkt', quiet=True)" """} if "example" in self.name else "echo Skipping"}, - {"run": { + { + "run": { + "name": "Download NLTK files", + "command": """python -c "import nltk; nltk.download('punkt', quiet=True)" """, + } + if "example" in self.name + else "echo Skipping" + }, + { + "run": { "name": "Show installed libraries and their size", - "command": """du -h -d 1 "$(pip -V | cut -d ' ' -f 4 | sed 's/pip//g')" | grep -vE "dist-info|_distutils_hack|__pycache__" | sort -h | tee installed.txt || true"""} + "command": """du -h -d 1 "$(pip -V | cut -d ' ' -f 4 | sed 's/pip//g')" | grep -vE "dist-info|_distutils_hack|__pycache__" | sort -h | tee installed.txt || true""", + } }, - {"run": { - "name": "Show installed libraries and their versions", - "command": """pip list --format=freeze | tee installed.txt || true"""} + { + "run": { + "name": "Show installed libraries and their versions", + "command": """pip list --format=freeze | tee installed.txt || true""", + } }, - {"run": { - "name": "Show biggest libraries", - "command": """dpkg-query --show --showformat='${Installed-Size}\t${Package}\n' | sort -rh | head -25 | sort -h | awk '{ package=$2; sub(".*/", "", package); printf("%.5f GB %s\n", $1/1024/1024, package)}' || true"""} + { + "run": { + "name": "Show biggest libraries", + "command": """dpkg-query --show --showformat='${Installed-Size}\t${Package}\n' | sort -rh | head -25 | sort -h | awk '{ package=$2; sub(".*/", "", package); printf("%.5f GB %s\n", $1/1024/1024, package)}' || true""", + } }, {"run": {"name": "Create `test-results` directory", "command": "mkdir test-results"}}, - {"run": {"name": "Get files to test", "command":f'curl -L -o {self.job_name}_test_list.txt <> --header "Circle-Token: $CIRCLE_TOKEN"' if self.name != "pr_documentation_tests" else 'echo "Skipped"'}}, - {"run": {"name": "Split tests across parallel nodes: show current parallel tests", - "command": f"TESTS=$(circleci tests split --split-by=timings {self.job_name}_test_list.txt) && echo $TESTS > splitted_tests.txt && echo $TESTS | tr ' ' '\n'" if self.parallelism else f"awk '{{printf \"%s \", $0}}' {self.job_name}_test_list.txt > splitted_tests.txt" - } + { + "run": { + "name": "Get files to test", + "command": f'curl -L -o {self.job_name}_test_list.txt <> --header "Circle-Token: $CIRCLE_TOKEN"' + if self.name != "pr_documentation_tests" + else 'echo "Skipped"', + } + }, + { + "run": { + "name": "Split tests across parallel nodes: show current parallel tests", + "command": f"TESTS=$(circleci tests split --split-by=timings {self.job_name}_test_list.txt) && echo $TESTS > splitted_tests.txt && echo $TESTS | tr ' ' '\n'" + if self.parallelism + else f"awk '{{printf \"%s \", $0}}' {self.job_name}_test_list.txt > splitted_tests.txt", + } }, # During the CircleCI docker images build time, we might already (or not) download the data. # If it's done already, the files are inside the directory `/test_data/`. - {"run": {"name": "fetch hub objects before pytest", "command": "cp -r /test_data/* . 2>/dev/null || true; python3 utils/fetch_hub_objects_for_ci.py"}}, - {"run": { - "name": "Run tests", - "command": f"({timeout_cmd} python3 -m pytest {marker_cmd} -n {self.pytest_num_workers} {junit_flags} {repeat_on_failure_flags} {' '.join(pytest_flags)} $(cat splitted_tests.txt) | tee tests_output.txt)"} + { + "run": { + "name": "fetch hub objects before pytest", + "command": "cp -r /test_data/* . 2>/dev/null || true; python3 utils/fetch_hub_objects_for_ci.py", + } }, - {"run": - { + { + "run": { + "name": "Run tests", + "command": f"({timeout_cmd} python3 -m pytest {marker_cmd} -n {self.pytest_num_workers} {junit_flags} {repeat_on_failure_flags} {' '.join(pytest_flags)} $(cat splitted_tests.txt) | tee tests_output.txt)", + } + }, + { + "run": { "name": "Check for test crashes", "when": "always", "command": """if [ ! -f tests_output.txt ]; then @@ -202,12 +243,30 @@ def to_dict(self): exit 1 else echo "Tests output file exists and no worker crashes detected" - fi""" + fi""", }, }, - {"run": {"name": "Expand to show skipped tests", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --skip"}}, - {"run": {"name": "Failed tests: show reasons", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --fail"}}, - {"run": {"name": "Errors", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --errors"}}, + { + "run": { + "name": "Expand to show skipped tests", + "when": "always", + "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --skip", + } + }, + { + "run": { + "name": "Failed tests: show reasons", + "when": "always", + "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --fail", + } + }, + { + "run": { + "name": "Errors", + "when": "always", + "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --errors", + } + }, {"store_test_results": {"path": "test-results"}}, {"store_artifacts": {"path": "test-results/junit.xml"}}, {"store_artifacts": {"path": "reports"}}, @@ -222,7 +281,11 @@ def to_dict(self): @property def job_name(self): - return self.name if ("examples" in self.name or "pipeline" in self.name or "pr_documentation" in self.name) else f"tests_{self.name}" + return ( + self.name + if ("examples" in self.name or "pipeline" in self.name or "pr_documentation" in self.name) + else f"tests_{self.name}" + ) # JOBS @@ -258,7 +321,7 @@ def job_name(self): pipelines_torch_job = CircleCIJob( "pipelines_torch", additional_env={"RUN_PIPELINE_TESTS": True}, - docker_image=[{"image":"huggingface/transformers-torch-light"}], + docker_image=[{"image": "huggingface/transformers-torch-light"}], marker="is_pipeline_test", parallelism=4, ) @@ -272,7 +335,7 @@ def job_name(self): examples_torch_job = CircleCIJob( "examples_torch", additional_env={"OMP_NUM_THREADS": 8}, - docker_image=[{"image":"huggingface/transformers-examples-torch"}], + docker_image=[{"image": "huggingface/transformers-examples-torch"}], # TODO @ArthurZucker remove this once docker is easier to build install_steps=["uv pip install . && uv pip install -r examples/pytorch/_tests_requirements.txt"], pytest_num_workers=4, @@ -281,9 +344,9 @@ def job_name(self): hub_job = CircleCIJob( "hub", additional_env={"HUGGINGFACE_CO_STAGING": True}, - docker_image=[{"image":"huggingface/transformers-torch-light"}], + docker_image=[{"image": "huggingface/transformers-torch-light"}], install_steps=[ - 'uv pip install .', + "uv pip install .", 'git config --global user.email "ci@dummy.com"', 'git config --global user.name "ci"', ], @@ -294,14 +357,14 @@ def job_name(self): exotic_models_job = CircleCIJob( "exotic_models", - docker_image=[{"image":"huggingface/transformers-exotic-models"}], + docker_image=[{"image": "huggingface/transformers-exotic-models"}], parallelism=4, pytest_options={"durations": 100}, ) repo_utils_job = CircleCIJob( "repo_utils", - docker_image=[{"image":"huggingface/transformers-consistency"}], + docker_image=[{"image": "huggingface/transformers-consistency"}], pytest_num_workers=4, resource_class="large", ) @@ -325,7 +388,7 @@ def job_name(self): command = f'echo """{py_command}""" > pr_documentation_tests_temp.txt' doc_test_job = CircleCIJob( "pr_documentation_tests", - docker_image=[{"image":"huggingface/transformers-consistency"}], + docker_image=[{"image": "huggingface/transformers-consistency"}], additional_env={"TRANSFORMERS_VERBOSITY": "error", "DATASETS_VERBOSITY": "error", "SKIP_CUDA_DOCTEST": "1"}, install_steps=[ # Add an empty file to keep the test step running correctly even no file is selected to be tested. @@ -333,7 +396,7 @@ def job_name(self): "touch dummy.py", command, "cat pr_documentation_tests_temp.txt", - "tail -n1 pr_documentation_tests_temp.txt | tee pr_documentation_tests_test_list.txt" + "tail -n1 pr_documentation_tests_temp.txt | tee pr_documentation_tests_test_list.txt", ], tests_to_run="$(cat pr_documentation_tests.txt)", # noqa pytest_options={"-doctest-modules": None, "doctest-glob": "*.md", "dist": "loadfile", "rvsA": None}, @@ -341,7 +404,7 @@ def job_name(self): pytest_num_workers=1, ) -REGULAR_TESTS = [torch_job, hub_job, tokenization_job, processor_job, generate_job, non_model_job] # fmt: skip +REGULAR_TESTS = [torch_job, hub_job, tokenization_job, processor_job, generate_job, non_model_job] # fmt: skip EXAMPLES_TESTS = [examples_torch_job] PIPELINE_TESTS = [pipelines_torch_job] REPO_UTIL_TESTS = [repo_utils_job] @@ -353,13 +416,16 @@ def create_circleci_config(folder=None): if folder is None: folder = os.getcwd() os.environ["test_preparation_dir"] = folder - jobs = [k for k in ALL_TESTS if os.path.isfile(os.path.join("test_preparation" , f"{k.job_name}_test_list.txt") )] + jobs = [k for k in ALL_TESTS if os.path.isfile(os.path.join("test_preparation", f"{k.job_name}_test_list.txt"))] print("The following jobs will be run ", jobs) if len(jobs) == 0: jobs = [EmptyJob()] else: - print("Full list of job name inputs", {j.job_name + "_test_list":{"type":"string", "default":''} for j in jobs}) + print( + "Full list of job name inputs", + {j.job_name + "_test_list": {"type": "string", "default": ""} for j in jobs}, + ) # Add a job waiting all the test jobs and aggregate their test summary files at the end collection_job = EmptyJob() collection_job.job_name = "collection_job" @@ -376,19 +442,26 @@ def create_circleci_config(folder=None): "GHA_Event": {"type": "string", "default": ""}, "GHA_Meta": {"type": "string", "default": ""}, "tests_to_run": {"type": "string", "default": ""}, - **{j.job_name + "_test_list":{"type":"string", "default":''} for j in jobs}, - **{j.job_name + "_parallelism":{"type":"integer", "default":1} for j in jobs}, + **{j.job_name + "_test_list": {"type": "string", "default": ""} for j in jobs}, + **{j.job_name + "_parallelism": {"type": "integer", "default": 1} for j in jobs}, }, - "jobs": {j.job_name: j.to_dict() for j in jobs} + "jobs": {j.job_name: j.to_dict() for j in jobs}, } if "CIRCLE_TOKEN" in os.environ: # For private forked repo. (e.g. new model addition) - config["workflows"] = {"version": 2, "run_tests": {"jobs": [{j.job_name: {"context": ["TRANSFORMERS_CONTEXT"]}} for j in jobs]}} + config["workflows"] = { + "version": 2, + "run_tests": {"jobs": [{j.job_name: {"context": ["TRANSFORMERS_CONTEXT"]}} for j in jobs]}, + } else: # For public repo. (e.g. `transformers`) config["workflows"] = {"version": 2, "run_tests": {"jobs": [j.job_name for j in jobs]}} with open(os.path.join(folder, "generated_config.yml"), "w") as f: - f.write(yaml.dump(config, sort_keys=False, default_flow_style=False).replace("' << pipeline", " << pipeline").replace(">> '", " >>")) + f.write( + yaml.dump(config, sort_keys=False, default_flow_style=False) + .replace("' << pipeline", " << pipeline") + .replace(">> '", " >>") + ) if __name__ == "__main__": diff --git a/.circleci/parse_test_outputs.py b/.circleci/parse_test_outputs.py index c58447155859..21f186c76b5e 100644 --- a/.circleci/parse_test_outputs.py +++ b/.circleci/parse_test_outputs.py @@ -5,50 +5,53 @@ def parse_pytest_output(file_path): skipped_tests = {} skipped_count = 0 - with open(file_path, 'r') as file: + with open(file_path, "r") as file: for line in file: - match = re.match(r'^SKIPPED \[(\d+)\] (tests/.*): (.*)$', line) + match = re.match(r"^SKIPPED \[(\d+)\] (tests/.*): (.*)$", line) if match: skipped_count += 1 test_file, test_line, reason = match.groups() skipped_tests[reason] = skipped_tests.get(reason, []) + [(test_file, test_line)] - for k,v in sorted(skipped_tests.items(), key=lambda x:len(x[1])): + for k, v in sorted(skipped_tests.items(), key=lambda x: len(x[1])): print(f"{len(v):4} skipped because: {k}") print("Number of skipped tests:", skipped_count) + def parse_pytest_failure_output(file_path): failed_tests = {} failed_count = 0 - with open(file_path, 'r') as file: + with open(file_path, "r") as file: for line in file: - match = re.match(r'^FAILED (tests/.*) - (.*): (.*)$', line) + match = re.match(r"^FAILED (tests/.*) - (.*): (.*)$", line) if match: failed_count += 1 _, error, reason = match.groups() failed_tests[reason] = failed_tests.get(reason, []) + [error] - for k,v in sorted(failed_tests.items(), key=lambda x:len(x[1])): + for k, v in sorted(failed_tests.items(), key=lambda x: len(x[1])): print(f"{len(v):4} failed because `{v[0]}` -> {k}") print("Number of failed tests:", failed_count) - if failed_count>0: + if failed_count > 0: exit(1) + def parse_pytest_errors_output(file_path): print(file_path) error_tests = {} error_count = 0 - with open(file_path, 'r') as file: + with open(file_path, "r") as file: for line in file: - match = re.match(r'^ERROR (tests/.*) - (.*): (.*)$', line) + match = re.match(r"^ERROR (tests/.*) - (.*): (.*)$", line) if match: error_count += 1 _, test_error, reason = match.groups() error_tests[reason] = error_tests.get(reason, []) + [test_error] - for k,v in sorted(error_tests.items(), key=lambda x:len(x[1])): + for k, v in sorted(error_tests.items(), key=lambda x: len(x[1])): print(f"{len(v):4} errored out because of `{v[0]}` -> {k}") print("Number of errors:", error_count) - if error_count>0: + if error_count > 0: exit(1) + def main(): parser = argparse.ArgumentParser() parser.add_argument("--file", help="file to parse") diff --git a/.github/scripts/assign_reviewers.py b/.github/scripts/assign_reviewers.py index 18567203596f..04319c555087 100644 --- a/.github/scripts/assign_reviewers.py +++ b/.github/scripts/assign_reviewers.py @@ -36,11 +36,12 @@ def pattern_to_regex(pattern): pattern = r"^\/?" + pattern # Allow an optional leading slash after the start of the string return pattern + def get_file_owners(file_path, codeowners_lines): # Process lines in reverse (last matching pattern takes precedence) for line in reversed(codeowners_lines): # Skip comments and empty lines, strip inline comments - line = line.split('#')[0].strip() + line = line.split("#")[0].strip() if not line: continue @@ -56,10 +57,11 @@ def get_file_owners(file_path, codeowners_lines): return owners # Remember, can still be empty! return [] # Should never happen, but just in case + def pr_author_is_in_hf(pr_author, codeowners_lines): # Check if the PR author is in the codeowners file for line in codeowners_lines: - line = line.split('#')[0].strip() + line = line.split("#")[0].strip() if not line: continue @@ -71,18 +73,19 @@ def pr_author_is_in_hf(pr_author, codeowners_lines): return True return False + def main(): script_dir = Path(__file__).parent.absolute() with open(script_dir / "codeowners_for_review_action") as f: codeowners_lines = f.readlines() - g = Github(os.environ['GITHUB_TOKEN']) + g = Github(os.environ["GITHUB_TOKEN"]) repo = g.get_repo("huggingface/transformers") - with open(os.environ['GITHUB_EVENT_PATH']) as f: + with open(os.environ["GITHUB_EVENT_PATH"]) as f: event = json.load(f) # The PR number is available in the event payload - pr_number = event['pull_request']['number'] + pr_number = event["pull_request"]["number"] pr = repo.get_pull(pr_number) pr_author = pr.user.login if pr_author_is_in_hf(pr_author, codeowners_lines): @@ -117,6 +120,5 @@ def main(): print(f"Failed to request review for {top_owners}: {e}") - if __name__ == "__main__": main() diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index 45853c5ae8ed..cb9cd28ff0af 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -3067,8 +3067,7 @@ def test_synthid_text_watermark_generation_mean_expected_bias(self): self.assertTrue(torch.all(is_close)) @slow - def test_TopH_example_integration(self): - + def test_TopH_example_integration(self): tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-3B") model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-3B") tokenizer.pad_token = tokenizer.eos_token @@ -3079,10 +3078,21 @@ def test_TopH_example_integration(self): torch.manual_seed(0) outputs = model.generate( - **input_ids, eos_token_id=model.config.eos_token_id, do_sample=True, temperature=1.0, top_h=0.4, max_new_tokens=32, pad_token_id=tokenizer.pad_token_id) + **input_ids, + eos_token_id=model.config.eos_token_id, + do_sample=True, + temperature=1.0, + top_h=0.4, + max_new_tokens=32, + pad_token_id=tokenizer.pad_token_id, + ) outputs = tokenizer.batch_decode(outputs, skip_special_tokens=True) - self.assertListEqual(outputs, ['Tell me a joke about a monkey. Why did the monkey go to the doctor? Because he was feeling a little "tropic"!']) - + self.assertListEqual( + outputs, + [ + 'Tell me a joke about a monkey. Why did the monkey go to the doctor? Because he was feeling a little "tropic"!' + ], + ) @slow def test_beam_search_example_integration(self): From 5e7a92d01dc5008fb6cc10404983171ea28ebb40 Mon Sep 17 00:00:00 2001 From: souvikku <107592858+souvikku@users.noreply.github.com> Date: Mon, 29 Sep 2025 21:48:18 -0700 Subject: [PATCH 202/204] Update README.md From 0c83d0efe43a7bc8246354188ea7ef3577ec0377 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Tue, 7 Oct 2025 19:57:10 -0700 Subject: [PATCH 203/204] Restore CI config to match main (remove accidental changes) --- .circleci/create_circleci_config.py | 196 ++++++------------ .circleci/parse_test_outputs.py | 28 ++- .github/ISSUE_TEMPLATE/bug-report.yml | 28 ++- .github/scripts/assign_reviewers.py | 22 +- .github/workflows/build_documentation.yml | 2 +- .github/workflows/model_jobs.yml | 46 ++-- .../workflows/pr_build_doc_with_comment.yml | 2 +- .github/workflows/self-comment-ci.yml | 2 +- .../self-scheduled-amd-mi355-caller.yml | 8 +- .github/workflows/self-scheduled-caller.yml | 1 - .github/workflows/self-scheduled.yml | 8 +- 11 files changed, 123 insertions(+), 220 deletions(-) diff --git a/.circleci/create_circleci_config.py b/.circleci/create_circleci_config.py index be2c8495c408..aff69510d636 100644 --- a/.circleci/create_circleci_config.py +++ b/.circleci/create_circleci_config.py @@ -16,9 +16,10 @@ import argparse import copy import os +import random from dataclasses import dataclass -from typing import Any, Optional - +from typing import Any, Dict, List, Optional +import glob import yaml @@ -31,7 +32,7 @@ "RUN_FLAKY": True, } # Disable the use of {"s": None} as the output is way too long, causing the navigation on CircleCI impractical -COMMON_PYTEST_OPTIONS = {"max-worker-restart": 0, "vvv": None, "rsfE": None} +COMMON_PYTEST_OPTIONS = {"max-worker-restart": 0, "vvv": None, "rsfE":None} DEFAULT_DOCKER_IMAGE = [{"image": "cimg/python:3.8.12"}] # Strings that commonly appear in the output of flaky tests when they fail. These are used with `pytest-rerunfailures` @@ -58,18 +59,14 @@ class EmptyJob: job_name = "empty" def to_dict(self): - steps = [{"run": "ls -la"}] + steps = [{"run": 'ls -la'}] if self.job_name == "collection_job": steps.extend( [ "checkout", {"run": "pip install requests || true"}, - { - "run": """while [[ $(curl --location --request GET "https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/job" --header "Circle-Token: $CCI_TOKEN"| jq -r '.items[]|select(.name != "collection_job")|.status' | grep -c "running") -gt 0 ]]; do sleep 5; done || true""" - }, - { - "run": "python utils/process_circleci_workflow_test_reports.py --workflow_id $CIRCLE_WORKFLOW_ID || true" - }, + {"run": """while [[ $(curl --location --request GET "https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/job" --header "Circle-Token: $CCI_TOKEN"| jq -r '.items[]|select(.name != "collection_job")|.status' | grep -c "running") -gt 0 ]]; do sleep 5; done || true"""}, + {"run": 'python utils/process_circleci_workflow_test_reports.py --workflow_id $CIRCLE_WORKFLOW_ID || true'}, {"store_artifacts": {"path": "outputs"}}, {"run": 'echo "All required jobs have now completed"'}, ] @@ -85,15 +82,15 @@ def to_dict(self): @dataclass class CircleCIJob: name: str - additional_env: dict[str, Any] = None - docker_image: list[dict[str, str]] = None - install_steps: list[str] = None + additional_env: Dict[str, Any] = None + docker_image: List[Dict[str, str]] = None + install_steps: List[str] = None marker: Optional[str] = None parallelism: Optional[int] = 0 pytest_num_workers: int = 8 - pytest_options: dict[str, Any] = None + pytest_options: Dict[str, Any] = None resource_class: Optional[str] = "xlarge" - tests_to_run: Optional[list[str]] = None + tests_to_run: Optional[List[str]] = None num_test_files_per_worker: Optional[int] = 10 # This should be only used for doctest job! command_timeout: Optional[int] = None @@ -108,10 +105,7 @@ def __post_init__(self): else: # BIG HACK WILL REMOVE ONCE FETCHER IS UPDATED print(os.environ.get("GIT_COMMIT_MESSAGE")) - if ( - "[build-ci-image]" in os.environ.get("GIT_COMMIT_MESSAGE", "") - or os.environ.get("GIT_COMMIT_MESSAGE", "") == "dev-ci" - ): + if "[build-ci-image]" in os.environ.get("GIT_COMMIT_MESSAGE", "") or os.environ.get("GIT_COMMIT_MESSAGE", "") == "dev-ci": self.docker_image[0]["image"] = f"{self.docker_image[0]['image']}:dev" print(f"Using {self.docker_image} docker image") if self.install_steps is None: @@ -123,7 +117,7 @@ def __post_init__(self): if isinstance(self.tests_to_run, str): self.tests_to_run = [self.tests_to_run] else: - test_file = os.path.join("test_preparation", f"{self.job_name}_test_list.txt") + test_file = os.path.join("test_preparation" , f"{self.job_name}_test_list.txt") print("Looking for ", test_file) if os.path.exists(test_file): with open(test_file) as f: @@ -136,14 +130,8 @@ def __post_init__(self): def to_dict(self): env = COMMON_ENV_VARIABLES.copy() - if self.job_name != "tests_hub": - # fmt: off - # not critical - env.update({"HF_TOKEN": "".join(["h", "f", "_", "H", "o", "d", "V", "u", "M", "q", "b", "R", "m", "t", "b", "z", "F", "Q", "O", "Q", "A", "J", "G", "D", "l", "V", "Q", "r", "R", "N", "w", "D", "M", "V", "C", "s", "d"])}) - # fmt: on - # Do not run tests decorated by @is_flaky on pull requests - env["RUN_FLAKY"] = os.environ.get("CIRCLE_PULL_REQUEST", "") == "" + env['RUN_FLAKY'] = os.environ.get("CIRCLE_PULL_REQUEST", "") == "" env.update(self.additional_env) job = { @@ -154,84 +142,50 @@ def to_dict(self): job["resource_class"] = self.resource_class all_options = {**COMMON_PYTEST_OPTIONS, **self.pytest_options} - pytest_flags = [ - f"--{key}={value}" if (value is not None or key in ["doctest-modules"]) else f"-{key}" - for key, value in all_options.items() - ] + pytest_flags = [f"--{key}={value}" if (value is not None or key in ["doctest-modules"]) else f"-{key}" for key, value in all_options.items()] pytest_flags.append( f"--make-reports={self.name}" if "examples" in self.name else f"--make-reports=tests_{self.name}" ) - # Examples special case: we need to download NLTK files in advance to avoid cuncurrency issues + # Examples special case: we need to download NLTK files in advance to avoid cuncurrency issues timeout_cmd = f"timeout {self.command_timeout} " if self.command_timeout else "" marker_cmd = f"-m '{self.marker}'" if self.marker is not None else "" - junit_flags = " -p no:warning -o junit_family=xunit1 --junitxml=test-results/junit.xml" + junit_flags = f" -p no:warning -o junit_family=xunit1 --junitxml=test-results/junit.xml" joined_flaky_patterns = "|".join(FLAKY_TEST_FAILURE_PATTERNS) repeat_on_failure_flags = f"--reruns 5 --reruns-delay 2 --only-rerun '({joined_flaky_patterns})'" - parallel = f" << pipeline.parameters.{self.job_name}_parallelism >> " + parallel = f' << pipeline.parameters.{self.job_name}_parallelism >> ' steps = [ "checkout", {"attach_workspace": {"at": "test_preparation"}}, {"run": "apt-get update && apt-get install -y curl"}, {"run": " && ".join(self.install_steps)}, - { - "run": { - "name": "Download NLTK files", - "command": """python -c "import nltk; nltk.download('punkt', quiet=True)" """, - } - if "example" in self.name - else "echo Skipping" - }, - { - "run": { + {"run": {"name": "Download NLTK files", "command": """python -c "import nltk; nltk.download('punkt', quiet=True)" """} if "example" in self.name else "echo Skipping"}, + {"run": { "name": "Show installed libraries and their size", - "command": """du -h -d 1 "$(pip -V | cut -d ' ' -f 4 | sed 's/pip//g')" | grep -vE "dist-info|_distutils_hack|__pycache__" | sort -h | tee installed.txt || true""", - } + "command": """du -h -d 1 "$(pip -V | cut -d ' ' -f 4 | sed 's/pip//g')" | grep -vE "dist-info|_distutils_hack|__pycache__" | sort -h | tee installed.txt || true"""} }, - { - "run": { - "name": "Show installed libraries and their versions", - "command": """pip list --format=freeze | tee installed.txt || true""", - } + {"run": { + "name": "Show installed libraries and their versions", + "command": """pip list --format=freeze | tee installed.txt || true"""} }, - { - "run": { - "name": "Show biggest libraries", - "command": """dpkg-query --show --showformat='${Installed-Size}\t${Package}\n' | sort -rh | head -25 | sort -h | awk '{ package=$2; sub(".*/", "", package); printf("%.5f GB %s\n", $1/1024/1024, package)}' || true""", - } + {"run": { + "name": "Show biggest libraries", + "command": """dpkg-query --show --showformat='${Installed-Size}\t${Package}\n' | sort -rh | head -25 | sort -h | awk '{ package=$2; sub(".*/", "", package); printf("%.5f GB %s\n", $1/1024/1024, package)}' || true"""} }, {"run": {"name": "Create `test-results` directory", "command": "mkdir test-results"}}, - { - "run": { - "name": "Get files to test", - "command": f'curl -L -o {self.job_name}_test_list.txt <> --header "Circle-Token: $CIRCLE_TOKEN"' - if self.name != "pr_documentation_tests" - else 'echo "Skipped"', - } - }, - { - "run": { - "name": "Split tests across parallel nodes: show current parallel tests", - "command": f"TESTS=$(circleci tests split --split-by=timings {self.job_name}_test_list.txt) && echo $TESTS > splitted_tests.txt && echo $TESTS | tr ' ' '\n'" - if self.parallelism - else f"awk '{{printf \"%s \", $0}}' {self.job_name}_test_list.txt > splitted_tests.txt", - } + {"run": {"name": "Get files to test", "command":f'curl -L -o {self.job_name}_test_list.txt <> --header "Circle-Token: $CIRCLE_TOKEN"' if self.name != "pr_documentation_tests" else 'echo "Skipped"'}}, + {"run": {"name": "Split tests across parallel nodes: show current parallel tests", + "command": f"TESTS=$(circleci tests split --split-by=timings {self.job_name}_test_list.txt) && echo $TESTS > splitted_tests.txt && echo $TESTS | tr ' ' '\n'" if self.parallelism else f"awk '{{printf \"%s \", $0}}' {self.job_name}_test_list.txt > splitted_tests.txt" + } }, # During the CircleCI docker images build time, we might already (or not) download the data. # If it's done already, the files are inside the directory `/test_data/`. - { - "run": { - "name": "fetch hub objects before pytest", - "command": "cp -r /test_data/* . 2>/dev/null || true; python3 utils/fetch_hub_objects_for_ci.py", - } + {"run": {"name": "fetch hub objects before pytest", "command": "cp -r /test_data/* . 2>/dev/null || true; python3 utils/fetch_hub_objects_for_ci.py"}}, + {"run": { + "name": "Run tests", + "command": f"({timeout_cmd} python3 -m pytest {marker_cmd} -n {self.pytest_num_workers} {junit_flags} {repeat_on_failure_flags} {' '.join(pytest_flags)} $(cat splitted_tests.txt) | tee tests_output.txt)"} }, - { - "run": { - "name": "Run tests", - "command": f"({timeout_cmd} python3 -m pytest {marker_cmd} -n {self.pytest_num_workers} {junit_flags} {repeat_on_failure_flags} {' '.join(pytest_flags)} $(cat splitted_tests.txt) | tee tests_output.txt)", - } - }, - { - "run": { + {"run": + { "name": "Check for test crashes", "when": "always", "command": """if [ ! -f tests_output.txt ]; then @@ -243,30 +197,12 @@ def to_dict(self): exit 1 else echo "Tests output file exists and no worker crashes detected" - fi""", + fi""" }, }, - { - "run": { - "name": "Expand to show skipped tests", - "when": "always", - "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --skip", - } - }, - { - "run": { - "name": "Failed tests: show reasons", - "when": "always", - "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --fail", - } - }, - { - "run": { - "name": "Errors", - "when": "always", - "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --errors", - } - }, + {"run": {"name": "Expand to show skipped tests", "when": "always", "command": f"python3 .circleci/parse_test_outputs.py --file tests_output.txt --skip"}}, + {"run": {"name": "Failed tests: show reasons", "when": "always", "command": f"python3 .circleci/parse_test_outputs.py --file tests_output.txt --fail"}}, + {"run": {"name": "Errors", "when": "always", "command": f"python3 .circleci/parse_test_outputs.py --file tests_output.txt --errors"}}, {"store_test_results": {"path": "test-results"}}, {"store_artifacts": {"path": "test-results/junit.xml"}}, {"store_artifacts": {"path": "reports"}}, @@ -281,11 +217,7 @@ def to_dict(self): @property def job_name(self): - return ( - self.name - if ("examples" in self.name or "pipeline" in self.name or "pr_documentation" in self.name) - else f"tests_{self.name}" - ) + return self.name if ("examples" in self.name or "pipeline" in self.name or "pr_documentation" in self.name) else f"tests_{self.name}" # JOBS @@ -321,7 +253,7 @@ def job_name(self): pipelines_torch_job = CircleCIJob( "pipelines_torch", additional_env={"RUN_PIPELINE_TESTS": True}, - docker_image=[{"image": "huggingface/transformers-torch-light"}], + docker_image=[{"image":"huggingface/transformers-torch-light"}], marker="is_pipeline_test", parallelism=4, ) @@ -335,7 +267,7 @@ def job_name(self): examples_torch_job = CircleCIJob( "examples_torch", additional_env={"OMP_NUM_THREADS": 8}, - docker_image=[{"image": "huggingface/transformers-examples-torch"}], + docker_image=[{"image":"huggingface/transformers-examples-torch"}], # TODO @ArthurZucker remove this once docker is easier to build install_steps=["uv pip install . && uv pip install -r examples/pytorch/_tests_requirements.txt"], pytest_num_workers=4, @@ -344,9 +276,9 @@ def job_name(self): hub_job = CircleCIJob( "hub", additional_env={"HUGGINGFACE_CO_STAGING": True}, - docker_image=[{"image": "huggingface/transformers-torch-light"}], + docker_image=[{"image":"huggingface/transformers-torch-light"}], install_steps=[ - "uv pip install .", + 'uv pip install .', 'git config --global user.email "ci@dummy.com"', 'git config --global user.name "ci"', ], @@ -357,14 +289,14 @@ def job_name(self): exotic_models_job = CircleCIJob( "exotic_models", - docker_image=[{"image": "huggingface/transformers-exotic-models"}], + docker_image=[{"image":"huggingface/transformers-exotic-models"}], parallelism=4, pytest_options={"durations": 100}, ) repo_utils_job = CircleCIJob( "repo_utils", - docker_image=[{"image": "huggingface/transformers-consistency"}], + docker_image=[{"image":"huggingface/transformers-consistency"}], pytest_num_workers=4, resource_class="large", ) @@ -388,7 +320,7 @@ def job_name(self): command = f'echo """{py_command}""" > pr_documentation_tests_temp.txt' doc_test_job = CircleCIJob( "pr_documentation_tests", - docker_image=[{"image": "huggingface/transformers-consistency"}], + docker_image=[{"image":"huggingface/transformers-consistency"}], additional_env={"TRANSFORMERS_VERBOSITY": "error", "DATASETS_VERBOSITY": "error", "SKIP_CUDA_DOCTEST": "1"}, install_steps=[ # Add an empty file to keep the test step running correctly even no file is selected to be tested. @@ -396,7 +328,7 @@ def job_name(self): "touch dummy.py", command, "cat pr_documentation_tests_temp.txt", - "tail -n1 pr_documentation_tests_temp.txt | tee pr_documentation_tests_test_list.txt", + "tail -n1 pr_documentation_tests_temp.txt | tee pr_documentation_tests_test_list.txt" ], tests_to_run="$(cat pr_documentation_tests.txt)", # noqa pytest_options={"-doctest-modules": None, "doctest-glob": "*.md", "dist": "loadfile", "rvsA": None}, @@ -404,7 +336,7 @@ def job_name(self): pytest_num_workers=1, ) -REGULAR_TESTS = [torch_job, hub_job, tokenization_job, processor_job, generate_job, non_model_job] # fmt: skip +REGULAR_TESTS = [torch_job, hub_job, tokenization_job, processor_job, generate_job, non_model_job] # fmt: skip EXAMPLES_TESTS = [examples_torch_job] PIPELINE_TESTS = [pipelines_torch_job] REPO_UTIL_TESTS = [repo_utils_job] @@ -416,16 +348,13 @@ def create_circleci_config(folder=None): if folder is None: folder = os.getcwd() os.environ["test_preparation_dir"] = folder - jobs = [k for k in ALL_TESTS if os.path.isfile(os.path.join("test_preparation", f"{k.job_name}_test_list.txt"))] + jobs = [k for k in ALL_TESTS if os.path.isfile(os.path.join("test_preparation" , f"{k.job_name}_test_list.txt") )] print("The following jobs will be run ", jobs) if len(jobs) == 0: jobs = [EmptyJob()] else: - print( - "Full list of job name inputs", - {j.job_name + "_test_list": {"type": "string", "default": ""} for j in jobs}, - ) + print("Full list of job name inputs", {j.job_name + "_test_list":{"type":"string", "default":''} for j in jobs}) # Add a job waiting all the test jobs and aggregate their test summary files at the end collection_job = EmptyJob() collection_job.job_name = "collection_job" @@ -442,26 +371,19 @@ def create_circleci_config(folder=None): "GHA_Event": {"type": "string", "default": ""}, "GHA_Meta": {"type": "string", "default": ""}, "tests_to_run": {"type": "string", "default": ""}, - **{j.job_name + "_test_list": {"type": "string", "default": ""} for j in jobs}, - **{j.job_name + "_parallelism": {"type": "integer", "default": 1} for j in jobs}, + **{j.job_name + "_test_list":{"type":"string", "default":''} for j in jobs}, + **{j.job_name + "_parallelism":{"type":"integer", "default":1} for j in jobs}, }, - "jobs": {j.job_name: j.to_dict() for j in jobs}, + "jobs": {j.job_name: j.to_dict() for j in jobs} } if "CIRCLE_TOKEN" in os.environ: # For private forked repo. (e.g. new model addition) - config["workflows"] = { - "version": 2, - "run_tests": {"jobs": [{j.job_name: {"context": ["TRANSFORMERS_CONTEXT"]}} for j in jobs]}, - } + config["workflows"] = {"version": 2, "run_tests": {"jobs": [{j.job_name: {"context": ["TRANSFORMERS_CONTEXT"]}} for j in jobs]}} else: # For public repo. (e.g. `transformers`) config["workflows"] = {"version": 2, "run_tests": {"jobs": [j.job_name for j in jobs]}} with open(os.path.join(folder, "generated_config.yml"), "w") as f: - f.write( - yaml.dump(config, sort_keys=False, default_flow_style=False) - .replace("' << pipeline", " << pipeline") - .replace(">> '", " >>") - ) + f.write(yaml.dump(config, sort_keys=False, default_flow_style=False).replace("' << pipeline", " << pipeline").replace(">> '", " >>")) if __name__ == "__main__": diff --git a/.circleci/parse_test_outputs.py b/.circleci/parse_test_outputs.py index 21f186c76b5e..a69da1a3eafb 100644 --- a/.circleci/parse_test_outputs.py +++ b/.circleci/parse_test_outputs.py @@ -1,57 +1,53 @@ -import argparse import re - +import argparse def parse_pytest_output(file_path): skipped_tests = {} skipped_count = 0 - with open(file_path, "r") as file: + with open(file_path, 'r') as file: for line in file: - match = re.match(r"^SKIPPED \[(\d+)\] (tests/.*): (.*)$", line) + match = re.match(r'^SKIPPED \[(\d+)\] (tests/.*): (.*)$', line) if match: skipped_count += 1 test_file, test_line, reason = match.groups() skipped_tests[reason] = skipped_tests.get(reason, []) + [(test_file, test_line)] - for k, v in sorted(skipped_tests.items(), key=lambda x: len(x[1])): + for k,v in sorted(skipped_tests.items(), key=lambda x:len(x[1])): print(f"{len(v):4} skipped because: {k}") print("Number of skipped tests:", skipped_count) - def parse_pytest_failure_output(file_path): failed_tests = {} failed_count = 0 - with open(file_path, "r") as file: + with open(file_path, 'r') as file: for line in file: - match = re.match(r"^FAILED (tests/.*) - (.*): (.*)$", line) + match = re.match(r'^FAILED (tests/.*) - (.*): (.*)$', line) if match: failed_count += 1 _, error, reason = match.groups() failed_tests[reason] = failed_tests.get(reason, []) + [error] - for k, v in sorted(failed_tests.items(), key=lambda x: len(x[1])): + for k,v in sorted(failed_tests.items(), key=lambda x:len(x[1])): print(f"{len(v):4} failed because `{v[0]}` -> {k}") print("Number of failed tests:", failed_count) - if failed_count > 0: + if failed_count>0: exit(1) - def parse_pytest_errors_output(file_path): print(file_path) error_tests = {} error_count = 0 - with open(file_path, "r") as file: + with open(file_path, 'r') as file: for line in file: - match = re.match(r"^ERROR (tests/.*) - (.*): (.*)$", line) + match = re.match(r'^ERROR (tests/.*) - (.*): (.*)$', line) if match: error_count += 1 _, test_error, reason = match.groups() error_tests[reason] = error_tests.get(reason, []) + [test_error] - for k, v in sorted(error_tests.items(), key=lambda x: len(x[1])): + for k,v in sorted(error_tests.items(), key=lambda x:len(x[1])): print(f"{len(v):4} errored out because of `{v[0]}` -> {k}") print("Number of errors:", error_count) - if error_count > 0: + if error_count>0: exit(1) - def main(): parser = argparse.ArgumentParser() parser.add_argument("--file", help="file to parse") diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 78e96e9b3386..6c3a71de04a1 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -36,23 +36,19 @@ body: Models: - - text models: @ArthurZucker @Cyrilvallez - - vision models: @yonigozlan @molbap - - audio models: @eustlb @ebezzam @vasqu - - multimodal models: @zucchini-nlp + - text models: @ArthurZucker + - vision models: @amyeroberts, @qubvel + - speech models: @eustlb - graph models: @clefourrier Library: + - flax: @gante and @Rocketknight1 - generate: @zucchini-nlp (visual-language models) or @gante (all others) - - continuous batching: @remi-or @ArthurZucker @McPatate - pipelines: @Rocketknight1 + - tensorflow: @gante and @Rocketknight1 - tokenizers: @ArthurZucker and @itazap - trainer: @zach-huggingface @SunMarc - - attention: @vasqu @ArthurZucker @CyrilVallez - - model loading (from pretrained, etc): @CyrilVallez - - distributed: @3outeille @ArthurZucker @S1ro1 - - CIs: @ydshieh Integrations: @@ -60,7 +56,6 @@ body: - ray/raytune: @richardliaw, @amogkam - Big Model Inference: @SunMarc - quantization (bitsandbytes, autogpt): @SunMarc @MekkCyber - - kernels: @MekkCyber @drbh Devices/Backends: @@ -74,6 +69,19 @@ body: - for issues with a model, report at https://discuss.huggingface.co/ and tag the model's creator. + HF projects: + + - accelerate: [different repo](https://github.com/huggingface/accelerate) + - datasets: [different repo](https://github.com/huggingface/datasets) + - diffusers: [different repo](https://github.com/huggingface/diffusers) + - rust tokenizers: [different repo](https://github.com/huggingface/tokenizers) + + Maintained examples (not research project or legacy): + + - Flax: @Rocketknight1 + - PyTorch: See Models above and tag the person corresponding to the modality of the example. + - TensorFlow: @Rocketknight1 + Research projects are not maintained and should be taken as is. placeholder: "@Username ..." diff --git a/.github/scripts/assign_reviewers.py b/.github/scripts/assign_reviewers.py index 04319c555087..02966204ea32 100644 --- a/.github/scripts/assign_reviewers.py +++ b/.github/scripts/assign_reviewers.py @@ -13,16 +13,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json import os +import github +import json +from github import Github import re from collections import Counter from pathlib import Path -import github -from github import Github - - def pattern_to_regex(pattern): if pattern.startswith("/"): start_anchor = True @@ -36,12 +34,11 @@ def pattern_to_regex(pattern): pattern = r"^\/?" + pattern # Allow an optional leading slash after the start of the string return pattern - def get_file_owners(file_path, codeowners_lines): # Process lines in reverse (last matching pattern takes precedence) for line in reversed(codeowners_lines): # Skip comments and empty lines, strip inline comments - line = line.split("#")[0].strip() + line = line.split('#')[0].strip() if not line: continue @@ -57,11 +54,10 @@ def get_file_owners(file_path, codeowners_lines): return owners # Remember, can still be empty! return [] # Should never happen, but just in case - def pr_author_is_in_hf(pr_author, codeowners_lines): # Check if the PR author is in the codeowners file for line in codeowners_lines: - line = line.split("#")[0].strip() + line = line.split('#')[0].strip() if not line: continue @@ -73,19 +69,18 @@ def pr_author_is_in_hf(pr_author, codeowners_lines): return True return False - def main(): script_dir = Path(__file__).parent.absolute() with open(script_dir / "codeowners_for_review_action") as f: codeowners_lines = f.readlines() - g = Github(os.environ["GITHUB_TOKEN"]) + g = Github(os.environ['GITHUB_TOKEN']) repo = g.get_repo("huggingface/transformers") - with open(os.environ["GITHUB_EVENT_PATH"]) as f: + with open(os.environ['GITHUB_EVENT_PATH']) as f: event = json.load(f) # The PR number is available in the event payload - pr_number = event["pull_request"]["number"] + pr_number = event['pull_request']['number'] pr = repo.get_pull(pr_number) pr_author = pr.user.login if pr_author_is_in_hf(pr_author, codeowners_lines): @@ -120,5 +115,6 @@ def main(): print(f"Failed to request review for {top_owners}: {e}") + if __name__ == "__main__": main() diff --git a/.github/workflows/build_documentation.yml b/.github/workflows/build_documentation.yml index ae67046435fd..c55638ded149 100644 --- a/.github/workflows/build_documentation.yml +++ b/.github/workflows/build_documentation.yml @@ -16,7 +16,7 @@ jobs: commit_sha: ${{ github.sha }} package: transformers notebook_folder: transformers_doc - languages: ar de en es fr hi it ja ko pt zh + languages: ar de en es fr hi it ko pt tr zh ja te custom_container: huggingface/transformers-doc-builder secrets: token: ${{ secrets.HUGGINGFACE_PUSH }} diff --git a/.github/workflows/model_jobs.yml b/.github/workflows/model_jobs.yml index 83f818fcda3b..7e30cde735fa 100644 --- a/.github/workflows/model_jobs.yml +++ b/.github/workflows/model_jobs.yml @@ -12,6 +12,9 @@ on: slice_id: required: true type: number + runner_map: + required: false + type: string docker: required: true type: string @@ -51,12 +54,10 @@ jobs: matrix: folders: ${{ fromJson(inputs.folder_slices)[inputs.slice_id] }} runs-on: - group: '${{ inputs.machine_type }}' + group: ${{ fromJson(inputs.runner_map)[matrix.folders][inputs.machine_type] }} container: image: ${{ inputs.docker }} options: --gpus all --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache/ - outputs: - machine_type: ${{ steps.set_machine_type.outputs.machine_type }} steps: - name: Echo input and matrix info shell: bash @@ -110,7 +111,6 @@ jobs: run: pip freeze - name: Set `machine_type` for report and artifact names - id: set_machine_type working-directory: /transformers shell: bash run: | @@ -126,49 +126,29 @@ jobs: echo "$machine_type" echo "machine_type=$machine_type" >> $GITHUB_ENV - echo "machine_type=$machine_type" >> $GITHUB_OUTPUT - - - name: Create report directory if it doesn't exist - shell: bash - run: | - mkdir -p /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports - echo "dummy" > /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/dummy.txt - ls -la /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports - name: Run all tests on GPU working-directory: /transformers - run: | - script -q -c "PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS=yes _PATCHED_TESTING_METHODS_OUTPUT_DIR=/transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports python3 -m pytest -rsfE -v --make-reports=${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports tests/${{ matrix.folders }}" test_outputs.txt - ls -la - # Extract the exit code from the output file - EXIT_CODE=$(tail -1 test_outputs.txt | grep -o 'COMMAND_EXIT_CODE="[0-9]*"' | cut -d'"' -f2) - exit ${EXIT_CODE:-1} + run: python3 -m pytest -rsfE -v --make-reports=${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports tests/${{ matrix.folders }} - name: Failure short reports if: ${{ failure() }} - # This step is only to show information on Github Actions log. - # Always mark this step as successful, even if the report directory or the file `failures_short.txt` in it doesn't exist continue-on-error: true - run: cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/failures_short.txt + run: cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports/failures_short.txt - - name: Captured information - if: ${{ failure() }} - continue-on-error: true - run: | - cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/captured_info.txt - - - name: Copy test_outputs.txt - if: ${{ always() }} - continue-on-error: true + - name: Run test + shell: bash run: | - cp /transformers/test_outputs.txt /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports + mkdir -p /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports + echo "hello" > /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports/hello.txt + echo "${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports" - name: "Test suite reports artifacts: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports" if: ${{ always() }} uses: actions/upload-artifact@v4 with: name: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports - path: /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports + path: /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports collated_reports: name: Collated Reports @@ -179,5 +159,5 @@ jobs: job: run_models_gpu report_repo_id: ${{ inputs.report_repo_id }} gpu_name: ${{ inputs.runner_type }} - machine_type: ${{ needs.run_models_gpu.outputs.machine_type }} + machine_type: ${{ inputs.machine_type }} secrets: inherit diff --git a/.github/workflows/pr_build_doc_with_comment.yml b/.github/workflows/pr_build_doc_with_comment.yml index 1fc6e57b08b4..ec43c5b2cf96 100644 --- a/.github/workflows/pr_build_doc_with_comment.yml +++ b/.github/workflows/pr_build_doc_with_comment.yml @@ -14,7 +14,7 @@ permissions: {} jobs: get-pr-number: name: Get PR number - if: ${{ github.event.issue.state == 'open' && contains(fromJSON('["ydshieh", "ArthurZucker", "zucchini-nlp", "molbap", "gante", "LysandreJik", "Cyrilvallez", "Rocketknight1", "SunMarc", "muellerzr", "eustlb", "MekkCyber", "manueldeprada", "vasqu", "ivarflakstad", "stevhliu", "ebezzam", "itazap"]'), github.actor) && (startsWith(github.event.comment.body, 'build-doc')) }} + if: ${{ github.event.issue.state == 'open' && contains(fromJSON('["ydshieh", "ArthurZucker", "zucchini-nlp", "qubvel", "molbap", "gante", "LysandreJik", "Cyrilvallez", "Rocketknight1", "SunMarc", "muellerzr", "eustlb", "MekkCyber", "manueldeprada", "vasqu", "ivarflakstad", "stevhliu", "ebezzam"]'), github.actor) && (startsWith(github.event.comment.body, 'build-doc')) }} uses: ./.github/workflows/get-pr-number.yml get-pr-info: diff --git a/.github/workflows/self-comment-ci.yml b/.github/workflows/self-comment-ci.yml index 6b8535410238..f1c93aab5a86 100644 --- a/.github/workflows/self-comment-ci.yml +++ b/.github/workflows/self-comment-ci.yml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-22.04 name: Get PR number # For security: only allow team members to run - if: ${{ github.event.issue.state == 'open' && contains(fromJSON('["ydshieh", "ArthurZucker", "zucchini-nlp", "molbap", "gante", "LysandreJik", "Cyrilvallez", "Rocketknight1", "SunMarc", "muellerzr", "eustlb", "MekkCyber", "manueldeprada", "vasqu", "ivarflakstad", "stevhliu", "ebezzam", "remi-or", "itazap"]'), github.actor) && (startsWith(github.event.comment.body, 'run-slow') || startsWith(github.event.comment.body, 'run slow') || startsWith(github.event.comment.body, 'run_slow')) }} + if: ${{ github.event.issue.state == 'open' && contains(fromJSON('["ydshieh", "ArthurZucker", "zucchini-nlp", "qubvel", "molbap", "gante", "LysandreJik", "Cyrilvallez", "Rocketknight1", "SunMarc", "muellerzr", "eustlb", "MekkCyber", "manueldeprada", "vasqu", "ivarflakstad", "stevhliu", "ebezzam", "remi-or"]'), github.actor) && (startsWith(github.event.comment.body, 'run-slow') || startsWith(github.event.comment.body, 'run slow') || startsWith(github.event.comment.body, 'run_slow')) }} outputs: PR_NUMBER: ${{ steps.set_pr_number.outputs.PR_NUMBER }} steps: diff --git a/.github/workflows/self-scheduled-amd-mi355-caller.yml b/.github/workflows/self-scheduled-amd-mi355-caller.yml index d7061f433569..bd2fde3b0529 100644 --- a/.github/workflows/self-scheduled-amd-mi355-caller.yml +++ b/.github/workflows/self-scheduled-amd-mi355-caller.yml @@ -23,7 +23,7 @@ jobs: runner_scale_set: amd-mi355-ci docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: hf-transformers-bot/transformers-ci-dummy + report_repo_id: optimum-amd/transformers_daily_ci secrets: inherit torch-pipeline: @@ -35,7 +35,7 @@ jobs: runner_scale_set: amd-mi355-ci docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: hf-transformers-bot/transformers-ci-dummy + report_repo_id: optimum-amd/transformers_daily_ci secrets: inherit example-ci: @@ -47,7 +47,7 @@ jobs: runner_scale_set: amd-mi355-ci docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: hf-transformers-bot/transformers-ci-dummy + report_repo_id: optimum-amd/transformers_daily_ci secrets: inherit deepspeed-ci: @@ -59,5 +59,5 @@ jobs: runner_scale_set: amd-mi355-ci docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: hf-transformers-bot/transformers-ci-dummy + report_repo_id: optimum-amd/transformers_daily_ci secrets: inherit diff --git a/.github/workflows/self-scheduled-caller.yml b/.github/workflows/self-scheduled-caller.yml index 01f5a0a48bdd..78c7f3c60f23 100644 --- a/.github/workflows/self-scheduled-caller.yml +++ b/.github/workflows/self-scheduled-caller.yml @@ -88,7 +88,6 @@ jobs: job: run_trainer_and_fsdp_gpu slack_report_channel: "#transformers-ci-daily-training" docker: huggingface/transformers-all-latest-gpu - runner_type: "a10" ci_event: Daily CI report_repo_id: hf-internal-testing/transformers_daily_ci commit_sha: ${{ github.sha }} diff --git a/.github/workflows/self-scheduled.yml b/.github/workflows/self-scheduled.yml index 7129b1867fc4..a5dbc9d59a82 100644 --- a/.github/workflows/self-scheduled.yml +++ b/.github/workflows/self-scheduled.yml @@ -68,6 +68,7 @@ jobs: outputs: folder_slices: ${{ steps.set-matrix.outputs.folder_slices }} slice_ids: ${{ steps.set-matrix.outputs.slice_ids }} + runner_map: ${{ steps.set-matrix.outputs.runner_map }} quantization_matrix: ${{ steps.set-matrix-quantization.outputs.quantization_matrix }} steps: - name: Update clone @@ -94,6 +95,7 @@ jobs: if [ "${{ inputs.job }}" = "run_models_gpu" ]; then echo "folder_slices=$(python3 ../utils/split_model_tests.py --models '${{ inputs.models }}' --num_splits ${{ env.NUM_SLICES }})" >> $GITHUB_OUTPUT echo "slice_ids=$(python3 -c 'd = list(range(${{ env.NUM_SLICES }})); print(d)')" >> $GITHUB_OUTPUT + echo "runner_map=$(python3 ../utils/get_runner_map.py)" >> $GITHUB_OUTPUT elif [ "${{ inputs.job }}" = "run_trainer_and_fsdp_gpu" ]; then echo "folder_slices=[['trainer'], ['fsdp']]" >> $GITHUB_OUTPUT echo "slice_ids=[0, 1]" >> $GITHUB_OUTPUT @@ -117,13 +119,14 @@ jobs: strategy: fail-fast: false matrix: - machine_type: [aws-g5-4xlarge-cache, aws-g5-12xlarge-cache] + machine_type: [single-gpu, multi-gpu] slice_id: ${{ fromJSON(needs.setup.outputs.slice_ids) }} uses: ./.github/workflows/model_jobs.yml with: folder_slices: ${{ needs.setup.outputs.folder_slices }} machine_type: ${{ matrix.machine_type }} slice_id: ${{ matrix.slice_id }} + runner_map: ${{ needs.setup.outputs.runner_map }} docker: ${{ inputs.docker }} commit_sha: ${{ inputs.commit_sha || github.sha }} runner_type: ${{ inputs.runner_type }} @@ -144,10 +147,9 @@ jobs: folder_slices: ${{ needs.setup.outputs.folder_slices }} machine_type: ${{ matrix.machine_type }} slice_id: ${{ matrix.slice_id }} + runner_map: ${{ needs.setup.outputs.runner_map }} docker: ${{ inputs.docker }} commit_sha: ${{ inputs.commit_sha || github.sha }} - runner_type: ${{ inputs.runner_type }} - report_repo_id: ${{ inputs.report_repo_id }} report_name_prefix: run_trainer_and_fsdp_gpu secrets: inherit From aa15f5d5671c31aaef80616d0a88ebf964a4deb9 Mon Sep 17 00:00:00 2001 From: ErfanBaghaei Date: Tue, 7 Oct 2025 20:03:43 -0700 Subject: [PATCH 204/204] Restore CI config to match upstream main (no diffs) --- .circleci/create_circleci_config.py | 31 +++-- .circleci/parse_test_outputs.py | 3 +- .github/ISSUE_TEMPLATE/bug-report.yml | 29 ++-- .github/PULL_REQUEST_TEMPLATE.md | 38 ++--- .github/scripts/assign_reviewers.py | 8 +- .github/scripts/codeowners_for_review_action | 130 +++++++++--------- .github/workflows/benchmark_v2.yml | 12 +- .github/workflows/benchmark_v2_a10_caller.yml | 2 + .../workflows/benchmark_v2_mi325_caller.yml | 2 + .github/workflows/build-docker-images.yml | 3 +- .github/workflows/build_documentation.yml | 14 +- .github/workflows/model_jobs.yml | 46 +++++-- .../workflows/pr_build_doc_with_comment.yml | 2 +- .github/workflows/self-comment-ci.yml | 2 +- .../self-scheduled-amd-mi325-caller.yml | 8 +- .../self-scheduled-amd-mi355-caller.yml | 20 +-- .github/workflows/self-scheduled-caller.yml | 1 + .github/workflows/self-scheduled.yml | 8 +- .github/workflows/ssh-runner.yml | 17 ++- 19 files changed, 214 insertions(+), 162 deletions(-) diff --git a/.circleci/create_circleci_config.py b/.circleci/create_circleci_config.py index aff69510d636..6e98ee0f1493 100644 --- a/.circleci/create_circleci_config.py +++ b/.circleci/create_circleci_config.py @@ -16,10 +16,9 @@ import argparse import copy import os -import random from dataclasses import dataclass -from typing import Any, Dict, List, Optional -import glob +from typing import Any, Optional + import yaml @@ -30,6 +29,7 @@ "RUN_PIPELINE_TESTS": False, # will be adjust in `CircleCIJob.to_dict`. "RUN_FLAKY": True, + "DISABLE_SAFETENSORS_CONVERSION": True, } # Disable the use of {"s": None} as the output is way too long, causing the navigation on CircleCI impractical COMMON_PYTEST_OPTIONS = {"max-worker-restart": 0, "vvv": None, "rsfE":None} @@ -82,15 +82,15 @@ def to_dict(self): @dataclass class CircleCIJob: name: str - additional_env: Dict[str, Any] = None - docker_image: List[Dict[str, str]] = None - install_steps: List[str] = None + additional_env: dict[str, Any] = None + docker_image: list[dict[str, str]] = None + install_steps: list[str] = None marker: Optional[str] = None parallelism: Optional[int] = 0 pytest_num_workers: int = 8 - pytest_options: Dict[str, Any] = None + pytest_options: dict[str, Any] = None resource_class: Optional[str] = "xlarge" - tests_to_run: Optional[List[str]] = None + tests_to_run: Optional[list[str]] = None num_test_files_per_worker: Optional[int] = 10 # This should be only used for doctest job! command_timeout: Optional[int] = None @@ -130,6 +130,12 @@ def __post_init__(self): def to_dict(self): env = COMMON_ENV_VARIABLES.copy() + if self.job_name != "tests_hub": + # fmt: off + # not critical + env.update({"HF_TOKEN": "".join(["h", "f", "_", "H", "o", "d", "V", "u", "M", "q", "b", "R", "m", "t", "b", "z", "F", "Q", "O", "Q", "A", "J", "G", "D", "l", "V", "Q", "r", "R", "N", "w", "D", "M", "V", "C", "s", "d"])}) + # fmt: on + # Do not run tests decorated by @is_flaky on pull requests env['RUN_FLAKY'] = os.environ.get("CIRCLE_PULL_REQUEST", "") == "" env.update(self.additional_env) @@ -149,7 +155,7 @@ def to_dict(self): # Examples special case: we need to download NLTK files in advance to avoid cuncurrency issues timeout_cmd = f"timeout {self.command_timeout} " if self.command_timeout else "" marker_cmd = f"-m '{self.marker}'" if self.marker is not None else "" - junit_flags = f" -p no:warning -o junit_family=xunit1 --junitxml=test-results/junit.xml" + junit_flags = " -p no:warning -o junit_family=xunit1 --junitxml=test-results/junit.xml" joined_flaky_patterns = "|".join(FLAKY_TEST_FAILURE_PATTERNS) repeat_on_failure_flags = f"--reruns 5 --reruns-delay 2 --only-rerun '({joined_flaky_patterns})'" parallel = f' << pipeline.parameters.{self.job_name}_parallelism >> ' @@ -180,6 +186,7 @@ def to_dict(self): # During the CircleCI docker images build time, we might already (or not) download the data. # If it's done already, the files are inside the directory `/test_data/`. {"run": {"name": "fetch hub objects before pytest", "command": "cp -r /test_data/* . 2>/dev/null || true; python3 utils/fetch_hub_objects_for_ci.py"}}, + {"run": {"name": "download and unzip hub cache", "command": 'curl -L -o huggingface-cache.tar.gz https://huggingface.co/datasets/hf-internal-testing/hf_hub_cache/resolve/main/huggingface-cache.tar.gz && apt-get install pigz && tar --use-compress-program="pigz -d -p 8" -xf huggingface-cache.tar.gz && mv -n hub/* /root/.cache/huggingface/hub/ && ls -la /root/.cache/huggingface/hub/'}}, {"run": { "name": "Run tests", "command": f"({timeout_cmd} python3 -m pytest {marker_cmd} -n {self.pytest_num_workers} {junit_flags} {repeat_on_failure_flags} {' '.join(pytest_flags)} $(cat splitted_tests.txt) | tee tests_output.txt)"} @@ -200,9 +207,9 @@ def to_dict(self): fi""" }, }, - {"run": {"name": "Expand to show skipped tests", "when": "always", "command": f"python3 .circleci/parse_test_outputs.py --file tests_output.txt --skip"}}, - {"run": {"name": "Failed tests: show reasons", "when": "always", "command": f"python3 .circleci/parse_test_outputs.py --file tests_output.txt --fail"}}, - {"run": {"name": "Errors", "when": "always", "command": f"python3 .circleci/parse_test_outputs.py --file tests_output.txt --errors"}}, + {"run": {"name": "Expand to show skipped tests", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --skip"}}, + {"run": {"name": "Failed tests: show reasons", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --fail"}}, + {"run": {"name": "Errors", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --errors"}}, {"store_test_results": {"path": "test-results"}}, {"store_artifacts": {"path": "test-results/junit.xml"}}, {"store_artifacts": {"path": "reports"}}, diff --git a/.circleci/parse_test_outputs.py b/.circleci/parse_test_outputs.py index a69da1a3eafb..c58447155859 100644 --- a/.circleci/parse_test_outputs.py +++ b/.circleci/parse_test_outputs.py @@ -1,5 +1,6 @@ -import re import argparse +import re + def parse_pytest_output(file_path): skipped_tests = {} diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 6c3a71de04a1..30ac3b4c9512 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -36,19 +36,23 @@ body: Models: - - text models: @ArthurZucker - - vision models: @amyeroberts, @qubvel - - speech models: @eustlb + - text models: @ArthurZucker @Cyrilvallez + - vision models: @yonigozlan @molbap + - audio models: @eustlb @ebezzam @vasqu + - multimodal models: @zucchini-nlp - graph models: @clefourrier Library: - - flax: @gante and @Rocketknight1 - generate: @zucchini-nlp (visual-language models) or @gante (all others) + - continuous batching: @remi-or @ArthurZucker @McPatate - pipelines: @Rocketknight1 - - tensorflow: @gante and @Rocketknight1 - tokenizers: @ArthurZucker and @itazap - trainer: @zach-huggingface @SunMarc + - attention: @vasqu @ArthurZucker @CyrilVallez + - model loading (from pretrained, etc): @CyrilVallez + - distributed: @3outeille @ArthurZucker @S1ro1 + - CIs: @ydshieh Integrations: @@ -56,6 +60,8 @@ body: - ray/raytune: @richardliaw, @amogkam - Big Model Inference: @SunMarc - quantization (bitsandbytes, autogpt): @SunMarc @MekkCyber + - kernels: @MekkCyber @drbh + - peft: @BenjaminBossan @githubnemo Devices/Backends: @@ -69,19 +75,6 @@ body: - for issues with a model, report at https://discuss.huggingface.co/ and tag the model's creator. - HF projects: - - - accelerate: [different repo](https://github.com/huggingface/accelerate) - - datasets: [different repo](https://github.com/huggingface/datasets) - - diffusers: [different repo](https://github.com/huggingface/diffusers) - - rust tokenizers: [different repo](https://github.com/huggingface/tokenizers) - - Maintained examples (not research project or legacy): - - - Flax: @Rocketknight1 - - PyTorch: See Models above and tag the person corresponding to the modality of the example. - - TensorFlow: @Rocketknight1 - Research projects are not maintained and should be taken as is. placeholder: "@Username ..." diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index aa1e881122c1..de4ed57873ef 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -39,20 +39,23 @@ members/contributors who may be interested in your PR. Models: -- text models: @ArthurZucker -- vision models: @amyeroberts, @qubvel -- speech models: @eustlb +- text models: @ArthurZucker @Cyrilvallez +- vision models: @yonigozlan @molbap +- audio models: @eustlb @ebezzam @vasqu +- multimodal models: @zucchini-nlp - graph models: @clefourrier Library: -- flax: @gante and @Rocketknight1 - generate: @zucchini-nlp (visual-language models) or @gante (all others) +- continuous batching: @remi-or @ArthurZucker @McPatate - pipelines: @Rocketknight1 -- tensorflow: @gante and @Rocketknight1 -- tokenizers: @ArthurZucker -- trainer: @zach-huggingface, @SunMarc and @qgallouedec -- chat templates: @Rocketknight1 +- tokenizers: @ArthurZucker and @itazap +- trainer: @zach-huggingface @SunMarc +- attention: @vasqu @ArthurZucker @CyrilVallez +- model loading (from pretrained, etc): @CyrilVallez +- distributed: @3outeille @ArthurZucker @S1ro1 +- CIs: @ydshieh Integrations: @@ -60,20 +63,17 @@ Integrations: - ray/raytune: @richardliaw, @amogkam - Big Model Inference: @SunMarc - quantization (bitsandbytes, autogpt): @SunMarc @MekkCyber +- kernels: @MekkCyber @drbh +- peft: @BenjaminBossan @githubnemo -Documentation: @stevhliu - -HF projects: +Devices/Backends: -- accelerate: [different repo](https://github.com/huggingface/accelerate) -- datasets: [different repo](https://github.com/huggingface/datasets) -- diffusers: [different repo](https://github.com/huggingface/diffusers) -- rust tokenizers: [different repo](https://github.com/huggingface/tokenizers) +- AMD ROCm: @ivarflakstad +- Intel XPU: @IlyasMoutawwakil +- Ascend NPU: @ivarflakstad -Maintained examples (not research project or legacy): +Documentation: @stevhliu -- Flax: @Rocketknight1 -- PyTorch: See Models above and tag the person corresponding to the modality of the example. -- TensorFlow: @Rocketknight1 +Research projects are not maintained and should be taken as is. --> diff --git a/.github/scripts/assign_reviewers.py b/.github/scripts/assign_reviewers.py index 02966204ea32..18567203596f 100644 --- a/.github/scripts/assign_reviewers.py +++ b/.github/scripts/assign_reviewers.py @@ -13,14 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os -import github import json -from github import Github +import os import re from collections import Counter from pathlib import Path +import github +from github import Github + + def pattern_to_regex(pattern): if pattern.startswith("/"): start_anchor = True diff --git a/.github/scripts/codeowners_for_review_action b/.github/scripts/codeowners_for_review_action index 7325b0f570cc..f6c4b65a1e22 100644 --- a/.github/scripts/codeowners_for_review_action +++ b/.github/scripts/codeowners_for_review_action @@ -7,8 +7,8 @@ docs/ @stevhliu /docker/ @ydshieh @ArthurZucker # More high-level globs catch cases when specific rules later don't apply -/src/transformers/models/*/processing* @molbap @yonigozlan @qubvel -/src/transformers/models/*/image_processing* @qubvel +/src/transformers/models/*/processing* @molbap @yonigozlan +/src/transformers/models/*/image_processing* @yonigozlan /src/transformers/models/*/image_processing_*_fast* @yonigozlan # Owners of subsections of the library @@ -186,65 +186,65 @@ trainer_utils.py @zach-huggingface @SunMarc /src/transformers/models/zamba/mod*_zamba* @ArthurZucker # Vision models -/src/transformers/models/beit/mod*_beit* @amyeroberts @qubvel -/src/transformers/models/bit/mod*_bit* @amyeroberts @qubvel -/src/transformers/models/conditional_detr/mod*_conditional_detr* @amyeroberts @qubvel -/src/transformers/models/convnext/mod*_convnext* @amyeroberts @qubvel -/src/transformers/models/convnextv2/mod*_convnextv2* @amyeroberts @qubvel -/src/transformers/models/cvt/mod*_cvt* @amyeroberts @qubvel -/src/transformers/models/deformable_detr/mod*_deformable_detr* @amyeroberts @qubvel -/src/transformers/models/deit/mod*_deit* @amyeroberts @qubvel -/src/transformers/models/depth_anything/mod*_depth_anything* @amyeroberts @qubvel -/src/transformers/models/depth_anything_v2/mod*_depth_anything_v2* @amyeroberts @qubvel -/src/transformers/models/deta/mod*_deta* @amyeroberts @qubvel -/src/transformers/models/detr/mod*_detr* @amyeroberts @qubvel -/src/transformers/models/dinat/mod*_dinat* @amyeroberts @qubvel -/src/transformers/models/dinov2/mod*_dinov2* @amyeroberts @qubvel -/src/transformers/models/dinov2_with_registers/mod*_dinov2_with_registers* @amyeroberts @qubvel -/src/transformers/models/dit/mod*_dit* @amyeroberts @qubvel -/src/transformers/models/dpt/mod*_dpt* @amyeroberts @qubvel -/src/transformers/models/efficientformer/mod*_efficientformer* @amyeroberts @qubvel -/src/transformers/models/efficientnet/mod*_efficientnet* @amyeroberts @qubvel -/src/transformers/models/focalnet/mod*_focalnet* @amyeroberts @qubvel -/src/transformers/models/glpn/mod*_glpn* @amyeroberts @qubvel -/src/transformers/models/hiera/mod*_hiera* @amyeroberts @qubvel -/src/transformers/models/ijepa/mod*_ijepa* @amyeroberts @qubvel -/src/transformers/models/imagegpt/mod*_imagegpt* @amyeroberts @qubvel -/src/transformers/models/levit/mod*_levit* @amyeroberts @qubvel -/src/transformers/models/mask2former/mod*_mask2former* @amyeroberts @qubvel -/src/transformers/models/maskformer/mod*_maskformer* @amyeroberts @qubvel -/src/transformers/models/mobilenet_v1/mod*_mobilenet_v1* @amyeroberts @qubvel -/src/transformers/models/mobilenet_v2/mod*_mobilenet_v2* @amyeroberts @qubvel -/src/transformers/models/mobilevit/mod*_mobilevit* @amyeroberts @qubvel -/src/transformers/models/mobilevitv2/mod*_mobilevitv2* @amyeroberts @qubvel -/src/transformers/models/nat/mod*_nat* @amyeroberts @qubvel -/src/transformers/models/poolformer/mod*_poolformer* @amyeroberts @qubvel -/src/transformers/models/pvt/mod*_pvt* @amyeroberts @qubvel -/src/transformers/models/pvt_v2/mod*_pvt_v2* @amyeroberts @qubvel -/src/transformers/models/regnet/mod*_regnet* @amyeroberts @qubvel -/src/transformers/models/resnet/mod*_resnet* @amyeroberts @qubvel -/src/transformers/models/rt_detr/mod*_rt_detr* @amyeroberts @qubvel -/src/transformers/models/segformer/mod*_segformer* @amyeroberts @qubvel -/src/transformers/models/seggpt/mod*_seggpt* @amyeroberts @qubvel -/src/transformers/models/superpoint/mod*_superpoint* @amyeroberts @qubvel -/src/transformers/models/swiftformer/mod*_swiftformer* @amyeroberts @qubvel -/src/transformers/models/swin/mod*_swin* @amyeroberts @qubvel -/src/transformers/models/swinv2/mod*_swinv2* @amyeroberts @qubvel -/src/transformers/models/swin2sr/mod*_swin2sr* @amyeroberts @qubvel -/src/transformers/models/table_transformer/mod*_table_transformer* @amyeroberts @qubvel -/src/transformers/models/textnet/mod*_textnet* @amyeroberts @qubvel -/src/transformers/models/timm_wrapper/mod*_timm_wrapper* @amyeroberts @qubvel -/src/transformers/models/upernet/mod*_upernet* @amyeroberts @qubvel -/src/transformers/models/van/mod*_van* @amyeroberts @qubvel -/src/transformers/models/vit/mod*_vit* @amyeroberts @qubvel -/src/transformers/models/vit_hybrid/mod*_vit_hybrid* @amyeroberts @qubvel -/src/transformers/models/vitdet/mod*_vitdet* @amyeroberts @qubvel -/src/transformers/models/vit_mae/mod*_vit_mae* @amyeroberts @qubvel -/src/transformers/models/vitmatte/mod*_vitmatte* @amyeroberts @qubvel -/src/transformers/models/vit_msn/mod*_vit_msn* @amyeroberts @qubvel -/src/transformers/models/vitpose/mod*_vitpose* @amyeroberts @qubvel -/src/transformers/models/yolos/mod*_yolos* @amyeroberts @qubvel -/src/transformers/models/zoedepth/mod*_zoedepth* @amyeroberts @qubvel +/src/transformers/models/beit/mod*_beit* @yonigozlan @molbap +/src/transformers/models/bit/mod*_bit* @yonigozlan @molbap +/src/transformers/models/conditional_detr/mod*_conditional_detr* @yonigozlan @molbap +/src/transformers/models/convnext/mod*_convnext* @yonigozlan @molbap +/src/transformers/models/convnextv2/mod*_convnextv2* @yonigozlan @molbap +/src/transformers/models/cvt/mod*_cvt* @yonigozlan @molbap +/src/transformers/models/deformable_detr/mod*_deformable_detr* @yonigozlan @molbap +/src/transformers/models/deit/mod*_deit* @yonigozlan @molbap +/src/transformers/models/depth_anything/mod*_depth_anything* @yonigozlan @molbap +/src/transformers/models/depth_anything_v2/mod*_depth_anything_v2* @yonigozlan @molbap +/src/transformers/models/deta/mod*_deta* @yonigozlan @molbap +/src/transformers/models/detr/mod*_detr* @yonigozlan @molbap +/src/transformers/models/dinat/mod*_dinat* @yonigozlan @molbap +/src/transformers/models/dinov2/mod*_dinov2* @yonigozlan @molbap +/src/transformers/models/dinov2_with_registers/mod*_dinov2_with_registers* @yonigozlan @molbap +/src/transformers/models/dit/mod*_dit* @yonigozlan @molbap +/src/transformers/models/dpt/mod*_dpt* @yonigozlan @molbap +/src/transformers/models/efficientformer/mod*_efficientformer* @yonigozlan @molbap +/src/transformers/models/efficientnet/mod*_efficientnet* @yonigozlan @molbap +/src/transformers/models/focalnet/mod*_focalnet* @yonigozlan @molbap +/src/transformers/models/glpn/mod*_glpn* @yonigozlan @molbap +/src/transformers/models/hiera/mod*_hiera* @yonigozlan @molbap +/src/transformers/models/ijepa/mod*_ijepa* @yonigozlan @molbap +/src/transformers/models/imagegpt/mod*_imagegpt* @yonigozlan @molbap +/src/transformers/models/levit/mod*_levit* @yonigozlan @molbap +/src/transformers/models/mask2former/mod*_mask2former* @yonigozlan @molbap +/src/transformers/models/maskformer/mod*_maskformer* @yonigozlan @molbap +/src/transformers/models/mobilenet_v1/mod*_mobilenet_v1* @yonigozlan @molbap +/src/transformers/models/mobilenet_v2/mod*_mobilenet_v2* @yonigozlan @molbap +/src/transformers/models/mobilevit/mod*_mobilevit* @yonigozlan @molbap +/src/transformers/models/mobilevitv2/mod*_mobilevitv2* @yonigozlan @molbap +/src/transformers/models/nat/mod*_nat* @yonigozlan @molbap +/src/transformers/models/poolformer/mod*_poolformer* @yonigozlan @molbap +/src/transformers/models/pvt/mod*_pvt* @yonigozlan @molbap +/src/transformers/models/pvt_v2/mod*_pvt_v2* @yonigozlan @molbap +/src/transformers/models/regnet/mod*_regnet* @yonigozlan @molbap +/src/transformers/models/resnet/mod*_resnet* @yonigozlan @molbap +/src/transformers/models/rt_detr/mod*_rt_detr* @yonigozlan @molbap +/src/transformers/models/segformer/mod*_segformer* @yonigozlan @molbap +/src/transformers/models/seggpt/mod*_seggpt* @yonigozlan @molbap +/src/transformers/models/superpoint/mod*_superpoint* @yonigozlan @molbap +/src/transformers/models/swiftformer/mod*_swiftformer* @yonigozlan @molbap +/src/transformers/models/swin/mod*_swin* @yonigozlan @molbap +/src/transformers/models/swinv2/mod*_swinv2* @yonigozlan @molbap +/src/transformers/models/swin2sr/mod*_swin2sr* @yonigozlan @molbap +/src/transformers/models/table_transformer/mod*_table_transformer* @yonigozlan @molbap +/src/transformers/models/textnet/mod*_textnet* @yonigozlan @molbap +/src/transformers/models/timm_wrapper/mod*_timm_wrapper* @yonigozlan @molbap +/src/transformers/models/upernet/mod*_upernet* @yonigozlan @molbap +/src/transformers/models/van/mod*_van* @yonigozlan @molbap +/src/transformers/models/vit/mod*_vit* @yonigozlan @molbap +/src/transformers/models/vit_hybrid/mod*_vit_hybrid* @yonigozlan @molbap +/src/transformers/models/vitdet/mod*_vitdet* @yonigozlan @molbap +/src/transformers/models/vit_mae/mod*_vit_mae* @yonigozlan @molbap +/src/transformers/models/vitmatte/mod*_vitmatte* @yonigozlan @molbap +/src/transformers/models/vit_msn/mod*_vit_msn* @yonigozlan @molbap +/src/transformers/models/vitpose/mod*_vitpose* @yonigozlan @molbap +/src/transformers/models/yolos/mod*_yolos* @yonigozlan @molbap +/src/transformers/models/zoedepth/mod*_zoedepth* @yonigozlan @molbap # Audio models /src/transformers/models/audio_spectrogram_transformer/mod*_audio_spectrogram_transformer* @eustlb @@ -304,7 +304,7 @@ trainer_utils.py @zach-huggingface @SunMarc /src/transformers/models/donut/mod*_donut* @zucchini-nlp /src/transformers/models/flava/mod*_flava* @zucchini-nlp /src/transformers/models/git/mod*_git* @zucchini-nlp -/src/transformers/models/grounding_dino/mod*_grounding_dino* @qubvel +/src/transformers/models/grounding_dino/mod*_grounding_dino* @yonigozlan /src/transformers/models/groupvit/mod*_groupvit* @zucchini-nlp /src/transformers/models/idefics/mod*_idefics* @zucchini-nlp /src/transformers/models/idefics2/mod*_idefics2* @zucchini-nlp @@ -326,10 +326,10 @@ trainer_utils.py @zach-huggingface @SunMarc /src/transformers/models/mgp_str/mod*_mgp_str* @zucchini-nlp /src/transformers/models/mllama/mod*_mllama* @zucchini-nlp /src/transformers/models/nougat/mod*_nougat* @NielsRogge -/src/transformers/models/omdet_turbo/mod*_omdet_turbo* @qubvel @yonigozlan +/src/transformers/models/omdet_turbo/mod*_omdet_turbo* @yonigozlan /src/transformers/models/oneformer/mod*_oneformer* @zucchini-nlp -/src/transformers/models/owlvit/mod*_owlvit* @qubvel -/src/transformers/models/owlv2/mod*_owlv2* @qubvel +/src/transformers/models/owlvit/mod*_owlvit* @yonigozlan +/src/transformers/models/owlv2/mod*_owlv2* @yonigozlan /src/transformers/models/paligemma/mod*_paligemma* @zucchini-nlp @molbap /src/transformers/models/perceiver/mod*_perceiver* @zucchini-nlp /src/transformers/models/pix2struct/mod*_pix2struct* @zucchini-nlp diff --git a/.github/workflows/benchmark_v2.yml b/.github/workflows/benchmark_v2.yml index dc078e67ea97..fc9e07635185 100644 --- a/.github/workflows/benchmark_v2.yml +++ b/.github/workflows/benchmark_v2.yml @@ -7,6 +7,14 @@ on: description: 'GH Actions runner group to use' required: true type: string + container_image: + description: 'Docker image to use' + required: true + type: string + container_options: + description: 'Container options to use' + required: true + type: string commit_sha: description: 'Commit SHA to benchmark' required: false @@ -38,8 +46,8 @@ jobs: (github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'run-benchmark')) || (github.event_name == 'schedule') container: - image: huggingface/transformers-pytorch-gpu - options: --gpus all --privileged --ipc host --shm-size "16gb" + image: ${{ inputs.container_image }} + options: ${{ inputs.container_options }} steps: - name: Get repo uses: actions/checkout@v4 diff --git a/.github/workflows/benchmark_v2_a10_caller.yml b/.github/workflows/benchmark_v2_a10_caller.yml index 6d4f6ad7fe9a..6573d398b000 100644 --- a/.github/workflows/benchmark_v2_a10_caller.yml +++ b/.github/workflows/benchmark_v2_a10_caller.yml @@ -13,6 +13,8 @@ jobs: uses: ./.github/workflows/benchmark_v2.yml with: runner: aws-g5-4xlarge-cache-use1-public-80 + container_image: huggingface/transformers-pytorch-gpu + container_options: --gpus all --privileged --ipc host --shm-size "16gb" commit_sha: ${{ github.sha }} run_id: ${{ github.run_id }} benchmark_repo_id: hf-internal-testing/transformers-daily-benchmarks diff --git a/.github/workflows/benchmark_v2_mi325_caller.yml b/.github/workflows/benchmark_v2_mi325_caller.yml index 9ed387aee2ef..ed403148e596 100644 --- a/.github/workflows/benchmark_v2_mi325_caller.yml +++ b/.github/workflows/benchmark_v2_mi325_caller.yml @@ -13,6 +13,8 @@ jobs: uses: ./.github/workflows/benchmark_v2.yml with: runner: amd-mi325-ci-1gpu + container_image: huggingface/transformers-pytorch-amd-gpu + container_options: --device /dev/kfd --device /dev/dri --env ROCR_VISIBLE_DEVICES --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache commit_sha: ${{ github.sha }} run_id: ${{ github.run_id }} benchmark_repo_id: hf-internal-testing/transformers-daily-benchmarks diff --git a/.github/workflows/build-docker-images.yml b/.github/workflows/build-docker-images.yml index fe1f18f42b99..b53c6a4671f0 100644 --- a/.github/workflows/build-docker-images.yml +++ b/.github/workflows/build-docker-images.yml @@ -5,6 +5,7 @@ on: branches: - build_ci_docker_image* repository_dispatch: + workflow_dispatch: workflow_call: inputs: image_postfix: @@ -221,7 +222,7 @@ jobs: latest-pytorch-amd: name: "Latest PyTorch (AMD) [dev]" runs-on: - group: aws-general-8-plus + group: aws-highcpu-32-priv steps: - name: Set up Docker Buildx diff --git a/.github/workflows/build_documentation.yml b/.github/workflows/build_documentation.yml index c55638ded149..28982d04eb46 100644 --- a/.github/workflows/build_documentation.yml +++ b/.github/workflows/build_documentation.yml @@ -16,8 +16,20 @@ jobs: commit_sha: ${{ github.sha }} package: transformers notebook_folder: transformers_doc - languages: ar de en es fr hi it ko pt tr zh ja te + languages: en custom_container: huggingface/transformers-doc-builder secrets: token: ${{ secrets.HUGGINGFACE_PUSH }} hf_token: ${{ secrets.HF_DOC_BUILD_PUSH }} + + build_other_lang: + uses: huggingface/doc-builder/.github/workflows/build_main_documentation.yml@main + with: + commit_sha: ${{ github.sha }} + package: transformers + notebook_folder: transformers_doc + languages: ar de es fr hi it ja ko pt zh + custom_container: huggingface/transformers-doc-builder + secrets: + token: ${{ secrets.HUGGINGFACE_PUSH }} + hf_token: ${{ secrets.HF_DOC_BUILD_PUSH }} \ No newline at end of file diff --git a/.github/workflows/model_jobs.yml b/.github/workflows/model_jobs.yml index 7e30cde735fa..83f818fcda3b 100644 --- a/.github/workflows/model_jobs.yml +++ b/.github/workflows/model_jobs.yml @@ -12,9 +12,6 @@ on: slice_id: required: true type: number - runner_map: - required: false - type: string docker: required: true type: string @@ -54,10 +51,12 @@ jobs: matrix: folders: ${{ fromJson(inputs.folder_slices)[inputs.slice_id] }} runs-on: - group: ${{ fromJson(inputs.runner_map)[matrix.folders][inputs.machine_type] }} + group: '${{ inputs.machine_type }}' container: image: ${{ inputs.docker }} options: --gpus all --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache/ + outputs: + machine_type: ${{ steps.set_machine_type.outputs.machine_type }} steps: - name: Echo input and matrix info shell: bash @@ -111,6 +110,7 @@ jobs: run: pip freeze - name: Set `machine_type` for report and artifact names + id: set_machine_type working-directory: /transformers shell: bash run: | @@ -126,29 +126,49 @@ jobs: echo "$machine_type" echo "machine_type=$machine_type" >> $GITHUB_ENV + echo "machine_type=$machine_type" >> $GITHUB_OUTPUT + + - name: Create report directory if it doesn't exist + shell: bash + run: | + mkdir -p /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports + echo "dummy" > /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/dummy.txt + ls -la /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports - name: Run all tests on GPU working-directory: /transformers - run: python3 -m pytest -rsfE -v --make-reports=${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports tests/${{ matrix.folders }} + run: | + script -q -c "PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS=yes _PATCHED_TESTING_METHODS_OUTPUT_DIR=/transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports python3 -m pytest -rsfE -v --make-reports=${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports tests/${{ matrix.folders }}" test_outputs.txt + ls -la + # Extract the exit code from the output file + EXIT_CODE=$(tail -1 test_outputs.txt | grep -o 'COMMAND_EXIT_CODE="[0-9]*"' | cut -d'"' -f2) + exit ${EXIT_CODE:-1} - name: Failure short reports if: ${{ failure() }} + # This step is only to show information on Github Actions log. + # Always mark this step as successful, even if the report directory or the file `failures_short.txt` in it doesn't exist continue-on-error: true - run: cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports/failures_short.txt + run: cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/failures_short.txt - - name: Run test - shell: bash + - name: Captured information + if: ${{ failure() }} + continue-on-error: true + run: | + cat /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports/captured_info.txt + + - name: Copy test_outputs.txt + if: ${{ always() }} + continue-on-error: true run: | - mkdir -p /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports - echo "hello" > /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports/hello.txt - echo "${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports" + cp /transformers/test_outputs.txt /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports - name: "Test suite reports artifacts: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports" if: ${{ always() }} uses: actions/upload-artifact@v4 with: name: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports - path: /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports + path: /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports collated_reports: name: Collated Reports @@ -159,5 +179,5 @@ jobs: job: run_models_gpu report_repo_id: ${{ inputs.report_repo_id }} gpu_name: ${{ inputs.runner_type }} - machine_type: ${{ inputs.machine_type }} + machine_type: ${{ needs.run_models_gpu.outputs.machine_type }} secrets: inherit diff --git a/.github/workflows/pr_build_doc_with_comment.yml b/.github/workflows/pr_build_doc_with_comment.yml index ec43c5b2cf96..59aa22eef1ec 100644 --- a/.github/workflows/pr_build_doc_with_comment.yml +++ b/.github/workflows/pr_build_doc_with_comment.yml @@ -14,7 +14,7 @@ permissions: {} jobs: get-pr-number: name: Get PR number - if: ${{ github.event.issue.state == 'open' && contains(fromJSON('["ydshieh", "ArthurZucker", "zucchini-nlp", "qubvel", "molbap", "gante", "LysandreJik", "Cyrilvallez", "Rocketknight1", "SunMarc", "muellerzr", "eustlb", "MekkCyber", "manueldeprada", "vasqu", "ivarflakstad", "stevhliu", "ebezzam"]'), github.actor) && (startsWith(github.event.comment.body, 'build-doc')) }} + if: ${{ github.event.issue.state == 'open' && contains(fromJSON('["ydshieh", "ArthurZucker", "zucchini-nlp", "molbap", "gante", "LysandreJik", "Cyrilvallez", "Rocketknight1", "SunMarc", "eustlb", "MekkCyber", "vasqu", "ivarflakstad", "stevhliu", "ebezzam", "itazap"]'), github.actor) && (startsWith(github.event.comment.body, 'build-doc')) }} uses: ./.github/workflows/get-pr-number.yml get-pr-info: diff --git a/.github/workflows/self-comment-ci.yml b/.github/workflows/self-comment-ci.yml index f1c93aab5a86..e485973dcb05 100644 --- a/.github/workflows/self-comment-ci.yml +++ b/.github/workflows/self-comment-ci.yml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-22.04 name: Get PR number # For security: only allow team members to run - if: ${{ github.event.issue.state == 'open' && contains(fromJSON('["ydshieh", "ArthurZucker", "zucchini-nlp", "qubvel", "molbap", "gante", "LysandreJik", "Cyrilvallez", "Rocketknight1", "SunMarc", "muellerzr", "eustlb", "MekkCyber", "manueldeprada", "vasqu", "ivarflakstad", "stevhliu", "ebezzam", "remi-or"]'), github.actor) && (startsWith(github.event.comment.body, 'run-slow') || startsWith(github.event.comment.body, 'run slow') || startsWith(github.event.comment.body, 'run_slow')) }} + if: ${{ github.event.issue.state == 'open' && contains(fromJSON('["ydshieh", "ArthurZucker", "zucchini-nlp", "molbap", "gante", "LysandreJik", "Cyrilvallez", "Rocketknight1", "SunMarc", "eustlb", "MekkCyber", "vasqu", "ivarflakstad", "stevhliu", "ebezzam", "remi-or", "itazap"]'), github.actor) && (startsWith(github.event.comment.body, 'run-slow') || startsWith(github.event.comment.body, 'run slow') || startsWith(github.event.comment.body, 'run_slow')) }} outputs: PR_NUMBER: ${{ steps.set_pr_number.outputs.PR_NUMBER }} steps: diff --git a/.github/workflows/self-scheduled-amd-mi325-caller.yml b/.github/workflows/self-scheduled-amd-mi325-caller.yml index 8c2bad414bcf..510b3f6e2c78 100644 --- a/.github/workflows/self-scheduled-amd-mi325-caller.yml +++ b/.github/workflows/self-scheduled-amd-mi325-caller.yml @@ -20,7 +20,7 @@ jobs: with: job: run_models_gpu slack_report_channel: "#amd-hf-ci" - runner_scale_set: amd-mi325-ci + runner_group: amd-mi325 docker: huggingface/transformers-pytorch-amd-gpu ci_event: Scheduled CI (AMD) - mi325 report_repo_id: optimum-amd/transformers_daily_ci @@ -33,7 +33,7 @@ jobs: with: job: run_pipelines_torch_gpu slack_report_channel: "#amd-hf-ci" - runner_scale_set: amd-mi325-ci + runner_group: amd-mi325 docker: huggingface/transformers-pytorch-amd-gpu ci_event: Scheduled CI (AMD) - mi325 report_repo_id: optimum-amd/transformers_daily_ci @@ -46,7 +46,7 @@ jobs: with: job: run_examples_gpu slack_report_channel: "#amd-hf-ci" - runner_scale_set: amd-mi325-ci + runner_group: amd-mi325 docker: huggingface/transformers-pytorch-amd-gpu ci_event: Scheduled CI (AMD) - mi325 report_repo_id: optimum-amd/transformers_daily_ci @@ -59,7 +59,7 @@ jobs: with: job: run_torch_cuda_extensions_gpu slack_report_channel: "#amd-hf-ci" - runner_scale_set: amd-mi325-ci + runner_group: amd-mi325 docker: huggingface/transformers-pytorch-deepspeed-amd-gpu ci_event: Scheduled CI (AMD) - mi325 report_repo_id: optimum-amd/transformers_daily_ci diff --git a/.github/workflows/self-scheduled-amd-mi355-caller.yml b/.github/workflows/self-scheduled-amd-mi355-caller.yml index bd2fde3b0529..1b5dbe96ad97 100644 --- a/.github/workflows/self-scheduled-amd-mi355-caller.yml +++ b/.github/workflows/self-scheduled-amd-mi355-caller.yml @@ -3,7 +3,7 @@ name: Self-hosted runner scale set (AMD mi355 scheduled CI caller) # Note: For every job in this workflow, the name of the runner scale set is finalized in the runner yaml i.e. huggingface/hf-workflows/.github/workflows/transformers_amd_ci_scheduled_arc_scale_set.yaml # For example, 1gpu : amd-mi355-ci-1gpu # 2gpu : amd-mi355-ci-2gpu - + on: workflow_run: workflows: ["Self-hosted runner (AMD scheduled CI caller)"] @@ -20,10 +20,10 @@ jobs: with: job: run_models_gpu slack_report_channel: "#amd-hf-ci" - runner_scale_set: amd-mi355-ci + runner_group: hfc-amd-mi355 docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: optimum-amd/transformers_daily_ci + report_repo_id: hf-transformers-bot/transformers-ci-dummy secrets: inherit torch-pipeline: @@ -32,10 +32,10 @@ jobs: with: job: run_pipelines_torch_gpu slack_report_channel: "#amd-hf-ci" - runner_scale_set: amd-mi355-ci + runner_group: hfc-amd-mi355 docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: optimum-amd/transformers_daily_ci + report_repo_id: hf-transformers-bot/transformers-ci-dummy secrets: inherit example-ci: @@ -44,20 +44,20 @@ jobs: with: job: run_examples_gpu slack_report_channel: "#amd-hf-ci" - runner_scale_set: amd-mi355-ci + runner_group: hfc-amd-mi355 docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: optimum-amd/transformers_daily_ci + report_repo_id: hf-transformers-bot/transformers-ci-dummy secrets: inherit deepspeed-ci: name: DeepSpeed CI uses: huggingface/hf-workflows/.github/workflows/transformers_amd_ci_scheduled_arc_scale_set.yaml@main - with: + with: job: run_torch_cuda_extensions_gpu slack_report_channel: "#amd-hf-ci" - runner_scale_set: amd-mi355-ci + runner_group: hfc-amd-mi355 docker: huggingface/testing-rocm7.0-preview ci_event: Scheduled CI (AMD) - mi355 - report_repo_id: optimum-amd/transformers_daily_ci + report_repo_id: hf-transformers-bot/transformers-ci-dummy secrets: inherit diff --git a/.github/workflows/self-scheduled-caller.yml b/.github/workflows/self-scheduled-caller.yml index 78c7f3c60f23..01f5a0a48bdd 100644 --- a/.github/workflows/self-scheduled-caller.yml +++ b/.github/workflows/self-scheduled-caller.yml @@ -88,6 +88,7 @@ jobs: job: run_trainer_and_fsdp_gpu slack_report_channel: "#transformers-ci-daily-training" docker: huggingface/transformers-all-latest-gpu + runner_type: "a10" ci_event: Daily CI report_repo_id: hf-internal-testing/transformers_daily_ci commit_sha: ${{ github.sha }} diff --git a/.github/workflows/self-scheduled.yml b/.github/workflows/self-scheduled.yml index a5dbc9d59a82..7129b1867fc4 100644 --- a/.github/workflows/self-scheduled.yml +++ b/.github/workflows/self-scheduled.yml @@ -68,7 +68,6 @@ jobs: outputs: folder_slices: ${{ steps.set-matrix.outputs.folder_slices }} slice_ids: ${{ steps.set-matrix.outputs.slice_ids }} - runner_map: ${{ steps.set-matrix.outputs.runner_map }} quantization_matrix: ${{ steps.set-matrix-quantization.outputs.quantization_matrix }} steps: - name: Update clone @@ -95,7 +94,6 @@ jobs: if [ "${{ inputs.job }}" = "run_models_gpu" ]; then echo "folder_slices=$(python3 ../utils/split_model_tests.py --models '${{ inputs.models }}' --num_splits ${{ env.NUM_SLICES }})" >> $GITHUB_OUTPUT echo "slice_ids=$(python3 -c 'd = list(range(${{ env.NUM_SLICES }})); print(d)')" >> $GITHUB_OUTPUT - echo "runner_map=$(python3 ../utils/get_runner_map.py)" >> $GITHUB_OUTPUT elif [ "${{ inputs.job }}" = "run_trainer_and_fsdp_gpu" ]; then echo "folder_slices=[['trainer'], ['fsdp']]" >> $GITHUB_OUTPUT echo "slice_ids=[0, 1]" >> $GITHUB_OUTPUT @@ -119,14 +117,13 @@ jobs: strategy: fail-fast: false matrix: - machine_type: [single-gpu, multi-gpu] + machine_type: [aws-g5-4xlarge-cache, aws-g5-12xlarge-cache] slice_id: ${{ fromJSON(needs.setup.outputs.slice_ids) }} uses: ./.github/workflows/model_jobs.yml with: folder_slices: ${{ needs.setup.outputs.folder_slices }} machine_type: ${{ matrix.machine_type }} slice_id: ${{ matrix.slice_id }} - runner_map: ${{ needs.setup.outputs.runner_map }} docker: ${{ inputs.docker }} commit_sha: ${{ inputs.commit_sha || github.sha }} runner_type: ${{ inputs.runner_type }} @@ -147,9 +144,10 @@ jobs: folder_slices: ${{ needs.setup.outputs.folder_slices }} machine_type: ${{ matrix.machine_type }} slice_id: ${{ matrix.slice_id }} - runner_map: ${{ needs.setup.outputs.runner_map }} docker: ${{ inputs.docker }} commit_sha: ${{ inputs.commit_sha || github.sha }} + runner_type: ${{ inputs.runner_type }} + report_repo_id: ${{ inputs.report_repo_id }} report_name_prefix: run_trainer_and_fsdp_gpu secrets: inherit diff --git a/.github/workflows/ssh-runner.yml b/.github/workflows/ssh-runner.yml index 622773630330..5dae68b40f7e 100644 --- a/.github/workflows/ssh-runner.yml +++ b/.github/workflows/ssh-runner.yml @@ -33,14 +33,17 @@ jobs: steps: - name: Get runner to use shell: bash + env: + NUM_GPUS: ${{ github.event.inputs.num_gpus }} + RUNNER_TYPE: ${{ github.event.inputs.runner_type }} run: | - if [[ "${{ github.event.inputs.num_gpus }}" == "single" && "${{ github.event.inputs.runner_type }}" == "t4" ]]; then + if [[ "$NUM_GPUS" == "single" && "$RUNNER_TYPE" == "t4" ]]; then echo "RUNNER=aws-g4dn-4xlarge-cache" >> $GITHUB_ENV - elif [[ "${{ github.event.inputs.num_gpus }}" == "multi" && "${{ github.event.inputs.runner_type }}" == "t4" ]]; then + elif [[ "$NUM_GPUS" == "multi" && "$RUNNER_TYPE" == "t4" ]]; then echo "RUNNER=aws-g4dn-12xlarge-cache" >> $GITHUB_ENV - elif [[ "${{ github.event.inputs.num_gpus }}" == "single" && "${{ github.event.inputs.runner_type }}" == "a10" ]]; then + elif [[ "$NUM_GPUS" == "single" && "$RUNNER_TYPE" == "a10" ]]; then echo "RUNNER=aws-g5-4xlarge-cache" >> $GITHUB_ENV - elif [[ "${{ github.event.inputs.num_gpus }}" == "multi" && "${{ github.event.inputs.runner_type }}" == "a10" ]]; then + elif [[ "$NUM_GPUS" == "multi" && "$RUNNER_TYPE" == "a10" ]]; then echo "RUNNER=aws-g5-12xlarge-cache" >> $GITHUB_ENV else echo "RUNNER=" >> $GITHUB_ENV @@ -85,9 +88,11 @@ jobs: - name: Store Slack infos #because the SSH can be enabled dynamically if the workflow failed, so we need to store slack infos to be able to retrieve them during the waitforssh step shell: bash + env: + GITHUB_ACTOR: ${{ github.actor }} run: | - echo "${{ github.actor }}" - github_actor=${{ github.actor }} + echo "$GITHUB_ACTOR" + github_actor=$GITHUB_ACTOR github_actor=${github_actor/'-'/'_'} echo "$github_actor" echo "github_actor=$github_actor" >> $GITHUB_ENV